0050

From GTAMods Wiki
Revision as of 17:15, 20 December 2016 by Spaceeinstein (talk | contribs) (more practical example)
Jump to navigation Jump to search

GTA III Vice City San Andreas GOSUB


Description
Gosub
Syntax
0050: gosub [label]
gosub [label]
Parameter
[label]
The position in the script it will go to, usually identified by a label

This opcode allows the code to jump to a line anywhere in the script. Between that line and a RETURN (0051), this section acts like a simple subroutine. The subroutine is independent of the script that the GOSUB is located. When the code reaches a RETURN, it will jump back to where the GOSUB is located and continues from there. GOSUBs can help dramatically simply repetitive code, and can help make the code cleaner and easier to read for the user. GOSUBs can be nested within GOSUBs (like a Matryoshka doll) but there is a limit of up to 6 nested in each other. Nesting more will crash the game. GOSUBs are also important to the structure of missions.

Example

The following example using Sanny Builder spawns five SWAT members to kill the player at the Washington Mall in Vice City after pressing button 13 (CAMERA key).

const
TEMP_VAR = 0@
SWAT_1 = 1@
SWAT_2 = 2@
SWAT_3 = 3@
SWAT_4 = 4@
SWAT_5 = 5@
HAS_BEEN_SPAWNED = 6@
end

var
TEMP_VAR : integer
SWAT_1 : integer
SWAT_2 : integer
SWAT_3 : integer
SWAT_4 : integer
SWAT_5 : integer
end

HAS_BEEN_SPAWNED = false
while true
    wait 10
    if
        00E1:   player 0 pressed_button 13
    then
        while 00E1:   player 0 pressed_button 13
            wait 0
        end
        if
            HAS_BEEN_SPAWNED == true
        then
            009B: destroy_actor_instantly SWAT_1
            009B: destroy_actor_instantly SWAT_2
            009B: destroy_actor_instantly SWAT_3
            009B: destroy_actor_instantly SWAT_4
            009B: destroy_actor_instantly SWAT_5
            01C2: mark_actor_as_no_longer_needed SWAT_1
            01C2: mark_actor_as_no_longer_needed SWAT_2
            01C2: mark_actor_as_no_longer_needed SWAT_3
            01C2: mark_actor_as_no_longer_needed SWAT_4
            01C2: mark_actor_as_no_longer_needed SWAT_5
        end
        HAS_BEEN_SPAWNED = true
        0247: request_model #COLT45
        0247: request_model #SWAT
        038B: load_requested_models
        009A: SWAT_1 = create_actor_pedtype 4 model #SWAT at 18.9999 -928.7729 15.0727
        TEMP_VAR = SWAT_1
        gosub @KILL_PLAYER
        009A: SWAT_2 = create_actor_pedtype 4 model #SWAT at -15.6727 -929.0634 15.066
        TEMP_VAR = SWAT_2
        gosub @KILL_PLAYER
        009A: SWAT_3 = create_actor_pedtype 4 model #SWAT at -10.2667 -937.9695 9.4077
        TEMP_VAR = SWAT_3
        gosub @KILL_PLAYER
        009A: SWAT_4 = create_actor_pedtype 4 model #SWAT at -9.9934 -939.7717 9.4492
        TEMP_VAR = SWAT_4
        gosub @KILL_PLAYER
        009A: SWAT_5 = create_actor_pedtype 4 model #SWAT at -15.225 -949.0593 15.072
        TEMP_VAR = SWAT_5
        gosub @KILL_PLAYER
        0249: release_model #COLT45
        0249: release_model #SWAT
    end
end

:KILL_PLAYER
0291: set_actor TEMP_VAR heed_threats 1
0243: set_actor TEMP_VAR ped_stats_to 16
011A: set_actor TEMP_VAR search_threat 1
01B2: give_actor TEMP_VAR weapon 17 ammo 999
01CA: actor TEMP_VAR kill_player $PLAYER_CHAR
return

Tricks

There are tricks one can use with GOSUB that Rockstar had never employed in their scripts.

Array

See also VC Arrays

The following example functions similarly to the example code above. As you can see it is more complicated but its extensibility allows for large arrays with fewer lines of code.

// set constants
const
PLAYER_CAR = 0@
COLOR_LABEL = 1@
CAR_MODEL = 2@
COLOR_ARRAY_ITEM_SIZE = 3@
end
 
COLOR_LABEL = @SET_COLOR_ARRAY  // gets the position of SET_COLOR_ARRAY
CAR_MODEL = #LINERUN  // initializes here so that this example works for III/VC/SA
COLOR_ARRAY_ITEM_SIZE = @SET_COLOR_ARRAY
COLOR_ARRAY_ITEM_SIZE *= -1
COLOR_ARRAY_ITEM_SIZE += @SET_COLOR_ITEM // holds correct offset for the next array item
while true
    wait 10
    if
        CAR_MODEL > #SENTINEL // reached past upper limit
    then
        COLOR_LABEL = @SET_COLOR_ARRAY  // reset position of label to beginning
        CAR_MODEL = #LINERUN  // reset car model to beginning
    end
    if
        00DD:   actor $PLAYER_ACTOR driving_vehicle_type CAR_MODEL
    then
        03C0: PLAYER_CAR = actor $PLAYER_ACTOR car
        gosub COLOR_LABEL  // gosub to set color
    end
    
    005A: COLOR_LABEL += COLOR_ARRAY_ITEM_SIZE
    CAR_MODEL += 1  // increment car model ide number
end
 
:SET_COLOR_ARRAY
0229: set_car PLAYER_CAR color_to 0 1
return
:SET_COLOR_ITEM
0229: set_car PLAYER_CAR color_to 10 11
return                            
0229: set_car PLAYER_CAR color_to 20 21
return

Keywords

jump, goto, gosub, subroutine, label