/EnemyScanner2
local db |
local _ |
local updating |
local total = 0 |
local anchor = CreateFrame("Button", nil, UIParent) |
ES2timer = CreateFrame("Frame") |
ES2messages = {} |
local rows = {} |
ES2temptable = {} |
if not EnemyScanner2DB then EnemyScanner2DB = {["position"] = {point = "RIGHT", x = -70, y = 0}, ["expire"] = 10,} 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: |
-- 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) |
local function isTargetHostile(flag) |
local HOSTILEUNITFLAG = 0x548 |
if bit.band(flag,HOSTILEUNITFLAG) == HOSTILEUNITFLAG then |
end |
end |
-- 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) |
end |
local EnemyScanner2 = CreateFrame("Button", nil, UIParent) |
EnemyScanner2 = CreateFrame("Button", nil, UIParent) |
EnemyScanner2:SetScript("OnEvent", function(self, event, ...) |
if self[event] then return self[event](self, event, ...) end |
end) |
EnemyScanner2:RegisterEvent("PLAYER_ENTERING_WORLD") |
-- Realm name is available only after PEW |
function EnemyScanner2:PLAYER_ENTERING_WORLD() |
-- Realm name is available only after PEW |
local realmName = GetCVar("realmName") |
if not EnemyScanner2DB then |
EnemyScanner2DB = { [realmName] = {}, } |
end |
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() |
end |
local function GetStats(unit) |
-- Unit exists, Unit is a player, and Unit is enemy to you. |
if UnitExists(unit) and UnitIsPlayer(unit) and UnitIsEnemy("player",unit) then |
local guidsource = UnitGUID(unit) |
local level = UnitLevel(unit) |
local class, classFilename, race, raceFilename, sex, name, realm = GetPlayerInfoByGUID(guidsource) |
local added = "" |
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 |
if name == "Unknown" then |
debugprint(4,"Mouseover: "..guidsource.." has no name yet?",1,0,0) |
return |
end |
-- Level is shown as '-1' with UnitLevel if the target is ovet 10 levels over your level. |
if level == -1 then |
level = UnitLevel("player")+10 |
end |
-- Player doesn't exist in the database, create a spot for player in database. |
if not db[guidsource] then |
db[guidsource] = level |
debugprint(4,name.." added and level set to: "..level) |
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 |
if level > db[guidsource] then |
db[guidsource] = level |
debugprint(4,name.." upgraded level to: "..level) |
debugprint(4,"Mouseover: "..name.." upgraded level to: "..level) |
end |
local found = false |
-- Let's check is the player shown on screen. |
for i=1,#ES2messages do |
if name == ES2messages[i]["name"] then |
-- Yeap! |
found = true |
end |
end |
-- Player was not on screen, let's add him. |
if not found then |
local uid = EnemyScanner2:AddMessage(name, db[guidsource], time()+EnemyScanner2DB.expire, classFilename) |
ES2temptable[guidsource] = uid |
-- Player was shown, let's upgrade the duration. |
else |
local uid = ES2temptable[guidsource] |
EnemyScanner2:EditMessage(uid,db[guidsource],time()+EnemyScanner2DB.expire) |
end |
end |
end |
-- Get stats of unit (mouseover) |
function EnemyScanner2:UPDATE_MOUSEOVER_UNIT() |
GetStats("mouseover") |
end |
-- Get stats of unit (tab-target) |
function EnemyScanner2:PLAYER_TARGET_CHANGED() |
GetStats("target") |
end |
-- Remember to make this local. |
tooltiptable = {} |
-- SEMI-Working? What will happen to the 'Level ??' players? |
local function tooltipScanner(guid) |
local tooltip = TestTooltip or CreateFrame("GameTooltip","TestTooltip",UIParent,"GameTooltipTemplate") |
local tooltip = ES2ScanTooltip or CreateFrame("GameTooltip","ES2ScanTooltip",UIParent,"GameTooltipTemplate") |
tooltip:SetOwner(UIParent, "ANCHOR_NONE") |
tooltip:SetPoint("BOTTOMRIGHT",UIParent,"BOTTOMRIGHT") |
tooltip:ClearLines() |
if not tooltiptable[guid] then tooltiptable[guid] = true end |
tooltip:Show() |
local close = CreateFrame("Button", nil, tooltip, "UIPanelCloseButton") |
close:SetPoint("TOPLEFT") |
close:SetPoint("TOPRIGHT",tooltip,"TOPLEFT",5,5) |
close:SetScript("OnClick", function() |
tooltip:Hide() |
end) |
local printline |
local line2 = TestTooltipTextLeft2:GetText() |
local line3 = TestTooltipTextLeft3:GetText() |
if string.match(line2, "Level %d+") then |
printline = string.match(line2, "%d+") |
elseif string.match(line3, "Level %d+") then |
printline = string.match(line3, "%d+") |
local lines = tooltip:NumLines() |
local maxlevel = GetMaxPlayerLevel() |
local maxplayerlevel = MAX_PLAYER_LEVEL_TABLE[GetAccountExpansionLevel()] |
local maxclientlevel = MAX_PLAYER_LEVEL_TABLE[GetExpansionLevel()] |
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 "??" |
end |
end |
end |
end |
-- Working! |
local function onUpdate(self,elapsed) |
total = total + elapsed |
if total >= 1 then |
updating = ES2timer:GetScript("OnUpdate") |
if updating and not next(ES2messages) then |
ES2timer:SetScript("OnUpdate",nil) |
EnemyScanner2:Clear() |
end |
for k,v in pairs(ES2temptable) do |
if time() == v["spotted"] then |
local uid = ES2temptable[k] |
EnemyScanner2:DelMessage(uid) |
end |
end |
total = 0 |
end |
if tonumber(printline) then |
tooltip:Hide() |
return tonumber(printline) |
else |
--debugprint(4,tostring(printline)) |
return false |
end |
end |
function EnemyScanner2:COMBAT_LOG_EVENT_UNFILTERED(_, _, minievent, _, guidsource, source, sourceflags, sourceflagsraid, guidtarget, target, targetflags, targetflagsraid, ...) |
return |
end |
local updating = ES2timer:GetScript("OnUpdate") |
-- Remove -Servername from player's name. |
source = source:match("[^-]+") |
local spellID,spellName = ... |
local level |
-- Stealth/Prowl watch |
-- Stealth/Prowl/Invisibility watch. |
local spellwatch = { |
[66] = true, -- Mage, Invisibility |
[110959] = true, -- Mage, Greater Invisibility |
[1784] = true, -- Rogue, Stealth |
[5215] = true, -- Druid, Prowl |
} |
-- Spell alert will show messages only once, after spell has been applied. |
if minievent == "SPELL_AURA_APPLIED" then |
if spellwatch[spellID] then |
local classFilename = select(2,GetPlayerInfoByGUID(guidsource)) |
spellName = GetSpellLink(spellID) |
end |
-- GUID does not exist in database, add as level 0 |
if not db[guidsource] then |
db[guidsource] = 0 |
end |
local texture = select(3,GetSpellInfo(spellID)) |
if not texture then |
texture = "Interface\\Icons\\INV_MISC_QUESTIONMARK" |
end |
-- 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 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 |
-- Let's do some tooltip magics! |
local tooltiplevel |
if guidsource ~= '' and not tooltiptable[guidsource] and db[guidsource] < 90 then |
debugprint(4,"Creating tooltip for "..guidsource) |
tooltiplevel = tooltipScanner(guidsource) |
if tooltiplevel and tooltiplevel > level then |
-- The next following line will propably result in ERROR with 'Level ??'! |
if (tooltiplevel and level) and (tooltiplevel > level) then |
db[guidsource] = tooltiplevel |
end |
end |
local class, classFilename, race, raceFilename, sex, name, realm = GetPlayerInfoByGUID(guidsource) |
local r,g,b = RAID_CLASS_COLORS[classFilename].r,RAID_CLASS_COLORS[classFilename].g,RAID_CLASS_COLORS[classFilename].b |
local levelcolor = GetQuestDifficultyColor(db[guidsource]) |
local levelcolorhex = DecimalToHex(levelcolor.r,levelcolor.g,levelcolor.b) |
debugprint(3,source.." |T"..texture..":0|t "..spellName.." - "..levelcolorhex..db[guidsource],r,g,b) |
--[[ <START> debugprint for ChatFrame3 ]] |
local texture = select(3,GetSpellInfo(spellID)) |
if not texture then |
texture = "Interface\\Icons\\INV_MISC_QUESTIONMARK" |
end |
local r,g,b |
if not classFilename then |
debugprint(3,"debugprint: "..guidsource.." does not have classFilename",1,0,0) |
r,g,b = 0.5,0.5,0.5 |
else |
r,g,b = RAID_CLASS_COLORS[classFilename].r,RAID_CLASS_COLORS[classFilename].g,RAID_CLASS_COLORS[classFilename].b |
end |
local levelcolor = GetQuestDifficultyColor(db[guidsource]) |
local levelcolorhex = DecimalToHex(levelcolor.r,levelcolor.g,levelcolor.b) |
debugprint(3,source.." |T"..texture..":0|t "..spellName.." - "..levelcolorhex..db[guidsource],r,g,b) |
--[[ <END> debugprint for ChatFrame3 ]] |
local found = false |
for i=1,#ES2messages do |
if source == ES2messages[i]["name"] then |
found = true |
end |
end |
-- If the player is new |
if not found then |
local uid = EnemyScanner2:AddMessage(source, db[guidsource], time()+EnemyScanner2DB.expire, classFilename) |
ES2temptable[guidsource] = uid |
-- If the player is already listed but does something new, refresh the expire. |
else |
local uid = ES2temptable[guidsource] |
EnemyScanner2:EditMessage(uid,db[guidsource],time()+EnemyScanner2DB.expire) |
end |
-- If we are not running onUpdate and there are messages in the queue, start it. |
if not updating and next(ES2messages) then |
ES2timer:SetScript("OnUpdate",onUpdate) |
end |
end |
end |
-- Working! |
-- Initialize the anchor where rows are SetPoint'd |
function EnemyScanner2:Initialize() |
anchor:SetFrameStrata("MEDIUM") |
anchor:SetHeight(30) |
anchor:SetBackdrop(GameTooltip:GetBackdrop()) |
anchor:SetBackdropColor(0.3, 0.3, 0.3) |
anchor.text = anchor:CreateFontString(nil, "BACKGROUND", "GameFontNormal") |
anchor.text:SetAllPoints(true) |
anchor.text:SetText("EnemyScanner2") |
anchor:SetWidth(anchor.text:GetStringWidth() + 16) |
anchor:EnableMouse(true) |
anchor:SetMovable(true) |
anchor:RegisterForDrag("LeftButton") |
anchor:SetScript("OnDragStart", anchor.StartMoving) |
anchor:SetScript("OnDragStop", function(self) |
self:StopMovingOrSizing() |
EnemyScanner2DB.position.point, EnemyScanner2DB.position.x, EnemyScanner2DB.position.y = "BOTTOMLEFT", self:GetLeft(), self:GetBottom() |
end) |
anchor:SetPoint(EnemyScanner2DB.position.point, EnemyScanner2DB.position.x, EnemyScanner2DB.position.y) |
end |
-- Working! |
-- Make sure nothing gets added if name is not found! |
-- 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 |
local uid = { |
name = name or "Unknown", |
level = level or 1, |
spotted = spotted or time()+EnemyScanner2DB.expire, |
class = class or "Priest" |
} |
table.insert(ES2messages, uid) |
EnemyScanner2:Update() |
return uid |
end |
-- Working! |
-- 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 |
ES2messages[i].level = level |
ES2messages[i].spotted = spotted |
EnemyScanner2:Update() |
return |
end |
end |
end |
-- Working! |
-- Removes a message from the alert frame |
function EnemyScanner2:DelMessage(uid) |
for i=1,#ES2messages do |
if ES2messages[i] == uid then |
table.remove(ES2messages, i) |
EnemyScanner2:Update() |
return |
end |
end |
end |
-- Working! |
-- Clears all messages from alert frame |
function EnemyScanner2:Clear() |
table.wipe(ES2messages) |
EnemyScanner2:Update() |
end |
-- Working! |
-- Updates the frame to display |
function EnemyScanner2:Update() |
-- Create enough frames, if necessary |
for i=#rows + 1, #ES2messages, 1 do |
row = CreateFrame("Button", nil, UIParent) |
row:SetFrameStrata("MEDIUM") |
row.text = row:CreateFontString(nil, "OVERLAY") |
row.text:SetPoint("RIGHT", 0, 0) |
row.text:SetJustifyH("RIGHT") |
rows[i] = row |
end |
-- Anchor the frames in order |
for idx,entry in ipairs(ES2messages) do |
local row = rows[idx] |
if idx == 1 then |
row:ClearAllPoints() |
row:SetPoint("TOPRIGHT", anchor, "BOTTOMRIGHT", 0, 5) |
else |
row:ClearAllPoints() |
row:SetPoint("TOPRIGHT", rows[idx-1], "BOTTOMRIGHT", 0, 5) |
end |
row:SetHeight(20) |
row:SetWidth(250) |
row.text:SetFontObject("GameFontNormal") |
row:EnableMouse(false) |
if tonumber(entry.level) then |
local levelcolor = GetQuestDifficultyColor(entry.level) |
local levelcolorhex = DecimalToHex(levelcolor.r,levelcolor.g,levelcolor.b) |
row.text:SetText(entry.name.." "..levelcolorhex..entry.level) |
else |
local levelcolorhex = DecimalToHex(1,0,0) |
row.text:SetText(entry.name.." "..levelcolorhex..entry.level) |
end |
local raidclass = RAID_CLASS_COLORS[entry.class] |
if not raidclass then |
raidclass = {} |
raidclass.r, raidclass.g, raidclass.b = 0.5, 0.5, 0.5 |
end |
row.text:SetTextColor(raidclass.r, raidclass.g, raidclass.b, 1) |
row:Show() |
end |
-- Hide any extra frames |
for i=#rows, #ES2messages + 1, -1 do |
rows[i]:Hide() |
end |
end |
## SavedVariables: EnemyScanner2DB |
## Version: 1 |
EnemyScanner2.lua |