心血来潮我也申请了一个Blog,虽然很早就知道博客但以前只觉得这就像在小学里写日记一样(以前在我第一任语文老师的谆谆教导下我开始写日记,到后来就从日记变成周记再变成月记......之所以不写不是怕别人看我的日记,谁想看就看我无所谓,是因为我懒、嫌麻烦就不写了,一直到初中我的第(1、2、......)3任语文老师的强逼之下我又开始写周记了,到了初二第二学期她又说不要写了,但马上又说每周交一次摘抄一直到我初中毕业。到现在我又开始X记了["X"是因为我不知道这写的算日记还是周记、月记(有月记?)],我能坚持多久???......
--bhu记于华跃网吧142座用键盘砸出来的序(还是赤脚写的)
2005年4月9日15:58
又是一个应用实例~~~
wowapi列表
http://www.wowwiki.com/World_of_Warcraft_API
lua语法
refman_5.0.pdf ( 463.69k ) 全英文的@_@
wow事件列表
http://www.wowwiki.com/Events
wow斜杠命令、表情命令、术语表
我个人觉得对MACRO、和UI解释的很清楚的网站
台湾对WOW中MACOR的定义
WOW的核心开放给玩家使用的指令
http://www.wowwiki.com/World_of_Warcraft_API
牛哥发的文章~~
http://bbs.16t.cn/bbs/index.php?showtopic=32397
金山在线翻译,看到不认识的单词就找它了
我又看了很多关于MACRO、UI,还找到了几个很有用的网站。其中很多指令都是有LUA+WOW核心指令组成的,涉及了MS的API接口,而且都是英文@_@。我看的很累但在中文解释下也算能看懂一点,至少程序里的都是简单的英文单词或者词组。至于官网的上的解释说明那个......
Script 实例
感谢牛哥孤单也是一种美
一些编写宏的命令集合
表情与动作命令全集
/console 执行控制台命令
/script 执行LUA脚本语言命令
MOD、SCRIPT、MACROC……
介绍一些基本概念:
1 Slash Commands / 命令
2 Macros 宏
3 Scripts 脚本
4 User Interface Mods and AddOns 用户界面 MOD与AddOn插件
5 Cosmos, Gypsy, CT_Mod 等常用的插件
6 独立与绿色的插件
WOW中的UI、宏命令
感谢那位叫光之荣耀的牛哥~~提供了这么好的一篇文章让我学习
Chapter One
玩了WOW有一段时间了,除了游戏本身所提供的基本功能之外,其它WOW的功能我都尽量的尝试.在这里我提供一下我个人的心得.
相信很多的玩家都知道,WOW有所谓的合法外挂(COSMOS),但是WOW又非常的严格的抓所谓的非法外挂,那么合法的外挂与非法的外挂差别在哪?
其实所谓的合法外挂,只是在于一些有心的玩家利用了WOW所提供的功能,以及指令,另外在WOW的游戏核心上,另外写了一些辅助性质的SCRIPT来帮助游戏接口的简易操作.至于非法外挂,就是利用任合游戏本身所没提供的功能来增加自身的利益(包括了所谓第三者程序third party program).
既然WOW本身有提供这样的功能,身为玩家的我们为什么不尽量的利用这些好处呢?有鉴于台湾玩家在获得这些信息上的困难(因为有关于这方面的讨论,大部分都是英文),我在这里提出讨论,或许能带给台湾的玩家另外一种的游戏体验.
暴风雪在WOW的官方网站上有很明确的提到,UI的修改是玩家对于游戏整体体验中的一部分.但是什么是UI?UI修改又是什么?
UI是USER INTERFACE(使用者接口),在WOW中,所有的UI都是模块化的,每一个按钮,每一个窗口都是属于某一个模块的定义.玩家在玩游戏的时候,并不是直接的对于游戏核心下达游戏指令,而是先在UI上面的动作,然后在藉由UI的模块上下达游戏核心指令.例如我们按下游戏中攻击的按钮,WOW会先检查这个按钮的定义是什么,然后才执行这个定义下的指令.
那么修改UI的好处又是什么呢?这样说好了.WOW本身所提供的UI,其背后的定义都是最基本的,最简化的.比如说快捷键按钮的设计,以及每个指令动作.在按钮以及窗口的设计上,使以简单容易上手为主要目的.但是对于进阶玩家而言,又会觉得WOW所提供的快捷键按钮不够用,所以自己在UI上面加以修改,这样就不但可以自行决定快捷键按钮的数目,也可以把这些按钮摆在自己最喜欢的地方.
另外关于指令动作上(键盘与老鼠在UI上面的指令),WOW基本的UI设定都是一个指令一个动作.我们按一个按钮,WOW做一个动作.但是我们可以自行设定UI,达到玩家的下达一个指令,WOW同时做很多动作.
比如说,WOW给玩家在攻击上的选择是,按TAB会帮玩家找出画面上距离最近的敌人(原始设定是20码的距离范围内),然后玩家必须按攻击的按钮或是T,在这样的情况下才会攻击.玩家下达了两个指令,做了两个动作.但是在UI的修改上,我们不但可以修改画面上距离最近的敌人的距离范围(适合远距离攻击的玩家),我们还可以设定按下TAB按键,不但会自动定位距离最近的敌人,还会自动开始攻击.
在这个讨论串当中,我主要是针对指令UI上的设定提出讨论,因为关于画面上的设定已经有很多现成的选择(COSMOS).因此我将针对CLASS上面辅助型的UI设定.在藉由讨论上,让台湾的玩家们也有机会自行设计出最方便,最有效率的攻击,法术施展,以及宠物控制.
当然我绝对欢迎玩家针对任何的UI设定提出讨论,但是我不见得有能力回答.毕竟我个人比较不喜欢去研究画面的排列,所以这方面花的功夫也比较少.
现在我只介绍XML在WOW模块设计上该如何使用。
| CODE |
| <Ui xmlns="http://www.blizzard.com/wow/ui/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.blizzard.com/wow/ui/"> <script file="hi.lua"/> <Frame name="hi_core"> <scripts> <OnLoad> this:RegisterEvent("VARIABLES_LOADED"); </OnLoad> <OnEvent> if (event == "VARIABLES_LOADED") then hi_initialize(); end </OnEvent> </Scripts> </Frame> </Ui> |
大家可以忽略前面几行<Ui xmlns ......... />.基本上每一个WOW模块XML文件都必须要有这几行.
重要的是 <script file="hi.lua"/> 在这里大家得定义出模块的核心档案是什么.以我们目前的例子,核心档案是hi.lua.
在 <Frame name="hi_core"> 这里定义出模块在游戏画面中要使用的的子画面的名称.这个名称必须是独一无二的,避免与其它的模块画面冲突到.
在上面的例子中我们可以看到<OnLoad>和<OnEvent>的标示,基本上<OnLoad>的意思是当WOW在加载游戏接口的时候,因该要做出什么动作.以我们的例子,我们要在WOW游戏里注册一个变量叫做"VARIABLES_LOADED".
<OnEvent>的意思是,如果发生了什么事件,那么该做出什么动作来反应.以我们的例子,如果注册"VARIABLES_LOADED"成功的话,我们就执行hi_initialize(). 当然,如果没有注册成功,也就不会有事件发生,这代表了我们的模块没有加载到游戏里面,所以我们也就没有后续动作.
hi.lua的介绍:
lua 是一个script语言.WOW所有的UI模块都是建立在这个语言之上.对于lua想要更深入的了解,请到官方网站:http://www.lua.org/manual/5.0/ 在这里可以查到所有关于lua的语法以及使用方式.
现在让我介绍我们目前的例子:
| CODE |
function hi_initialize() |
大家可以看到我们写两个小function 一个叫hi_initialize 一个叫 hi_command. 在hi.xml里面,如果模块顺利在入的话hi_initialize是第一个被呼叫的.在这里我们自行设定了一些"/"指令.我想大家因该对于游戏里面的一些"/"指令并不陌生.
同样的我们也可以帮我们的模块设定这些"/"指令.
SlashCmdList["HIHI"] = hi_command; 代表的意思是如果我们么组的"/"指令被呼叫的话,我们因该执行hi_command这一个function.
SLASH_HIHI1 = "/hihi";
SLASH_HIHI2 = "/您好";
这里是帮我们的"/"指令定出名称,目前我还不确定我们是否可以自行自做出中文指令,但是我想只要可以在WOW输入中文,上面的设计就因该没问题.(所以还请可以在WOW输入中文的玩家测试一下.
这里要稍微注意的一点是SlashCmdList["HIHI"]里面的HIHI必须要和SLASH_HIHI1和SLASH_HIHI2 的HIHI依样.如果我们把HIHI改成NIHAO 那么就会变成SlashCmdList["NIHAO"], SLASH_NIHAO1, 以及SLASH_NIHAO2. 至于HIHI 或是 NIHAO 后面的 1 和 2 只是变量,代表了同样的指令,有哪些变种的指令.
当我们打入了"/hihi"或是"/您好" 就会执行下面的function
function hi_command(msg)
message(msg);
end
基本上只是在游戏画面上出现一个窗口,然后窗口上面显示我们在指令后面打入的讯息.
例如我们输入"/hihi 测试"
那么出现的窗口就会显示 "测试" 在那上面.
好了,我们写好这三个档案了.现在我们要告诉WOW加载我们的HI模块.
首先,到"C:Program FilesWorld of Warcraftinterface"这个子目录里面.如果还没有这个子目录的话,自行开一个新的.然后在这个目录里面开一个新的目录叫做"AddOns"所有玩家设计的模块都因该摆在这个目录里面.然后在"AddOns"这个目录里面在开一个目录叫做"HI".最后把我们做好的三个档案存到这个目录里面.
"C:Program FilesWorld of WarcraftinterfaceAddOnsHI"
现在我们可以测试这个模块了喔.
稍微介绍一下WOW简易管理模块的方式.如果当玩家有安装自行设计的模块的话(比如说COSMOS),在进入角色选单的时候,我们可以看到画面的左下方有一个Addons的按钮.大家可以在者里自行选择所希望开启的模块.在模块名子前面打勾,表示选择角色之后,游戏就会开始加载模块.没打勾就代表不会加载. 请注意,WOW有模块加载的上限.所果所有加载的模块用到的资源超过32MB,游戏会自动关闭.这时候就需要去管理接口关掉一些模块喔.
下一篇文章,我将教大家如何在lua档案里面使用WOW的核心指令,以及如何只使用3个档案,就可以写出很有帮助的SCRIPT.
Chapter Three
在来一系列的文章,我要教猎人的玩家如何利用模块设计,有效率的执行远距离,近距离,以及宠物攻击. 顺便介绍一些WOW的核心指令.
我想玩过网络游戏的玩家,多多少少都因该听过外挂.什么是外挂?其实就是能自动的帮助玩家执行一些指令.基本上很类似MACRO(没听过MACRO的人,因该有听过EZSCRIPT吧)
WOW本身就有提供MACRO这样的功能.只要我们在游戏中输入"MACRO"之后,我们就可以开始设计我们自己的辅助指令.但是WOW的MACRO有很多限制.第一,WOW的MACRO是半自动的,意思就是说,你一定要按下某一个键盘按键,或是老鼠按键,才能执行你所设定的MACRO.第二,游戏中的MACRO有字数上的限制.最多只能输入255个英文字符.第三,WOW的MACRO无法设定时间上面的间隔.在MACRO里面的所有的指令会被一次执行.第四,如果你所执行的很多指令中有很多都有指令冷却时间(例如魔法的COOLDOWM),那么MACRO只会执行第一个可以执行的指令.
同样的,当我们设计模块的时候,我们也同样受限于这样的限制,但是却没有255个英文字符的限定,在这样的情况下,我们可以自做更复杂的指令方式.
今天我要教大家的模块是猎人辅助模块.
WOW的猎人是属于远距离攻击的单位,最需要控制的是如何有要的利用各式的ASPECT以及宠物攻击.当近距离攻击的时候,猎人需要用到ASPECT OF MONKEY,当远距离攻击的时候,需要用到ASPECT OF HAWK. 但是我想很多人因该都会遇到,同时指示宠物攻击,玩家攻击,以及转换ASPECT的时候,会手忙脚乱.现在我们的目标是如何设计一个模块可以让我们在操作上更顺畅.
猎人辅助模块设计目标:
1:玩家主动攻击的时候,宠物也会主动攻击(WOW的基本模式是,玩家按攻击,然后还要按宠物攻击).
2:玩家与宠物永远是攻击同一个目标,以最快最有效率的方式来减少战斗画面上的危机.避免宠物与玩家通时攻击不同的敌人,造成最后的结果是玩家与宠物同时阵亡.
3:有效的辨识玩家的攻击方式,然后执行最有效率的ASPECT.例如玩家近距离攻击的时候不是在ASPECT OF HAWK的状况下.
4:有效的?#092;用远距离攻击技能(包括了节省MANA,快速选择敌人目标等等)
好了,有了以上的目标,现在开始让我们来设计.首先,来制作模块所需要的最基本的三个档案.因为我替我的模块设计的名称叫做HunterAssistant(猎人辅助),所以我的三个基本档案叫做:
HunterAssistant.toc
HunterAssistant.xml
HunterAssistant.lua
| CODE |
HunterAssistant.toc: ## Interface: 4150 ## Title: Hunter Assistant V0.1 ## Notes: Macro scripts for assisting Hunter ## OptionalDeps: ## Dependencies: HunterAssistant.xml HunterAssistant.xml: <?xml version="1.0" encoding="utf-8" ?> <Ui xmlns="http://www.blizzard.com/wow/ui/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.blizzard.com/wow/ui/"> <script file="HunterAssistant.lua"/> <Frame name="HunterAssistantFrame"> <scripts> <OnLoad> this:RegisterEvent("VARIABLES_LOADED"); </OnLoad> <OnEvent> if (event == "VARIABLES_LOADED") then HunterAssistant_init(); end </OnEvent> </Scripts> </Frame> </Ui> |
我将不在第这两个档案多做解释.有疑问的,请参考上一篇文章.毕竟我只使用的最简单的设计.
现在的重点LUA核心檔.我先把档案内容列出来,然后在以另外的文章详细的解释每个指令.
HunterAssistant.lua:
| CODE |
| function HunterAssistant_init() -- define slash command here SlashCmdList["HA_HunterMarkI"] = HA_HunterMarkI; SLASH_HA_HunterMarkI1 = "/HAHunterMarkI"; SLASH_HA_HunterMarkI2 = "/hahmi"; SlashCmdList["HA_HunterMarkII"] = HA_HunterMarkII; SLASH_HA_HunterMarkII1 = "/HAHunterMarkII"; SLASH_HA_HunterMarkII2 = "/hahmii"; SlashCmdList["HA_AttackMelee"] = HA_AttackMelee; SLASH_HA_AttackMelee1 = "/HAAttackMelee"; SLASH_HA_AttackMelee2 = "/haam"; SlashCmdList["HA_AttackRangeI"] = HA_AttackRangeI; SLASH_HA_AttackRangeI1 = "/HAAttackRangeI"; SLASH_HA_AttackRangeI2 = "/haari"; SlashCmdList["HA_AttackRangeII"] = HA_AttackRangeII; SLASH_HA_AttackRangeII1 = "/HAAttackRangeII"; SLASH_HA_AttackRangeII2 = "/haarii"; SlashCmdList["HA_StingSerpentI"] = HA_StingSerpentI; SLASH_HA_StingSerpentI1 = "/HAStingSerpentI"; SLASH_HA_StingSerpentI2 = "/hasseri"; SlashCmdList["HA_StingSerpentII"] = HA_StingSerpentII; SLASH_HA_StingSerpentII1 = "/HAStingSerpentII"; SLASH_HA_StingSerpentII2 = "/hasserii"; SlashCmdList["HA_StingSerpentIII"] = HA_StingSerpentIII; SLASH_HA_StingSerpentII1 = "/HAStingSerpentIII"; SLASH_HA_StingSerpentII2 = "/hasseriii"; SlashCmdList["HunterTest"] = HunterTest_command; SLASH_HunterTest1 = "/HunterTest"; SLASH_HunterTest2 = "/ht"; end |
| CODE |
| function HA_AttackMelee() AssistUnit("pet"); if(not UnitExists("target")) then TargetNearestEnemy(); end; if(UnitExists("target")) then PetAttack(); CastSpellByName("Attack"); x=1 found=false; while (UnitBuff("player",x)) do if(string.find(UnitBuff("player",x), "Monkey")) then found=true; end; x=x+1; end; if(not found) then CastSpellByName("Aspect of the Monkey"); end; end; end |
| CODE |
| function HA_AttackRangeI() AssistUnit("pet"); if(not UnitExists("target")) then TargetNearestEnemy(); end; if(UnitExists("target")) then PetAttack(); CastSpellByName("Auto Shot"); x=1 found=false; while (UnitBuff("player",x)) do if(string.find(UnitBuff("player",x), "Raven")) then found=true; end; x=x+1; end; if(not found) then CastSpellByName("Aspect of the Hawk(Rank 1)"); end; end; end |
| CODE |
| function HA_AttackRangeII() AssistUnit("pet"); if(not UnitExists("target")) then TargetNearestEnemy(); end; if(UnitExists("target")) then PetAttack(); CastSpellByName("Auto Shot"); x=1 found=false; while (UnitBuff("player",x)) do if(string.find(UnitBuff("player",x), "Raven")) then found=true; end; x=x+1; end; if(not found) then CastSpellByName("Aspect of the Hawk(Rank 2)"); end; end; end |
| CODE |
function HA_HunterMarkI() AssistUnit("pet"); if(not UnitExists("target")) then TargetNearestEnemy(); end; if(UnitExists("target")) then PetAttack(); CastSpellByName("Hunter's Mark(Rank 1)"); end; end |
| CODE |
function HA_HunterMarkII() AssistUnit("pet"); if(not UnitExists("target")) then TargetNearestEnemy(); end; if(UnitExists("target")) then PetAttack(); CastSpellByName("Hunter's Mark(Rank 2)"); end; end |
| CODE |
function HA_StingSerpentI() AssistUnit("pet"); if(not UnitExists("target")) then TargetNearestEnemy(); end; if(UnitExists("target")) then PetAttack(); x=1 found=false; while (UnitDebuff("target",x)) do if(string.find(UnitDebuff("target",x), "Quickshot")) then found=true; end; x=x+1; end; if(not found) then CastSpellByName("Serpent Sting(Rank 1)"); end; end; end |
| CODE |
function HA_StingSerpentII() AssistUnit("pet"); if(not UnitExists("target")) then TargetNearestEnemy(); end; if(UnitExists("target")) then PetAttack(); x=1 found=false; while (UnitDebuff("target",x)) do if(string.find(UnitDebuff("target",x), "Quickshot")) then found=true; end; x=x+1; end; if(not found) then CastSpellByName("Serpent Sting(Rank 2)"); end; end; end |
Chapter Four
| CODE |
function HunterAssistant_init() -- define slash command here SlashCmdList["HA_HunterMarkI"] = HA_HunterMarkI; SLASH_HA_HunterMarkI1 = "/HAHunterMarkI"; SLASH_HA_HunterMarkI2 = "/hahmi"; SlashCmdList["HA_HunterMarkII"] = HA_HunterMarkII; SLASH_HA_HunterMarkII1 = "/HAHunterMarkII"; SLASH_HA_HunterMarkII2 = "/hahmii"; SlashCmdList["HA_AttackMelee"] = HA_AttackMelee; SLASH_HA_AttackMelee1 = "/HAAttackMelee"; SLASH_HA_AttackMelee2 = "/haam"; SlashCmdList["HA_AttackRangeI"] = HA_AttackRangeI; SLASH_HA_AttackRangeI1 = "/HAAttackRangeI"; SLASH_HA_AttackRangeI2 = "/haari"; SlashCmdList["HA_AttackRangeII"] = HA_AttackRangeII; SLASH_HA_AttackRangeII1 = "/HAAttackRangeII"; SLASH_HA_AttackRangeII2 = "/haarii"; SlashCmdList["HA_StingSerpentI"] = HA_StingSerpentI; SLASH_HA_StingSerpentI1 = "/HAStingSerpentI"; SLASH_HA_StingSerpentI2 = "/hasseri"; SlashCmdList["HA_StingSerpentII"] = HA_StingSerpentII; SLASH_HA_StingSerpentII1 = "/HAStingSerpentII"; SLASH_HA_StingSerpentII2 = "/hasserii"; SlashCmdList["HA_StingSerpentIII"] = HA_StingSerpentIII; SLASH_HA_StingSerpentII1 = "/HAStingSerpentIII"; SLASH_HA_StingSerpentII2 = "/hasseriii"; SlashCmdList["HunterTest"] = HunterTest_command; SLASH_HunterTest1 = "/HunterTest"; SLASH_HunterTest2 = "/ht"; end |
附注:HA_代表的意思是HunterAssistant的缩写.
其实这里没有什么特别的.这里只是帮模块设定一些简单的"/"指令.将来我们可以直接把这些指令?#092;用到游戏的MACRO中. 请注意的一点是,每一个指令都有一个FUNCTION相对应.另外,我每一个指令都一个全名指令,以及一个简写指令(方便使用).在指令命名设计上,我以看到指令名称就大概能猜到使用的结果是什么.还有就是每个指令前面加上HA_这样能有效的避免跟其它模块的指令冲突到.另外有几个指令后面有罗马数字,这些是代表了所使用到的猎人技能是有等级高低的.比如说HA_HunterMarkI使用的是等级1的Hunter's Mark,HA_HunterMarkII使用的是等级2的Hunter's Mark.
另外,我的指令排列是以英文顺序为主.这样方便我个人寻找BUG.
现在让我们继续往下看.
| CODE |
function HA_AttackMelee() AssistUnit("pet"); if(not UnitExists("target")) then TargetNearestEnemy(); end; if(UnitExists("target")) then PetAttack(); CastSpellByName("Attack"); x=1 found=false; while (UnitBuff("player",x)) do if(string.find(UnitBuff("player",x), "Monkey")) then found=true; end; x=x+1; end; if(not found) then CastSpellByName("Aspect of the Monkey"); end; end; end function HA_AttackMelee() AssistUnit("pet"); if(not UnitExists("target")) then TargetNearestEnemy(); end; if(UnitExists("target")) then PetAttack(); CastSpellByName("Attack"); x=1 found=false; while (UnitBuff("player",x)) do if(string.find(UnitBuff("player",x), "Monkey")) then found=true; end; x=x+1; end; if(not found) then CastSpellByName("Aspect of the Monkey"); end; end; end |
这一个function的主要目的是近距离攻击.首先第一行是AssistUnit("pet");这代表了什么?其实这是WOW的核心指令之一.AssistUnit()的意思是帮助某一个单位的意思.这个指令可以接受不同的变量,包括玩家单位,NPC友好单位,以及宠物单位.当执行了这个指令之后,你的敌人对象就会变成你所帮助的那个单位的敌人是同一个.在这里"pet"的意思就是主角单位的宠物.
我在这里会用AssistUnit("pet")开头的原因是,当你的宠物在攻击的时候敌人的时候,你跟你的宠物所选择的敌人不见得是同一个,所以我们要确定主角跟宠物攻击的对象是同一个.
(注意:目前我这样的设计好像有点逻辑上的问题.思考逻辑到底是主角该帮主宠物还是宠物帮助主角?游戏中的基本设定是主角受到攻击,宠物就会自动帮助第一个攻击主角的敌人,可是如果好几个人攻击主角,宠物还是会先专心的把第一个敌人解决掉.所以我一开始会这样设计,专心的先帮助宠物解决掉第一个敌人.可是当遇到我就是有特殊原因要先解决掉其它的敌人的时候(例如某些特殊任务),我这样的设计反而造成困扰,因为只要我一攻击,我的对象就就转换到宠物的敌人了.所以在未来的版本中,我可能会设定另一种攻击是,宠物永远帮助主角攻击同一个敌人,使用的指令是 PetAssistUnit("Player"). "Player"就是代表主角的意思.)
下一行, if(not UnitExists("target")) then
TargetNearestEnemy();
end;
这里的意思是检查执行帮忙的指令之后(AssistUnit())到底有没有敌人?如果主角的宠物没有在战斗状态,那么我们敌人的状态就是没有选择.UnitExists("target")) 就是检查我们有没有选择任何的目标.这个也是WOW的核心指令之一. 当然如果我们有选择目标,可是目标是有好单位呢?不用担心,WOW的设计本来就是无法攻击友好单位的.那么TargetNearestEnemy()又是什么意思呢?就是自动选择距离最近的非有好单位当作目标选项.所以这一段的意思就是,如果主角跟主角的宠物都没有目标的话,帮主角动挑一个最近的非有好单位当作目标.
| CODE |
if(UnitExists("target")) then PetAttack(); CastSpellByName("Attack"); |
这里代表的是,如果有目标的话,宠物攻击,然后主角攻击.PetAttack()是宠物攻击的指令,CastSpellByName("Attack")的意思是主角施展技能,这个技能是攻击(Attack). 这些全都是WOW的核心指令喔,酷吧.
| CODE |
| x=1 found=false; while (UnitBuff("player",x)) do found=true; end; x=x+1; end; if(not found) then CastSpellByName("Aspect of the Monkey"); end; end; end |
这里我定义了一个变量X,以及一个变量FOUND(中文是找到的意思),这两个变量不是WOW的专有变量,而是LUA的语法喔.为什么需要这两个变量?因为当我们在近距离攻击的时候,我必须要确定主角是在于ASPECT OF MONKEY 之下,有了这些变量可以方便我来做检查.
while (UnitBuff("player",x))的意思就是如果在主角的身上可以找到Buff的话. UnitBuff("player",1)会在寻找主角身上第一个buff的数据,然后传回讯息.如果没找到,就会传回一个否定的讯息.UnitBuff("player",2)就是寻找第二个buff的数据.
if(string.find(UnitBuff("player",x), "Monkey"))
string.find是lua语言上的指令,不是WOW的核心指令.这个指令的目的是寻找一个讯息中的字符串是否有特殊的字符.所以这一整段的意思是找寻主角身上的buff的信息是否有MONKEY(猴子)的字符串.如果有的话,就把FOUND设定为TRUE.
if(not found) then
CastSpellByName("Aspect of the Monkey");
这一段就是如果从头到尾都没有找相关的buff的话,代表了主角没有施展"Aspect of the Monkey",所以我们就执行施展技能的指令CastSpellByName("Aspect of the Monkey").
写到这里,让我顺便提出一些要点.不晓得大家有没有发现到,在这个function里面,从头到尾只有一个指令需要冷却时间那就是CastSpellByName("Aspect of the Monkey").其它,比如说攻击,全部都不需要冷却时间.这也就是为什么这么多指令都可以转变成一个单一指令.但是因为CastSpellByName("Aspect of the Monkey")需要冷却时间,所以我把她摆在最后执行,避免错误.另外一点就是,很多人在找寻主角身上的buff数据的时候,喜欢直接用UnitBuff("player",1)却没有想到其实主角身上可能有很多的buff呢.
所以我这样的设计一定可以确保如果主角已经施展了Aspect of the Monkey,就绝对不会重复施展第二次(浪费mana喔).
至于这个function 里面的一些IF, WHILE, NOT等等的?#092;用以及正确的语法,就请大家到LUA的官方网站去看.我就不多解释了.
在来是猎人的普通远距离攻击
| CODE |
| function HA_AttackRangeI() AssistUnit("pet"); if(not UnitExists("target")) then TargetNearestEnemy(); end; if(UnitExists("target")) then PetAttack(); CastSpellByName("Auto Shot"); x=1 found=false; while (UnitBuff("player",x)) do if(string.find(UnitBuff("player",x), "Raven")) then found=true; end; x=x+1; end; if(not found) then CastSpellByName("Aspect of the Hawk(Rank 1)"); end; end; end |
这一段其实跟近距离的普通攻击是同样的逻辑,但是CastSpellByName("Auto Shot") 这个是猎人专有的远距离自动攻击的指令.同样的这个指令可以跟其它需要冷却时间的指令同时使用.另外CastSpellByName("Aspect of the Hawk(Rank 1)") 这是执行第一级的ASPECT OF THE HAWK. 在我们模块function HA_AttackRangeII()里面就会执行第二级的ASPECT OF THE HAWK, CastSpellByName("Aspect of the Hawk(Rank 2)")
| CODE |
function HA_HunterMarkI() AssistUnit("pet"); if(not UnitExists("target")) then TargetNearestEnemy(); end; if(UnitExists("target")) then PetAttack(); CastSpellByName("Hunter's Mark(Rank 1)"); end; end function HA_HunterMarkI() AssistUnit("pet"); if(not UnitExists("target")) then TargetNearestEnemy(); end; if(UnitExists("target")) then PetAttack(); CastSpellByName("Hunter's Mark(Rank 1)"); end; end |
这一段没有什么特别的,唯一的好处就是当主角开始使用MARK的技能的时候,就开始命令宠物攻击.我们不需要按两个动作.另外,Hunter's Mark 也是有等级之分的,所以我写了其它相对应的等级指令
注意:(这个FUNCTION我还没有完全的完成,因为我没有检查是否敌人已经被MARK过了,也就是说这个指令允许重复MARK敌人,浪费MANA)
CODE
function HA_StingSerpentI()
AssistUnit("pet");
if(not UnitExists("target")) then
TargetNearestEnemy();
end;
if(UnitExists("target")) then
PetAttack();
x=1
found=false;
while (UnitDebuff("target",x)) do
if(string.find(UnitDebuff("target",x), "Quickshot")) then
found=true;
end;
x=x+1;
end;
if(not found) then
CastSpellByName("Serpent Sting(Rank 1)");
end;
end;
end
这一个跟普通远距离攻击的指令很像,但是并不是使用普通的AUTO SHOT,而是使用了Serpent Sting.另外这一个指令不会检查主角本身是否施展了ASPECT OF HAWK.因为Serpent Sting跟aspect of the hawk都要冷却时间,两个写在一起,只会执行其中的一个,那么就一点意义都没有了.既然这样,为什么要写这一个指令?其实这个指令会检查敌人身上是否已经被施展了Serpent Sting,毕竟Serpent Sting没有加成效过,所以我们要避免重复施展Serpent Sting.而WOW的基本Serpent Sting指令是不会做这样的检查的,所以我们还得一直盯着敌人的信息看着,避免浪费MANA.可是设计了另外的这个指令,玩家根本不用担心浪费MANA,只要想到了就执行一下,反证会自动检查,也不会中断AOTU SHOT的动作,更不会浪费MANA.另外,这个指令也有设计其它不同等级的相对应指令.
最后
CODE
function HunterTest_command()
x=1
found=false;
while(UnitBuff("player",x)) do
if(string.find(UnitBuff("player",x), "Raven")) then
found=true;
end;
x=x+1;
end;
if(not found) then
CastSpellByName("Aspect of the Hawk(Rank 1)");
end;
if(found) then
CastSpellByName("Aspect of the Monkey");
end;
end
这个指令只是我设计好玩拿来测试用的,当执行这个指令的时候,主角会交互的使用ASPECT OF MONKEY 或者 ASPECT OF HAWK.
模块的核心指令介绍到这里,下一篇文章将教玩家如何在游戏里?#092;用这些指令.
目前我们的模块有了最基本的三个档案了.现在让我们把这三个档案放入C:Program FilesWorld of WarcraftInterfaceAddOnsHunterAssistant这个数据夹里面.然后执行游戏.
现在让我解释一下WOW上面所谓的斜线指令("/指令")该如何?#092;用.
大家因该都清楚如何的?#092;用感情指令,或是交谈指令.这些都是斜线指令.但是WOW还有一些斜线指令是无法直接的输入, 比如说"/attack". 基本上这是WOW官方设计的攻击指令,其背后只是很简单的呼叫了CastSpellByName("Attack"). 但是为什么我们无法直接使用这些指令呢?因为暴风雪为了避免玩家利用其它的程序来设计非法的MACRO.
怎么说呢?因为WOW的MACRO没有时间间隔设计,避免玩家设计机器人,那么玩家设计机器人就必须利用其它的程序.如果,设计机器人,机器人程序就可以直接的仿真键盘输入指令,而不会影响到玩家对于鼠标的操做.所以WOW把很多的斜线指令的操作设定成只有在WOW的MACRO下才能使用.你设计一个MACRO以及MACRO图像按钮,你要执行这个MACRO,你就必须对这个按钮按一下,WOW才会执行这个动作.
当然,还是有其它的办法摆脱暴风雪这样的设计,但是我不会对类似这样的问题做出任和解说.因为暴风雪尽力的维护游戏免于外挂的侵入,身为玩家的我也有义务要帮助暴风雪.
有这样的限制的斜线指令包括了所有的会使用到执行特殊技能的指令.所以当我们设计的模块有用到执行特殊技能的时候,我们的斜线指令也只能在WOW下面的MACRO才能执行.(当然,我们的猎人辅助模块还是?#092;用在MACRO下面比较好,毕竟在战斗的时候谁还有时间慢慢的的用键盘输入指令,我们又不是机器人)
要使用WOW的MACRO很简单,只要在游戏中输入"/macro"或是按下Esc 然后选择macro的选项
在macor的画面,我们必须帮macro选择一个图像按钮,替macro命名,然后输入我们想要给macro的指令.
现在让我列出猎人辅助模块的简易斜线指令:
Hunter's Mark 包括了不同的等级
/hahmi/hahmii
Melee Attack(近距离攻击)
/haam"
Range Attack (远距离攻击)包括了不同的等级
/haari
/haarii
Serpent Sting(远距离特技)包括了不同的等级
/hasseri
/hasserii
/hasseriii
现在我们只要把macro的图像按钮选择好,然后给个名子,最后在底下输入指令的地方,挑一个你想要执行的辅助指令输入就好了. 注意喔,一个macro只能使用模块的一个指令喔,因为就算你输入了很多个,在执行macro的时候,游戏也只会执行情中的一个而已.(冷却时间的考虑)
当你设定好了macro之后,WALA~~~,你就可以把这个图形按钮抓到快捷工具栏上面使用了~~~就像是使用任何其它的基本图形按钮依样喔.好处是,你按一次按钮,却等于其它没有用辅助模块人按好几次按钮依样喔.还会自动帮你做一些额外的检查呢.有效率了多吧.
下一次,我将教大家如何设计辅助模块可以帮大家在半自动的施展BUFF,对象也会半自动的选择队友,宠物,或是自己.
附注1:因为我个人玩了10角色,包括了联盟的每一个CLASS,在未来的日子里,我将会不定期的替自己写模块.如此同时,我也会拿上来与大家分享.但是我将不会再花这么多的时间详细解释每一个指令.除非有网友提出问题,那时我会在尽力回答.
附注2:有关WOW的核心开放给玩家使用的指令,大家可以到这个网页找到.但是这里不是完整的列表,说明也不是很清楚,不过大家将就的用噜.
http://www.wowwiki.com/World_of_Warcraft_API
附注3:最有效率的研究模块的方式,就是到官网的UI Customization的论坛参与讨论喔.也许大家会找到一些意想不到,但是又很有帮助的模块喔.我个人就已经发现有人设计了一个挖矿采要的模块,这个模块会把你最到过的挖矿以及采药的地点纪录下来,然后显示在地图上.怎么样,很有用吧.
http://forums.worldofwarcraft.com/board.as...e-customization
Chapter Five
或许我在模块解释以及使用教学方面,因该采用更简单的例子来让大家能更容易上手.所以我决定不要直接的把我个人写好的模块拿上来,而是先的教大家如何使用WOW的MACRO,以及呼叫一些WOW的指令.
首先让我重新的介绍一下WOW的MACOR
(基本资料来源 魔兽台湾:http://www.wowtw.game.tw/)
在"魔兽台湾"的网页里,我们可以找到很清楚的MACOR中文定义以及解释:
宏[Macro]使你能够创建自己独创且非常酷的命令集,你可以通过点击一个按钮便完成一系列的命令。宏拥有许多用法。
宏的创建
输入"/macro"或者点击谈话[talk]按钮并且选择宏[Macro]选项,将会弹出一个对话框,里面记录着你现有的宏。在开始的时候里面应该没有任何宏。
点击对话框底部的"new"按钮,将会弹出另外一个对话框,其中要求你输入宏的名称并且为这个宏选择一个图标。
给你的宏命名,选择一个容易记忆的名字。例如,输入"assist[协助]"。
选择一个图标。这里我们选择的是一把剑。
点击"Okay"按钮。你现在能够在你的宏对话框里看到这个宏的名称(assist),在名称的旁边有你刚才选择的图标(剑)。
现在在assist[协助]图标上点鼠标左键加亮它。除了"new"按钮外,同时也有一个按钮用来改变你的宏的名称和图标,以便你以后想改变它的名称或者选择一个不同的图标。
一旦你的"assist"图标是加亮状态,你就可以向下移动你的鼠标指针进入"enter macro commands[输入宏命令]的区域。在这里你可以输入你想让这个宏按钮实现的命令。
输入"/assist Nebu[协助Nebu]"。
现在移动你的鼠标指针回到剑的图标(assist[协助]宏),在这个图标上压下鼠标的左键不松开。
现在拖动图标到你的动作条的空槽里去。
当你要使用这个新的宏的时候,键入这个动作按钮对应的数字或者直接右键点击按钮本身。
现在你拥有了一个宏按钮,它将在其它玩家(Nebu)攻击的时候协助他。无论何时,当Nebu攻击目标的时候,点击这个按钮后你的目标将会变为他正在攻击的目标。
以上是"魔兽台湾"给予MACRO的中文解释,以及一个很简单的例子.
现在让我们稍微加强一下上面的例子.
上面的例子里面,我们看到了MACRO的内容只有一行
/assist Nebu
现在我们来加强一下,让这个MACRO不但会协助,还会马上攻击.改过的MACRO会像底下这样.
/assist Nebu
/attack
好了,现在我们的MACRO有两行了.这个MACRO的目的是,协助Nebu(指定Nebu的敌人),然后攻击.
那么现在让我们写一个很简单以及实用的MACRO.加设Nebu是一个牧师,我们要帮Nebu写一个自动帮自己使用基本治疗的MACRO.
/target Nebu
/cast Lesser Heal(Rank 1)
以上的MACRO在执行的时候,每次都会选择Nebu作为治疗的对象.其中,/target Nebu 是选择Nebu为对象,/cast Lesser Heal(Rank 1)是对于对象施展Lesser Heal第一级的法术.
我想以上的例子因该已经很清楚的解释了基本的MACRO该如何使用.可是在在"魔兽台湾"的网页里也有提到:
宏的限制
宏是有长度限制的,如果你的信息太长了,就缩减一些!(显然)
这一点是没有错的,因为WOW的MACRO有255个英文字符的限制.我们该如何突破这个限制呢?
首先让我们先了解一下WOW的官方斜线指令.
上面那些MACRO里所用到的斜线指令,其实背后都有呼叫一些核心指令.例如:
/assist Nebu 呼叫了 AssistUnit("Nebu")
/attack 呼叫了 Attack("Target")
/target Nebu 呼叫了 TargetByName("Nebu")
/cast Lesser Heal(Rank 1) 呼叫了 CastSpellByName("Lesser Heal(Rank 1)")
这些核心指令除了可以使用官方的斜线指令来呼叫之外,我们还有其它几种方式来使用这些核心指令.
第一种方式,直接在MACRO里使用这些核心指令.要直接使用这些核心指令,我们必须用到一个斜线指令叫做/Script.
以下是把上面的MACRO例子改成使用核心指令的方式.
第一个MACRO 帮助Nebu攻击敌人
/Script AssistUnit("Nebu");
/Script Attack("Target");
第二个MACRO选择Nebu作为治疗的对象
/Script TargetByName("Nebu");
/Script CastSpellByName("Lesser Heal(Rank 1)");
要注意的一点是,当使用了/Script的时候,MACRO的每一行指令都要有";"作为结尾.
直接使用核心指令的好处是什么?因为WOW并没有帮每一个核心指令写对应的斜线指令,而很多的核心指令的功能却是非常强大的.
核心指令除了能直接利用在MACRO之外,另一个用途就是可以使用在模块里面使用.关于使用上的例子,大家可以参考我前几篇文章所提供的猎人辅助模块.在这里我们就可以利用模块所提供的斜线指令来变相的突破了MACRO上面的字符限制了.
希望这一篇文章能更容易的让大家了解斜线指令,核心指令,MACRO,以及模块的用途.
>※littlethe(东周小星星)提到:
>我是个programmer,
>macro在程序中是指宏指令,
>若我没有弄错的话,
>这个macro是不是用于制定"连续动作"用的?
>
>按个键,
>人物就会做出连续预设动作,
>
>若是这样,
>那wow可还真特别,
>开放玩家编写macro,
>
>等我拿到wow时,
>要好好的来玩看看
恩~没有错喔
可是WOW本身的MACRO有很多的限制.可是如果玩家使用非游戏本身的MACRO来玩WOW,暴风雪就可以砍此玩家的账号.
WOW本身的MACRO先天上就没有时间的设计.也就是说,MACRO里面所有的动作指令,通通当作及时指令(当然,非常严格的来说还是会有先后顺序上的差别,可是时间上的差别只有不到0.1秒.)这样的设计是避免玩家制作机器人.
另外,WOW很多的技能有冷却时间,如果把多个有冷却时间的技能写入MACRO,那么MACRO只会执行第一个达到条件的技能,其它有冷却时间的技能都会被忽略.
>※littlethe(东周小星星)提到:
>虾米??
>那这样的话,
>那岂不就不能使用连续法术了?
>法术也有cast time不是么?
>还是wow的法术都是direct的?
>哇累...
>本来想说能不能来个先闪电再插补血丈后嗜血之类的
WOW的技能大约能分为三种,实时的,有冷却时间的,需要施展时间的.
实时的就是可以一直连续使用.
有冷却时间的就是在使用过后,有一个时间限制是不能使用同一招.另外,使用这种技能之后,还会有大约不到一秒的时间无法使用任何其它的技能.
需要施展时间的,当使用的时候,在技能完全施展之前,无法使用任何其它的技能,除非先取消掉.
所以只要是有被时间限制上的技能,在MACRO里,就只有一个可以被驱动,而且最好是摆在MACRO的最后一行.如果摆在太前面,那么很可能就会使得后面的实时技能被挡掉.
>※willllee(balmung)提到:
>那可以用macro来配合其它程序吗?
使用任何不是魔兽纪元本身所提供的功能来执行游戏,都违反了魔兽纪元的使用条约.所以我无法在这里回答您所提出的其它的相关问题.
但是有一点可以确定的是,魔兽纪元所提供的核心指令,已经可以做出广大的环境判断了.包括判定血量多少,队友以及其宠物的状态,敌人的状态,等等.
目前官方论坛上已经有很多的模块能提供类似的功能.包括当自身血量低于某百分比,执行动作的时候,会先帮自己补血(魔法或是对象,取决于是否在战斗中),以及根据队友的血量百分比来决定宠物会先帮助哪个队友攻击.
如果有兴趣的网友,甚至可以写出根据敌人的状态做出不同的攻击或是反应的模块.
基本上,这些都可以只用到核心指令来达到的.
开山辟斧
心血来潮我也申请了一个Blog,虽然很早就知道博客但以前只觉得这就像在小学里写日记一样(以前在我第一任语文老师的谆谆教导下我开始写日记,到后来就从日记变成周记再变成月记......之所以不写不是怕别人看我的日记,谁想看就看我无所谓,是因为我懒、嫌麻烦就不写了,一直到初中我的第(1、2、......)3任语文老师的强逼之下我又开始写周记了,到了初二第二学期她又说不要写了,但马上又说每周交一次摘抄一直到我初中毕业。到现在我又开始X记了["X"是因为我不知道这写的算日记还是周记、月记(有月记?)],我能坚持多久???......
--bhu记于华跃网吧142座用键盘砸出来的序(还是赤脚写的)
2005年4月9日15:58
听说WOW允许使用插件所以上Google查找UI、宏命令的简介,在查看了N篇文章后我总算有点眉目了。里面用了XML,这东西的格式很像以前自学过的HTML,不过也只是一知半解,毕竟这是2个程序指令。宏命令中大量的使用了"/script"。2个程序语言都有"IF"语句也就是说WOW有判断功能,想必在PK的时候一定很有用能够腾出更多的空闲来操作其它东西(听说WOW很讲究微操,我连TFT 1vs1 Easy Computer都有困难......),还有一个阻碍我成为这方面的天才、砖家(吐吧~!吐吧~!把肚子里的都吐光了看你下次还能吐什么 ^_^~~)的内容是这2个都是老外发明的语言,它们的官网全是映个利息(我连PET都没过呢,听说PET和CET要取消了,我以后考什么托福、雅思???)不过还好有其它中文教程,虽然没官网的详细,但也无所谓,谁让我是未来的天才呢
咋还没吐光啊~!