Blood Druid |
02-04-09 07:41 AM |
Would like to bring up once again a question on an applied method of reception safezone:
today I had a fine possibility to be convinced that the applied method of reception the incorrect.
Certainly the question in that for what is it for Haste?
I tested it on Wintergrasp where logs are ideal for similar testing:)
My ping on GetNetStats() was 83ms, but thus on cast there was a delay in some seconds, and on castes a bar I was displayed small safezone corresponding ping 83ms.
Now I wish to offer a method which already was discussed, I tell about UNIT_SPELLCAST_SENT
Applying the given method I have received correct result of calculation Lags.
Can it is necessary to pass to this method, Haste?
Here an example copied by me castbar.lua:
Code:
--[[
Original codebase:
oUF_Castbar by starlon.
http://svn.wowace.com/wowace/trunk/oUF_Castbar/
Elements handled: .Castbar
Sub-elements: .Text, .Icon, .Time, .SafeZone, .Spark
Notes: This element will not work on units that require a OnUpdate.
(eventless units).
Functions that can be overridden from within a layout:
- :CustomDelayText(duration)
- :CustomTimeText(duration)
--]]
local parent = debugstack():match[[\AddOns\(.-)\]]
local global = GetAddOnMetadata(parent, 'X-oUF')
assert(global, 'X-oUF needs to be defined in the parent add-on.')
local oUF = _G[global]
local noop = function() end
local UnitName = UnitName
local GetTime = GetTime
local UnitCastingInfo = UnitCastingInfo
local UnitChannelInfo = UnitChannelInfo
local UNIT_SPELLCAST_SENT = function(self, event, unit)
if (unit == 'player') and (self.Castbar.SafeZone) then
self.Castbar.SafeZone.sendTime = GetTime()
end
end
local UNIT_SPELLCAST_START = function(self, event, unit, spell, spellrank)
if(self.unit ~= unit) then return end
local castbar = self.Castbar
local name, rank, text, texture, startTime, endTime, _, castid = UnitCastingInfo(unit)
if(not name) then
castbar:Hide()
return
end
endTime = endTime / 1e3
startTime = startTime / 1e3
local max = endTime - startTime
castbar.castid = castid
castbar.duration = GetTime() - startTime
castbar.max = max
castbar.delay = 0
castbar.casting = true
castbar:SetMinMaxValues(0, max)
castbar:SetValue(0)
if(castbar.Text) then castbar.Text:SetText(text) end
if(castbar.Icon) then castbar.Icon:SetTexture(texture) end
if(castbar.Time) then castbar.Time:SetText() end
local sf = castbar.SafeZone
if(sf) then
sf.timeDiff = GetTime() - sf.sendTime
sf.spellTimeSize = max
sf.timeDiff = sf.timeDiff > sf.spellTimeSize and sf.spellTimeSize or sf.timeDiff
sf.lagSize = sf.timeDiff / sf.spellTimeSize
sf:ClearAllPoints()
sf:SetPoint('BOTTOMRIGHT', castbar, 'BOTTOMRIGHT')
sf:SetWidth((castbar:GetWidth()) * sf.lagSize)
sf.Text:ClearAllPoints()
sf.Text:SetPoint('BOTTOMRIGHT', sf, 'TOPRIGHT', 0, 2)
sf.Text:SetJustifyH('RIGHT')
sf.Text:SetFormattedText('%dms', sf.timeDiff * 1000)
end
if(self.PostCastStart) then self:PostCastStart(event, unit, name, rank, text, castid) end
castbar:Show()
end
local UNIT_SPELLCAST_FAILED = function(self, event, unit, spellname, spellrank, castid)
if(self.unit ~= unit) then return end
local castbar = self.Castbar
if(castbar.castid ~= castid) then
return
end
castbar.casting = nil
castbar:SetValue(0)
castbar:Hide()
if(self.PostCastFailed) then self:PostCastFailed(event, unit, spellname, spellrank, castid) end
end
local UNIT_SPELLCAST_INTERRUPTED = function(self, event, unit, spellname, spellrank, castid)
if(self.unit ~= unit) then return end
local castbar = self.Castbar
if(castbar.castid ~= castid) then
return
end
castbar.casting = nil
castbar.channeling = nil
castbar:SetValue(0)
castbar:Hide()
if(self.PostCastInterrupted) then self:PostCastInterrupted(event, unit, spellname, spellrank, castid) end
end
local UNIT_SPELLCAST_DELAYED = function(self, event, unit, spellname, spellrank)
if(self.unit ~= unit) then return end
local name, rank, text, texture, startTime, endTime = UnitCastingInfo(unit)
if(not startTime) then return end
local castbar = self.Castbar
local duration = GetTime() - (startTime / 1000)
if(duration < 0) then duration = 0 end
castbar.delay = castbar.delay + castbar.duration - duration
castbar.duration = duration
castbar:SetValue(duration)
if(self.PostCastDelayed) then self:PostCastDelayed(event, unit, name, rank, text) end
end
local UNIT_SPELLCAST_STOP = function(self, event, unit, spellname, spellrank, castid)
if(self.unit ~= unit) then return end
local castbar = self.Castbar
if(castbar.castid ~= castid) then
return
end
castbar.casting = nil
castbar:SetValue(0)
castbar:Hide()
if(self.PostCastStop) then self:PostCastStop(event, unit, spellname, spellrank, castid) end
end
local UNIT_SPELLCAST_CHANNEL_START = function(self, event, unit, spellname, spellrank)
if(self.unit ~= unit) then return end
local castbar = self.Castbar
local name, rank, text, texture, startTime, endTime = UnitChannelInfo(unit)
if(not name) then
return
end
endTime = endTime / 1e3
startTime = startTime / 1e3
local max = (endTime - startTime)
local duration = endTime - GetTime()
castbar.duration = duration
castbar.max = max
castbar.delay = 0
castbar.channeling = true
castbar:SetMinMaxValues(0, max)
castbar:SetValue(duration)
if(castbar.Text) then castbar.Text:SetText(name) end
if(castbar.Icon) then castbar.Icon:SetTexture(texture) end
if(castbar.Time) then castbar.Time:SetText() end
local sf = castbar.SafeZone
if(sf) then
sf.timeDiff = GetTime() - sf.sendTime
sf.spellTimeSize = max
sf.timeDiff = sf.timeDiff > sf.spellTimeSize and sf.spellTimeSize or sf.timeDiff
sf.lagSize = sf.timeDiff / sf.spellTimeSize
sf:ClearAllPoints()
sf:SetPoint('BOTTOMLEFT', castbar, 'BOTTOMLEFT')
sf:SetWidth((castbar:GetWidth()) * sf.lagSize)
sf.Text:ClearAllPoints()
sf.Text:SetPoint('BOTTOMLEFT', sf, 'TOPLEFT', 0, 2)
sf.Text:SetJustifyH('LEFT')
sf.Text:SetFormattedText('%dms', sf.timeDiff * 1000)
sf:Show()
end
if(self.PostChannelStart) then self:PostChannelStart(event, unit, name, rank, text) end
castbar:Show()
end
local UNIT_SPELLCAST_CHANNEL_UPDATE = function(self, event, unit, spellname, spellrank)
if(self.unit ~= unit) then return end
local name, rank, text, texture, startTime, endTime, oldStart = UnitChannelInfo(unit)
local castbar = self.Castbar
local duration = (endTime / 1000) - GetTime()
castbar.delay = castbar.delay + castbar.duration - duration
castbar.duration = duration
castbar.max = (endTime - startTime) / 1000
castbar:SetMinMaxValues(0, castbar.max)
castbar:SetValue(duration)
if(self.PostChannelUpdate) then self:PostChannelUpdate(event, unit, name, rank, text) end
end
local UNIT_SPELLCAST_CHANNEL_STOP = function(self, event, unit, spellname, spellrank)
if(self.unit ~= unit) then return end
local castbar = self.Castbar
castbar.channeling = nil
castbar:SetValue(castbar.max)
castbar:Hide()
if(self.PostChannelStop) then self:PostChannelStop(event, unit, spellname, spellrank) end
end
local onUpdate = function(self, elapsed)
if self.casting then
local duration = self.duration + elapsed
if (duration >= self.max) then
self.casting = nil
self:Hide()
end
if self.SafeZone then
local width = self:GetWidth()
local _, _, ms = GetNetStats()
-- MADNESS!
local safeZonePercent = (width / self.max) * (ms / 1e5)
if(safeZonePercent > 1) then safeZonePercent = 1 end
self.SafeZone:SetWidth(width * safeZonePercent)
end
if self.Time then
if self.delay ~= 0 then
if(self.CustomDelayText) then
self:CustomDelayText(duration)
else
self.Time:SetFormattedText("%.1f|cffff0000-%.1f|r", duration, self.delay)
end
else
if(self.CustomTimeText) then
self:CustomTimeText(duration)
else
self.Time:SetFormattedText("%.1f", duration)
end
end
end
self.duration = duration
self:SetValue(duration)
if self.Spark then
self.Spark:SetPoint("CENTER", self, "LEFT", (duration / self.max) * self:GetWidth(), 0)
end
elseif self.channeling then
local duration = self.duration - elapsed
if(duration <= 0) then
self.channeling = nil
self:Hide()
return
end
if(self.SafeZone) then
local width = self:GetWidth()
local _, _, ms = GetNetStats()
-- MADNESS!
local safeZonePercent = (width / self.max) * (ms / 1e5)
if(safeZonePercent > 1) then safeZonePercent = 1 end
self.SafeZone:SetWidth(width * safeZonePercent)
end
if self.Time then
if self.delay ~= 0 then
if(self.CustomDelayText) then
self:CustomDelayText(duration)
else
self.Time:SetFormattedText("%.1f|cffff0000-%.1f|r", duration, self.delay)
end
else
if(self.CustomTimeText) then
self:CustomTimeText(duration)
else
self.Time:SetFormattedText("%.1f", duration)
end
end
end
self.duration = duration
self:SetValue(duration)
if self.Spark then
self.Spark:SetPoint("CENTER", self, "LEFT", (duration / self.max) * self:GetWidth(), 0)
end
else
self.unitName = nil
self.channeling = nil
self:SetValue(1)
self:Hide()
end
end
local Enable = function(object, unit)
local castbar = object.Castbar
if(unit and unit:match'%wtarget$') then return end
if(castbar) then
object:RegisterEvent("UNIT_SPELLCAST_SENT", UNIT_SPELLCAST_SENT)
object:RegisterEvent("UNIT_SPELLCAST_START", UNIT_SPELLCAST_START)
object:RegisterEvent("UNIT_SPELLCAST_FAILED", UNIT_SPELLCAST_FAILED)
object:RegisterEvent("UNIT_SPELLCAST_STOP", UNIT_SPELLCAST_STOP)
object:RegisterEvent("UNIT_SPELLCAST_INTERRUPTED", UNIT_SPELLCAST_INTERRUPTED)
object:RegisterEvent("UNIT_SPELLCAST_DELAYED", UNIT_SPELLCAST_DELAYED)
object:RegisterEvent("UNIT_SPELLCAST_CHANNEL_START", UNIT_SPELLCAST_CHANNEL_START)
object:RegisterEvent("UNIT_SPELLCAST_CHANNEL_UPDATE", UNIT_SPELLCAST_CHANNEL_UPDATE)
object:RegisterEvent("UNIT_SPELLCAST_CHANNEL_INTERRUPTED", 'UNIT_SPELLCAST_INTERRUPTED')
object:RegisterEvent("UNIT_SPELLCAST_CHANNEL_STOP", UNIT_SPELLCAST_CHANNEL_STOP)
castbar.parent = object
castbar:SetScript("OnUpdate", object.OnCastbarUpdate or onUpdate)
if object.unit == "player" then
CastingBarFrame:UnregisterAllEvents()
CastingBarFrame.Show = noop
CastingBarFrame:Hide()
elseif(object.unit == 'pet') then
PetCastingBarFrame:UnregisterAllEvents()
PetCastingBarFrame.Show = noop
PetCastingBarFrame:Hide()
end
if(not castbar:GetStatusBarTexture()) then
castbar:SetStatusBarTexture[[Interface\TargetingFrame\UI-StatusBar]]
end
local spark = castbar.Spark
if(spark and spark:IsObjectType'Texture' and not spark:GetTexture()) then
spark:SetTexture[[Interface\CastingBar\UI-CastingBar-Spark]]
end
local sz = castbar.SafeZone
if(sz and sz:IsObjectType'Texture' and not sz:GetTexture()) then
sz:SetTexture(1, 0, 0)
end
castbar:Hide()
return true
end
end
local Disable = function(object, unit)
local castbar = object.Castbar
if(castbar) then
object:UnregisterEvent("UNIT_SPELLCAST_SENT", UNIT_SPELLCAST_SENT)
object:UnregisterEvent("UNIT_SPELLCAST_START", UNIT_SPELLCAST_START)
object:UnregisterEvent("UNIT_SPELLCAST_FAILED", UNIT_SPELLCAST_FAILED)
object:UnregisterEvent("UNIT_SPELLCAST_STOP", UNIT_SPELLCAST_STOP)
object:UnregisterEvent("UNIT_SPELLCAST_INTERRUPTED", UNIT_SPELLCAST_INTERRUPTED)
object:UnregisterEvent("UNIT_SPELLCAST_DELAYED", UNIT_SPELLCAST_DELAYED)
object:UnregisterEvent("UNIT_SPELLCAST_CHANNEL_START", UNIT_SPELLCAST_CHANNEL_START)
object:UnregisterEvent("UNIT_SPELLCAST_CHANNEL_UPDATE", UNIT_SPELLCAST_CHANNEL_UPDATE)
object:UnregisterEvent("UNIT_SPELLCAST_CHANNEL_INTERRUPTED", UNIT_SPELLCAST_CHANNEL_INTERRUPTED)
object:UnregisterEvent("UNIT_SPELLCAST_CHANNEL_STOP", UNIT_SPELLCAST_CHANNEL_STOP)
castbar.parent = nil
castbar:SetScript("OnUpdate", nil)
end
end
oUF:AddElement('Castbar', function(...)
UNIT_SPELLCAST_START(...)
UNIT_SPELLCAST_CHANNEL_START(...)
end, Enable, Disable)
I did not change function OnUpdate, since I use the in the Layout...
Here my function OnUpdate:
Code:
local CastbarUpdate = function(self, elapsed)
if self.casting then
local duration = self.duration + elapsed
if (duration >= self.max) then
self.casting = nil
self:Hide()
return
end
if self.Time then
if self.parent.unit == 'player' then
if self.delay ~= 0 then
self.Time:SetFormattedText('%.1f/|cffff0000%.1f|r', duration, self.max + self.delay)
else
self.Time:SetFormattedText('%.1f/%.1f', duration, self.max)
end
else
self.Time:SetFormattedText('%.1f/%.1f', duration, self.max + self.delay)
end
end
self.duration = duration
self:SetValue(duration)
if self.Spark then
self.Spark:SetPoint('CENTER', self, 'LEFT', (duration / self.max) * self:GetWidth(), 0)
end
elseif self.channeling then
local duration = self.duration - elapsed
if(duration <= 0) then
self.channeling = nil
self:Hide()
return
end
if self.Time then
if self.parent.unit == 'player' then
if self.delay ~= 0 then
self.Time:SetFormattedText('%.1f/|cffff0000%.1f|r', duration, self.max - self.delay)
else
self.Time:SetFormattedText('%.1f/%.1f', duration, self.max)
end
else
self.Time:SetFormattedText('%.1f/%.1f', duration, self.max - self.delay)
end
end
self.duration = duration
self:SetValue(duration)
if self.Spark then
self.Spark:SetPoint('CENTER', self, 'LEFT', (duration / self.max) * self:GetWidth(), 0)
end
else
self.unitName = nil
self.casting = nil
self.channeling = nil
self:SetValue(1)
self:Hide()
end
end
|