
标题: DOS版三国志英杰传的研究心得——伍 [打印本页]
作者:
漫漫苦短 时间: 2025-8-9 19:19 标题: DOS版三国志英杰传的研究心得——伍
从前面几章的介绍来看,道具的数据也是有在内存中占有一块的数据空间,而且与人物的数据也是有联系的,这块数据究竟有多大,这个就是本章探索的问题。
不过说起道具,相信很多玩家想起英杰传的经典介绍。
《三国志英杰传》是KOEI出品的一个集战略模拟与角色扮演于一身的上乘之作。其故事与“三国”原著颇有关联,而且免去了繁琐的练兵、种田,并提供64种道具及30余种策略,让玩者在战场上杀得淋漓尽致。
虽然听上去64个道具很吸引眼球,不过实际上这似乎是个障眼法,有很多道具具有相似的功能,那么第一节就开始从道具的简介来了解英杰传的道具,然后再由已有的知识,结合道具的内存空间以及相关代码,获得更多道具相关的细节。
目录
- 一、道具的简介
- 二、道具数据的组成
- 三、道具价格的计算(买与卖)
- 四、道具的分类(1)
[ 本帖最后由 漫漫苦短 于 2025-11-9 19:21 编辑 ]
作者:
漫漫苦短 时间: 2025-8-19 19:19 标题: 一、道具的简介
对于这64个道具,根据已有的知识,可以先将它们分个几类,比如增加攻击力的武器:青龍偃月刀、蛇矛、方天畫戟等等;增加防御力的兵書:孫子兵法、吳子兵法、孟德新書等等;增加移动力的馬:赤兔馬、的盧、黃爪飛龍(没错,游戏中确实是叫这个名字);在每个行动回合开始自动恢復的道具:玉璽、赦命書、援軍報告;剩下的都是主动类道具(我军在行动回合操作使用的),并且是一次性道具,然后其实还可以再对这些道具进行一次再次分类,第一类只能对道具持有者使用并且有兵种使用限制的,比如有升职的,長槍、步兵車、連弩、發石車、馬鎧、近衛鎧、無賴精神、俠義精神,转职的,遁甲天書、青囊書、鼓吹具、弓術指南書、馬術指南書、劍術指南書。第二类只能对我军或友军使用的恢復用的道具,有必须指向的单体道具,酒、特級酒、老酒分别是三阶士气回复道具;豆、麥、米分别是三阶兵力回复道具;傷藥、中藥、茶分别是三阶士气兵力回复道具;有以使用者为中心的群体道具,平氣書、活氣書、勇氣書分别是三阶群体士气回复道具;援隊書、援部書、援軍書分别是三阶群体兵力回复道具。第三类只能对敌军使用的道具,濃霧書、雷陣雨書、豪雨書都是可以混乱敌军的,剩下的都是伤害类道具,焦熱書、火龍書、猛火書分别是三阶火系伤害道具;漩渦書、濁流書、海嘯書分别是三阶水系伤害道具;落石書、山崩書、山洪書分别是三阶石系伤害道具;最后还剩一个伤害道具炸弹,它是没有使用地形限制,然后伤害的算法也不太一样,算是特殊的道具。
根据上面的简要分析,先预估一个道具究竟需要多少字节来存储信息,首先需要1个字节来存储道具编号,64个道具对应16进制就是00至3F,还需要存储道具的名字,最长的道具有5个字,加上字符串末尾的0标志,就是11个字节,然后上述的道具分类,也需要1个字节存储,然后每个分类中每个道具的额外数值不一样,例如像攻击力的武器、防御力的兵書、移动力的馬的分类中可以有不同加成,升职和转职道具要记录变换的兵种和使用限制的兵种,这些也可能要占用几个字节,还有道具的黄金价格,最大的买道具的价格为2000(援軍書),最大的卖道具的价格为1910(不可买道具),但根据周瑜前辈的英杰传详细流程攻略,卖的道具可以由买的道具计算得出:
道具卖价是买价的75%,个位数直接舍去。
可以用2个字节记录买的价格或卖的价格,不过还有另一种可能性可能这个数据已经包含在前面的额外数值里。
那么实际上一个道具究竟在内存空间中占用多大的内存空间,每个字节究竟有什么作用,本章开始逐步分析。
作者:
漫漫苦短 时间: 2025-9-9 19:19 标题: 二、道具数据的组成
上节的简介已经将道具的现有知识,不过还有一部分疏漏,每个道具其实有一串比较长的文字叙述,这样其实每个道具占用的内存是比上节最后分析的内容要多。
如果用过龙吟或godtype以及其他作者的修改器,就会发现一个问题,如果要修改道具的名字属性等等,会修改BAKDATA.R3文件,但是如果改动道具的介绍的部分,则会改变MAIN.EXE的内容。上节讨论的道具的名字属性等等,也是程序通过读取BAKDATA.R3文件中道具的数据,并导入到内存空间中。而如果从内存分段的角度来说,这两部分都在DS段中,只是有部分数据是来自MAIN.EXE,可以称为内部数据,而来自BAKDATA.R3文件中的数据,可以称为外部数据,以下就简要分析外部数据的部分。
每个道具所占的(外部)数据共17个字节,对应的16进制的偏移就是00-10,但其实只有以下5个部分:
偏移+00 占n字节 道具名字
偏移+0D 占1字节 道具代码
偏移+0E 占1字节 道具购买黄金价格
偏移+0F 占1字节 道具特殊作用额外数值
偏移+10 占1字节 道具特殊作用
其中道具的名字占了13个字节的空间,但不是每个字节空间都被占用了,因为名字的长度不一样,但为了每个道具所占用的空间一样以及为了数据对齐的目的,这样就可以更加方便找到每个道具数据数据的首地址,强制占用了这些空间。一个汉字对应这2个字节的空间,这样看来可以把道具的名字最大改成为六个字的道具。
然后偏移+0E+0F+10就是本章将要讲述的重点,与上节的分析不太一致的地方就是道具购买黄金价格,这里只用了1个字节来记录,那么1个字节是如何记录道具购买黄金价格,下一节就开始分析一下。
[ 本帖最后由 漫漫苦短 于 2025-9-9 20:05 编辑 ]
作者:
漫漫苦短 时间: 2025-9-19 19:19 标题: 三、道具价格的计算(买与卖)
上一节提到了道具数据中只用了1个字节来记录购买黄金价格,如果过目了周瑜的英杰传详细流程攻略中的道具价格,就会看出所有的道具买与卖价格都是10的倍数,那么自然而然就有一个想法,像第肆章介绍的兵种基本兵力和兵种每等级兵力增幅,道具数据记录的购买黄金价格乘10就是游戏中看到的道具买的价格。
计算道具买的价格的代码,其中AX为道具的代码。
seg003:2041 6B F0 11 imul si, ax, 11h
seg003:2044 81 C6 1C BE add si, 0BE1Ch
seg003:2048 56 push si
seg003:2049 9A 3C 27 F0 3C call sub_3F63C
seg003:204E 2A E4 sub ah, ah
seg003:2050 6B F8 0A imul di, ax, 0Ah
计算道具卖的价格的代码,其中AX为道具的代码。
seg003:2532 6B F8 11 imul di, ax, 11h
seg003:2535 81 C7 1C BE add di, 0BE1Ch
seg003:2539 57 push di
seg003:253A 9A 3C 27 F0 3C call sub_3F63C
seg003:253F B1 03 mov cl, 3
seg003:2541 F6 E1 mul cl
seg003:2543 C1 E8 02 shr ax, 2
seg003:2546 6B F0 0A imul si, ax, 0Ah
可以看到都调用了sub_3F63C这个函数。
seg003:273C sub_3F63C proc far ; CODE XREF: sub_3EEB6+93↑P ; sub_3F29A+1A0↑P
seg003:273C
seg003:273C arg_0 = word ptr 6
seg003:273C
seg003:273C 55 push bp
seg003:273D 8B EC mov bp, sp
seg003:273F 8B 5E 06 mov bx, [bp+arg_0]
seg003:2742 8A 47 0E mov al, [bx+0Eh]
seg003:2745 C9 leave
seg003:2746 CA 02 00 retf 2
seg003:2746 sub_3F63C endp
买的部分的代码很简单,就是获取道具数据的偏移+0E的1字节保存在AL寄存器中,再乘10就是最终的价格,卖的部分的代码就需要注意一下计算的次序了。
作者:
漫漫苦短 时间: 2025-11-9 19:19 标题: 四、道具的分类(1)
这一节简单介绍道具特殊作用的分类,第一节的简单给道具作了分类,但这个分类只是根据我们在游戏中的经验作出的分类,而游戏中实际上对道具分了6大类。
dseg:3FE8 AA 5A BE B9 00 asc_447B8 text "BIG5", '武器',0 ; DATA XREF: dseg:400A↓o
dseg:3FED C5 DC B4 AB A5 CE 00 asc_447BD text "BIG5", '變換用',0 ; DATA XREF: dseg:400C↓o
dseg:3FF4 A7 F0 C0 BB A5 CE 00 asc_447C4 text "BIG5", '攻擊用',0 ; DATA XREF: dseg:400E↓o
dseg:3FFB AB EC B4 5F A5 CE 00 asc_447CB text "BIG5", '恢復用',0 ; DATA XREF: dseg:4010↓o
dseg:4002 B0 A8 00 asc_447D2 text "BIG5", '馬',0 ; DATA XREF: dseg:4012↓o
dseg:4005 A7 4C AE D1 00 asc_447D5 text "BIG5", '兵書',0 ; DATA XREF: dseg:4014↓o
dseg:400A E8 3F dw offset asc_447B8 ; "武器"
dseg:400C ED 3F dw offset asc_447BD ; "變換用"
dseg:400E F4 3F dw offset asc_447C4 ; "攻擊用"
dseg:4010 FB 3F dw offset asc_447CB ; "恢復用"
dseg:4012 02 40 dw offset asc_447D2 ; "馬"
dseg:4014 05 40 dw offset asc_447D5 ; "兵書"
也就是说前文介绍的“偏移+10 占1字节 道具特殊作用”只有6个值,00武器,01變換用,02攻擊用,03恢復用,04馬,05兵書,可以看到有一部分的猜想是准确的:
比如增加攻击力的武器:青龍偃月刀、蛇矛、方天畫戟等等;增加防御力的兵書:孫子兵法、吳子兵法、孟德新書等等;增加移动力的馬:赤兔馬、的盧、黃爪飛龍(没错,游戏中确实是叫这个名字);剩下的都是主动类道具(我军在行动回合操作使用的),并且是一次性道具
但玉璽、赦命書、援軍報告这3个道具却被归类到“恢復用”道具,而除了这3个,其他也被归类到“恢復用”道具例如酒、豆都是主动类一次性道具。
对于00武器,04馬,05兵書这三类道具,可以通过修改BAKDATA.R3,不仅能修改具体的额外数据,也能修改其分类,例如把00武器修改为04馬。
作者:
漫漫苦短 时间: 2025-11-19 19:19 标题: 五、道具的分类(2)
上一节介绍了游戏中实际上道具分的6大类,这一节对其中的一类"馬",也就是涉及部队移动力的道具介绍一下它所起的作用,关于移动力,曾经在五、人物数据的重要属性——兵种(4)有所介绍,当时还留了一部分代码没有介绍,此处正好将其补充介绍。
sub_33D26函数是计算部队移动力的方法,arg_0为部队战场数据的首地址。
seg002:6E26-seg002:6E6B是计算道具带来的移动力加成的计算并且保存到var_4中,由于涉及到道具的相关知识,本处省略其中的计算过程。
seg002:6E26 32 C0 xor al, al
seg002:6E28 88 46 FC mov [bp+var_4], al
seg002:6E2B 88 46 FE mov [bp+var_2], al
seg002:6E2E loc_33D4E: ; CODE XREF: sub_33D26+65↓j
seg002:6E2E 8A 46 FE mov al, [bp+var_2]
seg002:6E31 50 push ax
seg002:6E32 56 push si
seg002:6E33 9A DE C5 F6 1C call sub_2953E ; 获取部队第ax个道具的代码
seg002:6E38 88 46 FF mov [bp+var_1], al
seg002:6E3B 3C FF cmp al, 0FFh
seg002:6E3D 74 25 jz short loc_33D84
seg002:6E3F B0 11 mov al, 11h
seg002:6E41 F6 66 FF mul [bp+var_1]
seg002:6E44 05 1C BE add ax, 0BE1Ch
seg002:6E47 89 46 F6 mov [bp+var_A], ax
seg002:6E4A 50 push ax
seg002:6E4B 9A 68 6B F6 1C call sub_23AC8 ; 获取道具特殊作用
seg002:6E50 3C 04 cmp al, 4 ; 判断是不是04馬
seg002:6E52 75 10 jnz short loc_33D84
seg002:6E54 FF 76 F6 push [bp+var_A]
seg002:6E57 9A 5A 6B F6 1C call sub_23ABA ; 获取道具特殊作用额外数值
seg002:6E5C 3A 46 FC cmp al, [bp+var_4]
seg002:6E5F 76 03 jbe short loc_33D84
seg002:6E61 88 46 FC mov [bp+var_4], al ; 修改道具特殊作用额外数值最大值
seg002:6E64 loc_33D84:
seg002:6E64 FE 46 FE inc [bp+var_2]
seg002:6E67 80 7E FE 08 cmp [bp+var_2], 8
seg002:6E6B 72 C1 jb short loc_33D4E
这段代码有4个变量,var_1是道具代码,var_2是某个人物的道具编号,var_4是道具特殊作用额外数值最大值,var_A是根据道具代码计算出的道具数据的首地址。
代码的逻辑也不复杂,就是循环8个道具,seg002:6E3B先判断是不是空道具(FF),seg002:6E50判断这个道具是不是04馬,如果是04馬,就取出其特殊作用额外数值,seg002:6E5C将该数值与var_4比较,如果小于等于则跳转,否则在seg002:6E61修改var_4为该道具特殊作用额外数值。这也就保证了一个人物拥有赤兔马(+3移动力)或的卢(+2移动力),无论道具编号顺序是赤兔马在前或的卢在前,最后计算出的移动力加成都是3,而不是2或5。
从这段代码可以看到,一个道具是否具有能给部队增加移动力的功能,只与他的道具特殊作用(偏移+10 占1字节)是否为04馬,并不是与它的名称,买卖价格等属性有关,而它的特殊作用额外数值(偏移+0F 占1字节)也是只与这1个字节的数值有关。
同样也可以拓展一下,在未做代码修改的情况下,对于所有的道具,在00武器、04馬、05兵書三个额外作用中,他仅能拥有这三个额外作用中的一个,例如如果将赤兔马的特殊作用(偏移+10 占1字节)的值从04修改为05,那么这个赤兔马就不再具有馬(移动力加成)的功能,而是具有兵書(防御加成)即防御加成3%;而将霸王之剑的特殊作用的值从00修改为04,那么霸王之剑不再具有武器(攻击力加成)的功能,而是具有馬(移动力加成)即+24移动力,霸王之剑虽不再加成攻击力,但想去哪儿就去哪儿,赤兔马也只能望尘莫及。
[ 本帖最后由 漫漫苦短 于 2025-11-19 20:09 编辑 ]
| 欢迎光临 轩辕春秋文化论坛 (http://xycq.org.cn/forum/) |
Powered by Discuz! 5.0.0 |