| | |
|
刘国公 广南东路经略使 枢密直学士 ★★★★★★★★★★★★ ★★★
| |
| | |
|
| | |
|
组别 | 经略使 |
级别 | 卫将军 |
好贴 | 1 |
功绩 | 1314 |
帖子 | 6207 |
编号 | 111321 |
注册 | 2007-2-18 |
来自 | 我家 |
家族 | 轩辕学院 |
| |
| | |
|
|
|
第三部分 曹操传修改相关知识
一、内存
内存是非常重要的,在运行过程中程序对数据的读取都是从内存中读出并加以计算、修改,好借data.e5里面的数据就是在程序运行的时候就按一定的格式首先存入到内存的指定位置中。
在岱瀛的《解读KOEI曹操传代码》的最后面就有提到常用的一些内存地址,还有ssbye的《曹操传修改的实用汇总》里面有更多的内存资料,请详细阅读。我在这里只解释几个常用的。
=====================
1、4927F0
从4927F0开始存放了相当多的物理攻击的战斗信息,在程序中常有这样一句:MOV ECX,4927F0,而它的后面就有很多[ECX+1]、[ECX+4]……,具体的内容是:
4927F0+0 发动攻击的武将的战场编号(战场编号00-0E是我军,0F-22是友军,23-72是敌军)(BYTE)
4927F0+1 当前被攻击武将的战场编号(BYTE)
4927F0+4 发动攻击的武将的Data编号(512人的data就是000-1FF,1024人的data就是000-3FF)(DWORD)
4927F0+8 发动攻击的武将Data内存地址(DWORD)
4927F0+C 发动攻击的武将战场内存地址(DWORD)
4927F0+10 开始存放所有被攻击武将的战场编号,一共是73H*1(所有被攻击武将,指的就是穿透攻击中其他受影响的武将)(BYTE)
4927F0+84 开始是全体被攻击武将按被攻击顺序存放HP伤害值,一共是73H*4(DWORD)
4927F0+254 开始是全体被攻击武将按被攻击顺序存放MP伤害值,一共是73H*4(DWORD)
4927F0+424 穿透范围(BYTE)
4927F0+425和426 当前被攻击武将的坐标(BYTE)
4927F0+428 发动攻击的武将所得到的个人经验(DWORD)
4927F0+42C 发动攻击的武将所得到的武器经验(DWORD)
4927F0+430 开始是全体被攻击武将所得到的防具经验,一共是73H*4(DWORD)
4927F0+600 是否AI攻击
4927F0+604 是否发生爆击(DWORD)
4927F0+608 是否连击(BYTE)
4927F0+60C 是人物挨打动作播放时位移抖动的横坐标(DWORD)
4927F0+610 是人物挨打动作播放时位移抖动的纵坐标(DWORD)
4927F0+614 通常直接用492E04使用,是反击以及反击后反击的标志(DWORD)
=====================
2、497AF8
跟4927F0相类似,497AF8是存放使用策略的信息,具体的内容是:
497AF8+0 是策略编号(BYTE)
497AF8+1 是使用策略的武将的战场序号(BYTE)
497AF8+4 是使用策略的武将的DATA内存地址(DWORD)
497AF8+8 是使用策略的武将的战场内存地址(DWORD)
497AF8+C 是当前被策略攻击或被策略恢复、提升武将的战场序号(BYTE)
497AF8+D 开始是全体被策略攻击或被策略恢复、提升武将的战场序号,一共是73H*1(BYTE)
497AF8+84 开始是全体被策略攻击武将按被攻击顺序存放伤害值,一共是73H*4(DWORD)
497AF8+254 是策略效果标识(BYTE)
497AF8+255 开始是全体被策略攻击武将按被攻击顺序存放实际策略效果标识,一共是73H*1(这个在一般情况下是统一跟+254的标识值一样,但是特殊的多组合效果策略就会用到不同的效果标识,例如八阵和玄武)
497AF8+2C9和+2CA 分别是使用的策略的攻击范围和穿透范围(BYTE)
497AF8+2D0 是使用策略的武将所得到的个人经验(DWORD)
497AF8+2D4 是使用策略的武将所得到的武器经验(DWORD)
497AF8+2D8 开始是全体被策略攻击武将所得到的防具经验,一共是73H*4(DWORD)
497AF8+4A8 (暂未详细分析,只有0和1两个值,对应的是使用策略的武将是否可以控制。BYTE)
497AF8+4AC 最终输出用,表示是否成功使用策略,0不成功并返回选择策略界面,1成功并结束武将行动(DWORD)
497AF8+4B0 策略动画相关
因为与4927F0相类似,所以不多写了,注意如果是使用对已方的策略,攻击武将就是使用策略的武将,被攻击武将就是目标武将。
=====================
3、4B2C50
战场内存地址,按每个战场编号24H个字节排列。
在程序中常见这样的两条指令:
IMUL ECX,ECX,24
ADD ECX,004B2C50
就是根据4927F0中攻防双方的战场编号,得出战场内存地址。攻击方可以直接从[4927F0+C]中读出,而被攻击方就要从[4927F0+1]中读出战场编号再加上上面这两条指令才能读出战场内存地址。
而24H个字节具体的内容如下(没有标出为未知):
00-03:武将的Data序号
04:是战场形象编号
05:属于哪一方,00代表我军,01是友军,大于等于02是敌军
06:战场横坐标
07:战场纵坐标
0B:AI的行动顺序
0C:判断武将是否可见,01不可见,02可见,03撤退
0D:叠加数值。00是未行动,02与04同时存在就是已行动,08表示S形象的左右翻转
0E:是否能被玩家直接控制,07表示可控
0F:表示人物朝向,数值是0(上),1(右),2(下),3(左)
10-13:HPcur
14:MPcur
18:攻击状态,03为正常状态,大于03为提升,小于03为衰弱
19:防御状态
1A:精神状态
1B:爆发状态
1C:士气状态
1D:移动状态
1E:表示人物健康状态:00和01代表正常,02和03是麻痹,04和05是禁咒,06和07是麻痹加禁咒,08和09是混乱,0a和0b是麻痹加混乱,0c和0d是禁咒加混乱,0e和0f是混乱加麻痹加禁咒.10和11是中毒,12和13是麻痹加中毒,14和15是禁咒加中毒,16和17是麻痹加禁咒加中毒,18和19是混乱加中毒,1a和1b是麻痹加混乱加中毒,1c和1d是禁咒加混乱加中毒,1e和1f是禁咒加麻痹加混乱加中毒
08-0A与AI行动有关:
原帖由 star175 于 2009-8-10 12:07 发表
4B2C50 +8 和AI行动方针有关
+8 +9 +A +E(如果为7就是可控)
被动出击 FF 3
主动出击 FF 1
坚守原地 FF 2
攻击我将 要攻击武将的战场编号 0
到指定点 FF X Y 0
跟随武将 要跟随武将的战场编号 4
逃到指定点 FF X Y 4 =====================
4、4A1B68 或 0D60000
武将DATA内存。按每个武将的data编号48H个字节排列。其中512人data是从4A1B68开始,而1024人data就从0D60000开始,而STAR175的5.2版引擎开始采用了一种新方法,由系统自动安排DATA内存的起始位置。
在程序中常见这样的两条指令:
IMUL ECX,ECX,48
ADD ECX,004A1B68 或 ADD ECX,0D60000
就是根据武将的DATA编号(大部分情况下都是从战场内存地址的00-03中取出来)得出DATA内存地址。
而48H个字节具体的内容如下(没有标出为未知):
00-01:表示武将DATA编号,其中01位置为1X。比如0号武将就是00 10 ,1号武将就是01 10
02-03:R剧本形象代号
04-05:武将头像地址
08-0F:武将姓名(8字节,4个中文)
10:保留给武将姓名的结束符?
11-12:攻击力
13-14:防御力
15-16:精神力
17-18:爆发力
19-1A:士气
1C-1F:HP
20:MP
21-25:武统智敏运
26:致命一击台词类型
27:出阵场数
29:撤退场数
2A:是否我军,00是我军,FF不是我军
2B:兵种
2C:武将等级
2D:经验值
2E-30:武器编号、等级、经验
31-33:防具编号、等级、经验
34:辅助品
37-48:R剧本点击该人物是显示的名字
上面的是将五围从单字节扩展到双字节后(即突破255上限)的内容,如果是原版未突破255的,攻防精爆士的位置是15-19。
=====================
5、4B0770
也是常见的:MOV ECX,4B0770,从这里开始存放的内容也很重要,基本上都是存档中内容。
挑选几个简单说一下:
+6,即4B0776是章编号,0号武将的头像从第3章(章编号2)开始会从face.e5的第1-4张图片转用第5-8张图片,就是从这里判断的,当然具体的程序代码在其他地方。
C-F,即4B077C—4B077F是金钱的地址
+12,即4B0782是忠奸度
+13开始,即4B0783开始,每三位是一种武器或者防具或者辅助,一直到004B09DA为止。
其他的可以看岱瀛的帖,不多说了。
=====================
6、其他一些从DATA中导入的内存地址
1)物品属性(68H个)
IMUL ECX,ECX,19
ADD ECX,004A1140
2)部队属性(35H个)
IMUL ECX,ECX,1B
ADD ECX,004ABFA0
3)地形资料(1BH个)
IMUL ECX,ECX,3C
ADD ECX,004AE4E0
4)商店资料(3AH个 或 7FH个)
IMUL ECX,ECX,28
ADD ECX,004AEB68 或 ADD ECX,0D72000
商店有两种,同样是因为1024DATA的原因
5)策略属性(44H个)
IMUL ECX,ECX,46
ADD ECX,004AF4C0
以上的具体内容请参阅ssbye的《曹操传修改的实用汇总》。
=====================
7、497750
这个比较冷门,但是假如要修改消耗品,就要用到。基本用法与4927F0相似。MOV ECX,497750
[ECX]消耗品编号
[ECX+1]消耗品效果(3F-4C,HP恢复、MP恢复……)
[ECX+2]使用者战场编号(使用者就是点击道具的那个人)
[ECX+3]受用者战场编号(受用者就是道具用在谁的身上)
[ECX+4]使用者战场内存地址
[ECX+8]受用者战场内存地址
[ECX+C]使用者DATA内存地址
[ECX+10]受用者DATA内存地址
[ECX+14]道具DATA内存地址(4A1140+57*68开始,57就是第一个消耗品的编号)
[ECX+18]道具使用范围
[ECX+1C]结束使用用,表示是否成功使用道具,0不成功并返回选择界面,1成功并扣除道具数量后结束武将行动
想开发新类型的消耗品,就必须明白以上的几个关系。
=====================
=====================
二、常用到的指令以及组合
1、武将身上是否有某特效的装备
新人最喜欢改的东西。用到的子程序就是407A09,如果该特效还要从DATA中设置效果值,后面还需要一条407AF2读取效果值。这两条子程序都需要一个ECX值和一个参数输入,这个参数就是特效号,未扩展过的就是12-3E,而ECX的值是该武将的DATA内存地址,注意如果该特效是攻击方用的,就要先从攻击武将的战场内存中取出攻击武将的DATA编号,然后再转成攻击武将的DATA内存地址输入到ECX中,最后才能接相关的子程序。具体的格式如下:
MOV ECX,DWORD PTR SS:[EBP-4] ——这里假设[EBP-4]中已经存放了武将的DATA内存地址
PUSH 12 ——12就是特效号
CALL 407A09 ——执行判断是否带有12特效号的装备
TEST EAX,EAX
JE **** ——根据上一条TEST,这里表示没有12特效号的装备就跳到下一项内容中,如果用JNZ就表示带有12特效号的装备就跳到下一项内容中。后面接着的者是否则的内容。
这个时候如果是不需要在DATA中设置效果值的特效,就从这里开始写效果代码;如果需要在DATA中设置效果值,就加上以下指令:
MOV ECX,DWORD PTR SS:[EBP-4] ——同样需要将武将的DATA内存地址放进ECX中
PUSH 12 ——特效号必须作为输入参数1输入进去
CALL 407AF2 ——读取DATA效果值(当然这个值其实一早已经存进从4A1140开始的内存中,程序只是从内存中通过计算后,取出来而已)
AND EAX,0FF ——这个可用可不用,因为407AF2出来的值只是AL的值,所以有的时候需要零扩展一下,将EAX中除了AL,其他位置全清零。
后面同样是开始写效果代码。
2、获取武将的兵种
主要有406610、41DF70、4077D0、43B470,前两个是获取武将的兵种,后两个是获取武将的大兵种类。
406610与41DF70的区别是,406610直接从输入的ECX(武将的DATA内存地址)中取出对应+2B位置里面的代码,而41DF70是从输入的ECX(武将的战场内存地址)中取出武将的DATA编号,然后再转成武将的DATA内存地址,最后调用一次406610取出兵种代码。两者具体的原版代码如下:
00406610 /$ 55 PUSH EBP
00406611 |. 8BEC MOV EBP,ESP
00406613 |. 51 PUSH ECX
00406614 |. 894D FC MOV DWORD PTR SS:[EBP-4],ECX
00406617 |. 8B45 FC MOV EAX,DWORD PTR SS:[EBP-4]
0040661A |. 8A40 2B MOV AL,BYTE PTR DS:[EAX+2B]
0040661D |. 8BE5 MOV ESP,EBP
0040661F |. 5D POP EBP
00406620 \. C3 RETN
0041DF70 /$ 55 PUSH EBP
0041DF71 |. 8BEC MOV EBP,ESP
0041DF73 |. 51 PUSH ECX
0041DF74 |. 894D FC MOV DWORD PTR SS:[EBP-4],ECX
0041DF77 |. 8B45 FC MOV EAX,DWORD PTR SS:[EBP-4]
0041DF7A |. 8B08 MOV ECX,DWORD PTR DS:[EAX]
0041DF7C |. 6BC9 48 IMUL ECX,ECX,48
0041DF7F |. 81C1 681B4A00 ADD ECX,004A1B68
0041DF85 |. E8 8686FEFF CALL 00406610
0041DF8A |. 8BE5 MOV ESP,EBP
0041DF8C |. 5D POP EBP
0041DF8D \. C3 RETN
4077D0和43B470之间的关系也同样道理。
3、异常类攻击与概率测试
先看一段代码:
00405953 |. 6A 3C |PUSH 3C
00405955 |. E8 D8A10700 |CALL 0047FB32
0040595A |. 83C4 04 |ADD ESP,4
0040595D |. 85C0 |TEST EAX,EAX
0040595F |. 74 18 |JE SHORT 00405979
00405961 |. 6A 08 |PUSH 8
00405963 |. 8B45 F4 |MOV EAX,DWORD PTR SS:[EBP-C]
00405966 |. 33C9 |XOR ECX,ECX
00405968 |. 8A48 01 |MOV CL,BYTE PTR DS:[EAX+1]
0040596B |. 6BC9 24 |IMUL ECX,ECX,24
0040596E |. 81C1 502C4B00 |ADD ECX,004B2C50
00405974 |. E8 470D0000 |CALL 004066C0
以上是原版中,混乱攻击兵种的效果代码。其中47FB32是概率测试函数,需要输入一个参数作为需要测试概率,即是否有60%的机率发生(复习一下以前的知识,这里要用ADD ESP,4是因为47FB32的结尾是用RETN)。TEST是看这60%机率是否发生了,JE是没有发生就跳到下一项代码。这样概率测试就完成了,接下来这60%机率发生了,所以就要让被攻击的武将混乱,所以PUSH 8是4066C0的输入参数1,至于为什么是8?看前面内存部分4B2C50有关内容。这里的[EBP-C]存放的就是4927F0,所以[EAX+1]就是被攻击武将的战场编号,然后转成战场内存地址,调用4066C0,让被攻击武将添加上混乱的状态,完成。
4、其他主要的函数的用途,请看周大的《曹操传exe部分函数功能》
5、暂时想不到还有什么常用的,就先到此为止。
==============================
追加几条战场内存与DATA内存的算法
从战场内存地址计算DATA内存地址
MOV ECX,<战场内存地址>
MOV ECX,[ECX]
IMUL ECX,ECX,48
ADD ECX,4A1B68 <==要根据不同的引擎来实际改变
从DATA内存地址计算战场内存地址
1
MOV ECX,<DATA内存地址>
CALL 00477ADC
MOV CL,AL <==必须先加测试AL是否等于0FF,0FF表示不在战场必须跳过
AND ECX,0FF
IMUL ECX,ECX,24
ADD ECX,004B2C50
2
PUSH <DATA编号>
CALL 0043E4D6
ADD ESP,4
MOV CL,AL <==必须先加测试AL是否等于0FF,0FF表示不在战场必须跳过
AND ECX,0FF
IMUL ECX,ECX,24
ADD ECX,004B2C50
3
PUSH <DATA编号>
CALL 4796DC
ADD ESP,4
MOV ECX,EAX <==必须先加测试EAX是否等于0FFFF,0FFFF表示不在战场必须跳过
IMUL ECX,ECX,24
ADD ECX,004B2C50
[ 本帖最后由 godtype 于 2014-3-18 15:00 编辑 ]
|
|
|