三国群英2吧 关注:42,596贴子:989,187

修正版1.05+修改内容的具体说明

只看楼主收藏回复

一楼祭天


IP属地:美国1楼2018-04-02 16:42回复
    (这个红标题好像关不掉了……)
    本贴用以说明修正版1.05+所涉及的内容的具体修改方法。
    声明:并非所有内容都属原创。一些方法复制粘贴自他人成果,有的未求甚解。如(gu)果(ji)以(bu)后(tai)有(ke)空(neng),或许会把这些原理补全。
    以下列出了具体内容。如果您只对部分内容感兴趣,可按编号或标题在本贴内进行查找。
    本体修改内容:
    7./12. 空城招降和非空城招降
    8. 32位窗口化
    9. 播放MP3格式背景音乐
    10. 修复唯一物品在“回主选单”后重开的进程中可能无法搜到
    11. 修复大地图地形不随季节变化的BUG
    13. 支持在脚本中使用SYSCALL 0x213-219读取内存中的值或字符串
    14. 支持在脚本中使用SYSCALL 0x119召唤伏兵高级兵
    15. 支持在Things.ini中,主将/士兵/弓箭动画序列里加入!xxxxx启动脚本
    16. 修复用“进入城内”调部队入空城时,超员产生的BUG
    24. 修正生死门可能吸走武将
    25. 修正三圣华斩、五岳华斩武将技可能无法结束
    附加内容修改内容:
    1. 不斩将
    2. 等级上限和体力技力上限破解
    3. 假打概率
    4. 玩家武将自动升级补丁
    5. 显示技能等级(竖排)
    6. 修复逼近敌军、偷袭敌军等造成错位
    7. 修正君主招降


    IP属地:美国2楼2018-04-02 16:51
    回复
      7./12. 空城招降和非空城招降
      之前我和@G仔童鞋 大神讨论过相当一段时间。原贴见https://tieba.baidu.com/p/4440503065 .
      总结来看:空城招降BUG的核心有两处:
      一是该队伍被创建时,其君主指向城池所属君主(为空)。问题核心点在 ZhaoXiang__1(0x40EEAA) 函数。这解释了该BUG发生时为何不显示队伍。
      二是即使队伍君主正确,大地图显示队伍,但在自动进城时,仍然导致BUG的发生。核心点在 TroopEnterCity (0x438E59) 函数中,本质是0x438EF9位置,将城池所属方设置为该城池【主将】的君主。由于被招降武将的君主还未来得及设置,仍为空,最终导致城池君主为空。此现象和君主招降有密切的联系。
      感谢 @G仔童鞋 @醉听西风 的资料。
      关于目前的非空城招降修改:
      由于修正版1.05+的性质,我的想法是尽可能保持原汁原味。因此,遵照原版设置,被招降武将原则上应投入出发地城池,且在原城池易主时,会导致送将给对方。
      不过,当原城池满员的时候,仍然送将给对方就显得不太自然。于是我修改成,被招降武将属于我方,并举着我方旗帜;但如果原城池易主,且城容未满,则由于君主招降机制,该武将被所属方抓走。我认为这种改法是不大改原版逻辑的情况下最自然的。
      这也是我没有采取@G仔童鞋 大神在 https://tieba.baidu.com/p/5307326769 一贴中的修改方法的原因。
      需处理非空城招降的修复法:
      从:
      E2C7: 5B
      E2CD: 55
      E306: 83 7D
      E309: 00 75 17 68 41 04 00 00 68 5C 8C 48 00 68 78 8C 48 00 E8 40 13 04 00 83 C4 0C 8B 4D 08 0F BF 51 3C 83 FA 32 7C 18 8B 45 08 0F BF 40 3C D1 E0 99 B9 03 00 00 00 F7 F9
      E341: 55 08 66 89 42 3C 8B 45 0C 50 8B 4D 08 51 E8 01 7E FF FF 83 C4
      E357: 8B 55 14 52 8B 45 08 50 E8 35 31 00 00 83 C4 08
      改为:
      E2C7: 54
      E2CD: 4E
      E306: 8B 45
      E309: 83 78 10 00 75 0D 8B 55 0C 52 50 E8 5F 67 FF FF 83 C4 08 8B 4D 08 0F BF 51 3C 83 FA 32 7C 18 8B 45 08 0F BF 40 3C D1 E0 99 B9 03 00 00 00 F7 F9 8B 55 08 66 89 42 3C
      E341: 45 0C 50 8B 4D 08 51 E8 08 7E FF FF 83 C4 08 8B 55 14 52 8B 45
      E357: 50 E8 3C 31 00 00 83 C4 08 8B 4D 0C 89 48 08 90

      只修复空城招降的修复法(修改方法来自 @醉听西风 ):
      从:
      E30A: 75 17 68 41 04 00 00 68 5C 8C 48 00 68 78 8C 48 00 E8 40 13 04 00 83 C4 0C
      改为:
      E30A: 8B 45 14 8B 48 10 85 C9 75 0F 8B 55 0C 52 50 E8 5A 67 FF FF 83 C4 08 90 90


      IP属地:美国3楼2018-04-02 17:03
      回复(2)
        8. 32位窗口化
        目前,实现了32位色窗口化的包括注册大神的32bitEXE,以及西风大神的简体版EXE。
        手头有一份西风大神的代码,查看后发现为了实现16位色和32位色均可窗口化,修改较为复杂。反而是反汇编比对注册大神的EXE和原版EXE得到的修改方法相对简单,代价是不再支持16位色窗口化。
        考虑到一般人非必要基本不会切16位色,采取了较为简单的改法。
        具体修改位置,重写了 SangoCopyBitmap (4513FA) 函数。由于本人对相关问题一窍不通,未深究具体修改原理。
        从:
        507FA: 55 8B EC 83 EC 28 C7 45 DC 20 00 00 00 8D 45 DC 50 8B 0D 00 67 4A 00 51
        50813: 15 00 67 4A 00 8B 02 FF 50 54 89 45 D8 83 7D D8 00 74 05 E9 8A 00 00 00 83 7D E8 08 75 08 8B 4D 10 89 4D FC EB 3A 83 7D E8 10 74 06 83 7D E8 0F 75 0A 8B 55 10 D1 E2 89 55 FC EB 24 83 7D E8 18 75 0B 8B 45 10 6B C0 03 89 45 FC EB 13 83 7D E8 20 75 0B 8B 4D 10 C1 E1 02 89 4D FC EB 02 EB 42 C7 45 D8 00 00 00 00 EB 09 8B 55 D8 83 C2 01 89 55 D8 8B 45 D8 3B 45 14 7D 28 8B 4D FC 51 8B 55 18 52 8B 45 0C 50 E8 72 CA 01 00 83 C4 0C 8B 4D 0C 03 4D 08 89 4D 0C 8B 55 18 03 55 FC 89 55 18 EB C7 8B E5 5D C3
        改为:
        507FA: 90 90 90 90 8B 44 24 10 85 C0 7E 66 8B 4C 24 08 53 55 8B 6C 24 1C 56 57
        50813: 7C 24 1C 8D 51 02 89 44 24 20 85 FF 7E 31 8B F5 8B CA 66 8B 06 83 C6 02 8A D8 83 C1 04 C0 E3 03 88 59 FA 8B D8 C1 EB 05 66 C1 E8 0A C0 E3 03 C0 E0 03 88 59 FB 88 41 FC 4F 75 D7 8B 7C 24 1C 8B 4C 24 14 8D 04 3F 03 E8 8B 44 24 20 03 D1 48 89 44 24 20 75 B5 5F 5E 5D 5B C3 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90


        IP属地:美国4楼2018-04-02 17:10
        收起回复
          10. 修复唯一物品在“回主选单”后重开的进程中可能无法搜到
          BUG成因是点“回主选单”后“开始游戏”时,标志唯一物品已被搜到的字节不会被复位。也就是说,如果之前一局某一唯一物品已被搜走,则回主选单重开后,该物品将无法被搜到。
          解决方法:反正读档时也会读取该字节,只需保证开局时将它初始化为0即可。定位到点开时期的时候 (PreparePeriod, 42E233)。该函数连续调用若干参数相同的函数,优化了一下,把相同的压栈合并,腾出一堆字节。调用InitializeItemOwner(408680)解决问题。
          从:
          2D682: 83 C4 04 8B 45 FC 50 E8 F1 FA FF FF 83 C4 04 8B 4D FC 51 E8 56 F6 FF
          2D69A: 83 C4 04 8B 55 FC 52 E8 FD EE FF FF 83 C4 04 8B 45 FC 50 E8 94 F8 FF FF 83 C4 04 8B 4D FC 51 E8 F3 FB FF FF 83 C4 04 8B 55 FC 52 E8 46 FC FF FF 83 C4 04
          改为:
          2D682: E8 F8 FA FF FF E8 64 F6 FF FF E8 12 EF FF FF E8 B0 F8 FF FF E8 16 FC
          2D69A: FF E8 70 FC FF FF 83 C4 04 E8 D8 A3 FD FF 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90


          IP属地:美国6楼2018-04-02 17:23
          收起回复
            11. 修复大地图地形不随季节变化的BUG
            还记得Shape/Map/CHINAMAPX.msk中,只有CHINAMAP1是有用的吗?
            目标函数ChangeToSeason(0x41AB07)。一句话概括:奥汀忘了把当前季节的全局变量(g_nSeason, 0x4A6448)设置一下了……
            修改方法来自 @G仔童鞋 大神。我更倾向于原地修改,所以魔改了一下。也方便直接用UE改EXE的朋友。
            从:
            19F14: 83 3D
            19F1A: 00 74 0F 8B 0D 34 64 4A 00 51 E8 28 59 03 00 83 C4 04 68 34 64 4A 00 8B 15 48 64 4A 00 8B 04 95 B0 8A 48 00 50
            改为:
            19F14: 8B 0D
            19F1A: 85 C9 74 09 51 E8 2D 59 03 00 83 C4 04 8B 55 08 89 15 48 64 4A 00 68 34 64 4A 00 8B 04 95 B0 8A 48 00 50 90 90


            IP属地:美国7楼2018-04-02 17:31
            回复
              15. 支持在Things.ini中,主将/士兵/弓箭动画序列里加入!xxxxx启动脚本
              原贴见 https://tieba.baidu.com/p/3682361722
              思路和原来相同,仍然是挪用 MagicObjectProcess_0 (40AC82) 的代码:
              cmpdword ptr [ebp+C], 80000000h
              jne 453F71 //注:这里地址我是随便写的。要根据实际情况,跳到函数调用末尾返回的位置
              mov edx, [ebp+10]
              push edx
              mov eax, [ebp+8]
              push eax
              call 41F740 (DoScript_1)
              add esp, 8
              将这段内容加到以下三个函数:ForceSoldierObjectProcess_0(43DDBF),ForceMajorObjectProcess_0(43EF64)和ForceArrowObjectProcess_0(43E28B).
              这三条函数入口处马上就是大段的判断-跳转,判断不可能腾挪出空间原地修改。于是借用音乐部分的空间(见前面的9. 播放MP3格式背景音乐,那条废弃函数有很多空余空间),长跳过去,然后执行MagicObjectProcess的代码。
              修改内容过多,就不提供UE修改方法了,感兴趣的可以到1.05+的下载地址里面找到。


              IP属地:美国10楼2018-04-02 18:07
              回复
                13. 支持在脚本中使用SYSCALL 0x213-219读取内存中的值或字符串
                ……某论坛最近抽风效率有所下降啊。过了20分钟给我抽了。


                IP属地:美国11楼2018-04-02 18:15
                回复
                  补上楼图


                  IP属地:美国12楼2018-04-02 18:18
                  回复
                    14. 支持在脚本中使用SYSCALL 0x119召唤伏兵高级兵
                    原理:tieba.baidu.com/p/5318146257


                    IP属地:美国13楼2018-04-02 18:23
                    收起回复
                      16. 修复用“进入城内”调部队入空城时,超员产生的BUG
                      这句话什么意思呢?比如有一个6人队,遇到一个关卡,用“进入城内”把5个人调进去……然后就会发现该关卡的君主是空的。
                      严格来说这不算是一个BUG,因为原版玩家不可能有5人以上的队,而电脑不会使用“进入城内”。但如果修改者将出征人数提高,就有可能会引发BUG。所以我把它归类到“方便修改者”的特点中了。
                      修改方法来自 @醉听西风 。原始工具代码见后。
                      从:
                      199E8: 8B 15 D0 30 4C 00 52 8B 45 F4 8B 4D FC 8B 14 81 52 E8 95 C7 FE FF 83 C4 08 8B 45 F4 8B 4D FC 8B 14 81 52 E8 4E F1 FE FF 83 C4 04 85 C0 74 18 8B 45 F4 8B 4D FC 8B 14 81 52 A1 D0 30 4C 00 50 E8 E3 B1 FE FF 83 C4 08 8B 4D F4 8B 55 FC A1 D4 30 4C 00 8B 0C 8A
                      改为:
                      199E8: A1 D0 30 4C 00 50 8B 55 F4 8B 4D FC FF 34 91 83 78 10 00 75 19 8B 0D D4 30 4C 00 FF 71 08 50 E8 6C B0 FE FF 58 59 59 89 48 14 89 48 18 51 E8 78 C7 FE FF E8 3E F1 FE FF 59 5A 85 C0 74 0E 51 FF 35 D0 30 4C 00 E8 DD B1 FE FF 58 59 A1 D4 30 4C 00 90 90 90 90
                      =======================================


                      IP属地:美国15楼2018-04-02 22:06
                      回复
                        该楼层疑似违规已被系统折叠 查看此楼


                        IP属地:美国17楼2018-04-02 22:35
                        回复(1)
                          25. 修正三圣华斩、五岳华斩武将技可能无法结束
                          注:本修改是对Magic.so的修改。脚本可以重新编译,无需用UE直接改SO文件的字节,所以以下只提供代码。
                          坦诚讲我没研究出来华斩为什么会往回飞……目前感觉可能是奥汀的谜之浮点操作造成的。这或许说明了脚本的浮点运算有点问题。或许也不一定。
                          不过,要保证武将技结束却不困难:奥汀发现了华斩会射失,他们决定这是华斩特性的一部分;于是他们简单粗暴地加入了一个监测函数,当刀刃到达底线时删除刀刃物件,所有刀刃消失时结束武将技。
                          于是只需要在该函数中加一个倒计时就完事了,经过一段时间强制删除刀刃物件。这样即使它倒着飞也能结束。这段时间的长度可由 HalfMoonNewMotion() 函数得出。简单来说,它是刀刃飞过整个战场所需的时间,即GetBattleWidthInScreenX() / 36。
                          将以下函数直接替换同名函数即可。由于它可以被伪代码编译器直接编译,就不贴汇编的形式了。


                          IP属地:美国18楼2018-04-02 22:54
                          回复
                            附加内容修改内容:
                            1. 不斩将
                            众所周知,不斩将会导致玩家武将也不会被电脑斩首。当然这不是重点。重点是我用某修改器(划掉)改了之后,发现比预料之中的字节数要多……直觉上看,这种修改应该只需要把某个条件跳转改成JMP而已,似乎犯不着这么麻烦。用反汇编器仔细查才把另外一处不知道在干什么的改动排除。
                            结论:还是手动改。
                            3AD9: 73 -> EB


                            IP属地:美国19楼2018-04-02 23:23
                            收起回复
                              2. 等级上限和体力技力上限破解
                              以下改为您想要的等级上限,十六进制格式(暂不支持超过127 = 0x7F):
                              92E6: 63
                              9326: 63
                              以下改为您想要的HP/MP上限,十六进制格式(暂不支持超过32767 = 0x7F FF):
                              947E: FF 7F
                              9526: FF 7F
                              (转换为16进制后,以两位数为分隔成两段,然后把前后两段掉个个后输入。
                              例如 9999 = 0x27 0F, 则将上述两处改为 0F 27.)
                              注:遵照前人的改法。未涉及DALL+U这样的地方,可能不全面。


                              IP属地:美国20楼2018-04-02 23:26
                              回复