PVZ一代修改教程:戴夫的话的修改相关
特别声明:本教程所说的PVZ仅指英文原版、汉化一以及汉化二及这三个版本的改版
阅读此教程前请确保以及会一些基础的修改及汇编
关于戴夫的话,研究最迟在2020年五月就完成了,具体的日期我记不清了。
当然,这里的教程不包括如何新增一个戴夫的动作,那不属于“戴夫的话”

如何修改原版戴夫的对话
在原版的pak中,properties文件夹里的LawnStrings.txt文件中,有若干结构为[CRAZY_DAVE_%d[1]]的片段。
下面摘抄一段英文原版的资料:
[CRAZY_DAVE_201]
Evening, {PLAYER_NAME}.
[CRAZY_DAVE_202]
Those zombies just won't let up, will they?
……
[CRAZY_DAVE_302]
You know what that means...
[CRAZY_DAVE_303]
Crazy Dave's Twiddydinkies is open for business! {MOUTH_SMALL_SMILE}
这下面就是对应的文本。
而其中比较特殊的文本段,例如{PLAYER_NAME}和{MOUTH_SMALL_SMILE}
这两段将会在后面进行说明。
在这里,来说明一下原版怎么确定戴夫的对话是怎么结束的。
首先,原版的代码会从一个特定的编号开始(可以结合后面的代码内容查看),然后从那里开始进行对话,例如从201开始,然后依次播放202、203、204等。
播放到207后,由于208编号没有对应的文本,所以戴夫就停止对话了。
简而言之,在修改pak的时候,如果增添一个208,就可以在207后面再添加一个对话了。
同样,后面在新增的时候,也要确定这一点,不要让他们连接起来[2]

特殊文本句段
我暂且把特殊文本句段分成两类,变量类句段和控制类句段[3]
变量类句段是指,他的内容实际上不会是你输入的内容,他会被一些特定内容给替换掉。
共有以下几种:
{PLAYER_NAME}
{MONEY}
{UPGRADE_COST}
{SELL_PRICE}
{PLANT_TYPE}
包括了:称呼玩家的名字、金钱、升级费用、花园里卖植物使用的价格和植物类型
由于这些句段命名过于直接,我就不详细说明了。
关于他们的代码实现原理,我会在后面进行论述。
控制类句段是指,他的内容会指定戴夫当前的动作是什么[4],在原版中,有以下几种:
{MOUTH_SMALL_SMILE}
{MOUTH_BIG_SMILE}
{SCREAM}
{SCREAM2}
{NO_SOUND}
{NO_CLICK}
{MOUTH_SMALL_OH}
{DELAY_%d}
{SHOW_WALLNUT}
{SHAKE}
{SHOW_TREE_FOOD}
临时收集,可能不全。
这些句段命名也过于直接,我也不详细说明了。
关于他们的代码实现原理,我会在后面进行论述。

添加关卡开头的戴夫对话
大概在0x0043AB96左右,有一连串的检测关卡,然后改写ebp+0x28的值
我们通过观察可以发现,ebp+0x28的值就是起始对话编号(上文的特定的编号),当检测到规定关卡时,运行这串代码。
所以,只用在这段加入检测其他关卡,然后改写ebp+0x28到自己在文本LawnStrings.txt文件中添加的新文本的编号,然后就完成了。
关于这段的实际原理请自行摸索,或参考下一节(在游戏中途叫出戴夫)进行分析

在游戏中途叫出戴夫
原版的一周目4-5,砸罐子中途,戴夫多次出现了。
这意味着,戴夫不仅可以在关卡开头出现,在关卡中途也可以出现[5]。
所以我们也可以在关卡中途调用戴夫。
由于我很久没用早忘了,也为了防止科技泛滥,这里我只提供我当初找到的思路:
①开一局一周目4-5
②找到波数指针([[[[6a9ec0]+768]+160]+60]或[[[[6a9ec0]+768]+160]+6C],依旧是记不清了[6])
③由于第一波、第二波、第三波的对话不一样,查找该指针的访问,可以轻易的找到我们需要的地址
请自行摸索

特殊句段的实现原理
使用OD可以发现,在0x00453E10往下很长一段,都有这些特殊句段的相关信息。
变量类句段原理->搜索到指定句段->替换该句段到指定的文本
替换句段时大量运用了几个函数
0x00513660 String_ReplaceSubString
0x00403E20 String_SetSubstring
具体原理依旧自己研究
控制类句段则大量运用了
0x004419A0 String_FindSubString_CharsNum
找到指定文本后,进行对应的操作。
而在实际显示文本时,会删去控制类句段[7]

关于Upsell的戴夫
Upsell的戴夫比较特殊,他不是点击进入下一句,而是依靠延迟实现[8]的。
具体研究方法类似上面,先找到3300(Upsell的开始段),然后查访问啥的。

结语
该教程不建议死搬硬套,建议理解后食用
教程写的不够亲民是因为不想让科技太泛滥,拥有一定的PVZ修改经验和编程知识是能看懂的。
由于戴夫可以让很多改版更好的介绍特性,我就把这个东西做成教程了
该文章写的比较匆忙,后面可能会进行一些修改

参考资料与文献
PVZ指针表
Hope_20121221_(贴吧名)等人于2011年、zjfaok(贴吧名)等人于2014年研究发布
崇明人家123(贴吧名)于2017、2018年收集整合
Dr丶小黑、康师傅豆腐、4573去、Ghastasaucey、六三enjoy(均为贴吧名)先后于2019到2021增添修补
PVZ函数表
失控的指令(贴吧名)于2020、2021年收集整理
诸位的研究
主要是Ghastasaucey、4573去在2020年进行的研究

注释
[1] %d见C语言,指的是十进制有符号整数,下文的{DELAY_%d}同理
[2] 原版的对话大多都隔着100及以上的间隔,所以一般不会连起来
[3] 这两个名词是自己命的,不要认为是专业的名词
[4] 其中{DELAY_%d}指定的不是动作
[5] 花园里也有类似的例子出现
[6] 颜色仅为方便辨认指针
[7] 删去的时机需要验证
[8] {DELAY_%d}

文章作者:Ghastasaucey