Mercurial > wow > reaction
diff classes/Bar.lua @ 157:e77f716af1b7
Pushed state rule logic from State.lua to Bar.lua
author | Flick <flickerstreak@gmail.com> |
---|---|
date | Fri, 12 Jun 2009 21:44:44 +0000 |
parents | 611e6ce08717 |
children | 799c6ea9da7b |
line wrap: on
line diff
--- a/classes/Bar.lua Mon May 18 23:08:34 2009 +0000 +++ b/classes/Bar.lua Fri Jun 12 21:44:44 2009 +0000 @@ -127,6 +127,60 @@ end ]] .. _reaction_refresh +-- For reference +-- the option field names must match the field names of the options table, below +local stateProperties = { + hide = true, + --keybindState = true, TODO: broken + anchorEnable = true, + anchorFrame = true, + anchorPoint = true, + anchorRelPoint = true, + anchorX = true, + anchorY = true, + enableScale = true, + scale = true, + enableAlpha = true, + alpha = true, +} + + +---- Utility functions ---- + +-- traverse a table tree by key list and fetch the result or first nil +local function tfetch(t, ...) + for i = 1, select('#', ...) do + t = t and t[select(i, ...)] + end + return t +end + +-- traverse a table tree by key list and build tree as necessary +local function tbuild(t, ...) + for i = 1, select('#', ...) do + local key = select(i, ...) + if not t[key] then t[key] = { } end + t = t[key] + end + return t +end + +-- return a new array of keys of table 't', sorted by comparing +-- sub-fields (obtained via tfetch) of the table values +local function fieldsort( t, ... ) + local r = { } + for k in pairs(t) do + table.insert(r,k) + end + local path = { ... } + table.sort(r, function(lhs, rhs) + local olhs = tfetch(t[lhs], unpack(path)) or 0 + local orhs = tfetch(t[rhs], unpack(path)) or 0 + return olhs < orhs + end) + return r +end + ---- Bar class ---- local Bar = { } @@ -564,13 +618,29 @@ end end -function Bar:SetStateDriver( rule ) +function Bar:SetStateDriver( states ) + if states then + for state, props in pairs(states) do + self:SetSecureStateData(state, "active_", true) -- make sure there's a 'settings' field for this state + for propname, value in pairs(props) do + if propname == "anchorFrame" then + self:SetFrameRef("anchor-"..state, _G[value]) + elseif propname == "rule" then + -- do nothing + else + self:SetSecureStateData(state, propname, value) + end + end + end + end + local rule = states and self:BuildStateRule(states) if rule then RegisterStateDriver(self:GetFrame(),"reaction",rule) elseif self.statedriver then UnregisterStateDriver(self:GetFrame(),"reaction") end self.statedriver = rule + self:BuildStateKeybinds(states) self:RefreshSecureState() end @@ -589,7 +659,6 @@ self:RefreshSecureState() end --- set a keybind to push a value into "state-reaction" attribute function Bar:SetStateKeybind( key, state ) local f = self:GetFrame() local binds = self.statebinds @@ -604,7 +673,7 @@ end if key then - SetOverrideBinding(f, false, key, state, nil) -- state name is virtual mouse button + SetOverrideBindingClick(f, false, key, f:GetName(), state) -- state name is virtual mouse button end binds[state] = key end @@ -638,3 +707,129 @@ defaultAlpha = self:GetAttribute("defaultAlpha") ]]) end + +---- secure state driver rules ---- + +local playerClass = select(2, UnitClass("player")) +local function ClassFilter(...) + for i = 1, select('#',...) do + if playerClass == select(i,...) then + return false + end + end + return true +end + +local ruleformats = { + stealth = { format = "stealth", filter = ClassFilter("ROGUE","DRUID") }, + nostealth = { format = "nostealth", filter = ClassFilter("ROGUE","DRUID") }, + shadowdance = { format = "bonusbar:2", filter = ClassFilter("ROGUE") }, + shadowform = { format = "form:1", filter = ClassFilter("PRIEST") }, + noshadowform = { format = "noform", filter = ClassFilter("PRIEST") }, + battle = { format = "stance:1", filter = ClassFilter("WARRIOR") }, + defensive = { format = "stance:2", filter = ClassFilter("WARRIOR") }, + berserker = { format = "stance:3", filter = ClassFilter("WARRIOR") }, + caster = { format = "form:0/2/4/5/6", filter = ClassFilter("DRUID") }, + bear = { format = "form:1", filter = ClassFilter("DRUID") }, + cat = { format = "form:3", filter = ClassFilter("DRUID") }, + tree = { format = "form:5", filter = ClassFilter("DRUID") }, + moonkin = { format = "form:5", filter = ClassFilter("DRUID") }, + pet = { format = "pet" }, + nopet = { format = "nopet" }, + harm = { format = "target=target,harm" }, + help = { format = "target=target,help" }, + notarget = { format = "target=target,noexists" }, + focusharm = { format = "target=focus,harm" }, + focushelp = { format = "target=focus,help" }, + nofocus = { format = "target=focus,noexists" }, + raid = { format = "group:raid" }, + party = { format = "group:party" }, + solo = { format = "nogroup" }, + combat = { format = "combat" }, + nocombat = { format = "nocombat" }, + possess = { format = "target=vehicle,noexists,bonusbar:5" }, + vehicle = { format = "target=vehicle,exists,bonusbar:5" }, +} + +function Bar.InitRuleFormats() + local forms = { } + for i = 1, GetNumShapeshiftForms() do + local _, name = GetShapeshiftFormInfo(i) + forms[name] = i; + end + -- use 9 if not found since 9 is never a valid stance/form + local defensive = forms[GetSpellInfo(71)] or 9 + local berserker = forms[GetSpellInfo(2458)] or 9 + local bear = forms[GetSpellInfo(9634)] or forms[GetSpellInfo(5487)] or 9 + local aquatic = forms[GetSpellInfo(1066)] or 9 + local cat = forms[GetSpellInfo(768)] or 9 + local travel = forms[GetSpellInfo(783)] or 9 + local tree = forms[GetSpellInfo(33891)] or 9 + local moonkin = forms[GetSpellInfo(24858)] or 9 + local flight = forms[GetSpellInfo(40120)] or forms[GetSpellInfo(33943)] or 9 + + ruleformats.defensive.format = "stance:"..defensive + ruleformats.berserker.format = "stance:"..berserker + ruleformats.caster.format = format("form:0/%d/%d/%d", aquatic, travel, flight) + ruleformats.bear.format = "form:"..bear + ruleformats.cat.format = "form:"..cat + ruleformats.tree.format = "form:"..tree + ruleformats.moonkin.format = "form:"..moonkin +end + +function Bar:BuildStateRule(states) + -- states is a table : + -- states[statename].rule = { + -- order = #, + -- type = "default"/"custom"/"any"/"all", + -- values = { ... }, -- keys of ruleformats[] + -- custom = "...", + -- } + local rules = { } + local default + + for idx, state in ipairs(fieldsort(states, "rule", "order")) do + local c = states[state].rule + local type = c.type + if type == "default" then + default = default or state + elseif type == "custom" then + if c.custom then + -- strip out all spaces from the custom rule + table.insert(rules, format("%s %s", c.custom:gsub("%s",""), state)) + end + elseif type == "any" or type == "all" then + if c.values then + local clauses = { } + for key, value in pairs(c.values) do + if ruleformats[key] and not ruleformats[key].filter then + table.insert(clauses, ruleformats[key].format) + end + end + if #clauses > 0 then + local sep = (type == "any") and "][" or "," + table.insert(rules, format("[%s] %s", table.concat(clauses,sep), state)) + end + end + end + end + -- make sure that the default, if any, is last + if default then + table.insert(rules, default) + end + return table.concat(rules,";") +end + +function Bar:BuildStateKeybinds( states ) + if states then + for name, state in pairs(states) do + local rule = tfetch(state, "rule") + if rule and rule.type == "keybind" then + self:SetStateKeybind(rule.keybind, name) + else + self:SetStateKeybind(nil, name) -- this clears an existing keybind + end + end + end +end +