PCGTA侠盗猎车手中文论坛

 找回密码
 现在注册
查看: 1517|回复: 8

[基础教学内容] CLEO修改方法之高手进阶篇(从CLEO神的博客找来的)

[复制链接]
发表于 2016-7-3 00:01 | 显示全部楼层 |阅读模式
在本论坛里有个“修改CLEO常用的思路和模板……”,是修改CLEO的新手入门篇,基本上都看得懂的,但是还有一篇CLEO修改帖,叫做高手进阶篇,不知道什么原因CLEO神没发出来,我是在ljnedzq的博客里找来的(也就是CLEO神的博客,就是那个CLEO666大合集的收集、翻译、整理、说明书制作,再加上还有一部分原创):

http://ljnedzq.blog.163.com/blog/static/113321268201192182221423/

以下是这篇博客的全文:

以前发的那个是最基本的修改方法,是修改CLEO的入门必备知识,点击进入日志《CLEO修改大法——新手入门篇》:

http://ljnedzq.blog.163.com/blog/static/113321268201192182112904/

如果那个能看懂的话,就可以慢慢地试着自己改CLEO,一开始改出来的CLEO会和你套用的模板CLEO很相似,但如果你的思想超越了你所套用的CLEO本身的框架,那么就从“修改”升级成了“制作”。制作CLEO要掌握下列几点常用技巧:


技巧1、设置反向条件
所谓反向条件,就是把if语句的后面本来表示肯定的句子变为否定或表示否定的句子变为肯定。
例如:   Actor.Dead(1@) 人物1@死了
要是改成(如果)人物没死(就……),直接在前面加not就行了:not Actor.Dead(1@) 人物1@没死

这是CLEO语句前面没有标志码的情况,如果前面有一个十六进制的四位数标志码,例如:0AB0:   key_pressed 36  按了Home键
把肯定改否定就要把标志码第一位由0改成8,然后在语句前面加not:        8AB0:  not key_pressed 36  没按Home键

那把否定改肯定呢?过程是相反的,去掉not再把标志码第一位的8改成0(没有标志码的句子就更简单了)。

CLEO语句的标志码全都是以0或8开头的四位数十六进制代码,0和8相反,一个表示肯定一个表示否定,转换方式就是上面所述。

技巧2、添加人物模型

怪物类的CLEO全都是添加模型的,和替换模型相比它的好处就是没有替换任何NPC,不会走着走着就遇到一个怪兽(然而一打就死,这怪兽太水了吧……)。如果不是用其它CLEO修改而是想用一个从网上找的怪物模型自己动手来做个怪物类的CLEO,怎么添加模型呢?

游戏原版的人物,加载模型时都是这一句:
model.Load(#ARMY)
括号里的人物名称就是原版游戏里的人物名称,所以没问题,如果下载了一个人物用来制作一个要替换模型的怪物类CLEO,就不需要作说明了吧?
如果是想添加模型,它的名字一定不能和gta3.img里的任何模型重名,否则会死机,而且名字长度也不能大于6,超过6位的话电脑会自动截取前6位,那肯定就找不到模型了,也会死机,所以虽然金刚的英文名称叫kingkong但在圣安地列斯里的模型却叫kinkon,必须缩短。

要是想把金刚的模型添加进来,用这句:
023C: load_special_actor 'kinkon' as 1   加载“kinkon”为1号特殊人物
单引号里就是模型名称,后面的数字表示把它加载为几号模型,只有11个位置,数字为1~11之间的正整数。

判断是否加载了人物模型的句子就变成了这样:
023D:  special_actor 1 loaded

然后创建人物的时候,这个人物就叫#special01,特殊人物1号:
1@ = Actor.Create(CivMale, #SPECIAL01, -636.05, -2082.71, 29.946)

中间那个civmale是决定帮派属性的因素,如果想让怪兽刷出来做自己的小弟,就从召小弟的CLEO里复制这一句创建人物;如果是当成敌人刷出来,就从刷敌人的CLEO里复制。

用Imgtool把kinkon.dff和kinkon.txd添加到gta3.img里之后运行这个CLEO,就可以找到金刚了。

很多个怪物CLEO一起装的时候,由于添加的模型编号一共只有11个位置,所以加载模型的那一句不是放在程序里任何位置都合适的,弄不好会有“串模型”的现象出现。

比如:怪物甲和怪物乙分别属于两个不同的CLEO,但都是游戏一开始就加载为1号模型的话那么去了怪物甲所在的领地之后有可能刷出来的是怪物乙,或者是游戏里的剧情人物(因为剧情人物也是占用这11个位置,在不同的场景里分别调出来作为某一号特殊人物来用,所以11个位置也够了),这种串模型现象的出现就是因为加载模型的条件跟位置无关,把电脑搞迷糊了。这时候就要注意了,要把“加载怪物甲为1号特殊人物”这一句移动到“当CJ到达怪物甲的领地(有时候还有时间段)”这一句的后面,也就是进入它的领地就加载它的模型,不进入就不加载,怪物乙也这样改,那么在两者的领地没有重叠的情况下就算模型编号一样也不会串模型了,如果两个怪物CLEO的触发地点相近,就一定不能让数字相同,否则会串。“白龙马CLEO”和“天马CLEO”互为MOD关系,是同一个CLEO只是马的模型不同,程序都一模一样,我就是用这种方法使这两个CLEO可以共存。“机械公敌CLEO”和“高达CLEO”虽然是通过改模型名称改得可以共存了,但由于触发键没改所以同时装有可能会有位置重叠的现象,要么改按键、要么改刷出的位置,这样就可以真正共存了。

游戏里的剧情人物如果想调出来,和添加模型的方法一样,它们都是占用这11个特殊位置,“刷三合会CLEO”里的吴子就是这样加载的:
023C: load_special_actor 'WUZIMU' as 1

用召唤战士CLEO或召唤骷髅CLEO去打怪物,很容易出现串模型的情况。
用按键触发的添加人物CLEO和用地点触发的添加人物CLEO怎么避免串模型,是一个道理的。

技巧3、利用Sanny Builder的编码提示系统

在Sanny Builder里打出某一特定组合后,会出现一系列提示,都是以这个开头的,例如输入“Car.”,就会出现一大堆以“Car.”开头的,自己看想要哪个就选它按回车就行了,不用整句话都一个一个字符地敲上去。




输入“player.”后也会出现类似的提示。


加载模型的句子的括号里都是以#号开头的,输入字符#,也会出来一大堆,接着输入一两个字母,这个模型也该浮到前面的位置了,所以有些模型名字记不清也没关系,知道前几位再有个大概的印象就行了。




技巧4、利用Sanny Builder的代码搜索器

在Sanny Builder的菜单里,有个功能强大的代码搜索器:Tools→IDE tools→Opcode search


里面有CLEO所要用到的全部代码,这需要一定的英语基础才知道要搜索什么内容:

如果想让某辆车跟着CJ,就需要知道“跟着”是follow,在输入框里输入follow就会出来全部的包含follow的语句。



想要哪一句在它上面点右键选复制就行了。

这些全是与跟踪有关的:
0727: set_heli 377@ behavior_to_police_heli_and_follow_actor $PLAYER_ACTOR follow_car -1 radius 20.0
让直升机377@像警用直升机一样以20米的距离内跟踪着人物$PLAYER_ACTOR所开的车

0724: heli 114@ follow_and_attack_player $PLAYER_CHAR radius 50.0
直升机114@追着炸人物$PLAYER_CHAR,跟踪半径为50米

07F8: car 74@ follow_car 72@ radius 27.0
车辆74@跟着车辆72@,跟踪半径为27米

如果想让战斗机去打某个车,就得知道要搜索的是attack,输入attack就出来一大堆包含attack的句子。

有英语基础的话一看就知道这一句就是:
070E: hydra 126@(48@,2i) attack_player_car $PLAYER_CHAR radius 10.0
战斗机126@(48@,2i)轰炸人物$PLAYER_CHAR所开的车,跟踪半径是10米


用这个句子的时候必须保证被轰炸的人始终开着车,一旦此人下车就会死机或者战斗机会悬停在空中不动,原因就是没告诉电脑如果这个人物没开车时要怎么做,电脑就愣在那里了。

把数字4@加上1.5之后的数字重新储存为4@,这个语句的前面没有标志码,可以直接打出来: 4@ += 1.5
如果要加上的那个值不是个具体的数而是一个变量,这样就不行了,如果打“4@ += 5@”,编译不了的,因为前面没有标志码,电脑不认识它,而又不知道标志码是什么,也不知道在哪个CLEO里有这一句,复制也复制不成,这时候就在代码搜索器里搜索“+=”,可以看到这一句:005B: 4@ += 17@ // (float)  ,这就找到了。

技巧5、利用强大的障眼法

如果打开圣安地列斯的脚本文件main.scm看看,会发现游戏里很多视觉效果都是用的“障眼法”,在游戏虚拟的世界,眼见不一定为实。原版游戏在三星级的时候飞机上会有特警爬绳子下来,但那些特警真的是从飞机里跑出来的吗?只不过是在飞机旁边创建个绳子然后创建特警爬绳子下来而已。实际上飞机里连个驾驶员都没有。

为什么会有字数限制?接下一层楼:


本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?现在注册

x

评分

参与人数 2钱币* +80 收起 理由
2411437602 + 10 精品文章!
丶Vasyl + 70 赞一个!

查看全部评分

回复

使用道具 举报

 楼主| 发表于 2016-7-3 00:02 | 显示全部楼层
如果想成为制作CLEO的高手而不只是简单的修改,最重要的就是用“障眼法”来欺骗玩家的眼睛,什么叫障眼法,举个例子来说明一下。

这个游戏玩通关都好久了我才听说CLEO,第一次接触到CLEO的时候,是下载了个“潜艇”,当时还不知道这就叫CLEO,后来接触的CLEO越来越多,慢慢地也能看懂代码了,才发现潜艇其实是“骗人”的,它真的是往游戏里增加了一个交通工具吗?我一直特别崇拜这个CLEO的制作者。
下面就来揭密潜艇CLEO的原理:

按Ctrl+S刷出一艘Marquis船
创建一个物品“潜艇壳子”(哪个代号对应哪个物品,可以用地图编辑器来看,也可以用超级刷物CLEO刷出来看看)
把潜艇壳子套在Marquis船上,把Marquis隐藏掉
如果按攻击键就创建一个比萨店的小木牌子,创建烟雾并把烟雾粘在木牌上,把小木牌往鼠标所指的方向以某一速度扔出去(这就是所谓的“战术巡航导弹”)
如果木牌落地就在落地处创建一个半径为多少米的爆炸
创建鹞式战斗机粘在潜艇壳子上,战斗机隐藏,如果按次级武器键就用战斗机来攻击(这就是所谓的“鱼雷”)
如果按爬升键,就把潜艇壳子在船上的位置往下移,视线跟着铁壳子走(视线跟随铁壳子跑水里了但船仍然在水面上)
如果按俯冲键,就把潜艇壳子在船上的位置往上移,视线跟着铁壳子走
如果铁壳子相对于船的位置靠下,那么按攻击键无效(这就是为什么在水下只有一种武器了)

把submarine.cs从头看到尾,潜艇就是这么一回事,你所开的船并没有潜下去,只是铁壳子潜下去了,关于这一点可以这样来验证:开着潜艇往货船下面钻,看能钻得过去不?肯定钻不过去,因为真正开的船是Maiquis,它还在水面上挡着呢。

这就可以理解为什么保存游戏之后潜艇开不走了吧?重新读档之后Marquis已经消失而创建的物品仍在原地,它本来就不是个交通工具,只是借用船来开动而已,船都没了还怎么开?

上面的内容并不是为了讽刺潜艇是假的,这正是崇拜的地方,强大的“障眼法”!

那怎么用“障眼法”呢?这个要靠想像力了,随心所欲、为所欲为,你能想成什么样,就能做成什么样来,没有标准框架,也无法做具体说明。

光棱塔CLEO的制作过程:
我有一段时间想做个光棱塔CLEO,但怎么实现呢?红色警戒里的光棱塔是一个柱子顶上发出一道激光把人打死,而在侠盗车手的CLEO语句里并没有“用光线照死人”这样的命令,那可以换一种思路,我弄的光棱塔CLEO就是利用了障眼法。
光棱塔CLEO的lasertower.cs全文及翻译如下:

thread 'LASERTOWER'                 名称“LASERTOWER”

:LASERTOWER_19                      循环段落19
wait 0                              等待0毫秒
if and                              如果——→if and是说下面的条件要同时满足
   Player.Defined($PLAYER_CHAR)     CJ被定义了——→就是游戏开始了
0AB0:   key_pressed 32              按空格
0AB0:   key_pressed 76              按L键
else_jump @LASERTOWER_19            如果不满足上述条件就跳转到开头
04C4: store_coords_to 1@ 2@ 0@ from_actor $PLAYER_ACTOR with_offset 0.0 30.0 0.0   把从CJ偏移0.0,30.0,0.0的地方的坐标储存为1@ 2@ 0@
02CE: 3@ = ground_z_at 1@ 2@ 0@     定义3@为(1@,2@,0@)这个点的地面投影点的海拔高度——→这个很重要,不然CJ如果飞在天上刷光棱塔就刷到前面的空中去了,有了这一句,无论地形如何,都是放在前方的地面上
4@ = Object.Create(16778, 1@, 2@, 3@)   在1@, 2@, 3@这一点上创建物品16778,并定义为4@ ——→ 16778是飞碟柱子,这个东西我也是找了好久才找到它的编号
08E9: set_object 4@ liftable 1          设置物品4@可搬——→ 这就是让光棱塔可以搬得走
08D2: object 4@ scale_model 2.0         把物品4@扩大到原来的2倍——→搬起来之后就现原形了,变小了
jump @LASERTOWER_131                 跳转到循环段落131

:LASERTOWER_131                     循环段落131
0400: store_coords_to 5@ 6@ 7@ from_object 4@ with_offset 0.0 0.0 12.0   把从物品4@偏移0.0 0.0 12.0 的位置坐标值储存为5@ 6@ 7@——→这个就是飞碟柱子的顶端
08E5: get_actor_in_sphere 5@ 6@ 7@ radius 100.0 handle_as 8@   在以5@ 6@ 7@这个点为球心的半径为100米的球体内随机抽取个人定义为8@
if                                      如果
056D:   actor 8@ defined                8@被定义了——→也就是在光棱塔附近有人,这个条件很重要,如果没人就不会有8@,而下面要对人物8@执行一些指令,那肯定就要死机了
else_jump @LASERTOWER_202               不然就跳转到循环段落202——→202这一段是说在附近没人的情况下怎么办
jump @LASERTOWER_343                    跳转到循环段落343——→343这一段是说附近有人时怎么办

:LASERTOWER_202                           循环段落202
0400: store_coords_to 5@ 6@ 7@ from_object 4@ with_offset 0.0 0.0 12.0   把从物品4@偏移0.0 0.0 12.0 的位置坐标值储存为5@ 6@ 7@——→这个就是飞碟柱子的顶端
0208: 13@ = random_float_in_ranges -20.0 20.0          从-20到20这个区间随机找个数定义为13@
0208: 14@ = random_float_in_ranges -20.0 20.0          从-20到20这个区间随机找个数定义为14@
0400: store_coords_to 15@ 16@ 17@ from_object 4@ with_offset 13@ 14@ 0.0     把从飞碟柱子偏移13@ 14@ 0.0 的位置坐标值储存为15@ 16@ 17@——→这就是在飞碟柱子旁边20米范围内随机取点
02CE: 18@ = ground_z_at 15@ 16@ 17@              把15@ 16@ 17@这一点的地面投影点的海拔高度储存为18@
06B1: 13@ = create_searchlight_at 5@ 6@ 7@ radius 0.3 target 15@ 16@ 18@ radius 0.5  在5@ 6@ 7@这一点创建一条半径为0.5米的光线指向15@ 16@ 18@这个点,光线定义为13@
wait 200                               等待200毫秒
06B2: destroy_searchlight 13@          光线13@消失——→如果没有这句,光线会一直在那里,不会灭

:LASERTOWER_343                        循环段落343
else_jump @LASERTOWER_131              这一句是多余的,可能做的时候没注意吧,不过貌似也没什么影响,因为在它前面并没有给出条件来
04C4: store_coords_to 9@ 10@ 11@ from_actor 8@ with_offset 0.0 0.0 0.0  把人物8@所在的点的坐标值储存为9@ 10@ 11@
06B1: 12@ = create_searchlight_at 5@ 6@ 7@ radius 0.3 target 9@ 10@ 11@ radius 0.5 从5@ 6@ 7@这个点发一道半径为0.5米的激光照射9@ 10@ 11@这一点,光线定义为12@
0565: create_soundless_explosion_at 9@ 10@ 11@ type 8   在9@ 10@ 11@这一点上创建一个无声的隐形爆炸——→这才是NPC真正的死因,根本不是被光线照死的
0321: kill_actor 8@   杀死8@这个人物——→这一句是保证了他的死亡,为了防止某些NPC血很厚一下炸不死
Actor.RemoveReferences(8@)                 把人物8@的模型拿掉——→就是让尸体消失
wait 200                                    等待200毫秒
06B2: destroy_searchlight 12@               让光线12@灭掉
wait 1000                                   等待1000毫秒
jump @LASERTOWER_131                       跳转到循环段落131——→寻找下一个倒霉的NPC,嘎嘎!

可以看出,这是个无限循环,里面包含了两个子循环:如果有人就发激光创建爆炸并杀死他;如果没人就往周围地面随机发激光照射。
在有if的时候必须做到面面俱到,告诉电脑在每一种情况下要怎么做,要不然它就茫然不知所措(死机)。


我弄那个“崩屁神功”CLEO,也是利用了障眼法,breakwind.cs里面的全过程如下:

按Ctrl+K
CJ做一个撅屁股的动作
在CJ周围创建绿色的烟雾
在烟雾处创建无声的隐形爆炸(就是冲击波,能把人崩走)
从CJ附近抽取一个人
杀死这个人
跳转到开头

在这里面NPC也不是被屁熏死的,无论哪个语句都没有这个功能。但是“障眼法”的使用却达到了这么一种效果:NPC一走进绿色烟雾区就死掉,看起来感觉那人就是被熏死的,这就足够了,玩家追求的就是这个效果,只要玩起来很嗨就行了。如果深入追究起来的话整个游戏都是假的了。

类似的还有很多,所以制作CLEO的时候思想不能老拘泥于某一个条条框框,要有发散性思维,想想要做的CLEO是什么样,可以搞个分解动作,然后每一步用什么语句来实现就想想哪个CLEO里有这样的句子,去那里面复制进来就行了。如果实现不了的就看能不能换个方式去实现,只要让它看上去是那么回事,就可以算是成功了。

还有,为什么CLEO装多了会死机。根据CLEO的程序特点,一进游戏它就开始执行了,“如果主角……,就……(不满足条件就跳转回去)”,可以看出,热键启动的CLEO你即使没按那个键,它也在运行着,开车启动的CLEO,没开车它也在运行着,只是都无限次地跳转回去,看不出来罢了,可想而知,同时装几十个甚至几百个CLEO,即使你不使用那个功能,它也在执行很多个无限循环“如果主角没有满足这个CLEO的启动条件,就跳转到开头”,电脑就崩溃了!!!
回复 支持 反对

使用道具 举报

 楼主| 发表于 2016-7-3 00:20 | 显示全部楼层
好,我复制完了,这是CLEO神献给广大SA爱好者的大作。
回复 支持 反对

使用道具 举报

发表于 2016-7-3 11:00 | 显示全部楼层
看不懂兄弟        不过支持你
回复 支持 反对

使用道具 举报

 楼主| 发表于 2016-7-3 12:59 | 显示全部楼层
bilali 发表于 2016-7-3 11:00
看不懂兄弟        不过支持你

我能看懂一点点。以前那一篇好懂一些。
回复 支持 反对

使用道具 举报

发表于 2016-7-3 17:49 | 显示全部楼层
之前在虚拟世界都看过了,顺便还都复制下来存为doc文档了,可惜没有更多后续文章能够学习的了...
(呐,都领进门了该自己修行了...)
回复 支持 反对

使用道具 举报

01-CEO 该用户已被删除
发表于 2016-7-3 20:12 | 显示全部楼层
提示: 作者被禁止或删除 内容自动屏蔽
回复 支持 反对

使用道具 举报

发表于 2016-7-4 14:59 | 显示全部楼层
支持,精品文章!
回复 支持 反对

使用道具 举报

发表于 2018-2-9 18:40 | 显示全部楼层
这个看完之后受益良多啊
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 现在注册

本版积分规则

小黑屋|手机版|Archiver|PCGTA

GMT+8, 2024-5-3 14:10 , Processed in 0.174262 second(s), 29 queries .

Powered by Discuz! X3.4

© 2001-2017 Comsenz Inc.

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