From 229d58b58196bceaeb76aab2825b0299743e9af7 Mon Sep 17 00:00:00 2001 From: "Johnny C. Lam" Date: Fri, 22 Feb 2013 09:21:31 +0000 Subject: [PATCH] Implement OvalePaperDoll class that tracks the in-game paper doll stats. OvalePaperDoll caches the current player stats when it receives events noting that the stats have changed. Use OvalePaperDoll properties instead of Blizzard API when referencing player stats. This avoids a lot of unnecessary Blizzard API calls. The current stats cached by OvalePaperDoll are: * Primary stats: Agility, Intellect, Stamina, Strength, Spirit * Attack Power, Ranged Attack Power * Spellpower: bonus damage, bonus healing * Melee haste percent increase * Spell haste percent increase * Mastery effect percent increase Remove haste-tracking from OvaleAura as it is now maintained in OvalePaperDoll. git-svn-id: svn://svn.curseforge.net/wow/ovale/mainline/trunk@699 d5049fe3-3747-40f7-a4b5-f36d6801af5f --- Ovale.toc | 1 + OvaleAura.lua | 28 +-------- OvaleBestAction.lua | 2 +- OvaleCondition.lua | 27 ++++----- OvaleData.lua | 14 +++-- OvaleFuture.lua | 19 +++--- OvalePaperDoll.lua | 161 +++++++++++++++++++++++++++++++++++++++++++++++++++ OvaleState.lua | 10 ++-- 8 files changed, 197 insertions(+), 65 deletions(-) create mode 100644 OvalePaperDoll.lua diff --git a/Ovale.toc b/Ovale.toc index 6e7f593..d9bb70f 100644 --- a/Ovale.toc +++ b/Ovale.toc @@ -39,6 +39,7 @@ OvaleGUID.lua OvaleIcone.lua OvaleIcone.xml OvaleOptions.lua +OvalePaperDoll.lua OvaleRecount.lua OvaleSkada.lua OvaleSpellDamage.lua diff --git a/OvaleAura.lua b/OvaleAura.lua index baea4c3..e241bee 100644 --- a/OvaleAura.lua +++ b/OvaleAura.lua @@ -15,8 +15,6 @@ OvaleAura = LibStub("AceAddon-3.0"):NewAddon("OvaleAura", "AceEvent-3.0") -- OvaleAura.aura = {} OvaleAura.serial = 0 -OvaleAura.spellHaste = 1 -OvaleAura.meleeHaste = 1 OvaleAura.playerGUID = nil -- @@ -58,7 +56,7 @@ function OvaleAura:COMBAT_LOG_EVENT_UNFILTERED(event, ...) if sourceGUID == self.playerGUID and (event == "SPELL_AURA_APPLIED" or event == "SPELL_AURA_REFRESH" or event == "SPELL_AURA_APPLIED_DOSE") then local aura = self:GetAuraByGUID(destGUID, spellId, true) if aura then - aura.spellHaste = self.spellHaste + aura.spellHaste = OvalePaperDoll.spellHaste end end end @@ -132,12 +130,6 @@ end function OvaleAura:UpdateAuras(unitId, unitGUID) self.serial = self.serial + 1 - local hateBase - local hateCommune - local hateSorts - local hateCaC - local hateHero - local hateClasse local damageMultiplier if not unitId then @@ -154,12 +146,6 @@ function OvaleAura:UpdateAuras(unitId, unitGUID) end if unitId == "player" then - hateBase = GetCombatRatingBonus(18) - hateCommune = 0 - hateSorts = 0 - hateCaC = 0 - hateHero = 0 - hateClasse = 0 damageMultiplier = 1 end @@ -193,15 +179,6 @@ function OvaleAura:UpdateAuras(unitId, unitGUID) end if unitId == "player" then - if OvaleData.buffSpellList.spell_haste[spellId] then - hateSorts = 5 - elseif OvaleData.buffSpellList.melee_haste[spellId] then - hateCaC = 10 - elseif OvaleData.buffSpellList.burst_haste[spellId] then - hateHero = 30 - elseif OvaleData.selfHasteBuff[spellId] then - hateClasse = OvaleData.selfHasteBuff[spellId] - end if OvaleData.selfDamageBuff[spellId] then damageMultiplier = damageMultiplier * OvaleData.selfDamageBuff[spellId] end @@ -230,10 +207,7 @@ function OvaleAura:UpdateAuras(unitId, unitGUID) self.aura[unitGUID] = nil end - --Update player haste if unitId == "player" then - self.spellHaste = (1 + hateBase/100) * (1 + hateCommune/100) * (1 + hateSorts/100) * (1 + hateHero/100) * (1 + hateClasse/100) - self.meleeHaste = (1 + hateBase/100) * (1 + hateCommune/100) * (1 + hateCaC/100) * (1 + hateHero/100) * (1 + hateClasse/100) baseDamageMultiplier = damageMultiplier end diff --git a/OvaleBestAction.lua b/OvaleBestAction.lua index 45e6f71..7dc55f1 100644 --- a/OvaleBestAction.lua +++ b/OvaleBestAction.lua @@ -272,7 +272,7 @@ function OvaleBestAction:Compute(element) else --TODO: pas exact, parce que si ce sort est reporté de par exemple 0,5s par un debuff --ça tombera entre deux ticks - local ticks = floor(OvaleAura.spellHaste * OvaleData.spellInfo[OvaleState.currentSpellId].canStopChannelling + 0.5) + local ticks = floor(OvalePaperDoll.spellHaste * OvaleData.spellInfo[OvaleState.currentSpellId].canStopChannelling + 0.5) local tickLength = (OvaleState.attenteFinCast - OvaleState.startCast) / ticks local tickTime = OvaleState.startCast + tickLength if (Ovale.trace) then diff --git a/OvaleCondition.lua b/OvaleCondition.lua index 971cd95..8ad6e00 100644 --- a/OvaleCondition.lua +++ b/OvaleCondition.lua @@ -46,11 +46,11 @@ local lastSPD = {} local floor, pairs, select, strfind, tostring = math.floor, pairs, select, string.find, tostring local GetGlyphSocketInfo, GetInventoryItemID, GetInventoryItemLink = GetGlyphSocketInfo, GetInventoryItemID, GetInventoryItemLink local GetInventorySlotInfo, GetItemCooldown, GetItemCount = GetInventorySlotInfo, GetItemCooldown, GetItemCount -local GetItemInfo, GetMasteryEffect, GetRune = GetItemInfo, GetMasteryEffect, GetRune -local GetRuneCount, GetSpellBonusDamage, GetSpellCharges = GetRuneCount, GetSpellBonusDamage, GetSpellCharges +local GetItemInfo, GetRune = GetItemInfo, GetRune +local GetRuneCount, GetSpellCharges = GetRuneCount, GetSpellCharges local GetSpellInfo, GetTotemInfo, GetTrackingInfo = GetSpellInfo, GetTotemInfo, GetTrackingInfo local GetUnitSpeed, HasFullControl, IsSpellInRange = GetUnitSpeed, HasFullControl, IsSpellInRange -local IsStealthed, IsUsableSpell, UnitAttackPower = IsStealthed, IsUsableSpell, UnitAttackPower +local IsStealthed, IsUsableSpell = IsStealthed, IsUsableSpell local UnitCastingInfo, UnitChannelInfo, UnitClass = UnitCastingInfo, UnitChannelInfo, UnitClass local UnitClassification, UnitCreatureFamily, UnitCreatureType = UnitClassification, UnitCreatureFamily, UnitCreatureType local UnitDebuff, UnitDetailedThreatSituation, UnitExists = UnitDebuff, UnitDetailedThreatSituation, UnitExists @@ -83,9 +83,9 @@ local function avecHate(temps, hate) if (not hate) then return temps elseif (hate == "spell") then - return temps/OvaleAura.spellHaste + return temps/(1 + OvalePaperDoll.spellHaste) elseif (hate == "melee") then - return temps/OvaleAura.meleeHaste + return temps/(1 + OvalePaperDoll.meleeHaste) else return temps end @@ -478,8 +478,7 @@ end -- if AttackPower(more 10000) Spell(rake) OvaleCondition.conditions.attackpower = function(condition) - local base, posBuff, negBuff = UnitAttackPower("player") - return compare(base + posBuff + negBuff, condition[1], condition[2]) + return compare(OvalePaperDoll.attackPower, condition[1], condition[2]) end --- Get the total count of the given aura across all targets. @@ -1009,7 +1008,7 @@ end OvaleCondition.conditions.damage = function(condition) local spellId = condition[1] - local ret = OvaleData:GetDamage(spellId, UnitAttackPower("player"), GetSpellBonusDamage(2), OvaleState.state.combo) + local ret = OvaleData:GetDamage(spellId, OvalePaperDoll.attackPower, OvalePaperDoll.spellBonusDamage, OvaleState.state.combo) return 0, nil, ret * OvaleAura:GetDamageMultiplier(spellId), 0, 0 end @@ -1874,11 +1873,7 @@ end -- Spell(rake) OvaleCondition.conditions.mastery = function(condition) - local mastery = 0 - if OvaleData.level >= 80 then - mastery = GetMasteryEffect() - end - return compare(mastery, condition[1], condition[2]) + return compare(OvalePaperDoll.masteryEffect, condition[1], condition[2]) end --- Get the amount of health points of the target when it is at full health. @@ -2347,7 +2342,7 @@ end -- Spell(living_bomb) OvaleCondition.conditions.spellpower = function(condition) - return compare(GetSpellBonusDamage(2), condition[1], condition[2]) + return compare(OvalePaperDoll.spellBonusDamage, condition[1], condition[2]) end --- Test if the player is in a given stance. @@ -2472,7 +2467,7 @@ OvaleCondition.auraConditions.tickvalue = true OvaleCondition.conditions.ticks = function(condition) -- TODO: extend to allow checking an existing DoT (how to get DoT duration?) local spellId = condition[1] - local duration, tickLength = OvaleData:GetDuration(spellId, OvaleAura.spellHaste, OvaleState.state.combo, OvaleState.state.holy) + local duration, tickLength = OvaleData:GetDuration(spellId, OvalePaperDoll.spellHaste, OvaleState.state.combo, OvaleState.state.holy) if tickLength then local numTicks = floor(duration / tickLength + 0.5) return compare(numTicks, condition[2], condition[3]) @@ -2538,7 +2533,7 @@ OvaleCondition.auraConditions.ticksremain = true OvaleCondition.conditions.ticktime = function(condition) local start, ending, _, spellHaste = GetTargetAura(condition, getTarget(condition.target)) if not start or not ending or start > OvaleState.currentTime or ending < OvaleState.currentTime then - spellHaste = OvaleAura.spellHaste + spellHaste = OvalePaperDoll.spellHaste end local tickLength = OvaleData:GetTickLength(condition[1], spellHaste) if tickLength then diff --git a/OvaleData.lua b/OvaleData.lua index 9c5cbb3..12c5098 100644 --- a/OvaleData.lua +++ b/OvaleData.lua @@ -503,7 +503,7 @@ function OvaleData:GetGCD(spellId) if not cd then cd = 1.5 end - cd = cd / OvaleAura.spellHaste + cd = cd / (1 + OvalePaperDoll.spellHaste) if (cd<1) then cd = 1 end @@ -518,7 +518,7 @@ function OvaleData:GetGCD(spellId) return 1.0 elseif self.className == "MAGE" or self.className == "WARLOCK" or self.className == "PRIEST" or (self.className == "DRUID" and GetShapeshiftForm(true) ~= 1) then - local cd = 1.5 / OvaleAura.spellHaste + local cd = 1.5 / (1 + OvalePaperDoll.spellHaste) if (cd<1) then cd = 1 end @@ -586,7 +586,7 @@ function OvaleData:GetDuration(spellId, spellHaste, combo, holy) local si = self.spellInfo[spellId] if si and si.duration then local duration = si.duration - spellHaste = spellHaste or 1 + spellHaste = spellHaste or 0 combo = combo or 0 holy = holy or 1 if si.adddurationcp then @@ -611,10 +611,12 @@ end function OvaleData:GetTickLength(spellId, spellHaste) local si = self.spellInfo[spellId] if si then - if si.haste ~= "spell" then - return si.tick or 3 + local tick = si.tick or 3 + local haste = spellHaste or 0 + if si.haste == "spell" then + return tick / (1 + haste) else - return (si.tick or 3) / (spellHaste or 1) + return tick end else return nil diff --git a/OvaleFuture.lua b/OvaleFuture.lua index d1135e8..88af9bd 100644 --- a/OvaleFuture.lua +++ b/OvaleFuture.lua @@ -12,9 +12,12 @@ OvaleFuture = LibStub("AceAddon-3.0"):NewAddon("OvaleFuture", "AceEvent-3.0") -- -local ipairs, pairs, strfind, tremove = ipairs, pairs, string.find, table.remove -local GetMasteryEffect, GetSpellBonusDamage = GetMasteryEffect, GetSpellBonusDamage -local GetSpellInfo, UnitAttackPower, UnitBuff = GetSpellInfo, UnitAttackPower, UnitBuff +local ipairs = ipairs +local pairs = pairs +local strfind = string.find +local tremove = table.remove +local GetSpellInfo = GetSpellInfo +local UnitBuff = UnitBuff local UnitGUID = UnitGUID -- @@ -236,14 +239,10 @@ function OvaleFuture:AddSpellToList(spellId, lineId, startTime, endTime, channel local si = OvaleData.spellInfo[spellId] self.lastSpellId = spellId - self.lastSpellAP[spellId] = UnitAttackPower("player") - self.lastSpellSP[spellId] = GetSpellBonusDamage(2) + self.lastSpellAP[spellId] = OvalePaperDoll.attackPower + self.lastSpellSP[spellId] = OvalePaperDoll.spellBonusDamage self.lastSpellDM[spellId] = OvaleAura:GetDamageMultiplier(spellId) - if OvaleData.level < 80 then - self.lastSpellMastery[spellId] = 0 - else - self.lastSpellMastery[spellId] = GetMasteryEffect() - end + self.lastSpellMastery[spellId] = OvalePaperDoll.masteryEffect self.lastSpell[#self.lastSpell+1] = newSpell --Ovale:Print("on ajoute "..spellId..": ".. newSpell.start.." to "..newSpell.stop.." ("..tostring(OvaleState.maintenant)..")" ..#self.lastSpell .. " " ..tostring(newSpell.target)) diff --git a/OvalePaperDoll.lua b/OvalePaperDoll.lua new file mode 100644 index 0000000..8af05ed --- /dev/null +++ b/OvalePaperDoll.lua @@ -0,0 +1,161 @@ +--[[-------------------------------------------------------------------- + Ovale Spell Priority + Copyright (C) 2013 Johnny C. Lam + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License in the LICENSE + file accompanying this program. +--]]-------------------------------------------------------------------- + +-- This addon tracks the player's stats as available on the in-game paper doll. + +OvalePaperDoll = LibStub("AceAddon-3.0"):NewAddon("OvalePaperDoll", "AceEvent-3.0") + +-- +local Ovale = LibStub("AceAddon-3.0"):GetAddon("Ovale") + +local GetMasteryEffect = GetMasteryEffect +local GetMeleeHaste = GetMeleeHaste +local GetSpellBonusDamage = GetSpellBonusDamage +local GetSpellBonusHealing = GetSpellBonusHealing +local UnitAttackPower = UnitAttackPower +local UnitClass = UnitClass +local UnitRangedAttackPower = UnitRangedAttackPower +local UnitSpellHaste = UnitSpellHaste +local UnitStat = UnitStat +-- + +-- +-- primary stats +OvalePaperDoll.agility = 0 +OvalePaperDoll.intellect = 0 +OvalePaperDoll.spirit = 0 +OvalePaperDoll.stamina = 0 +OvalePaperDoll.strength = 0 + +-- secondary stats +OvalePaperDoll.attackPower = 0 +OvalePaperDoll.rangedAttackPower = 0 +-- percent increase of effect due to mastery +OvalePaperDoll.masteryEffect = 0 +-- percent increase to melee haste +OvalePaperDoll.meleeHaste = 0 +-- percent increase to spell haste +OvalePaperDoll.spellHaste = 0 +-- spellpower +OvalePaperDoll.spellBonusDamage = 0 +OvalePaperDoll.spellBonusHealing = 0 +-- + +-- +function OvalePaperDoll:OnEnable() + self:RegisterEvent("MASTERY_UPDATE") + self:RegisterEvent("PLAYER_ENTERING_WORLD") + self:RegisterEvent("UNIT_ATTACK_POWER") + self:RegisterEvent("UNIT_RANGED_ATTACK_POWER") + self:RegisterEvent("UNIT_SPELL_HASTE") + self:RegisterEvent("UNIT_SPELL_POWER") + self:RegisterEvent("UNIT_STATS") +end + +function OvalePaperDoll:OnDisable() + self:UnregisterEvent("MASTERY_UPDATE") + self:UnregisterEvent("PLAYER_ENTERING_WORLD") + self:UnregisterEvent("UNIT_ATTACK_POWER") + self:UnregisterEvent("UNIT_RANGED_ATTACK_POWER") + self:UnregisterEvent("UNIT_SPELL_HASTE") + self:UnregisterEvent("UNIT_SPELL_POWER") + self:UnregisterEvent("UNIT_STATS") +end + +function OvalePaperDoll:MASTERY_UPDATE(event) + if OvaleData.level < 80 then + self.masteryEffect = 0 + else + self.masteryEffect = GetMasteryEffect() + end +end + +function OvalePaperDoll:PLAYER_ENTERING_WORLD(event) + self:MASTERY_UPDATE(event) + self:UNIT_ATTACK_POWER(event, "player") + self:UNIT_RANGED_ATTACK_POWER(event, "player") + self:UNIT_SPELL_HASTE(event, "player") + self:UNIT_SPELL_POWER(event, "player") + self:UNIT_STATS(event, "player") +end + +function OvalePaperDoll:UNIT_ATTACK_POWER(event, unitId) + if unitId ~= "player" then return end + local base, posBuff, negBuff = UnitAttackPower(unitId) + self.attackPower = base + posBuff + negBuff +end + +function OvalePaperDoll:UNIT_RANGED_ATTACK_POWER(event, unitId) + if unitId ~= "player" then return end + local base, posBuff, negBuff = UnitRangedAttackPower(unitId) + self.rangedAttackPower = base + posBuff + negBuff +end + +function OvalePaperDoll:UNIT_SPELL_HASTE(event, unitId) + if unitId ~= "player" then return end + self.meleeHaste = GetMeleeHaste() + self.spellHaste = UnitSpellHaste(unitId) +end + +local _, className = UnitClass("player") +local classToSchool = { + DEATHKNIGHT = 4, -- Nature + DRUID = 4, -- Nature + HUNTER = 4, -- Nature + MAGE = 5, -- Frost + MONK = 4, -- Nature + PALADIN = 2, -- Holy + PRIEST = 2, -- Holy + ROGUE = 4, -- Nature + SHAMAN = 4, -- Nature + WARLOCK = 6, -- Shadow + WARRIOR = 4, -- Nature +} +local isHealingClass = { + DRUID = true, + MONK = true, + PALADIN = true, + PRIEST = true, + SHAMAN = true, +} + +function OvalePaperDoll:UNIT_SPELL_POWER(event, unitId) + if unitId ~= "player" then return end + self.spellBonusDamage = GetSpellBonusDamage(classToSchool[className]) + if isHealingClass[className] then + self.spellBonusHealing = GetSpellBonusHealing() + else + self.spellBonusHealing = self.spellBonusDamage + end +end + +function OvalePaperDoll:UNIT_STATS(event, unitId) + if unitId ~= "player" then return end + self.strength = UnitStat(unitId, 1) + self.agility = UnitStat(unitId, 2) + self.stamina = UnitStat(unitId, 3) + self.intellect = UnitStat(unitId, 4) + self.spirit = UnitStat(unitId, 5) +end + +function OvalePaperDoll:Debug() + Ovale:Print("Agility: " ..self.agility) + Ovale:Print("Intellect: " ..self.intellect) + Ovale:Print("Spirit: " ..self.spirit) + Ovale:Print("Stamina: " ..self.stamina) + Ovale:Print("Strength: " ..self.strength) + Ovale:Print("AP: " ..self.attackPower) + Ovale:Print("RAP: " ..self.rangedAttackPower) + Ovale:Print("Spell bonus damage: " ..self.spellBonusDamage) + Ovale:Print("Spell bonus healing: " ..self.spellBonusHealing) + Ovale:Print("Spell haste effect: " ..self.spellHaste.. "%") + Ovale:Print("Melee haste effect: " ..self.meleeHaste.. "%") + Ovale:Print("Mastery effect: " ..self.masteryEffect.. "%") +end +-- diff --git a/OvaleState.lua b/OvaleState.lua index d11b018..c229943 100644 --- a/OvaleState.lua +++ b/OvaleState.lua @@ -52,7 +52,7 @@ function OvaleState:UpdatePowerRates() self.powerRate[k] = 0 end - self.powerRate.energy = 10 * OvaleAura.meleeHaste + self.powerRate.energy = 10 * OvalePaperDoll.meleeHaste if OvaleData.className == "MONK" then -- Ascension (monk) @@ -71,7 +71,7 @@ function OvaleState:UpdatePowerRates() self.powerRate.energy = self.powerRate.energy * 2 end - self.powerRate.focus = 4 * OvaleAura.meleeHaste + self.powerRate.focus = 4 * OvalePaperDoll.meleeHaste end function OvaleState:Reset() @@ -318,7 +318,7 @@ function OvaleState:AddSpellToStack(spellId, startCast, endCast, nextCast, nocd, -- Set the duration to the proper length if it's a DoT. if auraSpellInfo and auraSpellInfo.duration then - duration = OvaleData:GetDuration(auraSpellId, OvaleAura.spellHaste, self.state.combo, self.state.holy) + duration = OvaleData:GetDuration(auraSpellId, OvalePaperDoll.spellHaste, self.state.combo, self.state.holy) end -- If aura is specified with a duration, then assume stacks == 1. @@ -350,7 +350,7 @@ function OvaleState:AddSpellToStack(spellId, startCast, endCast, nextCast, nocd, local tickLength = OvaleData:GetTickLength(auraSpellId, previousAura.spellHaste) local k = floor((previousAura.ending - endCast) / tickLength) newAura.ending = previousAura.ending - tickLength * k + duration - newAura.spellHaste = OvaleAura.spellHaste + newAura.spellHaste = OvalePaperDoll.spellHaste else newAura.ending = endCast + duration end @@ -375,7 +375,7 @@ function OvaleState:AddSpellToStack(spellId, startCast, endCast, nextCast, nocd, newAura.start = endCast newAura.ending = endCast + duration if isDoT then - newAura.spellHaste = OvaleAura.spellHaste + newAura.spellHaste = OvalePaperDoll.spellHaste end end end -- 1.7.9.5