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. GTA2 Scripting Information 1 Mission Language Structures 9 ? IF ... THEN ... 9 ? IF ... THEN ... ELSE ... 9 ? EXPRESSIONS 10 ? FOR LOOPS 10 ? WHILE LOOPS 11 ? WHILE EXEC LOOPS 11 ? DO WHILE LOOPS 11 ? SUBROUTINES & JUMPING 11 ? PSX / PC IFDEF BLOCKS 13 ? MULTI SCRIPTS 14 Mission Language Commands 15 ? CREATE PLAYER 15 ? CAR DECLARE 15 ? CAR DECLARE & SET 15 ? CAR CREATE 15 ? MAKE_CAR_A_DUMMY 16 ? OBJECT DECLARE 16 ? OBJECT DECLARE & SET 16 ? OBJECT SET 16 ? COUNTER DECLARE 17 ? COUNTER DECLARE & SET 17 ? CRANE DECLARE & SET 17 ? CONVEYOR DECLARE & SET 18 ? GENERATOR DECLARE & SET 18 ? DESTRUCTOR DECLARE & SET 18 ? DESTRUCTOR SET 19 ? LEVEL START 19 ? LEVEL END 19 ? CHECK CHARACTER'S HEALTH 19 ? HAS CHARACTER DIED? 19 ? CHECK CAR'S DAMAGE LEVEL 19 ? CHECK CAR HAS DRIVER 20 ? IS CHARACTER IN CAR? 20 ? IS CHARACTER STOPPED? 20 ? DECLARE ARROW 20 ? POINT ARROW AT SOMETHING 20 ? SWITCH OFF ARROW 20 ? DISPLAY MESSAGE 21 ? DISPLAY BRIEF 21 ? DISPLAY BRIEF NOW 21 ? ADD SCORE 21 ? MAP ZONE DECLARE 21 ? MAP ZONE DECLARE & SET 22 ? GIVE WEAPON 22 ? DELETE ITEM 23 ? LOCATE CHARACTER ANY MEANS 23 ? LOCATE CHARACTER ON FOOT 23 ? LOCATE CHARACTER BY CAR 24 ? LOCATE STOPPED CHARACTER 24 ? CHARACTER DECLARE 24 ? CHARACTER DECLARE & SET 25 ? CHARACTER SET 25 ? IS CAR IN BLOCK? 25 ? SET CHAR THREAT SEARCH 26 ? SET CHAR THREAT REACTION 26 ? SET CHAR OBJECTIVE 27 ? STORE CAR THAT CHARACTER IS IN 29 ? IS CAR WRECKED? 29 ? CHANGE CHAR REMAP 29 ? CHANGE CAR REMAP 30 ? CHECK CAR MODEL 30 ? CHECK CAR REMAP 30 ? CHECK CAR MODEL AND REMAP 30 ? DELAY HERE 30 ? DELAY 30 ? THREAD TRIGGERS 31 ? THREAD WAIT FOR CHAR IN CAR 31 ? THREAD WAIT FOR CHAR IN BLOCK 31 ? ENABLE THREAD TRIGGER 31 ? DISABLE THREAD TRIGGER 31 ? SET GANG INFO 32 ? SET GANG KILL REACTION 32 ? CHECK GANG RESPECT GREATER 32 ? CHECK GANG RESPECT LOWER 33 ? CHECK GANG RESPECT EQUAL 33 ? ANSWER PHONE 33 ? CHECK ANSWERED PHONE 33 ? CHECK FAIL PHONE TIMER 34 ? STOP PHONE 34 ? TELEPHONE EXAMPLE 34 ? EXPLODE WALL 34 ? IS CHAR FIRING ONSCREEN? 35 ? IS ITEM ONSCREEN? 35 ? MAKE CAR DRIVE AWAY 35 ? SET MAP ZONES 35 ? ORDER DRIVER OUT CAR 36 ? ORDER CHAR TO DRIVE CAR 36 ? HAS CAR JUST SUNK? 36 ? IS CAR IN THE AIR? 36 ? SET PATROL ROUTE FOR CHARACTER 36 ? CHECK SCORE GREATER 37 ? STORE SCORE 37 ? TIMER DECLARE 37 ? DISPLAY TIMER 37 ? CLEAR TIMER 37 ? GIVE DRIVER AND BRAKE 38 ? DECLARE DOOR INFO 38 ? IS CHAR IN GANG ZONE? 38 ? SET AMBIENT LEVEL 38 ? SET CAR NO COLLIDE 38 ? CLEAR CAR NO COLLIDE 39 ? IS CHAR FIRING IN AREA 39 ? CHECK PASSENGER COUNT 39 ? CLEAR WANTED LEVEL 39 ? CHECK CAR WRECKED IN AREA 39 ? THREAD WAIT FOR CHAR IN AREA 40 ? THREAD WAIT FOR ANSWER PHONE 40 ? CHECK NUMBER ALIVE IN GROUP 40 ? REMOVE CHAR FROM GROUP 40 ? SET CHAR SHOOTING SKILL 41 ? SET CHAR BRAVERY LEVEL 41 ? ADD_EXISTING_CHAR_TO_GROUP 41 ? SET COUNTER 42 ? DOOR DECLARE 43 ? IS CHARACTER IN MODEL? 44 ? IS CHARACTER IN ANY CAR? 44 ? DECLARE MISSION FLAG 44 ? IS TRAILER ATTACHED 44 ? IS CAR ON TRAILER 45 ? ENABLE CRANE 45 ? DISABLE CRANE 45 ? HAS CAR GOT WEAPON? 45 ? IS CHAR IN ZONE? 45 ? IS CHAR PRESSING HORN? 46 ? IS CHAR CAR CAPACITY? 46 ? SET PHONE DEAD 46 ? HAS CAR GOT DRIVER? 46 ? HAS CHAR SPOTTED PLAYER? 46 ? STORE LAST CHAR PUNCHED 47 ? HAS CHAR PUNCHED SOMEONE? 47 ? KILL ALL PASSENGERS 47 ? IS GROUP IN CAR? 47 ? IS CHAR STUNNED? 47 ? ORDER CHAR TO BACKDOOR 48 ? ADD EXISTING CHAR TO GROUP 48 ? SET MIN MEMBERS BEFORE GROUP SPLITS 48 ? ADD CHAR TO GANG 48 ? DO NOWT 48 ? MAKE NEW LEADER OF GROUP 49 ? IS CHAR OBJECTIVE PASSED? 49 ? IS CHAR OBJECTIVE FAILED? 49 ? EXPLODE 49 ? ALTER WANTED LEVEL 49 ? PARK 50 ? HAS PARK FINISHED? 50 ? CRUSHER DECLARE & SET 50 ? CHANGE GANG CHAR RESPECT 51 ? SET ARROW COLOUR 51 ? OPEN DOOR 51 ? CLOSE DOOR 51 ? MAKE DOOR AUTOMATIC 51 ? MAKE DOOR MANUAL 51 ? REMOVE WEAPONS 52 ? UPDATE DOOR TARGET 52 ? REMOVE BLOCK 52 ? ADD NEW BLOCK 52 ? CHANGE BLOCK TYPE 52 ? CHANGE BLOCK LID 53 ? CHANGE BLOCK SIDE 53 ? SWITCH GENERATOR 53 ? CHECK CAR DAMAGE POSITION 53 ? SWITCH ROAD OFF 54 ? SWITCH ROAD ON 54 ? CHECK CHAR BEEN PUNCHED BY 54 ? GET CAR INFO FROM CRANE 54 ? TAKE REMOTE CONTROL OF CAR 54 ? DO PHONE TEMPLATE 55 ? SAVE GAME 55 ? SAVED COUNTER DECLARE 55 ? CHANGE CAR LOCK 56 ? DECLARE LIGHT 56 ? DECLARE & SET LIGHT 56 ? CREATE LIGHT 57 ? CHANGE INTENSITY 57 ? CHANGE COLOUR 57 ? CHANGE RADIUS 57 ? SAVED COUNTER DECLARE & SET 58 ? PARK NO RESPAWN 58 ? ADD LIVES 58 ? CHECK NUM LIVES GREATER 58 ? STORE NUM LIVES 58 ? ADD MULTIPLIER 59 ? CHECK MULIPLIER GREATER 59 ? STORE MULTIPLIER 59 ? LOWER LEVEL 59 ? IS POINT ONSCREEN? 59 ? SET DIRECTION OF TV VAN DISHES 60 ? IS CHAR FALLING? 60 ? HAS CHAR JUST SUNK? 60 ? RADIO STATION DECLARE & SET 60 ? STORE CAR CURRENT SPEED 60 ? STORE CHAR CAR CURRENT SPEED 61 ? CHECK CAR SPEED 61 ? STORE MAX CAR SPEED 61 ? DECLARE_POLICELEVEL 61 ? SET_CAR_NUMBER_GRAPHIC 61 ? SETUP_MODELCHECK_DESTROY 62 ? HAS_MODELCHECK_HAPPENED 62 ? MODELCHECK EXAMPLE 62 ? LAUNCH MISSION 62 ? SET STATION INFO 63 ? SET CAR BULLETPROOF 63 ? SET CAR FLAMEPROOF 63 ? SET CAR ROCKETPROOF 63 ? SET CHAR DRIVE AGGRESSION 64 ? IS CARBOMB ACTIVE? 64 ? SET CHAR MAX DRIVESPEED 64 ? GIVE CAR ALARM 64 ? CLEAR ALL BRIEFS 64 ? PUT CAR ON TRAILER 64 ? CHECK HEADS GREATER 65 ? FINISH LEVEL 65 ? IS CAR CRUSHED? 65 ? THREAD ID 65 ? DISPLAY BRIEF SOON 65 ? CREATE THREAD 66 ? STOP THREAD 66 ? CHECK WEAPON TYPE HIT CHAR 66 ? IS CHAR ON FIRE? 66 ? DO EASY PHONE TEMPLATE 67 ? IS BRIEF ONSCREEN? 67 ? SOUND DECLARE 67 ? SOUND DECLARE & SET 67 ? CREATE SOUND 68 ? DELETE GROUP IN CAR 68 ? CREATE CHAR INSIDE CAR 68 ? DECLARE FINISH SCORE 68 ? DECLARE TOTAL MISSIONS 68 ? DECLARE TOTAL SECRETS 69 ? DECLARE MISSIONS PASSED FLAG 69 ? DECLARE GANG MISSIONS PASSED FLAG 69 ? SUPPRESS THIS CAR MODEL 69 ? DECLARE POWERUP CARLIST 69 ? DECIDE POWERUP FOR CRANE 70 ? IS ITEM ACCURATELY ONSCREEN 70 ? WARP FROM CAR TO POINT 70 ? CHECK WEAPON TYPE HIT CAR 70 ? SET GROUP TYPE 71 ? MAKE CHAR DO NOTHING 71 ? SET CAR EMERG LIGHTS 71 ? CHECK OBJ MODEL 71 ? SET CHAR INVINCIBLE 71 ? SET CHAR GRAPHIC TYPE 72 ? HAS CHAR BEEN ARRESTED? 72 ? CHECK ANY WEAPON TYPE HIT CAR 72 ? LOCATE ANOTHER CHARACTER ON FOOT 72 ? STOP CHAR DRIVING 73 ? IS BUS FULL? 73 ? STOP CHARS GETTING OFF BUS 73 ? KILL CHAR 73 ? SET SHADING LEVEL 73 ? SET CAR JAMMED ACCELERATOR 73 ? START BONUS CHECK 74 ? HAS BONUS FINISHED 75 ? HAS BONUS PASSED 75 ? HAS BONUS FAILED 75 ? BONUS CHECK EXAMPLE 75 ? SET CHAR MAX RUNSPEED 75 ? SET CHAR TO STAY IN CAR 76 ? SET CHAR TO USE CAR WEAPON 76 ? DECLARE GANG MISSIONS TOTAL 76 ? DECLARE SECRETS PASSED FLAG 76 ? DECLARE SECRETS FAILED FLAG 76 ? MAKE ALL CHARS MUGGERS 76 ? LOCATE ANOTHER CHARACTER BY CAR 77 ? LOCATE ANOTHER CHARACTER ANY MEANS 77 ? CHANGE GANG CHAR RESPECT AND UPDATE 77 ? MISSION HAS FINISHED 77 ? ADD SCORE NO MULT 78 ? CREATE GANG CAR 78 ? EXPLODE_LARGE 78 ? EXPLODE SMALL 78 ? BONUS DECLARE 78 ? STORE BONUS COUNT 79 ? SET ENTER CONTROL STATUS 79 ? SET ALL CONTROLS STATUS 79 ? EXPLODE NO RING 79 ? SET FAVOURITE MODEL 79 ? SET CHAR OCCUPATION 80 ? SET KF WEAPON 80 ? CLEAR KF WEAPON 80 ? ONSCREEN COUNTER DECLARE 80 ? ADD ONSCREEN COUNTER 80 ? CLEAR ONSCREEN COUNTER 81 ? CLEAR CLOCK ONLY 81 ? ARE EMERG LIGHTS ON? 81 ? CHANGE POLICE LEVEL 81 ? DESTROY GROUP 81 ? CHECK CHAR CURR WEAPON 81 ? ALTER WANTED LEVEL NO DROP 82 ? REWORKED KILL FRENZIES 82 ? START BASIC KF TEMPLATE 82 ? DO_BASIC_KF_TEMPLATE 82 ? KF TEMPLATE EXAMPLE 83 ? KF TEMPLATE BRIEFS 83 ? SET BONUS RATING TEXT ID 84 ? PARKED CAR DECLARE & SET 84 ? ADD TIME TO TIMER 84 ? THREAD WAIT FOR CHAR IN AREA ANY MEANS 84 ? DECLARE GANG DEATH BASE BRIEF 85 ? DECLARE GANG MISSION FLAG 85 ? SET DEATHARREST STATE 85 ? PERFORM SAVE GAME 85 ? SAVE GAME EXAMPLE 86 ? DECLARE CRANE POWERUP 86 ? LEVEL_END_POINT_ARROW_AT 86 ? CHECK DEATHARREST EXECUTED 86 ? SET RECYCLE MODEL WANTED 87 ? FORCE CLEANUP 87 Commands Still To Do 88 Nothing! 88 General Concepts 89 GTA2script Overview & Example 91 Frequently Asked Questions 96 ? What does "SSYacc105e: Error token failed, no valid token" mean? 96 ? How do I create a 're-spawning' powerup? 96 ? What does "Syntax Error: unrecognised token in scriptfile" mean? 96 ? I have one named character and I want to make him & the player a "group". How do I do this? 96 Character Occupation List 96 Character Remap List 96 Character Shooting Skill Levels 97 Character Bravery Levels 97 Weapon Types 97 Car Types 97 Car Remaps 99 Object Types 99 Shop Types 102 Door Opening Types 102 Door Closing Types 102 Arrow Colour Types 102 Slope Types 103 Lock Types 103 Radio Station Types 103 Damage Types 103 Sound Object Types 104 Mission Language Structures * 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. * 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 * 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! * 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 * MULTI SCRIPTS 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 execulted, e.g. WIL, STE, BIL. Launch the script using LAUNCH_MISSION. Mission Language Commands * CREATE 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 playername = CREATE_PLAYER ( float X , float Y , float Z ) remap rotation NOTES: playername: string to be used to refer to player throughout the script float X, Y, Z: coordinate to create player at * CAR DECLARE Declares 'space' for one car, without creating it rightaway. It is similar to the idea of a 'future car' in GTA. Later on in the game, do a "SET" on it to create it where/when you want it. CAR_DATA name NOTES: name: any valid string - must be unique * CAR DECLARE & SET Declares & 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!! CAR_DATA name = ( float X , float Y ) remap rotation model CAR_DATA name = ( float X , float Y ) remap rotation model trailermodel CAR_DATA name = ( float X , float Y , float Z ) remap rotation model CAR_DATA name = ( float X , float Y , float Z ) remap rotation model trailermodel NOTES: name: any valid string - must be unique floats: coordinates for car creation - if Z if left out or set to 255.0, the game will calculate correct Z remap: valid remap number - set this to -1 to have no remap applied model: valid model name - an uppercase name. See bottom of file for list. trailermodel: "second model" used to give the type of trailer to attach to this truck. set to "MINI_CAR" to make this car a small 'remote control' style car. rotation: value between 0 to 359 giving the direction of rotation. See below for details. * CAR CREATE This actually creates a car in game - the car must have been previously 'declared' using a CAR_DATA command. Needs a specific location, remap, rotation etc - behaves in the same way as a declare&set. name = CREATE_CAR ( float X , float Y ) remap rotation model END name = CREATE_CAR ( float X , float Y ) remap rotation model trailermodel END name = CREATE_CAR ( float X , float Y , float Z ) remap rotation model END name = CREATE_CAR ( float X , float Y , float Z ) remap rotation model trailermodel END NOTES: See CAR DECLARE&SET for details. * 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 ) NOTES: name: must be a valid, already existing car. * OBJECT DECLARE Declares space for an object without creating it rightaway. Similar to the concept of 'future objects'. There's no need to worry about location or type at this point. OBJ_DATA name * OBJECT DECLARE & SET Declares & creates an object of type "model" at a location, with a specific rotation. Z value works as above for cars. New: 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 = ( float X , float Y ) rotation model OBJ_DATA name = ( float X , float Y , float Z ) rotation model OBJ_DATA name = ( float X , float Y , float Z ) rotation model value OBJ_DATA name = ( float X , float Y , float Z ) rotation model shoptype NOTES: name: unique name for this object rotation: standard angle 0 - 359 model: model type from the list of valid names - can be lower/uppercase. value: ammo or remap value - integer value. shoptype: string detailing the 'shop type' - see bottom of document. * OBJECT SET Creates an object 'in game'. The object must have been previously declared. Z value works as above. NEW CHANGE: certain commands must have an 'end' at the end of the line. name = CREATE_OBJ ( float X , float Y ) rotation model END name = CREATE_OBJ ( float X , float Y , float Z ) rotation model END name = CREATE_OBJ ( float X , float Y , float Z ) rotation model value END name = CREATE_OBJ ( float X , float Y , float Z ) rotation model shoptype END NOTES: name: previously declared name rotation: 0 - 359 for angle of rotation model: a model type - given as a string. value: ammo or remap value - integer value. shoptype: string detailing the 'shop type' - see bottom of document. * COUNTER DECLARE Declares a 'counter' variable & sets it to the default value for counters, 0. Counters can be used to keep track of mission counts etc as in GTA, 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 NOTES: name: any valid string - must be unique. * COUNTER DECLARE & SET As above, but sets the newly declared counter to a different value COUNTER name = value * CRANE DECLARE & SET Declares & creates a crane. CRANE_DATA name = ( float X , float Y ) home-rotation homecrane (1) CRANE_DATA name = ( float X , float Y ) home-rotation homecrane FIRST ( float target X , float target Y ) target-rotation (2) CRANE_DATA name = ( float X , float Y ) home-rotation homecrane SECOND ( float target X , float target Y ) target-rotation (3) CRANE_DATA name = ( float X , float Y ) home-rotation homecrane FIRST ( float target X , float target 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. NOTE: name: valid name string float X,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,Y: This declares a 'target point', where any cars picked up will be dropped targetrotation: Any car picked up will be rotated when lifted so that it has this rotation when crane is finished. * CONVEYOR DECLARE & SET Declares & creates a conveyor. Conveyors move in a given direction any objects that are on its space. CONVEYOR name = ( float X , float Y ) ( float Width , float Height ) Xspeed Yspeed CONVEYOR name = ( float X , float Y , float Z ) ( float Width , float Height ) Xspeed Yspeed NOTE: name: any valid namestring floatXYZ: 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 movment. Down is positive, up is negative. * GENERATOR DECLARE & SET 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. Needs a coordinate & rotation where the objects get created, and two 'delays'. These give a minimum/maximum time between each object creation. If set the same, objects will be created at a regular interval. NOTE: Generators by default are switch OFF. GENERATOR name = ( float X , float Y ) rotation object-type mindelay maxdelay GENERATOR name = ( float X , float Y , float Z ) rotation object-type mindelay maxdelay GENERATOR name = ( float X , float Y ) rotation object-type mindelay maxdelay ammo GENERATOR name = ( float X , float Y , float Z ) rotation object-type mindelay maxdelay ammo NOTE: name: valid namestring XYZ: 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 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 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. * DESTRUCTOR DECLARE & SET Declares & 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 = ( float X , float Y ) ( width , height ) DESTRUCTOR name = ( float X , float Y , float Z ) ( width , height ) NOTE: name: valid name string float XYZ: coordinate for the centre of the destructor. width/height: width & height of the destructor - given as floats. * DESTRUCTOR SET Creates a destructor midgame. name = CREATE_DESTRUCTOR ( float X , float Y ) ( width , height ) END name = CREATE_DESTRUCTOR ( float X , float Y , float Z ) ( width , height ) END NOTE: See "DESTRUCTOR DECLARE & SET" for details. * LEVEL START This command 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. LEVELSTART * LEVEL END This flags the 'end' of the level commands. Should end the block of code after a levelstart. LEVELEND * CHECK CHARACTER'S 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 , pointvalue ) NOTE: carname: any valid carname. Must have been created beforehand pointvalue: value to check - valid range is 0 - 255, see above for examples. * 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 ) NOTE: name: any valid character name, including 'player_ped' for a check on the player. * 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 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 ( carname , value ) NOTE: carname: any valid carname. Must have been created beforehand value: percentage of damage to check. 0 is completely undamaged. 100% is completely wrecked. * 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 ( carname ) NOTE: carname: any valid carname. Must have been created beforehand * IS CHARACTER IN 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 ( charname , carname ) NOTE: charname: name of valid, existing character carname: name of valid, existing car * IS 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 ) NOTE: name: name of a valid existing character * DECLARE ARROW 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 NOTE: name: a unique namestring * 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 ( arrname, name ) POINT_ARROW_AT ( arrname, float x , float y , float z ) NOTE: arrname: name of an arrow declared with an ARROW_DATA name: name of either a car, character or object xyz: must be a valid float (X,Y,Z) coordinate. * SWITCH OFF ARROW Clears a previously created arrow REMOVE_ARROW ( arrname ) NOTE: arrname: name of an arrow declared with an ARROW_DATA * DISPLAY MESSAGE Displays a message in the large "bold" font in the centre of the screen. Used in GTA 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. DISPLAY_MESSAGE ( id ) NOTE: id: message ID to display - IDs are the numbers in the text file. * DISPLAY BRIEF Displays a "briefing" message at the bottom of the screen. Used in GTA for most messaging. GTA2 queues message to display. Messages have a low priority. DISPLAY_BRIEF ( id ) NOTE: id: message ID, from text file. * 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 ( id ) NOTE: id: message ID, from text file. * ADD SCORE Adds a score value to a given player. Limit of 65535 for value - this will change to much more! New alternative - add the value of a counter to the player's score. ADD_SCORE ( playername , value ) ADD_SCORE ( playername , counter name ) NOTE: playername: name of player! Value: integer score value. Can be positive or negative. Counter name: name of a previously declared counter * 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 NOTE: name: valid string that is in the map info. * MAP ZONE DECLARE & 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 = ( cardensity , goodcarratio , bad car ratio , police car ratio , ped density , mugger ratio , car thief ratio , elvis ratio , gang char ratio , police ped ratio , gang car ratio) car density how busy the zone is for cars good car ratio ratio of "good" quality models bad car ratio ratio of "bad" below average quality models police car ratio the chance of getting a patrolling police car driving around as a dummy ped density how busy the zone is for characters mugger ratio frequency of mugger peds car thief ratio frequency of car thieves elvis ratio frequency of elvis peds gang char ratio frequency of getting random gang members police ped ratio frequency of getting a policeman walking around as a dummy gang car ratio 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 upto 1000. e.g. 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 ) * 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! See bottom of document for list of weapon types. GIVE_WEAPON ( charname , weapon_type ) GIVE_WEAPON ( carname , weapon_type ) GIVE_WEAPON ( player name , weapon_type , amount of ammo ) NOTES: charname: any valid character name carname: name of a valid car weapon_type: a name of a valid weapon type: player name: name of a valid existing player character amount of ammo: interger value listing the amount of ammo to give player for this weapon. * 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 ) NOTE: name: previously created character or car or object or light! * LOCATE CHARACTER ANY MEANS 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, it 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. LOCATE_CHARACTER_ANY_MEANS ( charname , float X , float Y , float Z , float Width , float height ) Note: charname: name of a previously created character, including the player character. float XYZ centre point of 'box' to check float width, height dimensions of box to check for character. Example: LOCATE_CHARACTER_ANY_MEANS ( playerone , 123.5 , 45.5 , 2.0 , 3.0 , 1.0 ) This would check for the player entering the box ( 120.5, 44.5, 2.0 ) to ( 126.5 , 46.5 , 2.0 ) * LOCATE CHARACTER ON FOOT 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, it will return TRUE ONLY when this character enters the box on foot, FALSE otherwise LOCATE_CHARACTER_ON_FOOT ( charname , float X , float Y , float Z , float Width , float height ) Note: charname: name of a previously created character, including the player character. float XYZ centre point of 'box' to check float width, height dimensions of box to check for character. Example: LOCATE_CHARACTER_ON_FOOT ( playerone , 123.5 , 45.5 , 2.0 , 3.0 , 1.0 ) This would check for the player entering the box ( 120.5, 44.5, 2.0 ) to ( 126.5 , 46.5 , 2.0 ) on foot only. * LOCATE CHARACTER BY CAR 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, it will return TRUE ONLY when this character enters the box driving a car, FALSE otherwise. As with 'ANY MEANS', I may change this to return true if the character is a passenger in a car. LOCATE_CHARACTER_BY_CAR ( charname , float X , float Y , float Z , float Width , float height ) Note: charname: name of a previously created character, including the player character. float XYZ centre point of 'box' to check float width, height dimensions of box to check for character. E.g. LOCATE_CHARACTER_BY_CAR( playerone , 123.5 , 45.5 , 2.0 , 3.0 , 1.0 ) This would check for the player entering the box ( 120.5, 44.5, 2.0 ) to ( 126.5 , 46.5 , 2.0 ) on foot only * LOCATE STOPPED CHARACTER 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 ( charname , float X , float Y , float Z , float Width , float Height ) LOCATE_STOPPED_CHARACTER_ON_FOOT ( charname , float X , float Y , float Z , float Width , float Height ) LOCATE_STOPPED_CHARACTER_BY_CAR ( charname , float X , float Y , float Z , float Width , float Height ) Example LOCATE_STOPPED_CHARACTER_ON_FOOT ( dummychar , 253.0 , 12.0 , 3.0 , 1.0 , 5.0 ) This will return TRUE when the character 'dummychar' stops in the box (252.0 , 7.0) to ( 254.0 , 17.0) at height 3.0 * CHARACTER DECLARE Declares 'space' for a single character CHAR_DATA name NOTE: name: any valid unique string. * CHARACTER DECLARE & SET Declares & 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 = ( float X , float Y ) remap rotation occupation CHAR_DATA name = ( float X , float Y , float Z ) remap rotation occupation NOTES: name: a unique string that will be used to refer to this character. float X,Y,Z valid coordinates that the character will exactly be positioned at. remap: an integer detailing what remap to apply to this character. rotation: an integer detailing the angle the character will face. Valid angles are 0 to 359 occupation: a string detailing what 'occupation' or behavioud this character will start with. Example: 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 * CHARACTER SET Creates a character midgame using a previously declared character 'slot'. As with almost all 'creates', the Z value may be skipped, leaving the game to calculate the correct Z level. charname = CREATE_CHAR ( float X , float Y ) remap rotation occupation END charname = CREATE_CHAR ( float X , float Y , float Z ) remap rotation occupation END NOTE: charname: a previously declared character, declared using CHAR_DATA charname. float XYZ: valid gameworld coordinate, at which the character will be positioned. remap: remap given to the character on creation rotation: the rotation the character will face, valid values are 0 to 359 occupation: the default 'job'/'behaviour to give the character - given as a string. Example: CHAR_DATA examplechar CHAR_DATA anotherchar examplechar = CREATE_CHAR ( 123.4 , 5.6 , 2.0 ) 0 350 mugger END anotherchar = CREATE_CHAR ( 34.5 , 3.9 ) 3 180 car_thief END * 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. IS_CAR_IN_BLOCK ( carname , float X , float Y , float Z ) IS_CAR_IN_BLOCK ( carname , float X , float Y , float Z , float width , float height ) NOTE: carname: string giving the name of a previously created, existing car float XYZ: coordinates giving the block to check. width/height: width/height of location to check instead of 'just' one block. This is the TOTAL width/height - ie '1' will do it 0.5 in each direction... * SET CHAR 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. 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. Command: SET_CHAR_THREAT_SEARCH ( charname , search_type ) NOTES: charname: A valid existing character. search_type: One of the types listed above: NO_THREATS, AREA etc. * SET CHAR 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. 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. Command: SET_CHAR_THREAT_REACTION ( charname , reaction_type ) NOTE: charname: name of a valid previously created character reaction_type: one of the above reaction_types - NO_REACTION, RUN_AWAY etc 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 CHAR 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 GTA, 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. Command: SET_CHAR_OBJECTIVE ( charname , objective type ) The basic, straightforward command, taking in just the character's name & the new objective type. SET_CHAR_OBJECTIVE ( charname , objective type , second_item ) This command contains an extra piece of info - a name of a previously declared item. Objectives that need this info are likely to work on a second character, car or possibly an object, ie follows, kills, etc. SET_CHAR_OBJECTIVE ( charname , objective type , float X , float Y , float Z ) This command is for objectives dealing with locations - ie 'send to' style objectives. In addition to the charname/objective type, it has a (XYZ) coordinate detailed with floats. NOTE: There are likely to be future variants with different info... Objective Types: The following objective types need no extra 'info' to work, so use the above command. NO_OBJ Order's 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. * 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 ( charname , carname ) NOTE: charname: name of a valid existing character carname: name of a "CAR_DATA" slot. Will overwrite any info in it. * 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 ( carname ) NOTE: carname: name of a valid existing car... * CHANGE CHAR REMAP Alters the remap of a character's ped graphic to a new value CHANGE_CHAR_REMAP ( charname , new remap ) NOTE: charname: name of a previously created character, including the player new remap: an integer value describing the remap value - values will be given later. * CHANGE CAR REMAP Alters the remap of a car to a new value. If the car is an artic vehicle, it handles remapping the attached 'truck'. CHANGE_CAR_REMAP ( carname , new remap ) NOTE: carname: name of a previously created car. new remap: integer value describing the remap value to apply to the car. Legal values will be given at a later date. * CHECK CAR MODEL Checks to see if this car has a specific model - returns TRUE if so, FALSE if not. CHECK_CAR_MODEL ( carname , model ) NOTE: carname: name of a previously created car model: name of a valid carmodel, e.g rtype etc. * CHECK CAR REMAP Checks to see if this car has a specific remap - returns TRUE if so, FALSE if not. CHECK_CAR_REMAP ( carname , remap id ) NOTE: carname: name of a previously created car remap id: integer value listing a valid remap value. * 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 ( carname , model type , remap id ) NOTE: carname: name of a previously created car model type: name of a valid 'car model type' remap id: integer value listing a valid remap value. * 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 whileExec commands. DELAY_HERE ( count ) NOTE: count: integer number of cycles to wait * 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 ) NOTE: count: integer number of cycles to wait... * THREAD TRIGGERS Thread triggers are a new data type that operate in a similar way to 'triggers' in GTA. 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. * THREAD WAIT FOR CHAR 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 triggername = THREAD_WAIT_FOR_CHAR_IN_CAR ( charname, carname, labelname, NOTE: charname: name of a previously declared character. Does not need to have been created yet, but it MUST be created when the trigger is enabled. carname: 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. labelname: name of the subroutine to be called when the trigger is enabled & the trigger action 'fires'. Note the label should have a ':' after it! * THREAD WAIT FOR CHAR IN BLOCK This is similar to the above command, but waits for a particular character entering a block on foot. THREAD_TRIGGER triggername = THREAD_WAIT_FOR_CHAR_IN_BLOCK (charname , x , y , z , labelname ) NOTE: charname: name of a previously declared character. Again, does not need to have actually been created at this point... XYZ: Three integers declaring the block the character must enter on foot. labelname: the subroutine in the script that the game calls when the trigger action is fired. Note the labelname has a ':' at the end! 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: ) * 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 ) * 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 ( gangname , remap value , weapon 1 , weapon 2 , weapon 4 , arrow id , x , y , z , killchar , car model , car remap ) NOTE: gangname: string giving the name of a gang, e.g. commie , rednecks remapvalue: The remap to give all characters of this gang - standard char remaps can be used. Weapon 1: Weapontype 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,Y,Z: float coordinates detailing the 'centre' of your gang area that you want the general gang arrow to point to. killchar: 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 ( gangone , gangtwo , value ) NOTE: gangone: gangtwo: names of gangs previously declared in a 'SET_GANG_INFO'. value: integer listing the 'change' to happen e.g. gangtwo HATES gangone SET_GANG_KILL_REACTION ( gangone, gangtwo , 10) When player kills a gangone char, his respect rating with gangtwo goes up by 10. The player's rating automatically goes down with gangone, no matter the relationships, because you've killed a gang member! * CHECK GANG RESPECT GREATER Checks the player's 'respect level' for this gang - if greater than required level, returns TRUE otherwise FALSE. CHECK_RESPECT_GREATER ( playername , gangname , requiredlevel ) NOTE: playername: name of the character controlled by a player. MUST be player controlled! gangname: name of a previously declared gang, e.g. rednecks requiredlevel: integer giving the value to check the player's 'respect' against, valid range is 100 to 0 to -100. * 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 ( playername , gangname requiredlevel ) NOTE: playername: name of the character controlled by a player. MUST be player controlled! gangname: name of a previously declared gang, e.g. rednecks requiredlevel: integer giving the value to check the player's 'respect' against, valid range is 100 to 0 to -100. * 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 ( playername , gangname , requiredlevel ) NOTE: playername: name of the character controlled by a player. MUST be player controlled! gangname: name of a previously declared gang, e.g. rednecks requiredlevel: integer giving the value to check the player's 'respect' against, valid range is 100 to 0 to -100. * 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. ANSWER_PHONE ( char name , telephone name , timer value ) NOTE: char name: name of the player's character - this command ONLY works on players. telephone name: name of the telephone - this is a declared & created OBJ_DATA. timer value: integer value for how many cycles the phone will ring. Setting this to -1 means the phone will ring until you command it to stop. * 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 ) NOTE: Telephone name: the name of the telephone to check. * 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 ) NOTE: telephonename: name of the telephone used in the original ANSWER_PHONE. * 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 ) NOTE: telephone name: name of a telephone object. * 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 * EXPLODE WALL Creates a "wall explosion" at a particular (X,Y,Z) & in a certain direction. Same effect as a rocket hitting a wall at the moment. EXPLODE_WALL ( float x , float y , float z ) face NOTE: xyz: must be floats, and must be "on" a wall, ie x or y is likely to be a whole value. face: which face explosion should be on: left , right , top , bottom * IS CHAR 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 ) NOTE: name: name of a valid existing character * 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 ) NOTE: name: name of a valid existing character, car or object. * 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 ( carname ) NOTE: carname: name of a previously created car. * 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 , new value ) SET_GOODCAR_RATIO ( zone name , new value ) SET_BADCAR_RATIO ( zone name , new value ) SET_POLICECAR_RATIO ( zone name , new value ) SET_PEDDENSITY ( zone name , new value ) SET_MUGGER_RATIO ( zone name , new value ) SET_CARTHIEF_RATIO ( zone name , new value ) SET_ELVIS_RATIO ( zone name , new value ) SET_GANG_RATIO ( zone name , new value ) SET_POLICEPED_RATIO ( zone name , new value ) NOTE: zone name: name of a 'map_zone' declared previously. new value: a value between 0 & 1000, which will be stored in the map zone info. * ORDER DRIVER OUT 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 ( charname ) NOTE: charname: name of a valid existing character - see above for details * ORDER CHAR TO DRIVE 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 ( charname , carname ) NOTE: charname: name of valid existing character carname: name of valid existing car. * 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 ( carname ) NOTE: carname: name of a previously created car * 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 ( carname ) NOTE: carname: name of a previously created car. * SET PATROL ROUTE FOR CHARACTER 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 ( charname , float x , float y , float z ) NOTE: charname: name of a valid existing character xyz: float coordinates detailing the block the character should walk to. Note that there is a degree of redundancy here, the game only uses it as 'whole blocks'. * 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 ( playername , integer value ) NOTE: playername: name of a player created using a PLAYER_DATA command value: Integer giving the value to check the score against. * 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 ( playername , counter name ) NOTE: playername: name of a player created using a PLAYER_DATA command counter name: name of a valid counter * TIMER DECLARE 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 NOTE: name: unique name to give to this timer. Will be used elsewhere in script... * 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 ) NOTE: timer_name: name of a valid 'TIMER_DATA' item. count: number of cycles to count down towards zero from. * 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 ) NOTE: timer name: name of a valid 'TIMER_DATA' item. * 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 ) NOTES: name: must be a valid already existing car. * 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 ) NOTE: 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... * IS CHAR IN 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 ( charname , gangname ) NOTE: charname: name of a previously created character, including player gangname: name of a gang 'declared' using a SET_GANG_INFO. Name must match the name used in the zone's inside the map... * 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 ) NOTE: 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 CAR NO COLLIDE Sets a car as 'no collide', meaning it will not be moved/affected by any collisions. SET_CAR_NO_COLLIDE ( carname ) NOTE: carname: name of a valid existing car... * CLEAR CAR NO COLLIDE Clears the 'non-collide' property of cars CLEAR_CAR_NO_COLLIDE ( carname ) NOTE: carname: name of a valid existing car... * IS CHAR FIRING IN 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 GTA. IS_CHAR_FIRING_IN_AREA ( name , float X , float Y , float Z , width , height ) NOTE: name: name of a valid exising character - including player XYZ centre point of location to check, floats for accuracy Width/height width & height of area to check, * 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 ( carname , integer value ) NOTE: carname: name of a valid existing car. value: number of passengers to check for - usually 0 to around 4 etc. Never negative. * 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 ) NOTE: name: name of valid, existing character * 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 ( carname , x , y , z , width , height ) NOTE: carname: name of a valid exising car XYZ centre point of location to check, floats for accuracy width/height width & height of area to check, again floats * THREAD WAIT FOR CHAR IN AREA This is similar to the above command, but waits for a particular character entering a defined area on foot. THREAD_TRIGGER triggername = THREAD_WAIT_FOR_CHAR_IN_AREA (charname , x , y , z , width, height, labelname ) NOTE: charname: name of a previously declared character. Again, does not need to have actually been created at this point... XYZ: Three floats describing the centre of area... Width/height: width & height of area to check for. labelname: the subroutine in the script that the game calls when the trigger action is fired. Note the labelname has a ':' at the end! * THREAD WAIT FOR ANSWER PHONE This creates a trigger that waits for the given character (usually the player but not necessarily) nswering 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 triggername = THREAD_WAIT_FOR_ANSWER_PHONE ( charname, phonename, labelname, NOTE: charname: name of a previously declared character. Does not need to have been created yet, but it MUST be created when the trigger is enabled. phonename: name of a previously declared phone. Again, does not need to have been created yet, but it must be created when you go to use the trigger for real. labelname: name of the subroutine to be called when the trigger is enabled & the trigger action 'fires'. Note the label should have a ':' after it! * 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 , integer value ) NOTE: leader name: name of current group leader character value: value to check against * 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 ( leadername , second char ) NOTE: leadername: name of the current group leader character Second char: name of the character to remove from group. * SET CHAR 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 ) NOTE: charname: name of a valid previously created character. NOT the player Skill: string detailing the level to use. See below * SET CHAR 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 ) NOTE: charname: name of a valid previously created character. NOT the player. level: string detailing the bravery level to use. See below. * 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. ADD_EXISTING_CHAR_TO_GROUP ( leader name , second char ) NOTE: leadername: name of the valid created character, currently with a group of chars secondchar: name of the character to add to group... 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 ) * 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 countername = integer value SET countername = anothercounter SET countername = ( anothercounter + yet_another_counter ) SET countername = ( anothercounter - yet_another_counter ) SET countername = ( anothercounter / yet_another_counter ) SET countername = ( anothercounter * yet_another_counter ) SET countername = ( anothercounter mod yet_another_counter ) SET countername = ( anothercounter + value ) SET countername = ( anothercounter - value ) SET countername = ( anothercounter / value ) SET countername = ( anothercounter * value ) SET countername = ( anothercounter mod value ) NOTE: countername name of a previously declared counter integervalue the value to store anothercounter name of another previously declared counter to copy value from. Yetanothercounter name of yet another counter to use.... Value integer value to use in this arithmetic operation. * 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. i.e. 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 ( int X , int Y , int Z ) ( float check X , check Y , check Z , check width , check height ) face gr_id open_type close_type delay flip reverse DOOR_DATA name = style ( int X , int Y , int Z ) ( float check X , check Y , check Z , check width , check height ) face gr_id open_type close_type delay flip reverse somename DOOR_DATA name = style ( int X , int Y , int Z ) ( float check X , check Y , check Z , check width , check height ) face gr_id open_type close_type delay flip reverse value NOTE: name: unique string giving a name for this door style: either SINGLE or DOUBLE to tell game what style of door it is XYZ: integer values giving the coordinates of the block to put the door 'on' Check XYZ: floats describing the 'door check' trigger opening position... Check 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 GTA 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. somename: 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 * 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 ( charname , model ) NOTE: charname: name of a previously created character, including the player model: car model type, listed at the bottom of the document. * 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 ( charname ) NOTE: charname: name of a previously created character, including the player. * 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 ) NOTE: player name: name of a previously declared player's character counter name: name of the counter used to 'flag' being on a mission. Eg. PLAYER_PED player = ( 214.5 , 64.5 , 255.0 ) 1 1 COUNTER flag_on_mission = 0 DECLARE_MISSION_FLAG ( player , flag_on_mission ) * 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 ) NOTE: car name: name of a previously created car trailer name: name of a previously created car which is one of the trailer types... * 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 ) NOTE: car name: name of a previously created car transport name: name of a previously creater car transporter. * 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 ) NOTE: crane name: name of a previously created crane * 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 ) NOTE: crane name: name of a previously created crane * 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. NOTE: at the moment, valid car weapons are: CAR_BOMB CAR_OIL CAR_MINE HAS_CAR_GOT_WEAPON ( car name , weapon type ) NOTE: car name: name of a previously declared car weapon type: one of the weapon types from the list at the bottom of doc. * IS CHAR IN 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 ) NOTE: char name: name of a previously created character, including the player zone name: name of a local navigation zone. * IS CHAR PRESSING 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 ) NOTE: char name: name of a previously created character, including the player. * IS CHAR 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 ) NOTE: char name: name of a previously created character, including the player passenger value: integer describing the max passengers you want. * 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 ( obj name ) NOTE: obj name: name of the phone object. * 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 ) NOTE: car name: name of a previously created car * HAS CHAR 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 ( charname ) NOTE: charname: name of the character to check... * STORE LAST CHAR PUNCHED Variant on the old GTA '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 ) NOTE: char name: name of the character who did the punching store name: name of the "CHAR_DATA" slot to store the new character in. * HAS CHAR PUNCHED SOMEONE? Companion command to 'STORE_LAST..'. This returns TRUE if the character has just punched someone, FALSE if not. HAS_CHAR_PUNCHED_SOMEONE ( charname ) NOTE: charname: name of the character to check. * 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 ) NOTE: car name: name of the previously created car * 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 ) NOTE: leader name: name of a previously created character who is leader of the group. * IS CHAR 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 ) NOTE: char name: name of a previously created character * ORDER CHAR 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 ( charname , carname ) NOTE: charname: name of valid existing character carname: name of valid existing car. * ADD EXISTING CHAR TO GROUP Takes a character & adds the character to a group of characters created elsewhere. 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 , new char ) NOTE: leader name: name of the character currently leader of the group new char: name of the character to add to the group * 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 ) NOTE: leader name: name of the leader character value: integer value for the new minimum. * ADD CHAR TO GANG Sets a character's gang allegiance, ie makes him a gang character... ADD_CHAR_TO_GANG ( char name , gang name ) NOTE: char name: name of a valid previously created character gang name: name of a gang in this map. * 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 NOTE: No params, just simple DO_NOWT * 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 ) NOTE: old leader: name of the character who used to lead the group new leader: name of the character who is to be the new leader (inc player). * IS CHAR 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 ( charname ) NOTE: Charname: name of a previously created character * IS CHAR 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 ( charname ) NOTE: charname: name of a previously created character. * 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 ( float X , float Y , float Z ) NOTE: name: name of a previously created character, object or car. x,y,z: float coordinates describing the EXACT position to create the explosion at. Explosion can be at any point in block! * 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 , num heads ) NOTE: name: name of valid, existing character num heads: the new value of heads for the character * 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 GTA. 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 ) NOTE: car name: name of a previously created car, or a car you've stored the info of. door name: name of a door you previously declared. * 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 ( ) NOTE: No parameters!!! * CRUSHER DECLARE & SET 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 = ( centre x , centre y ) NOTE: Name: unique name string for this crusher centre XY: float X,Y describing the centre position of the crane. At the moment, it just uses the 'block' aspect of the coordinate... * 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 ) NOTE: gangname: name of the gang... char name: name of the player's character... diference: integer value to add to the respect. Can be negative! * 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 string ) NOTE: arrow name: name of a previously declared & created arrow colour string: the colour you want the arrow to be! * OPEN DOOR This forces a door to open. Note, the door should be MANUAL controlled for best effect. OPEN_DOOR ( doorname ) NOTE: doorname: name of a previously created door * CLOSE DOOR This forces a door to close. This waits for it to be clear of obstructions! CLOSE_DOOR ( doorname ) NOTE: doorname: name of a previously created door * 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 ( doorname ) NOTE: doorname: name of a previously created door * 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 ( doorname ) NOTE: doorname: name of a previously created door * REMOVE WEAPONS Removes all weapons that this character has. Works on player too! REMOVE_WEAPONS ( charname ) NOTE: charname: name of a previously created character. * 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 ( doorname , target name ) NOTE: doorname: name of a previously created door target name: name of the character or car related to this door. * REMOVE BLOCK Physically removes a block from the map. You can decide whether you want any blocks above to logically 'fall' down one zblock, 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 ) NOTE: xyz: 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. * 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 ) NOTE: xyz: Integer coordinate describing the particular position to add this new block. * 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 NOTE: 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 NOTE: xyz: 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 NOTE: xyz: 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 as as a 'flat' - either "FLAT" or "NOT_FLAT" flip_type: Make side's graphic flipped - either "FLIP" or "NOT_FLIP" rotation: Rotation value for this new graphic: either 0, 90, 180 or 270 new_tile: The new tile graphic id for this side! * 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 ) NOTE: 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. * 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 ( carname , position ) NOTE: carname: name of a previously created car position: one of the five positions listed above. * 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 ) NOTE: xyz: Integer coordinate describing the road to turn off. * 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 ) NOTE: xyz: Integer coordinate describing the road to turn on. * CHECK CHAR 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 ) NOTE: punched name: name of the character to check if he's been punched attacker name: name of the character doing the punching! * 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 carname to point to the car it was processing. GET_CAR_INFO_FROM_CRANE ( carname , cranename ) NOTE: carname: name of a CAR_DATA slot cranename: name of a previously created CRANE. * 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 ( char name , car name ) Note: char name: name of a previously created PLAYER's character. car name: name of a previously created car. Can be a mini-car or normal sized. * 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 ) * 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 ( ) NOTE: No params! * SAVED COUNTER DECLARE 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 NOTES: name: any valid string - must be unique. * 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 ) NOTE: car name: name of a valid car locktype: string listing a valid 'lock type'. See bottom of document. * DECLARE LIGHT This 'reserves' space for a single light, letting you create a light midgame. LIGHT name NOTE: name: A valid, unique name for this light. * DECLARE & SET LIGHT This declares & 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 = ( float X , float Y , float Z ) radius intensity ( red value , green value , blue value ) on_delay off_delay random_value NOTE: name: A valid unique name to refer to this light. float XYZ: Coordinate detailing the exact position to place this light at. Float radius: exact radius of light to give out. Valid values are (0.0 to 7.999 ) Integer intensity: integer value describing strength of light. Valid values are ( 0 to 255 ) red value: green value: blue value: 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. * CREATE LIGHT This command lets you create a light 'midgame'. See 'DECLARE & SET' for full details. name = CREATE_LIGHT ( float X , float Y , float Z ) radius intensity ( red , green , blue ) on_delay off_delay random_value NOTE: name: name of a previously declared light! float XYZ: Coordinate detailing the exact position to place this light at. Float radius: exact radius of light to give out. Valid values are (0.0 to 7.999 ) Integer intensity: integer value describing strength of light. Valid values are ( 0 to 255 ) red value: These three are the colour components that make up the colour this light should have. green value: Valid ranges for these values are (0 - 255) with 255 being the 'strongest'. blue value: ( 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. * CHANGE INTENSITY Alters the intensity setting for a previously created light. CHANGE_INTENSITY ( lightname , new intensity ) NOTE: lightname: name of a previously declared & created light new intensity: floating point value giving the new intensity value. * CHANGE COLOUR Alters the colour setting for an existing light. CHANGE_COLOUR ( lightname , new red , new green , new blue ) NOTE: lightname: name of a previously created light new red: integer value describing the red colour component (0 - 255 ) new green: integer value describing the green colour component (0 - 255 ) new blue: integer value describing the blue colour component (0 - 255 ) * CHANGE RADIUS Alters the radius for an existing light. CHANGE_RADIUS ( lightname , new radius ) NOTE: lightname: name of a previously created light new radius: float value describing the new radius ( 0.0 to 7.9999 ) * SAVED COUNTER DECLARE & 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 NOTE: Name: unique string Value: integer value for the 'default' for this counter. * 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 ) NOTE: car name: name of a previously created car, or a car you've stored the info of. door name: name of a door you previously declared. * 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 to add ) NOTE: player name: name of a previously created player's character value to add: integer value describing the number of lives to give to the player ( 0 - 99 ) * CHECK NUM 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 ( playername , integer value ) NOTE: playername: name of a previously declared player's character integer value: Integer describing the number of lives to check against * STORE NUM 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 ( playername , counter name ) NOTE: playername: name of a previously declared player's character counter name: name of a previously declared counter * 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 to add ) NOTE: player name: name of a previously created player's character value to add: integer value describing the number of lives to give to the player ( 0 - 99 ) * CHECK MULIPLIER GREATER Simply checks the current multiplier for this player against a particular value. If greater than it returns TRUE, else FALSE. CHECK_MULTIPLIER_GREATER ( playername , integer value ) NOTE: playername: name of a previously declared player's character integer value: Integer describing the multiplier count to check against * 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 ( playername , counter name ) NOTE: playername: name of a previously declared player's character counter name: name of a previously declared counter * 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 ( minx , miny ) ( maxx , maxy ) NOTE: Minx/miny: integer coordinates describing the top left corner of the area. Maxx/maxy: integer coordinates describing the bottom right corner of the area to drop. * 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 ( float x , float y , float z ) NOTE: xyz: float coordinates describing the exact point to check onscreen. * 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 ( float X , float Y ) NOTE: XY: float coordinates describing the exact point the dishes should point to. * IS CHAR 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_IN_AIR ( charname ) NOTE: charname: name of a previously created character, including the player. * HAS CHAR JUST SUNK? Checks to see if this character is sinking in water. Returns TRUE if so, FALSE if not. HAS_CHAR_JUST_SUNK ( charname ) NOTE: charname: name of a previously created character, including the player. * RADIO STATION DECLARE & SET 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 ( float X , float Y ) NOTE: name: unique namestring for this radio station. type: the 'type' of broadcast it has - list at bottom of document float XY: coordinate detailing the position on the map of the radio station. * 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 ( carname , counter ) NOTE: carname: name of a previously declared car. counter: name of a previously declared counter to store the speed in * STORE CHAR 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 ( charname , counter ) NOTE: charname: name of a previously declared character, inc. player counter: name of a previously declared counter to store the speed in. * 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 , integer value ) NOTE: car name: name of a previously created car integer value: value to check speed against. (0 - 16384) * STORE MAX CAR SPEED Stores the maximum speed for the car specified in a counter. STORE_MAX_CAR_SPEED ( car name , counter name ) NOTE: car name: name of a previously declared car counter name: name of a previously declared counter to store maxspeed in. * DECLARE_POLICELEVEL 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 ( integer heads ) NOTE: integer heads: integer value giving the maximum amount of heads possible on this level. * 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 ) NOTE: car name: name of a previously declared & created car Number: integer value describing the new 'number' for on top of the car. * 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 ) NOTE: car model: name of a particular model of car to check. * 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 * 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 ) NOTE: filename: name of the file.... Should end in .mis! * 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 name , num passenger , num freight , num boxcar ) SET_STATION_INFO ( platform name , NO_TRAIN ) NOTE: platform name: name of the platform linked to this station - this is how the game knows which station to work on. num passenger: integer value listing the number of passenger carriages for this train. num freight: integer value listing the number of freight carriages for this train. num boxcar: integer value listing the number of 'boxcar' carriages for this train. * 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 ( carname , ON ) SET_CAR_BULLETPROOF ( carname , OFF ) NOTE: Carname: name of a previously created car ON/OFF: string detailing whether to switch bulletproof on or 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 ( carname , ON ) SET_CAR_FLAMEPROOF ( carname , OFF ) NOTE: Carname: name of a previously created car ON/OFF: string detailing whether to switch flameproof on or 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 ( carname , ON ) SET_CAR_ROCKETPROOF ( carname , OFF ) NOTE: Carname: name of a previously created car ON/OFF: string detailing whether to switch rocketproof on or off * SET CHAR 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 ) NOTE: Char_name: name of a previously created character. ON/OFF: string detailing whether to switch agression on or off. * IS CARBOMB 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 ( carname ) NOTE: Carname: name of a previously created car * SET CHAR MAX 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 ) NOTE: Char_name: name of a previously created character Speed: Floating point value detailing the new 'max speed'. * 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 ) NOTE: Car_name: name of a previously created car. * 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 ( ) * 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 ) NOTE: car name: name of the car to put on top of the trailer Trailer name: name of a trailer - usually of "truktrns" model * 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 ) NOTE: player name: name of the player's character to check integer heads: integer value of the heads to check - valid range is ( 0 to 5 effectively) * 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 ) NOTE: Bonus_type: type of bonus from list above - BONUS_1 BONUS_2 BONUS_3 NO_BONUS * 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 ) NOTE: car name: name of a previously created car * THREAD ID Thread Ids 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 NOTE: name: string detailing the unique name for this 'THREAD_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 ( integer value ) NOTE: value: an integer value describing the message ID from e.gxt to display soon. * 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 GTA, 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: NOTE: 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 ) NOTE: thread_name: name of a previously declared THREAD_ID item * 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 ) NOTE: char name: name of a previously created character, including the player damage type: string detailing the 'type' of damage to look out for. * IS CHAR 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 ) NOTE: char name: name of a previously declared character * 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 ) * 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 ( ) * SOUND DECLARE Declares 'space' for one sound object, without creating it right away. 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! SOUND name NOTE: name: any valid string - must be unique * SOUND DECLARE & SET Declares & creates a 'sound object' of the type you specify at location (XYZ), with the play characteristic you give. At the moment, there are two characteristics: 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 obj name ) on it. See bottom of document for a list of 'sound object' types. SOUND name = ( float X , float Y , float Z ) type playtype NOTE: name: unique name for this sound object XYZ: exact location to position this sound's centre point at. type: the 'sound type' for this sound object - see bottom of document playtype: the playback characteristic - PLAY_FOREVER or PLAY_INSTANT * CREATE SOUND This command lets you create a sound object midgame. See 'SOUND DECLARE & SET' for details of the parameters/types etc. name = CREATE_SOUND ( float X , float Y , float Z ) type playtype END NOTE: name: unique name for this sound object XYZ: exact location to position this sound's centre point at. type: the 'sound type' for this sound object - see bottom of document playtype: the playback characteristic - PLAY_FOREVER or PLAY_INSTANT * 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 ( char leader ) NOTE: char leader: name of the leader of the group * CREATE CHAR INSIDE CAR This creates a 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 NOTE: char name: name of a 'CHAR_DATA' slot Car name: name of a previously created & declared car Remap: integer value describing the remap to give this character Occupation: the occupation to give this character. * 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). DECLARE_FINISH_SCORE ( integer value ) NOTE: value: integer declaring the score value * 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. DECLARE_TOTAL_MISSIONS ( integer value ) NOTE: value: integer declaring the number of missions in the script * DECLARE TOTAL SECRETS This signal to the game the total number of hidden 'secrets' on this level. DECLARE_TOTAL_SECRETS ( integer value ) NOTE: value: integer declaring the number of missions in the script * 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 ) NOTE: counter name: string detailing the name of the previously declared counter * 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 ) NOTE: counter name: string detailing the name of the previously declared counter * 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. SUPPRESS_THIS_CAR_MODEL ( model name ) NOTE: model name: string detailing the car model name to suppress, NONE to stop suppressing. * DECLARE POWERUP 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 ) NOTE: model x: string detailing a car model... * DECIDE POWERUP 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 to check , generator name ) NOTE: car to check: name of a previously declared car - this is the crushed car Generator name: name of the generator to use for the powerup * 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 ) NOTE: item name: name of a previously declared item - see 'is item onscreen' * WARP 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 , float X , float Y , float Z , int rotation ) NOTE: Char name: name of the character to warp Float XYZ: the new location to move to Int rotation: the rotation to set the character to face once warped. * 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 ) NOTE: car name: name of a previously created car damage type: string detailing the 'type' of damage to look out for. * 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 GTA MOB - follow the leader in a 'rabble' - this is the default behaviour. SET_GROUP_TYPE ( leader name , type ) NOTE: Leader name: name of a previously created character, with a group Type: one of the two types listed above - CHAIN or MOB * MAKE CHAR 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 ) NOTE: Char name: name of a previously created character * SET CAR EMERG 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 ) NOTE: Car name: name of a previously created car * CHECK OBJ 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 ) NOTE: Obj name: name of a previously created object Obj model: string detailing the model name from the list at the bottom of the doc * SET CHAR INVINCIBLE Using this command, you can make a character 'invincible' to all bullets/flames/rockets/explosions. The only way to harm him is to run him over & stun him! You can set this on & off... SET_CHAR_INVINCIBLE ( char name , ON ) SET_CHAR_INVINCIBLE ( char name , OFF ) NOTE: char name: name of a previously created character, including the player * SET CHAR 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 GANG_GRAPHIC SET_CHAR_GRAPHIC_TYPE ( char name , graphic type , remap value ) NOTE: char name: name of a previously created character graphic type: one of the types listed above. Remap value: the remap value to apply to this new graphic type... * HAS CHAR 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 ( char name ) NOTE char name: name of a player controlled character * 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 ) NOTE: car name: name of a previously created car * LOCATE ANOTHER CHARACTER ON FOOT 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 ) NOTE: main char: name of the char that is doing the 'running around', ie the player locate char: name of the char that is the 'target' for the locate width: floating point value detailing the total width of the check height: floating point value detailing the total width of the check * STOP CHAR 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 ) NOTE: char name: name of the character * 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. IS_BUS_FULL ( char name ) NOTE: char name: name of the player's character - must be driving a bus! * 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 ( char name , ON ) STOP_CHARS_GETTING_OFF_BUS ( char name , OFF ) NOTE: char name: just the name of the player. * KILL CHAR 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 ) NOTE: Char name: name of a previously created character. * 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 ) NOTE: Value: integer value detailing what level to set. * SET CAR JAMMED 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 ) NOTE: Car name: name of a previously created car, probably being driven by the player * 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. Bonus = START_BONUS_CHECK ( zone , time , count , score , type , exclusive mode , damage type , attack model , gang name ) Bonus = START_BONUS_CHECK ( zone , time , count , score , type , exclusive mode , damage type , attack model , gang name , target remap ) Bonus = START_BONUS_CHECK ( zone , time , count , score , type , exclusive mode , damage type , attack model , char occupation ) Bonus = START_BONUS_CHECK ( zone , time , count , score , type , exclusive mode , damage type , attack model , char occupation , target remap ) Bonus = START_BONUS_CHECK ( zone , time , count , score , type , exclusive mode , damage type , attack model , target car model ) Bonus = START_BONUS_CHECK ( zone , time , count , score , type , exclusive mode , damage type , attack model , target car model , target remap ) NOTE: Bonus: 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 ( name ) NOTE: Name: name of a bonus item, used by a START_BONUS_CHECK * 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 ( name ) NOTE: Name: name of a bonus item, used by a START_BONUS_CHECK * 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 ( name ) NOTE: Name: name of a bonus item, used by a START_BONUS_CHECK * 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 * SET CHAR MAX 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 ) NOTE: Char name: name of the character's speed to set Float speed: floating point value detailing new max. * SET CHAR TO STAY IN 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 ( charname , ON ) SET_CHAR_TO_STAY_IN_CAR ( charname , OFF ) NOTE: charname: name of the character to stay inside his car * SET CHAR TO USE 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 ( charname , ON ) SET_CHAR_TO_USE_CAR_WEAPON ( charname , OFF ) NOTE: Charname: name of the character to use car weapon... * 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 ) NOTE: Integer value: the number of available for this gang * 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 ) NOTE: counter name: name of the counter containing the info required * DECLARE SECRETS FAILED FLAG This tells the game a name of a counter containing a record of the number of secrets FAILED byt eh player so far in this game. Put it by your other DECLARE... commands. DECLARE_SECRETS_FAILED_FLAG ( counter name ) NOTE: Counter name: name of the counter containing the info required. * MAKE ALL CHARS MUGGERS Ignore the 'muggers' bit - this effectively makes new dummy characters "mad", as requested by Willie. Any hassles - bug IainR about it! MAKE_ALL_CHARS_MUGGERS ( ON ) MAKE_ALL_CHARS_MUGGERS ( OFF ) * LOCATE ANOTHER CHARACTER BY CAR Operates like the other locates, except with this the character must approach another character in a vehicle. 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_BY_CAR ( main char , locate char , width , height ) NOTE: main char: name of the char that is doing the 'running around', ie the player locate char: name of the char that is the 'target' for the locate width: floating point value detailing the total width of the check height: floating point value detailing the total width of the check * LOCATE ANOTHER CHARACTER ANY MEANS Operates like the other locates, except with this the character must approach another character in a vehicle or 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_ANY_MEANS ( main char , locate char , width , height ) NOTE: main char: name of the char that is doing the 'running around', ie the player locate char: name of the char that is the 'target' for the locate width: floating point value detailing the total width of the check height: floating point value detailing the total width of the check * 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 ) NOTE: gangname: name of the gang... char name: name of the player's character... diference: integer value to add to the respect. Can be negative! * 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 ( ) * ADD SCORE NO MULT This is a variation of the standard 'add score' command, except it ignores the multiplier. ADD_SCORE ( playername , value ) NOTE: playername: name of player! Value: integer score value. Can be positive or negative. * CREATE GANG CAR 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 ( float X , float Y ) remap rotation model END name = CREATE_GANG_CAR ( float X , float Y ) remap rotation model trailermodel END name = CREATE_GANG_CAR ( float X , float Y , float Z ) remap rotation model END name = CREATE_GANG_CAR ( float X , float Y , float Z ) remap rotation model trailermodel END NOTES: See CAR DECLARE&SET for details. * 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 ( float X , float Y , float Z ) NOTE: name: name of a previously created character, object or car. x,y,z: float coordinates describing the EXACT position to create the explosion at. Explosion can be at any point in block! * 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 ( float X , float Y , float Z ) NOTE: Name: name of a previously created character, object etc Xyz: float coordinates describing the EXACT position to create the explosion at. * 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 NOTE: Name: unique name to give to this 'bonus' item. * 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 ) NOTE: Bonus name: name of a 'BONUS' item that's currently being used with a START_BONUS_CHECK command Counter name: name of a counter to store the value in. * 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 ) NOTE: player name: name of the player's character! * SET ALL CONTROLS 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 ) NOTE: Player name: name of the player to act on. Usually just the local player. * 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 ( float X , float Y , float Z ) NOTE: Name: name of a previously created character, object etc Xyz: float coordinates describing the EXACT position to create the explosion at. * 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 ) NOTE: Char name: name of a previously created character Model name: name of a car model. * SET CHAR OCCUPATION This lets you change a character's occupation mid-game. Not applicable to the player's char! SET_CHAR_OCCUPATION ( char name , occupation ) NOTE: Char name: name of the character Occupation: string detailing the new occupation * SET KF 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 ( char name , weapon type ) NOTE: Char name: name of a player controlled character Weapon type: the type of weapon to give! * CLEAR KF 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 ( char name ) NOTE: Char name: name of a player controlled character * ONSCREEN COUNTER DECLARE 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 ) NOTE: Onscreen_counter name: name of a 'ONSCREEN_COUNTER' for referring to this command. Counter name: the name of the actual COUNTER to display onscreen. * CLEAR ONSCREEN COUNTER This removes a counter from the screen, leaving the clock running if one is onscreen. CLEAR_ONSCREEN_COUNTER ( onscreen counter name ) NOTE: Onscreen counter name: name of the offscreen_counter holding the details for the one currently getting displayed * 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 ) NOTE: Timer name: name of the 'timer data' containing the hook to the onscreen timer. * ARE EMERG 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 ) NOTE: Car name: name of a previously declared/created car * 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 ) NOTE: new maxheads: integer value detailing the maximum level of heads. * DESTROY GROUP This command effectively 'splits'a group, making all the members wander off as individuals again. DESTROY_GROUP ( leader name ) NOTE: Leader name: name of a character * CHECK CHAR CURR 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 ( char name , weapon type ) NOTE: Char name: name of a player controlled character Weapon type: type of weapon to check for * 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 ) NOTE: name: name of valid, existing character num heads: the new value of heads for the character * 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 KF 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 ) NOTE: 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_KF_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 ) NOTE: 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. * KF 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 * KF 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! * 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 ) NOTE: rating id: integer value detailing the player's rating * PARKED CAR DECLARE & SET 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 = ( float X , float Y ) remap rotation model PARKED_CAR_DATA name = ( float X , float Y ) remap rotation model trailermodel PARKED_CAR_DATA name = ( float X , float Y , float Z ) remap rotation model PARKED_CAR_DATA name = ( float X , float Y , float Z ) remap rotation model trailermodel NOTES: name: any valid string - must be unique floats: coordinates for car creation - if Z if left out or set to 255.0, the game will calculate correct Z remap: valid remap number - set this to -1 to have no remap applied model: valid model name - an uppercase name. See bottom of file for list. trailermodel: "second model" used to give the type of trailer to attach to this truck. set to "MINI_CAR" to make this car a small 'remote control' style car. rotation: value between 0 to 359 giving the direction of rotation. See below for details. * 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 ) NOTE: Timer name: name of an existing 'TIMER' Seconds: integer value detailing in seconds the time to add. * THREAD WAIT FOR CHAR 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 triggername = THREAD_WAIT_FOR_CHAR_IN_AREA_ANY_MEANS (charname , x , y , z , width, height, labelname ) NOTE: charname: name of a previously declared character. Again, does not need to have actually been created at this point... XYZ: Three floats describing the centre of area... Width/height: width & height of area to check for. labelname: the subroutine in the script that the game calls when the trigger action is fired. Note the labelname has a ':' at the end! * 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 ) NOTE: Player name: name of the player associated with this brief Integer base: integer value detailing the 'base brief id' in the e.gxt file * 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 ) NOTE: Player name: name of the player Flag name: name of the 'counter' used to store the info. * SET DEATHARREST 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 ) NOTE: Player name: name of the player's character * 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 ) NOTE: Trigger_name: name of a THREAD_TRIGGER used to start the savegame thread. Xyz: coordinates of the centre of the range to use for checking location Width/height: area to check. * 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 * DECLARE CRANE POWERUP 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 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 ) NOTE: crane name: name of a previously created crane Generator name: name of a previously created generator XYZ: Integer values describing the position inside the building. * LEVEL_END_POINT_ARROW_AT 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 ( arrname, name ) LEVEL_END_POINT_ARROW_AT ( arrname, float x , float y , float z ) NOTE: arrname: name of an arrow declared with an ARROW_DATA name: name of either a car, character or object xyz: must be a valid float (X,Y,Z) coordinate. * CHECK DEATHARREST 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 ( ) * 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 ) NOTE: Car model type: just a string detailing a particular model to use, e.g. HOTDOG * 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 ) NOTE: Object name: name of a previously declared & created object! * The angle system is N 180 W 270 E 90 S 0 * 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 */ * FLOATS Floating point numbers are used extensively instead of the "fixed point" as in GTA. 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. * TRIGGERS 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. Example triggers: THREAD_WAIT_FOR_ANSWER_PHONE THREAD_WAIT_FOR_CHAR_IN_CAR THREAD_WAIT_FOR_CHAR_IN_BLOCK THREAD_WAIT_FOR_CHAR_IN_AREA THREAD_WAIT_FOR_CHAR_IN_AREA_ANY_MEANS * 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 GTA, 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 GTA. 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. * GENERAL 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 GTA, 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. GTA2script Overview & Example GTA2 will contain a mission scripting system much improved over GTA'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 GTA. 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: FOR ( x = 0) DO ... 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 GTA, 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 ( charname , 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. Readability of scripts GTA2scripts are be long & detailed. To help designers read & follow their scripts, comments can easily be added using two different C++ style constructs /* this is a comment spanning two lines */ // this is a single line comment Judicious use of whitespace to break up functions, separate out sections of code will help the readability of GTA2script files. On-screen Messages Designers will be able to display text messages onscreen in a similar fashion to GTA, 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 ) Example: This is a detailed GTA2script example of the structure & contents of a simple mission from beginning to end, with comments detailing what is happening. // player PLAYER_PED player = ( 113.5 , 124.7 , 255.0 ) 25 1 //cars for mission CAR_DATA armoured_car_zh1 CAR_DATA car1_zh1 //characters for mission CHAR_DATA dealer_leader1 CHAR_DATA dealer_leader2 //objects for the mission OBJ_DATA gun_zh1 //counters COUNTER flag_both_cars_destroyed = 0 COUNTER flag_armoured_car_zh1_destroyed = 0 COUNTER flag_car1_zh1_destroyed = 0 COUNTER counter_timer_zh1 = 10799 TIMER_DATA timer_zh1 //start of mission do_zaibatsugang_hard_phone_m1: SET flag_on_mission = 1 SET flag_on_zaibatsugang_mission = 1 SET flag_failed_zaibatsugang_hard_phone_m1 = 0 DISPLAY_MESSAGE ( 1987 ) //"ARMOURED CARS" DISPLAY_BRIEF ( 1701 ) //"Zack has been kidnapped by the Yakuza, He knows too much, and soon will crack under torture, we need you to get rid of him!" POINT_ARROW_AT ( arrow , armoured_car_zh1 ) POINT_ARROW_AT ( arrow1 , car1_zh1 ) DISPLAY_TIMER ( timer_zh1 , 360 ) WHILE_EXEC ( NOT ( flag_both_cars_destroyed = 2 ) ) -- counter_timer_zh1 IF ( ( IS_CAR_WRECKED ( armoured_car_zh1 ) ) AND ( NOT ( flag_armoured_car_zh1_destroyed = 1 ) ) ) DISPLAY_BRIEF_NOW ( 1703 ) //"That's one of the cars now get the other!" REMOVE_ARROW ( arrow ) ++ flag_both_cars_destroyed SET flag_armoured_car_zh1_destroyed = 1 -- counter_timer_zh1 ENDIF IF ( ( IS_CAR_WRECKED ( car1_zh1 ) ) AND ( NOT ( flag_car1_zh1_destroyed = 1 ) ) ) DISPLAY_BRIEF_NOW ( 1703 ) //"That's one of the cars now get the other!" REMOVE_ARROW ( arrow1 ) ++ flag_both_cars_destroyed SET flag_car1_zh1_destroyed = 1 -- counter_timer_zh1 ENDIF IF ( counter_timer_zh1 = 0 ) CLEAR_ALL_BRIEFS ( ) DISPLAY_BRIEF_NOW ( 1705 ) //"You took too long and Zack spilled his guts. Mission Failed!" DISPLAY_MESSAGE ( 1125 ) SET flag_mission_state = 1 SET flag_failed_zaibatsugang_hard_phone_m1 = 1 -- counter_timer_zh1 RETURN ENDIF ENDWHILE IF ( ( flag_mission_state = 0 ) AND ( NOT ( counter_timer_zh1 = 0 ) ) ) CLEAR_ALL_BRIEFS ( ) DISPLAY_BRIEF ( 1702 ) //"Well Done! Its a pity about Zack but he should not have been so stupid as to get caught in the first place. Mission Complete!" DISPLAY_MESSAGE ( 1124 ) ADD_SCORE ( player , 60000 ) ADD_MULTIPLIER ( player , 1 ) CLEAR_WANTED_LEVEL ( player ) CHANGE_GANG_CHAR_RESPECT_AND_UPDATE ( zaibatsugang , player , 1 ) SET flag_passed_zaibatsugang_hard_phone_m1 = 1 ENDIF RETURN //------------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------------ //mission cleanup clean_up_zaibatsugang_hard_phone_m1: SET flag_on_mission = 0 SET flag_on_zaibatsugang_mission = 0 SET flag_mission_state = 0 REMOVE_ARROW ( arrow ) REMOVE_ARROW ( arrow1 ) CLEAR_TIMER ( timer_zh1 ) CLEAR_WANTED_LEVEL ( player ) MISSION_HAS_FINISHED ( ) IF ( flag_passed_zaibatsugang_hard_phone_m1 = 1 ) ++ counter_number_of_missions_passed ++ counter_number_of_zaibatsugang_missions_passed ENDIF IF ( flag_failed_zaibatsugang_hard_phone_m1 = 1 ) ++ counter_number_of_missions_failed ++ counter_number_of_zaibatsugang_missions_failed CLEAR_WANTED_LEVEL ( player ) CHANGE_GANG_CHAR_RESPECT_AND_UPDATE ( zaibatsugang , player , -1 ) ENDIF RETURN //------------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------------ LEVELSTART EXEC armoured_car_zh1 = CREATE_GANG_CAR ( 124.5 , 104.5 , 2.0 ) 15 0 miura END SET_CAR_BULLETPROOF ( armoured_car_zh1 , on ) SET_CAR_ROCKETPROOF ( armoured_car_zh1 , on ) SET_CAR_FLAMEPROOF ( armoured_car_zh1 , on ) car1_zh1 = CREATE_GANG_CAR ( 124.5 , 100.5 , 2.0 ) 15 0 miura END SET_CAR_BULLETPROOF ( car1_zh1 , on ) SET_CAR_ROCKETPROOF ( car1_zh1 , on ) SET_CAR_FLAMEPROOF ( car1_zh1 , on ) dealer_leader1 = CREATE_CHAR_INSIDE_CAR ( armoured_car_zh1 ) 13 criminal END SET_CHAR_DRIVE_AGGRESSION ( dealer_leader1 , on ) SET_CHAR_THREAT_REACTION ( dealer_leader1 , no_reaction ) SET_CHAR_THREAT_SEARCH ( dealer_leader1 , no_threats ) dealer_leader2 = CREATE_CHAR_INSIDE_CAR ( car1_zh1 ) 13 criminal END SET_CHAR_DRIVE_AGGRESSION ( dealer_leader2 , on ) SET_CHAR_THREAT_SEARCH ( dealer_leader2 , no_threats ) SET_CHAR_THREAT_REACTION ( dealer_leader2 , no_reaction ) GIVE_WEAPON ( dealer_leader2 , pistol ) CHANGE_CAR_LOCK ( armoured_car_zh1 , locked ) CHANGE_CAR_LOCK ( car1_zh1 , locked ) ENDEXEC GOSUB do_zaibatsugang_hard_phone_m1: GOSUB clean_up_zaibatsugang_hard_phone_m1: LEVELEND * Frequently Asked Questions * What does "SSYacc105e: Error token failed, no valid token" mean? This error message 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. * How do I create a 're-spawning' powerup? Create a generator that makes the correct collectible, and switch it on. Give it a really long delay, and it will recreate another powerup after that time if the last object was collected. If no player has picked it up, it will do nothing. * What does "Syntax Error: unrecognised token in scriptfile" mean? Generally, this error message 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! * I have one named character and I want to make him & the player a "group". How do I do this? Dead easy. Do "ADD_GROUP_TO_CHAR" 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. * Character Occupation List This is a list of the currently valid character occupations. Please clarify with Iain Ross any queries over types, information, objectives. NO_OCCUPATION just used for START_BONUS checks! DUMMY normal, dummy ped PSYCHO a 'psycho' who randomly walks around the city killing other characters. MUGGER attacks one random character nearby & promptly runs away BANK_ROBBER CRIMINAL_TYPE1 Like a criminal, but hates criminal type 2, and will not shoot any criminal_1 CRIMINAL_TYPE2 hates any criminal_type1. TANK_DRIVER DRONE REFUGEES ANY_LAW_ENFORCEMENT Primarily for bonus checks - these count as any dummy of ANY_EMERGENCY_SERVICE_MAN this type ANY_GANG_MEMBER ANY_ELVIS * Character Remap List Num Description 0 Blue Police 1 Green Police 2 Red Police 3 Yellow Police 4 Khaki Police 5 Red head Redneck 6 Blond head Redneck 7 Yellow Scientist 8 Zaibatsu remap 9 Kristna remap 10 Russian remap 11 Loony remap 12 Elvis remap 13 Yakuza remap 14 Fireman remap 15 Green Shorts Ped 16 Medic Remap 17 Mugger Remap 18 Blue Dumy remap 19 Light Blue Dummy remap 20 T-Shirt and shorts dummy remap 21 short sleeved shirt and trousers dummy remap 22 prison uniform 23 Hulk1 ( normal ) 24 Hulk2 ( green ) 25 player ped 26 naked dummy 27-52 assorted dummy remaps * Character Shooting Skill Levels CRAP_SHOT NORMAL_SHOT CRACK_SHOT Character Bravery Levels COWARD AVERAGE LOONY Weapon Types Ped Weapons: PISTOL MACHINE_GUN ROCKET_LAUNCHER ELECTRO_GUN MOLOTOV SHOTGUN ELECTRO_BATON SILENCED_MACHINE_GUN FLAME_THROWER DUAL_PISTOL GRENADE MICROWAVE * Car Weapons: CAR_BOMB CAR_MACHINE_GUN CAR_OIL CAR_FLAMETHROWER CAR_MINE WATER_CANNON TANK_GUN JEEP_GUN CAR_BOMB_INSTANT * Car Types ALFA ALLARD AMDB4 APC BANKVAN BMW BOXCAR BOXTRUCK BUG BUG2 BUICK BURNT1 BURNT2 BUS COPCAR DART EDSEL EDSELFBI F250 FIAT FIRETRUK GRAHAM GTRUCK GT24640 GT90 GUNJEEP HOTDOG ICECREAM ISETLIMO ISETTA JEEP JEFFREY LIMO LIMO2 MEDICAR MERC MESSER MIURA MONSTER MORGAN MORRIS PICKUP RTYPE SKYLINE SPIDER SPRITE STINGRAY STRATOS STRATOSB STRIPETB STYPE STYPECAB SWATVAN T2000GT TANK TANKER TAXI TBIRD TOWTRUCK TRAIN TRAINCAB TRAINFB TRANCEAM TRUKCAB1 TRUKCAB2 TRUKCONT TRUKTRNS TVVAN VAN VESPA VTYPE WBTWIN XK120 ZCX5 * Car Remaps List of all car remaps - not all models have each remap. 0 AlpBlue 1 Black 2 Black3 3 Blue 4 BlueGrey 5 BrGreen 6 BriteRed 7 Brown 8 Browner 9 BSilver 10 BYellow 11 Cream 12 Cyan 13 DBeige 14 DBlue 15 DeepBlue 16 DGreen 17 DRed 18 Drust 19 Gold 20 Green 21 Grey 22 LBrown 23 Olive 24 Orange 25 PaleBlue 26 PinkRed 27 Purple 28 Red 29 Rust 30 Silver 31 Skyblue 32 Turquoiz 33 White 34 Whiter 35 Yellow 36 zzgbank * Object Types BIN // solid, very but can be moved by car BIN_LID // same BLASTER // radio that plays music until you kick or run over it BLOOD // blood - same as in gta1!! BOLLARD // the stairs car blocker BRIEFCASE // can't be picked up... CAR_SHOP CONE // traffic cone, you can kick it away on foot MINE // works - explodes OIL // works too! PHONE // blue GREEN_PHONE RED_PHONE YELLOW_PHONE RED_FOOTPRINTS // strange thing... RUBBISH // some trash (boxes and vegetibles) TRAFFIC_LIGHT // light only, no light box BIG_BROWN_SKID BIG_GREY_SKID BIG_RED_SKID BIG_WHITE_SKID SMALL_BROWN_SKID SMALL_GREY_SKID SMALL_RED_SKID SMALL_WHITE_SKID MEDIUM_BROWN_SKID MEDIUM_GREY_SKID MEDIUM_RED_SKID MEDIUM_WHITE_SKID HUGE_RED_SKID HUGE_WHITE_SKID HUGE_BROWN_SKID HUGE_GREY_SKID INVISIBLE_TARGET FBI BLOCK POWERGEN // goes to powergen_dead when destroyed POWERGEN_DEAD INVISIBLE_DESTRUCTIBLE // goes to invisble_dead when destroyed TUNNEL_BLOCKER // use this to block off train tunnels! REMOTE // remote control handset for KFs! KILL_FRENZY INVISIBLE_DEAD BONUS_TOKEN BOMB COLLECT_00 // pistol COLLECT_01 // machine gun COLLECT_02 // rocket launcher COLLECT_03 // electro gun COLLECT_04 // molotov COLLECT_05 // grenade COLLECT_06 // shotgun COLLECT_07 // COLLECT_08 // flame thrower COLLECT_09 // silenced machine gun COLLECT_10 // dual pistol COLLECT_11 // COLLECT_12 // COLLECT_13 // COLLECT_14 // COLLECT_15 // car - car bomb COLLECT_16 // car - oil COLLECT_17 // car - mine COLLECT_18 // car - machine gun COLLECT_19 // car - tank's gun (not collectable) COLLECT_20 // car - water cannon (not collectable) COLLECT_21 // car - flamethrower (not collectable) COLLECT_22 // car - jeep gun (not collectable) COLLECT_23 // car - instant bomb COLLECT_24 // COLLECT_25 // COLLECT_26 // COLLECT_27 // COLLECT_28 // multiplier powerup COLLECT_29 // life powerup COLLECT_30 // health powerup COLLECT_31 // armour powerup COLLECT_32 // get out of jail free powerup COLLECT_33 // police bribe powerup COLLECT_34 // invulnerability powerup COLLECT_35 // double damage powerup COLLECT_36 // double fire-rate powerup COLLECT_37 // electrify powerup COLLECT_38 // respect powerup COLLECT_39 // invisibility powerup COLLECT_40 // temporary gang powerup (multiplayer only!) COLLECT_41 // COLLECT_42 // COLLECT_43 // COLLECT_44 // MOVING_COLLECT_00 // pistol MOVING_COLLECT_01 // machine gun MOVING_COLLECT_02 // rocket launcher MOVING_COLLECT_03 // electro gun MOVING_COLLECT_04 // molotov MOVING_COLLECT_05 // grenade MOVING_COLLECT_06 // shotgun MOVING_COLLECT_07 // MOVING_COLLECT_08 // flame thrower MOVING_COLLECT_09 // silenced machine gun MOVING_COLLECT_10 // dual pistol MOVING_COLLECT_11 // MOVING_COLLECT_12 // MOVING_COLLECT_13 // MOVING_COLLECT_14 // MOVING_COLLECT_15 // car - car bomb MOVING_COLLECT_16 // car - oil MOVING_COLLECT_17 // car - mine MOVING_COLLECT_18 // car - machine gun MOVING_COLLECT_19 // car - tank's gun (not collectable) MOVING_COLLECT_20 // car - water cannon (not collectable) MOVING_COLLECT_21 // car - flamethrower (not collectable) MOVING_COLLECT_22 // car - jeep gun (not collectable) MOVING_COLLECT_23 // car - instant bomb MOVING_COLLECT_24 // MOVING_COLLECT_25 // MOVING_COLLECT_26 // MOVING_COLLECT_27 // MOVING_COLLECT_28 // multiplier powerup MOVING_COLLECT_29 // life powerup MOVING_COLLECT_30 // health powerup MOVING_COLLECT_31 // armour powerup MOVING_COLLECT_32 // get out of jail free powerup MOVING_COLLECT_33 // police bribe powerup MOVING_COLLECT_34 // invulnerability powerup MOVING_COLLECT_35 // double damage powerup MOVING_COLLECT_36 // double fire-rate powerup MOVING_COLLECT_37 // electrify powerup MOVING_COLLECT_38 // respect powerup MOVING_COLLECT_39 // invisibility powerup MOVING_COLLECT_40 // temporary gang powerup (multiplayer only!) MOVING_COLLECT_41 // MOVING_COLLECT_42 // MOVING_COLLECT_43 // MOVING_COLLECT_44 // * Shop Types BOMB_SHOP MINES_SHOP OILSLICK_SHOP MACHINEGUN_SHOP * Door Opening Types ANY_PLAYER ANY_CAR ONE_CAR - requires name of car! ONE_MODEL - requires name of model! ONE_CHAR_ON_FOOT - requires name of character! ANY_PLAYER_ONE_CAR - requires name of car! Door Closing Types CLOSE_NEVER CLOSE_TIME_DELAY CLOSE_WHEN_CLEAR CLOSE_WHEN_OPEN_RULE_FAILS * Arrow Colour Types RED GREEN BLUE YELLOW * Slope Types 0 = none 1- 2 = up 26 low, high 3 - 4 = down 26 low, high 5 - 6 = left 26 low, high 7 - 8 = right 26 low, high 9 - 16 = up 7 low - high 17 - 24 = down 7 low - high 25 - 32 = left 7 low - high 33 - 40 = right 7 low - high 41 - 44 = 45 up,down,left,right 45 = diagonal, facing up left 46 = diagonal, facing up right 47 = diagonal, facing down left 48 = diagonal, facing down right 49 = 3 or 4-sided diagonal slope, facing up left 50 = 3 or 4-sided diagonal slope, facing up right 51 = 3 or 4-sided diagonal slope, facing down left 52 = 3 or 4-sided diagonal slope, facing down right 53 = partial block left 54 = partial block right 55 = partial block top 56 = partial block bottom 57 = partial block top left corner 58 = partial block top right corner 59 = partial block bottom right corner 60 = partial block bottom left corner 61 = partial centre block 16x16 62 = reserved for future use 63 = indicates slope in block above * Lock Types NO_LOCK LOCKED // locks out everyone, including players LOCKOUT_THIEF // locks out only carthiefs UNLOCKED // unlocked LOCKED_PERMANENTLY // ALWAYS locked for everyone!! LOCKOUT_PLAYER // locks out ONLY players! Radio Station Types STATION_ZAIBATSU STATION_YAKUZA STATION_LOONIE STATION_REDNECK STATION_KRISHNA STATION_RUSSIAN STATION_SCIENTIST STATION_INDUSTRIAL STATION_RESIDENTIAL STATION_DOWNTOWN * Damage Types BY_EXPLOSION BY_DROWNING BY_PUNCH BY_GUN BY_CAR_BOMB BY_FIRE BY_FLAMETHROWER BY_GRENADE BY_MOLOTOV BY_ROCKET_LAUNCHER BY_ELECTRO_WEAPON BY_SHOTGUN BY_WATER_CANNON BY_ANY_WEAPON BY_ANY_FOOT_WEAPON // use this to check for player killing things while on foot only! * Sound Object Types WIND SKID NIGHT_CLUB BAR GENERATOR_RUMBLE WORKSHOP VAT CHURCH_SINGING TEMPLE_CHANT INDUSTRIAL_HIGHT HUMAN_ABATTOIR FUNNY_FARM BANK_ALARM INDUSTRIAL_LOW PORTA_LOO WATERFALL CRICKETS PRISON PRISON_ALARM GANG_DUMPED SMUG_LAUGH PRISON_YARD PRISON_RIOT GANG_LOCKED_IN_BUS SHOPPING_MALL CLOCK_TOWER YEEHA_BOMB BOWLING_ALLEY CROWD_NOISE FAN_NOISE GENERATOR_LOSE_POWER SCREAM BOMB_TICK BOMB_TICK_SHIT DETECTED_MUMBLE KRISHNA_CHANT CRYING ROCKET_LAUNCH_FAIL_CLICK ROCKET_FAIL_LAUGH POISONED POWER_PLANT MUMBLE JAZZ_CLUB COUNTRY_CLUB PYLON DISGRACELAND BAR_2 STRIP_CLUB TEMPLE_2 GARAGE_OPEN - really for code GARAGE_CLOSE - really for code LET_ME_OUT * Delfi's complete list of all weapons NO_WEAPON WEAPON_27 WEAPON_26 WEAPON_25 WEAPON_24 CAR_BOMB_INSTANT JEEP_GUN CAR_FLAMETHROWER WATER_CANNON TANK_GUN CAR_MACHINE_GUN CAR_MINE CAR_OIL CAR_BOMB WEAPON_14 WEAPON_13 WEAPON_12 WEAPON_11 DUAL_PISTOL SILENCED_MACHINE_GUN FLAME_THROWER ELECTRO_BATON SHOTGUN GRENADE MOLOTOV ELECTRO_GUN ROCKET_LAUNCHER MACHINE_GUN PISTOL * Delfi's complete list of valid objects: TUNNEL_BLOCKER INVISIBLE_DEAD GENLITE INVISIBLE_DESTRUCTIBLE POWERGEN_DEAD POWERGEN INVISIBLE_TARGET SOUND_INSTANT TASER_BULLET BONUS_TOKEN PISTOL_BULLET SPARK CROSSING BLOOD RED_FOOTPRINTS TRAFFIC_LIGHT BULLET BIG_RED_SKID BIG_GREY_SKID BIG_BROWN_SKID BOMB MOVING_COLLECT_44 MOVING_COLLECT_43 MOVING_COLLECT_42 MOVING_COLLECT_41 MOVING_COLLECT_40 MOVING_COLLECT_39 MOVING_COLLECT_38 MOVING_COLLECT_37 MOVING_COLLECT_36 MOVING_COLLECT_35 MOVING_COLLECT_34 MOVING_COLLECT_33 MOVING_COLLECT_32 MOVING_COLLECT_31 MOVING_COLLECT_30 MOVING_COLLECT_29 MOVING_COLLECT_28 MOVING_COLLECT_27 MOVING_COLLECT_26 MOVING_COLLECT_25 MOVING_COLLECT_24 MOVING_COLLECT_23 MOVING_COLLECT_22 MOVING_COLLECT_21 MOVING_COLLECT_20 MOVING_COLLECT_19 MOVING_COLLECT_18 MOVING_COLLECT_17 MOVING_COLLECT_16 MOVING_COLLECT_15 MOVING_COLLECT_14 MOVING_COLLECT_13 MOVING_COLLECT_12 MOVING_COLLECT_11 MOVING_COLLECT_10 MOVING_COLLECT_09 MOVING_COLLECT_08 MOVING_COLLECT_07 MOVING_COLLECT_06 MOVING_COLLECT_05 MOVING_COLLECT_04 MOVING_COLLECT_03 MOVING_COLLECT_02 MOVING_COLLECT_01 MOVING_COLLECT_00 COLLECT_44 COLLECT_43 COLLECT_42 COLLECT_41 COLLECT_40 COLLECT_39 COLLECT_38 COLLECT_37 COLLECT_36 COLLECT_35 COLLECT_34 COLLECT_33 COLLECT_32 COLLECT_31 COLLECT_30 COLLECT_29 COLLECT_28 COLLECT_27 COLLECT_26 COLLECT_25 COLLECT_24 COLLECT_23 COLLECT_22 COLLECT_21 COLLECT_20 COLLECT_19 COLLECT_18 COLLECT_17 COLLECT_16 COLLECT_15 COLLECT_14 COLLECT_13 COLLECT_12 COLLECT_11 COLLECT_10 COLLECT_09 COLLECT_08 COLLECT_07 COLLECT_06 COLLECT_05 COLLECT_04 COLLECT_03 COLLECT_02 COLLECT_01 COLLECT_00 WATER_BULLET FIRE FLAMING_BULLET SHOT GREEN_PHONE_RINGING GREEN_PHONE YELLOW_PHONE_RINGING YELLOW_PHONE RED_PHONE_RINGING RED_PHONE BRIEFCASE PHONE_DEAD PHONE_RINGING PHONE MOVING_BIN_LID MOVING_BIN MOVING_CONE DEAD_RUBBISH ANIMATING_RUBBISH ANTENNA TANKTOP HUGE_GREY_SKID HUGE_BROWN_SKID HUGE_WHITE_SKID HUGE_RED_SKID MOLOTOV_MOVING BUSY_CAR_SHOP CAR_SHOP BUS_STOP_MARKER ROCKET SMALL_WHITE_SKID MEDIUM_WHITE_SKID BIG_WHITE_SKID CAR_STOP CAR_CROSSING MEDIUM_RED_SKID MEDIUM_GREY_SKID MEDIUM_BROWN_SKID SMALL_RED_SKID SMALL_GREY_SKID SMALL_BROWN_SKID FIREJET PARTICLE_SYSTEM BLOOD_SPARK SMALL_ARROW EXPLODE_MEDIUM TOWER PACKAGE BENCH ROADBLOCK HYDRANT_UNLID HYDRANT HYDRANT_LID TYRE OILDRUM NEWSDIS HARDBOX FOOTY CRATE BUSH MINE OIL ANIMATING_OIL BIN RUBBISH BLASTER BOXES CONE BOLLARD BIN_LID INVISIBLE_DESTRUCTIBLE is solid until you blow it up