Mercurial > wow > reaction
comparison 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 |
comparison
equal
deleted
inserted
replaced
| 156:611e6ce08717 | 157:e77f716af1b7 |
|---|---|
| 125 else | 125 else |
| 126 state_override = button | 126 state_override = button |
| 127 end | 127 end |
| 128 ]] .. _reaction_refresh | 128 ]] .. _reaction_refresh |
| 129 | 129 |
| 130 -- For reference | |
| 131 -- the option field names must match the field names of the options table, below | |
| 132 local stateProperties = { | |
| 133 hide = true, | |
| 134 --keybindState = true, TODO: broken | |
| 135 anchorEnable = true, | |
| 136 anchorFrame = true, | |
| 137 anchorPoint = true, | |
| 138 anchorRelPoint = true, | |
| 139 anchorX = true, | |
| 140 anchorY = true, | |
| 141 enableScale = true, | |
| 142 scale = true, | |
| 143 enableAlpha = true, | |
| 144 alpha = true, | |
| 145 } | |
| 146 | |
| 147 | |
| 148 ---- Utility functions ---- | |
| 149 | |
| 150 -- traverse a table tree by key list and fetch the result or first nil | |
| 151 local function tfetch(t, ...) | |
| 152 for i = 1, select('#', ...) do | |
| 153 t = t and t[select(i, ...)] | |
| 154 end | |
| 155 return t | |
| 156 end | |
| 157 | |
| 158 -- traverse a table tree by key list and build tree as necessary | |
| 159 local function tbuild(t, ...) | |
| 160 for i = 1, select('#', ...) do | |
| 161 local key = select(i, ...) | |
| 162 if not t[key] then t[key] = { } end | |
| 163 t = t[key] | |
| 164 end | |
| 165 return t | |
| 166 end | |
| 167 | |
| 168 -- return a new array of keys of table 't', sorted by comparing | |
| 169 -- sub-fields (obtained via tfetch) of the table values | |
| 170 local function fieldsort( t, ... ) | |
| 171 local r = { } | |
| 172 for k in pairs(t) do | |
| 173 table.insert(r,k) | |
| 174 end | |
| 175 local path = { ... } | |
| 176 table.sort(r, function(lhs, rhs) | |
| 177 local olhs = tfetch(t[lhs], unpack(path)) or 0 | |
| 178 local orhs = tfetch(t[rhs], unpack(path)) or 0 | |
| 179 return olhs < orhs | |
| 180 end) | |
| 181 return r | |
| 182 end | |
| 183 | |
| 130 | 184 |
| 131 ---- Bar class ---- | 185 ---- Bar class ---- |
| 132 local Bar = { } | 186 local Bar = { } |
| 133 local weak = { __mode = "k" } | 187 local weak = { __mode = "k" } |
| 134 local frameList = { } | 188 local frameList = { } |
| 562 else | 616 else |
| 563 self:GetFrame():SetAttribute("frameref-"..name,nil) | 617 self:GetFrame():SetAttribute("frameref-"..name,nil) |
| 564 end | 618 end |
| 565 end | 619 end |
| 566 | 620 |
| 567 function Bar:SetStateDriver( rule ) | 621 function Bar:SetStateDriver( states ) |
| 622 if states then | |
| 623 for state, props in pairs(states) do | |
| 624 self:SetSecureStateData(state, "active_", true) -- make sure there's a 'settings' field for this state | |
| 625 for propname, value in pairs(props) do | |
| 626 if propname == "anchorFrame" then | |
| 627 self:SetFrameRef("anchor-"..state, _G[value]) | |
| 628 elseif propname == "rule" then | |
| 629 -- do nothing | |
| 630 else | |
| 631 self:SetSecureStateData(state, propname, value) | |
| 632 end | |
| 633 end | |
| 634 end | |
| 635 end | |
| 636 local rule = states and self:BuildStateRule(states) | |
| 568 if rule then | 637 if rule then |
| 569 RegisterStateDriver(self:GetFrame(),"reaction",rule) | 638 RegisterStateDriver(self:GetFrame(),"reaction",rule) |
| 570 elseif self.statedriver then | 639 elseif self.statedriver then |
| 571 UnregisterStateDriver(self:GetFrame(),"reaction") | 640 UnregisterStateDriver(self:GetFrame(),"reaction") |
| 572 end | 641 end |
| 573 self.statedriver = rule | 642 self.statedriver = rule |
| 643 self:BuildStateKeybinds(states) | |
| 574 self:RefreshSecureState() | 644 self:RefreshSecureState() |
| 575 end | 645 end |
| 576 | 646 |
| 577 -- pass unit=nil to set up the unit elsewhere, if you want something more complex | 647 -- pass unit=nil to set up the unit elsewhere, if you want something more complex |
| 578 function Bar:RegisterUnitWatch( unit, enable ) | 648 function Bar:RegisterUnitWatch( unit, enable ) |
| 587 end | 657 end |
| 588 self.unitwatch = enable | 658 self.unitwatch = enable |
| 589 self:RefreshSecureState() | 659 self:RefreshSecureState() |
| 590 end | 660 end |
| 591 | 661 |
| 592 -- set a keybind to push a value into "state-reaction" attribute | |
| 593 function Bar:SetStateKeybind( key, state ) | 662 function Bar:SetStateKeybind( key, state ) |
| 594 local f = self:GetFrame() | 663 local f = self:GetFrame() |
| 595 local binds = self.statebinds | 664 local binds = self.statebinds |
| 596 if not binds then | 665 if not binds then |
| 597 binds = { } | 666 binds = { } |
| 602 if binds[state] then | 671 if binds[state] then |
| 603 SetOverrideBinding(f, false, binds[state], nil) | 672 SetOverrideBinding(f, false, binds[state], nil) |
| 604 end | 673 end |
| 605 | 674 |
| 606 if key then | 675 if key then |
| 607 SetOverrideBinding(f, false, key, state, nil) -- state name is virtual mouse button | 676 SetOverrideBindingClick(f, false, key, f:GetName(), state) -- state name is virtual mouse button |
| 608 end | 677 end |
| 609 binds[state] = key | 678 binds[state] = key |
| 610 end | 679 end |
| 611 | 680 |
| 612 function Bar:GetStateKeybind( state ) | 681 function Bar:GetStateKeybind( state ) |
| 636 f:SetAttribute("defaultAlpha",self:GetAlpha()) | 705 f:SetAttribute("defaultAlpha",self:GetAlpha()) |
| 637 f:Execute([[ | 706 f:Execute([[ |
| 638 defaultAlpha = self:GetAttribute("defaultAlpha") | 707 defaultAlpha = self:GetAttribute("defaultAlpha") |
| 639 ]]) | 708 ]]) |
| 640 end | 709 end |
| 710 | |
| 711 ---- secure state driver rules ---- | |
| 712 | |
| 713 local playerClass = select(2, UnitClass("player")) | |
| 714 local function ClassFilter(...) | |
| 715 for i = 1, select('#',...) do | |
| 716 if playerClass == select(i,...) then | |
| 717 return false | |
| 718 end | |
| 719 end | |
| 720 return true | |
| 721 end | |
| 722 | |
| 723 local ruleformats = { | |
| 724 stealth = { format = "stealth", filter = ClassFilter("ROGUE","DRUID") }, | |
| 725 nostealth = { format = "nostealth", filter = ClassFilter("ROGUE","DRUID") }, | |
| 726 shadowdance = { format = "bonusbar:2", filter = ClassFilter("ROGUE") }, | |
| 727 shadowform = { format = "form:1", filter = ClassFilter("PRIEST") }, | |
| 728 noshadowform = { format = "noform", filter = ClassFilter("PRIEST") }, | |
| 729 battle = { format = "stance:1", filter = ClassFilter("WARRIOR") }, | |
| 730 defensive = { format = "stance:2", filter = ClassFilter("WARRIOR") }, | |
| 731 berserker = { format = "stance:3", filter = ClassFilter("WARRIOR") }, | |
| 732 caster = { format = "form:0/2/4/5/6", filter = ClassFilter("DRUID") }, | |
| 733 bear = { format = "form:1", filter = ClassFilter("DRUID") }, | |
| 734 cat = { format = "form:3", filter = ClassFilter("DRUID") }, | |
| 735 tree = { format = "form:5", filter = ClassFilter("DRUID") }, | |
| 736 moonkin = { format = "form:5", filter = ClassFilter("DRUID") }, | |
| 737 pet = { format = "pet" }, | |
| 738 nopet = { format = "nopet" }, | |
| 739 harm = { format = "target=target,harm" }, | |
| 740 help = { format = "target=target,help" }, | |
| 741 notarget = { format = "target=target,noexists" }, | |
| 742 focusharm = { format = "target=focus,harm" }, | |
| 743 focushelp = { format = "target=focus,help" }, | |
| 744 nofocus = { format = "target=focus,noexists" }, | |
| 745 raid = { format = "group:raid" }, | |
| 746 party = { format = "group:party" }, | |
| 747 solo = { format = "nogroup" }, | |
| 748 combat = { format = "combat" }, | |
| 749 nocombat = { format = "nocombat" }, | |
| 750 possess = { format = "target=vehicle,noexists,bonusbar:5" }, | |
| 751 vehicle = { format = "target=vehicle,exists,bonusbar:5" }, | |
| 752 } | |
| 753 | |
| 754 function Bar.InitRuleFormats() | |
| 755 local forms = { } | |
| 756 for i = 1, GetNumShapeshiftForms() do | |
| 757 local _, name = GetShapeshiftFormInfo(i) | |
| 758 forms[name] = i; | |
| 759 end | |
| 760 -- use 9 if not found since 9 is never a valid stance/form | |
| 761 local defensive = forms[GetSpellInfo(71)] or 9 | |
| 762 local berserker = forms[GetSpellInfo(2458)] or 9 | |
| 763 local bear = forms[GetSpellInfo(9634)] or forms[GetSpellInfo(5487)] or 9 | |
| 764 local aquatic = forms[GetSpellInfo(1066)] or 9 | |
| 765 local cat = forms[GetSpellInfo(768)] or 9 | |
| 766 local travel = forms[GetSpellInfo(783)] or 9 | |
| 767 local tree = forms[GetSpellInfo(33891)] or 9 | |
| 768 local moonkin = forms[GetSpellInfo(24858)] or 9 | |
| 769 local flight = forms[GetSpellInfo(40120)] or forms[GetSpellInfo(33943)] or 9 | |
| 770 | |
| 771 ruleformats.defensive.format = "stance:"..defensive | |
| 772 ruleformats.berserker.format = "stance:"..berserker | |
| 773 ruleformats.caster.format = format("form:0/%d/%d/%d", aquatic, travel, flight) | |
| 774 ruleformats.bear.format = "form:"..bear | |
| 775 ruleformats.cat.format = "form:"..cat | |
| 776 ruleformats.tree.format = "form:"..tree | |
| 777 ruleformats.moonkin.format = "form:"..moonkin | |
| 778 end | |
| 779 | |
| 780 function Bar:BuildStateRule(states) | |
| 781 -- states is a table : | |
| 782 -- states[statename].rule = { | |
| 783 -- order = #, | |
| 784 -- type = "default"/"custom"/"any"/"all", | |
| 785 -- values = { ... }, -- keys of ruleformats[] | |
| 786 -- custom = "...", | |
| 787 -- } | |
| 788 local rules = { } | |
| 789 local default | |
| 790 | |
| 791 for idx, state in ipairs(fieldsort(states, "rule", "order")) do | |
| 792 local c = states[state].rule | |
| 793 local type = c.type | |
| 794 if type == "default" then | |
| 795 default = default or state | |
| 796 elseif type == "custom" then | |
| 797 if c.custom then | |
| 798 -- strip out all spaces from the custom rule | |
| 799 table.insert(rules, format("%s %s", c.custom:gsub("%s",""), state)) | |
| 800 end | |
| 801 elseif type == "any" or type == "all" then | |
| 802 if c.values then | |
| 803 local clauses = { } | |
| 804 for key, value in pairs(c.values) do | |
| 805 if ruleformats[key] and not ruleformats[key].filter then | |
| 806 table.insert(clauses, ruleformats[key].format) | |
| 807 end | |
| 808 end | |
| 809 if #clauses > 0 then | |
| 810 local sep = (type == "any") and "][" or "," | |
| 811 table.insert(rules, format("[%s] %s", table.concat(clauses,sep), state)) | |
| 812 end | |
| 813 end | |
| 814 end | |
| 815 end | |
| 816 -- make sure that the default, if any, is last | |
| 817 if default then | |
| 818 table.insert(rules, default) | |
| 819 end | |
| 820 return table.concat(rules,";") | |
| 821 end | |
| 822 | |
| 823 function Bar:BuildStateKeybinds( states ) | |
| 824 if states then | |
| 825 for name, state in pairs(states) do | |
| 826 local rule = tfetch(state, "rule") | |
| 827 if rule and rule.type == "keybind" then | |
| 828 self:SetStateKeybind(rule.keybind, name) | |
| 829 else | |
| 830 self:SetStateKeybind(nil, name) -- this clears an existing keybind | |
| 831 end | |
| 832 end | |
| 833 end | |
| 834 end | |
| 835 |
