Quantcast

Jump to content

» «
Photo

[SA] ~ CLEO Script Tutorial ~

926 replies to this topic
ZAZ
  • ZAZ

    Kernlochbohrer

  • Feroci
  • Joined: 10 Jan 2005
  • European-Union
  • Contribution Award [Mods]
    Helpfulness Awards [Mods]

#1

Posted 20 March 2009 - 10:17 PM Edited by ZAZ, 30 August 2012 - 06:35 PM.

CLEO Script Tutorial
english language

CLEO Script Tutorial deutschsprachig



INDEX
Chapterlesson
First Steps in Cleo scripting
with Sannybuilder
- Start for newbies
The Editor- The main functions
- Option: different view of the decompiled code
- Classes and Keywords
Data types- locals @, globals $, "strings '
and hash # to enter modelname
Scripting/Writing a Thread

coding in praxis,
a must-read for newbies
- Using conditional checks
- The IF - Variation
- Script structure simple
- Script structure extended
- Script exemble: Slowmotion

- Spawn a 3D model
- Placing cars by using parked_car_generator
Special Particularities in Cleo- enable_thread_saving
- special cleo global var

- Script Exemble by using Special Global Cleo Variable/ Store a car at any place
- Template for Cleo Mission Script
gosub ... to read a subscript- basic knowledge to understand mission scripts



Chapterlesson
Additional Themes

the lessons are in one post
- Create a FXT file
- Load a special actor
- Tuning parts
- Animations
- sounds of Audio folder
Math coding

the lessons are in one post
- give access with math coding
- Access check with local variables
- Declare or not declare (first reason)
- Time check for milliseconds in real time
- Time check for game hours
- Integer values and floating points
- Declare or not declare (second reason)
- Integer to float and reversed
- Show the calculated values with text_draw opcode
- Math calculations
Save script- simple save script example
Arrays- advanced method to unify same functions of more instances in one process
Memory Coding

the lessons are in one post
-cheat codes
- Gravity
- ASCII Table
- related links to car struct, actor struct, object struct
Advanced Memory Access to learn the basics
Changing Car Handling
call_scm_function- for advanced
Catch random actor- get_actor_in_sphere
- RandomActor_for_to_step_method
KEY_PRESS- external topic about key_press
Car Drive Tutorial

the lessons are in one post
- car drive_to
- drive-to commands
- Let the driver do corrections
- Let the driver drive
- Define a scmpath for the driver
- Car drive scripts in praxis
Carrec Paths- Record a path with Seemanns carrec.cs
- assign_car to_path
Particle Effects- show particle effects of effects.fxp
Special opcodes to show particles- sparks, gunflash, blood, corona, shadow, smoke
LIGHT and shadow- the light in gta
- Flash_Light_Illumination
- create_searchlight
- shadow
Object - COLLISION - check

the lessons are in one post
- object.dat definitions
- beachball and bball_col
- throw object
- Missilescript
MENUE-interactive- create_panel
JumpTable- 0871: init_jump_table
Teleport- Sphere (red marker)
- Location Check
Teleport into interior- Interior Entrance
related links
gtamodding.com: List_of_opcodes
GTA:SA Opcodes, Discussion thread
PLPyntons_UnifiedOpcodes
opcode descriptions by PLPynton in sascm.ini format
(be careful, some opcodes are nevermore compatible
because of changed parameter order)
my opcodes.txt
Dejis Opcode Database

______________________________________________________________________________________
______________________________________________________________________________________



First Steps in Cleo scripting with Sannybuilder

Download newest version of Sannybuilder from Seeman at http://sannybuilder.com/


Install Sannybuilder and create a folder for your scripts
Therefor youre promt to indicate your GTASA-Install dir.

Then start Sannybuilder,
Open a new blank page, copy the script below and insert it into the new page.

CODE
{$CLEO .cs}
:DEMOTEXT
03A4: name_thread "DEMO"
wait 1000

:DEMOTEXT_1
wait 0
if
0256:   player $PLAYER_CHAR defined
004D: jump_if_false @DEMOTEXT_1
if
00E1:   key_pressed  0  17
004D: jump_if_false @DEMOTEXT_1
00BA: text_styled 'FEM_OK'  1000 ms  1
0A93: end_custom_thread


Save it in your Sannyscript folder and give it a name.
user posted image

Compile the script. Click on menue icon with "running man" to choose compile + copy
If the CLEO - Library is installed, the script will be compiled and copied in to GTASA\CLEO - folder

The Cleo script file get then the file extension, which is written in the Cleo Script directive at the beginning of the script

{$CLEO .cs} = Cleo directive will be compiled to *.cs
As DEMOTEXT.txt saved and compiled as DEMOTEXT.cs

______________________________________________________________________________________

If CLEO is not installed, then sannybuilder will prompt you to do it and at the lower right corner of the editor
appears the CLEO - box with a red border. Click on it and Sannybuilder installs Cleo immediately.
Or download the cleo auto install exe at http://cleo.sannybuilder.com
______________________________________________________________________________________

If the compiling process was successful you get then a report message
user posted image
click on OK to confirm
the lower value "Largest Script" shows the script file size
the other values belongs to a compiling process of a main.scm

Test then the script ingame, press fire button to display the text message "OK"
The script ends then, will be deactivated because it ends with opcode 0A93: end_custom_thread

______________________________________________________________________________________
______________________________________________________________________________________



The Editor

The main functions can be found as icon button in the menue bar

1. Decompile: sanny opens script files with extensions .CS, .CM or .SCM

2. Compile: sanny compiles by default to a [Name]main.SCM

Sanny compiles automaticly to Cleoscript files, if the script have a Cleo-Direktive as entry

{$CLEO .cs} = Cleo-Direktive, will be compiled to Name.CS
{$CLEO .cm} = Cleo-Direktive, will be compiled to Name.CM

user posted image



Useful tools

Choose TOOLS on menue, then IDE Tools >> Coords Manager
to read the x,y,z coordinate and the z-angle of the current player position if the game is running

Choose TOOLS on menue, then IDE Tools >> Opcode Search
to search for opcodes
type any keyword to find a codeline which include this word
or type an opcode to find the description
the foundings are allways existing lines of original main.scm
The opcode search tool requires to create the opcode.txt in Sanny Builder 3\data\sa folder
Load the decompiled original main into sannybuilder then choose TOOLS on sanny menue, then: make opcodes.txt

user posted image


Line numbers
Choose TOOLS, then options
in option menu EDITOR you can find the feature to switch Line numbers off/on
The line number is part of the editor, not of the script


The Sannybuilder HELP

Choose HELP on menue, then Content to find informations,
such like key_press numbers, weapon numbers, bodyparts etc..

user posted image

______________________________________________________________________________________
______________________________________________________________________________________



Option: different view of the decompiled code

Choose TOOLS, then options
in option menu GENERAL you can find the feature to switch between 2 ways for decompiling

either decompile by writing opcodes
or decompiling without opcodes

user posted image


1. Writing Opcodes
All entries are shown with their opcodes
The opcodes are the real programm codes of the script functions
and by showing them is like to see the name of the command
Script with opcodes:
CODE
:CARSL_6439
00D6: if
00E1:   player 0 pressed_key 16
004D: jump_if_false @CARSL_6535
010B: [email protected] = player $PLAYER_CHAR money
00D6: if
002D:   [email protected] >= [email protected] // (int)
004D: jump_if_false @CARSL_6512
0012: [email protected] *= -1
0109: player $PLAYER_CHAR money += [email protected]  
0002: jump @CARSL_6700


2. Without Opcodes
The script is more slim, maybe more clear (but not for me)
especially 004D: jump_if_false will be now jf
But not all opcodes are disappeared. Many codes must be used furthermore by applying their opcodes.
Script without opcodes:
CODE
:CARSL_6439
if
00E1:   player 0 pressed_key 16
jf @CARSL_6535
[email protected] = Player.Money($PLAYER_CHAR)
if
002D:   [email protected] >= [email protected] // (int)
jf @CARSL_6512
[email protected] *= -1
Player.Money($PLAYER_CHAR) += [email protected]
jump @CARSL_6700


By compiling it doesnt matter if you use codes with opcodes or without opcodes
You can merge everything and sanny compile it as well,
provided that the code is correct and codelines which includes opcodes by decompiling without opcodes
must be used furthermore by using opcodes


A special feature by decompiling without opcodes is to translate opcode based commands into
Classes and Keywords

For a couple of codes can be used CLASSES
Read more about classes in Sannybuilder-HELP theme: Coding >> Classes

This code by decompiling with writing opcodes
00AB: put_car [email protected] at -1577.942 52.6333 40.0

will by shown by decompiling with without opcodes in this kind:

Car.PutAt([email protected], -1577.942, 52.6333, 40.0)

the meaning of the code is defined by the class entries

Car= class-name
PutAt= class-member
name and member are combined with a dot in the middle
[email protected] = class-owner
class-owner and parameters are placed in brackets and separated with comma
(parameter = needed information for the command)



Sanny allows to use some KEYWORDS instead using opcodes

Opcode = Keyword
_____________
0001: = wait
00d6: = if
004d: = else_jump
004d: = jf
0002: = jump
0051: = return
0050: = gosub
016a: = fade
01B6: = set_weather
03a4: = thread
04BB: = select_interior
0417: = start_mission
00d8: = mission_cleanup
0317: = increment_mission_attempts


Instead writing
004D: jump_if_false @MAIN_6
can be written
jf @MAIN_6
or
else_jump @MAIN_6
you also can merge it
004D: jf @MAIN_6


______________________________________________________________________________________
______________________________________________________________________________________


Data types


: (doublepoint) marks a Label (adress)
CODE
:MAIN_1


@ is used for 2 different functions

1. in jump instruction to mark the label which should be reached
CODE
004D: jump_if_false @SAVE_5
0050: gosub @SAVE_14
0002: jump @SAVE_1


2. to mark LOCAL VARIABLES

The stuff in the game needs a identity for registration to can handle with it
The identities can be variable, for exemble by calculating something

The local variable is builded with the @ sign and a number
[email protected], [email protected], ... [email protected] from [email protected] up to [email protected] is possible, [email protected] and [email protected] are for timers, thats maximum in an .cs file

[email protected] defines a parked_car generator
CODE
014B: [email protected] = init_parked_car_generator #PCJ600 0 17 1 alarm 0 door_lock 0 0 10000 at 2490.0 -1682.0 13.5 angle 90.0

[email protected] can then be used furthermore as variable name of the parked_car generator
CODE
014C: set_parked_car_generator [email protected] cars_to_generate_to 101



$ is used to mark a GLOBAL VARIABLE

The stuff in the game needs a identity for registration to can handle with it
The identities can be variable, for exemble by calculating something

The global variable is builded with the $ sign and a a letter or a word or a number or both
But using global variables in Cleo scripts can cause heavy bugs or crashs
only $PLAYER_CHAR, $PLAYER_ACTOR, $ONMISSION are valid



global, local, whats that ?
Global variables are used in the main.scm to communicate between different threads
Local variables are also used in the main.scm but they can not communicate between different threads
You can create a car with a LOCAL variable in a thread as [email protected] and also with [email protected] in an other thread of main.scm
[email protected] = create_car
You have then 2 different cars, commanded from 2 different threads

You can create a car with GLOBAL variable in a thread but dont use again the same global to create it again in an other thread.
$mycar5 = create_car
But you can command the car from an other thread of the main.scm by using a GLOBAL variable
At least:
The GLOBAL variables are storable, the LOCAL variables not

But dont using global variables in Cleo scripts because they can cause heavy bugs or crashs
only $PLAYER_CHAR, $PLAYER_ACTOR, $ONMISSION are valid


# marks the connected entry as filename of a loadable model
CODE
0247: load_model #BMYCG
0247: load_model #HMYCM
0247: load_model #SWATVAN
0247: load_model #M4
0247: load_model #COLT45

For Cleo can only be used models which are defined in vehicles.ide, peds.ide or default.ide
Other models needs to use their ID number


'...' short string to insert letters or numbers like GXT entrynames or names of special IPL entries
CODE
03A4: name_thread 'MAIN'
0917: audio_zone 'BEACH' enable_sound 0
00BA: show_text_styled GXT 'INTRO_1' time 1000 style 2
0299: activate_garage 'MODLAST'
07FB: set_interior 'GYM1' access 1  // Ganton Gym
0390: load_txd_dictionary 'LD_BEAT'
076C: set_zone 'GAN1' gang 1 density_to 25


"..." long string to insert letters or numbers like animation- and IFP file names, bodypart names, particel names, etc...
CODE
087B: set_player $PLAYER_CHAR clothes_texture "PLAYER_FACE" model "HEAD" body_part 1
038F: load_texture "DOWN" as 1 // Load dictionary with 0390 first
0605: actor -1 perform_animation_sequence "DAN_LOOP_A" IFP_file "DANCING" 4.0 loop 1 0 0 0 time -1 // versionA
0674: set_car_model #GREENWOO numberplate "GROVE4L_"
0245: set_actor [email protected] walk_style_to "GANG2"
064B: [email protected] = create_particle "EXPLOSION_MOLOTOV" at 2010.0 -1610.0 16.5 type 1


To set entries of strings equal to variable names must be used special opcodes and extended variable signs
05AA:
05A9:
06D2:
06D1:
furthermore can strings also replaced with variables by using extended variable signs

@s - local-string-variable
CODE
05AA: [email protected] = 'FEM_OK'
00BC: show_text_highpriority GXT [email protected] time 10000 flag 1


s$ - global-string-variable
Attension by using Global vars in cleo scripts, it can cause bugs or crashes!
CODE
05A9: s$Actor_Speech_GXT_Reference = 'CATX_UA'  // ~z~Carl, you are a f*cking idiota!                    
00BC: show_text_highpriority GXT s$Actor_Speech_GXT_Reference time 10000 flag 1
05AA: [email protected] = s$Actor_Speech_GXT_Reference
00BC: show_text_highpriority GXT [email protected] time 10000 flag 1


@v - local-long-string-variable
CODE
06D2: [email protected] = "LAPDAN1" // @v = string
0812: AS_actor $PLAYER_ACTOR perform_animation "LAPDAN_P" IFP_file [email protected] 1000.0 loopA 0 lockX 0 lockY 0 lockF 1 time -1


v$ - global-long string-variable
Attension by using Global vars in cleo scripts, it can cause bugs or crashes!
CODE
06D1: v$1225 = "Bat_block"// 16-byte strings                    
0605: actor $PLAYER_ACTOR perform_animation_sequence v$1225 from_file "BASEBALL"  4.0  1  0  0  0 -1 ms



______________________________________________________________________________________
______________________________________________________________________________________


Scripting/Writing a Thread

The scripts which are running in GTA are called THREAD
They are defined in the main.scm as thread with the create_thread command or a mission script as mission
As well the Extern scripts of script.img are also threads.

The cleo programm checks if there is .cs file in the Cleo folder
and if yes, it start this script as thread

Script structur / short version:

At first, the head, it beginns with the Cleo directive
CODE
{$CLEO .cs}

First Label (adress)
CODE
:Akt

Then give the thread a name
CODE
03A4: name_thread 'AKT'

now put a code inthere which will doing something and then end_custom_thread as last code
its ready then to test it ingame

CODE
{$CLEO .cs}
:Akt
03A4: name_thread 'AKT'
08B2: toggle_thermal_vision 1
0A93: end_custom_thread

Script above activates the Infrarot view unless in cutscenes
The script ends then, will be deactivated because it ends with opcode 0A93: end_custom_thread
The script will be started by each loading of savegame or by start new game

______________________________________________________________________________________



Next step / using conditional checks

A conditional check requires minimum 3 opcodes

1. the IF-variation
2. the real question
3. the jump instruction by negation




1. if

2. 0AB0: key_pressed 8

3. 004D: jump_if_false @akt_01



We use the previous script again but now we wonna be able to switch into normal view
Therefore we use a conditional check and build a "LOOP"

Loop means that a jump instruction can send the reading process to a previous adress
I call such an adress "Loop-adress"
Important:
The first opcode after such a Loop-adress must be the wait opcode
mostly wait 0 millisecond

the jump instruction can be a jump instruction by negation
or also a normal jump instruction

CODE
004D: jump_if_false @akt_01

or
CODE
0002: jump @akt_01



The conditional check of a key press in the script below should be passed by pressing BACKSPACE

CODE
{$CLEO .cs}
:Akt
03A4: name_thread 'AKT'
08B2: toggle_thermal_vision 1

:Akt_01//----------------------------Loop adresse
0001: wait 0 ms
if
0AB0:   key_pressed 8
004D: jump_if_false @Akt_01//--------jump instruction by negation
08B2: toggle_thermal_vision 0
0A93: end_custom_thread

Script above activates the Infrarot view and toggle back to normal view by key_press
The reading process is looping as long as BACKSPACE is not pressed
the jump instruction by negation sends the reading process allways to the label :Akt_01
1000 times per second

______________________________________________________________________________________



The IF - Variation


CODE
if
00FF:   actor $PLAYER_ACTOR  1 (in-sphere)near_point_on_foot 2493.5  -1682.5  13.35 radius  1.0  1.0  1.0
004D: jump_if_false @Teleport_2


By more than one question in an conditional check requires to determine,
if it means if or or if and

CODE
if and
00DF:   actor $PLAYER_ACTOR driving
8119:   NOT   car [email protected] wrecked
004D: jump_if_false @AD_5

CODE
if or
00E1: key_pressed 0 0
00E1: key_pressed 0 1
00E1: key_pressed 0 14
00E1: key_pressed 0 18
004D: jump_if_false @AD_7

CODE
if or
8118:   NOT   actor [email protected] dead
8118:   NOT   actor [email protected] dead
004D: jump_if_false @AD_25
0002: jump @AD_12


The most question codes can be changed into the opposite question
by changing the ciro of the opcode into 8 and insert "not" into the code line

exemble:
CODE
00E1: key_pressed 0 10

and
CODE
80E1: NOT key_pressed 0 11


______________________________________________________________________________________



Next Step/ Script structure simple

The previous scripts ended because of the opcode 0A93: end_custom_thread
Instead let the script ending we use a jump instruction at script end to the 1.Loop adress
So the reading process is permanent looping
CODE
0002: jump @Akt_01

And since now we add a check in our loop which we add allways after a Loop adress.
It is:
CODE
if
0256:   player $PLAYER_CHAR defined
004D: jump_if_false @Akt_01

It should prevent crashes if the player dies or gets arrested
The "IF Player- Defined-check" should allway be the first check in a loop

Script structure simple with 1 Loop:
-Script head
-1.Loop-Adress
-wait code
-IF player_defined-check
-Conditional Check
-Event
-Normal jump instruction to 1.LoopAdress

CODE
{$CLEO .cs}
:Akt
03A4: name_thread 'AKT'

:Akt_01
0001: wait 0 ms
if
0256: player $PLAYER_CHAR defined
004D: jump_if_false @Akt_01
if
0AB0:   key_pressed 8//-----------------key = Backspace
004D: jump_if_false @Akt_01
08B2: toggle_thermal_vision 1
0001: wait 3000 ms
08B2: toggle_thermal_vision 0
0002: jump @Akt_01//--------Normal jump instruction to 1.LoopAdress

Script above activates the Infrarot view after key_press
and toggle back to normal view after 3 seconds

______________________________________________________________________________________



Next Step/ Script structure extended

To start an event with our script will change the game state and the conditions.
This needs to redirect the reading process to prevent that the same code will be read again.
Therefore we add a second Loop in the script
Loop 1 - before the event
Loop 2 - after the event

Script structure extended with 2 Loops:
-Script head
-1.Loop-Adress
-wait code
-IF player_defined-check
-Conditional Check
-Event
-2.Loop-Adress
-wait code
-IF player_defined-check
-Conditional Check
-Normal jump instruction to 1.LoopAdress

CODE
{$CLEO .cs}
:akt
03A4: name_thread 'AKT'

:akt01//----------------------------1.Loop Adress
0001: wait 0 ms
if
0256:   player $PLAYER_CHAR defined
004D: jump_if_false @akt01
if
00DF:   actor $PLAYER_ACTOR driving
004D: jump_if_false @akt01

03C0: [email protected] = actor $PLAYER_ACTOR car
0229: set_car [email protected] color_to 17 0
02AC: set_car [email protected] immunities BP 1 FP 1 EP 1 CP 1 MP 1
053F: set_car [email protected] tires_vulnerability 0


:akt03//----------------------------2.Loop Adress
0001: wait 0 ms
if
0256:   player $PLAYER_CHAR defined
004D: jump_if_false @akt03
if
80DF:   not actor $PLAYER_ACTOR driving
004D: jump_if_false @akt03

01C3: remove_references_to_car [email protected]

0002: jump @akt01//--------Normal jump instruction to 1.LoopAdress

The script above makes the player_car undestructable as soon as a car is entered
Therefore we must registrate the instance of the car and define it with a variable name
03C0: [email protected] = actor $PLAYER_ACTOR car
Then we can use this variable name [email protected] to make the car immun

After player has left the car, the reading process jumps back into the first Loop.

Youre not restricted by 2 Loops and there are also other kinds of script structure
But I recommand to build your scripts with this structure as long as you have not much experience

user posted image


______________________________________________________________________________________



Script exemble: Slowmotion

The script toggle by key_press between slowmotion and normal speed
set_gamespeed .3 make the game slow and also the reading process
wait 50 milliseconds needs ca. 1 second
A "if_player_defined"-check is not nessesary because the script dont have any codes which belongs to the player
After a passed key_press check it makes sense to set a wait of one second otherwise the key_press check will be repeated to fast.

CODE
{$CLEO .cs}
:slow_0
03A4: name_thread 'SLW'

:slow_1
0001: wait  0 ms
if
0AB0:   key_pressed 8//-----------------key = Backspace
004D: jump_if_false @slow_1
015D: set_gamespeed  .3
0001: wait  50 ms

:slow_2
0001: wait  0 ms
if
0AB0:   key_pressed 8//-----------------key = Backspace
004D: jump_if_false @slow_2
015D: set_gamespeed  1.0
0001: wait  1000 ms
0002: jump @slow_1


______________________________________________________________________________________



Next Step/ Spawn a 3D model

Using models requires 5 steps by applying with models and their definition in its variable name

1. first step to load the model
CODE
0247: request_model #INFERNUS

2. second step to prove if the model is loaded in an extra "load-model-check-Loop"
CODE
:Load_Model_Check
0001: wait  0 ms
if
0248:   model #INFERNUS available
004D: jump_if_false @Load_Model_Check

3. The model can be created as soon as the model file is loaded and define it with a variable name
CODE
00A5: [email protected] = create_car #INFERNUS at 2487.5  -1660.5  13.35
0175: set_car [email protected] z_angle_to 90.0

4. release the loaded model file if it not needed anymore
CODE
0249: release_model #INFERNUS

5. Release the defined item from script when the script has done its work
The script can then go to the status quo by jumping back into the first Loop
CODE
01C3: remove_references_to_car [email protected]  // Like turning a car into any random car

Releasing a spawned car by using 01C3: remove_references_to_car deletes the instance of the car for our script
but its still available in the game but can not used anymore in our script.

An other way to release the car is to delete it complete:
CODE
00A6: destroy_car [email protected]


This 2 different kinds for releasing exist for vehicles, actors and objects each with own opcodes

CODE
{$CLEO .cs}
:3dModels_1
03A4: name_thread 'MODL'

:3dModels_2
0001: wait  0 ms
if
0256:   player $PLAYER_CHAR defined
004D: jump_if_false @3dModels_2
if
00FF:   actor $PLAYER_ACTOR  1 (in-sphere)near_point_on_foot 2491.5  -1667.5  13.35 radius  1.0  1.0  1.0
004D: jump_if_false @3dModels_2

0247: request_model #INFERNUS

:Load_Model_Check
0001: wait  0 ms
if
0248:   model #INFERNUS available
004D: jump_if_false @Load_Model_Check

00A5: [email protected] = create_car #INFERNUS at 2487.5  -1660.5  13.35
0175: set_car [email protected] z_angle_to 90.0
0249: release_model #INFERNUS

:3dModels_3
0001: wait  0 ms
if
0256:   player $PLAYER_CHAR defined
004D: jump_if_false @3dModels_3
if
80FF:   NOT   actor $PLAYER_ACTOR  0 ()near_point_on_foot 2491.5  -1667.5  13.35 radius  2.0  2.0  2.0
004D: jump_if_false @3dModels_3
01C3: remove_references_to_car [email protected]  // Like turning a car into any random car
0002: jump @3dModels_2

Script above spawns the car Infernus in Grovestreet if player goes into red marker(sphere)
If player leave the spot the car will be released from script and the reading process jumps back into 1.Loop


# marks the connected entry as filename of a loadable model
For Cleo can only be used models which are defined in vehicles.ide, peds.ide or default.ide
Other models needs to use their ID number

For exemble to spawn the object 1655, waterjumpx2 of data\maps\generic\multiobj.ide
CODE
{$CLEO .cs}
:JumpR00
03A4: name_thread 'JPR'

:JumpR01
0001: wait  0 ms
if
0256: player $PLAYER_CHAR defined
004D: jump_if_false @JumpR01
if
00E1:   key_pressed  0  10//--------- No key  
004D: jump_if_false @JumpR01
0247: request_model 1655

:JumpR02
0001: wait  0 ms
if
0248:   model 1655 available
004D: jump_if_false @JumpR02
0172: [email protected] = actor $PLAYER_ACTOR z_angle
04C4: create_coordinate [email protected] [email protected] [email protected] from_actor $PLAYER_ACTOR offset 0.0 14.5 -1.8
0107: [email protected] = create_object 1655 at  [email protected] [email protected] [email protected]
0177: set_object [email protected] z_angle_to  [email protected]
0001: wait  0 ms
0249: release_model 1655
0001: wait  1000 ms
01C4: remove_references_to_object [email protected]  // This object will now disappear when the player looks away
0002: jump @JumpR01

Script above spawns a jumpramp by key_press

You can allways use the ID number to spawn models, also for cars and actors
As next we use 120 intead #TRIBOSS to spawn an actor

CODE
{$CLEO .cs}
:Actor_1
03A4: name_thread 'Actor'

:Actor_2
0001: wait  0 ms
if
0256:   player $PLAYER_CHAR defined
004D: jump_if_false @Actor_2
if
00FF:   actor $PLAYER_ACTOR  1 (in-sphere)near_point_on_foot 2491.5  -1667.5  13.35 radius  1.0  1.0  1.0
004D: jump_if_false @Actor_2

0247: request_model 120
0247: request_model #AK47

:Load_models_check
0001: wait  0 ms
00D6: if  and
0248:   model 120 available
0248:   model #AK47 available
004D: jump_if_false @Load_models_check

009A: [email protected] = create_actor  24 120 at  2486.5  -1664.5  13.45
0173: set_actor [email protected] z_angle_to  180.0
01B2: give_actor [email protected] weapon  30 ammo  99999  // Load the weapon model before using this
02E2: set_actor [email protected] weapon_accuracy_to  100
0223: set_actor [email protected] health_to  1000
05E2: AS_actor [email protected] kill_actor $PLAYER_ACTOR
0249: release_model 120

:Loop_1
0001: wait  0 ms
if
8118:   NOT   actor [email protected] dead
004D: jump_if_false @Cleanup_1
if
0104:   actor $PLAYER_ACTOR near_actor [email protected] radius  80.0  80.0  10.0 sphere  0
004D: jump_if_false @Cleanup_1
0002: jump @Loop_1

:Cleanup_1
01C2: remove_references_to_actor [email protected] // Like turning an actor into a random pedestrian
0002: jump @Actor_2

Script above spawns the actor Triboss with gun in Grovestreet
If player leave the area with radius 80.0 80.0 or if the actor is dead,
the actor will be released from script and the reading process jumps back into 1.Loop

To give the actor or the player a weapon requires also to load first the model file
But to give it then really into his hands needs to insert a special weapon number which is not documented in any game file.
To find the right weapon number look in Sannybuilder HELP: SCM Documentation >> GTA SA >> Weapon numbers

Weapon given to actors are not created in same sense like the other models,
so it dont it to release them from script like other items

The spawned actors have predefined execodet behaviors which is dependent by the pedtype parameter of the create_actor opcode.
Look for pedtypes in Sannybuilder HELP: SCM Documentation >> GTA SA >> PedTypes

An actor with pedtype 8 is recruitable like a homie
CODE
009A: [email protected] = create_actor  8 #TRIBOSS at  2486.5  -1664.5  13.45

An actor with pedtype 7 is agressive like an enemy gangmember
CODE
009A: [email protected] = create_actor  7 #TRIBOSS at  2486.5  -1664.5  13.45


______________________________________________________________________________________



Placing cars by using parked_car_generator

Init parked_car_generators or pickups need to insert the Cleo opcode:

0A95: enable_thread_saving

Read the discription about enable_thread_saving in the theme:
Special Particularities in Cleo >> Registrate (store) the Script State

The placing of cars by using parked_car_generator dont allows the using of its variable name in vehicle associated opcodes
because its not a car but a car_generator

CODE
{$CLEO .cs}
:PaCar_1
03A4: name_thread "PACR"
0001: wait  1000 ms
0A95: enable_thread_saving

014B: [email protected] = init_parked_car_generator #BANSHEE -1 -1  1 alarm  0 door_lock  0  0  10000 at  920.1994  2020.546  11.79 angle  100.0
014C: set_parked_car_generator [email protected] cars_to_generate_to  101

032B: [email protected] = create_weapon_pickup #MINIGUN  15 ammo  5000 at  2113.373 1520.674  10.82

0A93: end_custom_thread

Script above adds a parked_car_generator to spawn the car Banshee
and a weapon pickup with MINIGUN


generate_to 101 means that the car will be spawned again and again
generate_to 0 deactivates the car_generator

the two parameters after the model name -1 -1 gives the secondary and primary color
by setting -1 -1the game choose the colors randomly

by setting 0 17 it give black (0) to primary and red (17) to secondary color

alarm 0 can be a value between 0 and 100 and means the probable chance to execute an alarm

door_lock 0 can be a value between 0 and 100 and means the probable chance to execute a door lock


For pickups exist 2 different opcodes for 2 different kinds of pickups
032B: for weapons with ammo and for the Jetpack
0213: for melee weapons and objects like parachute (GUN_PARA) or bodyarmour (1242, bodyarmour)
the parameter after the model ID #MINIGUN 15 is the pickup-typ
Typ 15 is a pickup, which appears again and again
Typ 3 is a pickup, which appears only for one time


______________________________________________________________________________________
______________________________________________________________________________________




Special Particularities in Cleo

The extra-Cleo opcodes can be found in Sannybuilder-HELP
CLEO 3 Code Library >> CLEO 3: opcodes CLEO 3 Code Library>> CLEO 3: opcodes

______________________________________________________________________________________


Two major codes to start scripts are those which already exist in the main.scm and have been re-created for Cleo:

1.) 004F: create_thread @SAVEGAME starts an ordinary thread in the main.scm.
We dont need it in Cleo because it will be allready started from Cleo programm
To start an other thread of a cleo script, started from a cleo script needs following opcode:

0A92: create_custom_thread "New_Test_thread.cs"

The code needs to insert the name of the script file which should get started inclusiv dot and extension

The Cleo script file get then the file extension, which is written in the Cleo Script directive at the beginning of the script
{$CLEO .cs} = Cleo directive will be compiled to *.cs
As New_Test_thread.txt saved and compiled as New_Test_thread.cs

The script get then started at second once. Once from Cleo programm and once from the 0A92: create_custom_thread
It needs to set a conditional check at script beginn to let the script ending when it was started from Cleo programm.

An other chance is to give the script the extension .s
This needs to insert following:

0A92: create_custom_thread "New_Test_thread.s"

The Cleo script file which should get started, must have {$CLEO .cs} as directive and will be compiled as *.cs
You must change the extension manual by renaming from *.cs into *.s
In this case the Cleo script will only run if it was started with 0A92: create_custom_thread from an other Cleo script.

The opcode 0A92: create_custom_thread can transport more information to the script which should be started
This opcode can be extended with up to 30 values or variables as parameters
exemble:
CODE
0A92: create_custom_thread "PimpmyCarFULL2A1.cs" 1 2 0 [email protected] [email protected] [email protected] [email protected] [email protected] [email protected] [email protected] [email protected]

The started thread recieves these parameter values with following rule
[email protected] get value of 1.parameter
[email protected] get value of 2.parameter
[email protected] get value of 3.parameter
[email protected] get value of 4.parameter
[email protected] get value of 5.parameter
etc...
Its also possible to start much threads in one and the same Cleo script, started from the same script which recieve the create_thread commands.


2.)

0417: start_mission 3
starts a mission script of the main.scm. It needs to insert the number which the mission script get from the listing of the mission table

In Cleo dont exist a mission table and its listing.
But it needs allways a Cleo mission starter script with following command:

0A94: start_custom_mission "DriftMission"

The code needs to insert the name of the script file which should get started but without extension

The Cleo script file get then the file extension, which is written in the Cleo Script directive at the beginning of the script
{$CLEO .cm} = Cleo directive will be compiled to *.cm
As DriftMission.txt saved and compiled as DriftMission.cm

______________________________________________________________________________________


0A93: end_custom_thread let a script ending. Its disabled then.

The original version of this code of the main.scm is 004E: end_thread

And this original version must be used furthermore in Cleo mission scripts (*.cm)

004E: end_thread

Again:

0A93: end_custom_thread in normal Cleo scripts, compiled to a *.cs file
CODE
{$CLEO .cs}
0A93: end_custom_thread


004E: end_thread in mission scripts, compiled to a *.cm file
CODE
{$CLEO .cm}
004E: end_thread


______________________________________________________________________________________


Cleo creates extra save files if a save was done,
stored in folder CLEO\Cleo_save


By loading a save file must taken care to check that the presence of the scripts in Cleo folder
is the same as it was as the save was done.
Special attention in this case are going to those scripts which includes the Cleo opcode
to registrate and store the Script State

______________________________________________________________________________________



Registrate (store) the Script State

The Cleo scripts with extension .cs are started allways from new by loading a save game or start new game,
If such a script includes for exemble a parked car generator and execute it and after this a save game is made,
and then this save game is loaded,
will be created a duplicate of the item, in this case a duplicate of a parked car generator.
This happens with parked car generator, pickups as well as placed objects.

To prevent this or to read the script state by using special special Cleo-variable
must be used following Cleo opcode:
CODE
0A95: enable_thread_saving

This instruct Cleo to store the script state by making a savegame

______________________________________________________________________________________


Special Global Cleo Variable

This theme requires the understanding of the description about Local Variables and Global Variables
of the previous theme Datatype
especially this part which tells why there exist Local Variables and Global Variables
Global Variables are used in main.scm to communicate between different scripts and they are storable.
Using Global Variables in Cleo scripts can cause bugs and crashes

To realize Global Variables for Cleo scripts exist following Cleo opcode connected with a special expression:

Opcode 0AB3: and 0AB4:

The expression var together with a number, <var><space><number> is builing the Special Global Cleo Variable

CODE
0AB3: var 0 = 10
or
0006: [email protected] =  10  // integer values
0AB3: var 0 = [email protected]

and
0AB4: [email protected]= var 0

var 0 up to var 999 will be stored, in exemble var 0 is stored with 10

to get then stored value into your script needs to submit into a local:
CODE
0AB4: [email protected] = var 44
if
0039:   [email protected] ==  1  // integer values
004D: jump_if_false @nextlabel


______________________________________________________________________________________
______________________________________________________________________________________



Script Exemble by using Special Global Cleo Variable/ Store a car at any place
(requires to understand all previous themes of this tut)

Script below saves a car at any place
If player is in car and key F7 is pressed, it stores x,y,z coords and angle, also the car ID, its primary and secondary color and its paintjob.

The player exit then the car and car will be locked and made immun
If player leave the location and the distance to the car will be greater then 100.0
the car will be released from script and the reading process jumps back into an other Loop

If player then comes back to the location, near 80.0 the car will be spawned as new
Only to store the car settings by making savegame needs to give the values into the Special Global Cleo Variable

As I wrote in the theme "Registrate (store) the Script State"
is the Carstore script running from new by loading a save game or start new game"...

...and checks first if var 955 is ciro
its only not ciro if a car was stored in the loaded savegame

If var 955 is ciro, the script starts with the 1.Loop
If var 955 is not ciro, the reading process jumps into the 3.Loop with the check if player is near the car store location

A special side effect of this kind of car store is that the storable entries then available in memory for all savefiles.
Only by shut down the game and start again is the stored car only stored in the savegame which was done to store the car.

CODE
{$CLEO .cs}
:CARSTORE
03A4: name_thread 'CARSTOR'
0001: wait 1000 ms
0AB4: [email protected] = var 955
00D6: if
8039:   not  [email protected] == 0
004D: jump_if_false @CARSTOR_150
0AB4: [email protected] = var 951
0AB4: [email protected] = var 952
0AB4: [email protected] = var 953
0AB4: [email protected] = var 954
0AB4: [email protected] = var 955
0AB4: [email protected] = var 956
0AB4: [email protected] = var 957
0AB4: [email protected] = var 958
0093: [email protected] = integer [email protected] to_float
0093: [email protected] = integer [email protected] to_float
0093: [email protected] = integer [email protected] to_float
0093: [email protected] = integer [email protected] to_float
0001: wait 1000 ms
0002: jump @CARSTOR_555

:CARSTOR_150
0001: wait 0 ms
00D6: if
0256:   player $PLAYER_CHAR defined
004D: jump_if_false @CARSTOR_150
00D6: if and
00DF:   actor $PLAYER_ACTOR driving
0AB0:   key_pressed 118//-------------------key F7
004D: jump_if_false @CARSTOR_150
01B4: set_player $PLAYER_CHAR can_move 0
03C0: [email protected] = actor $PLAYER_ACTOR car
00AA: store_car [email protected] position_to [email protected] [email protected] [email protected]
0174: [email protected] = car [email protected] Z_angle
0441: [email protected] = car [email protected] model
0988: get_car [email protected] paintjob [email protected]
03F3: get_car [email protected] primary_color_to [email protected] secondary_color_to [email protected]
020A: set_car [email protected] door_status_to 0
02AC: set_car [email protected] immunities BP 1 FP 1 EP 1 CP 1 MP 1
0519: set_car [email protected] locked 1
0633: AS_actor $PLAYER_ACTOR exit_car
0092: [email protected] = float [email protected] to_integer
0092: [email protected] = float [email protected] to_integer
0092: [email protected] = float [email protected] to_integer
0092: [email protected] = float [email protected] to_integer
0AB3: var 951 = [email protected]
0AB3: var 952 = [email protected]
0AB3: var 953 = [email protected]
0AB3: var 954 = [email protected]
0AB3: var 955 = [email protected]
0AB3: var 956 = [email protected]
0AB3: var 957 = [email protected]
0AB3: var 958 = [email protected]
0001: wait 2000 ms
01B4: set_player $PLAYER_CHAR can_move 1
0002: jump @CARSTOR_403

:CARSTOR_403
0001: wait 0 ms
00D6: if
0256:   player $PLAYER_CHAR defined
004D: jump_if_false @CARSTOR_550
00D6: if
82BF:   not car [email protected] sunk
004D: jump_if_false @CARSTOR_738
00D6: if
8119:   not car [email protected] wrecked
004D: jump_if_false @CARSTOR_550
00D6: if
0202:   actor $PLAYER_ACTOR near_car [email protected] radius 100.0 100.0 flag 0
004D: jump_if_false @CARSTOR_550
00D6: if
00DF:   actor $PLAYER_ACTOR driving
004D: jump_if_false @CARSTOR_403
00D6: if
00DB:   actor $PLAYER_ACTOR in_car [email protected]
004D: jump_if_false @CARSTOR_403
02AC: set_car [email protected] immunities BP 0 FP 0 EP 0 CP 0 MP 0
0519: set_car [email protected] locked 0
0002: jump @CARSTOR_738

:CARSTOR_550
01C3: remove_references_to_car [email protected] // Like turning a car into any random car

:CARSTOR_555
0001: wait 0 ms
00D6: if
0256:   player $PLAYER_CHAR defined
004D: jump_if_false @CARSTOR_555
00D6: if
00FE:   actor $PLAYER_ACTOR sphere 0 in_sphere [email protected] [email protected] [email protected] radius 80.0 80.0 50.0
004D: jump_if_false @CARSTOR_555
0002: jump @CARSTOR_624

:CARSTOR_624
0247: load_model [email protected]

:CARSTOR_629
0001: wait 0 ms
00D6: if
0248:   model [email protected] available
004D: jump_if_false @CARSTOR_629
0001: wait 0 ms
00A5: [email protected] = create_car [email protected] at [email protected] [email protected] [email protected]
0175: set_car [email protected] Z_angle_to [email protected]
06ED: set_car [email protected] paintjob [email protected]
0229: set_car [email protected] primary_color_to [email protected] secondary_color_to [email protected]
020A: set_car [email protected] door_status_to 0
02AC: set_car [email protected] immunities BP 1 FP 1 EP 1 CP 1 MP 1
0519: set_car [email protected] locked 1
0249: release_model [email protected]
0002: jump @CARSTOR_403

:CARSTOR_738
01C3: remove_references_to_car [email protected] // Like turning a car into any random car
0AB3: var 955 = 0
0002: jump @CARSTOR_150


______________________________________________________________________________________
______________________________________________________________________________________



Template for Cleo Mission Script
(requires to understand all previous themes of this tut)

To run a Cleo mission script requires allways 2 Cleo script files
1. A .cs file to start the Cleo mission script file
2. The Cleo mission script file itself with extension .cm


The mission starter thread below is done with a conditional check to check if the player is near a specified point,
which must passed to start the mission.

The coordinates of the near_point check are the location in San Fierro/Carlton Heights near savehouse
Edit the coordinates to set your own location for starting

The parameter 1 of the near_point opcode 00FE: actor $PLAYER_ACTOR 1 (in-sphere)near_point
is displaying a red marker (sphere).
If the parameter is ciro 00FE: actor $PLAYER_ACTOR 0 (in-sphere)near_point does not displaying a red marker.
To display a red marker in this way needs to set 0ms as maximum in the wait code of this Loop
CODE
{$CLEO .cs}
:Test_M_Start_1
03A4: name_thread 'TSTM'

:Test_M_Start_2
0001: wait  0 ms
00D6: if  0
0256:   player $PLAYER_CHAR defined
004D: jump_if_false @Test_M_Start_2
00D6: if  0
0038:   $ONMISSION ==  0  // integer values
004D: jump_if_false @Test_M_Start_2

:Test_M_Start_6
00D6: if  0
00FE:   actor $PLAYER_ACTOR  1 (in-sphere)near_point 2480.1343 -1665.475 13.3348 radius  3.5  3.5  5.5
004D: jump_if_false @Test_M_Start_2
00BA: text_styled 'STAD_02'  1000 ms  2
0004: $ONMISSION =  1  // integer values
0A94: start_custom_mission "TestMission"  //
0002: jump @Test_M_Start_2

The mission starter script includes the following Cleo opcode to start the Cleo mission script:
0A94: start_custom_mission "TestMission"

The code needs to insert the name of the script file which should get started but without extension

The Cleo script file get then the file extension, which is written in the Cleo Script directive at the beginning of the script
{$CLEO .cm} = Cleo directive will be compiled to *.cm
As TestMission.txt saved and compiled as TestMission.cm

CODE
{$CLEO .cm}
:TestMiss_1
03A4: name_thread "TESTM"  
0050: gosub @TestMiss_main_1
00D6: if  0
0112:   wasted_or_busted
004D: jump_if_false @TestMiss_end_1
0050: gosub @TestMiss_fail_1                    

:TestMiss_end_1
0050: gosub @TestMiss_clep_1
004E: end_thread

:TestMiss_main_1
0317: increment_mission_attempts//here starts the missionscript
0004: $ONMISSION =  1
054C: use_GXT_table 'MENU2P'
00BC: text_highpriority 'MENU_18'  5000 ms  1

:TestMiss_11
0001: wait 0 ms
if and
02D8:   actor $PLAYER_ACTOR currentweapon == 0
00E1:   key_pressed 0 17
004D: jump_if_false @TestMiss_11

:TestMiss_pass_1
00BA: text_styled 'M_PASS'  5000 ms  1
0051: return

:TestMiss_fail_1
00BA: text_styled 'M_FAIL'  5000 ms  1
0051: return

:TestMiss_clep_1
0004: $ONMISSION =  0
00D8: mission_cleanup
0051: return


When the mission script from above is running it can be completed by pressing fire key while player have weapon 0/naked fist.


The secret of the onmission mode

$ONMISSION is not only a variable to check if a mission script is running or not.
Set $ONMISSION to 1 activates a special mission mode if some important conditions are accomplished.
R*s mission scripts run allways in a subroutine which will be cancled from the exe if player is wasted or busted like reading a return code in the script.

1. At first it needs to set $ONMISSION equal to on_mission_flag
CODE
0180: set_on_mission_flag_to $ONMISSION// Note: your missions have to use the variable defined here

This code is set by default in the main part of the original main.scm

2. By starting the mission script must sended the reading precess with a gosub command into a subroutine for the main part of the mission script.
It must be the first gosub of the mission script.
CODE
0050: gosub @TestMiss_main_1


3. By starting the mission script must be activated the onmission mode with
CODE
0004: $ONMISSION =  1
0317: increment_mission_attempts//here starts the missionscript


Then the mission is running in a subroutine and dont needs to check if player is defined or dead or busted.
If player dies or get busted, the exe cancels the subroutine as like as a return code of our script is readed

The rest of the mission script is just a cunning gosub construct.

______________________________________________________________________________________
______________________________________________________________________________________



gosub

The gosub command leads the reading process to an excluded subscript.
Excluded means the codes of the subscript are not binded in code following of our thread.
CODE
0050: gosub @MODLSUBROUTINE

The subscript must end with return
CODE
0051: return


If the subscript ends with 0051: return, our thread then continues with reading the codes after the 0050: gosub command

Exemble:
CODE
{$CLEO .cs}
:MODLSUB_1
03A4: name_thread 'MODLSUB'

:MODLSUB_2
0001: wait  0 ms
00D6: if  0
0256:   player $PLAYER_CHAR defined
004D: jump_if_false @MODLSUB_2
00D6: if  0
00FF:   actor $PLAYER_ACTOR  1 (in-sphere)near_point_on_foot 2491.5  -1667.5  13.35 radius  1.0  1.0  1.0
004D: jump_if_false @MODLSUB_2
0050: gosub @MODLSUBROUTINE

:Loop_1
0001: wait  0 ms
00D6: if  0
8118:   NOT   actor [email protected] dead
004D: jump_if_false @Cleanup_1
00D6: if  0
0104:   actor $PLAYER_ACTOR near_actor [email protected] radius  80.0  80.0  10.0 sphere  0
004D: jump_if_false @Cleanup_1
0002: jump @Loop_1

:Cleanup_1
01C2: remove_references_to_actor [email protected] // Like turning an actor into a random pedestrian
0002: jump @MODLSUB_2


:MODLSUBROUTINE
0005: [email protected] = 2473.25
0005: [email protected] = -1657.79
0005: [email protected] = 13.4
0005: [email protected] = 2501.12
0005: [email protected] = -1676.5
0005: [email protected] = 13.4
0208: [email protected] = random_float_in_ranges [email protected] [email protected]
0208: [email protected] = random_float_in_ranges [email protected] [email protected]
0208: [email protected] = random_float_in_ranges [email protected] [email protected]
0247: request_model #TRIBOSS
0247: request_model #AK47

:Load_MODLSUB_Check
0001: wait  0 ms
00D6: if  and
0248:   model #TRIBOSS available
0248:   model #AK47 available
004D: jump_if_false @Load_MODLSUB_Check

009A: [email protected] = create_actor  24 #TRIBOSS at  [email protected] [email protected] [email protected]
0173: set_actor [email protected] z_angle_to  180.0
01B2: give_actor [email protected] weapon  30 ammo  99999  // Load the weapon model before using this
02E2: set_actor [email protected] weapon_accuracy_to  100
0223: set_actor [email protected] health_to  1000
05E2: AS_actor [email protected] kill_actor $PLAYER_ACTOR
0249: release_model #TRIBOSS
0051: return

Script above spawns the actor Triboss with gun in Grovestreet at different places
The coords are generated random
The part with the coords generation and actor spawn is excluded in a subscript

If player leave the area with radius 80.0 80.0 or if the actor is dead,
the actor will be released from script and the reading process jumps back into 1.Loop


______________________________________________________________________________________
______________________________________________________________________________________


Additional Themes

  • Graven, In45do, TheGodfather. and 7 others like this

coin-god
  • coin-god

    High Roller

  • $outh $ide Hoodz
  • Joined: 18 Mar 2007
  • None

#2

Posted 22 March 2009 - 12:24 AM

Great work on the Tuto ZAZ icon14.gif

Dutchy3010
  • Dutchy3010

    Female SCM coder!

  • Moderator
  • Joined: 30 Jul 2006
  • Netherlands
  • Best Script 2013 [DYOM]
    Best Script 2012 [DYOM]

#3

Posted 22 March 2009 - 12:32 AM

Nice ZAZ. smile.gif

I already told you, this was the tutorial I was missing on this forum. A tutorial all about CLEO. smile.gif

cookie.gif

ZAZ
  • ZAZ

    Kernlochbohrer

  • Feroci
  • Joined: 10 Jan 2005
  • European-Union
  • Contribution Award [Mods]
    Helpfulness Awards [Mods]

#4

Posted 23 March 2009 - 04:42 PM Edited by ZAZ, 04 November 2016 - 02:43 PM.

Additional Themes
1. Create a FXT file
2. Load a special actor
3. Tuning parts
4. Animations
5. sounds of Audio folder

next chapter:Give access with math coding


______________________________________________________________________________________

______________________________________________________________________________________


Create a FXT file to show your own text

Cleo makes possible to use a custom file to store text for using ingame
its called fake XT, according to the gxt file of the game
This requires to install the GxtHook.cleo in Cleo folder and an extra folder for the fxt files

Much users make it wrong, so again the explanation:
GxtHook.cleo must be placed in Cleo folder, not in a sub folder
Cleo_text folder must be a sub folder of Cleo folder
The fxt file must be placed in Cleo_text folder

GTASA game dir
- Cleo:GxtHook.cleo
- Cleo\Cleo_text: text.fxt

The fxt file will be read by game start.
If you have modified your fxt file it needs first to close the game complete
and then start again to apply the changes.

To create a fxt file needs to insert an entry name for the script and the real text to show, in a normal txt file
Then rename the file by chaning the extension from .txt into .fxt
Or create it directly with Sannybuilder and save it as .fxt , choose Any file (*.*) as extension

Entry name for the script and the real text to show must be done in this way:
<Entryname><space><text message>
only 1 space between Entryname and text message
Important:
only 1 space between words of the text message are allowed and NO space at the end
Maximum 7 symbols as entry name are allowed

Exemble:
Copy this line into a blanc page and save it as anyname.fxt

TXT_01 This is text of Cleo fxt file

Then use the script below to show the text by key_press

{$CLEO .cs}
:FXT
03A4: name_thread 'FXT'

:FXT_01
0001: wait 0 ms
if
0AB0:   key_pressed 84//--------- key = T
004D: jump_if_false @FXT_01
00BA: text_styled 'TXT_01'  1000 ms  1
0A93: end_custom_thread

The opcodes to show text are the same like to show text of american.gxt
There exist several opcodes to show text in different kinds. Look in opcode search tool.
Or look in Dutchys coding tut

If you wonna use entry names of american.gxt to use its text messages,
so look for a complete translation txt file in Sanny Install directory:
Sanny Builder 3\help\GXT Strings\GTASA.text


______________________________________________________________________________________
______________________________________________________________________________________



Load a special_actor

There exist 2 kinds of actor models in the game.
One kind are models which are defined with a ID number in peds.ide and must be loaded with opcode 0247:

The other kind of actor models are not defined in peds.ide and must be loaded with opcode 023C:
These are called special actors and there are ID numbers reserved in peds.ide. From 290 up to 299
So 10 different special actors can be spawned at same time.

According to the theme Spawn a 3D model we need also 5 steps but with other opcodes

1. first step to load the special actor needs to insert the model name as short string

023C: load_special_actor 'ogloc' as 1

2. second step to prove if the model is loaded in an extra "load-model-check-Loop"

:Load_Model_Check
0001: wait  0 ms
00D6: if  0
023D:   special_actor  1 loaded
004D: jump_if_false @Load_Model_Check

3. The model can be created as soon as the model file is loaded and define it with a variable name

009A: [email protected] = create_actor_pedtype 24 model #SPECIAL01 at 2491.5  -1667.5  13.35

4. release the loaded special actor model file if it not needed anymore
 

0296: unload_special_actor  1

5. Release the defined item from script when the script has done its work
same like other actors

01C2: remove_references_to_actor [email protected]

The script below spawns a special actor by key_press at 4 virtual meters infront of the player
The script reads also the current interior to can spawn everywhere by using opcode 0860:
If the actor is dead he will be released from script und the reading process jumps back into 1.Loop
 

{$CLEO .cs}
:SPLACTOR_1
03A4: name_thread 'SPACTOR'

:SPACTOR_11
0001: wait 0 ms
00D6: if
0256:   player $PLAYER_CHAR defined
004D: jump_if_false @SPACTOR_11
00D6: if
0AB0:   key_pressed 57//--------------------------------- key 9
004D: jump_if_false @SPACTOR_11
077E: get_active_interior_to [email protected]
023C: load_special_actor 'ogloc' as 1 // models 290-299

:SPACTOR_51
0001: wait 0 ms
00D6: if
823D:   not special_actor 1 loaded
004D: jump_if_false @SPACTOR_90
023C: load_special_actor 'OGLOC' as 1 // models 290-299
0002: jump @SPACTOR_51

:SPACTOR_90
04C4: store_coords_to [email protected] [email protected] [email protected] from_actor $PLAYER_ACTOR with_offset 0.0 4.0 0.2
009A: [email protected] = create_actor_pedtype 24 model #SPECIAL01 at [email protected] [email protected] [email protected]
0223: set_actor [email protected] health_to 10000
0860: link_actor [email protected] to_interior [email protected]
0296: unload_special_actor 1

:SPACTOR_158
0001: wait 0 ms
00D6: if
0256:   player $PLAYER_CHAR defined
004D: jump_if_false @SPACTOR_201
00D6: if
8118:   not actor [email protected] dead
004D: jump_if_false @SPACTOR_201
0002: jump @SPACTOR_158

:SPACTOR_201
01C2: remove_references_to_actor [email protected] // Like turning an actor into a random pedestrian
0002: jump @SPACTOR_11

The opcode to create the actor is the same like for a normal ped.
Instead of inserting the peds model name will be used the entry #SPECIAL01
SPECIAL01 represent the ID 290 which the actor then get from the script
Its also possible to use the ID numbers instead of SPECIAL01

By creating more different special actors needs to give it then entries with numbers in ascending order
#SPECIAL01 and #SPECIAL02 or 290 and 291

The script below spawns 5 special actors
If one actor is dead all actors will be released from script und the reading process jumps back into 1.Loop
An advantage of special actors is to can add a new actor model with new model name without editing data files
Important: Maximum 7 symbols are allowed as model name
 

{$CLEO .cs}
:SPLACTOR_1
03A4: name_thread 'SPACMOR'

:SPACMOR_11
0001: wait 0 ms
00D6: if
0256:   player $PLAYER_CHAR defined
004D: jump_if_false @SPACMOR_11
00D6: if
0AB0:   key_pressed 57//--------------------------------- key 9
004D: jump_if_false @SPACMOR_11
077E: get_active_interior_to [email protected]
023C: load_special_actor 'OGLOC' as 1 // models 290-299
023C: load_special_actor 'SMOKE' as 2 // models 290-299
023C: load_special_actor 'SWEET' as 3 // models 290-299
023C: load_special_actor 'RYDER2' as 4 // models 290-299
023C: load_special_actor 'CESAR' as 5 // models 290-299

:SPACMOR_116
0001: wait 0 ms
00D6: if or
823D:   not special_actor 1 loaded
823D:   not special_actor 2 loaded
823D:   not special_actor 3 loaded
823D:   not special_actor 4 loaded
823D:   not special_actor 5 loaded
004D: jump_if_false @SPACMOR_223
023C: load_special_actor 'OGLOC' as 1 // models 290-299
023C: load_special_actor 'SMOKE' as 2 // models 290-299
023C: load_special_actor 'SWEET' as 3 // models 290-299
023C: load_special_actor 'RYDER2' as 4 // models 290-299
023C: load_special_actor 'CESAR' as 5 // models 290-299
0002: jump @SPACMOR_116

:SPACMOR_223
04C4: store_coords_to [email protected] [email protected] [email protected] from_actor $PLAYER_ACTOR with_offset -2.0 2.0 0.2
009A: [email protected] = create_actor_pedtype 24 model #SPECIAL01 at [email protected] [email protected] [email protected]
0223: set_actor [email protected] health_to 10000
0860: link_actor [email protected] to_interior [email protected]
04C4: store_coords_to [email protected] [email protected] [email protected] from_actor $PLAYER_ACTOR with_offset 0.0 2.0 0.2
009A: [email protected] = create_actor_pedtype 24 model 291 at [email protected] [email protected] [email protected]
0223: set_actor [email protected] health_to 10000
0860: link_actor [email protected] to_interior [email protected]
04C4: store_coords_to [email protected] [email protected] [email protected] from_actor $PLAYER_ACTOR with_offset 2.0 2.0 0.2
009A: [email protected] = create_actor_pedtype 24 model #SPECIAL03 at [email protected] [email protected] [email protected]
0223: set_actor [email protected] health_to 10000
0860: link_actor [email protected] to_interior [email protected]
04C4: store_coords_to [email protected] [email protected] [email protected] from_actor $PLAYER_ACTOR with_offset -2.0 4.0 0.2
009A: [email protected] = create_actor_pedtype 24 model 293 at [email protected] [email protected] [email protected]
0223: set_actor [email protected] health_to 10000
0860: link_actor [email protected] to_interior [email protected]
04C4: store_coords_to [email protected] [email protected] [email protected] from_actor $PLAYER_ACTOR with_offset 2.0 4.0 0.2
009A: [email protected] = create_actor_pedtype 24 model #SPECIAL05 at [email protected] [email protected] [email protected]
0223: set_actor [email protected] health_to 10000
0860: link_actor [email protected] to_interior [email protected]
0296: unload_special_actor 1
0296: unload_special_actor 2
0296: unload_special_actor 3
0296: unload_special_actor 4
0296: unload_special_actor 5

:SPACMOR_563
0001: wait 0 ms
00D6: if
0256:   player $PLAYER_CHAR defined
004D: jump_if_false @SPACMOR_626
00D6: if and
8118:   not actor [email protected] dead
8118:   not actor [email protected] dead
8118:   not actor [email protected] dead
8118:   not actor [email protected] dead
8118:   not actor [email protected] dead
004D: jump_if_false @SPACMOR_626
0002: jump @SPACMOR_563

:SPACMOR_626
01C2: remove_references_to_actor [email protected] // Like turning an actor into a random pedestrian
01C2: remove_references_to_actor [email protected] // Like turning an actor into a random pedestrian
01C2: remove_references_to_actor [email protected] // Like turning an actor into a random pedestrian
01C2: remove_references_to_actor [email protected] // Like turning an actor into a random pedestrian
01C2: remove_references_to_actor [email protected] // Like turning an actor into a random pedestrian
0002: jump @SPACMOR_11

______________________________________________________________________________________
______________________________________________________________________________________


Tuning parts

According to the theme Spawn a 3D model we need in this case only 4 steps and with other opcodes

1. first step to load the tuning part

06E9: request_car_component #hydralics
06E9: request_car_component #NTO_B_S
06E9: request_car_component 1115

2. second step to prove if the model is loaded in an extra "load-model-check-Loop"

:Load_Model_Check
0001: wait  0 ms
if  and
06EA:   car_component_available #hydralics
06EA:   car_component_available #NTO_B_S
06EA:   car_component_available 1115
004D: jump_if_false @Load_Model_Check

3. The tuning part can be created as soon as the model file is loaded by attaching to the car

06E7: [email protected] = add_car_component #NTO_B_S to_car [email protected]
06E7: [email protected] = add_car_component #hydralics to_car [email protected]
06E7: [email protected] = add_car_component 1115 to_car [email protected]

4. release the loaded tuning part model file if it is not needed anymore

06EB: release_car_component #hydralics
06EB: release_car_component #NTO_B_S
06EB: release_car_component 1115

To release the defined item from script is not nessesary

The script below spawns the car SLAMVAN with nitro, hydraulics and front bumper
and the paintjob 1 in Grovestreet if player goes into red marker
Adding paintjobs needs first to give the car white colors
Painjobs requires existing paintjob textures
These are additional txd files which have the same name like the dff model and its basic txd with an additional number
slamvan.dff and slamvan.txd as basic model files
slamvan1.txd as paintjob 0, slamvan2.txd as paintjob 1, etc...
If player leave the spot the car will be released from script and the reading process jumps back into 1.Loop
 

{$CLEO .cs}
:TuneP_1
03A4: name_thread 'TuneP'

:TuneP_2
0001: wait  0 ms
00D6: if  
0256:   player $PLAYER_CHAR defined
004D: jump_if_false @TuneP_2
00D6: if  
00FF:   actor $PLAYER_ACTOR  1 (in-sphere)near_point_on_foot 2491.5  -1667.5  13.35 radius  1.0  1.0  1.0
004D: jump_if_false @TuneP_2

0247: request_model #SLAMVAN
06E9: request_car_component #hydralics
06E9: request_car_component #NTO_B_S
06E9: request_car_component 1115

:Load_Model_Check
0001: wait  0 ms
if  and
0248:   model #SLAMVAN available
06EA:   car_component_available #hydralics
06EA:   car_component_available #NTO_B_S
06EA:   car_component_available 1115
004D: jump_if_false @Load_Model_Check

00A5: [email protected] = create_car #SLAMVAN at 2487.5  -1660.5  13.35
0175: set_car [email protected] z_angle_to 180.0

06E7: [email protected] = add_car_component #NTO_B_S to_car [email protected]
06E7: [email protected] = add_car_component #hydralics to_car [email protected]
06E7: [email protected] = add_car_component 1115 to_car [email protected]

0229: set_car [email protected] color_to  1  1
06ED: set_car [email protected] paintjob  1

06EB: release_car_component #hydralics
06EB: release_car_component #NTO_B_S
06EB: release_car_component 1115
0249: release_model #SLAMVAN

:TuneP_4
0001: wait  0 ms
00D6: if  
0256:   player $PLAYER_CHAR defined
004D: jump_if_false @TuneP_4
00D6: if  
80FF:   NOT   actor $PLAYER_ACTOR  0 ()near_point_on_foot 2491.5  -1667.5  13.35 radius  2.0  2.0  2.0
004D: jump_if_false @TuneP_4
01C3: remove_references_to_car [email protected]  // Like turning a car into any random car
0002: jump @TuneP_2

______________________________________________________________________________________
______________________________________________________________________________________



Animations

To use animations exist 2 opcodes, 0605: and 0812:

0605: actor $PLAYER_ACTOR perform_animation_sequence "TAI_CHI_IN" IFP_file "PARK" 4.0 loop 0 1 1 0 time -1
0812: AS_actor $PLAYER_ACTOR perform_animation "SWIM_BREAST" IFP_file "SWIM" 1.0 loopA 1 lockX 1 lockY 1 lockF 1 time -2

The animations are embeded in the IFP files

Important:

The IFP file ped.ifp is placed in GTASA\anim folder and all animations of ped.ifp are loaded by gamestart
It dont need to load the animation for the script. Never load the ifp file "ped" !!

The other IFP files are archived in gta3.img
It needs first to load the IFP file before using an animation of its file

The script below is an exemble to assign an animation of IFP file "ped" by key_press to player actor

{$CLEO .cs}
:IFP_PED
03A4: name_thread 'IFP_PED'

:IFP_PED_01
0001: wait 0 ms
if
0256: player $PLAYER_CHAR defined
004D: jump_if_false @IFP_PED_01
if  and
0AB0:   key_pressed 8//-----------------key = Backspace
80DF:   not actor $PLAYER_ACTOR driving
004D: jump_if_false @IFP_PED_01
0605: actor $PLAYER_ACTOR perform_animation_sequence "CAR_ROLLOUT_RHS" IFP_file "PED" 4.0 loop 0 1 1 0 time -1
0001: wait 2000 ms
0002: jump @IFP_PED_01

Several animations are defined as extra opcodes
Some exembles:
05C7: AS_actor $PLAYER_ACTOR use_atm
05C2: AS_actor $PLAYER_ACTOR show_the_finger
05C9: AS_actor $PLAYER_ACTOR on_guard 2000 ms
05C4: AS_actor $PLAYER_ACTOR hands_up 15000 ms
0729: AS_actor $PLAYER_ACTOR hold_cellphone 1// requires to load first the model #cellphone
0729: AS_actor $PLAYER_ACTOR hold_cellphone 0
05BC: AS_actor $PLAYER_ACTOR jump 1
05C3: AS_actor $PLAYER_ACTOR hands_cower
05C5: AS_actor $PLAYER_ACTOR cower 3000 ms



The other IFP files are archived in gta3.img and needs first to load the IFP file before using an animation of its file
According to the theme Spawn a 3D model we need also 5 steps but with other opcodes

1. first step to load the IFP file needs to insert the IFP file name as long string

04ED: load_animation "PARK"

2. second step to prove if the file is loaded in an extra "load-model-check-Loop"

:Load_Model_Check
0001: wait  0 ms
00D6: if  0
04EE:   animation "PARK" loaded
004D: jump_if_false @Load_Model_Check

3. The animation can now assigned to an actor as soon as the IFP file is loaded and the actor is available.
It requires to insert animation name and name of IFP file as long string
 

0812: AS_actor $PLAYER_ACTOR perform_animation "TAI_CHI_IN" IFP_file "PARK" 1.0 loopA 1 lockX 1 lockY 1 lockF 1 time -2

4. release the loaded IFP file if it is not needed anymore

04EF: release_animation "PARK"

5. Release a defined item is not possible but in some cases it needs to remove the animation from actor

0792: disembark_instantly_actor $PLAYER_ACTOR

In addition by using animation packs, it needs to release the pack
 

061B: remove_references_to_AS_pack [email protected]

The script below is an exemble to assign an animation of IFP file "PARK" by key_press to player actor
The animation will be repeated as long as the key is not pressed again, because of the value 1 in the parameter of loopA

{$CLEO .cs}
:IFP_PARK
03A4: name_thread 'IFPPARK'

:IFP_PARK_11
0001: wait 0 ms
00D6: if
0256:   player $PLAYER_CHAR defined
004D: jump_if_false @IFP_PARK_11
00D6: if
0AB0:   key_pressed 8//-----------------key = Backspace
004D: jump_if_false @IFP_PARK_11
04ED: load_animation "PARK"

:IFP_PARK_54
0001: wait 0 ms
00D6: if
04EE:   animation "PARK" loaded
004D: jump_if_false @IFP_PARK_54

0812: AS_actor $PLAYER_ACTOR perform_animation "TAI_CHI_IN" IFP_file "PARK" 1.0 loopA 1 lockX 1 lockY 1 lockF 1 time -2 // versionB
0001: wait 1000 ms

:IFP_PARK_141
0001: wait 0 ms
00D6: if
0256:   player $PLAYER_CHAR defined
004D: jump_if_false @IFP_PARK_141
00D6: if and
8AB0:   not key_pressed 8//-----------------key = Backspace
80E1:   not player 0 pressed_key 15
004D: jump_if_false @IFP_PARK_221
0002: jump @IFP_PARK_141

:IFP_PARK_221
0792: disembark_instantly_actor $PLAYER_ACTOR
04EF: release_animation "PARK"
0001: wait 1000 ms
0002: jump @IFP_PARK_11

Combine several animation to an AS_pack
The script below assigns sevaral animations of different IFP files combined in an AS_pack by key_press to player actor

{$CLEO .cs}
:AMPAK_00
03A4: name_thread 'APK'
0001: wait  2000 ms

:AMPAK_1
0001: wait 50 ms
00D6: if
0256:   player $PLAYER_CHAR defined
004D: jump_if_false @AMPAK_1
if
0AB0:   key_pressed 8//-----------------key = Backspace
004D: jump_if_false @AMPAK_1
04ED: load_animation "STRIP"
04ED: load_animation "DANCING"

:AMPAK_12
0001: wait  0 ms
if  and
04EE:   animation "STRIP" loaded
04EE:   animation "DANCING" loaded
004D: jump_if_false @AMPAK_13
0002: jump @AMPAK_14

:AMPAK_13
04ED: load_animation "STRIP"
04ED: load_animation "DANCING"
0002: jump @AMPAK_12

:AMPAK_14
0615: define_AS_pack_begin [email protected]
0605: actor -1 perform_animation_sequence "STR_B2C" from_file "STRIP"  4.0  0  0  0  1 -1 ms  
0605: actor -1 perform_animation_sequence "DNCE_M_A" from_file "DANCING"  4.0  0  0  0  1 -1 ms
0605: actor -1 perform_animation_sequence "STR_B2C" from_file "STRIP"  4.0  0  0  0  1 -1 ms
0605: actor -1 perform_animation_sequence "DNCE_M_A" from_file "DANCING"  4.0  0  0  0  1 -1 ms
0605: actor -1 perform_animation_sequence "STR_B2C" from_file "STRIP"  4.0  0  0  0  1 -1 ms
0605: actor -1 perform_animation_sequence "DAN_LOOP_A" from_file "DANCING"  4.0  0  0  0  1 -1 ms
0605: actor -1 perform_animation_sequence "DNCE_M_D" from_file "DANCING"  4.0  0  0  0  1 -1 ms
0643: set_AS_pack [email protected] loop 1
0616: define_AS_pack_end [email protected]
0618: assign_actor $PLAYER_ACTOR to_AS_pack [email protected]
0001: wait 1000 ms

:AMPAK_21
0001: wait 0 ms
00D6: if
0256:   player $PLAYER_CHAR defined
004D: jump_if_false @AMPAK_end
if
80E1:   not key_pressed  0  15
004D: jump_if_false @AMPAK_end
if  or
0611:   actor $PLAYER_ACTOR animation == "STR_B2C"
0611:   actor $PLAYER_ACTOR animation == "DNCE_M_A"
0611:   actor $PLAYER_ACTOR animation == "STR_B2C"
0611:   actor $PLAYER_ACTOR animation == "DNCE_M_D"
004D: jump_if_false @AMPAK_end
0002: jump @AMPAK_21

:AMPAK_end
061B: remove_references_to_AS_pack [email protected]
04EF: release_animation "STRIP"
04EF: release_animation "DANCING"
0002: jump @AMPAK_1

Animation in air needs to move the actor with opcode 083C: and to use animation code 0812: with -2 as last parameter
Script below let the player swimming in air by key_press

{$CLEO .cs}
:Airswim
03A4: name_thread 'Airswim'

:AIRSWIM_11
0001: wait 0 ms
00D6: if
0256:   player $PLAYER_CHAR defined
004D: jump_if_false @AIRSWIM_11
00D6: if
0AB0:   key_pressed 8//-----------------key = Backspace
004D: jump_if_false @AIRSWIM_11
04ED: load_animation "SWIM"

:AIRSWIM_54
0001: wait 0 ms
00D6: if
04EE:   animation "SWIM" loaded
004D: jump_if_false @AIRSWIM_54
083C: set_actor $PLAYER_ACTOR velocity_in_direction_XYZ 0.0 0.0 20.0
0001: wait 1000 ms
0812: AS_actor $PLAYER_ACTOR perform_animation "SWIM_BREAST" IFP_file "SWIM" 1.0 loopA 1 lockX 1 lockY 1 lockF 1 time -2 // versionB

:AIRSWIM_141
0001: wait 0 ms
00D6: if
0256:   player $PLAYER_CHAR defined
004D: jump_if_false @AIRSWIM_141
083C: set_actor $PLAYER_ACTOR velocity_in_direction_XYZ 0.0 2.0 2.0
00D6: if and
8AB0:   not key_pressed 8
0611:   actor $PLAYER_ACTOR performing_animation "SWIM_BREAST"
004D: jump_if_false @AIRSWIM_221
0002: jump @AIRSWIM_141

:AIRSWIM_221
0792: disembark_instantly_actor $PLAYER_ACTOR
04EF: release_animation "SWIM"
0001: wait 1000 ms
0002: jump @AIRSWIM_11

How to find Animations:
use Ryosukes Animation Manager
The animations are stored in *.ifp files
One ifp file is the GTASA\anim\ped.ifp
(GTASA\anim\anim.img is unused)
The other ifp files are in gta3.img like colt45.ifp, python.ifp, rifle.ifp, tec.ifp, weapons.ifp
Import these and play these with Animation Manager
Deji provides a list of the animation names: List of animations in San Andreas

______________________________________________________________________________________
______________________________________________________________________________________


Music, wave and sounds of Audio folder

GTASA\AUDIO\Streams includes *.ogg files for music in vehicle, interiors, some missions and for cutscene
GTASA\AUDIO\SFX includes *.wav files for sounds and dialoge
look at GTA: SA SFX Directory

The Radio Musicfiles can only be played in vehicles:
There is no chance for scripting to play them on foot
For radio exist only these codes to set radio station, to get radio staion number and to set to favourites station
 

041E: set_radio_station 3
051E: [email protected] = get_current_radio_station
0A26: set_radio_to_favorite_station

Music of GTASA\AUDIO\Streams\BEATand AMBIENCEcan be played with other opcodes
 

0953: get_soundtrack_status_to [email protected]
if
0039:   [email protected] ==  0;; integer values
004D: jump_if_false @
//
0952: load_soundtrack 12
//
0954: start_playing_loaded_soundtrack
//
0955: end_playing_loaded_soundtrack


//use following track numbers: 1, 2, 3, 4, 8, 9, 10, 12, 13

Play titel song

0394: play_music 1
//or
0394: play_music 2

its mostly used as flourish by mission comlete
find the song file in GTASA\AUDIO\Streams\BEAT



Sounds or speeches of GTASA\AUDIO\SFXare used for "wav"- or "sound"- playing
But the sounds of GENRL can not be played with scripting


A part of them are documented in data\AudioEvents.txt
These for the story dialoges and sounds for gameplay


///////SOUNDS/////
A small part of the listed sounds in AudioEvents can be startet with play sound opcodes: 018C: 097A: 09F1:
Find sounds in the range from SOUND_1002 to SOUND_1191. Not all worked by me. It seems that someone only can used from the exe
Someone of these sounds are durable and must be started with 018D: and stoped with 018E:

Some other ones of these sounds have a replay mode (music for minigames) and can be stoped with a stop sound
SOUND_PILOT_AWARD_TRACK_START 1187 start sound
SOUND_PILOT_AWARD_TRACK_STOP 1188 stop sound

Click spoiler to view a list of audio ID's, made by OrionSR, playable with 018C:

Spoiler


///////WAVE/////
The most part of AudioEvents.txt includes waves and must used with

03CF: load_wav  1828 as  1
00D6: if  
03D0:   wav  1 loaded
004D: jump_if_false @
03D1: play_wav 1

can be attached to actor or object

0949: link_wav 1 to_actor [email protected]

if wave is finish should be unloaded

040D: unload_wav 1

in original is usual to unload wav before loading a wav

:AUDIOL_33
00D6: if  
0039:   [email protected] ==  0  // integer values
004D: jump_if_false @AUDIOL_38
040D: unload_wav [email protected]
03CF: load_wav [email protected] as [email protected]

you can also check if the sound is finish

00D6: if 
03D2:   wav 1 ended
004D: jump_if_false @

The sounds which are used with 03CF: load_wav 1828 as 1
are mostly dialog sounds of missions
The names of these waves, listed in AudioEvents.txt are the entry names from gxt dialog texts
exemble:
SOUND_MAN5_BK 24412
search in american.gxt for MAN5_BK
and find the dialog text:
~z~You got ice cold gangstas running through your veins!

The sound numbers have NO association with Audio file numbers, folder, banks
Only way I know to find sounds is to write a sound test script



///autom. phrases///////
Other way to let actor speak which is not written in AudioEvents.txt is

09D5: play_sound_of_actor $PLAYER_ACTOR soundslot 342 flags 1  1  1 as [email protected]

first param, $PLAYER_ACTOR is the actor variable name
second param (342) is a slot with some different phrases sounds
third, fourth, fift param of flags are unknown
last param, [email protected] is variable name of this sound function, isnt need to release or deload it in any way
and cant used further more in any other opcode.

Note: the soundslots includes more sounds which are changed automaticly if the same soundslot runs again
The soundslot with same number includes different sounds for different actors

PLAYER_ACTOR, special actors, Females and males have different sounds
only with the special girlfriends actors (GANGRL2) is it possible to play the sex voices of GFSEX script
The shop sellers have own sounds and can not played with other actors

opcode 09D5 is the only way to play these voice sounds which are also mostly used from exe for random peds on street
like pain sounds, breathing, coughing ect...
presumable uses PAIN_A SFX, SPC_FA SFX, SPC_PA SFX Archive Directory,

look at GTA: SA SFX Directory

The audio file id's have no association to the id's used for scripting
but some members found a method to identify audio script id's from audio file id's
find it here: GTA SA - How to determine Sound ID?

______________________________________________________________________________________
______________________________________________________________________________________

  • In45do, sherip008 and 4sinayousefi like this

PatrickW
  • PatrickW

    GTA Juggernaut

  • Moderator
  • Joined: 07 Jan 2004
  • Netherlands
  • Best Script 2013 [DYOM]
    Best Script 2012 [DYOM]

#5

Posted 23 March 2009 - 08:14 PM

Good work, ZAZ. icon14.gif


ZAZ
  • ZAZ

    Kernlochbohrer

  • Feroci
  • Joined: 10 Jan 2005
  • European-Union
  • Contribution Award [Mods]
    Helpfulness Awards [Mods]

#6

Posted 29 March 2009 - 03:00 PM Edited by ZAZ, 04 November 2016 - 03:15 PM.

Good work, ZAZ. icon14.gif

Thx master



Math coding
- Give access with math coding
- Access check with local variables
- Declare or not declare (first reason)
- Time check for milliseconds in real time
- Time check for game hours

- Integer values and floating points
- Declare or not declare (second reason)
- Integer to float and reversed
- Show the calculated values with text_draw opcode

- Math coding for calculations


______________________________________________________________________________________
______________________________________________________________________________________


Give access with math coding

Math coding is not only for calculating.
A very imortant aspect to use math coding is to give access to script parts

Therfore we declare a variable with an value
 
//example:

$RYDER_TOTAL_PASSED_MISSIONS = 0
[email protected] = 0

As following we can check if this variable is equal to this value
If yes the reading process can pass the check

The 2 most famouse check for access are in the misson starter scripts of original main.scm and the check if onmission is zero

$ONMISSION is declared in the main part of the original main.scm as special mission mode controler
 
0180: set_on_mission_flag_to $ONMISSION


the first change of onmission by new game start is in Intro mission at Airport
 
:INTRO_47
$ONMISSION = 1




The scriptpart below is a ripped version of the RYDER mission starter script
it checks if $ONMISSION == 0 and if $RYDER_TOTAL_PASSED_MISSIONS == 0
if the check is passed, it gives access to the mission start
but first it changes $ONMISSION into 1 to prevent access to more mission starts from the starter script

the value of $RYDER_TOTAL_PASSED_MISSIONS changes in the Ryder mission in case of mission complete

Attension by using Global vars in cleo scripts, it can cause bugs or crashes. Only $PLAYER_CHAR, $PLAYER_ACTOR, $ONMISSION are valid
 
:RYDER_11
wait 0
if
  Player.Defined($PLAYER_CHAR)
else_jump @RYDER_342
if
 $ONMISSION == 0
else_jump @RYDER_342
if
00FF:   actor $PLAYER_ACTOR sphere 0 in_sphere $X_RYDER_HOUSE $Y_RYDER_HOUSE $Z_RYDER_HOUSE radius 1.6 1.2 2.0 on_foot
else_jump @RYDER_342  
if
 $RYDER_TOTAL_PASSED_MISSIONS == 0
else_jump @RYDER_238
$ONMISSION = 1  
start_mission 24  // Home Invasion
jump @RYDER_238


:RYDER_238
if
 $RYDER_TOTAL_PASSED_MISSIONS == 1
else_jump @RYDER_290
$ONMISSION = 1
start_mission 25  // Catalyst

:RYDER_290
if
 $RYDER_TOTAL_PASSED_MISSIONS == 2
else_jump @RYDER_342
$ONMISSION = 1
start_mission 26  // Robbing Uncle Sam

:RYDER_342
jump @RYDER_11
		



the value of $RYDER_TOTAL_PASSED_MISSIONS changes in the Ryder mission in case of mission complete
there will be added a value
 
$RYDER_TOTAL_PASSED_MISSIONS += 1




the mission passed variable then is equal to 1
$RYDER_TOTAL_PASSED_MISSIONS = 1

the check for $RYDER_TOTAL_PASSED_MISSIONS == 1 gives then access to start the next mission
 
if
 $RYDER_TOTAL_PASSED_MISSIONS == 1
else_jump @RYDER_290
$ONMISSION = 1
start_mission 25  // Catalyst



Access check with local variables

Use one equals sign to give a variable a value


[email protected] = 0


Use 2 equals sign to check if this variable is equal to a specified value
[email protected] ==  0      


The script below removes the access to the Johnsons House and gives it free if the actor [email protected] is killed
The checks for the value of the variable [email protected] subdivide the script in 3 steps
So we need only one Loop to manage more seguences
(and a model load check loop which doesnt belongs to the script steps)

In first step the script checks if the player is in interior 0; this means in the outside map
to prevent that the player will be locked in Johnsons House
077E: get_active_interior_to [email protected] declares the variable [email protected] and its value
If player is outside, the access to the house will be removed and the value for the access check will be changed
[email protected] = 1

Now the script gives access to second step which checks if the player is going into red marker to start the action
if
0039: [email protected] == 1
if
00FF: actor $PLAYER_ACTOR 1 (in-sphere)near_point_on_foot 2491.5 -1667.5 13.35 radius 1.0 1.0 1.0


If both conditions are accomplished the actor [email protected] will be spawned to give the player a fight
and the value for the access check will be changed again to gives access to third step which checks if the actor [email protected] is dead

If actor [email protected] is dead enables the interior access to the Johnsons House and the script ends

If player doesnt fight and goes away brings back the second step
therefore the check if distance of actor [email protected] to the player is greater than 80.0
actor [email protected] then will be released from our script and [email protected] get the value 1
 
{$CLEO .cs}
:Access_1
03A4: name_thread 'Access_'
[email protected] = 0

:Access_2
0001: wait  0 ms
00D6: if  0
0256:   player $PLAYER_CHAR defined
004D: jump_if_false @Access_2

if//-- first access check
0039:   [email protected] ==  0
004D: jump_if_false @Access_3//------ jumps to next access check
077E: get_active_interior_to [email protected]
if
0039:   [email protected] ==  0
004D: jump_if_false @Access_2
07FB: set_interior 'CARLS' access 0
[email protected] = 1//--- gives access for second access check

:Access_3//-- second access check
if
0039:   [email protected] ==  1
004D: jump_if_false @Access_7//------ jumps to next access check
if
00FF:   actor $PLAYER_ACTOR  1 (in-sphere)near_point_on_foot 2491.5  -1667.5  13.35 radius  1.0  1.0  1.0
004D: jump_if_false @Access_2
0247: request_model #TRIBOSS
0247: request_model #AK47

:Access_4//-- load model check loop
0001: wait  0 ms
00D6: if  and
0248:   model #TRIBOSS available
0248:   model #AK47 available
004D: jump_if_false @Access_4//-- load model check loop
009A: [email protected] = create_actor  24 #TRIBOSS at  2486.5  -1664.5  13.45
01B2: give_actor [email protected] weapon  30 ammo  99999
05E2: AS_actor [email protected] kill_actor $PLAYER_ACTOR
0249: release_model #TRIBOSS
[email protected] = 2//--- gives access for third access check

:Access_7//-- third access check
if
0039:   [email protected] ==  2
004D: jump_if_false @Access_2//------ jumps back to loop adress
00D6: if  0
0118:   actor [email protected] dead
004D: jump_if_false @Access_9
01C2: remove_references_to_actor [email protected]
07FB: set_interior 'CARLS' access 1
0A93: end_custom_thread

:Access_9
00D6: if  0
8104:   NOT actor $PLAYER_ACTOR near_actor [email protected] radius  80.0  80.0  10.0 sphere  0
004D: jump_if_false @Access_2
009B: destroy_actor [email protected]
[email protected] = 1//--- gives access for second access check
0002: jump @Access_2 
		        





______________________________________________________________________________________
______________________________________________________________________________________


Declare or not declare (first reason)

It doesnt need allways to declare the variables value
Without declaration the variabels are set to zero by default

It refers to the situation and its purpose
I recommand to declare the variable if it is used for an access check
It makes the script more stable because it prevends bugs which can happen by crossover calculation of more threads if they are running at same time

An argument to declare it not is to select a step by script start.
An exemple script for this case is "Store a car at any place"

Read the theme: Special Particularities in Cleo
- Script Exemble by using Special Global Cleo Variable/ Store a car at any place

this script beginns with:
 
{$CLEO .cs}
:CARSTORE
03A4: name_thread 'CARSTOR'
0001: wait 1000 ms
0AB4: [email protected] = var 955
00D6: if
8039:   not  [email protected] == 0
004D: jump_if_false @CARSTOR_150




If the Carstore script is running from new by loading a save game or start new game ...

..it checks first if var 955 is zero
its only not zero if a car was stored in the loaded savegame

If var 955 is zero, the script starts with the 1.Loop
If var 955 is not zero, the reading process jumps into the 3.Loop with the check if player is near the car store location


One more exemple is the check if a script was started from Cleo programm
or from an other thread by using create_custom_thread
0A92: create_custom_thread "ThreadStartTest.cs"
Read the description of the theme: Special Particularities in Cleo >> create_custom_thread

The .CS script is started from Cleo programm by default.
To cancel the the initialisation of Cleo programm because it should only be started from an other thread with create_custom_thread
can be done with an access check for a variables value which was not declared.

Without declaration the variabels are set to zero by default,
especially if it was started from Cleo programm

We can now use the create_custom_thread command to declare a local variable of the other thread
by using create_custom_thread with parameter
0A92: create_custom_thread "ThreadStartTest.cs" 1
The started thread recieves these parameter value with following rule
[email protected] get value of 1.parameter

The script below must be saved as ThreadStartTest.txt and compiled as ThreadStartTest.cs
because of the entry of the create_thread command
 
create_custom_thread "ThreadStartTest.cs" 1


If it was started from Cleo programm the variabel [email protected] is set to zero by default
and reads as next the end_custom_thread to cancel the thread execution

If it was started from an other thread with the create_thread command of above
the variable [email protected] gets the value 1
in this case the access check leads the reading process into the Loop to can enable the thermal_vision
 
{$CLEO .cs}
:ThreadStartTest
if
0039:   [email protected] ==  0
004D: jump_if_false @ThreadStartTest_1
0A93: end_custom_thread

:ThreadStartTest_1
03A4: name_thread "THREADST"

:ThreadStartTest_2
0001: wait 0 ms
if
0256: player $PLAYER_CHAR defined
004D: jump_if_false @ThreadStartTest_2
if
0AB0:   key_pressed 8//-----------------key = Backspace
004D: jump_if_false @ThreadStartTest_2
08B2: toggle_thermal_vision 1
0001: wait 3000 ms
08B2: toggle_thermal_vision 0
0002: jump @ThreadStartTest_2
		




This variation of access check and using create_custom_thread with parameter
allows to place more than one threads into a .CS file and let them all running at same time
The create_custom_thread command with parameter can be placed in the same script file which includes the thread to start


______________________________________________________________________________________
______________________________________________________________________________________


Time check for milliseconds in real time

The local variables [email protected] and [email protected] are reserved for using in time checks
Its values are permanently counting ascending in milliseconds
They are allways integer values
We can restore the counting by setting the variable to zero
			
{$CLEO .cs}
:Timecheck_1
[email protected] = 0 


After this its permanently counting again ascending from the specified value
Then it is possible to check if a specified time is passed
 
if
[email protected] > 5000



The script below checks permanently if 5 seconds are passed
If yes will show a text message and restore the counter
 
{$CLEO .cs}
:Timecheck_1
thread "TIME"
[email protected] = 0

:Timecheck_2
wait 0 ms
if
[email protected] > 5000
jf @Timecheck_2
00BA: text_styled 'FEM_OK'  1000 ms  1
[email protected] = 0
jump @Timecheck_2		


Important:
To set the game speed slow makes the real time slow in same relation


______________________________________________________________________________________
______________________________________________________________________________________


Time check for game hours
The opcode 00BF: gives the values of hours and minutes of the game time
 
00BF: [email protected] = current_time_hours, [email protected] = current_time_minutes



Using math symbols like "if greater than" > or "if greater than or equal" >=
let check a duration of the game time

The script below enables the thermal_vision in the night between 22 o`clock and 2 o`clock
The variable [email protected] prevent that the opcode 08B2: will be read permanently
The time check gets the duration which should view the thermal_vision
It doesnt matter if you arrived at midnight after loading a savegame
or if you are present before the view change and can experience the change

 
			
{$CLEO .cs}
:GameTime_1
thread "GTIME"
[email protected] = 0

:GameTime_2
wait 0
00BF: [email protected] = current_time_hours, [email protected] = current_time_minutes
if or
 [email protected] >= 22
 2 > [email protected]
jf @GameTime_3  
if
 [email protected] == 0
jf @GameTime_3
08B2: enable_thermal_vision 1
[email protected] = 1

:GameTime_3
if and
 [email protected] > 1
 22 > [email protected]
 [email protected] == 1
jf @GameTime_2
08B2: enable_thermal_vision 0
[email protected] = 0
jump @GameTime_2
		




______________________________________________________________________________________
______________________________________________________________________________________


Integer values and floating points

The explanation above includes only the using of Integer values
For sevarel cases must be used floating points e.g. coords checks or calculation of coords values

The script below puts the player into the sky in a height of 500.0 virtual meters
The player falls down and will put again into the sky if the distance to the ground is to near
At first a check for the interior to make shure that the player is in the outside map
The script reads pemanently the distance of the player_actor to the ground if he is outside
The opcode to check if a specified floating point value is greater than the floating point value of the variable
gives access to read the put_actor code
if
0023: 25.0 > [email protected]


 
{$CLEO .cs}
:Floatcheck_1
03A4: name_thread "FLOAT"

:Floatcheck_2
0001: wait 0 ms
if
0256: player $PLAYER_CHAR defined
004D: jump_if_false @Floatcheck_2
077E: get_active_interior_to [email protected]
if
0039:   [email protected] ==  0
004D: jump_if_false @Floatcheck_2
0819: [email protected] = actor $PLAYER_ACTOR distance_from_ground
if
0023:   25.0 > [email protected]
004D: jump_if_false @Floatcheck_2
00A1: put_actor $PLAYER_ACTOR at 0.0 0.0 500.0
0002: jump @Floatcheck_2





______________________________________________________________________________________
______________________________________________________________________________________


Declare or not declare (second reason)

The game engine can not handle with intger values when floating points are required and reversed
In addition exist for math coding function different opcodes each if they are used with integer or with floats

Well, Sanny is intelligent and know when a fuction should use floats or integer and do the work for us by compiling
Compile the script of above and then decompile the created .cs file with the option "without opcodes"
and you will get this:

 
{$CLEO .cs}
thread "FLOAT"

:FLOAT_9
wait 0
if
  Player.Defined($PLAYER_CHAR)
jf @FLOAT_9
077E: get_active_interior_to [email protected]
if
 [email protected] == 0
jf @FLOAT_9
0819: [email protected] = actor $PLAYER_ACTOR distance_from_ground
if
 25.0 > [email protected]
jf @FLOAT_9
Actor.PutAt($PLAYER_ACTOR, 0.0, 0.0, 500.0)
jump @FLOAT_9
		



The most opcodes are disappeared
Sanny knows that floats are meant in this function:
25.0 > [email protected]

But by sevaral fuctions is it unknown
for exemple to calculate 2 variables:
 
[email protected] -= [email protected]


Writing this function with the opcode is one solution to clarify if floats are meant or integer
 
0063: [email protected] -= [email protected] // (float)		



An other solution is to declare if the variable is a float or an integer
Just set the variable equal to a value at script beginn,
either as integer
 
[email protected] = 0
[email protected] = 0



or as float
 
[email protected] = 0.0
[email protected] = 0.0




Read more about that theme in Sannybuilder HELP: Coding >> Variables
and in Sannybuilder HELP: Coding >> Constants


______________________________________________________________________________________
______________________________________________________________________________________



Integer to float and reversed

The opcodes 0092: changes a floating point into a integer value
 
0092: [email protected] = float [email protected] to_integer



[email protected] must be a float
[email protected] gives than the integer
The value behind comma disappear

The opcodes 0093: changes an integer value into a floating point
 
0093: [email protected] = integer [email protected] to_float



[email protected] must be an integer
[email protected] gives than the float
The value behind comma will than be .0


______________________________________________________________________________________
______________________________________________________________________________________


Show the calculated values with text_draw opcode
this can help to find failures or to prove running scripts
 
03F0: enable_text_draw 1
045A: text_draw_1number  250.0  40.0 'NUMBER' [email protected]




opcode 045A: can display the value of the inserted variable
but it can only display an integer value
to display floats need to invert the float first into an integer with opcode 0092:

opcode 045A: needs to be read permanently in a loop connected with opcode 03F0: which must be read before
opcode 045A: is a function of the categorie text_draw like the opcodes to display textures of GTASA\models\txd

To set opcode 03F0: to 1 as first and than the text_draw opcode in a permanent readed loop
is the mostly done variation to use the text_draw opcodes e.g. in the race tournament to show the time and the rank
It is also used to display Cleo speedometers

Text_draw opcodes have a disadvantage:
They disturb Text massages of some other kinds of text opcodes
Or invers, they will not be shown if a text is shown of some other kinds of text opcodes

To display a value with 045A: without permanent reading in a loop can be used a trick:
 
03F0: text_draw_toggle  1
0001: wait  50 ms
03F0: text_draw_toggle  0
0001: wait  50 ms
045A: text_draw_1number  250.0  40.0 'NUMBER' [email protected]



This shows the value till 03F0: will be read from anywhere


The script below is a mix of two scripts from above: Timecheck and Floatcheck
It displays the values of the real time counter [email protected] (upper value)
the interior number (middle value)
the distance_from_ground (lower value)

If you arrive in a savehouse interior after gameload the distance_from_ground is not shown
but you can see the interior number
If you go outside the player will be put into the sky and you can see the distance_from_ground
The real time counter will be restored after 50 seconds which let show then the text message OK
The text message of opcode 00BA: disturbs then the text_draw displaying
 
{$CLEO .cs}
:ValueCheck_1
03A4: name_thread "VCHECK"
[email protected] = 0

:ValueCheck_2
0001: wait 0 ms
if
0256: player $PLAYER_CHAR defined
004D: jump_if_false @ValueCheck_2
077E: get_active_interior_to [email protected]
03F0: enable_text_draw 1
045A: text_draw_1number  250.0  40.0 'NUMBER' [email protected]
045A: text_draw_1number  250.0  50.0 'NUMBER' [email protected]
if
0039:   [email protected] ==  0
004D: jump_if_false @ValueCheck_3
0819: [email protected] = actor $PLAYER_ACTOR distance_from_ground
0092: [email protected] = float [email protected] to_integer
03F0: enable_text_draw 1
045A: text_draw_1number  250.0  60.0 'NUMBER' [email protected]
if
0023:   25.0 > [email protected]
004D: jump_if_false @ValueCheck_3
00A1: put_actor $PLAYER_ACTOR at 0.0 0.0 500.0

:ValueCheck_3
if
[email protected] > 50000
jf @ValueCheck_2
00BA: text_styled 'FEM_OK'  1000 ms  1
[email protected] = 0
jump @ValueCheck_2




______________________________________________________________________________________
______________________________________________________________________________________



Math coding for calculations

It allows to use the basic functions with integer and also with floats

add: +=
substract: -=
divide: /=
multiplicate: *=
is equal: =

To calculate a point in a circle by inserted angle can be used sine or cosine function
Only floats are allowed
02F7: [email protected] = sine 45.0 // (float)
02F6: [email protected] = cosine 45.0 // (float)
This function refers to a circle with radius 1.0 at game center

In conditional checks can be used
if greater than: >
if greater than or equal: >=
if is equal: ==

Additional commands can be found in Sannybuilder Help: Coding >> Additional commands

The script below applies smoke around the player by key_press
Keeping Backspaces key pressed creates smoke permanently in a circle
[email protected] is used as angle degrees and by calculating with cosine it gives the X-coord
by calculating with sine it gives the Y-coord
Then multiplicate it with 4.0 and we get XY coords which refers to a circle with radius 4.0 at game center
putting these values as offset into 04C4: represents than the coords around the player axis
At last we add 5.0 degrees to the angle for the next point to create smoke
 
{$CLEO .cs}
:Sine_1
03A4: name_thread 'SINE'
0007: [email protected] = 0.0  // floating-point values

:Sine_2
0001: wait 0 ms
00D6: if  0
0256:   player $PLAYER_CHAR defined
004D: jump_if_false @Sine_2
if
0AB0:   key_pressed 8//------Backspace  
004D: jump_if_false @Sine_2
02F6: [email protected] = cosine [email protected]  // sinus swapped with cosine
0013: [email protected] *= 4.0  // floating-point values (never used in VC or GTA 3)
02F7: [email protected] = sinus [email protected] // cosine swapped with sinus
0013: [email protected] *= 4.0  // floating-point values (never used in VC or GTA 3)
04C4: create_coordinate [email protected] [email protected] [email protected] from_actor $PLAYER_ACTOR offset [email protected] [email protected] 0.2
095C: create_smoke_at [email protected] [email protected] [email protected] velocity 0.0 0.0 0.0 RGBA 1.0  1.0  1.0 1.0 size 0.2 last_factor 0.1
000B: [email protected] += 5.0
if
0021:   [email protected] >  354.0  // floating-point values  
004D: jump_if_false @Sine_2
0007: [email protected] = 0.0
jump @Sine_2






The last script shows the current coords of the player position
inklusiv the values behind the comma but a dot in the middle is not shown
You have to imagine it
 
{$CLEO .cs}
:coords_00
03A4: name_thread 'COO'
0006: [email protected] =  0  // integer values
0006: [email protected] =  0  // integer values
0006: [email protected] =  0  // integer values
0006: [email protected] =  0  // integer values
0006: [email protected] =  0  // integer values
0006: [email protected] =  0  // integer values
0006: [email protected] =  0  // integer values
0006: [email protected] =  0  // integer values

:coords_01
0001: wait  0 ms
00D6: if  0
0256:   player $PLAYER_CHAR defined
004D: jump_if_false @coords_01
03F0: enable_text_draw 1
045A: text_draw_1number  50.0  425.0 'NUMBER' [email protected]    // value
045A: text_draw_1number  200.0  425.0 'NUMBER' [email protected]    // value
045A: text_draw_1number  350.0  425.0 'NUMBER' [email protected]    // value
045A: text_draw_1number  100.0  425.0 'NUMBER' [email protected]    // value
045A: text_draw_1number  250.0  425.0 'NUMBER' [email protected]    // value
045A: text_draw_1number  400.0  425.0 'NUMBER' [email protected]    // value
045A: text_draw_1number  450.0  425.0 'NUMBER' [email protected]    // value
if
0019:   [email protected] >  1000  // integer values
004D: jump_if_false @coords_01
0006: [email protected] =  0  // integer values
00A0: store actor $PLAYER_ACTOR position to [email protected] [email protected] [email protected]
0092: [email protected] = float_to_integer [email protected]  
0092: [email protected] = float_to_integer [email protected]  
0092: [email protected] = float_to_integer [email protected]  

0093: [email protected] = integer_to_float [email protected]  
0093: [email protected] = integer_to_float [email protected]  
0093: [email protected] = integer_to_float [email protected]  

0063: [email protected] -= [email protected]  // floating-point values
0063: [email protected] -= [email protected]  // floating-point values
0063: [email protected] -= [email protected]  // floating-point values
0013: [email protected] *=  100.0  // floating-point values
0013: [email protected] *=  100.0  // floating-point values
0013: [email protected] *=  100.0  // floating-point values

0092: [email protected] = float_to_integer [email protected]  
0092: [email protected] = float_to_integer [email protected]  
0092: [email protected] = float_to_integer [email protected]

:coords_02
00D6: if  0
001B:    0 > [email protected]  // integer values
004D: jump_if_false @coords_03
0012: [email protected] *= -1  // integer values

:coords_03
00D6: if  0
001B:    0 > [email protected]  // integer values
004D: jump_if_false @coords_04
0012: [email protected] *= -1  // integer values

:coords_04
00D6: if  0
001B:    0 > [email protected]  // integer values
004D: jump_if_false @coords_05
0012: [email protected] *= -1  // integer values

:coords_05
0172: [email protected] = actor $PLAYER_ACTOR z_angle
0092: [email protected] = float_to_integer [email protected]
0002: jump @coords_01




______________________________________________________________________________________
______________________________________________________________________________________
  • 4sinayousefi likes this

/!\ErManu/!\
  • /!\ErManu/!\

    /!\Custom Cars/!\

  • Members
  • Joined: 25 Jun 2008

#7

Posted 30 March 2009 - 03:40 PM

Thank you for using your time in this tutorial icon14.gif cookie.gif cookie.gif cookie.gif

This is very useful for all!

Thanks and bye!!good work icon14.gif

Rafinha
  • Rafinha

    But I just don't give a f*ck...

  • BUSTED!
  • Joined: 08 Feb 2009

#8

Posted 09 May 2009 - 02:20 PM

OMG, ZAZ, you waste your time for us!
Thanks for this!

AB033
  • AB033

    Hustler

  • Members
  • Joined: 14 May 2009

#9

Posted 14 May 2009 - 08:46 AM Edited by AB033, 14 May 2009 - 08:51 AM.

Yeah, ZAZ, thank you!

But, I'm looking at this text 2 months and I just don't get it!
Can you pleeeeeeeeease put here, on forum, a video tutorial about making an own mission. That mission doesn't has to be big or something, I just wanna see how! Everybody is talking and putting tutorial text but nobody puts a video tutorial. I said, I'm learning 2 months and I just just just just can't f***ing understand it! Plleease, ZAZ!
I hope this ain't too much. If you can please do this but if you can't, no problem, you don't have to, I understand.

You're my only hope.

noelgamo
  • noelgamo

    LOL

  • Members
  • Joined: 30 Jan 2009

#10

Posted 15 May 2009 - 07:55 AM

Great tut.... cookie.gif cookie.gif cookie.gif

uhm how to make savepoints? cause I dont think I seen one from the tut. but if there is can you tell me wich bit is it.sorry for being a noob. smile.gif smile.gif

spaceeinstein
  • spaceeinstein

    Chocolate

  • GTA Mods Staff
  • Joined: 17 Jul 2003
  • Hong-Kong
  • Major Contribution Award [Mods]
    Helpfulness Awards [Mods]

#11

Posted 16 May 2009 - 09:17 PM

Wow, this is impressive.

coin-god
  • coin-god

    High Roller

  • $outh $ide Hoodz
  • Joined: 18 Mar 2007
  • None

#12

Posted 16 May 2009 - 10:07 PM

Amazing work ZAZ. icon14.gif

ZAZ
  • ZAZ

    Kernlochbohrer

  • Feroci
  • Joined: 10 Jan 2005
  • European-Union
  • Contribution Award [Mods]
    Helpfulness Awards [Mods]

#13

Posted 17 May 2009 - 07:07 PM Edited by ZAZ, 04 November 2016 - 03:21 PM.

uhm how to make savepoints? cause I dont think I seen one from the tut. but if there is can you tell me wich bit is it.sorry for being a noob. smile.gif   smile.gif


Right, I forgot it.
Here it is:

The savescript with savedisk_pickup needs to insert 2 or 3 coords points.
One for the savedisk_pickup
One to put Playerchar beside the pickup
One for the radar marker, same as pickup but If the savedisk is in an interior the location of the radar marker can be very different to pickup

Script below adds a save radar icon and a savedisk with save fuction at Ottos Autos in San Fierro
Edit the coords as descripted in the comments


CODE
{$CLEO .cs}
thread 'SAVE'
wait 1000
0A95: enable_thread_saving  
// [email protected], [email protected], [email protected] = x,y,z coords for pickup
0007: [email protected] = -1668.6
0007: [email protected] = 1207.2
0007: [email protected] = 7.25
// [email protected], [email protected], [email protected] = x,y,z coords and [email protected] = z_angle for put_actor $PLAYER_ACTOR at
0007: [email protected] = -1666.4
0007: [email protected] = 1209.2
0007: [email protected] = 7.25
0007: [email protected] = 315.9
0213: [email protected] = create_pickup 1277 type 3 at [email protected] [email protected] [email protected]
0570: [email protected] = create_asset_radar_marker_with_icon 35 at [email protected] [email protected] [email protected]
018B: show_on_radar [email protected] 2
//00BC: show_text_highpriority GXT 'fem_on' time 3000 flag 1

while true
wait 0
   if
      Player.Defined($PLAYER_CHAR)
   then
       if
           0214:   pickup [email protected] picked_up
       then
           if
               0038:   $ONMISSION == 0
           then
               03D8: show_save_screen
           end
           wait 0
           00A1: put_actor $PLAYER_ACTOR at [email protected] [email protected] [email protected]
           0173: set_actor $PLAYER_ACTOR Z_angle_to [email protected]
           01B4: set_player $PLAYER_CHAR can_move 1
           wait 1000
           0213: [email protected] = create_pickup 1277 type 3 at [email protected] [email protected] [email protected]
           090D: highlight_all_inactive_gang_zones_as_available_for_gangwars
           //00BC: show_text_highpriority GXT 'fem_ok' time 1000 flag 1
           
       end                                                                                                  
   end
end

noelgamo
  • noelgamo

    LOL

  • Members
  • Joined: 30 Jan 2009

#14

Posted 17 May 2009 - 08:27 PM

Thanks it helps me saving in my new safehouse
Great tutorial cookie.gif cookie.gif cookie.gif cookie.gif

ZAZ
  • ZAZ

    Kernlochbohrer

  • Feroci
  • Joined: 10 Jan 2005
  • European-Union
  • Contribution Award [Mods]
    Helpfulness Awards [Mods]

#15

Posted 05 June 2009 - 02:13 PM Edited by ZAZ, 04 September 2010 - 01:09 PM.

Arrays

Generally the prinzip of arrays is really simple but the lot of context script arround the arrays makes confuse.
Furthermore the array construction seems complicate.

Basicly we can assign more content to the same variable
The variable then is like a family with childs
and the Index of the Family defines which part of the family is meant

Family[index 0] = father
Family[index 1] = mother
Family[index 2] = son
Family[index 3] = doughter
Family[index 4] = Carl


Family[index 1] goes in the kitchen
means:
mother goes in the kitchen

Lets go to GTA and local variables
We can use the same variable in the array construct
but we must reserve more local variables

[email protected][index 0] = father
[email protected][index 1] = mother
[email protected][index 2] = son
[email protected][index 3] = doughter
[email protected][index 4] = Carl


the assignment of ascending index values uses new locals in ascending order

[email protected] = father
[email protected] = mother
[email protected] = son
[email protected] = doughter
[email protected] = Carl


the most important entry in the array construct is the INDEX

the array construct:
[email protected]([email protected],5i)

[email protected] is the array index

we define the value of the index:
0006: [email protected] = 4

now
[email protected]([email protected],5i) goes in the kitchen
means
Carl goes in the kitchen
its the same like:
[email protected] goes in the kitchen


Some script examples for the praxis:
The following 4 scripts spawns allways the same 5 item-pickups in the Grovestreet

modelID, name
1239, info
1240, health
1241, adrenaline
1242, bodyarmour
1247, bribe

each script in an other variation
step by step from simple pickup spawn till a script with an array-loop

1. the simple pickup spawn in the Grovestreet
CODE
{$CLEO .cs}
:more_items1
03A4: name_thread 'm_item1'

//1239, info
//1240, health
//1241, adrenaline
//1242, bodyarmour
//1247, bribe

0213: [email protected] = create_pickup 1239 type 15 at 2490.0 -1662.0 13.5
0213: [email protected] = create_pickup 1240 type 15 at 2492.0 -1662.0 13.5
0213: [email protected] = create_pickup 1241 type 15 at 2494.0 -1662.0 13.5
0213: [email protected] = create_pickup 1242 type 15 at 2496.0 -1662.0 13.5
0213: [email protected] = create_pickup 1247 type 15 at 2498.0 -1662.0 13.5

0A93: end_custom_thread


2. now we use local variables to define the modelID
CODE
{$CLEO .cs}
:more_items2
03A4: name_thread 'm_item2'

0006: [email protected] = 1239  // info        
0006: [email protected] = 1240  // health      
0006: [email protected] = 1241  // adrenaline  
0006: [email protected] = 1242  // bodyarmour  
0006: [email protected] = 1247  //bribe

0213: [email protected] = create_pickup [email protected] type 15 at 2490.0 -1662.0 13.5
0213: [email protected] = create_pickup [email protected] type 15 at 2492.0 -1662.0 13.5
0213: [email protected] = create_pickup [email protected] type 15 at 2494.0 -1662.0 13.5
0213: [email protected] = create_pickup [email protected] type 15 at 2496.0 -1662.0 13.5
0213: [email protected] = create_pickup [email protected] type 15 at 2498.0 -1662.0 13.5

0A93: end_custom_thread


3. now we use an array construct to define the modelID
[email protected] is the array index
after each pickup spawn we add 1 to the array index
000A: [email protected] += 1
CODE
{$CLEO .cs}
:Array_items1
03A4: name_thread 'Array_1'

0006: [email protected] = 1239  // info        
0006: [email protected] = 1240  // health      
0006: [email protected] = 1241  // adrenaline  
0006: [email protected] = 1242  // bodyarmour  
0006: [email protected] = 1247  //bribe

0006: [email protected] = 0  // ---Array Index is 0
0213: [email protected] = create_pickup [email protected]([email protected],5i) type 15 at 2490.0 -1662.0 13.5

000A: [email protected] += 1// ---Array Index is 1
0213: [email protected] = create_pickup [email protected]([email protected],5i) type 15 at 2492.0 -1662.0 13.5

000A: [email protected] += 1// ---Array Index is 2
0213: [email protected] = create_pickup [email protected]([email protected],5i) type 15 at 2494.0 -1662.0 13.5

000A: [email protected] += 1// ---Array Index is 3
0213: [email protected] = create_pickup [email protected]([email protected],5i) type 15 at 2496.0 -1662.0 13.5

000A: [email protected] += 1// ---Array Index is 4
0213: [email protected] = create_pickup [email protected]([email protected],5i) type 15 at 2498.0 -1662.0 13.5

0A93: end_custom_thread


4. the array-loop contains only one line which creates 5 different pickups
the loop will be read 5 times
it adds allways 1 to the array index before the reading process jumps back to the loop adress
to read the pickup spawn again with a changed index value
We must protect that the loop will be read more than 5 times and add a check if the index is smaller than 5:
if
001B: 5 > [email protected]

furthermore we can not spawn the 5 different pickups at the same coords
we need to change minimum the x-coords and use an array construct in that parameter
so we must first define variables with coords.
CODE
{$CLEO .cs}
:Array_items2
03A4: name_thread 'Array_2'

0006: [email protected] = 1239  // info        
0006: [email protected] = 1240  // health      
0006: [email protected] = 1241  // adrenaline  
0006: [email protected] = 1242  // bodyarmour  
0006: [email protected] = 1247  //bribe      

0007: [email protected] = 2490.0
0007: [email protected] = 2492.0
0007: [email protected] = 2494.0
0007: [email protected] = 2496.0
0007: [email protected] = 2498.0

0006: [email protected] = 0  // ---Array Index


:Array_items2_loop
0001: wait  0 ms
if
001B:   5 > [email protected]
004D: jump_if_false @Array_items2_end
0213: [email protected]([email protected],5i) = create_pickup [email protected]([email protected],5i) type 15 at [email protected]([email protected],5f) -1662.0 13.5
000A: [email protected] += 1
0002: jump @Array_items2_loop

:Array_items2_end
0A93: end_custom_thread


---------------------------------------------------------------------------------------------------------------------------------------

At last the complete array description:
[email protected]([email protected],5i)
<family variable>(<index varable>,<max amount of array definitions><kind of content: i means integer, f means floats, s means string>)

max amount of array definitions means the max amount of the example above is 5
so we can create only 5 items with arrays
if we use [email protected]([email protected],2i)we can create only 2 items with arrays
but we can write [email protected]([email protected],12i) to create only 5 items with arrays
and if we want to create 20 items we need to increase the max amount: [email protected]([email protected],20i)
but its not possible to create 20 items in an array loop in a Cleo-CS file
because we need 20 locals for the item definitions and 20 locals for the different coords
and a normal thread like the cs file supports only 32 locals

---------------------------------------------------------------------------------------------------------------------------------------

Another way to write arrays looks a bit more clear,
only arrayname and the index in square brackets: [email protected][[email protected]]
requires to define the array at the beginnig:

var
[email protected]: array 5 of Integer
end

script below without opcodes, this array construct will be changed after recompiling into the syntax from above
CODE
{$CLEO .cs}
thread 'ARRAY_2'

var
[email protected]: array 5 of Integer
[email protected]: array 5 of Integer
[email protected]: array 5 of Float
end

[email protected] = 1239
[email protected] = 1240
[email protected] = 1241
[email protected] = 1242
[email protected] = 1247
[email protected] = 2490.0
[email protected] = 2492.0
[email protected] = 2494.0
[email protected] = 2496.0
[email protected] = 2498.0
[email protected] = 0

:ARRAY_1
wait 0
if
 5 > [email protected]
jf @ARRAY_3
[email protected][[email protected]] = Pickup.Create([email protected][[email protected]], 15, [email protected][[email protected]], -1662.0, 13.5)
[email protected] += 1
jump @ARRAY_1

:ARRAY_3
0A93: end_custom_thread


---------------------------------------------------------------------------------------------------------------------------------------

The next script below shows how to use the array defined items forthermore in the script
either with using the simple local variable which is equal to a child of the family variable:
if
0214: pickup [email protected] picked_up

or with using the array construct and set the index to a value:
0006: [email protected] = 1 // ---Array Index
0164: disable_marker [email protected]([email protected],5i)

or to restore the index and assigne markers to the pickups in an array loop:
:Array_items3_restore
0006: [email protected] = 0 // ---Array Index restore

:Array_items3_marker
0001: wait 0 ms
if
001B: 5 > [email protected]
004D: jump_if_false @Array_items3_check1
03DC: [email protected]([email protected],5i) = create_marker_above_pickup [email protected]([email protected],5i)
000A: [email protected] += 1
0002: jump @Array_items3_marker
CODE
{$CLEO .cs}
:Array_items3
03A4: name_thread 'Array_3'

0006: [email protected] = 1239  // info        
0006: [email protected] = 1240  // health      
0006: [email protected] = 1241  // adrenaline  
0006: [email protected] = 1242  // bodyarmour  
0006: [email protected] = 1247  //bribe      

0007: [email protected] = 2490.0
0007: [email protected] = 2492.0
0007: [email protected] = 2494.0
0007: [email protected] = 2496.0
0007: [email protected] = 2498.0

0006: [email protected] = 0  // ---Array Index


:Array_items3_create
0001: wait  0 ms
if
001B:   5 > [email protected]
004D: jump_if_false @Array_items3_restore
0213: [email protected]([email protected],5i) = create_pickup [email protected]([email protected],5i) type 3 at [email protected]([email protected],5f) -1662.0 13.5
000A: [email protected] += 1
0002: jump @Array_items3_create

:Array_items3_restore
0006: [email protected] = 0  // ---Array Index restore

:Array_items3_marker
0001: wait  0 ms
if
001B:   5 > [email protected]
004D: jump_if_false @Array_items3_check1
03DC: [email protected]([email protected],5i) = create_marker_above_pickup [email protected]([email protected],5i)
000A: [email protected] += 1
0002: jump @Array_items3_marker

:Array_items3_check1
0001: wait  0 ms
if
0256:   player $PLAYER_CHAR defined
004D: jump_if_false @Array_items3_check1
if
0214:   pickup [email protected] picked_up
004D: jump_if_false @Array_items3_check2
0006: [email protected] = 0  // ---Array Index
0164: disable_marker [email protected]([email protected],5i)

:Array_items3_check2
if
0214:   pickup [email protected] picked_up
004D: jump_if_false @Array_items3_check3
0006: [email protected] = 1  // ---Array Index
0164: disable_marker [email protected]([email protected],5i)

:Array_items3_check3
if
0214:   pickup [email protected] picked_up
004D: jump_if_false @Array_items3_check4
0006: [email protected] = 2  // ---Array Index
0164: disable_marker [email protected]([email protected],5i)

:Array_items3_check4
if
0214:   pickup [email protected] picked_up
004D: jump_if_false @Array_items3_check5
0006: [email protected] = 3  // ---Array Index
0164: disable_marker [email protected]([email protected],5i)

:Array_items3_check5
if
0214:   pickup [email protected] picked_up
004D: jump_if_false @Array_items3_check6
0006: [email protected] = 4  // ---Array Index
0164: disable_marker [email protected]([email protected],5i)

:Array_items3_check6
if or
075C:   marker [email protected] enabled
075C:   marker [email protected] enabled
075C:   marker [email protected] enabled
075C:   marker [email protected] enabled
075C:   marker [email protected] enabled
004D: jump_if_false @Array_items3_Endrestore
0002: jump @Array_items3_check1

:Array_items3_Endrestore
0006: [email protected] = 0  // ---Array Index
0002: jump @Array_items3_create



The next script below is a more useful script which spawns 10 actors with markers
it deletes the markers of each killed actor and counts the dead actors with an extra local variable
go to the street and press key 9 to activate the spawning
CODE
{$CLEO .cs}
:ArrayAct_1
03A4: name_thread 'ARRAY_A'
0006: [email protected] =  0  // counter for dead actors
0006: [email protected] =  0  // Array index
0007: [email protected] = 2.5  // y offset for spawn coords

:ArrayAct_2
0001: wait  0 ms
00D6: if  0
0256:   player $PLAYER_CHAR defined
004D: jump_if_false @ArrayAct_2
if  and
0AB0:   key_pressed 57//----------------key 9
80DF:   not actor $PLAYER_ACTOR driving
004D: jump_if_false @ArrayAct_2
077E: get_active_interior_to [email protected]
00D6: if  0
0039:   [email protected] ==  0  // integer values
004D: jump_if_false @ArrayAct_2

0247: request_model #fbi

:ArrayAct_3
0001: wait  0 ms
if   and
0248:   model #fbi available
004D: jump_if_false @ArrayAct_3

:ArrayAct_4
0001: wait  10 ms
00D6: if  0
0256:   player $PLAYER_CHAR defined
004D: jump_if_false @ArrayAct_4
if
001B:    10 > [email protected]  // integer values
004D: jump_if_false @ArrayAct_10
04C4: create_coordinate [email protected] [email protected] [email protected] from_actor $PLAYER_ACTOR offset 0.0  [email protected]  0.2
009A: [email protected]([email protected],12i) = create_actor_pedtype 6 model #fbi at [email protected] [email protected] [email protected]
0187: [email protected]([email protected],12i) = create_marker_above_actor [email protected]([email protected],12i)
000B: [email protected] +=  2.0  // add 2.0 to the y offset for spawn coords
000A: [email protected] +=  1  // Array index
0002: jump @ArrayAct_4


:ArrayAct_10
0006: [email protected] =  0  // Array index

:ArrayAct_11
0001: wait  10 ms
if
0256:   player $PLAYER_CHAR defined
004D: jump_if_false @ArrayAct_40
if
001B:    10 > [email protected]  // integer values
004D: jump_if_false @ArrayAct_15
if
0118:  actor [email protected]([email protected],12i) dead
004D: jump_if_false @ArrayAct_13
if
075C:   marker [email protected]([email protected],12i) enabled
004D: jump_if_false @ArrayAct_13
0164: disable_marker [email protected]([email protected],12i)
000A: [email protected] +=  1  // counter for dead actors

:ArrayAct_13
000A: [email protected] +=  1  // Array index
if
001B:    10 > [email protected]  // integer values
004D: jump_if_false @ArrayAct_40
0002: jump @ArrayAct_11

:ArrayAct_15
0006: [email protected] =  0  // Array index
0002: jump @ArrayAct_11

:ArrayAct_40
0006: [email protected] =  0  // Array index

:ArrayAct_45
if
001B:    10 > [email protected]  // integer values
004D: jump_if_false @ArrayAct_50
if
075C:   marker [email protected]([email protected],12i) enabled
004D: jump_if_false @ArrayAct_47
0164: disable_marker [email protected]([email protected],12i)

:ArrayAct_47
01C2: remove_references_to_actor [email protected]([email protected],12i) // Like turning an actor into a random pedestrian
000A: [email protected] +=  1  // Array index
0002: jump @ArrayAct_45

:ArrayAct_50
0006: [email protected] =  0  // counter for dead actors
0006: [email protected] =  0  // Array index
0007: [email protected] = 2.5  // y offset for spawn coords
0249: release_model #fbi
0001: wait  1000 ms
0002: jump @ArrayAct_2


---------------------------------------------------------------------------------------------------------------------------------------

At the end I show how to use Global Variables as arrays.
But it can only be used in main.scm and will crash in Cleo

Its a bit easier to understand sigh.gif because it looks like the exemble from beginning:

Family[index 0] = father
Family[index 1] = mother
Family[index 2] = son
Family[index 3] = doughter
Family[index 4] = Carl

The global will be like a family
with assignement of an index in brackets

$ACTORS[0] = 0
$ACTORS[1] = 0
$ACTORS[2] = 0
$ACTORS[3] = 0
$ACTORS[4] = 0
$ACTORS[5] = 0

the array construct can look like this:
$ACTORS($ACT_INDEX,30i)
CODE
:Much_Actor_array
03A4: name_thread 'MACTARY'

:LABEL_start
0001: wait 1000 ms
0007: [email protected] = -25.0     // Range
0007: [email protected] = 25.0      // Range    
0007: [email protected] = 5.0       // X
0007: [email protected] = 0.0       // Y
0006: [email protected] = 0         // PED ID
0006: [email protected] = 0         // PED handle
0006: [email protected] = 0         // PED creation counter
0006: [email protected] = 29        // Max number of PEDs
0004: $ACTORS[0] = 0 // PED handle  
0004: $ACTORS[1] = 0 // PED handle
0004: $ACTORS[2] = 0 // PED handle
0004: $ACTORS[3] = 0 // PED handle
0004: $ACTORS[4] = 0 // PED handle
0004: $ACTORS[5] = 0 // PED handle
0004: $ACTORS[6] = 0 // PED handle
0004: $ACTORS[7] = 0 // PED handle
0004: $ACTORS[8] = 0 // PED handle
0004: $ACTORS[9] = 0 // PED handle
0004: $ACTORS[10] = 0 // PED handle
0004: $ACTORS[11] = 0 // PED handle
0004: $ACTORS[12] = 0 // PED handle
0004: $ACTORS[13] = 0 // PED handle
0004: $ACTORS[14] = 0 // PED handle
0004: $ACTORS[15] = 0 // PED handle
0004: $ACTORS[16] = 0 // PED handle
0004: $ACTORS[17] = 0 // PED handle
0004: $ACTORS[18] = 0 // PED handle
0004: $ACTORS[19] = 0 // PED handle
0004: $ACTORS[20] = 0 // PED handle
0004: $ACTORS[21] = 0 // PED handle
0004: $ACTORS[22] = 0 // PED handle
0004: $ACTORS[23] = 0 // PED handle
0004: $ACTORS[24] = 0 // PED handle
0004: $ACTORS[25] = 0 // PED handle
0004: $ACTORS[26] = 0 // PED handle
0004: $ACTORS[27] = 0 // PED handle
0004: $ACTORS[28] = 0 // PED handle
0004: $ACTORS[29] = 0 // PED handle
0004: $ACT_INDEX = 0

:LABEL_0
0001: wait 0 ms
if
0256:   player $PLAYER_CHAR defined
004D: jump_if_false @LABEL_0
if
80DF:   not actor $PLAYER_ACTOR driving
004D: jump_if_false @LABEL_0
if
001F:   [email protected] > $ACT_INDEX // (int)
004D: jump_if_false @LABEL_2
0209: [email protected] = random_int_in_ranges 209 264
0247: load_model [email protected]
038B: load_requested_models

:LABEL_1
0001: wait 0 ms
00D6: if 0
0248:   model [email protected] available
004D: jump_if_false @LABEL_1
0208: [email protected] = random_float_in_ranges [email protected] [email protected]  
0208: [email protected] = random_float_in_ranges [email protected] [email protected]
04C4: store_coords_to $TEMPVAR_FLOAT_1 $TEMPVAR_FLOAT_2 $TEMPVAR_FLOAT_3 from_actor $PLAYER_ACTOR with_offset [email protected] [email protected] -1.0
009A: $ACTORS($ACT_INDEX,30i) = create_actor_pedtype 4 model [email protected] at $TEMPVAR_FLOAT_1 $TEMPVAR_FLOAT_2 $TEMPVAR_FLOAT_3
05E2: AS_actor $ACTORS($ACT_INDEX,30i) kill_actor $PLAYER_ACTOR
0008: $ACT_INDEX += 1
0002: jump @LABEL_0

:LABEL_2
0004: $ACT_INDEX = 0

:LABEL_3
0001: wait 0 ms
if
0256:   player $PLAYER_CHAR defined
004D: jump_if_false @Cleanup_1
if
001F:   [email protected] > $ACT_INDEX
004D: jump_if_false @LABEL_5
if
8118:   not actor $ACTORS($ACT_INDEX,30i) dead
004D: jump_if_false @PED_CREATION_CONTROL_COUNT_UP
0332: set_actor $ACTORS($ACT_INDEX,30i) bleeding 1
0245: set_actor $ACTORS($ACT_INDEX,30i) walk_style_to "oldwoman"  
04C4: store_coords_to $TEMPVAR_FLOAT_1 $TEMPVAR_FLOAT_2 $TEMPVAR_FLOAT_3 from_actor $PLAYER_ACTOR with_offset 0.0 0.0 0.0
07CD: AS_actor $ACTORS($ACT_INDEX,30i) walk_to $TEMPVAR_FLOAT_1 $TEMPVAR_FLOAT_2 $TEMPVAR_FLOAT_3 stop_with_angle 0.0 within_radius 1.0

:PED_CREATION_CONTROL_COUNT_UP
0008: $ACT_INDEX += 1
0002: jump @LABEL_3

:LABEL_5
0001: wait 250 ms
if
0256:   player $PLAYER_CHAR defined
004D: jump_if_false @Cleanup_1
0002: jump @LABEL_5

:Cleanup_1
0004: $ACT_INDEX = 0

:Cleanup_2
0001: wait 0 ms
if
001F:   [email protected] > $ACT_INDEX
004D: jump_if_false @Cleanup_3
01C2: remove_references_to_actor $ACTORS($ACT_INDEX,30i)
0008: $ACT_INDEX += 1
0002: jump @Cleanup_2

:Cleanup_3
0002: jump @LABEL_start



ZAZ
  • ZAZ

    Kernlochbohrer

  • Feroci
  • Joined: 10 Jan 2005
  • European-Union
  • Contribution Award [Mods]
    Helpfulness Awards [Mods]

#16

Posted 05 June 2009 - 08:34 PM Edited by ZAZ, 17 August 2012 - 04:34 AM.

read_memory

the cleo opcodes 0A8D: and 0A8C: to read the content of memory adresses
at first we must know which adress have a function
you can find a list at: gtamodding.com
for exemple:
0x863984 - [Int32] Gravity

a simple GRAVITY script with text_draw opcodes to show the content of the adress:
CODE
{$CLEO .cs}
thread 'GRAVITY'
wait 3000
:GRAVITY_1
0A8D: [email protected] = read_memory 0x863984   size 4 virtual_protect 1
wait 100
03F0: text_draw_toggle  1
0001: wait  50 ms
03F0: text_draw_toggle  0
0001: wait  50 ms
045A: text_draw_1number  250.0  40.0 'NUMBER' [email protected]
0A8C: write_memory 0x863984   size 4 value 2 virtual_protect 1 //clear the buffer
0A93: end_custom_thread


at the end we pushes the value 2 into the memory adress
test the script and look for result
2 seems to have the best effect but this adress is really crazy and if we push a float value the effect is different
try
CODE
0A8C: write_memory 0x863984   size 4 value 10.0 virtual_protect 1 //clear the buffer

and you will see the trees deforming


You will need more information about menory handling and should read Seemanns topic:
SA Memory handling
as well as
Documenting GTA-SA memory adresses



CODE
0A8D: $result = read_memory [email protected] size 4 virtual_protect 0

0A8D reads the game memory and stores the result to a variable.

Parameters:
1 – variable to store read result (any variable or array item)
2 – memory addressа to read (any integer value)
3 – number of bytes to read: 1, 2 or 4 bytes
4 – Virtual Protect: use 1 if the address is unreadable, 0 – if address is readable.


CODE
0A8C: write_memory 0x00969110 size 4 value 0 virtual_protect 0

0A8C writes a value to the game memory.

Parameters:
1 – memory address (any integer value)
2 – number of bytes to write: 1, 2 or 4 bytes
3 – value to write (any number)
4 – Virtual Protect: use 1 to write to the read-only address, 0 – if the address is rewritable.

we can use the adress 0x00969110 as cheat key_press check

we have to use the hex charackter of ASCII Table
to check for a key_press
40 = @
41 = A
42 = B
43 = C
44 = D
45 = E
46 = F
47 = G
48 = H
49 = I
4A = J
4B = K
4C = L
4D = M
4E = N
4F = O
50 = P
51 = Q
52 = R
53 = S
54 = T
55 = U
56 = V
57 = W
58 = X
59 = Y
5A = Z
5B = [
5C = \
5D =]
5E =^

ascii-table calculator



The check if key M is pressed requires first to read 1 byte of the adress 0x00969110
CODE
0A8D: [email protected] = read_memory 0x00969110 size 1 virtual_protect 0

the check if the returned value is equal to the ascii character as hex of M
CODE
if
04A4:   [email protected] == 0x4D


check 2 keys: MM
CODE
0A8D: [email protected] = read_memory 0x00969110 size 2 virtual_protect 0
if
04A4:   [email protected] == 0x4D4D


check 4 keys: WILD
CODE
0A8D: [email protected] = read_memory 0x00969110 size 4 virtual_protect 1
if
04A4:   [email protected] == 0x57494C44 //checks if [email protected] = WILD



The script below activate the Mega Jump if you type JUMP
CODE
{$CLEO .cs}
thread 'cheat'

:Cheatcode_1
wait 0
0A8D: [email protected] = read_memory 0x00969110 size 4 virtual_protect 0
if
04A4:   [email protected] == 0x4A554D50 //checks if [email protected] = JUMP
004D: jump_if_false @Cheatcode_1
03E5: text_box 'CHEAT1'
0109: player $PLAYER_CHAR money += 1000000
0A8C: write_memory 0x00969110 size 4 value 0 virtual_protect 0 //clear the buffer
0A8C: write_memory 0x96916C size 4 value 1 virtual_protect 0 //-- activates Mega Jump
0A93: end_custom_thread


To check for more than 4 charackter needs to use an additional memory adress: 0x00969114
It requires to assigne the first 4 charackter to this adress and the following 1, 2 or 4 charackter to 0x00969110

The script above spawns a Jump Ramp if you type JUMPRAMP
CODE
{$CLEO .cs}
thread 'cheat'

:Cheatcode_1
wait 0
0A8D: [email protected] = read_memory 0x00969110 size 4 virtual_protect 0 //
0A8D: [email protected] = read_memory 0x00969114 size 4 virtual_protect 0 //
if  and
04A4:   [email protected] == 0x52414D50 //checks if [email protected] = RAMP
04A4:   [email protected] == 0x4A554D50 //checks if [email protected] = JUMP
004D: jump_if_false @Cheatcode_1
03E5: text_box 'CHEAT1'
0109: player $PLAYER_CHAR money += 1000000
0A8C: write_memory 0x00969110 size 4 value 0 virtual_protect 0 //clear the buffer
0A8C: write_memory 0x00969114 size 4 value 0 virtual_protect 0 //clear the buffer
0247: request_model 1655

:Cheatcode_JRamp
0001: wait  0 ms
00D6: if  0
0248:   model 1655 available
004D: jump_if_false @Cheatcode_JRamp
0172: [email protected] = actor $PLAYER_ACTOR z_angle
04C4: create_coordinate [email protected] [email protected] [email protected] from_actor $PLAYER_ACTOR offset 0.0 14.5  -1.8
0107: [email protected] = create_object 1655 at  [email protected] [email protected] [email protected]
0177: set_object [email protected] z_angle_to  [email protected]
0001: wait  0 ms
0249: release_model 1655
0001: wait  1000 ms
01C4: remove_references_to_object [email protected]  // This object will now disappear when the player looks away
0002: jump @Cheatcode_1


type ARMOUR to have a bodyarmour pickup in Grovestreet
CODE
{$CLEO .cs}
thread 'cheat'

:Cheatcode_1//ARMOUR
wait 0
0A8D: [email protected] = read_memory 0x00969110 size 4 virtual_protect 0 //
0A8D: [email protected] = read_memory 0x00969114 size 2 virtual_protect 0 //
if  and
04A4:   [email protected] == 0x4D4F5552//MOUR
04A4:   [email protected] == 0x4152//AR
004D: jump_if_false @Cheatcode_1
03E5: text_box 'CHEAT1'
0109: player $PLAYER_CHAR money += 1000000
0A8C: write_memory 0x00969110 size 4 value 0 virtual_protect 0 //clear the buffer
0A8C: write_memory 0x00969114 size 2 value 0 virtual_protect 0 //clear the buffer
Pickup.Create([email protected], 1242, 3, 2495.1387, -1680.1288, 13.3388)
0002: jump @Cheatcode_1


QUOTE (Rapier @ Aug 31 2009, 04:05)
QUOTE (ZAZ @ Jun 5 2009, 18:34)
we can use the adress 0x00969110 as cheat key_press check

This memory address is for version 1.0, but, for version 1.01 which will be?
That's because my mods did not work anymore after I did the upgrade to version 1.01 and all are activated as a cheat.

QUOTE (Wesser @ Aug 31 2009, 07:21)
It's 0x96B790 for 1.1. smile.gif



related topic about memory adress
car struct, actor struct, object struct
Help With Advanced Memory Access, Help me learn the basics
Changing Car Handling


coin-god
  • coin-god

    High Roller

  • $outh $ide Hoodz
  • Joined: 18 Mar 2007
  • None

#17

Posted 05 June 2009 - 09:38 PM

So.. you did have this in your german site all the time? tounge.gif


Awesome work ZAZ, its usefull for me to understand some things i didnt got during this years coding smile.gif

ZAZ
  • ZAZ

    Kernlochbohrer

  • Feroci
  • Joined: 10 Jan 2005
  • European-Union
  • Contribution Award [Mods]
    Helpfulness Awards [Mods]

#18

Posted 06 June 2009 - 02:23 AM Edited by ZAZ, 26 July 2010 - 04:18 PM.


call_scm_function


QUOTE (The_Siggi's sent pm)
Well, as it has been already explained in other ways, I'll try to let you understand a more confortable one hopefully.
0AB1 works like 004F does but it has the ability to return:

  • TRUE/FALSE, respectively with 0485 and 059A, but the function must end with 0AB2 without returned params, otherwise the game would crash. These are kinda useful when you want to make a contition function.

  • Any value by using 0AB2.

IN AN EXTERN THREAD

0AB1 is structured in such way:
CODE
0AB1: call_scm_func <thread> <param_count> | <param1> <param2> ...

As many as the parameters count says. Those params can be a number or a local/global var, indipendendlty for what it's their offset.

IN THE FUNCTION THREAD

All passed params are stored in a progressive offsets chain which starts always from 0. So the 1st passed param will be stored in [email protected], the 2nd in [email protected] and so on until the max local var offset ([email protected]). Don't forget to end the function with 0AB2 which has about the same sintax:
CODE
0AB2: ret <param_count> | <param1> <param2> ...

If it returns at least one param, you should store the returned var/s at 0AB1 as follows:
CODE
0AB1: call_scm_func <thread> <param_count> | <param1> <param2> ... |  <param1> <param2> ...


FUNCTION SAMPLES

CONDITION
CODE
[...]
if
0AB1: call_scm_func @isActorDriving 1 actor $PLAYER_ACTOR
then
 03C0: [email protected] = actor $PLAYER_ACTOR car
end
[...]

:isActorDriving
{
 [email protected] - actor
}
if
00DF:  actor [email protected] driving
then
 0485: return_true
else
 059A: return_false
end
0AB2: ret 0

SET
CODE
[...]
0AB1: call_scm_func @setActorHealth 2 actor $PLAYER_ACTOR health 100
[...]

:setActorHealth
{
 [email protected] - actor
 [email protected] - health
}
0223: set_actor [email protected] health_to [email protected]
0AB2: ret 0

GET
CODE
[...]
0AB1: call_scm_func @getActorArmour 1 actor $PLAYER_ACTOR armour_to [email protected]
[...]

:getActorArmour
{
 [email protected] - actor
}
04DD: [email protected] = actor [email protected] armour
0AB2: ret 1 [email protected]

SET/GET
CODE
[...]
00A0: store_actor $PLAYER_ACTOR position_to [email protected] [email protected] [email protected]
0AB1: call_scm_func @getRandomPos 4 in [email protected] [email protected] [email protected] radius [email protected] out_to [email protected] [email protected] [email protected]
[...]

:getRandomPos
{
 [email protected] - X pos
 [email protected] - Y pos
 [email protected] - Z pos
 [email protected] - radius
}
0087: [email protected] = [email protected]
0087: [email protected] = [email protected]
0063: [email protected] -= [email protected]
0063: [email protected] -= [email protected]
005B: [email protected] += [email protected]
005B: [email protected] += [email protected]
[email protected] = random([email protected], [email protected])
[email protected] = random([email protected], [email protected])
02CE: [email protected] = ground_z_at [email protected] [email protected] [email protected]
0AB2: ret 3 [email protected] [email protected] [email protected]

how many parameter can 0AB1: have?
QUOTE (Wesser @ Jul 26 2010, 15:50)
I guess it takes 34 params as max since they're stored in the function from [email protected] to [email protected] biggrin.gif





Script to show text without gxt or fxt like the example script of the sannybuilder files
Script by Rapier
CODE
{$CLEO}

thread 'MSG_TEST'
wait 5000
0AB1: call_scm_func @LabelMSGMain 1 @LabelMSG01
wait 5000
0AB1: call_scm_func @LabelMSGMain 1 @LabelMSG02
0A93: end_custom_thread

:LabelMSGMain
0A9F: [email protected] = current_thread_pointer
[email protected] += 16
0A8D: [email protected] = read_memory [email protected] size 4 virtual_protect 0
0062: [email protected] -= [email protected] // (int)
[email protected] += 4
if
0AA9:  is_game_version_original
jf @LabelMSGVersion101
0AA5: call 0x588BE0 num_params 4 pop 4 0 0 0 [email protected] // v1.0
jump @LabelMSGMain02

:LabelMSGVersion101
0AA5: call 0x5893B0 num_params 4 pop 4 0 0 0 [email protected] // v1.01

:LabelMSGMain02
0AB2: ret 0

:LabelMSG01
0900: "You are playing..."

:LabelMSG02
0900: "GTA San Andreas"
0000: nop



related topic
Help With Advanced Memory Access, Help me learn the basics

----------------------------------------------------------------------------------------------------------------------------------------


QUOTE (goin-god @ Jun 5 2009, 21:38)
So.. you did have this in your german site all the time? tounge.gif

Yes, since August 2008, but not all that themes like here.

DvD463
  • DvD463

    Player Hater

  • Members
  • Joined: 02 Dec 2008
  • None

#19

Posted 02 July 2009 - 11:47 AM

Can you please somebody make the tutorial to Czech?

ZAZ
  • ZAZ

    Kernlochbohrer

  • Feroci
  • Joined: 10 Jan 2005
  • European-Union
  • Contribution Award [Mods]
    Helpfulness Awards [Mods]

#20

Posted 02 July 2009 - 08:01 PM Edited by ZAZ, 05 September 2010 - 11:59 AM.

QUOTE (DvD463 @ Jul 2 2009, 11:47)
Can you please somebody make the tutorial to Czech?

use google translater click me

_____________________________________________________________________________________


Catch random actor



There are several opcodes to get random actors at several points :

CODE
089E: get_actor_in_sphere [email protected] [email protected] [email protected] radius 5.0 handle_as [email protected] // versionB
08E5: get_actor_in_sphere [email protected] [email protected] [email protected] radius 50.0 handle_as [email protected]
073F: get_actor_in_sphere [email protected] [email protected] [email protected] radius 20.0 with_pedtype_civilian 1 gang 1 criminal/prostitute 1 handle_as [email protected]


But they couldn't get gang type, drug dealer, and any other actors (especially custom actors in missions!)

furthermore there is a cleo opcde :

CODE
0AB5: store_actor $PLAYER_ACTOR closest_vehicle_to [email protected] closest_ped_to [email protected]


But, it only get the nearest actor, otherwise you can't!
And also if these opcodes used in a place without any single human, it will gone crash!

------------------------------------------------------------------------------------------------------

Our member Wesser posted a method to get every actor in the gameworld, also those of missions, extern scripts as well as other cleo script except those of the food stores like burgershop etc.

find Wessers original template here: call_func @getActorInSphere

He used the opcode 0AB1: call_func which is explained above, in previous theme
furthermore the for-to-step-method which is used in several programming languages and supported in Sannybuilder
The for loop repeats a block of code while a control variable runs through an arithmetic progression.

A smaller and faster vaiation was done by Deji. Find the template >here<

To make it more clear I composed and recompiled Wessers script into an example for gta praxis
1. script with opcodes
2. script without opcodes
The script catches any random actor, shows his pedtype and let him die

1. script with opcodes
CODE
{$CLEO .cs}
:RandomActor_for_to_step_method
thread 'RAFSTEP'

:RAFSTEP_1
0001: wait 0 ms
00D6: if
0256:   player $PLAYER_CHAR defined
004D: jump_if_false @RAFSTEP_1
00A0: store_actor $PLAYER_ACTOR position_to [email protected] [email protected] [email protected]
0AB1: call_scm_func @RAFSTEP_func 4 [email protected] [email protected] [email protected] 5.0 [email protected]
00D6: if
8039:   not  [email protected] == -1
004D: jump_if_false @RAFSTEP_1
00D6: if
8118:   not actor [email protected] dead
004D: jump_if_false @RAFSTEP_1
089F: get_actor [email protected] pedtype_to [email protected]
03F0: enable_text_draw 1
0001: wait 50 ms
03F0: enable_text_draw 0
0001: wait 50 ms
045A: draw_text_1number 250.0 40.0 GXT 'NUMBER' number [email protected]  // ~1~
05BE: AS_kill_actor [email protected]
01C2: remove_references_to_actor [email protected] // Like turning an actor into a random pedestrian
0002: jump @RAFSTEP_1

:RAFSTEP_func
0006: [email protected] = 0
0006: [email protected] = 0

:RAFSTEP_countLoop
00D6: if
056D:   actor [email protected] defined
004D: jump_if_false @RAFSTEP_11
00D6: if and
803B:   not  $PLAYER_ACTOR == [email protected] // (int)
00FE:   actor [email protected] sphere 0 in_sphere [email protected] [email protected] [email protected] radius [email protected] [email protected] [email protected]
004D: jump_if_false @RAFSTEP_11
0006: [email protected] = 1
0002: jump @RAFSTEP_12

:RAFSTEP_11
000A: [email protected] += 1
00D6: if
0019:   [email protected] > 30000
004D: jump_if_false @RAFSTEP_countLoop

:RAFSTEP_12
00D6: if
0039:   [email protected] == 0
004D: jump_if_false @RAFSTEP_Result
0006: [email protected] = -1

:RAFSTEP_Result
0AB2: ret 1 [email protected]


2. script without opcodes
CODE
{$CLEO .cs}
:RandomActor_for_to_step_method
thread 'RAFSTEP'

:RAFSTEP_1
wait 0
if
  Player.Defined($PLAYER_CHAR)
jf @RAFSTEP_1
Actor.StorePos($PLAYER_ACTOR, [email protected], [email protected], [email protected])
0AB1: call_scm_func @RAFSTEP_func 4 [email protected] [email protected] [email protected] 5.0 [email protected]
if
  not [email protected] == -1
jf @RAFSTEP_1
if
  not Actor.Dead([email protected])
jf @RAFSTEP_1
089F: get_actor [email protected] pedtype_to [email protected]
03F0: enable_text_draw 1
wait 50
03F0: enable_text_draw 0
wait 50
045A: draw_text_1number 250.0 40.0 GXT 'NUMBER' number [email protected]  // ~1~
05BE: AS_kill_actor [email protected]
Actor.RemoveReferences([email protected])
jump @RAFSTEP_1

:RAFSTEP_func
[email protected] = 0
[email protected] = 0

:RAFSTEP_countLoop
if
  Actor.Defined([email protected])
jf @RAFSTEP_11
if and
803B:   not  $PLAYER_ACTOR == [email protected] // (int)
00FE:   actor [email protected] sphere 0 in_sphere [email protected] [email protected] [email protected] radius [email protected] [email protected] [email protected]
jf @RAFSTEP_11
[email protected] = 1
jump @RAFSTEP_12

:RAFSTEP_11
[email protected] += 1
if
 [email protected] > 30000
jf @RAFSTEP_countLoop

:RAFSTEP_12
if
 [email protected] == 0
jf @RAFSTEP_Result
[email protected] = -1

:RAFSTEP_Result
0AB2: ret 1 [email protected]



DarthGrijo
  • DarthGrijo

    V.I.P MEMBER! yeah, i wish

  • Members
  • Joined: 01 May 2008

#21

Posted 03 July 2009 - 08:12 AM

Hey,

How would u make a cleo mod that displays the vehicle( your currently in)'s health?

like if i were in a slamvan it would display the slamvan's current health? suicidal.gif

Thanx biggrin.gif

ZAZ
  • ZAZ

    Kernlochbohrer

  • Feroci
  • Joined: 10 Jan 2005
  • European-Union
  • Contribution Award [Mods]
    Helpfulness Awards [Mods]

#22

Posted 03 July 2009 - 09:28 AM

QUOTE (DarthGrijo @ Jul 3 2009, 08:12)
Hey,

How would u make a cleo mod that displays the vehicle( your currently in)'s health?

like if i were in a slamvan it would display the slamvan's current health?  suicidal.gif

Thanx  biggrin.gif

Please post here questions which belongs to the tutorial.
Generell questions of mission coding will be answerd in the mission coding forum
use opcode search tool to find opcodes for your plan
you need to get the instance of the player car, then read the health of the car and use any text opcode which allows to display a value.

DvD463
  • DvD463

    Player Hater

  • Members
  • Joined: 02 Dec 2008
  • None

#23

Posted 03 July 2009 - 10:11 AM

Ok, Thanks wink.gif

DaBeast.
  • DaBeast.

    I can has polygon?

  • Members
  • Joined: 12 Jan 2009
  • None

#24

Posted 03 July 2009 - 12:19 PM

Awesomely detailed tutorial ZAZ, truly awesome. I also like the flowchart. Keep it up man! icon14.gif

bull.04
  • bull.04

    :D

  • Members
  • Joined: 11 Apr 2008

#25

Posted 14 August 2009 - 06:43 AM

I know it's kind of A bump, but I need to load from SPC_GA the bank_087 sound_023 how would I load that from a script?

ZAZ
  • ZAZ

    Kernlochbohrer

  • Feroci
  • Joined: 10 Jan 2005
  • European-Union
  • Contribution Award [Mods]
    Helpfulness Awards [Mods]

#26

Posted 16 August 2009 - 09:35 AM

QUOTE (bull.04 @ Aug 14 2009, 06:43)
I know it's kind of A bump, but I need to load from SPC_GA the bank_087 sound_023 how would I load that from a script?

Sorry, I don't know. I think there is no way to execute this sound by script.
Maybe it's possible with 09D5: but it needs to do a lot of trail and error to find out which sound number plays which sound.
The sound numbers for script use have no association to the file names.
opcode 09D5 plays voice sounds which are also mostly used from exe for random peds on street
like pain sounds, breathing, coughing ect...
presumable uses PAIN_A SFX, SPC_FA SFX, SPC_PA SFX Archive Directory

bull.04
  • bull.04

    :D

  • Members
  • Joined: 11 Apr 2008

#27

Posted 16 August 2009 - 03:55 PM

Hmmm, I was trying to get the sound from SPC_GA.

markbaker
  • markbaker

    Player Hater

  • Members
  • Joined: 26 Aug 2009

#28

Posted 26 August 2009 - 12:36 PM

Great Tutorial!

I have a couple simple questions - how can I spawn a vehicle & have it drive forward on it's own, either in a straight line or along a specified path? Also, is it possible to spawn a vehicle that has peds driving/riding in it?

ZAZ
  • ZAZ

    Kernlochbohrer

  • Feroci
  • Joined: 10 Jan 2005
  • European-Union
  • Contribution Award [Mods]
    Helpfulness Awards [Mods]

#29

Posted 28 August 2009 - 06:30 PM Edited by ZAZ, 03 October 2009 - 09:38 AM.


Car Drive Tutorial

QUOTE (markbaker @ Aug 26 2009, 12:36)
Great Tutorial!

I have a couple simple questions -  how can I spawn a vehicle & have it drive forward on it's own, either in a straight line or along a specified path?  Also, is it possible to spawn a vehicle that has peds driving/riding in it?

Ok, lets start with the base: "how can I spawn a vehicle" and use the exemple script of
tutorial theme: Scripting/Writing a Thread -- Next Step/ Spawn a 3D model

Script below spawns the car Infernus in Grovestreet if player goes into red marker(sphere)
If player leave the spot the car will be released from script and the reading process jumps back into 1.Loop
CODE
{$CLEO .cs}
:3dModels_1
03A4: name_thread 'MODL'

:3dModels_2
0001: wait  0 ms
00D6: if  0
0256:   player $PLAYER_CHAR defined
004D: jump_if_false @3dModels_2
00D6: if  0
00FF:   actor $PLAYER_ACTOR  1 (in-sphere)near_point_on_foot 2491.5  -1667.5  13.35 radius  1.0  1.0  1.0
004D: jump_if_false @3dModels_2

0247: request_model #INFERNUS

:Load_Model_Check
0001: wait  0 ms
00D6: if  0
0248:   model #INFERNUS available
004D: jump_if_false @Load_Model_Check

00A5: [email protected] = create_car #INFERNUS at 2487.5  -1660.5  13.35
0175: set_car [email protected] z_angle_to 90.0
0249: release_model #INFERNUS

:3dModels_3
0001: wait  0 ms
00D6: if  0
0256:   player $PLAYER_CHAR defined
004D: jump_if_false @3dModels_3
00D6: if  0
80FF:   NOT   actor $PLAYER_ACTOR  0 ()near_point_on_foot 2491.5  -1667.5  13.35 radius  2.0  2.0  2.0
004D: jump_if_false @3dModels_3
01C3: remove_references_to_car [email protected]  // Like turning a car into any random car
0002: jump @3dModels_2



In the next step I spawn 2 actors in the car and let the car drive to a fix coord destination
fourthermore I add an marker to can see on radar where the car is.

To spawn the actor directly in the car I use opcode 0129: for the driver and 01C8: for the passenger.
It's also possible to spawn the actors by normal placement and let then the actors enter the car. Either as driver or as passenger, also with different opcodes.
The passenger opcodes needs to set the seat number in the last parameter:
0 = front passenger seat, 1 or 2 for the back seats

To let the car drive I use a simple "drive_to opcode"
There are a lot of other variation to let a car drive and it requires allways to set the speed.

The Loop after the "drive-to commands" needs now conditions which belongs to the car drive action
Very important is to check if the car is wrecked.
We need one or more ways to let the script refresh, I mean to release the car, it's marker and the actors from our script in some cases to can beginn the script from beginning.
Such situations can be if player dies or gets arrested, if the car is wrecked or if it is far away
if or
0119: car [email protected] wrecked
01F4: car [email protected] flipped
8202: not actor $PLAYER_ACTOR near_car [email protected] radius 500.0 500.0 flag 0


Script below spawns the car Infernus in Grovestreet with two homies inthere,
if player goes into red marker(sphere)
It drives to the next crossroad and stays there till player is far away from car (500.0 units)
CODE
{$CLEO .cs}
:CarDrive_1
03A4: name_thread 'CDRIVE'

:CarDrive_2
0001: wait  0 ms
if
0256:   player $PLAYER_CHAR defined
004D: jump_if_false @CarDrive_2
if
00FF:   actor $PLAYER_ACTOR  1 (in-sphere)near_point_on_foot 2491.5  -1667.5  13.35 radius  1.0  1.0  1.0
004D: jump_if_false @CarDrive_2

0247: request_model #INFERNUS
0247: request_model #fam1
0247: request_model #fam2

:CarDrive_3
0001: wait  0 ms
if  and
0248:   model #INFERNUS available
0248:   model #fam1 available
0248:   model #fam2 available
004D: jump_if_false @CarDrive_3

00A5: [email protected] = create_car #INFERNUS at 2487.5  -1660.5  13.35
0175: set_car [email protected] z_angle_to 90.0
0129: [email protected] = create_actor  8 #fam1 in_car [email protected] driverseat
01C8: [email protected] = create_actor  8 #fam2 in_car [email protected] passenger_seat  0
0186: [email protected] = create_marker_above_car [email protected]
07E0: set_marker [email protected] type_to 1

0249: release_model #INFERNUS
0249: release_model #fam1
0249: release_model #fam2

////////////////////  the drive-to commands --vv----

00A7: car [email protected] drive_to 2353.1528 -1658.6493 13.3846//---simple drive-to command
00AD: set_car [email protected] max_speed_to  20.0//---speed declaration, important!!
00AE: unknown_set_car [email protected] to_ignore_traffic_lights  2//--optional, sets car to ignore red-lights and drive around traffic


////////////////////  the drive-to commands --^^----



:CarDrive_13
0001: wait  0 ms
if
0256:   player $PLAYER_CHAR defined
004D: jump_if_false @CarDrive_13
if  or
0119:     car [email protected] wrecked
01F4:     car [email protected] flipped
8202:   not actor $PLAYER_ACTOR near_car [email protected] radius 500.0 500.0 flag 0
004D: jump_if_false @CarDrive_13
01C3: remove_references_to_car [email protected]  // Like turning a car into any random car
01C2: remove_references_to_actor [email protected] // Like turning an actor into a random pedestrian
01C2: remove_references_to_actor [email protected] // Like turning an actor into a random pedestrian
0164: disable_marker [email protected]
0002: jump @CarDrive_2



As I said, there are a lot of other variation to let a car drive. The opcode 00A7: of the exemple above is the simpliest.
The car drive then strictly along the gta paths. The paths are stored in the nodes.dat in gta3.img
These paths are the routes for the random cars in traffic.
If you place a car in an area without path like in middle of the desert and let then the car drive, it drives first to the path
and then to the destination.
The car can not reach the destination if the destination is not on a path.
A car drive script can be a very annoying work, also if the destinations are on paths.
It often won't drive that route which we want or it stucks.

----------------------------------------------------------------------------

We have several opcodes to force the car to let it do what we want

----------------------------------------------------------------------------

opcode 04e0: let the car ingnore the paths and let it drive straight ahead to the destination
04e0: car [email protected] abandon_path_radius 200

replace the script part with the drive-to commands of script above with this drive-to commands:
CODE
////////////////////  the drive-to commands --vv----

00A7: car [email protected] drive_to 2431.5864 -1628.0818 13.698//---simple drive-to command
00AD: set_car [email protected] max_speed_to  20.0//---speed declaration, important!!
00AE: unknown_set_car [email protected] to_ignore_traffic_lights  2//--optional, sets car to ignore red-lights and drive around traffic
04e0: car [email protected] abandon_path_radius 200

////////////////////  the drive-to commands --^^----

the destination is between the highway and grovestreet at that empty area
without 04e0: the car drives a long way on the street
opcode 04e0: works only in the given radius,
it means: by radius 200 the startpoint and the next destination may not be bigger than 200 units
more than 250 is not possible

----------------------------------------------------------------------------

the car chases the player with opcode 00AF: and 2 as last parameter

CODE
////////////////////  the drive-to commands --vv----

00AD: set_car [email protected] max_speed_to  20.0//---speed declaration, important!!
00AE: unknown_set_car [email protected] to_ignore_traffic_lights  2//--optional, sets car to ignore red-lights and drive around traffic
00AF: set_car [email protected] driver_behaviour_to  2//-- 2 as last param let chase the player

////////////////////  the drive-to commands --^^----


four valid settings for opcode 00AF:
1 - follow road, drive back if way is blocked
2 - kill the player
4 - drive to player and stop
8 - ignore road-paths

----------------------------------------------------------------------------

the car drives automaticly along the paths with opcode 00AF: and 1 as last parameter

CODE
////////////////////  the drive-to commands --vv----

00AD: set_car [email protected] max_speed_to  20.0//---speed declaration, important!!
00AE: unknown_set_car [email protected] to_ignore_traffic_lights  2//--optional, sets car to ignore red-lights and drive around traffic
00AF: set_car [email protected] driver_behaviour_to 1

////////////////////  the drive-to commands --^^----


----------------------------------------------------------------------------

We can use an opcode to read the coords infront of the car and let it drive to that point

CODE
////////////////////  the drive-to commands --vv----

0407: create_coordinate [email protected] [email protected] [email protected] from_car [email protected] offset  -10.0  15.0  0.0
00A7: car [email protected] drive_to [email protected] [email protected] [email protected]//---simple drive-to command
00AD: set_car [email protected] max_speed_to  20.0//---speed declaration, important!!
00AE: unknown_set_car [email protected] to_ignore_traffic_lights  2//--optional, sets car to ignore red-lights and drive around traffic


////////////////////  the drive-to commands --^^----


----------------------------------------------------------------------------

We can use an opcode to read the coords infront of the car and let it drive to that point
and give it a start boost with opcode 04BA:

CODE
////////////////////  the drive-to commands --vv----

0407: create_coordinate [email protected] [email protected] [email protected] from_car [email protected] offset  -10.0  15.0  0.0
00A7: car [email protected] drive_to [email protected] [email protected] [email protected]//---simple drive-to command
00AD: set_car [email protected] max_speed_to  20.0//---speed declaration, important!!
00AE: unknown_set_car [email protected] to_ignore_traffic_lights  2//--optional, sets car to ignore red-lights and drive around traffic
04BA: set_car [email protected] speed_instantly  50.0

////////////////////  the drive-to commands --^^----


----------------------------------------------------------------------------

Let the driver do corrections

R* use in the main.scm a stuck car check, but this function don't work in Cleo
But to let the driver do corrections can be used opcode 06C7:

CODE
////////////////////  the drive-to commands --vv----

06C7: AS_actor [email protected] driver_of_car [email protected] perform_action 14 timelimit 3000    //backward circle
00A7: car [email protected] drive_to 2353.1528 -1658.6493 13.3846//---simple drive-to command
00AD: set_car [email protected] max_speed_to  20.0//---speed declaration, important!!
00AE: unknown_set_car [email protected] to_ignore_traffic_lights  2//--optional, sets car to ignore red-lights and drive around traffic

////////////////////  the drive-to commands --^^----


the driver make first a backward circle for ca. 3 seconds, then the car drives to the given point
----------------------------------------------------------------------------
some different versions of opcode 06C7:
CODE
06C7: AS_actor [email protected] driver_of_car [email protected] perform_action 6 timelimit 1000     //a short stop                    
06C7: AS_actor [email protected] driver_of_car [email protected] perform_action 6 timelimit 2000000  //a long stop                    
06C7: AS_actor [email protected] driver_of_car [email protected] perform_action 3 timelimit 3000     //backwards to the right side, than straight ahead
06C7: AS_actor [email protected] driver_of_car [email protected] perform_action 22 timelimit 3000    //backwards to the left side, than straight ahead  
06C7: AS_actor [email protected] driver_of_car [email protected] perform_action 14 timelimit 3000    //backward circle                  
06C7: AS_actor [email protected] driver_of_car [email protected] perform_action 9 timelimit 3000     //bump forward                        
06C7: AS_actor [email protected] driver_of_car [email protected] perform_action 7 timelimit 3000     //steer left                            
06C7: AS_actor [email protected] driver_of_car [email protected] perform_action 8 timelimit 3000     //steer right


----------------------------------------------------------------------------

Let the driver drive

Opcode 05D1: let the driver drive instead to let the car drive

This function can also ignore the paths (like using 04e0: car [email protected] abandon_path_radius)
and let the driver drive the car directly to the given point
It's depending from the setting in the flags

0 0 5 let it drive on paths
2 0 5 ignore the paths

CODE
////////////////////  the drive-to commands --vv----

05D1: AS_actor [email protected] drive_car [email protected] to  2353.1528 -1658.6493 13.384 speed  20.0  0  0  5

////////////////////  the drive-to commands --^^----


----------------------------------------------------------------------------

Opcode 05D1: can be set more times as combo in an AS_Pack
It needs than to set -1 instead the variable name of the driver
and assign the actor [email protected] after the AS_pack-setup to the defined AS_pack

CODE
////////////////////  the drive-to commands --vv----

0615: define_action_sequences [email protected]
05D1: AS_actor -1 drive_car [email protected] to  2353.1528 -1658.6493 13.384 speed  20.0  0  0  5
05D1: AS_actor -1 drive_car [email protected] to  2431.7739 -1674.7444 13.6643 speed  20.0  0  0  5
05D1: AS_actor -1 drive_car [email protected] to  2431.5864 -1628.0818 13.698 speed  20.0  2  0  5
0616: define_action_sequences_end [email protected]
0618: assign_actor [email protected] to_action_sequences [email protected]
061B: remove_references_to_AS_pack [email protected]

////////////////////  the drive-to commands --^^----



----------------------------------------------------------------------------

Define a scmpath for the driver

Set first opcode 05D6: to clear first a possibly created previous scmpath
Than set new coords for the scmpath and use opcode 07E7: to let the driver drive along this path

This function can also ignore the paths (like using 04e0: car [email protected] abandon_path_radius)
and let the driver drive the car directly to the given point
It's depending from the setting in the flags

0 0 5 let it drive on paths
2 0 5 ignore the paths

CODE
////////////////////  the drive-to commands --vv----

05D6: clear_scmpath
05D7: add_point_to_scmpath  2353.1528 -1658.6493 13.384
05D7: add_point_to_scmpath  2431.7739 -1674.7444 13.6643
07E7: AS_assign_scmpath_to_actor [email protected] in_car [email protected] speed  20.0 flags  0  0  5

////////////////////  the drive-to commands --^^----


----------------------------------------------------------------------------

Car drive scripts in praxis

----------------------------------------------------------------------------

In praxis to write a car drive script with a longer specific route needs a more complex script,
which checks if the car reached the destination to can submit the new destination.
Because you can not check the same destination coords which you want to submit when the car reached it,
you must use access checks

Fourthermore it needs to check if the car do airborns because it looses the coord information
and we must give this information again in this case

A check if the car is fliped or wrecked makes allways sense, because it can not continue the route and the script should cancel the action in this case

R* use in the main.scm a stuck car check, but this function don't work in Cleo
a check if the car speed is smaller than 1.0 can help

----------------------------------------------------------------------------

The SF-Airport Circle version 1

The script below teleport the player to the SF airport on a motorbike and spawns an opponent driver on motorbike who drives around the airort building.
Go outside to the exterior map and press Backspace then follow the opponent driver to see what he do
Opcode 00A7: car [email protected] drive_to is used and 04e0: car [email protected] abandon_path_radius
The driver falls from bike sometimes and enters again his ride to continue the drive
Alternativ you can activte the opcode 08C6:
CODE
//08C6: set_actor [email protected]  stay_on_bike 1

To refresh the script needs to leave the aiport, you must have a distance of 700.0 units to the startpoint

CODE
{$CLEO .cs}
:Drive_1
03A4: name_thread 'DRIV'

:Drive_3
0001: wait 0 ms
if
0256: player $PLAYER_CHAR defined
jf @Drive_3
077E: [email protected] = active_interior
if  and
0039:   [email protected] ==  0  // integer values
0AB0:   key_pressed 8//----------------------------------------Backspace  
jf @Drive_3
016A: fade  0 ()  250 ms
0001: wait 250 ms
01B4: set_player $PLAYER_CHAR frozen_state  0 (frozen)
0362: remove_actor $PLAYER_ACTOR from_car_and_place_at -1338.5  -408.1  14.1
0173: set_actor $PLAYER_ACTOR z_angle_to  90.8
0001: wait  500 ms
0247: request_model #NRG500
0247: request_model #MAFFA

:Drive_5
0001: wait  0 ms
if  and
0248:   model #NRG500 available
0248:   model #MAFFA available
jf @Drive_5
00A5: [email protected] = create_car #NRG500 at -1333.5  -408.1  14.1
0175: set_car [email protected] z_angle_to  280.0
0224: set_car [email protected] health_to  2000
00A5: [email protected] = create_car #NRG500 at -1354.5  -419.1  14.1
0175: set_car [email protected] z_angle_to  280.0
0224: set_car [email protected] health_to  2000
020A: set_car  [email protected] door_status_to 4
02AC: set_car [email protected] immunities  1  1  1  1  1
01EC: make_car [email protected] very_heavy  1
0129: [email protected] = create_actor  24 #MAFFA in_car [email protected] driverseat
0223: set_actor [email protected] health_to  3000
04E4: unknown_refresh_game_renderer_at  -1333.5  -408.1
03CB: set_camera  -1333.5  -408.1  14.1
029B: [email protected] = init_object 1655 at -1576.02  -202.34  13.76
0177: set_object [email protected] z_angle_to  270.0
01C7: remove_object_from_mission_cleanup_list [email protected]
0382: set_object [email protected] collision_detection  1
029B: [email protected] = init_object 1655 at -1597.9  -506.5  21.7
0177: set_object [email protected] z_angle_to  270.0
01C7: remove_object_from_mission_cleanup_list [email protected]
0382: set_object [email protected] collision_detection  1
029B: [email protected] = init_object 1655 at -1375.9  -581.5  13.69
0177: set_object [email protected] z_angle_to  270.0
01C7: remove_object_from_mission_cleanup_list [email protected]
0382: set_object [email protected] collision_detection  1
029B: [email protected] = init_object 1655 at -1374.9  -585.5  13.69
0177: set_object [email protected] z_angle_to  270.0
01C7: remove_object_from_mission_cleanup_list [email protected]

0382: set_object [email protected] collision_detection  1
0177: set_object [email protected] z_angle_to  135.0
0177: set_object [email protected] z_angle_to  225.0
0177: set_object [email protected] z_angle_to  280.0
0177: set_object [email protected] z_angle_to  280.0
0186: [email protected] = create_marker_above_car [email protected]
07E0: set_marker [email protected] type_to 1

0249: release_model #NRG500
0249: release_model #MAFFA
04e0: car [email protected] abandon_path_radius 200
00AD: set_car [email protected] max_speed_to  100.0
04BA: set_car [email protected] speed_instantly  30.0
00AF: set_car [email protected] driver_behaviour_to  1
00AE: unknown_set_car [email protected] to_ignore_traffic_lights  2
0001: wait  250 ms
036A: put_actor $PLAYER_ACTOR in_car [email protected]
0001: wait  250 ms
016A: fade  1 ()  1000 ms
0001: wait  1000 ms
0373: set_camera_directly_behind_player
02EB: restore_camera_with_jumpcut
01B4: set_player $PLAYER_CHAR frozen_state  1 (unfrozen)
0006: [email protected] =  0  // integer values
0006: [email protected] =  0  // integer values
0006: [email protected] =  20000  // floating-point values
0006: [email protected] =  0  // integer values
0007: [email protected] =  -1320.48  // floating-point values
0007: [email protected] =  -407.1  // floating-point values
0007: [email protected] =  13.76  // floating-point values
00A7: car [email protected] drive_to  [email protected] [email protected] [email protected]
00AD: set_car [email protected] max_speed_to  1.0
04e0: car [email protected] abandon_path_radius 250
//08C6: set_actor [email protected]  stay_on_bike 1

:Drive_7
0001: wait 0 ms
if
0256: player $PLAYER_CHAR defined
jf @Drive_7

0050: gosub @Drive_sub_3

if  and
8119:   NOT   car [email protected] wrecked
8119:   NOT   car [email protected] wrecked
8118:   NOT   actor [email protected] dead
jf @Drive_7
if
00FE:   actor $PLAYER_ACTOR  0 ()near_point -1333.5  -408.1  14.1 radius  650.5  650.5  50.5
jf @Drive_12
jump @Drive_7

:Drive_12
0164: disable_marker [email protected]
01C3: remove_references_to_car [email protected]  // Like turning a car into any random car
01C3: remove_references_to_car [email protected]  // Like turning a car into any random car
01C2: remove_references_to_actor [email protected]  // Like turning an actor into a random pedestrian
0108: destroy_object [email protected]
0108: destroy_object [email protected]
0108: destroy_object [email protected]
0108: destroy_object [email protected]
jump @Drive_3


:Drive_sub_3
if
8119:   NOT   car [email protected] wrecked
jf @Drive_sub_109
if
00DB:   actor [email protected] in_car [email protected]
jf @Drive_sub_99
if
0039:   [email protected] ==  1  // integer values
jf @Drive_sub_10
0006: [email protected] =  0  // integer values
jump @Drive_sub_100

:Drive_sub_10
if
0039:   [email protected] ==  0  // integer values
jf @Drive_sub_11
if
01AF:   car [email protected]  0 ()near_point [email protected] [email protected] [email protected] radius  5.2  5.2  5.0
jf @Drive_sub_11
0006: [email protected] =  1  // integer values
0007: [email protected] =  -1181.78  // floating-point values
0007: [email protected] =  -331.30  // floating-point values
0007: [email protected] =  13.76  // floating-point values
000A: [email protected] +=  0  // integer values
0007: [email protected] =  100.0  // floating-point values
0007: [email protected] =  20.0  // floating-point values
04e0: car [email protected] abandon_path_radius 250
jump @Drive_sub_100

:Drive_sub_11
if
0039:   [email protected] ==  1  // integer values
jf @Drive_sub_12
if
01AF:   car [email protected]  0 ()near_point [email protected] [email protected] [email protected] radius  15.2  15.2  5.0
jf @Drive_sub_12
00AD: set_car [email protected] max_speed_to  10.0
0006: [email protected] =  2  // integer values
0007: [email protected] =  -1282.1  // floating-point values
0007: [email protected] =  -159.3  // floating-point values
0007: [email protected] =  13.76  // floating-point values
0175: set_car [email protected] z_angle_to 340.0
000A: [email protected] +=  0  // integer values
0007: [email protected] =  100.0  // floating-point values
0007: [email protected] =  20.0  // floating-point values
04e0: car [email protected] abandon_path_radius 250
jump @Drive_sub_100


:Drive_sub_12
if
0039:   [email protected] ==  2  // integer values
jf @Drive_sub_13
if
01AF:   car [email protected]  0 ()near_point [email protected] [email protected] [email protected] radius  15.2  15.2  5.0
jf @Drive_sub_13
00AD: set_car [email protected] max_speed_to  25.0
0006: [email protected] =  3  // integer values
0007: [email protected] =  -1498.78  // floating-point values
0007: [email protected] =  -138.30  // floating-point values
0007: [email protected] =  13.76  // floating-point values
0175: set_car [email protected] z_angle_to 65.0
000A: [email protected] +=  0  // integer values
0007: [email protected] =  100.0  // floating-point values
0007: [email protected] =  20.0  // floating-point values
04e0: car [email protected] abandon_path_radius 250
jump @Drive_sub_100

:Drive_sub_13
if
0039:   [email protected] ==  3  // integer values
jf @Drive_sub_14
if
01AF:   car [email protected]  0 ()near_point [email protected] [email protected] [email protected] radius  8.2  8.2  5.0
jf @Drive_sub_14
00AD: set_car [email protected] max_speed_to  25.0
0006: [email protected] =  4  // integer values
0007: [email protected] =  -1576.78  // floating-point values
0007: [email protected] =  -202.30  // floating-point values
0007: [email protected] =  13.76  // floating-point values
0175: set_car [email protected] z_angle_to 135.0
000A: [email protected] +=  0  // integer values
0007: [email protected] =  100.0  // floating-point values
0007: [email protected] =  20.0  // floating-point values
04e0: car [email protected] abandon_path_radius 250
jump @Drive_sub_100



:Drive_sub_14
if
0039:   [email protected] ==  4  // integer values
jf @Drive_sub_15
if
01AF:   car [email protected]  0 ()near_point [email protected] [email protected] [email protected] radius  5.2  5.2  5.0
jf @Drive_sub_15
0006: [email protected] =  5  // integer values
0007: [email protected] =  -1694.78  // floating-point values
0007: [email protected] =  -352.30  // floating-point values
0007: [email protected] =  13.9  // floating-point values
0175: set_car [email protected] z_angle_to 135.0
000A: [email protected] +=  0  // integer values
0007: [email protected] =  100.0  // floating-point values
0007: [email protected] =  20.0  // floating-point values
04e0: car [email protected] abandon_path_radius 250
jump @Drive_sub_100

:Drive_sub_15
if
0039:   [email protected] ==  5  // integer values
jf @Drive_sub_16
if
01AF:   car [email protected]  0 ()near_point [email protected] [email protected] [email protected] radius  15.2  15.2  5.0
jf @Drive_sub_16
00AD: set_car [email protected] max_speed_to  10.0
0006: [email protected] =  6  // integer values
0007: [email protected] =  -1691.78  // floating-point values
0007: [email protected] =  -409.30  // floating-point values
0007: [email protected] =  13.9  // floating-point values
0175: set_car [email protected] z_angle_to 180.0
000A: [email protected] +=  0  // integer values
0007: [email protected] =  40.0  // floating-point values
0007: [email protected] =  10.0  // floating-point values
04e0: car [email protected] abandon_path_radius 250
00AE: unknown_set_car [email protected] to_ignore_traffic_lights  2
jump @Drive_sub_100

:Drive_sub_16
if
0039:   [email protected] ==  6  // integer values
jf @Drive_sub_17
if
01AF:   car [email protected]  0 ()near_point [email protected] [email protected] [email protected] radius  8.2  8.2  5.0
jf @Drive_sub_17
00AD: set_car [email protected] max_speed_to  0.0
0006: [email protected] =  7  // integer values
0007: [email protected] =  -1519.78  // floating-point values
0007: [email protected] =  -580.30  // floating-point values
0007: [email protected] =  13.76  // floating-point values
0175: set_car [email protected] z_angle_to 250.0
000A: [email protected] +=  0  // integer values
0007: [email protected] =  100.0  // floating-point values
0007: [email protected] =  0.0  // floating-point values
04e0: car [email protected] abandon_path_radius 250
00AE: unknown_set_car [email protected] to_ignore_traffic_lights  2
jump @Drive_sub_100

:Drive_sub_17
if
0039:   [email protected] ==  7  // integer values
jf @Drive_sub_18
if
01AF:   car [email protected]  0 ()near_point [email protected] [email protected] [email protected] radius  15.2  15.2  5.0
jf @Drive_sub_18
00AD: set_car [email protected] max_speed_to  5.0
01EB: set_car_density_to  0.0
0006: [email protected] =  8  // integer values
0007: [email protected] =  -1299.78  // floating-point values
0007: [email protected] =  -565.30  // floating-point values
0007: [email protected] =  13.76  // floating-point values
0175: set_car [email protected] z_angle_to 0.0
000A: [email protected] +=  0  // integer values
0007: [email protected] =  100.0  // floating-point values
0007: [email protected] =  20.0  // floating-point values
04e0: car [email protected] abandon_path_radius 250
jump @Drive_sub_100


:Drive_sub_18
if
0039:   [email protected] ==  8  // integer values
jf @Drive_sub_109
if
01AF:   car [email protected]  0 ()near_point [email protected] [email protected] [email protected] radius  25.2  25.2  5.0
jf @Drive_sub_109
00AD: set_car [email protected] max_speed_to  0.0
0006: [email protected] =  1  // integer values
000A: [email protected] +=  1  // integer values
0007: [email protected] =  -1181.78  // floating-point values
0007: [email protected] =  -331.30  // floating-point values
0007: [email protected] =  13.76  // floating-point values
0175: set_car [email protected] z_angle_to 1.0
0007: [email protected] =  100.0  // floating-point values
0007: [email protected] =  20.0  // floating-point values
04e0: car [email protected] abandon_path_radius 250
00AE: unknown_set_car [email protected] to_ignore_traffic_lights  2

if
0039:   [email protected] ==  2  // integer values
jf @Drive_sub_100
00BC: text_highpriority 'BJ_LOSE'  5000 ms  1
jump @Drive_sub_100


:Drive_sub_99
if
0039:   [email protected] ==  0  // integer values
jf @Drive_sub_109
00AD: set_car [email protected] max_speed_to  0.0
05CB: actor_goto_and_enter_car [email protected] [email protected]  5000
0006: [email protected] =  1  // integer values
jump @Drive_sub_109

:Drive_sub_100
00A7: car [email protected] drive_to  [email protected] [email protected] [email protected]
00AD: set_car [email protected] max_speed_to  [email protected]
03F0: text_draw_toggle  0
0006: [email protected] =  0  // integer values
jump @Drive_sub_109



:Drive_sub_102
if
01F3:   car [email protected] airborne
jf @Drive_sub_103
0007: [email protected] =  0.0  // floating-point values
00A7: car [email protected] drive_to  [email protected] [email protected] [email protected]
04BA: set_car [email protected] speed_instantly  [email protected]
00AD: set_car [email protected] max_speed_to  [email protected]
jump @Drive_sub_103

:Drive_sub_103
if
01AF:   car [email protected]  0 ()near_point [email protected] [email protected] [email protected] radius  30.2  30.2  5.0
jf @Drive_sub_104
jump @Drive_sub_105

:Drive_sub_104
02E3: [email protected] = car [email protected] speed
if
81F3:   NOT   car [email protected] airborne
jf @Drive_sub_106
if  and
0021:   [email protected] >  30.0  // floating-point values
0019:   [email protected] >  700  // integer values
jf @Drive_sub_105
04BA: set_car [email protected] speed_instantly  50.0

:Drive_sub_105
if
0019:   [email protected] >  2000  // integer values
jf @Drive_sub_109

:Drive_sub_106
0006: [email protected] =  0  // integer values


:Drive_sub_109
0051: return


----------------------------------------------------------------------------

The SF-Airport Circle version 2

Same script as above but now opcode 07E7: AS_assign_scmpath_to_actor is used
It teleports the player to the SF airport on a motorbike and spawns an opponent driver on motorbike who drives around the airort building.
Go outside to the exterior map and press Backspace then follow the opponent driver to see what he do
To refresh the script needs to leave the aiport, you must have a distance of 700.0 units to the startpoint

CODE
{$CLEO .cs}
:scmpath_1
03A4: name_thread 'SCMP'

:scmpath_3
0001: wait 0 ms
if
0256: player $PLAYER_CHAR defined
jf @scmpath_3
077E: [email protected] = active_interior
if  and
0038:   [email protected] ==  0  // integer values
0AB0:   key_pressed 8//----------------------------------------Backspace  
jf @scmpath_3
016A: fade  0 ()  250 ms
0001: wait 250 ms
01B4: set_player $PLAYER_CHAR frozen_state  0 (frozen)
0362: remove_actor $PLAYER_ACTOR from_car_and_place_at -1338.5  -408.1  14.1
0173: set_actor $PLAYER_ACTOR z_angle_to  90.8
0001: wait  500 ms
0247: request_model #NRG500
0247: request_model #MAFFA

:scmpath_5
0001: wait  0 ms
if  and
0248:   model #NRG500 available
0248:   model #MAFFA available
jf @scmpath_5
00A5: [email protected] = create_car #NRG500 at -1333.5  -408.1  14.1
0175: set_car [email protected] z_angle_to  280.0
0224: set_car [email protected] health_to  2000
00A5: [email protected] = create_car #NRG500 at -1354.5  -419.1  14.1
0175: set_car [email protected] z_angle_to  280.0
0224: set_car [email protected] health_to  2000
020A: set_car  [email protected] door_status_to 4
02AC: set_car [email protected] immunities  1  1  1  1  1
01EC: make_car [email protected] very_heavy  1
0129: [email protected] = create_actor  24 #MAFFA in_car [email protected] driverseat
0223: set_actor [email protected] health_to  3000
04E4: unknown_refresh_game_renderer_at  -1333.5  -408.1
03CB: set_camera  -1333.5  -408.1  14.1
029B: [email protected] = init_object 1655 at -1576.02  -202.34  13.76
0177: set_object [email protected] z_angle_to  270.0
01C7: remove_object_from_mission_cleanup_list [email protected]
0382: set_object [email protected] collision_detection  1
029B: [email protected] = init_object 1655 at -1597.9  -506.5  21.7
0177: set_object [email protected] z_angle_to  270.0
01C7: remove_object_from_mission_cleanup_list [email protected]
0382: set_object [email protected] collision_detection  1
029B: [email protected] = init_object 1655 at -1375.9  -581.5  13.69
0177: set_object [email protected] z_angle_to  270.0
01C7: remove_object_from_mission_cleanup_list [email protected]
0382: set_object [email protected] collision_detection  1
029B: [email protected] = init_object 1655 at -1374.9  -585.5  13.69
0177: set_object [email protected] z_angle_to  270.0
01C7: remove_object_from_mission_cleanup_list [email protected]

0382: set_object [email protected] collision_detection  1
0177: set_object [email protected] z_angle_to  135.0
0177: set_object [email protected] z_angle_to  225.0
0177: set_object [email protected] z_angle_to  280.0
0177: set_object [email protected] z_angle_to  280.0
0186: [email protected] = create_marker_above_car [email protected]
07E0: set_marker [email protected] type_to 1

0249: release_model #NRG500
0249: release_model #MAFFA
04e0: car [email protected] abandon_path_radius 200
00AD: set_car [email protected] max_speed_to  100.0
04BA: set_car [email protected] speed_instantly  30.0
00AF: set_car [email protected] driver_behaviour_to  1
00AE: unknown_set_car [email protected] to_ignore_traffic_lights  2
0001: wait  250 ms
036A: put_actor $PLAYER_ACTOR in_car [email protected]
0001: wait  250 ms
016A: fade  1 ()  1000 ms
0001: wait  1000 ms
0373: set_camera_directly_behind_player
02EB: restore_camera_with_jumpcut
01B4: set_player $PLAYER_CHAR frozen_state  1 (unfrozen)
0006: [email protected] =  0  // integer values
0006: [email protected] =  0  // integer values
0006: [email protected] =  20000  // floating-point values
0006: [email protected] =  0  // integer values
0007: [email protected] =  -1320.48  // floating-point values
0007: [email protected] =  -407.1  // floating-point values
0007: [email protected] =  13.76  // floating-point values
00A7: car [email protected] drive_to  [email protected] [email protected] [email protected]
00AD: set_car [email protected] max_speed_to  1.0
04e0: car [email protected] abandon_path_radius 250
08C6: set_actor [email protected]  stay_on_bike 1





:scmpath_7
0001: wait 0 ms
if
0256: player $PLAYER_CHAR defined
jf @scmpath_7

0050: gosub @scmpath_sub_3

if  and
8119:   NOT   car [email protected] wrecked
8119:   NOT   car [email protected] wrecked
8118:   NOT   actor [email protected] dead
jf @scmpath_7
if
00FE:   actor $PLAYER_ACTOR  0 ()near_point -1333.5  -408.1  14.1 radius  650.5  650.5  50.5
jf @scmpath_12
jump @scmpath_7

:scmpath_12
0164: disable_marker [email protected]
01C3: remove_references_to_car [email protected]  // Like turning a car into any random car
01C3: remove_references_to_car [email protected]  // Like turning a car into any random car
01C2: remove_references_to_actor [email protected]  // Like turning an actor into a random pedestrian
0108: destroy_object [email protected]
0108: destroy_object [email protected]
0108: destroy_object [email protected]
0108: destroy_object [email protected]
jump @scmpath_3


:scmpath_sub_3
if
8119:   NOT   car [email protected] wrecked
jf @scmpath_sub_109
if
00DB:   actor [email protected] in_car [email protected]
jf @scmpath_sub_99
if
0039:   [email protected] ==  1  // integer values
jf @scmpath_sub_10
0006: [email protected] =  0  // integer values
jump @scmpath_sub_100

:scmpath_sub_10
if
0039:   [email protected] ==  0  // integer values
jf @scmpath_sub_11
if
01AF:   car [email protected]  0 ()near_point [email protected] [email protected] [email protected] radius  5.2  5.2  5.0
jf @scmpath_sub_11
0006: [email protected] =  1  // integer values
05D6: clear_scmpath
0007: [email protected] =  -1181.78  // floating-point values
0007: [email protected] =  -331.30  // floating-point values
0007: [email protected] =  13.76  // floating-point values
000A: [email protected] +=  0  // integer values
0007: [email protected] =  100.0  // floating-point values
0007: [email protected] =  20.0  // floating-point values
05D7: add_point_to_scmpath [email protected] [email protected] [email protected]
jump @scmpath_sub_100

:scmpath_sub_11
if
0039:   [email protected] ==  1  // integer values
jf @scmpath_sub_12
if
01AF:   car [email protected]  0 ()near_point [email protected] [email protected] [email protected] radius  15.2  15.2  5.0
jf @scmpath_sub_12
00AD: set_car [email protected] max_speed_to  10.0
0006: [email protected] =  2  // integer values
05D6: clear_scmpath
0007: [email protected] =  -1282.1  // floating-point values
0007: [email protected] =  -159.3  // floating-point values
0007: [email protected] =  13.76  // floating-point values
000A: [email protected] +=  0  // integer values
0007: [email protected] =  100.0  // floating-point values
0007: [email protected] =  20.0  // floating-point values
05D7: add_point_to_scmpath [email protected] [email protected] [email protected]
jump @scmpath_sub_100


:scmpath_sub_12
if
0039:   [email protected] ==  2  // integer values
jf @scmpath_sub_13
if
01AF:   car [email protected]  0 ()near_point [email protected] [email protected] [email protected] radius  15.2  15.2  5.0
jf @scmpath_sub_13
00AD: set_car [email protected] max_speed_to  25.0
0006: [email protected] =  3  // integer values
05D6: clear_scmpath
0007: [email protected] =  -1498.78  // floating-point values
0007: [email protected] =  -138.30  // floating-point values
0007: [email protected] =  13.76  // floating-point values
000A: [email protected] +=  0  // integer values
0007: [email protected] =  100.0  // floating-point values
0007: [email protected] =  20.0  // floating-point values
05D7: add_point_to_scmpath [email protected] [email protected] [email protected]
jump @scmpath_sub_100

:scmpath_sub_13
if
0039:   [email protected] ==  3  // integer values
jf @scmpath_sub_14
if
01AF:   car [email protected]  0 ()near_point [email protected] [email protected] [email protected] radius  8.2  8.2  5.0
jf @scmpath_sub_14
00AD: set_car [email protected] max_speed_to  25.0
0006: [email protected] =  4  // integer values
05D6: clear_scmpath
0007: [email protected] =  -1576.78  // floating-point values
0007: [email protected] =  -202.30  // floating-point values
0007: [email protected] =  13.76  // floating-point values
000A: [email protected] +=  0  // integer values
0007: [email protected] =  100.0  // floating-point values
0007: [email protected] =  20.0  // floating-point values
05D7: add_point_to_scmpath [email protected] [email protected] [email protected]
jump @scmpath_sub_100



:scmpath_sub_14
if
0039:   [email protected] ==  4  // integer values
jf @scmpath_sub_15
if
01AF:   car [email protected]  0 ()near_point [email protected] [email protected] [email protected] radius  5.2  5.2  5.0
jf @scmpath_sub_15
0006: [email protected] =  5  // integer values
05D6: clear_scmpath
0007: [email protected] =  -1694.78  // floating-point values
0007: [email protected] =  -352.30  // floating-point values
0007: [email protected] =  13.9  // floating-point values
000A: [email protected] +=  0  // integer values
0007: [email protected] =  100.0  // floating-point values
0007: [email protected] =  20.0  // floating-point values
05D7: add_point_to_scmpath [email protected] [email protected] [email protected]
jump @scmpath_sub_100

:scmpath_sub_15
if
0039:   [email protected] ==  5  // integer values
jf @scmpath_sub_16
if
01AF:   car [email protected]  0 ()near_point [email protected] [email protected] [email protected] radius  15.2  15.2  5.0
jf @scmpath_sub_16
00AD: set_car [email protected] max_speed_to  10.0
0006: [email protected] =  6  // integer values
05D6: clear_scmpath
0007: [email protected] =  -1691.78  // floating-point values
0007: [email protected] =  -409.30  // floating-point values
0007: [email protected] =  13.9  // floating-point values
000A: [email protected] +=  0  // integer values
0007: [email protected] =  40.0  // floating-point values
0007: [email protected] =  10.0  // floating-point values
05D7: add_point_to_scmpath [email protected] [email protected] [email protected]
00AE: unknown_set_car [email protected] to_ignore_traffic_lights  2
jump @scmpath_sub_100

:scmpath_sub_16
if
0039:   [email protected] ==  6  // integer values
jf @scmpath_sub_17
if
01AF:   car [email protected]  0 ()near_point [email protected] [email protected] [email protected] radius  8.2  8.2  5.0
jf @scmpath_sub_17
00AD: set_car [email protected] max_speed_to  0.0
0006: [email protected] =  7  // integer values
05D6: clear_scmpath
0007: [email protected] =  -1519.78  // floating-point values
0007: [email protected] =  -580.30  // floating-point values
0007: [email protected] =  13.76  // floating-point values
000A: [email protected] +=  0  // integer values
0007: [email protected] =  100.0  // floating-point values
0007: [email protected] =  0.0  // floating-point values
05D7: add_point_to_scmpath [email protected] [email protected] [email protected]
00AE: unknown_set_car [email protected] to_ignore_traffic_lights  2
jump @scmpath_sub_100

:scmpath_sub_17
if
0039:   [email protected] ==  7  // integer values
jf @scmpath_sub_18
if
01AF:   car [email protected]  0 ()near_point [email protected] [email protected] [email protected] radius  15.2  15.2  5.0
jf @scmpath_sub_18
00AD: set_car [email protected] max_speed_to  5.0
01EB: set_car_density_to  0.0
0006: [email protected] =  8  // integer values
05D6: clear_scmpath
0007: [email protected] =  -1299.78  // floating-point values
0007: [email protected] =  -565.30  // floating-point values
0007: [email protected] =  13.76  // floating-point values
000A: [email protected] +=  0  // integer values
0007: [email protected] =  100.0  // floating-point values
0007: [email protected] =  20.0  // floating-point values
05D7: add_point_to_scmpath [email protected] [email protected] [email protected]
jump @scmpath_sub_100


:scmpath_sub_18
if
0039:   [email protected] ==  8  // integer values
jf @scmpath_sub_109
if
01AF:   car [email protected]  0 ()near_point [email protected] [email protected] [email protected] radius  25.2  25.2  5.0
jf @scmpath_sub_109
00AD: set_car [email protected] max_speed_to  0.0
0006: [email protected] =  1  // integer values
000A: [email protected] +=  1  // integer values
05D6: clear_scmpath
0007: [email protected] =  -1181.78  // floating-point values
0007: [email protected] =  -331.30  // floating-point values
0007: [email protected] =  13.76  // floating-point values
0007: [email protected] =  100.0  // floating-point values
0007: [email protected] =  20.0  // floating-point values
05D7: add_point_to_scmpath [email protected] [email protected] [email protected]

if
0039:   [email protected] ==  2  // integer values
jf @scmpath_sub_100
00BC: text_highpriority 'BJ_LOSE'  5000 ms  1
jump @scmpath_sub_100


:scmpath_sub_99
if
0039:   [email protected] ==  0  // integer values
jf @scmpath_sub_109
00AD: set_car [email protected] max_speed_to  0.0
05CB: actor_goto_and_enter_car [email protected] [email protected]  5000
0006: [email protected] =  1  // integer values
jump @scmpath_sub_109

:scmpath_sub_100
07E7: AS_assign_scmpath_to_actor [email protected] in_car [email protected] speed [email protected] flags 2 0 3
03F0: text_draw_toggle  0
0006: [email protected] =  0  // integer values
jump @scmpath_sub_109



:scmpath_sub_102
if
01F3:   car [email protected] airborne
jf @scmpath_sub_103
0007: [email protected] =  0.0  // floating-point values
04BA: set_car [email protected] speed_instantly  [email protected]
07E7: AS_assign_scmpath_to_actor [email protected] in_car [email protected] speed [email protected] flags 2 0 3
jump @scmpath_sub_103

:scmpath_sub_103
if
01AF:   car [email protected]  0 ()near_point [email protected] [email protected] [email protected] radius  30.2  30.2  5.0
jf @scmpath_sub_104
jump @scmpath_sub_105

:scmpath_sub_104
02E3: [email protected] = car [email protected] speed
if
81F3:   NOT   car [email protected] airborne
jf @scmpath_sub_106
if  and
0021:   [email protected] >  30.0  // floating-point values
0019:   [email protected] >  700  // integer values
jf @scmpath_sub_105
04BA: set_car [email protected] speed_instantly  50.0

:scmpath_sub_105
if
0019:   [email protected] >  2000  // integer values
jf @scmpath_sub_109

:scmpath_sub_106
0006: [email protected] =  0  // integer values


:scmpath_sub_109
0051: return

ZAZ
  • ZAZ

    Kernlochbohrer

  • Feroci
  • Joined: 10 Jan 2005
  • European-Union
  • Contribution Award [Mods]
    Helpfulness Awards [Mods]

#30

Posted 29 August 2009 - 01:22 PM Edited by ZAZ, 07 March 2016 - 04:59 PM.

Use Carrec Paths to let a vehicle move along a recorded route

Record a path with Seemanns carrec.cs
More informations at http://www.gtaforums...howtopic=297295

Its created then in GTASA\data\paths

Rename it to carrec899.rrr and import it into carrec.img
Then use the script below to assigne player car to the path


{$CLEO .cs}
:DrvCarrec_1
03A4: name_thread 'DRVCARC'

:DRVCARC_11
0001: wait 0 ms
00D6: if
0256:   player $PLAYER_CHAR defined
004D: jump_if_false @DRVCARC_11
00D6: if and
0AB0:   key_pressed 57
00DF:   actor $PLAYER_ACTOR driving
004D: jump_if_false @DRVCARC_11
03C0: [email protected] = actor $PLAYER_ACTOR car
0A30: repair_car [email protected]
0224: set_car [email protected] health_to 1000
0006: [email protected] = 899
07C0: load_path [email protected]

:DRVCARC_85
0001: wait 0 ms
00D6: if
07C1:   path [email protected] available
004D: jump_if_false @DRVCARC_85
00D6: if
8119:   not car [email protected] wrecked
004D: jump_if_false @DRVCARC_218
0001: wait 500 ms
05EB: assign_car [email protected] to_path [email protected]

:DRVCARC_148
0001: wait 0 ms
00D6: if
0256:   player $PLAYER_CHAR defined
004D: jump_if_false @DRVCARC_218
00D6: if or
0AB0:   key_pressed 48
0119:   car [email protected] wrecked
004D: jump_if_false @DRVCARC_195
0002: jump @DRVCARC_218

:DRVCARC_195
00D6: if
00DF:   actor $PLAYER_ACTOR driving
004D: jump_if_false @DRVCARC_218
0002: jump @DRVCARC_148

:DRVCARC_218
0001: wait 0 ms
00D6: if
0256:   player $PLAYER_CHAR defined
004D: jump_if_false @DRVCARC_218
0373: set_camera_directly_behind_player
02EB: restore_camera_with_jumpcut
05EC: release_car [email protected] from_path
0873: release_path [email protected]
01C3: remove_references_to_car [email protected] // Like turning a car into any random car
0001: wait 1000 ms
0002: jump @DRVCARC_11




1 user(s) are reading this topic

0 members, 1 guests, 0 anonymous users