Advertisement
Guest User

Fragment Affdots fix

a guest
Nov 8th, 2015
541
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 59.27 KB | None | 0 0
  1. AffDots = LibStub( "AceAddon-3.0" ):NewAddon("AffDots","AceEvent-3.0")
  2. AffDots.SharedMedia = LibStub("LibSharedMedia-3.0")
  3. local _
  4. local options
  5. local playerGuid, class, spec
  6. local timer, throttle           = 0, 0.1
  7. local dot_damage, targets       = {},{}
  8.  
  9. AffDots.track                           = {}
  10.  
  11. local in_combat                         = false
  12. local colors
  13. local dmg_buff                          = 1
  14.  
  15. AffDots.execute_percent         = 0
  16.  
  17. local corr_id = 172
  18.  
  19. if select(4, GetBuildInfo()) >= 50400 then
  20.         corr_id = 146739
  21. end
  22.  
  23. local corruption = { ["base"] = 18, ["duration"] = 18, ["tick"] = 5.4 }
  24. local agony =      { ["base"] = 24, ["duration"] = 24, ["tick"] = 7.2 }
  25. local unstablea =  { ["base"] = 14, ["duration"] = 14, ["tick"] = 4.2 }
  26. --- Archimonde trinket versions
  27. local fragment_of_the_dark_star = {
  28.     -- normal
  29.     [0] = {
  30.         ["itemVersion"] = "Normal",
  31.         ["not_warforged"] = {
  32.             ["multiplier"] = 21.41,1
  33.         },
  34.  
  35.         ["warforged"] = {
  36.             ["multiplier"] = 22.62,
  37.         }
  38.     },
  39.  
  40.     -- heroic
  41.     [566] = {
  42.         ["itemVersion"] = "Heroic",
  43.         ["not_warforged"] = {
  44.             ["multiplier"] = 24.63,
  45.         },
  46.  
  47.         ["warforged"] = {
  48.             ["multiplier"] = 26.03,
  49.         }
  50.     },
  51.  
  52.     -- mythic
  53.     [567] = {
  54.         ["itemVersion"] = "Mythic",
  55.         ["not_warforged"] = {
  56.             ["multiplier"] = 28.31,
  57.         },
  58.  
  59.         ["warforged"] = {
  60.             ["multiplier"] = 29.92,
  61.         }
  62.     },
  63. }
  64. local spells = {
  65.         corr                    = GetSpellInfo(corr_id),
  66.         agony                   = GetSpellInfo(980),
  67.         ua                      = GetSpellInfo(30108),
  68.         poison                  = GetSpellInfo(93068),
  69.         shadowflame             = GetSpellInfo(47960),
  70.         soulleech               = GetSpellInfo(108366),
  71.         sacpact                 = GetSpellInfo(108416),
  72.         havoc                   = GetSpellInfo(80240),
  73.         backdraft               = GetSpellInfo(117896),
  74.         fluidity                = GetSpellInfo(138002), -- Fluidity +40%
  75.         nutriment               = GetSpellInfo(140741), -- Primal Nutriment +100% +10% per stack
  76.         tricks                  = GetSpellInfo(57934),  -- Tricks of the Trade + 15%
  77.         fearless                = GetSpellInfo(118977), -- Fearless + 60%
  78.         -- twilightWard         = GetSpellInfo(6229), -- test
  79.        
  80.         -- Warlock T16 Bonuses
  81.         destructiveInfluence = GetSpellInfo(145075), --
  82.         fieryWrath           = GetSpellInfo(146043), --
  83.         emberMaster          = GetSpellInfo(145164), --
  84. }
  85.  
  86. local DmgBuffEvents = {
  87.         ["SPELL_AURA_APPLIED"] = 1,
  88.         ["SPELL_AURA_REMOVED"] = 1,
  89.         ["SPELL_AURA_REFRESH"] = 1,
  90.         ["SPELL_AURA_APPLIED_DOSE"] = 1,
  91. }
  92. AffDots.tidyspells = {
  93.         ["Interface\\Icons\\Spell_Shadow_AbominationExplosion"] = { spell =     corr_id,        pandemic =  5.4 },
  94.         ["Interface\\Icons\\Spell_Shadow_CurseOfSargeras"]              = { spell =     980,            pandemic = 7.2 },
  95.         ["Interface\\Icons\\Spell_Shadow_UnstableAffliction_3"] = { spell = 30108,              pandemic =  4.2 },
  96.         ["Interface\\Icons\\Spell_Shadow_AuraOfDarkness"]               = { spell =     603,            pandemic = 18 },
  97.         ["Interface\\Icons\\Ability_Mage_WorldInFlames"]                = { spell = 108686,     pandemic = 4.5 },
  98.         ["Interface\\Icons\\Spell_Fire_Immolation"]                             = { spell =     157736,                 pandemic = 4.5 },
  99. }
  100.  
  101. local GetTime                           = GetTime
  102. local GetMastery                        = GetMastery
  103. local GetRangedHaste                    = GetRangedHaste
  104. local GetSpellCritChance                = GetSpellCritChance
  105. local GetSpellBonusDamage               = GetSpellBonusDamage
  106. local UnitDebuff                        = UnitDebuff
  107. local UnitHealth                        = UnitHealth
  108. local UnitHealthMax                     = UnitHealthMax
  109. local UnitExists                        = UnitExists
  110. local UnitGUID                          = UnitGUID
  111. local UnitPower                         = UnitPower
  112. local math_floor                        = math.floor
  113.  
  114. local mainFrame                 = CreateFrame("Frame", "AffDotsTarget", UIParent)
  115. local focusFrame                = CreateFrame("Frame",  "AffDotsFocus", UIParent)
  116.  
  117. mainFrame:SetClampedToScreen(true)
  118. focusFrame:SetClampedToScreen(true)
  119.  
  120. mainFrame:SetFrameStrata("LOW")
  121. focusFrame:SetFrameStrata("LOW")
  122.  
  123. local function Round(num) return math_floor(num+.5) end
  124. local function SecondsRound(num)
  125.         if num > 2 then return math_floor(num+.5)
  126.         else return math_floor(num*10+.5)/10 end
  127. end
  128.  
  129. function AffDots:FindColor(GUID, time_left, spell, pandemic)
  130.         if not targets[GUID..spell] then
  131.                 return 7
  132.         end
  133.        
  134.         local color = 3
  135.  
  136.         if time_left <= pandemic then color = 1 end
  137.        
  138.         return color
  139. end
  140.  
  141. local function OnMouseDown(self, button)
  142.         if button == "LeftButton" and not self.isMoving then
  143.                 self:StartMoving()
  144.                 self.isMoving = true
  145.         end
  146. end
  147.  
  148. local function OnMouseUp(self, button)
  149.         local p, _, rp, x, y = self:GetPoint()
  150.        
  151.         if self == mainFrame then
  152.                 options.p = p;
  153.                 options.rp = rp;
  154.                 options.x = x;
  155.                 options.y = y
  156.         elseif self == focusFrame then
  157.                 options.focus_p = p;
  158.                 options.focus_rp = rp;
  159.                 options.focus_x = x;
  160.                 options.focus_y = y
  161.         end
  162.        
  163.         if button == "LeftButton" and self.isMoving then
  164.                 self:StopMovingOrSizing()
  165.                 self:SetUserPlaced(false)
  166.                 self.isMoving = false
  167.         end
  168. end
  169.  
  170. mainFrame:SetScript("OnMouseDown", OnMouseDown)
  171. mainFrame:SetScript("OnMouseUp", OnMouseUp)
  172.  
  173. focusFrame:SetScript("OnMouseDown", OnMouseDown)
  174. focusFrame:SetScript("OnMouseUp", OnMouseUp)
  175.  
  176. function AffDots:ScaleAnimation(frame, duration)
  177.         local w = frame.secw * duration
  178.        
  179.         frame.f.scaleanimation:Stop()
  180.        
  181.         if w > options.bars.w then
  182.                 local delay = duration - options.bars.w / frame.secw
  183.                 frame.f.scale:SetStartDelay(delay)
  184.                 w = options.bars.w
  185.                 duration = options.bars.w / frame.secw
  186.         else
  187.                 frame.f.scale:SetStartDelay(0)
  188.         end
  189.        
  190.         frame.f.statusbar:SetWidth(w)
  191.         frame.f.statusbar:Show()
  192.     frame.f.scale:SetDuration(duration)
  193.     frame.f.scale:SetScale(0, 1)
  194.         frame.f.scaleanimation:Play()
  195. end
  196.  
  197. function AffDots:Visibility()
  198.  
  199.         if (options.hide_ui) then
  200.                 mainFrame:Hide();
  201.                 mainFrame:SetParent(nil)
  202.         elseif(options.hide and not in_combat) then
  203.                 mainFrame:Hide();
  204.                 mainFrame:SetParent(nil)
  205.         else
  206.                 mainFrame:SetParent(UIParent)
  207.                 mainFrame:Show();
  208.         end
  209.  
  210.         if(UnitGUID("focus") and options.focus and (in_combat or not options.hide)) then
  211.                 focusFrame:SetParent(UIParent)
  212.                 focusFrame:Show()
  213.         else
  214.                 focusFrame:Hide()
  215.                 focusFrame:SetParent(nil)
  216.         end
  217.  
  218.         mainFrame:SetMovable(not options.locked);
  219.         mainFrame:EnableMouse(not options.locked)
  220.        
  221.         focusFrame:SetMovable(not options.locked);
  222.         focusFrame:EnableMouse(not options.locked)
  223. end
  224.  
  225. ---------------------------------------------------------------
  226. local framepool, active_frames = {}, {}
  227.  
  228. function AffDots:ReleaseFrames()
  229.         for i, frame in pairs(active_frames) do
  230.                 frame:Hide()
  231.                 tinsert(framepool, frame)
  232.         end
  233.        
  234.         wipe(active_frames)
  235. end
  236.  
  237. function AffDots:GetFrame(parent)
  238.         local frame = tremove(framepool)
  239.         if not frame then
  240.                 frame                   = CreateFrame("Frame", nil, parent)
  241.                 frame.statusbar = frame:CreateTexture(nil, "ARTWORK")
  242.                 frame.bg                = frame:CreateTexture(nil, "BACKGROUND")
  243.                 frame.tick1             = frame:CreateTexture(nil, "OVERLAY")
  244.                 frame.tick2             = frame:CreateTexture(nil, "OVERLAY")
  245.                 frame.t1                = frame:CreateFontString(nil, "OVERLAY")
  246.                 frame.t2                = frame:CreateFontString(nil, "OVERLAY")
  247.                 frame.icon              = CreateFrame("Frame", nil, frame)
  248.                 frame.icon.file = frame.icon:CreateTexture(nil, "OVERLAY")
  249.                 frame.cd                = CreateFrame("COOLDOWN", nil, frame.icon)
  250.                 frame.statusbar:SetPoint("TOPLEFT")
  251.                 frame.bg:SetAllPoints(frame)
  252.                 frame.cd:SetAllPoints(frame.icon)
  253.                 frame.icon.file:SetAllPoints(frame.icon)
  254.                 frame.t1:SetFont("Fonts\\FRIZQT__.TTF",14,"OUTLINE")
  255.                 frame.t2:SetFont("Fonts\\FRIZQT__.TTF",14,"OUTLINE")
  256.                 frame.scaleanimation = frame.statusbar:CreateAnimationGroup()
  257.                 frame.scaleanimation:SetScript("OnFinished", function() frame.statusbar:Hide() end)
  258.                 frame.scale = frame.scaleanimation:CreateAnimation("Scale")
  259.                 frame.scale:SetOrder(1)
  260.                 frame.scale:SetOrigin("TOPLEFT", 0, 0)
  261.         else
  262.                 frame:SetParent(parent)
  263.         end
  264.         tinsert(active_frames, frame)
  265.         frame:Show()
  266.         return frame
  267. end
  268. ---------------------------------------------------------------
  269.  
  270. function AffDots:Track(id, update, target, duration, tick, order, active, noprop)
  271.         if not active then return end
  272.         local spell = {}
  273.         local parent
  274.        
  275.         if target == "target" then
  276.                 parent = AffDotsTarget
  277.         else
  278.                 parent = AffDotsFocus
  279.         end
  280.        
  281.         frame = AffDots:GetFrame(parent)
  282.        
  283.         if id > 0 then
  284.                 local n,r,i = GetSpellInfo(id)
  285.                
  286.                 spell["pandemic"]       = duration / 3
  287.                 spell["name"]           = n
  288.                 spell["rank"]           = r
  289.                 spell["iconfile"]       = i
  290.                 spell["spell"]          = id
  291.                 spell["timer"]          = 0
  292.         end
  293.        
  294.         spell["tick"]           = tick
  295.         spell["duration"]       = duration
  296.         spell["f"]                      = frame
  297.         spell["target"]         = target
  298.         spell["order"]          = order
  299.         spell["update"]         = update
  300.        
  301.         if noprop then spell["noprop"] = true end
  302.        
  303.         tinsert(AffDots.track, spell)
  304. end
  305.  
  306. function AffDots:InitFrames()
  307.         if options.layout == "bars" then
  308.                 AffDots.FrameDraw = AffDots.Bar
  309.         else
  310.                 AffDots.FrameDraw = AffDots.Box
  311.         end
  312.        
  313.         local msize, fsize = 0, 0
  314.         local font              = AffDots.SharedMedia:Fetch("font", options.font)
  315.         local statusbar = AffDots.SharedMedia:Fetch("statusbar", options.bg)
  316.        
  317.         mainFrame:ClearAllPoints();
  318.         focusFrame:ClearAllPoints()
  319.         mainFrame:Show();
  320.        
  321.         if options.focus then focusFrame:Show() end
  322.        
  323.         mainFrame:SetPoint(options.p, nil, options.rp, options.x, options.y)
  324.         focusFrame:SetPoint(options.focus_p, nil, options.focus_rp, options.focus_x, options.focus_y)
  325.        
  326.         --layout
  327.         for k,v in pairs(AffDots.track) do
  328.                 local c = AffDots.track[k]
  329.                 c.f.scaleanimation:Stop()
  330.                 c.dataold = {color = nil, bg = nil, tick = nil, t1 = nil, t2 = nil, setw = options.bars.w}
  331.                 c.datanew = {color = colors[1], bg = colors[8], tick = 0, t1 = "", t2 = "", setw = options.bars.w}
  332.                
  333.                 if c.target == "target" then
  334.                         c.f:SetScale(options.scale)
  335.                 else
  336.                         c.f:SetScale(options.focus_scale)
  337.                 end
  338.                
  339.                 c.f.t1:SetTextColor(unpack(options.color11))
  340.                 c.f.t2:SetTextColor(unpack(options.color11))
  341.                
  342.                 c.f.icon:Hide();
  343.                 c.f.cd:Hide();
  344.                
  345.                 c.f.t1:Hide();
  346.                 c.f.t2:Hide();
  347.                
  348.                 c.f.tick1:Hide();
  349.                 c.f.tick2:Hide();
  350.                
  351.                 c.f.statusbar:Hide();
  352.                
  353.                 c.f:ClearAllPoints();
  354.                
  355.                 c.f.icon:ClearAllPoints();
  356.                 c.f.t1:ClearAllPoints();
  357.                 c.f.t2:ClearAllPoints();
  358.                
  359.                 c.f.t1:SetText("");
  360.                 c.f.t2:SetText("")
  361.                
  362.                 c.f.bg:SetTexture(statusbar)
  363.                 c.f.bg:SetVertexColor(1, 1, 1, 1)
  364.                
  365.                 if c.spell then
  366.                         if c.target == "target" then msize = msize + 1 else fsize = fsize + 1 end
  367.                         if options.layout == "horizontal" then
  368.                                 c.f:SetSize(options.boxes_h.w,options.boxes_h.h)
  369.                                 c.f:SetPoint("TOPLEFT", options.boxes_h.w*c.order, 0)
  370.                                
  371.                                 c.f.icon.file:SetTexture(c.iconfile)
  372.                                 c.f.icon:SetSize(options.boxes_h.icon_size,options.boxes_h.icon_size)
  373.                                 c.f.icon.file:SetTexCoord(0.1,0.9,0.1,0.9)
  374.                                 c.f.icon:SetPoint("TOP",0,-options.boxes_h.icon_position)
  375.                                
  376.                                 c.f.t1:SetPoint("TOP",0,-options.boxes_h.text_position);
  377.                                 c.f.t1:SetFont(font,options.large_text_size,"OUTLINE")
  378.                                
  379.                                 if not options.hide_text then c.f.t1:Show() end
  380.                                 if not options.hide_icons then c.f.icon:Show();c.f.cd:Show() end
  381.                         elseif options.layout == "vertical" then
  382.                                 c.f:SetSize(options.boxes_v.w,options.boxes_v.h)
  383.                                 c.f:SetPoint("TOPLEFT", 0, -options.boxes_v.h*c.order)
  384.                                
  385.                                 c.f.icon.file:SetTexture(c.iconfile)
  386.                                 c.f.icon:SetSize(options.boxes_v.icon_size,options.boxes_v.icon_size)
  387.                                 c.f.icon.file:SetTexCoord(0.1,0.9,0.1,0.9)
  388.                                
  389.                                 c.f.icon:SetPoint("LEFT",options.boxes_v.icon_position,0)
  390.                                 c.f.t1:SetPoint("RIGHT",options.boxes_v.text_position-50,0);c.f.t1:SetFont(font,options.large_text_size,"OUTLINE")
  391.                                
  392.                                 if not options.hide_text then c.f.t1:Show() end
  393.                                 if not options.hide_icons then c.f.icon:Show();c.f.cd:Show() end
  394.                         elseif options.layout == "bars" then
  395.                                 c.f:SetSize(options.bars.w,options.bars.h)
  396.                                 c.f:SetPoint("TOPLEFT",0,-options.bars.h*c.order-(c.order*options.bars.margin))
  397.                                
  398.                                 c.f.tick1:SetSize(1,options.bars.h)
  399.                                 c.f.tick1:SetTexture("Interface\\CastingBar\\UI-CastingBar-Spark")
  400.                                 c.f.tick1:SetVertexColor(1, 1, 1, 0.75);
  401.                                
  402.                                 c.f.statusbar:SetHeight(options.bars.h)
  403.                                 c.f.statusbar:SetTexture(statusbar)
  404.                                 c.f.statusbar:SetVertexColor(0, 0, 0, options.transparency)
  405.                                
  406.                                 if options.bars.proportional and not c.noprop then
  407.                                         if c.tick > 0 and c.tick < options.bars.limit then
  408.                                                 c.f.tick1:SetPoint("LEFT", c.tick / options.bars.limit * options.bars.w,0)
  409.                                         end
  410.                                         c.secw = options.bars.w / options.bars.limit
  411.                                 else
  412.                                         if c.tick > 0 then
  413.                                                 c.f.tick1:SetPoint("LEFT", c.tick / c.duration * options.bars.w, 0)
  414.                                         end
  415.                                         c.secw = options.bars.w / c.duration
  416.                                 end
  417.                                
  418.                                 c.f.tick2:SetSize(1,options.bars.h)
  419.                                 c.f.tick2:SetTexture("Interface\\CastingBar\\UI-CastingBar-Spark")
  420.                                 c.f.tick2:SetVertexColor(1, 1, 1, 0.75);
  421.                                
  422.                                 c.f.icon.file:SetTexture(c.iconfile)
  423.                                 c.f.icon:SetSize(options.bars.h,options.bars.h)
  424.                                 c.f.icon.file:SetTexCoord(0.1,0.9,0.1,0.9)
  425.                                 c.f.icon:SetPoint("LEFT",-options.bars.h,0)
  426.                                
  427.                                 c.f.t1:SetPoint("CENTER",options.bars.text_position*(options.bars.w/100),0);
  428.                                 c.f.t1:SetFont(font,options.large_text_size,"OUTLINE")
  429.                                 c.f.t2:SetPoint("RIGHT",-3,0);
  430.                                 c.f.t2:SetFont(font,options.large_text_size,"OUTLINE")
  431.                                 c.f.bg:SetVertexColor(colors[8][1],colors[8][2],colors[8][3],options.transparency)
  432.                                
  433.                                 if not options.hide_text then c.f.t1:Show();c.f.t2:Show() end
  434.                                 if not options.hide_icons then c.f.icon:Show(); end
  435.                                
  436.                                 if c.tick > 0 then c.f.tick1:Show() end
  437.                         end
  438.                 else
  439.                         local w
  440.                         if options.layout == "horizontal" then
  441.                                 w = options.boxes_h.w
  442.                         elseif  options.layout == "vertical" then
  443.                                 w = options.boxes_v.w/2
  444.                         elseif  options.layout == "bars" then
  445.                                 w = 40
  446.                         end
  447.                        
  448.                         c.f.statusbar:Hide()
  449.                         c.f:SetSize(w,20)
  450.                         c.f:SetPoint("TOPLEFT", 0, 22)
  451.                        
  452.                         c.f.t1:SetPoint("CENTER", 0, 0);
  453.                         c.f.t1:SetFont(font,options.small_text_size,"OUTLINE");
  454.                         c.f.t1:Show()
  455.                        
  456.                         if c.update == AffDots.Update.sl then
  457.                                 local position = 0
  458.                                
  459.                                 if options.hp then position = position + 1 end
  460.                                
  461.                                 c.f:SetPoint("TOPLEFT", w*position, 22)
  462.                         end
  463.                 end
  464.         end
  465.  
  466.         if(options.layout == "horizontal") then
  467.                 mainFrame:SetSize(msize*options.boxes_h.w*options.scale, options.boxes_h.h*options.scale)
  468.                 focusFrame:SetSize(fsize*options.boxes_h.w*options.focus_scale, options.boxes_h.h*options.focus_scale)
  469.         elseif(options.layout == "vertical") then
  470.                 mainFrame:SetSize(options.boxes_v.w*options.scale, msize*options.boxes_v.h*options.scale)
  471.                 focusFrame:SetSize(options.boxes_v.w*options.focus_scale, fsize*options.boxes_v.h*options.focus_scale)
  472.         elseif(options.layout == "bars") then
  473.                 mainFrame:SetSize(options.bars.w*options.scale, msize*(options.bars.h+options.bars.margin)*options.scale)
  474.                 focusFrame:SetSize(options.bars.w*options.focus_scale, fsize*(options.bars.h+options.bars.margin)*options.focus_scale)
  475.         end
  476.  
  477.         AffDots:Visibility()
  478. end
  479.  
  480. function AffDots:Tidy()
  481.         local TidyPlates = TidyPlates
  482.         local time_left, icon, spell, pandemic, GUID, c
  483.         for plate in pairs(TidyPlates.NameplatesByVisible) do
  484.                 if not plate.extended.widgets.DebuffWidget then return false end
  485.                 GUID = plate.extended.unit.guid
  486.                 if GUID then
  487.                         for id,frame in pairs(plate.extended.widgets.DebuffWidget.AuraIconFrames) do
  488.                                 icon = frame.Icon:GetTexture()
  489.                                 if AffDots.tidyspells[icon] then
  490.                                         spell = AffDots.tidyspells[icon].spell; pandemic = AffDots.tidyspells[icon].pandemic
  491.                                         time_left = tonumber(frame.TimeLeft:GetText())
  492.                                 end
  493.                                 if not frame.affdots then
  494.                                         frame.Icon:SetDrawLayer("ARTWORK")
  495.                                         frame.Border:SetDrawLayer("BACKGROUND")
  496.                                         frame.Border:SetSize(options.tidyplates.w,options.tidyplates.h)
  497.                                         frame.Border:SetPoint("CENTER", 0, 0)
  498.                                         frame.affdots = true
  499.                                 end
  500.                                 if spell and time_left then
  501.                                         c = AffDots:FindColor(GUID,time_left,spell,pandemic)
  502.                                         frame.Border:SetTexture(colors[c][1],colors[c][2],colors[c][3],options.tidyplates.transparency)
  503.                                 else
  504.                                         frame.Border:SetTexture(0,0,0,options.tidyplates.transparency)
  505.                                 end
  506.                         end
  507.                 end
  508.         end
  509. end
  510.  
  511. function AffDots:Bar(frame)
  512.         if frame.dataold.color ~= frame.datanew.color then
  513.                 if options.color_text then
  514.                         frame.f.t1:SetTextColor(frame.datanew.color[1], frame.datanew.color[2], frame.datanew.color[3])
  515.                 end
  516.                 frame.f.statusbar:SetVertexColor(frame.datanew.color[1],frame.datanew.color[2],frame.datanew.color[3],options.transparency)
  517.                 frame.dataold.color = frame.datanew.color
  518.         end
  519.        
  520.         if frame.dataold.bg ~= frame.datanew.bg then
  521.                 frame.f.bg:SetVertexColor(frame.datanew.bg[1], frame.datanew.bg[2], frame.datanew.bg[3], options.transparency)
  522.                 frame.dataold.bg = frame.datanew.bg
  523.         end
  524.        
  525.         if frame.dataold.t1 ~= frame.datanew.t1 then
  526.                 frame.f.t1:SetText(frame.datanew.t1)
  527.                 frame.dataold.t1 = frame.datanew.t1
  528.         end
  529.        
  530.         if frame.dataold.t2 ~= frame.datanew.t2 then
  531.                 frame.f.t2:SetText(frame.datanew.t2)
  532.                 frame.dataold.t2 = frame.datanew.t2
  533.         end
  534.        
  535.         if frame.dataold.tick ~= frame.datanew.tick then              
  536.                 if frame.datanew.tick > 0 and frame.secw * frame.datanew.tick < options.bars.w then
  537.                         frame.f.tick2:SetPoint("LEFT", frame.secw * frame.datanew.tick, 0);
  538.                         frame.f.tick2:Show()
  539.                 else
  540.                         frame.f.tick2:Hide()
  541.                 end
  542.                
  543.                 frame.dataold.tick = frame.datanew.tick
  544.         end
  545.        
  546.         if frame.datanew.setcd then
  547.                 local duration = frame.datanew.expires - GetTime()
  548.                 AffDots:ScaleAnimation(frame, duration)
  549.                 frame.datanew.setcd = false
  550.         end
  551.        
  552.         if frame.datanew.hidecd then
  553.                 frame.f.statusbar:Hide()
  554.                 frame.datanew.hidecd = false
  555.         end
  556.        
  557.         if frame.dataold.setw ~= frame.datanew.setw then
  558.                 frame.f.statusbar:Show()
  559.                 frame.f.statusbar:SetWidth(frame.datanew.setw)
  560.                 frame.dataold.setw = frame.datanew.setw
  561.         end
  562. end
  563.  
  564. function AffDots:Box(frame)
  565.         if frame.dataold.color ~= frame.datanew.color then
  566.                 if options.color_text then
  567.                         frame.f.t1:SetTextColor(frame.datanew.color[1],frame.datanew.color[2],frame.datanew.color[3])
  568.                 end
  569.                 frame.f.bg:SetTexture(frame.datanew.color[1],frame.datanew.color[2],frame.datanew.color[3],options.transparency)
  570.                 frame.dataold.color = frame.datanew.color
  571.         end
  572.         if frame.dataold.t1 ~= frame.datanew.t1 then
  573.                 frame.f.t1:SetText(frame.datanew.t1)
  574.                 frame.dataold.t1 = frame.datanew.t1
  575.         end
  576.  
  577.         if frame.datanew.setcd and not options.hide_icons then
  578.                 frame.f.cd:Show()
  579.  
  580.                 if (not options.hide_duration) then
  581.                         frame.f.cd:SetCooldown(frame.datanew.expires - frame.datanew.duration, frame.datanew.duration)
  582.                 end
  583.                 frame.datanew.setcd = false
  584.         end
  585.         if frame.datanew.hidecd then
  586.                 frame.f.cd:Hide()
  587.                 frame.datanew.hidecd = false
  588.         end
  589. end
  590.  
  591. local function onUpdate(self,elapsed)
  592.     timer = timer + elapsed;
  593.     if timer >= throttle then
  594.                 for k,v in pairs(AffDots.track) do
  595.                         AffDots.track[k].update(AffDots.track[k])
  596.                         AffDots:FrameDraw(AffDots.track[k])
  597.                 end
  598.                
  599.                 if options.tidyplates.enable and TidyPlates then
  600.                         AffDots:Tidy()
  601.                 end
  602.                
  603.                 timer = 0
  604.     end
  605. end
  606.  
  607. SLASH_AFFDOTS1 = '/affdots'
  608. function AffDotsHandler(msg, editBox)
  609.         AffDots:GetLayoutOptions()
  610.         AffDots:GetSpecOptions(class..spec)
  611.         LibStub("AceConfigDialog-3.0"):Open("AffDots")
  612. end
  613. SlashCmdList["AFFDOTS"] = AffDotsHandler
  614.  
  615. function AffDots:PLAYER_REGEN_ENABLED()
  616.         in_combat = false;
  617.         AffDots:Visibility()
  618.         local t = GetTime()
  619.         for k,v in pairs(targets) do
  620.                 if targets[k][2] < t-120 then targets[k]=nil end
  621.         end
  622. end
  623.  
  624. function AffDots:PLAYER_REGEN_DISABLED()
  625.         in_combat = true;
  626.         AffDots:Visibility()
  627. end
  628.  
  629. function AffDots:PLAYER_FOCUS_CHANGED()
  630.         AffDots:Visibility()
  631. end
  632.  
  633.  
  634. function AffDots:PLAYER_EQUIPMENT_CHANGED(self, slot, hasItem)
  635.    
  636.     if ( (slot == 13 or slot == 14) and hasItem ) then
  637.         -- update trinket list
  638.         if ( IsEquippedItem(124522) ) then
  639.             local trinketID = GetInventoryItemID("player", slot)
  640.             if ( trinketID == 124522 ) then
  641.                 updateAgonyData(slot)
  642.             end
  643.         else
  644.             updateAgonyData(slot, true)
  645.         end
  646.  
  647.     end
  648.  
  649. end
  650.  
  651. function AffDots:SaveColors()
  652.         options = self.db.profile
  653.         colors = {
  654.                 options.color1,
  655.                 options.color2,
  656.                 options.color3,
  657.                 options.color4,
  658.                 options.color5,
  659.                 options.color6,
  660.                 options.color7,
  661.                 options.color8,
  662.                 options.color9,
  663.                 options.color10,
  664.                 options.color11
  665.         }
  666. end
  667.  
  668. AffDots.Update = {
  669.         dot     = function(f)
  670.                 local guid = UnitGUID(f.target)
  671.                 local _,_,_,_,_,duration,expires = UnitDebuff(f.target,f.name,f.rank,"player")
  672.                
  673.                 if duration and guid and targets[guid..f.spell] then
  674.  
  675.                         if(math.abs(expires - f.timer) > 1) then
  676.                                 if f.spell == 980 then
  677.                                         if targets[guid..f.spell][4] == 0 then
  678.                                                 targets[guid.."980"][4] = expires
  679.                                         elseif expires - targets[guid..f.spell][4] > 1 then
  680.                                                 targets[guid.."980"][4] = expires
  681.                                                 targets[guid.."980"][1] = dot_damage[980][1]
  682.                                                 targets[guid.."980"][3] = dot_damage[980][2]
  683.                                         end
  684.                                 end
  685.  
  686.                                 f.datanew.expires = expires
  687.                                 f.datanew.duration = duration
  688.                                 f.datanew.setcd = true
  689.                                 f.timer = expires
  690.                         end
  691.                         f.datanew.color = colors[AffDots:FindColor(guid,expires - GetTime(),f.spell,f.pandemic)]
  692.                         f.datanew.tick = targets[guid..f.spell][3]
  693.                         f.datanew.t2 = SecondsRound(f.timer-GetTime())
  694.                         -- if options.reltext then
  695.                                 -- f.datanew.t1 = Round(dot_damage[f.spell][1]*100/targets[guid..f.spell][1])
  696.                         -- elseif options.layout == "bars" then
  697.                                 -- f.datanew.t1 = dot_damage[f.spell][1].."/"..targets[guid..f.spell][1]
  698.                         -- else
  699.                                 -- f.datanew.t1 = dot_damage[f.spell][1].."\n"..targets[guid..f.spell][1]
  700.                         -- end
  701.                 else
  702.                         f.datanew.color = colors[7]
  703.                         -- f.datanew.t1 = 0
  704.                         f.datanew.t2 = ""
  705.                         f.datanew.tick = 0
  706.                         f.timer = 0
  707.                         f.datanew.hidecd = true
  708.                 end
  709.         end,
  710.         doom    = function(f)
  711.                 local guid = UnitGUID(f.target)
  712.                 local _,_,_,_,_,duration,expires = UnitDebuff(f.target,f.name,f.rank,"player")
  713.                 if duration and guid and targets[guid..f.spell] then
  714.                         if(math.abs(expires-f.timer)>1) then
  715.                                 f.datanew.expires = expires
  716.                                 f.datanew.duration = duration
  717.                                 f.datanew.setcd = true
  718.                                 f.timer = expires
  719.                         end
  720.                         f.datanew.color = colors[AffDots:FindColor(guid,expires - GetTime(),f.spell,f.pandemic)]
  721.                         f.datanew.tick = targets[guid..f.spell][3]
  722.                         f.datanew.t2 = SecondsRound(f.timer-GetTime())
  723.                         -- if options.reltext then
  724.                                 -- f.datanew.t1 = Round(dot_damage[f.spell][1]*100/targets[guid..f.spell][1])..targets[guid..f.spell][4]
  725.                         -- elseif options.layout == "bars" then
  726.                                 -- f.datanew.t1 = dot_damage[f.spell][1].."/"..targets[guid..f.spell][1]..targets[guid..f.spell][4]
  727.                         -- else
  728.                                 -- f.datanew.t1 = dot_damage[f.spell][1].."\n"..targets[guid..f.spell][1]..targets[guid..f.spell][4]
  729.                         -- end
  730.                 else
  731.                         f.datanew.color = colors[7]
  732.                         -- f.datanew.t1 = 0
  733.                         f.datanew.t2 = ""
  734.                         f.datanew.tick = 0
  735.                         f.timer = 0
  736.                         f.datanew.hidecd = true
  737.                 end
  738.         end,
  739.         haunt = function(f)
  740.                 local guid = UnitGUID(f.target)
  741.                 local shards = UnitPower("player", 7)
  742.                 local _,_,_,_,_,duration,expires = UnitDebuff(f.target, f.name,"","player")
  743.                
  744.                 f.datanew.t1 = shards
  745.                
  746.                 if duration and guid and targets[guid .. f.spell] then
  747.                         f.datanew.color = colors[AffDots:FindColor(guid, expires - GetTime(), f.spell, f.pandemic)]
  748.                         f.datanew.t2 = SecondsRound(f.timer - GetTime())
  749.                         f.datanew.duration = duration
  750.                         f.datanew.expires = expires
  751.                         f.datanew.setcd = true
  752.                         f.timer = expires
  753.                 else
  754.                         -- Nothing found on the target ...
  755.                         f.datanew.hidecd = true
  756.                         f.datanew.t2 = ""
  757.                         f.timer = 0
  758.                        
  759.                         if shards > 3 then
  760.                                 f.datanew.color = colors[4]
  761.                         else
  762.                                 f.datanew.color = colors[1]
  763.                         end
  764.                 end
  765.         end,
  766.         hp = function(f)
  767.                 f.datanew.color = colors[7]; f.datanew.bg = colors[8]
  768.                 if UnitExists(f.target) then
  769.                         local hp = Round(UnitHealth(f.target)*100/UnitHealthMax(f.target))
  770.                         f.datanew.t1 = hp
  771.                         if AffDots.execute_percent >= hp then
  772.                                 f.datanew.color = colors[9]; f.datanew.bg = colors[9]
  773.                         end
  774.                 end
  775.         end,
  776.         sl = function(f)
  777.                 local _,_,_,_,_,_,_,_,_,_,_,_,_,_,sl = UnitAura("player", spells.soulleech)
  778.                 local _,_,_,_,_,_,_,_,_,_,_,_,_,_,sp = UnitAura("player", spells.sacpact)
  779.                 local bubble = 0
  780.                 if sl and sl > 0 then bubble = bubble + sl end
  781.                 if sp and sp > 0 then bubble = bubble + sp end
  782.                 if bubble > 0 then
  783.                         f.datanew.color = colors[9]; f.datanew.bg = colors[9]
  784.                         f.datanew.t1 = Round(bubble/1000).."k"
  785.                 else
  786.                         f.datanew.color = colors[7]; f.datanew.bg = colors[8]
  787.                         f.datanew.t1 = ""
  788.                 end
  789.         end,
  790.         df = function(f)
  791.                 local power = UnitPower("player", 15)
  792.                 local color = 1
  793.                 if              power <= options.demo.switch1 then color = 1
  794.                 elseif  power <= options.demo.switch2 then color = 2
  795.                 elseif  power <= options.demo.switch3 then color = 3
  796.                 elseif  power <= options.demo.switch4 then color = 4
  797.                 elseif  power <= options.demo.switch5 then color = 5
  798.                 end
  799.                 f.datanew.setw = options.bars.w*power/1000
  800.                 f.datanew.t1 = power
  801.                 f.datanew.color = options.demo["color"..color]
  802.         end,
  803.         hog = function(f)
  804.                 local currentCharges, maxCharges, timeLastCast, cooldownDuration = GetSpellCharges(105174)
  805.                 f.datanew.color = colors[7]; f.datanew.bg = colors[8]
  806.                 if currentCharges == maxCharges then
  807.                         f.datanew.t1 = currentCharges
  808.                         f.datanew.color = colors[9]; f.datanew.bg = colors[9]
  809.                 else
  810.                         local t = cooldownDuration-GetTime()+timeLastCast
  811.                         f.datanew.t1 = currentCharges.."/"..SecondsRound(t)
  812.                         if currentCharges == maxCharges - 1 and t < 5 then
  813.                                 f.datanew.color = colors[9]; f.datanew.bg = colors[9]
  814.                         end
  815.                 end
  816.                 local _,_,_,_,_,_,expires = UnitDebuff("target", spells.shadowflame,nil,"player")
  817.                 if expires then
  818.                         if options.layout == "bars" then f.datanew.color = colors[1] end
  819.                         f.datanew.t2 = SecondsRound(expires-GetTime())
  820.                         f.datanew.expires = expires
  821.                         f.datanew.duration = duration
  822.                         f.datanew.setcd = true
  823.                 else
  824.                         f.datanew.t2 = ""
  825.                         f.datanew.hidecd = true
  826.                 end
  827.         end,
  828.         immo = function(f)
  829.                 local guid = UnitGUID(f.target)
  830.                 local _,_,_,_,_,duration,expires,_,_,_,id = UnitDebuff(f.target,f.name,f.rank,"player")
  831.                 if duration and guid and targets[guid..id] then
  832.                         if id == 157736 and f.iconfile == spells.fnbImmoIcon then
  833.                                 f.iconfile = spells.immoIcon
  834.                                 f.f.icon.file:SetTexture(f.iconfile)
  835.                         elseif id == 108686 and f.iconfile == spells.immoIcon then
  836.                                 f.iconfile = spells.fnbImmoIcon
  837.                                 f.f.icon.file:SetTexture(f.iconfile)
  838.                         end
  839.                         if(math.abs(expires-f.timer)>1) then
  840.                                 f.datanew.expires = expires
  841.                                 f.datanew.duration = duration
  842.                                 f.datanew.setcd = true
  843.                                 f.timer = expires
  844.                         end
  845.                         f.datanew.color = colors[AffDots:FindColor(guid,expires - GetTime(),id,f.pandemic)]
  846.                         f.datanew.tick = targets[guid..id][3]
  847.                         f.datanew.t2 = SecondsRound(f.timer-GetTime())
  848.                         -- if options.reltext then
  849.                                 -- f.datanew.t1 = Round(dot_damage[id][1]*100/targets[guid..id][1])
  850.                         -- elseif options.layout == "bars" then
  851.                                 -- f.datanew.t1 = dot_damage[id][1].."/"..targets[guid..id][1]
  852.                         -- else
  853.                                 -- f.datanew.t1 = dot_damage[id][1].."\n"..targets[guid..id][1]
  854.                         -- end
  855.                 else
  856.                         if f.iconfile ~= spells.immoIcon then
  857.                                 f.iconfile = spells.immoIcon
  858.                                 f.f.icon.file:SetTexture(f.iconfile)
  859.                         end
  860.                         f.datanew.color = colors[7]
  861.                         -- f.datanew.t1 = 0
  862.                         f.datanew.t2 = ""
  863.                         f.datanew.tick = 0
  864.                         f.timer = 0
  865.                         f.datanew.hidecd = true
  866.                 end
  867.         end,
  868.         embers = function(f)  
  869.                 local power = UnitPower("player", 14, true)
  870.                 local color = 1
  871.                 if              power <= options.destro.switch1 then color = 1
  872.                 elseif  power <= options.destro.switch2 then color = 2
  873.                 elseif  power <= options.destro.switch3 then color = 3
  874.                 elseif  power <= options.destro.switch4 then color = 4
  875.                 end
  876.                 f.datanew.setw = options.bars.w*power/40
  877.                 f.datanew.t1 = power
  878.                 f.datanew.color = options.destro["color"..color]
  879.         end,
  880.         conflag = function(f)
  881.                 local currentCharges, maxCharges, timeLastCast, cooldownDuration = GetSpellCharges(17962)
  882.                 f.datanew.bg = colors[8]
  883.                 if options.layout == "bars" then f.datanew.color = colors[3] else f.datanew.color = colors[7] end
  884.                 if currentCharges == maxCharges then
  885.                         f.datanew.color = colors[9]; f.datanew.bg = colors[9]
  886.                         f.datanew.t2 = ""
  887.                         f.datanew.hidecd = true
  888.                 else
  889.                         f.datanew.expires = timeLastCast+cooldownDuration
  890.                         f.datanew.duration = cooldownDuration
  891.                         f.datanew.setcd = true
  892.                         f.datanew.t2 = SecondsRound(cooldownDuration-GetTime()+timeLastCast)
  893.                 end
  894.                 f.datanew.t1 = currentCharges
  895.         end,
  896.         rof = function(f)
  897.                 local _,_,_,_,_,duration,expires = UnitAura("player",f.name,nil,"player")
  898.                 if expires then
  899.                         f.datanew.color = colors[9]
  900.                         f.datanew.t2 = SecondsRound(expires-GetTime())
  901.                         f.datanew.expires = expires
  902.                         f.datanew.duration = duration
  903.                         f.datanew.setcd = true
  904.                 else
  905.                         f.datanew.color = colors[7]
  906.                         f.datanew.t2 = ""
  907.                         f.datanew.hidecd = true
  908.                 end
  909.         end,
  910.         havoc = function(f)
  911.                 local _,_,_,count,_,duration,expires = UnitAura("player",spells.havoc)
  912.                 local cdstart, cdduration, cdenabled = GetSpellCooldown(spells.havoc)
  913.                 if count then
  914.                         f.datanew.t1 = count
  915.                         f.datanew.color = colors[9]
  916.                 else
  917.                         f.datanew.t1 = 0
  918.                         f.datanew.color = colors[7]
  919.                 end
  920.                 if(cdstart > 0 and cdduration > 1.5) then
  921.                         f.datanew.t2 = SecondsRound(cdstart + cdduration - GetTime())
  922.                         f.datanew.expires = cdstart + cdduration
  923.                         f.datanew.duration = cdduration
  924.                         f.datanew.setcd = true
  925.                 else
  926.                         f.datanew.color = colors[9]
  927.                         f.datanew.t2 = "Ready"
  928.                         f.datanew.hidecd = true
  929.                         f.datanew.setw = options.bars.w
  930.                 end
  931.         end,
  932.         draft = function(f)
  933.                 local _,_,_,count = UnitAura("player",spells.backdraft)
  934.                 if count then
  935.                         f.datanew.t1 = count
  936.                         f.datanew.color = colors[9]
  937.                         f.datanew.setw = options.bars.w*count/6
  938.                 else
  939.                         f.datanew.t1 = 0
  940.                         f.datanew.color = colors[7]
  941.                         f.datanew.hidecd = true
  942.                 end
  943.         end,
  944. }
  945.  
  946. local GetDotDmg = {
  947.         function()
  948.                 local mastery, haste, crit, spd = GetMastery(), UnitSpellHaste("player"), GetSpellCritChance(6), GetSpellBonusDamage(6)
  949.                 if crit > 100 then crit = 100 end
  950.        
  951.                 damage_bonus            = (1 + crit / 100) * (1 + (mastery * 3.1) /100)
  952.                 tick_every                      = 2 / (1 + (haste / 100))
  953.  
  954.                 ticks                           = Round(24 / tick_every)
  955.                 duration                        = ticks * tick_every
  956.                 damage                          = ticks * (280 + spd * 0.26) * damage_bonus *dmg_buff
  957.                 dps                                     = Round(damage / duration)
  958.                 dot_damage[980]         = {Round(dps / 100) / 10, tick_every}
  959.  
  960.                 ticks                           = Round(18 / tick_every)
  961.                 duration                        = ticks * tick_every
  962.                 damage                          = (1926 + ticks * spd * 0.2) * damage_bonus * dmg_buff
  963.                 dps                                     = Round(damage / duration)
  964.                 dot_damage[corr_id]     = { Round(dps / 100) / 10, tick_every }
  965.  
  966.                 ticks                           = Round(14 / tick_every)
  967.                 duration                        = ticks * tick_every
  968.                 damage                          = (1792 + ticks * spd * 0.24) * damage_bonus * dmg_buff
  969.                 dps                                     = Round(damage / duration)
  970.                 dot_damage[30108]       = { Round(dps / 100) / 10, tick_every }
  971.         end,
  972.         function()
  973.                 local mastery, haste, crit, spd = GetMastery(), UnitSpellHaste("player"), GetSpellCritChance(6), GetSpellBonusDamage(6)
  974.                 if crit > 100 then crit = 100 end
  975.        
  976.                 damage_bonus            = (1 + crit / 100) * (1 + (mastery) / 100)
  977.                 bonus                           = (1 + crit / 100) * (1 + (mastery * 3) /100)
  978.  
  979.                 tick_every                      = 2 / (1 + (haste / 100))
  980.                 ticks                           = Round(18 / tick_every)
  981.                 duration                        = ticks * tick_every
  982.                 damage                          = (1926 + ticks * spd * 0.2) * damage_bonus * dmg_buff
  983.                 dps                                     = Round(damage / duration)
  984.                 dot_damage[corr_id]     = { Round(dps / 100) / 10, tick_every }
  985.  
  986.                 tick_every                      = 15 / (1 + (haste / 100))
  987.                 ticks                           = Round(60 / tick_every)
  988.                 duration                        = ticks * tick_every
  989.                 damage                          = (5340 / ticks + spd * 1.25) * bonus * ticks * dmg_buff
  990.                 dps                                     = Round(damage / duration)
  991.                
  992.                 local c
  993.                 if crit == 100 then
  994.                         c = "c"
  995.                 else
  996.                         c = ""
  997.                 end
  998.                
  999.                 dot_damage[603]         = { Round(dps / 100) / 10, tick_every, c }
  1000.         end,
  1001.         function()
  1002.                 local mastery, haste, crit, spd = GetMastery(), UnitSpellHaste("player"), GetSpellCritChance(6), GetSpellBonusDamage(6)
  1003.                 if crit > 100 then crit = 100 end
  1004.        
  1005.                 damage_bonus            = (1 + crit / 100) * (1 + (mastery + 1) / 100)
  1006.                 bonus                           = (100 + mastery * 3) * 0.35 / 100
  1007.  
  1008.                 tick_every                      = 3 / (1 + (haste / 100))
  1009.                 ticks                           = Round(15 / tick_every)
  1010.                 duration                        = ticks * tick_every
  1011.                 damage                          = (1980 + ticks * spd * 0.371) * damage_bonus * dmg_buff
  1012.                 dps                                     = Round(damage / duration)
  1013.                 dot_damage[157736]              = { Round(dps / 100) / 10, tick_every }
  1014.                 dot_damage[108686]      = { Round(dps * bonus / 100) / 10, tick_every }
  1015.         end,
  1016. }
  1017.  
  1018. local soulswapstorage           = {}
  1019. local CombatLog = {
  1020.         function(_,_,timestamp,event,_,source_GUID,_,_,_,dest_GUID,_,_,_, ...)
  1021.                 if(source_GUID ~= playerGuid or (event ~= "SPELL_AURA_REFRESH" and event ~= "SPELL_AURA_APPLIED" and event ~= "SPELL_DAMAGE" and event ~= "SPELL_CAST_SUCCESS")) then return end
  1022.  
  1023.                 spell = select(1, ...)
  1024.                
  1025.                 local afterCastBeforeApply = ((timestamp - (soulswapstorage['time'] or 0)) > .8)
  1026.                 -- If UA is cast between inhale and exhale, all 3 dots are applied at the same timestamp (exactly like a 3 DoT exhale). We need to check if the dots were stored on inhale. If DoTs are applied after the exhale GCD, afterCast will be TRUE. In the other case of FALSE, UA will be applied b/c it's not stored in the soulswapstorage variable. The other DoTs don't have this problem at all, I'm including it in the IF statements just in case.
  1027.                 if(event == "SPELL_AURA_APPLIED" or event == "SPELL_AURA_REFRESH") then
  1028.                                 if(spell == 30108) and (afterCastBeforeApply or (soulswapstorage[30108] == nil)) then
  1029.                                         targets[dest_GUID.."30108"] = { dot_damage[30108][1], GetTime(), dot_damage[30108][2] }
  1030.                                 elseif(spell == corr_id or spell == 87389) and (afterCastBeforeApply or soulswapstorage[corr_id] == nil) then
  1031.                                         targets[dest_GUID..corr_id] = { dot_damage[corr_id][1], GetTime(), dot_damage[corr_id][2] }
  1032.                                 elseif(spell == 980) and (afterCastBeforeApply or soulswapstorage[980] == nil) then
  1033.                                         targets[dest_GUID.."980"] = { dot_damage[980][1], GetTime(), dot_damage[980][2], 0 }
  1034.                                 elseif (spell == 48181) then
  1035.                                         targets[dest_GUID .. "48181"] = { 0, GetTime(), 0, 0 }
  1036.                                 end
  1037.                 end
  1038.         end,
  1039.        
  1040.         function(_,_,_,event,_,source_GUID,_,_,_,dest_GUID,_,_,_, ...)
  1041.                 if(source_GUID ~= playerGuid or (event ~= "SPELL_AURA_REFRESH" and event ~= "SPELL_AURA_APPLIED" and event ~= "SPELL_DAMAGE")) then return end
  1042.  
  1043.                 spell = select(1, ...)
  1044.                 if(event == "SPELL_AURA_APPLIED" or event == "SPELL_AURA_REFRESH") then
  1045.                         if(spell == corr_id) then
  1046.                                 targets[dest_GUID..corr_id] = {dot_damage[corr_id][1],GetTime(),dot_damage[corr_id][2]}
  1047.                         elseif(spell == 603) then
  1048.                                 targets[dest_GUID.."603"] = {dot_damage[603][1],GetTime(),dot_damage[603][2],dot_damage[603][3]}
  1049.                         end
  1050.                 elseif(event == "SPELL_DAMAGE" and spell == 103964) then
  1051.                         targets[dest_GUID..corr_id] = {dot_damage[corr_id][1],GetTime(),dot_damage[corr_id][2]}
  1052.                 end
  1053.         end,
  1054.        
  1055.         function(_,_,_,event,_,source_GUID,_,_,_,dest_GUID,_,_,_, ...)
  1056.                 if(source_GUID ~= playerGuid or (event ~= "SPELL_AURA_REFRESH" and event ~= "SPELL_AURA_APPLIED" and event ~= "SPELL_DAMAGE")) then return end
  1057.  
  1058.                 spell = select(1, ...)
  1059.                 if(event == "SPELL_AURA_APPLIED" or event == "SPELL_AURA_REFRESH") then
  1060.                         if(spell == 157736) then
  1061.                                 targets[dest_GUID.."157736"] = {dot_damage[157736][1],GetTime(),dot_damage[157736][2]}
  1062.                         elseif(spell == 108686) then
  1063.                                 targets[dest_GUID.."108686"] = {dot_damage[108686][1],GetTime(),dot_damage[108686][2]}
  1064.                         end
  1065.                 end
  1066.         end,
  1067. }
  1068.  
  1069. function AffDots:InitSpec()
  1070.         AffDots:ReleaseFrames()
  1071.         wipe(AffDots.track)
  1072.  
  1073.         if spec == 1 then
  1074.                 AffDots.execute_percent = 20;
  1075.  
  1076.                 AffDots:Track(corr_id, AffDots.Update.dot, "target", corruption.duration, corruption.tick, options.aff.corr, true)
  1077.                 AffDots:Track(980, AffDots.Update.dot, "target", agony.duration, agony.tick, options.aff.agony, true)
  1078.                 AffDots:Track(30108, AffDots.Update.dot, "target", unstablea.duration, unstablea.tick, options.aff.ua, true)
  1079.                 AffDots:Track(48181, AffDots.Update.haunt, "target", 10, 3.3, options.aff.haunt, options.aff.show_haunt)
  1080.                 AffDots:Track(0, AffDots.Update.hp, "target", 0, 0, 0, options.hp)
  1081.                 AffDots:Track(0, AffDots.Update.sl, "target", 0, 0, 2, options.sl)
  1082.                
  1083.                 if options.focus then
  1084.                         AffDots:Track(corr_id, AffDots.Update.dot, "focus", 23.4, 5.4, options.aff.corr, true)
  1085.                         AffDots:Track(980, AffDots.Update.dot, "focus", 31.2, 7.2, options.aff.agony, true)
  1086.                         AffDots:Track(30108, AffDots.Update.dot, "focus", 18.2, 4.2, options.aff.ua, true)
  1087.                         AffDots:Track(0, AffDots.Update.hp, "focus", 0, 0, 0, options.hp)
  1088.                 end
  1089.         elseif spec == 2 then
  1090.                 AffDots.execute_percent = 25;
  1091.                
  1092.                 AffDots:Track(corr_id, AffDots.Update.dot, "target",    18, 5.4, options.demo.corr, true)
  1093.                 AffDots:Track(603, AffDots.Update.doom, "target",       60, 18, options.demo.doom, true)
  1094.                 AffDots:Track(105174, AffDots.Update.hog, "target", 6, 3, options.demo.hog, options.demo.show_hog)
  1095.                 AffDots:Track(104315, AffDots.Update.df, "target", 0, 0, options.demo.df, options.demo.show_df, true)
  1096.                 AffDots:Track(0, AffDots.Update.hp, "target", 0, 0, 0, options.hp)
  1097.                 AffDots:Track(0, AffDots.Update.sl, "target", 0, 0, 2, options.sl)
  1098.  
  1099.                 if options.focus then
  1100.                         AffDots:Track(corr_id, AffDots.Update.dot, "focus", 23.4, 5.4, options.demo.corr, true)
  1101.                         AffDots:Track(603, AffDots.Update.doom, "focus", 78, 18, options.demo.doom, true)
  1102.                         AffDots:Track(0, AffDots.Update.hp, "focus", 0, 0, 0, options.hp)
  1103.                 end
  1104.         elseif spec == 3 then
  1105.                 AffDots.execute_percent = 20;
  1106.  
  1107.                 AffDots:Track(157736, AffDots.Update.immo, "target", 15, 4.5, options.destro.immo, true)
  1108.                 AffDots:Track(17962, AffDots.Update.conflag, "target", 12, 0, options.destro.conflag, options.destro.show_conflag)
  1109.                 AffDots:Track(108647, AffDots.Update.embers, "target", 40, 0, options.destro.embers, options.destro.show_embers, true)
  1110.                 AffDots:Track(5740, AffDots.Update.rof, "target", 7, 0, options.destro.rof, options.destro.show_rof)
  1111.                 AffDots:Track(80240, AffDots.Update.havoc, "target", 25, 10,    options.destro.havoc, options.destro.show_havoc, true)
  1112.                 AffDots:Track(117896, AffDots.Update.draft, "target", 0, 0, options.destro.backdraft, options.destro.show_backdraft, true)
  1113.                 AffDots:Track(0, AffDots.Update.hp, "target", 0, 0, 0, options.hp)
  1114.                 AffDots:Track(0, AffDots.Update.sl, "target", 0, 0, 2, options.sl)
  1115.  
  1116.                 if options.focus then
  1117.                         AffDots:Track(157736, AffDots.Update.immo, "focus", 19.5, 4.5, options.destro.immo, true)
  1118.                         AffDots:Track(0, AffDots.Update.hp, "focus", 0, 0, 0, options.hp)
  1119.                 end
  1120.         end
  1121.  
  1122.         AffDots:InitFrames()
  1123. end
  1124.  
  1125. function AffDots:InitializeClass()
  1126.         spells.immoIcon         = select(3, GetSpellInfo(157736))
  1127.         spells.fnbImmoIcon      = select(3, GetSpellInfo(108686))
  1128.  
  1129.         AffDots:UnregisterEvent("COMBAT_LOG_EVENT_UNFILTERED")
  1130.         AffDots:UnregisterEvent("COMBAT_RATING_UPDATE")
  1131.         AffDots:UnregisterEvent("SPELL_POWER_CHANGED")
  1132.         AffDots:UnregisterEvent("UNIT_STATS")
  1133.         AffDots:UnregisterEvent("PLAYER_DAMAGE_DONE_MODS")
  1134.         AffDots:UnregisterEvent("PLAYER_REGEN_ENABLED")
  1135.         AffDots:UnregisterEvent("PLAYER_REGEN_DISABLED")
  1136.         AffDots:UnregisterEvent("PLAYER_FOCUS_CHANGED")
  1137.         AffDots:UnregisterEvent("PLAYER_EQUIPMENT_CHANGED")
  1138.        
  1139.         AffDotsTarget:SetScript("OnUpdate", nil)
  1140.        
  1141.         AffDotsTarget:Hide();
  1142.         AffDotsFocus:Hide();
  1143.        
  1144.         spec = GetSpecialization() or ""
  1145.  
  1146.         if (spec == 1 and options.aff.enabled) or (spec == 2 and options.demo.enabled) or (spec == 3 and options.destro.enabled) then
  1147.                 AffDots.GetDotDmg = GetDotDmg[spec]
  1148.                 AffDots.CombatLog = CombatLog[spec]
  1149.                 AffDots:GetDotDmg()
  1150.                
  1151.                 AffDots:RegisterEvent("COMBAT_LOG_EVENT_UNFILTERED", "CombatLog")
  1152.                 AffDots:RegisterEvent("COMBAT_RATING_UPDATE", "GetDotDmg")
  1153.                 AffDots:RegisterEvent("SPELL_POWER_CHANGED", "GetDotDmg")
  1154.                 AffDots:RegisterEvent("UNIT_STATS", "GetDotDmg")
  1155.                 AffDots:RegisterEvent("PLAYER_DAMAGE_DONE_MODS", "GetDotDmg")
  1156.                 AffDots:RegisterEvent("PLAYER_REGEN_ENABLED")
  1157.                 AffDots:RegisterEvent("PLAYER_REGEN_DISABLED")
  1158.                 AffDots:RegisterEvent("PLAYER_FOCUS_CHANGED")
  1159.                 AffDots:RegisterEvent("PLAYER_EQUIPMENT_CHANGED")
  1160.                
  1161.                 AffDotsTarget:SetScript("OnUpdate", onUpdate)
  1162.                
  1163.                 AffDots:InitSpec()
  1164.         end
  1165. end
  1166.  
  1167. function updateAgonyData(slot, unequip)
  1168.     -- get the right trinket slot
  1169.     if ( unequip ) then
  1170.        
  1171.         AffDots.track[1].duration = corruption.base
  1172.         AffDots.track[1].tick = corruption.base * 3/10
  1173.         AffDots.track[1].pandemic = corruption.base / 3
  1174.  
  1175.         AffDots.track[2].duration = agony.base
  1176.         AffDots.track[2].tick = agony.base * 3/10
  1177.         AffDots.track[2].pandemic = agony.base / 3
  1178.  
  1179.         AffDots.track[3].duration = unstablea.base
  1180.         AffDots.track[3].tick = unstablea.base * 3/10
  1181.         AffDots.track[3].pandemic = unstablea.base / 3
  1182.  
  1183.         AffDots:InitFrames() -- Update Bars
  1184.        
  1185.         return
  1186.     end
  1187. -- Item Versions BonusID's
  1188.     local itemVersion, warforged = 0
  1189.     local numBonusIDs = (select(14, strsplit(":", GetInventoryItemLink("player", slot)))):gsub("%D", "")
  1190.  
  1191.     for i=15,14+numBonusIDs do
  1192.         local bonusID = (select(i, strsplit(":", GetInventoryItemLink("player", slot)))):gsub("%D", "")
  1193.  
  1194.         if ( (bonusID == "560") or (bonusID == "561") or (bonusID == "562") ) then
  1195.             warforged = true
  1196.         end
  1197.  
  1198.         if ( bonusID == "566" or bonusID == "567" ) then
  1199.             itemVersion = tonumber(bonusID)
  1200.         end
  1201.     end
  1202. -- Calculating pandemic ... sort of
  1203.     local multiplier = fragment_of_the_dark_star[itemVersion][warforged and "warforged" or "not_warforged"].multiplier
  1204.  
  1205.     corruption.duration = (100 - multiplier) * corruption.base / 100
  1206.     corruption.tick = corruption.duration * 3/10
  1207.     corruption.pandemic = corruption.duration / 3
  1208.  
  1209.     agony.duration = (100 - multiplier) * agony.base / 100
  1210.     agony.tick = agony.duration * 3/10
  1211.     agony.pandemic = agony.duration / 3
  1212.  
  1213.     unstablea.duration = (100 - multiplier) * unstablea.base / 100
  1214.     unstablea.tick = unstablea.duration * 3/10
  1215.     unstablea.pandemic = unstablea.duration / 3
  1216. -- If you see these prints in chat... it works! Also you know how much duration each spell has without checking the tooltip :)
  1217.     print(("Fragment of the Dark Star (%s%s):"):format(fragment_of_the_dark_star[itemVersion].itemVersion, warforged and " - Warforged" or ""))
  1218.     print("Agony duration set to: " .. agony.duration)
  1219.     print("Corruption duration set to: " .. corruption.duration)
  1220.     print("Unstable Affliction duration set to: " .. unstablea.duration)
  1221.  
  1222.     if ( AffDots.track and AffDots.track[2] and AffDots.track[2].spell == 980 ) then
  1223.  
  1224.         AffDots.track[1].duration = corruption.duration
  1225.         AffDots.track[1].tick = corruption.tick
  1226.         AffDots.track[1].pandemic = corruption.pandemic
  1227.  
  1228.         AffDots.track[2].duration = agony.duration
  1229.         AffDots.track[2].tick = agony.tick
  1230.         AffDots.track[2].pandemic = agony.pandemic
  1231.  
  1232.         AffDots.track[3].duration = unstablea.duration
  1233.         AffDots.track[3].tick = unstablea.tick
  1234.         AffDots.track[3].pandemic = unstablea.pandemic
  1235.  
  1236.         AffDots:InitFrames() -- Update Bars
  1237.     end
  1238.  
  1239. end
  1240.  
  1241. function AffDots:OnInitialize()
  1242.         playerGuid = UnitGUID("player")
  1243.        
  1244.         AffDots:DefaultOptions()
  1245.        
  1246.         self.db.RegisterCallback(self, "OnProfileChanged", "OnInitialize")
  1247.     self.db.RegisterCallback(self, "OnProfileCopied", "OnInitialize")
  1248.     self.db.RegisterCallback(self, "OnProfileReset", "OnInitialize")
  1249.  
  1250.         self.options = self:OptionsTable()
  1251.        
  1252.     LibStub('LibDualSpec-1.0'):EnhanceDatabase(self.db, "AffDots")
  1253.     LibStub('LibDualSpec-1.0'):EnhanceOptions(self.options.args.profile, self.db)
  1254.         LibStub("AceConfig-3.0"):RegisterOptionsTable("AffDots", self.options)
  1255.        
  1256.         self:MigrateOptions()
  1257.         options = self.db.profile
  1258.        
  1259.         colors = { options.color1, options.color2, options.color3, options.color4, options.color5, options.color6, options.color7, options.color8, options.color9, options.color10, options.color11 }
  1260.  
  1261.         class = select(2, UnitClass("player"))
  1262.         spec = GetSpecialization() or ""
  1263.  
  1264.         if ( IsEquippedItem(124522) ) then
  1265.             updateAgonyData(GetInventoryItemID("player", 13) == 124522 and 13 or 14)
  1266.         end
  1267.        
  1268.         if class ~= "WARLOCK" then
  1269.                 local loaded = LoadAddOn("AffDots"..class)
  1270.                 if loaded then
  1271.                         AffDots:InitializeClass()
  1272.                 end
  1273.         else
  1274.                 AffDots:RegisterEvent("PLAYER_TALENT_UPDATE", "InitializeClass")
  1275.                 AffDots:InitializeClass()
  1276.         end
  1277. end
  1278.  
  1279. function AffDots:OnEnable()
  1280.         AffDots:OnInitialize()
  1281. end
  1282.  
  1283. function AffDots:OnDisable()
  1284. end
  1285.  
  1286. function AffDots.FrameDraw()
  1287. end
  1288.  
  1289. AffDots.targets = targets
  1290. AffDots.dot_damage = dot_damage
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement