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 |