找回密码
 注册
搜索
查看: 4265|回复: 2

[L2] MD版梦幻模拟战2地图形象的限制及解决

[复制链接]
发表于 2017-5-8 22:07 | 显示全部楼层 |阅读模式
本帖最后由 衔着鱼D猫 于 2017-5-8 22:09 编辑

作者:huangzhihui007(痕)
来源:https://tieba.baidu.com/p/4138786848



MD版的L2内建有许多机制来限制或者实现某些功能,比如AT、MP之类的数值有上限,某些道具不会掉落,圣剑只有某些人能用等等。
本文所要说的也是其中一个,关于指挥官和佣兵的地图形象的限制。
起因是有人问我为什么把敌军替换成友军会出现地图形象错乱,然后就找时间调试了一下,把这个问题的原因和解决方法做了出来。
首先是通过调试发现的游戏机制:
1、指挥官的地图形象上限为18个,这个是由显存限制的,对应的显存地址0x300-0x347。其中我方及NPC方为10个,敌方为8个,这个是由游戏程序设定的,职业跟形象的对应关系在内存地址0xa7fe-0xa84d,每4字节为一个指挥官的对应,共20个,所以关卡中同时登场的部队上限为20个。
2、佣兵的地图形象上限为26个,这个也是由显存限制的,对应的显存地址0x348-0x3af。佣兵的形象也分阵营,判断标准是看指挥官的阵营,而不是看佣兵本身是什么阵营的兵种。其中我方及NPC方为16个,敌方为10个,这个也是由游戏程序设定的,佣兵跟形象的对应关系在内存0xa84e-0xa8b5,每4字节为一个兵种的对应,共26个。其中我方及NPC方的形象被程序设定为0x62-0x71。而敌方的佣兵形象则根据实际登场的兵种写入内存0xa88e-0xa8b5。
3、第七个佣兵即召唤物的地图形象上限为4个,这个也是由显存限制的,对应的显存地址为0x3f0-0x3ff,召唤物跟形象的对应关系在内存0xa8b6-0xa8c5,每4字节为一个兵种的对应,共4个。


可以看到内存地址划分为我方一块,敌方一块,如果其中一块超出了限制就会出现问题。所以这种把内存地址划分为敌我两方的设定导致了几个问题:
1、指挥官形象中,如果其中一方的形象数量超出了上限,即使总数量没有超过18也会出现形象错乱
2、佣兵形象中,游戏程序默认把0x62-0x71共16个兵种设定为我方及NPC方的佣兵形象,所以我方及NPC方的阵营使用敌方的兵种会花屏,而敌方的上限只有10个,超过这个数量也会花屏


所以这就是为什么把敌军替换成友军会出现地图形象错乱,因为友军形象数量超出限制了。原因找到了,解决方法也比较简单,把这种内存划分去掉就好了。


去掉指挥官形象阵营限制比较简单,就改一个地方:
112D6:movea.w #$6500,A0 (307C6500)
修改成
112D6:nop nop (4E714E71)


去掉佣兵形象阵营限制比较麻烦,需要把程序修改成全部佣兵都按实际登场来加载形象:
11390:moveq #$f,D6 (7C0F) -> moveq #$0,D6 (7C00)
11410:movea.w #$7100,A0 (307C7100) -> movea.w #$6900,A0 (307C6900)
1141A:lea $ffa88e.l,A2 (45F9FFFFA88E) -> lea $ffa84e.l,A2 (45F9FFFFA84E)
11432:bne $114c8 (66000094) -> 11432:nop nop (4e714e71)
11454:lea $ffa88e.l,A4 (49F9FFFFA88E) -> lea $ffa84e.l,A4 (49F9FFFFA84E)
11684:moveq #$f,D0 (700F) -> moveq #$19,D0 (7019)
116C2:lea $ffa88e.l,A0 (41F9FFFFA88E) -> lea $ffa84e.l,A0 (41F9FFFFA88E)
116C8:moveq #$9,D0 (7009) -> moveq #$19,D0 (7019)


这样就完了,看效果






成品在这,不会修改的可以跟狼组原版ROM对比一下修改的地方
修复形象错误:http://pan.baidu.com/s/1jGD8zFS
另外附一个改着玩的东西,有兴趣的可以看看,从0x150000开始是判断值,按职业代码排列,一个职业一个字节,可以自己修改,满FF可以行动。
判断测试版:http://pan.baidu.com/s/1sjknWmT
 楼主| 发表于 2017-5-8 22:08 | 显示全部楼层
武器掉落控制:



防具掉落控制:



饰品掉落控制:




简单解释一下第一张图:
1行:将D1这个寄存器清空
2行:读取指挥官的装备代码到D1
3行:如果D1=0则跳转到0x15728,从0x156da开始是物品掉落的程序,这个跳转就是直接跳过掉落
4行:把D1与0xE比较
5行:如果相等则跳转到0x15728,即跳过掉落
6行:把D1与0x26比较
7行:如果相等则跳转到0x15728,即跳过掉落
8行:把D1与0xD比较
9行:如果不相等则跳转到0x156da,即跳转到物品掉落的程序
10行:从内存0xa49c读取两个字节,与0x1B比较,0xa49c是保存关卡编号的地方
11行:如果大于0x1B,则跳转到0x15728,即跳过掉落,意思是27关以后的关卡都不掉落物品,这里是27关以后,那么为什么27关都不掉落物品呢,原因在前面一点的地方,0x156a6这里就判断了如果是27关就直接跳过全部掉落




12行:从这里开始是物品掉落的程序,不继续分析了


然后想要全部都不掉落物品,很简单,修改ROM:
不掉落武器:156B6: 67 -> 60
不掉落防具:15732: 67 -> 60
不掉落饰品:1579E: 67 -> 60
而如果想更简洁一点的话,也可以,修改一个字节就行了:
全部物品不掉落:156AC:67 -> 60
根据需要自己选吧。
然后还想说的是,汇编没有你想象中的那么难,其实汇编只是把各种运算用符号用字母来表示而已,开始的时候我也是什么都看不懂,然后像查字典一样一个一个命令去查指令书,才能看懂。这种感觉就像是,刚学会加减的时候,不会乘除,你会觉得乘除难,学会乘除的时候,不会乘方开方,你会觉得乘方开方很难。当你全部都学会了,你就会觉得,只不过是换了一个符号,换了一种运算而已,并不难。
 楼主| 发表于 2017-5-8 22:09 | 显示全部楼层
修复形象错误 修正版


去掉指挥官形象阵营限制:
112D6:movea.w #$6500,A0 (307C6500)
修改成
112D6:nop nop (4e714e71)


去掉佣兵形象阵营限制:
11432:bne $114c8 (66000094) -> 11432:nop nop (4e714e71)
11454:lea $ffa88e.l,A4 (49F9FFFFA88E) -> lea $ffa84e.l,A4 (49F9FFFFA84E)
11684:moveq #$f,D0 (700F) -> moveq #$19,D0 (7019)
116C2:lea $ffa88e.l,A0 (41F9FFFFA88E) -> lea $ffa84e.l,A0 (41F9FFFFA84E)
116C8:moveq #$9,D0 (7009) -> moveq #$19,D0 (7019)


修复没有行动结束形象的兵种:


版本A:有黑白形象的用黑白形象,没有的用彩色形象
a588:addi.w #$68,D6 (06460068) -> jump $150200 (4ef900150200)
a58c:bra $a5b6


150200:moveq #$0,D1 (7200)
150202:move.b ($0,A3),D1 (122b0000)
150206:cmpi.b #$62,D1 (0c010062)
15020A:blt $15021E (6d000012)
15020E:cmpi.b #$71,D1 (0c010071)
150212:bgt $15021E (6e00000A)
150216:addi.w #$68,D6 (06460068)
15021A:jump $00a5b6 (4ef90000a5b6)
15021E:jump $00a534 (4ef90000a534)


版本B:佣兵全用彩色形象
a56c:bne $a534 -> bra $a534


版本C:指挥官和佣兵全用彩色形象
a56c:bne $a534 -> bra $a534
a510:bne $a534 -> bra $a534


成品:http://pan.baidu.com/s/1dDc6qDb
您需要登录后才可以回帖 登录 | 注册

本版积分规则

Archiver|手机版|虎纹猫家园

GMT+8, 2024-11-21 23:50 , Processed in 0.048951 second(s), 15 queries .

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

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