Skip to content

Commit

Permalink
Rebuilt ranged haste calculation
Browse files Browse the repository at this point in the history
  • Loading branch information
SabineWren committed Nov 10, 2023
1 parent 0c10567 commit 1c42f68
Show file tree
Hide file tree
Showing 8 changed files with 87 additions and 78 deletions.
78 changes: 15 additions & 63 deletions Lib/Aura.lua
Original file line number Diff line number Diff line change
@@ -1,54 +1,3 @@
local resetTooltip = (function()
local tooltip = nil
local createTooltip = function()
-- https://wowwiki-archive.fandom.com/wiki/UIOBJECT_GameTooltip
tt = CreateFrame("GameTooltip", "QuiverAuraScanningTooltip", nil, "GameTooltipTemplate")
tt:SetScript("OnHide", function() tt:SetOwner(WorldFrame, "ANCHOR_NONE") end)
tt:Hide()
tt:SetFrameStrata("Tooltip")
return tt
end
return function()
if not tooltip then tooltip = createTooltip() end
tooltip:SetOwner(WorldFrame, "ANCHOR_NONE")
return tooltip
end
end)()

-- 10% at full hp, to a max of 30% at 40% hp
-- That's a line with equation f(hp)= (130-hp) / 3, but capped at 30%
local getTrollBerserkBonus = function()
local percent = UnitHealth("player") / UnitHealthMax("player")
return math.min(0.3, (1.30 - percent) / 3.0)
end

--[[
UnitBuff indexes from 1.
GetPlayerBuffTexture indexes from 0.
They also don't have the same iteration order.
Haven't found a reason to use one over the other. ]]
Quiver_Lib_Aura_GetRangedAttackSpeedMultiplier = function()
local speed = 1.0
for i=1,QUIVER.Buff_Cap do
local texture = UnitBuff("player", i)
if texture == QUIVER.Icon.CurseOfTongues then
speed = speed * 0.5
-- Unsure if it's safe to remove the wrong one. Maybe that would break other servers.
elseif texture == QUIVER.Icon.NaxxTrinket
or texture == QUIVER.Icon.NaxxTrinketWrong
then
speed = speed * 1.2
elseif texture == QUIVER.Icon.Quickshots then
speed = speed * 1.3
elseif texture == QUIVER.Icon.RapidFire then
speed = speed * 1.4
elseif texture == QUIVER.Icon.TrollBerserk then
speed = speed * (1.0 + getTrollBerserkBonus())
end
end
return speed
end

-- This doesn't work for duplicate textures (ex. cheetah + zg mount).
-- For those you have to scan by name using the GameTooltip.
Quiver_Lib_Aura_GetIsActiveTimeLeftByTexture = function(targetTexture)
Expand All @@ -64,21 +13,24 @@ Quiver_Lib_Aura_GetIsActiveTimeLeftByTexture = function(targetTexture)
return false, 0
end

Quiver_Lib_Aura_GetIsBuffActive = function(buffname)
local tooltip = resetTooltip()
for i=0,QUIVER.Buff_Cap do
local buffIndex, isCancellable = GetPlayerBuff(i, "HELPFUL|PASSIVE")
if buffIndex >= 0 then
tooltip:ClearLines()
tooltip:SetPlayerBuff(buffIndex)
local fs1 = _G["QuiverAuraScanningTooltipTextLeft1"]
if fs1 and fs1:GetText() == buffname then
return true
Quiver_Lib_Aura_GetIsBuffActive = (function()
local resetTooltip = Quiver_Lib_Tooltip_Factory("QuiverAuraScanningTooltip")
return function(buffname)
local tooltip = resetTooltip()
for i=0,QUIVER.Buff_Cap do
local buffIndex, isCancellable = GetPlayerBuff(i, "HELPFUL|PASSIVE")
if buffIndex >= 0 then
tooltip:ClearLines()
tooltip:SetPlayerBuff(buffIndex)
local fs1 = _G["QuiverAuraScanningTooltipTextLeft1"]
if fs1 and fs1:GetText() == buffname then
return true
end
end
end
return false
end
return false
end
end)()

-- This works great. Don't delete because I'm sure it will be useful in the future.
--[[
Expand Down
53 changes: 43 additions & 10 deletions Lib/Spellbook.lua
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
-- TODO parse spellbook in case a patch changes them, instead of hard-coding here
local HUNTER_CASTABLE_SHOTS = {
[QUIVER_T.Spellbook.Aimed_Shot] = 3.0,
[QUIVER_T.Spellbook.Multi_Shot] = 0.5,
[QUIVER_T.Spellbook.Trueshot] = 1.3,
[QUIVER_T.Spellbook.Multi_Shot] = 0.0,
[QUIVER_T.Spellbook.Trueshot] = 1.0,
}

local _HUNTER_INSTANT_SHOTS = {
Expand All @@ -14,6 +15,46 @@ local _HUNTER_INSTANT_SHOTS = {
QUIVER_T.Spellbook.Wyvern_Sting,
}

local calcRangedWeaponSpeedBase = (function()
local resetTooltip = Quiver_Lib_Tooltip_Factory("QuiverRangedWeaponScanningTooltip")

-- Might be cachable. GetInventoryItemLink("Player", slot#) returns a link, ex. [name]
-- Weapon name always appears at line TextLeft1
return function()
local tooltip = resetTooltip()
tooltip:ClearLines()
tooltip:SetInventoryItem("player", 18)-- ranged weapon slot

for i=1, tooltip:NumLines() do
local fs = _G["QuiverRangedWeaponScanningTooltipTextRight"..i]
local text = fs and fs:GetText()
if text ~= nil then
local _, _, speed = string.find(text, "Speed (%d+%.%d+)")
if speed ~= nil then
local parsed = tonumber(speed)
if parsed ~= nil then
return parsed
end
end
end
end
end
end)()

Quiver_Lib_Spellbook_CalcCastTime = function(spellName)
local baseTime = HUNTER_CASTABLE_SHOTS[spellName]
local _,_, msLatency = GetNetStats()
local start = GetTime() + msLatency / 1000

local speedCurrent = UnitRangedDamage("player")
local speedBase = calcRangedWeaponSpeedBase()
local speedMultiplier = speedCurrent / speedBase

-- https://www.mmo-champion.com/content/2188-Patch-4-0-6-Feb-22-Hotfixes-Blue-Posts-Artworks-Comic
local casttime = 0.5 + baseTime * speedMultiplier
return casttime, start
end

local GetIsSpellLearned = function(spellName)
local i = 0
while true do
Expand Down Expand Up @@ -66,14 +107,6 @@ Quiver_Lib_Spellbook_TryFindTexture = function(nameSeek)
end
end

Quiver_Lib_Spellbook_GetCastTime = function(spellName)
local baseTime = HUNTER_CASTABLE_SHOTS[spellName]
local _,_, msLatency = GetNetStats()
local start = GetTime() + msLatency / 1000
local casttime = baseTime / Quiver_Lib_Aura_GetRangedAttackSpeedMultiplier()
return casttime, start
end

Quiver_Lib_Spellbook_GetIsSpellCastableShot = function(spellName)
for name, _castTime in HUNTER_CASTABLE_SHOTS do
if spellName == name then return true end
Expand Down
21 changes: 21 additions & 0 deletions Lib/Tooltip.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
local createTooltip = function(frameName)
-- https://wowwiki-archive.fandom.com/wiki/UIOBJECT_GameTooltip
local tt = CreateFrame("GameTooltip", frameName, nil, "GameTooltipTemplate")
tt:SetScript("OnHide", function() tt:SetOwner(WorldFrame, "ANCHOR_NONE") end)
tt:Hide()
tt:SetFrameStrata("Tooltip")
return tt
end

--[[ [ Quiver_Lib_Tooltip_Factory ]
@description Returns a function that clears the tooltip and gets a reference to it.
@param frameName string name for tooltip element
]]
Quiver_Lib_Tooltip_Factory = function(frameName)
local tooltip = nil
return function()
if not tooltip then tooltip = createTooltip(frameName) end
tooltip:SetOwner(WorldFrame, "ANCHOR_NONE")
return tooltip
end
end
2 changes: 1 addition & 1 deletion Modules/AutoShotTimer.lua
Original file line number Diff line number Diff line change
Expand Up @@ -191,7 +191,7 @@ local onSpellcast = function(spellName)
if isShooting and (not isReloading) then
timeStartShootOrReload = GetTime()
end
castTime, timeStartCast = Quiver_Lib_Spellbook_GetCastTime(spellName)
castTime, timeStartCast = Quiver_Lib_Spellbook_CalcCastTime(spellName)
end

local handleEvent = function()
Expand Down
4 changes: 2 additions & 2 deletions Modules/Castbar.lua
Original file line number Diff line number Diff line change
Expand Up @@ -83,12 +83,12 @@ end
-- ************ Custom Event Handlers ************
local displayTime = function(current)
if current < 0 then current = 0 end
frame.SpellTime:SetText(string.format("%.1f / %.1f", current, castTime))
frame.SpellTime:SetText(string.format("%.1f / %.2f", current, castTime))
end
local onSpellcast = function(spellName)
if isCasting then return end
isCasting = true
castTime, timeStartCasting = Quiver_Lib_Spellbook_GetCastTime(spellName)
castTime, timeStartCasting = Quiver_Lib_Spellbook_CalcCastTime(spellName)
frame.SpellName:SetText(spellName)
frame.Castbar:SetWidth(1)
displayTime(0)
Expand Down
2 changes: 1 addition & 1 deletion Modules/pfUIPlugins.lua
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ Quiver_Module_pfUITurtleTrueshot = function()
-- Somehow player isn't defined, but all the other locals from pfUI work
local player = UnitName("player")
if begin then
local castTime, start = Quiver_Lib_Spellbook_GetCastTime(QUIVER_T.Spellbook.Trueshot)
local castTime, start = Quiver_Lib_Spellbook_CalcCastTime(QUIVER_T.Spellbook.Trueshot)
local duration = duration or (castTime * 1000)
-- add cast action to the database
libcast.db[player].cast = trueshotName
Expand Down
2 changes: 2 additions & 0 deletions Quiver.lua
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,14 @@ _G.Quiver_Modules = {
}

local savedVariablesRestore = function()
-- If first time running Quiver, then savedVars are nil, so make defaults
Quiver_Store.IsLockedFrames = Quiver_Store.IsLockedFrames == true
Quiver_Store.ModuleEnabled = Quiver_Store.ModuleEnabled or {}
Quiver_Store.ModuleStore = Quiver_Store.ModuleStore or {}
for _k, v in _G.Quiver_Modules do
Quiver_Store.ModuleEnabled[v.Id] = Quiver_Store.ModuleEnabled[v.Id] ~= false
Quiver_Store.ModuleStore[v.Id] = Quiver_Store.ModuleStore[v.Id] or {}
-- Loading saved variables into each module gives them a chance to set their own defaults.
v.OnSavedVariablesRestore(Quiver_Store.ModuleStore[v.Id])
end
end
Expand Down
3 changes: 2 additions & 1 deletion Quiver.toc
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,14 @@
## Title: Quiver - |cff00ff00Hunter
## Notes: A collection of hunter utilities.
## Author: SabineWren, 2022-2023
## Version: 2.6.1
## Version: 2.6.2
## SavedVariables: Quiver_Store

Lib\F.lua
Constants.lua
Locale\enUS.lua

Lib\Tooltip.lua
Lib\Aura.lua
Lib\Print.lua
Lib\Spellbook.lua
Expand Down

0 comments on commit 1c42f68

Please sign in to comment.