


BW's Vice Mission Builder test version v0.12
--------------------------------------------

Changes since v0.11:
- New format, compiler is now more than 3 times faster
  than any earlier mission builders.


Changes since v0.1:
- Now compatible with the PC version (and still compatible with
  the PS2 version).
- Added two new opcodes (used in the PC version only).



Test version 0.12 info
----------------------

The new format in this version is not compatible with any earlier
versions.

Please note that this version is an untested test version. It has
not been tested on the PS2 version or the PC version of GTA Vice.

You can decompile and recompile the Vice mission script. Dunno
if it works with the game or not.

This readme file is based on the readme file of the mission builders
from gta 3. This file needs some more work. I will change it later.

The F1 key feature doesn't work with this version. The files
'opcodes.txt', the ID list files and the 'stripped.txt' file
is not included in this version.

The 32-bit single-precision data used with Floating-Point numbers
in the builder is still inaccurate.




Installation
------------
Unzip to anywhere. Run 'ViceBuilder011.exe'. The first time
you run the program, you must specify where you installed Gta Vice.

NOTE! If you get an arrow with that hour-glass, you can still
use the arrow to set up the mission builder.

NOTE! If you don't have the PC version of Vice, copy the
'default.ide' and 'american.gxt' file from your Vice version
PS2 DVD to where 'ViceBuilder01.exe' is. You can not start
GTA VICE from the builder if you do this. The 'Compile % copy'
and the 'Compile, copy % Run' feature will be disabled if you
do this.




Starting the mission builder
----------------------------
Run 'ViceBuilder011.exe'.




Files in the distributed ZIP package
------------------------------------
Since this mission builder is based on others work and
since those other people made some rules about what their
work could be used for, I included some information about
that in the STUFF folder. You should read through these
files since some of them have some useful information
about using the text editor.







Menues, buttons and the rest of the IDE
---------------------------------------

The menues and buttons should to some extent explain
themselves. The button that looks like 'open multiple files'
does something completely different - it disables custom
IDs when decompiling.

Press F1 to find opcodes and parameters for commands.

Example, if you write:

   end_thread


and press the F1 key, the line changes to:

   004E: end_thread()


This feature is pretty complex. It is based on 3 different
files that are loaded when the mission builder loads. It
searches for word matches. You can combine words by putting
and underscore between them. The above example searches for
the exact match "end thread" (or "end_thread") only. If you
just write:

   thread


and press the F1 key, every time you press F1, you get another
match. When you press F1 on lines that doesn't have any
underscores at all, the result doesn't include any either.
With "thread", you get one of these:

   00D7: create thread with wasted busted check(Label011C74)
   004F: create thread Label0091D0
   004E: end thread()
   03A4: name thread("MAIN")


Another example, you want to know what opcodes are used with
"create_actor". Every time you press F1, the line toggles
between these commands:

   0129: create_actor( 4?, 29?, $busted_help_cop_1) in_car_driverseat($busted_help_policecar_1)
   01C8: create_actor( 4?, 29?,  0?, $luigi4_pimp) as_car($luigi4_pimp_car)_passenger
   009A: create_actor($char_gunshopowner,  21?, 29?) at( 1070.75!, -396.938!,  14.1875!)








Learning stuff
--------------

To load a text file or a .scm file, use the file menu or press
the 'open file' icon. If you load a .scm file, this happends:
- The file will be decompiled. The window title shows the progress.
- A file with the extention .TXT will be created. If you load the
  original main.scm file, a file called main.scm.txt will be created.
  If you load a file called something.scm, a file called
  something.scm.txt will be created.
- The file being created will be loaded into the mission builder as
  a text file.

If you load any file other than a .scm file, this happends:
- The file gets loaded as a text file into the mission builder.

If you activate the RUN menu and select compile or just press the
compile icon, this happends:
- The selected text file loaded into the mission builder editor gets
  compiled into a .scm (mission script) file.
- If the name of the text file is something.scm.txt, a mission script
  file called something.scm will be generated. If the name of the
  selected text file is something.txt, a mission script file called
  something.txt.scm will be generated.



This is an example of a "line" inside the editor.

03CB: set_camera( 807!, -937!,  36.5625! )
  |          |                     |   | 
  |          |                     |   |_ *4
  |          |                     |      
  |          |                     |_____ *3
  |          |                           
  |          |___________________________ *2
  |                                     
  |______________________________________ *1  




*1  This is one of the opcodes.

*2  This is the command string. This part is ignored by this
    version of this mission builder (and any future versions).

*3  This is a number.

*4  This part is VERY IMPORTANT. It identifies the data type
    of the number.



DATA TYPES (you MUST learn and understand this part)
----------------------------------------------------
Data types are used to identify numbers. They exists because BIG numbers require
more storage space than SMALL numbers. This mission builder uses 8 different
data types to identify the numbers. Strings that appear in the mission scripts are
enclosed in " ". Any jump instruction (gosub, jump, jump_if_false, create_thread
call and such) use labels. Labels are defined with a colon in the beginning
of a line and referenced using  signs. LOCAL jumps (that is all jumps from
one label to another inside a mission) use one    before the label. GLOBAL
jumps (that is, jumps from the MAIN part of the code to any missions, jumps
from labels in MAIN to other labels in MAIN and jumps from missions to MAIN)
use    (two of them).


DATA TYPE           MEANING
   ?                Stores 8-bit numbers. You can enter any value from
                    -128 to 127.


   ??               Stores unsigned 16-bit numbers. You can enter any value
                    from 0 to 65535. The values used must be divideable by 4.
                    These numbers represent locations in memory and is used
                    to store data at these locations. With the mission
                    builder version 4.0 and later (because of its automatic
                    memory management), you don't need to use this data type
                    when adding new commands, just use any named constants instead.
                    This data type is used with ID's.


   &                Stores signed 16-bit numbers (INTEGER/Boolean/smallint/whatever).
                    You can enter any value from -32768 to 32767. The value
                    will be converted to signed.


   &&               Stores signed 32-bit numbers (LONG INTEGER/whatever)
                    and other 32-bit data.


   !                Stores 32-bit IPL co-ordinates and other data in standard
                    single-precision form. This will probably change in later
                    versions to a different format because Rockstar might have
                    used a different format.


   @                Stores special 16-bit numbers used with internal timers or
                    internal parameter passing in GTA.











CONSTANTS (or named identifiers) (or custom identifiers) (or whatever)
----------------------------------------------------------------------
Constants (or named identifiers) defined in the scm.ini have a
  $  (dollar sign) preceding the constant.
Constants are stored as 16-bit numbers in the mission script.
Constants can be replaced with unsigned 16-bit numbers. Use ?? as
data type. 

You can define IDs (identifiers) by creating a line like this:

  DEFINE ID $<Name of identifier> AS <number>

This instruction can override existing identifiers
in the scm.ini file. It can also override existing identifiers
defined by using  DEFINE ID $<Name of identifier> AS <number>.

Use this command to reserve memory at any given address and
to give that reserved memory address a name.

Please note that only the numbers can be overridden. If you
use the same name multiple times, you get a compile error. In this
example, test2 overrides test1:
  DEFINE ID $test1 AS 123
  DEFINE ID $test2 AS 123

This example gives a compile error:
  DEFINE ID $test1 AS 123
  DEFINE ID $test1 AS 234

Please note:
* Lines like these should precede any other lines.
* Do not include any data type identifier in <number>.
* <number> always use  ??  as data type internally.
* Compiled .scm files do not contain any named identifiers.






The automatic memory management system
--------------------------------------
The automatic memory management system was introduced with
the mission builder version 4.0. With this system, you get
3 different ways of accessing the mission script memory:
1. You can use the data type  ??  to access the memory directly.
2. You can use the command
     DEFINE ID $<Name of identifier> AS <number>
   to define a constant at any memory address.
3. You can simply just use  $<Name of identifier>  without the
   'DEFINE ID' command to let the compiler find a free memory
   address on its own.







CAR, ACTOR, MODEL, OBJECT AND WEAPON IDENTIFIERS
------------------------------------------------
Cars, actors, models, objects and weapons can be added or
changed using numbers or names as defined in the 'default.ide' file.

Examples: #KURUMA, #GANG03, #CUTOBJ01, #BAT, #COLT45, #UZI

Objects defined in the "second segment" of the mission script file
still use numbers with the name of the object inclosed in
parenthesis.






CONDITIONAL COMMAND STRINGS (getting complicated)
-------------------------------------------------
Conditional command strings are command strings that change depended on the
value of the conditional variable contained within the condition.   :-)

An example of a conditional command string:

  toggle_widescreen_::off0?::
  toggle_widescreen_::on1?::

The conditional variable in the two line above is the 0? and the 1?.
0 means FALSE, 1 means TRUE. Any values other than 0 returnes TRUE
and sets this conditional command string to toggle_widescreen_::on<variable>?::.

All conditional command strings can be recognized by their colon pairs.

NOTE: The compiler ignores the text. It reads the numbers (0? or 1? above)
when the file is compiled. This means this line (and other lines)
doesn't need the text, just the opcode and numbers with their data types.

If you want it to look better, you can use any text you want, like this:
  toggle_widescreen_off  0?
  toggle_widescreen_on  1?

or like this:
  toggle_widescreen 0?
  toggle_widescreen 1?

just don't forget that opcode   8-)





Stuff
------------------------------------------------------
Sometimes names of objects is enclosed inside parenthesis.
The number preceding it identifies that object. If you want
to change any of these objects, you must change their numbers.

(Please) Note that when a name of a object appear inside parenthesis,
the number that reference that object does not always reference
an object at all. The name of the object is just a suggestion
that usually is 100% correct.

You should NEVER EVER remove lines with the  DEFINE OBJECT  command
because you must then change ALL the commands in the mission script
that access these objects by their numbers.







IF YOU THINK IT LOOKS UGLY, YOU CAN CHANGE IT
---------------------------------------------
All the commands in my mission builders can be changed.
Just change the 'scm.ini' file. Don't blame me if you
mess it up. Create a backup first.








RULES THAT MUST BE FOLLOWED WHEN CODING
---------------------------------------

Definitions: 
- 'MAIN part of the code' means the code between the line reading
  ';---MAIN---' and the line reading ';---MISSION 0----'.
- 'MISSION part of the code' mean everything following the line
  ';---MISSION 0----'.


Lines with mission code must start with a 4 letter opcode.
There must be a colon after the opcode. Example:
        01C7: spawn_object( 204??)

If you change that into:
        1C7: spawn_object( 204??)

it will not compile. There is a very good reasons for this rule.
SPEED. Without an opcode, the builder would need to find the 
opcode based on the text. Longer compile times and possible
"missunderstandings" do to a badly programmed AI could be the result.

Some types of lines doesn't include direct mission code. There are a
total of 4 different types of lines used. Lines that begins with a
colon are labels. Lines that begins with DEFINE are used to name
identifiers and to set up the first, second and third segments.
Lines that begins with a semicolon are used for remarks. Examples of
lines with labels:

  :Label0123
  :MyLabel
  :anytext

As you can see, labels can contain anything. What they contain is
not important. NEW: Labels should only contain text and numbers.

Examples of lines that remarks something:

  ;Hi there, I'm a waterduck.
  ;
  ;----Mission 23---------
  ; Originally: Luigi mission 5 'THE FUZZ BALL'

Examples of lines with remarks in them:

  DEFINE MEMORY  17245   \\ this is a remark
  DEFINE OBJECT PLAYERSDOOR   \\ Object number -1  (this is also a remark)



In this mission builder, the user is responsible for
setting up the first, second and third segments correctly.
If you decompile a mission script, you never need to do
this yourself. If you want to start a mission script from
scratch, do this:

1. Create a new text file.

2. On the top line, put:
     DEFINE VERSION 3.1  (or DEFINE VERSION 3.0)
   without it, it can't compile.

3. Start the code with a jump code like:
     0002: jump(SecondSegment)

3. Put
     DEFINE MEMORY  17245
   after that. The  DEFINE MEMORY  command is used to set up
   the amount of memory to allocate for the mission script.
   You have now defined the first segment.

4. Put a label at the start of the second segment, like this:
     :SecondSegment

   The start of the second segment is now at the 4th line of your
   text file.

5. Put another jump instruction in there, like:
     0002: jump(ThirdSegment)

6. Now, set up the second segment using DEFINE OBJECTS and the number
   of objects to define after that, like:
     DEFINE OBJECTS  186

7. To complete the second segment, use DEFINE OBJECT with the names
   of ALL the objects needed after that, like:
     DEFINE OBJECT (no name)
     DEFINE OBJECT PLAYERSDOOR
     DEFINE OBJECT FAKETARGET
     (and all the rest of them. Note that the first object is unused.
     In dans mission editor, the name and version of the dans editor
     is placed there.)

8. Put another label at the beginning of the third segment, like:
     :ThirdSegment

9. Define the entry of the MAIN part of the code by using a jump
   instruction here (at the start of the third segment), like:
     0002: jump(Main)

10. The total number of mission pointers goes next. Use DEFINE MISSIONS
    and the number of missions, like:
      DEFINE MISSIONS  80

11. After that, set up labels for each missions by using DEFINE MISSION
    <zero-based number of mission> AT <label> like this:

    DEFINE MISSION 0 AT SomeNewMajorIntro
    DEFINE MISSION 1 AT ANewMissionOrSomeThing

    (and the rest of them)

12. Now, set up the MAIN part of the code. This is a pretty complex
    and big thing. See the original file (the text file you created)
    for clues.





Rules for programming the MAIN part of the code
-----------------------------------------------
- Use GLOBAL addressing. By putting two pound symbols in pairs
  in front of a label you get GLOBAL addressing. Examples of
  GLOBAL addressing:
  - 0002: jump(Label004364)
  - 0050: gosub(Label015239)
  - 02CD: call(Label00FEAD, Label00FEAD)
  - 004F: create_thread_Label0091D0
  - 00D7: create_thread_with_wasted_busted_check(Label011C74)
  - 004D: ) jump_if_false(Label008E07)




Rules for programming the MISSION part of the code
--------------------------------------------------
- Use LOCAL addressing. By putting a single pound symbol in 
  front of a label you get LOCAL addressing. Examples of
  LOCAL addressing:
  - 0002: jump(Label01A9E7)
  - 0050: gosub(Label01CBEA)
  - 004D: ) jump_if_false(Label01AA16)
- The commands 'call', 'create_thread' and
  'create_thread_with_wasted_busted_check' are NEVER used with
  LOCAL addressing in the original mission script. They can all
  be used in the MISSION part of the code if GLOBAL addressing
  is used. When they are used in the MISSION part of the code,
  they MUST point to code in the MAIN part of the mission script.





OLD rules that MUST be followed when modding
--------------------------------------------
There can be NO SPACES between numbers and their corresponding data type identifiers
(meaning this
   1?, 2?, 3?
works, this
   1 ?, 2 ?, 3   ?
does not work).





The STRIPPED.TXT file (not included in the test versions)
---------------------------------------------------------
The  stripped.txt  file is a stripped version of the original main.scm file
decompiled into a text file.

I stripped out all the missions including taxi driver, vigilante, firefighter
paramedic and all the offroad missions. Since the MAIN part controls most stuff
in the game, this is what's left:
- code that controls when gates open and close.
- code that controls when hookers enter the players car.
- code that checks if the player is doing stunts outside unique stunt bonus areas.
- code that checks if the player is doing a unique stunt.
- code that checks if the player is inside ammu-nation shops.
- locations of hidden packages, weapons, kill frenzies/rampages, health, armor,
  some cars, boats and planes. Most parked vehicles has been removed.
- code that controls bonuses when the player has done this or that or found stuff.
- code that controls camera angles when the player is in certain areas.
- code that controls when the player can save his game.
- code for mission script objects like doors on buildings.





The OPCODES.TXT file (not included in the test versions)
--------------------------------------------------------
The OPCODES.TXT file has all the opcodes used in the mission script. It is in
alphabetical order. Load it up in the IDE in a separate window as a TXT file.







Simple mission coding
---------------------

  Coding with conditional checking, 'IF commands'
  -----------------------------------------------

  Example:

  00D6: if( 1?,
  0038:   ($ONMISSION ==  1?)
  0038:   ($BUSTED_PICKUP_MADE_FLAG ==  1?)
  004D: ) jump_if_false(Label008FCA)

  There are TWO conditional checks in this code. The first
  conditional check checks if the player is currently on a mission.
  The second conditional check checks if the $BUSTED_PICKUP_MADE_FLAG
  variable is equal to 1. 

  The first line defines the NUMBER OF CONDITIONS to include in the
  conditional check and if the checking is to be done in an INCLUSIVE
  or EXCLUSIVE manner.

  The example code uses INCLUSIVE checking. With INCLUSIVE checking,
  the number in the first line is equal to the number of lines with
  conditional checks MINUS 1. The BASIC programming language uses
  the operand 'AND' for INCLUSIVE conditional checking.

  With EXCLUSIVE checking, the number in the first line is equal to
  the number of lines with conditional checks PLUSS 19. The BASIC
  programming language uses the operand 'OR' for EXCLUSIVE conditional
  checking.

  This is the BASIC equivalent to the example code above:

  IF $ONMISSION=1 AND $BUSTED_PICKUP_MADE_FLAG = 1 THEN

  With EXCLUSIVE checking the code looks like this:

  00D6: if( 21?,
  0038:   ($ONMISSION ==  1?)
  0038:   ($BUSTED_PICKUP_MADE_FLAG ==  1?)
  004D: ) jump_if_false(Label008FCA)

  Two conditional checks + 19 for EXCLUSIVE checking = 21 in the first line.

  This is the BASIC equivalent to the example code with EXCLUSIVE
  checking:

  IF $ONMISSION=1 OR $BUSTED_PICKUP_MADE_FLAG = 1 THEN

  When all the conditional checks are checked, the result of all the
  checks is controlled by the '004D: ) jump_if_false' opcode and
  command. If the result is FALSE, the code "jumps" to the label
  in the command. If the result is TRUE, the code following the
  '004D: ) jump_if_false' opcode and command is executed.

  You must remember to follow the rules for GLOBAL and LOCAL
  addressing when coding. When coding in the MAIN part of the code,
  use GLOBAL addressing with the label in the '004D: ) jump_if_false'
  command. The code in the examples uses GLOBAL addressing. This means
  this code must be placed in the MAIN part of the mission script.

  This is the same code using LOCAL addressing. This code must be
  placed in the MISSION part of the mission script:

  00D6: if( 21?,
  0038:   ($ONMISSION ==  1?)
  0038:   ($BUSTED_PICKUP_MADE_FLAG ==  1?)
  004D: ) jump_if_false(Label008FCA)




  Coding a simple mission with the 'stripped.txt' file
  ---------------------------------------------------- 

  First, follow these steps:
  - Start up the mission builder.
  - Load the file 'stripped.txt' into the mission builder.
  - Press <Ctrl> + F to use the 'Find Text' dialog box.
  - Search for the text  ;---
  - Press F3 to repeat the search until you get the text
    ;-------------Mission 0---------------
  - About 26 lines below that is some code for loading
    a cheetah into the game. It should look something like:

    0247: request_model(#CHEETAH)
    :check1
    00D6: if( 0?,
    8248:   NOT   model(#CHEETAH).available
    004D: ) jump_if_false(check1ok)
    0001: wait( 0? ms)
    0002: jump(check1)

    :check1ok
    00A5: create_car(#CHEETAH, $eight_car) at( 812!, -945.5!,  35.75!)
    0249: release_model(#CHEETAH)
  
  Lets take a look at this code :-)

  The '0247: request_model(#CHEETAH)' command tells the game that we want
  to create a cheetah car. Before a car, actor or object is created, it
  must be loaded or requested. This code requests the model for the cheetah.
  The model for the cheetah is now loaded in a "low priority" manner. You
  can think of this like a way of loading something "in the background" of
  the game. The model isn't loaded until the game "finds the right time" to
  load it.

  Since the model of the cheetah must be loaded before we can create the
  cheetah car, we must check if the model has been loaded before we can
  create the cheetah car. This is done with this code:

    :check1
    00D6: if( 0?,
    8248:   NOT   model(#CHEETAH).available
    004D: ) jump_if_false(check1ok)
    0001: wait( 0? ms)
    0002: jump(check1)

    :check1ok

  The conditional command '8248:   NOT   model(#CHEETAH).available' returns
  FALSE if the model of the CHEETAH is loaded. The command
  '004D: ) jump_if_false(check1ok)' "jumps" to label 'check1ok' if the
  command '8248:   NOT   model(#CHEETAH).available' returns FALSE. This
  means that the code waits until the model of the cheetah is available
  before the code following the label 'check1ok' is executed.

  This code creates the cheetah car:

    00A5: create_car(#CHEETAH, $eight_car) at( 812!, -945.5!,  35.75!)

  A handle to the car is now stored in the '$eight_car' variable. This
  handle can be used with any commands that require a handle to a car.
  The 'at( 812!, -945.5!,  35.75!)' part of the command defines where in
  the gaming world the cheetah car will be created. The best way (in my
  opinion) is to use the ADMIN CONSOLE to get coordinates of cars in the
  game.

  When the cheetah car is created, we no longer need the "model" for it,
  so the "memory" for the "model" can be freed up. We do that using the
  '0249: release_model(#CHEETAH)' command.




  Setting up a new mission in the 'stripped.txt' file
  ---------------------------------------------------

  To set up a new mission in the 'stripped.txt' file,
  copy this code and change everything enclosed in < > .

    ;-------------Mission <mission number>---------------
    :Mission<mission number>  
    0050: gosub( <label where the mission code starts> )
    00D6: if( 0?,
    0112:  wasted_or_busted()
    004D: ) jump_if_false( <label for skipping the mission failure code> )
    0050: gosub( <label for mission failure code. Executed if player dies or gets arrested during the mission> )
 
    :<label for skipping the mission failure code>
    0050: gosub( <label for the mission cleanup code> )
    004E: end_thread()
 
    :<label where the mission code starts>
    0317: increment_mission_attempts()
    03A4: name_thread("<thread name>")
    0004: $onmission =  1?
    0110: player($PLAYER_CHAR).wanted_level = 0

    :<Label for mission loop>
    0001: wait( 0? ms)
    0002: jump( <Label for mission loop> )

    :<label for mission failure code. Executed if player dies or gets arrested during the mission>
    00BA: text_styled("M_FAIL",  4000&ms,  1?) \\ MISSION FAILED!
    0051: return()

    :<label for the mission cleanup code>
    0004: $ONMISSION =  0?
    00D8: mission_cleanup()
    0051: return()


  When you have done that, change this line 'DEFINE MISSIONS <number of missions>'
  and add this line 'DEFINE MISSION <mission number> AT Mission<mission number>'.
  Adding code in the MAIN part of the code for starting the new mission is also
  a good idea :-)


  Learning more
  -------------

  To learn more about simple mission coding, decompile the original mission
  script and start reading  :-)

  You can also download sample missions and source code from

    http://www.gtaforums.com
    http://www.codenamenetwork.com/wingding42
    http://home.c2i.net/barton49
    http://home.no.net/barton57





Advanced mission coding
-----------------------

  Multi-Task programming
  ----------------------

  You can create missions to run in a single- or multi-task manner.
  To make a mission run in multiple tasks, use the 'create_thread'
  or the 'create_thread_with_wasted_busted_check' command.

  Example:
     004F: create_thread_Snipers        \\ Simulated snipers

  This command can be put in the MAIN part of the code or in the MISSION
  part of the code.




  Rules for Multi-task programming
  --------------------------------

  Unless proven otherways, these are the rules:

  - NEVER use the 'create_thread' command unless you actually want your
    missions to run multiple mission codes simultaniously.

  - When using 'create_thread <label>' the label and the code following
    it must in the MAIN part of the code. See 'Rules for programming
    the MAIN part of the code' for more information.

  - The 'create_thread' command can be issued from both the MAIN part of
    the code and the MISSION part of the code.

  - In the original script, most of the threads started with the
    'create_thread' command runs in a 'low-priority' manner. Use
    the 'wait' command to set the priority of a thread.

    Example:
        0001: wait($wait_time ms)

    When using '0001: wait($wait_time ms)', the priority is set with
    a "wait-state" of 250 milliseconds.

  - It might be possible to "overload" the mission script by running
    a certain number of high priority threads simultaniously. If it is
    possible, it might hurt the frame-rate or the time it takes to
    load the scenery, resulting in the famous "temporary missing texture
    loss" thing.





LINKS
-----

The Grand Theft Auto, Grand Theft Auto II , Grand Theft Auto III and
Grand Theft Auto: Vice City forums - GTAForums:
  http://www.gtaforums.com


My files:
  http://www.codenamenetwork.com/wingding42
  http://home.c2i.net/barton49
  http://home.no.net/barton57




