/branches/castbar/Aloft/Aloft
-- return -- TODO: watch this carefully |
else |
-- nameplate setup cannot occur during combat, but all of the rest of this can |
-- ChatFrame7:AddMessage("AloftFrame:SetupFrame(): set height/width " .. tostring(nameplateFrame) .. "/" .. tostring(aloftData.name)) |
nameplateFrame:SetWidth(self.db.profile.packingWidth+self.db.profile.width) |
nameplateFrame:SetHeight(self.db.profile.packingHeight+self.db.profile.height) |
if not aloftData.invisible then |
function AloftFrame:OnNameplateShow(message, aloftData) |
-- ChatFrame7:AddMessage("AloftFrame:OnNameplateShow(): " .. tostring(message)) |
-- self:DoNameplateShow(aloftData) |
self:ScheduleTimer(function(aloftData) AloftFrame:DoNameplateShow(aloftData) end, 0.0, aloftData) -- next frame |
self:ScheduleTimer(function(aloftData) AloftFrame:DoNameplateShow(aloftData) end, 0.1, aloftData) -- a bit more than next frame |
-- self:ScheduleTimer(function(aloftData) AloftFrame:DumpCoords(aloftData) end, 0.3, aloftData) |
end |
----------------------------------------------------------------------------- |
--[[ zhTW ]] L["Aloft FuBar support disabled itself because FuBar2Broker is loaded. Will attempt to load Aloft direct LDB support instead."] = "Aloft FuBar support disabled itself because FuBar2Broker is loaded. Will attempt to load Aloft direct LDB support instead." |
--[[ zhTW ]] L["Aloft FuBar support disabled itself because FuBar2Broker is loaded. Will attempt to load Aloft direct LDB support instead."] = "Aloft FuBaræ¯æ´å·²ç¦ç¨å çºBroker2FuBarå·²è¼å ¥ãå°å試è¼å ¥Aloftèä¸æ¯ç´æ¥LDBæ¯æ´ãAloft FuBar support disabled itself because FuBar2Broker is loaded. Will attempt to load Aloft direct LDB support instead." |
--[[ zhTW ]] L["Aloft"] = "Aloft" |
--[[ zhTW ]] L["Fubar Options"] = "Fubar é¸é " |
--[[ zhTW ]] L["Standard FuBar options"] = "æ¨æº Fubar é¸é " |
--[[ zhTW ]] L["Click to toggle nameplates."] = "|cffeda55få·¦æ: |råæåçã" |
--[[ zhTW ]] L["Right-Click to open configuration."] = "|cffeda55fRight-å·¦æ: |ræéè¨å®ã" |
--[[ zhTW ]] L["Fubar Options"] = "Fubar è¨å®" |
--[[ zhTW ]] L["Standard FuBar options"] = "æ¨æº Fubar è¨å®" |
--[[ zhTW ]] L["Click to toggle nameplates."] = "|cffeda55fé»æ: |råæåçã" |
--[[ zhTW ]] L["Right-Click to open configuration."] = "|cffeda55få³éµ-é»æ: |réåè¨å®ã" |
--[[ zhTW ]] L["Hostile Nameplates"] = "æµå°åç" |
--[[ zhTW ]] L["Friendly Nameplates"] = "å好åç" |
--[[ enUS ]] L["Unable to determine module providing data: "] = "Unable to determine module providing data: " |
--[[ enUS ]] L["Internal error: Dependency list not resolved - cyclic dependency?"] = "Internal error: Dependency list not resolved - cyclic dependency?" |
--[[ enUS ]] L["Warning: Tag<->module dependency list not resolved - non-fatal cyclic dependency?"] = "Warning: Tag<->module dependency list not resolved - non-fatal cyclic dependency?" |
-- player states; should match strings in AloftAutoShow/AloftAutoShowOptions.lua and AloftAutoShow localizations |
--[[ enUS ]] L["Combat"] = "Combat" |
--[[ koKR ]] L["Unable to determine module providing data: "] = "ë°ì´í°ë¥¼ ìí 모ëì ê²°ì í ì ììµëë¤: " |
--[[ koKR ]] L["Internal error: Dependency list not resolved - cyclic dependency?"] = "ë´ë¶ì ì¤ë¥: ëª©ë¡ ìì¡´ì±ì´ í´ê²°ëì§ ìììµëë¤ - ìíì ì¸ ìì¡´ì±?" |
--[[ koKR ]] L["Warning: Tag<->module dependency list not resolved - non-fatal cyclic dependency?"] = "Warning: Tag<->module dependency list not resolved - non-fatal cyclic dependency?" |
-- player states; should match strings in AloftAutoShow/AloftAutoShowOptions.lua and AloftAutoShow localizations |
--[[ koKR ]] L["Combat"] = "Combat" |
--[[ ruRU ]] L["Unable to determine module providing data: "] = "Ðевозможно опÑеделиÑÑ Ð¼Ð¾Ð´ÑлÑ, пÑедоÑÑавлÑÑÑий даннÑе" |
--[[ ruRU ]] L["Internal error: Dependency list not resolved - cyclic dependency?"] = "ÐнÑÑÑеннÑÑ Ð¾Ñибка: Ðевозможно ÑазÑеÑиÑÑ ÑпиÑок завиÑимоÑÑей â ÑиклиÑеÑÐºÐ°Ñ Ð·Ð°Ð²Ð¸ÑимоÑÑÑ?" |
--[[ ruRU ]] L["Warning: Tag<->module dependency list not resolved - non-fatal cyclic dependency?"] = "Warning: Tag<->module dependency list not resolved - non-fatal cyclic dependency?" |
-- player states; should match strings in AloftAutoShow/AloftAutoShowOptions.lua and AloftAutoShow localizations |
--[[ ruRU ]] L["Combat"] = "Ðой" |
--[[ zhCN ]] L["Unable to determine module providing data: "] = "æ æ³ç¡®è®¤æä¾æ°æ®ç模å" |
--[[ zhCN ]] L["Internal error: Dependency list not resolved - cyclic dependency?"] = "å é¨é误ï¼æªæ¾å°ä¾èµå表 - æ¯å¦éåä¾èµï¼" |
--[[ zhCN ]] L["Warning: Tag<->module dependency list not resolved - non-fatal cyclic dependency?"] = "Warning: Tag<->module dependency list not resolved - non-fatal cyclic dependency?" |
-- player states; should match strings in AloftAutoShow/AloftAutoShowOptions.lua and AloftAutoShow localizations |
--[[ zhCN ]] L["Combat"] = "ææ" |
----------------------------------------------------------------------------- |
--[[ zhTW ]] L["Aloft"] = "Aloft" |
--[[ zhTW ]] L["Unknown"] = "Unknown" -- unit name for "Unknown" units |
--[[ zhTW ]] L["Unknown"] = "æªç¥" -- unit name for "Unknown" units |
--[[ zhTW ]] L["Level"] = "çç´" |
--[[ zhTW ]] L["Load Options"] = "è¼å ¥é¸é " |
--[[ zhTW ]] L["Load options for Aloft modules"] = "Aloft 模çµçè¼å ¥é¸é " |
--[[ zhTW ]] L["gui"] = "gui" |
--[[ zhTW ]] L["Load Options"] = "è¼å ¥è¨å®" |
--[[ zhTW ]] L["Load options for Aloft modules"] = "Aloft 模çµçè¼å ¥è¨å®" |
--[[ zhTW ]] L["gui"] = "åå½¢ä»é¢" |
-- labels for keybindings; should match strings in AloftAutoShow/AloftAutoShowOptions.lua and AloftAutoShow localizations |
--[[ zhTW ]] L["Show Neutral/Enemy Name Plates"] = "Show Neutral/Enemy Name Plates" |
--[[ zhTW ]] L["Show Friendly Name Plates"] = "Show Friendly Name Plates" |
--[[ zhTW ]] L["Show All Name Plates"] = "Show All Name Plates" |
--[[ zhTW ]] L["Show Neutral/Enemy Name Plates"] = "顯示ä¸ç«/æµå°åç" |
--[[ zhTW ]] L["Show Friendly Name Plates"] = "顯示å好åç" |
--[[ zhTW ]] L["Show All Name Plates"] = "顯示ææåç" |
--[[ zhTW ]] L["Unable to determine module providing data: "] = "ä¸è½æ¸¬å®æ¨¡çµãè³æ: " |
--[[ zhTW ]] L["Internal error: Dependency list not resolved - cyclic dependency?"] = "å §é¨é¯èª¤: 循ç°åé ?" |
--[[ zhTW ]] L["Unable to determine module providing data: "] = "ç¡æ³æ±ºå®æ¨¡çµæä¾çè³æï¼" |
--[[ zhTW ]] L["Internal error: Dependency list not resolved - cyclic dependency?"] = "å §é¨é¯èª¤: ç¸ä¾æ§æ¸ å®æªè§£æ±º - 循ç°ç¸ä¾?" |
--[[ zhTW ]] L["Warning: Tag<->module dependency list not resolved - non-fatal cyclic dependency?"] = "è¦å: æ¨ç±¤<->模çµç¸ä¾æ¸ å®æªè§£æ±º - éè´å½æ§å¾ªç°ç¸ä¾?" |
-- player states; should match strings in AloftAutoShow/AloftAutoShowOptions.lua and AloftAutoShow localizations |
--[[ zhTW ]] L["Combat"] = "æ°æ" |
--[[ zhTW ]] L["Flagged/PvP"] = "Flagged/PvP" |
--[[ zhTW ]] L["Combat"] = "æ°é¬¥" |
--[[ zhTW ]] L["Flagged/PvP"] = "æ¨å¹/PvP" |
--[[ zhTW ]] L["Resting"] = "ä¼æ¯" |
--[[ zhTW ]] L["Group"] = "å°é" |
--[[ zhTW ]] L["Default"] = "é»èª" |
--[[ zhTW ]] L["Group"] = "éä¼" |
--[[ zhTW ]] L["Default"] = "é è¨" |
-- player locations; should match strings in AloftAutoShow/AloftAutoShowOptions.lua and AloftAutoShow localizations |
--[[ zhTW ]] L["Player Location"] = "Player Location" |
--[[ zhTW ]] L["World"] = "World" |
--[[ zhTW ]] L["Battleground"] = "Battleground" |
--[[ zhTW ]] L["Arena"] = "Arena" |
--[[ zhTW ]] L["5-Man Instance"] = "5-Man Instance" |
--[[ zhTW ]] L["Raid Instance"] = "Raid Instance" |
--[[ zhTW ]] L["Player Location"] = "ç©å®¶ä½ç½®" |
--[[ zhTW ]] L["World"] = "ä¸ç" |
--[[ zhTW ]] L["Battleground"] = "æ°å ´" |
--[[ zhTW ]] L["Arena"] = "競æå ´" |
--[[ zhTW ]] L["5-Man Instance"] = "5人å¯æ¬" |
--[[ zhTW ]] L["Raid Instance"] = "åéå¯æ¬" |
----------------------------------------------------------------------------- |
--[[ zhTW ]] dL["shortrareelite"] = "ç¨+" |
--[[ zhTW ]] dL["shortworldboss"] = "é¦" |
--[[ zhTW ]] dL["Unknown"] = "Unknown" -- unit name for "Unknown" units |
--[[ zhTW ]] dL["Unknown"] = "æªç¥" -- unit name for "Unknown" units |
----------------------------------------------------------------------------- |
----------------------------------------------------------------------------- |
-- TODO: need zhTW translation for oT |
--[[ zhTW ]] oT["Tremor Totem"] = "æ°æ å騰" |
--[[ zhTW ]] oT["Grounding Totem"] = "æ ¹åºå騰" |
--[[ zhTW ]] oT["Earthbind Totem"] = "å°ç¸å騰" |
--[[ zhTW ]] oT["Cleansing Totem"] = "ç¥ç å騰" |
--[[ zhTW ]] oT["Mana Tide Totem"] = "æ³åä¹æ½®å騰" |
----------------------------------------------------------------------------- |
profile = |
{ |
enable = false, |
totemEnable = true, |
totemCrop = 0.08, |
alpha = 1.0, |
point = "RIGHT", |
relativeToPoint = "LEFT", |
----------------------------------------------------------------------------- |
function AloftClassIcon:CreateRegion(aloftData, texture) |
local layoutFrame = aloftData.layoutFrame |
if not layoutFrame then |
layoutFrame = Aloft:AcquireLayoutFrame(aloftData) |
end |
local classIconRegion = layoutFrame.classIconRegion |
-- Check if this nameplate already has a class icon assigned to it |
if not classIconRegion then |
classIconRegion = aloftData:CreateTexture() |
layoutFrame.classIconRegion = classIconRegion |
self:PlaceFrame(classIconRegion, layoutFrame, self.db.profile, 0, 0) |
end |
classIconRegion:SetTexture(texture) |
return classIconRegion |
end |
function AloftClassIcon:SetupFrame(message, aloftData) |
if aloftData.class then |
local layoutFrame = aloftData.layoutFrame |
if not layoutFrame then |
layoutFrame = Aloft:AcquireLayoutFrame(aloftData) |
end |
local classIconRegion = layoutFrame.classIconRegion |
local classIconRegion = self:CreateRegion(aloftData, "Interface\\WorldStateFrame\\Icons-Classes") |
local l, r, t, b = self:GetClassIconTexCoord(aloftData.class) |
-- Check if this nameplate already has a class icon assigned to it |
if not classIconRegion then |
classIconRegion = aloftData:CreateTexture() |
classIconRegion:SetTexture("Interface\\WorldStateFrame\\Icons-Classes") |
classIconRegion:SetTexCoord(l, r, t, b) |
layoutFrame.classIconRegion = classIconRegion |
return classIconRegion |
elseif self.db.profile and self.db.profile.totemEnable then |
local totemIcon = Aloft:IsTotem(aloftData) |
if totemIcon then |
local classIconRegion = self:CreateRegion(aloftData, totemIcon) |
local crop = self.db.profile.totemCrop |
self:PlaceFrame(classIconRegion, layoutFrame, self.db.profile, 0, 0) |
classIconRegion:SetTexCoord(0 + crop, 1 - crop, 0 + crop, 1 - crop) -- full texture (less crop of the border) |
return classIconRegion |
end |
-- always assign at least a blank region of the texture; here when we originally discover the nameplate |
local l, r, t, b = self:GetClassIconTexCoord(aloftData.class) |
classIconRegion:SetTexCoord(l, r, t, b ); |
return classIconRegion |
end |
-- ChatFrame7:AddMessage("AloftClassIcon:SetupFrame(): no classIconRegion " .. tostring(aloftData.name) .. "/" .. tostring(aloftData.class)) |
-- borrowed from Blizzard's FrameXML/Constants.lua/WorldStateFrame.lua/WorldStateScoreFrame_Update() and XPerl |
local classButtons = CLASS_ICON_TCOORDS -- now sourcing from Constants.lua, which seems to duplicate stuff from WorldStateFrame.lua/CLASS_BUTTONS |
function AloftClassIcon:GetClassIconTexCoord(class) |
if (class) then |
if class then |
local texCoord = classButtons[class] |
if (texCoord) then |
if texCoord then |
return unpack(texCoord) |
end |
end |
if aloftData.name == L["Unknown"] or (aloftData.nameTextRegion and aloftData.nameTextRegion:GetText() == L["Unknown"]) then |
aloftData.type = "unknown" |
-- ChatFrame7:AddMessage("Aloft:UpdateAloftTypeData(): explicit " .. tostring(aloftData.nameplateFrame) .. "/" .. tostring(aloftData.name) .. "/" .. tostring(aloftData.type) .. "/" .. tostring(aloftData.nameplateFrame and aloftData.nameplateFrame:IsVisible())) |
-- ChatFrame7:AddMessage("Aloft:UpdateAloftTypeData(): " .. tostring(aloftData.name) .. "/" .. tostring(aloftData.type) .. "/" .. tostring(aloftData.nameplateFrame) .. "/" .. tostring(aloftData.nameplateFrame and aloftData.nameplateFrame:IsVisible()) .. " explicit") |
elseif r == 255 and g == 0 and b == 0 then -- red |
-- ChatFrame7:AddMessage("Aloft:UpdateAloftTypeData(): " .. tostring(aloftData.name) .. "/hostile") |
aloftData.type = "hostile" |
-- ChatFrame7:AddMessage("Aloft:UpdateAloftTypeData(): " .. tostring(aloftData.name) .. "/" .. tostring(aloftData.type) .. "/" .. tostring(aloftData.nameplateFrame) .. "/" .. tostring(aloftData.nameplateFrame and aloftData.nameplateFrame:IsVisible())) |
elseif r == 0 and g == 0 and b == 255 then -- blue |
aloftData.type = "friendlyPlayer" |
aloftData.isPlayer = true |
elseif r == 0 and g == 255 and b == 0 then -- green |
aloftData.type = "friendlyNPC" |
-- ChatFrame7:AddMessage("Aloft:UpdateAloftTypeData(): " .. tostring(aloftData.name) .. "/" .. tostring(aloftData.type) .. "/" .. tostring(aloftData.nameplateFrame) .. "/" .. tostring(aloftData.nameplateFrame and aloftData.nameplateFrame:IsVisible())) |
elseif r == 255 and g == 255 and b == 0 then -- yellow |
-- ChatFrame7:AddMessage("Aloft:UpdateAloftTypeData(): " .. tostring(aloftData.name) .. "/neutral") |
aloftData.type = "neutral" |
-- ChatFrame7:AddMessage("Aloft:UpdateAloftTypeData(): " .. tostring(aloftData.name) .. "/" .. tostring(aloftData.type) .. "/" .. tostring(aloftData.nameplateFrame) .. "/" .. tostring(aloftData.nameplateFrame and aloftData.nameplateFrame:IsVisible())) |
elseif Aloft.showClassColorInVKey then |
-- assume hostile player, due to the new Blizzard "Combat>Class Colors in Nameplates" option |
aloftData.type = "hostilePlayer" |
aloftData.isPlayer = true |
-- ChatFrame7:AddMessage("Aloft:UpdateAloftTypeData(): " .. tostring(aloftData.name) .. "/class hostile") |
-- ChatFrame7:AddMessage("Aloft:UpdateAloftTypeData(): " .. tostring(aloftData.name) .. "/" .. tostring(aloftData.type) .. "/" .. tostring(aloftData.nameplateFrame) .. "/" .. tostring(aloftData.nameplateFrame and aloftData.nameplateFrame:IsVisible()) .. " class") |
else |
aloftData.type = "unknown" |
-- ChatFrame7:AddMessage("Aloft:UpdateAloftTypeData(): implicit " .. tostring(aloftData.nameplateFrame) .. "/" .. tostring(aloftData.name) .. "/" .. tostring(aloftData.type) .. "/" .. tostring(aloftData.nameplateFrame and aloftData.nameplateFrame:IsVisible())) |
-- ChatFrame7:AddMessage("Aloft:UpdateAloftTypeData(): " .. tostring(aloftData.name) .. "/" .. tostring(aloftData.type) .. "/" .. tostring(aloftData.nameplateFrame) .. "/" .. tostring(aloftData.nameplateFrame and aloftData.nameplateFrame:IsVisible())) |
end |
end |
end |
-- ChatFrame7:AddMessage("Aloft:IsNameplateFrame(): " .. frameName .. " good frame name") |
--[[ |
-- legacy frame identification method, presumably rendered obsolete by nameplate frame names |
local region1, region2 = frame:GetRegions() |
overlayRegion = region2 |
if not overlayRegion then |
return false |
end |
-- ChatFrame7:AddMessage("Aloft:IsNameplateFrame(): " .. frameName .. " good overlayRegion texture " .. tostring(overlayRegionTexture)) |
]] |
-- ChatFrame7:AddMessage("Aloft:IsNameplateFrame(): " .. frameName .. " IS NAMEPLATE") |
return true |
end |
end |
local cyclicWarning |
function Aloft:DetermineDataSources() |
-- ChatFrame7:AddMessage("Aloft:DetermineDataSources(): ENTER") |
-- empty the data required map |
for k in pairs(dataRequiredList) do |
dataRequiredList[k] = nil |
local iterationCount = 0 -- A safety factor |
local requiredModules = { } |
while iterationCount < 100 and next(moduleToModuleListMap) do |
-- ChatFrame7:AddMessage("Aloft:DetermineDataSources(): ITERATION") |
for module, moduleList in pairs(moduleToModuleListMap) do |
-- ChatFrame7:AddMessage("Aloft:DetermineDataSources(): considering module " .. tostring(module)) |
for requiredModule in pairs(moduleList) do |
-- ChatFrame7:AddMessage("Aloft:DetermineDataSources(): setting required module for " .. tostring(requiredModule) .. " to true") |
-- ChatFrame7:AddMessage("Aloft:DetermineDataSources(): " .. tostring(module) .. " requires " .. tostring(requiredModule)) |
requiredModules[requiredModule] = true |
end |
end |
local moduleRemoved = false |
for module, _ in pairs(moduleToModuleListMap) do |
if module:IsPurelyData() and not requiredModules[module] then |
-- ChatFrame7:AddMessage("Aloft:DetermineDataSources(): not required or purely data "..tostring(module)) |
-- ChatFrame7:AddMessage("Aloft:DetermineDataSources(): not required or purely data " .. tostring(module)) |
moduleToModuleListMap[module] = nil |
self:RemoveRequiredModuleFromModuleToModuleListMap(module) |
moduleRemoved = true |
end |
if not moduleRemoved then break end |
for k in pairs(requiredModules) do |
-- ChatFrame7:AddMessage("Aloft:DetermineDataSources(): setting required for " .. tostring(k) .. " to nil") |
-- ChatFrame7:AddMessage("Aloft:DetermineDataSources(): clearing required for " .. tostring(k)) |
requiredModules[k] = nil |
end |
iterationCount = iterationCount + 1 |
moduleList[requiredModule] = nil |
elseif not moduleToModuleListMap[requiredModule] then |
-- The required module isn't dependent on anything! Put it into our dataSourceList and remove from all modules that request it |
-- ChatFrame7:AddMessage("Aloft:DetermineDataSources(): enabling module " .. tostring(requiredModule)) |
-- ChatFrame7:AddMessage("Aloft:DetermineDataSources(): directly enabling module " .. tostring(requiredModule)) |
table.insert(dataSourceList, requiredModule) |
requiredModule:EnableDataSource() |
requiredModule.needToDisable = nil |
end |
if next(moduleToModuleListMap) then |
self:Print(L["Internal error: Dependency list not resolved - cyclic dependency?"]) |
-- self:Print(L["Internal error: Dependency list not resolved - cyclic dependency?"]) |
if self.db.profile.startMessageEnable and not cyclicWarning then |
-- warn about cyclic dependencies just once, if enabled |
self:Print(L["Warning: Tag<->module dependency list not resolved - non-fatal cyclic dependency?"]) |
cyclicWarning = true |
end |
for k in pairs(moduleToModuleListMap) do |
-- ChatFrame7:AddMessage("Aloft:DetermineDataSources(): cyclic dependency " .. tostring(k)) |
moduleToModuleListMap[k] = nil |
end |
end |
-- Empty our maps |
for k in pairs(dataNameToModuleMap) do |
dataNameToModuleMap[k] = nil |
aloftData.healthBarMaxValue = healthBarMaxValue |
aloftData.isTarget = nil |
aloftData.nameplateFrame.originalAlpha = nil |
local nameplateFrame = aloftData.nameplateFrame |
nameplateFrame.originalAlpha = nil |
aloftData.isBoss = aloftData.bossIconRegion:IsShown() |
aloftData.isElite = aloftData.stateIconRegion:IsVisible() -- quick way to track elites; pure rares do not have a region on the nameplate |
aloftData.level = nil -- level is initialized on the following OnUpdate |
UpdateAloftTypeData(aloftData, healthBar) |
--[[ |
self:UpdateAloftData(aloftData) |
self:SendMessage("Aloft:OnNameplateShow", aloftData) |
]] |
-- hook the update script here, since this code can be reached from several points |
-- ChatFrame7:AddMessage("Aloft:OnNameplateShow(): hook update script " .. tostring(aloftData.name)) |
if not aloftData.updateDefer then aloftData.updateDefer = 0 end |
if not self:IsHooked(nameplateFrame, "OnUpdate") then |
self:RawHookScript(nameplateFrame, "OnUpdate", "OnNameplateUpdateScript") -- hook to run on the next OnUpdate |
end |
-- ChatFrame7:AddMessage("Aloft:OnNameplateShow(): exit " .. tostring(aloftData.name)) |
end |
-- only called from OnNameplateUpdateScript() |
function Aloft:OnNameplateUpdate(aloftData) |
self:SetNameplateName(aloftData, nil) |
-- TODO: this repeats what is done in OnNameplateShow |
-- When a nameplate is first shown, grab some data about it |
local levelTextRegion = aloftData.levelTextRegion |
local levelText = levelTextRegion:GetText() |
local level = tonumber(levelText) |
end |
self:UpdateAloftData(aloftData) |
-- ChatFrame7:AddMessage("Aloft:OnNameplateUpdate(): " .. tostring(aloftData.name) .. " SEND Aloft:OnNameplateShow") |
self:SendMessage("Aloft:OnNameplateShow", aloftData) |
-- ChatFrame7:AddMessage("Aloft:OnNameplateUpdate(): exit " .. tostring(aloftData.name)) |
end |
-- ChatFrame7:AddMessage("Aloft:OnNameplateShowScript(): clear noTargetNameplate") |
visibleNameplateList[aloftData] = true |
self:OnNameplateShow(aloftData) |
aloftData.updateDefer = 0 |
self.hooks[this]["OnShow"](this) |
self:RawHookScript(this, "OnUpdate", "OnNameplateUpdateScript") -- hook to run on the next OnUpdate |
end |
-- hooked from OnNameplateShow() |
function Aloft:OnNameplateUpdateScript(this) |
local aloftData = this.aloftData |
aloftData.updateDefer = aloftData.updateDefer + 1 |
end |
end |
-- ChatFrame7:AddMessage("Aloft:OnNameplateUpdateScript(): " .. tostring(aloftData.name) .. "/" .. tostring(aloftData.updateDefer) .. "/" .. tostring(update)) |
if update then |
self:OnNameplateUpdate(aloftData) |
if update then |
if self:IsHooked(this, "OnUpdate") then self:Unhook(this, "OnUpdate") end -- unhook if necessary, we want to run only once |
-- ChatFrame7:AddMessage("Aloft:OnNameplateUpdateScript(): unhook update " .. tostring(aloftData.name)) |
end |
end |
-- ChatFrame7:AddMessage("Aloft:SetNameplateName(): WAS unknown " .. tostring(aloftData.nameplateFrame) .. "/" .. tostring(aloftData.name) .. "/" .. tostring(aloftData.type) .. "/" .. tostring(newNameText) .. "/" .. tostring(aloftData.nameplateFrame and aloftData.nameplateFrame:IsVisible())) |
-- end |
local notify = nil |
if not newNameText then |
-- should only occur when a nameplate first becomes visible |
nameTextRegion = aloftData.nameTextRegion |
if (nameToNameplateMultiMap[name]) then nameToNameplateMultiMap[name][aloftData] = nil end |
end |
if newNameText then |
if newNameText ~= name then |
-- ChatFrame7:AddMessage("Aloft:SetNameplateName(): " .. tostring(aloftData) .. "/" .. tostring(aloftData.name) .. ">" .. tostring(newNameText)) |
aloftData.name = newNameText |
notify = true |
end |
if not aloftData.name then aloftData.name = "[invalid]" end |
if not aloftData.name then |
aloftData.name = "[invalid]" |
notify = true |
end |
-- make a record of the new name |
name = aloftData.name |
nameToNameplateMultiMap[name][aloftData] = true |
end |
if notify then |
self:SendMessage("Aloft:OnUnitNameChanged", aloftData) |
end |
-- NOTE: aloftData.nameTextRegionText is set via the Aloft:SetNameTextRegionText() "SetText" hook |
end |
self.db.profile.colorByClass or |
self.db.profile.colorHostileByClass then |
updateTextMethod = "UpdateText" |
-- ChatFrame7:AddMessage("AloftNameText:RegisterEvents(): updateTextMethod " .. tostring(updateTextMethod)) |
end |
self:RegisterMessage("Aloft:OnNameplateShow", updateTextMethod) |
-- ChatFrame7:AddMessage("AloftNameText:RegisterEvents(): register 1 " .. tostring(updateTextMethod)) |
if self.db.profile.colorByClass or self.db.profile.colorHostileByClass then |
-- ChatFrame7:AddMessage("AloftNameText:RequiresData(): register Aloft:OnClassDataChanged") |
self:RegisterMessage("Aloft:OnClassDataChanged", updateTextMethod) |
end |
-- apply to name and recentlyDamaged, and disable this module if not |
function AloftNameText:ProvidesData() |
return "recentlyDamaged" |
-- NOTE: this self-hooks the AloftNameText into the data/module heirarchy; |
-- AloftNameText is an always-loaded module, and the [Name] tag is always valid, so this should be harmless, |
-- and it provides an anchor for things like the [Class] tag, if it is needed for various "Color By Class" option(s) |
-- TODO: self-hook AloftLevelText as well, vis [Level]? |
return "name", "recentlyDamaged" |
end |
function AloftNameText:UpdateData(aloftData) |
local dataRequiredList = { } |
function AloftNameText:RequiresData() |
-- ChatFrame7:AddMessage("AloftNameText:RequiresData(): enter") |
-- ChatFrame7:AddMessage("AloftNameText:RequiresData(): ENTER") |
self:RegisterEvents() |
-- ChatFrame7:AddMessage("AloftNameText:RequiresData(): events registered") |
if self.db.profile.colorByClass or |
self.db.profile.colorHostileByClass or |
not self:IsArrayEqual(self.db.profile.colors.hostileNPC, self.db.profile.colors.hostilePlayer) then |
-- ChatFrame7:AddMessage("AloftNameText:RequiresData(): CLASS") |
table.insert(dataRequiredList, "class") |
end |
end |
end |
--[[ |
for i = 1,#dataRequiredList do |
ChatFrame7:AddMessage("AloftNameText:RequiresData(): requires " .. tostring(dataRequiredList[i])) |
end |
]] |
return unpack(dataRequiredList) |
end |
nameTextRegion:SetNonSpaceWrap(false) |
end |
nameTextRegion:SetDrawLayer("OVERLAY") |
self:PrepareText(nameTextRegion, self.db.profile) |
end |
self:PrepareText(nameTextRegion, self.db.profile) |
-- NOTE: no user-selected attach points, just direct placement, therefore no funky inset logic |
nameTextRegion:ClearAllPoints() |
nameTextRegion:SetPoint("TOPLEFT", layoutFrame, "TOPLEFT", self.db.profile.offsets.left, self.db.profile.offsets.vertical) |
----------------------------------------------------------------------------- |
function AloftNameText:UpdateTextSimple(message, aloftData) |
-- ChatFrame7:AddMessage("AloftNameText:UpdateTextSimple(): " .. tostring(aloftData.name)) |
-- ChatFrame7:AddMessage("AloftNameText:UpdateTextSimple(): " .. |
-- ("|cff%02x%02x%02x%s"):format(floor(aloftData.originalHealthBarR*255), floor(aloftData.originalHealthBarG*255), floor(aloftData.originalHealthBarB*255), tostring(aloftData.name) .. "/" .. tostring(aloftData.class))) |
----------------------------------------------------------------------------- |
function AloftNameText:ColourFriendlyPlayer(aloftData) |
-- ChatFrame7:AddMessage("AloftNameText:ColourFriendlyPlayer(): " .. tostring(aloftData.name) .. "/" .. tostring(self.db.profile.colorByClass) .. "/" .. tostring(aloftData.class)) |
if self.db.profile.colorByClass then |
local class = aloftData.class |
if class then |
local color = Aloft.db.profile.classColors[class] |
if color then |
-- ChatFrame7:AddMessage("AloftNameText:ColourFriendlyPlayer(): " .. tostring(aloftData.name) .. "/" .. tostring(class)) |
self:SetTextColor(aloftData, color) |
return |
end |
} |
function AloftNameText:UpdateText(message, aloftData) |
-- ChatFrame7:AddMessage("AloftNameText:UpdateText(): " .. tostring(aloftData.name) .. "/" .. tostring(aloftData.type)) |
-- ChatFrame7:AddMessage("AloftNameText:UpdateText(): " .. |
-- ("|cff%02x%02x%02x%s"):format(floor(aloftData.originalHealthBarR*255), floor(aloftData.originalHealthBarG*255), floor(aloftData.originalHealthBarB*255), tostring(aloftData.name) .. "/" .. tostring(aloftData.class))) |
end |
function AloftNameText:UpdateTextNone(message, aloftData) |
-- ChatFrame7:AddMessage("AloftNameText:UpdateTextNone(): " .. tostring(aloftData.name)) |
-- ChatFrame7:AddMessage("AloftNameText:UpdateTextNone(): " .. |
-- ("|cff%02x%02x%02x%s"):format(floor(aloftData.originalHealthBarR*255), floor(aloftData.originalHealthBarG*255), floor(aloftData.originalHealthBarB*255), tostring(aloftData.name) .. "/" .. tostring(aloftData.class))) |
-- .. "/" .. tostring(aloftData.isTarget or aloftData:IsTarget()) |
-- .. "/" .. tostring(self.textMethodData.functionString)) |
-- ChatFrame7:AddMessage("AloftNameText:UpdateTextNone(): " .. tostring(message) .. "/" .. tostring(aloftData.name) .. "/" .. tostring(self.textMethodData.functionString)) |
local text = self.textMethod(aloftData) |
local layoutFrame = aloftData.layoutFrame |
local nameTextRegion = layoutFrame and layoutFrame.nameTextRegion |
self:RegisterMessage("Aloft:OnPetOwnersNameDataChanged", "OnIsPetDataChanged") |
end |
--[[ |
if not self.db.profile.showCritters or |
not self.db.profile.showHostilePlayers or |
not self.db.profile.showHostilePets or |
not self.db.profile.showGroupPets or |
not self.db.profile.showPet or |
self.db.profile.friendlyPlayers ~= "ALL" then |
]] |
-- ChatFrame7:AddMessage("AloftVisibility:RegisterEvents(): register OnNameplateShow") |
self:RegisterMessage("Aloft:OnNameplateShow", "OnNameplateShow") |
self:RegisterMessage("Aloft:OnUnitidDataChanged", "OnUnitidDataChanged") |
end |
-- end |
end |
end |
end |
end, |
["friendlyNPC"] = function(frame, aloftData) |
-- ChatFrame7:AddMessage("AloftVisibility:showTypeMethods:[friendlyNPC](): " .. tostring(aloftData.name) .. "/" .. tostring(aloftData.unitid)) |
-- ChatFrame7:AddMessage("AloftVisibility:showTypeMethods:[friendlyNPC](): " .. tostring(aloftData.name) .. "/" .. tostring(aloftData.unitid) .. "/" .. tostring(aloftData.nameplateFrame)) |
if AloftVisibility.db.profile.enableHideUnitNames and AloftVisibility.db.profile.hideUnitNames[aloftData.name] then |
AloftVisibility:DoFrameHide(frame, aloftData) |
elseif UnitExists("pet") and UnitName("pet") == aloftData.name then |
end |
function AloftVisibility:OnNameplateShow(message, aloftData) |
-- ChatFrame7:AddMessage("AloftVisibility:OnNameplateShow(): " .. tostring(aloftData) .. "/".. tostring(aloftData.name) .. "/" .. tostring(aloftData.unitid) .. "/" .. tostring(aloftData.nameplateFrame:GetAlpha()) .. "/".. tostring(message)) |
-- ChatFrame7:AddMessage("AloftVisibility:OnNameplateShow(): " .. tostring(aloftData.name) .. "/" .. tostring(aloftData.unitid) .. "/" .. tostring(aloftData.nameplateFrame) .. "/" .. tostring(aloftData.type)) |
-- if aloftData.isTarget or aloftData:IsTarget() then ChatFrame7:AddMessage("AloftVisibility:OnNameplateShow(): " .. tostring(aloftData.name) .. "/TARGET") end |
self:ScheduleTimer(function(aloftData) AloftVisibility:DoNameplateShow(aloftData) end, 0.1, aloftData) -- seems to need just a little more than next frame |
end |
function AloftVisibility:DoNameplateShow(aloftData) |
-- ChatFrame7:AddMessage("AloftVisibility:DoNameplateShow(): " .. tostring(frame) .. "/".. tostring(aloftData.name) .. "/".. tostring(aloftData.nameplateFrame:GetAlpha())) |
-- ChatFrame7:AddMessage("AloftVisibility:DoNameplateShow(): " .. tostring(aloftData.name) .. "/" .. tostring(aloftData.unitid) .. "/" .. tostring(aloftData.nameplateFrame) .. "/" .. tostring(aloftData.type)) |
-- if self.db.profile.target and self.db.profile.useAlpha and AloftAlpha and (aloftData.isTarget or aloftData:IsTarget()) then ChatFrame7:AddMessage("AloftVisibility:DoNameplateShow(): " .. tostring(aloftData.name) .. "/TARGET") end |
-- if self.db.profile.target and self.db.profile.useAlpha and AloftAlpha and not (aloftData.isTarget or aloftData:IsTarget()) then ChatFrame7:AddMessage("AloftVisibility:DoNameplateShow(): " .. tostring(aloftData.name) .. "/NOTARGET") end |
-- should be using nameplate hide |
aloftData.invisible = true |
-- ChatFrame7:AddMessage("AloftVisibility:DoFrameHide(): hide " .. tostring(aloftData.name)) |
-- ChatFrame7:AddMessage("AloftVisibility:DoFrameHide(): straight hide " .. tostring(aloftData.name) .. "/" .. tostring(aloftData.nameplateFrame)) |
frame:Hide() |
-- TODO: turns out this can be dangerous; hide the nameplate, disable the mouse, and it can intermittently remain disabled, if recycled in combat |
if not showTarget or not isTarget then |
aloftData.invisible = true |
aloftData.alphaOverride = 0.0 |
-- ChatFrame7:AddMessage("AloftVisibility:DoFrameHide(): use alpha " .. tostring(aloftData.name)) |
-- ChatFrame7:AddMessage("AloftVisibility:DoFrameHide(): alpha hide " .. tostring(aloftData.name) .. "/" .. tostring(aloftData.nameplateFrame)) |
frame:SetAlpha(aloftData.alphaOverride) |
end |
end |
----------------------------------------------------------------------------- |
--[[ zhTW ]] fL["Threat"] = "Threat" |
--[[ zhTW ]] fL["Threat"] = "ä»æ¨" |
--[[ zhTW ]] fL["PvP"] = "PvP" |
--[[ zhTW ]] fL["^Requires "] = "^Requires " |
--[[ zhTW ]] fL["^Requires "] = "^éè¦ " |
----------------------------------------------------------------------------- |
AloftModules:AddInitializer("AloftLDB", function() |
--[[ zhTW ]] L["Aloft LDB support disabled itself because Broker2FuBar is loaded. Will attempt to load Aloft direct FuBar support instead."] = "Aloft LDB support disabled itself because Broker2FuBar is loaded. Will attempt to load Aloft direct FuBar support instead." |
--[[ zhTW ]] L["Aloft LDB support disabled itself because Broker2FuBar is loaded. Will attempt to load Aloft direct FuBar support instead."] = "Aloft LDBæ¯æ´å·²ç¦ç¨å çºBroker2FuBarå·²è¼å ¥ãå°å試è¼å ¥Aloftèä¸æ¯ç´æ¥FuBaræ¯æ´ã" |
--[[ zhTW ]] L["Aloft"] = "Aloft" |
--[[ zhTW ]] L["Click to toggle nameplates."] = "|cffeda55få·¦æ: |råæåçã" |
--[[ zhTW ]] L["Right-Click to open configuration."] = "|cffeda55fRight-å·¦æ: |ræéè¨å®ã" |
--[[ zhTW ]] L["Click to toggle nameplates."] = "|cffeda55fé»æ: |råæåçã" |
--[[ zhTW ]] L["Right-Click to open configuration."] = "|cffeda55få³éµ-é»æ: |réåè¨å®ã" |
--[[ zhTW ]] L["Hostile Nameplates"] = "æµå°åç" |
--[[ zhTW ]] L["Friendly Nameplates"] = "å好åç" |
--[[ zhTW ]] L["Preset 1"] = "é å è¨å®1" |
--[[ zhTW ]] L["Preset 2"] = "é å è¨å®2" |
--[[ zhTW ]] L["Preset 3"] = "é å è¨å®3" |
--[[ zhTW ]] L["Preset Acapela"] = "é å è¨å®Acapela" |
--[[ zhTW ]] L["Preset Unit Frame"] = "é å è¨å®Unit Frame" |
--[[ zhTW ]] L["Preset Acapela"] = "é å è¨å®æå " |
--[[ zhTW ]] L["Preset Unit Frame"] = "é å è¨å®å®ä½æ¡æ¶" |
--[[ zhTW ]] L["Preset PvP"] = "é å è¨å®PvP" |
----------------------------------------------------------------------------- |
gainEnable = true, |
texture = "Blizzard", |
height = 4, |
incremental = true, |
targetOnly = true, |
border = "None", |
borderEdgeSize = 16, |
----------------------------------------------------------------------------- |
function AloftThreatBar:NeedsBorder(aloftData) |
if not self.db.profile.targetOnly or (aloftData and (aloftData.isTarget or aloftData:IsTarget())) then |
-- ChatFrame7:AddMessage("AloftThreatBar:NeedsBorder(): border " .. tostring(self.db.profile.border)) |
return self.db.profile.border ~= "None" |
end |
return nil |
end |
function AloftThreatBar:GetBorder(aloftData) |
if not self.db.profile.targetOnly or (aloftData and (aloftData.isTarget or aloftData:IsTarget())) then |
-- ChatFrame7:AddMessage("AloftHealthBar:GetBorder(): border " .. tostring(self.db.profile.border)) |
-- ChatFrame7:AddMessage("AloftThreatBar:GetBorder(): border " .. tostring(self.db.profile.border)) |
return ((self.db.profile.border ~= "None") and self.db.profile.borderInset) or 0, SML:Fetch("border", self.db.profile.border) |
-- return 0, SML:Fetch("border", "None") |
else |
end |
-- the threat bar is constructed; show it, initially with bogus colors (only once, before the first frame-delay) |
if not threatBar.init or threatBar.init < BORDER_INIT_ATTEMPTS then |
if self:NeedsBorder(aloftData) and self.db.profile.incremental and (not threatBar.init or threatBar.init < BORDER_INIT_ATTEMPTS) then |
threatBar:SetBackdropColor(0, 0, 0, 0.1) |
threatBar:SetBackdropBorderColor(0, 0, 0, 0.1) |
threatBar:Show() |
end |
-- frame delay to flip the backdrop color(s); hopefully avoids the "malformed border" issue |
self:ScheduleTimer(function(arg) AloftThreatBar:DoShowThreatBar(arg) end, 0.15, { aloftData = aloftData, threatRegionWidth = threatRegionWidth, gainRegionWidth = gainRegionWidth, }) -- a bit more than one frame |
-- ChatFrame7:AddMessage("AloftThreatBar:Update(): show threat bar " .. tostring(aloftData.name)) |
if self:NeedsBorder(aloftData) and self.db.profile.incremental then |
-- frame delay to flip the backdrop color(s); hopefully avoids the "malformed border" issue |
self:ScheduleTimer(function(arg) AloftThreatBar:DoShowThreatBar(arg) end, 0.15, { aloftData = aloftData, threatRegionWidth = threatRegionWidth, gainRegionWidth = gainRegionWidth, }) -- a bit more than one frame |
-- ChatFrame7:AddMessage("AloftThreatBar:Update(): show threat bar on delay " .. tostring(aloftData.name)) |
else |
self:DoShowThreatBar({ aloftData = aloftData, threatRegionWidth = threatRegionWidth, gainRegionWidth = gainRegionWidth, }) |
-- ChatFrame7:AddMessage("AloftThreatBar:Update(): show threat bar immediately " .. tostring(aloftData.name)) |
end |
-- if the nameplate's unit has maximum threat, show the flash bar as well |
if flashFrame and self.db.profile.flashEnable then |
layoutFrame.threatTextRegion = threatTextRegion |
self:PrepareText(threatTextRegion, self.db.profile) |
self:PlaceFrame(threatTextRegion, layoutFrame, self.db.profile, 0, 0) |
end |
self:PrepareText(threatTextRegion, self.db.profile) |
-- ChatFrame7:AddMessage("AloftThreatText:UpdateText(): assign text") |
threatTextRegion:SetText(text) |
threatTextRegion:Show() |
end |
function AloftClassData:ProvidesData() |
-- ChatFrame7:AddMessage("AloftClassData:ProvidesData(): enter") |
return "class" |
end |
function AloftClassData:EnableDataSource() |
-- ChatFrame7:AddMessage("AloftClassData:EnableDataSource(): enter") |
self:UnregisterAllEvents() |
self:UnregisterAllMessages() |
self:CancelAllTimers() |
----------------------------------------------------------------------------- |
-- TODO: snake trap spawn, death knight bloodworms |
-- hunter snake trap spawn |
--[[ zhTW ]] totemMap["è®è"] = SnakeIcon |
--[[ zhTW ]] totemMap["æ¯è"] = SnakeIcon |
-- death knight bloodworms |
--[[ zhTW ]] totemMap["è¡è²"] = BloodwormIcon |
----------------------------------------------------------------------------- |
end |
----------------------------------------------------------------------------- |
--[[ ruRU ]] mL["AloftThreat"] = "AloftThreat" |
--[[ ruRU ]] mL["Display threat data, bars, and text on nameplates"] = "ÐÑобÑÐ°Ð¶Ð°ÐµÑ ÑекÑÑ/полоÑÑ/даннÑе по ÑгÑозе" |
----------------------------------------------------------------------------- |
elseif (locale == "zhCN") then |
----------------------------------------------------------------------------- |
----------------------------------------------------------------------------- |
--[[ zhCN ]] mL["AloftThreat"] = "å¨èå¼" |
--[[ zhCN ]] mL["Display threat data, bars, and text on nameplates"] = "å¨å§åæ¿ä¸æ¾ç¤ºå¨èå¼æ°æ®ã计éæ¡åææ¬" |
----------------------------------------------------------------------------- |
elseif (locale == "zhTW") then |
----------------------------------------------------------------------------- |
----------------------------------------------------------------------------- |
-- long forms |
--[[ zhTW ]] dL[THREAT_RANGED] = "Ranged" |
--[[ zhTW ]] dL[THREAT_MELEE] = "Melee" |
--[[ zhTW ]] dL[THREAT_TANK] = "Tank" |
--[[ zhTW ]] dL[THREAT_GROUP] = "Group" |
--[[ zhTW ]] dL[THREAT_RANGED] = "é ç¨" |
--[[ zhTW ]] dL[THREAT_MELEE] = "é²æ°" |
--[[ zhTW ]] dL[THREAT_TANK] = "å¦å " |
--[[ zhTW ]] dL[THREAT_GROUP] = "éä¼" |
-- short forms |
--[[ zhTW ]] dL[SHORT_THREAT_TYPES[THREAT_RANGED]] = "R" |
----------------------------------------------------------------------------- |
--[[ zhTW ]] mL["AloftThreat"] = "å¨è å¼" |
--[[ zhTW ]] mL["Display threat data, bars, and text on nameplates"] = "å¨åçä¸é¡¯ç¤ºå¨è å¼è³æãè¨éæ¢åææ¬" |
----------------------------------------------------------------------------- |
end |
----------------------------------------------------------------------------- |
aLevelTextRegion:SetNonSpaceWrap(false) |
end |
aLevelTextRegion:SetDrawLayer("OVERLAY") |
self:PrepareText(aLevelTextRegion, self.db.profile) |
end |
-- if aloftData.name == "[invalid]" or not self.db or not self.db.profile or not self.db.profile.font or not self.db.profile.fontSize or not self.db.profile.outline then |
-- ChatFrame7:AddMessage("AloftLevelText:SetupFrame(): " .. debugstack()) |
-- end |
self:PrepareText(aLevelTextRegion, self.db.profile) |
self:PlaceFrame(aLevelTextRegion, layoutFrame, self.db.profile, 0, 0) |
-- self:ScheduleTimer(function(aloftData) AloftLevelText:DoPlaceFrame(aloftData) end, 0.0, aloftData) |
local Aloft = Aloft |
if not Aloft then return end |
local error = error |
local AloftRoster = Aloft:NewModule("Roster", Aloft, "AceEvent-3.0", "AceTimer-3.0") |
local unknownUnits = {} |
LegitimateUnits["arena" .. i] = true |
LegitimateUnits["arena" .. i .. "pet"] = true |
end |
--[[ these are legitimate units, just not ones for which we want to track pets, etc |
for i = 1, 4 do |
LegitimateUnits["boss" .. i] = true |
end |
]] |
setmetatable(LegitimateUnits, {__index=function(self, key) |
if type(key) ~= "string" then |
return false |
end |
function AloftRoster:OnUnitPet(event, unitid) |
self:ScheduleTimer(function() AloftRoster:ScanPet(unitid) end, 0.2) |
-- apparently some boss encounters can generate the UNIT_PET event (reported by Myster); insure this is a legitimate unitid |
if LegitimateUnits[unitid] then |
self:ScheduleTimer(function() AloftRoster:ScanPet(unitid) end, 0.2) |
end |
end |
------------------------------------------------ |
function AloftRoster:CreateOrUpdateUnit(unitid, isInRaid) |
if not LegitimateUnits[unitid] then |
AloftRoster:error("Bad argument #2 to `CreateOrUpdateUnit'. %q is not a legitimate UnitID.", unitid) |
error(("Bad argument #2 to 'CreateOrUpdateUnit'. %q is not a legitimate UnitID."):format(unitid)) |
end |
-- check for name |
local name = UnitName(unitid) |
function AloftRoster:GetUnitIDFromUnit(unit) |
-- TEST: error(("AloftRoster:GetUnitIDFromUnit(): checking %q."):format(unit)) |
if not LegitimateUnits[unit] then |
AloftRoster:error("Bad argument #2 to `GetUnitIDFromUnit'. %q is not a legitimate UnitID.", unit) |
error(("Bad argument #2 to 'GetUnitIDFromUnit'. %q is not a legitimate UnitID."):format(unit)) |
end |
local name = UnitName(unit) |
if name and roster[name] then |
end |
end |
function AloftRoster:GetUnitObjectFromName(name) |
return roster[name] |
end |
function AloftRoster:GetUnitObjectFromUnit(unit) |
if not LegitimateUnits[unit] then |
AloftRoster:error("Bad argument #2 to `GetUnitObjectFromUnit'. %q is not a legitimate UnitID.", unit) |
error(("Bad argument #2 to 'GetUnitObjectFromUnit'. %q is not a legitimate UnitID."):format(unit)) |
end |
local name = UnitName(unit) |
return roster[name] |
vertical = -12, |
}, |
height = 10, |
incremental = true, |
border = "None", |
borderEdgeSize = 16, |
return castFrame |
end |
function AloftCastBar:NeedsBorder(aloftData, noInterrupt) |
if noInterrupt then |
return self.db.profile.nointerBorder ~= "None" |
else |
return self.db.profile.border ~= "None" |
end |
end |
function AloftCastBar:GetBorder(aloftData, noInterrupt) |
if noInterrupt then |
return ((self.db.profile.nointerBorder ~= "None") and self.db.profile.nointerBorderInset) or 0, SML:Fetch("border", self.db.profile.nointerBorder) |
local castBar = aloftData.castBar |
local value = castFrame.elapsedTime or 0.0 |
local minValue, maxValue = castBar:GetMinMaxValues() |
local width = (value / maxValue) * (castFrame:GetWidth() - (2 * inset)) |
local width = ((maxValue and maxValue > 0) and (value / maxValue) * (castFrame:GetWidth() - (2 * inset))) or 0 |
return minValue, value, maxValue, width |
end |
local minValue, value, maxValue, width = self:CalculateFrameWidth(aloftData, castFrame) |
if (value >= minValue) and (value <= maxValue) then |
local castRegion = castFrame.castRegion |
if width and castRegion then |
if width and width > 0 and castRegion then |
-- ChatFrame7:AddMessage("AloftCastBar:Update(): " .. tostring(aloftData.name) .. "/" .. tostring(value) .. "/" .. tostring(width)) |
if not castFrame.init or castFrame.init < BORDER_INIT_ATTEMPTS then |
if AloftCastBar:NeedsBorder(aloftData, noInterrupt) and self.db.profile.incremental and (not castFrame.init or castFrame.init < BORDER_INIT_ATTEMPTS) then |
castRegion:SetWidth(1) -- width is initially bogus, updated after a frame delay below |
end |
castFrame:Show() -- show on every value change |
-- frame delay to set the real width; hopefully avoids the "missing/malformed border" issue |
self:ScheduleTimer(function(arg) AloftCastBar:DoShowCastFrame(arg) end, 0.0, width) -- one frame |
if AloftCastBar:NeedsBorder(aloftData, noInterrupt) and self.db.profile.incremental then |
-- frame delay to set the real width; hopefully avoids the "missing/malformed border" issue |
self:ScheduleTimer(function(arg) AloftCastBar:DoShowCastFrame(arg) end, 0.0, width) -- one frame |
else |
self:DoShowCastFrame(width) |
end |
return |
end |
layoutFrame.manaTextRegion = manaTextRegion |
self:PrepareText(manaTextRegion, self.db.profile) |
self:PlaceFrame(manaTextRegion, layoutFrame, self.db.profile, 0, 0) |
end |
self:PrepareText(manaTextRegion, self.db.profile) |
-- ChatFrame7:AddMessage("AloftManaText:UpdateText(): " .. tostring(aloftData.name) |
-- .. "/" .. tostring(text) |
-- .. "/" .. tostring(self.textMethodData.functionString)) |
--[[ zhTW ]] dL["Tauren"] = "ç" |
--[[ zhTW ]] dL["Troll"] = "é£" |
--[[ zhTW ]] dL["Undead"] = "ä¸" |
--[[ zhTW ]] dL["Worgen"] = "Wo" |
--[[ zhTW ]] dL["Goblin"] = "Go" |
--[[ zhTW ]] dL["Worgen"] = "ç¼" |
--[[ zhTW ]] dL["Goblin"] = "å¥" |
----------------------------------------------------------------------------- |
-- This is checked against when we gather data. If it's not specified, don't store it. |
--[[ zhTW ]] dL["Not specified"] = "æªæå®" |
--[[ zhTW ]] dL["Non-combat Pet"] = "éæ°æ寵ç©" |
--[[ zhTW ]] dL["Non-combat Pet"] = "éæ°é¬¥å¯µç©" |
-- short forms |
--[[ zhTW ]] dL["ShortBeast"] = "é" |
--[[ zhTW ]] dL["PetTest"] = "(.*)ç寵ç©" |
--[[ zhTW ]] dL["MinionTest"] = "(.*)çåå¾" |
--[[ zhTW ]] dL["GuardianTest"] = "(.*)'s Guardian" |
--[[ zhTW ]] dL["GuardianTest"] = "(.*)çå®è·è " |
----------------------------------------------------------------------------- |
----------------------------------------------------------------------------- |
local groupTargetCount = setmetatable({ }, { __index = function() return 0 end }) |
local groupTargetGUIDCount = setmetatable({ }, { __index = function() return 0 end }) |
----------------------------------------------------------------------------- |
numeric = true |
} |
Aloft.TagData.GroupTargetGUIDCount = |
{ |
data = "groupTargetGUIDCount", |
events = "Aloft:OnGroupTargetGUIDCountChanged", |
tableData = "groupTargetGUIDCount", |
numeric = true |
} |
----------------------------------------------------------------------------- |
--[[ |
----------------------------------------------------------------------------- |
function AloftGroupTargetCountData:ProvidesData() |
return "groupTargetCount" |
return "groupTargetCount", "groupTargetGUIDCount" |
end |
function AloftGroupTargetCountData:EnableDataSource() |
-- ChatFrame7:AddMessage("AloftGroupTargetCountData:EnableDataSource(): enter") |
self:ScheduleRepeatingTimer(function() AloftGroupTargetCountData:Update() end, 0.25) -- 4x per second |
end |
----------------------------------------------------------------------------- |
function AloftGroupTargetCountData:Update() |
-- ChatFrame7:AddMessage("AloftGroupTargetCountData:Update(): enter") |
for k in pairs(groupTargetCount) do |
groupTargetCount[k] = nil |
end |
for k in pairs(groupTargetGUIDCount) do |
groupTargetGUIDCount[k] = nil |
end |
local groupTarget = nil |
local playerTarget = nil |
local playerTargetGUID = nil |
local raidMembers = GetNumRaidMembers() |
if raidMembers > 0 then |
groupTarget = true |
for i=1,raidMembers-1 do -- Exclude the player, who is the top raid# |
local name = UnitName("raid"..i.."target") |
local uid = "raid"..i.."target" |
local name = UnitName(uid) |
local guid = UnitGUID(uid) |
if name then |
groupTargetCount[name] = groupTargetCount[name] + 1 |
end |
if guid then |
groupTargetGUIDCount[guid] = groupTargetGUIDCount[guid] + 1 |
-- ChatFrame7:AddMessage("AloftGroupTargetCountData:Update(): raid " .. tostring(name) .. "/" .. tostring(guid) .. "/" .. tostring(groupTargetGUIDCount[guid])) |
end |
end |
else |
local partyMembers = GetNumPartyMembers() |
if partyMembers > 0 then |
groupTarget = true |
for i=1,partyMembers do |
local name = UnitName("party"..i.."target") |
local uid = "party"..i.."target" |
local name = UnitName(uid) |
local guid = UnitGUID(uid) |
if name then |
groupTargetCount[name] = groupTargetCount[name] + 1 |
end |
if guid then |
groupTargetGUIDCount[guid] = groupTargetGUIDCount[guid] + 1 |
-- ChatFrame7:AddMessage("AloftGroupTargetCountData:Update(): group " .. tostring(name) .. "/" .. tostring(guid) .. "/" .. tostring(groupTargetGUIDCount[guid])) |
end |
end |
elseif (UnitExists("pet")) then -- the simplest form of "group": the player with a pet |
playerTarget = UnitName("target") -- just add the player |
local guid = UnitGUID("target") |
if guid then |
groupTargetGUIDCount[guid] = groupTargetGUIDCount[guid] + 1 |
-- ChatFrame7:AddMessage("AloftGroupTargetCountData:Update(): player " .. tostring(name) .. "/" .. tostring(guid) .. "/" .. tostring(groupTargetGUIDCount[guid])) |
end |
end |
end |
-- TODO: incorporate race/class and raid target assignment to differentiate counts |
-- TODO: add an option to include pets? |
-- list of nameplates with a modified groupTargetGUIDCount |
local groupTargetGUIDList = { } |
for aloftData in Aloft:IterateVisibleNameplates() do |
-- clear the GUID target count |
local guid = aloftData.groupTargetGUIDCount |
if guid then |
aloftData.groupTargetGUIDCount = nil |
groupTargetGUIDList[aloftData] = true |
end |
-- process the name-based target count |
local count |
if (groupTarget) then |
if groupTarget then |
count = groupTargetCount[aloftData.name] |
elseif playerTarget == aloftData.name and (aloftData.isTarget or aloftData:IsTarget()) then |
count = 1 |
end |
if count ~= aloftData.groupTargetCount then -- this clears if needed |
aloftData.groupTargetCount = count |
self:SendMessage("Aloft:OnGroupTargetCountChanged", aloftData) |
end |
-- ChatFrame7:AddMessage("AloftGroupTargetCountData:Update(): " .. tostring(aloftData.name) .. "/" .. tostring(aloftData.groupTargetCount)) |
end |
local targetGUID = UnitGUID("target") |
if targetGUID then |
local aloftData = Aloft:GetTargetNameplate() |
if aloftData then |
local guid = groupTargetGUIDCount[targetGUID] |
if guid then |
aloftData.groupTargetGUIDCount = guid |
groupTargetGUIDList[aloftData] = true |
end |
end |
end |
for aloftData in pairs(groupTargetGUIDList) do |
groupTargetGUIDList[aloftData] = nil |
self:SendMessage("Aloft:OnGroupTargetGUIDCountChanged", aloftData) |
end |
end |
----------------------------------------------------------------------------- |
self.textMethodData = Aloft:CreateTag(self.db.profile.format, true) |
self.textMethod = self.textMethodData.method |
end |
-- ChatFrame7:AddMessage("AloftCommentText:UpdateText(): " .. tostring(message) .. "/" .. tostring(aloftData.name) .. "/" .. tostring(self.textMethodData.functionString)) |
local text = self.textMethod and self.textMethod(aloftData) |
-- ChatFrame7:AddMessage("AloftCommentText:UpdateText(): " .. tostring(aloftData.name) .. "/" .. tostring(text)) |
layoutFrame.commentTextRegion = commentTextRegion |
self:PrepareText(commentTextRegion, self.db.profile) |
self:PlaceFrame(commentTextRegion, layoutFrame, self.db.profile) |
end |
-- ChatFrame7:AddMessage("AloftCommentText:UpdateText(): assemble " .. tostring(aloftData.name) .. "/" .. tostring(text) .. "/" .. tostring(layoutFrame.commentTextRegion:GetText()) .. "/" .. tostring(layoutFrame) .. "/" .. tostring(layoutFrame.commentTextRegion:GetParent())) |
self:PrepareText(commentTextRegion, self.db.profile) |
commentTextRegion:SetText(text) |
commentTextRegion:Show() |
layoutFrame.guildTextRegion = guildTextRegion |
self:PrepareText(guildTextRegion, self.db.profile) |
self:PlaceFrame(guildTextRegion, layoutFrame, self.db.profile) |
end |
self:PrepareText(guildTextRegion, self.db.profile) |
guildTextRegion:SetText(text) |
guildTextRegion:Show() |
-- ChatFrame7:AddMessage("AloftGuildText:UpdateText(): show " .. tostring(aloftData.name) .. "/" .. tostring(text) .. "/" .. tostring(layoutFrame.guildTextRegion:GetText())) |
return |
end |
self.textMethodData = Aloft:CreateTag(self.db.profile.format, true) |
self.textMethod = self.textMethodData.method |
end |
-- ChatFrame7:AddMessage("AloftHealthText:UpdateText(): " .. tostring(message) .. "/" .. tostring(aloftData.name) .. "/" .. tostring(self.textMethodData.functionString)) |
local text = self.textMethod and self.textMethod(aloftData) |
-- ChatFrame7:AddMessage("AloftHealthText:UpdateText(): text " .. tostring(text)) |
-- ChatFrame7:AddMessage("AloftHealthText:UpdateText(): " .. tostring(aloftData.name) .. "/" .. tostring(text)) |
if text and text ~= "" then |
local layoutFrame = aloftData.layoutFrame |
layoutFrame.healthTextRegion = healthTextRegion |
self:PrepareText(healthTextRegion, self.db.profile) |
self:PlaceFrame(healthTextRegion, layoutFrame, self.db.profile, 0, 0) |
end |
self:PrepareText(healthTextRegion, self.db.profile) |
-- ChatFrame7:AddMessage("AloftHealthText:UpdateText(): " .. tostring(aloftData.name) .. "/" .. tostring(self.db.profile.offsetX) .. "/" .. tostring(self.db.profile.offsetY) .. "/" .. tostring(hinset) .. "/" .. tostring(vinset)) |
healthTextRegion:SetText(text) |
healthTextRegion:Show() |
return |
end |
self:OnNameplateHide(message, aloftData) |
----------------------------------------------------------------------------- |
-- COMBAT_LOG_* event handling; this is intended to replace UNIT_COMBAT event handling at some point, at least the "WOUND" event, so we can differentiate swing/"white" damage from spell damage |
function AloftCombatText:OnCombatLogEvent(event, timestamp, subtype, hideCaster, originGUId, originName, originFlags, targetGUId, targetName, targetFlags, suffix1, suffix2, suffix3, suffix4, suffix5, suffix6, suffix7, suffix8, suffix9, suffix10, suffix11, suffix12) |
function AloftCombatText:OnCombatLogEvent(event, timestamp, subtype, hideCaster, originGUId, originName, originFlags, originFlags2, targetGUId, targetName, targetFlags, argetFlags2, suffix1, suffix2, suffix3, suffix4, suffix5, suffix6, suffix7, suffix8, suffix9, suffix10, suffix11, suffix12) |
-- ChatFrame7:AddMessage(("|cff%02x%02x%02x%s|r"):format(255, 255, 0, "AloftCombatText:OnCombatLogEvent(): ") .. tostring(timestamp) .. "/" .. tostring(subtype) .. "/" .. tostring(originGUId) .. "/" .. tostring(originName) .. "/" .. tostring(originFlags) .. "/" .. tostring(targetGUId) .. "/" .. tostring(targetName) .. "/" .. tostring(targetFlags) |
-- .. "/" .. tostring(suffix1) .. "/" .. tostring(suffix2) .. "/" .. tostring(suffix3) .. "/" .. tostring(suffix4) .. "/" .. tostring(suffix5) .. "/" .. tostring(suffix6) .. "/" .. tostring(suffix7) .. "/" .. tostring(suffix8) .. "/" .. tostring(suffix9) .. "/" .. tostring(suffix10) .. "/" .. tostring(suffix11) .. "/" .. tostring(suffix12)) |
Aloft.TagData.Level = |
{ |
-- TODO: self-hook AloftLevelText as well, vis [Level]? |
events = "Aloft:OnUnitLevelChanged", |
tableData = "level", numeric = true, |
} |
Aloft.TagData.Name = |
{ |
-- NOTE: the data field here allows the AloftNameText module to self-hook itself into the data/module heirarchy; |
-- AloftNameText is an always-loaded module, and the [Name] tag is always valid, so this should be harmless, |
-- and it provides an anchor for things like the [Class] tag, if it is needed for various "Color By Class" option(s) |
data = "name", |
events = "Aloft:OnUnitNameChanged", |
tableData = "name", guaranteeResult = true |
tableData = "name", |
guaranteeResult = true |
} |
Aloft.TagData.HealthBarColor = |