seg002:9DBD loc_36CDD: ; CODE XREF: sub_36C9C+3C↑j
seg002:9DBD C6 46 F6 00 mov [bp+var_A], 0 ; 長槍-短兵
seg002:9DC1 C6 46 F7 01 mov [bp+var_9], 1 ; 步兵車-长兵
seg002:9DC5 C6 46 F8 03 mov [bp+var_8], 3 ; 連弩-弓兵
seg002:9DC9 C6 46 F9 04 mov [bp+var_7], 4 ; 發石車-连弩兵
seg002:9DCD C6 46 FA 06 mov [bp+var_6], 6 ; 馬鎧-轻骑兵
seg002:9DD1 C6 46 FB 07 mov [bp+var_5], 7 ; 近衛鎧-重骑兵
seg002:9DD5 C6 46 FC 09 mov [bp+var_4], 9 ; 無賴精神-山贼
seg002:9DD9 C6 46 FD 0A mov [bp+var_3], 0Ah ; 俠義精神-恶贼
seg002:9DDD B0 0F mov al, 15
seg002:9DDF 88 46 E6 mov [bp+var_1A], al ; 長槍
seg002:9DE2 88 46 E8 mov [bp+var_18], al ; 連弩
seg002:9DE5 88 46 EA mov [bp+var_16], al ; 馬鎧
seg002:9DE8 88 46 EC mov [bp+var_14], al ; 無賴精神
seg002:9DEB B0 1E mov al, 30
seg002:9DED 88 46 E7 mov [bp+var_19], al ; 步兵車
seg002:9DF0 88 46 E9 mov [bp+var_17], al ; 發石車
seg002:9DF3 88 46 EB mov [bp+var_15], al ; 近衛鎧
seg002:9DF6 88 46 ED mov [bp+var_13], al ; 俠義精神
可以看到seg002:9DBD-9DF6都是一段非常有规律的代码,作用就是对着一堆var变量设置值,虽然可以一眼就看出其中的写法规律,但分析其中的实际作用还得看后续的代码。
seg002:9DF9 8A 46 08 mov al, byte ptr [bp+arg_2]
seg002:9DFC 2C 13 sub al, 13h
seg002:9DFE 88 46 FF mov [bp+var_1], al
seg002:9E01 56 push si
seg002:9E02 9A 6C 93 F2 2C call sub_3628C ; 获取部队兵种代码
seg002:9E07 8A 4E FF mov cl, [bp+var_1]
seg002:9E0A 2A ED sub ch, ch
seg002:9E0C 8B F9 mov di, cx
seg002:9E0E 38 43 F6 cmp [bp+di+var_A], al ; 判断是否是对应兵种
seg002:9E11 74 03 jz short loc_36D36
seg002:9E13 E9 98 00 jmp loc_36DCE ; 不是对应兵种
这段代码初看会觉得这里花里胡哨的。为什么seg002:9DFC要将部队兵种代码减去13h?为什么要把这个值先保存到var_1并且最后再传到di中,以及最后的seg002:9E0E为什么能实现兵种间的比较。
首先兵种代码保存在di中属于无奈之举,由于汇编代码的机器码指令有限,换句话说就是不能像高级语言编程一样可以各种定义变量以及实现各种复杂书写方式,所以只能实现一种特定的比较方式,在seg002:9E0E的这个比较中di只能被换成bx或si。而[bp+di+var_A]应该将其分为[bp+var_A]和di两部分来看待,而随着di值的变化,[bp+di+var_A]的最终指向的变量也会变化,这就是动态比较,而为了方便比较,通过兵种代码减去13h的操作,最终di的值的取值范围在0-7之间,例如di=0,那么[bp+di+var_A]实际上就是[bp+var_A],di=3,[bp+di+var_A]实际上是[bp+var_7],di=7,[bp+di+var_A]实际上是[bp+var_3],这样便实现了动态比较,比起通过逐个比较的代码而言相当简洁。
那么现在可以列明一个表格:
道具 長槍 步兵車 連弩 發石車 馬鎧 近衛鎧 無賴精神 俠義精神
道具代码 13 14 15 16 17 18 19 1A
di 0 1 2 3 4 5 6 7
变量 var_A var_9 var_8 var_7 var_6 var_5 var_4 var_3
兵种代码 00 1 3 4 6 7 9 0A
兵种 短兵 长兵 弓兵 連弩兵 輕騎兵 重騎兵 山賊 惡賊
这样每个道具就与升阶后的道具对应上了,但只对应上兵种可不行,还需要高出转职等级,不然可以体验一下10级的战车刘备。
seg002:9E16 loc_36D36: ; CODE XREF: sub_36C9C+95↑j
seg002:9E16 FF 76 EE push [bp+var_12]
seg002:9E19 9A DA 6A F6 1C call sub_23A3A ; 获取部队等级
seg002:9E1E 8B 7E FF mov di, word ptr [bp+var_1]
seg002:9E21 81 E7 FF 00 and di, 0FFh
seg002:9E25 89 7E E4 mov [bp+var_1C], di
seg002:9E28 38 43 E6 cmp [bp+di+var_1A], al ; 判断等级是否满足
seg002:9E2B 77 7A ja short loc_36DC7 ; 等級不夠使用道具
有了上面的表格和解释,如何比较等级的表格也不难得出:
道具 長槍 步兵車 連弩 發石車 馬鎧 近衛鎧 無賴精神 俠義精神
道具代码 13 14 15 16 17 18 19 1A
di 0 1 2 3 4 5 6 7
变量 var_1A var_19 var_18 var_17 var_16 var_15 var_14 var_13
等级 15 30 15 30 15 30 15 30
接下来会在屏幕上显示升阶后的兵种,并显示08變換級別的声音,再修改兵种后,还会显示部队兵种变化。
seg002:9E2D 8A 5B F6 mov bl, [bp+di+var_A]
seg002:9E30 2A FF sub bh, bh
seg002:9E32 03 DB add bx, bx
seg002:9E34 81 C3 A4 0A add bx, 0AA4h
seg002:9E38 89 5E E2 mov [bp+var_1E], bx
seg002:9E3B FF 37 push word ptr [bx]
seg002:9E3D 1E push ds
seg002:9E3E 68 F4 3A push 3AF4h ; "將部隊變換成%s."
seg002:9E41 6A 02 push 2
seg002:9E43 9A 42 32 F6 1C call sub_201A2 ;显示升阶后的兵种
seg002:9E48 83 C4 08 add sp, 8
seg002:9E4B 0B C0 or ax, ax
seg002:9E4D 75 03 jnz short loc_36D72
seg002:9E4F E9 74 06 jmp loc_373E6
seg002:9E52 loc_36D72: ; CODE XREF: sub_36C9C+D1↑j
seg002:9E52 6A 08 push 8 ; 08變換級別
seg002:9E54 68 80 54 push 5480h
seg002:9E57 9A 9C 57 F6 1C call sub_226FC ; 修改音效
seg002:9E5F 8A 43 F6 mov al, [bp+di+var_A]
seg002:9E62 FE C0 inc al ; 升职后兵种代码
seg002:9E64 50 push ax
seg002:9E65 FF 76 EE push [bp+var_12]
seg002:9E68 9A 68 93 F6 1C call sub_262C8 ; 修改部队兵种系代码
seg002:9E83 8B 5E E2 mov bx, [bp+var_1E]
seg002:9E86 FF 37 push word ptr [bx]
seg002:9E88 FF 76 EE push [bp+var_12]
seg002:9E8B 9A 58 39 F6 1C call sub_208B8 ; 名字的偏移地址
seg002:9E90 50 push ax
seg002:9E91 1E push ds
seg002:9E92 68 05 3B push offset aSS_0 ; "%s變成%s了!"
seg002:9E95 loc_36DB5: ; CODE XREF: sub_36C9C+6FE↓j
seg002:9E95 6A 00 push 0
seg002:9E97 9A 42 32 F6 1C call sub_201A2 ;显示部队兵种变化
但需要注意一个细节,就是seg002:9E34为什么是把bx的值加上0AA4h,在兵种的显示部分已经讲过了兵种的指引地址是从ds:0AA2开始的,而升阶后的兵种都是当前兵种的下一个兵种,将当前兵种对应的指引地址+2就是升阶后的兵种,个人认为这肯定不是一种巧合,而是故意设计的,因为这样可以方便代码的设计。
这样关于01變換用的道具就讲完了,接下来还要介绍02攻擊用和03恢復用的道具,这俩类道具最大的特点就是,大多数都有策略与之匹配,如焦熱書和焦熱,補給和麥,豪雨書和偽裝,也有些特例,玉璽、赦命書、援軍報告这三个道具虽然属于03恢復用道具,但没有对应的策略(本来就不是使用类道具),而大漩渦大山崩等大策略以及牽制挑撥欺壓三种策略没有对应的道具(不然谁买一大堆焦熱書)。