产品展示
  • 适用于19-21款缤智前杠包角防撞条改装汽车雾灯中网外观装饰配件
  • 适用铃木奥拓雨燕羚羊启悦天语汽车同轴喇叭音响6.5寸改装扬声器
  • 上汽荣威350 360 550 RX5 i5汽车同轴音响喇叭前后门改装高重低音
  • 马自达老款马3三汽车内饰改装中控专用配件装饰仪表台遮光避光垫
  • 精选三个装引磁片车载磁吸手机磁性支架配件背带强力3M胶无磁铁片
联系方式

邮箱:admin@aa.com

电话:020-123456789

传真:020-123456789

产品中心

WOW原始UI代码分析【ActionButton】

2024-05-07 19:51:42      点击:971

WOW原始UI代码分析【ActionButton】

 

开场白 :
1 、码分这是码分我分析WOW原始UI代码后,对一些比较关键的码分部分 ,记录下来的码分
2、文章里面如果有什么纰漏 ,码分希望大家毫不客气的码分提出来 ,我一定查究 !码分
3 、码分关于基础问题可以参考
   WOW UI
 《UI制作入门》http://{ 域名已经过期}/netgames/zhuanti/wow/expert/Ui.htm
 《WOW UI定制入门》http://202.113.13.169/site/mybbs/read.php?码分tid=33
 《WOW插件制作指南》http://{ 域名已经过期}/bluefee/archive/2005/04/14/137217.html
 《ADDONS编写普及》http://{ 域名已经过期}/viewthread.php?tid=216755&extra=page%3D1
 《动手写个属于自己的UI》http://{ 域名已经过期}/viewthread.php?tid=149814&fpage=1&highlight=
   XML
 《XML初学进阶》http://{ 域名已经过期}/code/code.asp?id=173/5058
 《XMLSpy 2005 Enterprise Edition》http://{ 域名已经过期}/download_spy_enterprise.html
   Lua
 《Lua5.0参考手册中文版》http://{ 域名已经过期}/bluefee/archive/2005/04/15/138576.html
 《Lua 程序设计初步》http://{ 域名已经过期}/read.php?tid=541871&fpage=1
 《通过例子学习Lua》http://{ 域名已经过期}/bbs/read.php?tid=4999&fpage=2
 《Programming in LUA中文版》http://{ 域名已经过期}/bbs/read.php?tid=4998&fpage=2
 《LuaEdit v2.5》http://{ 域名已经过期}/projects/luaedit/
4、关于如何提取MPQ文件 ,码分如何查看BLP图像 ,码分可以参考
 《WoW Working Link》http://www.fukt.bth.se/%7Ek/wow/stuff/howto-extract-interface-files.txt
 《Win MPQ》http://{ 域名已经过期}/2005-05-16/007R/26857843.html
 《Win BLP Viewer》http://{ 域名已经过期}/game/108/108805.html
5 、码分关于查询资料可以参考
 《WoW Wiki》http://{ 域名已经过期}/Interface_Customization/
 《WOW APIs》http://{ 域名已经过期}/bluefee/archive/2005/04/12/136270.html
 《UI&Macro Forum》http://{ 域名已经过期}/board.aspx?码分fn=wow-interface-customization
6 、如果该问题是码分可以类推 ,或是码分从上下文能马上理解 ,或是从字面就知道含义的我就不罗嗦了
7 、对于相同的问题我一般只分析一次,或是简要的提示一下 ,具体内容可以参考我以前的分析
8 、如果你对自己查找资料的能力感到抱歉,可以E-mail向我询问 ,我会努力帮助你
9、联系方式E-mail: asdic.xxs@{ 域名已经过期}    Blog: { 域名已经过期}/tcxxs     QQ: 35548917
10 、做人要厚道,转载请注明出处!


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


正式开始:
1、版本 :1.7.1 (4659)
2  、这次我写的是ActionbuttonTemplate.xml,ActionBarFrame.xml和ActionButton.lua
   他们是动作按钮的基础UI ,也是大家比较关心的一部分 ,在Interface/FrameXML里面
3 、这次分析用到的名词解释:
 【模板】学过C++语言的人都知道虚函数 ,实际上是一个道理,只是作为子代继承的规范,不可创建实例
 【栅格】一个用来放置图标的格子,默认为无图标时隐藏 ,当然你也可以显示它
 【额外栅格】包括了战士姿态 ,德鲁依外形,盗贼潜行的栅格
 【栅格ID】每个栅格都有对应的ID ,是该栅格的唯一标示
 【图标】每个技能和物品  ,包括交易技能 ,食物,宏等都有一个可以拖动的图标
 【动作键】当把图标放置到栅格上时 ,这个整体就叫动作键
 【额外动作键】当把图标放置到额外栅格上时,这个整体就叫额外动作键
 【动作条】一般12个栅格组成一排或者一列 ,称这个为动作条
 【额外动作条】由12个额外栅格组成一排或者一列,称这个为额外动作条
 【动作条ID】在默认动作条中每个动作条都有页码 ,是这个动作条的唯一标示
  这里解释一下各个动作条的位置 ,主动作条包括1 ,2页
  然后右边1,右边2,右下,左下依次为3到6页 ,栅格ID排列如图
  61-72(左下)49-60(右下)37    25
        (右边2) I     I (右边1)
  1-12(主AB)13-24(2页)  48    36
  这里注意一个问题,为什么有的UI可以实现96个(FB,DUF等)或者更多呢
  这是因为额外栅格的存在,这些UI把空闲的额外栅格加以利用罢了
  调用这些额外栅格的动作键应该用其对应的函数
 【闪动】当执行自动攻击或者自动射击技能时 ,改动作键就处于闪动状态
 【CD】CoolDown的简写
 【信息提示】即GameTooltip ,当鼠标指向某个东西时显示的提示信息
 【光环】包括buff,debuff,物品附加属性等
 【arg1..N】arg为事件触发是传入的参数 ,可以为0到多个
 

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

源代码及注释

-----------------------ActionButtonTemplate.xml


<Ui xmlns="http://{ 域名已经过期}/wow/ui/" xmlns:xsi="http://{ 域名已经过期}/2001/XMLSchema-instance" xsi:schemaLocation="http://{ 域名已经过期}/wow/ui/
..FrameXMLUI.xsd">
 <CheckButton name="ActionButtonTemplate" virtual="true">
 【动作键】【模板】
  <Size>
   <AbsDimension x="36" y="36"/>
  </Size>
  <Layers>
   <Layer level="BACKGROUND">
    <Texture name="$parentIcon"/>
    背景层放置【图标】
   </Layer>
   <Layer level="ARTWORK">
   层的从下到上为 :BackGround,ArtWork,OverLay
    <Texture name="$parentFlash" file="InterfaceButtonsUI-QuickslotRed" hidden="true"/>
    【闪动】效果的纹理
    <FontString name="$parentHotKey" inherits="NumberFontNormalSmallGray" justifyH="RIGHT">
    该【动作键】的快捷键信息
     <Size>
      <AbsDimension x="32" y="10"/>
     </Size>
     <Anchors>
      <Anchor point="TOPLEFT">
       <Offset>
        <AbsDimension x="2" y="-2"/>
       </Offset>
      </Anchor>
     </Anchors>
    </FontString>
    <FontString name="$parentCount" inherits="NumberFontNormal" justifyH="RIGHT">
    该【动作键】数量信息
     <Anchors>
     注意,这里没有Size标签,所以它为自动大小
      <Anchor point="BOTTOMRIGHT">
       <Offset>
        <AbsDimension x="-2" y="2"/>
       </Offset>
      </Anchor>
     </Anchors>
    </FontString>
   </Layer>
   <Layer level="OVERLAY">
    <FontString name="$parentName" inherits="GameFontHighlightSmallOutline">
    该【动作键】名字,例如:宏的名字
     <Size>
      <AbsDimension x="36" y="10"/>
     </Size>
     <Anchors>
      <Anchor point="BOTTOM">
       <Offset>
        <AbsDimension x="0" y="2"/>
       </Offset>
      </Anchor>
     </Anchors>
    </FontString>
   </Layer>
  </Layers>
  <Frames>
   <Model name="$parentCooldown" inherits="CooldownFrameTemplate"/>
   直接应用【CD】模板 ,没有测试过,还望高人赐教,或者等我以后试
  </Frames>
  <NormalTexture name="$parentNormalTexture" file="InterfaceButtonsUI-Quickslot2">
  【图标】边框纹理 ,如果该【栅格】已放置【图标】 ,则显示这个纹理
  若没有放置 ,则显示UI-Quickslot ,它比UI-Quickslot2稍微小点
   <Size>
    <AbsDimension x="64" y="64"/>
   </Size>
   <Anchors>
    <Anchor point="CENTER">
     <Offset>
      <AbsDimension x="0" y="-1"/>
      立体效果,而且UI-Quickslot的显示位置也依赖UI-Quickslot2
      但是【图标】的实际放置位置却并不依赖这个位置 ,由BackGround层决定
     </Offset>
    </Anchor>
   </Anchors>
  </NormalTexture>
  <PushedTexture file="InterfaceButtonsUI-Quickslot-Depress"/>
  点击【动作键】时的纹理
  <HighlightTexture alphaMode="ADD" file="InterfaceButtonsButtonHilight-Square"/>
  鼠标经过【栅格】时的纹理
  <CheckedTexture alphaMode="ADD" file="InterfaceButtonsCheckButtonHilight"/>
  等待施法时【栅格】的纹理 ,例如  :你点击加血法术到选择目标那段时间显示
 </CheckButton>
</Ui>


------------------------ActionBarFrame.xml


<Ui xmlns="http://{ 域名已经过期}/wow/ui/" xmlns:xsi="http://{ 域名已经过期}/2001/XMLSchema-instance" xsi:schemaLocation="http://{ 域名已经过期}/wow/ui/
..FrameXMLUI.xsd">
 <Script file="ActionButton.lua"/>
 <CheckButton name="ActionBarButtonTemplate" inherits="ActionButtonTemplate" virtual="true">
  <Scripts>
   <OnLoad>
    ActionButton_OnLoad();
   </OnLoad>
   <OnEvent>
    ActionButton_OnEvent(event);
   </OnEvent>
   <OnClick>
    if ( IsShiftKeyDown() ) then
    安住shift再点【动作键】,即拖拉【图标】
     PickupAction(ActionButton_GetPagedID(this));
     鼠标吸附该【图标】
    else
    否则执行该【动作键】命令
     MacroFrame_EditMacro();
     UseAction(ActionButton_GetPagedID(this), 1);
     UseAction(slot [,checkCursor] [,onSelf])函数
     slot参数为该【动作键】ID号
     checkCursor参数为是否在其他事件中返回是鼠标点击,0或者1
     onSelf参数为是否对自己施法,0或者1
    end
    ActionButton_UpdateState();
    点击后应该更新【动作键】状态
   </OnClick>
   <OnDragStart>
    if ( LOCK_ACTIONBAR ~= "1" ) then
    如果【动作键】并未设定为锁定
     PickupAction(ActionButton_GetPagedID(this));
     ActionButton_UpdateState();
    end
   </OnDragStart>
   <OnReceiveDrag>
    if ( LOCK_ACTIONBAR ~= "1" ) then
     PlaceAction(ActionButton_GetPagedID(this));
     PlaceAction,放下鼠标上吸附的【动作键】
     注意,这里并不要求一定要放在栅格上,因为你可以摧毁一个【动作键】
     ActionButton_UpdateState();
    end
   </OnReceiveDrag>
   <OnEnter>
    ActionButton_SetTooltip();
    经过【动作键】时 ,显示【信息提示】
   </OnEnter>
   <OnLeave>
    this.updateTooltip = nil;
    GameTooltip:Hide();
   </OnLeave>
   <OnUpdate>
    ActionButton_OnUpdate(arg1);
    更新【闪动】效果
   </OnUpdate>
  </Scripts>
 </CheckButton>
 下面定义了主【动作条】
 <CheckButton name="ActionButton1" inherits="ActionBarButtonTemplate" parent="MainMenuBarArtFrame" id="1">
 MainMenuBarArtFrame,即默认最下面的一条工具栏 ,包括了主【动作条】,人物工具条  ,背包
 但是注意 ,并不包括两旁的2只鹰的纹理
  <Anchors>
   <Anchor point="BOTTOMLEFT">
    <Offset>
     <AbsDimension x="8" y="4"/>
     左下和右下的【动作条】都依据主【动作条】的位置
     【信息提示】和【额外栅格】并不依据这个偏移,但是它会根据左下和右下【动作条】的出现而更改高度
     若仅改变该偏移,则如果该人物有【额外栅格】 ,则人物的主【动作条】将会在原位又出现一个
    </Offset>
   </Anchor>
  </Anchors>
 </CheckButton>
 <CheckButton name="ActionButton2" inherits="ActionBarButtonTemplate" parent="MainMenuBarArtFrame" id="2">
  <Anchors>
   <Anchor point="LEFT" relativeTo="ActionButton1" relativePoint="RIGHT">
    <Offset>
     <AbsDimension x="6" y="0"/>
    </Offset>
   </Anchor>
  </Anchors>
 </CheckButton>
 <CheckButton name="ActionButton3" inherits="ActionBarButtonTemplate" parent="MainMenuBarArtFrame" id="3">
  <Anchors>
   <Anchor point="LEFT" relativeTo="ActionButton2" relativePoint="RIGHT">
    <Offset>
     <AbsDimension x="6" y="0"/>
    </Offset>
   </Anchor>
  </Anchors>
 </CheckButton>
 <CheckButton name="ActionButton4" inherits="ActionBarButtonTemplate" parent="MainMenuBarArtFrame" id="4">
  <Anchors>
   <Anchor point="LEFT" relativeTo="ActionButton3" relativePoint="RIGHT">
    <Offset>
     <AbsDimension x="6" y="0"/>
    </Offset>
   </Anchor>
  </Anchors>
 </CheckButton>
 <CheckButton name="ActionButton5" inherits="ActionBarButtonTemplate" parent="MainMenuBarArtFrame" id="5">
  <Anchors>
   <Anchor point="LEFT" relativeTo="ActionButton4" relativePoint="RIGHT">
    <Offset>
     <AbsDimension x="6" y="0"/>
    </Offset>
   </Anchor>
  </Anchors>
 </CheckButton>
 <CheckButton name="ActionButton6" inherits="ActionBarButtonTemplate" parent="MainMenuBarArtFrame" id="6">
  <Anchors>
   <Anchor point="LEFT" relativeTo="ActionButton5" relativePoint="RIGHT">
    <Offset>
     <AbsDimension x="6" y="0"/>
    </Offset>
   </Anchor>
  </Anchors>
 </CheckButton>
 <CheckButton name="ActionButton7" inherits="ActionBarButtonTemplate" parent="MainMenuBarArtFrame" id="7">
  <Anchors>
   <Anchor point="LEFT" relativeTo="ActionButton6" relativePoint="RIGHT">
    <Offset>
     <AbsDimension x="6" y="0"/>
    </Offset>
   </Anchor>
  </Anchors>
 </CheckButton>
 <CheckButton name="ActionButton8" inherits="ActionBarButtonTemplate" parent="MainMenuBarArtFrame" id="8">
  <Anchors>
   <Anchor point="LEFT" relativeTo="ActionButton7" relativePoint="RIGHT">
    <Offset>
     <AbsDimension x="6" y="0"/>
    </Offset>
   </Anchor>
  </Anchors>
 </CheckButton>
 <CheckButton name="ActionButton9" inherits="ActionBarButtonTemplate" parent="MainMenuBarArtFrame" id="9">
  <Anchors>
   <Anchor point="LEFT" relativeTo="ActionButton8" relativePoint="RIGHT">
    <Offset>
     <AbsDimension x="6" y="0"/>
    </Offset>
   </Anchor>
  </Anchors>
 </CheckButton>
 <CheckButton name="ActionButton10" inherits="ActionBarButtonTemplate" parent="MainMenuBarArtFrame" id="10">
  <Anchors>
   <Anchor point="LEFT" relativeTo="ActionButton9" relativePoint="RIGHT">
    <Offset>
     <AbsDimension x="6" y="0"/>
    </Offset>
   </Anchor>
  </Anchors>
 </CheckButton>
 <CheckButton name="ActionButton11" inherits="ActionBarButtonTemplate" parent="MainMenuBarArtFrame" id="11">
  <Anchors>
   <Anchor point="LEFT" relativeTo="ActionButton10" relativePoint="RIGHT">
    <Offset>
     <AbsDimension x="6" y="0"/>
    </Offset>
   </Anchor>
  </Anchors>
 </CheckButton>
 <CheckButton name="ActionButton12" inherits="ActionBarButtonTemplate" parent="MainMenuBarArtFrame" id="12">
  <Anchors>
   <Anchor point="LEFT" relativeTo="ActionButton11" relativePoint="RIGHT">
    <Offset>
     <AbsDimension x="6" y="0"/>
    </Offset>
   </Anchor>
  </Anchors>
 </CheckButton>
 <Button name="ActionBarUpButton" parent="MainMenuBarArtFrame">
 主【动作条】位置上的上翻页按钮
  <Size>
   <AbsDimension x="32" y="32"/>
  </Size>
  <Anchors>
   <Anchor point="CENTER" relativeTo="MainMenuBarArtFrame" relativePoint="TOPLEFT">
    <Offset>
     <AbsDimension x="522" y="-22"/>
    </Offset>
   </Anchor>
  </Anchors>
  <HitRectInsets>
   <AbsInset left="6" right="6" top="7" bottom="7"/>
   这个一直没有测试成功,还望高人指点迷津
  </HitRectInsets>
  <Scripts>
   <OnLoad>
    MainMenuBarPageNumber:SetText(CURRENT_ACTIONBAR_PAGE);
    CURRENT_ACTIONBAR_PAGE ,当前【动作条ID】
    当你显示了其他【动作条】如 :左下【动作条】,那么它将不会在翻页中重复出现
    this:RegisterEvent("ACTIONBAR_PAGE_CHANGED");
    当主【动作条】的页码改变时触发
   </OnLoad>
   <OnEvent>
    if ( event == "ACTIONBAR_PAGE_CHANGED" ) then
     MainMenuBarPageNumber:SetText(CURRENT_ACTIONBAR_PAGE);
    end
   </OnEvent>
   <OnClick>
    ActionBar_PageUp();
    PlaySound("UChatScrollButton");
    PlaySound(SoundName)  ,播放一个WOW内置的声音
    SoundName为内置参数的名字 ,可以参考下面地址
    http://{ 域名已经过期}/API_PlaySound
    注意,你不要试图在MPQ文件中找到这个名字
   </OnClick>
  </Scripts>
  <NormalTexture file="InterfaceMainMenuBarUI-MainMenu-ScrollUpButton-Up"/>
  <PushedTexture file="InterfaceMainMenuBarUI-MainMenu-ScrollUpButton-Down"/>
  <DisabledTexture file="InterfaceButtonsUI-ScrollBar-ScrollUpButton-Disabled"/>
  被锁定时的纹理 ,未测试成功  ,望高人指点一二
  <HighlightTexture alphaMode="ADD" file="InterfaceMainMenuBarUI-MainMenu-ScrollUpButton-Highlight"/>
 </Button>
 <Button name="ActionBarDownButton" parent="MainMenuBarArtFrame">
  <Size>
   <AbsDimension x="32" y="32"/>
  </Size>
  <Anchors>
   <Anchor point="CENTER" relativeTo="MainMenuBarArtFrame" relativePoint="TOPLEFT">
    <Offset>
     <AbsDimension x="522" y="-42"/>
    </Offset>
   </Anchor>
  </Anchors>
  <HitRectInsets>
   <AbsInset left="6" right="6" top="7" bottom="7"/>
  </HitRectInsets>
  <Scripts>
  上翻中已经注册并处理了事件,这里不重复
   <OnClick>
    ActionBar_PageDown();
    PlaySound("UChatScrollButton");
   </OnClick>
  </Scripts>
  <NormalTexture file="InterfaceMainMenuBarUI-MainMenu-ScrollDownButton-Up"/>
  <PushedTexture file="InterfaceMainMenuBarUI-MainMenu-ScrollDownButton-Down"/>
  <DisabledTexture file="InterfaceButtonsUI-ScrollBar-ScrollDownButton-Disabled"/>
  <HighlightTexture alphaMode="ADD" file="InterfaceMainMenuBarUI-MainMenu-ScrollDownButton-Highlight"/>
 </Button>
</Ui>


------------------------ActionButton.lua

CURRENT_ACTIONBAR_PAGE = 1;
当前【动作条ID】
NUM_ACTIONBAR_PAGES = 6;
【动作条ID】总数
NUM_ACTIONBAR_BUTTONS = 12;
每个【动作条】的【动作键】数
ATTACK_BUTTON_FLASH_TIME = 0.4;
【闪动】效果时间间隔 ,为0.4S

BOTTOMLEFT_ACTIONBAR_PAGE = 6;
初始左下【动作条ID】
BOTTOMRIGHT_ACTIONBAR_PAGE = 5;
初始右下【动作条ID】
LEFT_ACTIONBAR_PAGE = 4;
初始右边2【动作条ID】
RIGHT_ACTIONBAR_PAGE = 3;
初始右边1【动作条ID】

-- Table of actionbar pages and whether they're viewable or not
VIEWABLE_ACTION_BAR_PAGES = { 1, 1, 1, 1, 1, 1};
初始化为每页【动作条】都能够显示 ,0为隐藏

function ActionButtonDown(id)
实现按下【动作键】
 if ( BonusActionBarFrame:IsVisible() ) then
 如果是【额外动作键】
  local button = getglobal("BonusActionButton"..id);
  if ( button:GetButtonState() == "NORMAL" ) then
  若未按下
   button:SetButtonState("PUSHED");
  end
  return;
  该函数用if-else是同样的
 end
 
 local button = getglobal("ActionButton"..id);
 if ( button:GetButtonState() == "NORMAL" ) then
  button:SetButtonState("PUSHED");
 end
end

由上下2个函数可以看出 ,暴雪对【动作键】和【额外动作键】同样对待
这个也是其他UI可以利用【额外栅格】的基础

function ActionButtonUp(id, onSelf)
 if ( BonusActionBarFrame:IsVisible() ) then
  local button = getglobal("BonusActionButton"..id);
  if ( button:GetButtonState() == "PUSHED" ) then
   button:SetButtonState("NORMAL");
   -- Used to save a macro
   MacroFrame_EditMacro();
   UseAction(ActionButton_GetPagedID(button), 0);
   if ( IsCurrentAction(ActionButton_GetPagedID(button)) ) then
   IsCurrentAction,等待施法 ,并不是正在吟唱
    button:SetChecked(1);
    设定该【动作键】正处于等待状态
   else
    button:SetChecked(0);
   end
  end
  return;
 end

 local button = getglobal("ActionButton"..id);
 if ( button:GetButtonState() == "PUSHED" ) then
  button:SetButtonState("NORMAL");
  -- Used to save a macro
  MacroFrame_EditMacro();
  UseAction(ActionButton_GetPagedID(button), 0, onSelf);
  if ( IsCurrentAction(ActionButton_GetPagedID(button)) ) then
   button:SetChecked(1);
  else
   button:SetChecked(0);
  end
 end
end

function ActionBar_PageUp()
 CURRENT_ACTIONBAR_PAGE = CURRENT_ACTIONBAR_PAGE + 1;
 local nextPage;
 for i=CURRENT_ACTIONBAR_PAGE, NUM_ACTIONBAR_PAGES do
  if ( VIEWABLE_ACTION_BAR_PAGES[i] ) then
  如果该页能显示
   nextPage = i;
   break;
  end
 end
 
 if ( not nextPage ) then
 如果没有找到能够显示的下一页
  CURRENT_ACTIONBAR_PAGE = 1;
 else
  CURRENT_ACTIONBAR_PAGE = nextPage;
 end
 ChangeActionBarPage();
 这个函数变换将当主【动作条】变换到CURRENT_ACTIONBAR_PAGE指向的【动作条】
end

function ActionBar_PageDown()
 CURRENT_ACTIONBAR_PAGE = CURRENT_ACTIONBAR_PAGE - 1;
 local prevPage;
 for i=CURRENT_ACTIONBAR_PAGE, 1, -1 do
  if ( VIEWABLE_ACTION_BAR_PAGES[i] ) then
   prevPage = i;
   break;
  end
 end
 
 if ( not prevPage ) then
  for i=NUM_ACTIONBAR_PAGES, 1, -1 do
  把“1”换成“CURRENT_ACTIONBAR_PAGE+1”也是可以的
  把这个for循环对比ActionBar_PageUp的同一地方
  可见,暴雪员工相当的肯定在上翻的时候第1页是可以显示的
  而在下翻的时候显得信心不足,还重复检查了一次NUM_ACTIONBAR_PAGES到CURRENT_ACTIONBAR_PAGE
  这是因为左下  、右下AB的出现只是修改5,6页的可见性 ,并不影响1页的可见性
  所以在下翻的时候需要对1到6页均做可见性检查
  但是,重复检查的区间的确是多余的,估计是暴雪员工偷懒
  因为“1”比“CURRENT_ACTIONBAR_PAGE+1”要好写得多
   if ( VIEWABLE_ACTION_BAR_PAGES[i] ) then
    prevPage = i;
    break;
   end
  end
 end
 CURRENT_ACTIONBAR_PAGE = prevPage;
 ChangeActionBarPage();
end

function ActionButton_OnLoad()
 this.showgrid = 0;
 显示空【栅格】的标志
 this.flashing = 0;
 处于【闪动】的标志
 this.flashtime = 0;
 【闪动】时间间隔计算的中间量
 ActionButton_Update();
 this:RegisterForDrag("LeftButton", "RightButton");
 对this所指向的窗体注册鼠标拖拉行为,参数至少一个,也可以注册多个
 参数为LeftButton,RightButton ,表示使用某个鼠标键执行
 this:RegisterForClicks("LeftButtonUp", "RightButtonUp");
 对this所指向的窗体注册鼠标点击行为,参数至少一个 ,也可以注册多个
 参数为LeftButtonDown ,LeftButtonUp,RightButtonDown,RightButtonUp
 注意,在OnClick标签中传入的arg1参数只返回LeftButton或者RightButton
 this:RegisterEvent("PLAYER_ENTERING_WORLD");
 this:RegisterEvent("UPDATE_BONUS_ACTIONBAR");
 当【额外栅格】更新时触发
 this:RegisterEvent("ACTIONBAR_SHOWGRID");
 当拖拉【图标】时触发 ,arg1为LeftButton或者RightButton
 this:RegisterEvent("ACTIONBAR_HIDEGRID");
 当停止拖拉【图标】时触发
 this:RegisterEvent("ACTIONBAR_PAGE_CHANGED");
 this:RegisterEvent("ACTIONBAR_SLOT_CHANGED");
 当【栅格】内容变更时触发,arg1为变更【栅格ID】
 this:RegisterEvent("ACTIONBAR_UPDATE_STATE");
 当【栅格】状态更新时触发,包括了【CD】和可用性鉴定
 但是不包括自动攻击和自动射击事件
 arg1为鼠标LeftButton ,RightButton ,也可能为nil
 this:RegisterEvent("ACTIONBAR_UPDATE_USABLE");
 当更新【图标】可用性后触发
 this:RegisterEvent("ACTIONBAR_UPDATE_COOLDOWN");
 当更新【CD】后触发
 当【CD】开始的时候,arg1返回使用的鼠标按钮LeftButton或者RightButton
 当【CD】结束的时候,arg1返回nil
 this:RegisterEvent("UPDATE_INVENTORY_ALERTS");
 当变更装备时或者经过一定时间后触发
 this:RegisterEvent("PLAYER_AURAS_CHANGED");
 当玩家【光环】改变时触发 ,包括了【光环】的消失和出现
 注意  ,属性完全相同【光环】重复释放并不能触发该事件
 this:RegisterEvent("PLAYER_TARGET_CHANGED");
 当玩家的目标变更时触发,包括取消和选定目标
 arg1为该目标持续时间 ,单位分钟 ,小数保留3位
 this:RegisterEvent("UNIT_AURASTATE");
 当某单位短时间【光环】改变时触发 ,需进一步测试
 this:RegisterEvent("UNIT_INVENTORY_CHANGED");
 当玩家装备变更时或者当观察玩家装备并发生装备变更时触发
 this:RegisterEvent("CRAFT_SHOW");
 this:RegisterEvent("CRAFT_CLOSE");
 工艺窗口的显示与关闭,arg1为鼠标点击键
 this:RegisterEvent("TRADE_SKILL_SHOW");
 this:RegisterEvent("TRADE_SKILL_CLOSE");
 交易技能制作物品窗口的显示与关闭,arg1为鼠标点击键
 this:RegisterEvent("UNIT_HEALTH");
 当任何一个单位的血量发生变化时触发 ,arg1参数为该单位ID
 player,pet ,target ,mouseover ,party1..4,partypet1..4,raid1..40 ,raidpet1..40,npc
 注意,该事件拥有很高的优先级 ,特别当参数为player时
 this:RegisterEvent("UNIT_MANA");
 当任何一个单位的魔法量发生变化时触发  ,arg1参数为该单位ID
 this:RegisterEvent("UNIT_RAGE");
 当任何一个单位的怒气值发生变化时触发 ,arg1参数为该单位ID
 this:RegisterEvent("UNIT_FOCUS");
 当任何一个单位的焦距值发生变化时触发,arg1参数为该单位ID
 注意,该事件实际上已经废除,因为现在猎人使用MANA,而不是FOCUS
 this:RegisterEvent("UNIT_ENERGY");
 当任何一个单位的能量发生变化时触发 ,arg1参数为该单位ID
 this:RegisterEvent("PLAYER_ENTER_COMBAT");
 当玩家进入自动攻击状态时触发 ,自动射击不包括在内
 注意 ,仅当你使用自动攻击时触发该事件
 使用其他任何技能或者攻击行为都不可触发
 this:RegisterEvent("PLAYER_LEAVE_COMBAT");
 离开自动攻击状态或者死亡时触发
 this:RegisterEvent("PLAYER_COMBO_POINTS");
 当连击点变更时触发 ,arg1总返回player,而并不时连击点数
 this:RegisterEvent("UPDATE_BINDINGS");
 当快捷键更改时触发
 this:RegisterEvent("START_AUTOREPEAT_SPELL");
 当自动射击开始时触发 ,而不是自动攻击
 this:RegisterEvent("STOP_AUTOREPEAT_SPELL");
 离开自动射击状态或者死亡时触发
 ActionButton_UpdateHotkeys();
end

function ActionButton_UpdateHotkeys(actionButtonType)
 if ( not actionButtonType ) then
  actionButtonType = "ACTIONBUTTON";
 end
 local hotkey = getglobal(this:GetName().."HotKey");
 该对象在模板中为Fontstring
 local action = actionButtonType..this:GetID();
 actionButtonType,为该类命令的名字
 this:GetID,得到该命令在该类中的ID号
 注意,这2个字符串组成了最终的命令的名字
 如NUMPAD2,NUMPAD为类型 ,2为ID
 但是有些类型就一个命令无ID,如LEFT
 hotkey:SetText(KeyBindingFrame_GetLocalizedName(GetBindingKey(action), "KEY_"));
 GetBindingKey得到命令的快捷键名字,后面加上KEY_是为了显示命令的字串
 例如:KEY_NUMPAD2就显示为“数字键盘2”
 KeyBindingFrame_GetLocalizedName ,由这个函数在快捷键窗口中显示该命令的快捷键
end

function ActionButton_Update()
 -- Special case code for bonus bar buttons
 -- Prevents the button from updating if the bonusbar is still in an animation transition
 if ( this.isBonus and this.inTransition ) then
  ActionButton_UpdateUsable();
  ActionButton_UpdateCooldown();
  return;
 end
 
 local icon = getglobal(this:GetName().."Icon");
 local buttonCooldown = getglobal(this:GetName().."Cooldown");
 local texture = GetActionTexture(ActionButton_GetPagedID(this));
 if ( texture ) then
  icon:SetTexture(texture);
  icon:Show();
  如果该【栅格】有【图标】,即若为【动作键】则显示
  this.rangeTimer = TOOLTIP_UPDATE_TIME;
  每隔TOOLTIP_UPDATE_TIME事件间隔更新一次距离信息
  TOOLTIP_UPDATE_TIME为0.2S
  this:SetNormalTexture("Interface\Buttons\UI-Quickslot2");
  -- Save texture if the button is a bonus button, will be needed later
  if ( this.isBonus ) then
  判断自己是否为【额外栅格】
   this.texture = texture;
  end
 else
  icon:Hide();
  buttonCooldown:Hide();
  this.rangeTimer = nil;
  this:SetNormalTexture("Interface\Buttons\UI-Quickslot");
  getglobal(this:GetName().."HotKey"):SetVertexColor(0.6, 0.6, 0.6);
 end
 ActionButton_UpdateCount();
 if ( HasAction(ActionButton_GetPagedID(this)) ) then
 判断该【栅格】是否有【图标】,即是否为【动作键】
  this:Show();
  ActionButton_UpdateState();
  ActionButton_UpdateUsable();
  ActionButton_UpdateCooldown();
  ActionButton_UpdateFlash();
 elseif ( this.showgrid == 0 ) then
  this:Hide();
 else
 这里表示 ,当该【栅格】没有【图标】
 但是显示空【栅格】选项开启时  ,不显示公共CD效果
  buttonCooldown:Hide();
 end
 if ( GameTooltip:IsOwned(this) ) then
 判断该【动作键】是否拥有【信息提示】
  ActionButton_SetTooltip();
 else
  this.updateTooltip = nil;
 end

 -- Update Macro Text
 local macroName = getglobal(this:GetName().."Name");
 macroName:SetText(GetActionText(ActionButton_GetPagedID(this)));
 GetActionText返回宏的名字
end

function ActionButton_ShowGrid(button)
 if ( not button ) then
  button = this;
 end
 button.showgrid = button.showgrid+1;
 getglobal(button:GetName().."NormalTexture"):SetVertexColor(1.0, 1.0, 1.0, 0.5);
 SetVertexColor(R,G,B)这个函数需要注意 ,可能学过3D的都知道 ,这个是顶点着色,取值0到1小数
 顶点着色并不是直接设置RGB的数值,而是在原有的RGB数值上乘以顶点着色指定的RGB百分比修正值
 例如:一个色块RGB为50,100 ,30 ,如果你写入SetVertexColor(0.5,0,1) ,结果RGB为25 ,0,30
 button:Show();
end

function ActionButton_HideGrid(button) 
 if ( not button ) then
  button = this;
 end
 button.showgrid = button.showgrid-1;
 if ( button.showgrid == 0 and not HasAction(ActionButton_GetPagedID(button)) ) then
 把这里判断showgrid变量为0和这一对函数对showgrid的操作联系起来看
 就像是用堆栈实现括号配对一样保证了显示和隐藏的规范
  button:Hide();
 end
end

function ActionButton_UpdateState()
 if ( IsCurrentAction(ActionButton_GetPagedID(this)) or IsAutoRepeatAction(ActionButton_GetPagedID(this)) ) then
 IsAutoRepeatAction ,自动射击
 IsAttackAction,自动攻击
  this:SetChecked(1);
 else
  this:SetChecked(0);
 end
end

function ActionButton_UpdateUsable()
注意,这个函数的主体是个技能按钮模板,所以针对的是一个【动作键】
所以 ,当你拖动某个【图标】时 ,其他【图标】并不会跟着更新
 local icon = getglobal(this:GetName().."Icon");
 模板中定义
 local normalTexture = getglobal(this:GetName().."NormalTexture");
 local isUsable, notEnoughMana = IsUsableAction(ActionButton_GetPagedID(this));
 得到当前技能栅格的ID ,这个是所有栅格ID号 ,包括73~96的
 if ( isUsable ) then
 是否在射程,当前在其他游戏规则中是否可用,是否在CD等
  icon:SetVertexColor(1.0, 1.0, 1.0);

  normalTexture:SetVertexColor(1.0, 1.0, 1.0);
 elseif ( notEnoughMana ) then
 是否足够魔法  、怒气、能量
  icon:SetVertexColor(0.5, 0.5, 1.0);
  normalTexture:SetVertexColor(0.5, 0.5, 1.0);
 else
  icon:SetVertexColor(0.4, 0.4, 0.4);
  这个是灰色效果 ,当你拖拉【图标】时,原【栅格】则为这个效果
  normalTexture:SetVertexColor(1.0, 1.0, 1.0);
 end
end

function ActionButton_UpdateCount()
 local text = getglobal(this:GetName().."Count");
 在模板中数量为Fontstring
 if ( IsConsumableAction(ActionButton_GetPagedID(this)) ) then
 判断是否改【栅格】的物品为消费品
  text:SetText(GetActionCount(ActionButton_GetPagedID(this)));
 else
  text:SetText("");
 end
end

function ActionButton_UpdateCooldown()
 local cooldown = getglobal(this:GetName().."Cooldown");
 在模板中该【CD】定义为一个Model
 local start, duration, enable = GetActionCooldown(ActionButton_GetPagedID(this));
 CooldownFrame_SetTimer(cooldown, start, duration, enable);
end

function ActionButton_OnEvent(event)
 if ( event == "ACTIONBAR_SLOT_CHANGED" ) then
  if ( arg1 == -1 or arg1 == ActionButton_GetPagedID(this) ) then
  如果变更的【栅格】不明或者变更的【栅格】为自己则更新
   ActionButton_Update();
  end
  return;
 end
 if ( event == "PLAYER_ENTERING_WORLD" or event == "ACTIONBAR_PAGE_CHANGED" ) then
 总结起来是 ,当游戏环境有大的变化时,更新自己
  ActionButton_Update();
  return;
 end
 if ( event == "UPDATE_BONUS_ACTIONBAR" ) then
  if ( this.isBonus ) then
   ActionButton_Update();
  end
  return;
 end
 if ( event == "ACTIONBAR_SHOWGRID" ) then
  ActionButton_ShowGrid();
  return;
 end
 if ( event == "ACTIONBAR_HIDEGRID" ) then
  ActionButton_HideGrid();
  return;
 end
 if ( event == "UPDATE_BINDINGS" ) then
  ActionButton_UpdateHotkeys();
  return;
 end

 -- All event handlers below this line MUST only be valid when the button is visible
 if ( not this:IsVisible() ) then
 如果该【图标】不可见 ,那么直接返回 ,即下面的所有事件均要求该【图标】可见 ,即应该为一个【动作键】
  return;
 end

 if ( event == "UNIT_HEALTH" or event == "UNIT_MANA" or event == "UNIT_RAGE" or event == "UNIT_FOCUS" or event == "UNIT_ENERGY" ) then
  if ( arg1 == "player" ) then
  如果发生在玩家身上 ,应该判断所有技能的可用性
   ActionButton_UpdateUsable();
  end
 elseif ( event == "PLAYER_TARGET_CHANGED" or event == "PLAYER_AURAS_CHANGED" ) then
  ActionButton_UpdateUsable();
 elseif ( event == "UNIT_AURASTATE" ) then
  if ( arg1 == "player" or arg1 == "target" ) then
   ActionButton_UpdateUsable();
  end
 elseif ( event == "UNIT_INVENTORY_CHANGED" ) then
  if ( arg1 == "player" ) then
   ActionButton_Update();
  end
 elseif ( event == "ACTIONBAR_UPDATE_STATE" ) then
  ActionButton_UpdateState();
 elseif ( event == "ACTIONBAR_UPDATE_USABLE" or event == "UPDATE_INVENTORY_ALERTS" or event == "ACTIONBAR_UPDATE_COOLDOWN" ) then
  ActionButton_UpdateUsable();
  ActionButton_UpdateCooldown();
 elseif ( event == "CRAFT_SHOW" or event == "CRAFT_CLOSE" or event == "TRADE_SKILL_SHOW" or event == "TRADE_SKILL_CLOSE" ) then
  ActionButton_UpdateState();
 elseif ( event == "PLAYER_ENTER_COMBAT" ) then
  if ( IsAttackAction(ActionButton_GetPagedID(this)) ) then
   ActionButton_StartFlash();
  end
 elseif ( event == "PLAYER_LEAVE_COMBAT" ) then
  if ( IsAttackAction(ActionButton_GetPagedID(this)) ) then
   ActionButton_StopFlash();
  end
 elseif ( event == "PLAYER_COMBO_POINTS" ) then
  ActionButton_UpdateUsable();
 elseif ( event == "START_AUTOREPEAT_SPELL" ) then
  if ( IsAutoRepeatAction(ActionButton_GetPagedID(this)) ) then
   ActionButton_StartFlash();
  end
 elseif ( event == "STOP_AUTOREPEAT_SPELL" ) then
  if ( ActionButton_IsFlashing() and not IsAttackAction(ActionButton_GetPagedID(this)) ) then
  如果该技能在【闪动】,并且不是自动攻击
   ActionButton_StopFlash();
  end
 end
end

function ActionButton_SetTooltip()
 if ( GetCVar("UberTooltips") == "1" ) then
 Uber ,乳房 。。 。 。。
 这句应该是判断是否属于一般类型,母类型
 UberTooltips详细信息提示
  GameTooltip_SetDefaultAnchor(GameTooltip, this);
  一般位于屏幕右下角 ,会根据【动作条】的多少自动改变位置
 else
 如果这个【栅格】的【信息提示】不属于默认的形式则
  if ( this:GetParent() == MultiBarBottomRight or this:GetParent() == MultiBarRight or this:GetParent() == MultiBarLeft ) then
  【动作条】MultiBarBottomRight右下 ,MultiBarRight右方,MultiBarLeft左边下
   GameTooltip:SetOwner(this, "ANCHOR_LEFT");
   这里解释下SetOwner函数,GameTooltip:SetOwner(owner, anchor);
   其中owner是参照物 ,anchor是对齐方式,取值如下 :
   ANCHOR_TOPRIGHT 相当于 SetPoint("BOTTOMRIGHT",object,"TOPRIGHT")
   ANCHOR_RIGHT 相当于 SetPoint("BOTTOMLEFT",object,"TOPRIGHT")
   ANCHOR_BOTTOMRIGHT 相当于 SetPoint("TOPLEFT",object,"BOTTOMRIGHT")
   ANCHOR_TOPLEFT 相当于 SetPoint("BOTTOMLEFT",object,"TOPLEFT")
   ANCHOR_LEFT 相当于 SetPoint("BOTTOMRIGHT",object,"TOPLEFT")
   ANCHOR_BOTTOMLEFT 相当于 SetPoint("TOPRIGHT",object,"BOTTOMLEFT")
  else
   GameTooltip:SetOwner(this, "ANCHOR_RIGHT");
  end
 end
 
 if ( GameTooltip:SetAction(ActionButton_GetPagedID(this)) ) then
 SetAction ,返回值为该【信息提示】是否需要实时更新
  this.updateTooltip = TOOLTIP_UPDATE_TIME;
 else
  this.updateTooltip = nil;
 end
end

function ActionButton_OnUpdate(elapsed)
 if ( ActionButton_IsFlashing() ) then
  this.flashtime = this.flashtime - elapsed;
  if ( this.flashtime <= 0 ) then
  flashtime初始为0 ,即第一次flash的时间并不为0.4 ,而是第一个elapsed决定
   local overtime = -this.flashtime;
   overtime,该函数的一个中间量 ,用语变化符号
   if ( overtime >= ATTACK_BUTTON_FLASH_TIME ) then
   这个if为了下面给flashtime更新是不出现负数考虑
   注意,ERROR文本框的文本并不和这里的时间挂钩
    overtime = 0;
   end
   this.flashtime = ATTACK_BUTTON_FLASH_TIME - overtime;
   更新flashtime,使得从第二次开始间隔一个ATTACK_BUTTON_FLASH_TIME

   local flashTexture = getglobal(this:GetName().."Flash");
   if ( flashTexture:IsVisible() ) then
   效果的实现即为反复显示这个flash纹理
    flashTexture:Hide();
   else
    flashTexture:Show();
   end
  end
 end
 
 -- Handle range indicator
 if ( this.rangeTimer ) then
  if ( this.rangeTimer < 0 ) then
  
   local count = getglobal(this:GetName().."HotKey");
   if ( IsActionInRange( ActionButton_GetPagedID(this)) == 0 ) then
   IsActionInRange ,返回指定【动作键】是否在距离之内
   返回nil表示该【栅格】无【图标】 ,或者没有选定目标
   返回0表示不在距离之内,返回1表示在距离之内
   注意 ,如果你没有试图释放这个【动作键】在目标身上 ,它可能总返回1
    count:SetVertexColor(1.0, 0.1, 0.1);
   else
    count:SetVertexColor(0.6, 0.6, 0.6);
   end
   this.rangeTimer = TOOLTIP_UPDATE_TIME;
  else
   this.rangeTimer = this.rangeTimer - elapsed;
  end
 end

 if ( not this.updateTooltip ) then
  return;
 end

 this.updateTooltip = this.updateTooltip - elapsed;
 if ( this.updateTooltip > 0 ) then
  return;
 end

 if ( GameTooltip:IsOwned(this) ) then
  ActionButton_SetTooltip();
 else
  this.updateTooltip = nil;
 end
end

function ActionButton_GetPagedID(button)
 if( button == nil ) then
  message("nil button passed into ActionButton_GetPagedID(), contact Jeff");
  严重错误需要弹出消息框
  return 0;
 end
 if ( button.isBonus and CURRENT_ACTIONBAR_PAGE == 1 ) then
 如果是【额外动作条】并且当前【动作条ID】为1
  local offset = GetBonusBarOffset();
  GetBonusBarOffset ,得到【额外动作条】的偏移量
  返回1到3 ,分别对应1到3号战士姿态 ,或者德鲁依外形  ,或者是盗贼状态
  if ( offset == 0 and BonusActionBarFrame and BonusActionBarFrame.lastBonusBar ) then
  应该是判断当意外失去【额外动作条】定位时 ,定位于最近一次改变的
  注意,如果该职业无【额外动作条】时 ,偏移量也为0
   offset = BonusActionBarFrame.lastBonusBar;
  end
  return (button:GetID() + ((NUM_ACTIONBAR_PAGES + offset - 1) * NUM_ACTIONBAR_BUTTONS));
  注意NUM_ACTIONBAR_PAGES + offset用的是加法,所以我们肯定暴雪偷偷藏了24个【额外栅格】
 elseif ( button:GetParent():GetName() == "MultiBarBottomLeft" ) then
  return (button:GetID() + ((BOTTOMLEFT_ACTIONBAR_PAGE - 1) * NUM_ACTIONBAR_BUTTONS));
 elseif ( button:GetParent():GetName() == "MultiBarBottomRight" ) then
  return (button:GetID() + ((BOTTOMRIGHT_ACTIONBAR_PAGE - 1) * NUM_ACTIONBAR_BUTTONS));
 elseif ( button:GetParent():GetName() == "MultiBarLeft" ) then
  return (button:GetID() + ((LEFT_ACTIONBAR_PAGE - 1) * NUM_ACTIONBAR_BUTTONS));
 elseif ( button:GetParent():GetName() == "MultiBarRight" ) then
  return (button:GetID() + ((RIGHT_ACTIONBAR_PAGE - 1) * NUM_ACTIONBAR_BUTTONS));
 else
  return (button:GetID() + ((CURRENT_ACTIONBAR_PAGE - 1) * NUM_ACTIONBAR_BUTTONS))
 end
end

function ActionButton_UpdateFlash()
 local pagedID = ActionButton_GetPagedID(this);
 if ( (IsAttackAction(pagedID) and IsCurrentAction(pagedID)) or IsAutoRepeatAction(pagedID) ) then
  ActionButton_StartFlash();
 else
  ActionButton_StopFlash();
 end
end

function ActionButton_StartFlash()
 this.flashing = 1;
 this.flashtime = 0;
 ActionButton_UpdateState();
end

function ActionButton_StopFlash()
 this.flashing = 0;
 getglobal(this:GetName().."Flash"):Hide();
 ActionButton_UpdateState();
end

function ActionButton_IsFlashing()
 if ( this.flashing == 1 ) then
  return 1;
 else
  return nil;
 end
end


---------------------总结一下


常量
TOOLTIP_UPDATE_TIME         【信息提示】更新间隔
CURRENT_ACTIONBAR_PAGE        当前【动作条ID】
NUM_ACTIONBAR_PAGES         总页码
NUM_ACTIONBAR_BUTTONS        一个【动作条】的【栅格】数
ATTACK_BUTTON_FLASH_TIME       【闪动】间隔
BOTTOMLEFT_ACTIONBAR_PAGE       左下【动作条ID】
BOTTOMRIGHT_ACTIONBAR_PAGE       右下【动作条ID】
LEFT_ACTIONBAR_PAGE         右边2【动作条ID】
RIGHT_ACTIONBAR_PAGE        右边1【动作条ID】

事件
ACTIONBAR_PAGE_CHANGED        【动作条】翻页
UPDATE_BONUS_ACTIONBAR        【额外动作条】更新
ACTIONBAR_SHOWGRID         显示【栅格】
ACTIONBAR_HIDEGRID         隐藏【栅格】
ACTIONBAR_SLOT_CHANGED        【栅格】内容变更
ACTIONBAR_UPDATE_STATE        【动作键】更新状态
ACTIONBAR_UPDATE_USABLE        【动作键】更新可用性
ACTIONBAR_UPDATE_COOLDOWN       【动作键】更新【CD】
UPDATE_INVENTORY_ALERTS        装备警告
PLAYER_AURAS_CHANGED        【光环】改变
PLAYER_TARGET_CHANGED        目标改变
UNIT_AURASTATE          单位【光环】改变
UNIT_INVENTORY_CHANGED        单位装备改变
CRAFT_SHOW           工艺窗口显示
CRAFT_CLOSE           工艺窗口隐藏
TRADE_SKILL_SHOW         交易技能窗口显示
TRADE_SKILL_CLOSE         交易技能窗口隐藏
UNIT_HEALTH           单位血量改变(优先级极高)
UNIT_MANA           单位魔法改变
UNIT_RAGE           单位怒气改变
UNIT_FOCUS           单位焦距改变(已废除)
UNIT_ENERGY           单位能量改变
PLAYER_ENTER_COMBAT         开始自动攻击
PLAYER_LEAVE_COMBAT         结束自动攻击
PLAYER_COMBO_POINTS         连击点改变
UPDATE_BINDINGS          快捷键更新
START_AUTOREPEAT_SPELL        开始自动射击
STOP_AUTOREPEAT_SPELL        结束自动射击

函数
IsShiftKeyDown          Shift键是否按下
PickupAction          吸附【图标】
PlaceAction           放置【图标】
UseAction           使用【动作键】
GetButtonState          得到【动作键】状态
SetButtonState          设置【动作键】状态
Frame:RegisterForDrag        注册拖拉行为
Frame:RegisterForClicks        注册点击行为
GetBindingKey          得到快捷键
HasAction           【栅格】是否放置了【图标】
Frame:SetVertexColor        顶点色彩修正
IsAutoRepeatAction         是否正在自动射击
IsAttackAction          是否正在自动攻击
IsUsableAction          【动作键】是否可用
IsConsumableAction         是否为消费品
GetActionCooldown         得到【CD】
GetCVar            有待测试
GameTooltip:SetAction        设置【信息提示】
Frame:IsVisible          是否可见
IsActionInRange          是否在距离之内
GetBonusBarOffset         得到【额外动作条】偏移量

累死了。  。 。。。。明天再贴图片和排版彩色

http://{ 域名已经过期}/forumdisplay.php?fid=138

这个帖子我已经贴了图片


《原神》大佬养成系列——迪卢克篇(你不可不知的火系养成)
萨满锁甲:翡翠猎豹!可爱母熊猫绿色幻化