ACE2 系插件专用转贴!!!

ACE2 系插件专用转贴!!!

ACE2系列
[ game ]

ag_Unitframes  头像
菜单调出命令:/aguf config,如果安装了DeuceCommander,则可以直接从DeuceCommander调载命令

最新版本已经支持显示3D头像,需要在设置中选择显示头像,头像显示需要ABF模式支持。

更改字体方法:复制你喜欢的字体到游戏根目录的\FONTS文件夹(没有就自己建一个,推荐使用狂鼠字体),重命名为FRIZQT__.TTF和FZXHJW.TTF

安装后可自由拖动,但默认情况下框体较小,可通过菜单中的缩放调节。

未安装mobhealth3时显示HP为百分比,安装后为准确数字。

状态条材质可以选择N种材质来做HP MP的背景材质

锁定框体勾选后就无法再拖动所有头像框体

可按照职业颜色(就是游戏默认职业颜色,平时RAID列表里的那种,如:盗贼是黄色,法师是蓝色)显示生命条

插件默认设置:如果你处于团队时隐藏小队框体,如需显示请在团队选项中关闭此条。

插件不显示宠物快乐度图标,但宠物快乐判定以宠物生命条的颜色显示,绿色为愉快,黄色为一般,红色为......干吗要让宝宝不高兴呢?!

菜单中的“光环”就是我们通常说的BUFF  DEBUFF和DOT,可调节为:全部显示和只显示相关的(与本职业相关的各种魔法),默认初始状态为显示职业相关,想看到所有状态请关闭过滤。

下面说说ACE2类插件的一个共有缺点(也许是我认为的缺点):如果不保存设置的话,那么你这次设置只对这一个角色生效,意思就是如果你上小号发现小号也要再设置一遍。菜单中的保存选项为菜单底部的profile选项,可以一次性设置本服务器此阵营的所有角色。


Autobar  消耗品助手工具条
/autoBar调出控制台


Aggromemnon  得到和失去仇恨时报警


Antagonist  敌对施法进度监视

Acceptance 自动接受好友或公会成员的组队邀请

AutoAttack  自动攻击目标


Atlas+AtlasLoot  副本地图+副本boss掉落查询


BigWigs  首领报警
一种首领模块,支持CWOW 与CT_RABossMods相比,模块自动激活关闭,资源占用比较低。
命令行: /bw /bigwigs


BidHelper  记录拍卖成功和失败详情





ChannelClean  聊天过滤和防刷屏


CraftFilter  在专业技能制作框上添加个搜索框


cyCircled  动作条皮肤
使用DeuceCommander控制台进行设置


ChatSounds  聊天声音提示

Cartographer  世界地图透明及缩放,功能简单实用


CooldownCount  显示冷却计时


DeuceCommander  Ace2设置工具
集中了几乎所以ace2系列的命令设置


Detox  多国语言版(一键净化队伍/团队不良状态)
/detox Clean group

distanceWarning  全职业距离监控
/dw lock 锁定进度条
/dw unlock 解除锁定
/dw scale 缩放(参数范围:0.5~3系统默认的是1)
/dw usedefault 使用默认配置(当你不小心将进度条拖到屏幕外面时可以使用此命令使其重新回到屏幕中央)

EgoCast  自我施法

ElkBuffBar  漂亮的BUFF条
/ebb设置 可以看见设置BUFF的参数.
/ebb locked true 锁定
/ebb locked false 解除锁定
/ebb width 设置BUFF长
/ebb height 设置BUFF高

FreeRefills  自动购买物品,使用方法
PS: /freerefills add [物品名] 数量物品名按shift点击物品


Fizzle  一款 Ace2 的耐久度显示,直接显示在装备上




GMail  邮件工具类似ct_mod


InFlight  飞行计时器




idChat2  ACE2的聊天框插件,支持鼠标中间滚动,隐藏翻页按钮


Mendeleev  显示装备掉落地点出处、物品用途收集方法
作用:
给出物品可能的用途[这个不希奇]
给出物品可能加工出的东西[这个也不希奇]
给出装备掉落地点[在那个区域掉落]
给出装备掉落BOSS[看道具是那个boss身上掉落的]


OneBag  经典的整合背包(已经能支持多角色查看)分成好几个个组件了,支持钥匙链



oSkin  界面美化用的(宽屏效果就是oskin)

oCB  施法条美化
/ocb



oCD  技能冷却计时类似CooldownTimers暂时没有设置界面和状态条
/ocd




PartyQuestComm  队友任务跟踪




PlayerMenu  玩家菜单




RangeRecolor  超出技能距离重新着色图标


RangeColor  超出施法范围按钮就显示红色

SW_Stats  战斗统计插件


simpleMinimap  用这个可以改变小地图的外形,而且可以拖动小地图
/smm hide可以隐藏或者显示区域,时间和缩放按钮
/smm hide time可以把那个显示时间的太阳/月亮隐藏
/smm show zoom可以隐藏跟显示缩放按钮
/smm alpha (0.1  0.2~0.9  1)设置透明度 括号里的数字自己填一个你满意的透明度
/smm scale (0.1~0.9  1)设置大小
/smm lock锁定.输入一次锁定,再输入一次解锁.


TinyTip  提示条插件


Unexplorer  未探索地图半透明显示


VoicesFromBeyond  Down掉Boss时候发声


XLoot  使拣取框吸附鼠标并简化拣取框
拾取物品时下方有个link右键点击设置链接选项,左键点击可以按照link设置里的方式打出到聊天内通知别人

[ 本帖最后由 youdead 于 2007-1-29 11:09 编辑 ]


一切随缘.....
[img][/img]

TOP

oRA2+sRF/PRaid/Target+XRS+Squishy  团队助手

ORA2的前身是ora,一个功能与CTRA完全一样并且兼容的ace插件。这个插件的功能:
1 检查队员耐久度
2 检查队员抗性
3 检查队员携带物资
4 检查队员区域/准备就绪情况
5 制作组队邀请列表等
6 团队报警(似乎只是个接口,用bigwigs就ok了)
7 mt,tot,totot血量监视与点击宏设定                移动这些框体是按住alt键移动。。。

Compared with CT_RaidAssist it has the following Features:

Feature                          CT_RaidAssist                           oRA2  
Ressurection Monitor       Yes                                           Yes                           --------复活监视器
Decursive System            Yes                                           No, but  Detox      ----解除debuff系统
Emergency Monitor          Yes                                           No, but  Squishy    ----------紧急状况监视器        
RaidFrames                      Yes                                           No, but  sRaidFrames/PerfectRaid        ----团队框体
Raidstatus                       Yes                                           No, but  XRS  ---------团队状况
Boss Mod                         Yes (CT_Bossmod)                   No, but  BigWigs      ----------boss报警
Ready Check                    Yes                                           Yes    -----------------预备检查
Version Check                  Yes                                           Yes          --------------版本检查
Vote system                     Yes                                           Yes          ----------投票系统
Item check                       Yes (complete string match)     Yes (substring match)     --------物品准备情况检查
MT Frames                        Yes                                          Yes     ------------MTT
Durability Check               Yes                                           Yes     ---------------耐久度检查
Zone check                       Yes                                          Yes      --------------区域检查


团队框体sRaidFrames







团队框体PerfectRaid

perfectraid是基于ace2的一个插件(无需安装ace2),占用资源(cpu/mem)与功能都比团队助手好很多,功能则更胜一筹。
1 他可以以任意的方式对40人状态进行分类,比如小组,职业,远程近程,dps/healer,姓名,奇数偶数。。。。
2 会显示团队中没有buff的人员,当然只显示职业相关的,比如牧师,你可以知道谁没有韧,谁在你的范围内。比如你是术士,那你就知道谁梆了石头!
3 会显示中了debuff的人员。
4 会显示hp/mp缺乏者





团队状态监视XRS






智能目标列表PerfectTarget
perfecttarget是一个目标指示插件。显示的就是大家的目标,rl的标记或者mt的目标等。概念比较费解,但你用起来就知道有多好用了。







紧急情况监视器Squishy



[ 本帖最后由 youdead 于 2007-1-29 10:28 编辑 ]

TOP

小巧实用的动作条Bartender2
[ game ]

Bartender2来了,解决了以往的问题,新加入了可爱皮肤和快捷翻页功能。依然小巧实用。
基本功能:任意移动,缩放大小,调整间距,可多行显示[1X12,2X6,3X4...]。扩展以后提供:新颖皮肤,快捷翻页,特殊情况呼出动作条。

Bartender2 主程序 [ActionBar AddOn which modifies the layout using buttons provided by Blizzard] 利用BLZ动作条作出来的,加上ACE插件,占用超小。

Bartender2 扩展插件--------请仔细阅读各扩展插件的用途,选择你需要,尤其是非fubar用户,毕竟命令行设置比较繁琐.
包括:     
    Bartender2_BindingSwap   [Swaps the keybindings amongst the bars. ] 可以在不同的动作条之间切换快捷键

    Bartender2_Circled  [ Round skinned action buttons. ] 超可爱的圆圈皮肤。

    Bartender2_DruidBar  [This add-on reproduces the bar switch that happens when a Rogue goes into Stealth but with Prowl. ] 允许潜行职业在形态转化的时候自动切换动作条,如贼,小D的潜行。

    Bartender2_HunterBars  [Hunter Range/Melee Bar change] 猎人扩展..

    Bartender2_Pagemaster  [Performs page swaps on bar 1 when you hold shift, ctrl, alt, etc. ]利用快捷键迅速达到动作条翻页,你的动作条远远不止5个!! [注意:pagemaster有这么几个功能,快捷键翻页,变形后翻页[小D  MS暗影形态等等],选择友方目标后翻页,鉴于不是很多人使用fubar  设置相对繁琐,不强烈推荐使用]

    Bartender2_ShadowBar  [This add-on gives you a seperate page for priest's shadow form. ] 单独的牧师暗影形态切换时的动作条切换。

Fubartender :  和Fubar关联的插件。


使用:
游戏中输入/bar设置,强烈建议与Fubar同时使用,方便设置。可以隐藏系统按键栏和背包栏。
设置单个动作条,如动作条1。请键入:/bar bar1  依此类推。


相关:
另外 bartender2 与炽火大大的cooldown搭配很好:
炽火大大:http://bbs.game.mop.com/viewthre ... hlight=%B3%E3%BB%F0


Bartender2官网地址:http://wiki.wowace.com/files/  官方版本就包括中文版了

ACE2 & Libs 下载页面:
http://bbs.game.mop.com/viewthread.php?tid=1312063


TOP

原帖由 feifeiyu 于 2007-1-29 10:23 发表
哪里有的下,我去下个


这并不像 大脚 WOWSHELL 等整合插件  要下自己去找找 不推荐 所谓的傻瓜包!!

[ 本帖最后由 youdead 于 2007-1-29 11:12 编辑 ]

TOP

ACE插件的选择一、为什么需要插件?

为了能够在游戏中更方便得完成自己想要做的事,更清楚得看到自己想要看的内容。

二、为什么选择ACE系列?

为了在插件达到自己所要求的前提下,占用更少的内存,运行得更有效率。

三、我们需要哪些功能?

这完全因人而异,不同的职业,不同的游戏方式,每个人需要的插件肯定各有不同,明确自己想要什么是最重要的,对于没有经验的人来说,参考别人的想法很重要,不光看别人用哪些插件,更重要的是为什么用这个插件,那怕仅仅是因为美型,也是一个很棒的理由。



--------------------------------------------------------------------------------

头像增强,为了能够更清楚看清自己,队友,目标的HP,MP,还有目标的目标功能

我的选择:ag UnitFrames

下载:ttp://www.wowace.com/files/index.php?path=ag_UnitFrames/

介绍:http://www.wowace.com/wiki/Ag_UnitFrames

其他选择:无推荐,ag UnitFrames是ACE系列中头像增强的绝对强者,其他如AceUnitFrames,oUF,SnagoUF都远远不如其强大。

非ACE选择:Perl Classic Unit Frames等等
相关应用:MobHealth3

下载:http://www.wowace.com/files/index.php?path=MobHealth/

介绍:http://www.wowace.com/wiki/MobHealth3

在目标头像上显示HP和MP的具体数值


--------------------------------------------------------------------------------

动作条增强,为了能够更加精减默认动作条所占用的空间,去除不需要的元素

我的选择:Bartender2

下载:http://www.wowace.com/files/index.php?path=Bartender2/

介绍:http://www.wowace.com/wiki/Bartender2

其他选择:无推荐,动作条方面目前还是ACE系列的弱项,FlexBar2是FlexBar向ACE进化的尝试,但还在一个比较初始的阶段,尚不推荐。

非ACE选择:DAB(Discord Action Bars),FlexBar等等

相关应用:CooldownCount

下载:http://www.wowace.com/files/index.php?path=CooldownCount/

http://www.wowace.com/files/index.php?path=!CooldownCount/

在动作条上显示物品/技能的冷却时间
相关应用:RangeRecolor

下载:http://www.wowace.com/files/index.php?path=!RangeRecolor/

介绍:http://www.curse-gaming.com/en/w ... gerecolor-ace2.html

当目标在物品/技能可用范围之外时改变动作条按钮的颜色
相关应用:Bartender2 Circled

下载:http://www.wowace.com/files/index.php?path=Bartender2_Circled/

将动作条按钮以圆形显示


--------------------------------------------------------------------------------

背包增强,为了能够将所有背包和银行里的物品一次性全部打开显示

我的选择:OneBag,OneBank

下载:http://www.wowace.com/files/index.php?path=OneBag/

http://www.wowace.com/files/index.php?path=OneBank/

介绍:http://www.wowace.com/wiki/OneBag

其他选择:无推荐,唔,似乎这是ACE系列唯一的背包增强插件,不过此类插件功能基本雷同,一个也足够了。 非ACE选择:Bagnon,All in One Inventory等等,EngBag是个异类,能够将物品分类显示,很方便

相关应用:OneView

下载:http://www.wowace.com/files/index.php?path=OneView/

显示当前帐号上其他角色的背包和银行


--------------------------------------------------------------------------------

状态条,在一条或多条状态条上显示所需要的信息,如时间,背包空余,弹药,延迟,内存占用

我的选择:FuBar

下载:http://www.wowace.com/files/index.php?path=FuBar/

介绍:http://www.wowace.com/wiki/FuBar

其他选择:无
非ACE选择,Titan Panel,最初的状态条插件,几乎和WOW同期出现,现在很少更新了
相关应用:众多FuBar插件

下载:http://www.wowinterface.com/downloads/info4571-FuBar_2.0.html




--------------------------------------------------------------------------------

拾取增强,美化拾取界面,定位到鼠标所在位置

我的选择:XLoot

下载:http://www.wowace.com/files/index.php?path=XLoot/

介绍:http://www.wowace.com/wiki/XLoot

其他选择:FruityLoots,不改变默认拾取界面

非ACE选择:QuickLoot




--------------------------------------------------------------------------------

邮件增强,向一个人同时发出数封物品邮件,同时打开接收数个邮件

我的选择:GMail

下载:http://www.wowace.com/files/index.php?path=GMail/

介绍:http://www.wowace.com/wiki/GMail

其他选择:BulkMail,ExpressMail

非ACE选择:CT MailMod




--------------------------------------------------------------------------------

施法条增强,更美观的施法条,显示施法时间

我的选择:oCB

下载:http://www.wowace.com/files/index.php?path=oCB/

其他选择:无
非ACE选择:eCastingBar



--------------------------------------------------------------------------------

BUFF增强,将BUFF以更美观,显著的方式显示

我的选择:ElkBuffBar

下载:http://www.wowace.com/files/index.php?path=ElkBuffBar/

介绍:http://www.wowace.com/wiki/ElkBuffBar

其他选择:SeriousBuffTimers,仅仅优化了BUFF时间的显示;Buffalo

非ACE选择:Morganti's Buffbars



--------------------------------------------------------------------------------

团队助手,为RAID提供便利,提供MT目标,物品/抗性/耐久度检查,复活监视等功能

我的选择:oRA2

下载:http://www.wowace.com/files/index.php?path=oRA2/

介绍:http://www.wowace.com/wiki/ORA2

其他选择:无推荐,唯一ACE化的CT RaidAssist

非ACE选择:CT RaidAssist

相关应用:EeMon

下载:http://www.wowace.com/files/index.php?path=eeMon/

介绍:http://www.wowace.com/wiki/EeMon

紧急情况监视器,类似的还有Squishy
相关应用:XRS

下载:http://www.wowace.com/files/index.php?path=XRS/

介绍:http://www.wowace.com/wiki/XRS

团队状态监视器,显示团队某职业的HP,MP总体情况,总体AFK,死亡,BUFF的情况
相关应用:PerfectRaid

下载:http://www.wowace.com/files/index.php?path=PerfectRaid/

介绍:http://www.wowace.com/wiki/Perfect_Raid

团队框体,显示团队中每个人的状态(HP,DEBUFF等等),类似的还有SRaidFrames



--------------------------------------------------------------------------------

首领报警,为RAID副本的BOSS战斗提供各种报警

我的选择:BigWigs

下载:http://www.wowace.com/files/index.php?path=BigWigs/

介绍:http://www.wowace.com/wiki/BigWigs

其他选择:无推荐,ACE系唯一的首领报警插件
非ACE选择:La Vendetta Boss Mods,CT BossMods

TOP

AceOO-2.0 指南译者:simonw
原文发表于: AceOO-2.0_Tutorial



目录

AceOO-2.0 指南
开始
声明新类
获取类的实例
添加 :ToString()
添加方法
继承
构造函数
静态方法 vs. 实例方法
接口
Mixins
Metamethods
注释: 以下的示例我使用了一个自定义的打印函数.

切换行号显示    1 function print(text)
   2     DEFAULT_CHAT_FRAME:AddMessage(tostring(text))
   3 end


开始为了访问AceOO-2.0, 你需要将AceOO-2.0 library 加入到你的项目中并且在TOC中这样写:

切换行号显示    1 AceOO-2.0\AceOO-2.0.lua

在lua文件中你需要加入:

切换行号显示    1 local AceOO = AceLibrary("AceOO-2.0")

获得一个AceOO-2.0的local reference.


声明新类
切换行号显示    1 local Chicken = AceOO.Class()

这创建了一个没有额外方法的Chicken空白类, 衍生自Class.


获取类的实例
切换行号显示    1 local kingRooster = Chicken:new()

king rooster 是Chicken类的一个实例. 我们可以调用 :new() 多次来创建多个不同的Chicken类的实例.


添加 :ToString()通过类的引用来打印出类型信息.

切换行号显示    1 function Chicken:ToString()
   2     return "Chicken"
   3 end
   4 -- So now this happens:
   5
   6 print(Chicken) -- "Chicken"
   7 print(kingRooster) -- "<Chicken instance>"
   8 object:ToString() -- will be called whenever tostring(object) is called


添加方法创建一个猫的类, 做2件事情: 爱抚(pet) 和 泼水(spray with water). (猫不喜欢被泼水.)

切换行号显示    1 local AceOO = AceLibrary("AceOO-2.0")
   2
   3 local Cat = AceOO.Class()
   4
   5 Cat.prototype.happiness = "Neutral"
   6
   7 function Cat.prototype:Pet()
   8     if self.happiness == "Unhappy" then
   9         self.happiness = "Neutral"
  10     else
  11         self.happiness = "Happy"
  12     end
  13 end
  14
  15 function Cat.prototype:SprayWithWater()
  16     if self.happiness == "Happy" then
  17         self.happiness = "Neutral"
  18     else
  19         self.happiness = "Unhappy"
  20     end
  21 end
  22
  23 local reginald = Cat:new() -- 一只猫
  24 local fluffers = Cat:new() -- 另一只猫
  25
  26 -- reginald is cute. fluffers was bad.
  27 reginald:Pet()
  28 fluffers:SprayWithWater()
  29 print(string.format("%s - %s", reginald.happiness, fluffers.happiness)) -- "Happy - Unhappy"

尽快例子有点傻但却是做了个很好的示范. 两只不同的猫有不同的特征各自独立互相不依赖.

你可能对 .prototype 有点奇怪. 所有的实例均继承于此, 而不是继承自Class. 稍后会详细解释.

切换行号显示    1 print(AceOO.inherits(reginald, Cat)) -- true
   2 print(AceOO.inherits(fluffers, Cat)) -- true
   3 print(reginald ~= fluffers) -- true

这里展示了reginald 和 fluffers 都是猫但不是同一只猫.


继承类可以从其他类继承, 当前所有的类均继承自标准的Class. 这里将展现一个类继承自一个用户定义的类.

切换行号显示    1 local AceOO = AceLibrary("AceOO-2.0")
   2
   3 local Dog = AceOO.Class()
   4 Dog.virtual = true -- 这个意思是禁止实例化. (即不能调用 :new())
   5
   6 function Dog.prototype:Bark()
   7     -- 如果子类没有实现这个方法将引发一个异常.
   8     error("`Bark' not implemented", 2)
   9 end
  10
  11 local Chihuahua = AceOO.Class(Dog) -- 新类, 继承自Dog类.
  12
  13 function Chihuahua.prototype:Bark()
  14     return "Arf! Arf! Arf!"
  15 end
  16
  17 local Bulldog = AceOO.Class(Dog) -- 新类, 继承自Dog类.
  18
  19 function Bulldog.prototype:Bark()
  20    return "Wuff! *slobber*"
  21 end
  22
  23 local Sheepdog = AceOO.Class(Dog) -- 新类, 继承自Dog类.
  24
  25 function Sheepdog.prototype:Bark()
  26     return "Ruff."
  27 end
  28
  29 local killer = Chihuahua:new()
  30 local muffin = Bulldog:new()
  31 local leopold = Sheepdog:new()
  32
  33 print(killer:Bark()) -- "Arf! Arf! Arf!"
  34 print(muffin:Bark()) -- "Wuff! *slobber*"
  35 print(leopold:Bark()) -- "Ruff."

这些都是狗的类型但他们的叫法均不同, 因为是不同类型的狗类.


构造函数
切换行号显示    1 local AceOO = AceLibrary("AceOO-2.0")
   2
   3 local Pig = AceOO.Class()
   4
   5 function Pig.prototype:init(name)
   6     Pig.super.prototype.init(self) -- 非常重要, 缺少会报错.
   7     self.name = name
   8 end
   9
  10 function Pig.prototype:tostring()
  11     return self.name
  12 end
  13
  14 local bacon = Pig:new("Bacon") -- new pig named Bacon
  15
  16 print(bacon) -- should print "Bacon", cause that's its name.

这个 :init(...) 方法在 AceOO-2.0 中代表构造方法. 在其中, 第一行必须先调用父类的 init 方法, 可以任意传递适当的参数给他. 如果你传递了参数, 父类的构造函数将不会被自动调用.

当类实例化的时候构造函数将被调用. (调用 :new(...)的时候). :new(...) 所有的参数(最多20个)将被传递到 :init(...)


静态方法 vs. 实例方法静态方法是本类所特定的, 子类并不继承他们. 实例方法属于类的实例(即对象)子类将继承他们.

切换行号显示    1 local AceOO = AceLibrary("AceOO-2.0")
   2
   3 local Box = AceOO.Class()
   4 Box.numBoxes = 0
   5
   6 function Box:GetNumBoxes()
   7     return self.numBoxes
   8 end
   9
  10 function Box.prototype:init()
  11     Box.super.prototype.init(self)
  12     
  13     Box.numBoxes = Box.numBoxes + 1
  14 end
  15
  16 function Box.prototype:Shake()
  17     print("You hear something crunch")
  18 end
  19
  20 local blueBox = Box:new()
  21 local redBox = Box:new()
  22 print(Box:GetNumBoxes()) -- 2
  23
  24 local Crate = AceOO.Class(Box)
  25 Crate.numCrates = 0
  26
  27 function Crate:GetNumCrates()
  28     return Crate.numCrates
  29 end
  30
  31 function Crate.prototype:init()
  32     Crate.super.prototype.init(self) -- 调用 Box 的构造函数
  33     
  34     Crate.numCrates = Crate.numCrates + 1
  35 end
  36
  37 local greenCrate = Crate:new()
  38 local blackCrate = Crate:new()
  39 print(Box:GetNumBoxes()) -- 4
  40 print(Crate:GetNumCrates()) -- 2
  41 -- 注意: Crate 没有 a :GetNumBoxes() 这样的方法
  42 blackCrate:Shake() -- You hear something crunch.

所有的 crates 都是 boxes, 总共有 4个 boxes. 因为 crates 是 boxes 所以你也可以shake crates. 静态方法class本身中声明, 而实例方法需要在 class 的 prototype 中声明.


接口接口定义了对象或类的特定契约.

切换行号显示    1 local AceOO = AceLibrary("AceOO-2.0")
   2
   3 local ISpeakable = AceOO.Interface { Speak = "function" }
   4 -- 声明一个只包含 Speak 方法的接口.
   5
   6 local Dog = AceOO.Class(ISpeakable)
   7
   8 function Dog.prototype:Speak()
   9     return "Bark!"
  10 end
  11
  12 local Cat = AceOO.Class(ISpeakable)
  13
  14 function Cat.prototype:Speak()
  15     return "Meow!"
  16 end
  17
  18 local fluffy = Dog:new()
  19 local mrPants = Cat:new()
  20 assert(fluffy:Speak() == "Bark!")
  21 assert(mrPants:Speak() == "Meow!")
  22
  23 print(not AceOO.inherits(Cat, Dog)) -- true
  24 print(not AceOO.inherits(Dog, Cat)) -- true
  25 print(AceOO.inherits(Cat, ISpeakable)) -- true
  26 print(AceOO.inherits(Dog, ISpeakable)) -- true
  27
  28 -- 如果 Cat 或 Dog 没有实现 speak 方法, 将会抛出一个异常.
  29 -- 一个好的建议是将所有的数据定义放在你的接口定义前, 如下.
  30
  31 local AceOO = AceLibrary("AceOO-2.0")
  32
  33 local Dog = AceOO.Class()
  34
  35 Dog.prototype.happiness = 5
  36
  37 function Dog:Hug()
  38     self.happiness = self.happiness + 1
  39 end
  40
  41 local Cat = AceOO.Class()
  42
  43 function Cat:Hug()
  44     print("Purr")
  45 end
  46
  47 local muffin = Dog:new()
  48 local mephistophiles = Cat:new()
  49 muffin:Hug()
  50 mephistophiles:Hug() -- "Purr"
  51
  52 print(not AceOO.inherits(Cat, Dog)) -- true
  53 print(not AceOO.inherits(Dog, Cat)) -- true
  54
  55 local IHuggable = AceOO.Interface { Hug = "function" }
  56 -- 声明一个新接口, 包含 Hug 方法.
  57
  58 print(AceOO.inherits(Cat, IHuggable)) -- true
  59 print(AceOO.inherits(Dog, IHuggable)) -- true

Cat 和 Dog 均继承自 IHuggable 接口, 因此上面的测试通过.


MixinsMixins(混入)提供了一种多继承的方式, 同时没有一些多继承所带来的问题, 如菱形继承(译注, 是指在多继承树中包含了同名的祖先而引发的问题).

切换行号显示    1 local AceOO = AceLibrary("AceOO-2.0")
   2
   3 local Artist = AceOO.Mixin { "Paint", "Sculpt" } -- Artist 混入了 Paint 和 Sculpt 方法.
   4
   5 function Artist:Paint()
   6     print(string.format("%s paints a beautiful picture", self))
   7 end
   8  
   9 function Artist:Sculpt()
  10     print(string.format("%s sculpts a delightful statue", self))
  11 end
  12
  13 local Scientist = AceOO.Mixin { "Think" } -- Scientist 混入了Think 方法
  14
  15 function Scientist:Think()
  16     print(string.format("%s thinks about life", self))
  17 end
  18
  19 local Inventor = AceOO.Mixin { "Invent" } -- Inventor 混入了 Invent 方法
  20
  21 function Inventor:Invent()
  22     print(string.format("%s invents a cool device", self))
  23 end
  24
  25 local GreatPerson = AceOO.Class(Artist, Scientist, Inventor) -- 一个伟人将具备Artist, Scientist, Inventor 的所有的优良品德.
  26
  27 function GreatPerson.prototype:init(name)
  28     GreatPerson.super.prototype.init(self)
  29     self.name = name
  30 end
  31
  32 function GreatPerson.prototype:ToString()
  33     return self.name
  34 end
  35
  36 local daVinci = GreatPerson:new("Leonardo da Vinci")
  37 daVinci:Think()
  38 daVinci:Invent()
  39 daVinci:Paint()
  40 daVinci:Sculpt()

daVinci(应该是本文的作者)具备很多 cool 特性  


Metamethods如果你声明了一个使用了以下名字的方法, 将会对应lua的metamethod.

切换行号显示    1 --这里是一些lua metamethod:
   2 self:ToString() -- tostring(self)
   3 self:Add(other) -- self + other
   4 self:Subtract(other) -- self - other
   5 self:Multiply(other) -- self * other
   6 self:Divide(other) -- self / other
   7 self:Exponent(other) -- self ^ other
   8 self:Concatenate(other) -- self .. other
   9 self:UnaryNegation() -- -self
  10 self:Equals(other) -- self == other
  11 self:IsLessThan(other) -- self < other
  12 self:IsLessThanOrEqualTo(other) -- self <= other
  13 self:CompareTo(other) -- (self.value - other.value)

There is no :IsGreaterThan(other) or :IsGreaterThanOrEqualTo(other), since not (self < other) == self >= other and not (self <= other) == self > other.

Also, :IsLessThanOrEqualTo(other) is optional if you have :IsLessThan(other), since not (other < self) == self <= other.

Also, if you have :CompareTo(other) available, it can replace :Equals(other), :IsLessThan(other), and :IsLessThanOrEqualTo(other). self:CompareTo(other) == 0 implies to self == other. For < 0, self < other. For > 0, self > other.

切换行号显示    1 local AceOO = AceLibrary("AceOO-2.0")
   2
   3 local Number = AceOO.Class()
   4
   5 function Number.prototype:init(value)
   6     Number.super.prototype.init(self)
   7     
   8     self.value = value
   9 end
  10
  11 function Number.prototype:ToString()
  12     return "Number(" .. self.value .. ")"
  13 end
  14
  15 function Number.prototype:Add(other)
  16     return Number:new(self.value + other.value)
  17 end
  18
  19 function Number.prototype:Equals(other)
  20     return self.value == other.value
  21 end
  22
  23 print(Number:new(1) + Number:new(2)) -- "Number(3)"

TOP

WelcomeHome - 你的第一个ACE2插件译者: leobluewing
原文发表于:WelcomeHome_-_Your_first_Ace2_Addon


本文的toc文件表明的是用于2.0版本,由于CWOW在本文翻译时还是1.2版本,所以请大家在实验的时候将toc文件的第一行改为:

## Interface: 12000
并且钩选加载过期插件,文章介绍中toc文件均未修改,最后源代码已经改成12000。


目录

WelcomeHome - 你的第一个ACE2插件
介绍
开始
加入ACE库
说hello
响应事件
不重起游戏进行插件重载
使用WOW_API
斜杠命令和注册信息
让你的信息更显著一点
保存你的设置
本地化
加入AceLocale-2.2
绑定本地文件
在插件中使用本地化文件
结论
代码
WelcomeHome.toc
Core.lua
Locale-enUS.lua

介绍看这篇文章前你一定已经打算提高一个层次了,也就是说你希望从一个“玩家”变成一个“开发者”。但是你从哪里开始着手呢? 在网上,适合于初级开发者的资料实在是不多,所以,很可惜的是,很多“开发者”在他们还没明白addon到底是怎么一回事情的时候,他们就已经对不停的从一个插件里面拷贝代码到自己的插件这件事情感到厌倦,以至于放弃了“ 开发”。
于是,这份指南的目的就是向你们介绍如何一步一步的来完成一个叫做WelcomeHome的插件的开发,当然,它是基于ACE2库的。这个插件的功能是当你到达你的炉石设置的家的时候,系统自动的给你发送问候语,并且,这个问候语是可以自己设置的。
当你开始这一切的时候,我假设你对一些脚本语言比较熟悉(例如ruby,js等等)当然,lua知识也是不可少的,另外你还需要了解WOW API。
好了,让我们开始吧。


开始因为这是一份基于ace2的插件开发指南,所以我一开始要象你介绍如何在游戏里载入一个最简单的插件。所有的插件都是安放在\Interface\Addons文件夹下的,并且所有的插件都要安放在自己的文件夹下.所以一开始我们就要在addons下建立一个新的,名为WelcomeHome的文件夹。当WOW启动的时候,它会去addons文件夹下寻找所有的子文件夹,然后在子文件夹中寻找一个toc(table of contents)文件,这个文件记录了该插件要用到的所有文件。而且,这个toc文件的文件名和子文件夹要相同,拿我们这个插件为例,它就叫WelcomeHome.toc。
接下来,我们就来创建一个最简单的toc文件。格式如下:

## Interface: 20000
## Title: Welcome Home
## Notes: Displays a welcome message when you get to your home zone.
## Author: Your Name Here
## Version: 0.1
## X-Category: Interface Enhancements

Core.lua
以上这些就是最基本的信息,比如Interface: 20000就代表了版本号等等,其中X-Category属性你要使用一个ace推荐列表中的选项。 另外,在toc文件中,你还可以包括很多其他的信息。接着,你需要在子文件夹中建一个Core.lua的文件(空的就行)。然后你启动WOW就会在插件列表中发现WelcomeHome这个插件。
OK! 我们这不是建立了一个插件了吗? 虽然它做不了任何事情,但好的开端是成功的一半,不是吗?


加入ACE库接下来,我们要做的是加入ACE2库,因为我们要学习的是如何在ACE2上进行开发。ACE2库使用了“植入库”的概念,它让开发人员不需要把一些公用的文件拷来拷去,而只需要把它们放在一个统一的地方就好了。(类似于头文件以及java中的import概念)。这意味着你需要下载那些我们写的公用的库文件,你可以从我们的SVN上来下载最新的版本放到本地。在下载完后,在你的插件目录中新建一个文件夹叫Libs,并将下载来的文件解压到Libs中,然后,除了AceAddon-2.0 ,AceConsole-2.0 ,AceDB-2.0 ,AceEvent-2.0,AceLibrary ,AceOO-2.0 这6个文件夹以外,其他的全部删除!因为在这个教程里,我们只需要用到这6个文件。当你掌握了更多的知识的时候,把其他文件添加回来吧。

做完这一切后,我想你的树状显示图应该是下面这样的。

WelcomeHome

Libs
AceAddon-2.0

AceAddon-2.0.lua

AceConsole-2.0

AceConsole-2.0.lua

AceDB-2.0
AceDB-2.0.lua
AceEvent-2.0

AceEvent-2.0.lua

AceLibrary

AceLibrary.lua

AceOO-2.0
AceOO-2.0.lua
WelcomeHome.toc Core.lua

好了,现在你已经有了ACE2库了,唯一要做的就是把这些库的位置告诉你的插件,以便你的插件能够找到它们,所以我们又要修改toc文件了!改成如下格式:

## Interface: 20000
## Title: Welcome Home
## Notes: Displays a welcome message when you get to your home zone.
## Author: Your Name Here
## Version: 0.1
## OptionalDeps: Ace2
## SavedVariables: WelcomeHomeDB
## SavedVariablesPerCharacter: WelcomeHomeDBPC
## X-Category: Interface Enhancements

Libs\AceLibrary\AceLibrary.lua
Libs\AceOO-2.0\AceOO-2.0.lua
Libs\AceAddon-2.0\AceAddon-2.0.lua
Libs\AceDB-2.0\AceDB-2.0.lua
Libs\AceConsole-2.0\AceConsole-2.0.lua
Libs\AceEvent-2.0\AceEvent-2.0.lua

Core.lua
将这些库列在Core.lua之前是为了保证他们能先被加载。在这个toc文件中,我加入了一些目前还用不到的信息,比如SavedVariables,但是,相信我,最终一定会用到的。


说hello第三步比起前面两步来说有点难度了,现在,用任何一个文本编辑器打开你的Core.lua文件(译者推荐:Scite),然后敲入以下的代码:

切换行号显示    1 WelcomeHome = AceLibrary("AceAddon-2.0"):new("AceConsole-2.0")
   2
   3 function WelcomeHome:OnInitialize()
   4     -- 当插件载入时执行
   5 end
   6
   7 function WelcomeHome:OnEnable()
   8     -- 当插件打开时执行
   9 end
  10
  11 function WelcomeHome:OnDisable()
  12     -- 当插件关闭时执行
  13 end

这是一个基于ACE2插件的基本结构,第一句话建立了一个AceAddon类的实例,因为我们需要在聊天窗口输出语句和接受斜杠命令(比如:/XXX)所以在建立实例的时候我混合了AceConsole-2.0库. AceConsole-2.0库会给我们提供打印函数。
混入是在很多面向对象语言里都有的概念,使用混入可以使你在类里使用其他类的方法。(译者注:类似与java里的多接口继承) 接下来的两个是重写的方法,OnEnable方法只有在插件被打开的时候才执行,OnDisable方法在插件被关闭的时候执行。(你可以用/ace命令来打开和关闭基于ACE的插件)你需要知道,当整个WOW的UI被载入时候,如果插件是打开的,那么最先被执行的是OnEnable函数。所以,你经常要选择在OnInitialize和OnEnable到底是重写哪一个函数。一般来说,你应该为那些不需要在打开和关闭的时候要执行的事件来重写OnInitialize函数。另外一个重要的方面是,你要根据你接下来需要的东西以及何时这些东西能够被准备好来选择你要重写的函数。下面为了演示插件被载入了,我们要这个插件在聊天窗口中打印出"Hello World!"来。为了实现这个,我们需要在OnEnable函数里加一行代码:

切换行号显示    1 function WelcomeHome:OnEnable()
   2     self:Print("Hello World!")
   3 end

好了,然后重新启动你的wow,一旦你登入了,你要赶快把聊天窗口翻上去查看是否有输出过什么东西。好了,你现在看着那句“Hello World”,是不是感到很骄傲呢?
在我们走的更远之前,把OnEnable函数里的这句话删掉吧。仅仅因为需要知道插件是否被载入而在聊天窗口输出一行话是很不良好的编写风格。已经有很多别的插件能做这个功能了并且你可以使用/ace list命令来得知哪些基于ACE插件被加载了。而且你也可以删除OnInitialized 和OnDisable 方法了,因为我们不会再用到这两个方法了。


响应事件恩,前面我说过了,当你回到“家”的时候,这个插件会亲切的问候你一句。对,我们就是要实现这个功能。可是,插件怎么会知道我们到了家呢?这是因为当玩家进入一个新的地方的时候系统会发出一个ZONE_CHANGED事件,我们所需要做的就是响应这个ZONE_CHANGED事件。
我肯定你会这么问自己:“事件?这是什么鬼东西?”。这个概念和很多其他的程序语言环境类似,那就是说,WOW是事件驱动的。在wow里,当有事情发生时,就会产生一个事件信息,然后你就可以捕捉这个信息从而触发你的事件处理代码。事实上,如果没有事件,你的插件就象一只无头苍蝇,它不知道要去做什么,也不知道什么时候去做。也就是说,你的插件所做的事情都是在响应事件。
BLZ给我们列出了所有的事件,你可以看见,ZONE_CHANGED正是其中之一。让我们对Core.lua文件做些改动来使它能响应这个事件吧。 在我们开始改代码前,我们需要我们的插件能提供响应事件的支持,你猜到了吗?是的!我们又要混入另外一个库了!我们要改写Core.lua的第一句话了,因为我们需要混合AceEvent-2.0库来做支持。改写如下:

切换行号显示    1 WelcomeHome = AceLibrary("AceAddon-2.0"):new("AceConsole-2.0", "AceEvent-2.0")

做完上面那步,我们就可以使用RegisterEvent这个方法来表明我们要接受哪些事件。因为我们要接收ZONE_CHANGED这个事件,所以我们要这么改写OnEnable函数。

切换行号显示    1 function WelcomeHome:OnEnable()
   2     -- Called when the addon is enabled
   3     self:RegisterEvent("ZONE_CHANGED")
   4 end

然后我们要写一个事件处理方法来处理这个事件,我们在Core.lua代码里做如下添加:

切换行号显示    1 function WelcomeHome:ZONE_CHANGED()
   2     self:Print("You have changed zones!")
   3 end

你也许会想,我们应该在OnDisable函数里取消所有的事件监听,可是,不需要。因为AceEvent-2.0已经帮我们都做了。好了,重启游戏,控制你的人物去一个新的区域,你应该会看见你的聊天窗口会打印出“You have changed zones!”这句话。


不重起游戏进行插件重载(译者按:知道/console reloadui 的人可以跳过这一章了)
好了,在我们继续前进之前,我要教你些小技巧,你应该会觉得方便的。

一遍一遍的重启游戏不烦么?? 烦啊,我也烦,所以,现在教你个不用重启的方法。

进入游戏,别关它,最小化然后打开文本编辑器我们来改改代码,改成下面那样:


切换行号显示    1 function WelcomeHome:ZONE_CHANGED()
   2     self:Print("This is a different message!")
   3 end

好了,回到游戏,去试一下,打印出什么了?e...T_T还是原来那句。

为什么呢?因为WOW不会因为文件修改而去动态载入UI,所以,我们需要一个新的命令---/script ReloadUI() 它会为我们重载所有的插件。

其实,很多人会说/console reloadui也可以做同样的事情,是的,我承认,可是我遇见过一次/console reloadui这个命令没起作用,所以我以后就一直用/script ReloadUI()这个命令了。

好了,现在不用重启了。:)


使用WOW_API我们现在已经有了一个可以在地点变换的时候执行的函数了,可是我们知道玩家到底在哪个地方吗?他的炉石又在哪呢?

让我们返回WOW API页面去找Character Functions,我们会发现第二个问题的答案,是的,就是GetBindLocation这个函数,它会返回你的炉石所绑的地方。

接下来我们要找是否有函数能返回我们到底在哪,好吧,我们可以在Location Function里找到这个函数,就是GetSubZoneText,它会返回你当前所在的地方。

我们只要比较这两个函数的返回值就可以很轻松的知道我们到底是不是回到炉石的地方了。 所以,函数改为以下:

切换行号显示    1 function WelcomeHome:ZONE_CHANGED()
   2     if GetBindLocation() == GetSubZoneText() then
   3         self:Print("Welcome Home!")
   4     end
   5 end

yes! 我们做到了开头我们提出的要求!重载一下UI并且测试一下你的成果吧。


斜杠命令和注册信息但是除了上面那些,我们还可以做很多有趣的东西。让我们开始吧!

首先,我们先来让这个插件支持斜杠命令吧,这不是很酷吗?我们需要在Croe.lua文件里先初始化一个table类型,并且要让插件知道我们想要它对哪些命令有反应,代码做如下调整:

切换行号显示    1 local options = {
   2     type='group',
   3     args = {}
   4 }
   5 WelcomeHome = AceLibrary("AceAddon-2.0"):new("AceConsole-2.0", "AceEvent-2.0")
   6 WelcomeHome:RegisterChatCommand({"/welcomehome", "/wh"}, options)

好了,现在这个table是空的所以我们还不能支持什么命令。

在重载UI之后,你敲入/welcomehome或者/wh后,你只会看到一些帮助信息。比如这个插件的名字,描述,以及提供哪些附加命令,现在你可以发现只有一个about附加命令,你可以输入/wh about来看一下这个about附加命令是干什么用的。

好,现在让我们将options丰富一下,来丰富我们的斜杠附加命令。代码如下:

切换行号显示    1 local options = {
   2     type='group',
   3     args = {
   4         msg = {
   5             type = 'text',
   6             name = 'msg',
   7             desc = 'The message text to be displayed',
   8             usage = "<Your message here>",
   9             get = "GetMessage",
  10             set = "SetMessage",
  11         },
  12     },
  13 }

这样之后,我们就建立了第一个附加斜杠命令叫做msg,它带有一个text类型的参数,并且可以用GetMessage和SetMessage这两个方法来获得和设值,在后面完成后,你可以用/wh msg <message> 来调用它,现在让我们来写这两个函数,代码如下

切换行号显示    1 function WelcomeHome:GetMessage()
   2     return self.message
   3 end
   4
   5 function WelcomeHome:SetMessage(newValue)
   6     self.message = newValue
   7 end
   8
   9 WelcomeHome.message = "Welcome Home!" --默认的初始值

好,接下来重载UI,并且打/wh看看吧,是不是多了一个msg的附加命令?

然后,我们可以通过/wh msg <message>这个格式来给它随意赋值了。

最后,我们只要改写ZONE_CHANGED()函数就可以让他输出我们想要输出的值。代码如下:

切换行号显示    1 function WelcomeHome:ZONE_CHANGED()
   2     if GetBindLocation() == GetRealZoneText() then
   3         self:Print(self.message)
   4     end
   5 end

好了,去四周随便玩玩吧~~看看你的成果。


让你的信息更显著一点现在,我们要做的就是让这个提示信息更加显著一点了,记得那些经常在屏幕中间出现的小白字吗?? 比如说什么怒气不足啊,你背对着目标啊什么的,好了,现在我们就是要让我们的信息也出现在那里,还是一样,改代码吧。如下:

现在开始,我将不解释代码了,我希望你们能自己看懂这些代码了.

切换行号显示    1 local options = {
   2     type='group',
   3     args = {
   4          msg = {
   5             type = 'text',
   6             name = 'Message',
   7             desc = 'The message text to be displayed',
   8             get = "GetMessage",
   9             set = "SetMessage",
  10             usage = "<Your message here>",
  11         },
  12         showInChat = {
  13             type = 'toggle',
  14             name = 'Show in Chat',
  15             desc = 'Toggles the display of the message in the chat window',
  16             get = "IsShowInChat",
  17             set = "ToggleShowInChat",
  18         },
  19         showOnScreen = {
  20             type = 'toggle',
  21             name = 'Show on Screen',
  22             desc = 'Toggles the display of the message on the screen',
  23             get = "IsShowOnScreen",
  24             set = "ToggleShowOnScreen"
  25         },
  26     },
  27 }

接着是新的默认值

切换行号显示    1 WelcomeHome.showInChat = false
   2 WelcomeHome.showOnScreen = true

新的get/set方法

切换行号显示    1 function WelcomeHome:IsShowInChat()
   2     return self.showInChat
   3 end
   4
   5 function WelcomeHome:ToggleShowInChat()
   6     self.showInChat = not self.showInChat
   7 end
   8
   9 function WelcomeHome:IsShowOnScreen()
  10     return self.showOnScreen
  11 end
  12
  13 function WelcomeHome:ToggleShowOnScreen()
  14     self.showOnScreen = not self.showOnScreen
  15 end

最后新的显示方法:

切换行号显示    1 function WelcomeHome:ZONE_CHANGED()
   2     if GetBindLocation() == GetSubZoneText() then
   3         if self.showInChat then
   4             self:Print(self.message)
   5         end
   6
   7         if self.showOnScreen then
   8             UIErrorsFrame:AddMessage(self.message, 1.0, 1.0, 1.0, 5.0)
   9         end
  10     end
  11 end

去看看显示在屏幕中央的字吧~  


保存你的设置有一件事情你也许发现了,每次重新加载UI后,你设置的message都重新变回默认的了,的确是这样,那么我们在哪里能保存这些设置呢?

WOW提供了一种方法用来保存这些设置,但是ACE提供了它自己的方法来保存,就是用AceDB-2.0库,我们已经在toc文件里加入了这个库,但是我们在前面并没有将它混入进来,没错,你猜对了,改代码,如下:

切换行号显示    1 WelcomeHome = AceLibrary("AceAddon-2.0"):new("AceEvent-2.0", "AceConsole-2.0", "AceDB-2.0");

接着,我们要修改一下默认代码的设置,我们要将他们保存下来。如下:

切换行号显示    1 WelcomeHome:RegisterDB("WelcomeHomeDB", "WelcomeHomeDBPC")
   2 WelcomeHome:RegisterDefaults("profile", {
   3     message = "Welcome Home!",
   4     showInChat = false,
   5     showOnScreen = true,
   6 } )

在这里,我们使用了profile来保存,你也可以使用char, class, realm or account来保存,请参见AceDB-2.0 API。 自然,我们也要修改get/set方法,让他们直接修改保存的文件,这样,当你重载UI后,数据就不会丢失了。代码如下:

切换行号显示    1 function WelcomeHome:GetMessage()
   2     return self.db.profile.message
   3 end
   4
   5 function WelcomeHome:SetMessage(newValue)
   6     self.db.profile.message = newValue
   7 end
   8
   9 function WelcomeHome:IsShowInChat()
  10     return self.db.profile.showInChat
  11 end
  12
  13 function WelcomeHome:ToggleShowInChat()
  14     self.db.profile.showInChat = not self.db.profile.showInChat
  15 end
  16
  17 function WelcomeHome:IsShowOnScreen()
  18     return self.db.profile.showOnScreen
  19 end
  20
  21 function WelcomeHome:ToggleShowOnScreen()
  22     self.db.profile.showOnScreen = not self.db.profile.showOnScreen
  23 end
  24 And here is the new event handler:
  25
  26 function WelcomeHome:ZONE_CHANGED()
  27     if GetBindLocation() == GetSubZoneText() then
  28         if self.db.profile.showInChat then
  29             self:Print(self.db.profile.message);
  30         end
  31
  32         if self.db.profile.showOnScreen then
  33             UIErrorsFrame:AddMessage(self.db.profile.message, 1.0, 1.0, 1.0, 5.0);
  34         end
  35     end
  36 end

就象你看见的一样,每次我们都是读取保存文件中的值,他们绝对不会因为你的重载UI而变化了。 这个练习其实有一点点无聊,因为你以后做的插件总是在初始化的时候就读取这些变量了,不可能会直接在函数里去读,但是你要明白的整个过程和如何来获得这些值。


本地化有一件事情,是大多数开发者(尤其是英语使用者)会经常忘记的,那就是很多使用他们开发的插件的玩家也许并不在一个英文服务器中。 这就是说,应该有一种简洁的方法能够使他们进行本地化的工作。(当然,那些本地化工作者能够将他们本地化的文件提供给原作者就更好了) 在ACE2中,我们使用AceLocale-2.2库来帮助大家。这个库不象前面能混合使用,所以用起来有点不同。


加入AceLocale-2.2首先,让我们把AceLocale-2.2 library包放到Libs文件夹中,并且我们要先建立一个空的文件来存放这些需要本地化的数据。先建立一个叫做Locale-enUS.lua空文件到你的文件夹下。

这个时候,你的文件夹结构应该是这样的:

WelcomeHome

Libs
AceAddon-2.0

AceAddon-2.0.lua

AceConsole-2.0

AceConsole-2.0.lua

AceDB-2.0
AceDB-2.0.lua
AceEvent-2.0

AceEvent-2.0.lua

AceLibrary

AceLibrary.lua

AceLocale-2.2

AceLocale-2.2.lua

AceOO-2.0
AceOO-2.0.lua
Core.lua Locale-enUS.lua
WelcomeHome.toc

然后,修改一下toc文件,你没忘记吧?

## Interface: 20000
## Title: Welcome Home
## Notes: Displays a welcome message when you get to your home zone.
## Author: Your Name Here
## Version: 0.1
## OptionalDeps: Ace2
## SavedVariables: WelcomeHomeDB
## SavedVariablesPerCharacter: WelcomeHomeDBPC
## X-Category: Interface Enhancements

Libs\AceLibrary\AceLibrary.lua
Libs\AceOO-2.0\AceOO-2.0.lua
Libs\AceAddon-2.0\AceAddon-2.0.lua
Libs\AceDB-2.0\AceDB-2.0.lua
Libs\AceConsole-2.0\AceConsole-2.0.lua
Libs\AceEvent-2.0\AceEvent-2.0.lua
Libs\AceLocale-2.2\AceLocale-2.2.lua

Locale-enUS.lua
Core.lua
注意,Locale-enUS.lua要写在Core.lua之前,这个是很重要的,记住!

这次,因为你修改了toc文件包含的库和文件,使用/reloadui将没用了,你一定要重新登陆一次了,确保插件可以正常运行。


绑定本地文件现在,我们可以在Locale-enUS.lua这个文件中放入那些在英语环境下工作的数据,我们需要在原代码中仔细找一下哪些数据是需要本地化的。 当然,在你以后的写插件的过程中,这个步骤是要第一步做的。

在观察过Core.lua后,我找到了这些数据:

切换行号显示    1 local L = AceLibrary("AceLocale-2.2"):new("WelcomeHome")
   2
   3 L:RegisterTranslations("enUS", function() return {
   4      ["Slash-Commands"] = { "/welcomehome", "/wh" }
   5      
   6      ["Welcome Home!"] = true, -- default message
   7      
   8      ["Message"] = true,
   9      ["Sets the message to be displayed when you get home."] = true,
  10      ["<your message>"] = true, -- usage
  11      
  12      ["Show in Chat"] = true,
  13      ["If set, your message will be displayed in the General chat window."] = true,
  14      
  15      ["Show on Screen"] = true,
  16      ["If set, your message will be displayed on the screen near the top of the game field."] = true,
  17 } end)

这个文件有两部分组成,第一部分我们建立了一个本地化的实例,叫做"WelcomeHome",第二部分我们建立了一个匿名的函数,用来返回需要的字符串,将值设置为true,表示返回的值将和标识名相同,比如我们需要Welcome Home!的时候,将会返回"Welcome Home!"这个字符串。


在插件中使用本地化文件前面我说过,不能使用混入方式来实例化AceLocale,我们要自己实例化一个出来。

切换行号显示    1 local L = AceLibrary("AceLocale-2.2"):new("WelcomeHome")

好了,添加代码吧,把下面的代码添加到Core.lua的顶端,确保在数组建立前初始化。

切换行号显示    1 local L = AceLibrary("AceLocale-2.2"):new("WelcomeHome")
   2 Now we can use this anywhere we need a string. For example the first part of our options table now becomes this:
   3
   4 local opts = {
   5     type='group',
   6     args = {
   7          msg = {
   8             type = 'text',
   9             name = L["Message"],
  10             desc = L["Sets the message to be displayed when you get home."],
  11             usage = L["<your message>"],
  12             get = "GetMessage",
  13             set = "SetMessage",
  14         },
  15         ...etc...
  16     }
  17 }

代码很简单,我就不把多余的写出来了。你可以参照后最后的完整版本。


结论到现在为止,你从一点也不会到自己完成了一个能够本地化的,拥有斜杠命令,能响应事件,能提供交互的插件。相信我,如果你继续努力,你会在插件中发现更多有趣的东西。

最后,希望这个教程能够使你踏上ACE2开发的道路,最终写出属于你自己的插件,祝你好运。


代码
WelcomeHome.toc
## Interface: 12000
## Title: Welcome Home
## Notes: Displays a welcome message when you get to your home zone.
## Author: Your Name Here
## Version: 0.1
## OptionalDeps: Ace2
## SavedVariables: WelcomeHomeDB
## SavedVariablesPerCharacter: WelcomeHomeDBPC
## X-Category: Interface Enhancements

Libs\AceLibrary\AceLibrary.lua
Libs\AceOO-2.0\AceOO-2.0.lua
Libs\AceAddon-2.0\AceAddon-2.0.lua
Libs\AceDB-2.0\AceDB-2.0.lua
Libs\AceConsole-2.0\AceConsole-2.0.lua
Libs\AceEvent-2.0\AceEvent-2.0.lua
Libs\AceLocale-2.2\AceLocale-2.2.lua

Locale-enUS.lua
Core.lua

Core.lua
local L = AceLibrary("AceLocale-2.2"):new("WelcomeHome")

local opts = {
    type='group',
    args = {
         msg = {
            type = 'text',
            name = L["Message"],
            desc = L["Sets the message to be displayed when you get home."],
            usage = L["<your message>"],
            get = "GetMessage",
            set = "SetMessage",
        },
        showInChat = {
            type = 'toggle',
            name = L["Show in Chat"],
            desc = L["If set, your message will be displayed in the General chat window."],
            get = "IsShowInChat",
            set = "ToggleShowInChat",
        },
        showOnScreen = {
            type = 'toggle',
            name = L["Show on Screen"],
            desc = L["If set, your message will be displayed on the screen near the top of the game field."],
            get = "IsShowOnScreen",
            set = "ToggleShowOnScreen"
        },
    },
}

WelcomeHome = AceLibrary("AceAddon-2.0"):new("AceConsole-2.0", "AceEvent-2.0", "AceDB-2.0")
WelcomeHome:RegisterChatCommand(L["Slash-Commands"], opts)

WelcomeHome:RegisterDB("WelcomeHomeDB", "WelcomeHomeDBPC")
WelcomeHome:RegisterDefaults("profile", {
    message = L["Welcome Home!"],
    showInChat = false,
    showOnScreen = true,
} )

function WelcomeHome:OnEnable()
    self:RegisterEvent("ZONE_CHANGED")
end

function WelcomeHome:ZONE_CHANGED()
    if GetBindLocation() == GetSubZoneText() then
        if self.db.profile.showInChat then
            self:Print(self.db.profile.message)
        end

        if self.db.profile.showOnScreen then
            UIErrorsFrame:AddMessage(self.db.profile.message, 1.0, 1.0, 1.0, 5.0)
        end
    end
end

function WelcomeHome:GetMessage()
    return self.db.profile.message
end

function WelcomeHome:SetMessage(newValue)
    self.db.profile.message = newValue
end

function WelcomeHome:IsShowInChat()
    return self.db.profile.showInChat
end

function WelcomeHome:ToggleShowInChat()
    self.db.profile.showInChat = not self.db.profile.showInChat
end

function WelcomeHome:IsShowOnScreen()
    return self.db.profile.showOnScreen
end

function WelcomeHome:ToggleShowOnScreen()
    self.db.profile.showOnScreen = not self.db.profile.showOnScreen
end

Locale-enUS.lua
local L = AceLibrary("AceLocale-2.2"):new("WelcomeHome")

L:RegisterTranslations("enUS", function() return {
     ["Slash-Commands"] = { "/welcomehome", "/wh" }
     
     ["Welcome Home!"] = true, -- default message
     
     ["Message"] = true,
     ["Sets the message to be displayed when you get home."] = true,
     ["<your message>"] = true, -- usage
     
     ["Show in Chat"] = true,
     ["If set, your message will be displayed in the General chat window."] = true,
     
     ["Show on Screen"] = true,
     ["If set, your message will be displayed on the screen near the top of the game field."] = true,
} end)

TOP

ACE2系列插件中文本地化经验和技巧作者: 昏睡墨鱼
版权: 发表于CWDG,本文属于昏睡墨鱼所有,拥有其著作权。




--------------------------------------------------------------------------------


本文通过汉化Skinner的例子,对Ace2插件的汉化技巧做一些简单的介绍。




Ace2插件本地化原理
Ace2插件本地化API我们可以在http://www.wowace.com/wiki/AceLocale-2.2查看Ace2本地化API和使用方法。


本地化的核心Ace2通过建立一个插件属性表(metatable)来管理自己的插件,其中,本地化语言的变量通过AceLocale创建和添加。

做汉化工作,我们不必知道表的结构,和其他的用法,只需要知道以下几点:

用于进行汉化的AceLocale API版本必须一致;

汉化时,汉化的表名称必须与英文原版相同;
本地化变量集必须是默认语言子集。

例子这个是根据语言显示问候语句的例子:


切换行号显示    1 -- Locale-enUS.lua 文件
   2 local L = AceLibrary("AceLocale-2.2"):new("MyAddon")
   3 L:RegisterTranslations("enUS", function()    return {
   4         ["Hello World!”] = true,
   5     }
   6 end)


切换行号显示    1 -- Locale-zhCN.lua 文件
   2 local L = AceLibrary("AceLocale-2.2"):new("MyAddon")
   3 L:RegisterTranslations("zhCN", function()    return {
   4         ["Hello World!”] = "你好!",
   5     }
   6 end)


切换行号显示    1 -- Core.lua 文件
   2 local L = AceLibrary("AceLocale-2.2"):new("MyAddon")
   3 DEFAULT_CHAT_FRAME: AddMessage(L["Hello World!”])
   4
   5 L = AceLibrary("AceLocale-2.2"):new("MyAddon")

AceLocale-2.2是API版本号,MyAddon是插件的本地化变量表名称,两个字符串必须保持不变,才能保证本地化的正确性,否则只能显示默认语言,通常是美国英语(enUS)。而L作为一个特殊处理器,用于对本地化变量进行处理,这个处理器可以也最好只用在局部,我们只要知道其两种用法:

注册本地变量表:

切换行号显示    1 L:RegisterTranslations("zhCN", function() return {["Hello World!] = "你好!", } end)

其中“zhCN”是用于转换字符串的代码页,通过改变它,我们可以制作魔兽世界里任何语言版本的本地化变量表。

return后面跟着的是一个变量表,里面是整个汉化内容的核心部分,因为lua强大的表功能,我们可以将字符串作为变量名,这样,使得我们的翻译变得简单,而且,在Ace2插件中设定了默认语言后,可以将变量设置为boolean值,这就使得我们常看到enUS表中以


切换行号显示    1 ["Hello World!”] = true

代替


切换行号显示    1  ["Hello World!”] = "Hello World!”;

返回本地字符串:

切换行号显示    1 DEFAULT_CHAT_FRAME:L["Hello World!”]

AceLocale返回以紧跟L的字符串为变量名的字符串值,而这个值,以正在运行的魔兽世界语言版本为优先,如果该本地化变量表不存在,则返回默认语言的字符串变量。 事实上,在这里,我们已经可以对已经分出本地化部分的插件进行汉化了。

注意

如果在不同文件中应用处理器(L)处理语言变量表,最好将默认语言文件作为本地化的最后加载文件;
不同文件中采用处理器(L)提取变量,必须在引用之前注册处理器(L);
同一个文件中进行的本地化工作可以不重置处理器(L),变量表语言顺序没有要求;
处理器(L)处理变量表后,不管在哪里引用,只要注册相同的Acelocal版本号和表名称,就可以引用表中任何变量;

同一语种语言文件不能分两次加载。


--------------------------------------------------------------------------------



进阶:分析并提取Ace2插件的可汉化部分我们通过汉化游戏框架美化插件Skinner过程来学习没有本地语种文件插件的汉化方法。


观察文件列表我们打开Skinner.toc文件,查看文件加载列表。


切换行号显示    1 …
   2 Skinner.lua
   3 options.lua
   4 AddonFrames.lua
   5 CharacterFrames1.lua
   6 CharacterFrames2.lua
   7 UIElements1.lua
   8 UIElements2.lua
   9 NPCFrames.lua
  10
  11 ##
  12 ##>> Addon files start here, must be prefixed by SkinMe\
  13 ##
  14 …
  15 下略

我们可以看出,可能含有的信息集中在Skinner.lua和options.lua两个文件内。



提取本地化变量在游戏中呼出Skinner设置菜单,分析options.lua文件,发现


切换行号显示    1 name = "Default Colours",
   2 desc = "Change the default colour settings",

这类变量是设置菜单的描述,其中name是名称,desc是解释,都是我们汉化的部分。注意

type = "group"
变量是Ace2插件的菜单类型,不能汉化。

那么我们提取出变量,按照Ace2的规范应将原始的字符串值变成本地化变量的变量名,用于AceLocale的转化那么就变成:


切换行号显示    1 name = L["Default Colours"],
   2 desc = L["Change the default colour settings"],

因为前面说过,要使用转换器创建并提取本地化变量表,那么在local.lua和options.lua文件前头都加上:


local L = AceLibrary("AceLocale-2.2"):new("Skinner")
现在我们新建一个local.lua文件,用AceLocale-2.2处理"Skinner"变量表,在local.lua文件中,我们需要原始的enUS作为默认语言,而汉化自然就是zhCN了,那么创建两个变量表:


切换行号显示    1 local L = AceLibrary("AceLocale-2.2"):new("Skinner")
   2
   3 L:RegisterTranslations("enUS", function() return {
   4         ["Default Colours"] = true,
   5         ["Change the default colour settings"] = true,
   6 }
   7 end)
   8
   9 L:RegisterTranslations("zhCN", function() return {
  10         ["Default Colours"] = "默认颜色",
  11         ["Change the default colour settings"] = "更改默认颜色设定",
  12 }
  13 end)

这样,我们就已经创建了以原版英文字串为变量的本地化变量表,以此类推,我们找出Skinner.lua和options.lua中所有需汉化的字符串添加到表中,就可以完成本地化变量的提取和汉化工作。


最终完成汉化我们得到了汉化文件后,该文件需要在插件加载次序中优先于插件本身的文件,修改skinner.toc文件为


切换行号显示    1 …
   2 local.lua
   3 skinner.lua
   4 options.lua
   5 …

于是,汉化工作就完成了。

TOP

想念CPGL上论坛的各位同胞!

TOP

CPGL-全国电子体育联盟 ( 京ICP备017102001121300009 ) |联系我们 |Archiver|WAP

Powered by Discuz! 7.2 Licensed © 2001-2009 Comsenz Inc.