WoWInterface SVN mikma

Compare Revisions

  • This comparison shows the changes necessary to convert path
    /EnemyScanner2
    from Rev 698 to Rev 699
    Reverse comparison

Rev 698 → Rev 699

EnemyScanner2.lua
1,3 → 1,13
-- mikma, 10/2014
 
-- debugprint works only if debug.EnemyScanner2 is set.
local function debugprint(chatframe,text,r,g,b)
if debug.EnemyScanner2 then
_G["ChatFrame"..chatframe]:AddMessage(text,r,g,b)
end
end
 
-- Let's create some locals.
local db
local _
local updating
3,31 → 13,28
local total = 0
local anchor = CreateFrame("Button", nil, UIParent)
ES2timer = CreateFrame("Frame")
ES2messages = {}
local ES2timer = CreateFrame("Frame")
local ES2messages = {}
local rows = {}
ES2temptable = {}
local ES2temptable = {}
local pvpmatch
 
if not EnemyScanner2DB then EnemyScanner2DB = {["position"] = {point = "RIGHT", x = -70, y = 0}, ["expire"] = 10,} end
-- If SavedVariables database does not exist, create it and add some default values for anchor, expiration time and temporary PvP table.
if not EnemyScanner2DB then EnemyScanner2DB = {["position"] = {point = "RIGHT", x = -70, y = 0}, ["expire"] = 10, ["PvP"] = {},} end
 
local function debugprint(chatframe,text,r,g,b)
if debug.EnemyScanner2 then
_G["ChatFrame"..chatframe]:AddMessage(text,r,g,b)
end
end
 
-- bit.band the sourceflag to check the following:
-- bit.band the flag to check the following:
-- Type: COMBATLOG_OBJECT_TYPE_PLAYER 0x00000400
-- Controller: COMBATLOG_OBJECT_CONTROL_PLAYER 0x00000100
-- Reaction: COMBATLOG_OBJECT_REACTION_HOSTILE 0x00000040
-- Controller affiliation: COMBATLOG_OBJECT_AFFILIATION_OUTSIDER 0X00000008
-- PLAYER controlled by PLAYER which is REACTION HOSTILE and is OUTSIDER (not in raid or party with you)
-- PLAYER controlled by PLAYER which is REACTION HOSTILE and is OUTSIDER (not in raid or party with you).
local function isTargetHostile(flag)
local HOSTILEUNITFLAG = 0x548
if bit.band(flag,HOSTILEUNITFLAG) == HOSTILEUNITFLAG then
-- Yeap!
return true
end
end
 
-- Converts R,G,B into hexcolor. Example: RAID_CLASS_COLORS['SHAMAN'] (r,g,b) 0,0.44,0,87 turns into '|cff0070dd'
-- Converts R,G,B into hexcolor. Example: RAID_CLASS_COLORS['SHAMAN'] (r,g,b) 0,0.44,0,87 turns into '|cff0070dd'.
local function DecimalToHex(r,g,b)
return string.format("|cff%02x%02x%02x", r*255, g*255, b*255)
39,18 → 46,61
if self[event] then return self[event](self, event, ...) end
end)
 
EnemyScanner2:RegisterEvent("PLAYER_ENTERING_WORLD")
-- Register all the needed events.
function EnemyScanner2:Enable()
EnemyScanner2:RegisterEvent("COMBAT_LOG_EVENT_UNFILTERED")
EnemyScanner2:RegisterEvent("PLAYER_LOGIN")
EnemyScanner2:RegisterEvent("UPDATE_MOUSEOVER_UNIT")
EnemyScanner2:RegisterEvent("PLAYER_TARGET_CHANGED")
EnemyScanner2:RegisterEvent("ZONE_CHANGED_NEW_AREA")
end
 
-- Realm name is available only after PEW
function EnemyScanner2:PLAYER_ENTERING_WORLD()
-- Unregister all events except ZONE_CHANGED_NEW_AREA, which is used to enable the addon once again.
function EnemyScanner2:Disable()
EnemyScanner2:UnregisterAllEvents()
EnemyScanner2:RegisterEvent("ZONE_CHANGED_NEW_AREA")
updating = ES2timer:GetScript("OnUpdate")
-- Clear the messages and disable onUpdate timer
if updating then
EnemyScanner2:Clear()
ES2timer:SetScript("OnUpdate",nil)
end
end
 
-- We use this to enable/disable the addon when player enter instance.
function EnemyScanner2:ZONE_CHANGED_NEW_AREA()
local instancetype = select(2,GetInstanceInfo())
if instancetype == "pvp" then
table.wipe(EnemyScanner2DB["PvP"])
EnemyScanner:Enable()
pvpmatch = true
-- Change temptable to PvP.
temptable = EnemyScanner2DB["PvP"]
EnemyScanner2DB.expire = 10
EnemyScanner2:Clear()
debugprint(3,"EnemyScanner2 PvP",0,0,1)
elseif instancetype == "party" or instancetype == "raid" or instancetype == "arena" then
EnemyScanner2:Disable()
debugprint(3,"EnemyScanner2 Disabled",1,0,0)
else
-- Change temptable to realmName.
temptable = EnemyScanner2DB[realmName]
EnemyScanner2DB.expire = 30
EnemyScanner2:Enable()
if pvpmatch then
EnemyScanner2:Clear()
pvpmatch = nil
end
debugprint(3,"EnemyScanner2 Enabled",0,1,0)
end
end
 
-- realmName is available after login.
function EnemyScanner2:PLAYER_LOGIN()
local realmName = GetCVar("realmName")
if not EnemyScanner2DB[realmName] then EnemyScanner2DB[realmName] = {} end
db = EnemyScanner2DB[realmName]
EnemyScanner2:RegisterEvent("COMBAT_LOG_EVENT_UNFILTERED")
EnemyScanner2:RegisterEvent("UPDATE_MOUSEOVER_UNIT")
EnemyScanner2:RegisterEvent("PLAYER_TARGET_CHANGED")
EnemyScanner2:UnregisterEvent("PLAYER_ENTERING_WORLD")
EnemyScanner2:Initialize()
EnemyScanner2:ZONE_CHANGED_NEW_AREA()
end
 
local function GetStats(unit)
60,7 → 110,7
local level = UnitLevel(unit)
local name = UnitName(unit)
local classFilename = select(2,UnitClass(unit))
-- In case game haven't had the time to cache the player's name yet
-- In case game haven't had the time to cache the player's name yet.
if name == "Unknown" then
debugprint(4,"Mouseover: "..guidsource.." has no name yet?",1,0,0)
return
77,7 → 127,7
debugprint(4,"Mouseover: "..name.." added and level set to: "..level)
end
 
-- Player exists in the database but level is greater than the one stored, upgrade it
-- Player exists in the database but level is greater than the one stored, upgrade it.
if level > db[guidsource] then
db[guidsource] = level
debugprint(4,"Mouseover: "..name.." upgraded level to: "..level)
103,60 → 153,68
end
end
 
-- Get stats of unit (mouseover)
-- Get stats of unit (mouseover).
function EnemyScanner2:UPDATE_MOUSEOVER_UNIT()
GetStats("mouseover")
end
 
-- Get stats of unit (tab-target)
-- Get stats of unit (tab-target).
function EnemyScanner2:PLAYER_TARGET_CHANGED()
GetStats("target")
end
 
-- Remember to make this local.
tooltiptable = {}
-- We use this to store the guid of the players if they are at max level so they won't be scanned again.
local tooltiptable = {}
 
-- SEMI-Working? What will happen to the 'Level ??' players?
-- Let's create a simple tooltip what we use to scan the players. - Thanks Semlar!
local tooltip = CreateFrame("GameTooltip")
local toolText2 = tooltip:CreateFontString()
local toolText3 = tooltip:CreateFontString()
-- We only care about the Line2 left text (person's level without guild) and Line3 left text (person's level in a guild).
tooltip:AddFontStrings(tooltip:CreateFontString(),tooltip:CreateFontString())
tooltip:AddFontStrings(toolText2, tooltip:CreateFontString())
tooltip:AddFontStrings(toolText3, tooltip:CreateFontString())
tooltip:SetOwner(UIParent, "ANCHOR_NONE")
 
-- Working!
local function tooltipScanner(guid)
local tooltip = ES2ScanTooltip or CreateFrame("GameTooltip","ES2ScanTooltip",UIParent,"GameTooltipTemplate")
tooltip:SetOwner(UIParent, "ANCHOR_NONE")
tooltip:SetPoint("BOTTOMRIGHT",UIParent,"BOTTOMRIGHT")
local tooltip = tooltip
tooltip:ClearLines()
tooltip:SetHyperlink('unit:' .. guid)
if not tooltiptable[guid] then tooltiptable[guid] = true end
tooltip:Show()
local close = CreateFrame("Button", nil, tooltip, "UIPanelCloseButton")
close:SetPoint("TOPRIGHT",tooltip,"TOPLEFT",5,5)
close:SetScript("OnClick", function()
tooltip:Hide()
end)
 
local printline
local lines = tooltip:NumLines()
local maxlevel = GetMaxPlayerLevel()
local maxplayerlevel = MAX_PLAYER_LEVEL_TABLE[GetAccountExpansionLevel()]
local maxclientlevel = MAX_PLAYER_LEVEL_TABLE[GetExpansionLevel()]
local lines = tooltip:NumLines()
-- debugprint required stuff, can be deleted later.
local class, classFilename, race, raceFilename, sex, name, realm = GetPlayerInfoByGUID(guid)
 
if lines > 0 then
for i=1,lines do
if string.match(_G["ES2ScanTooltipTextLeft"..i]:GetText(), "Level %d+") then
printline = string.match(_G["ES2ScanTooltipTextLeft"..i]:GetText(), "%d+")
if name then
tooltip:Hide()
else
debugprint(4,"Tooltip: name not cached yet!",1,0,0)
return
end
debugprint(4,"Tooltip: scanning "..guid..": "..name..", "..printline)
return tonumber(printline)
elseif string.match(_G["ES2ScanTooltipTextLeft"..i]:GetText(), "Level ??") then
debugprint(4,"Tooltip: scanning "..guid..": "..name..", ??")
return "??"
if string.match(toolText2:GetText(), "Level %d+") then
printline = string.match(toolText2:GetText(), "%d+")
if not name then debugprint(4,"Tooltip: name not cached yet!",1,0,0); return; end
debugprint(4,"Tooltip: scanning "..guid..": "..name..", "..printline)
return tonumber(printline)
elseif string.match(toolText3:GetText(), "Level %d+") then
printline = string.match(toolText3:GetText(), "%d+")
if not name then debugprint(4,"Tooltip: name not cached yet!",1,0,0); return; end
debugprint(4,"Tooltip: scanning "..guid..": "..name..", "..printline)
return tonumber(printline)
elseif string.match(toolText2:GetText(), "Level ??") then
debugprint(4,"Tooltip: scanning "..guid..": "..name..", ??")
if UnitLevel("player") <= MAX_PLAYER_LEVEL_TABLE[GetAccountExpansionLevel()] - 10 then
return UnitLevel("player")+10
else
return 0
end
end
elseif string.match(toolText3:GetText(), "Level ??") then
debugprint(4,"Tooltip: scanning "..guid..": "..name..", ??")
if UnitLevel("player") <= MAX_PLAYER_LEVEL_TABLE[GetAccountExpansionLevel()] - 10 then
return UnitLevel("player")+10
else
return 0
end
end
end
 
end
 
-- Working!
178,6 → 236,7
end
end
 
-- Working!
function EnemyScanner2:COMBAT_LOG_EVENT_UNFILTERED(_, _, minievent, _, guidsource, source, sourceflags, sourceflagsraid, guidtarget, target, targetflags, targetflagsraid, ...)
if isTargetHostile(sourceflags) then --and not UnitIsPVPSanctuary("player") then
if guidsource == '' then
201,6 → 260,7
}
 
-- Spell alert will show messages only once, after spell has been applied.
-- Might need to find a better way of printing the alerts on screen.
if minievent == "SPELL_AURA_APPLIED" then
if spellwatch[spellID] then
local classFilename = select(2,GetPlayerInfoByGUID(guidsource))
211,27 → 271,27
end
end
 
-- Catch if action is melee
-- Catch if action is melee.
if minievent:match("[^_]+") == "SWING" then
-- Turn ie. "SWING_MISS" text into "Swing Miss"
-- Turn ie. "SWING_MISS" text into "Swing Miss".
spellName = minievent:gsub('_',' '):lower()
spellName = spellName:gsub("(%l)(%w*)", function(a,b) return string.upper(a)..b end)
end
 
-- Check if action is spell
-- Check if action is spell.
if minievent:match("[^_]+") ~= "SWING" and tonumber(spellID) then
level = GetSpellLevelLearned(spellID)
spellName = GetSpellLink(spellID)
end
 
-- GUID does not exist in database, add as level 0
-- GUID does not exist in database, add as level 0.
if not db[guidsource] then
db[guidsource] = 0
end
 
-- If spell is greater than the one stored in database, upgrade it in the database
-- If spell is greater than the one stored in database, upgrade it in the database.
if level and (db[guidsource] < level) then
-- If spell level is greater than current max level in player's expansion, don't upgrade
-- If spell level is greater than current max level in player's expansion, don't upgrade.
if level > MAX_PLAYER_LEVEL_TABLE[GetAccountExpansionLevel()] then
level = MAX_PLAYER_LEVEL_TABLE[GetAccountExpansionLevel()]
else
240,11 → 300,10
db[guidsource] = level
end
 
-- Let's do some tooltip magics!
-- Let's do some tooltip scanning!
local tooltiplevel
if guidsource ~= '' and not tooltiptable[guidsource] and db[guidsource] < 90 then
tooltiplevel = tooltipScanner(guidsource)
-- The next following line will propably result in ERROR with 'Level ??'!
if (tooltiplevel and level) and (tooltiplevel > level) then
db[guidsource] = tooltiplevel
end
294,7 → 353,7
end
 
-- Working!
-- Initialize the anchor where rows are SetPoint'd
-- Initialize the anchor where rows are SetPoint'd.
function EnemyScanner2:Initialize()
anchor:SetFrameStrata("MEDIUM")
anchor:SetHeight(30)
317,7 → 376,7
 
-- Working!
-- Make sure nothing gets added if name is not found!
-- Adds a message to the alert frame, returns a uid
-- Adds a message to the alert frame, returns a uid.
function EnemyScanner2:AddMessage(name, level, spotted, class)
if not name then debugprint(4,"AddMessage: Name not found!",1,0,0) return end
if name == "Unknown" then debugprint(4,"AddMessage: Name not cached!",1,0,0) return end
334,7 → 393,7
 
 
-- Working!
-- Edits a message if it already exists and is being displayed in alert frame
-- Edits a message if it already exists and is being displayed in alert frame.
function EnemyScanner2:EditMessage(uid,level,spotted)
for i=1,#ES2messages do
if ES2messages[i] == uid then
347,7 → 406,7
end
 
-- Working!
-- Removes a message from the alert frame
-- Removes a message from the alert frame.
function EnemyScanner2:DelMessage(uid)
for i=1,#ES2messages do
if ES2messages[i] == uid then
359,16 → 418,16
end
 
-- Working!
-- Clears all messages from alert frame
-- Clears all messages from alert frame.
function EnemyScanner2:Clear()
table.wipe(ES2messages)
EnemyScanner2:Update()
end
 
-- Working!
-- Updates the frame to display
-- Updates the frame to display.
function EnemyScanner2:Update()
-- Create enough frames, if necessary
-- Create enough frames, if necessary.
for i=#rows + 1, #ES2messages, 1 do
row = CreateFrame("Button", nil, UIParent)
row:SetFrameStrata("MEDIUM")
377,7 → 436,7
row.text:SetJustifyH("RIGHT")
rows[i] = row
end
-- Anchor the frames in order
-- Anchor the frames in order.
for idx,entry in ipairs(ES2messages) do
local row = rows[idx]
if idx == 1 then
407,8 → 466,13
row.text:SetTextColor(raidclass.r, raidclass.g, raidclass.b, 1)
row:Show()
end
-- Hide any extra frames
-- Hide any extra frames.
for i=#rows, #ES2messages + 1, -1 do
rows[i]:Hide()
end
end
\ No newline at end of file +end + +-- Initialize the anchor frame. +EnemyScanner2:Initialize() +-- Enable the addon by registering all the needed events. +EnemyScanner2:Enable() \ No newline at end of file