轩辕春秋文化论坛 » 曹操传MOD制作交流 » 基于STAR 5.7 、5.6 的[原创武将] 修改(更新贴)


2010-12-31 02:23 永不言弃
基于STAR 5.7 、5.6 的[原创武将] 修改(更新贴)

基于STAR 5.7 、5.6 的[原创武将] 修改


    支持创建6 名原创武将并且能够由玩家自由设定五围能力、头像、兵种,
    另一个方面MOD 作者则可以根据玩家所选择的兵种职业来为原创武将指定不同的R、S 造型、必杀与成长方向等等。
    增加原创武将名检测方案避免与其它武将名重复,感谢godtype毅大提供!

    由外部DLL 链接实现(语言为VC++),游戏引擎只需少量修改(5.6 与 5.7 版的修改方法完全一样)




   
    *. 注: 1. 通过改造[71H: 特效请求] 指令, 特效值指定为原创武将的DATA 编号(若指定大于1023 的值会导致指令不被执行,
               MOD 作者可以自由定制这些值的处理)。

            2. 使用了[4050]、[4051]号整型变量来设置8 种玩家可选兵种职业,数值为修改器里看到的值加1,每一字节表示一种
               可选职业(如: 轻步兵的兵种编号为3,则这里应设置为4),若不指定可选职业则默认为群雄玩家将无其它选择。

            3. [71H: 特效请求] 指令处理函数返回时会在[4050]号整型变量返回玩家选择的职业项目,MOD作者可以测试这个变量
               的结果,若为0 表示玩家选择的是第一种职业(如:剧本设置了四种可选职业分别为群雄、轻骑兵、弓弩手和刺客
               当71H 指令返回后4050 号整型变量的值为1 表示玩家选择的职业为轻骑兵)。

            4. [71H: 特效请求] 指令处理函数返回时会在[4051]号整型变量返回原创武将的性别(0表示男性,1表示女性),MOD
               作者可以使用[77H: 变量运算] 指令针对[4051]号整型变量修改战场特殊形象编号。如:77: 整型变量 4051 += 5,
               若原创为男性则战场特殊形象编号将被指定为5,若原创为男性则战场特殊形象编号将被指定为6。

            5. 可以通过修改[创建原创武将对话框]导出函数的几个参数对系统加以控制:

            (VC++函数原形)
              _DKEXPORTS_API  BOOL  _DkOriPerCreateDlg(
                                                      <DWORD: 版本信息>,                // 0:表示5.6版,1:表示5.7版
                                                      <DWORD: 武将名检测范围>,                 // 0:表示禁用
                                                      <DWORD: 请求武将DATA编号>,
                                                      <DWORD: 分配点数总和>,
                                                      <DWORD: 武将默认的标准能力值>,
                                                      <DWORD: 武将极限能力值>);

            (对应反汇编形式默认设置)
                      005181EA    6A 5A                push    5A
                      005181EC    6A 46                push    46
                      005181EE    6A 28                push    28
                      005181F0    FF75 FC              push    dword ptr [ebp-4]
                      005181F3    68 00040000          push    400
                      005181F8    6A 01                push    1
                      005181FA    FFD0                 call    eax


            6. 剧本中少不免会使用武将名来作一些编排(最明显的就是S 剧本的[19H: 胜利条件]指令,如:“失败条件:XXX死亡
               ,若XXX 为原创武将时MOD 作者将无法知道玩家实际的输入的名字),所以为剧本中一些指令者都作了格式化处理
               只要剧本指令内容中包括*.x (x 的取值范围为1 ~6 对应1 ~6号原创武将)都可以自动转换为真实武将名。

               通过测试的指令包括:
               [12H: 选择框]
               [14H: 对话](如:&*.2\n你好!我的名字是*.2。)
               [15H: 战场对话2]
               [16H: 信息]
               [17H: 场所名]
               [18H: 事件名设定]
               [19H: 胜利条件]
               [1AH: 显示胜利条件]
               [2CH: 地图文字显示]
               [63H: 单挑对话]
               [67H: 章名]
               [69H: 旁白]
               (若测试中发现还有其它指令无法格式化的话请各位回复本贴子)

            7. 由于游戏程序不会主动刷新武将SAV 映射中的武将名和R 剧本武将名这两个字段,所以使用了一个name.e5 的文件
               来保存玩家输入的人物姓名,在游戏存档时写入到这个文件,读档时则先从data.e5 中读出存档中所有原创武将的姓
               名到SAV 映射,之后再从name.e5 文件中读入武将原创名,这样做目的是防止A 存档中有DATA 号XX 武将为原创武将
               ,而B 存档没有XX 号原创武将导致的武将名显示错误。

            8. 原创武将的真彩头像男女各10张,编号安排到600 (908 - 301 - 7) 处,所以Tou.dll 文件要增加头像了,与之对应
               的小头像 Face.e5 文件则应该增加导入到608 ~ 627 处

               对于Tou.dll 由于是借用别人MOD 里的我没有BMP 文件而一张一张重新导入十分浪费时间,我的做法是使用ResHacker
               将DLL 文件中的所有位图全部导出再修改资源脚本后重新编译,若想使用这种方法可以下载《源代码与旧版修改说明》

               真彩头像工程文件(编写语言为Win32asm)或者到岱大新引擎发布贴中下载VC 工程。

            9. 使用[71H: 特效请求] 指令之前必须先使用[3BH: 武将加入],另外本系统是基于五围能力单数显示的,大家测试代码
               前请先将引擎改为单数显示。
                                                                                                                                  (详细语法请参照剧本事例)
;--------------------------------------------------------------------------------------------------------------------

[color=Silver][[i] 本帖最后由 永不言弃 于 2011-9-6 23:13 编辑 [/i]][/color]

2010-12-31 02:24 永不言弃
第一部分修改: 装配 _text2.bin 文件

    1. 运行LordPE ==> [选项] ==> 在[PE 编辑器] 一栏中选上[区段表:自动修正镜像大小] ==> [确定]

    2. 点[PE编辑器] ==> 打开Ekd5.exe ==> [区段] ==> 右键 ==> [从磁盘载入段] ==> 打开 _text2.bin 文件
       ==>   提示:区段载入成功 :)

    3. 在[_text2.b] 区块上右键 ==> [编辑区段] ==> 将[名称] 改为:.text2

    4. 点[标志] 傍边的[ ..] 按钮设置[区段标志] ==> 取消[包含未初始化数据] 的勾选 ==> [确定]
       (此时[标志] 值为:E0000060) ==> [保存] ==> 退出LordPE

;--------------------------------------------------------------------------------------------------------------------

第二部分修改: 反汇编修改

    (1). 更改[武将情报]时真彩头像显示控制

       00407660     /E9 00010000   jmp     00407765

    (2). 游戏启动时装载_DkExports.dll

       0047558C    - E9 8F2B0A00   jmp     00518120

    (3). 游戏退出时卸载_DkExports.dll

       00409239    - E9 0EEF1000   jmp     0051814C

    (4). 原创武将名存档读出处理

       0041ADC1    - E9 9ED30F00   jmp     00518164

    (5). 原创武将名存档写入处理

       0041B22E    - E9 55CF0F00   jmp     00518188

    (6). 注册[71H: 特效请求] 指令处理函数入口地址

       拷贝二进数据于00410C02 处: B4 81 51 00

    (7). 从EEX 剧本映射中读取文字格式化处理

       004179C3     80FA 2A       |cmp     dl, 2A
       004179C6     75 06         |jnz     short 004179CE
       004179C8     FF15 A0805100 |call    dword ptr [5180A0]
       004179CE     80FA 20       cmp     dl, 20
       004179D1     7D 35         jge     short 00417A08
       004179D3     80FA 0A       cmp     dl, 0A
       004179D6     75 12         |jnz     short 004179EA
       004179D8     90            nop
       004179D9     90            |nop
       004179DA     90            nop

         二进制数据:

         80 FA 2A 75 06 FF 15 A0 80 51 00 80 FA 20 7D 35 80 FA 0A 75 12 90 90 90


    (8). [14H: 对话] 指令武将真彩头像显示格式化处理

       004137F3    80F9 0A           ||cmp     cl, 0A
       004137F6    74 26             ||je      short 0041381E
       004137F8    80F9 2A           ||cmp     cl, 2A
       004137FB    75 06             ||jnz     short 00413803
       004137FD    FF15 A4805100     call    dword ptr [5180A4]
       00413803    8B55 F4           mov     edx, dword ptr [ebp-C]
       00413806    888C2A F0FBFFFF   mov     byte ptr [edx+ebp-410], cl
       0041380D    FF45 F4           ||inc     dword ptr [ebp-C]

         二进制数据:

         80 F9 0A 74 26 80 F9 2A 75 06 FF 15 A4 80 51 00 8B 55 F4 88 8C 2A F0 FB FF FF FF 45 F4

    (9). [1AH: 显示胜利条件] 指令内容格式化处理

       0044BF23    0FB602          ||movzx   eax, byte ptr [edx]
       0044BF26    84C0            test    al, al
       0044BF28    74 37           je      short 0044BF61
       0044BF2A    3C 2A           cmp     al, 2A
       0044BF2C    75 06           jnz     short 0044BF34
       0044BF2E    FF15 A8805100   call    dword ptr [5180A8]
       0044BF34    3C 0A           ||cmp     al, 0A
       0044BF36    75 0C           jnz     short 0044BF44
       0044BF38    90              nop

         二进制数据:

         0F B6 02 84 C0 74 37 3C 2A 75 06 FF 15 A8 80 51 00 3C 0A 75 0C 90

    (10). [18H: 事件名设定] 指令内容格式化处理

       0040BB4B   B8 28114A00     mov   eax, 004A1128
       0040BB50   50              push  eax
       0040BB51   FF75 08         push  dword ptr [ebp+8]
       0040BB54   50              push  eax
       0040BB55   E8 4BBE0000     call  004179A5
       0040BB5A   90              nop
       0040BB5B   90              nop
       0040BB5C   90              nop
       0040BB5D   90              nop
       0040BB5E   90              nop
       0040BB5F   90              nop
       0040BB60 |.E8 AAA90600     call  0047650F
       0040BB65   90              nop
       0040BB66   90              nop
       0040BB67   90              nop
       0040BB68   90              nop
       0040BB69   90              nop
       0040BB6A   90              nop
       0040BB6B   90              nop

         二进制数据:

         B8 28 11 4A 00 50 FF 75 08 50 E8 4B BE 00 00 90 90 90 90 90 90 E8 AA A9 06 00 90 90 90 90 90 90
         90

;-----------------------------------------------------------------------------------------------------------

2010-12-31 02:25 永不言弃
_DkExports.dll 与游戏引擎接口的数据说明,非常重要!


    *. 注: 1. 这部分数据位于 _DkOriPerInitInsVar 函数内,当 _DkExports.dll 被装入内存时被初始化为指定值,
               游戏改动导致无法自创武将、读写自创武将名失败、格式化自创武将名失败等时参考修改


        g_lpProcAddrHead = (LPDWORD)0x518090;                // 自建_DkExports.dll输入表入口地址(首地址0x518090存放了DLL模块句柄)
        lpDwordVar = (LPDWORD)0x4B6A60;
        g_hInstanceMain = (HINSTANCE)*lpDwordVar;        // 主模块句柄
        lpDwordVar += 2;
        g_hWinMain = (HWND)*lpDwordVar;                                // 主窗口句柄
        lpDwordVar = (LPDWORD)0x500EF5;
        g_hTouDll = (HMODULE)*lpDwordVar;                        // TouDll模块句柄
        lpDwordVar = (LPDWORD)0x4CEA00;
        g_lpSavImage = (LPBYTE)*lpDwordVar;                // 武将SAV映射指针
        g_lpNameImage = (PORI_PER_NAME_IMAGE)0x518010;                // 原创武将检索区域组入口
        g_lpGalVar_4050 = (LPDWORD)0x505F48;                // 4050号整形变量地址
        _48BEA8H = 0x48BEA8;                                                // 兵种名地址数组

        _4179B4H = 0x4179B4;        // 从EEX 剧本映射中读取文字格式化处理时成功返回
        _417A08H = 0x417A08;        // 从EEX 剧本映射中读取文字格式化处理时非自创武将返回
        _41383CH = 0x41383C;        // [14H: 对话] 指令武将真彩头像显示格式化处理时成功返回
        _413801H = 0x413801;        // [14H: 对话] 指令武将真彩头像显示格式化处理时非自创武将返回
        _44BEF5H = 0x44BEF5;        // [1AH: 显示胜利条件] 指令内容格式化处理时成功返回
        _44BF44H = 0x44BF44;        // [1AH: 显示胜利条件] 指令内容格式化处理时非自创武将返回


         反汇编形式(左侧虚拟地址看玩家的系统而定):

       021D20AC    C705 A8B11D02 90805100   mov     dword ptr [21DB1A8], 518090
       021D20B6    C745 F4 606A4B00         mov     dword ptr [ebp-C], 4B6A60
       021D20BD    8B45 F4                  mov     eax, dword ptr [ebp-C]
       021D20C0    8B08                     mov     ecx, dword ptr [eax]
       021D20C2    890D D0B11D02            mov     dword ptr [21DB1D0], ecx
       021D20C8    8B45 F4                  mov     eax, dword ptr [ebp-C]
       021D20CB    83C0 08                  add     eax, 8
       021D20CE    8945 F4                  mov     dword ptr [ebp-C], eax
       021D20D1    8B45 F4                  mov     eax, dword ptr [ebp-C]
       021D20D4    8B08                     mov     ecx, dword ptr [eax]
       021D20D6    890D CCB11D02            mov     dword ptr [21DB1CC], ecx
       021D20DC    C745 F4 F50E5000         mov     dword ptr [ebp-C], 500EF5
       021D20E3    8B45 F4                  mov     eax, dword ptr [ebp-C]
       021D20E6    8B08                     mov     ecx, dword ptr [eax]
       021D20E8    890D C8B11D02            mov     dword ptr [21DB1C8], ecx
       021D20EE    C745 F4 00EA4C00         mov     dword ptr [ebp-C], 4CEA00
       021D20F5    8B45 F4                  mov     eax, dword ptr [ebp-C]
       021D20F8    8B08                     mov     ecx, dword ptr [eax]
       021D20FA    890D C0B11D02            mov     dword ptr [21DB1C0], ecx
       021D2100    C705 B8B11D02 10805100   mov     dword ptr [21DB1B8], 518010
       021D210A    C705 ACB11D02 485F5000   mov     dword ptr [21DB1AC], 505F48
       021D2114    C705 98B11D02 A8BE4800   mov     dword ptr [21DB198], 48BEA8
       021D211E    C705 94B11D02 B4794100   mov     dword ptr [21DB194], 4179B4
       021D2128    C705 90B11D02 087A4100   mov     dword ptr [21DB190], 417A08
       021D2132    C705 8CB11D02 3C384100   mov     dword ptr [21DB18C], 41383C
       021D213C    C705 88B11D02 01384100   mov     dword ptr [21DB188], 413801
       021D2146    C705 84B11D02 F5BE4400   mov     dword ptr [21DB184], 44BEF5
       021D2150    C705 80B11D02 44BF4400   mov     dword ptr [21DB180], 44BF44

;-----------------------------------------------------------------------------------------------------------

_test2.bin 内容文件说明:


    *. 注: 1. 游戏改动导致无法自创武将、读写自创武将名失败、格式化自创武将名失败等时参考修改


一: 初始化原创武将检索区域内存,增加_DkExports.dll 名字符串,初始化导入函数地址表
    (00 数据进入游戏时会被映射)

00518000  CE E4 BD AB BC EC CB F7 C7 F8 D3 F2 CA BC 00 00  武将检索区域始..
00518010  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
00518020  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
00518030  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
00518040  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
00518050  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
00518060  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
00518070  5F 44 6B 45 78 70 6F 72 74 73 2E 64 6C 6C 00 00  _DkExports.dll..
00518080  B5 BC C8 EB BA AF CA FD B5 D8 D6 B7 B1 ED 00 00  导入函数地址表..
00518090  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
005180A0  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
005180B0  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
005180C0  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
005180D0  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
005180E0  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
005180F0  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
00518100  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
00518110  00 00 00 00 00 00 00 00 B4 FA C2 EB C7 F8 00 00  ........代码区..


二: 反汇编代码部分

    (1). 游戏启动成功时装载_DkExports.dll

00518120    68 70805100       push    00518070                               ; ASCII "_DkExports.dll"
00518125    FF15 24614800     call    dword ptr [<&KERNEL32.LoadLibraryA>]   ; kernel32.LoadLibraryA
0051812B    09C0              or      eax, eax
0051812D  - 0F84 7BD4F5FF     je      004755AE
00518133    BA 90805100       mov     edx, 00518090
00518138    8902              mov     dword ptr [edx], eax
0051813A    6A 00             push    0
0051813C    68 F4010000       push    1F4
00518141  - E9 4DD4F5FF       jmp     00475593


    (2). 游戏退出时卸载_DkExports.dll

0051814C    B8 90805100       mov     eax, 00518090
00518151    FF30              push    dword ptr [eax]
00518153    FF15 1C614800     call    dword ptr [<&KERNEL32.FreeLibrary>]    ; kernel32.FreeLibrary
00518159  - E9 A134F1FF       jmp     0042B5FF


    (3). 原创武将名存档读出处理

00518164    B8 90805100       mov     eax, 00518090
00518169    B9 01000000       mov     ecx, 1
0051816E    8D0488            lea     eax, dword ptr [eax+ecx*4]
00518171    8B00              mov     eax, dword ptr [eax]
00518173    09C0              or      eax, eax
00518175    74 05             je      short 0051817C
00518177    FF75 08           push    dword ptr [ebp+8]
0051817A    FFD0              call    eax
0051817C  - E9 D171FBFF       jmp     004CF352


    (4). 原创武将名存档写入处理

00518188    FF75 08           push    dword ptr [ebp+8]
0051818B    E8 3A6DFBFF       call    004CEECA
00518190    B8 90805100       mov     eax, 00518090
00518195    B9 02000000       mov     ecx, 2
0051819A    8D0488            lea     eax, dword ptr [eax+ecx*4]
0051819D    8B00              mov     eax, dword ptr [eax]
0051819F    09C0              or      eax, eax
005181A1    74 05             je      short 005181A8
005181A3    FF75 08           push    dword ptr [ebp+8]
005181A6    FFD0              call    eax
005181A8  - E9 8930F0FF       jmp     0041B236


    (5). [71H: 特效请求] 指令处理函数

005181B4    55                push    ebp
005181B5    8BEC              mov     ebp, esp
005181B7    83C4 FC           add     esp, -4
005181BA    6A 04             push    4
005181BC    8B4D 08           mov     ecx, dword ptr [ebp+8]
005181BF    E8 3302F0FF       call    004183F7
005181C4    3D 00000080       cmp     eax, 80000000
005181C9    74 07             je      short 005181D2
005181CB    3D FF030000       cmp     eax, 3FF
005181D0    76 02             jbe     short 005181D4
005181D2    EB 33             jmp     short 00518207
005181D4    8945 FC           mov     dword ptr [ebp-4], eax
005181D7    B8 90805100       mov     eax, 00518090
005181DC    B9 03000000       mov     ecx, 3
005181E1    8D0488            lea     eax, dword ptr [eax+ecx*4]
005181E4    8B00              mov     eax, dword ptr [eax]
005181E6    0BC0              or      eax, eax
005181E8    74 1D             je      short 00518207
005181EA    6A 5A             push    5A
005181EC    6A 46             push    46
005181EE    6A 28             push    28
005181F0    FF75 FC           push    dword ptr [ebp-4]
005181F3    68 00040000       push    400
005181F8    6A 01             push    1
005181FA    FFD0              call    eax
005181FC    0BC0              or      eax, eax
005181FE    74 07             je      short 00518207
00518200    B8 01000000       mov     eax, 1
00518205    EB 05             jmp     short 0051820C
00518207    B8 05000000       mov     eax, 5
0051820C    C9                leave
0051820D    C2 0400           retn    4


    (6). 00518220 以后未使用,可自由发挥

;-----------------------------------------------------------------------------------------------------------

2010-12-31 02:25 永不言弃
[12.31更新]使用VC++ 重写代码,增加原创武将名检测方案避免与其它武将名重复,感谢godtype毅大提供!

2010-12-31 02:28 Axie89
咦。。?好像和蛇夫座的原创武将一样。。。:doubt:

2010-12-31 08:29 godtype
回复 #5 Axie89 的帖子

凭4楼的一句话就已经知道是他本人了,因为只有我跟他提过那个建议,而且原帖已经有注明了。

2010-12-31 10:01 513633522
新的啊:hz1001:

2010-12-31 10:01 bastenbaty
东西不错,慢慢研读吧

2011-1-1 09:16 冯励
占个楼来看看。:hz1019:

2011-1-1 10:47 狂煞∑小星
顶一个,好久没上轩辕了。

2011-1-21 20:11 一流也
第一部分修改: 装配 _text2.bin 文件看的懂,也修改成功了,其他的看不懂,
第二部分修改: 反汇编修改,说明,我看不懂,要用什么软体?要怎么修改呢?

2011-4-14 15:09 王友良
问个基本问题

自创武将,可不可以定为主角,也就是游戏的主角留空,让玩家自定

2011-4-14 15:11 王友良
基于STAR 5.6 的[原创武将] 修改的问题

我用了这里的一个引擎,结果,兵种名和职业名不对称,好像是职业名少了两个。STAR5.6是完整的

2011-4-14 15:27 王友良
怎么没有这个文件运行不了呢!(MSVCR100D.dll)

2011-4-16 06:01 王友良
我错了,原来这个引擎真的很实用,多谢楼主了!

2011-5-5 03:25 cswaccz
不知在说什么?怎么使用啊?

2011-5-5 08:27 kawxov1815
太好了!可以有自創武將

太好了!可以有自創武將,將來MOD自由化會更哦!

2011-5-6 01:50 cswaccz
楼主说详细点怎么修改使用?

2011-5-6 08:21 513633522
回复 #1 永不言弃 的帖子

啥时候在godtybe的5.0上搞个自创武将:hz1024:

2011-9-6 23:10 永不言弃
回复 #14 王友良 的帖子

太久没上论坛了,没注意你的问题,对不起!
一楼,已将[项目][配置属性][C/C++][代码生成][运行库]设置为:[多线程:(/MTd)]
MTD会自动定义 _DEBUG
应该不会再提示找不到:MSVCR100.DLL与MSVCR100D.DLL

[color=Silver][[i] 本帖最后由 永不言弃 于 2011-9-6 23:17 编辑 [/i]][/color]

2012-12-16 12:46 狂煞∑小星
时隔一年,回来挖个坟。话说5.8修正版发布后,再按照你的5.6、5.7的修改方法去修改,已经木有用了说,哪位仁兄可以改一下5.8修正版的……:hz1005:

2012-12-16 12:52 狂煞∑小星
(6). 注册[71H: 特效请求] 指令处理函数入口地址

    拷贝二进数据于00410C02 处: B4 81 51 00

其实我一直都没看懂这条要怎么操作的说……

页: [1]


Powered by Discuz! Archiver 5.0.0  © 2001-2006 Comsenz Inc.