fucckz 发表于 2012-6-12 00:29:48

魔兽多种族模板

前言

自从魔兽3发布的那一天起,就有无数人尝试在游戏中添加娜迦这个种族,但在暴雪BT的限制下最终都没出现完美的自定义种族。
有了这个模板,你现在想添加什么种族就可以添加什么种族,并且可以自定义所添加种族的UI、音效,且不会和默认4族冲突。






我开发这个模板主要是用于我自己的一个mod(未完成),同时也希望更多人能使用这个模板做出些高质量的mod。


功能如图所示:
在种族下拉列表中添加了多个可选的item(理论上最多能够添加100个)。

可以给新种族添加独立的UI,互相间不冲突。 (我只用了鼠标指针做演示,指针数字对应种族在下拉列表中的index )

支持局域网多人游戏(BNET没测试过)





========================================================================

基于 1.260.6401(1.26a)修改,理论上1.24以上就可以了,但是我也没测试过。



如何安装和使用:

1. 复制以下文件去你的魔兽3根目录:(不要忘记备份Game.dll)

Race.mpq    -    自定义附件MPQ包,在游戏启动时加载。
Game.dll    -    修改过的 Game.dll(1.26a)
UserInterface    -    这个文件夹包含了自定义的UImpq包。(1.mpq对应人族,2.mpq对于兽族,依此类推。。。种族不使用自定义UI的话可以删除)
            *目前我只做了10个,自定义的鼠标指针,用于演示*

2. 所有对于游戏内如何生成新种族单位等等的说明,都在Race.mpq的Blizzard.j里。


.Sample\handicap2.w3x是一副测试判断选族的演示图,话说已经打包了Blizzard.j就不再需要它了呵呵。




========================================================================
已知BUG:
1. 随机种族无UI。               
[目前产生随机族的过程在游戏中实现,所以不知道加载什么UI如果玩家选了随机;我也可以使产生随机族的过程在没进入游戏前就实现,但是进入游戏后又不知道该生成什么单位。我还尝试过用API传值进游戏,但又会造成内存不同步,多人游戏掉线。无限蛋疼中。。。]

2. 在玩有队伍1,队伍2的地图时,自定义UI的加载会存在各种问题。

3. 目前在64位系统上各种不稳定。




========================================================================
Credits:
* 感谢Aeris在制作这个多种族模板时候给予我的帮助!

* 如遇bug欢迎给我发邮件反馈,谢谢。我的邮箱:[email protected]


*EDIT 2012-6-17*

2楼为原理图以及更详细的说明。

17楼放了自动整合地图脚本进Blizzard.j的小工具。(需要.NET FRAMEWORK 2.0 或以上)

fucckz 发表于 2012-6-12 00:30:30

看还有很多人不理解这个的东西,请看图:


还不明白的话我也不知道说什么好了。。。

*Race.mpq中存放自定义种族单位数据;

*Interface文件夹中按序列放置自定义UI mpq包;

*Blizzard.j 中实现种族判断的脚本:(核心为MeleeStartingUnits()这个函数)globals

//... ...



    // race constant
    constant integer   mc_RACE_HUMAN          = 1
    constant integer   mc_RACE_ORC            = 2
    constant integer   mc_RACE_UNDEAD         = 3
    constant integer   mc_RACE_NIGHTELF       = 4
    constant integer   mc_RACE_5            = 5
    constant integer   mc_RACE_6            = 6
    constant integer   mc_RACE_7            = 7
    constant integer   mc_RACE_8            = 8
    constant integer   mc_RACE_9            = 9
constant integer   mc_RACE_10             = 10

endglobals


//====================================================================

function MeleeStartingUnits takes nothing returns nothing
local integerindex
local player   indexPlayer
local location indexStartLoc
local integerindexRace

set index = 0
loop
   set indexPlayer = Player(index)
      if (GetPlayerSlotState(indexPlayer) == PLAYER_SLOT_STATE_PLAYING) then
            set indexStartLoc = GetStartLocationLoc(GetPlayerStartLocation(indexPlayer))
            set indexRace = R2I(GetPlayerHandicapBJ(indexPlayer))

            if (indexRace == 100) then
                // Player choose Random
            else
                // indexRace is a integer converted from real, so automatically add 1
                set indexRace=indexRace+1
            endif

            // Debug message, shows each player's choice.
            call BJDebugMsg( ( "Player"+I2S(index)+" RaceIndex:" + I2S(indexRace) ) )
            

            // Create initial race-specific starting units
            if (indexRace == mc_RACE_HUMAN) then
                call MeleeStartingUnitsHuman(indexPlayer, indexStartLoc, true, true, true)
            elseif (indexRace == mc_RACE_ORC) then
                call MeleeStartingUnitsOrc(indexPlayer, indexStartLoc, true, true, true)
            elseif (indexRace == mc_RACE_UNDEAD) then
                call MeleeStartingUnitsUndead(indexPlayer, indexStartLoc, true, true, true)
            elseif (indexRace == mc_RACE_NIGHTELF) then
                call MeleeStartingUnitsNightElf(indexPlayer, indexStartLoc, true, true, true)
            elseif (indexRace == mc_RACE_5) then
                call MeleeStartingUnitsUnknownRace(indexPlayer, indexStartLoc, true, true, true)
            elseif (indexRace == mc_RACE_6) then
                call MeleeStartingUnitsUnknownRace(indexPlayer, indexStartLoc, true, true, true)
            elseif (indexRace == mc_RACE_7) then
                call MeleeStartingUnitsUnknownRace(indexPlayer, indexStartLoc, true, true, true)
            elseif (indexRace == mc_RACE_8) then
                call MeleeStartingUnitsUnknownRace(indexPlayer, indexStartLoc, true, true, true)
            elseif (indexRace == mc_RACE_9) then
                call MeleeStartingUnitsUnknownRace(indexPlayer, indexStartLoc, true, true, true)
            elseif (indexRace == mc_RACE_10) then
                call MeleeStartingUnitsUnknownRace(indexPlayer, indexStartLoc, true, true, true)
            else
                call MeleeStartingUnitsUnknownRace(indexPlayer, indexStartLoc, true, true, true)
            endif
      endif
   set index = index + 1
   exitwhen index == bj_MAX_PLAYERS
endloop

endfunction


    -还原玩家handicap为100%,初始化自定义触发都可以在这条函数中完成。


*最后还需要对这三条函数做相应修改:
MeleeStartingAI()
MeleeStartingHeroLimit()

MeleeGetAllyKeyStructureCount()

一个自定义种族MOD完成了。就是这么简单

brethren0 发表于 2012-6-12 01:42:13

这算是一个突破性的设置么,以前确实没见过

417948913 发表于 2012-6-12 08:19:31

期待~~~~

麦德三世 发表于 2012-6-12 10:02:55

hmmm~~其实我倒是试过交换颜色选项和种族选项这个法子~~

不过那是很久很久以前了~不确定如今的war3还是不是这个样子~~

fucckz 发表于 2012-6-12 12:58:35

回 麦德三世 的帖子

麦德三世:hmmm~~其实我倒是试过交换颜色选项和种族选项这个法子~~

不过那是很久很久以前了~不确定如今的war3还是不是这个样子~~ (2012-06-12 10:02) images/back.gif

我用的不是交换颜色选项,是直接用handicap选项覆盖。
主要是破解handicap选项要比种族选项简单很多。

麦德三世 发表于 2012-6-12 13:19:19

我并没有说你用的就是这个法子。只是提一下我以前用的法子而已。

何况颜色也没100个。

fucckz 发表于 2012-6-12 13:30:23

回 麦德三世 的帖子

麦德三世:我并没有说你用的就是这个法子。只是提一下我以前用的法子而已。

何况颜色也没100个。 (2012-06-12 13:19) images/back.gif

谢谢头目的分享。

现在主要是JAPI传递本地数据到游戏中多人游戏会掉线解决不了,要是能解决这个问题此模板就完美了。

xu695622238 发表于 2012-6-13 19:40:37

看来随机应该另外有代码的吧……

lo 发表于 2012-6-14 11:14:47

- 补丁 1.24e
--------------------------------------------------------------------------

修正

- 修正了一个滥用游戏架构,导致建筑物无法与其它游戏部分互动的错误。
- 修正了一个滥用游戏架构,让玩家能够跳过召唤技能冷却时间的错误。
- 修正了一个客户端冲突,此冲突会导致游戏中工人在非主动状态下无法建造建筑物。
- 修正了一个滥用游戏构架,让血法师的凤凰能够立刻复活的错误。
- 修正了一个错误,此错误让玩家能够选择一个无效的比赛匹配种族并导致这位玩家的全部单位和建筑物都变成羊。





不知道lz那个满是羊的截图和这个有没有关联……

fucckz 发表于 2012-6-14 12:41:25

回 lo 的帖子

lo:
- 补丁 1.24e
--------------------------------------------------------------------------

修正

....... images/back.gif


有一个函数叫 MeleeStartingUnitsUnknownRace 。。。在Blizzard.j里。。。没错我是故意的。

宫小燕 发表于 2012-6-15 10:47:35

我好久没玩这个游戏了

娜迦族后裔 发表于 2012-6-16 13:42:17

都是高手啊,如果能稳定,简直是个里程碑式的壮举,期待稳定版本

actboy168 发表于 2012-6-16 21:53:41

要替换gamedll太不科学了吧,怎么不用注入的方式

actboy168 发表于 2012-6-16 22:14:57

仔细看了一下,除了UI上的区别,其他似乎都没改魔兽的必要

fucckz 发表于 2012-6-17 00:31:27

回 actboy168 的帖子

actboy168:仔细看了一下,除了UI上的区别,其他似乎都没改魔兽的必要 (2012-06-16 22:14) images/back.gif

我也想过做注入。。但是

*跳转的偏移太多,注入前pattern寻址判断会显得很麻烦。
*同时也不希望做成Loader的方式,因为那样许多vlan的平台会玩不了。
*每个地方的自定义代码少,还是汇编方便些。

另外game.dll可以随意命名(目前这个不行- -),如果你是担心会覆盖原game.dll的话。

-----------------------------------------------------------------
UI不是最主要的。核心是破解handicap选单可选取的最大值限制以及选取后的赋值有效化,不改魔兽是实现不了的。。。

fucckz 发表于 2012-6-17 00:32:54

*EDIT*
主要是注入的话就是要实现各版本通用,但是不同版本的game.dll又不能联机,所以感觉没有意义。

为什么就没有人讨论下对于多人游戏JAPI传值造成内存不同步掉线的解决办法??

fucckz 发表于 2012-6-17 02:05:59

增加一个自己做的小工具,用于整合地图上触发与自定义函数进Blizzard.j。

只需要点一下:
地图做好以后保存并解出 war3map.j 和 war3map.wts 并把它们放在工具的 Input文件夹里。
打开工具,点Merge,去 Output文件夹找到整合好的bj,将它打包进自己的mpq。
P.S.你还是要自己手动改MeleeStartingUnits这个函数,并且整合前必须删掉你地图中生成初始单位的触发。



。。。不懂怎么改的话,下面还有一种更无脑的方法。。。

*进BJ直接把这几条函数清空:(留下头和尾)
MeleeStartingUnits();
MeleeStartingAI();
MeleeStartingHeroLimit();

*地图里自己写生成初始单位、启动AI、判断输赢的触发。

*最后就是用工具了(不用删除任何自定义触发)

仅能用于WE默认生成的war3map.j,用vjass编译的或者混淆过的war3map.j后果自负...

------------------------------------
Input文件里的war3map.j和war3map.wts是一个例子——点单位显示其名字 。整合在bj里后可以用于任何对战地图。

娜迦族后裔 发表于 2012-6-17 14:47:56

874565415 发表于 2012-7-9 19:58:48

Race.mpq这个文件会用什么方式打开呢?
页: [1] 2
查看完整版本: 魔兽多种族模板