这是教学贴,有问题可以问,不爱看就别看,别几把跟打卡一样发学习了学习了,当我版主是摆设是吧,再见到给你删成大负翁
不是很高大上的教程,目的是为了填目前没有ref入门教程的坑(因为佬们都很忙,悲),虽然也不是个多难的东西,但是ref这种有点奇怪的门槛确实劝退了不少人。因为比较笨比而且没有方向,我自己学这个花了挺久,所以这篇教程的目的就是让后面有心学lua的小白少走点弯路。整篇教程以照顾小白为主(能力只够教小白),尽量讲的细。
但是,这里我也放一句O佬未完成教程的原话
本教程适用于:1. 已经有一定编程基础 2. 能够独立自己安装REFramework 3. 有一定英文基础的玩家进行阅读和学习
意思是完完全全的从零开始写教程是很难的,如果连类似上述第二条这种都会有问题的话,那确实没办法了,从0到1和从0.1到1是完全的质变
以及比所有资料都重要的,一内内英语水平。
同时呢,也以这篇教程致敬在世界时候写了一大堆教程的各位佬
东西很多很杂,教程会分多期,反正基本上有时间可能就写点
ref_github发布地址
reframework_book
对于ref来说,ref book是最核心的教程,想改一个东西的时候,查ref book是最好的,也是最最最常用的网站(不过由于很久没更新了,随意好多新的语法糖并没有写完全,遇到问题可以多去discord问问)
lua_菜鸟教程
快速上手lua各种操作
作用域和闭包
lua的补充知识,作用域这个东西建议多看多理解
零酱的数据表格
很多常用的数据零酱是整理好的,如果不清楚一些数据可以上这查
毒舌傲娇唯宝之lua小白教学
很多修改文件参数的mod实际上都可以通过ref+lua的方式实现,虽然可以达成的效果一致,但使用lua的优点超级多
- 实时debug,不用转移文件不用换武器重载,大多数lua修改后只需要点击reset scripts就可以刷新,并且ref菜单中自带报错提示,相当好用。而最经典的例子是使用010editor配合rsz模板修改派生,但凡改过就会知道刷新一次模板至少得好几分钟,并且不论你劈吸配置多高,众生平等的慢
- 实时修改,像使用了xxx动作xxx技能得到增强之类的很容易实现
- 卡表之力,可以直接调用卡表程序员留下的各种方法和参数,没错,这是ref最nb的地方,比如想要把合气效果移植到其它动作,可以直接调用它的特效与回翔虫的方法,几句简单的代码就可以实现效果,拿来把你
知道了ref的大致优点,我们来认识一下核心工具——
DeveloperTools > ObjectExplorer,
一般点开DeveloperTools会小卡一下,正常现象
所有的参数寻找都在这里
以及下面是调试时候最常用的reset scripts,用于重新载入脚本
下面分标题详细介绍一下各个部分
见过一个G的json吗,没错,当你点击这个按钮,等待一会,你的游戏根目录就会多出一个按G算的json
这里面是ref里所有Type的定义之类的东西,打开会很卡很卡
不开游戏的话可以在这里面查看各种量,但一般来说低配劈吸还是别这么干,卡的批爆,不如直接开游戏
一起dump下来的另一个东西更有用
就是这个,枚举列表,人话说,就是有一些只能取特定值的量,它们这些量的取值范围,比如玩家的武器类型
这样你可以很方便的把这个复制到你的lua里作为一个表之类的
除此之外,enum在显示数据的时候也会用到,我们后面再说
打开Singletons会发现里面有超级多的东西,并且一层套一层
这里用零酱的话来简单说明一下
如果之前有接触过一点ce的应该很容易就懂了什么意思,放个导图大概理解一下
不过平常会用的也就方法和字段,最主要是要明白,搜索栏里搜到的类定义为什么不能直接操作
用一个例子来说
类定义就是可乐瓶子,瓶子是不能喝的,因为他没有实际的数据,装了可乐(实例化,就是填入实际数据)之后,变成一个真正的可乐(对象/实例),就能喝了(使用对象的操作),也许讲的很怪,但基本上多用就会理解
反正基本思路就是,能从售货机里找到可乐(singletons里的object),是最方便的,如果售货机里没有,那么就去工厂直接拿(用sdk.hook勾住特定类的一个method)
而Singletons里存放的是已经实例化的各种对象,我们要做的,就是找到自己想要的数据,拿到或者修改它们
这里我以最常见也最常用的snow.player.PlayerManager为例(实际上一般人想改的99%的参数都能在这里找到)
我们设一个小目标先,修改人物的技能参数
首先我给出一个已知条件:人物的技能参数存放在snow.player.PlayerManager的field中
先来对snow.player.PlayerManager展开后的结构有个大概认识
第一步,拿到它
现在我们找到它了,怎么得到它呢,我们去ref_book里康一康
在介绍页里,我们看到,要得到这个量,我们可以使用
sdk.get_managed_singleton("name")
所以我们这么写
如果一个量不是布尔值,放在判断里的话,意思就是判断这个量存不存在,存在为true,不存在为false,这个写法很常用,用于判断某个量不存在时直接结束,这个写法在hook里不要乱用,很危险,很危险,很危险!!!
我们先展开playerManager的fields看一看
左边的白字是这个field的类型(type),右边是这个field的名称(name)
有点英语水平的话,应该很容易看到红框里的PlayerUserDataSkillParameterer很可能就是我们要找的技能参数
展开它,基本就可以确定了,它的field从上至下分别是
那么第二步,拿到这个field
因为上面拿到的playerManager是一个已经实例化的object,这个field在playerManager下面,所以我们去找对object操作的方法
这里可以看到对object使用get_field操作可以拿到它下面的field
因此我们这样写
再展开下面的装备技能,可以看到技能参数之类的雀氏存在这里
因为_EquipSkillParameter是_PlayerUserDataSkillParameter下面的field
因此要拿到它,我们这么写
那么总共串起来就是这样
接下来我们选一个技能来修改,比如匠,但这些命名基本上都是——EquipSkill_xxx的格式,怎么知道匠对应哪个,这时,就请去【资料】>【零酱的数据表】里,找到技能相关
这里可以知道匠的后缀是021
可以看到它是一个Int32的数值,大小是10,什么意思呢
结合游戏会很容易理解,每级匠会增加十刀斩味,就对应了这个10
所以这个10指的是每级匠的增加斩味
然后,这个已经是一个单独的数值,不能再展开,那么它作为对象_EquipSkillParameter下的一个field,去看ref_book可以找到修改对象下面字段的操作
我们想设置匠为为每级20刀
做完这些操作后,我们把这些代码放进一个函数内封装起来,并放入re.on_frame中,这个函数每帧运行一次
保存为lua文件后,放入reframework/autorun下,就可以自动运行了
这是一个很基础的流程,会了这个其实singletons里的绝大多数就都能改了,
不过实际上除了这个,还需要加一些判断之类的,避免在这个类还没有被加载出来的时候获取到空值
留一个小作业,修改寒气练成的增伤倍率
如果觉得有疑问,欢迎在评论区提问
那么这期到此结束,下期再见吧