一只双眼皮 发表于 2018-12-28 13:46

【2018.12.28】圣火令mod的制作过程(部分代码分析图示)及漫漫长夜设定讨论-第一篇:分割取整

本帖最后由 一只双眼皮 于 2018-12-28 19:29 编辑

前情提要:圣火令答应过制作mod教学系列贴,供普通玩家入门游戏修改,从此摆脱受制于人的窘境。
本贴为系列第一贴。
---------------------
本贴必须用到的工具软件:dnspy(百度,到处都有)
虽然dnspy是个绿色软件,但因为它是反编译软件,因此按版本不同,需要.Net 4.0(3.6版)或 .net 4.72 (dnspy 5.09版)支持。
.net 4.0 一般操作系统都会集成。但 .net 4.72 在win7 X64下经常安装不上。
这就需要另一个软件 : Windows Install Clean Up msicuu2 (请百度之)
实测这是确定能清除 .net 4.62C 的软件。
因圣火令用俄毛win7X64旗舰版,默认集成了 .net 4.62和4.62C 导致.net 4.72 无法安装,无法使用能直接编译C#的高版本dnspy,这个教学贴耽搁了很久。
-----------------------------------
关于dnspy 3.X 和dnspy 5.X的区别 ,在于 5.X的dnspy可以部分直接编译C#代码,避免了 IL 指令入门难度太高的问题
-----------------------------------
但为照顾不会搭建.net环境的网友,本贴将多以IL指令来实现游戏修改和mod制作。
-----------------------------------
讨论区:
尸体分割时,有余数是正常的吗?
以鹿为例

8.2kg的鹿,被分割成了4份,每份 4.1 (分割出袋子的重量是肉重*2)
这时我们想问个为什么?因为这是不符合玩家逻辑的。
一个袋子能装几斤肉它应该是固定的。我们为什么要在分割的时候不把袋子装满,却偏要每袋都装一半呢?好我们看看代码

分割时肉会被分成几袋,代码控制中有三个重要点:
1、向上取整。意思是 7/3=2.33333 ,只要有小数点部分,就会向上取为整数,结果为3
2、这个.尸体.可获取的肉重 做为被除数
3、这个.尸体.肉袋容量 作为除数(最好理解为 这'种'.尸体.的肉袋容量限制。)
那么我们来算一下:
8.2kg / x = 4 * ?
因为存在函数向上取整,因此x的实际值近似8.2 /4 = 2.1
这种带固定小数的袋子容量限制,是正常逻辑吗?
当然不是。既不是正常人的逻辑,也不是正常程序猿的逻辑。
我们把这个x 暂时忽略。看一下把肉放进袋子的操作代码

在这里,我们发现了一个传递。
具体传递流程为:
CalculateNumberOfQuartersToSpawn   定制要分成几袋
被 SpawnQuarters 函数调用,做循环“具像化”
再把“准备具像化的次数(也就是数列长度)” 给与 TransferMeatToQuarters
TransferMeatToQuarters赋值肉重的字段,被SpawnQuarters函数调回,“具像化”肉袋到游戏中。
“具像化”这个说法不严谨但便于理解,意思就是让这次分割出的肉袋,从游戏代码变成玩家可以看到可以捡到的肉袋。
(有兴趣的玩家自行百度UnityEngine.Object.Instantiate)
这里我们得到一个关于代码的结论:
如果用原版函数,分肉到整是很难实现的。因为它是用固定的肉重/肉袋重,又做了向上取整。
那么只要肉重有小数部分,例如5.123.49.9 等,那么肉袋里的肉,一定不是整数重量。
因为5.1 会被分成 5.1/x 取整= 3 袋。而每袋重量 1.7 (玩家可用原版做个实验)
我们想要的是什么呢?1袋 5kg,另1袋 0.1公斤。这样才符合正常逻辑:1袋装满,再装下一袋。
------------------------
这个时候卡壳了。因为它是先分袋,再做除法分重量。
(有经验的老玩家,在分割熊、驼鹿的时候,知道先把小数部分割掉。
比如21.7kg,先选满所有肉,再退回来,退到1.7,把这个1.7先割出来,再分袋,这样会获得4个正好5kg肉的肉袋)
这个操作是可以满足强迫症每袋肉都取整这个愿望的。这个操作太繁琐,太不优雅了。
------------------------
先公布一下关于x的结论:x并不是一个固定值。
在尸体为鹿、狼时,x=2.5 以利于玩家分割后的袋子正好重5
在尸体为驼鹿、熊时,x=5 这就是玩家经验:肉袋上限重10(5kg肉)的出现原因,这个经验被证伪,因为它不是固定值。
我们可以找一头 >10kg的鹿来做实验,先切掉 >10的部分,再用分割功能。会发现分成了4袋,肉袋每袋重5(肉重每袋2.5)
------------------------
如何优雅的把肉装进袋子呢? 我们分两步来调整代码
先修改CalculateNumberOfQuartersToSpawn这个函数

我们先把肉袋容量做一个向下取整,原熊和驼鹿的5kg 不变,原鹿狼的2.5会变成2,这样肉袋的重量会变成4kg,方便玩家拿取又不会因为2.5的限制导致产生0.5的肉块
如果想简单一点可以到此为止。改好保存文件。
游戏中先切下一部分肉,让鹿狼的剩余肉重维持2的倍数,熊驼的剩余肉重为5的倍数,肉袋就始终是4kg和10kg,就不会再出现0.5kg的情况。
——当然这还是不够优雅,只是折中实现了一半。
接下来,我们想不用这么麻烦的游戏内操作,直接让它分割好。就要大改TransferMeatToQuarters这个函数了。

打开两个窗口,一个原版,一个改好的版本,然后使用 新建垂直标签组。会变成这样

IL指令的操作,玩家可以下载改好的 mod 对比查看。因dnspy 5.X 允许同时两个实例(开两个窗口)
玩家可以一个开原版,另一个开改版,查看不同的IL代码
我们用改好的文件进游戏,试下效果


9.5kg的鹿,按原版会分割为 4袋,每袋肉重2.375 袋重显示为4.75kg,每袋都有整有零
改版后直接分割成了 4袋2kg,1袋1.7kg。
--------------------------
对鹿狼来说,也许这个变动并不明显。但对熊和驼鹿来说,假设不先切碎肉直接分割,则会出现每袋都有整有零,大量散肉的状况。
拿图举例


原版会分成逼死强迫症的 9.56 /袋。
因为不符合5的倍数。
43/5=8.6,向上取整为9袋。每袋肉 4.7777778,袋重9.555556 ,近似显示为9.56

而改好的mod版,则是8袋 10kg +1袋 6.04kg。
计算肉重为 8*5=40+6.04/2=43.02
效果实现。
-------------------------
各位强迫症,是不是感觉好多了?
做为合理党,我也觉得舒服多了。毕竟我是装满一个袋子才会装下一个。不可能给每个袋子都平均装,都装半袋。
-------------------------
分割到整数这项功能,从漫漫长夜1.44版的《圣火令V6》开始集成,会始终维持直到官方修改设定为止。
感谢你看到这里。第一篇分割取整教程到此为止。
本贴欢迎各种游戏设定的合理化讨论。如玩家在其他设定方面有好的想法,也许我们一起实现了呢?
对C#大神,各位码农或Unity引擎专精玩家,也希望能在很多方面多多交流,谢谢。
——圣火令 2018.12.28 PM 18:30


3DM翔哥 发表于 2018-12-28 19:55

逼死强迫症的分割

Hanxill 发表于 2018-12-29 14:17

原来是这样改的代码,{:3_113:}

2238231864 发表于 2019-1-2 21:23

辛苦辛苦

qq1065230 发表于 2019-2-4 04:38

{:3_142:}楼主知道修改体力是有关哪些吗←_←本来想直接搜冲刺的英文结果发现一堆之前又没改过←_←mod也没关这类的。。。

一只双眼皮 发表于 2019-2-4 10:16

qq1065230 发表于 2019-2-4 04:38
楼主知道修改体力是有关哪些吗←_←本来想直接搜冲刺的英文结果发现一堆之前又没改过←_←mod也没 ...

搜索Stamina相关。1.46之前可以直接锁Stamina下限。1.46直接锁的修改方法失效。倾向于这是版本bug。

qq1065230 发表于 2019-2-5 05:23

一开始找到的是加上限的发现加了好像不能达成我想要的效果,然后继续找发现了这个就是图片上的这行,翻译过来是每秒冲刺使用率,默认上限是100f这个就每秒用掉10f,然后不知道怎么改这个数值,楼主能说下吗←_←。。。。感谢

一只双眼皮 发表于 2019-2-13 18:05

qq1065230 发表于 2019-2-5 05:23
一开始找到的是加上限的发现加了好像不能达成我想要的效果,然后继续找发现了这个就是图片上的这行,翻译过 ...

不确定行不行的改法:把Range 的范围从 0 10 改为 0 0

qq1065230 发表于 2019-2-13 21:00

{:3_142:}那个···我只问的姿势不对,其实我是想说我不知道怎么改动,我右键点rang那行代码没编辑方法选项。

绯色彼岸花开 发表于 2019-5-15 14:27

画地图范围怎么改。。。。。
页: [1]
查看完整版本: 【2018.12.28】圣火令mod的制作过程(部分代码分析图示)及漫漫长夜设定讨论-第一篇:分割取整