QQ登录

只需一步,快速开始

 找回密码
 定下契约(新注册)

QQ登录

只需一步,快速开始

查看: 5293|回复: 30
收起左侧

【CLEO教学系列】CLEO脚本教程(未完工)

[复制链接]

传奇 Legend

虚拟世界,属于你的世界

Rank: 16

UID
4
宝石
154 粒
金币
5594 枚
节操
458 斤
灵石
0 块
精力
509 ℃
QQ
发表于 2012-4-7 09:44:29 | 显示全部楼层 |阅读模式

你这样只看不注册,真的大丈夫?~

您需要 登录 才可以下载或查看,没有账号?定下契约(新注册)

x
本帖最后由 【游骑兵】天涯 于 2012-4-14 08:56 编辑

翻译:【游骑兵】天涯
原帖地址:http://www.gtaforums.com/index.php?showtopic=403594
初次接触翻译 纰漏之处 在所难免 望指正
建议前往英文站看英文原文 便于理解
注:目前正在汉化中,没有审核已汉化部分,所以请勿过分相信已翻译部分 待翻译完毕+后期审核完毕后请再次查看
由于小道时间不够 手机上论坛常挂 所以正在使用手机Word编辑软件编辑要翻译的内容(汗 手机打字翻译好辛苦)--意思是 近期 此贴将不会更新 完工后更新 sorry for my bad chinese
                                                                                               未经许可 谢绝转载
______________________________________________________________________________________
       ______________________________________________________________________________________

使用Sanny Builder(以下简称SB)进行CLEO脚本编写的第一步:
下载最新版本的Sanny Builder:
http://sannybuilder.com/
或者下载【下载】SB汉化版+最小启动包 有汉化版SB
下载地址:http://game.55660.net/thread-138-1-1.html
安装SB并为你的脚本文件创建一个目录
因此你可以选择到你的游戏目录(此句不明)
然后启动SB
打开一个新的空白页面
复制如下脚本源码并把它插入到新的页面






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


把它保存到你刚才创建的脚本文件文件存放目录并且重命名


编译这个脚本 点击菜单上奔跑的人形图标来执行编译+复制操作
如果已经安装过CLEO library 这个脚本文件会被编译并且复制到游戏目录/CLEO目录(前提是安装过CLEO主程序)
{$CLEO .cs} = Cleo 指令会被编译为 以*.cs为后缀的格式文件
而DEMOTEXT.txt 会被保存 并且编译为 DEMOTEXT.cs
______________________________________________________________________________________

如果CLEO主程序没有安装,在SB的右下角处会有红色的安装提示.点击此处SB会快速安装完成.(此处不明 不知道是什么情况 SB自动安装CLEO主程序?)
也可以前往
http://cleo.sannybuilder.com下载最新版CLEO主程序安装器
______________________________________________________________________________________

如果编译成功完成,你会看到如下提示框






点击OK确定

最下面的部分 Largest Script显示的是脚本文件大小
其他的部分属于Main.scm的编译信息
进入游戏测试此脚本,点击0键或Ctrl键按键来显示TEXT的文本信息
这个脚本执行结束,会被收起(不明)因为此脚本是以opcode
0A93: end_custom_thread
而结束。

______________________________________________________________________________________
______________________________________________________________________________________

编辑器

主要的功能可以在菜单栏的相关按钮处找到
1. 汇编: SB打开如下几种脚本文件扩展名 .CS, .CM or .SCM

2. 编译: SB 编译 通过默认(不明)一个 [Name]main.SCM

SB自动编译CLEO脚本文件, 如果这个脚本 有一个  Cleo-Direktive 作为入口

{$CLEO .cs} = Cleo-Direktive, 会被编译为 .CS后缀名的文件
{$CLEO .cm} = Cleo-Direktive, 会被编译为.CM后缀名的文件














有用的小工具
选择菜单栏上的Tools选项 IDE tools--Coords Manager
读取X Y Z  
coordinate(不明)和主角CJ的当前方位的方位角(前提是游戏运行)

选择菜单栏上的Tools选项 IDE tools--Opcode Search
来搜索Opcode
输入任何字符来寻找包含这个字符的句子
或者输入Opcode来搜索这类型的句子
搜索结果存在于原版main.scm中
这个Opcode搜索工具需要在 Sanny Builder 3\data\sa folder下创建一个Opcode.txt文本
用SB加载汇编的原版 main 然后选择SB的工具栏, 制作Opcode.txt.

行号
选择Tools(工具)--Option(选项)
在选项 编辑栏 你可以找到开关行号显示的选项
行号是编辑器的一部分,不是脚本的内容。

SB帮助文本
选择菜单栏的帮助文本, 然后按照需要查找信息。,
比如键位, 武器编号, 身体部分等等..



______________________________________________________________________________________
______________________________________________________________________________________



选项: different view of the decompiled code

选择 TOOLS(工具), option(选项)

Option(选项)整体 你可以看见不同的编译方法(不明)




1. 编写Opcode

所有条目以Opcode显示
Opcode是脚本功能的程序编码
他们看起来就像是命令指令
带有Opcode的脚本:

CODE
:CARSL_6439
00D6: if
00E1:   player 0 pressed_key 16
004D: jump_if_false @CARSL_6535
010B: 5@ = player $PLAYER_CHAR money
00D6: if
002D:   5@ >= 14@ // (int)
004D: jump_if_false @CARSL_6512
0012: 14@ *= -1
0109: player $PLAYER_CHAR money += 14@  
0002: jump @CARSL_6700


2. 不使用Opcode
脚本更加小, 可能更加清晰
特别是004D: jump_if_false 可以简写为jf
但并不是所有Opcode不使用. 更多编码会被广泛的使用以此运行相应的功能

Script without opcodes:

CODE
:CARSL_6439
if
00E1:   player 0 pressed_key 16
jf @CARSL_6535
5@ = Player.Money($PLAYER_CHAR)
if
002D:   5@ >= 14@ // (int)
jf @CARSL_6512
14@ *= -1
Player.Money($PLAYER_CHAR) += 14@
jump @CARSL_6700


你使用还是不使用Opcode并不会有什么影响
SB还是会正常编译

一个不使用Opcode汇编额特殊方法是把Opcode Based命令翻译为
ClassesKeywords

详情参阅Sannybuilder-帮助主题文件: Coding >> Classes

下面是使用Opcode编译的代码:
00AB: put_car 22@ at -1577.942 52.6333 40.0

此句不使用Opcode就如下显示:

Car.PutAt(22@, -1577.942, 52.6333, 40.0)

编码的意义 by the class entries(不清楚)

Car= 类-name
PutAt= 类-member
name and member are combined with a dot in the middle(不明)
22@ = class-owner
class-owner and parameters are placed in brackets and separated with comma
(parameter = needed information for the command)--此段不清晰 望翻译




SB可以使用Keywords(关键词)来替代Opcode
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


004D: jump_if_false @MAIN_6
可以写为
jf @MAIN_6
或者else_jump @MAIN_6
你还可以合并为
004D: jf @MAIN_6


______________________________________________________________________________________
______________________________________________________________________________________


Data types(数据类型)


: (doublepoint) marks a Label (adress)--不明

CODE
:MAIN_1


@ 有2种不同功能
1. 跳转到相应的标签
CODE
004D: jump_if_false @SAVE_5
0050: gosub @SAVE_14
0002: jump @SAVE_1


2.链接局部变量
游戏中的物件需要 一个类似身份登记的办法 来处理

执行
这个身份登记可以理解为 变量,
局部变量由@和数字组合而成

0@, 1@, ... 30@ 从
0@ 到 31@ 是允许的 , 32@ 和33@ are for timers, thats maximum in an .cs file(不懂此处作用 等kami)
如下
1@ 定义 一个车辆的创建产生
CODE
014B: 1@ = 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

1@ 还可以用作局部变量名称(此处指代替这辆车)
CODE
014C: set_parked_car_generator 1@ cars_to_generate_to 101



$ 用来链接全局变量
游戏中的物件需要 一个类似身份登记的办法 来处理
执行
这个身份登记可以理解为 变量
全局变量是以$ 为标志和一些单词,数字之类组成的
在CLE脚本中使用全局变量会导致游戏BUG和崩溃

只有 $PLAYER_CHAR, $PLAYER_ACTOR, $ONMISSION 才是有效地

全局, 局部, 何解?
全局变量运用于Mani.scm中以此在不同游戏线程中相互连接

局部变量同样也是运用于main.scm中但是他们不能在不同游戏线程中相互连接
你可以在线程中用局部变量创建一辆汽车标记为1@同时在main.scm的其他线程中使用1@
1@ = create_car
你有2种不同的车辆,存在于不同的线程命令中

你可以在一个线程中使用全局变量创建一辆汽车但是不在其他线程中再次使用同一个全局变量来创建这辆汽车
$mycar5 = create_car
但是你可以从main.scm的其他线程中调用这辆汽车
全局变量是可储存的,而局部变量则不行
但是在CLEO脚本中使用全局变量会导致游戏BUG和崩溃
只有 $PLAYER_CHAR, $PLAYER_ACTOR, $ONMISSION 才不会



#作为加载模型名称的接入口标志


CODE
0247: load_model #BMYCG
0247: load_model #HMYCM
0247: load_model #SWATVAN
0247: load_model #M4
0247: load_model #COLT45

CLEO只能调用已经定义存储于vehicles.ide, peds.ide or default.ide的内容
其他的模型需要使用他们的ID编号

'...' 短型字符串是用来插入字母或编号 就像GTX entrynames 或者  特殊 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


"..."长型字符串是用来插入字母或编号比如动作-  IFP 文件名称, 身体部位名称, particel 名称, 等待
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 5@ walk_style_to "GANG2"
064B: 25@ = 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设定线程接入口(或者说变量名称)必须使用特殊的Opcode和扩展变量标志( 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: 5@s = 'FEM_OK'
00BC: show_text_highpriority GXT 5@s time 10000 flag 1


s$ - global-string-variable(全局线程变量)
注意在CLEO脚本中使用全局变量 会导致游戏BUG或者崩溃
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: 5@s = s$Actor_Speech_GXT_Reference
00BC: show_text_highpriority GXT 5@s time 10000 flag 1


@v - local-long-string-variable(局部长型线程变量)
CODE
06D2: 28@v = "LAPDAN1" // @v = string
0812: AS_actor $PLAYER_ACTOR perform_animation "LAPDAN_P" IFP_file 28@v 1000.0 loopA 0 lockX 0 lockY 0 lockF 1 time -1


v$ - global-long string-variable(全局长型变量)
注意在CLEO脚本中使用全局变量 会导致游戏BUG或者崩溃
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(不明)

在游戏中运行的脚本叫做线程

他们是用create_thread命令或者一个定义任务的脚本定义于Main.scm中作为线程

The cleo programm checks if there is .cs file in the Cleo folder
and if yes, it start this script as threadCLEO程序会扫描CLEO目录是否存在CS文件

如果存在,游戏就会加载这个CLEO脚本。

Script structur / short version:(不知道)

首先,在开头,会以CLEO指令开始

CODE
{$CLEO .cs}

First Label (adress)
CODE
:Akt

然后给线程定义一个名称
CODE
03A4: name_thread 'AKT'

现在写入一个代码然后用end_custom_thread 结束线程
一切OK后进游戏测试

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(不知道)
脚本会以opcode 0A93: end_custom_thread结束
The script will be started by each loading of savegame or by start new game

这个脚本会在每次加载存档运行或者开启新游戏后运行

______________________________________________________________________________________



下一步/使用环境条件检查

一个环境条件检查需要最少3个Opcode

1. IF 条件

2. 真正情况
3. 反向跳转设置


1. if

2. 0AB0: key_pressed 8

3. 004D: jump_if_false @akt_01


我们再次使用先前的脚步但是现在我们想要切换到正常模式因此我们使用一个环境检查,建立一个循环

Loop means that a jump instruction can send the reading process to a previous adress
I call such an adress "Loop-adress"循环意味着一个跳转命令可以传达信息到先前的地址 我把它叫做循环地址(Loop-adress)--不确定

在这样一个循环跳转后必须等待XXX毫秒

跳转指令可以是反向跳转或者正向跳转

CODE
004D: jump_if_false @akt_01

or
CODE
0002: jump @akt_01



对于如下脚本的按键环境检查是通过按Backspace键执行的

  1. CODE
  2. {$CLEO .cs}:Akt03A4: name_thread 'AKT'08B2: toggle_thermal_vision 1:Akt_01//----------------------------Loop adresse0001: wait 0 msif0AB0: key_pressed 8004D: jump_if_false @Akt_01//--------jump instruction by negation08B2: toggle_thermal_vision 00A93: 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

  1. CODE
  2. if00FF: actor $PLAYER_ACTOR 1 (in-sphere)near_point_on_foot 2493.5 -1682.5 13.35 radius 1.0 1.0 1.0004D: 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 0@ 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 7@ dead
8118:   NOT   actor 8@ 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: 1@ = actor $PLAYER_ACTOR car
0229: set_car 1@ color_to 17 0
02AC: set_car 1@ immunities BP 1 FP 1 EP 1 CP 1 MP 1
053F: set_car 1@ 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 1@

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: 1@ = actor $PLAYER_ACTOR car
Then we can use this variable name 1@ 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




______________________________________________________________________________________



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
00D6: if  0
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: 1@ = create_car #INFERNUS at 2487.5  -1660.5  13.35
0175: set_car 1@ 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 1@  // 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 1@


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
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: 1@ = create_car #INFERNUS at 2487.5  -1660.5  13.35
0175: set_car 1@ 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 1@  // 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
00D6: if 0
0256: player $PLAYER_CHAR defined
004D: jump_if_false @JumpR01
00D6: if  0
00E1:   key_pressed  0  10//--------- No key  
004D: jump_if_false @JumpR01
0247: request_model 1655

:JumpR02
0001: wait  0 ms
00D6: if  0
0248:   model 1655 available
004D: jump_if_false @JumpR02
0172: 2@ = actor $PLAYER_ACTOR z_angle
04C4: create_coordinate 11@ 12@ 13@ from_actor $PLAYER_ACTOR offset 0.0 14.5 -1.8
0107: 1@ = create_object 1655 at  11@ 12@ 13@
0177: set_object 1@ z_angle_to  2@
0001: wait  0 ms
0249: release_model 1655
0001: wait  1000 ms
01C4: remove_references_to_object 1@  // 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
00D6: if  0
0256:   player $PLAYER_CHAR defined
004D: jump_if_false @Actor_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 @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: 1@ = create_actor  24 120 at  2486.5  -1664.5  13.45
0173: set_actor 1@ z_angle_to  180.0
01B2: give_actor 1@ weapon  30 ammo  99999  // Load the weapon model before using this
02E2: set_actor 1@ weapon_accuracy_to  100
0223: set_actor 1@ health_to  1000
05E2: AS_actor 1@ kill_actor $PLAYER_ACTOR
0249: release_model 120

:Loop_1
0001: wait  0 ms
00D6: if  0
8118:   NOT   actor 1@ dead
004D: jump_if_false @Cleanup_1
00D6: if  0
0104:   actor $PLAYER_ACTOR near_actor 1@ 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 1@ // 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: 1@ = create_actor  8 #TRIBOSS at  2486.5  -1664.5  13.45

An actor with pedtype 7 is agressive like an enemy gangmember
CODE
009A: 1@ = 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: 1@ = 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 1@ cars_to_generate_to  101

032B: 2@ = 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 3@ 4@ 5@ 6@ 29@ 8@ 9@ 10@

The started thread recieves these parameter values with following rule
0@ get value of 1.parameter
1@ get value of 2.parameter
2@ get value of 3.parameter
3@ get value of 4.parameter
4@ 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: 13@ =  10  // integer values
0AB3: var 0 = 13@

and
0AB4: 0@= 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: 13@ = var 44
if
0039:   13@ ==  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: 7@ = var 955
00D6: if
8039:   not  7@ == 0
004D: jump_if_false @CARSTOR_150
0AB4: 3@ = var 951
0AB4: 4@ = var 952
0AB4: 5@ = var 953
0AB4: 6@ = var 954
0AB4: 7@ = var 955
0AB4: 8@ = var 956
0AB4: 9@ = var 957
0AB4: 10@ = var 958
0093: 3@ = integer 3@ to_float
0093: 4@ = integer 4@ to_float
0093: 5@ = integer 5@ to_float
0093: 6@ = integer 6@ 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: 2@ = actor $PLAYER_ACTOR car
00AA: store_car 2@ position_to 3@ 4@ 5@
0174: 6@ = car 2@ Z_angle
0441: 7@ = car 2@ model
0988: get_car 2@ paintjob 8@
03F3: get_car 2@ primary_color_to 9@ secondary_color_to 10@
020A: set_car 2@ door_status_to 0
02AC: set_car 2@ immunities BP 1 FP 1 EP 1 CP 1 MP 1
0519: set_car 2@ locked 1
0633: AS_actor $PLAYER_ACTOR exit_car
0092: 13@ = float 3@ to_integer
0092: 14@ = float 4@ to_integer
0092: 15@ = float 5@ to_integer
0092: 16@ = float 6@ to_integer
0AB3: var 951 = 13@
0AB3: var 952 = 14@
0AB3: var 953 = 15@
0AB3: var 954 = 16@
0AB3: var 955 = 7@
0AB3: var 956 = 8@
0AB3: var 957 = 9@
0AB3: var 958 = 10@
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 2@ sunk
004D: jump_if_false @CARSTOR_738
00D6: if
8119:   not car 2@ wrecked
004D: jump_if_false @CARSTOR_550
00D6: if
0202:   actor $PLAYER_ACTOR near_car 2@ 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 2@
004D: jump_if_false @CARSTOR_403
02AC: set_car 2@ immunities BP 0 FP 0 EP 0 CP 0 MP 0
0519: set_car 2@ locked 0
0002: jump @CARSTOR_738

:CARSTOR_550
01C3: remove_references_to_car 2@ // 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 3@ 4@ 5@ radius 80.0 80.0 50.0
004D: jump_if_false @CARSTOR_555
0002: jump @CARSTOR_624

:CARSTOR_624
0247: load_model 7@

:CARSTOR_629
0001: wait 0 ms
00D6: if
0248:   model 7@ available
004D: jump_if_false @CARSTOR_629
0001: wait 0 ms
00A5: 2@ = create_car 7@ at 3@ 4@ 5@
0175: set_car 2@ Z_angle_to 6@
06ED: set_car 2@ paintjob 8@
0229: set_car 2@ primary_color_to 9@ secondary_color_to 10@
020A: set_car 2@ door_status_to 0
02AC: set_car 2@ immunities BP 1 FP 1 EP 1 CP 1 MP 1
0519: set_car 2@ locked 1
0249: release_model 7@
0002: jump @CARSTOR_403

:CARSTOR_738
01C3: remove_references_to_car 2@ // 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 1@ dead
004D: jump_if_false @Cleanup_1
00D6: if  0
0104:   actor $PLAYER_ACTOR near_actor 1@ 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 1@ // Like turning an actor into a random pedestrian
0002: jump @MODLSUB_2


:MODLSUBROUTINE
0005: 1@ = 2473.25
0005: 2@ = -1657.79
0005: 3@ = 13.4
0005: 4@ = 2501.12
0005: 5@ = -1676.5
0005: 6@ = 13.4
0208: 7@ = random_float_in_ranges 1@ 4@
0208: 8@ = random_float_in_ranges 2@ 5@
0208: 9@ = random_float_in_ranges 3@ 6@
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: 1@ = create_actor  24 #TRIBOSS at  7@ 8@ 9@
0173: set_actor 1@ z_angle_to  180.0
01B2: give_actor 1@ weapon  30 ammo  99999  // Load the weapon model before using this
02E2: set_actor 1@ weapon_accuracy_to  100
0223: set_actor 1@ health_to  1000
05E2: AS_actor 1@ 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
Create a FXT file to show your own text message
Load a special actor
Tuning parts
Animations
Music, wave and sounds of Audio folder

Give access with math coding

______________________________________________________________________________________
______________________________________________________________________________________


Create a FXT file to show your own text message

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
CODE
TXT_01 This is text of Cleo fxt file

Then use the script below to show the text by key_press
CODE
{$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
CODE
023C: load_special_actor 'ogloc' as 1

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
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
CODE
009A: 0@ = 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
CODE
0296: unload_special_actor  1

5. Release the defined item from script when the script has done its work
same like other actors
CODE
01C2: remove_references_to_actor 0@


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
CODE
{$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 29@
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 11@ 12@ 13@ from_actor $PLAYER_ACTOR with_offset 0.0 4.0 0.2
009A: 0@ = create_actor_pedtype 24 model #SPECIAL01 at 11@ 12@ 13@
0223: set_actor 0@ health_to 10000
0860: link_actor 0@ to_interior 29@
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 0@ dead
004D: jump_if_false @SPACTOR_201
0002: jump @SPACTOR_158

:SPACTOR_201
01C2: remove_references_to_actor 0@ // 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

CODE
{$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 29@
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 11@ 12@ 13@ from_actor $PLAYER_ACTOR with_offset -2.0 2.0 0.2
009A: 0@ = create_actor_pedtype 24 model #SPECIAL01 at 11@ 12@ 13@
0223: set_actor 0@ health_to 10000
0860: link_actor 0@ to_interior 29@
04C4: store_coords_to 11@ 12@ 13@ from_actor $PLAYER_ACTOR with_offset 0.0 2.0 0.2
009A: 1@ = create_actor_pedtype 24 model 291 at 11@ 12@ 13@
0223: set_actor 1@ health_to 10000
0860: link_actor 1@ to_interior 29@
04C4: store_coords_to 11@ 12@ 13@ from_actor $PLAYER_ACTOR with_offset 2.0 2.0 0.2
009A: 2@ = create_actor_pedtype 24 model #SPECIAL03 at 11@ 12@ 13@
0223: set_actor 2@ health_to 10000
0860: link_actor 2@ to_interior 29@
04C4: store_coords_to 11@ 12@ 13@ from_actor $PLAYER_ACTOR with_offset -2.0 4.0 0.2
009A: 3@ = create_actor_pedtype 24 model 293 at 11@ 12@ 13@
0223: set_actor 3@ health_to 10000
0860: link_actor 3@ to_interior 29@
04C4: store_coords_to 11@ 12@ 13@ from_actor $PLAYER_ACTOR with_offset 2.0 4.0 0.2
009A: 4@ = create_actor_pedtype 24 model #SPECIAL05 at 11@ 12@ 13@
0223: set_actor 4@ health_to 10000
0860: link_actor 4@ to_interior 29@
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 0@ dead
8118:   not actor 1@ dead
8118:   not actor 2@ dead
8118:   not actor 3@ dead
8118:   not actor 4@ dead
004D: jump_if_false @SPACMOR_626
0002: jump @SPACMOR_563

:SPACMOR_626
01C2: remove_references_to_actor 0@ // Like turning an actor into a random pedestrian
01C2: remove_references_to_actor 1@ // Like turning an actor into a random pedestrian
01C2: remove_references_to_actor 2@ // Like turning an actor into a random pedestrian
01C2: remove_references_to_actor 3@ // Like turning an actor into a random pedestrian
01C2: remove_references_to_actor 4@ // 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
CODE
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"
CODE
: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
CODE
06E7: 1@ = add_car_component #NTO_B_S to_car 0@
06E7: 2@ = add_car_component #hydralics to_car 0@
06E7: 3@ = add_car_component 1115 to_car 0@

4. release the loaded tuning part model file if it is not needed anymore
CODE
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
CODE
{$CLEO .cs}
:TuneP_1
03A4: name_thread 'TuneP'

:TuneP_2
0001: wait  0 ms
00D6: if  0
0256:   player $PLAYER_CHAR defined
004D: jump_if_false @TuneP_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 @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: 0@ = create_car #SLAMVAN at 2487.5  -1660.5  13.35
0175: set_car 0@ z_angle_to 180.0

06E7: 1@ = add_car_component #NTO_B_S to_car 0@
06E7: 2@ = add_car_component #hydralics to_car 0@
06E7: 3@ = add_car_component 1115 to_car 0@

0229: set_car 0@ color_to  1  1
06ED: set_car 0@ 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  0
0256:   player $PLAYER_CHAR defined
004D: jump_if_false @TuneP_4
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 @TuneP_4
01C3: remove_references_to_car 0@  // Like turning a car into any random car
0002: jump @TuneP_2



______________________________________________________________________________________
______________________________________________________________________________________



Animations

To use animations exist 2 opcodes, 0605: and 0812:
CODE
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

CODE
{$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
CODE
04ED: load_animation "PARK"

2. second step to prove if the file is loaded in an extra "load-model-check-Loop"
CODE
: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
CODE
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
CODE
04EF: release_animation "PARK"

5. Release a defined item is not possible but in some cases it needs to remove the animation from actor
CODE
0792: disembark_instantly_actor $PLAYER_ACTOR

In addition by using animation packs, it needs to release the pack
CODE
061B: remove_references_to_AS_pack 0@



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
CODE
{$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
CODE
{$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 0@
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 0@ loop 1
0616: define_AS_pack_end 0@
0618: assign_actor $PLAYER_ACTOR to_AS_pack 0@
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 0@
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
CODE
{$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 Music files 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
CODE
041E: set_radio_station 3
051E: 1@ = get_current_radio_station
0A26: set_radio_to_favorite_station



Music of GTASA\AUDIO\Streams\BEAT and AMBIENCE can be played with other opcodes
CODE
0953: get_soundtrack_status_to 17@
if
0039:   17@ ==  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
CODE
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\SFX are 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


///////WAVE/////
The most part of AudioEvents.txt includes waves and must used with
CODE
03CF: load_wav  1828 as  1
00D6: if  0
03D0:   wav  1 loaded
004D: jump_if_false @
03D1: play_wav 1

can be attached to actor or object
CODE
0949: link_wav 1 to_actor 0@

if wave is finish should be unloaded
CODE
040D: unload_wav 1

in original is usual to unload wav before loading a wav
CODE
:AUDIOL_33
00D6: if  0
0039:   4@ ==  0  // integer values
004D: jump_if_false @AUDIOL_38
040D: unload_wav 3@
03CF: load_wav 7@ as 3@

you can also check if the sound is finish
CODE
00D6: if  0
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
CODE
09D5: play_sound_of_actor $PLAYER_ACTOR soundslot 342 flags 1  1  1 as 2@


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, 2@ 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


______________________________________________________________________________________
______________________________________________________________________________________




评分

参与人数 5宝石 +14 金币 +142 精力 +4 节操 +2 灵石 +2 +2 收起 理由
SONY + 2 + 2 + 2 + 2 + 2 + 2
750523466 + 20
kwanz + 2 + 20 这个真心是大坑啊= =
祭祀秀忒 + 2 + 20 + 2 支持下
Ycccccc + 8 + 80 大工程,先加分了

查看全部评分

传奇 Legend

虚拟世界,属于你的世界

Rank: 16

UID
4
宝石
154 粒
金币
5594 枚
节操
458 斤
灵石
0 块
精力
509 ℃
QQ
 楼主| 发表于 2012-4-7 10:36:55 | 显示全部楼层
本帖最后由 kwanz 于 2012-4-18 18:05 编辑

数学运算编程
-用数学运算实现流程控制
-用局部变量实现流程控制
-声明还是不声明? (I)
-时间检测-真实毫秒数
-时间检测-游戏时间
-整型数和浮点数
-声明还是不声明? (II)
-整型与浮点型的转换
-用text_draw opcode显示数学运算的值
-运算编程
______________________________________________________________________________________
______________________________________________________________________________________
用数学运算实现流程控制
运算编程不只是用来计算。
写运算程序的一个重要作用是控制脚本程序的执行段落
为此我们声明一个变量
  1. //example:
  2. $RYDER_TOTAL_PASSED_MISSIONS = 0
  3. 0@ = 0
复制代码

接下来我们检查这个变量是否等于某个值,若相等,则想判定的条件成立
两个最重要的流程控制检查,是原版main.scm中的任务启动代码和ONMISSION标志是否为零的检测
$ONMISSION声明在原版main.scm的MAIN分节,作为一个特殊的任务状态控制器
  1. set_on_mission_flag_to $ONMISSION
复制代码

ONMISSION在新游戏开始时的第一次更改,是自由城机场的开场任务
  1. :INTRO_47
  2. $ONMISSION = 1
复制代码

下面的代码是任务RYDER的启动部分的缩减版
检测$ON_MISSION==0且$RYDER_TOTAL_PASSED_MISSIONS==0
若条件成立,则跳到RYDER任务开始处
但它首先把$ONMISSION设为1,防止其他任务从启动代码处启动
$RYDER_TOTAL_PASSED_MISSIONS的值在R点任务完成的时候改变
注意,在CLEO中使用全局变量,可能会导致bug或死机,只有%PLAYER_CHAR, $PLAYER_ACTOR, $ONMISSION可以放心使用
  1. :RYDER_11
  2. wait 0
  3. if
  4. Player.Defined($PLAYER_CHAR)
  5. else_jump @RYDER_342
  6. if
  7. $ONMISSION == 0
  8. else_jump @RYDER_342
  9. if
  10. 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
  11. else_jump @RYDER_342
  12. if
  13. $RYDER_TOTAL_PASSED_MISSIONS == 0
  14. else_jump @RYDER_238
  15. $ONMISSION = 1
  16. start_mission 24 // Home Invasion
  17. jump @RYDER_238

  18. :RYDER_238
  19. if
  20. $RYDER_TOTAL_PASSED_MISSIONS == 1
  21. else_jump @RYDER_290
  22. $ONMISSION = 1
  23. start_mission 25 // Catalyst

  24. :RYDER_290
  25. if
  26. $RYDER_TOTAL_PASSED_MISSIONS == 2
  27. else_jump @RYDER_342
  28. $ONMISSION = 1
  29. start_mission 26 // Robbing Uncle Sam

  30. :RYDER_342
  31. jump @RYDER_11
复制代码

$RYDER_TOTAL_PASSED_MISSIONS的值在R点任务完成的时候改变 它会自加1
  1. $RYDER_TOTAL_PASSED_MISSIONS += 1
复制代码

第一个任务结束后它就等于1
  1. $RYDER_TOTAL_PASSED_MISSIONS = 1
复制代码

然后再检查是否有$RYDER_TOTAL_PASSED_MISSIONS==1成立,若是则开始下一个任务
  1. if
  2. $RYDER_TOTAL_PASSED_MISSIONS == 1
  3. else_jump @RYDER_290
  4. $ONMISSION = 1
  5. start_mission 25 // Catalyst 催化剂
复制代码


用局部变量实现流程控制

用单等号赋值
  1. 1@ = 0
复制代码


用双等号判断两个值是否相等
  1. 1@ == 0
复制代码


下面的代码去除进出老家的倒三角,并在人物5@被杀死后还原
检查标志变量1@分为3步
我们这里只需要一个循环来执行多条指令
当然还有一个检测模型加载的循环不在讨论范围内

首先,程序检查玩家是否在0号空间,也就是室外空间,以防玩家被困在屋内
077E: get_active_interior_to 29@ 声明了变量29@并赋值
如果玩家在室外,进入室内标志被移除,标志变量被改写
1@ = 1
然后程序执行第二步检查,检查玩家是否进圈,继续执行程序
if
0039: 1@ == 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

如果两个条件同时满足,则刷出人物5@,跟玩家打架
若人物5@被杀死,则再次改写标志变量,继续执行第三步程序
也就是,若人物5@被杀死,则老家恢复可进入,程序结束

若玩家不攻击5@而逃跑,则返回第二步判断
检测5@和玩家的距离是否大于80.0
若是,则解除对人物5@的引用,1@被赋为1
  1. {$CLEO .cs}
  2. :Access_1
  3. 03A4: name_thread 'Access_'
  4. 1@ = 0

  5. :Access_2
  6. 0001: wait 0 ms
  7. 00D6: if 0
  8. 0256: player $PLAYER_CHAR defined
  9. 004D: jump_if_false @Access_2

  10. if//-- 第一步检测
  11. 0039: 1@ == 0
  12. 004D: jump_if_false @Access_3//------ 跳到下一步
  13. 077E: get_active_interior_to 29@
  14. if
  15. 0039: 29@ == 0
  16. 004D: jump_if_false @Access_2
  17. 07FB: set_interior 'CARLS' access 0
  18. 1@ = 1//--- 记录开启第二步判断

  19. :Access_3//-- 第二步判断
  20. if
  21. 0039: 1@ == 1
  22. 004D: jump_if_false @Access_7//------ 跳到下一步
  23. if
  24. 00FF: actor $PLAYER_ACTOR 1 (in-sphere)near_point_on_foot 2491.5 -1667.5 13.35 radius 1.0 1.0 1.0
  25. 004D: jump_if_false @Access_2
  26. 0247: request_model #TRIBOSS
  27. 0247: request_model #AK47

  28. :Access_4//-- 加载模型循环
  29. 0001: wait 0 ms
  30. 00D6: if and
  31. 0248: model #TRIBOSS available
  32. 0248: model #AK47 available
  33. 004D: jump_if_false @Access_4//--加载模型循环
  34. 009A: 5@ = create_actor 24 #TRIBOSS at 2486.5 -1664.5 13.45
  35. 01B2: give_actor 5@ weapon 30 ammo 99999
  36. 05E2: AS_actor 5@ kill_actor $PLAYER_ACTOR
  37. 0249: release_model #TRIBOSS
  38. 1@ = 2//--- 记录开启第三步判断

  39. :Access_7//-- 第三步判断
  40. if
  41. 0039: 1@ == 2
  42. 004D: jump_if_false @Access_2//------ 返回上层判断
  43. 00D6: if 0
  44. 0118: actor 5@ dead
  45. 004D: jump_if_false @Access_9
  46. 01C2: remove_references_to_actor 5@
  47. 07FB: set_interior 'CARLS' access 1
  48. 0A93: end_custom_thread

  49. :Access_9
  50. 00D6: if 0
  51. 8104: NOT actor $PLAYER_ACTOR near_actor 5@ radius 80.0 80.0 10.0 sphere 0
  52. 004D: jump_if_false @Access_2
  53. 009B: destroy_actor 5@
  54. 1@ = 1//--- 返回第二层判断
  55. 0002: jump @Access_2
复制代码

______________________________________________________________________________________
______________________________________________________________________________________
声明还是不声明? (I)

声明变量有时是不必要的
未声明的变量会自动被设为0

这跟变量的引用位置和作用密切相关
我建议在用变量做流程控制的时候都预先声明
这样能使程序更稳定,因为声明避免了多线程访问时交叉引用和计算赋值引起的bug

有一种不用声明的情况是变量从脚本执行开始前已经存在
一个说明这种情况的例子是“随处存车”
请参阅主题:Special Particularities in Cleo
- Script Exemble by using Special Global Cleo Variable/ Store a car at any place

程序的开头部分是这样的
  1. {$CLEO .cs}
  2. :CARSTORE
  3. 03A4: name_thread 'CARSTOR'
  4. 0001: wait 1000 ms
  5. 0AB4: 7@ = var 955
  6. 00D6: if
  7. 8039: not 7@ == 0
  8. 004D: jump_if_false @CARSTOR_150
复制代码


如果存车程序从新游戏或者载入存档时开始运行
它首先检查var 955是否为0
它尽当车子已经存在载入的存档里时不为0
若955为0,则开始循环1
若955不为0,程序跳到循环3,检查玩家是否在车子的保存位置

另外一个例子是检查一段程序是从CLEO中加载的,还是用create_custom_thread中创建的线程
0A92: create_custom_thread "ThreadStartTest.cs"
请参阅主题: Special Particularities in Cleo >> create_custom_thread

.CS脚本默认从CLEO主程序直接加载执行
若某脚本程序只能从另一个线程中用create_custom_thread启动,可以通过检查某个未声明变量的方法,跳过 CLEO程序的初始化部分

未声明变量默认设为0,尤其是它从CLEO程序启动的时候
现在我们可以用带参的create_custom_thread声明另一个线程中的局部变量
0A92: create_custom_thread "ThreadStartTest.cs" 1
启动线程按以下规则得到参数的值
0@ <---- 参数1

下面的程序必须被保存为ThreadStartTest.txt,并编译为ThreadStartTest.cs,因为另外的程序已经指定了create_thread命令的入口
0A92: create_custom_thread "ThreadStartTest.cs" 1

若程序从CLEO主程序启动,0@默认被设为0
然后继续执行end_custom_thread语句终止线程

若它从另一个线程中用以上的create_thread命令启动
0@经传递获得数值1
程序经检测后跳入循环,启动热敏夜视仪
  1. {$CLEO .cs}
  2. :ThreadStartTest
  3. if
  4. 0039: 0@ == 0
  5. 004D: jump_if_false @ThreadStartTest_1
  6. 0A93: end_custom_thread

  7. :ThreadStartTest_1
  8. 03A4: name_thread "THREADST"

  9. :ThreadStartTest_2
  10. 0001: wait 0 ms
  11. if
  12. 0256: player $PLAYER_CHAR defined
  13. 004D: jump_if_false @ThreadStartTest_2
  14. if
  15. 0AB0: key_pressed 8//-----------------按退格
  16. 004D: jump_if_false @ThreadStartTest_2
  17. 08B2: toggle_thermal_vision 1
  18. 0001: wait 3000 ms
  19. 08B2: toggle_thermal_vision 0
  20. 0002: jump @ThreadStartTest_2
复制代码

稍微改变流程控制检测的写法并使用带参的create_custom_thread可以在单个cs文件中写多个线程,并让它们同时执行
带参的create_custom_thread可以启动调用命令的同一段程序(递归调用)
______________________________________________________________________________________
______________________________________________________________________________________
时间检测-真实毫秒数

局部变量32@和33@是预留作时间检测用的,它们的数值是以毫秒为单位递增的,并且总是整型
我们可以把变量置零来重置计数器
  1. 33@ = 0
复制代码

赋值以后它从新值开始继续增加
利用它可以判断是否已过一段时间
  1. if
  2. 33@ > 5000
复制代码

下面的代码不断检查是否已过5秒
若是,则显示一条消息并清零计数器
  1. {$CLEO .cs}
  2. :Timecheck_1
  3. thread "TIME"
  4. 33@ = 0

  5. :Timecheck_2
  6. wait 0 ms
  7. if
  8. 33@ > 5000
  9. jf @Timecheck_2
  10. 00BA: text_styled 'FEM_OK' 1000 ms 1
  11. 33@ = 0
  12. jump @Timecheck_2
复制代码

重要提示 若调慢游戏时间,则实时计时器也随之变慢
______________________________________________________________________________________
______________________________________________________________________________________
时间检测-游戏时间
Opcode 00BG返回游戏时间的小时和分钟数值
  1. 00BF: 0@ = current_time_hours, 1@ = current_time_minutes
复制代码


可用关系算符如>或>=来检测经过的游戏时间
下面的代码在22点和2点之间启动热敏夜视仪
变量3@的作用是防止opcode 08B2被无限执行
时间判断语句获得使用夜视仪的时间
无论你是一读档就是半夜,还是游戏进行到开启时间,效果都是一样的
  1. {$CLEO .cs}
  2. :GameTime_1
  3. thread "GTIME"
  4. 3@ = 0

  5. :GameTime_2
  6. wait 0
  7. 00BF: 0@ = current_time_hours, 1@ = current_time_minutes
  8. if or
  9. 0@ >= 22
  10. 2 > 0@
  11. jf @GameTime_3
  12. if
  13. 3@ == 0
  14. jf @GameTime_3
  15. 08B2: enable_thermal_vision 1
  16. 3@ = 1

  17. :GameTime_3
  18. if and
  19. 0@ > 1
  20. 22 > 0@
  21. 3@ == 1
  22. jf @GameTime_2
  23. 08B2: enable_thermal_vision 0
  24. 3@ = 0
  25. jump @GameTime_2
复制代码

______________________________________________________________________________________
______________________________________________________________________________________
整型数和浮点数
以上的讲解都还只用到整型数
但有些情况还是要用到浮点数的,比如坐标检测和计算
下面的代码把玩家传送到500.0单位高的空中
玩家会一直下落,在离地面很近的时候,又被送到天上
首先,程序检查确保玩家在室外空间
然后,程序不断读取玩家离地面的高度
这里用到了浮点大小比较opcode来控制put_actor语句的执行
if
0023: 25.0 > 3@

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

  4. :Floatcheck_2
  5. 0001: wait 0 ms
  6. if
  7. 0256: player $PLAYER_CHAR defined
  8. 004D: jump_if_false @Floatcheck_2
  9. 077E: get_active_interior_to 29@
  10. if
  11. 0039: 29@ == 0
  12. 004D: jump_if_false @Floatcheck_2
  13. 0819: 3@ = actor $PLAYER_ACTOR distance_from_ground
  14. if
  15. 0023: 25.0 > 3@
  16. 004D: jump_if_false @Floatcheck_2
  17. 00A1: put_actor $PLAYER_ACTOR at 0.0 0.0 500.0
  18. 0002: jump @Floatcheck_2
复制代码

______________________________________________________________________________________
______________________________________________________________________________________
声明还是不声明? (II)
在需要浮点数的地方,游戏不能处理整型数,反之亦然
另外,对整型数和浮点数的数值运算有两套不同的opcode

还好,SB很智能,知道什么时候要用整型,什么时候要用浮点,调正确的函数的工作在编译的时候就完成了
试试编译上面的程序,然后反编译生成的cs,并勾上选项without opcodes
然后你会得到这样的代码
  1. {$CLEO .cs}

  2. //-------------MAIN---------------
  3. thread "FLOAT"

  4. :FLOAT_9
  5. wait 0
  6. if
  7. Player.Defined($PLAYER_CHAR)
  8. jf @FLOAT_9
  9. 077E: get_active_interior_to 29@
  10. if
  11. 29@ == 0
  12. jf @FLOAT_9
  13. 0819: 3@ = actor $PLAYER_ACTOR distance_from_ground
  14. if
  15. 25.0 > 3@
  16. jf @FLOAT_9
  17. Actor.PutAt($PLAYER_ACTOR, 0.0, 0.0, 500.0)
  18. jump @FLOAT_9


  19. The most opcodes are disappeared
  20. Sanny knows that floats are meant in this function:
  21. 25.0 > 3@
复制代码


但是有几处函数是不明确的,比如计算两个变量
  1. 21@ -= 2@
复制代码

要指明用到的是整型数还是浮点,一种方法是写出带opcode的函数
  1. 0063: 21@ -= 2@ // (float)
复制代码

另一种方法是在赋初值的时候,声明变量是浮点数还是整数
如整型变量
  1. 21@ = 0
  2. 2@ = 0
复制代码

或浮点
  1. 21@ = 0.0
  2. 2@ = 0.0
复制代码

相关请参阅SB帮助:Coding >> Variables, Coding >> Constants
______________________________________________________________________________________
______________________________________________________________________________________
整型与浮点型的转换
Opcode 0092: 浮点数转换为整数
  1. 0092: 3@ = float 2@ to_integer
复制代码

2@ 为浮点数 3@为整数 小数部分截去

Opcode 0093: 整数转换为浮点数
  1. 0093: 9@ = integer 8@ to_float
复制代码

8@ 为整数 9@为浮点数,在8@后加.0
______________________________________________________________________________________
______________________________________________________________________________________
用text_draw opcode显示数学运算的值
显示数值可以帮助查找错误,调试程序
  1. 03F0: enable_text_draw 1
  2. 045A: text_draw_1number 250.0 40.0 'NUMBER' 3@
复制代码

opcode 045A: 显示指定变量的值
但只能显示整型数
要显示浮点数,必须先用0092转换
opcode 045A需要写在循环里,并且循环外调用opcode 03F0
opcode 045A是text_draw类函数的一个,用于显示GTASA\models\txd存储的字体
先设03F0为1,再循环调用text_draw语句是一种常用的做法,比如在赛车中显示时间和排名,还有CLEO速度表

text_draw类opcode有一个缺点,就是会影响其他text类opcode的消息显示
反之,若有另外的text opcode调用,这条文本就显示不出来了

如果不用循环的话,有一个小技巧
  1. 03F0: text_draw_toggle 1
  2. 0001: wait 50 ms
  3. 03F0: text_draw_toggle 0
  4. 0001: wait 50 ms
  5. 045A: text_draw_1number 250.0 40.0 'NUMBER' 3@
复制代码

这样消息就会一直显示,直到03F0再次被调用

下面的程序是前面的时间检测和浮点检测的综合
它显示实时计数器33@的值(上),空间编号(中),离地距离(下)
如果你在读档后进入建筑内部,离地距离不会显示,但是你能看到室内空间编号
当你出到室外以后,就会被瞬移到天上,然后就可以看到离地距离
实时计数器会每隔50秒刷新,并显示消息OK
调00BA显示的消息会中断text_draw显示
  1. {$CLEO .cs}
  2. :ValueCheck_1
  3. 03A4: name_thread "VCHECK"
  4. 33@ = 0

  5. :ValueCheck_2
  6. 0001: wait 0 ms
  7. if
  8. 0256: player $PLAYER_CHAR defined
  9. 004D: jump_if_false @ValueCheck_2
  10. 077E: get_active_interior_to 29@
  11. 03F0: enable_text_draw 1
  12. 045A: text_draw_1number 250.0 40.0 'NUMBER' 33@
  13. 045A: text_draw_1number 250.0 50.0 'NUMBER' 29@
  14. if
  15. 0039: 29@ == 0
  16. 004D: jump_if_false @ValueCheck_3
  17. 0819: 3@ = actor $PLAYER_ACTOR distance_from_ground
  18. 0092: 4@ = float 3@ to_integer
  19. 03F0: enable_text_draw 1
  20. 045A: text_draw_1number 250.0 60.0 'NUMBER' 4@
  21. if
  22. 0023: 25.0 > 3@
  23. 004D: jump_if_false @ValueCheck_3
  24. 00A1: put_actor $PLAYER_ACTOR at 0.0 0.0 500.0

  25. :ValueCheck_3
  26. if
  27. 33@ > 50000
  28. jf @ValueCheck_2
  29. 00BA: text_styled 'FEM_OK' 1000 ms 1
  30. 33@ = 0
  31. jump @ValueCheck_2
复制代码

______________________________________________________________________________________
______________________________________________________________________________________
运算编程
可以使用以下基本的整型和浮点操作
自加: +=
自减: -=
自除: /=
自乘: *=
赋值: =

计算圆上定角的坐标可以用正弦和余弦函数,必须用浮点
02F7: 13@ = sine 45.0 // (float)
02F6: 14@ = cosine 45.0 // (float)

另外可以用以下的判断
大于: >
大于等于: >=
判等: ==

其他命令可以查阅SB帮助: Coding >> Additional commands

下面的代码当按退格时在玩家周围生成烟雾
按住退格键显示一圈烟雾
4@用作角度,求余弦得x坐标,求正弦得y坐标,然后乘4.0,得到以玩家为心以4为半径的圆
把数值传入04C4 绕玩家的相对坐标
然后每次递增5度,计算下一个烟雾生成点的位置
  1. {$CLEO .cs}
  2. :Sine_1
  3. 03A4: name_thread 'SINE'
  4. 0007: 4@ = 0.0 // floating-point values

  5. :Sine_2
  6. 0001: wait 0 ms
  7. 00D6: if 0
  8. 0256: player $PLAYER_CHAR defined
  9. 004D: jump_if_false @Sine_2
  10. if
  11. 0AB0: key_pressed 8//------Backspace
  12. 004D: jump_if_false @Sine_2
  13. 02F6: 5@ = cosine 4@ // sinus swapped with cosine
  14. 0013: 5@ *= 4.0 // floating-point values (never used in VC or GTA 3)
  15. 02F7: 6@ = sinus 4@ // cosine swapped with sinus
  16. 0013: 6@ *= 4.0 // floating-point values (never used in VC or GTA 3)
  17. 04C4: create_coordinate 1@ 2@ 3@ from_actor $PLAYER_ACTOR offset 5@ 6@ 0.2
  18. 095C: create_smoke_at 1@ 2@ 3@ velocity 0.0 0.0 0.0 RGBA 1.0 1.0 1.0 1.0 size 0.2 last_factor 0.1
  19. 000B: 4@ += 5.0
  20. if
  21. 0021: 4@ > 354.0 // floating-point values
  22. 004D: jump_if_false @Sine_2
  23. 0007: 4@ = 0.0
  24. jump @Sine_2
复制代码


最后这个程序显示玩家的当前坐标
含分割符逗号,但无小数点,请自行YY
  1. {$CLEO .cs}
  2. :coords_00
  3. 03A4: name_thread 'COO'
  4. 0006: 33@ = 0 // integer values
  5. 0006: 3@ = 0 // integer values
  6. 0006: 4@ = 0 // integer values
  7. 0006: 5@ = 0 // integer values
  8. 0006: 11@ = 0 // integer values
  9. 0006: 12@ = 0 // integer values
  10. 0006: 13@ = 0 // integer values
  11. 0006: 9@ = 0 // integer values

  12. :coords_01
  13. 0001: wait 0 ms
  14. 00D6: if 0
  15. 0256: player $PLAYER_CHAR defined
  16. 004D: jump_if_false @coords_01
  17. 03F0: enable_text_draw 1
  18. 045A: text_draw_1number 50.0 425.0 'NUMBER' 3@ // value
  19. 045A: text_draw_1number 200.0 425.0 'NUMBER' 4@ // value
  20. 045A: text_draw_1number 350.0 425.0 'NUMBER' 5@ // value
  21. 045A: text_draw_1number 100.0 425.0 'NUMBER' 11@ // value
  22. 045A: text_draw_1number 250.0 425.0 'NUMBER' 12@ // value
  23. 045A: text_draw_1number 400.0 425.0 'NUMBER' 13@ // value
  24. 045A: text_draw_1number 450.0 425.0 'NUMBER' 9@ // value
  25. if
  26. 0019: 33@ > 1000 // integer values
  27. 004D: jump_if_false @coords_01
  28. 0006: 33@ = 0 // integer values
  29. 00A0: store actor $PLAYER_ACTOR position to 0@ 1@ 2@
  30. 0092: 3@ = float_to_integer 0@
  31. 0092: 4@ = float_to_integer 1@
  32. 0092: 5@ = float_to_integer 2@

  33. 0093: 6@ = integer_to_float 3@
  34. 0093: 7@ = integer_to_float 4@
  35. 0093: 8@ = integer_to_float 5@

  36. 0063: 0@ -= 6@ // floating-point values
  37. 0063: 1@ -= 7@ // floating-point values
  38. 0063: 2@ -= 8@ // floating-point values
  39. 0013: 0@ *= 100.0 // floating-point values
  40. 0013: 1@ *= 100.0 // floating-point values
  41. 0013: 2@ *= 100.0 // floating-point values

  42. 0092: 11@ = float_to_integer 0@
  43. 0092: 12@ = float_to_integer 1@
  44. 0092: 13@ = float_to_integer 2@

  45. :coords_02
  46. 00D6: if 0
  47. 001B: 0 > 11@ // integer values
  48. 004D: jump_if_false @coords_03
  49. 0012: 11@ *= -1 // integer values

  50. :coords_03
  51. 00D6: if 0
  52. 001B: 0 > 12@ // integer values
  53. 004D: jump_if_false @coords_04
  54. 0012: 12@ *= -1 // integer values

  55. :coords_04
  56. 00D6: if 0
  57. 001B: 0 > 13@ // integer values
  58. 004D: jump_if_false @coords_05
  59. 0012: 13@ *= -1 // integer values

  60. :coords_05
  61. 0172: 9@ = actor $PLAYER_ACTOR z_angle
  62. 0092: 9@ = float_to_integer 9@
  63. 0002: jump @coords_01
复制代码

______________________________________________________________________________________
______________________________________________________________________________________

传奇 Legend

虚拟世界,属于你的世界

Rank: 16

UID
4
宝石
154 粒
金币
5594 枚
节操
458 斤
灵石
0 块
精力
509 ℃
QQ
 楼主| 发表于 2012-4-7 10:37:35 | 显示全部楼层
本帖最后由 kwanz 于 2012-4-18 18:10 编辑

数组

总的来讲,数组的原理是很简单的,不过运用到数组的各种程序很容易造成疑惑。另外,数组的构造也比较纠结。

简单地说,我们可以为一个变量赋予更多内容,这个变量就像一个有孩子的家庭,家庭的索引定义了每一部分的含义。

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

Family[index 1]进了厨房
意思就是母亲进了厨房

我们用GTA和局部变量的术语来解释,我们用同一个变量名来维护数组结构,但我们必须预留更多的局部变量

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

指定递增的索引数,实际上需要占用升序的后续局部变量的空间
6@ = father
7@ = mother
8@ = son
9@ = doughter
10@ = Carl

数组结构里最重要的访问入口就是索引
数组的结构是这样的
6@(30@,5i)

30@是数组索引
我们现在定义索引的值为
0006: 30@ = 4

那么
6@(30@,5i)进了厨房
意思就是Carl进了厨房
它等同于
10@进了厨房

一些实际程序的例子:
下面的4段程序都在Grove St生成5样相同的物品

模型ID, 名称
1239, info
1240, health
1241, adrenaline
1242, bodyarmour
1247, bribe

每一段代码都做了一点修改
我们一点点地做,首先看执行几个简单的生成命令的版本

1. 简单版
  1. {$CLEO .cs}
  2. :more_items1
  3. 03A4: name_thread 'm_item1'

  4. //1239, info
  5. //1240, health
  6. //1241, adrenaline
  7. //1242, bodyarmour
  8. //1247, bribe

  9. 0213: 0@ = create_pickup 1239 type 15 at 2490.0 -1662.0 13.5
  10. 0213: 1@ = create_pickup 1240 type 15 at 2492.0 -1662.0 13.5
  11. 0213: 2@ = create_pickup 1241 type 15 at 2494.0 -1662.0 13.5
  12. 0213: 3@ = create_pickup 1242 type 15 at 2496.0 -1662.0 13.5
  13. 0213: 4@ = create_pickup 1247 type 15 at 2498.0 -1662.0 13.5

  14. 0A93: end_custom_thread
复制代码
2. 然后我们用局部变量来定义物品ID
  1. {$CLEO .cs}
  2. :more_items2
  3. 03A4: name_thread 'm_item2'

  4. 0006: 6@ = 1239 // info
  5. 0006: 7@ = 1240 // health
  6. 0006: 8@ = 1241 // adrenaline
  7. 0006: 9@ = 1242 // bodyarmour
  8. 0006: 10@ = 1247 //bribe

  9. 0213: 0@ = create_pickup 6@ type 15 at 2490.0 -1662.0 13.5
  10. 0213: 1@ = create_pickup 7@ type 15 at 2492.0 -1662.0 13.5
  11. 0213: 2@ = create_pickup 8@ type 15 at 2494.0 -1662.0 13.5
  12. 0213: 3@ = create_pickup 9@ type 15 at 2496.0 -1662.0 13.5
  13. 0213: 4@ = create_pickup 10@ type 15 at 2498.0 -1662.0 13.5

  14. 0A93: end_custom_thread
复制代码
3. 现在我们用数组来定义物品 ID
30@为数组索引
每刷出一个物品,就把索引增加1
000A: 30@ += 1
  1. {$CLEO .cs}
  2. :Array_items1
  3. 03A4: name_thread 'Array_1'

  4. 0006: 6@ = 1239 // info
  5. 0006: 7@ = 1240 // health
  6. 0006: 8@ = 1241 // adrenaline
  7. 0006: 9@ = 1242 // bodyarmour
  8. 0006: 10@ = 1247 //bribe

  9. 0006: 30@ = 0 // ---Array Index is 0
  10. 0213: 0@ = create_pickup 6@(30@,5i) type 15 at 2490.0 -1662.0 13.5

  11. 000A: 30@ += 1// ---Array Index is 1
  12. 0213: 1@ = create_pickup 6@(30@,5i) type 15 at 2492.0 -1662.0 13.5

  13. 000A: 30@ += 1// ---Array Index is 2
  14. 0213: 2@ = create_pickup 6@(30@,5i) type 15 at 2494.0 -1662.0 13.5

  15. 000A: 30@ += 1// ---Array Index is 3
  16. 0213: 3@ = create_pickup 6@(30@,5i) type 15 at 2496.0 -1662.0 13.5

  17. 000A: 30@ += 1// ---Array Index is 4
  18. 0213: 4@ = create_pickup 6@(30@,5i) type 15 at 2498.0 -1662.0 13.5

  19. 0A93: end_custom_thread
复制代码
4. 我们把生成5个物品的命令缩为一句,这句命令要执行5次
每次程序跳回生成命令前,数组索引自加1,以读取一个新的物品ID
为了确保命令被执行5遍,需要判断索引是否小于等于5
if
001B: 5 > 30@

并且我们不能把5个东西刷出在同一个位置上
我们需要修改坐标参数,也就是把x坐标用数组储存
因此我们首先定义存放坐标的变量
  1. {$CLEO .cs}
  2. :Array_items2
  3. 03A4: name_thread 'Array_2'

  4. 0006: 6@ = 1239 // info
  5. 0006: 7@ = 1240 // health
  6. 0006: 8@ = 1241 // adrenaline
  7. 0006: 9@ = 1242 // bodyarmour
  8. 0006: 10@ = 1247 //bribe

  9. 0007: 11@ = 2490.0
  10. 0007: 12@ = 2492.0
  11. 0007: 13@ = 2494.0
  12. 0007: 14@ = 2496.0
  13. 0007: 15@ = 2498.0

  14. 0006: 30@ = 0 // ---数组索引


  15. :Array_items2_loop
  16. 0001: wait 0 ms
  17. if
  18. 001B: 5 > 30@
  19. 004D: jump_if_false @Array_items2_end
  20. 0213: 0@(30@,5i) = create_pickup 6@(30@,5i) type 15 at 11@(30@,5f) -1662.0 13.5
  21. 000A: 30@ += 1
  22. 0002: jump @Array_items2_loop

  23. :Array_items2_end
  24. 0A93: end_custom_thread
复制代码
---------------------------------------------------------------------------------------------------------------------------------------
最后我们给出数组的完整描述方式:
6@(30@,5i)
<家族变量名>(<索引变量>,<最大存放量><成员类型:i表示整型,f表示浮点,s表示字符串>)

最大存放量的意思是,上面的例子里,最大的变量数为5
所以我们只能用数组创建5个物体
如果我们写成6@(30@,2i)我们只能创建2个物体
不过我们可以写6@(30@,12i),但只创建5个物体
如果我们需要创建20个物体,我们需要增加最大值:6@(30@,20i)
但是在Cleo CS脚本里是不可能创建20个物体的
因为我们需要20个局部变量来定义物体,20个局部变量来存储不同的坐标
而cs正常线程只支持32个局部变量
---------------------------------------------------------------------------------------------------------------------------------------
另外一种数组的表示方法看起来更清晰一点
只写上数组明和方括号括起的索引:0@[30@]
这种表达需要一开始就定义好数组
var
0@: array 5 of Integer
end

下面是不带opcode的程序。按上面的格式修改编译后,数组的结构会发生改变
  1. {$CLEO .cs}
  2. thread 'ARRAY_2'

  3. var
  4. 0@: array 5 of Integer
  5. 6@: array 5 of Integer
  6. 11@: array 5 of Float
  7. end

  8. 6@ = 1239
  9. 7@ = 1240
  10. 8@ = 1241
  11. 9@ = 1242
  12. 10@ = 1247
  13. 11@ = 2490.0
  14. 12@ = 2492.0
  15. 13@ = 2494.0
  16. 14@ = 2496.0
  17. 15@ = 2498.0
  18. 30@ = 0

  19. :ARRAY_1
  20. wait 0
  21. if
  22. 5 > 30@
  23. jf @ARRAY_3
  24. 0@[30@] = Pickup.Create(6@[30@], 15, 11@[30@], -1662.0, 13.5)
  25. 30@ += 1
  26. jump @ARRAY_1

  27. :ARRAY_3
  28. 0A93: end_custom_thread
复制代码
---------------------------------------------------------------------------------------------------------------------------------------
下面的代码演示了如何在程序中进一步利用数组定义的物品
下面两种使用普通局部变量的做法和访问一族变量的子成员是一样的:
if
0214: pickup 2@ picked_up

一是使用数组结构,并用数值指定索引
0006: 30@ = 1 // ---数组索引
0164: disable_marker 16@(30@,5i)

二是在循环过程中还原索引和物品标记
or to restore the index and assigne markers to the pickups in an array loop:
:Array_items3_restore
0006: 30@ = 0 // ---还原数组索引

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

  4. 0006: 6@ = 1239 // info
  5. 0006: 7@ = 1240 // health
  6. 0006: 8@ = 1241 // adrenaline
  7. 0006: 9@ = 1242 // bodyarmour
  8. 0006: 10@ = 1247 //bribe

  9. 0007: 11@ = 2490.0
  10. 0007: 12@ = 2492.0
  11. 0007: 13@ = 2494.0
  12. 0007: 14@ = 2496.0
  13. 0007: 15@ = 2498.0

  14. 0006: 30@ = 0 // ---数组索引


  15. :Array_items3_create
  16. 0001: wait 0 ms
  17. if
  18. 001B: 5 > 30@
  19. 004D: jump_if_false @Array_items3_restore
  20. 0213: 0@(30@,5i) = create_pickup 6@(30@,5i) type 3 at 11@(30@,5f) -1662.0 13.5
  21. 000A: 30@ += 1
  22. 0002: jump @Array_items3_create

  23. :Array_items3_restore
  24. 0006: 30@ = 0 // ---还原索引

  25. :Array_items3_marker
  26. 0001: wait 0 ms
  27. if
  28. 001B: 5 > 30@
  29. 004D: jump_if_false @Array_items3_check1
  30. 03DC: 16@(30@,5i) = create_marker_above_pickup 0@(30@,5i)
  31. 000A: 30@ += 1
  32. 0002: jump @Array_items3_marker

  33. :Array_items3_check1
  34. 0001: wait 0 ms
  35. if
  36. 0256: player $PLAYER_CHAR defined
  37. 004D: jump_if_false @Array_items3_check1
  38. if
  39. 0214: pickup 0@ picked_up
  40. 004D: jump_if_false @Array_items3_check2
  41. 0006: 30@ = 0 // ---数组索引
  42. 0164: disable_marker 16@(30@,5i)

  43. :Array_items3_check2
  44. if
  45. 0214: pickup 1@ picked_up
  46. 004D: jump_if_false @Array_items3_check3
  47. 0006: 30@ = 1 // ---数组索引
  48. 0164: disable_marker 16@(30@,5i)

  49. :Array_items3_check3
  50. if
  51. 0214: pickup 2@ picked_up
  52. 004D: jump_if_false @Array_items3_check4
  53. 0006: 30@ = 2 // --数组索引
  54. 0164: disable_marker 16@(30@,5i)

  55. :Array_items3_check4
  56. if
  57. 0214: pickup 3@ picked_up
  58. 004D: jump_if_false @Array_items3_check5
  59. 0006: 30@ = 3 // ---数组索引
  60. 0164: disable_marker 16@(30@,5i)

  61. :Array_items3_check5
  62. if
  63. 0214: pickup 4@ picked_up
  64. 004D: jump_if_false @Array_items3_check6
  65. 0006: 30@ = 4 // ---数组索引
  66. 0164: disable_marker 16@(30@,5i)

  67. :Array_items3_check6
  68. if or
  69. 075C: marker 16@ enabled
  70. 075C: marker 17@ enabled
  71. 075C: marker 18@ enabled
  72. 075C: marker 19@ enabled
  73. 075C: marker 20@ enabled
  74. 004D: jump_if_false @Array_items3_Endrestore
  75. 0002: jump @Array_items3_check1

  76. :Array_items3_Endrestore
  77. 0006: 30@ = 0 // ---数组索引
  78. 0002: jump @Array_items3_create
复制代码
下面的程序十分有用,它生成10个带箭头标号的人物,并且去除被杀死的人物的箭头,另用一个局部变量记录被杀死的人数
走到室外并按9触发刷人程序
  1. {$CLEO .cs}
  2. :ArrayAct_1
  3. 03A4: name_thread 'ARRAY_A'
  4. 0006: 28@ = 0 // 杀死数计数器
  5. 0006: 30@ = 0 // 数组索引
  6. 0007: 31@ = 2.5 // 刷人坐标的y偏移量

  7. :ArrayAct_2
  8. 0001: wait 0 ms
  9. 00D6: if 0
  10. 0256: player $PLAYER_CHAR defined
  11. 004D: jump_if_false @ArrayAct_2
  12. if and
  13. 0AB0: key_pressed 57//----------------key 9
  14. 80DF: not actor $PLAYER_ACTOR driving
  15. 004D: jump_if_false @ArrayAct_2
  16. 077E: get_active_interior_to 29@
  17. 00D6: if 0
  18. 0039: 29@ == 0 // integer values
  19. 004D: jump_if_false @ArrayAct_2

  20. 0247: request_model #fbi

  21. :ArrayAct_3
  22. 0001: wait 0 ms
  23. if and
  24. 0248: model #fbi available
  25. 004D: jump_if_false @ArrayAct_3

  26. :ArrayAct_4
  27. 0001: wait 10 ms
  28. 00D6: if 0
  29. 0256: player $PLAYER_CHAR defined
  30. 004D: jump_if_false @ArrayAct_4
  31. if
  32. 001B: 10 > 30@ // integer values
  33. 004D: jump_if_false @ArrayAct_10
  34. 04C4: create_coordinate 24@ 25@ 26@ from_actor $PLAYER_ACTOR offset 0.0 31@ 0.2
  35. 009A: 0@(30@,12i) = create_actor_pedtype 6 model #fbi at 24@ 25@ 26@
  36. 0187: 10@(30@,12i) = create_marker_above_actor 0@(30@,12i)
  37. 000B: 31@ += 2.0 // y自增2.0
  38. 000A: 30@ += 1 // 数组索引
  39. 0002: jump @ArrayAct_4


  40. :ArrayAct_10
  41. 0006: 30@ = 0 // 数组索引

  42. :ArrayAct_11
  43. 0001: wait 10 ms
  44. if
  45. 0256: player $PLAYER_CHAR defined
  46. 004D: jump_if_false @ArrayAct_40
  47. if
  48. 001B: 10 > 30@ // integer values
  49. 004D: jump_if_false @ArrayAct_15
  50. if
  51. 0118: actor 0@(30@,12i) dead
  52. 004D: jump_if_false @ArrayAct_13
  53. if
  54. 075C: marker 10@(30@,12i) enabled
  55. 004D: jump_if_false @ArrayAct_13
  56. 0164: disable_marker 10@(30@,12i)
  57. 000A: 28@ += 1 // 计数器+1

  58. :ArrayAct_13
  59. 000A: 30@ += 1 // 数组索引
  60. if
  61. 001B: 10 > 28@ // integer values
  62. 004D: jump_if_false @ArrayAct_40
  63. 0002: jump @ArrayAct_11

  64. :ArrayAct_15
  65. 0006: 30@ = 0 // 数组索引
  66. 0002: jump @ArrayAct_11

  67. :ArrayAct_40
  68. 0006: 30@ = 0 // 数组索引

  69. :ArrayAct_45
  70. if
  71. 001B: 10 > 30@ // integer values
  72. 004D: jump_if_false @ArrayAct_50
  73. if
  74. 075C: marker 10@(30@,12i) enabled
  75. 004D: jump_if_false @ArrayAct_47
  76. 0164: disable_marker 10@(30@,12i)

  77. :ArrayAct_47
  78. 01C2: remove_references_to_actor 0@(30@,12i) // 设为普通路人
  79. 000A: 30@ += 1 // Array index
  80. 0002: jump @ArrayAct_45

  81. :ArrayAct_50
  82. 0006: 28@ = 0 // 杀死数计数器
  83. 0006: 30@ = 0 // 数组索引
  84. 0007: 31@ = 2.5 // y偏移
  85. 0249: release_model #fbi
  86. 0001: wait 1000 ms
  87. 0002: jump @ArrayAct_2
复制代码
---------------------------------------------------------------------------------------------------------------------------------------
最后我演示一下如何使用全局变量数组
不过这种方法只能在main.scm中使用,在CLEO中会死机

这稍容易理解,因为它跟我们开头举的例子很像

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

全局变量就像一个家庭,在方括号内赋予数组索引
$ACTORS[0] = 0
$ACTORS[1] = 0
$ACTORS[2] = 0
$ACTORS[3] = 0
$ACTORS[4] = 0
$ACTORS[5] = 0

数组的结构大概是这样
$ACTORS($ACT_INDEX,30i)
  1. :Much_Actor_array
  2. 03A4: name_thread 'MACTARY'

  3. :LABEL_start
  4. 0001: wait 1000 ms
  5. 0007: 0@ = -25.0 // 范围
  6. 0007: 1@ = 25.0 // 范围
  7. 0007: 2@ = 5.0 // X
  8. 0007: 3@ = 0.0 // Y
  9. 0006: 4@ = 0 // PED ID
  10. 0006: 5@ = 0 // PED标示符(handle)
  11. 0006: 6@ = 0 // PED生成量计数
  12. 0006: 7@ = 29 // PEDs最大数目
  13. 0004: $ACTORS[0] = 0 // PED handle
  14. 0004: $ACTORS[1] = 0 // PED handle
  15. 0004: $ACTORS[2] = 0 // PED handle
  16. 0004: $ACTORS[3] = 0 // PED handle
  17. 0004: $ACTORS[4] = 0 // PED handle
  18. 0004: $ACTORS[5] = 0 // PED handle
  19. 0004: $ACTORS[6] = 0 // PED handle
  20. 0004: $ACTORS[7] = 0 // PED handle
  21. 0004: $ACTORS[8] = 0 // PED handle
  22. 0004: $ACTORS[9] = 0 // PED handle
  23. 0004: $ACTORS[10] = 0 // PED handle
  24. 0004: $ACTORS[11] = 0 // PED handle
  25. 0004: $ACTORS[12] = 0 // PED handle
  26. 0004: $ACTORS[13] = 0 // PED handle
  27. 0004: $ACTORS[14] = 0 // PED handle
  28. 0004: $ACTORS[15] = 0 // PED handle
  29. 0004: $ACTORS[16] = 0 // PED handle
  30. 0004: $ACTORS[17] = 0 // PED handle
  31. 0004: $ACTORS[18] = 0 // PED handle
  32. 0004: $ACTORS[19] = 0 // PED handle
  33. 0004: $ACTORS[20] = 0 // PED handle
  34. 0004: $ACTORS[21] = 0 // PED handle
  35. 0004: $ACTORS[22] = 0 // PED handle
  36. 0004: $ACTORS[23] = 0 // PED handle
  37. 0004: $ACTORS[24] = 0 // PED handle
  38. 0004: $ACTORS[25] = 0 // PED handle
  39. 0004: $ACTORS[26] = 0 // PED handle
  40. 0004: $ACTORS[27] = 0 // PED handle
  41. 0004: $ACTORS[28] = 0 // PED handle
  42. 0004: $ACTORS[29] = 0 // PED handle
  43. 0004: $ACT_INDEX = 0

  44. :LABEL_0
  45. 0001: wait 0 ms
  46. if
  47. 0256: player $PLAYER_CHAR defined
  48. 004D: jump_if_false @LABEL_0
  49. if
  50. 80DF: not actor $PLAYER_ACTOR driving
  51. 004D: jump_if_false @LABEL_0
  52. if
  53. 001F: 7@ > $ACT_INDEX // (int)
  54. 004D: jump_if_false @LABEL_2
  55. 0209: 4@ = random_int_in_ranges 209 264
  56. 0247: load_model 4@
  57. 038B: load_requested_models

  58. :LABEL_1
  59. 0001: wait 0 ms
  60. 00D6: if 0
  61. 0248: model 4@ available
  62. 004D: jump_if_false @LABEL_1
  63. 0208: 2@ = random_float_in_ranges 0@ 1@
  64. 0208: 3@ = random_float_in_ranges 0@ 1@
  65. 04C4: store_coords_to $TEMPVAR_FLOAT_1 $TEMPVAR_FLOAT_2 $TEMPVAR_FLOAT_3 from_actor $PLAYER_ACTOR with_offset 2@ 3@ -1.0
  66. 009A: $ACTORS($ACT_INDEX,30i) = create_actor_pedtype 4 model 4@ at $TEMPVAR_FLOAT_1 $TEMPVAR_FLOAT_2 $TEMPVAR_FLOAT_3
  67. 05E2: AS_actor $ACTORS($ACT_INDEX,30i) kill_actor $PLAYER_ACTOR
  68. 0008: $ACT_INDEX += 1
  69. 0002: jump @LABEL_0

  70. :LABEL_2
  71. 0004: $ACT_INDEX = 0

  72. :LABEL_3
  73. 0001: wait 0 ms
  74. if
  75. 0256: player $PLAYER_CHAR defined
  76. 004D: jump_if_false @Cleanup_1
  77. if
  78. 001F: 7@ > $ACT_INDEX
  79. 004D: jump_if_false @LABEL_5
  80. if
  81. 8118: not actor $ACTORS($ACT_INDEX,30i) dead
  82. 004D: jump_if_false @PED_CREATION_CONTROL_COUNT_UP
  83. 0332: set_actor $ACTORS($ACT_INDEX,30i) bleeding 1
  84. 0245: set_actor $ACTORS($ACT_INDEX,30i) walk_style_to "oldwoman"
  85. 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
  86. 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

  87. :PED_CREATION_CONTROL_COUNT_UP
  88. 0008: $ACT_INDEX += 1
  89. 0002: jump @LABEL_3

  90. :LABEL_5
  91. 0001: wait 250 ms
  92. if
  93. 0256: player $PLAYER_CHAR defined
  94. 004D: jump_if_false @Cleanup_1
  95. 0002: jump @LABEL_5

  96. :Cleanup_1
  97. 0004: $ACT_INDEX = 0

  98. :Cleanup_2
  99. 0001: wait 0 ms
  100. if
  101. 001F: 7@ > $ACT_INDEX
  102. 004D: jump_if_false @Cleanup_3
  103. 01C2: remove_references_to_actor $ACTORS($ACT_INDEX,30i)
  104. 0008: $ACT_INDEX += 1
  105. 0002: jump @Cleanup_2

  106. :Cleanup_3
  107. 0002: jump @LABEL_start
复制代码

传奇 Legend

虚拟世界,属于你的世界

Rank: 16

UID
4
宝石
154 粒
金币
5594 枚
节操
458 斤
灵石
0 块
精力
509 ℃
QQ
 楼主| 发表于 2012-4-7 10:37:57 | 显示全部楼层
本帖最后由 kwanz 于 2012-4-18 18:11 编辑

内存读取

Opcode 0A8D, 0A8C读取内存地址上的内容
首先要了解哪些地址上有函数
你可以在gtamodding.com上找到清单
比如0x863984 – [Int32] Gravity(重力)

下面是一段读GRAVITY程序,用text_draw opcode显示内存地址上的内容
  1. {$CLEO .cs}
  2. thread 'GRAVITY'
  3. wait 3000
  4. :GRAVITY_1
  5. 0A8D: 1@ = read_memory 0x863984 size 4 virtual_protect 1
  6. wait 100
  7. 03F0: text_draw_toggle 1
  8. 0001: wait 50 ms
  9. 03F0: text_draw_toggle 0
  10. 0001: wait 50 ms
  11. 045A: text_draw_1number 250.0 40.0 'NUMBER' 1@
  12. 0A8C: write_memory 0x863984 size 4 value 2 virtual_protect 1 //清除缓存
  13. 0A93: end_custom_thread
复制代码

程序结束处我们把2写入内存,请测试一下程序看看结果
2打进去效果貌似不错,但是如果把浮点值写进去会发生很奇葩的情况
试一下
  1. 0A8C: write_memory 0x863984 size 4 value 10.0 virtual_protect 1 //clear the buffer
复制代码

然后你就会看到树木开始扭曲。。。

更多的内存操作的相关内容请参阅Seemann的帖子SA Memory handling
  1. 0A8D: $result = read_memory 1@ size 4 virtual_protect 0
复制代码


0A8D读取游戏内存并把数据存入变量

参数:
1 – 存入变量(任意变量/数组)
2 – 读取内存地址(整型)
3 – 读取字节数: 1, 2 or 4 bytes
4 – Virtual Protect: 防当机保护。若地址不可读(受保护区域),使用1,否则使用0
  1. 0A8C: write_memory 0x00969110 size 4 value 0 virtual_protect 0
复制代码

0A8C把数值写入游戏内存

参数:
1 – 内存地址(整型)
2 – 写入字节数: 1, 2 or 4 bytes
3 – 写入值(任意数)
4 – Virtual Protect: 防当机保护。若地址只读,使用1,否则使用0

我们可以用地址0x00969110用作模拟作弊码key_press检测
需要用到十六进制的ASCII码表
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 =^

检测M是否按下,需要从地址0x00969110读入一个字节
  1. 0A8D: 1@ = read_memory 0x00969110 size 1 virtual_protect 0
复制代码


测试按键是否M的十六进制键码
  1. if
  2. 04A4: 1@ == 0x4D


  3. check 2 keys: MM
  4. CODE
  5. 0A8D: 1@ = read_memory 0x00969110 size 2 virtual_protect 0
  6. if
  7. 04A4: 1@ == 0x4D4D
复制代码

检测4个键: WILD
  1. 0A8D: 1@ = read_memory 0x00969110 size 4 virtual_protect 1
  2. if
  3. 04A4: 1@ == 0x57494C44 //检测1@ = WILD
复制代码

下面的程序当输入JUMP的时候启动超级跳作弊
  1. {$CLEO .cs}
  2. thread 'cheat'

  3. :Cheatcode_1
  4. wait 0
  5. 0A8D: 1@ = read_memory 0x00969110 size 4 virtual_protect 0
  6. if
  7. 04A4: 1@ == 0x4A554D50 //检测1@ = JUMP
  8. 004D: jump_if_false @Cheatcode_1
  9. 03E5: text_box 'CHEAT1'
  10. 0109: player $PLAYER_CHAR money += 1000000
  11. 0A8C: write_memory 0x00969110 size 4 value 0 virtual_protect 0 //清除缓存
  12. 0A8C: write_memory 0x96916C size 4 value 1 virtual_protect 0 //-- 启动作弊
  13. 0A93: end_custom_thread
复制代码

要检测多于4个字符,需要用到额外的内存地址0x00969114
原理是:首先把前面4个字符存入这个地址,然后剩下的1/2/4个字符存入0x00969110

下面的程序在输入JUMPRAMP的时候刷出一个特技跳斜坡
  1. {$CLEO .cs}
  2. thread 'cheat'

  3. :Cheatcode_1
  4. wait 0
  5. 0A8D: 1@ = read_memory 0x00969110 size 4 virtual_protect 0 //
  6. 0A8D: 2@ = read_memory 0x00969114 size 4 virtual_protect 0 //
  7. if and
  8. 04A4: 1@ == 0x52414D50 //检测1@ = RAMP
  9. 04A4: 2@ == 0x4A554D50 //检测2@ = JUMP
  10. 004D: jump_if_false @Cheatcode_1
  11. 03E5: text_box 'CHEAT1'
  12. 0109: player $PLAYER_CHAR money += 1000000
  13. 0A8C: write_memory 0x00969110 size 4 value 0 virtual_protect 0 //清除缓存
  14. 0A8C: write_memory 0x00969114 size 4 value 0 virtual_protect 0 //清除缓存
  15. 0247: request_model 1655

  16. :Cheatcode_JRamp
  17. 0001: wait 0 ms
  18. 00D6: if 0
  19. 0248: model 1655 available
  20. 004D: jump_if_false @Cheatcode_JRamp
  21. 0172: 2@ = actor $PLAYER_ACTOR z_angle
  22. 04C4: create_coordinate 11@ 12@ 13@ from_actor $PLAYER_ACTOR offset 0.0 14.5 -1.8
  23. 0107: 1@ = create_object 1655 at 11@ 12@ 13@
  24. 0177: set_object 1@ z_angle_to 2@
  25. 0001: wait 0 ms
  26. 0249: release_model 1655
  27. 0001: wait 1000 ms
  28. 01C4: remove_references_to_object 1@ // 解除引用,物品会在玩家视角移开以后刷掉
  29. 0002: jump @Cheatcode_1
复制代码

输入ARMOUR在Grove St刷一件防弹衣
  1. {$CLEO .cs}
  2. thread 'cheat'

  3. :Cheatcode_1//ARMOUR
  4. wait 0
  5. 0A8D: 1@ = read_memory 0x00969110 size 4 virtual_protect 0 //
  6. 0A8D: 2@ = read_memory 0x00969114 size 2 virtual_protect 0 //
  7. if and
  8. 04A4: 1@ == 0x4D4F5552//MOUR
  9. 04A4: 2@ == 0x4152//AR
  10. 004D: jump_if_false @Cheatcode_1
  11. 03E5: text_box 'CHEAT1'
  12. 0109: player $PLAYER_CHAR money += 1000000
  13. 0A8C: write_memory 0x00969110 size 4 value 0 virtual_protect 0 //清除缓存
  14. 0A8C: write_memory 0x00969114 size 2 value 0 virtual_protect 0 //清除缓存
  15. Pickup.Create(0@, 1242, 3, 2495.1387, -1680.1288, 13.3388)
  16. 0002: jump @Cheatcode_1
复制代码


引用 (Rapier @ Aug 31 2009, 04:05)
  引用 (ZAZ @ Jun 5 2009, 18:34)
  我们可以用地址0x00969110用作模拟作弊码key_press检测
这个地址是1.0用的,那1. 1呢?

引用 (Wesser @ Aug 31 2009, 07:21)
1.10地址为0x96B790.

传奇 Legend

虚拟世界,属于你的世界

Rank: 16

UID
4
宝石
154 粒
金币
5594 枚
节操
458 斤
灵石
0 块
精力
509 ℃
QQ
 楼主| 发表于 2012-4-7 10:38:18 | 显示全部楼层
本帖最后由 kwanz 于 2012-4-18 18:14 编辑

调用scm函数

引用 (The_Siggi's sent pm)
额,这个之前已经解释过,在这里我再讲解一下
调0AB1就类似004F,但它可以通过调0485/059A返回TRUE/FALSE;但这时调用函数必须以不带返回值的0AB2结束,不然游戏会挂。这些opcode在你想写条件判断函数的时候很有用。
在单用0AB2时,可以返回任意值
外部线程
0AB1的格式如下:
  1. call_scm_func <线程> <参数数目> | <参数1> <参数2> ...
复制代码
参数数和前面的数目一致。所有的参数可以是数值或局部/全局变量,传入时各占一个独立的偏移量。

被调线程(函数线程)
所有传入的参数都存储在从0开始连续的偏移位置上,即参数1存为0@,参数2存为1@...如此类推,直到到达局部变量的最大偏移(33@)记得用类似格式的0AB2结束调用函数
  1. 0AB2: ret <参数数目> | <参数1> <参数2> ...
复制代码
如果函数返回至少一个参数,0AB1应该改造如下,以存入返回值
  1. 0AB1: call_scm_func <线程> <传入参数数> | <入参1> <入参2> ... | <出参1> <出参2> ...
复制代码
自定义函数示例
条件判断函数
  1. [...]
  2. if
  3. 0AB1: call_scm_func @isActorDriving 1 actor $PLAYER_ACTOR
  4. then
  5. 03C0: 0@ = actor $PLAYER_ACTOR car
  6. end
  7. [...]

  8. :isActorDriving
  9. {
  10. 0@ - actor
  11. }
  12. if
  13. 00DF: actor 0@ driving
  14. then
  15. 0485: return_true
  16. else
  17. 059A: return_false
  18. end
  19. 0AB2: ret 0
复制代码
写入参数
  1. [...]
  2. 0AB1: call_scm_func @setActorHealth 2 actor $PLAYER_ACTOR health 100
  3. [...]

  4. :setActorHealth
  5. {
  6. 0@ - actor
  7. 1@ - health
  8. }
  9. 0223: set_actor 0@ health_to 1@
  10. 0AB2: ret 0
复制代码
读取参数
  1. [...]
  2. 0AB1: call_scm_func @getActorArmour 1 actor $PLAYER_ACTOR armour_to 10@
  3. [...]

  4. :getActorArmour
  5. {
  6. 0@ - actor
  7. }
  8. 04DD: 1@ = actor 0@ armour
  9. 0AB2: ret 1 1@
复制代码
读取/写入
  1. [...]
  2. 00A0: store_actor $PLAYER_ACTOR position_to 1@ 2@ 3@
  3. 0AB1: call_scm_func @getRandomPos 4 in 1@ 2@ 3@ radius 4@ out_to 5@ 6@ 7@
  4. [...]

  5. :getRandomPos
  6. {
  7. 0@ - X pos
  8. 1@ - Y pos
  9. 2@ - Z pos
  10. 3@ - radius
  11. }
  12. 0087: 4@ = 0@
  13. 0087: 5@ = 1@
  14. 0063: 4@ -= 3@
  15. 0063: 5@ -= 3@
  16. 005B: 0@ += 3@
  17. 005B: 1@ += 3@
  18. 0@ = random(4@, 0@)
  19. 1@ = random(5@, 1@)
  20. 02CE: 2@ = ground_z_at 1@ 2@ 3@
  21. 0AB2: ret 3 0@ 1@ 2@
复制代码
0AB1:最多可带多少个参数?
引用 (Wesser @ Jul 26 2010, 15:50)
我猜最多为34个参数,因为参数在被调函数中存储为0@到33@
下面的程序类似SB的示例文件,演示了如何不使用gxt/fxt数据显示文本
作者Rapier
  1. {$CLEO}

  2. thread 'MSG_TEST'
  3. wait 5000
  4. 0AB1: call_scm_func @LabelMSGMain 1 @LabelMSG01
  5. wait 5000
  6. 0AB1: call_scm_func @LabelMSGMain 1 @LabelMSG02
  7. 0A93: end_custom_thread

  8. :LabelMSGMain
  9. 0A9F: 1@ = current_thread_pointer
  10. 1@ += 16
  11. 0A8D: 1@ = read_memory 1@ size 4 virtual_protect 0
  12. 0062: 1@ -= 0@ // (int)
  13. 1@ += 4
  14. if
  15. 0AA9: is_game_version_original
  16. jf @LabelMSGVersion101
  17. 0AA5: call 0x588BE0 num_params 4 pop 4 0 0 0 1@ // v1.0
  18. jump @LabelMSGMain02

  19. :LabelMSGVersion101
  20. 0AA5: call 0x5893B0 num_params 4 pop 4 0 0 0 1@ // v1.01

  21. :LabelMSGMain02
  22. 0AB2: ret 0

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

  25. :LabelMSG02
  26. 0900: "GTA San Andreas"
  27. 0000: nop
复制代码
相关话题
高级内存访问帮助/基础教程

传奇 Legend

虚拟世界,属于你的世界

Rank: 16

UID
4
宝石
154 粒
金币
5594 枚
节操
458 斤
灵石
0 块
精力
509 ℃
QQ
 楼主| 发表于 2012-4-7 10:38:32 | 显示全部楼层
本帖最后由 kwanz 于 2012-4-18 18:15 编辑

_____________________________________________________________________________________
在代码中访问随机路人
若干个opcode可以在某地获取随机人物的访问:
  1. 089E: get_actor_in_sphere 3@ 4@ 5@ radius 5.0 handle_as 11@ // versionB
  2. 08E5: get_actor_in_sphere 27@ 28@ 29@ radius 50.0 handle_as 0@
  3. 073F: get_actor_in_sphere 4@ 7@ 10@ radius 20.0 with_pedtype_civilian 1 gang 1 criminal/prostitute 1 handle_as 27@
复制代码
但这几个都不能获取帮派成员,药品贩子等特殊人物,尤其是任务里的特殊人物。
另外还有一个opcode
  1. 0AB5: store_actor $PLAYER_ACTOR closest_vehicle_to 0@ closest_ped_to 1@
复制代码
但它只能获得最近的一个人物,对其他人无能为力。
并且,如果在四下无人的地方用这些opcode,游戏会挂。。。
------------------------------------------------------------------------------------------------------
我坛的Wesser发过一个方法可以获取游戏世界的每一个人物,包括任务人物,外部脚本(包括CLEO)使用的人物;只有食品摊子,比如快餐店的人物除外。
Wesser的源程序是这样用的:call_func @getActorInSphere
他使用了上一节中解释过的0AB1: call_func
以及多种程序语言中用到,SB支持的按步长循环结构(for-to-step)
for循环重复执行一个代码块,循环变量等差递增
Deji写了一个更加简单快速的版本
为了解释清楚,我把Wesser的程序改成了下面的例子,GTA实测可用,包括:
1. 带opcode版本
2. 不带opcode版本
程序获取一个随机人物,显示他的PED类别,然后把他杀死。

1. 带opcode版本
  1. {$CLEO .cs}
  2. :RandomActor_for_to_step_method
  3. thread 'RAFSTEP'

  4. :RAFSTEP_1
  5. 0001: wait 0 ms
  6. 00D6: if
  7. 0256: player $PLAYER_CHAR defined
  8. 004D: jump_if_false @RAFSTEP_1
  9. 00A0: store_actor $PLAYER_ACTOR position_to 1@ 2@ 3@
  10. 0AB1: call_scm_func @RAFSTEP_func 4 1@ 2@ 3@ 5.0 0@
  11. 00D6: if
  12. 8039: not 0@ == -1
  13. 004D: jump_if_false @RAFSTEP_1
  14. 00D6: if
  15. 8118: not actor 0@ dead
  16. 004D: jump_if_false @RAFSTEP_1
  17. 089F: get_actor 0@ pedtype_to 31@
  18. 03F0: enable_text_draw 1
  19. 0001: wait 50 ms
  20. 03F0: enable_text_draw 0
  21. 0001: wait 50 ms
  22. 045A: draw_text_1number 250.0 40.0 GXT 'NUMBER' number 31@ // ~1~
  23. 05BE: AS_kill_actor 0@
  24. 01C2: remove_references_to_actor 0@ // 设为普通路人
  25. 0002: jump @RAFSTEP_1

  26. :RAFSTEP_func
  27. 0006: 5@ = 0
  28. 0006: 4@ = 0

  29. :RAFSTEP_countLoop
  30. 00D6: if
  31. 056D: actor 4@ defined
  32. 004D: jump_if_false @RAFSTEP_11
  33. 00D6: if and
  34. 803B: not $PLAYER_ACTOR == 4@ // (int)
  35. 00FE: actor 4@ sphere 0 in_sphere 0@ 1@ 2@ radius 3@ 3@ 3@
  36. 004D: jump_if_false @RAFSTEP_11
  37. 0006: 5@ = 1
  38. 0002: jump @RAFSTEP_12

  39. :RAFSTEP_11
  40. 000A: 4@ += 1
  41. 00D6: if
  42. 0019: 4@ > 30000
  43. 004D: jump_if_false @RAFSTEP_countLoop

  44. :RAFSTEP_12
  45. 00D6: if
  46. 0039: 5@ == 0
  47. 004D: jump_if_false @RAFSTEP_Result
  48. 0006: 4@ = -1

  49. :RAFSTEP_Result
  50. 0AB2: ret 1 4@
复制代码
2. 不带opcode版本
  1. {$CLEO .cs}
  2. :RandomActor_for_to_step_method
  3. thread 'RAFSTEP'

  4. :RAFSTEP_1
  5. wait 0
  6. if
  7. Player.Defined($PLAYER_CHAR)
  8. jf @RAFSTEP_1
  9. Actor.StorePos($PLAYER_ACTOR, 1@, 2@, 3@)
  10. 0AB1: call_scm_func @RAFSTEP_func 4 1@ 2@ 3@ 5.0 0@
  11. if
  12. not 0@ == -1
  13. jf @RAFSTEP_1
  14. if
  15. not Actor.Dead(0@)
  16. jf @RAFSTEP_1
  17. 089F: get_actor 0@ pedtype_to 31@
  18. 03F0: enable_text_draw 1
  19. wait 50
  20. 03F0: enable_text_draw 0
  21. wait 50
  22. 045A: draw_text_1number 250.0 40.0 GXT 'NUMBER' number 31@ // ~1~
  23. 05BE: AS_kill_actor 0@
  24. Actor.RemoveReferences(0@)
  25. jump @RAFSTEP_1

  26. :RAFSTEP_func
  27. 5@ = 0
  28. 4@ = 0

  29. :RAFSTEP_countLoop
  30. if
  31. Actor.Defined(4@)
  32. jf @RAFSTEP_11
  33. if and
  34. 803B: not $PLAYER_ACTOR == 4@ // (int)
  35. 00FE: actor 4@ sphere 0 in_sphere 0@ 1@ 2@ radius 3@ 3@ 3@
  36. jf @RAFSTEP_11
  37. 5@ = 1
  38. jump @RAFSTEP_12

  39. :RAFSTEP_11
  40. 4@ += 1
  41. if
  42. 4@ > 30000
  43. jf @RAFSTEP_countLoop

  44. :RAFSTEP_12
  45. if
  46. 5@ == 0
  47. jf @RAFSTEP_Result
  48. 4@ = -1

  49. :RAFSTEP_Result
  50. 0AB2: ret 1 4@
复制代码

传奇 Legend

虚拟世界,属于你的世界

Rank: 16

UID
4
宝石
154 粒
金币
5594 枚
节操
458 斤
灵石
0 块
精力
509 ℃
QQ
 楼主| 发表于 2012-4-7 10:39:27 | 显示全部楼层
本帖最后由 kwanz 于 2012-4-13 19:22 编辑

车辆行驶编写教程
___
引用 (markbaker @ Aug 26 2009, 12:36)
很给力的教程!

我有几个简单的问题 - 如何刷出车辆并让它自己行驶,直线驾驶抑或走特定路径?还有,能否生成有行人做驾驶员或乘客的车辆?
___
首先让我们从最简单的问题开始:“如何刷车”,我直接拉教程Scripting/Writing a Thread -- Next Step/ Spawn a 3D model里的例子过来

下面的代码当玩家入圈时在Grove St刷出Infernus
玩家离开后,代码会释放对车辆的引用,跳回判断外循环
  1. {$CLEO .cs}
  2. :3dModels_1
  3. 03A4: name_thread 'MODL'

  4. :3dModels_2
  5. 0001: wait 0 ms
  6. 00D6: if 0
  7. 0256: player $PLAYER_CHAR defined
  8. 004D: jump_if_false @3dModels_2
  9. 00D6: if 0
  10. 00FF: actor $PLAYER_ACTOR 1 (in-sphere)near_point_on_foot 2491.5 -1667.5 13.35 radius 1.0 1.0 1.0
  11. 004D: jump_if_false @3dModels_2

  12. 0247: request_model #INFERNUS

  13. :Load_Model_Check
  14. 0001: wait 0 ms
  15. 00D6: if 0
  16. 0248: model #INFERNUS available
  17. 004D: jump_if_false @Load_Model_Check

  18. 00A5: 1@ = create_car #INFERNUS at 2487.5 -1660.5 13.35
  19. 0175: set_car 1@ z_angle_to 90.0
  20. 0249: release_model #INFERNUS

  21. :3dModels_3
  22. 0001: wait 0 ms
  23. 00D6: if 0
  24. 0256: player $PLAYER_CHAR defined
  25. 004D: jump_if_false @3dModels_3
  26. 00D6: if 0
  27. 80FF: NOT actor $PLAYER_ACTOR 0 ()near_point_on_foot 2491.5 -1667.5 13.35 radius 2.0 2.0 2.0
  28. 004D: jump_if_false @3dModels_3
  29. 01C3: remove_references_to_car 1@ // 解除对车辆的引用,车子变成一辆普通的随机街车
  30. 0002: jump @3dModels_2
复制代码


下一步,我在车上刷出两个人物,让车子开往指定地点
更进一步,我在车上放了个箭头,你可以在小地图上看车子开到哪儿

刷出人物只需要直接调opcode: 0129刷司机,01C8刷乘客
当然也可以用正常的刷人代码,然后让人物上车,同样的对司机和乘客用不同的opcode
乘客上车opcode需要设定最后一个参数为座椅号
0=副驾,1/2为后排

让车辆行驶,我直接使用了简单的drive_to
行驶指令有很多变体,所有的用法都需要设定速度

drive-to命令后的循环需要对车辆的行驶动作的条件判定
有一个重要的检查就是判断车辆废了没有
比如说,程序里设定的人物死了,被捕,或者车子毁了开远了,我们需要用些法子执行刷新,也就是解除对车辆,箭头和乘客的引用,来从头开始执行代码。
  1. if or
  2. 0119: car 1@ wrecked
  3. 01F4: car 1@ flipped
  4. 8202: not actor $PLAYER_ACTOR near_car 1@ radius 500.0 500.0 flag 0
复制代码

下面的代码在玩家进圈时在老家刷出Infernus,车上有两个小弟
玩家进圈后,车辆会开到下一个路口并停止,直到玩家离车足够远(500.0单位)
  1. CODE
  2. {$CLEO .cs}
  3. :CarDrive_1
  4. 03A4: name_thread 'CDRIVE'

  5. :CarDrive_2
  6. 0001: wait 0 ms
  7. if
  8. 0256: player $PLAYER_CHAR defined
  9. 004D: jump_if_false @CarDrive_2
  10. if
  11. 00FF: actor $PLAYER_ACTOR 1 (in-sphere)near_point_on_foot 2491.5 -1667.5 13.35 radius 1.0 1.0 1.0
  12. 004D: jump_if_false @CarDrive_2

  13. 0247: request_model #INFERNUS
  14. 0247: request_model #fam1
  15. 0247: request_model #fam2

  16. :CarDrive_3
  17. 0001: wait 0 ms
  18. if and
  19. 0248: model #INFERNUS available
  20. 0248: model #fam1 available
  21. 0248: model #fam2 available
  22. 004D: jump_if_false @CarDrive_3

  23. 00A5: 1@ = create_car #INFERNUS at 2487.5 -1660.5 13.35
  24. 0175: set_car 1@ z_angle_to 90.0
  25. 0129: 2@ = create_actor 8 #fam1 in_car 1@ driverseat
  26. 01C8: 3@ = create_actor 8 #fam2 in_car 1@ passenger_seat 0
  27. 0186: 4@ = create_marker_above_car 1@
  28. 07E0: set_marker 4@ type_to 1

  29. 0249: release_model #INFERNUS
  30. 0249: release_model #fam1
  31. 0249: release_model #fam2

  32. //////////////////// drive_to块开始

  33. 00A7: car 1@ drive_to 2353.1528 -1658.6493 13.3846//---简单的drive_to
  34. 00AD: set_car 1@ max_speed_to 20.0//---设定速度,很重要
  35. 00AE: unknown_set_car 1@ to_ignore_traffic_lights 2//--可选,设定车辆遵守交通规则

  36. //////////////////// drive_to块结束

  37. :CarDrive_13
  38. 0001: wait 0 ms
  39. if
  40. 0256: player $PLAYER_CHAR defined
  41. 004D: jump_if_false @CarDrive_13
  42. if or
  43. 0119: car 1@ wrecked
  44. 01F4: car 1@ flipped
  45. 8202: not actor $PLAYER_ACTOR near_car 1@ radius 500.0 500.0 flag 0
  46. 004D: jump_if_false @CarDrive_13
  47. 01C3: remove_references_to_car 1@ // 解除引用,设为随机车辆
  48. 01C2: remove_references_to_actor 2@ // 解除引用,设为普通路人
  49. 01C2: remove_references_to_actor 3@ // 解除引用,设为普通路人
  50. 0164: disable_marker 4@
  51. 0002: jump @CarDrive_2
复制代码


让车辆行驶还有很多变体。最简单的例子是00A7
车辆会严格按照path行驶,path存储在gta3.img中的nodes.dat里,是交通车辆的行驶路径。如果你在没有path的地方刷车,比如沙漠里,然后调行驶命令,它首先会开到path上,然后走path到目的地。如果目的地不在path上,车子是到不了的。
写车辆行驶代码是让人非常恼火的事情,即便目的地在path上。它经常不走寻常路,或者卡住。
----------------------------------------------------------------------------
我们还有别的opcode强行控制车辆
----------------------------------------------------------------------------

opcode 04e0: 让车辆忽略path直接开往目的地
04e0: car 1@ abandon_path_radius 200

用下面的代码块换掉上面的drive_to块
  1. //////////////////// drive-to块开始

  2. 00A7: car 1@ drive_to 2431.5864 -1628.0818 13.698//---简单的drive_to
  3. 00AD: set_car 1@ max_speed_to 20.0//---设定速度,很重要
  4. 00AE: unknown_set_car 1@ to_ignore_traffic_lights 2//--可选,设定车辆忽略交通灯并绕过其他车辆
  5. 04e0: car 1@ abandon_path_radius 200

  6. //////////////////// drive-to块结束
复制代码

目的地是Grove St和高速公路之间的空地
若没有04e0:,车辆会在路上开很远
opcode 04e0: 仅在一定半径范围内有效
它表示起点要在path的200单位范围内,目的地也一样
大于250则失效
----------------------------------------------------------------------------
用opcode 00AF: 并设最后一个参数为2,车辆会追玩家
  1. //////////////////// drive-to块开始

  2. 00AD: set_car 1@ max_speed_to 20.0//---设定速度,很重要
  3. 00AE: unknown_set_car 1@ to_ignore_traffic_lights 2//--可选,设定车辆忽略交通灯并绕过其他车辆
  4. 00AF: set_car 1@ driver_behaviour_to 2//-- 追着玩家

  5. //////////////////// drive-to块结束
复制代码


opcode 00AF可以接受4种行为设定
1 - 在道路上开,如果道路被堵,就倒车
2 - 杀死玩家
4 - 开向玩家并停车
8 - 忽略所有路径
----------------------------------------------------------------------------
用opcode 00AF: 并设最后一个参数为2,车辆会自动沿path行驶
  1. //////////////////// drive-to块开始

  2. 00AD: set_car 1@ max_speed_to 20.0//---设定速度,很重要
  3. 00AE: unknown_set_car 1@ to_ignore_traffic_lights 2//--可选,设定车辆忽略交通灯并绕过其他车辆
  4. 00AF: set_car 1@ driver_behaviour_to 1

  5. //////////////////// drive-to块结束
复制代码

----------------------------------------------------------------------------
我们可以用opcode读车前坐标,并让车子行驶到此处
  1. //////////////////// drive-to块开始

  2. 0407: create_coordinate 11@ 12@ 13@ from_car 1@ offset -10.0 15.0 0.0
  3. 00A7: car 1@ drive_to 11@ 12@ 13@//---简单的drive-to
  4. 00AD: set_car 1@ max_speed_to 20.0//---设定速度,很重要
  5. 00AE: unknown_set_car 1@ to_ignore_traffic_lights 2//--可选,设定车辆忽略交通灯并绕过其他车辆

  6. //////////////////// drive-to块结束
复制代码

----------------------------------------------------------------------------
我们可以用opcode读车前坐标,并让车子行驶到此处;并且调04BA执行瞬时加速
  1. //////////////////// drive-to块开始

  2. 0407: create_coordinate 11@ 12@ 13@ from_car 1@ offset -10.0 15.0 0.0
  3. 00A7: car 1@ drive_to 11@ 12@ 13@//---简单的drive-to
  4. 00AD: set_car 1@ max_speed_to 20.0//---设定速度,很重要
  5. 00AE: unknown_set_car 1@ to_ignore_traffic_lights 2//--可选,设定车辆忽略交通灯并绕过其他车辆
  6. 04BA: set_car 1@ speed_instantly 50.0

  7. //////////////////// drive-to块结束
复制代码



----------------------------------------------------------------------------
让司机执行行驶纠正
R*在main.scm里有车辆堵塞检测,但这个函数在CLEO中无效
不过可以调06C7做行驶纠正
  1. //////////////////// drive-to块开始

  2. 06C7: AS_actor 2@ driver_of_car 1@ perform_action 14 timelimit 3000 // 倒车设定
  3. 00A7: car 1@ drive_to 2353.1528 -1658.6493 13.3846//---简单的drive-to
  4. 00AD: set_car 1@ max_speed_to 20.0//---设定速度,很重要
  5. 00AE: unknown_set_car 1@ to_ignore_traffic_lights 2//--可选,设定车辆忽略交通灯并绕过其他车辆

  6. //////////////////// drive-to块结束
复制代码

司机首先会做约3秒的转圈倒车,然后开往目的地
----------------------------------------------------------------------------
Opcode 06C7还有一些不同版本
  1. 06C7: AS_actor 2@ driver_of_car 1@ perform_action 6 timelimit 1000 //短暂停车
  2. 06C7: AS_actor 2@ driver_of_car 1@ perform_action 6 timelimit 2000000 //长时间停车
  3. 06C7: AS_actor 2@ driver_of_car 1@ perform_action 3 timelimit 3000 //倒车向右,然后前进
  4. 06C7: AS_actor 2@ driver_of_car 1@ perform_action 22 timelimit 3000 //倒车向左,然后前进
  5. 06C7: AS_actor 2@ driver_of_car 1@ perform_action 14 timelimit 3000 //倒车转圈
  6. 06C7: AS_actor 2@ driver_of_car 1@ perform_action 9 timelimit 3000 //加速前进
  7. 06C7: AS_actor 2@ driver_of_car 1@ perform_action 7 timelimit 3000 //左转
  8. 06C7: AS_actor 2@ driver_of_car 1@ perform_action 8 timelimit 3000 //右转
复制代码

----------------------------------------------------------------------------
指定司机驾车

Opcode 05D1不是控制车辆的指令,它是作用于司机的

这个函数也可以忽略path,让司机直线开向目的地,正如04e0: car 1@ abandon_path_radius
这取决于标志位的设定

0 0 5 沿path
2 0 5 忽略path
  1. //////////////////// drive-to块开始

  2. 05D1: AS_actor 2@ drive_car 1@ to 2353.1528 -1658.6493 13.384 speed 20.0 0 0 5

  3. //////////////////// drive-to块结束
复制代码

----------------------------------------------------------------------------
Opcode 05D1可被调用多次来设定AS_Pack的组合动作
调用的时候需要设定驾驶员参数为-1,并在设置完AS_Pack后将人物2@赋给该AS_Pack
  1. //////////////////// drive-to块开始

  2. 0615: define_action_sequences 5@
  3. 05D1: AS_actor -1 drive_car 1@ to 2353.1528 -1658.6493 13.384 speed 20.0 0 0 5
  4. 05D1: AS_actor -1 drive_car 1@ to 2431.7739 -1674.7444 13.6643 speed 20.0 0 0 5
  5. 05D1: AS_actor -1 drive_car 1@ to 2431.5864 -1628.0818 13.698 speed 20.0 2 0 5
  6. 0616: define_action_sequences_end 5@
  7. 0618: assign_actor 2@ to_action_sequences 5@
  8. 061B: remove_references_to_AS_pack 5@

  9. //////////////////// drive-to块结束
复制代码

----------------------------------------------------------------------------
为司机定义scmpath

先调用05D6清除先前设定的scmpath
然后设定新的坐标,然后调07E7让司机沿路径驾驶

这个函数也可以设定为忽略路径,让司机直线行驶,正如04E0: car 1@ abandon_path_radius
这取决于标志位的设定

0 0 5 沿path
2 0 5 忽略path
  1. //////////////////// drive-to块开始

  2. 05D6: clear_scmpath
  3. 05D7: add_point_to_scmpath 2353.1528 -1658.6493 13.384
  4. 05D7: add_point_to_scmpath 2431.7739 -1674.7444 13.6643
  5. 07E7: AS_assign_scmpath_to_actor 2@ in_car 1@ speed 20.0 flags 0 0 5

  6. //////////////////// drive-to块结束
复制代码

----------------------------------------------------------------------------
车辆行驶脚本的实际应用
----------------------------------------------------------------------------
在实际写车辆沿指定的长路径行驶的时候需要写比较复杂的代码,不断检测车辆是否到达检查点并设定下一个路点。因为你不能等车到了地方以后才检查车辆的位置,你必须要沿路经过时做检查
并且,程序需要检测车子是否飞到了空中,因为此时它会丢失坐标信息,我们必须补充相关的信息
检测是否翻车或毁车永远是必要的,因为车子废了就不能继续开,程序结束
R*在main.scm中用到了车辆堵塞检测,但这个函数在CLEO中不可用
不过我们可以检测车速是否低于1.0
----------------------------------------------------------------------------
SF机场环行程序V1
以下的脚本把玩家传送到SF机场,坐上摩托车,并且刷出骑车绕机场大楼转圈的人物
请走到室外空间,按退格键,跟着这个NPC看看
这里用到了Opcode 00A7: car 1@ drive_to和04e0: car 1@ abandon_path_radius
这人有时会摔下车,然后上车继续跑
作为替代,你也可以调08C6
  1. //08C6: set_actor 9@ stay_on_bike 1
复制代码


要刷新这段代码你需要离机场足够远,至少700.0单位
  1. CODE
  2. {$CLEO .cs}
  3. :Drive_1
  4. 03A4: name_thread 'DRIV'

  5. :Drive_3
  6. 0001: wait 0 ms
  7. if
  8. 0256: player $PLAYER_CHAR defined
  9. jf @Drive_3
  10. 077E: 0@ = active_interior
  11. if and
  12. 0039: 0@ == 0 // integer values
  13. 0AB0: key_pressed 8//----------------------------------------Backspace
  14. jf @Drive_3
  15. 016A: fade 0 () 250 ms
  16. 0001: wait 250 ms
  17. 01B4: set_player $PLAYER_CHAR frozen_state 0 (frozen)
  18. 0362: remove_actor $PLAYER_ACTOR from_car_and_place_at -1338.5 -408.1 14.1
  19. 0173: set_actor $PLAYER_ACTOR z_angle_to 90.8
  20. 0001: wait 500 ms
  21. 0247: request_model #NRG500
  22. 0247: request_model #MAFFA

  23. :Drive_5
  24. 0001: wait 0 ms
  25. if and
  26. 0248: model #NRG500 available
  27. 0248: model #MAFFA available
  28. jf @Drive_5
  29. 00A5: 1@ = create_car #NRG500 at -1333.5 -408.1 14.1
  30. 0175: set_car 1@ z_angle_to 280.0
  31. 0224: set_car 1@ health_to 2000
  32. 00A5: 7@ = create_car #NRG500 at -1354.5 -419.1 14.1
  33. 0175: set_car 7@ z_angle_to 280.0
  34. 0224: set_car 7@ health_to 2000
  35. 020A: set_car 7@ door_status_to 4
  36. 02AC: set_car 7@ immunities 1 1 1 1 1
  37. 01EC: make_car 7@ very_heavy 1
  38. 0129: 9@ = create_actor 24 #MAFFA in_car 7@ driverseat
  39. 0223: set_actor 9@ health_to 3000
  40. 04E4: unknown_refresh_game_renderer_at -1333.5 -408.1
  41. 03CB: set_camera -1333.5 -408.1 14.1
  42. 029B: 23@ = init_object 1655 at -1576.02 -202.34 13.76
  43. 0177: set_object 23@ z_angle_to 270.0
  44. 01C7: remove_object_from_mission_cleanup_list 23@
  45. 0382: set_object 23@ collision_detection 1
  46. 029B: 24@ = init_object 1655 at -1597.9 -506.5 21.7
  47. 0177: set_object 24@ z_angle_to 270.0
  48. 01C7: remove_object_from_mission_cleanup_list 24@
  49. 0382: set_object 24@ collision_detection 1
  50. 029B: 25@ = init_object 1655 at -1375.9 -581.5 13.69
  51. 0177: set_object 25@ z_angle_to 270.0
  52. 01C7: remove_object_from_mission_cleanup_list 25@
  53. 0382: set_object 25@ collision_detection 1
  54. 029B: 26@ = init_object 1655 at -1374.9 -585.5 13.69
  55. 0177: set_object 26@ z_angle_to 270.0
  56. 01C7: remove_object_from_mission_cleanup_list 26@

  57. 0382: set_object 26@ collision_detection 1
  58. 0177: set_object 23@ z_angle_to 135.0
  59. 0177: set_object 24@ z_angle_to 225.0
  60. 0177: set_object 25@ z_angle_to 280.0
  61. 0177: set_object 26@ z_angle_to 280.0
  62. 0186: 29@ = create_marker_above_car 7@
  63. 07E0: set_marker 29@ type_to 1

  64. 0249: release_model #NRG500
  65. 0249: release_model #MAFFA
  66. 04e0: car 7@ abandon_path_radius 200
  67. 00AD: set_car 7@ max_speed_to 100.0
  68. 04BA: set_car 7@ speed_instantly 30.0
  69. 00AF: set_car 7@ driver_behaviour_to 1
  70. 00AE: unknown_set_car 7@ to_ignore_traffic_lights 2
  71. 0001: wait 250 ms
  72. 036A: put_actor $PLAYER_ACTOR in_car 1@
  73. 0001: wait 250 ms
  74. 016A: fade 1 () 1000 ms
  75. 0001: wait 1000 ms
  76. 0373: set_camera_directly_behind_player
  77. 02EB: restore_camera_with_jumpcut
  78. 01B4: set_player $PLAYER_CHAR frozen_state 1 (unfrozen)
  79. 0006: 15@ = 0 // integer values
  80. 0006: 16@ = 0 // integer values
  81. 0006: 20@ = 20000 // floating-point values
  82. 0006: 19@ = 0 // integer values
  83. 0007: 11@ = -1320.48 // floating-point values
  84. 0007: 12@ = -407.1 // floating-point values
  85. 0007: 13@ = 13.76 // floating-point values
  86. 00A7: car 7@ drive_to 11@ 12@ 13@
  87. 00AD: set_car 7@ max_speed_to 1.0
  88. 04e0: car 7@ abandon_path_radius 250
  89. //08C6: set_actor 9@ stay_on_bike 1

  90. :Drive_7
  91. 0001: wait 0 ms
  92. if
  93. 0256: player $PLAYER_CHAR defined
  94. jf @Drive_7

  95. 0050: gosub @Drive_sub_3

  96. if and
  97. 8119: NOT car 1@ wrecked
  98. 8119: NOT car 7@ wrecked
  99. 8118: NOT actor 9@ dead
  100. jf @Drive_7
  101. if
  102. 00FE: actor $PLAYER_ACTOR 0 ()near_point -1333.5 -408.1 14.1 radius 650.5 650.5 50.5
  103. jf @Drive_12
  104. jump @Drive_7

  105. :Drive_12
  106. 0164: disable_marker 29@
  107. 01C3: remove_references_to_car 1@ // 转为随机车辆
  108. 01C3: remove_references_to_car 7@ //转为随机车辆
  109. 01C2: remove_references_to_actor 9@ //转为随机人物
  110. 0108: destroy_object 23@
  111. 0108: destroy_object 24@
  112. 0108: destroy_object 25@
  113. 0108: destroy_object 26@
  114. jump @Drive_3


  115. :Drive_sub_3
  116. if
  117. 8119: NOT car 7@ wrecked
  118. jf @Drive_sub_109
  119. if
  120. 00DB: actor 9@ in_car 7@
  121. jf @Drive_sub_99
  122. if
  123. 0039: 19@ == 1 // integer values
  124. jf @Drive_sub_10
  125. 0006: 19@ = 0 // integer values
  126. jump @Drive_sub_100

  127. :Drive_sub_10
  128. if
  129. 0039: 15@ == 0 // integer values
  130. jf @Drive_sub_11
  131. if
  132. 01AF: car 7@ 0 ()near_point 11@ 12@ 13@ radius 5.2 5.2 5.0
  133. jf @Drive_sub_11
  134. 0006: 15@ = 1 // integer values
  135. 0007: 11@ = -1181.78 // floating-point values
  136. 0007: 12@ = -331.30 // floating-point values
  137. 0007: 13@ = 13.76 // floating-point values
  138. 000A: 16@ += 0 // integer values
  139. 0007: 17@ = 100.0 // floating-point values
  140. 0007: 18@ = 20.0 // floating-point values
  141. 04e0: car 7@ abandon_path_radius 250
  142. jump @Drive_sub_100

  143. :Drive_sub_11
  144. if
  145. 0039: 15@ == 1 // integer values
  146. jf @Drive_sub_12
  147. if
  148. 01AF: car 7@ 0 ()near_point 11@ 12@ 13@ radius 15.2 15.2 5.0
  149. jf @Drive_sub_12
  150. 00AD: set_car 7@ max_speed_to 10.0
  151. 0006: 15@ = 2 // integer values
  152. 0007: 11@ = -1282.1 // floating-point values
  153. 0007: 12@ = -159.3 // floating-point values
  154. 0007: 13@ = 13.76 // floating-point values
  155. 0175: set_car 7@ z_angle_to 340.0
  156. 000A: 16@ += 0 // integer values
  157. 0007: 17@ = 100.0 // floating-point values
  158. 0007: 18@ = 20.0 // floating-point values
  159. 04e0: car 7@ abandon_path_radius 250
  160. jump @Drive_sub_100

  161. :Drive_sub_12
  162. if
  163. 0039: 15@ == 2 // integer values
  164. jf @Drive_sub_13
  165. if
  166. 01AF: car 7@ 0 ()near_point 11@ 12@ 13@ radius 15.2 15.2 5.0
  167. jf @Drive_sub_13
  168. 00AD: set_car 7@ max_speed_to 25.0
  169. 0006: 15@ = 3 // integer values
  170. 0007: 11@ = -1498.78 // floating-point values
  171. 0007: 12@ = -138.30 // floating-point values
  172. 0007: 13@ = 13.76 // floating-point values
  173. 0175: set_car 7@ z_angle_to 65.0
  174. 000A: 16@ += 0 // integer values
  175. 0007: 17@ = 100.0 // floating-point values
  176. 0007: 18@ = 20.0 // floating-point values
  177. 04e0: car 7@ abandon_path_radius 250
  178. jump @Drive_sub_100

  179. :Drive_sub_13
  180. if
  181. 0039: 15@ == 3 // integer values
  182. jf @Drive_sub_14
  183. if
  184. 01AF: car 7@ 0 ()near_point 11@ 12@ 13@ radius 8.2 8.2 5.0
  185. jf @Drive_sub_14
  186. 00AD: set_car 7@ max_speed_to 25.0
  187. 0006: 15@ = 4 // integer values
  188. 0007: 11@ = -1576.78 // floating-point values
  189. 0007: 12@ = -202.30 // floating-point values
  190. 0007: 13@ = 13.76 // floating-point values
  191. 0175: set_car 7@ z_angle_to 135.0
  192. 000A: 16@ += 0 // integer values
  193. 0007: 17@ = 100.0 // floating-point values
  194. 0007: 18@ = 20.0 // floating-point values
  195. 04e0: car 7@ abandon_path_radius 250
  196. jump @Drive_sub_100



  197. :Drive_sub_14
  198. if
  199. 0039: 15@ == 4 // integer values
  200. jf @Drive_sub_15
  201. if
  202. 01AF: car 7@ 0 ()near_point 11@ 12@ 13@ radius 5.2 5.2 5.0
  203. jf @Drive_sub_15
  204. 0006: 15@ = 5 // integer values
  205. 0007: 11@ = -1694.78 // floating-point values
  206. 0007: 12@ = -352.30 // floating-point values
  207. 0007: 13@ = 13.9 // floating-point values
  208. 0175: set_car 7@ z_angle_to 135.0
  209. 000A: 16@ += 0 // integer values
  210. 0007: 17@ = 100.0 // floating-point values
  211. 0007: 18@ = 20.0 // floating-point values
  212. 04e0: car 7@ abandon_path_radius 250
  213. jump @Drive_sub_100

  214. :Drive_sub_15
  215. if
  216. 0039: 15@ == 5 // integer values
  217. jf @Drive_sub_16
  218. if
  219. 01AF: car 7@ 0 ()near_point 11@ 12@ 13@ radius 15.2 15.2 5.0
  220. jf @Drive_sub_16
  221. 00AD: set_car 7@ max_speed_to 10.0
  222. 0006: 15@ = 6 // integer values
  223. 0007: 11@ = -1691.78 // floating-point values
  224. 0007: 12@ = -409.30 // floating-point values
  225. 0007: 13@ = 13.9 // floating-point values
  226. 0175: set_car 7@ z_angle_to 180.0
  227. 000A: 16@ += 0 // integer values
  228. 0007: 17@ = 40.0 // floating-point values
  229. 0007: 18@ = 10.0 // floating-point values
  230. 04e0: car 7@ abandon_path_radius 250
  231. 00AE: unknown_set_car 7@ to_ignore_traffic_lights 2
  232. jump @Drive_sub_100

  233. :Drive_sub_16
  234. if
  235. 0039: 15@ == 6 // integer values
  236. jf @Drive_sub_17
  237. if
  238. 01AF: car 7@ 0 ()near_point 11@ 12@ 13@ radius 8.2 8.2 5.0
  239. jf @Drive_sub_17
  240. 00AD: set_car 7@ max_speed_to 0.0
  241. 0006: 15@ = 7 // integer values
  242. 0007: 11@ = -1519.78 // floating-point values
  243. 0007: 12@ = -580.30 // floating-point values
  244. 0007: 13@ = 13.76 // floating-point values
  245. 0175: set_car 7@ z_angle_to 250.0
  246. 000A: 16@ += 0 // integer values
  247. 0007: 17@ = 100.0 // floating-point values
  248. 0007: 18@ = 0.0 // floating-point values
  249. 04e0: car 7@ abandon_path_radius 250
  250. 00AE: unknown_set_car 7@ to_ignore_traffic_lights 2
  251. jump @Drive_sub_100

  252. :Drive_sub_17
  253. if
  254. 0039: 15@ == 7 // integer values
  255. jf @Drive_sub_18
  256. if
  257. 01AF: car 7@ 0 ()near_point 11@ 12@ 13@ radius 15.2 15.2 5.0
  258. jf @Drive_sub_18
  259. 00AD: set_car 7@ max_speed_to 5.0
  260. 01EB: set_car_density_to 0.0
  261. 0006: 15@ = 8 // integer values
  262. 0007: 11@ = -1299.78 // floating-point values
  263. 0007: 12@ = -565.30 // floating-point values
  264. 0007: 13@ = 13.76 // floating-point values
  265. 0175: set_car 7@ z_angle_to 0.0
  266. 000A: 16@ += 0 // integer values
  267. 0007: 17@ = 100.0 // floating-point values
  268. 0007: 18@ = 20.0 // floating-point values
  269. 04e0: car 7@ abandon_path_radius 250
  270. jump @Drive_sub_100

  271. :Drive_sub_18
  272. if
  273. 0039: 15@ == 8 // integer values
  274. jf @Drive_sub_109
  275. if
  276. 01AF: car 7@ 0 ()near_point 11@ 12@ 13@ radius 25.2 25.2 5.0
  277. jf @Drive_sub_109
  278. 00AD: set_car 7@ max_speed_to 0.0
  279. 0006: 15@ = 1 // integer values
  280. 000A: 16@ += 1 // integer values
  281. 0007: 11@ = -1181.78 // floating-point values
  282. 0007: 12@ = -331.30 // floating-point values
  283. 0007: 13@ = 13.76 // floating-point values
  284. 0175: set_car 7@ z_angle_to 1.0
  285. 0007: 17@ = 100.0 // floating-point values
  286. 0007: 18@ = 20.0 // floating-point values
  287. 04e0: car 7@ abandon_path_radius 250
  288. 00AE: unknown_set_car 7@ to_ignore_traffic_lights 2

  289. if
  290. 0039: 16@ == 2 // integer values
  291. jf @Drive_sub_100
  292. 00BC: text_highpriority 'BJ_LOSE' 5000 ms 1
  293. jump @Drive_sub_100

  294. :Drive_sub_99
  295. if
  296. 0039: 19@ == 0 // integer values
  297. jf @Drive_sub_109
  298. 00AD: set_car 7@ max_speed_to 0.0
  299. 05CB: actor_goto_and_enter_car 9@ 7@ 5000
  300. 0006: 19@ = 1 // integer values
  301. jump @Drive_sub_109

  302. :Drive_sub_100
  303. 00A7: car 7@ drive_to 11@ 12@ 13@
  304. 00AD: set_car 7@ max_speed_to 17@
  305. 03F0: text_draw_toggle 0
  306. 0006: 33@ = 0 // integer values
  307. jump @Drive_sub_109

  308. :Drive_sub_102
  309. if
  310. 01F3: car 7@ airborne
  311. jf @Drive_sub_103
  312. 0007: 18@ = 0.0 // floating-point values
  313. 00A7: car 7@ drive_to 11@ 12@ 13@
  314. 04BA: set_car 7@ speed_instantly 18@
  315. 00AD: set_car 7@ max_speed_to 17@
  316. jump @Drive_sub_103

  317. :Drive_sub_103
  318. if
  319. 01AF: car 7@ 0 ()near_point 11@ 12@ 13@ radius 30.2 30.2 5.0
  320. jf @Drive_sub_104
  321. jump @Drive_sub_105

  322. :Drive_sub_104
  323. 02E3: 20@ = car 7@ speed
  324. if
  325. 81F3: NOT car 7@ airborne
  326. jf @Drive_sub_106
  327. if and
  328. 0021: 20@ > 30.0 // floating-point values
  329. 0019: 33@ > 700 // integer values
  330. jf @Drive_sub_105
  331. 04BA: set_car 7@ speed_instantly 50.0

  332. :Drive_sub_105
  333. if
  334. 0019: 33@ > 2000 // integer values
  335. jf @Drive_sub_109

  336. :Drive_sub_106
  337. 0006: 33@ = 0 // integer values

  338. :Drive_sub_109
  339. 0051: return
复制代码

----------------------------------------------------------------------------
SF机场环行程序V2
这段程序和上面的是一样的,不过用到了07E7: AS_assign_scmpath_to_actor
  1. {$CLEO .cs}
  2. :scmpath_1
  3. 03A4: name_thread 'SCMP'

  4. :scmpath_3
  5. 0001: wait 0 ms
  6. if
  7. 0256: player $PLAYER_CHAR defined
  8. jf @scmpath_3
  9. 077E: 0@ = active_interior
  10. if and
  11. 0038: 0@ == 0 // integer values
  12. 0AB0: key_pressed 8//----------------------------------------Backspace
  13. jf @scmpath_3
  14. 016A: fade 0 () 250 ms
  15. 0001: wait 250 ms
  16. 01B4: set_player $PLAYER_CHAR frozen_state 0 (frozen)
  17. 0362: remove_actor $PLAYER_ACTOR from_car_and_place_at -1338.5 -408.1 14.1
  18. 0173: set_actor $PLAYER_ACTOR z_angle_to 90.8
  19. 0001: wait 500 ms
  20. 0247: request_model #NRG500
  21. 0247: request_model #MAFFA

  22. :scmpath_5
  23. 0001: wait 0 ms
  24. if and
  25. 0248: model #NRG500 available
  26. 0248: model #MAFFA available
  27. jf @scmpath_5
  28. 00A5: 1@ = create_car #NRG500 at -1333.5 -408.1 14.1
  29. 0175: set_car 1@ z_angle_to 280.0
  30. 0224: set_car 1@ health_to 2000
  31. 00A5: 7@ = create_car #NRG500 at -1354.5 -419.1 14.1
  32. 0175: set_car 7@ z_angle_to 280.0
  33. 0224: set_car 7@ health_to 2000
  34. 020A: set_car 7@ door_status_to 4
  35. 02AC: set_car 7@ immunities 1 1 1 1 1
  36. 01EC: make_car 7@ very_heavy 1
  37. 0129: 9@ = create_actor 24 #MAFFA in_car 7@ driverseat
  38. 0223: set_actor 9@ health_to 3000
  39. 04E4: unknown_refresh_game_renderer_at -1333.5 -408.1
  40. 03CB: set_camera -1333.5 -408.1 14.1
  41. 029B: 23@ = init_object 1655 at -1576.02 -202.34 13.76
  42. 0177: set_object 23@ z_angle_to 270.0
  43. 01C7: remove_object_from_mission_cleanup_list 23@
  44. 0382: set_object 23@ collision_detection 1
  45. 029B: 24@ = init_object 1655 at -1597.9 -506.5 21.7
  46. 0177: set_object 24@ z_angle_to 270.0
  47. 01C7: remove_object_from_mission_cleanup_list 24@
  48. 0382: set_object 24@ collision_detection 1
  49. 029B: 25@ = init_object 1655 at -1375.9 -581.5 13.69
  50. 0177: set_object 25@ z_angle_to 270.0
  51. 01C7: remove_object_from_mission_cleanup_list 25@
  52. 0382: set_object 25@ collision_detection 1
  53. 029B: 26@ = init_object 1655 at -1374.9 -585.5 13.69
  54. 0177: set_object 26@ z_angle_to 270.0
  55. 01C7: remove_object_from_mission_cleanup_list 26@

  56. 0382: set_object 26@ collision_detection 1
  57. 0177: set_object 23@ z_angle_to 135.0
  58. 0177: set_object 24@ z_angle_to 225.0
  59. 0177: set_object 25@ z_angle_to 280.0
  60. 0177: set_object 26@ z_angle_to 280.0
  61. 0186: 29@ = create_marker_above_car 7@
  62. 07E0: set_marker 29@ type_to 1

  63. 0249: release_model #NRG500
  64. 0249: release_model #MAFFA
  65. 04e0: car 7@ abandon_path_radius 200
  66. 00AD: set_car 7@ max_speed_to 100.0
  67. 04BA: set_car 7@ speed_instantly 30.0
  68. 00AF: set_car 7@ driver_behaviour_to 1
  69. 00AE: unknown_set_car 7@ to_ignore_traffic_lights 2
  70. 0001: wait 250 ms
  71. 036A: put_actor $PLAYER_ACTOR in_car 1@
  72. 0001: wait 250 ms
  73. 016A: fade 1 () 1000 ms
  74. 0001: wait 1000 ms
  75. 0373: set_camera_directly_behind_player
  76. 02EB: restore_camera_with_jumpcut
  77. 01B4: set_player $PLAYER_CHAR frozen_state 1 (unfrozen)
  78. 0006: 15@ = 0 // integer values
  79. 0006: 16@ = 0 // integer values
  80. 0006: 20@ = 20000 // floating-point values
  81. 0006: 19@ = 0 // integer values
  82. 0007: 11@ = -1320.48 // floating-point values
  83. 0007: 12@ = -407.1 // floating-point values
  84. 0007: 13@ = 13.76 // floating-point values
  85. 00A7: car 7@ drive_to 11@ 12@ 13@
  86. 00AD: set_car 7@ max_speed_to 1.0
  87. 04e0: car 7@ abandon_path_radius 250
  88. 08C6: set_actor 9@ stay_on_bike 1

  89. :scmpath_7
  90. 0001: wait 0 ms
  91. if
  92. 0256: player $PLAYER_CHAR defined
  93. jf @scmpath_7

  94. 0050: gosub @scmpath_sub_3

  95. if and
  96. 8119: NOT car 1@ wrecked
  97. 8119: NOT car 7@ wrecked
  98. 8118: NOT actor 9@ dead
  99. jf @scmpath_7
  100. if
  101. 00FE: actor $PLAYER_ACTOR 0 ()near_point -1333.5 -408.1 14.1 radius 650.5 650.5 50.5
  102. jf @scmpath_12
  103. jump @scmpath_7

  104. :scmpath_12
  105. 0164: disable_marker 29@
  106. 01C3: remove_references_to_car 1@ // Like turning a car into any random car
  107. 01C3: remove_references_to_car 7@ // Like turning a car into any random car
  108. 01C2: remove_references_to_actor 9@ // Like turning an actor into a random pedestrian
  109. 0108: destroy_object 23@
  110. 0108: destroy_object 24@
  111. 0108: destroy_object 25@
  112. 0108: destroy_object 26@
  113. jump @scmpath_3

  114. :scmpath_sub_3
  115. if
  116. 8119: NOT car 7@ wrecked
  117. jf @scmpath_sub_109
  118. if
  119. 00DB: actor 9@ in_car 7@
  120. jf @scmpath_sub_99
  121. if
  122. 0039: 19@ == 1 // integer values
  123. jf @scmpath_sub_10
  124. 0006: 19@ = 0 // integer values
  125. jump @scmpath_sub_100

  126. :scmpath_sub_10
  127. if
  128. 0039: 15@ == 0 // integer values
  129. jf @scmpath_sub_11
  130. if
  131. 01AF: car 7@ 0 ()near_point 11@ 12@ 13@ radius 5.2 5.2 5.0
  132. jf @scmpath_sub_11
  133. 0006: 15@ = 1 // integer values
  134. 05D6: clear_scmpath
  135. 0007: 11@ = -1181.78 // floating-point values
  136. 0007: 12@ = -331.30 // floating-point values
  137. 0007: 13@ = 13.76 // floating-point values
  138. 000A: 16@ += 0 // integer values
  139. 0007: 17@ = 100.0 // floating-point values
  140. 0007: 18@ = 20.0 // floating-point values
  141. 05D7: add_point_to_scmpath 11@ 12@ 13@
  142. jump @scmpath_sub_100

  143. :scmpath_sub_11
  144. if
  145. 0039: 15@ == 1 // integer values
  146. jf @scmpath_sub_12
  147. if
  148. 01AF: car 7@ 0 ()near_point 11@ 12@ 13@ radius 15.2 15.2 5.0
  149. jf @scmpath_sub_12
  150. 00AD: set_car 7@ max_speed_to 10.0
  151. 0006: 15@ = 2 // integer values
  152. 05D6: clear_scmpath
  153. 0007: 11@ = -1282.1 // floating-point values
  154. 0007: 12@ = -159.3 // floating-point values
  155. 0007: 13@ = 13.76 // floating-point values
  156. 000A: 16@ += 0 // integer values
  157. 0007: 17@ = 100.0 // floating-point values
  158. 0007: 18@ = 20.0 // floating-point values
  159. 05D7: add_point_to_scmpath 11@ 12@ 13@
  160. jump @scmpath_sub_100

  161. :scmpath_sub_12
  162. if
  163. 0039: 15@ == 2 // integer values
  164. jf @scmpath_sub_13
  165. if
  166. 01AF: car 7@ 0 ()near_point 11@ 12@ 13@ radius 15.2 15.2 5.0
  167. jf @scmpath_sub_13
  168. 00AD: set_car 7@ max_speed_to 25.0
  169. 0006: 15@ = 3 // integer values
  170. 05D6: clear_scmpath
  171. 0007: 11@ = -1498.78 // floating-point values
  172. 0007: 12@ = -138.30 // floating-point values
  173. 0007: 13@ = 13.76 // floating-point values
  174. 000A: 16@ += 0 // integer values
  175. 0007: 17@ = 100.0 // floating-point values
  176. 0007: 18@ = 20.0 // floating-point values
  177. 05D7: add_point_to_scmpath 11@ 12@ 13@
  178. jump @scmpath_sub_100

  179. :scmpath_sub_13
  180. if
  181. 0039: 15@ == 3 // integer values
  182. jf @scmpath_sub_14
  183. if
  184. 01AF: car 7@ 0 ()near_point 11@ 12@ 13@ radius 8.2 8.2 5.0
  185. jf @scmpath_sub_14
  186. 00AD: set_car 7@ max_speed_to 25.0
  187. 0006: 15@ = 4 // integer values
  188. 05D6: clear_scmpath
  189. 0007: 11@ = -1576.78 // floating-point values
  190. 0007: 12@ = -202.30 // floating-point values
  191. 0007: 13@ = 13.76 // floating-point values
  192. 000A: 16@ += 0 // integer values
  193. 0007: 17@ = 100.0 // floating-point values
  194. 0007: 18@ = 20.0 // floating-point values
  195. 05D7: add_point_to_scmpath 11@ 12@ 13@
  196. jump @scmpath_sub_100

  197. :scmpath_sub_14
  198. if
  199. 0039: 15@ == 4 // integer values
  200. jf @scmpath_sub_15
  201. if
  202. 01AF: car 7@ 0 ()near_point 11@ 12@ 13@ radius 5.2 5.2 5.0
  203. jf @scmpath_sub_15
  204. 0006: 15@ = 5 // integer values
  205. 05D6: clear_scmpath
  206. 0007: 11@ = -1694.78 // floating-point values
  207. 0007: 12@ = -352.30 // floating-point values
  208. 0007: 13@ = 13.9 // floating-point values
  209. 000A: 16@ += 0 // integer values
  210. 0007: 17@ = 100.0 // floating-point values
  211. 0007: 18@ = 20.0 // floating-point values
  212. 05D7: add_point_to_scmpath 11@ 12@ 13@
  213. jump @scmpath_sub_100

  214. :scmpath_sub_15
  215. if
  216. 0039: 15@ == 5 // integer values
  217. jf @scmpath_sub_16
  218. if
  219. 01AF: car 7@ 0 ()near_point 11@ 12@ 13@ radius 15.2 15.2 5.0
  220. jf @scmpath_sub_16
  221. 00AD: set_car 7@ max_speed_to 10.0
  222. 0006: 15@ = 6 // integer values
  223. 05D6: clear_scmpath
  224. 0007: 11@ = -1691.78 // floating-point values
  225. 0007: 12@ = -409.30 // floating-point values
  226. 0007: 13@ = 13.9 // floating-point values
  227. 000A: 16@ += 0 // integer values
  228. 0007: 17@ = 40.0 // floating-point values
  229. 0007: 18@ = 10.0 // floating-point values
  230. 05D7: add_point_to_scmpath 11@ 12@ 13@
  231. 00AE: unknown_set_car 7@ to_ignore_traffic_lights 2
  232. jump @scmpath_sub_100

  233. :scmpath_sub_16
  234. if
  235. 0039: 15@ == 6 // integer values
  236. jf @scmpath_sub_17
  237. if
  238. 01AF: car 7@ 0 ()near_point 11@ 12@ 13@ radius 8.2 8.2 5.0
  239. jf @scmpath_sub_17
  240. 00AD: set_car 7@ max_speed_to 0.0
  241. 0006: 15@ = 7 // integer values
  242. 05D6: clear_scmpath
  243. 0007: 11@ = -1519.78 // floating-point values
  244. 0007: 12@ = -580.30 // floating-point values
  245. 0007: 13@ = 13.76 // floating-point values
  246. 000A: 16@ += 0 // integer values
  247. 0007: 17@ = 100.0 // floating-point values
  248. 0007: 18@ = 0.0 // floating-point values
  249. 05D7: add_point_to_scmpath 11@ 12@ 13@
  250. 00AE: unknown_set_car 7@ to_ignore_traffic_lights 2
  251. jump @scmpath_sub_100

  252. :scmpath_sub_17
  253. if
  254. 0039: 15@ == 7 // integer values
  255. jf @scmpath_sub_18
  256. if
  257. 01AF: car 7@ 0 ()near_point 11@ 12@ 13@ radius 15.2 15.2 5.0
  258. jf @scmpath_sub_18
  259. 00AD: set_car 7@ max_speed_to 5.0
  260. 01EB: set_car_density_to 0.0
  261. 0006: 15@ = 8 // integer values
  262. 05D6: clear_scmpath
  263. 0007: 11@ = -1299.78 // floating-point values
  264. 0007: 12@ = -565.30 // floating-point values
  265. 0007: 13@ = 13.76 // floating-point values
  266. 000A: 16@ += 0 // integer values
  267. 0007: 17@ = 100.0 // floating-point values
  268. 0007: 18@ = 20.0 // floating-point values
  269. 05D7: add_point_to_scmpath 11@ 12@ 13@
  270. jump @scmpath_sub_100

  271. :scmpath_sub_18
  272. if
  273. 0039: 15@ == 8 // integer values
  274. jf @scmpath_sub_109
  275. if
  276. 01AF: car 7@ 0 ()near_point 11@ 12@ 13@ radius 25.2 25.2 5.0
  277. jf @scmpath_sub_109
  278. 00AD: set_car 7@ max_speed_to 0.0
  279. 0006: 15@ = 1 // integer values
  280. 000A: 16@ += 1 // integer values
  281. 05D6: clear_scmpath
  282. 0007: 11@ = -1181.78 // floating-point values
  283. 0007: 12@ = -331.30 // floating-point values
  284. 0007: 13@ = 13.76 // floating-point values
  285. 0007: 17@ = 100.0 // floating-point values
  286. 0007: 18@ = 20.0 // floating-point values
  287. 05D7: add_point_to_scmpath 11@ 12@ 13@

  288. if
  289. 0039: 16@ == 2 // integer values
  290. jf @scmpath_sub_100
  291. 00BC: text_highpriority 'BJ_LOSE' 5000 ms 1
  292. jump @scmpath_sub_100

  293. :scmpath_sub_99
  294. if
  295. 0039: 19@ == 0 // integer values
  296. jf @scmpath_sub_109
  297. 00AD: set_car 7@ max_speed_to 0.0
  298. 05CB: actor_goto_and_enter_car 9@ 7@ 5000
  299. 0006: 19@ = 1 // integer values
  300. jump @scmpath_sub_109

  301. :scmpath_sub_100
  302. 07E7: AS_assign_scmpath_to_actor 9@ in_car 7@ speed 17@ flags 2 0 3
  303. 03F0: text_draw_toggle 0
  304. 0006: 33@ = 0 // integer values
  305. jump @scmpath_sub_109

  306. :scmpath_sub_102
  307. if
  308. 01F3: car 7@ airborne
  309. jf @scmpath_sub_103
  310. 0007: 18@ = 0.0 // floating-point values
  311. 04BA: set_car 7@ speed_instantly 18@
  312. 07E7: AS_assign_scmpath_to_actor 9@ in_car 7@ speed 17@ flags 2 0 3
  313. jump @scmpath_sub_103

  314. :scmpath_sub_103
  315. if
  316. 01AF: car 7@ 0 ()near_point 11@ 12@ 13@ radius 30.2 30.2 5.0
  317. jf @scmpath_sub_104
  318. jump @scmpath_sub_105

  319. :scmpath_sub_104
  320. 02E3: 20@ = car 7@ speed
  321. if
  322. 81F3: NOT car 7@ airborne
  323. jf @scmpath_sub_106
  324. if and
  325. 0021: 20@ > 30.0 // floating-point values
  326. 0019: 33@ > 700 // integer values
  327. jf @scmpath_sub_105
  328. 04BA: set_car 7@ speed_instantly 50.0

  329. :scmpath_sub_105
  330. if
  331. 0019: 33@ > 2000 // integer values
  332. jf @scmpath_sub_109

  333. :scmpath_sub_106
  334. 0006: 33@ = 0 // integer values

  335. :scmpath_sub_109
  336. 0051: return
复制代码

传奇 Legend

虚拟世界,属于你的世界

Rank: 16

UID
4
宝石
154 粒
金币
5594 枚
节操
458 斤
灵石
0 块
精力
509 ℃
QQ
 楼主| 发表于 2012-4-7 10:39:44 | 显示全部楼层
本帖最后由 kwanz 于 2012-4-13 19:23 编辑

用Carrec Path指定车辆行驶路径

用Seemann的carrec.cs记录路径 http://cleo.sannybuilder.com/
详见 http://www.gtaforums.com/index.php?showtopic=297295

然后它会在GTASA\data\paths中建立path

把它改名为carrec899.rrr并导入carrec.img
然后就可以用下面的程序指定路径
  1. {$CLEO .cs}
  2. :DrvCarrec_1
  3. 03A4: name_thread 'DRVCARC'

  4. :DRVCARC_11
  5. 0001: wait 0 ms
  6. 00D6: if
  7. 0256: player $PLAYER_CHAR defined
  8. 004D: jump_if_false @DRVCARC_11
  9. 00D6: if and
  10. 0AB0: key_pressed 57
  11. 00DF: actor $PLAYER_ACTOR driving
  12. 004D: jump_if_false @DRVCARC_11
  13. 03C0: 0@ = actor $PLAYER_ACTOR car
  14. 0A30: repair_car 0@
  15. 0224: set_car 0@ health_to 1000
  16. 0006: 8@ = 899
  17. 07C0: load_path 8@

  18. :DRVCARC_85
  19. 0001: wait 0 ms
  20. 00D6: if
  21. 07C1: path 8@ available
  22. 004D: jump_if_false @DRVCARC_85
  23. 00D6: if
  24. 8119: not car 0@ wrecked
  25. 004D: jump_if_false @DRVCARC_218
  26. 0001: wait 500 ms
  27. 05EB: assign_car 0@ to_path 8@

  28. :DRVCARC_148
  29. 0001: wait 0 ms
  30. 00D6: if
  31. 0256: player $PLAYER_CHAR defined
  32. 004D: jump_if_false @DRVCARC_218
  33. 00D6: if or
  34. 0AB0: key_pressed 48
  35. 0119: car 0@ wrecked
  36. 004D: jump_if_false @DRVCARC_195
  37. 0002: jump @DRVCARC_218

  38. :DRVCARC_195
  39. 00D6: if
  40. 00DF: actor $PLAYER_ACTOR driving
  41. 004D: jump_if_false @DRVCARC_218
  42. 0002: jump @DRVCARC_148

  43. :DRVCARC_218
  44. 0001: wait 0 ms
  45. 00D6: if
  46. 0256: player $PLAYER_CHAR defined
  47. 004D: jump_if_false @DRVCARC_218
  48. 0373: set_camera_directly_behind_player
  49. 02EB: restore_camera_with_jumpcut
  50. 05EC: release_car 0@ from_path
  51. 0873: release_path 8@
  52. 01C3: remove_references_to_car 0@ // 设为随机车辆
  53. 0001: wait 1000 ms
  54. 0002: jump @DRVCARC_11
复制代码

传奇 Legend

虚拟世界,属于你的世界

Rank: 16

UID
4
宝石
154 粒
金币
5594 枚
节操
458 斤
灵石
0 块
精力
509 ℃
QQ
 楼主| 发表于 2012-4-7 10:40:01 | 显示全部楼层
本帖最后由 kwanz 于 2012-4-13 19:24 编辑

在Carrec path中使用镜头

只有015F和0159合用可以实现镜头自动跟踪移动物体
但在SA里我们在SA中已有足够多的代码来实现各种效果。
我们可以把车辆的位置读入变量,然后把变量赋给标准的镜头定位函数来调视角
使用parked_car_generator的车辆位置标志不能用于车辆相关的opcode,因为那不是一辆车,只是一个生成器,但我们可以直接把坐标用于镜头定位函数

下面的代码会刷出一辆NRG500,按8让镜头跟随carrec899.rrr中定义的carrec路径
镜头指向固定的XYZ坐标点
(我在SF机场摆了一台Monster然后开摩托绕着它转,并在代码中直接利用了parked_car Monster的坐标)
  1. //-init_parked_car_generator #MONSTER color -1 -1 1 alarm 0 door_lock 0 0 10000 at -1355.7821 -71.4736 14.1462 angle 86.0
  2. 0160: set_camera_point_at -1355.7821 -71.4736 14.1462 mode 2
复制代码
  1. {$CLEO .cs}
  2. :CameraDrive_1
  3. 03A4: name_thread 'DRVCARC'

  4. :CameraDrive_11
  5. 0001: wait 0 ms
  6. 00D6: if
  7. 0256: player $PLAYER_CHAR defined
  8. 004D: jump_if_false @CameraDrive_11
  9. if
  10. 0AB0: key_pressed 56//----------- key 8
  11. 004D: jump_if_false @CameraDrive_11
  12. 0247: request_model #NRG500

  13. :CameraDrive_13
  14. 0001: wait 0 ms
  15. 00D6: if 0
  16. 0248: model #NRG500 available
  17. 004D: jump_if_false @CameraDrive_13

  18. 00A5: 0@ = create_car #NRG500 at 0.0 0.0 100.0
  19. 0175: set_car 0@ z_angle_to 0.0
  20. 02AC: set_car 0@ immunities BP 1 FP 1 EP 1 CP 1 MP 1
  21. 0249: release_model #NRG500
  22. 0006: 8@ = 899
  23. 07C0: load_path 8@

  24. :CameraDrive_17
  25. 0001: wait 0 ms
  26. 00D6: if
  27. 07C1: path 8@ available
  28. 004D: jump_if_false @CameraDrive_17
  29. 00D6: if
  30. 8119: not car 0@ wrecked
  31. 004D: jump_if_false @CameraDrive_50
  32. 0001: wait 500 ms
  33. 05EB: assign_car 0@ to_path 8@

  34. :CameraDrive_21
  35. 0001: wait 0 ms
  36. 00D6: if
  37. 0256: player $PLAYER_CHAR defined
  38. 004D: jump_if_false @CameraDrive_50
  39. 00D6: if or
  40. 00E1: key_pressed 0 15//Enter/Exit
  41. 0119: car 0@ wrecked
  42. 004D: jump_if_false @CameraDrive_25
  43. 0002: jump @CameraDrive_50

  44. :CameraDrive_25
  45. 0407: create_coordinate 11@ 12@ 13@ from_car 0@ with_offset 0.0 0.0 1.0
  46. 015F: set_camera_position 11@ 12@ 13@ rotation 0.0 0.0 0.0
  47. //init_parked_car_generator #MONSTER at -1355.7821 -71.4736 14.1462
  48. 0160: set_camera_point_at -1355.7821 -71.4736 14.1462 mode 2
  49. 0002: jump @CameraDrive_21

  50. :CameraDrive_50
  51. 0001: wait 0 ms
  52. 00D6: if
  53. 0256: player $PLAYER_CHAR defined
  54. 004D: jump_if_false @CameraDrive_50
  55. 0373: set_camera_directly_behind_player
  56. 02EB: restore_camera_with_jumpcut
  57. 05EC: release_car 0@ from_path
  58. 0873: release_path 8@
  59. 01C3: remove_references_to_car 0@ // Like turning a car into any random car
  60. 0001: wait 1000 ms
  61. 0002: jump @CameraDrive_11
复制代码

从移动的车辆上查看移动的目标会稍微复杂一点,因为我们需要编程跟踪移动的目标,同时实现镜头在carrec path上的移动。
我把车辆行驶程序和镜头移动程序整在一起
下面的代码在Grove St刷出Infernus,车上有两个小弟,当玩家进圈时,程序再刷出一辆NRG500,行驶路径为carrect899.rrr的carrec path,镜头跟随并指向行驶的Infernus。
  1. {$CLEO .cs}
  2. :CarrecCamCarDrive_1
  3. 03A4: name_thread 'CRCMCDR'

  4. :CarrecCamCarDrive_2
  5. 0001: wait 0 ms
  6. if
  7. 0256: player $PLAYER_CHAR defined
  8. 004D: jump_if_false @CarrecCamCarDrive_2
  9. if
  10. 00FE: actor $PLAYER_ACTOR 1 (in-sphere)near_point 2491.5 -1667.5 13.35 radius 1.0 1.0 1.0
  11. 004D: jump_if_false @CarrecCamCarDrive_2

  12. 0247: request_model #INFERNUS
  13. 0247: request_model #fam1
  14. 0247: request_model #fam2
  15. 0247: request_model #NRG500

  16. :CarrecCamCarDrive_3
  17. 0001: wait 0 ms
  18. if and
  19. 0248: model #INFERNUS available
  20. 0248: model #fam1 available
  21. 0248: model #fam2 available
  22. 0248: model #NRG500 available
  23. 004D: jump_if_false @CarrecCamCarDrive_3

  24. 00A5: 1@ = create_car #INFERNUS at 2487.5 -1660.5 13.35
  25. 0175: set_car 1@ z_angle_to 90.0
  26. 0129: 2@ = create_actor 8 #fam1 in_car 1@ driverseat
  27. 01C8: 3@ = create_actor 8 #fam2 in_car 1@ passenger_seat 0
  28. 0186: 4@ = create_marker_above_car 1@
  29. 07E0: set_marker 4@ type_to 1

  30. 00A5: 0@ = create_car #NRG500 at 0.0 0.0 100.0
  31. 0175: set_car 0@ z_angle_to 0.0
  32. 02AC: set_car 0@ immunities BP 1 FP 1 EP 1 CP 1 MP 1

  33. 0006: 8@ = 899
  34. 07C0: load_path 8@

  35. :CarrecCamCarDrive_5
  36. 0001: wait 0 ms
  37. 00D6: if
  38. 07C1: path 8@ available
  39. 004D: jump_if_false @CarrecCamCarDrive_5
  40. 00D6: if
  41. 8119: not car 0@ wrecked
  42. 004D: jump_if_false @CarrecCamCarDrive_50
  43. 0001: wait 500 ms
  44. 05EB: assign_car 0@ to_path 8@

  45. //////////////////// drive-to块开始

  46. 0615: define_action_sequences 5@
  47. 05D1: AS_actor -1 drive_car 1@ to 2353.1528 -1658.6493 13.384 speed 20.0 0 0 5
  48. 05D1: AS_actor -1 drive_car 1@ to 2431.7739 -1674.7444 13.6643 speed 20.0 0 0 5
  49. 05D1: AS_actor -1 drive_car 1@ to 2431.5864 -1628.0818 13.698 speed 20.0 2 0 5
  50. 0616: define_action_sequences_end 5@
  51. 0618: assign_actor 2@ to_action_sequences 5@
  52. 061B: remove_references_to_AS_pack 5@

  53. //////////////////// drive-to块结束

  54. :CarrecCamCarDrive_13
  55. 0001: wait 0 ms
  56. if
  57. 0256: player $PLAYER_CHAR defined
  58. 004D: jump_if_false @CarrecCamCarDrive_13

  59. //////////////////// camera块 必须循环
  60. 0407: create_coordinate 11@ 12@ 13@ from_car 0@ with_offset 0.0 0.0 1.5
  61. 015F: set_camera_position 11@ 12@ 13@ rotation 0.0 0.0 0.0
  62. 0407: create_coordinate 14@ 15@ 16@ from_car 1@ with_offset 0.0 0.0 1.0
  63. 0160: set_camera_point_at 14@ 15@ 16@ mode 2
  64. //////////////////// camera块 必须循环

  65. if or
  66. 00E1: key_pressed 0 15//Enter/Exit
  67. 0119: car 0@ wrecked
  68. 0119: car 1@ wrecked
  69. 01F4: car 1@ flipped
  70. 8202: not actor $PLAYER_ACTOR near_car 1@ radius 500.0 500.0 flag 0
  71. 004D: jump_if_false @CarrecCamCarDrive_13

  72. :CarrecCamCarDrive_50
  73. 0001: wait 0 ms
  74. 00D6: if
  75. 0256: player $PLAYER_CHAR defined
  76. 004D: jump_if_false @CarrecCamCarDrive_50
  77. 0373: set_camera_directly_behind_player
  78. 02EB: restore_camera_with_jumpcut
  79. 05EC: release_car 0@ from_path
  80. 0873: release_path 8@
  81. 01C3: remove_references_to_car 0@ // 设为随机车辆
  82. 01C3: remove_references_to_car 1@ // 设为随机车辆
  83. 01C2: remove_references_to_actor 2@ // 设为随机行人
  84. 01C2: remove_references_to_actor 3@ // 设为随机行人
  85. 0164: disable_marker 4@
  86. 0249: release_model #INFERNUS
  87. 0249: release_model #fam1
  88. 0249: release_model #fam2
  89. 0249: release_model #NRG500
  90. 0001: wait 1000 ms
  91. 0002: jump @CarrecCamCarDrive_2
复制代码

传奇 Legend

虚拟世界,属于你的世界

Rank: 16

UID
4
宝石
154 粒
金币
5594 枚
节操
458 斤
灵石
0 块
精力
509 ℃
QQ
 楼主| 发表于 2012-4-7 10:55:24 | 显示全部楼层
本帖最后由 kwanz 于 2012-4-13 19:26 编辑

----------------------------------------
显示粒子特效的特殊opcode
----------------------------------------
有几个特殊的opcode支持直接调用显示预定义的粒子特效,不需要特别的参数。特效只能显示很短的一段时间,要看到效果必须用到循环。

1.
08EB: create_sparks_at 1@ 2@ 3@ velocity_direction 0.0 5.0 20.0 density 100
火花(spark)是仅在effects.fxp中有效的附加fxs数据(sub-fxs-data)
我猜08EB的火花是exe中直接编程实现的,没有用到材质
08EB带有7个参数
参数1,2,3=x,y,z 浮点型,生成火花的绝对坐标
参数4,5,6=x,y,z浮点型,火花溅射方向的相对坐标
参数7=密度,整型
增加方向坐标可以增大火花的范围

下面的代码能生成最大密度的火花
按退格键在玩家面前产生火花
  1. {$CLEO .cs}
  2. :Particle_Sparks
  3. 03A4: name_thread 'PRTSPRK'

  4. :PRTSPRK_01
  5. 0001: wait 0 ms
  6. if
  7. 0256: player $PLAYER_CHAR defined
  8. 004D: jump_if_false @PRTSPRK_01
  9. if
  10. 0AB0: key_pressed 8//-----------------------按退格
  11. 004D: jump_if_false @PRTSPRK_01
  12. 04C4: create_coordinate 1@ 2@ 3@ from_actor $PLAYER_ACTOR offset 0.0 3.5 0.3
  13. 08EB: create_sparks_at 1@ 2@ 3@ velocity_direction 0.0 5.0 20.0 density 100
  14. jump @PRTSPRK_01
复制代码
2.
058A: create_gun_flash_from 1@ 2@ 3@ to 11@ 12@ 13@
058A显示开枪的弹道效果,需要生成位置和方向的绝对坐标
058A带6个参数
参数1,2,3=x,y,z浮点型,生成位置的绝对坐标
参数4,5,6=x,y,z浮点型,方向的绝对坐标

下面的代码显示出和玩家朝向相同的弹道效果
按退格键在玩家面前生成弹道
  1. {$CLEO .cs}
  2. :Particle_GunFlash
  3. 03A4: name_thread 'PRTGFLS'

  4. :PRTGFLS_01
  5. 0001: wait 0 ms
  6. if
  7. 0256: player $PLAYER_CHAR defined
  8. 004D: jump_if_false @PRTGFLS_01
  9. if
  10. 0AB0: key_pressed 8//-----------------------按退格
  11. 004D: jump_if_false @PRTGFLS_01
  12. 04C4: create_coordinate 1@ 2@ 3@ from_actor $PLAYER_ACTOR offset 0.0 1.5 0.3
  13. 04C4: create_coordinate 11@ 12@ 13@ from_actor $PLAYER_ACTOR offset 0.0 10.5 0.3
  14. 058A: create_gun_flash_from 1@ 2@ 3@ to 11@ 12@ 13@
  15. jump @PRTGFLS_01
复制代码
3.
09B8: create_blood_gush_at 1@ 2@ 3@ with_offset 0.0 3.0 0.0 density 80 on_actor $PLAYER_ACTOR
09B8显示prt_blood.fxs的掉血效果,但跟PLAYMODE: 2参数没有关系
它会显示为红色,但如果直接调opcode用prt_blood效果的话,是无色的
09B8带8个参数
参数1,2,3=x,y,z浮点型,生成位置的绝对坐标
参数4,5,6=x,y,z浮点型,血液溅射方向的相对坐标;但这个偏移量取的是单位圆上的绝对方向
参数7=密度
参数8=启用效果的人物对象变量

按退格键,玩家身上开始掉血
  1. {$CLEO .cs}
  2. :Particle_Blood_Gush
  3. 03A4: name_thread 'PTBLOOD'

  4. :PTBLOOD_01
  5. 0001: wait 0 ms
  6. if
  7. 0256: player $PLAYER_CHAR defined
  8. 004D: jump_if_false @PTBLOOD_01
  9. if
  10. 0AB0: key_pressed 8//-----------------------press Backspace
  11. 004D: jump_if_false @PTBLOOD_01
  12. 04C4: create_coordinate 1@ 2@ 3@ from_actor $PLAYER_ACTOR offset 0.2 0.0 0.5
  13. 09B8: create_blood_gush_at 1@ 2@ 3@ with_offset 0.0 3.0 3.0 density 80 on_actor $PLAYER_ACTOR
  14. jump @PTBLOOD_01
复制代码
4.
04D5: create_corona_at 1@ 2@ 3@ radius 1.5 type 2 flare 1 RGB 247 206 12
04D5用GTASA\models\particle.txd中存储的材质,显示出一个半透明的发光源物体
opcode 04D5带9个参数
参数1,2,3=x,y,z浮点型,生成位置的绝对坐标
参数4=大小,浮点型
参数5=类型,整型,更换材质
参数6=显示发光效果,布尔型0/1
参数7,8,9=整型,RGB颜色值

按退格键在玩家面前显示4种不同的光圈
  1. {$CLEO .cs}
  2. :Corona_1
  3. 03A4: name_thread 'CORA'

  4. :Corona_3
  5. 0001: wait 0 ms
  6. if
  7. 0256: player $PLAYER_CHAR defined
  8. 004D: jump_if_false @Corona_3
  9. 00D6: if
  10. 0AB0: key_pressed 8//-----------------------按退格
  11. 004D: jump_if_false @Corona_3
  12. 04C4: create_coordinate 1@ 2@ 3@ from_actor $PLAYER_ACTOR offset -5.0 7.0 2.2
  13. 04D5: create_corona_at 1@ 2@ 3@ radius 1.5 type 1 flare 1 RGB 150 0 255
  14. 04C4: create_coordinate 4@ 5@ 6@ from_actor $PLAYER_ACTOR offset -2.0 7.0 3.2
  15. 04D5: create_corona_at 4@ 5@ 6@ radius 1.5 type 2 flare 1 RGB 247 206 12
  16. 04C4: create_coordinate 7@ 8@ 9@ from_actor $PLAYER_ACTOR offset 3.0 7.0 5.2
  17. 04D5: create_corona_at 7@ 8@ 9@ radius 1.5 type 3 flare 0 RGB 255 7 7
  18. 04C4: create_coordinate 10@ 11@ 12@ from_actor $PLAYER_ACTOR offset 6.0 7.0 3.2
  19. 04D5: create_corona_at 10@ 11@ 12@ radius 1.5 type 4 flare 0 RGB 3 3 255
  20. 0002: jump @Corona_3
复制代码
5.
016F: create_particle 1 rotation_factor 0.0 size 180.0 intensity 250 flags 0 0 0 at 1@ 2@ 3@
opcode 016F: 在地面上显示阴影
opcode 016F: 带10个参数
参数1 =阴影强度 1 = 深阴影 / 2 = 浅阴影
参数2 =旋转因子(未知),浮点型
参数 3 =大小,浮点型
参数4 = 强度, 浮点型
参数5,6,7 =标志位变量 (未测试)
参数 8,9,10 = x,y,z浮点型, 生成位置的绝对坐标

按退格键在地面上显示阴影
  1. {$CLEO .cs}
  2. :Particle_Shadow
  3. 03A4: name_thread 'PTSHAD'

  4. :PTSHAD_01
  5. 0001: wait 0 ms
  6. if
  7. 0256: player $PLAYER_CHAR defined
  8. 004D: jump_if_false @PTSHAD_01
  9. if
  10. 0AB0: key_pressed 8//-----------------------按退格
  11. 004D: jump_if_false @PTSHAD_01
  12. 04C4: create_coordinate 1@ 2@ 3@ from_actor $PLAYER_ACTOR offset 0.0 0.0 0.0
  13. 016F: create_particle 1 rotation_factor 0.0 size 180.0 intensity 250 flags 0 0 0 at 1@ 2@ 3@
  14. jump @PTSHAD_01
复制代码
6.
095C: create_smoke_at 1@ 2@ 3@ velocity 0.0 1.0 7.0 RGBA 0.0 0.0 0.0 1.0 size 0.1 last_factor 0.02//black
Opcode 095C 显示prt_smoke_huge.fxs中的烟雾效果,但与PLAYMODE: 2参数无关

095C带有12个参数,全为浮点型
参数1,2,3 = x,y,z 生成位置的绝对坐标
参数4,5,6 = x,y,z 烟雾蔓延方向的相对坐标
参数7,8,9,10 = 颜色值,R-G-B-不透明度
参数11 = 初始大小
参数12 =结束大小

下面的代码显示8股烟雾,不同颜色、大小、移动速度(较大的方向坐标能让烟雾移动更快)
按退格键产生烟雾
opcode 04C4: 获得玩家前3.5个单位的坐标
opcode 095C: 生成烟雾
  1. {$CLEO .cs}
  2. :Particle_Smoke
  3. 03A4: name_thread 'PRTSMOK'

  4. :PRTSMOKE_01
  5. 0001: wait 0 ms
  6. if
  7. 0256: player $PLAYER_CHAR defined
  8. 004D: jump_if_false @PRTSMOKE_01
  9. if
  10. 0AB0: key_pressed 8//-----------------------按退格
  11. 004D: jump_if_false @PRTSMOKE_01
  12. 04C4: create_coordinate 1@ 2@ 3@ from_actor $PLAYER_ACTOR offset 0.0 3.5 0.3
  13. 33@ = 0

  14. :PRTSMOKE_02_black
  15. wait 0
  16. if
  17. 3000 > 33@
  18. jf @PRTSMOKE_03_blue
  19. 095C: create_smoke_at 1@ 2@ 3@ velocity 0.0 1.0 7.0 RGBA 0.0 0.0 0.0 1.0 size 0.1 last_factor 0.02//black
  20. jump @PRTSMOKE_02_black

  21. :PRTSMOKE_03_blue
  22. wait 0
  23. if
  24. 6000 > 33@
  25. jf @PRTSMOKE_04_green
  26. 095C: create_smoke_at 1@ 2@ 3@ velocity 0.0 0.0 50.0 RGBA 0.0 0.0 1.0 1.0 size 0.5 last_factor 0.02//blue
  27. jump @PRTSMOKE_03_blue

  28. :PRTSMOKE_04_green
  29. wait 0
  30. if
  31. 9000 > 33@
  32. jf @PRTSMOKE_05_red
  33. 095C: create_smoke_at 1@ 2@ 3@ velocity 0.0 0.0 10.0 RGBA 0.0 1.0 0.0 1.0 size 1.0 last_factor 0.02//green
  34. jump @PRTSMOKE_04_green

  35. :PRTSMOKE_05_red
  36. wait 0
  37. if
  38. 12000 > 33@
  39. jf @PRTSMOKE_06_yellow
  40. 095C: create_smoke_at 1@ 2@ 3@ velocity 0.0 0.0 1.0 RGBA 1.0 0.0 0.0 1.0 size 5.5 last_factor 0.02//red
  41. jump @PRTSMOKE_05_red

  42. :PRTSMOKE_06_yellow
  43. wait 0
  44. if
  45. 15000 > 33@
  46. jf @PRTSMOKE_07_turquoise
  47. 095C: create_smoke_at 1@ 2@ 3@ velocity 0.0 0.0 20.0 RGBA 1.0 1.0 0.0 1.0 size 9.5 last_factor 0.02//yellow
  48. jump @PRTSMOKE_06_yellow

  49. :PRTSMOKE_07_turquoise
  50. wait 0
  51. if
  52. 18000 > 33@
  53. jf @PRTSMOKE_08_pink
  54. 095C: create_smoke_at 1@ 2@ 3@ velocity 0.0 0.0 20.0 RGBA 0.0 1.0 1.0 1.0 size 0.5 last_factor 0.02//turquoise
  55. jump @PRTSMOKE_07_turquoise

  56. :PRTSMOKE_08_pink
  57. wait 0
  58. if
  59. 21000 > 33@
  60. jf @PRTSMOKE_09_white
  61. 095C: create_smoke_at 1@ 2@ 3@ velocity 0.0 0.0 20.0 RGBA 1.0 0.0 1.0 1.0 size 0.5 last_factor 0.02//pink
  62. jump @PRTSMOKE_08_pink

  63. :PRTSMOKE_09_white
  64. wait 0
  65. if
  66. 24000 > 33@
  67. jf @PRTSMOKE_01
  68. 095C: create_smoke_at 1@ 2@ 3@ velocity 0.0 0.0 20.0 RGBA 1.0 1.0 1.0 1.0 size 0.5 last_factor 0.02//white
  69. jump @PRTSMOKE_09_white
复制代码
相关主题:灯光和阴影

传奇 Legend

虚拟世界,属于你的世界

Rank: 16

UID
4
宝石
154 粒
金币
5594 枚
节操
458 斤
灵石
0 块
精力
509 ℃
QQ
 楼主| 发表于 2012-4-7 10:55:55 | 显示全部楼层
本帖最后由 kwanz 于 2012-4-12 15:30 编辑

灯光的创建

GTASA中,灯光应符合三条事实:
1. 存在光源
2. 它带有光圈、光柱或类似的材质效果
3. 它能照亮环境

据我所知,满足这三条事实的灯光包括:
-车头灯:可以通过设定模型编辑器中的车灯对象来修改
-警灯:同上,但仅用于警车和其他紧急车辆
-火焰:通过创建火焰来实现,但使用粒子效果创建火焰并不会照亮环境
-爆炸:通过创建爆炸来实现,但使用粒子效果创建爆炸并不会照亮环境
-某些街灯
-交通灯

以上的事实3,照亮环境,是灯光效果最吸引人之处
只要试一下截个车辆截图你就会发现,显示效果取决于车辆的朝向和镜头的倾角。别的车的车灯会照亮你的车子,街灯和交通灯亦然。显示效果就像是你提着一盏灯站在后院里,同时受到路上的街车影响一样。

若要用地图修改的方式编辑灯光,我所知有两种方法
用MaxScript导出SA中的灯光和粒子效果
这些灯光对人物也有效,然而在我的测试中并不满足事实3,即照亮环境。
用3ds max设置带颜色的模型预照明 (prelighting)
这种方法可以充分地照亮模型,但是环境照明效果有限。

关于在脚本中调effects.fxp的效果,详情可参阅教程CLEO Script Tutorial>>Particle Effects
经测试这样的灯光都不满足事实3

09E5: create_flash_light 有照亮除地面外的环境的效果,但是它不具备事实1和2的性质,无光源,无光柱

以下代码演示了按9键照亮人物和环境的效果
  1. {$CLEO .cs}
  2. :Flash_Light_Illumination
  3. thread 'FLHILLU'

  4. :FLHILLU_11
  5. wait 0
  6. if
  7. 0AB0: key_pressed 57// key 9
  8. jf @FLHILLU_11

  9. :FLHILLU_46
  10. wait 0
  11. if
  12. Player.Defined($PLAYER_CHAR)
  13. jf @FLHILLU_46
  14. if
  15. 0AB0: key_pressed 57// key 9
  16. jf @FLHILLU_141
  17. 04C4: store_coords_to 1@ 2@ 3@ from_actor $PLAYER_ACTOR with_offset 0.0 0.0 1.0
  18. 09E5: create_flash_light_at 1@ 2@ 3@ RGB_mask 255 255 255 radius 200.0
  19. jump @FLHILLU_46

  20. :FLHILLU_141
  21. wait 0
  22. if
  23. Player.Defined($PLAYER_CHAR)
  24. jf @FLHILLU_141
  25. 04C4: store_coords_to 1@ 2@ 3@ from_actor $PLAYER_ACTOR with_offset 0.0 0.0 1.0
  26. 09E5: create_flash_light_at 1@ 2@ 3@ RGB_mask 255 255 255 radius 200.0
  27. if
  28. 0AB0: key_pressed 57// key 9
  29. jf @FLHILLU_141

  30. :FLHILLU_229
  31. wait 0
  32. if
  33. 0AB0: key_pressed 57// key 9
  34. jf @FLHILLU_11
  35. jump @FLHILLU_229
复制代码

Opcode create_searchlight会照亮地面并显示白色的光柱
以下代码能在8键按下时在玩家上方创建探照灯光
  1. {$CLEO .cs}
  2. :WhiteSearchLightLamp
  3. thread 'WSLAMP'

  4. :WhitSrchLght_11
  5. wait 0
  6. if
  7. 0256: player $PLAYER_CHAR defined
  8. jf @WhitSrchLght_11
  9. if
  10. 0AB0: key_pressed 56// 8 key
  11. jf @WhitSrchLght_11
  12. 04C4: store_coords_to 1@ 2@ 3@ from_actor $PLAYER_ACTOR with_offset 0.0 0.0 70.0
  13. 04C4: store_coords_to 4@ 5@ 6@ from_actor $PLAYER_ACTOR with_offset 0.0 0.0 -0.5
  14. 06B1: 10@ = create_searchlight_at 1@ 2@ 3@ radius 5.0 target 4@ 5@ 6@ radius 71.0
  15. 06B6: set_searchlight 10@ follow_actor $PLAYER_ACTOR speed 1.2
  16. wait 1000

  17. :WhitSrchLght_46
  18. wait 0
  19. if
  20. 0256: player $PLAYER_CHAR defined
  21. jf @WhitSrchLght_47
  22. if
  23. 0AB0: key_pressed 56// 8 key
  24. jf @WhitSrchLght_46

  25. :WhitSrchLght_47
  26. 06B2: destroy_searchlight 10@
  27. wait 1000
  28. jump @WhitSrchLght_11
复制代码


________
阴影的创建
________
016F: create_particle 1 在地面上创建阴影
以下的代码当退格键按住时在玩家下方创建阴影

  1. {$CLEO .cs}
  2. :Particle_Shadow
  3. 03A4: name_thread 'PTSHAD'

  4. :PTSHAD_01
  5. 0001: wait 0 ms
  6. if
  7. 0256: player $PLAYER_CHAR defined
  8. 004D: jump_if_false @PTSHAD_01
  9. if
  10. 0AB0: key_pressed 8//-----------------------press Backspace
  11. 004D: jump_if_false @PTSHAD_01
  12. 04C4: create_coordinate 1@ 2@ 3@ from_actor $PLAYER_ACTOR offset 0.0 0.0 0.0
  13. 016F: create_particle 1 rotation_factor 0.0 size 180.0 intensity 250 flags 0 0 0 at 1@ 2@ 3@
  14. jump @PTSHAD_01
复制代码


___
引用 (hellya2011 @ Oct 3 2010, 01:03)
嗨zaz你能帮我么?我想把效果"sparycan"绑定到某武器上,按退格键时显示,应该怎么写?求助

opcode 0883: 把粒子特效绑定到人物骨骼
这可以让粒子出现在player_actors的手上:
  1. 066A: 0@ = attach_particle "spraycan" to_actor $PLAYER_ACTOR with_offset -0.301 -0.2 0.17 rotation -5.5 -3.5 0.0 flag 1
  2. 0883: attach_particle 0@ to_actor $PLAYER_ACTOR on_bone 26
  3. 064C: make_particle 0@ visible
复制代码

你需要对不同的武器设定不同的偏移量。

下面的代码把"spraycan"绑定到人物手上,使用手枪或微冲按右键或瞄准键时适用
但是只有在用消声手枪和MP5的时候效果最好
别的武器的偏移量是不同的
当你用鼠标控制视角,在车子或者摩托上做driveby时也是好用的
  1. {$CLEO .cs}
  2. :Spraycan_at_ActorHand
  3. 03A4: name_thread 'SPRAYWP'

  4. :SPRAYWP_01
  5. 0001: wait 0 ms
  6. if
  7. 0256: player $PLAYER_CHAR defined
  8. 004D: jump_if_false @SPRAYWP_01
  9. if or
  10. 00E1: key_pressed 0 17
  11. 00E1: key_pressed 0 6
  12. 0AB0: key_pressed 2// -- RMB
  13. 004D: jump_if_false @SPRAYWP_01
  14. if
  15. 8965: not actor $PLAYER_ACTOR swimming
  16. 004D: jump_if_false @SPRAYWP_01
  17. if or
  18. 02D8: actor $PLAYER_ACTOR current_weapon == 22
  19. 02D8: actor $PLAYER_ACTOR current_weapon == 23
  20. 02D8: actor $PLAYER_ACTOR current_weapon == 24
  21. 004D: jump_if_false @SPRAYWP_02
  22. 066A: 0@ = attach_particle "spraycan" to_actor $PLAYER_ACTOR with_offset -0.1 -0.22 0.13 rotation -1.5 -3.5 0.0 flag 1
  23. 0883: attach_particle 0@ to_actor $PLAYER_ACTOR mode 26
  24. 064C: make_particle 0@ visible
  25. 0002: jump @SPRAYWP_13

  26. :SPRAYWP_02
  27. if
  28. 02D8: actor $PLAYER_ACTOR current_weapon == 29
  29. 004D: jump_if_false @SPRAYWP_03
  30. 0002: jump @SPRAYWP_10

  31. :SPRAYWP_03
  32. if or
  33. 02D8: actor $PLAYER_ACTOR current_weapon == 32
  34. 02D8: actor $PLAYER_ACTOR current_weapon == 28
  35. 004D: jump_if_false @SPRAYWP_01
  36. if or
  37. 00E1: key_pressed 0 17
  38. 0AB0: key_pressed 2// -- RMB
  39. 004D: jump_if_false @SPRAYWP_01
  40. if
  41. 0449: actor $PLAYER_ACTOR in_a_car
  42. 004D: jump_if_false @SPRAYWP_01

  43. :SPRAYWP_10
  44. 066A: 0@ = attach_particle "spraycan" to_actor $PLAYER_ACTOR with_offset -0.301 -0.2 0.17 rotation -5.5 -3.5 0.0 flag 1
  45. 0883: attach_particle 0@ to_actor $PLAYER_ACTOR on_bone 26
  46. 064C: make_particle 0@ visible

  47. :SPRAYWP_13
  48. 0001: wait 0 ms
  49. if
  50. 0256: player $PLAYER_CHAR defined
  51. 004D: jump_if_false @SPRAYWP_15
  52. if or
  53. 00E1: key_pressed 0 17
  54. 00E1: key_pressed 0 6
  55. 0AB0: key_pressed 2// -- RMB
  56. 004D: jump_if_false @SPRAYWP_15
  57. if
  58. 8965: not actor $PLAYER_ACTOR swimming
  59. 004D: jump_if_false @SPRAYWP_15
  60. if or
  61. 02D8: actor $PLAYER_ACTOR current_weapon == 22
  62. 02D8: actor $PLAYER_ACTOR current_weapon == 23
  63. 02D8: actor $PLAYER_ACTOR current_weapon == 24
  64. 02D8: actor $PLAYER_ACTOR current_weapon == 28
  65. 02D8: actor $PLAYER_ACTOR current_weapon == 29
  66. 02D8: actor $PLAYER_ACTOR current_weapon == 32
  67. 004D: jump_if_false @SPRAYWP_15
  68. 0002: jump @SPRAYWP_13

  69. :SPRAYWP_15
  70. 0976: destroy_particle 0@
  71. 0001: wait 1000 ms
  72. 0002: jump @SPRAYWP_01
复制代码

传奇 Legend

虚拟世界,属于你的世界

Rank: 16

UID
4
宝石
154 粒
金币
5594 枚
节操
458 斤
灵石
0 块
精力
509 ℃
QQ
 楼主| 发表于 2012-4-7 10:58:43 | 显示全部楼层
本帖最后由 kwanz 于 2012-4-12 15:33 编辑

跳转列表

定义一个变量
  1. 1@ = 3
复制代码


下面的代码用变量的值控制代码跳转的位置
  1. 0871: init_jump_table 1@ total_jumps 7 0 @JPTABL_T00 jumps 0 @JPTABL_T01 1 @JPTABL_T11 2 @JPTABL_T22 3 @JPTABL_T33 4 @JPTABL_T44 5 @JPTABL_T55 6 @JPTABL_T66
复制代码

代码的格式是
<opcode> <指令描述符> <跳转变量> <指令描述符> <跳转分支数> <指令描述符> <缺省跳转指令> <7 x 跳转指令>
现在我们不看那堆opcode和英文,分析一下用法
参数1 - 指示变量
参数2 - 总跳转数
参数3+4 - 缺省跳转指令
参数5-14 - 分支跳转指令
支持的跳转数目:
Opcode 0871支持最多7个跳转指令
Opcode 0872支持最多9个跳转指令

变量值不在列表内时的缺省跳转(参数3+4)不计入跳转数之内

通过在0871跳转后追加0872语句,可以增多跳转分支的数目,最多支持75个。

  1. 0871: init_jump_table 1@ total_jumps 23 0 @JPTABL_T00 jumps 0 @JPTABL_T01 1 @JPTABL_T11 2 @JPTABL_T22 3 @JPTABL_T33 4 @JPTABL_T44 5 @JPTABL_T55 6 @JPTABL_T66
  2. 0872: jump_table_jumps 7 @JPTABL_T77 8 @JPTABL_T88 9 @JPTABL_T99 10 @JPTABL_T101 11 @JPTABL_T111 12 @JPTABL_T122 13 @JPTABL_T133 14 @JPTABL_T144 15 @JPTABL_T155
  3. 0872: jump_table_jumps 16 @JPTABL_T166 17 @JPTABL_T177 18 @JPTABL_T188 19 @JPTABL_T199 20 @JPTABL_T201 21 @JPTABL_T211 22 @JPTABL_T222 -1 @JPTABL_T00 -1 @JPTABL_T00
复制代码

7重跳转的写法
0 @JPTABL_T01 1 @JPTABL_T11 2 @JPTABL_T22 3 @JPTABL_T33 4 @JPTABL_T44 5 @JPTABL_T55 6 @JPTABL_T66

一条跳转指令带有两个参数
0 @JPTABL_T01
第一个参数指定触发跳转的特定数值
第二个参数为条件满足时的跳转地址

以下是实例代码
按SHIFT改变天气
变量1@是跳转指示器
1@在跳转列表执行完毕后自加1
若1@大于6,则执行缺省跳转
<即1@的值不在跳转列表内>,
也就是跳转到@JPTABL_T00
  1. {$CLEO .cs}
  2. :JUMPTABLE
  3. 03A4: name_thread 'JPTABL'
  4. 1@ = 0

  5. :JPTABL_1
  6. 0001: wait 0 ms
  7. if
  8. 0256: player $PLAYER_CHAR defined
  9. jf @JPTABL_1
  10. 03F0: enable_text_draw 1
  11. 045A: text_draw_1number 400.0 50.0 'NUMBER' 1@ // 显示数值
  12. if1 q$ R& Q$ h% G! d7 G
  13. 0AB0: key_pressed 16 // -- shift
  14. jf @JPTABL_1

  15. :JPTABL_Table
  16. 0871: init_jump_table 1@ total_jumps 7 0 @JPTABL_T00 jumps 0 @JPTABL_T01 1 @JPTABL_T11 2 @JPTABL_T22 3 @JPTABL_T33 4 @JPTABL_T44 5 @JPTABL_T55 6 @JPTABL_T66

  17. :JPTABL_T00// 缺省
  18. 00BA: text_styled 'fem_off' 1000 ms 4
  19. wait 1000
  20. 0002: jump @JPTABL_1

  21. :JPTABL_T01
  22. 01B6: set_weather 0// = Extra Sunny LA
  23. 0002: jump @JPTABL_EXIT

  24. :JPTABL_T11
  25. 01B6: set_weather 1// = Sunny LA
  26. 0002: jump @JPTABL_EXIT

  27. :JPTABL_T22
  28. 01B6: set_weather 2// = Sunny LA
  29. 0002: jump @JPTABL_EXIT

  30. :JPTABL_T33
  31. 01B6: set_weather 3// = Sunny Smog LA
  32. 0002: jump @JPTABL_EXIT

  33. :JPTABL_T44
  34. 01B6: set_weather 4// = Cloudy LA
  35. 0002: jump @JPTABL_EXIT

  36. :JPTABL_T55
  37. 01B6: set_weather 5// = Sunny SF
  38. 0002: jump @JPTABL_EXIT

  39. :JPTABL_T66
  40. 01B6: set_weather 6// = Extra Sunny SF
  41. 0002: jump @JPTABL_EXIT

  42. :JPTABL_EXIT
  43. 1@ += 1
  44. 0001: wait 1000 ms
  45. 0002: jump @JPTABL_1
复制代码


下面的代码是以上的加强版
用0872增加了16个跳转
  1. {$CLEO .cs}
  2. :JUMPTABLE
  3. 03A4: name_thread 'JPTABL'
  4. 1@ = 0

  5. :JPTABL_1
  6. 0001: wait 0 ms
  7. if
  8. 0256: player $PLAYER_CHAR defined
  9. jf @JPTABL_1
  10. 03F0: enable_text_draw 1
  11. 045A: text_draw_1number 400.0 50.0 'NUMBER' 1@ // 显示数值
  12. if
  13. 0AB0: key_pressed 16 // -- shift
  14. jf @JPTABL_1

  15. :JPTABL_Table
  16. 0871: init_jump_table 1@ total_jumps 23 0 @JPTABL_T00 jumps 0 @JPTABL_T01 1 @JPTABL_T11 2 @JPTABL_T22 3 @JPTABL_T33 4 @JPTABL_T44 5 @JPTABL_T55 6 @JPTABL_T66
  17. 0872: jump_table_jumps 7 @JPTABL_T77 8 @JPTABL_T88 9 @JPTABL_T99 10 @JPTABL_T101 11 @JPTABL_T111 12 @JPTABL_T122 13 @JPTABL_T133 14 @JPTABL_T144 15 @JPTABL_T155
  18. 0872: jump_table_jumps 16 @JPTABL_T166 17 @JPTABL_T177 18 @JPTABL_T188 19 @JPTABL_T199 20 @JPTABL_T201 21 @JPTABL_T211 22 @JPTABL_T222 -1 @JPTABL_T00 -1 @JPTABL_T00

  19. :JPTABL_T00// 缺省

  20. 00BA: text_styled 'fem_off' 1000 ms 4
  21. wait 1000
  22. 0002: jump @JPTABL_1

  23. :JPTABL_T01
  24. 01B6: set_weather 0// = Extra Sunny LA
  25. 0002: jump @JPTABL_EXIT

  26. :JPTABL_T11
  27. 01B6: set_weather 1// = Sunny LA
  28. 0002: jump @JPTABL_EXIT

  29. :JPTABL_T22
  30. 01B6: set_weather 2// = Sunny LA
  31. 0002: jump @JPTABL_EXIT

  32. :JPTABL_T33
  33. 01B6: set_weather 3// = Sunny Smog LA
  34. 0002: jump @JPTABL_EXIT

  35. :JPTABL_T44
  36. 01B6: set_weather 4// = Cloudy LA
  37. 0002: jump @JPTABL_EXIT

  38. :JPTABL_T55
  39. 01B6: set_weather 5// = Sunny SF
  40. 0002: jump @JPTABL_EXIT

  41. :JPTABL_T66
  42. 01B6: set_weather 6// = Extra Sunny SF
  43. 0002: jump @JPTABL_EXIT

  44. :JPTABL_T77
  45. 01B6: set_weather 7// = Cloudy SF
  46. 0002: jump @JPTABL_EXIT

  47. :JPTABL_T88
  48. 01B6: set_weather 8// = Rainy SF
  49. 0002: jump @JPTABL_EXIT

  50. :JPTABL_T99
  51. 01B6: set_weather 9// = Foggy SF
  52. 0002: jump @JPTABL_EXIT

  53. :JPTABL_T101
  54. 01B6: set_weather 10// = Sunny LV
  55. 0002: jump @JPTABL_EXIT

  56. :JPTABL_T111
  57. 01B6: set_weather 11// Extra Sunny LV
  58. 0002: jump @JPTABL_EXIT

  59. :JPTABL_T122
  60. 01B6: set_weather 12// Cloudy LV
  61. 0002: jump @JPTABL_EXIT

  62. :JPTABL_T133
  63. 01B6: set_weather 13// Extra Sunny Country
  64. 0002: jump @JPTABL_EXIT

  65. :JPTABL_T144
  66. 01B6: set_weather 14// Sunny Country
  67. 0002: jump @JPTABL_EXIT

  68. :JPTABL_T155
  69. 01B6: set_weather 15// Cloudy Country
  70. 0002: jump @JPTABL_EXIT

  71. :JPTABL_T166
  72. 01B6: set_weather 16// Rainy Country
  73. 0002: jump @JPTABL_EXIT

  74. :JPTABL_T177
  75. 01B6: set_weather 17// Extra Sunny Desert
  76. 0002: jump @JPTABL_EXIT

  77. :JPTABL_T188
  78. 01B6: set_weather 18// Sunny Desert
  79. 0002: jump @JPTABL_EXIT

  80. :JPTABL_T199
  81. 01B6: set_weather 19// Sandstorm Desert
  82. 0002: jump @JPTABL_EXIT

  83. :JPTABL_T201
  84. 01B6: set_weather 20// Underwater
  85. 0002: jump @JPTABL_EXIT

  86. :JPTABL_T211
  87. 01B6: set_weather 21// Extracolours 1
  88. 0002: jump @JPTABL_EXIT

  89. :JPTABL_T222
  90. 01B6: set_weather 22// Extracolours 2
  91. 0002: jump @JPTABL_EXIT

  92. :JPTABL_EXIT
  93. 1@ += 1
  94. 0001: wait 1000 ms
  95. 0002: jump @JPTABL_1
复制代码


0494: get_joystick_data 0 1@ 2@ 3@ 4@
这个opcode读取玩家通过键盘,手柄做出的移动动作
具体键位由暂停菜单中>options>controller settings设定的<left/right> <forward/backward>有关

参数1: 玩家编号, player 1 = 0(主手柄), player 2 = 1(副手柄)
参数2: 左右移动的值
参数3: 前后移动的值
参数4,5: 未知

参数2,3返回的是正数或负数,你需要判定正负来判断是左/前移还是右/后移

下面是一个例子
  1. {$CLEO .cs}
  2. :Joystick_data
  3. 03A4: name_thread 'JOYDATA'

  4. :JOYDATA_1
  5. wait 0
  6. 0494: get_joystick_data 0 1@ 2@ 3@ 4@
  7. if
  8. 1@ > 0
  9. 004D: jump_if_false @JOYDATA_04
  10. 03F0: enable_text_draw 1
  11. 045A: text_draw_1number 250.0 250.0 'NUMBER' 1@ // 显示值
  12. 0002: jump @JOYDATA_07

  13. :JOYDATA_04
  14. if
  15. 0 > 1@
  16. 004D: jump_if_false @JOYDATA_07
  17. 03F0: enable_text_draw 1
  18. 045A: text_draw_1number 350.0 250.0 'NUMBER' 1@ // 显示值
  19. 0002: jump @JOYDATA_07

  20. :JOYDATA_07
  21. if
  22. 2@ > 0
  23. 004D: jump_if_false @JOYDATA_09
  24. 03F0: enable_text_draw 1
  25. 045A: text_draw_1number 300.0 200.0 'NUMBER' 2@ // 显示值
  26. 0002: jump @JOYDATA_10

  27. :JOYDATA_09
  28. if
  29. 0 > 2@
  30. 004D: jump_if_false @JOYDATA_10
  31. 03F0: enable_text_draw 1
  32. 045A: text_draw_1number 300.0 300.0 'NUMBER' 2@ // 显示值
  33. 0002: jump @JOYDATA_10

  34. :JOYDATA_10
  35. 0002: jump @JOYDATA_1
复制代码


0A4A: store_joystick_X_offset_to 1@ Y_offset_to 2@
opcode 0A4A返回鼠标移动,以下代码试试便知
[code]{$CLEO .cs}
:Mousecontrole
03A4: name_thread 'MOUSXY'

:MControl_01
wait 0
0A4A: store_joystick_X_offset_to 1@ Y_offset_to 2@
0092: 4@ = float_to_integer 1@
0092: 5@ = float_to_integer 2@
03F0: enable_text_draw 1
045A: text_draw_1number 200.0 50.0 'NUMBER' 4@ // value
045A: text_draw_1number 350.0 50.0 'NUMBER' 5@ // value
0002: jump @MControl_01

传奇 Legend

虚拟世界,属于你的世界

Rank: 16

UID
4
宝石
154 粒
金币
5594 枚
节操
458 斤
灵石
0 块
精力
509 ℃
QQ
 楼主| 发表于 2012-4-7 10:59:25 | 显示全部楼层
本帖最后由 kwanz 于 2012-4-13 13:15 编辑

瞬移,红圈和地点检测

先看一个简单的例子
在Grove St创建一个传送到CJ家屋顶上的红圈
  1. {$CLEO .cs}
  2. :Teleport_1
  3. 03A4: name_thread 'TELE'

  4. :Teleport_2
  5. wait 0
  6. if
  7. 0256: player $PLAYER_CHAR defined
  8. jf @Teleport_2
  9. if
  10. 00FF: actor $PLAYER_ACTOR sphere 1 in_sphere 2493.5 -1682.5 13.35 radius 1.0 1.0 1.0 on_foot
  11. jf @Teleport_2
  12. 00A1: put_actor $PLAYER_ACTOR at 2524.5 -1677.5 19.95
  13. jump @Teleport_2
复制代码

创建红圈需要调用opcode 00FF且把第二参数设为sphere 1 (sphere 0红圈不可见)
另外,必须把等待时间调为0ms,否则红圈不会显示。

例子:
  1. :Teleport_2
  2. wait 10
复制代码

此时红圈不可见

另外很重要的一点,游戏能创建的红圈数是有限的
参考SB帮助: SCM Documentation: GTA Limits

还有一些Opcode可以显示红圈
下面是仅创建一个红圈的例子
  1. 03BC: 1@ = create_sphere_at 2493.5 -1682.5 13.35 radius 1.0
  2. //注意最后要移除创建的红圈
  3. 03BD: destroy_sphere 1@
复制代码


带小地图标记点的红圈
  1. 02A7: 0@ = create_icon_marker_and_sphere 35 at 2493.5 -1682.5 13.35
  2. //或者可用下面这句
  3. 0570: 1@ = create_asset_radar_marker_with_icon 35 at -2007.8 189.1 27.5
  4. //注意最后要移除创建的红圈
  5. 0164: disable_marker 0@
  6. 0164: disable_marker 1@
复制代码
地点检测
  1. 00FE: actor $PLAYER_ACTOR sphere 1 in_sphere 2493.5 -1682.5 13.35 radius 15.0 15.0 15.0
  2. 00FF: actor $PLAYER_ACTOR sphere 1 in_sphere 2493.5 -1682.5 13.35 radius 1.0 1.0 2.0 on_foot
  3. 0100: actor $PLAYER_ACTOR in_sphere 2493.5 -1682.5 13.35 radius 4.0 4.0 4.0 sphere 1 in_car
  4. 0101: actor $PLAYER_ACTOR in_sphere 2493.5 -1682.5 13.35 radius 5.0 5.0 3.0 sphere 1 stopped
  5. 0102: actor $PLAYER_ACTOR in_sphere 2493.5 -1682.5 13.35 radius 1.2 1.2 3.0 sphere 1 stopped_on_foot
  6. 0103: actor $PLAYER_ACTOR in_sphere 2493.5 -1682.5 13.35 radius 4.0 4.0 6.0 sphere 1 stopped_in_car
  7. 0104: actor $PLAYER_ACTOR near_actor 1@ radius 15.0 15.0 15.0 sphere 1
  8. 0105: actor $PLAYER_ACTOR near_actor 1@ radius 5.0 5.0 2.0 sphere 1 on_foot
复制代码


驾车地点检测
  1. 01AD: car 1@ sphere 1 near_point 2493.5 -1682.5 radius 6.0 6.0
  2. 01AE: car 1@ sphere 1 near_point 2493.5 -1682.5 radius 3.0 3.0 stopped
  3. 01AF: car 1@ sphere 1 in_sphere 2493.5 -1682.5 radius 0.2 0.2 1.0
  4. 01B0: car 1@ sphere 1 in_sphere 2493.5 -1682.5 13.35 radius 4.0 4.0 4.0 stopped
复制代码


带红圈显示的地点检测语句是非常好用的,注意要把循环时间设置为0ms。

现在我们可以通过增加地点检测语句的方法,设定多个瞬移入口。
老家四个瞬移点:
  1. {$CLEO .cs}
  2. :Teleport_1
  3. 03A4: name_thread 'TELE'

  4. :Teleport_2
  5. wait 0
  6. if
  7. 0256: player $PLAYER_CHAR defined
  8. jf @Teleport_2
  9. if
  10. 00FF: actor $PLAYER_ACTOR sphere 1 in_sphere 2493.5 -1682.5 13.35 radius 1.0 1.0 1.0 on_foot
  11. jf @Teleport_3
  12. 00A1: put_actor $PLAYER_ACTOR at 2524.5 -1677.5 19.95
  13. jump @Teleport_2

  14. :Teleport_3
  15. if
  16. 00FF: actor $PLAYER_ACTOR sphere 1 in_sphere 2530.5 -1678.5 19.95 radius 1.0 1.0 1.0 on_foot
  17. jf @Teleport_4
  18. 00A1: put_actor $PLAYER_ACTOR at 2512.5 -1670.5 13.5
  19. jump @Teleport_2

  20. :Teleport_4
  21. if
  22. 00FF: actor $PLAYER_ACTOR sphere 1 in_sphere 2507.5 -1673.5 13.4 radius 1.0 1.0 1.0 on_foot
  23. jf @Teleport_5
  24. 00A1: put_actor $PLAYER_ACTOR at 2490.5 -1717.5 18.6
  25. jump @Teleport_2

  26. :Teleport_5
  27. if
  28. 00FF: actor $PLAYER_ACTOR sphere 1 in_sphere 2504.5 -1719.5 18.6 radius 1.0 1.0 1.0 on_foot
  29. jf @Teleport_2
  30. 00A1: put_actor $PLAYER_ACTOR at 2497.5 -1681.5 13.4
  31. jump @Teleport_2
复制代码

禁止发言

GoogleTranslation

UID
115
宝石
0 粒
金币
212 枚
节操
8 斤
灵石
0 块
精力
87 ℃
发表于 2012-4-7 13:07:28 | 显示全部楼层
提示: 作者被禁止或删除 内容自动屏蔽

落魄 Abjection

Rank: 1

UID
822
宝石
1 粒
金币
319 枚
节操
21 斤
灵石
0 块
精力
210 ℃
发表于 2012-4-8 10:37:26 | 显示全部楼层
顶个吧!虽然看不懂- -,

本版积分规则

    切换繁體
    Archiver|手机版|小黑屋|

GMT+8, 2024-11-23 12:00 , Processed in 0.272278 second(s), 165 queries .

沪ICP备2021020632号-1

快速回复 返回顶部 返回列表