Scripting manual (GTA2)

GTA2 Scripting Information
(1998/1999 DMA Design Ltd.)

PLEASE NOTE: This product is not a patch but rather a software utility which the user employs at his or her own risk. DMA provides no remedies or warranties, whether express or implied, for this utility. The software and documentation accompanying the tool are provided "as is". You acknowledge that due to the complexity of the software it is possible that use of the software could lead to the unintentional corruption or loss of data, limb and life. You assume all risks of such data loss or corruption. In no case shall DMA be liable for any indirect, incidental, special, punitive, consequential or inconsequential damages or loss, including, without limitation, lost profits or the inability to use equipment or access data whether such damages are based upon a breach of express or implied warranties, breach of contract, negligence, strict tort, or any other legal theory. This document and program is released UNSUPPORTED. It was designed for internal use only, under suitable guidance. The compiler, miss2.exe, is very particular about script layout & syntax. You must follow the examples otherwise your scripts will not compile. Note the example script will take a while to compile!

This document is an overview of the GTA2 scripting process, listing details of each command and the various parameters. Various tables of info such as remap values, car types etc, are also included.

Compiling a script

  • Create your basic script as a textfile using any text editor.
  • Give it a name such as "text.mis" - all raw scripts must have a .mis extension
  • Compile the mis file using the Miss2.exe compiler program. This will generate a .tmp file, a .txt file & a .scr file of your raw script.
  • Once successfully compiled, copy the resulting .scr file into the DATA folder inside the GTA2 folder on your harddrive.

The error "SSYacc105e: Error token failed, no valid token" occurs when the compiler comes across a command that makes no sense. Usually, you've misspelled a name or command, or very often the number of 'brackets' doesn't add up. The error "Syntax Error: unrecognised token in scriptfile" generally means one of two things - you've either mistyped a word's name, or you've got the syntax wrong for a command. This means too many parameters, too few parameters, check you've got numbers as floats not integers etc. Check your brackets for commands too!


Mission language structures

GTA2script overview

GTA2 will contain a mission scripting system much improved over GTA1's. Instead of a constrained, linenumber/macro system where commands were hardcoded in a specific format, GTA2 uses a freeform scripting system, with a structure & syntax similar to Basic & "C". It provides predefined types for easy creation of characters, cars, objects, timers, triggers & the other items featured on a level.

The scripting language provides predefined types for easy creation of these 'items':

  • characters/pedestrians
  • cars
  • objects, e.g. telephones, rubbish, etc.
  • timers
  • counters
  • in-game 'trigger points' that cause events to happen in the scriptfile.

These can be created at startup or during the game. There is no concept of a 'future ped' or 'future car' in GTA2script as the scripting logic can now handle the difference. An example of creating a ped is

CHAR_DATA testped = ( 10.0 , 5.0 , 255.0 ) 90 0 CRIMINAL

In this example, GTA2script automatically places the ped at the correct 'z level' if asked to by the designer using 255.0 as 'z', any other value will place the ped at that 'z level', easing the problem of handling different z levels from GTA1. The different numbers are, in order, the coordinates to put the ped at, the angle (between 0 & 360) the ped should be facing and finally, the remap id. Cars, objects, etc all have similar create commands. If the designer tries to place a ped on a bridge or on a block with two heights of road or pavement, it will choose the higher 'z level' on top of the bridge. An alternative would be

CHAR_DATA anothertest
...
...
...
anothertest = CREATE_CHAR ( 10.0 , 5.5 , 255.0 ) 90 0 dummy END

This would 'reserve' the space for the ped at startup, but would create the ped later on midgame when the CREATE_PED line is executed. A more detailed example of this will be shown later.

In addition, GTA2script will contain a number of predefined programming structures. These are:

WHILE (x) DO (y)
( (x) AND (y) )
NOT (y)
IF (x) THEN y ENDIF
IF (x) THEN y ELSE z ENDIF

These can be used freely, and will lessen the need for designers to code these structures themselves. By having them predefined, also aids debugging - the designers can rely on them to work correctly. These can also be mixed & matched e.g.

	IF ( ( x ) AND (y))
		// Do something
		FOR ( x = 0 to 10)
			do_something
		ENDFOR
	ENDIF

GTA2script allows 'multitasking' of mission commands in a similar fashion to GTA1, but this is used less than it was in GTA1 - the ability to execute multiple lines in one cycle succeeds this. Separate "functions" are started as a new thread, running in sequence to the current thread. When the thread reaches the end of the function code, it kills itself. More control will be given to the designers over the timing & 'start/stop' of threads. A function looks like this in code:

labelname:
	//code
return

wait_for_ped:
	WHILE( NOT( IS_CHAR_IN_BLOCK ( char_name , 123 , 34 , 1 ) ) ) 
++ counter 
	ENDWHILE
return

In this example, the program waits until a ped has reached a given location, incrementing a counter each turn. Functions need not be called as a new thread, they can be 'jumped to' and run in sequence instead of parallel. The GOSUB label call acts 'in sequence'. There is no GOTO, only GOSUB so that the program *must* return out of the function. Example code:

In sequence:

ped = CREATE_CHAR ( 90.0 , 44.5 , 255.0 ) 90 1 bank_robber END
	GOSUB wait_for_ped:
	// here - ped has reached the target location	
	KILL_PED(ped)

In parallel:

ped = CREATE_CHAR ( 90.0 , 44.5 , 255.0 ) 1 90 dummy
new_thread = CREATE_THREAD wait_for_ped:
	// do something else, at the same time as wait_for_ped

The designers will have functions that can check the current state of a thread they've started, allowing them to check it has completed properly or handle problems. One of the original scripts' biggest problem was timing of commands - designers had little control over the sequencing of multiple threads or the timing of completion. In GTA2script, designers can pinpoint exactly when commands should 'kick start', as well as marking sections of code to be executed all at once, rather than one command at a time. Used in the right places, this will lessen a lot of timing errors & aid more precise events in critical sections of missions.

Comments

GTA2scripts are be long & detailed. To help designers read & follow their scripts, comments can easily be added using two different C++ style constructs. Comments in the scriptfile can be done two ways:

/* This is a comment */ 
// This is another comment 

The /* ... */ system can wrap over multiple lines, but there must be a matching /* */ pair. The // system effectively 'comments out' the rest of the line it is on, e.g.

PED_DATA one_ped 		// this ped is an example ped for simple demos

or

/* send_player_to_phones
This subroutine orders the player to the main phones & waits for him to arrive there */ 

Judicious use of whitespace to break up functions, separate out sections of code will help the readability of GTA2script files.

Angles

The angle system is:

NW N NE
225° 180° 135°
W 270° X 90° E
315° 45°
SW S SE

Floats

Floating point numbers are used extensively instead of the "fixed point" as in GTA1. If you want say, the centre of a block, 123.5 is used. For a quarter, 123.25 is needed. One limit of the script language is that all floating point numbers must have a .0 at the end. So the following are legal: 0.0 , 12.35 Whole numbers are not, e.g. 123

Integers

Integers are whole numbers in the range of -32767 to 32768. In GTA2script, they are mainly used in counters as floats are used to represent coordinates in general.

Automatic Z calculating

As noted in many 'creation' commands, it's possible for the game to automatically calculate the correct Z value for a given item, eg cars. This will only work in certain positions: effectively, the game will position the car at the highest Z value at this (X,Y). Any pipes or other structures will count. If something needs to be positioned in a block below a roof or an overhang etc, you will need to specify the correct Z manually.

Level start and level end

LEVELSTART lets the game know where the 'start' of the level processing should be. It will contain a group of commands that effectively "run" the level. LEVELEND flags the 'end' of the level commands. Should end the block of code after a levelstart.

LEVELSTART

LEVELEND

IF ... THEN ...

A basic "If X is true, then do Y". Used to control flow, branching if certain events have happened, if certain states are true. "X" can be as complex or as simple as needed. It can contain arithmetic checks or state checks on characters, cars, etc, e.g.

	IF ( IS_CAR_ WRECKED ( car_one ) ) 
		// handle car being wrecked
	ENDIF

	IF ( missions_passed > 10 )
		// end of level!
	ENDIF

Should avoid trying to "do" things in the "X" part of the if statement, aim to just do state checks etc. You can use "NOT" to check if things haven't happened yet, e.g.

	IF( NOT ( IS_CHAR_AT_LOCATION ( ped_one , location ) ) )
		// not quite at location yet
	ENDIF

The "Y" part can be any sort of normal command statement - it can be one or many.

IF ( expression )
	command
ENDIF

NOTE: Important to remember the number of brackets must be balanced, ie if there are 4 '(' brackets, there should be 4 ')' by the end of the line.

IF ... THEN ... ELSE ...

Similar to the normal IF (X) THEN (Y) statement, except with an extra ELSE (Z). If the (X) evaluates to TRUE then it executes Y, if FALSE, it executes Z, e.g.

	IF ( IS_CAR_WRECKED ( car_one ) )
		// do message "You've wrecked the car!"
	ELSE
		// do message "Well done the car is safe!"
	ENDIF
IF ( expression ) 
	command
ELSE
	command
ENDIF

Expressions

But what exactly is a valid expression as mentioned above?? As mentioned, commands that check 'state' of things are valid, e.g.

	IS_CAR_WRECKED ( car_one ) 
	IS_CHAR_IN_BLOCK ( char )
	IS_CHAR_DEAD ( char_two ) 

In addition, arithmetic expressions using counters are valid. This means you can check whether a counter has a certain value, less than, greater than etc. Valid arithmetic expressions are:

	counter < value
	counter < counter
	counter <= value 
	counter <= counter
	counter > value
	counter > counter
	counter >= value
	counter >= counter
	counter = value
	counter = counter

e.g.

	IF ( missions_completed > 10 )
	IF ( time_delay <= 200 )
	IF ( timer1 >= timer2 )

Just to make things more flexible & complex, "AND" , "NOT" & "OR" can be used in expressions. NOT negates the result of an expression. "AND" evaluates both expressions, returning TRUE if both are TRUE. "OR" evaluates both expressions returning TRUE if either expression is TRUE. These can be used together, e.g.

	IF ( ( missions_completed > 10 ) AND ( IS_CHAR_DEAD ( player ) )
	IF ( ( timer < timer 2 ) AND ( NOT ( timer2 = 0 ) ) )
	IF ( ( NOT ( IS_CHAR_STUNNED ( enemy_ped ) ) OR ( IS_CHAR_DEAD ( enemy_ped) ))
NOT ( expression ) 
( expression1 ) AND ( expression2 )
( expression1 ) OR ( expression2 )

NOTE: These are all comparison expressions, '=' will not 'store' the given value in a counter.

Counters

Declares a 'counter' variable and sets it to the default value for counters, 0. Counters can be used to keep track of mission counts etc. as in Grand Theft Auto, or as simple on/off flags. They can only store integer values. Fairly straightforward. Are also used in "FOR" loops etc. to control program flow. Counters have a range of values of: -32768 to 32767

COUNTER name
COUNTER name = value 

Set counter

This allows you to change a counter's contents during the game. You can explicitly set it equal to a certain value, or equal to another counter.

SET counter_name = integer value
SET counter_name = another_counter
SET counter_name = ( another_counter + yet_another_counter ) 
SET counter_name = ( another_counter - yet_another_counter ) 
SET counter_name = ( another_counter / yet_another_counter ) 
SET counter_name = ( another_counter * yet_another_counter ) 
SET counter_name = ( another_counter mod yet_another_counter ) 
SET counter_name = ( another_counter + value ) 
SET counter_name = ( another_counter - value ) 
SET counter_name = ( another_counter / value ) 
SET counter_name = ( another_counter * value ) 
SET counter_name = ( another_counter mod value )

Saved counters

Declares a 'counter' variable & sets it to the default value for counters, 0. A SAVED_COUNTER differs from a regular counter in that it gets 'stored' & restored in a savegame. Its value at the time of saving will be restored when a savegame is loaded. All your important mission status flags, all important 'number of missions done' counters etc should be SAVED_COUNTERs. At the moment, there is a maximum of 300 SAVED_COUNTERs - this isn't a limit on the number of COUNTERs you can have!

These should ONLY be in your main script, NEVER in one of the 'single mission' scripts that get loaded mid-game.

SAVED_COUNTER name

Save counter declare and set

As above, but sets the newly declared counter to a different value. If a savegame is getting loaded, whatever value in the samegame takes precedence & gets set, not this default value.

SAVED_COUNTER name = value 

Onscreen counters

This is a 'declaration' of space to be used to store a 'hook' for onscreen counters. You must put this outside the normal functions, in a similar position to your other declares. You only need one of these really, i.e. one for every counter onscreen at any time - not in TOTAL. This does not work like a counter - it's just a space to store some info related to the onscreen counters/timers.

ONSCREEN_COUNTER name

Add onscreen counter

This takes a 'COUNTER' variable & starts to display its contents onscreen, until your timer is removed, or you call 'CLEAR_ONSCREEN_COUNTER'. As you change the value of this counter, it will be automatically updated onscreen.

ADD_ONSCREEN_COUNTER ( onscreen_counter_name , counter_name )

Clear onscreen counter

This removes a counter from the screen, leaving the clock running if one is onscreen.

CLEAR_ONSCREEN_COUNTER ( onscreen_counter_name )

Timers

New concept alert! On-screen timers, ie countdowns, now have their own data declaration. You cannot display or use an onscreen timer without declaring at least one 'timer_data' item. I don't forsee you needing many of these in each file - and there's certainly no need to have individual timers for each separate mission. You should be able to get away with declaring maybe two or three at the top of your file.

TIMER_DATA name 

Display timer

Displays an onscreen "timer which counts down in game cycles to 0. It needs to be linked to a 'timer_data' item to store some extra info in.

DISPLAY_TIMER ( timer_name , count ) 

Clear timer

Clears one onscreen timer that's been created using a 'TIMER_DATA' & a 'DISPLAY_TIMER'. It clears only one timer. It will remove the CLOCK AND TIMER!

CLEAR_TIMER ( timer_name ) 

Clear clock only

This removes the 'timer' part of an onscreen display, leaving the counter to be displayed on its own.

CLEAR_CLOCK_ONLY ( timer_name ) 

Add time to timer

Adds time to an existing onscreen timer. Takes the time in as seconds, and the timer must be onscreen.

ADD_TIME_TO_TIMER ( timer_name , seconds )

WHILE loops

"While X Do Y" is another simple looping mechanism, with an expression check at the start of the block of commands. It will execute Y while X evaluates to TRUE. X can be any valid expression, Y is any valid block of commands e.g.

	WHILE ( NOT ( IS_CHAR_DEAD ( ped_one ) ) )
		// ped still alive
		TIMER = TIMER - 1
	ENDWHILE
WHILE ( expression ) 
	commands
ENDWHILE

WHILE EXEC loops

Similar to the standard WHILE loop except all of the code in the command block gets executed this processing cycle, ie instead of doing it one line at a time, it does all the lines. Very powerful but use carefully - too much use will slow down the game. e.g.

	WHILE_EXEC ( IS_PED_ALIVE ( player ) )
		IF ( score > needed_score ) 
			// congrats message
		ENDIF
		IF ( timer1 > endtimer ) 
			// different message
		ENDIF
	ENDWHILE
WHILE_EXEC ( expression)
	commands
ENDWHILE

DO WHILE loops

Another loop variant. However, this loop guarantees to execute the commands in the block once as the end check is at the end of the loop, e.g.

	DO 
		counter = counter + 1
	WHILE_TRUE ( counter < 100 ) 
DO
	commands
WHILE_TRUE ( expression ) 

Subroutines & jumping

With the new script system, it's a lot easier to "jump" to other subroutines in the scriptfile without the messy line numbers. Instead you label a section of commands, and later in the code you "GOSUB" to it. When the subroutine code finishes processing, the game will return to the line after the GOSUB command, effectively 'inserting' the code contained at the label. e.g.

subroutine: 
	SEND_PED_TO_BLOCK ( ped_one, location_one ) 
	WHILE ( NOT ( IS_PED_IN_BLOCK ( ped_one , location_one ) 
		counter = counter + 1
	ENDWHILE
RETURN

LEVELSTART
	ped_one = PED ( ... )
	GOSUB subroutine: 
// at this point, ped reached the location. 
ENDLEVEL

NOTE: Subroutines are very powerful, but be careful again with using them too much - they code make your code messy & difficult to follow. As you no longer need linenumbers, jumping about the file shouldn't be needed quite as much - just insert the new code!

Delay here

Waits for a given number of game cycles. This is a 'blocking' command - the game will not pass this line until the cycle count is passed. Should not be used inside EXEC blocks or WHILE_EXEC commands.

DELAY_HERE ( count ) 

Delay

Waits for a given number of game cycles, but does not "block". Returns TRUE while timer hasn't run out, FALSE once it's passed its cycle check.

DELAY ( count )

Do nowt

Simple, quick & straightforward command - it does nothing! Just proceeds onto the next line of your script. May be useful inside WHILE_EXEC blocks etc.

DO_NOWT 

PSX / PC IFDEF blocks

With the latest version of V8.3 of GTA2, we have some new script commands to help keep using just the one set of scripts on both the PC & PlayStation. You can now 'section off' certain blocks of commands, marking them to be only run on the PC or PlayStation - for instance, the number of parked cars could be reduced on the PlayStation just by doing:

PARKED_CAR xxxx
PARKED_CAR xxxx
PARKED_CAR xxxx

#ifdef PC 
PARKED_CAR xxxx
PARKED_CAR xxxx
PARKED_CAR xxxx
#endif

This would create three cars on the PSX, but six on the PC. This works just as well doing something ONLY on the PlayStation:

#ifdef PSX
	// do something for the PSX!
#endif

The other construct available lets you do one block of commands on the PC, with another block executed on the PlayStation:

#ifdef PC
	// do something PC specific
#else
	// do something on the PSX
#endif

or

#ifdef PSX
	// do something PSX
#else
	// do something PC
#endif

Important points:

  • You cannot 'nest' these constructs. In other words, you must finish a block with a '#endif' before you can do another '#ifdef'.
  • Every '#ifdef' must have an equivalent '#endif'.
  • You can never have a '#' anywhere else in your script from now on - it will ALWAYS be treated as the start of a '#ifdef'.
  • You can "comment out" these new commands by placing '//' right in front of the #. Note you have to do it for each '#' line e.g.
		//#ifdef PC
			do something
		//#endif

Multiscripts

The game is now capable of handling 'multiscripts' - this is the ability for each individual mission to be contained within an individual script which is loaded in when the main script demands it. The mainscript stays in memory at all times, with one other 'multiscript' allowed to be running at any time. A multiscript is a 'little' script - it has declarations at the top, separate functions & a main body flagged with 'MISSIONSTART' instead of LEVELSTART. It's at this MISSIONSTART that execution begins. Be aware that you cannot create anything in the declarations, only reserve space for items - this is because there's no 'initialisation' phase in a multiscript, it just gets loaded. You're free to do CREATE_CARs etc though as normal. One thing to note: you cannot have a FORWARD as the very first command in a multiscript!

Multiscripts are stored in a subdirectory inside DATA. It should have the same name as the mainscript being executed, e.g. WIL, STE, BIL. Launch the script using LAUNCH_MISSION.

Thread triggers

Thread triggers are a new data type that operate in a similar way to 'triggers' in GTA1. They start a new mission thread (like an old kickstart) when a particular condition has been met, e.g. a character enters a car, or the player enters a specific area (or block). They have a slightly different behaviour to other data types in GTA2script - they are always declared & set at the same time - never midgame. They can however be disabled & enabled. So it's possible to declare a thread_trigger using a car that has yet to be physically created. As long as it has been declared & has been created before the trigger is enabled, the game will operate.

Triggers in GTA2 are much different to GTA1. They are predominately used to start new threads & missions in the script, rather than as checks for events happening. The entire phone system relies on these "thread triggers" to kickstart a new process when the player answers a gang phone - the game waits for the player's collision with the ringing phone, finds an empty thread slot & starts it running at the function label referred to in the trigger setup. When the game finishes executing the function (and any sub-functions), the slot is returned & free to be re-used by another trigger.

Have an array of "trigger info 0-255, has details of type, action, state (ie true/false) etc. Whenever we create a trigger, say "WAIT FOR PED IN BLOCK we store the id of its triggerinfo in the object's spare info byte. When the trigger gets collided with, it calls object_hit which then does the checking of ids/states etc as requested by the triggerinfo it has a link to. The missionscript must check this each cycle to learn the state of the trigger, with designers aware of the fact that they will 'halt' until passed. Certain triggers can be designed with the idea of 'starting' a new process at a certain line.

Wait for character in car

This creates a trigger that waits for the given character (usually the player but not necessarily) entering a given car. When this happens, a new mission thread (ie process) is started, running the function listed. When the new thread encounters its last 'RETURN' command, it will shutdown itself. This is a 'declare' & should be outside any 'functions'. Note, there is a limit of about 30 of these in any one script. This should be more than enough.

THREAD_TRIGGER trigger_name = THREAD_WAIT_FOR_CHAR_IN_CAR ( char_name, car_name, label_name: )
char_name name of a previously declared character. Does not need to have been created yet, but it MUST be created when the trigger is enabled.
car_name name of a previously declared car. Again, does not need to have been created yet, but it must be created when you go to use the trigger for real.
label_name: name of the subroutine to be called when the trigger is enabled & the trigger action 'fires'. Note the label should have a ':' after it!

Wait for character in block

This is similar to the above command, but waits for a particular character entering a block on foot.

THREAD_TRIGGER trigger_name = THREAD_WAIT_FOR_CHAR_IN_BLOCK (char_name , x , y , z , labelname: )

Example:

CHAR_DATA player
CAR_DATA dummycar
THREAD_TRIGGER charcarthread = THREAD_WAIT_FOR_CHAR_IN_CAR ( player, dummycar, somecode: )
THREAD_TRIGGER charblock = THREAD_WAIT_FOR_CHAR_IN_BLOCK ( player, 123, 43, 2, someothercode: )

Wait for character in area

This is similar to the above command, but waits for a particular character entering a defined area on foot.

THREAD_TRIGGER trigger_name = THREAD_WAIT_FOR_CHAR_IN_AREA ( char_name , X.x , Y.y , Z.z , width, height, labelname: ) 

Wait for character in area any means

This is similar to the THREAD_WAIT_FOR_CHAR_IN_AREA command, but waits for a particular character entering a defined area by any means!

THREAD_TRIGGER trigger_name = THREAD_WAIT_FOR_CHAR_IN_AREA_ANY_MEANS (char_name , x , y , z , width, height, labelname: )

Wait for answer phone

This creates a trigger that waits for the given character (usually the player but not necessarily) answering a given phone. When this happens, a new mission thread (ie process) is started, running the function listed.

When the new thread encounters its last 'RETURN' command, it will shutdown itself. This is a 'declare' & should be outside any 'functions'. Note, there is a limit of about 30 of these in any one script. This should be more than enough.

THREAD_TRIGGER trigger_name = THREAD_WAIT_FOR_ANSWER_PHONE ( char_name, phone_name, labelname: )


Enable thread trigger

Switches on a previously created THREAD_TRIGGER item. Any car or character involved in the thread_trigger must have been created at this point.

ENABLE_THREAD_TRIGGER ( trigger_name ) 

Disable thread trigger

Switches off a previously created THREAD TRIGGER item. Any thread_triggers that you've yet to 'create' the cars/chars involved with it should be DISABLED.

DISABLE_THREAD_TRIGGER ( trigger_name ) 

Create thread

This command is used to create a new mission 'thread' or process, that runs in the background of the current thread. This is very similar to 'kickstarts' in GTA1, however due to the 'WHILE_EXEC' system we have in GTA2, you shouldn't need to use these 'threads' anywhere near as much. One effective use will be for checking cranes/powerups etc that run in the background constantly. Each thread you create needs a 'THREAD_ID' to store its info in.

CREATE_THREADs launch the new process at the start of a section of commands beginning with a specific label somewhere in yourfile, in a similar fashion to the way 'THREAD_TRIGGERs' start off their functions. The thread you've started terminates & closes itself down when it's executed its last 'RETURN' command, again similiarly to the threads started by a thread_trigger.

thread_name = CREATE_THREAD label_name:
thread_name name of a previously declared 'THREAD_ID' item
label_name: name of a previously declared label - including the ':' at the end!

Stop thread

This is the partner command to 'create_thread' - it stops a thread that has been previously started. The thread is told to terminate when it next executes - it will do no more processing.

STOP_THREAD ( thread_name ) 

Thread ID

Thread ID's are used to store info about threads created using 'create_thread'. They should be declared at the top of your script, beside all your other declarations.

THREAD_ID name 

EXEC

This command can be used in GTA2, but isn't mentioned in DMA Design's scripting manual.

EXEC
//commands that should be executed instantaneous.
ENDEXEC

Finish level

This command ends the current game & tells the 'frontend' that the player has successfully completed this level. The game will end rightaway! The new parameter is the bonus to award the player. Either BONUS_1 or BONUS_2 or BONUS_3 for bonus level 1,2 or 3. Use NO_BONUS if no extra level is to be awarded.

FINISH_LEVEL ( bonus_type )

Mission language commands

Player

Creates a player ped at a specific location with a specific remap & rotation. If float Z is given as 255.0, the game will calculate the correct Z value for the (X,Y) position.

PLAYER_PED player_name = CREATE_PLAYER ( X.x , Y.y , Z.z ) remap rotation

Add lives

Quick & easy function that lets you give a player extra lives - it simply adds them to his total, without messing around with powerups etc. Note there is a maximum of 99 lives for each player.

ADD_LIVES ( player_name , value ) 

Add multiplier

Increases the player's multiplier level by a certain number. There is a maximum multiplier level of 99.

ADD_MULTIPLIER ( player_name , value ) 

Store number lives

Stores the number of lives for this player in a previously declared counter - this counter can then be used in the normal arithmetic functions.

STORE_NUM_LIVES ( player_name , counter_name ) 

Store multiplier

Stores the current multiplier for this player in a previously declared counter - this counter can then be used in the arithmetic functions.

STORE_MULTIPLIER ( player_name , counter_name ) 

Set enter control status

This allows you to switch off the player's 'enter' control at specific points in the missions. This is a DANGEROUS command that could cause problems. You MUST switch it back on as soon as you're ready to. It may affect replays if you don't!

SET_ENTER_CONTROL_STATUS ( player_name , ON )
SET_ENTER_CONTROL_STATUS ( player_name , OFF )

Set all control status

This switches on/off all of the player's controls. This is HIGHLY HIGHLY DANGEROUS and should only be done when you DEFINITELY need to - e.g. during a warp command. Be very wary of doing this command! You must switch the controls back on at the earliest possible opportunity.

SET_ALL_CONTROLS_STATUS ( player_name , ON ) 
SET_ALL_CONTROLS_STATUS ( player_name , OFF ) 

Checks

Check char current weapon

This is a simple straightforward check - it looks at this character's currently selected weapon & returns TRUE if it matches a specific type, or FALSE if not. You should only really do this command on PLAYER controlled characters!

CHECK_CHAR_CURR_WEAPON ( player_name , weapon type ) 
Check number lives greater

Simply checks the number of lives for a player against a particular value. If greater than returns TRUE, else FALSE.

CHECK_NUM_LIVES_GREATER ( player_name , value ) 
Check multiplier greater

Simply checks the current multiplier for this player against a particular value. If greater than it returns TRUE, else FALSE.

CHECK_MULTIPLIER_GREATER ( player_name , value ) 
Is item onscreen?

Checks to see if a particular character, car or object is on the player's screen. Works with any valid item that exists. Returns TRUE if so, FALSE if not.

IS_ITEM_ONSCREEN ( name )
Is item accurately onscreen?

Highly accurate 'screen check' - it checks each corner of the item's collision information. Returns TRUE if so, FALSE if not.

IS_ITEM_ACCURATELY_ONSCREEN ( item_name )
Is point onscreen?

Checks to see if a particular (XYZ) is on any players' screen - will return TRUE if so, FALSE if not. If there are any 'remote control' cameras or anything similar, these are checked too. This command is really only suitable for single player missions.

IS_POINT_ONSCREEN ( X.x , Y.y , Z.z ) 

Cars

Declares and/or creates a car of model type "model" at a location, with a specific remap & rotation. When no Z value is given, the game will calculate the correct value for this (X,Y) position. In addition, if you want a truck with a trailer attached, just give an additional 'trailermodel' & the game will create an articulated vehicle - note that you're still giving the position/details of the cab at the front & make sure you have enough space! Set the trailermodel to "MINI_CAR" to make this car a small 'remote control' style car.

CAR_DATA name 

CAR_DATA name = ( X.x , Y.y ) remap rotation model
CAR_DATA name = ( X.x , Y.y ) remap rotation model trailermodel
CAR_DATA name = ( X.x , Y.y , Z.z ) remap rotation model
CAR_DATA name = ( X.x , Y.y , Z.z ) remap rotation model trailermodel

name = CREATE_CAR ( X.x , Y.y ) remap rotation model END
name = CREATE_CAR ( X.x , Y.y ) remap rotation model trailermodel END
name = CREATE_CAR ( X.x , Y.y , Z.z ) remap rotation model END
name = CREATE_CAR ( X.x , Y.y , Z.z ) remap rotation model trailermodel END

Gang cars

This new command is similar to the 'create_car' command, but makes a 'gang car' instead. You must use one of the predefined gang car types, eg isetta, miura etc with it! It will automatically add the gang logo decal to the car.

name = CREATE_GANG_CAR ( X.x , Y.y ) remap rotation model END
name = CREATE_GANG_CAR ( X.x , Y.y ) remap rotation model trailermodel END
name = CREATE_GANG_CAR ( X.x , Y.y , Z.z ) remap rotation model END
name = CREATE_GANG_CAR ( X.x , Y.y , Z.z ) remap rotation model trailermodel END

Parked car

Declares & creates a 'parked car' of model type "model" at a location, with a specific remap & rotation. When no Z value is given, the game will calculate the correct value for this (X,Y) position. In addition, if you want a truck with a trailer attached, just give an additional 'trailermodel' & the game will create an articulated vehicle - note that you're still giving the position/details of the cab at the front & make sure you have enough space!

PARKED_CARs are different to regular cars in that they just sit there, doing as little as possible until the player steals one. Additionally, they don't take up a slot reserved for mission cars. The maximum parked cars allowed is 48, with 8 on the PSX. These numbers are liable to change!

PARKED_CAR_DATA name = ( X.x , Y.y ) remap rotation model
PARKED_CAR_DATA name = ( X.x , Y.y ) remap rotation model trailermodel
PARKED_CAR_DATA name = ( X.x , Y.y , Z.z ) remap rotation model
PARKED_CAR_DATA name = ( X.x , Y.y , Z.z ) remap rotation model trailermodel

Change car remap

Alters the remap of a car to a new value. If the car is an articulated vehicle, it handles remapping the attached 'truck'.

CHANGE_CAR_REMAP ( car_name , new remap )

Set car number graphic

Sets the 'number' graphic on top of the GT24640 model of car. Valid numbers are 0 - 9. Call this command after you have done a CREATE_CAR. Only valid to call this command on this particular model!

SET_CAR_NUMBER_GRAPHIC ( car_name , number ) 

Set car bulletproof

Allows you to set & clear the 'bulletproof' status of a particular car. Bulletproof means the car will not take damage from bullets - it will however still be damaged from rockets & nearby explosions.

SET_CAR_BULLETPROOF ( car_name , ON )
SET_CAR_BULLETPROOF ( car_name , OFF ) 

Set car flameproof

Allows you to set & clear the 'flameproof' status of a particular car. Flameproof means the car will not take damage from flames (e.g. flamethrower) - it will however still be damaged from rockets & nearby explosions, and bullets.

SET_CAR_FLAMEPROOF ( car_name , ON )
SET_CAR_FLAMEPROOF ( car_name , OFF ) 

Set car rocketproof

Allows you to set & clear the 'rocketproof' status of a particular car. This means the car will not take damage from direct hits by rockets, molotovs or 'small explosions', e.g. grenades, nearby cars been wrecked etc. It will explode if a 'car bomb' blows up very close by.

SET_CAR_ROCKETPROOF ( car_name , ON )
SET_CAR_ROCKETPROOF ( car_name , OFF ) 

Give car alarm

Simply gives this particular car an alarm - it will ring if the car is stolen or if damaged by bullets etc.

GIVE_CAR_ALARM ( car_name ) 

Set car emergency lights

This lets you manipulate the lights on an 'emergency vehicle' that you've created, such as a copcar or firetruck. You can set the lights on or off as often as you like. If the car doesn't have these lights, it just does nothing.

SET_CAR_EMERG_LIGHTS ( car_name , ON ) 
SET_CAR_EMERG_LIGHTS ( car_name , OFF ) 

Set direction of TV Van dishes

Simply sets the location that all TV Van dishes point towards. This can be changed as often as you like mid-game.

SET_DIR_OF_TV_VANS ( X.x , Y.y )

Set car jammed car accelerator

As requested by Steve, this allows you to force a car's accelerator to be permanently on - the player cannot slow the car down. You can switch this on/off on any car that the player is controlling.

SET_CAR_JAMMED_ACCELERATOR ( car_name , ON ) 
SET_CAR_JAMMED_ACCELERATOR ( car_name , OFF )

Set car no collide

Sets a car as 'no collide', meaning it will not be moved/affected by any collisions.

SET_CAR_NO_COLLIDE ( car_name ) 

Change car lock

Allows you to alter the 'lock' on the doors on a particular car. The default lock for all mission cars is 'LOCKOUT_THIEF_ONLY'. Note that if you make a door 'LOCKED_PERMANENT', it will always be this state! See bottom of document for list of lock types.

CHANGE_CAR_LOCK ( car_name , lock_type ) 

Put car on trailer

This takes in two vehicles, one a "TRUKTRNS" - a trailer suitable for carrying cars, and another already created car. It places the car on top of the trailer & attaches it - effectively making the car on top of the trailer. This should never happen when the player is next to it, it will look STRANGE.

PUT_CAR_ON_TRAILER ( car_name , trailer_name ) 

Make car a dummy

Takes an already existing car, gives it a dummy driver & switches it "on" to driving - allowing it to drive around the city.

MAKE_CAR_A_DUMMY ( name ) 

Make car drive away

Makes an already created car 'drive off', ie drive around the city like a dummy would. This command requires the car to already have a driver!

MAKE_CAR_DRIVE_AWAY ( car_name )

Give driver and brake

Takes an existing car & gives it a dummy driver, but orders it to "stop" so it will stay in the block it's in.

GIVE_DRIVER_AND_BRAKE ( name )

Set recycle model wanted

This is a PSX 'special command' that allows you to specify a 'normal' car model you need generated by the recycler for the player to pick up. Using this command means you can depend on an icecream van coming along just when you require in the mission without actually creating one explicitly. Set the model to NONE if you no longer care - this is the default value. The cleanup code will ALWAYS set this to NONE just to be safe. You shouldn't use this command for ambulances/copcars etc - they'll be created as normal when the player does stuff! This command only works on the PSX - it just gets ignored on the PC.

SET_RECYCLE_MODEL_WANTED ( car model type )

Kill all passengers

Straightforward command to delete/kill every character who are currently passengers inside a car. The driver is left unharmed. One thing to be aware of is that your CHAR_DATA slots will not be wiped - these are invalid after you call this command.

KILL_ALL_PASSENGERS ( car_name ) 

Take remote control of car

Allows you to force a player to take control of another vehicle. The camera switches to viewing this car, and the player's character is immobilised. Note this character is still able to be killed/arrested. Control returns to the original character when the 'remote' vehicle is destroyed. The vehicle doesn't have to be a 'mini-car', it can be a normal sized car.

TAKE_REMOTE_CONTROL_OF_CAR ( player_name , car_name )

Store car that character is in

Looks to see whatever car this specified character is in, and stores its info as a valid car_data. If the character is not in a car, it currently will generate an error, but in the final game it will proceed to the next command.

STORE_CAR_CHARACTER_IS_IN ( char_name , car_name )

Store car current speed

Stores the current speed of this car in a counter. The values for this 'speed' is 0 (for stationary), 16384 for 1.0 speed. Normal car speeds are around 0 to 8192. You can then use the value in the counter as you would a normal counter - just check it against bigger values than normal!

STORE_CAR_CURRENT_SPEED ( car_name , counter ) 

Store character car current speed

Variant of the previous command - stores the speed of the car currently being driven by the specified character in this counter. Includes the player.

STORE_CHAR_CAR_CURRENT_SPEED ( char_name , counter ) 

Store maximum car speed

Stores the maximum speed for the car specified in a counter.

STORE_MAX_CAR_SPEED ( car_name , counter_name ) 

Suppress this car model

This lets you prevent the recycling from creating 'dummy vehicles' of a certain type. You can do this on only one type at any time, but you change this model as often as you like. If you want to finish suppressing a particular model, call the command with 'NONE' as the model. Willie's using this to prevent the game creating Isetta Limos until a particular mission involving one is done, there may be other uses for it, say prevent a specific model appearing during a specific mission. Use NONE as model_name to stop suppressing a model.

SUPPRESS_THIS_CAR_MODEL ( model_name ) 

Stop chars getting off bus

Setting this to ON prevents any passengers from getting off the public transport bus. Set it to OFF to switch it back to normal.

STOP_CHARS_GETTING_OFF_BUS ( player_name , ON )
STOP_CHARS_GETTING_OFF_BUS ( player_name , OFF )  

Checks

Is car in block?

This command checks to see if a particular car is inside a particular block. Returns TRUE if so, FALSE if not. The car must have previously been created. Add width and height of the location to check an area instead of 'just' one block. This is the TOTAL width/height - ie '1' will do it 0.5 in each direction.

IS_CAR_IN_BLOCK ( car_name , X.x , Y.y , Z.z )
IS_CAR_IN_BLOCK ( car_name , X.x , Y.y , Z.z , width , height )
Is car wrecked?

Checks to see if car's damage level means it's wrecked or if the car has just started sinking. Similar to the damage check, but simpler for speed. Returns TRUE if wrecked, FALSE if not.

IS_CAR_WRECKED ( car_name ) 
Is car crushed?

Checks to see if this particular car has been crushed. Returns TRUE if so, FALSE if not.

IS_CAR_CRUSHED ( car_name ) 
Has car just sunk?

Checks to see if a car has just sunk under water. Returns TRUE if so, FALSE if not

HAS_CAR_JUST_SUNK ( car_name )
Is car in the air?

Checks to see if a car is 'flying' through the air, ie left the ground. Be aware this may be triggered by going over the top of hills. Returns TRUE if so, FALSE if not.

IS_CAR_IN_AIR ( car_name ) 
Check car model

Checks to see if this car has a specific model - returns TRUE if so, FALSE if not.

CHECK_CAR_MODEL ( car_name , model ) 
Check car remap

Checks to see if this car has a specific remap - returns TRUE if so, FALSE if not.

CHECK_CAR_REMAP ( car_name , remap ) 
Check car model and remap

Checks to see if this car has a specific remap AND a specific model. TRUE if so, FALSE if not. Provided to ease checks & increase efficiency.

CHECK_CAR_MODEL_AND_REMAP ( car_name , model type , remap id ) 
Check passenger count

Checks to see if this car has a passenger count greater or equal to a particular value. Returns TRUE if so, FALSE if not.

CHECK_PASSENGER_COUNT ( car_name , value ) 
Check car wrecked in area

Checks to see if a specific car has just been destroyed inside a specific area, Returns TRUE if so, FALSE otherwise.

CHECK_CAR_WRECKED_IN_AREA ( car_name , X.x , Y.y , Z.z , width , height )
Check car's damage level

Performs a check on this car to see the percentage level of damage. If greater or equal to the specified value, returns TRUE otherwise FALSE. Note this works in percentages, *different* to how character health works 0 is completely undamaged. 100% is completely wrecked. e.g.

IF ( CHECK_CAR_DAMAGE_LEVEL ( car_one , 50 )
	// display message - "car is well bashed!"
ELSE
	// display message - only a little dent!
ENDIF
CHECK_CAR_DAMAGE_LEVEL ( car_name , value )
Check car damage position

This is a sneaky little command letting you do some clever things: it checks to see whether a particular car has 'damage' in a particular position - this effectively checks whether the car has a graphic damage delta on one of its four corners or on its window. It returns TRUE if so, FALSE if not. Valid positions to check are: "FRONT_LEFT" "FRONT_RIGHT" "BACK_LEFT" "BACK_RIGHT" "WINDOW"

CHECK_CAR_DAMAGE_POSITION ( car_name , position ) 
Check any weapon type hit car

This sets up a check that looks for any weapon to hit a particular car. It will return TRUE if such a hit has happened, FALSE if not. If you do a CHECK_WEAPON_TYPE_HIT_CAR after this returns true, you can check to see the particular type that's hit. See bottom of doc for list of 'types'

CHECK_ANY_WEAPON_TYPE_HIT_CAR ( car_name )
Check weapon type hit car

This is the car equivalent of 'check weapon type hit char'. Takes the name of a previously created car, and waits to see if a particular damage 'type' hits it. See 'check weapon type hit char' for full details.

CHECK_WEAPON_TYPE_HIT_CAR ( car_name , damage type ) 
Check car has driver

Performs a check on this car to see if it has a valid driver. Returns TRUE if it does, FALSE if not. A car needs a virtual driver for it to be able to drive around the city.

CHECK_CAR_HAS_DRIVER ( car_name )
Is trailer attached?

Checks to see whether this particular car has a particular trailer attached to it. Returns TRUE if so, FALSE if not. Set trailer_name to the same as car_name, and the game will check for ANY trailer being attached, not just a particular one.

IS_TRAILER_ATTACHED ( car_name , trailer_name )
Is car on trailer?

Checks to see whether a particular car is sitting on top of a particular car transporter. Returns TRUE if so, FALSE if not.

IS_CAR_ON_TRAILER ( car_name , transport name )
Has car got driver?

Simple quick check to see if a particular car currently has a driver - this can be any character driving it, whether scripted or a random dummy. Returns TRUE if so, FALSE if not.

HAS_CAR_GOT_DRIVER ( car_name ) 
Has car got weapon?

Checks whether a particular car currently has a weapon - use this to see if a car has a bomb on it! Returns TRUE if so, FALSE if not. At the moment, valid car weapons are: CAR_BOMB, CAR_OIL and CAR_MINE

HAS_CAR_GOT_WEAPON ( car_name , weapon type ) 
Is car bomb active?

Checks to see whether there is a carbomb active in this particular car - active means the timer is currently 'counting down' towards detonation. Returns TRUE if so, FALSE if not.

IS_CARBOMB_ACTIVE ( car_name ) 
Are emergency lights on?

Simple car check that looks to see if an emergency vehicle's lights are switched on. Returns TRUE if so, FALSE if not.

ARE_EMERG_LIGHTS_ON ( car_name )
Check car speed

Checks to see if the speed of this car is above a certain level. Ranges for the speed are 0 for stationary to anything upto 16384 (for 1.0!). If car speed is GREATER than value, returns TRUE, otherwise FALSE.

CHECK_CAR_SPEED ( car_name , speed ) 
Setup modelcheck destroy

This allows you to check to see if any vehicles of a particular model have been destroyed. You can have only one of these checks running at any time - call this command just before you want to do the check, and then call HAS_MODELCHECK_HAPPENED each cycle you want to check.

SETUP_MODELCHECK_DESTROY ( car_model )
Has modelcheck happened

This command is the partner to the 'setup' command - this looks to see if any of the model have been destroyed or sunk. It will return TRUE if so, FALSE if not. You must call this once a cycle, otherwise you will miss cars being destroyed!

HAS_MODELCHECK_HAPPENED ( ) 
Modelcheck example
COUNTER num_destroyed = 0
COUNTER timer = 2000

SETUP_MODELCHECK_DESTROY ( COPCAR ) 

WHILE_EXEC ( ( timer > 0 ) AND ( num_destroyed < 5 ) ) 
	IF ( HAS_MODELCHECK_HAPPENED ( ) 
		++ num_destroyed 
	ENDIF
-- timer 
ENDWHILE

IF ( num_destroyed >= 5 ) 
	DISPLAY_BRIEF ( 1001 ) // well done you passed the test!
ELSE
	DISPLAY_BRIEF ( 1002 ) // you failed to kill all the cops!
ENDIF
Is bus full?

Checks to see if the bus that this character is driving is full or not. Returns TRUE if so, FALSE if not. Current max passengers for a bus is 10. The character must be driving a bus!

IS_BUS_FULL ( char_name ) 

Characters

This is just a general overview of characters to be fleshed out in consultation with IainR. I need to discuss in depth actual access functions, objectives etc - this will be done next week.

Characters are created with a (X, Y, Z), a rotation, remap, graphic type, and an occupation - this will operate in a similar fashion to GTA1, eg. driver, bus passenger, psycho, mugger, elvis, medic.

Additionally, extra characteristics can be set: bravery & shooting skill - these affect how the character handles events in a group - say, a group gets wasted & only a few chars are left, a Coward will runaway. Shooting skill affects how accurate a shot this character has. The current levels for these are: bravery: coward, average, loony shooting skill: crap, normal, crack.

Once a character is created, it can be given an objective - for example, kill a character, wait for a bus. Additional "commands for characters are ones such as sending to a local position on foot, sending to a faraway location by any means (ie by car, by taxi). Characters can be given "patrol zones" through a list of points, and they'll follow that path. The script command "CHECK_OBJECTIVE" will check the state of the objective, whether it's succeeded, still being done, or failed.

On top of all this, groups of characters can be created & accessed through the 'leader' character - a totally new group (with leader) can be made, a new group given to an existing character, or given to the player's character. When a leader is killed, another character in the group becomes leader, this will be automatically updated in the mission info by a mission callback function - designers do not need to worry about this. Groups can be given the same objectives/"commands" as normal characters can.

Create character

Declares and/or creates a character at the specified (X, Y, Z). If Z is missed out, the game will automatically place the character at the top 'Z' value, in the same way as cars' Z is handled. The character will have the remap & rotation listed, as well as the occupation listed. A list of ped remaps will be created. See bottom of document for valid occupations.

A character's occupation defines his behaviour. For instance a dummy ped will just wander around in the way a 'dummy' does, a 'mugger' will go attack a ped & run away. See below for a current list of valid occupations.

CHAR_DATA name

CHAR_DATA name = ( X.x , Y.y ) remap rotation occupation
CHAR_DATA name = ( X.x , Y.y , Z.z ) remap rotation occupation

char_name = CREATE_CHAR ( X.x , Y.y ) remap rotation occupation END
char_name = CREATE_CHAR ( X.x , Y.y , Z.z ) remap rotation occupation END

Create character inside a car

This creates a pre-declared character inside of a pre-created car, setting him up to be the driver of this car. By calling this command, it means you do not need to create the char outside, send him to the char, wait for his objective & /then/ do what you really want to do - it's an effective 'shortcut' for cutting down the script complexity.

char_name = CREATE_CHAR_INSIDE_CAR ( car_name ) remap occupation END

Examples

CHAR_DATA future_ped

CHAR_DATA mugger_one = ( 123.4 , 23.2 , 2.0 ) 0 180 MUGGER
CHAR_DATA just_a_dummy = ( 4.4 , 110.5 , 4.0 ) 3 45 DUMMY

future_ped = CREATE_CHAR ( 123.4 , 5.6 , 2.0 ) 0 350 mugger END

Set character graphic type

This lets you manipulate the 'graphic' of a particular character, as well as his remap. Use this to make a character look like a policeman or a gang member when he isn't.

Valid graphic types are: DUMMY_GRAPHIC, EMERG_GRAPHIC and GANG_GRAPHIC

SET_CHAR_GRAPHIC_TYPE ( char_name , graphic type , remap value ) 

Set character shooting skill

Sets the 'shooting skill' level for a character. Not currently activated, but you can still set this for the moment. See bottom of document for valid skill levels.

SET_CHAR_SHOOTING_SKILL ( char_name , skill ) 

Set character bravery level

Sets the bravery level for this character - this is implemented. Governs not a lot at the moment, threat reactions are more important. See bottom of document for valid bravery levels

SET_CHAR_BRAVERY_LEVEL ( char_name , level )

Set character drive aggression

This allows you to set whether this particular character should drive aggressively or not - if he does, he will ignore traffic lights etc, speed limits etc. This can be switched on & off at will.

SET_CHAR_DRIVE_AGGRESSION ( char_name , ON ) 
SET_CHAR_DRIVE_AGGRESSION ( char_name , OFF )

Set character invincible

Using this command, you can make a character (including the player) 'invincible' to all bullets/flames/rockets/explosions. The only way to harm him is to stun him! You can set this on & off.

SET_CHAR_INVINCIBLE ( char_name , ON ) 
SET_CHAR_INVINCIBLE ( char_name , OFF ) 

Set character maximum runspeed

Allows you to set the maximum 'run speed' for a particular character. This controls the speed he runs at.

SET_CHAR_MAX_RUNSPEED ( char_name , float speed )

Set character maximum drivespeed

Sets the 'max speed' that this character is allowed to drive at. Use this to tweak your chases/hunts etc. Sensible values are between 0.0 & 0.4 - the fastest car in the game travels around this speed. Note the character cannot drive faster than the top speed of the car he is in.

SET_CHAR_MAX_DRIVESPEED ( char_name , speed )

Set char to use his car weapon

This command forces a character to use any car weapon that is available to him in the car - use this to make "dummy" characters use gun jeeps, tanks etc properly. Again, this can be toggled ON/OFF

SET_CHAR_TO_USE_CAR_WEAPON ( char_name , ON ) 
SET_CHAR_TO_USE_CAR_WEAPON ( char_name , OFF )

Set favourite model

This allows you to make a character 'prefer' a favourite model for when he is doing a 'KILL_CHAR_ANY_MEANS'. If the char creates a car to use, it will be of this model.

SET_FAVOURITE_MODEL ( char_name , model name ) 

Set character occupation

This lets you change a character's occupation mid-game. Not applicable to the player's char!

SET_CHAR_OCCUPATION ( char_name , occupation ) 

Set character threat search

This command allows you to set the details of the new 'threat' searching for a character. A threat is for instance another shooting at this one, a rival gang member, or the player's character. By setting the 'threat search' you alter how this character will look for possible threats - you can make him ignore some threats, or only look for threats in his 'line of sight'. A character can only have one 'threat search' at any time, but this can be altered as often as you like.

SET_CHAR_THREAT_SEARCH ( char_name , threat_search )

Threat search types:

NO_THREATS Does not look for threats.
LINE_OF_SIGHT 90 Degree search angle in the direction the character is facing, ie if char is facing angle 90, the line of sight is between angle 45 & angle 135. 'Line of Sight' gets stopped by walls & buildings, but not by cars/objects. This means that the player can hide round corners & won't be spotted by other scripted characters using this search type.
AREA Will look for any threats with a certain area surrounding the character's current position. This area 'moves' with the character, ie it's effectively a box surrounding the character. At the moment this is fixed to a radius of three blocks in each direction - this will be changed in the future if necessary.
AREA_PLAYER_ONLY This is similar to the AREA search type, but ONLY the player counts as a threat.
LINE_OF_SIGHT_PLAYER_ONLY Similar to the LINE_OF_SIGHT_ search type, but the player's character is the only threat looked for.

Set character threat reaction

A follow on command from 'SET_CHARACTER_THREAT_SEARCH', this command allows you to decide how a character reacts once he's found a threat.

SET_CHAR_THREAT_REACTION ( char_name , reaction_type )

Threat reaction types:

NO_REACTION Ignores the threat.
REACT_AS_NORMAL This causes the char to perform his 'normal' reaction - ie a guard will go try to shoot the threat.
RUN_AWAY This simply orders the character to 'flee' when he sees a threat. As soon as he's far enough away from the threat, he'll return to his normal objective/action.

Example:

SET_CHAR_THREAT_SEARCH ( mayor_char , LINE_OF_SIGHT_PLAYER ) 
SET_CHAR_THREAT_REACTION ( mayor_char , RUN_AWAY ) 

These two commands make the character 'mayor_char' run away from the player as soon as the character sees the player.

Set character objective

This is a critical command that allows you to effectively order about characters. A character objective is a 'command' to its AI routines to do something, attempt something, go somewhere, kill something. Objectives will be used for character send-tos for example. They will take away a lot of the complexity involved with character missions in GTA1, and give a flexibility as well that should allow for more detailed, more complex missions & pre-defined 'scenes'.

Each character can have one main objective at any time, but this may be changed as often as needed - there should be little overhead in doing this. Additionally, each character in the game has a secondary objective based on its gang affiliation - this is all 'under the surface' and you should never need to worry about it. This second objective is used to make the 'gang zones' work.

Objectives have different possible 'states' - executing & passed. Certain objectives have a further state - 'failed'. Two secondary commands allow you to check the status of objectives, see below for information.

SET_CHAR_OBJECTIVE ( char_name , objective type ) 
SET_CHAR_OBJECTIVE ( char_name , objective type , second_item ) 
SET_CHAR_OBJECTIVE ( char_name , objective type , X.x , Y.y , Z.z ) 

The following objective types need no extra 'info' to work, so use the above command.

NO_OBJ: Orders the character to pretend to be a dummy & just wander around doing nothing in particular. Useful for when you're no longer interested in a character.
WAIT_ON_FOOT: Orders the char to wait on his current 'spot'/location, ie the char will stand on his current spot until something else happens.
FLEE_ON_FOOT_TILL_SAFE: The char 'flees' its current area until the char thinks he is safe. The size of the area is currently hardcoded to about 6 blocks, but this will change with future releases.
GUARD_SPOT: Orders the character to 'guard' his current standing position. If another character 'attacks' him, ie shoots nearby, the guard will attemp to shoot back. Best to give him a weapon!
GUARD_AREA: Similar to GUARD_SPOT, except the char guards his current area. At the moment, this is hardcoded to roughly 3/6 blocks, but this will be changed in the near future.
WAIT_IN_CAR: Orders the character to just 'wait' inside his current car. He'll do nothing - won't drive off like a normal driver.

These Objective Types need a second 'item' to work on. The item must be of the correct type, ie char/car/obj and have been created previously in the script.

KILL_CHAR_ON_FOOT: Orders the char to chase & kill this other particular character. To be effective, you should give the character a weapon, otherwise he'll hunt down the char & start punching him. Set 'second item' to be the name of the char to kill.
KILL_CHAR_ANY_MEANS: Orders the char to chase & kill this other particular character. If target is offscreen, this character will chase by car. Character will warp so don't put an arrow on him! Set 'second item' to be the name of the char to kill.
FLEE_CHAR_ON_FOOT_TILL_SAFE: Orders the character to runaway on foot from a second char until he feels 'safe'. When this happens, main objective gets flagged as 'passed', and the char will just start walking around normally. Change this behaviour by watching out for the objective getting passed, then give him a different objective. Set 'second item' to be the name of the character to flee.
FLEE_CHAR_ON_FOOT_ALWAYS: Orders the character to runaway on foot from a second char forever. Set 'second item' to be the name of the character to flee.
GOTO_CHAR_ON_FOOT: Orders the character to follow a second character. The char will run towards the second char, chasing after if necessary. As soon as the char 'catches up' with the second char, the objective is flagged as passed. IainR will be adding a 'goto_char_always' command that will continually follow a character. Set 'second item' to be the name of the character to go to.
LEAVE_CAR: Orders the character to exit this car. Set 'second item' to be the name of the car the character is in.
ENTER_CAR_AS_PASSENGER: Orders the character to enter this car as a passenger, via one of the car's passenger doors - NOT the backdoor! Set 'second item' to be the name of the car for the character to enter.
ENTER_CAR_AS_DRIVER: Orders the character to enter this car as a driver, via the car's driver door if possible. Set 'second item' to be the name of the car for the character to enter.
FOLLOW_CAR_IN_CAR: Orders the character to follow this second car in the car he is currently driving. The character must be in a car when you set this objective! Set 'second item' to be the name of the car to follow!
FIRE_AT_OBJECT_FROM_VEHICLE: Orders the character to fire from his current vehicle at a particular object. Really only useful when the character is inside a tank! Set 'second item' to be the name of the object to fire at. Only works with Tank at moment!
DESTROY_OBJECT: Orders the character to shoot & destroy a particular object. Set 'second item' to be the name of the object
DESTROY_CAR: Orders the character to shoot & destroy a particular car. Again, set 'second item' to be the name of the car.

These Objective Types require a 'coordinate' - ie use SET_CHARACTER_OBJECTIVE ( name , type Float X, float Y , float Z ).

GOTO_AREA_ON_FOOT Orders the character to run on foot to a particular spot on the map.
GOTO_AREA_IN_CAR Orders the character to go by car to a particular spot on the map. You must make sure character is inside a car!

These Objective Types require a 'second item', an integer value, and a floating point 'offset' value.

FOLLOW_CAR_ON_FOOT_WITH_OFFSET Orders the character to follow the movements of a particular car 'on foot'. You can set the distance from the centre of the car he should walk, plus the angle from the car he should be. e.g. to make him follow to left of the car: 270 , 1.5; to make him follow some distance behind: 180 , 4.0. Set 'second item' to the name of the car to follow.

Set patrol route

Characters can be given 'patrol routes' that they follow, looking for any threats to react to. These routes are basically a big list of points that should 'loop round'. If the character sees a threat along the route, they will break off & attack it depending on their occupation/reaction etc. This gives you a more sophisticated guard ped system - eventually, you'll be able to set up guards that the player has to sneak around avoiding their line of sight Metal Gear Solid style.

Note that calling 'ADD_PATROL_POINT' will override any objective previously given to this character, but will leave his occupation/threats etc intact. To give a character a patrol, call

ADD_PATROL_POINT ( char_name , X.x , Y.y , Z.z )

Change char remap

Alters the remap of a character's ped graphic to a new value

CHANGE_CHAR_REMAP ( char_name , remap ) 

Order character to drive a car

Orders a character to go to a specific car & enter it to become its driver. The character's objective will be set to passed when this is complete, which you can use for checks.

ORDER_CHAR_TO_DRIVE_CAR ( char_name , car_name )

Order character to backdoor

Orders a character to go to car & enter it as a passenger. If character is leader of a group, they will attempt to enter car as well.

ORDER_CHAR_TO_BACKDOOR ( char_name , car_name )

Set character to stay in his car

This command forces a non-player character to stay inside his current car - he will not get out voluntarily. This can be toggled ON/OFF.

SET_CHAR_TO_STAY_IN_CAR ( char_name , ON ) 
SET_CHAR_TO_STAY_IN_CAR ( char_name , OFF ) 

Order driver out of his car

Orders a character to stop driving a car & exit it. The character will end up standing beside the car's door. Character must be driving a car - it will give a fatal error midgame otherwise. If you want to do something to the character once he's outside the car, check for his objective getting passed - this show's he is finished getting out.

ORDER_DRIVER_OUT_CAR ( char_name )

Store the last punched character

Variant on the old GTA1 'store char' command. This looks at one character, sees which character he last punched & stores this dummy char in a 'CHAR_DATA' slot, letting you treat him as a normal mission character. At the moment, the character is still a dummy character, we can change this if necessary to make him a 'proper' mission char.

Additional note: you must make sure the character has just punched someone before calling this command, you'll cause game crashes otherwise! Use "HAS_CHAR_PUNCHED_SOMEONE" for this.

STORE_LAST_CHAR_PUNCHED ( char_name , store_name ) 

Give weapon

Gives a previously existing character a weapon - used specifically for non-player characters. It gets given a certain amount of predefined ammo, and note each character can only use one weapon type at any time. Do not use the car_ types at this time. To give player a weapon, you must specify the amount of ammo to give him! See second variant of command. This now works on a CAR as well as a char!

GIVE_WEAPON ( char_name , weapon_type )
GIVE_WEAPON ( car_name , weapon_type )
GIVE_WEAPON ( player_name , weapon_type , ammo )

Remove weapons

Removes all weapons that this character has. Works on player too!

REMOVE_WEAPONS ( char_name )

Warp character from car to point

New 'warp' command asked by Steve. Takes a character who is driving a car, and warps him to a new position outside the car. He must be driving a car. And note, the player has control of the character in the time it takes the camera to update to his new position.

WARP_FROM_CAR_TO_POINT ( char_name , X.x , Y.y , Z.z , rotation )

Make character do nothing

This is an important new command, which should be used a lot in 'tidying up' mission characters. It effectively makes a character stop chasing another character, and stops him from doing most things. It should be used instead of setting a char to doing 'NO_OBJ' for his character objective.

MAKE_CHAR_DO_NOTHING ( char_name )

Stop character driving

Orders a particular character to 'stop driving'. It effectively makes him slam on the breaks & stop dead. At that point, you can then order him out of the car etc. He must be driving a car when you call this command!

STOP_CHAR_DRIVING ( char_name )

Kill character

Makes a character instantly 'die' - fall on the floor dead. Different to delete. You shouldn't do this on a player controlled character.

KILL_CHAR ( char_name ) 

Make all characters muggers

Ignore the 'muggers' bit - this effectively makes new dummy characters "mad", as requested by Willie. Any hassles - bug Iain R. about it!

MAKE_ALL_CHARS_MUGGERS ( ON ) 
MAKE_ALL_CHARS_MUGGERS ( OFF ) 

Checks

Is character objective passed?

This command allows you to check the state of a character/group's current objective. If the character has completed it, it will return TRUE. If not, it will return FALSE. This is highly useful for checking for character leaving/entering cars.

IS_CHAR_OBJECTIVE_PASSED ( char_name ) 
Is character objective failed?

This command is the complement of 'IS_CHAR_OBJECTIVE_FAILED?' - it returns TRUE if the character has failed to complete the objective, FALSE otherwise. Why might an objective fail? Good example: if the character has to enter a car & the car gets destroyed, the objective will fail.

IS_CHAR_OBJECTIVE_FAILED ( char_name ) 
Is character in a zone?

Checks whether a character is in a particular named local navigation zone. If you want an irregular area of zones checked, make them all have the same name. Returns TRUE if so, FALSE if not. Note that you must use "NAVIGATION" or "LOCAL NAVIGATION" zones for this to work!

IS_CHAR_IN_ZONE ( char_name , zone_name ) 
Is character in a gang zone?

Straightforward check to see whether the given character is currently inside a particular gang's zones. Returns TRUE if so, FALSE if not.

IS_CHAR_IN_GANGZONE ( char_name , gang_name )
Check characters health

Performs a check on this character's health. If health is greater or equal to the specified point value, returns TRUE otherwise FALSE. Example point values: 50 for a dummy ped, 100 for a gang ped, 255 for invincibility, 0 means character is dead.

CHECK_CHARACTER_HEALTH ( name , value )
Has character died?

Performs a simple check on a character's health to see if they've just died. Returns TRUE if char is dead, FALSE if char is still alive

HAS_CHARACTER_DIED ( name ) 
Is character in a car?

Checks to see if a particular character is in a particular car. Returns TRUE if it is, FALSE if not.

IS_CHARACTER_IN_CAR ( char_name , car_name )
Is character in any car?

Command to check whether a given character is currently driving anycar in the world. Returns TRUE if so, FALSE if not.

IS_CHARACTER_IN_ANY_CAR ( char_name )
Is character in model?

Command to check whether a given character is currently driving a car with a particular model. Returns TRUE if so, FALSE if not.

IS_CHARACTER_IN_MODEL ( char_name , model )
Has character stopped?

Checks to see if a particular character is stationary (ie not moving!). If in a car/train, checks its speed, if on foot, checks ped's speed. Works with any valid character. Returns TRUE if stopped, FALSE if not.

IS_CHARACTER_STOPPED ( name )
Is character firing onscreen?

Checks to see if character is firing a weapon onscreen. Works with any character, though doesn't make sense for player's own character. Returns TRUE if so, FALSE if not. Punching does NOT count as firing a weapon!

IS_CHAR_FIRING_ONSCREEN ( name )
Is character firing in an area?

Checks to see if character is firing a weapon inside a specific location & width/height. Works with any character, including the player - use this to check if player is shooting inside an area of a map near a building etc. Returns TRUE if so, FALSE if not. Need to decide if punching counts as firing weapon - it didn't in GTA1.

IS_CHAR_FIRING_IN_AREA ( name , X.x , Y.y , Z.z , width , height )
Is character pressing the horn?

Checks whether a given character is currently pressing the horn of the car he's driving. Returns TRUE if so, FALSE if not.

IS_CHAR_PRESSING_HORN ( char_name ) 
Is characters car capacity?

This is a fiddly sounding command that's actually simple. It checks to see what the possible number of passengers that can fit in the car currently being driven by a particular character. If it's greater or equal to the value you decide, it returns TRUE, if not, returns FALSE. This command is likely to be useful when the player has a group of guys with him & you want him to go steal a truck or something suitable for them all to fit in as passengers.

IS_CHAR_CAR_CAPACITY ( char_name , passenger_value ) 
Has character spotted player?

Check to see if this particular character has just spotted the player. Careful use of this command will let you do nice stealthy Metal Gear/Goldeneye missions. Note that this will work only on the player, not another character - it also shouldn't be used in multiplayer.

HAS_CHAR_SPOTTED_PLAYER ( char_name ) 
Has character punched someone?

Companion command to 'STORE_LAST.'. This returns TRUE if the character has just punched someone, FALSE if not.

HAS_CHAR_PUNCHED_SOMEONE ( char_name )
Check character been punched by

Checks to see whether a particular character was last punched by another particular character. Returns TRUE if so, FALSE if not.

CHECK_CHAR_BEEN_PUNCHED_BY ( punched_name , attacker_name ) 
Is character stunned?

Checks to see whether a character is stunned unconscious, ie lying on the ground stunned. Returns TRUE if so, FALSE if not. This will work on the player.

IS_CHAR_STUNNED ( char_name ) 
Is character falling?

Checks to see if this character is 'falling' through the air, ie doing the 'falling' animation. Returns TRUE if so, FALSE if not.

IS_CHAR_FALLING ( char_name ) 
Has character just sunk?

Checks to see if this character is sinking in water. Returns TRUE if so, FALSE if not.

HAS_CHAR_JUST_SUNK ( char_name )  
Is character on fire?

Straightforward check to see if a particular character is on fire - ie has a little fire attached to him! Returns TRUE if so, FALSE if not.

IS_CHAR_ON_FIRE ( char_name )
Has character been arrested?

Checks to see if this player character has been arrested. Returns TRUE if so, FALSE if not. It actually checks for you being thrown out the car by the police. Bear that in mind. Only the player gets arrested - other characters are just killed by the police.

HAS_CHAR_BEEN_ARRESTED ( player_name ) 

Locate

Waits for a particular character to enter a particular 'location', ie an (XYZ) with a (width, height) giving the ability to check a 'box' rather than just one particular block. This 'box' can be less than a block in width/height. This is NOT a blocking function

LOCATE_CHARACTER_ANY_MEANS ( char_name , X.x , Y.y , Z.z , width , height )
LOCATE_CHARACTER_ON_FOOT ( char_name , X.x , Y.y , Z.z , width , height )
LOCATE_CHARACTER_BY_CAR ( char_name , X.x , Y.y , Z.z , width , height ) 
ANY_MEANS: This will return TRUE when this character enters the box whether on foot or driving a car, FALSE otherwise. (If necessary, I can change it to return TRUE if a passenger inside a car - this will complicate the code however. )
ON_FOOT: This will return TRUE ONLY when this character enters the box on foot, FALSE otherwise
BY_CAR: This will return TRUE ONLY when this character enters the box driving a car, FALSE otherwise. (If necessary, I can change it to return TRUE if a passenger inside a car - this will complicate the code however. )
char_name name of a previously created character, including the player character.
X.x , Y.y , Z.z centre point of 'box' to check
width, height dimensions of box to check for character, given as floats.
Locate while stopped

These operate exactly like LOCATE_CHARACTER, except for one difference: the character must *stationary* inside the box, ie have zero speed. Returns TRUE when character fulfils condition, FALSE otherwise.

LOCATE_STOPPED_CHARACTER_ANY_MEANS ( char_name , X.x , Y.y , Z.z , width , height ) 
LOCATE_STOPPED_CHARACTER_ON_FOOT ( char_name , X.x , Y.y , Z.z , width , height ) 
LOCATE_STOPPED_CHARACTER_BY_CAR ( char_name , X.x , Y.y , Z.z , width , height ) 
Locate another character

Operates like the other locates, except with this the character must approach another character on foot. It continually updates a 'range' around the 'locate char' , and returns true if the char enters this, FALSE if not. Use this basically to check for the player approaching another character, instead of an exact 'area'.

LOCATE_ANOTHER_CHARACTER_ON_FOOT ( main char , locate char , width , height ) 
LOCATE_ANOTHER_CHARACTER_BY_CAR ( main char , locate char , width , height )
LOCATE_ANOTHER_CHARACTER_ANY_MEANS ( main char , locate char , width , height ) 
Examples
LOCATE_CHARACTER_ON_FOOT ( playerone , 123.5 , 45.5 , 2.0 , 3.0 , 1.0 ) 
LOCATE_CHARACTER_BY_CAR( playerone , 123.5 , 45.5 , 2.0 , 3.0 , 1.0 )
LOCATE_STOPPED_CHARACTER_ON_FOOT ( dummychar , 253.0 , 12.0 , 3.0 , 1.0 , 5.0 )

Groups

Making a named character and the player a group is dead easy. Do "ADD_GROUP_TO_CHARACTER" on the named character, but set the number of chars to 0 - this effectively adds the group logic without any physical characters. Then simply make the player the new leader of this group.

Add existing char to group

After you've added a group to one character, you can use this command to add a second character to this group, one that you'd previously created him. Best seen in an example. Until the character gets removed from the group, you should only use the leader of the group to manipulate things.

ADD_EXISTING_CHAR_TO_GROUP ( leader_name , char_to_add )

Example:

CHAR_DATA enemyleader = ( 123.5 , 34.5 ) 0 1 criminal
CHAR_DATA bodyguard = ( 124.5 , 35.5 ) 0 1 criminal

ADD_GROUP_TO_CHARACTER ( enemyleader , 3 ) 
ADD_EXISTING_CHAR_TO_GROUP ( enemyleader , bodyguard ) 

WHILE_EXEC ( CHECK_NUMBER_ALIVE_IN_GROUP ( enemyleader , 2 ) ) 
	// do something
ENDWHILE
REMOVE_CHAR_FROM_GROUP ( enemyleader , bodyguard ) 
SET_CHAR_OBJECTIVE ( bodyguard , KILL_CHAR_ON_FOOT , player ) 

Remove char from group

Counter command to 'ADD_EXISTING' - this removes a previously created character from a group of characters, letting you manipulate him individually again.

REMOVE_CHAR_FROM_GROUP ( leader_name , char_to_remove )

Make new leader of group

This command takes a previously created group & makes this particular character its new leader, replacing the old leader. The old leader is still part of the group, he just acts as an ordinary character in the group.

MAKE_NEW_LEADER_OF_GROUP ( old_leader , new_leader )

Set group type

This lets you manipulate groups of characters by letting you alter how they follow their leader. It's done through the leader's character - and he must have a group already added to him. Valid types at the moment are:

  • CHAIN - follow the leader like the Krishnas in GTA1.
  • MOB - follow the leader in a 'rabble' - this is the default behaviour.
SET_GROUP_TYPE ( leader name , type ) 

Set min members before group splits

This group management function allows you to tweak the minimum number of members left in the group before the group 'splits' back into individual characters. Default value is 0 for the moment.

SET_MIN_MEMBERS_BEFORE_GROUP_SPLITS ( leader_name , value ) 

Destroy group

This command effectively 'splits' a group, making all the members wander off as individuals again.

DESTROY_GROUP ( leader name ) 

Delete group in car

This commands allows you to delete a group of characters - all of whom must be in a car. The leader is deleted as well.

DELETE_GROUP_IN_CAR ( group_leader ) 

Check number alive in group

Useful character group command to check whether the number of members still alive is greater than or equal to a certain value. Possible uses would be to change the objectives/behaviour of the group if someone gets killed. Returns TRUE if greater/equal, FALSE otherwise.

CHECK_NUMBER_ALIVE_IN_GROUP ( leader_name , value )

Is group in car?

Simple command to check whether all members of a group have finished entering a car. Returns TRUE if so, FALSE if not.

IS_GROUP_IN_CAR ( leader_name ) 

Gangs

Set gang info

Declares & sets the information for a gang. Currently allows you to choose the colour of gang members & their weapon type to use, but this will eventually change to allow their 'gang car' type & any other info needed.

Gang names must match the gang names you use in the GANG ZONES set up inside your map. The first four characters of each gang must be unique as its those that are used to 'differentiate' between gang zones. Note gang names can be longer than 4 characters though! This command can now also be called 'midgame' to change the gang's details, ie use this midgame to alter what weapon the gang members use. However, you should still do a SET_GANG_INFO for each gang near the top of your file, BEFORE your phones.

SET_GANG_INFO ( gang_name , char_remap , weapon_1 , weapon_2 , weapon_3 , arrow_id , X.x , Y.y , Z.z , kill_char , car_model , car_remap )
gang_name string giving the name of a gang, e.g. commie , rednecks
char_remap The remap to give all characters of this gang - standard char remaps can be used.
Weapon_1 Weapon type that is given to each character in the gang.
Weapon_2 the 'second level' of weapon to give to this gang
Weapon_3 the 'third level' - when gang REALLY hates the player.
arrow_id Arrow graphic id to use for this gang - see Keith.
X.x , Y.y , Z.z float coordinates detailing the 'centre' of your gang area that you want the general gang arrow to point to.
kill_char integer value detailing how much the player's respect should change when he kills a 'gang ped'. At the moment, it's 10, it's supposed to be 1 in the final game!
Car_model the model to give any generated gang cars
Car_remap remap value to set for all gang cars.

Set gang kill reaction

This sets the relationship between two gangs & how it affects the player when a gang member dies. Gangone is the gang whose member has just died, so gangtwo's respect towards the player is adjusted by value. See example.

SET_GANG_KILL_REACTION ( gang_one , gang_two , value )

e.g. gang_two HATES gang_one:

SET_GANG_KILL_REACTION ( gang_one, gang_two , 10)

When player kills a gang_one character, his respect rating with gang_two goes up by 10. The player's rating automatically goes down with gang_one, no matter the relationships, because you've killed a gang member!

Check gang respect greater

Checks the player's 'respect level' for this gang (100 to 0 to -100.). If greater than required level, returns TRUE otherwise FALSE.

CHECK_RESPECT_GREATER ( player_name , gang_name , respect ) 

Check gang respect lower

Checks to see if this player's respect level for this gang is *lower* than a certain level. Returns TRUE if so, FALSE otherwise.

CHECK_RESPECT_LOWER ( player_name , gang_name , respect ) 

Check gang respect equal

Checks the player's 'respect level' for this gang - if exactly equal to a certain level, returns TRUE otherwise FALSE.

CHECK_RESPECT_EQUAL ( player_name , gang_name , respect ) 

Add char to gang

Sets a character's gang allegiance, ie makes him a gang character.

ADD_CHAR_TO_GANG ( char_name , gang_name ) 

Change gang char respect

This command lets you change the respect level that a character has with a particular gang - ie the levels that are displayed on screen. Bear in mind that valid respect levels are in the range of -5...0...5. To reduce the respect, use a negative number. Also, this command only makes sense on a player's character.

CHANGE_GANG_CHAR_RESPECT ( gang_name , char_name , difference ) 

Change gang char respect and update

This command lets you change the respect level that a character has with a particular gang - ie the levels that are displayed on screen. Bear in mind that valid respect levels are in the range of -5...0...5. To reduce the respect, use a negative number. In addition, this command updates the other respects - increasing/decreasing depending on the gang relationships.

CHANGE_GANG_CHAR_RESPECT_AND_UPDATE ( gang_name , char_name , difference ) 

Objects

Declares and/or creates an object of type "model" at a location, with a specific rotation. Z value works as above for cars.

  • To create a respray shop - give model as 'CAR_SHOP'
  • If the model is a collectible, you can specify the amount of ammunition for this collectible.
  • If the model is a car_shop ( ie a respray shop.) you can specify the car remap value that this shop gives.
  • If the model is a car shop other than a respray, you can specify the type of car weapon powerup to give.
OBJ_DATA name

OBJ_DATA name = ( X.x , Y.y ) rotation model 
OBJ_DATA name = ( X.x , Y.y , Z.z ) rotation model 
OBJ_DATA name = ( X.x , Y.y , Z.z ) rotation model value
OBJ_DATA name = ( X.x , Y.y , Z.z ) rotation model shoptype

name = CREATE_OBJ ( X.x , Y.y ) rotation model END
name = CREATE_OBJ ( X.x , Y.y , Z.z ) rotation model END
name = CREATE_OBJ ( X.x , Y.y , Z.z ) rotation model value END
name = CREATE_OBJ ( X.x , Y.y , Z.z ) rotation model shoptype END

Check object model

This command, when used with a destructable object, lets you detect when it's been destroyed - these objects change model when blown up. See Keith for details. It returns true if the object's current model matches the one listed, FALSE if not.

CHECK_OBJ_MODEL ( obj name , obj model ) 

Delete item

Orders the game to delete a previously created car/object/character/light. This generic command replaces the DELETE_CAR/CHAR/OBJECT commands.

DELETE_ITEM ( name )

Generators

Declares & creates a generator. Generators create new objects of a given type at regular intervals. Ideally placed at the top of a conveyor belt. Multiple generators can be placed at the same position to give more than one object type created at a spot. Objects will be created at a regular interval.

To create a 're-spawning' power-up, create a generator that makes the correct collectible, and switch it on. Give it a really long delay, and it will recreate another power-up after that time if the last object was collected. If no player has picked it up, it will do nothing.

NOTE: Generators by default are switched OFF.

GENERATOR name = ( X.x , Y.y ) rotation object-type mindelay maxdelay
GENERATOR name = ( X.x , Y.y , Z.z ) rotation object-type mindelay maxdelay
GENERATOR name = ( X.x , Y.y ) rotation object-type mindelay maxdelay ammo
GENERATOR name = ( X.x , Y.y , Z.z ) rotation object-type delay delay ammo
name valid namestring
X.x , Y.y , Z.z coordinate at which the objects will be positioned - if Z is missed out, the game will place it at the top Z level as normal.
rotation This is the rotation value all objects created will be given
object-type A string listing one object type - this generator will create objects of this type
delay delay Two integers describing the length of game cycles between creation. Should be identical to have a predictable generator.
ammo If you're generating weapons, use this to specify a particular ammo value to give each generated weapon. Miss it out, and the game will use the 'default' value for this weapon.

Switch generator

These commands allow you to manipulate a generator midgame, switching its state or method of execution. You can switch it off completely, switch it on, or order it to create a certain number of items - after which it switches itself off.

SWITCH_GENERATOR ( generator_name , ON ) 
SWITCH_GENERATOR ( generator_name , OFF ) 
SWITCH_GENERATOR ( generator_name , number ) 

generator_name: name of a previously declared GENERATOR item.

number: integer value describing the number of items to create. The generator will create the type of item given in its declaration.

Cranes

Declares & creates a crane.

CRANE_DATA name = ( X.x , Y.y ) home-rotation homecrane //1
CRANE_DATA name = ( X.x , Y.y ) home-rotation homecrane FIRST ( target X.x , target Y.y ) target-rotation //2
CRANE_DATA name = ( X.x , Y.y ) home-rotation homecrane SECOND ( target X.x , target Y.y ) target-rotation //3
CRANE_DATA name = ( X.x , Y.y ) home-rotation homecrane FIRST ( target X.x , target Y.y ) target-rotation SECOND ( float target X , float target Y ) target-rotation //4
  1. This declares a basic crane
  2. This declares a "target crane" - any cars picked up will be dropped at the target (XY) with the given rotation
  3. This declares a "second target crane" - this will drop any crushed cars in its vicinity at the target (XY) with the given rotation.
  4. This declares a "two target crane" used to link with crushers/conveyors. The first target is the position cars are initially dropped at. The second target is the point that the crushed car will be dropped off on.
name: valid name string
X.x , Y.y: the (X,Y) position to create the base of the crane on - the crane will automatically be placed at the correct Z - a crane cannot be placed 'underneath' a lid.
Home-rotation: This is the rotation the crane 'returns' to when it isn't picking up anything, i.e. the angle the crane points to normally.
Homecrane: name of another crane or 'NO_HOMECRANE'. This allows you to make the crane wait for another crane nearby to return to its own home position before doing any processing. Use this to prevent two cranes from colliding with each other.
target X.x , Y.y: This declares a 'target point', where any cars picked up will be dropped
target-rotation: Any car picked up will be rotated when lifted so that it has this rotation when crane is finished.

Enable crane

This switches a crane 'on', letting it proceed with lifting cars etc. This is the default state for all cranes. You only need to worry about crane states if you want to switch them off for some reason.

ENABLE_CRANE ( crane_name )

Disable crane

This switches off a crane, stopping it from lifting any cars etc. This will instantly stop the crane from working - if it is in the middle of lifting a car, it will stop mid-air. Use 'ENABLE_CRANE' to get it moving again.

DISABLE_CRANE ( crane_name ) 

Get car info from crane

This command essentially does two things - it returns TRUE if crane/whatever has successfully finished processing its current car, FALSE if not. If TRUE, it also sets car_name to point to the car it was processing.

GET_CAR_INFO_FROM_CRANE ( car_name , crane_name ) 

Declare power-up carlist

This command is tied to the new 'powerup generator' template command: it basically details to the game a long list of 18 car models, to be used to decide what type of powerup to create when a crushed car is delivered by the crane system. This command should be placed at the top of your mainscript, beside the other 'declare' commands. It requries 18 models, and it must be called if you plan on using 'DECIDE_POWERUP_FOR_CRANE'.

DECLARE_POWERUP_CARLIST ( model_1 , model_2 , model_3 , model_4 , model_5 , model_6 , model_7 , model_8 , model_9 , model_10 , model_11 , model_12 , model_13 , model_14 , model_15 , model_16 , model_17 , model_18 )

Decide power-up for crane

This is the 'partner' command to 'DECLARE_POWERUP_CARLIST'. It should be called when the player had delivered a car to the 'powerup crane system', the car has been crushed, and is on the conveyor belt to the point where it gets deleted. This command simply takes in the car & a generator, and decides what type of reward to give the player via the generator. It compares the model of this car against the models listed in the powerup carlist, and if it matches, creates the correct powerup. If there's no match, the player gets given a pistol powerup.

If the final type is a weapon, it tells the generator to make three of them, if it's a powerup, it will make only one. See Billy for details of this - he asked for it!

DECIDE_POWERUP_FOR_CRANE ( car_name , generator_name ) 

Declare crane power-up

This is a new 'template style' command. It takes over the job of waiting for your 'background' cranes picking up a car & awarding a weapon/powerup as a result of the car model. It links into the powerup_carlist you declare to make the decision.

It needs the name of the second crane - the crane that places the crushed car on the conveyor belt. It also requires the name of the generator to use to create the reward, plus the coordinates inside the building to use to wait for the crushed car disappearing.

This is a 'declare' - so put it nearby the other declarations, outside of any functions.

DECLARE_CRANE_POWERUP ( crane_name , generator_name , X , Y , Z ) 

Conveyors

Declares & creates a conveyor. Conveyors move in a given direction any objects that are on its space.

CONVEYOR name = ( X.x , Y.y ) ( width , height ) Xspeed Yspeed
CONVEYOR name = ( X.x , Y.y , Z.z ) ( width , height ) Xspeed Yspeed
name: any valid namestring
X.x , Y.y , Z.z: coordinates to place conveyor. This is the centre of the conveyor. If z is missed out, the game will place it automatically.
width , height: The width & height of the conveyor, given as floats.
Xspeed: this is an integer value describing how many pixels the conveyor will move objects horizontally each game cycle. To the right is positive, left is negative
Yspeed: As Xspeed, but describing the vertical movement. Down is positive, up is negative.

Destructors

Declares and/or creates a destructor. Destructors 'delete' any object that enters its space. Destructors now remove any cars/chars/objects that enters its space. Ideally placed at the end of a conveyor to remove any objects moving along.

Needs a coordinate plus width & height.

DESTRUCTOR name = ( X.x , Y.y ) ( width , height )
DESTRUCTOR name = ( X.x , Y.y , Z.z ) ( width , height )

name = CREATE_DESTRUCTOR ( X.x , Y.y ) ( width , height ) END
name = CREATE_DESTRUCTOR ( X.x , Y.y , Z.z ) ( width , height ) END

Crushers

Declares & creates a 'crusher' item in game. This item is usually linked up to a crane, and it will 'crush' any car within its centre square, which is the point you define. Be aware the crusher takes up one block in each direction from the centre spot.

Like the crane, the game automatically handles the z position for the crusher.

CRUSHER name = ( X.x , Y.y ) 

Lighting

Lights

This declares and/or creates a stationary 'light' in the script, at a particular coordinate with particular characteristics. Set the delays & randomvalue to 0 for a constant light that doesn't flicker.

LIGHT name

LIGHT name = ( X.x , Y.y , Z.z ) radius intensity ( red , green , blue ) on_delay off_delay random_value

name = CREATE_LIGHT ( X.x , Y.y , Z.z ) radius intensity ( red , green , blue ) on_delay off_delay random_value
name A valid unique name to refer to this light.
X.x , Y.y , Z.z Coordinate detailing the exact position to place this light at.
radius float radius of light to give out. Valid values are (0.0 to 7.999 )
intensity integer value describing strength of light. Valid values are ( 0 to 255 )
red , green , blue These three are the colour components that make up the colour this light should have. Valid ranges for these values are (0 - 255) with 255 being the 'strongest'. ( 255 , 255 , 255 ) will give 'white light'.
on_delay integer value of how many game cycles (0-255) the light should stay on for.
off_delay integer value of how many game cycles (0-255) the light should then stay off for.
random_value integer value - if greater than 0, becomes the 'max' random value to add to each on/off cycle. On_delay + random_value and off_delay + random_value should both be < 255.

Altering scripted lights

CHANGE_INTENSITY ( light_name , intensity ) 
CHANGE_COLOUR ( light_name , red , green , blue )
CHANGE_RADIUS ( light_name , new_radius ) 

Set ambient level

Allows you to set the background ambient light level in your map. It can change instantly to this new level, or do it over time. This should be one of the very first commands after your 'LEVELSTART'.

SET_AMBIENT_LEVEL ( float_level , integer_time )
level new ambient level. 0.0 is black, 1.0 is 'normal' GTA without light.
time number of cycles to do change over. Set to 0 to do instantly.

Set shading level

Similar to the SET_AMBIENT_LEVEL command, this sets the shading 'contrast' for the level. Valid values are 0 - 31, with 15 being the 'normal' level.

SET_SHADING_LEVEL ( integer_value ) 

Sounds

A 'sound object' is an item created at a particular (XYZ) which plays a sound or sample. These 'sounds' behave like every other sound in the game - they have volume, get loud/quiet as the player approaches etc. At the moment, there are only two sound types - more will be added! These commands declare and/or create a 'sound object' of the type you specify at location (XYZ), with the play characteristic you give. At the moment, there are two playtypes:

  • PLAY_FOREVER - the sound object will continually play the sound forever
  • PLAY_INSTANT - the sound object plays /once/ and then switches off.

If you have a PLAY_FOREVER object & wish to remove it at a later point in the game, you can call DELETE_ITEM ( sound_name ) on it. See bottom of document for a list of 'sound object' types.

SOUND name 

SOUND name = ( X.x , Y.y , Z.z ) type playtype

name = CREATE_SOUND ( X.x , Y.y , Z.z ) type playtype END

Radio stations

This command 'declares' & creates a new 'radio station' in the game world. There is a maximum of four radio stations in the world - one should be 'global', with the other three related to your specific gangs. A list of types is at the bottom of the document. Radio stations are positioned on a particular (XY) with a preset "range" of broadcast - you can't change these ranges unfortunately. Radio stations can be deleted using the normal DELETE_ITEM command.

These declares should be in your 'general' script file, along with your other car/ped/counter declares.

RADIO_STATION name = type ( X.x , Y.y ) 

Kill Frenzies and bonuses

Bonus declare

This 'declares' space for the new 'bonus' info needed for interfacing with START_BONUS_CHECK. Basically, put it by your other declares. These can be re-used.

BONUS name 

Start bonus check

This is a complicated command used to check for the player scoring repeatedly, e.g. for kill frenzies. It handles a lot of different cases, so it has a lot of parameters. These don't all need to be set - there are default values for each type, like -1 or 'NONE'.

Basically, you're telling the game to look for the player causing a certain number of score 'events' in a certain period of time. These events can be killing certain peds, car models, peds with occupations, gang peds, peds with certain remap, certain car models with certain remaps, etc. On top of that you can make it so that only doing it with certain weapon types counts.

name = START_BONUS_CHECK ( zone , time , count , score , type , exclusive_mode , damage_type , attack_model , gang_name )
name = START_BONUS_CHECK ( zone , time , count , score , type , exclusive_mode , damage_type , attack_model , gang_name , target_remap )
name = START_BONUS_CHECK ( zone , time , count , score , type , exclusive_mode , damage_type , attack_model , char_occupation )
name = START_BONUS_CHECK ( zone , time , count , score , type , exclusive_mode , damage_type , attack_model , char_occupation , target_remap )
name = START_BONUS_CHECK ( zone , time , count , score , type , exclusive_mode , damage_type , attack_model , target_car_model )
name = START_BONUS_CHECK ( zone , time , count , score , type , exclusive_mode , damage_type , attack_model , target_car_model , targe_remap )
name this is the name of a 'BONUS ITEM' used to store details about the Bonus check. This is new!
time the number of cycles allowed for the check
count the number of 'scores' of this type the player must do to pass
score a bonus score given to the player when he successfully passes. Set to 0 to give no 'extra' score
type This is 'how' the player must do the scores - either CHAR or CAR
exclusive_mode this is a flag to tell the game whether the player can commit other score types while you're checking for this particular test. Either EXCLUSIVE or NOT_EXCLUSIVE
damage_type this is one of the 'damage types' listed at the bottom - set to BY_ANY_WEAPON if you don't care what weapon type used to commit the score. Setting it a damage_type means that ONLY scores with that weapon count.
attack_model this is for car based checks - if set to a car model other than NONE, it will check for scores caused by the player inside a particular car model.
Target_car_model again, for car based checks - this will check for scores /on/ a particular car model. Set to NONE for char based attacks, or if you don't care.
Gang_name this lets you check for the player killing gang member peds. Set to the name of the gang used in your SET_GANG_INFO command.
Target_remap use this to make the check work on a particular 'remap' - only cars or chars with this remap will count for the check.
Char_occupation use this to check for characters only with this occupation, e.g. ELVIS peds. Or NO_OCCUPATION if you don't care!
Zone name of a zone that the check MUST happen in - put NO_ZONE if you don't care about the zone! This is NEW!

Has bonus finished

Checks to see whether the bonus has finished executing. If it has, use one of the other two commands to then see why. Returns TRUE if finished, FALSE if still executing.

HAS_BONUS_FINISHED ( bonus_name ) 

Has bonus passed

This is used to check whether the bonus you've setup has been 'passed' or completed by the player. Returns TRUE if so, FALSE if not.

HAS BONUS PASSED ( bonus_name )

Has bonus failed

This is used to detect if the bonus check has failed - ie the player has either ran out of time or if exclusive, commited some other score event. Returns TRUE if so, FALSE if not.

HAS_BONUS_FAILED ( bonus_name ) 

Bonus check example

This checks for the player killing 3 yakuzagang members.

START_BONUS_CHECK ( KILL_ANY_MEANS , 3000 , 3 , 20000 , CHAR , NOT_EXCLUSIVE , BY_ANY_WEAPON , NONE , yakuzagang )

	DISPLAY_TIMER ( timer , 3000 ) 
	WHILE_EXEC ( NOT ( HAS_BONUS_FINISHED ( ) ) ) 
		DO_NOWT
	ENDWHILE

	CLEAR_TIMER ( timer ) 
	IF ( HAS_BONUS_PASSED ( ) )
		SET_AMBIENT_LEVEL ( 0.4 , 100 ) 
		DISPLAY_BRIEF ( 8001 ) 
	ENDIF
	IF ( HAS_BONUS_FAILED ( ) ) 
		SET_AMBIENT_LEVEL ( 1.0 , 0 ) 
		DISPLAY_MESSAGE ( 8002 ) 
	ENDIF

Store bonus count

This takes a currently executing bonus check & stores the current 'number' achieved by the player in a counter. In other words - it takes the current number of 'events' done by the player & stores it in a counter, letting you work & manipulate that value.

STORE_BONUS_COUNT ( bonus_name , counter_name ) 

Set Kill Frenzy weapon

Use this to give the player an 'infinite' weapon to be used during a kill frenzy. You must clear this off when you're finished! The game will automatically remember the player's 'real' ammo count for this weapon.

SET_KF_WEAPON ( player_name , weapon_type ) 

Clear Kill Frenzy weapon

This clears off a previously given 'kf weapon', and restores the value of ammo the player had before the start of it.

CLEAR_KF_WEAPON ( player_name )

Reworked Kill Frenzies

As an optimisation, there's a new scheme for doing the basic kill frenzy of 'kill x within y with z', giving a reward of either score, multiplier or lives. In a similar fashion to the multiphones, we have two template commands that do most of the work, cutting down on the amount of space in the scriptfile as well as aiding execution speed.

A full example is given below.

Start basic Kill Frenzy template

This 'sets up' the kill frenzy, doing the basic work in setting one up. It will disable the thread trigger, display a couple of messages, delete the item used to start the kill frenzy & switch on the kill frenzy weapon. It effectively does the work of five lines.

START_BASIC_KF_TEMPLATE ( thread_trigger_name , base_brief_ID , start_item_name , player_name , weapon_type )
thread_trigger_name this is the name of the THREAD_TRIGGER used to start the KF.
base_brief_ID An integer detailing the ID of the 'base brief' for the KF in the text file.
start_item_name Name of the object used to 'start' the kill frenzy
player_name name of the player's character
weapon_type Type of weapon to be used for this kill frenzy. Set to NO_WEAPON if you don't want the player to use a particular weapon.
Do basic Kill Frenzy template

This does most of the hard work for the kill frenzy. It sets up the timer & counter onscreen, and waits for the bonus to finish - updating the onscreen counter each cycle. When the bonus is finished, it checks whether the player passed or failed, and updates the relevant 'secrets counted' as well as displaying the relevant brief/message - "You've passed!" etc. In addition, if the player has passed, he will get awarded a 'prize' - either score, lives or multiplier.

DO_BASIC_KF_TEMPLATE ( bonus_name , timer_name , time_limit , onscreen_counter_name , running_count_name , target_total , base_brief_ID , player_name , reward_type , reward_value )
bonus_name name of a 'BONUS', the one used in your START_BONUS_CHECK call.
timer_name name of a TIMER_DATA item to use for the onscreen timer
Time_limit integer value detailing the number of seconds for this kill frenzy
onscreen_counter_name name of a 'ONSCREEN_COUNTER' item to use for the onscreen counter
running_count_name name of a counter to use for displaying the running count onscreen
Target total the target total of 'scores' for this kill frenzy
base_brief_ID integer detailing the ID of the 'base brief' for this KF in the text file
player_name name of the player's character
reward_type string detailing NOTHING , SCORE , LIVES or MULT
reward_value the amount of the 'reward type' to award! If NOTHING, set this to 0.
Kill Frenzy template example

This is a fully working, fully tested example of the KF template in action, complete with a list of the relevant briefs you need to put in your textfile (and the order in which they need to be!). This does a 'kill 20 people in 60 seconds with molotovs!' type bonus. It's a reworking of Willy's current KF example.

THREAD_TRIGGER thr_molotov_kill_frenzy1 = THREAD_WAIT_FOR_CHAR_IN_BLOCK ( player , 130 , 109 , 6 , do_molotov_kill_frenzy1: )

do_molotov_kill_frenzy1:
START_BASIC_KF_TEMPLATE ( thr_molotov_kill_frenzy1 , 6900 , molotov_kill_frenzy1 , player , molotov )
killfrenzy1 = START_BONUS_CHECK ( kill_any_means , 1800 , 10 , 0 , char , not_exclusive , by_molotov , none , no_occupation , -2 ) 
DO_BASIC_KF_TEMPLATE ( killfrenzy1 , frenzy_timer_downtown , 60 , kf_counter , counter_total , 10 , 6900 , player , SCORE , 5000 ) 
RETURN
Kill Frenzy template briefs

The KF briefs have changed - the base brief you specify is now just the number of the one unique brief per frenzy.

[6900] Kill 20 people with molotovs within 60 seconds!

These other briefs are in the gen_e.txt file, and you no longer need them in your own textfile.

[kfstart] KILL FRENZY

[kfpass] FRENZY PASSED!

[kffail] FRENZY FAILED!

Declare total secrets

This signal to the game the total number of hidden 'secrets' on this level. Must be integer!

DECLARE_TOTAL_SECRETS ( value ) 

Declare secrets passed flag

This tells the game a name of a counter containing a record of the number of secrets passed by the player so far in the game. Put it by your other DECLARE commands.

DECLARE_SECRETS_PASSED_FLAG ( counter_name ) 

Declare secrets failed flag

This tells the game a name of a counter containing a record of the number of secrets failed by the player so far in this game. Put it by your other DECLARE commands.

DECLARE_SECRETS_FAILED_FLAG ( counter_name )

Missions

Declare mission flag

This command is used to tell the game code which particular counter is used in the script to signify whether the player is currently on a mission or not. At the moment, it's mainly for the gang arrows to work properly, but more things may end up using it.

This is a declaration command, to be used at the top of your script outside any labelled function - but make sure to put it after the actual COUNTER & PLAYER_DATA declarations!

DECLARE_MISSION_FLAG ( player_name , counter_name ) 

Eg.

PLAYER_PED player = ( 214.5 , 64.5 , 255.0 ) 1 1
COUNTER flag_on_mission = 0
DECLARE_MISSION_FLAG ( player , flag_on_mission )

Set phone dead

This allows you to tell the game that a particular phone is 'dead', ie that it should no longer ring or give out missions etc. Use when the player has used up all the missions from a particular phone.

SET_PHONE_DEAD ( phone_name ) 

Do phone template

This effectively takes over control of what happens when the player answers a particular phone. It checks mission states & respect, generating a brief & action. It looks complicated. It is complicated.

DO_PHONE_TEMPLATE ( integer base brief , string name of file containing mission 1 from this phone , string name of file containing mission 2 from this phone , counter_name of counter stating if player has passed mission 1 , counter_name of counter stating if player has failed mission 1 , counter_name of counter stating if player has played mission 2 , counter_name of counter showing player on mission for gang 1 , counter_name of counter showing player on mission for gang 2 , counter_name of counter showing player on mission for gang 3 , gang name of gang this phone is connected to , integer the respect value needed to start mission ( 0 - 5 ) )

Example:

DO_PHONE_TEMPLATE ( 1098 , WILL_KE1.MIS , WILL_KE2.MIS , flag_passed_yakuzagang_easy_phone1_m1 , flag_failed_yakuzagang_easy_phone1_m1 , flag_played_yakuzagang_easy_phone1_m2 , flag_on_yakuzagang_mission , flag_on_looniegang_mission , flag_on_zaibgang_mission , yakuzagang , 5 )

Launch mission

This is a powerful new command that launches a mission midgame from a different file to the current one. The new file must have a block of commands starting with a MISSIONSTART command & ending in a MISSIONEND command, similar to 'LEVELSTART ... LEVELEND'. When the command is run, the game will load in the file & 'jump' to the MISSIONSTART line. Think of it making the script do a 'GOSUB' to a label, it just so happens the jump is into a different file, with the label being the filename rather than the actual label. That make sense?

LAUNCH_MISSION ( filename.mis )

Mission has finished

This is a straightforward command to signal to the game that the player has either failed/passed a mission. It forces the game to run the 'clean up' mission code - ie flag all peds/cars etc that were created in this mission to be deleted as soon as possible.

MISSION_HAS_FINISHED ( ) 

Do easy phone template

This is an alternative version of the 'phone template', set up especially to handle just one mission coming from this phone. Use this for your new simpler 'easy phones'. The information that's changed between this & the other template is no 'name of file for mission 2' & no 'counter stating if player has played mission2'.

DO_EASY_PHONE_TEMPLATE ( integer base brief , string name of file containing mission 1 from this phone , counter_name of counter stating if player has passed mission 1 , counter_name of counter stating if player has failed mission 1 , counter_name of counter showing player on mission for gang 1 , counter_name of counter showing player on mission for gang 2 , counter_name of counter showing player on mission for gang 3 , gang name of gang this phone is connected to , integer the respect value needed to start mission ( 0 - 5 ) )

Example:

DO_EASY_PHONE_TEMPLATE ( 1098 , WILL_KE1.MIS , flag_passed_yakuzagang_easy_phone1_m1 , flag_failed_yakuzagang_easy_phone1_m1 , flag_on_yakuzagang_mission , flag_on_looniegang_mission , flag_on_zaibgang_mission , yakuzagang , 5 )

Declare total missions

This signals to the game the total number of missions on this level, not including 'secrets' like kill frenzies etc. Again, this is for the pause screen. Must be integer!

DECLARE_TOTAL_MISSIONS ( value ) 

Declare missions passed flag

This signals to the game the name of the counter containing the number of missions passed by the player.

DECLARE_MISSIONS_PASSED_FLAG ( counter_name ) 

Declare gang missions passed flag

This signals to the game the name of the counter containing the number of missions passed by the player for the first gang in your city - these declares should be after your SETGANGINFO commands. Gang One/Two/Three names are the order you do the setganginfo commands in.

DECLARE_GANG_ONE_MISSIONS_PASSED_FLAG ( counter_name ) 
DECLARE_GANG_TWO_MISSIONS_PASSED_FLAG ( counter_name ) 
DECLARE_GANG_THREE_MISSIONS_PASSED_FLAG ( counter_name )

Declare gang missions total

This tells the game the total number of missions available for each gang in your city. These declares should be after your SETGANGINFO commands. Gang One/Two/Three names are the order you do the setganginfo commands in.

DECLARE_GANG_ONE_MISSIONS_TOTAL ( integer_value ) 
DECLARE_GANG_TWO_MISSIONS_TOTAL ( integer_value ) 
DECLARE_GANG_THREE_MISSIONS_TOTAL ( integer_value ) 

Declare gang mission flag

This declares to the game the 'COUNTER' variables used to store which gang the player is currently involved with doing a mission for. You already have these flags all set up - the game just now needs to know about them. Do these commands AFTER you declare the COUNTERs.

DECLARE_GANG_ONE_MISSION_FLAG ( player_name , flag_name ) 
DECLARE_GANG_TWO_MISSION_FLAG ( player_name , flag_name )
DECLARE_GANG_THREE_MISSION_FLAG ( player_name , flag_name )

Declare gang death base brief

This declares to the game the starting id of the first gang's 'death' base brief. There should be five death briefs followed by five 'arrest' briefs for each gang. Each gang's base brief must be declared for the death/arrest code to work correctly.

These are DECLARE commands, so they should be beside all your other flag declarations at the top of the mainscript.

DECLARE_GANG_ONE_DEATH_BASE_BRIEF ( player_name , integer_base )
DECLARE_GANG_TWO_DEATH_BASE_BRIEF ( player_name , integer_base )
DECLARE_GANG_THREE_DEATH_BASE_BRIEF ( player_name , integer_base )

Force cleanup

This command is SPECIFICALLY for 'collectable' powerup type objects - it orders the game to add it to its internal 'cleanup' list - so that when the player passes/fails the mission, it will be deleted. Normally collectables are NOT in this list. The game will cope with the object being collected - just do this command & forget about it.

FORCE_CLEANUP ( object name )

Set death/arrest state

This allows you easy access to switching the death/arrest check on & off in your scripts. At the moment, it defaults to OFF, this will get changed to defaulting to ON. Make sure to switch it to OFF at the start of any missions you want to handle yourself, switching it back on during your cleanup!

SET_DEATHARREST_STATE ( player_name , ON ) 
SET_DEATHARREST_STATE ( player_name , OFF )

Check death/arrest executed

This is a new vital command to link with the new 'deatharrest' code - you must call this in your cleanup code to check whether the player FAILED the mission instead of checking your own internal 'failed' flag for the mission. That flag will not be set by the deatharrest code!

It returns TRUE if the deatharrest code executed & failed the mission, FALSE otherwise.

CHECK_DEATHARREST_EXECUTED ( )

Phones

Answer phone

This command starts a phone ringing, and sets a mechanism in motion that waits for a specific player to answer it. As soon as the specific player answers the phone, it stops ringing. You can make the phone ring for a specific number of game cycles then stop too. There is a limit on how many ANSWER_PHONEs you can have running at any one time. Currently this is 5 - you can have more than this in total, just not at the ONE TIME. I can increase this if necessary. Setting timer_value to -1 means the phone will ring until you command it to stop.

ANSWER_PHONE ( char_name , telephone_name , timer_value )

Check answered phone

Use this to check whether the player has answered the phone or not. Returns TRUE if so, FALSE if not.

CHECK_ANSWERED_PHONE ( telephone name ) 

Check fail phone timer

Use this to check whether the timer on a phone has 'run out' - if you're using a timed answer_phone, you must call this command once each 'cycle', ie stick it inside a while_exec or something similar. When the timer has run out, it returns TRUE. If the timer is still counting down, or there is no timer, the command returns FALSE.

CHECK_FAIL_PHONE_TIMER ( telephone_name ) 

Stop phone

This makes a phone stop 'ringing', ie changes its animation to that of a 'normal' phone, stopping any sound playing etc.

STOP_PHONE ( telephone_name ) 

Telephone example

This is a detailed example of a working 'answer telephone'. It may be possible to streamline or alter it slightly.

OBJ_DATA testphone = (108.5 , 151.5 , 2.0 ) 0 phone
PLAYER_PED player = ( 108.5 , 150.5 , 255.0 ) 0 1
COUNTER exit = 0

LEVELSTART
	ANSWER_PHONE ( player , testphone , 40 ) 

	WHILE_EXEC ( exit = 0 ) 
		++ exit
		IF ( CHECK_ANSWERED_PHONE ( testphone ) )
			DISPLAY_BRIEF ( 8012 )	// well done!
		ENDIF
		IF ( CHECK_FAIL_PHONE_TIMER ( testphone ) )
			DISPLAY_BRIEF ( 8013 ) 	// failed!
		ENDIF
	ENDWHILE

	IF ( exit = 1 )
		// player answered phone.
	ELSE
		// player didn't answer phone.
	ENDIF
LEVELEND

On-screen messages

Designers will be able to display text messages onscreen in a similar fashion to GTA1, through a unique ID for each message. The actual text will be kept in a file separate from the mission script to allow easy translations & alterations to be made. There will be a number of different commands for displaying text, to handle the different methods, such as 'big message' & 'standard' message, e.g.

DISPLAY_MESSAGE ( 123 ) 
DISPLAY_BRIEF ( 123 )

Display message

Displays a message in the large "bold" font in the centre of the screen. Used in GTA1 for the "Wasted!" messages. These messages MUST be all upper-case. We need some coordination with messages like 'MISSION COMPLETE!' - these should be in the gen_e.txt file, shared between all three scripts, rather than specific to each one. No point duplicating text/effort. ID's are the numbers in the text file.

DISPLAY_MESSAGE ( message_ID )

Display brief

Displays a "briefing" message at the bottom of the screen. Used in GTA1 for most messaging. GTA2 queues message to display. Messages have a low priority.

DISPLAY_BRIEF ( message_ID ) 

Display brief soon

Another new brief command - use this for messages that are important more important than ordinary 'DISPLAY_BRIEF', but less important than 'DISPLAY_BRIEF_NOW'. So, a DISPLAY_BRIEF_SOON will always get done before display_brief, but /after/ any SOONs already in the queue. A DISPLAY_BRIEF_NOW will always override anything in the queue, including other 'NOW's.

DISPLAY_BRIEF_SOON ( message_ID ) 

Display brief now

Displays a "briefing" message at the bottom of the screen. Use this for important messages, as they have a high priority!

DISPLAY_BRIEF_NOW ( message_ID ) 

Clear all briefs

Clears all queued briefs currently waiting to be displayed. Do this after a DISPLAY_BRIEF_NOW & you will effectively be clearing all waiting text & any text that was getting displayed before the display_brief_now.

CLEAR_ALL_BRIEFS ( ) 

Is brief onscreen?

Checks to see if any brief is being displayed onscreen at this moment. Returns TRUE if so, FALSE if not. Added for Willie's training mission.

IS_BRIEF_ONSCREEN ( ) 


Set bonus rating text ID

This command is purely for the bonus levels - it allows the designers to pass a 'text id' denoting the rating of the player's performance in this bonus mission. The value passed should be a regular integer detailing the 'text id' in the e.gxt file.

SET_BONUS_RATING_TEXT_ID ( rating_ID ) 

Score

Add score

Adds a score value to a given player. Limit of 65535 for value - this will change to much more! (Can be positive or negative) New alternative - add the value of a counter to the player's score.

ADD_SCORE ( player_name , value )
ADD_SCORE ( player_name , counter_name ) 

Add score no mult

This is a variation of the standard 'add score' command, except it ignores the multiplier. The score to add can be positive or negative

ADD_SCORE ( player_name , value )

Check score greater

Simply checks the current score for this player against a particular value. If greater than it returns TRUE, else FALSE.

CHECK_SCORE_GREATER ( player_name , value ) 

Store score

Stores the current score for this player in a previously declared counter - this counter can then be used in the normal arithmetic functions.

STORE_SCORE ( player_name , counter_name ) 

Declare finish score

This signifies to the game what the 'target score' for this level is. The game does no checking for this yet - this info is for the 'pause screen'. This 'DECLARE' & the others that follow should be places at the top of your main script, near your 'DECLARE_MISSION_FLAG' - and /after/ the counters referred to (obviously). Must be integer!

DECLARE_FINISH_SCORE ( value )

Doors

There are two types of doors: doors on buildings, "garage doors and doors that block passage into another section, "barrier doors". Barrier doors operate in a similar way to GTA1, they can open for one specific car, a specific model etc or when you demand it to open in the script. Garage doors are more complex - they will open for the same set of conditions, but their actual operation is fiddly.

Garage doors are effectively "one way" - a car goes in, a ped comes out. They will open for the car the player is in as long as it meets the requirements for this door, say model/colour. The car must approach the door fairly straight, give or take a few degrees. When the front two corners ( if going forwards, the back two if reversing in) are over the "line" of the door, the game will suck in the car, and chuck out the ped in front of the door in a similar fashion to GTA1.

However, if the player isn't lined up correctly, or has only one corner over the "line the game will not automatically pull him in - the car must be lined up straight. Once it's started to be "sucked the game will switch off collisions with the car - things can bounce off the car, but the car will be unaffected by collisions. The invisible "line" across the doorway (a collidable object) will prevent any other cars/peds/weapons from crossing in under the door/building. The car is sucked in at a constant rate - if the player was accelerating fast, it will drop to that speed as it gets pulled in - may look a little strange, but necessary.

As soon as the car is being "pulled the game will switch off the 'exit' key for the player to prevent him exiting in a strange position. This will be switched back on when the movement is finished.

Declare door info

Another new concept: this command allows you to set up the graphics used for doors. It requires a start frame, an end frame, and the speed to play the animation at.

The 'start frame' is effectively the 'closed' frame of the door. The 'end frame' is what the door will look like when it's opened. Speed is an integer value detailing the animation speed, usually 1 to show one cycle between each frame.

These commands should be at the top of your script outside of any actual 'function', like your other declarations. Note that the order you place the DECLARE_DOOR_INFO commands in is important for when you actually make doors - don't go changing it!

DECLARE_DOOR_INFO ( start_frame , end_frame , speed )
startframe Integer value giving the tile to give door initially
endframe Integer value giving the tile that door has when animation of opening is finished.
speed Integer value giving animation speed.

Door declare

Doors in GTA2 are one way - their primary use is on buildings for 'garages'. They give the illusion of the player entering a building & dumping a car inside. They will usually be used in conjunction with a 'PARK' command to take the player inside & dump his/her car.

These may appear to be a little fiddly to set up properly, but they give you a lot of different power. Doors must be declared & created at the top of your file outside any functions. At the moment, all doors are automatic & default to closed - barriers will come later.

Doors can either be single or double. If you select double, the game will automatically position another door to the 'right' of your coordinates, depending on the direction the door should face.

  • if facing top, it will generate one block to the right,
  • if facing bottom, it will generate one block to the left,
  • if facing right, it will generate one block to the bottom,
  • if facing left, it will generate one block to the top.

Double doors' opening logic defaults to being over both blocks immediately in front of the two doors, instead of the single block in front that happens with single doors. You can now change this easily through the 'check' values - this is a float (XYZ) which is the centre of the range to check, plus a width & height giving the size of the area to check.

The "gr_id" is a single integer value telling the game what set of 'graphics' to use. This value is basically a reference to a DECLARE_DOOR_INFO. If you want this door to use the second door_info data, set this to 1, if you want the first,use 0.

Open_type is the rule for opening this door. See bottom of document for list. Basically, at the moment you can order doors to open for players, for any car, for particular cars you've created, for a particular model of car. If you want the door to open for a particular car, you need to give its name at the end of the line, see 'somename'. If you want the door to open for a particular model, you need to give this as 'somename'.

Close_type is the rule for closing the door. This is a little more straightforward. If you give the door a 'close never' type, it will stay permanently open & will let anything go through. All other types will only let the 'type' that opened it through, e.g the player, a particular car. Another common close type will be 'delayed' which waits a certain number of game cycles & then attempts to close the door.

One word of warning: at the moment, the game will not close the door while whatever opens the door is still standing on the opening trigger in front of the door.

DOOR_DATA name = style ( X , Y , Z ) ( X.x , Y.y , Z.z , width , height ) face gr_id open_type close_type delay flip reverse
DOOR_DATA name = style ( X , Y , Z ) ( X.x , Y.y , Z.z , width , height ) face gr_id open_type close_type delay flip reverse some_name
DOOR_DATA name = style ( X , Y , Z ) ( X.x , Y.y , Z.z , width , height ) face gr_id open_type close_type delay flip reverse value
name unique string giving a name for this door
style either SINGLE or DOUBLE to tell game what style of door it is
X , Y , Z integer values giving the coordinates of the block to put the door 'on'
X.x , Y.y , Z.z floats describing the 'door check' trigger opening position.
width , height width & height of the new trigger position. Set these check values to 0.0 to make the game automatically generate a trigger covering the area 'in front' of the door. (same way as GTA1 did it).
Face facetype is either TOP, BOTTOM, LEFT, RIGHT detailing which face to physically place the door on.
gr_id an integer detailing which 'DOOR_INFO' to use. 0 is the first valid door_info!
open_type An open_type string from the bottom of the document
close_type Again, a close_type string from the bottom of the document
delay Integer detailing the number of cycles to wait. 255 is the maximum wait.
flip String which is either "FLIP_RIGHT" or "NOT_FLIPPED". If flipright, the righthand door has its graphic flipped.
some_name Usually the name of a car or carmodel - only used with specific open_types
value integer value not currently used - you do not need to worry about putting in any sort of value for it.
reverse extra flag detailing "backwards door" - use this for the 'fudged' doors where you effectively have two doors on the one block. SEE ME! Should be either REVERSED or NOT_REVERSED

Open door

This forces a door to open. Note, the door should be MANUAL controlled for best effect.

OPEN_DOOR ( door_name ) 

Close door

This forces a door to close. This waits for it to be clear of obstructions!

CLOSE_DOOR ( door_name ) 

Make door automatic

Orders a door to behave 'normally' & automatically - ie wait for its opening conditions to pass, open, wait for its closing conditions & then close itself. This is the default state for doors.

MAKE_DOOR_AUTOMATIC ( door_name ) 

Make door manual

The opposite of 'MAKE_DOOR_AUTOMATIC' - this makes the door fully manual & under script control. It will do nothing unless you order it to open/close.

MAKE_DOOR_MANUAL ( door_name ) 

Update door target

This allows you to use doors with 'future cars / characters', ie you can use a door with a car that doesn't yet exist when the game runs, only when you've stored its info. You should call 'UPDATE_DOOR_TARGET' once you have a 'proper' pointer to the car/character stored.

UPDATE_DOOR_TARGET ( door_name , target_name )

Park

This command 'parks' a particular car inside a particular door. It may look simple, but there's a lot of pitfalls to be wary of. The door can be a single or double door, but the building should have a lot of room. It needs at LEAST one block free inside the building to each side of the door, and three blocks free in the direction of the door (on the inside of the building) for long vehicles to behave properly.

Parking works by waiting for the front two corners of the car being 'over' the edge of the door, at which point the code "pulls in" the car, until all corners are in & hidden from view. When this is finished, the car is flagged to destroy itself, all passengers are killed & the player is placed outside the closing door. During this process, the car cannot be collided with, the player's controls are disabled, and the car is 'pulled in' at a constant rate. When the parking is finished, all of this is reset to let play continue as normal. NOTE - only one park can run at any time!

Eventually, the character will 'run out' of the door rather than just being warped there as present. Nothing is done to the camera yet either - it doesn't get 'fixed' outside the garage like in GTA1.

Parking has changed a bit. If you want to park long vehicles ( length >= 1 block!), you must ensure you have enough space around the door. If you don't, the game will ASSERT & generate an error when you do your PARK command. What's enough space? For a double door facing north, you must have two blocks either side, and three blocks depth. In other words - six blocks by three blocks. You MUST have this amount of space inside the garage to handle acute angles of parking etc.

PARK ( car_name , door_name ) 

Has park finished?

Simple check to see whether the current 'parking' has finished or not. Returns TRUE if so, returns FALSE if not.

HAS_PARK_FINISHED ( ) 

Park no respawn

Alternative version of 'PARK' - this command doesn't respawn a character standing outside of the garage when the park has finished. This will be very useful for missions - you can make a mission character drive to a garage, drive in, and then 'end' the mission.

IMPORTANT: Do NOT use this command on the player!

PARK_NO_RESPAWN ( car_name , door_name ) 

Save game

Using this command 'forces' the game to save itself. Note this must be done "outside" of a mission, and it will only save certain information. The best way of ensuring the player is outside a mission is simply to check your 'on mission' flag.

I would create a 'thread trigger' on the character entering a specific location, and when that happens - check the player's mission status, display a suitable 'SAVED GAME' brief, save game & then 'return', finishing the thread.

SAVE_GAME ( ) 

Perform save game

This new command handily wraps up all the details of saving the game. It checks whether the player is on a mission, checks whether he has enough of a score to pay, and handles subtracting the cost at the end of it. Use this instead of your current routine - it needs to be called from a THREAD_TRIGGER command as before - similar fashion to the kill frenzy templates you've already set up. There's an example below. The coords/width/height are the area around the savegame spot that the player must leave before he can save again - these should be the same as the range for the thread_trigger.

PERFORM_SAVE_GAME ( trigger_name , x , y , z , width , height ) 

Save game example

This is a working example of a new perform save game from willie's level.

THREAD_TRIGGER thr_save_slot_one = THREAD_WAIT_FOR_CHAR_IN_AREA ( player , 159.0 , 137.0 , 2.0 , 4.0 , 1.0 , do_save_slot_one: )

do_save_slot_one:
	PERFORM_SAVE_GAME ( thr_save_slot_one , 159.0 , 137.0 , 2.0 , 4.0 , 1.0 ) 
RETURN

Arrows

This command 'declares' space for an arrow to be later used in the game. Currently, you really only need one arrow for each possible colour, but it's possible to set up multiple arrows of the same colour. Current maximum is likely to be around 4 or 6, but this could be changed if necessary.

ARROW_DATA name

Point arrow at something

Sets an existing arrow to point towards either a location, character, car or object. All items must be valid existing items. If target is an object, the arrow must be cancelled before object gets deleted.

POINT_ARROW_AT ( arrow_name, item_name )
POINT_ARROW_AT ( arrow_name, X.x , Y.y , Z.z ) 

Point level end arrow at something

Sets an existing arrow to point towards either a location, character, car or object, using the new special 'LEVEL END' colouring. All items must be valid existing items. If target is an object, the arrow must be cancelled before object gets deleted. Use this only for the arrowing point towards the END OF LEVEL target!

LEVEL_END_POINT_ARROW_AT ( arrow_name, name )
LEVEL_END_POINT_ARROW_AT ( arrow_name, X.x , Y.y , Z.z ) 

Switch off arrow

Clears a previously created arrow

REMOVE_ARROW ( arrow_name )

Set arrow colour

Allows you to set the colour of non-gang arrows, ie the normal everyday mission arrow. Possibly more useful for multiplayer scripts. More colours are likely to be added.

SET_ARROW_COLOUR ( arrow_name , colour )

Explosions

Explode

Creates an explosion at a particular item's current location, or at a particular XYZ. Item can be a car, object or character.

EXPLODE ( name )
EXPLODE ( X.x , Y.y , Z.z )

Explode small

Creates a small explosion at a particular item's location or at a particular XYZ. Behaves similiarly to the other explosion commands, except this creates a WEAK small explosion.

EXPLODE_SMALL ( name )
EXPLODE_SMALL ( X.x , Y.y , Z.z ) 

Explode large

Creates an explosion at a particular item's current location, or at a particular XYZ. Item can be a car, object or character. This explosion is a LARGE explosion! A REALLY large explosion!

EXPLODE_LARGE ( name )
EXPLODE_LARGE ( X.x , Y.y , Z.z )

Explode no ring

Creates a medium explosion at a particular item's location or at a particular XYZ. Behaves similarly to the normal explode command, except this has no blast ring coming out of it.

EXPLODE_NO_RING ( name )
EXPLODE_NO_RING ( X.x , Y.y , Z.z ) 

Explode wall

Creates a "wall explosion" at a particular (X,Y,Z) & in a certain direction (LEFT, RIGHT, TOP or BOTTOM). Same effect as a rocket hitting a wall at the moment.

EXPLODE_WALL ( X.x , Y.y , Z.z ) face

Map zones

Map zone declare

Simple command to "declare" a mapzone with a name. This zone must exist in your map, otherwise an error will be given when the game tries to load the script. Using GTA2script, you can set some of the parameters for zones, such as densities, car ratios, gang affiliation etc.

MAP_ZONE name 

Map zone declare and set

Like the declare, but sets up values for each piece of info for this zone info structure. Essentially, ten pieces of info are needed, for densities & ratios for cars & character types. The fields are:

MAP_ZONE name = ( car_density , good_cars , bad_cars , police_cars , ped_density , muggers , carthiefs , elvis , gang_chars , police_peds , gang_cars)
car_density how busy the zone is for cars
good cars ratio of "good" quality models
bad cars ratio of "bad" below average quality models
police cars the chance of getting a patrolling police car driving around as a dummy
ped density how busy the zone is for characters
muggers frequency of mugger peds
carthiefs frequency of car thieves
elvis frequency of elvis peds
gang_chars frequency of getting random gang members
police_peds frequency of getting a policeman walking around as a dummy
gang_cars frequency of getting a gang car generated

Densities work in a range of 0 to 1000. 0 guarantees no cars/peds are created, 1000 means the game will attempt to make 2 cars each cycle, 3 peds. 500 means 1 car each cycle, approx 1 or 2 peds.

Car ratios:

All car ratios must add up to 1000 and again work on a sort of percentage style. If you have a good car ratio of 100, then 1 time in 10, a good car will be created. If that ratio was 500, then 1 in 2 would be "good". On top of the ratios listed, there is an "average car ratio" which is automatically calculated average ratio = 1000 - (goodcar ratio + badcar ratio + policecar ratio). Thus, if you want no average cars, make sure all other ratios add up to 1000.

  • a high class neighbourhood with little crime: goodcar 600; badcar 0; policecar 300 (average thus 100)
  • a rundown, crimeridden neighbourhood: goodcar 0; badcar 700; policecar 0 (average thus 300)

Ped ratios:

Again, ped ratios work in a range of 0 to 1000, with all ratios adding up to a total of 1000 again. Each ratio is the "chance" of getting a random ped in the zone of this occupation. This time, on top of the given ratios, there is a "dummy ped" ratio, calculated by dummyped ratio = 1000 - (muggers + car thieves + elvis + gangpeds + police peds)

Set map zones

These next commands allow you to change the parameters of a 'map zone' mid-game, during the execution of a script. This should give quite a bit of power, letting you increase/decrease how busy certain areas are as a game progresses. Note that the same constraints of a mapzone declare exist - all the number of car ratios must add up to 1000 etc.

SET_CARDENSITY ( zone_name , value )
SET_GOODCAR_RATIO ( zone_name , value )
SET_BADCAR_RATIO ( zone_name , value )
SET_POLICECAR_RATIO ( zone_name , value )
SET_PEDDENSITY ( zone_name , value )
SET_MUGGER_RATIO ( zone_name , value )
SET_CARTHIEF_RATIO ( zone_name , value )
SET_ELVIS_RATIO ( zone_name , value )
SET_GANG_RATIO ( zone_name , value )
SET_POLICEPED_RATIO ( zone_name , value )

Set station info

This command "sets up" a railway station at the start of the game. Basically, using this you can decide which stations should have trains, which shouldn't, which are passenger trains, freight trains etc. Basically, you have control over the number of carriages of each type - the maximum number of total carriages is 4, and passenger carriages are always created right behind the engine, e.g. a train of 2 passenger carriages + 2 freight carriages looks like: ENGINE-PASSENGER-PASSENGER-FREIGHT-FREIGHT

In addition, you can order a station to not have a train linked to it at the start of the game. Other trains will travel through the station & stop at it as normal though.

SET_STATION_INFO ( platform_zone_name , passenger_cars , freight_cars , box_cars ) 
SET_STATION_INFO ( platform_zone_name , NO_TRAIN ) 

Police

Declare police level

Sets the maximum police heads it's possible to achieve on this level. Valid values for this are 4, 5 or 6 heads. This should be 'outside' your missions, so put it beside your initial SET_GANG_INFO & other declarations.

DECLARE_POLICELEVEL ( heads ) 

Change police level

This command allows you to change the maximum level of heads in this level midgame. Obeys the standard rules for maximum heads.

CHANGE_POLICE_LEVEL ( new maxheads ) 

Alter wanted level

Alters the player's wanted level to a given level of heads. Effectively, you're now setting the number of heads the player should have. Valid values are between 1 & 6. Don't use this command to clear the wanted level!

ALTER_WANTED_LEVEL ( name , wanted_level )

Alter wanted level no drop

Alters the player's wanted level to a given level of heads, but only if the player has less than this number of heads!. Effectively, you're now setting the number of heads the player should have. Valid values are between 1 & 6. With this command however, if the player has 4 heads, and you request 2, it will not change it - it will NOT drop the heads lower than the player's current count!

ALTER_WANTED_LEVEL_NO_DROP ( name , num heads )

Clear wanted level

Resets the "wanted level" for a given character. This does not have to be the player character - other chars have crime levels now.

CLEAR_WANTED_LEVEL ( name )

Check heads greater

Useful command that allows you to quickly check what level of 'wanted heads' the player currently has. It returns true if heads are GREATER than the value, FALSE if equal or less.

CHECK_HEADS_GREATER ( player_name , integer heads ) 

Blocks

Add new block

Physically 'adds' a block to the map at a specific (XYZ). This new block will be completely clear & set to air - you will need to call 'CHANGE_BLOCK' after this command to actually set its type, faces etc.

ADD_NEW_BLOCK ( X , Y , Z ) 

Change block type

This allows you to alter the type & slope information for a block mid-game, i.e. you can make a block that was previously field into air, or change a block into a steep slope or one of the new fancy blocktypes. For a complete list of slopetypes, see bottom of document.

CHANGE_BLOCK TYPE ( X , Y , Z ) new_type slope_type 
X , Y , Z integer coordinates
new_type string describing new blocktype - "AIR" "FIELD" "ROAD" "PAVEMENT"
slope_type number describing the new particular slopetype. '0' for no slope!

Change block lid

This lets you to alter the details for the lid of any block in the world mid-game. You can change the graphic & the properties of the lid.

CHANGE_BLOCK LID ( X , Y , Z ) flat_type flip_type lighting rotation new_tile
X , Y , Z Integer coordinate describing the particular block position to alter
flat_type Make lid a 'flat' - either 'FLAT' or 'NOT_FLAT'
flip_type Make lid flipped - either 'FLIP' or 'NOT_FLIP'
lighting Integer describing the lighting level. 0 is normal brightness, 1-3 are increasing levels of darkness. Valid range is 0 - 3.
rotation Rotation value for this graphic: either 0, 90, 180 or 270.
new_tile The new tile graphic id for the lid!

Change block side

This is the most complicated looking CHANGE_BLOCK command. It allows you to change all the abilities for one particular side of a block, from its graphic to its wall flag. If you want to remove walls or add walls to block off particular sections of the map midgame, this is the command to use.

CHANGE_BLOCK SIDE ( X , Y , Z ) face_type wall_type bullet_type flat_type flip_type rotation new_tile 
X , Y , Z Integer coordinate describing the particular block position to alter
face_type Particular face to alter - either "TOP" "BOTTOM" "LEFT" "RIGHT"
wall_type Make side act as wall - either "WALL" or "NOT_WALL"
bullet_type Make side act as 'bullet wall' - either "BULLET" or "NOT_BULLET"
flat_type Make side a 'flat' - either 'FLAT' or 'NOT_FLAT'
flip_type Make side's graphic flipped - either 'FLIP' or 'NOT_FLIP'
rotation Rotation value for this graphic: either 0, 90, 180 or 270.
new_tile The new tile graphic id for this side!

Remove block

Physically removes a block from the map. You can decide whether you want any blocks above to logically 'fall' down one Z-block, or to stay mid-air. Note that any faces now showing because of this drop will be empty. You may have to change their values to valid tiles.

REMOVE_BLOCK ( X , Y , Z , DO_DROP ) 
REMOVE_BLOCK ( X , Y , Z , DONT_DROP )
X , Y , Z integer coordinate describing the exact block to remove
DO_DROP this forces the game to make any blocks above fall down by one level.
DONT_DROP this makes the game keep the blocks above at their current level.

Lower level

Physically 'drops' an area of the map by one level - it removes the very bottom z-level across the area specified. To drop by more than one level, call this command multiple times. All columns are automatically shuffled down, ie it does a 'DO_DROP' always.

LOWER_LEVEL ( min_X , min_Y ) ( max_X , max_Y ) 
min_X , min_Y integer coordinates describing the top left corner of the area.
max_X , max_Y integer coordinates describing the bottom right corner of the area to drop.

Switch road off

This allows you to effectively 'turn off' a road midgame, preventing the car routefinder from utilising it for routes. Note the coordinates must be a particular point on the road that is not inside the actual junctions.

SWITCH_ROAD OFF ( X , Y , Z ) 

Switch road on

The opposite of 'SWITCH_ROAD OFF', it turns a road back on again to allow the car routefinder to use it for any routes. As before, the coordinates must be a point on the road outside of any junctions.

SWITCH_ROAD ON ( x , y , z ) 

Unusable commands

Commands that are mentioned in DMA Design's official document, but appear to be non-functional.

FOR loops

FOR x = 0 TO 10 DO ... is a simple, straightforward looping mechanism that will run a set of commands X times. Used to repeat things easily. e.g

	FOR counter = 1 TO 10
		// do some stuff here
	ENDFOR

Notes: FOR loops "ascend" in steps of 1, so first number must be less than the second number. Any previous value stored in counter is discarded.

FOR counter = integer TO integer
	commands
ENDFOR

Clear car no collide

Clears the 'non-collide' property of cars.

CLEAR_CAR_NO_COLLIDE ( car_name )

Check weapon type hit char

Checks to see if a particular character has just been hit by a "bullet type" - these are roughly the same as weapon types, but not quite as precise. All machine guns & pistols fire the same type of bullets for instance. You'll have to keep this in mind. Returns true if the char has been hit, false if not.

Another thing to remember with this is that you must call it before the weapon hits - it needs to set up some stuff internally to watch for the hit - so don't expect it to work on a char being hit /before/ you check it. Put it in a loop, getting called each cycle.

See bottom of document for a list of 'DAMAGE_TYPES'.

CHECK_WEAPON_TYPE_HIT_CHAR ( char_name , damage_type )

Is char in air?

Checks to see if this character is 'falling' through the air, ie doing the 'falling' animation. Returns TRUE if so, FALSE if not.

IS_CHAR_IN_AIR ( char_name ) 

Delays for generators

Generators need two 'delays'. These give a minimum/maximum time between each object creation. If set the same, objects will be created at a regular interval.

mindelay an integer describing the minimum length of game cycles between creation. Valid range is 0 to 65535 cycles. Should be divisible by 4.
maxdelay an integer describing the maximum length of game cycles between creation

See also

Modding tutorials of Grand Theft Auto 2
Mapping Map Editor · Buildings · Roads · Water & animations · Slopes · Flat tiles · Collision info · Level edge · Zones · Putting a level ingame
Scripting Declarering: Main script · Script Compiler · Code lists · Commands · Vehicles · Objects · Sounds · Characters
Programming: IF · WHILE · COUNTERs · Subroutines · THREAD TRIGGERs · Kill Frenzies
Both Manual · Lighting · Car shops · Cranes & crushers · Gangs · Subway · Multiplayer levels
File types .gci · .gmp · .gxt · .mis · .mmp · .scr · .seq · .tmp · .sty
Other Texting · Physics · Creating vehicles · Terminology · Installing levels