魔獸地圖修改教程

[ 2006-03-01 14:07:14 | Author: wujimmy ]
Font Size: Large | Medium | Small
本文用到的编辑器
点击下载
这个工具最好用了,地图玩不过就用这个改,改商品价格等
点击下载
Quote
下面的文章如果看不懂就不要看了,直接下载上面的第二个文件改地图吧。
魔獸地圖修改教程

===魔獸地圖修改===

這是關於加密的圖修改的。

先用ULTRAEDIT这个软件打开你要改的图
http://www.crsky.com/soft/931.html 去这个地方下载
找到0000 0200h这一行

把地图文件改成图中的样子
保存地图,退出ultraedit

然后去这个地方http://jd188.ys168.com下载mpqworkshop
用它打开刚才的地图,不是我AD,現在論壇的附件不放心阿...........只好自己找地方

然后把这个东西解压到一个好找的地方
比如桌面
w3u是英雄的个人属性
w3a是英雄的技能
一般改的话只用改这2个就差不多了
mpqworkshop就这样放着吧,先不用关了

然后就要用到地图编辑器了
也就是传说中的WE
我习惯用12K的WAR3镜像和daemon tools
去这个地方下http://www.crsky.com/soft/1158.html
daemon装完之后要重启的
用daemon tools装入12K景象
就可以启动WE了
好像现在剑心在众人要求下也作了WE的免CD补丁,有兴趣的可以自己找
如果有免CD,就可以不用镜像拉

现在启动WE吧,随便打开一个没有加密的地图
暴雪对战的地图都没有加密,都可以直接打开

然后点物体编辑器

物体编辑器出来的时候显示的是单位条栏

然后点输入单位设置

以剑圣为例子吧

物体编辑器右边的 状态 大部分是可以改的
双击他,然后就可以了

然后点到 技能 栏目

地图编辑器要靠自己摸索了,我懂的也不多,
也以剑圣 风暴为例

在改完了数据后就要保存了

最好把以前的数据文件覆盖了

现在可以把WE关闭了
回到mpqworkshop
现在要把数据重新导入MPQ中去
我就以技能w3a文件为例,其他的同理

删除后还要进行下个步骤

添加文件
w3a
然后还要重复一个步骤

到此为止啊
直接关闭MPQ
把图放到MAP中去吧
去测试你所改的地图
要是你们拿去传播的话真的是天理不容了

如果用mpqworkshop打不开地图
如果用mpqworkshop打不开地图 说明mpq的文件头被损坏,可以用UltraEdit 32 打开地图,魔兽争霸III的地图就像一个Zip文件。

首先是一个 512 字节大小的地图文件头,它记录了一些信息。然后附带一个MPQ 档案, 这个MPQ 档案中包含了一个地图所需的全部文件。 MPQ 文件的前4个字节是一个标识符。它可以被识别为 ’MPQ’。接下来的4个字节是文件头大小,通常是16进制 hex 0x20 00 00 00的形式。 有些加密者将 20 00 00 00 改成一个随机数值,例如F6 6E BA 76这个样子。 目前多数 MPQ 程序因为大小错误而无法打开这样的 MPQ 档案。而 Warcraft3 似乎忽略了这种错误的文件头大小,所以这些地图仍可以在魔兽中运行。

这种加密只要把数值改回 0x20 00 00 00就可以轻易破解掉。

然后看到的这些文件都是地图的原始数据我们可以*直接修改它们来达到修改地图的内容。
下边是一些有用的文件的列表
war3map.w3u 单位
war3map.w3t 物品
war3map.w3b 可破坏的
war3map.w3d 地形装饰物
war3map.w3a 技能
war3map.w3h 魔法特效
war3map.w3q 升级
等等,这些都是地图的基本设置文件,我们可以用WE中的物品编辑器直接导入进行编辑。
war3map.wtg 触发事件
这个是保存各种触发事件的地方。我们在地图里搞装备合成,刷怪,作任务等,都是依*触发指令来完成的。但是一般的加密地图都把war3map.wtg和war3map.wts删除了。
war3map.j jass数据库
这个是地图的核心,所有跟地图设置有关的资料如地图摆放的建筑物、角色、技能、触发事件的指令等等,只可惜是用jass语言保存的。如果你懂jass的话可以在这个文件里任意改动任何数据。包括触发指令。
war3map.shd 地层数据
war3map.wpm mp3,wav等媒体文件的设置
war3mapPreview.tga 地图缩略图
war3mapmap.blp 图形文件的设置
war3mapmisc.txt 游戏平衡常数

下边是最重要的,因为很多人把文件修改完以后都不知道该怎么还原。
我们现在就要用到mpqediten或MPQWorkshop了
新建一个MPQ文件,然后把那些文件全部添加进去再保存。
现在你们得到一个MPQ文件了。下一步是添加w3x地图文件的文件头
用UltraEdit-32随便打开一个w3x魔兽地图文件和自己的mpq文件。
对比一下,就会发现w3x文件比MPQ文件多了一个16字节的文件头
后边的事我不用说了吧,w3x文件中复制,然后在MPQ中粘贴这个16字节的文件头,然后把后缀名MPQ改成w3x就可以了。
修改地图就是这么简单,欢迎大家修改地图,尤其是好地图。

==============分界綫是必須的==========================
WE] 谈加密地图的原理,破解加密地图的可能及研究加密地图的方法

1.不可还原式删除加密, 即破坏性加密
说明: 这种加密难度小, 方法简单, 比较常用
原理: 魔兽的地图是一个mpq压缩文件, 里面存放了一些游戏中和WE中要用的数据, 其中一部分数据是只有WE要用而游戏时不要用的, 我们可以将它们移掉, 造成启动WE无法读到相关数据
方法: 1.用Import Manager导入这些文件的替代空文件2.用mpq工具删掉这些文件
破解可能: 由于需要的文件已经被移掉, 而Jass->Trigger的还原难度非常大, 所以基本不能完全还原原来的地图

2.可还原式移动加密
说明: 这种加密比较复杂, 但可以利用一些密钥还原
原理: 根据上面一种方法的原理, 我们把地图里的一些文件改名为特殊的文件名或者移动到特殊的目录去, 并且删掉(listfile), 这个文件是用于获取mpq格式的文件里面的文件列表的, 这样WE也无法读取到这些文件从而无法启动
方法: 根据一定的算法把密钥哈希成一个字符串, 然后把文件改名或者移动到用这个字符串生成的文件名里. 还原时只要有密钥就可以找到移动后的文件并还原
破解可能: 这些算法通常是md5等不可逆算法, 或RSA等大素数可逆算法, 加上我们根本连移动或改名后的文件名或路径都不知道, 基本很难破, 除非你知道密钥

3.可还原式破坏WE显示加密
说明: 该方法简单但如果被知道了了方法很容易破解
原理: WE启动时和读取地图时会读取一些模型, 音乐, 贴图等, 如果我们导入一些错误的文件, 在WE读取时会先读地图里的文件, 就会因为这些错误的文件而出错
方法: 我自己不太清楚可以导哪些文件, 大家可参考以前的一些帖子
破解可能: 如果你知道这个方法, 那么只要从地图里删除坏文件就可以了
然后讲一下几个加密中会用到的技巧:
1.删掉(listfile), 这样别人不能看你的文件列表, 无法知道你的加密方法
2.把war3map.j移动到Scripts\\目录下, 这样仍然被游戏读取, 但是一般人不知道就会无法解压出这个文件
3.针对一些mpq工具可能会将文件头部的一个数改掉导致mpq工具无法处理, 通常offset是0x218, 用16进制工具把这个位置改为20 00 00 00即可还原

最后讲一下如何研究加密的地图:
1.学会Jass语言《jass使用教程·基础篇》
2.用mpq工具解压出war3map.j(如果没有则参见上面的第二条解压Scripts\\war3map.j), 注意如果mpq工具如果不能读取则按照上面第3条的做法修复文件头
3.结合所学的Jass看war3map.j, 就能知道对方地图的处理过程
4.关于地形的获得我还没有好办法, 我把别人的地形文件导进自己的地图会出现读取错误, 估计是有些选项必须符合, 考虑到有些人加密地图就是为了保护地形不让别人"盗版", 所以我也没有多做研究, 只要知道war3map.j的内容就可以学习别人所有的地图处理过程了
总结一下:
解密是很难的, 但是可以通过解压war3map.j来分析别人的地图, 希望这篇文章对大家关于加密解密的争论能给出一个理论依据.

MPQ軟體

MPQ軟體
 

MPQ 是什麼?
MPQ 是 Blizzard 公司將遊戲資料包裝在一起的一種檔案格式,內容放置採取 Joliet 檔案格式 (MS-DOS 路徑型態+長檔名),與 Unix/Linux 路徑型態不同。內部採取可壓縮設計,但對於不同檔案型態,其壓縮方式也不同。

後來據說某位國外的天才,將 MPQ 檔案格式解碼後, 利用星海爭霸任務編輯器staredit.exe 搭配 storm.dll 檔案,配合他自行製作的幾個 MPQ 功能,成為 MPQ2000 軟體。之後又陸續出現了很多新的MPQ軟體,例如MPQ View、WinMPQ、MPQ Editor、MPQ Workshop、……,軟體的使用範圍也從DOS模式延伸到Windows。

這些軟體最主要的功能是可以解出MPQ檔案下的東西(就像使用WinZip解開.zip檔案一樣),甚至可以壓入檔案到.mpq中。它可以用來解出魔獸爭霸III中的圖檔、動畫、戰役地圖、原始資料等。此外,也可以用在星海爭霸(Strcraft)及暗黑破壞神(Diablo)中,以及製作特別版(但是製作出來的版本原則上無法與正常的版本在b.net上連線遊戲,只能自high)。本文只討論基本的解檔功能,其他進階的功能請大家自行研究。

此外,對於某些MPQ程式,為了要開啟MPQ檔案,你必須提供該MPQ檔內部的路徑表(listfile),才打的開這個檔案。有些比較高級的程式如WinMPQ,可使用該檔案內部的listfile開啟,但是如果該檔案沒有附listfile,則無法順利開啟。listfile為.txt文件,如果需要的話,可以把附錄 War3 All Listfile 的內容複製起來,貼到記事本並存成.txt檔即可使用。

 

MPQ程式也可以加入檔案,但是處理MPQ的檔案和處理一般檔案的情形有些不同。當你刪除檔案(或者用同名稱的檔案覆蓋)時,它的空間不會被釋放,換句話說,刪除檔案後,檔案不會變小,只是不會被讀到而已。就筆者所知,目前只有最難操作的MPQ2K可以釋放空間,所以大家最好不要隨便用MPQ程式刪檔和加檔,不然該檔案會越變越大。

 

魔獸的MPQ檔案
war3.mpq:主程式的資料
War3x.mpq:資料片的資料
War3Patch.mpq:改版的資料,想找最新版本的新東西就解這個
War3xlocal.mpq:中文化(或者其他國家的語言)的資料


orachard 2006-01-13 14:17
转帖:这里收集有关触发器和 Jass 的问题=======

Q:什么是触发?(Trigger),触发是如何工作的?

触发(Trigger) - 根据字面意思可以理解为: 事件A 发生后会直接或者间接的导致 事件B 发生的过程~~
关于触发的工作原理,举例如下:
动物踩上地雷,地雷就BOOMMMMMMM!:)~~
以上这就是一个触发,踩地雷 是 事件A ,我们称它为 事件(EVENT)~~而 地雷爆炸 则对应 事件B ,我们称他为 行为(ACTION)~~大家还可能考虑到,如果踩上地雷的不是人,而是质量很小的昆虫,则不可能发生爆炸,于是我们引入一个概念,就是 条件(CONDITON)~~它决定了 事件 发生后是不是会导致连带的结果,即 行为 的实施~~
一个触发分为三个状态:就绪状态、工作状态、屏蔽状态。其基本状态是 就绪状态。
就绪状态:处于就绪状态的触发可以接收其相应的 事件,只要 事件 发生,则此触发建立一个单独的进程进入工作状态,这个接收事件转入工作状态的过程称为 响应(RESPONSE)~~
工作状态:从就绪到工作,首先进行 条件(CONDITON)检测 ,如果通过就开始 行为的实施 ,从检测到实施完毕的整个过程为工作状态(无论是否通过检测)。需要注意的是,一个处于工作状态的触发是一个单独的进程~~一个触发可以同时或者异步响应 N次 。
屏蔽状态:处于屏蔽状态的触发不能 响应 任何事件,但是可以通过 调用行为 进行调用,调用后直接进入 工作状态。在调用的时候可以选择是否跳过 条件检测。
注]:同一个触发中的多个 事件 之间是 OR 关系,满足其中之一则触发响应;多个 条件 之间为 AND 关系,全部满足才通过检测;而多个 行为 的执行是按照顺序进行从上到下的处理。

Q:触发器的里各语句的位置有影响么/能换么?

不能换。Trigger 的执行顺序是从上到下依次执行的。
不过 Category 的先后顺序则无关紧要。

Q:玩家的初始金钱和木材在那里改?

在地图初始化的触发里选择 Set Property .就可以更改金钱和木材了。

Q:如何更改英雄取得经验的比例?

ACTION - HERO - HERO EXPERIENCE RATE,设成多少百分比看自己的情况决定咯。

Q:怎么去掉单位身上的那些默认按钮啊?~~比如攻击~~集结点什么什么的~~

通常用 UNIT - REMOVE ABILITY 可以用来去掉一些按钮~~
REMOVE UNKNOWN (Aatk) 可以去掉攻击~~
REMOVE UNKNOWN (Amov) 可以去掉移动/巡逻/停止~~
REMOVE UNKNOWN (Aral) 可以去掉集结点
…………

Q:Letterbox 和 Cinematic 有什么区别啊?似乎都是打开影片模式哦

Letterbox 不会改变可视度~~没有被探索的地方也同样不会显现~~Cinematic 反之~~

Q:怎么可以实现物品栏里每一个格子只能放一类物品,且同类道具只能放有一个呢?

这个问题会涉及到变量的使用还有 TRIGGER 。
首先你需要创建一个变量数组(VAR ARRAY),命名为 IF,类型为 布尔(BOOLEAN),容量为 7(因为下标是从0开始的,所以要对应6个道具栏一般就设置为7比较好操作)。
然后在 ITEM EDITOR 里面为不同类型的道具设定相同的等级,比如武器就是 L1,头盔就是 L2,等等。
最后就是写 TEIGGER 了:
E - 单位拣到道具
C -
A -
+暂时关闭此触发
+如果以道具等级为下标的变量 IF 值为假,则
- 把物品栏的第 N 格道具丢弃,N 的值为拣到的道具等级
- 把刚拣到的道具放到第 N 格
- 把刚才丢弃的道具放置到第 M 格,M 的的值为此道具等级
- 设置以道具等级为下标的变量 IF 值为真,则
+否则如果以道具等级为下标的变量 IF 值为真,则
- 丢弃这个被捡道具
+打开此触发
这个是捡道具的步骤,同样的你需要写一个丢弃道具的 TRIGGER ,内容就是将 以丢弃的道具等级为下标的 IF 设置为假。

Q:怎么做一个自动刷兵的效果呢?

一般是要定时刷新的~~所以EVENT用PERIODIC TIME EVENT(周期性时间事件)~~间隔时间自己决定~~
刷兵总得有个限制~~否则一直刷下去你打的完吗?所以在CONDITION中~~用INTEGER COMPRAISON - UNIT - COUNT UNIT IN UNIT GROUP(计算组内单位的数量,具体组的设定自己解决……)来比较你希望的一个数量~~如果小于这个数量~~则执行下面的 ACTIONS ~
出兵最简单~~ ACTION - UNIT - CREATE UNIT~~种类、所属自己选~~位置就放在你要刷的地方~~一般是你要求刷出兵的建筑附近~~
PS:以上就是最基本的刷兵了,至于其他的,例如什么时候开始刷,什么时候停止刷,EVENT自己决定吧,用ACTION - TRIGGER - TURN ON/OFF TRIGGER来开关触发器。

Q:在对战地图中,杀死对方的兵是不会获得金钱的,如何在战役中,可以获得金钱?

在 TRIGGER EDITOR 里面用 Player - Turn Player Flag ON/OFF 开启金钱奖励~~
在 UNIT EDITOR 里面用 Stats - Bounty Awarded - 来修改某杀死某单位后的金钱数量~~

Q:怎么才能设计一个简单的对话为主的动画呢?

首先打开剧场模式 ACTION - CINEMATIC - CINEMATIC MODE ON
然后用 ACTION - CINEMATIC - TRANSMISSION FROM UNIT 选择说话的单位、对话及时间等
完了别忘了关闭剧场模式 TURN CINEMATIC MODE OFF
PS:不开剧场模式一样可以使用TRANSMISSION FROM UNIT显示对话,要记得在初始化地图时打开普通场景下的字幕显示,ACTION - CINAMATIC - SUBTITLE DISPLAY OVERRIDE ON

Q:怎么才能设计出用 ESC 跳过的电影?

建议打开官方的地图学习咯~~
首先建立一个 BOOLEAN 变量 CIN_FLAG = FALSE ~~这个的作用是表示你是不是按下了 ESC 期望跳过~~
然后在你写的影片 TRIGGER 中~~每一句后面都增加一句 "如果 CIN_FALSE == TRUE 则 略过后面的 ACTIONS 且 调用 中断处理 TRIGGER" ~~也就是说~~如果记录是否跳过的变量表示为真~~则可以略过后面所有的 ACTIONS ~~
接着创建一个 TRIGGER ~~
EVENT - 按下 ESC 键
ACTIONS - SET CIN_FLAG = TRUE ~~这个就是让你在按下 ESC 后把变量表示为真~~这样就可以在上面的步骤中略过了~~
最后建立一个 TRIGGER 作为中断处理部分~~提供上面说道的那个调用~~内容就是影片结束后的状态~~比如什么单位最后在什么位置~~

Q:如何做选英雄的TRIGGER?

以下是最基本的英雄选择方法。
先做些准备工作,在地图上放一个选人用的小精灵,再在适当位置放上一个力量之环(CIRCLE OF POWER)作为标识,在上面放上待选英雄,然 后在力量之环所在位置画上一个区域(REGION)。
-建立TRIGGER-
EVENT - UNIT ENTER REGION REGION就选你建立的那个REGION
CONDITION - UNIT(TYPE) COMPARISON - ENTERING UNIT EQUAL TO 小精灵 条件判断,判断进入该区域的单位是不是小精灵(或者也可以用 UNIT TYPE COMPARISON来判断进入区域的单位类型是不是小精灵 UNIT TYPE OF ENTERING UNIT)
POSITION就用你希望出现在的地方(一般你应该建立一个REGION表示游戏的起始点,就是这个啦)
然后KILL ENTERING UNIT(杀死进入的单位,你要的是英雄而不是小精灵,杀死前你可以HIDE UNIT以隐藏死亡动作,或者干脆REMOVE掉)
以上完成的就是最基本的选英雄的TRIGGER了,当然每多一个英雄你就得多做一个TRIGGER,并修改相应的CREATE UNIT的类型。对于那些只能选 一次英雄的方法嘛,只要在ACTION中加上TURN OFF THIS TRIGGER(关闭该触发)就可以了~~

Q:如何制作随机掉落物品?

很多人问刷出来的怪怎么掉宝,以下是一种简单的基本的方法。

EVENT 为 UNIT DIE 当然是要怪死了才掉宝的嘛
CONDITION 怎么说呢,一般来说RPG地图里只要是敌人都有机会掉宝,那就用PLAYER COMPARISON - OWNER OF DYING UNIT 来判断。
同时可以利用INTEGER COMPARISON - MATH - RANDOM NUMBER BETWEEN A TO B(A和B之间的随机数)是否等于(大于/小于)某值来做掉宝的几率。
ACTION 用 CREATE ITEM ,ITEM TYPE可以选RANDOM ITEM-TYPE,然后选择等级(0-10级,可以根据某些规则来决定掉的是几级的宝,具体自己考虑吧,-1表示所有等级的宝物) POSITION就是POSITION OF DYING UNIT(死亡单位的位置)
以上可以完成最简单的随机掉宝,具体大家可以慢慢考虑呵呵。

Q:SUBSTRING函数 有什么用啊?

SUBSTRING是截取字符用的~~如在下面一个赋值过程中:
Set StoreEquitDate[StoreEquitDateLOG] = (Substring(‘XXXXXXXX’), 1, 5)
(Substring(), 1, 5) 表示取字符串‘XXXXXXXX’中第1到第5位之间的字符串~~
Q:如何让游戏开起后,起始位置不会出现主城和工人?

进入Trigger Editor,找到Melee Initialization,如果没改过的话应该如下:  
Melee Initialization

Events

......Map initialization

Actions

......Melee Game - Use melee time of day (for all players)

使一开始的游戏时间是早上6:00(如果删掉就会从00:00开始)

......Melee Game - Limit Heroes to 1 per Hero-type (for all players) 让所有玩家不能生產重覆的英雄

......Melee Game - Give trained Heroes a Scroll of Town Portal (for all players) 让第一个生產出来的英雄有传送卷轴

......Melee Game - Set starting resources (for all players) 让所有玩家一开始有一定的Gold和Lumber

......Melee Game - Remove creeps and critters from used start locations (for all players) 如果某起始位置有玩家,就删除附近的Creep

......Melee Game - Create starting units (for all players) 產生主城和工人于玩家的起始位置
......Melee Game - Run melee AI s (for computer players) 让电脑玩家有AI

......Melee Game - Enforce victory/defeat conditions (for all players) 使用一般的胜利/失败设定(毁掉对方所有建筑者胜) 

将蓝色的那一条删掉即可  

Q:如何製作一个群体Sleep技能?

Sleep在製作时就被销定為单体技能,因此想这麼做不是AE或者MOD可以解决的,必须使用Trigger来帮忙。以下為可行方法的其中之一:  

1、将Sleep复製贴上,改名為Group Sleep - Sleep(举例,请自己决定一个适当的名字)。 把mana cost改為0、range改為99999(全地图)、改成单位技能(Is a hero ability = false)  

2、製作一单位Sleep Caster,model改成none、技能加入刚才做的Group Sleep - Sleep及Invulnerable (Netural)。  

3、将Sleep技能改名為Group Sleep  

4、写Trigger:  

Group Sleep Order

......Events

............Unit - A unit Is issued an order targeting an object

//当一个单位接收到一个指定物件的指令

......Conditions

............(Issued order) Equal to (Order(sleep))

//指令為sleep

......Actions

............Set GroupSleep_MajorTarget = (Target unit of issued order)

//将指令指定的单位存在GroupSleep_MajorTarget这个变数中 

Group Sleep

....Events

........Unit - A unit Starts the effect of an ability

//当一个单位使得一项技能开始生效

....Conditions

........(Ability being cast) Equal to Group Sleep

//使用的技能為Group Sleep

....Actions

........Unit Group - Pick every unit in (Units within 300.00 of (Position of GroupSleep_MajorTarget)) and do (Actions)

//选取GroupSleep_MajorTarget这个单位附近300范围的所有单位并执行Loop Action内的所有动作

............Loop - Actions

................Unit - Create 1 Sleep Caster for (Owner of (Triggering unit)) at (Position of (Triggering unit)) facing 0.00 degrees     

//產生一个单位于施法者(触发的单位)旁边,设定所有者為拥有施法者的玩家

................Unit - Add a 2.00 second Generic expiration timer to (Last created unit)

//设定刚刚產生的单位生命时间為2.00(长度自己决定,足够施放AMS即可) ................Unit - Order (Last created unit) to Undead Dreadlord - Sleep (Picked unit)

//命令刚刚產生的单位对选到的单位使用自身技能中Order為sleep的技能   这样就能做出一个范围300的群体催眠术咯!

Q:假设在一张 RPG 地图中, 给每一位玩家一个工人, 让玩家选英雄

Event

......Unit - A unit enters

Action

......Unit - Create 1 for Trigging Player at center of

facing ......  

为什麼单位进入该Region时没有反应?  

设定错误。由于引发事件的是单位,而不是玩家,所以 Trigging Player 无法表明到底是哪一个玩家。正确的设定方式如下:  

Event

......Unit - A unit enters

Action

......Unit - Create 1 for (Owner of (Trigging Unit)) at center of facing ......    

Q:请问如何加入随机效果?  

在设定Trigger时,用If/Then/Else做设定,例如:  

PaladinSkill:

Events

......Unit - A unit Is attacked

//一个单位遭受攻击

Conditions

......(Unit-type of (Attacking unit)) Equal to Paladin

//攻击者為Paladin Actions

......If (All Conditions are True) then do (Then Actions) else do (Else Actions)

............If - Conditions

..................(Random integer number between 1 and 10) Equal to 1

//如果1-10中随机选到的数字為1

............Then - Actions

..................Unit - Kill (Triggering unit)

------1/10

//杀死引起触发的单位(遭受攻击的单位,用Attacked Unit也可以)
............Else - Actions

..................If (All Conditions are True) then do (Then Actions) else do

(Else Actions) ------9/10

........................If - Conditions

..............................(Random integer number between 1 and 9) Equal to 1

//如果1-9中随机选到的数字為1

........................Then - Actions

..............................Unit - Set life of (Triggering unit) to ((Life of (Triggering unit)) / 2.00) -----1/9*9/10= 1/10

//将引起触发的单位生命值设為(触发单位生命值 / 2.00)
........................Else - Actions    
 
这么一来,当Paladin攻击敌人时,就会有1/10的机会瞬间杀死对方,1/10的机会使目标的生命值减半。其他的依此类推。这是目前最简单有效的方法,更好的方法大概只能用JASS写了。

Q:如何获得一个技能的目标点?  

用 TARGET POINT OF ABILITY BEING CAST 就能取到。
Q:我想用 play 某个单位的 walk animation 来让该单位在原地跑,结果进入一看不行,这个动作不是持续的,请问我该怎么办?  

用 Jass :

call SetUnitAnimationByIndex( UnitId, AnimationIndex)

用这个可以让单位一直保持某个动作的状态不变。

但是并不是所有动作都能被保持的

E:简单地说一下 GAME CACHE 的使用

GAME CACHE ~~字面意思就是 游戏缓存 ~~用于开辟一个内存空间来保存用户希望 保留 的数据(最后需要将 CACHE 保存到 硬盘上)~~
主要作用是将 地图A 的一些数据保留到 地图B 中~~比如战役中英雄的等级或者道具技能什么什么的~~

GAME CACHE 是用 TRIGGER EDITOR 来操作的~~下面说说相关 ACTIONS 的含义~

1]创建一个缓存~~想要使用缓存~~当然要先创建啦~~
Game Cache - Create a game cache from MapName.w3v
这就是一个创建 CACHE 语句~~后面的 MapName.w3v 是你创建的 CACHE 的名字~~:)~~

2]创建以后~~就可以用他来保存资料了~~
Game Cache - Store Unit as Lable of Category in (Last created game cache)
这是一个 保存单位 的语句~~在 Unit 处选好需要保存的单位~~填写好 标识(Lable) 和 分类(Category) ~~最后 选择将 单位保存到 哪个 CACHE 里面~~其中 标识 和 分类是可以随意填写的~~:)~~

类似的~~还有下面一些类型的数据可以保存到 CACHE 里面~~使用方法同上!
Game Cache - Store Real as Lable of Category in (Last created game cache)
Game Cache - Store Integer as Lable of Category in (Last created game cache)
Game Cache - Store Boolean as Lable of Category in (Last created game cache)
Game Cache - Store String as Lable of Category in (Last created game cache)

(UNIT:单位 / REAL:实数 / INTEGER:整数 / BOOLEAN:布尔 / STRING:字符串)

保存玩需要的数据后不要忘记保存 CACHE 本身~~
Game Cache - Save (Last created game cache)

上面说的是保存数据~~但是怎么取出数据呢?~~
首先在任何可以使用 你想取出的数据类型 的地方都可以通过 GAME CACHE - LOAD XXXXXX CALUE 来取出数据~~

另外~~
Game Cache - Restore lable of Category from (Last created game cache) for Player 1 (Red) at (Center of (Playable map area)) facing 0.00
Game Cache - Restore lable of Category from (Last created game cache) for Player 1 (Red) at (Center of (Playable map area)) facing (Position of (Triggering unit))
这个语句是专门用于 取出一个被保存的单位且放置在地图上的~~

最后~~如果想清除 CACHE 中的数据可以使用下面两个语句~~
Game Cache - Clear (Last created game cache)
清除所有数据~~
Game Cache - Clear all labels of Category in (Last created game cache)
清除某一类的数据~~

Q:嗯,如何动态改变中立商店/酒馆里卖的东西呢?

Neutral Building - Add 物品/单位 to (商店/酒馆) with 初始存货数 in stock and a max stock of 最大存货数

把贩售物存入一个数组,用trigger随机生成数组索引,可以做到真正的”人流不息“的酒馆。又如根据玩家游戏进行的状态,如获得的物品,在商店生成同等级的物品(TM中间的市场一样)等~
记得商店/酒馆必须有相关的贩售技能(废话-_-)

Q:如何让一个召唤生物不能被选中但能被攻击呢?

给一个单位添加 "Aloc" 技能, 就可以使它不能被选取, 就好象不死小强的终极技能Locust swarm召唤出的小小小飞强一样~~
但是, 这个单位也同时失去了碰撞大小, 就是任何人都摸不到他拉, (像鬼魂般穿身而过). 这时配合"Chaos"就可完美解决!
做两个相同的单位, 一个为真身, 一个为替身. 再自定一个Chaos技能, Data New Unit Type填单位的真身
把"Aloc", 自定的"Chaos"添加给她, 这时候Chaos立即起作用, 替身单位变为真身, Aloc的"不被选取"作用保留, 而该单位也可同时承受攻击了!
比如你想做召唤单位, Actions就是

Custom : call UnitAddAbilityBJ( 'Aloc', GetSummonedUnit() )
Custom : call UnitAddAbilityBJ( 'S001', GetSummonedUnit() )
('S001'是你自定chaos技能的代码)

就这么简单!
这个"Aloc" + "Chaos"的组合是wc3c的一位mapper发现的, 用在雇佣兵上真是妙! 不用单心混战中错点到他们了~~

Q:如何让自定义英雄和普通英雄一样有建造限制呢?

首先,在游戏平衡常数中将您的自定义英雄添加到“科技 - 等价物 - 英雄”列表里面去,这样的话就能保证每升一级主基地只能造一个了。
然后还要添加一条 Trigger :

Player - Limit training of xxx to 1 for Player n (其中“ xxx ”为该自定义英雄的单位类型)

这样您的英雄就只能造一个了

Q:如何让死掉的树复活呢?

很简单的,用 Destructible - Resurrect 即可。


orachard 2006-01-13 14:19
什么是地图加密

地图加密就是通过特殊方法破坏地图文件,使它可以在魔兽中运行,却不能被World Editor读取。

目前有哪些加密方法

现在已有很多种加密War3地图的方法。

1: 破坏 MPQ 文件头大小信息
魔兽争霸III的地图就像一个Zip文件。 首先是一个 512 字节大小的地图文件头,它记录了一些信息。然后附带一个MPQ 档案,
这个MPQ 档案中包含了一个地图所需的全部文件。 MPQ 文件的前4个字节是一个标识符。它可以被识别为 ’MPQ’。接下来的4个字节
是文件头大小,通常是16进制 hex 0x20 00 00 00的形式。 有些加密者将 0x20 00 00 00 改成一个随机数值,例如hex 0xF6 6E BA 76这个
样子。 目前多数 MPQ 程序因为大小错误而无法打开这样的 MPQ 档案。而 Warcraft3 似乎忽略了这种错误的文件头大小,所以这些地图
仍可以在魔兽中运行。
这种加密只要把数值改回 0x20 00 00 00就可以轻易破解掉。
为了能够正常打开地图并提取文件信息,本网站(wc3sear.ch)将自动修复这类加密文件。

(译者:这一段的术语翻译可能并不正确,因为我对文件结构本就知之甚少。望谅解)

2: 删除地图内的 war3map.wtg文件
war3map.wtg 文件中包含了地图中所用到的变量,触发,数组等必需信息。但这个文件只对World-Editor有用。
war3map.wtg 文件丢失或者被改动都将导致 World-Editor 无法读取地图。
当然,这种加密也可以完美地解除。 通过一个小程序你就可以利用war3map.j 文件中存储的信息来重建 war3map.wtg 文件。
本网站忽略掉war3map.wtg 文件,而是直接从war3map.j 文件中提取诸如触发数目,变量数目等信息。
你可能注意到,既然一个简单的 PHP 脚本就可以提取出 war3map.j,那么使用其它脚本就有可能重建war3map.wtg 文件。

2b: 删除 war3map.w3c, war3map.w3s, war3map.w3r 文件
war3map.w3c 存储了world editor的镜头设置。 war3map.w3s 存储了world editor在地图中所设置的声音。 war3map.w3r 存储了world editor中的区域设定。
这几个文件同样只对World Editor有用,而且同样可以通过 war3map.j 文件进行重建。参见上面的 “删除地图内的 war3map.wtg 文件“ 。

3: 隐藏 war3map.j 文件
有些耍小聪明的加密者找到了隐藏 war3map.j 的办法,这样我们就无法用一个网页脚本来轻易将它解出了。
正规的地图中 war3map.j 是直接保存在根目录里的。而这些加密者发现把它移动到 “Scripts\“下面也可以正常运行。
只要知道了这一点,就很容易破解这种加密 ;-) 非常感谢 BahamutZERO 和Quantam 帮我解决这种方法。

4: 打乱war3map.j 文件
有些加密者认为自己很聪明,他们用随机数字重命名了所有的变量和函数。这使常人很难读懂 war3map.j 文件。但这对脚本是不起作用的。
我为这个网站所写的脚本根本不在乎关键字,它只搜索模式,所以我仍然可以从地图中提取我所需要的信息 ;-)
只要借助能够重建 war3map.wtg 的脚本,这种加密方法同样可以破解。恐怕你唯一没法改变的就是已经重命名的变量和函数。
但这并不重要,因为你仍然可以用world editor打开它。 ;-)

加密的安全性如何

正如你所读到的,地图加密也许可以避免菜鸟们用world editor打开你的地图。
但事实是只要魔兽可以运行你的地图,就有办法修复它,从而可以用 World Editor打开它。

地图加密的利弊

有利面:
- 让菜鸟们不能打开你的地图并篡改它。
- 让你显得很聪明
- 因为删除了某些文件而使地图变小。
不利面:
- 它实际上是没用的
- 大家不能研究你的地图
- 自己丢失原版后将无法对地图进行修改

地图的破译

大家拿到文件包以后可以看到里边有很多文件,

这个都是用mpqediten解开地图以后的文件

只不过我根据这些文件的文件头整理了一下,重新命了一次名。

这些文件都是地图的原始数据我们可以*直接修改它们来达到修改地图的内容。

下边是一些有用的文件的列表

war3map.w3u 单位

war3map.w3t 物品

war3map.w3b 可破坏的

war3map.w3d 地形装饰物

war3map.w3a 技能

war3map.w3h 魔法特效

war3map.w3q 升级

等等,这些都是地图的基本设置文件,

我们可以用WE中的物品编辑器直接导入进行编辑。

war3map.wtg 触发事件

这个是保存各种触发事件的地方。我们在地图里搞装备合成,刷怪,作任务

等,都是依*触发指令来完成的。但是一般的加密地图都把war3map.wtg和war3map.wts删除了。

war3map.j jass数据库

这个是地图的核心,所有跟地图设置有关的资料如地图摆放的建筑物、角色、技能、触发事件的指令等等,只可惜是用jass语言保存的。如果你懂jass的话可以在这个文件里任意改动任何数据。包括触发指令。

war3map.shd 地层数据

war3map.wpm mp3,wav等媒体文件的设置

war3mapPreview.tga 地图缩略图

war3mapmap.blp 图形文件的设置

war3mapmisc.txt 游戏平衡常数

下边是最重要的,因为很多人把文件修改完以后都不知道该怎么还原。

我们现在就要用到mpqediten或MPQWorkshop了

新建一个MPQ文件,然后把那些文件全部添加进去再保存。

现在你们得到一个MPQ文件了。下一步是添加w3x地图文件的文件头

你们用UltraEdit-32随便打开一个w3x魔兽地图文件和自己的mpq文件。

对比一下,你们就会发现w3x文件比MPQ文件多了一个16字节的文件头

后边的事我不用说了吧,w3x文件中复制,然后在MPQ中粘贴这个

16字节的文件头,然后把后缀名MPQ改成w3x就可以了。

修改地图就是这么简单,欢迎大家修改地图,尤其是好地图

-======= 基本常规问题类 =======- [G-1]
-=怎么手动加密地图啊??=-
1) 首先 FILE -> EXPORT SCRIPTS ~~导出一个脚本文件命名为 WAR3MAP.J ~~
2) 建立两个空文件~~命名为 WAR3MAP.WTG 、WAR3MAP.WCT ~~
3) 建立一个空文件命名为 (listfile) ~~
4) 把上面四个文件都用 IMPORT MANAGER 导入~~
5) 全部自己定义路径~~具体如下:
SCRIPTS\WAR3MAP.J
WAR3MAP.WTG
WAR3MAP.WCT
(listfile)

-=怎么才能让英雄可以超过10级啊?=-
Menu(菜单) -> Advenced(高阶) -> Gameplay Constant(游戏<平衡>常数) -> Hero - Max Level(英雄 - 最大等级)

-=怎麼讓五级以上英雄打野生動物也能得到经验?=-
Menu -> Advenced -> Gameplay Constant -> Hero Xp Gained - Creep Reduction Table(英雄经验获取 - 野生单位经验表)
表中每一项表示每一等级可以获得的经验百分比~~如:
第一個數值為等級 1 的英雄杀掉野生動物可得到的經驗的百分比~~
第二個數值為等級 2 的英雄~~如此類推~~

-=怎么修改游戏读取时显示的小地图图片啊?=-
1] 先做好你希望显示的小地图图片,格式要求是 24/32bit 的 TGA 格式,尺寸为 256x256。
2] 然后使用 TGA<->BLP工具 转换成 BLP 格式。>>点击下载转换工具<<
3] 用 WE 开启地图,打开 IMPORT MANAGER(F12) ~~将图片导入。
4] 如果希望图片仅在读取事有效,则重命名为 WAR3MAPPREVIEW.BLP 。
5] 如果希望覆盖掉游戏中的小地图,则重命名为 WAR3MAPMAP.BLP 。

-=关于 Angle Attack 究竟是什么呢?=-
Angle Attack 就是视角~~
很多人不明白具体的角度代表什么位置的视角~~这个图片可以很清楚的表示出来`~
今天翻以前的教程找到的~~:)~~
来点掌声哦!

啊?我用WE感觉好慢!=-
Menu(菜单) -> Window(窗口) -> Brush List(图刷列表)
把这个列表关闭后速度就会得到很大程度的提升了~~

-=我想把地图A的触发复制到地图B,但是为什么总是缺少变量而出错啊?=-
因为在复制TRIGGER的时候不会复制TRIGGER用到的变量,所以就会出错了,解决方法是打开复制未知变量的功能:
Menu -> File -> Preferences -> General -> Automatically create unknown variables while pasting triggers

-=怎么才能给字加上颜色啊?=-
在WAR3中~~经常可以看到带颜色的字~~无论是地图名称~~还是技能道具说明~~或者对话什么什么地方~~都可以用 显色标签 来为特定的字加颜色~~
标签的格式是 |CTTRRGGBBTEXT|R
‘|C’ 是显色标签的开始部分~~
‘|R’ 是显色标签的结束部分~~
‘TTRRGGBB’ 是色彩代码~~采用4组2位16进制来确定颜色~~
第一组 ‘TT’ 表示透明度~~
第二组 ‘RR’ 表示红色~~
第二组 ‘GG’ 表示绿色~~
第二组 ‘BB’ 表示蓝色~~
‘TEXT’ 位置就是你需要显色的文字了~~
[例]:|cff004444DANEXX是猪|r -> DANEXX是猪
[注]:16进制为 0123456789ABCDEF ~~
Set Player_colors[1] = |cffff0303
Set Player_colors[2] = |cff0042ff
Set Player_colors[3] = |cff1ce6b9
Set Player_colors[4] = |cff540081
Set Player_colors[5] = |cfffffc00
Set Player_colors[6] = |cfffe8a0e
Set Player_colors[7] = |cff20c000
Set Player_colors[8] = |cffe55bb0
Set Player_colors[9] = |cff959697
Set Player_colors[10] = |cff7ebff1
Set Player_colors[11] = |cff106246
Set Player_colors[12] = |cff492a04

-=为啥我在这里下的有些地图电脑说太大了玩不了啊?为什么我要开始游戏的时候总是说我缺少一个对手不能开始游戏呢?=-
这种地图需要在 SINGLE PLAYER(单一玩家) -> CUSTOM GAME(自定义游戏) 中进入~~

-=扩展名为 .W3N 的战役要放在哪里~~怎么才能玩啊?=-
W3N 文件需要放在游戏目录下的 CAMPAIGNS 文件夹下面~~ 在 SINGLE PLAYER(单一玩家) -> CUSTOM CAMPAIGNS(自定义战役) 中进入~


orachard 2006-01-13 14:34
今天真的很累了!!明天将会继续吧!!!!

下面我将会发新手制作地图的方法。希望大家支持!!


orachard 2006-01-13 15:09
单位数据详解--战斗部分

武器类型:没有、普通、立即的、炮火、炮火(直线)、箭矢、箭矢(溅射)、箭矢(反弹)、箭矢(直线)
没有 - 不能攻击其它单位,如小精灵、鬼魂
普通 - 所有近战单位,受吸血光环、荆棘光环影响,不受强击光环影响。//注:大多3C里狼洞的狼的射程虽有600但还是属于近战单位
立即的 - 代表单位有火枪手和直升飞机,与其它远程攻击比较它的优势是攻击发出后立即作用于目标单位,不用担心子弹在空中飞行而有所延时
炮火 - 范围溅射性攻击,以目标单位为圆心周围的单位都会受到伤害,攻击范围有下限,即目标距离太近时无法攻击目标,被打死的目标没有尸体。代表单位有迫击炮小队、粉碎者、绞肉车
炮火(直线) - 直线溅射性攻击,能伤害到站在目标后面的其他单位,攻击范围有下限,即目标距离太近时无法攻击目标,被打死的目标没有尸体。代表单位有投刃车
箭矢 - 最常见的远程攻击模式,也是最没个性的模式=。=!
箭矢(溅射) - 范围溅射性攻击,以目标单位为圆心周围的单位都会受到伤害。代表单位 奇美拉、变身后的恶魔猎手
箭矢(反弹) - 代表单位是女猎手
箭矢(直线) - 直线溅射性攻击,能伤害到站在目标后面的其他单位。代表单位是狮鹫骑士
主动攻击范围: 主动攻击进入有效范围的敌方单位,与之相对应的是被动攻击--当原单位或它附近的朋友被攻击时会反击。注:当主动攻击范围设为0时实际是最范围。
允许攻击模式:没有、只攻击1、只攻击2、都
没有 - 不能攻击其它单位
只攻击1 - 只有 (战斗-攻击1-) 里的数据起作用
只攻击2 - 只有 (战斗-攻击2-) 里的数据起作用
都 - (战斗-攻击1-) 和 (战斗-攻击2-)里的数据都起作用,但是在目标允许的选项里有重叠的话则只发挥攻击1里的数据的作用
基础防御:单位的初始防御或英雄敏捷为0时的防御。注:英雄默认的基础防御是-2
全伤害影响范围
中等伤害影响范围
伤害因素-中等的
小伤害影响范围
伤害因素-小的
以上数据只对应武器类型为 箭矢(溅射) 和 炮火 起作用。以变身后的恶魔猎手为例分析
全伤害影响范围 50
中等伤害影响范围 150
伤害因素-中等的 0.50
小伤害影响范围 250
伤害因素-小的 0.25
在以目标单位为圆心,50为半径的圆内的单位将受到与目标同等的伤害; 在以目标单位为圆心,50为内径,150为外径的圆环内的单位将接受目标50%的伤害; 在以目标单位为圆心,150为内径,250为外径的圆环内的单位将接受目标25%的伤害。
补:全伤害影响范围还对箭矢(反弹) 起作用,当然两个单位的距离小于这个范围时就有可能被反弹的箭矢击到
伤害丢失因素:对应武器类型为箭矢(反弹)、箭矢(直线)、炮火(直线)起作用。如女猎手的伤害丢失因素是0.5,意为被反弹到的下一个单位所受伤害为前一个单位的50%; 投刃车的伤害丢失因素是0.2,意为被溅射到的单位所受伤害为主单位的80%。
基础伤害
伤害数量概率
攻击伤害面
三者共同决定单位的实际攻击力。设基础伤害为A,伤害数量概率为B,攻击伤害面为C,那么该单位的攻击力为A+B~A+B*C。以对战中的火枪手为例,A=16,B=2,C=4,他的实际攻击力就是18~24。注:伤害数量概率和攻击伤害面最好不要设为0,否则会有BUG
伤害升级数量:与升级科技中的攻击伤害奖励对应,与防御升级奖励相类似
允许伤害范围目标:对武器类型为炮火、炮火(直线)、箭矢(溅射)、箭矢(反弹)、箭矢(直线)的单位有效。变身的恶魔的溅射不会伤害到自己人而奇美拉会,炮手拆建筑时旁边的树会倒,这些的不同都可在此修改
动画回复点
动画损伤点
决定攻击动作与发出箭矢的同步性。动画损伤点的另一个作用就是限制单位最大攻击速度,即单位的最小攻击冷却时间不能低于动画损伤点
射弹弧度:顾名思义吧
射弹速率:还是顾名思义吧=。=!,设高无所谓,设得太低这个单位就废了
投射图像:顾名思义……^_^
射弹自导允许:设为true时射出的箭矢会自动跟踪目标而不会因为目标移动而打空,代表单位为不死族的所有防御塔。设为false则与之相反,代表单位为所有远程攻城单位
显示UI:没发现有什么实际作用
溅射伤害范围
溅射伤害距离
对武器类型为炮火(直线)、箭矢(直线)的单位起作用
目标允许:空中、地面、建筑、守卫、中立、别人的、古代的、可攻击的、地形、墙、敌人、无敌的、有机的、朋友、机械的、树、桥、死亡、残骸、没有、活的、物品、玩家单位、结盟的、自己的、自杀性的、英雄、装饰品、非-古代的、非-自杀性的、非英雄。
空中、地面、建筑、守卫是4大类,如果选只选了这4项就能够攻击绝大部分物体。这4项必须至少选一项,否则单位就无法战斗(当然它还可以砍柴)。中立、敌人、朋友是一组,设为A组,默认为全选。别人的、自己的是一组,设为B组,默认为全选、原理同上。古代的(应译为古树)、非古代的为又C组,原理同上。可攻击的、无敌的为D组,默认为可攻击的。有机的、机械的为E组,默认为全选。死亡、活的为F组,默认为活的。玩家单位、结盟的,其实这两项应该是朋友的支项,也可以将A组分成中立、敌人、玩家单位、结盟的。英雄、非-英雄为G组,默认为全选。自杀性的、非-自杀性的还没弄明白什么意思。从A到G,7组。组内是兼容的,即满足其中一个就可执行,组间是不兼容的,即某个物体要成为目标允许的对象,而且已经满足了其中一组的条件,那么它必须也要满足其它6组的条件。
运动范围缓冲:未知……
远程:应该译为射程或攻击范围
魔法施放时间间隔时间:应该译为(初始)攻击冷却时间,单位的最小攻击冷却时间不能低于(初始)攻击冷却时间的1/5
最小攻击范围:较常作用于攻城单位,即太近不能攻击
死亡类型:会腐化则有尸体,不会腐化则没有
装甲类型:声音效果而已
锁定作为:与目标允许对应
防御升级奖励:与科技升级中的应用防御升级奖励相对应
攻击类型
防御类型


orachard 2006-01-13 21:53
====这里是一些很初级的问题收集,比如“地图编辑器是什么、在哪里”=====

Q:什么是地图编辑器?如何打开?

地图编辑器是Blizzard(暴雪:魔兽争霸的制作组织)提供给所有玩家的创建和编辑属于自己的地图的工具。在WAR3(魔兽3)的游戏目录下找到World Editor(世界编辑器),双击打开,这个就是地图编辑器。

Q:什么是Object Editor?

Object Editor就是对象编辑器,其中包含了单位编辑器,技能编辑器,装饰物编辑器,科技编辑器等,可以允许地图制作者修改已有的上述对象或者建立新的对象。
打开对象编辑器的方法是在地图编辑窗口按F6或者点击快截工具栏中的头盔样按钮。

Q:什么是Trigger?

Trigger就是触发器,在地图编辑窗口按F4或者点击快截工具栏中的带有a字的按钮即可打开Trigger Editor(触发器编辑器)。
触发器是地图编辑器中用于控制地图中所发生的事件的工具,一个基本的触发器由Event(事件),Condition(环境/条件),Action(动作)三部分组成。下面用一个简单的例子来说明这三部分之间的关系:
“你在此论坛提出的有价值的问题都会得到解答”
如果将上面这句话看做一个触发器,那么“你提出问题”就是整个触发器的Event(事件),接下来要发生的一切,不管是“我们为你解答问题”或者“我们不理会你”,都是在“你提出问题”之后发生的。
而限制你所提出的问题是否会得到解答的条件则是“你提出的问题有价值”,也就是整个触发器的条件,这个条件直接影响你“是否得到我们的解答”。
最后,当你提出的问题满足“有价值”这个条件的时候,就会发生“我们为你解答问题”这个动作,也就是整个触发器的动作。

Q:什么是JASS?

JASS是用于编辑地图的一种简单的语言,可以说是文本化以后的触发器(地图脚本:MAP SCRIPTS),但是由于触发器并没有提供JASS所具备的所有功能,所以可以说JASS在某种意义上是触发器功能的扩展。
编辑JASS可以通过以下三种途径:
1, 在触发编辑器(TRIGGER EDITOR)中,通过 MENU -> EDIT -> CONVERT TO CUSTOM TEXT 可以将当前选定的触发转换成脚本模式,也就是以JASS编辑的模式。
2,在触发编辑器中点击触发树(TRIGGER TREE,就是最左边列出所有触发的地方)的最顶端地图名,可以进入自定义脚本功能块,在这里可以用 JASS 写需要的函数,并且在其他的触发器中通过命令来调用。

3,使用 ACTIONS 中的 CUSTOM SCRIPT 动作可以在触发中插入一行 JASS 脚本代码。

Q:什么是“高级-游戏平衡常数”(英文名称Advanced - Gameplay Constants)

最上方菜单左起第7个菜单上数第4个选择,这个选项里面包括了很多不能用T修改但是很有用的设置。比如买卖东西的距离,各种攻击类型对防御类型的伤害,英雄的等级经验复活数据等等。

Q:地图扩展名中的w3m,w3x,w3n,w3g分别是什么意思?

w3m:混乱之制(roc)版本的地图。
w3x:冰封王座(tft)版本的地图。
w3n:战役地图,这类地图必须放在War3(魔兽)目录下的Campaigns(战役)文件夹中才能使用。
w3g:游戏录象,位于War3(魔兽)目录下的Replay文件夹下。

E:地图类型解释

Melee - 对战地图,即 War3 默认的游戏方式,BN Ladder 指定游戏类型。
Non-Melee - 除了 melee 以外的所有类型统称。
Custom - 非官方地图,但是通常表示 非官方的 non-melee 地图。
RPG - Role Play Games(角色扮演)~~但是现在很多人把所有 Non-Melee 地图都叫成 RPG。
Mini - 迷你游戏,通常指没有突出剧情、快节奏、游戏周期短的地图,没有固定的游戏方式,不含 rpg 。
Offence - 通常是对抗性地图统称,有时也表示一些进攻npc为主题的地图。
3C - Offence 的一种,本来只是一个地图的名称,通常是指 有 3条进攻路线的 Offence 。
Arena - Offence 一种,竞技场,通常是指选定英雄后在固定区域内进行决斗的地图。
Defence - 通常是指防守性地图统称,有时候也表示一些在非平衡的 NPC进攻前提下的防守与反攻。
TD - Defence 的一种,建造 Tower(炮台) 防守 NPC 有规律的进攻。
Cutscene - 通常是指剪辑影片,内容比较简单。(非 CG )
Cinematic - 通常是指完整影片,内容比较丰富。(非 CG )


orachard 2006-01-13 21:54
转帖][WE] 地精研究部分成果及有用资料部分Order

没有string形式的id
0xD0002(851970) -- 和smart(右键点击)基本相同, 区别是对地上物品使用该order不会去主动捡起来
0xD0005(851973)/0xD0007(851975)/0xD0013(851975) -- 都和stop一样
0xD0017(851979) -- 设定移动目标点后移动到该位置并抖动身体, 很奇怪的命令
0xD0033(852019) -- 同harvest

还有一些奇怪的ID, 虽然有string形式, 但猜不出有什么用
0xD0016(851978), "AImove" -- 感觉上和move一样, 没发现什么区别
0xD002F(852015), "detectaoe" -- 不知作用
0xD0037(852023), "neutralaoe" -- 不知作用
0xD004B(852043), "board" -- 不知作用
0xD004C(852044), "forceboard" -- 不知作用

//by 游戏鸬鹚·枫叶红杏猫
//2004-4-9

常规通用Order-----------------------------------

右键点击:smart(851971)-点目标/单位目标
移动:move(851968)-点目标/单位目标
停止:stop(851972)-没有目标
保持位置:holdpostion(851993)-没有目标
攻击:attack(851983)-点目标/单位目标
攻击一次:attackonce(851985)-单位目标
巡逻:patrol(851990)-点目标/单位目标
攻击地面:attackground(851983)-点目标
设定集结点:setrally(851908)-点目标/单位目标
选择使用者:neutralinteract(852566)-单位目标
搭乘(登上可装载类单位):load(825046)-单位目标
卸载(登下可装载类单位):load(825047)-单位目标
装载单位(海面船只)-board(852043)-单位目标
卸载单位-stop(851972)-没有目标
卸载全部单位-unloadall(825048)-点目标
普通修理、打开/关闭:repair/repairon/repairoff(852024/852025/852026)-点目标/没有目标
僧侣类修理、打开/关闭:restoration/restoraionon/restorationoff(852024/852025/852026)-点目标/没有目标
小精灵类修理、打开/关闭:renew/renewon/renewoff(852024/852025/852026)-点目标/没有目标
取消建造:(851976)-没有目标
采集:harvest(852018)-单位目标
自动采集(采集类单位自动重复采集动作):(852019)-单位目标
运送资源:-resumeharvesting(852017)没有目标/单位目标
祭坛复活英雄第一格/第二格/第三格…:(852027/852028/852029)-没有目标
小旅店快速复活英雄第一格/第二格/第三格…:(852462/852463/852464)-没有目标
移动物品1格-6格:(852002、852003、852004、852005、852006、852007)-单位目标
使用物品1格-6格:(852008、852009、852010、852011、852012、852013)-单位目标
人类Order------------------------------------

<农民>
战斗号召:milita(852072)-没有目标
回到工作:militaoff(852073)-没有目标
建造城镇大厅:townhall(1752461175)-点目标
建造兵营:humanbarracks(1751277938)-点目标
建造伐木场:humanlumbermill(1751938413)-点目标
建造铁匠铺:blacksmith(1751280737)-点目标
建造农场:farm(1751674741)-点目标
建造英雄祭坛:altarofkings(1751215220)-点目标
建造神秘圣地:arcanesanctum(1751216755)-点目标
建造车间:workshop(1751216749)-点目标
建造岗哨塔:scouttower(1752659063)-点目标
建造狮鹫笼:gryphonaviary(1751609953)-点目标
建造神秘商店:arcanevault(1752591476)-点目标

<血魔法师>
学习烈焰风暴:(1095263859)-没有目标
烈焰风暴:flamestrike(852488)-点目标
学习驱散:(1095262830)-没有目标
驱散:banish(852486)-单位目标
学习魔法吸取:(1095263346)-没有目标
魔法吸取:drain(852487)-单位目标
学习召唤凤凰:(1095266424)-没有目标
召唤凤凰:summonphoneix(852429)-没有目标

<圣骑士>
学习神圣之光:(1095264354)-没有目标
神圣之光:holybolt(852092)-单位目标
学习神圣护甲:(1095263347)-没有目标
神圣护甲打开/关闭:divineshied/undivineshied(852090/852091)-没有目标
学习专注光环:(1095262564)-没有目标
学习复活:(1095266917)-没有目标
复活:resurrection(852094)-没有目标

<山丘之王>
学习雷霆一击:(1095267427)-没有目标
雷霆一击:thunderclap(852096)-没有目标
学习风暴之锤:(1095267426)-没有目标
风暴之锤:thunderbolt(852095)-单位目标
学习重击:(1095262824)-没有目标
学习天神下凡:(1095262582)-没有目标
天神:avatr(852086)-没有目标

<大法师>
学习暴风雪:(1095262842)-没有目标
暴风雪:blizzard(852089)-点目标
学习水元素:(1095268197)-没有目标
水元素:waterelemental(852097)-没有目标
学习辉煌光环:(1095262562)-没有目标
学习群体传送:(1095265652)-没有目标
群体传送:massteleport(852093)-点目标/单位目标

<城镇大厅>
训练农民:peasant(1752196449)-没有目标
升级到主城:keep(1751868773)-没有目标
升级到城堡:castle(1751343475)-没有目标

<人类兵营>
训练剑士:footman(17515436633)-没有目标
训练火枪手:rifleman(1752328550)-没有目标
训练骑士:knight(1751871081)-没有目标
研究防御:(1382573157)-没有目标
研究长管火枪:(1382576745)-没有目标
研究动物作战技术:(1382572398)-没有目标

<伐木场>
研究伐木效率:(1382575208)-没有目标
研究石工技术:(1382572387)-没有目标

<铁匠铺>
研究剑术:(1382575461)-没有目标
研究铁甲:(1382572402)-没有目标
研究火药:(1382576737)-没有目标
研究皮甲:(1382575201)-没有目标

<国王祭坛>
召唤血魔法师:bloodmage(1214409837)-没有目标
召唤大法师:archmage(1214344551)-没有目标
召唤山丘之王:mountainking(1215130471)-没有目标
召唤圣骑士:paladin(1215324524)-没有目标

<神秘圣地>
训练牧师:priest(1752002674)-没有目标
训练女巫:sorceress(1752395634)-没有目标
训练破法者:spellbreaker(1752395892)-没有目标
研究女巫专家:(1382577012)-没有目标
研究牧师专家:(1382576244)-没有目标
研究控制魔法:(1382577011)-没有目标
研究魔法岗哨:(1382576997)-没有目标

<车间>
训练飞行机器:flyingmachine(1751617762)-没有目标
训练迫击炮小队:mortarteam(1752003693)-没有目标
训练蒸汽机车:siegeengine(1752003700)-没有目标
研究高射炮火:(1382573677)-没有目标
研究飞行器炸弹:(1382573922)-没有目标
研究碎片攻击:(1382573683)-没有目标
研究照明弹:(1382573676)-没有目标
研究弹幕攻击:(1382576756)-没有目标

<岗哨塔>
箭塔:guardtower(1751610487)-没有目标
神秘之塔:humanarcanetower(1751217217)-没有目标
炮塔:cannontower(1751348143)-没有目标

<狮鹫笼>
训练狮鹫:gryphonrider(1751609977)-没有目标
训练龙鹰骑士:dragonhawk(1751410807)-没有目标
研究风暴战锤:(1382574178)-没有目标
研究乌云:(138252900)-没有目标

<神秘商店>
购买恢复卷轴:(1936876903)-没有目标
购买小净化药水:(1886151532)-没有目标
购买机械的小玩意:(1835233897)-没有目标
购买生命药水:(1885889889)-没有目标
购买魔法药水:(1886216558)-没有目标
购买回城卷轴:(1937012592)-没有目标
购买象牙塔:(1953719156)-没有目标
购买火焰之球:(1868982642)-没有目标
购买避难权杖:(1936941442)-没有目标

<人族船坞>
训练人族运输船:humantransportship(1751281524)-没有目标

<高精兵营>
训练高精剑士:highelvenswordman(1751672197)-没有目标
训练高精弓箭手:highelvenarcher(1852335457)-没有目标
训练龙鹰:windserpent(1853322033)-没有目标

<步兵>
防御打开/关闭:defend/undefend(852055/852056)-没有目标

<牧师>
治疗、打开/关闭:heal/healon/healoff(852063/852064/852065)-单位目标、没有目标
驱散魔法:dispel(852057)-点目标
心灵之火、打开/关闭:innerfire/innerfireon/innerfireoff(852066/852067/852068)-单位目标、没有目标

<女巫>
减速、打开/关闭:slow/slowon/slowoff(852075/852076/852077)-单位目标、没有目标
隐形:invisiblity(852069)-点目标
变羊:polymorph(852074)-点目标

<破法者>
魔法防御打开/关闭:magicdefense/magicundefense(852478/852479)-没有目标
魔法盗取、打开/关闭:spellsteal/spellstealon/spellstealoff(852483/852484/852485)-单位目标、没有目标
控制魔法:controlmagic(852474)-点目标

<迫击炮小队>
照明弹:flare(852060)-点目标

<龙鹰骑士>
空中锁链:magicleash(852480)-单位目标
乌云:cloudoffog(852473)-点目标

<凤凰>
变蛋-phoneixmorph(852482)-没有目标

<麦迪文>
乌鸦形态打开/关闭-ravenfrom/unravenfrom(852155/852156)-没有目标

娜伽Order--------------------------------------

<娜伽通用>
潜水-submerge/unsubmerge(825604/825605)-没有目标

<穆格尔奴隶>
建造潮汐神庙:templeoftides(1852732532)-点目标
建造产卵之地:spawninggrounds(185272263)-点目标
建造珊瑚礁:coralbed(1852728941)-点目标
建造守护者:tidalguardian(1852732519)-点目标
建造艾萨拉女王庙:shrineofazshara(1852732257)-点目标
建造深渊祭坛:altarofthedepths(1852727652)-点目标

<潮汐神庙>
训练穆格尔奴隶:murgulslave(1852665957)-没有目标
训练穆格尔掠夺者:nagamurgul(185230727)-没有目标
研究珊瑚剑:(1382965602)-没有目标
研究长管火枪:(1382965613)-没有目标
研究潜水:(1382970210)-没有目标

<产卵之地>
训练娜伽暴徒:nagamyrmidion(1852668674)-没有目标
训练飞龙:snapdragon(1853058672)-没有目标
训练龙龟:campaignturtle(1852340579)-没有目标
研究诱捕:(1382966638)-没有目标

<艾萨拉女王庙>
训练娜伽海妖:siren(1852732279)-没有目标
训练飞蛇:nagacoutl(1853319027)-没有目标
研究娜伽海妖专家训练:(1382970231)-没有目标
研究驱散魔法:(1382970217)-没有目标

<娜伽海妖>
寄生虫、打开/关闭:parasite/parasiteon/parasiteoff(852601/852602/852603)-单位目标、没有目标

<召唤者>
召唤仪式:roar(852164)-没有目标

通用Order--------------------------------------

<娜伽女巫>
学习*状闪电:(1095657068)-没有目标
*状闪电:forkedlightning(852587)-单位目标
学习霜冻之箭:(1095657057)-没有目标
霜冻之箭、打开/关闭:coldarrowstarg/coldarrows/uncoldarrow(852243/852244/852245)-单位目标/没有目标
学习魔法护盾:(1095658867)-没有目标
魔法护盾有效、无效:manashieldon/shieldoff(852589/852590)-没有目标
学习龙卷风:(1095660566)-没有目标
龙卷风:tornado(852597)-点目标/单位目标

<黑暗游侠>
学习沉默魔法:(1095660393)-没有目标
沉默魔法:slience(852592)-点目标
学习黑暗之箭:(1095656033)-没有目标
黑暗之箭、打开/关闭:blackarrow/blackarrowon/blackarrowoff(852577/852578/852599)-没有目标/单位目标
学习生命汲取:(1095656562)-没有目标
生命汲取:drain(852487)-单位目标
学习符咒:(1095660566)-没有目标
符咒:charm(852581)-单位目标

<熊猫人酒仙>
学习火焰呼吸:(1095656038)-没有目标
火焰呼吸:breathoffire(852580)-点/单位目标
学习酒罪云雾:(1095656552)-没有目标
酒醉云雾:drunkenhaze(852585)-单位目标
学习醉拳:(1095656546)-没有目标
学习火土风暴:(1095656806)-没有目标
火土风暴:elementalfury(852586)-没有目标

<兽王>
学习召唤熊:(1095660391)-没有目标
召唤熊:summongrizzly(852594)-没有目标
学习召唤豪猪:(1095660401)-没有目标
召唤豪猪:summonquillbeast(852595)-没有目标
学习召唤战鹰:(1095660407)-没有目标
召唤战鹰:summonwareagle(852596)-没有目标
学习惊吓:(1095660404)-没有目标
惊吓:stampede(852581)-单位目标/点目标

<深渊领主>
学习火焰雨:(1095660134)-没有目标
火焰雨:rainoffire(852238)-点目标
学习分裂攻击:(1095656289)-没有目标
学习恐怖嚎叫:(1095657588)-没有目标
恐怖嚎叫:howlofterro(852588)-没有目标
学习魔鬼缠身:(1095656559)-没有目标
魔鬼缠身:doom(852583)-单位目标/点目标

<小酒店>
召唤娜伽女巫:seawitch(1315858291)-没有目标
召唤黑暗游侠:darkranger(1315074670)-没有目标
召唤熊猫人酒仙:padarenbrewmaster(1315988077)-没有目标
召唤兽王:pitlord(1315990632)-没有目标
召唤深渊领主:beastmaster(1315074932)-没有目标

<地精船坞>
雇佣地精运输船:transportship(1851944820)-没有目标

<雇佣兵军团>
雇佣树魔影子牧师:foresttrollshadowpriest(1852207984)-没有目标
雇佣树魔狂战士:foresttrollberserker(1852208226)-没有目标
雇佣泥潭傀儡:mudgolem(1852273529)-没有目标
雇佣食人鬼拳手:ogre2(1852794733)-没有目标

<红龙巢穴>
雇佣红幼龙:reddragonwhelp(1852990571)-没有目标
雇佣红浮游:reddrake(1852990578)-没有目标
雇佣红龙:reddragon(1852995437)-没有目标

<地精实验室>
雇佣地精工兵:goblinsapper(1852273520)-没有目标
雇佣地精飞艇:goblinzeppelin(18523515120)-没有目标
雇佣地精伐木机:goblinshredder(1852270962)-没有目标
显示:neutraldetectaoe(852023)-点目标

<地精商店>
购买速度之靴:(1651732580)-没有目标
购买生命护生符:(1886549620)-没有目标
购买贵族圆环:(1668181858)-没有目标
购买尘土之影:(1685418868)-没有目标
购买守护卷轴:(1936749167)-没有目标
购买隐形药水:(1885957750)-没有目标
购买回城卷轴:(1937012592)-没有目标
购买传送权杖:(1937007980)-没有目标
购买再训练之书:(1953654132)-没有目标
购买群体医疗:(1936221537)-没有目标
购买无敌药水:(1886287468)-没有目标

特效附着点列表~~~~

(主要骨架附着点)PRIMARY BONES
(胸)chest bone_chest
(足)foot bone_foot unused
(手)hand bone_hand unused
(头)head bone_head
(炮塔?)turret bone_turret

(骨架附着点位置修正)BONE QUALIFIERS
(互生?交替?)alternate alternate
(左)left left unused
(骑马的)mount mount unused
(右)right right unused
(灵巧的?大大的?)smart smart unused

(主要身体部位附着点)PRIMARY LINK POINTS
(胸)chest chest
(双足)feet feet
(足)foot foot
(手)hand hand
(头)head head
(原点?来源?)origin origin
(头顶)overhead overhead
(魂?点?)sprite sprite (for building attachment points)
(武器)weapon weapon

(身体部位附着点位置修正)LINK POINT QUALIFIERS
(互生?交替?)alternate alternate
(左)left left
(骑马的)mount mount
(右)right right
(背后)rear rear
(灵巧的?大大的?)smart smart
(第一?)first first (for building attachment points)
(第二?)second second (for building attachment points)
(第三?)third third (for building attachment points)
(第四?)fourth fourth (for building attachment points)
(第五?)fifth fifth (for building attachment points)
(第六?)sixth sixth (for building attachment points)
(小?)small small (for building attachment points)
(中?)medium medium (for building attachment points)
(大?)large large (for building attachment points)
(金?农民采矿后被上背的金袋?)gold gold
(聚集点?)rally rallypoint (for building attachment points)
(吞噬树木?)eattree eattree
-------------------------------------------------------------------------------------------
基本规则:
PRIMARY,QUALIFIERS(左手如:hand,left)

关于Warcraft 3攻击速度的研究

基本知识:

1. cooldown和attack speed
很简单 attack speed = 1 / cooldown
每个单位或者英雄有个初始攻击cooldown

2. agi和attack speed
attack speed = 初始 attack speed * ( 1 + 0.02 * agi )
所以agi越高, 实际上每点增加的攻击速度越少

3. slow, fast, very fast
slow 的分界线是: attack cooldown = 2s
fast 的分界线是: attack cooldown = 1.5s
very fast 的分界线是: attack cooldown = 1s

不为人知的隐藏知识 :

1. 技能对攻击速度的影响方式(包括宝物, 魔法)
技能里面写的增加攻速50%, 是50%么? 答案是: NO!
举个例子, +15%攻击速度的手套, 加的攻速是这样的:
攻速 = 初始攻速 * ( 1 + 15% ) * ( 1 + 15% + 0.02 * agi )
也就是说, 加15%被计算了2次, 在第一次的时候, 其实已经增加了15%, 所以, 当没有别的影响攻速的宝物或者魔法的时候, 实际增加的攻速大于显示的值!
我个人认为这个是个bug

2. 攻击速度上限
roc的攻击速度没有上限, 但是tft英雄的攻击速度存在上限了, 这个上限对于不同的英雄是不同的, 和英雄的初始攻击速度有关, 是个固定的比例
存在攻速上限意味着, agi加到一定程度, 再怎么增加也不会增加攻速, 再怎么使用加速魔法, 加速宝物也不能增加任何的速度
这个上限并不太高, 而且他是各种影响攻速的条件共同达到的, 也就是说, 正常可能是300 agi达到攻速上限, 但是因为你带了个加速50%的宝物, 而在200 agi就打到了攻速上限

对于初始攻击速度的特别高的人, 有可能遇到另一个瓶颈是Animation Damage Point, 但是并不是这个值是0.5就是最低cooldown只能到0.5, 一般除非初始cooldown特别低(1s左右或者以下?), 遇到的上限瓶颈并不是这个

目前为止最详细的 OrderID <=> OrderString 对照表:(Soar 提供)

0xD0002=(smart)
0xD0005=(stop)
0xD0007=(stop)
0xD0013=(stop)
0xD0017=(shakebody)
0xD0033=(harvest)

0xD0003=smart
0xD0004=stop
0xD0008=(cancel)
0xD000C=setrally
0xD000D=getitem
0xD000F=attack
0xD0010=attackgrouned
0xD0011=attackonce
0xD0012=move
0xD0014=AImove
0xD0016=patrol
0xD0019=holdposition
0xD001A=build
0xD001B=humanbuild
0xD001C=orcbuild
0xD001D=nightelfbuild
0xD001E=undeadbuild
0xD001F=resumebuild
0xD0021=dropitem
0xD0022=(putitem1)
0xD0023=(putitem2)
0xD0024=(putitem3)
0xD0025=(putitem4)
0xD0026=(putitem5)
0xD0027=(putitem6)
0xD0028=(useitem1)
0xD0029=(useitem2)
0xD002A=(useitem3)
0xD002B=(useitem4)
0xD002C=(useitem5)
0xD002D=(useitem6)
0xD002F=detectaoe
0xD0031=resumeharvesting
0xD0032=harvest
0xD0034=returnresources
0xD0035=autoharvestgold
0xD0036=autoharvestlumber
0xD0037=neutraldetectaoe
0xD0038=repair
0xD0039=repairon
0xD003A=repairoff
0xD003B=(revivehero1)
0xD003C=(revivehero2)
0xD003D=(revivehero3)
0xD003E=(revivehero4)
0xD003F=(revivehero5)
0xD0047=revive
0xD0048=selfdestruct
0xD0049=selfdestructon
0xD004A=selfdestructoff
0xD004B=board
0xD004C=forceboard
0xD004E=load
0xD004F=unload
0xD0050=unloadall
0xD0051=unloadallinstant
0xD0052=loadcorpse
0xD0055=loadcorpseinstant
0xD0056=unloadallcorpses
0xD0057=defend
0xD0058=undefend
0xD0059=dispel
0xD005C=flare
0xD005F=heal
0xD0060=healon
0xD0061=healoff
0xD0062=innerfire
0xD0063=innerfireon
0xD0064=innerfireoff
0xD0065=invisibility
0xD0067=militiaconvert
0xD0068=militia
0xD0069=militiaoff
0xD006A=polymorph
0xD006B=slow
0xD006C=slowon
0xD006D=slowoff
0xD006F=tankdroppilot
0xD0070=tankloadpilot
0xD0071=tankpilot
0xD0072=townbellon
0xD0073=townbelloff
0xD0076=avatar
0xD0077=unavatar
0xD0079=blizzard
0xD007A=divineshield
0xD007B=undivineshield
0xD007C=holybolt
0xD007D=massteleport
0xD007E=resurrection
0xD007F=thunderbold
0xD0080=thunderclap
0xD0081=waterelemental
0xD0083=battlestations
0xD0084=berserk
0xD0085=bloodlust
0xD0086=bloodluston
0xD0087=bloodlustoff
0xD0088=devour
0xD0089=evileye
0xD008A=ensnare
0xD008B=ensnareon
0xD008C=ensnareoff
0xD008D=healingward
0xD008E=lightningshield
0xD008F=purge
0xD0091=standdown
0xD0092=stasistrap
0xD0097=chainlightning
0xD0099=earthquake
0xD009A=farsight
0xD009B=mirrorimage
0xD009D=shockwave
0xD009E=spiritwolf
0xD009F=stomp
0xD00A0=whirlwind
0xD00A1=windwalk
0xD00A2=unwindwalk
0xD00A3=ambush
0xD00A4=autodispel
0xD00A5=autodispelon
0xD00A6=autodispeloff
0xD00A7=barkskin
0xD00A8=barkskinon
0xD00A9=barkskinoff
0xD00AA=bearform
0xD00AB=unbearform
0xD00AC=corrosivebreath
0xD00AE=loadarcher
0xD00AF=mounthippogryph
0xD00B0=cyclone
0xD00B1=detonate
0xD00B2=eattree
0xD00B3=entangle
0xD00B4=entangleinstant
0xD00B5=faeriefire
0xD00B6=faeriefireon
0xD00B7=faeriefireoff
0xD00BB=ravenform
0xD00BC=unravenform
0xD00BD=recharge
0xD00BE=rechargeon
0xD00BF=rechargeoff
0xD00C0=rejuvination
0xD00C1=renew
0xD00C2=renewon
0xD00C3=renewoff
0xD00C4=roar
0xD00C5=root
0xD00C6=unroot
0xD00CB=entanglingroots
0xD00CD=flamingarrowstarg
0xD00CE=flamingarrows
0xD00CF=unflamingarrows
0xD00D0=forceofnature
0xD00D1=immolation
0xD00D2=unimmolation
0xD00D3=manaburn
0xD00D4=metamorphosis
0xD00D5=scout
0xD00D6=sentinel
0xD00D7=starfall
0xD00D8=tranquility
0xD00D9=acolyteharvest
0xD00DA=antimagicshell
0xD00DB=blight
0xD00DC=cannibalize
0xD00DD=cripple
0xD00DE=curse
0xD00DF=curseon
0xD00E0=curseoff
0xD00E3=freezingbreath
0xD00E4=possession
0xD00E5=raisedead
0xD00E6=raisedeadon
0xD00E7=raisedeadoff
0xD00E8=instant
0xD00E9=requestsacrifice
0xD00EA=restoration
0xD00EB=restorationon
0xD00EC=restorationoff
0xD00ED=sacrifice
0xD00EE=stoneform
0xD00EF=unstoneform
0xD00F1=unholyfrenzy
0xD00F2=unsummon
0xD00F3=web
0xD00F4=webon
0xD00F5=weboff
0xD00F6=wispharvest
0xD00F7=auraunholy
0xD00F8=auravampiric
0xD00F9=animatedead
0xD00FA=carrionswarm
0xD00FB=darkritual
0xD00FC=darksummoning
0xD00FD=deathanddecay
0xD00FE=deathcoil
0xD00FF=deathpact
0xD0100=dreadlordinferno
0xD0101=frostarmor
0xD0102=frostnova
0xD0103=sleep
0xD0104=darkconversion
0xD0105=darkportal
0xD0106=fingerofdeath
0xD0107=firebold
0xD0108=inferno
0xD0109=gold2lumber
0xD010A=lumber2gold
0xD010B=spies
0xD010D=rainofchaos
0xD010E=rainoffire
0xD010F=request_hero
0xD0110=disassociate
0xD0111=revenge
0xD0112=soulpreservation
0xD0113=coldarrowstarg
0xD0114=coldarrows
0xD0115=uncoldarrows
0xD0116=creepanimatedead
0xD0117=creepdevour
0xD0118=creepheal
0xD0119=creephealon
0xD011A=creephealoff
0xD011C=creepthunderbold
0xD011D=creepthunderclap
0xD011E=poisonarrowstarg
0xD011F=poisonarrows
0xD0120=unpoisonarrows
0xD01EA=frostarmoron
0xD01EB=frostarmoroff
0xD01EE=(reviveintavern1)
0xD01EF=(reviveintavern2)
0xD01F0=(reviveintavern3)
0xD01F1=(reviveintavern4)
0xD01F2=awaken
0xD01F3=nagabuild
0xD01F5=mount
0xD01F6=dismount
0xD01F9=cloudoffog
0xD01FA=controlmagic
0xD01FE=magicdefense
0xD01FF=magiceundefense
0xD0200=magicleash
0xD0201=phoenixfire
0xD0202=phoenixmorph
0xD0203=spellsteal
0xD0204=spellstealon
0xD0205=spellstealoff
0xD0206=banish
0xD0207=drain
0xD0208=flamestrike
0xD0209=summonphoenix
0xD020A=ancestralspirit
0xD020B=ancestralspirittarget
0xD020D=corporealform
0xD020E=uncorporealform
0xD020F=disenchant
0xD0210=etherealform
0xD0211=unetherealform
0xD0213=spiritlink
0xD0214=unstableconcoction
0xD0215=healingwave
0xD0216=hex
0xD0217=voodo
0xD0218=ward
0xD0219=autoentangle
0xD021A=autoentangleinstant
0xD021B=coupletarget
0xD021C=coupleinstant
0xD021D=decouple
0xD021F=grabtree
0xD0220=manaflareon
0xD0221=manaflareoff
0xD0222=phaseshift
0xD0223=phaseshifton
0xD0224=phaseshiftoff
0xD0225=phaseshiftinstant
0xD0228=taunt
0xD0229=vengeance
0xD022A=vengeanceon
0xD022B=vengeanceoff
0xD022C=vengeanceinstant
0xD022D=blink
0xD022E=fanofknives
0xD022F=shadowstrike
0xD0230=spiritofvengeance
0xD0231=absorb
0xD0233=avengerform
0xD0234=unavengerform
0xD0235=burrow
0xD0236=unburrow
0xD0238=devourmagic
0xD023B=flamingattacktarg
0xD023C=flamingattack
0xD023D=unflamingattack
0xD023E=replenish
0xD023F=replenishon
0xD0240=replenishoff
0xD0241=replenishlife
0xD0242=replenishlifeon
0xD0243=replenishlifeoff
0xD0244=replenishmana
0xD0245=replenishmanaon
0xD0246=replenishmanaoff
0xD0247=carrionscarabs
0xD0248=carrionscarabson
0xD0249=carrionscarabsoff
0xD024A=carrionscarabsinstant
0xD024B=impale
0xD024C=locustswarm
0xD0250=breathoffrost
0xD0251=frenzy
0xD0252=frenzyon
0xD0253=frenzyoff
0xD0254=mechanicalcritter
0xD0255=mindrot
0xD0256=neutralinteract
0xD0258=preservation
0xD0259=sanctuary
0xD025A=shadowsight
0xD025B=spellshield
0xD025C=spellshieldaoe
0xD025D=spirittroll
0xD025E=steal
0xD0260=attributemodskill
0xD0261=blackarrow
0xD0262=blackarrowon
0xD0263=blackarrowoff
0xD0264=breahoffire
0xD0265=charm
0xD0267=doom
0xD0269=drunkenhaze
0xD026A=elementalfury
0xD026B=forkedlightning
0xD026C=howlofterror
0xD026D=manashieldon
0xD026E=manashieldoff
0xD026F=monsoon
0xD0270=silence
0xD0271=stampede
0xD0272=summongrizzly
0xD0273=summonquillbeast
0xD0274=summonwareagle
0xD0275=tornado
0xD0276=wateryminion
0xD0277=battleroar
0xD0278=channel
0xD0279=parasite
0xD027A=parasiteon
0xD027B=parasiteoff
0xD027C=submerge
0xD027D=unsubmerge
0xD0296=neutralspell
0xD02AB=militiaunconvert
0xD02AC=clusterrockets
0xD02B0=robogoblin
0xD02B1=unrobogoblin
0xD02B2=summonfactory

1.17新的order id

0x000D02B6=acidbomb
0x000D02B7=chemicalrage
0x000D02B8=healingspray
0x000D02B9=transmute
0x000D02BB=lavamonster
0x000D02BC=soulburn
0x000D02BD=volcano

12位玩家的标准颜色代码:
|c00ff0000 Player1|r
|c000000ff Player2|r
|c0018e7bd Player3|r
|c00520084 Player4|r
|c00ffff00 Player5|r
|c00ff8a08 Player6|r
|c0018be00 Player7|r
|c00e759ad Player8|r
|c00949694 Player9|r
|c007bbef7 Player10|r
|c00086142 Player11|r
|c004a2800 Player12|r


orachard 2006-01-13 21:56
新手做图入门指导教程〔第一章〕

前言:
现在有很多玩家都对WE有着浓厚的兴趣,而且都想能创作出自己的魔兽地图,虽然在论坛里也有很多相关的讨论贴,但是大部份都是针对一些对WE有一定了解的玩家所做的,而对于刚刚起步并才开始弄WE的玩家则没有一些基本的教程或讨论贴,所以,在此,本人决定以自己学习WE及做图的经验与心得写一个面向初识WE玩家的地图制作指导教程,希望对各位新手们有所帮助!当然要完成一张RPG地图或是对战地图还要有作者的很大的决心及恒心,对魔兽这个游戏,包括战役地图,对战地图及RPG地图要有一定的了解,至少要会玩魔兽。如果你有以上两点条件的话,呵呵,那么请继续往下看吧,你一定会有所收获的!
                 第一章:  认识WE
             第一节 相关的名词及概念
  相信有些新手们还不知道什么是WE吧!呵呵,WE就是World Editor的简写啦,译做中文应该是叫做世界编辑器,这个东西就是大多数地图制作者们的工具了,你只需要在魔兽的安装目录下就能找到了。如果是第一次运行的话,会出现个用户协议之类的,不用管了,有对话框就只管按确定吧!
  关于什么是T?-我们在一些讨论贴中经常会看到一些诸如“用T吧,T不对吧”的语句,其实这个T也是一个简写,它是触发事件编辑器(Trigger),它的功能是很强大的,知道为什么对战地图时一来每个玩家都有一定的资源和单位吗?就是它弄的了,还有像一些RPG地图里的剧情啊,对话啊,包括开始时选择英雄也是用它来实现的,可以说,只要是一张RPG地图的话,T就是整个地图的精髓与灵魂所在。没有T,那么你的地图就只是一张好看的摆设罢了!!!(由于这是新手教学贴,所以在以下的课程里面会专门提出来进行讲解,现在暂不讨论)
  关于JASS,我想还是有很多人听说过JASS吧,这个的确是个好东东,功能比T还要强大,但是需要一定的程序设计能力的人才会用了吧,这对于新手来说更是不沾边的了,所以在本教程中不涉及讨论!如果各位有兴趣的话可以自己去找点相关的教程!
  另外的几个相关东东:物品管理器,声音管理器及输入管理器将在具体的制图过程教学中提到!

                第二节 熟悉WE
  不知怎么说呢,大多数地图作者都必须经历的一个过程吧:修改地图。呵呵,没错,修改地图是了解并熟悉WE的一个捷径。虽然现在都不提倡修改地图,不过做为学习WE的一个手段,我还是建议大家先从改图学起,而最简单的就是先修改官方的对战地图了!下面将以Lost Temple这张人气较高的对战图来入手,让我们一起揭开WE的神秘面纱!
  运行WE,进入后先将菜单栏里的窗口选项打开,将里面的刷子表那里的勾去掉,这样WE的速度会有所提高。选择菜单栏里的文件-打开地图,在目录里找到要打开的地图,如:Lost Temple.打开之后,就是这个地图的地形了!
认识工具面板:在地图中有一个工具面板,如果没显示的话可以在菜单栏的层面里面打开。它包括:地形面板,地形装饰物品面板,单位面板,地区面板和镜头面板。以下将会分别说明!
1.地形面板,最好理解的一个了,你现在所能看到的整个地图的地形。包括平地,坡地,水,草地和悬崖等都是用它弄出来的,自己试着改改看吧!
2.地形装饰物面板,呵呵,和上面那个差不多,不过内容就多了,看到地图上的树啊,花啊鸟啊什么的了吗?就是用它弄了,同理,自己试着改去吧!
3.单位面板:也是事先放东西的工具了,地图上的中立怪,商店,生命泉和金矿就是用这个放的了,还有一个就是玩家开始地点也是由这个来完成。
4.地区面板:基本上是用在T里面的,现在唯一能做的就是弄传送门。暂时先不管!
5.镜头面板:用在交待剧情时用,同样要用T来弄,也先不管了!
说到这里,基本上WE里要用到的几个工具大家都知道一点点了,具体怎么用就在下面以修改地图的实例来说明了。(示范图为Lost Temple)
一.修改金矿的数量,是不是觉得对战时金矿不够采,才12500的金子,改多一点吧。先将工具面板打开至单位面板,此时在地图上选中一个金矿,双击,会出现一个对话框,里面很明显有个“金钱含量”的框框,默认的是12500,这个就是该金矿的含金量了,想改多少自己弄吧。
二.如何让中立怪死后掉落物品。是不是看到金矿旁边的怪有两个有白色圈圈在动啊?那个就说明杀了此单位后它会掉东东,怎么弄呢?同上面一样,选中它,双击,出现对话框了,此时你可以修改它的一些属性,如生命值比例,所属玩家等。看到掉落物品的选项没?就是那个,点了它后,打开下拉列表,里面有两个选项,两个都可以设置其死后掉落的物品,自己试试看怎么设置吧,这里就不再说明了!
三.在原有地图上加一些单位:如商店,酒馆或是金矿放几个怪!打开单位面板,在中立无敌意里面可以找到如金矿,泉水,商店酒馆等中立建筑,也有一些单位,如小鸡野狗等。想在哪里放就放吧。要加入怪的话就打开中立敌对里面,慢慢找吧。放了之后就自己设置其掉落物品了,当然也可以改更其所属玩家,如果将怪改为中立无敌意,那么它就不会主动攻击你,根本就不会攻击你了,但是你杀了他也得不到经验和金钱!
四.如何加个传送门。以地图的左上和右下的两个小岛为例,先在两边各放一个传送门(单位面板-中立无敌意-建筑),之后将工具面板打开为地区面板,点击后在左上的传送门所以位置(门下)弄出一个区域来,之后命名为DOOR A,同理在右下传送门处也弄一个,名为DOOR B,下面则是激活传送门了,切换回单位面板,双击左上传送门,出现对话框后有个激活选项,打勾,出现下拉列表,选择DOOR B,此时这个传送门就好了,接下来同样的方法弄右下的,选择DOOR A。
至此,简单的修改就已经完成了,当然了,我们并不满足这点点的修改,接下来当然要来点实在的,比如改改英雄啊,技能啊什么的!

第三节 物体编辑器初识
物体编辑器来了,这个相当于一个数据库了,魔兽地图中的所有数据都差不多在这个里面了。打开物体编辑器后会有一排的各种选项,先看单位的吧!
单位列表:里面有所有你在正常地图里面所能见到的一切单位!而要弄懂这个也并不太难,只不过是里面的内容很多,弄起来费时间吧了,我就找几个常用的来介绍说明。
先来个变态的,比如,将农民改的比英雄还强大,首先打开人族,对战,单位,选中农民,右边就会出现该单位的相关数据了。要变态当然是攻击超高,护甲超强,技能超变态,血超多,跑得超快,打人也快,好的,慢慢来,一项一项改吧!
首先是护甲,里面有个基础防御,这个就是初始护甲了,改吧,改为100。之后是战斗-攻击-基础伤害。这个就是攻击力,也改为100吧。然后是战斗-攻击-攻击类型,可以改为混乱,这样就暴强了。战斗-攻击-魔法施放时间间隔时间,就是攻击的间隔,改为1试试,每秒打一下,哈哈,其他的几个较为好理解,故不再说明,自己一试就明白了!有些比较奇怪的就可以不用去管了!接下来是战斗-防御类型,改为神圣吧,这样就只有混乱攻击才打得动了。下面是技能-普通,这个就是该单位的技能了,可以自己加了,想加什么就双击看吧~!后面的什么生命值啊魔法值这些就不用我再多说了吧。这样一来,你的这个农民已经暴强了,哪个英雄见了都吓跑!
其它的一些单位也同样的改,至于建筑嘛,会多出几个东西来,如升级的科技,训练的单位,都是一看就知道是什么了,所以不再多说,如果是商店的话,看一下它技能及售出的商品及可雇佣的单位等就行了。关于英雄则有些初始属性等,这些也是自己试试就行了!
物品:很简单,就是物品,或是称宝物等,就是游戏中的那些!
可破坏物:就是树啊,箱子,门等
地形装饰物:各种雕像,柱子。。。。。。。
技能:又是一个重要的东西,和单位及物品关联大呢。在这里就是让玩家自己修改单位或物品技能的地方了,举例说明一下,想让大法师的水元素一次召唤出10个水元素来吗?先找到该技能,然后修改里面的数据-召唤单位计数。改为10吧。其实在技能这个地方最多的就是修改各种数据了,比如等级,伤害值,魔法消耗,施放间隔等,自己试着改一改,因为要每个东西都说明的话估计要一年吧~!汗!
而后面的效果及科技呢就是在自己做图时再考虑了,不过自己也可以先看看,不难!
第四节 具体问题解答
现在说一下几个常见的问题吧!
1.物品技能怎么修改?比如想把一个血瓶改成加血10000!
先在物体编辑器里的物品里找到你要改的物品(血瓶),在右边的数据里找到技能-技能:具有医疗效果的物品(较小的),这个就是加血多少的技能了,然后再切换到技能里,找到特殊的-物品,在里面找到相应的技能(具有医疗效果的物品(较小的)),将生命值取得那里改成10000就行了!
是不是只觉得只有一个血瓶不过瘾,改多点吧,好的,切换回物品,还是先中血瓶,在右边找到状态-负荷数量 改吧,改成100,哈哈,一买血瓶就有100个了,爽!
2.想让英雄的技能多一点,可以,单位里面找到英雄,比如大法师,找到技能-英雄。在这里加吧,加个先知的召唤狼也行,不过最多此处技能不能超过5个。想加点一般技能么?如重生。在技能-普通里面加吧!
其它的一些如英雄升级可超过10级等将会在以后的分类主题里面给大家说的,不过目前此类问题都有置顶贴解答了,大家不妨可以去看看!


orachard 2006-01-13 21:58
AI基础教程--建立一个基础的对战AI

这个教程将会一步一步的教你如何去编写一个基础的.ai型的对战AI脚本。如果你以为这个教程可以让你做出比AMAI更强大的AI的话,那么你得重新考虑下是不是还要看这个了。本教程仅仅能教会你基础的JASS,内置本地函数以及你要成为一个对战AI脚本程序员而必须知道的一些概念。

------------------------------------------
目前的内容:
1.Hello World!
2.采集资源
3.训练更多的农民
4.建造农场来支持更多的农民
5.一些JASS理论:主函数,变量和类型
6.建造一个兵营并且训练士兵
7.更多的JASS理论:流控制,条件和循环
8.函数:目前为止我们所用到的
9.何时该建造何物
10.建立和使用函数

即将更新的内容:
1.本地函数总浏览
2.语法检查器
3.MF(Creeping)
4.你们所希望增加的内容或许也会贴出来
-----------------------------
已经发现和修正的BUG:
变量后缀:local已经在声明中添加进去了。

==============================================================
Hello World!

让我们从编写和运行一个简单的Hello World脚本开始吧!

function main takes nothing returns nothing
call DisplayTextToPlayer( GetLocalPlayer(), 0.0, 0.0, "Hello World!" ) // 按F12看看呢?
endfunction

将以上代码粘贴到一个名为human.ai的文件中去(建立一个文本文件然后改名为human.ai)
运行地图编辑器
打开你最爱的对战地图,将它以另外一个名字保存(最好放在另外一个文件夹里面)
按F12(或者点Modules(模块)菜单,然后选择Import manager(输入管理器))
在Import manager(输入管理器)中选择File ->Import file (文件 -> 输入文件)
选择刚刚建立好的human.ai.
鼠标右击已经导入的文件,选择Modify file properties(修改文件属性)
将文件位置设置为\Scripts\human.ai
保存地图(顺便把地图关上)
运行魔兽争霸III,选择单人游戏->自定义游戏->你刚刚保存的地图。
将电脑的种族设置为人类
将地图设置为完全可见
游戏开始后在屏幕上寻找Hello World!字样(它在屏幕上一闪而过)

如果你认为它消失的太快了或者你不确定是否看到了那么试试下面的代码:

function main takes nothing returns nothing
call Sleep( 2 ) // <--- 用来确认游戏已经准备好记录这条问候了。
call DisplayTimedTextToPlayer( GetLocalPlayer(), 0.0, 0.0, 3600, "Hello World!" )
endfunction

如果你离开了你的电脑超过了1个小时而没看到这段话的话请按F12 =)

==============================================================
采集资源

地球人都知道在魔兽里采集资源是非常重要的...那么我们来看看一个采集资源的AI脚本该如何编写吧

function main takes nothing returns nothing
call Sleep( 1.0 ) // 休眠1秒
call DisplayTextToPlayer( GetLocalPlayer(), 0.0, 0.0, "Script started" )

loop // 开始永恒循环
call ClearHarvestAI() // 首先重置采集管理器并且
call HarvestGold( 0, 4 ) // 告诉电脑用4个农民采集金矿
call HarvestWood( 0, 1 ) // 和1个农民采集木头
call DisplayTextToPlayer( GetLocalPlayer(), 0.0, 0.0, "Harvesting" )
call Sleep( 1.0 ) //有时候如果不进行休眠引擎就会自动将这个进程关掉
endloop

call DisplayTextToPlayer( GetLocalPlayer(), 0.0, 0.0, "Script exiting" )
endfunction

用试验Hello World!脚本的方法试一下上面这段代码。只需要把以前导入的文件删掉换上新的就行了。你也可以在Import Manager(输入管理器)中右击以前导入的文件然后选择replace(替换)。

不要忘了在高级地图设置中将地图设置为始终可见,不然你在开始就看不到电脑的行动了。

为什么我们总是要重置和再分配采集管理器呢?试想,如果不这么做,当一个农民在采木头的时候被杀死会怎么样?很简单,永远不会有另外一个农民来接替他的工作。

==============================================================
训练更多的农民

用5个农民不知道要花多长时间才能采集够建立一支军队的资源,所以我们需要训练更多的农民来保证资源供给。

function main takes nothing returns nothing
call Sleep( 1.0 ) // 休眠1秒
call DisplayTextToPlayer( GetLocalPlayer(), 0.0, 0.0, "Script started" )

loop // 开始永恒循环
call ClearHarvestAI() // 首先重置采集管理器并且
call HarvestGold( 0, 4 ) // 告诉电脑用4个农民采集金矿
call HarvestWood( 0, GetUnitCountDone('hpea')-4 ) // 和1个农民采集木头
call DisplayTextToPlayer( GetLocalPlayer(), 0.0, 0.0, "Harvesting" )

call SetProduce(1, 'hpea', 0) // 试着训练一个农民

call Sleep( 3.0 ) // 有时候如果不进行休眠引擎就会自动将这个进程关掉
endloop

call DisplayTextToPlayer( GetLocalPlayer(), 0.0, 0.0, "Script exiting" )
endfunction

调用GetUnitCountDone('hpea')可以清点这个玩家拥有多少的人类农民。这用来计算有多少农民没有在采金子从而让他们去采集木头。看看电脑是怎么样建造成堆的农民的...= )

启动地图的另一个更加方便我们观察所创建的AI玩家行为方法:建立一个局域网游戏,在地图高级设置中选择观察者模式,将你自己设置成观察者,这样你在游戏中就可以点击电脑的单位或者建筑来观察他采集了多少资源。

感到厌烦了吗?它是否只在不停的造农民?不?它是需要更多的人口么?那么让我们来教他怎么多造点农场吧! =P

==============================================================
建造农场来支持更多的农民

让我们建造更多的农场,训练更多的农民,采集更多的资源吧!= )
假设我们在还剩余3个额外人口的时候就建造一个新的农场。

function main takes nothing returns nothing
call Sleep( 1.0 ) // 休眠1秒
call DisplayTextToPlayer( GetLocalPlayer(), 0.0, 0.0, "Script started" )

loop
call ClearHarvestAI()
call HarvestGold( 0, 4 )
call HarvestWood( 0, GetUnitCountDone( 'hpea' )-4 )
call DisplayTextToPlayer( GetLocalPlayer(), 0.0, 0.0, "Harvesting" )

// 如果我们正在训练一个农民那么下面的SetProduce就会失效
call SetProduce( 1, 'hpea', 0 ) // 训练人类农民

// 我们的基地可以提供12个人并且每个基地分配6个人
// 比较目前人口上限和单位所占人口数量来决定
// 是否需要建造一个新的人类农场

if ( 12 + 6 * GetUnitCount('hhou') - GetUnitCount('hpea') < 3 ) then
call DisplayTextToPlayer( GetLocalPlayer(), 0.0, 0.0, "Trying to build a house" )
call SetProduce( 1, 'hhou', 0 ) // 建造一个人类农场
endif

call Sleep( 3.0 )
endloop

call DisplayTextToPlayer( GetLocalPlayer(), 0.0, 0.0, "Script exiting" )
endfunction

这样我们就有许多的工人和许多的资源啦!但是我们是不是该把这些资源花掉呢?我们是不是要建造更多的房子来会帮助我们训练军队呢?请注意下面关于建筑的部分啦~

==============================================================
一些JASS理论:主函数,变量和类型

呵呵。抱歉了,我们在看建造建筑前要打断一下了~我觉得在其之前有必要想想JASS了.不过如果你对JASS已经很熟悉了就可以跳过这一段啦。好了~准备好来学习JASS吧!

主函数main

function main takes nothing returns nothing
// 许多的代码
endfunction

所有在AI脚本中的动作都会在游戏引擎调用main函数的时候开始。
main函数必须像上面的那样,不然脚本就无法执行。

变量
通常它被用来记录一些东东非常好使。在JASS中你必须用变量来保存值。不同类型的变量可以用来保存不同类型的值。

function main takes nothing returns nothing
local integer number // 告诉(声明)引擎我们要储存一个数字(声明)
local integer anotherNumber // 并且(声明)另外一个数字
local float decimalNumber // 还有(声明)一个十进制数
local string someText // 以及(声明)一些文本

set number = 42
set anotherNumber = 6 * 9
set decimalNumber = 3.14
set someText = "Is this to easy for you? ;-)"
endfunction

实现同样功能的另外一种方法是:

function main takes nothing returns nothing
local integer number = 42 // 声明的同时赋值给它,一行用起来比两行清楚多了~
local integer anotherNumber = 6 * 9
local float decimalNumber = 3.14
local string someText = "Is this to easy for you? ;-)"
endfunction

另外需要注意的是在函数开始的时候我们必须声明(告诉引擎)所有我们将在这个函数里使用的变量。下面的例子是不合法的。

function main takes nothing returns nothing
local integer number = 42 // 声明的同时赋值给它,一行用起来比两行清楚多了~
local integer anotherNumber = 6 * 9
local float decimalNumber = 3.14
set anotherNumber = number // 不合法
local string someText = "Is this to easy for you? ;-)"
set anotherNumber = number // 不过在这个地方倒是合法的
endfunction

我们在声明一个变量前总是要加上local字样。Local意味着这个变量只在这个函数中有效。这个并不是必须的,稍后我们会看到如何使用全局变量。

现在深呼吸,然后跟我说:“变量是我们的朋友~ = D ”。

好了~~这个理论部分比我预想的要长呢。或许我们应该接着造建筑了~或许我们会建造一个兵营,或者训练一个士兵?我们自己的士兵(或者说是AI的=))

==============================================================
建造一个兵营并且训练士兵

现在我们就开始建造一支无所不摧的军队的第一步吧!扼,先从训练步兵开始吧 =P

function main takes nothing returns nothing
call Sleep( 1.0 )
call DisplayTextToPlayer( GetLocalPlayer(), 0.0, 0.0, "Script started" )

loop
call ClearHarvestAI()
call HarvestGold( 0, 4 )
call HarvestWood( 0, GetUnitCountDone( 'hpea' )-4 )
call DisplayTextToPlayer( GetLocalPlayer(), 0.0, 0.0, "Harvesting" )

call SetProduce( 1, 'hpea', 0 ) // 训练人族农民

// 判断何时建造农场

if ( 12 + 6 * GetUnitCount('hhou') - GetUnitCount('hpea') < 3 ) then
call DisplayTextToPlayer( GetLocalPlayer(), 0.0, 0.0, "Trying to build a house" )
call SetProduce( 1, 'hhou', 0 )

endif

if ( GetUnitCount( 'hbar' ) < 1 ) then // 我们已经有人类的兵营了吗?
call DisplayTextToPlayer( GetLocalPlayer(), 0.0, 0.0, "Trying to build a barrack" )
call SetProduce( 1, 'hbar', 0 ) // 在0号基地中建立一个人类兵营
else
call DisplayTextToPlayer( GetLocalPlayer(), 0.0, 0.0, "Trying to train a footman" )
call SetProduce( 1, 'hfoo', 0 ) // 在0号基地中训练步兵
endif

call Sleep( 3.0 )
endloop

call DisplayTextToPlayer( GetLocalPlayer(), 0.0, 0.0, "Script exiting" )
endfunction

或许你已经注意到了在建造农场和训练单位间停顿了一小会。你知道是为什么吗?是我们没有足够多的农场吗?或许我们正被计算目前正在使用多少人口困扰。或者你会在我公布答案前自己试着修复这个问题.(提示:在条件(conditon)中有个地方错了)

在我们扩展代码前,像是建造不同的建筑,训练不同的兵种或者是让士兵去战斗。不过那对这个基础教程来说偏难了。呵呵。

在指出为什么它会比较难之前我们又需要学习更多的JASS了~现在到了学习使用更多更加有用的函数的时候了~现在甚至是我们学习所有这些函数的来源和工作原理的时候了!不要走开哦!

==============================================================
更多的JASS理论:流控制,条件和循环

流控制是关于如何实现在一个程序中使用不同的方法的内容。JASS中用if语句和循环结构来支持它。让我们看看吧。

if

通常我们会遇到在不同的情况下执行不同的操作的问题。最基础的方法就是当某事为真的时候我们就做什么,否则我们就做另外的什么事(或者什么事也不做)

if condition then
doSomething
doSomethingMore
endif

if GetUnitCount( 'hpea' ) < 12 then // 如果我们的农民少于12个
call setProduce( 1, 'hpea', 0) // 在我们的起始基地中建造一个农民
endif

嘿!我们如果我们农民足够的时候该做什么呢?

if condition then
doSomething
else
doSomethingElse
endif

if GetUnitCount( 'hpea' ) < 12 then //如果我们的农民少于12个
call setProduce( 1, 'hpea', 0) // 在我们的起始基地中建造一个农民
else
call DisplayTextToPlayer( GetLocalPlayer(), 0.0, 0.0, "We need no more peasants" )
endif

这只在只有2种情况可供选择的时候有效,我们如何在多种分支中选择呢?

if condition then
doSomething
elseif condition2
doSomethingElse
else
doSomeOtherThing
endif

if GetUnitCount( 'hpea' ) < 12 then // 如果我们的农民少于12个
call DisplayTextToPlayer( GetLocalPlayer(), 0.0, 0.0, "We need more peasants" )
call setProduce( 1, 'hpea', 0) // 在我们的起始基地中建造一个农民
elseif GetUnitCount( 'hpea' ) < 20 then
call DisplayTextToPlayer( GetLocalPlayer(), 0.0, 0.0, "We need no more peasants" )
else
call DisplayTextToPlayer( GetLocalPlayer(), 0.0, 0.0, "We have to many peasants" )
endif

添加更多的elseif语句你就可以写一个在很多的动作间选择的程序了。你需要注意的仅仅是适当的放置条件。下面这个就没有按正确的顺序放。

if GetUnitCount( 'hpea' ) < 20 then
call DisplayTextToPlayer( GetLocalPlayer(), 0.0, 0.0, "We need no more peasants" )
elseif GetUnitCount( 'hpea' ) < 12 then
call DisplayTextToPlayer( GetLocalPlayer(), 0.0, 0.0, "We need more peasants" )
call setProduce( 1, 'hpea', 0)
else
call DisplayTextToPlayer( GetLocalPlayer(), 0.0, 0.0, "We have to many peasants" )
endif

如果我们有一个农民,这段代码会说我们不需要更多的农民。这是因为条件是从上而下依次检查的。

循环
循环就是不断的重复做某事。如果你在其他的编程中用过循环结构,在使用JASS的循环时你可能会感到不适应。不过有一种编写在JASS中的while循环和for循环的方法。

让我们来看一个将永远执行下去的循环(或者执行到游戏引擎关闭掉它。)

loop
doSomethingForever
endloop

loop
call DisplayTextToPlayer( GetLocalPlayer(), 0.0, 0.0, "Let's spam the user forever")
call Sleep( 1.0 ) // 不用休眠的话就无法永远的执行
endloop

永远执行的循环有它们自己的用处,但是他们并不很灵活。所以让我们来看如何跳出循环。

loop
doSomething
exitwhen condition
doSomethingMore
endloop

local integer i = 1
loop
call Sleep( 1.0 )
exitwhen i > 10
call DisplayTextToPlayer( GetLocalPlayer(), 0.0, 0.0, "Let's spam the user 10 times")
set i = i + 1
endloop

for循环
我们在JASS中不能使用For循环,但是我们可以做一个像for循环的循环。

for ( initStatement; condition; endOfIterationStatement ) {
stuff;
}

在JASS中可以这样做

initStatement
loop
exitwhen not (condition)
stuff
endOfIterationStatement
endloop

现在让我们来看看一个更加具体的例子。

for (int i = 0; i < 10; i++) {
printf("We need to say it 10 times");
}

在JASS中变成

local integer i = 0
loop
exitwhen not ( i < 10 ) // 当 i >= 10 时跳出
call DisplayTextToPlayer( GetLocalPlayer(), 0.0, 0.0, "We need to say it 10 times")
set i = i + 1
endloop

while
或许你应该自己来研究如何在JASS中实现while循环。如果你不太习惯用while循环那么就无视它们吧,反正JASS是没有这种循环。

如果你想了解更多,去查询TRIGGER和JASS的相关教程吧。

==============================================================
函数:目前为止我们所用到的

这部分列出了目前我们用到的所有的函数,看看它们是如何工作的,能干什么,以及为什么我们只让它们做什么。希望你会喜欢这部分。
对于每一个我们用过的函数,我都会写出来它们在资源文件中是如何声明的,在引数中是怎么解释的,它能做什么以及它返回什么。

native Sleep takes real seconds returns nothing
call Sleep( 3.5 ) // 让脚本暂停3.5,秒
如果我们不让脚本休眠,引擎会强制终止它

constant native GetLocalPlayer takes nothing returns player
local Player p = GetLocalPlayer() //区别玩家的电脑
利用它可以用来指定显示文本的对象。

native DisplayTextToPlayer takes player toPlayer, real x, real y, string message returns nothing
call DisplayTextToPlayer( GetLocalPlayer(), 0.0, 0.0, "Hello local player!" )
我们需要告诉这个函数显示给谁什么内容。把那些0改成不同的内容我们就可以控制文字在屏幕上显示的位置了。试验的时候随便写吧,用0一般就足够了。显示的内容会在一小会后消失,这由文本的长度决定。

native DisplayTimedTextToPlayer takes player toPlayer, real x, real y, real duration, string message returns nothing
call DisplayTextToPlayer( GetLocalPlayer(), 0.0, 0.0, 60, "Hello for 60 secs!" )
同上,不过我们可以控制文本显示的时间。

native ClearHarvestAI takes nothing returns nothing
call ClearHarvestAI() // 命令采集AI停止采集
这个函数和下面的2个配合起来一起用可以用来控制用几个农民采金子和几个农民采木头

native HarvestGold takes integer town, integer peons returns nothing
call HarvestGold( 0, 5 ) // 让主基地中的5个农民采集金子
如果这个函数被调用2次的时候,如果没用上面的那个函数的话就会让10个农民去采金子了。。。

native HarvestWood takes integer town, integer peons returns nothing
call HarvestWood( 0, 10 )
同上,只是这个采集的是木头

native SetProduce takes integer qty, integer id, integer town returns boolean
local boolean success = SetProduce( 1, 'hpea', 0 ) // 在主基地训练一个农民

call SetProduce( 1, 'hpea', 0 )
我并不完全相信返回值,它让我在很多时候产生疑惑

native GetUnitCount takes integer unitid returns integer
set numberOfPeasants = GetUnitCount( 'hpea' ) //清点AI玩家的农民数量
包含了正在训练的农民

native GetUnitCountDone takes integer unitid returns integer
set numberOfPeasants = GetUnitCount( 'hpea' ) // 清点AI玩家农民的数量
不包含正在训练的农民
==============================================================
何时该建造何物

这部分我们将用我们自己的函数来进行建筑,不过可能中间夹杂着不少的理论内容。所以我们必须考虑我们何时候该造何种建筑或者训练什么单位。在我们只有兵营而没有铁匠铺的时候显然是不能训练火枪手的。

让AI忽视任何需求尝试建造一个建筑是最简单的。如果我们把所有的建筑顺序写在一个循环里,它将会尝试建造所有我们命令它建造的建筑(如果我们没有忘记科技树的话)它在很多时候都用的不是很好,我们可能会建造许多同样的建筑,例如3个铁匠铺(真是疯了。。。),那么该如何解决呢?

如果我们回头看一下第四部分,关于建造更多的农场来支持更多的农民,和第六部分,建造兵营并且训练单位,我们不难发现,它们中用了一些if语句,用来决定该做什么事的规则。试想,如果是我们正在玩游戏,我们通常在脑中都会有一些,至少是一条建筑的规则。所以,我们还等什么呢?来试试吧!

规则 1: 当我们缺乏农民的时候应该训练农民
规则 2: 当我们人口不足时应该建造农场
规则 3: 没有兵营时应该造兵营
规则 4: 有兵营了就可以造步兵了
规则 5: 如果有兵营了就可以造一个铁匠铺了
规则 6: 如果我们没有祭坛就造一个祭坛
规则 7: 如果我们有祭坛而没有英雄就需要造一个英雄

让我们看看这些规则,它们会让我们建立一支由英雄带队的步兵和火枪手组成的部队。想想如何在JASS中实现他们吧!(回顾一下第七节会很有帮助)

懒得自己试么? =) 好吧,我带你们一起搞吧。。。呵呵
让我们看看如何将规则1应用到JASS中去,似乎用IF语句非常适合。

if "we have to few peasant" then
"train more peasants"
endif

few具体是指多少?让我们将规则1改为:

规则1B : 如果我们有少于10个农民那么就开始训练一个农民。

然后将它用JASS实现。

if GetUnitCount('hpea') < 10 then
call SetProduce( 1, 'hpea', 0 ) // 0是指我们最开始的基地
endif

好的~

那么我们以此类推来改一下其他的规则吧~

规则 2b: 如果我们人口剩余少于6个就造一个农场
规则 3b: 如果我们的兵营少于1个就建造一个兵营
规则 4b: 如果我们的兵营多于1个就训练一个步兵
规则 5b: 如果我们的兵营多于1个而铁匠铺少于1个就早一个铁匠铺
规则 6b: 如果我们祭坛少于1个就早一个祭坛
规则 7b: 如果我们的祭坛多于0个而英雄少于1个就训练一个英雄
规则 8b: 如果我们有少于一个的非JASS的规则那么我们就将它改为一个符合JASS的规则 =)

==============================================================
建立和使用函数

函数...他们到底好在哪里,为什么我们要用他们呢?厄...如果有另外一个人写了大量的不错的函数来给我们调用,我们就不用自己写了。如果我们想自己写几个函数,我们就可以防止我们的代码变成一团乱麻了。分割!征服!。把你的代码分割成很多函数,然后征服每个函数吧!

让我们来看一个简单的不能再简单的函数。

function myFunc takes nothing returns nothing
endfunction

这个函数什么也不能做。但是它包含了每个函数都必须具有的部分。它以function关键字开始,以endfunction结束。在function后是函数名:这里是MyFunc。下面的是takes以及函数使用的所有参数。这个函数不使用任何参数。它也不返回任何东西。它教给我们什么了?一个函数名为muFunc的函数,没有任何的实参和形参并且没有任何的返回值。

那我们现在来做一个可以实现一些功能,使用一些参数并且有返回值的函数吧。

function add takes integer a, integer b returns //a+b的和
return a + b
endfunction

他的功能很明显,不是吗?而且它一点也不实用。我们可以直接用+直接计算而不是用函数。让我们来做个更加有用的函数,用来让所有的农民采集资源。

function resourceManager takes goldPeasants returns nothing
call ClearHarvestAI()
call HarvestGold( 0, goldPeasants )
call HarvestWood( 0, GetUnitCountDone('hpea') - goldPeasants )
endfunctions

这个函数使用了决定多少个农民采集金子(其余的都去采木头)的参数。它在另外一个函数(例如main)中调用方法如下:

call resourceManager( 5 )

这样就可以让5个农民去采金子而其他的去采木头了。在前面的程序中使用这个函数我们在main中可以省去很多行的代码。在第二部分的程序可写为:

function resourceManager takes goldPeasants returns nothing
call ClearHarvestAI()
call HarvestGold( 0, goldPeasants )
call HarvestWood( 0, GetUnitCountDone('hpea') - goldPeasants )
endfunctions

function main takes nothing returns nothing
call Sleep( 1.0 )
call DisplayTextToPlayer( GetLocalPlayer(), 0.0, 0.0, "Script started" )

loop
call resourceManager( 4 )
call Sleep( 1.0 )
endloop

call DisplayTextToPlayer( GetLocalPlayer(), 0.0, 0.0, "Script exiting" )
endfunction

要注意被调用的极限函数是要写在调用它的函数前的。不然魔兽III的程序就会这样想:这是什么怪函数?从来没听说过嘛!我最好关闭这个脚本,它看上去不完整嘛。
另外一个有用的极限函数是像这样的:

function print takes string message returns nothing
call DisplayTimedTextToPlayer( GetLocalPlayer(), 0.0, 0.0, 3600, message )
endfunction
==============================================================
一个战斗脚本

这部分可能出现的过早了。让我们一起重新编写一下第六部分中的代码。建造兵营并且训练一些士兵。

为了增加代码的可读性,我把它分成了用来控制资源,建造建筑和训练单位这几个不同的管理器中了

function resourceManager takes nothing returns nothing
local integer goldPeasants = 5
local integer peasantsDone = GetUnitCountDone('hpea')
if peasantsDone < 6 then
set goldPeasants = peasantsDone - 1
endif

call DisplayTextToPlayer(GetLocalPlayer(), 0.0, 0.0, "In manager")
call ClearHarvestAI()
call HarvestGold( 0, goldPeasants ) // then tell it to have

call HarvestWood( 0, GetUnitCountDone('hpea') - goldPeasants )

endfunction

function unitManager takes nothing returns nothing
if GetUnitCount('hpea') < 12 then
call SetProduce(1, 'hpea', -1) //在任何可行的地方训练农民
endif
call SetProduce(1, 'hfoo', -1) // 在任何可行的地方训练地面部队
endfunction

function buildingManager takes nothing returns nothing
local integer produced = 12 + 6 * GetUnitCount('hhou')
local integer used = 1 * GetUnitCount('hpea') + 2 * GetUnitCount('hfoo')
local integer foodSpace = produced - used
local integer barrack = GetUnitCount('hbar')

if foodSpace < 6 then
call DisplayTextToPlayer(GetLocalPlayer(),0.0,0.0,"Building house")
call SetProduce(1,'hhou',-1)
endif

if barrack < 1 then
call SetProduce(1,'hbar',-1)
endif
endfunction

function main takes nothing returns nothing
call Sleep( 1.0 )
call DisplayTextToPlayer(GetLocalPlayer(), 0.0, 0.0, "Script started")

loop
call DisplayTextToPlayer(GetLocalPlayer(), 0.0, 0.0, "in loop")
call resourceManager()
call unitManager()
call buildingManager()
call Sleep( 1.0 )
endloop

call DisplayTextToPlayer(GetLocalPlayer(), 0.0, 0.0, "Script exiting")
endfunction

这个代码将会训练许多的仅仅在原地站着不动的士兵。但是需要注意的是...让我们来创建一个让AI控制步兵前往地图上的某个地方的脚本吧!希望他们能找到敌人...我们很快就会考虑构建一个如何利用作弊来解决控制问题的AI...-_-

globals //声明全局变量
unit scoutUnit = null
real scoutX = 0
real scoutY = 0
real scoutHealth
endglobals
//================================================== =======
// resourceManager资源管理器
//
// 控制农民采集资源
//================================================== =======
function resourceManager takes nothing returns nothing
local integer goldPeasants = 5
local integer peasantsDone = GetUnitCountDone('hpea')
if peasantsDone < 6 then
set goldPeasants = peasantsDone - 1
endif

call ClearHarvestAI()
call HarvestGold( 0, goldPeasants )

call HarvestWood( 0, GetUnitCountDone('hpea') - goldPeasants )

endfunction
//================================================== =======
// unitManager单位管理器
//
// 训练单位
//================================================== =======
function unitManager takes nothing returns nothing
if GetUnitCount('hpea') < 12 then
call SetProduce(1, 'hpea', -1)
endif
if GetUnitCount('hfoo') < 15 then
call SetProduce(1, 'hfoo', -1)
endif
endfunction
//================================================== =======
// buildingManager建筑管理器
//
// 建造建筑
//================================================== =======
function buildingManager takes nothing returns nothing
local integer produced = 12 + 6 * GetUnitCount('hhou')
local integer used = 1 * GetUnitCount('hpea') + 2 * GetUnitCount('hfoo')
local integer foodSpace = produced - used
local integer barrack = GetUnitCount('hbar')

if foodSpace < 6 then

call SetProduce(1,'hhou',-1)
endif

if barrack < 2 then
call SetProduce(1,'hbar',-1)
endif
endfunction
//================================================== =======
// allocateScout指派一个侦察兵
//
// 选择一个单位作为侦察兵,用来引导其他的部队
//================================================== =======
function allocateScout takes nothing returns nothing
local group grp = CreateGroup()
call GroupEnumUnitsOfType(grp, "footman", null)
set scoutUnit = FirstOfGroup(grp)
call RemoveGuardPosition(scoutUnit)
set scoutX = GetUnitX(scoutUnit)
set scoutY = GetUnitY(scoutUnit)
set scoutHealth = GetUnitState(scoutUnit, UNIT_STATE_LIFE)
endfunction
//================================================== =======
// init初始化
//
// 初始化脚本
//================================================== =======
function init takes nothing returns nothing
endfunction
//================================================== =======
// walk移动
//
// 命令单位移动到前方某处
//================================================== =======
function walk takes unit u, real distance returns nothing
local real dir = GetUnitFacing(u) * 3.14 / 180
local real x = GetUnitX(u) + distance * Cos(dir)
local real y = GetUnitY(u) + distance * Sin(dir)
call IssuePointOrder( u, "move", x, y)
endfunction
//================================================== =======
// walk移动
//
// 命令单位移动到指定方向某处
//================================================== =======
function walkDir takes unit u, real distance, real direction returns nothing
local real dir = direction * 3.14 / 180
local real x = GetUnitX(u) + distance * Cos(dir)
local real y = GetUnitY(u) + distance * Sin(dir)
call IssuePointOrder( u, "move", x, y)
endfunction
//================================================== =======
// helpScout帮助侦察兵
//
// 命令单位跟随侦察兵
//================================================== =======
function helpScout takes nothing returns nothing
local group grp = CreateGroup()
local unit u
call GroupEnumUnitsOfType(grp, "footman", null)
set u = FirstOfGroup(grp)
loop
exitwhen u == null
if u != scoutUnit then
call IssuePointOrder( u, "attack", scoutX, scoutY)
endif
call GroupRemoveUnit(grp, u)
set u = FirstOfGroup(grp)
endloop
call DestroyGroup(grp)
endfunction
//================================================== =======
// scout侦察兵
//
// 控制侦察兵前往地图上的一个随机点
//================================================== =======
function scout takes nothing returns nothing
local real R = 1024
local real x = GetUnitX(scoutUnit)
local real y = GetUnitY(scoutUnit)

if scoutX == x and scoutY == y then
call walkDir(scoutUnit, R, GetUnitFacing(scoutUnit) + GetRandomReal(90, 270))
else
set scoutX = x
set scoutY = y
call walk(scoutUnit, R)
endif
endfunction
//================================================== =======
// combatManager战斗管理器
//
// 控制军队跟随侦察兵
//================================================== =======
function combatManager takes nothing returns nothing
// call DisplayTextToPlayer(GetLocalPlayer(), 0.0, 0.0, "In combatManager")
if scoutUnit == null or not UnitAlive(scoutUnit) then
call allocateScout()
endif
if GetUnitCountDone('hfoo') > 4 and scoutUnit != null then
call scout()
call helpScout()
endif
endfunction
//================================================== =======
// main主函数
//
// 运行AI的主函数
//================================================== =======
function main takes nothing returns nothing
call Sleep( 1.0 )
call DisplayTextToPlayer(GetLocalPlayer(), 0.0, 0.0, "Script started")
call init()

loop

call resourceManager()
call unitManager()
call buildingManager()
call combatManager()
call Sleep( 5.0 )
endloop

call DisplayTextToPlayer(GetLocalPlayer(), 0.0, 0.0, "Script exiting")
endfunction
[Last Modified By wujimmy, at 2006-08-17 17:49:16]
Comments Feed Comments Feed: http://wjm.name/feed.asp?q=comment&id=89

View Mode: Show All | Comments: 14 | Trackbacks: 0 | Toggle Order | Views: 76099
Quote shelby
[ 2006-03-14 02:50:00 ]
把地图文件改成图中的样子
保存地图,退出ultraedit
--------------------------
请问图在哪啊??????????????????? [rolleyes] [rolleyes]
Quote wujimmy
[ 2006-03-14 08:35:45 ]
一般你只要用到这个文件就可以达到修改的目的了:

http://www.wujimmy.com/lbs/uploads/200603/03_142744_w3mmaster.rar
Quote fengzheng
[ 2006-03-19 12:08:25 ]
《一般你只要用到这个文件就可以达到修改的目的了》
大哥能不能说清楚点啊。我学了半天就这弄不懂啊!!!
Quote wujimmy
[ 2006-03-19 12:21:59 ]
不知道你是想修改地图还是想研究地图.
如果是想修改地图以达到快速过关的目的,那么,只要用上文中提到的工具就可以达到目的,修修改其中的物价,英雄等级等等,均可以达到目的.

而如果你是想研究学习这个地图的话,那么你还是认真学习
war3map.j文件的内容.
这个文件也是通过上面的程序可以获得的到的.
Quote dc0001
[ 2006-04-02 17:25:32 ]
大哥不懂啊
中英文结合看不懂啊!尤其是那个单体技能该成群体的也看不懂
Quote jixianna
[ 2006-05-15 14:21:43 ]
import manager软件没有啊,不知道这位大哥能不能提供
Quote TTT*
[ 2006-07-09 02:18:08 ]
我想把一个既能改成自动施放性的,怎么改啊?
Quote fengzheng
[ 2006-08-31 23:17:41 ]
找到0000 0200h这一行

把地图文件改成图中的样子
保存地图,退出ultraedit

改成什么啊????
Quote HIKALU*
[ 2007-07-03 20:43:37 ]
有没可以直接用地图编辑器打开加密的地图啊
Quote qln927*
[ 2007-11-14 04:34:24 ]
我认为
Quote ioz743*
[ 2008-07-21 17:54:17 ]
编号:
Quote ldn448*
[ 2008-07-23 12:52:03 ]
很好!
Quote oog396*
[ 2008-07-25 09:03:55 ]
编号:
Quote wpf981*
[ 2008-08-05 12:36:55 ]
Optical Coating Material
Optics and optical components are often coated with a fine layer of material in order to modify the light reflected or emitted from them. This material is called an Optical Coating Material, and it is used on everything from bulbs and lenses to mirrors and prisms. The prime uses of Optical Coating Material are to block certain wavelengths of light or to provide a highly reflective surface. In some cases, they provide both functions, reflecting specific wavelengths, while allowing others to pass through unobstructed.

编号:

Post Comment
Smilies
[微笑] [忧伤] [鬼脸] [高兴] [眨眼] [困惑] [爱意] [脸红] [吐舌头] [吻你]
[惊诧] [生气] [坏笑]
Enable UBB Codes
Auto Convert URL
Show Smilies
自动复制
Hidden Comment
Username:   Password:   Register Now?