diff --git a/Categories/Characteristics.lua b/Categories/Characteristics.lua index 7d9401b..70f6ba0 100644 --- a/Categories/Characteristics.lua +++ b/Categories/Characteristics.lua @@ -1,23 +1,23 @@ local MAJOR_VERSION = "LibDogTag-3.0" local MINOR_VERSION = tonumber(("$Revision$"):match("%d+")) or 0 -if MINOR_VERSION > _G.DogTag_MINOR_VERSION then - _G.DogTag_MINOR_VERSION = MINOR_VERSION +if MINOR_VERSION > _G.DogTag_Unit_MINOR_VERSION then + _G.DogTag_Unit_MINOR_VERSION = MINOR_VERSION end DogTag_Unit_funcs[#DogTag_Unit_funcs+1] = function(DogTag_Unit, DogTag) local L = DogTag_Unit.L -local FakeGlobals = DogTag.FakeGlobals DogTag:AddTag("Unit", "IsFriend", { - code = [=[return UnitIsFriend('player', ${unit})]=], + code = function(unit) + return UnitIsFriend('player', unit) + end, arg = { 'unit', 'string', '@req' }, ret = "boolean", events = "UNIT_FACTION#$unit", - globals = "UnitIsFriend", doc = L["Return True if unit is a friend"], example = ('[IsFriend] => %q; [IsFriend] => ""'):format(L["True"]), category = L["Characteristics"] @@ -34,12 +34,13 @@ DogTag:AddTag("Unit", "IsEnemy", { }) DogTag:AddTag("Unit", "CanAttack", { - code = [[return UnitCanAttack('player', ${unit})]], + code = function(unit) + return UnitCanAttack('player', unit) + end, arg = { 'unit', 'string', '@req' }, ret = "boolean", - globals = "UnitCanAttack", events = "UNIT_FACTION#$unit", doc = L["Return True if unit can be attacked"], example = ('[CanAttack] => %q; [CanAttack] => ""'):format(L["True"]), @@ -47,42 +48,41 @@ DogTag:AddTag("Unit", "CanAttack", { }) DogTag:AddTag("Unit", "Name", { - code = [[return UnitName(${unit})]], + code = UnitName, arg = { 'unit', 'string', '@req' }, ret = "string", events = "UNIT_NAME_UPDATE#$unit", - globals = "UnitName", doc = L["Return the name of unit"], example = ('[Name] => %q'):format(UnitName("player")), category = L["Characteristics"] }) DogTag:AddTag("Unit", "Exists", { - code = [[return UnitExists(${unit})]], + code = UnitExists, arg = { 'unit', 'string', '@req' }, ret = "boolean", - globals = "UnitExists", doc = L["Return True if unit exists"], example = ('[Exists] => %q; [Exists] => ""'):format(L["True"]), category = L["Characteristics"] }) DogTag:AddTag("Unit", "Realm", { - code = [[local _, realm = UnitName(${unit}) - if realm == "" then - realm = nil - end - return realm]], + code = function(unit) + local _, realm = UnitName(unit) + if realm == "" then + realm = nil + end + return realm + end, arg = { 'unit', 'string', '@req' }, ret = "string;nil", events = "UNIT_NAME_UPDATE#$unit", - globals = "UnitName", doc = L["Return the realm of unit if not your own realm"], example = ('[Realm] => %q'):format(GetRealmName()), category = L["Characteristics"] @@ -99,17 +99,18 @@ DogTag:AddTag("Unit", "NameRealm", { }) DogTag:AddTag("Unit", "Level", { - code = [[local level = UnitLevel(${unit}) - if level <= 0 then - level = "??" - end - return level]], + code = function(unit) + local level = UnitLevel(unit) + if level <= 0 then + level = "??" + end + return level + end, arg = { 'unit', 'string', '@req' }, ret = "number;string", events = "UNIT_LEVEL#$unit", - globals = "UnitLevel", doc = L["Return the level of unit"], example = ('[Level] => "%d"; [Level] => "??"'):format(UnitLevel("player")), category = L["Characteristics"] @@ -126,36 +127,41 @@ DogTag:AddTag("Unit", "IsMaxLevel", { }) DogTag:AddTag("Unit", "Class", { - code = ([[return UnitClass]] .. (_G.UnitClassBase and "Base" or "") .. [[(${unit}) or %q]]):format(UNKNOWN), + code = _G.UnitClassBase and function(unit) + return UnitClassBase(unit) or UNKNOWN + end or function(unit) + return UnitClass(unit) or UNKNOWN + end, arg = { 'unit', 'string', '@req' }, ret = "string", - globals = _G.UnitClassBase and "UnitClassBase" or "UnitClass", doc = L["Return the class of unit"], example = ('[Class] => %q'):format((UnitClass("player"))), category = L["Characteristics"] }) DogTag:AddTag("Unit", "Creature", { - code = ([[return UnitCreatureFamily(${unit}) or UnitCreatureType(${unit}) or %q]]):format(UNKNOWN), + code = function(unit) + return UnitCreatureFamily(unit) or UnitCreatureType(unit) or UNKNOWN + end, arg = { 'unit', 'string', '@req' }, ret = "string", - globals = "UnitCreatureFamily;UnitCreatureType", doc = L["Return the creature family or type of unit"], example = ('[Creature] => %q; [Creature] => %q'):format(L["Cat"], L["Humanoid"]), category = L["Characteristics"] }) DogTag:AddTag("Unit", "CreatureType", { - code = ([[return UnitCreatureType(${unit}) or %q]]):format(UNKNOWN), + code = function(unit) + return UnitCreatureType(unit) or UNKNOWN + end, arg = { 'unit', 'string', '@req' }, ret = "string", - globals = "UnitCreatureType", doc = L["Return the creature type of unit"], example = ('[CreatureType] => %q; [CreatureType] => %q'):format(L["Beast"], L["Humanoid"]), category = L["Characteristics"] @@ -163,35 +169,35 @@ DogTag:AddTag("Unit", "CreatureType", { DogTag:AddTag("Unit", "Classification", { - code = ([[local c = UnitClassification(${unit}) - if c == "rare" then - return %q - elseif c == "rareelite" then - return %q - elseif c == "elite" then - return %q - elseif c == "worldboss" then - return %q - else - return nil - end]]):format(L["Rare"], L["Rare-Elite"], L["Elite"], L["Boss"]), + code = function(unit) + local c = UnitClassification(unit) + if c == "rare" then + return L["Rare"] + elseif c == "rareelite" then + return L["Rare-Elite"] + elseif c == "elite" then + return L["Elite"] + elseif c == "worldboss" then + return L["Boss"] + else + return nil + end + end, arg = { 'unit', 'string', '@req' }, ret = "string;nil", - globals = "UnitClassification", doc = L["Return the classification of unit"], example = ('[Classification] => %q; [Classification] => %q; [Classification] => ""'):format(L["Elite"], L["Boss"]), category = L["Characteristics"] }) DogTag:AddTag("Unit", "Race", { - code = [[return UnitRace(${unit})]], + code = UnitRace, arg = { 'unit', 'string', '@req' }, ret = "string", - globals = "UnitRace", doc = L["Return the race of unit"], example = ('[Race] => %q'):format((UnitRace("player"))), category = L["Characteristics"] @@ -208,215 +214,222 @@ DogTag:AddTag("Unit", "SmartRace", { }) DogTag:AddTag("Unit", "Sex", { - code = ([[local sex = UnitSex(${unit}) - if sex == 2 then - return %q - elseif sex == 3 then - return %q - else - return nil - end]]):format(L["Male"], L["Female"]), + code = function(unit) + local sex = UnitSex(unit) + if sex == 2 then + return L["Male"] + elseif sex == 3 then + return L["Female"] + else + return nil + end + end, arg = { 'unit', 'string', '@req' }, ret = "string;nil", - globals = "UnitSex", doc = L["Return Male, Female, or blank depending on unit"], example = ('[Sex] => %q; [Sex] => %q; [Sex] => ""'):format(L["Male"], L["Female"]), category = L["Characteristics"] }) DogTag:AddTag("Unit", "GuildRank", { - code = [[local _, rank = GetGuildInfo(${unit}) - return rank]], + code = function(unit) + local _, rank = GetGuildInfo(unit) + return rank + end, arg = { 'unit', 'string', '@req' }, ret = "string;nil", - globals = "GetGuildInfo", doc = L["Return the guild rank of unit"], example = ('[GuildRank] => %q; [GuildRank] => %q'):format(L["Guild Leader"], L["Initiate"]), category = L["Characteristics"] }) DogTag:AddTag("Unit", "IsPlayer", { - code = [[return UnitIsPlayer(${unit})]], + code = UnitIsPlayer, arg = { 'unit', 'string', '@req' }, ret = "boolean", - globals = "UnitIsPlayer", doc = L["Return True if unit is a player"], example = ('[IsPlayer] => %q; [IsPlayer] => ""'):format(L["True"]), category = L["Characteristics"] }) DogTag:AddTag("Unit", "IsPet", { - code = [[return not UnitIsPlayer(${unit}) and UnitPlayerControlled(${unit})]], + code = function(unit) + return not UnitIsPlayer(unit) and (UnitPlayerControlled(unit) or UnitPlayerOrPetInRaid(unit)) + end, arg = { 'unit', 'string', '@req' }, ret = "boolean", - globals = "UnitIsPlayer;UnitPlayerControlled", doc = L["Return True if unit is a player's pet"], example = ('[IsPet] => %q; [IsPet] => ""'):format(L["True"]), category = L["Characteristics"] }) DogTag:AddTag("Unit", "IsPlayerOrPet", { - code = [[return (UnitIsPlayer(${unit}) or UnitPlayerControlled(${unit}) or UnitPlayerOrPetInRaid(${unit}))]], + code = function(unit) + return UnitIsPlayer(unit) or UnitPlayerControlled(unit) or UnitPlayerOrPetInRaid(unit) + end, arg = { 'unit', 'string', '@req' }, fakeAlias = "IsPlayer || IsPet", ret = "boolean", - globals = "UnitIsPlayer;UnitPlayerControlled;UnitPlayerOrPetInRaid", doc = L["Return True if unit is a player or a player's pet"], example = ('[IsPlayerOrPet] => %q; [IsPlayerOrPet] => ""'):format(L["True"]), category = L["Characteristics"] }) DogTag:AddTag("Unit", "PvPRank", { - code = [=[local pvpname = UnitPVPName(${unit}) - local name = UnitName(${unit}) - if name ~= pvpname and pvpname then - if not ${value} then - local str = "%s*" .. name .. "%s*" - return pvpname:gsub(str, '') + code = function(value, unit) + local pvpname = UnitPVPName(unit) + local name = UnitName(unit) + if name ~= pvpname and pvpname then + if not value then + local str = "%s*" .. name .. "%s*" + return pvpname:gsub(str, '') + else + return pvpname:gsub(name, value) + end else - return pvpname:gsub(name, ${value}) + return value end - else - return ${value} - end]=], + end, arg = { 'value', 'string;undef', '@undef', 'unit', 'string', '@req', }, ret = "string;nil", events = "UNIT_NAME_UPDATE#$unit;PLAYER_ENTERING_WORLD#$unit", - globals = "UnitPVPName;UnitName", doc = L["Return the PvP rank or wrap the PvP rank of unit around value"], example = ('[PvPRank] => %q; [NameRealm:PvPRank] => %q'):format(_G.PVP_RANK_10_1, _G.PVP_RANK_10_1 .. " " .. UnitName("player") .. "-" .. GetRealmName()), category = L["Characteristics"] }) DogTag:AddTag("Unit", "HostileColor", { - code = [[local r, g, b + code = function(value, unit) + local r, g, b - if UnitIsPlayer(${unit}) or UnitPlayerControlled(${unit}) then - if UnitCanAttack(${unit}, "player") then - -- they can attack me - if UnitCanAttack("player", ${unit}) then - -- and I can attack them - r, g, b = unpack(colors.hostile) + if UnitIsPlayer(unit) or UnitPlayerControlled(unit) then + if UnitCanAttack(unit, "player") then + -- they can attack me + if UnitCanAttack("player", unit) then + -- and I can attack them + r, g, b = unpack(DogTag.__colors.hostile) + else + -- but I can't attack them + r, g, b = unpack(DogTag.__colors.civilian) + end + elseif UnitCanAttack("player", unit) then + -- they can't attack me, but I can attack them + r, g, b = unpack(DogTag.__colors.neutral) + elseif UnitIsPVP(unit) then + -- on my team + r, g, b = unpack(DogTag.__colors.friendly) else - -- but I can't attack them - r, g, b = unpack(colors.civilian) + -- either enemy or friend, no violence + r, g, b = unpack(DogTag.__colors.civilian) end - elseif UnitCanAttack("player", ${unit}) then - -- they can't attack me, but I can attack them - r, g, b = unpack(colors.neutral) - elseif UnitIsPVP(${unit}) then - -- on my team - r, g, b = unpack(colors.friendly) + elseif (UnitIsTapped(unit) and not UnitIsTappedByPlayer(unit)) or UnitIsDead(unit) then + r, g, b = unpack(colors.tapped) else - -- either enemy or friend, no violence - r, g, b = unpack(colors.civilian) - end - elseif (UnitIsTapped(${unit}) and not UnitIsTappedByPlayer(${unit})) or UnitIsDead(${unit}) then - r, g, b = unpack(colors.tapped) - else - local reaction = UnitReaction(${unit}, "player") - if reaction then - if reaction >= 5 then - r, g, b = unpack(colors.friendly) - elseif reaction == 4 then - r, g, b = unpack(colors.neutral) + local reaction = UnitReaction(unit, "player") + if reaction then + if reaction >= 5 then + r, g, b = unpack(DogTag.__colors.friendly) + elseif reaction == 4 then + r, g, b = unpack(DogTag.__colors.neutral) + else + r, g, b = unpack(DogTag.__colors.hostile) + end else - r, g, b = unpack(colors.hostile) + r, g, b = unpack(DogTag.__colors.unknown) end - else - r, g, b = unpack(colors.unknown) end - end - if ${value} then - return ("|cff%02x%02x%02x%s|r"):format(r * 255, g * 255, b * 255, ${value}) - else - return ("|cff%02x%02x%02x"):format(r * 255, g * 255, b * 255) - end]], + if value then + return ("|cff%02x%02x%02x%s|r"):format(r * 255, g * 255, b * 255, value) + else + return ("|cff%02x%02x%02x"):format(r * 255, g * 255, b * 255) + end + end, arg = { 'value', 'string;undef', '@undef', 'unit', 'string', '@req', }, ret = "string", events = "UNIT_FACTION#$unit", - globals = "UnitIsPlayer;UnitPlayerControlled;UnitCanAttack;UnitIsPVP;UnitIsTapped;UnitIsTappedByPlayer;UnitIsDead;UnitReaction", doc = L["Return the color or wrap value with the hostility color of unit"], example = '["Hello":HostileColor] => "|cffff0000Hello|r"; [HostileColor "Hello"] => "|cffff0000Hello"', category = L["Characteristics"] }) DogTag:AddTag("Unit", "AggroColor", { - code = [=[local val = UnitReaction("player", ${unit}) or 5 + code = function(value, unit) + local val = UnitReaction("player", unit) or 5 - local info = UnitReactionColor[val] - if ${value} then - return ("|cff%02x%02x%02x%s|r"):format(info.r * 255, info.g * 255, info.b * 255, ${value}) - else - return ("|cff%02x%02x%02x"):format(info.r * 255, info.g * 255, info.b * 255) - end - ]=], + local info = UnitReactionColor[val] + if value then + return ("|cff%02x%02x%02x%s|r"):format(info.r * 255, info.g * 255, info.b * 255, value) + else + return ("|cff%02x%02x%02x"):format(info.r * 255, info.g * 255, info.b * 255) + end + end, arg = { 'value', 'string;undef', '@undef', 'unit', 'string', '@req', }, ret = "string", events = "UNIT_FACTION#$unit", - globals = "UnitReaction;UnitReactionColor", doc = L["Return the color or wrap value with the aggression color of unit"], example = '["Hello":AggroColor] => "|cffffff00Hello|r"; [AggroColor "Hello"] => "|cffffff00Hello"', category = L["Characteristics"] }) DogTag:AddTag("Unit", "ClassColor", { - code = [=[local _, class = UnitClass(${unit}) - local r, g, b = unpack(colors[class] or colors.unknown) - if ${value} then - return ("|cff%02x%02x%02x%s|r"):format(r * 255, g * 255, b * 255, ${value}) - else - return ("|cff%02x%02x%02x"):format(r * 255, g * 255, b * 255) - end]=], + code = function(value, unit) + local _, class = UnitClass(unit) + local r, g, b = unpack(DogTag.__colors[class] or DogTag.__colors.unknown) + if value then + return ("|cff%02x%02x%02x%s|r"):format(r * 255, g * 255, b * 255, value) + else + return ("|cff%02x%02x%02x"):format(r * 255, g * 255, b * 255) + end + end, arg = { 'value', 'string;undef', '@undef', 'unit', 'string', '@req', }, ret = "string", - globals = "UnitClass", doc = L["Return the color or wrap value with the class color of unit"], example = '["Hello":ClassColor] => "|cfff58cbdHello|r"; [ClassColor "Hello"] => "|cfff58cbdHello"', category = L["Characteristics"] }) DogTag:AddTag("Unit", "DifficultyColor", { - code = [=[local level = UnitLevel(${unit}) - if level <= 0 or UnitClassification(${unit}) ~= "normal" then - level = 99 - end - local info = GetDifficultyColor(level) - if ${value} then - return ("|cff%02x%02x%02x%s|r"):format(info.r * 255, info.g * 255, info.b * 255, ${value}) - else - return ("|cff%02x%02x%02x"):format(info.r * 255, info.g * 255, info.b * 255) - end]=], + code = function(value, unit) + local level = UnitLevel(unit) + if level <= 0 or UnitClassification(unit) ~= "normal" then + level = 99 + end + local info = GetDifficultyColor(level) + if value then + return ("|cff%02x%02x%02x%s|r"):format(info.r * 255, info.g * 255, info.b * 255, value) + else + return ("|cff%02x%02x%02x"):format(info.r * 255, info.g * 255, info.b * 255) + end + end, arg = { 'value', 'string;undef', '@undef', 'unit', 'string', '@req', }, ret = "string", events = "UNIT_LEVEL#$unit;PLAYER_LEVEL_UP#$unit", - globals = "GetDifficultyColor;UnitLevel;UnitClassification", doc = L["Return the color or wrap value with the difficulty color of unit's level compared to your own level"], example = '["Hello":DifficultyColor] => "|cffff7f00Hello|r"; [DifficultyColor "Hello"] => "|cffff7f00Hello"', category = L["Characteristics"] @@ -424,12 +437,11 @@ DogTag:AddTag("Unit", "DifficultyColor", { if _G.UnitClassBase then DogTag:AddTag("Unit", "Guid", { - code = [=[return UnitGUID(${unit})]=], + code = UnitGUID, arg = { 'unit', 'string', '@req', }, ret = "string", - globals = "UnitGUID", doc = L["Return the GUID for the unit, an internal identifier."] }) end diff --git a/Categories/Experience.lua b/Categories/Experience.lua index d6f9028..e733f65 100644 --- a/Categories/Experience.lua +++ b/Categories/Experience.lua @@ -9,49 +9,51 @@ DogTag_Unit_funcs[#DogTag_Unit_funcs+1] = function(DogTag_Unit, DogTag) local L = DogTag_Unit.L -DogTag:AddEventListener("UNIT_PET_EXPERIENCE", function(event, ...) +DogTag:AddEventHandler("UNIT_PET_EXPERIENCE", function(event, ...) DogTag:FireEvent("UpdateExperience", "pet") DogTag:FireEvent("UpdateExperience", "playerpet") end) -DogTag:AddEventListener("PLAYER_XP_UPDATE", function(event, ...) +DogTag:AddEventHandler("PLAYER_XP_UPDATE", function(event, ...) DogTag:FireEvent("UpdateExperience", "player") end) DogTag:AddTag("Unit", "XP", { - code = [[if ${unit} == "player" then - return UnitXP(${unit}) - elseif ${unit} == "pet" or ${unit} == "playerpet" then - return GetPetExperience() - else - return 0 - end]], + code = function(unit) + if unit == "player" then + return UnitXP(unit) + elseif unit == "pet" or unit == "playerpet" then + return GetPetExperience() + else + return 0 + end + end, arg = { 'unit', 'string', '@req', }, ret = "number", events = "UpdateExperience#$unit", - globals = "GetPetExperience;UnitXP", doc = L["Return the current experience of unit"], example = '[XP] => "8540"', category = L["Experience"] }) DogTag:AddTag("Unit", "MaxXP", { - code = [[if ${unit} == "player" then - return UnitXPMax(${unit}) - elseif ${unit} == "pet" or ${unit} == "playerpet" then - local _, max = GetPetExperience() - return max - else - return 0 - end]], + code = function(unit) + if unit == "player" then + return UnitXPMax(unit) + elseif unit == "pet" or unit == "playerpet" then + local _, max = GetPetExperience() + return max + else + return 0 + end + end, arg = { 'unit', 'string', '@req', }, ret = "number", events = "UpdateExperience#$unit", - globals = "GetPetExperience;UnitXPMax", doc = L["Return the current experience of unit"], example = '[MaxXP] => "10000"', category = L["Experience"] @@ -88,17 +90,18 @@ DogTag:AddTag("Unit", "MissingXP", { }) DogTag:AddTag("Unit", "RestXP", { - code = [[if ${unit} == "player" then - return GetXPExhaustion() - else - return 0 - end]], + code = function() + if unit == "player" then + return GetXPExhaustion() + else + return 0 + end + end, arg = { 'unit', 'string', '@req', }, ret = "number", events = "UpdateExperience#$unit", - globals = "GetXPExhaustion", doc = L["Return the accumulated rest experience of unit"], example = '[RestXP] => "5000"', category = L["Experience"] diff --git a/Categories/Health.lua b/Categories/Health.lua index 23df44c..3719cf5 100644 --- a/Categories/Health.lua +++ b/Categories/Health.lua @@ -9,58 +9,118 @@ DogTag_Unit_funcs[#DogTag_Unit_funcs+1] = function(DogTag_Unit, DogTag) local L = DogTag_Unit.L -local LibMobHealth, MobHealth3, MobHealth_PPP -DogTag:AddAddonFinder("Unit", "LibStub", "LibMobHealth-4.0", function(v) LibMobHealth = v end) -DogTag:AddAddonFinder("Unit", "_G", "MobHealth3", function(v) MobHealth3 = v end) -DogTag:AddAddonFinder("Unit", "_G", "MobHealth_PPP", function(v) MobHealth_PPP = v end) +local function HP_func(unit, known) + local hp = UnitHealth(unit) + if known and UnitHealthMax(unit) == 100 then + return nil + else + return hp + end +end + +local function MaxHP_func(unit, known) + local maxhp = UnitHealthMax(unit) + if known and maxhp == 100 then + return nil + else + return maxhp + end +end + +DogTag:AddAddonFinder("Unit", "LibStub", "LibMobHealth-4.0", function(v) + local LibMobHealth = v + function HP_func(unit, known) + local hp, found = LibMobHealth:GetUnitCurrentHP(unit) + if known and not found then + return nil + else + return hp + end + end + function MaxHP_func(unit, known) + local maxhp, found = LibMobHealth:GetUnitMaxHP(unit) + if known and not found then + return nil + else + return maxhp + end + end +end) + +DogTag:AddAddonFinder("Unit", "_G", "MobHealth3", function(v) + local MobHealth3 = v + function HP_func(unit, found) + local currValue = UnitHealth(unit) + if not UnitIsFriend("player", unit) then + local maxValue = UnitHealthMax(unit) + local curr, max, found = MobHealth3:GetUnitHealth(unit, currValue, maxValue) + if found then + return curr + elseif known then + return nil + end + elseif known and UnitHealthMax(unit) == 100 then + return nil + end + return currValue + end + function MaxHP_func(unit, found) + local maxValue = UnitHealthMax(unit) + if not UnitIsFriend("player", unit) then + local curr, max, MHfound = MobHealth3:GetUnitHealth(unit, 1, maxValue) + if MHfound then + return max + elseif known then + return nil + end + elseif known and maxValue == 100 then + return nil + end + return maxValue + end +end) + +DogTag:AddAddonFinder("Unit", "_G", "MobHealth_PPP", function(v) + local MobHealth_PPP = v + function HP_func(unit, found) + local currValue = UnitHealth(unit) + if not UnitIsFriend("player", unit) then + local name = UnitName(unit) + local level = UnitLevel(unit) + local ppp = MobHealth_PPP(name..":"..level) + if ppp > 0 then + return math.floor(currValue * ppp + 0.5) + elseif known then + return nil + end + elseif known and UnitHealthMax(unit) == 100 then + return nil + end + return currValue + end + function MaxHP_func(unit, found) + local maxValue = UnitHealthMax(unit) + if not UnitIsFriend("player", unit) then + local name = UnitName(unit) + local level = UnitLevel(unit) + local ppp = MobHealth_PPP(name..":"..level) + if ppp > 0 then + return math_floor(100 * ppp + 0.5) + elseif known then + return nil + end + elseif known and maxValue == 100 then + return nil + end + return maxValue + end +end) DogTag:AddTag("Unit", "HP", { code = function(args) - if LibMobHealth then - return [=[local hp, found = LibMobHealth:GetUnitCurrentHP(${unit}) - if ${known} and not found then - return nil - else - return hp - end]=] - elseif MobHealth3 then - return [=[local currValue = UnitHealth(${unit}) - if not UnitIsFriend("player", ${unit}) then - local maxValue = UnitHealthMax(${unit}) - local curr, max, found = MobHealth3:GetUnitHealth(${unit}, currValue, maxValue) - if found then - currValue = curr - elseif ${known} then - currValue = nil - end - elseif ${known} and UnitHealthMax(${unit}) == 100 then - currValue = nil - end - return currValue]=] - elseif MobHealth_PPP then - return [=[local currValue = UnitHealth(${unit}) - if not UnitIsFriend("player", ${unit}) then - local name = UnitName(${unit}) - local level = UnitLevel(${unit}) - local ppp = MobHealth_PPP(name..":"..level) - if ppp > 0 then - currValue = math_floor(currValue * ppp + 0.5) - elseif ${known} then - currValue = nil - end - elseif ${known} and UnitHealthMax(${unit}) == 100 then - currValue = nil - end - return currValue]=] - else - return [=[local hp = UnitHealth(${unit}) - if ${known} and UnitHealthMax(${unit}) == 100 then - return nil - else - return hp - end]=] - end + return HP_func end, + dynamicCode = true, arg = { 'unit', 'string', '@req', 'known', 'boolean', false, @@ -73,17 +133,6 @@ DogTag:AddTag("Unit", "HP", { end end, events = "UNIT_HEALTH#$unit;UNIT_MAXHEALTH#$unit", - globals = function(args) - if LibMobHealth then - return "LibMobHealth-4.0" - elseif MobHealth3 then - return "UnitHealth;UnitIsFriend;UnitHealthMax;MobHealth3" - elseif MobHealth_PPP then - return "UnitHealth;UnitIsFriend;UnitHealthMax;UnitName;UnitLevel;MobHealth_PPP;math.floor" - else - return "UnitHealth;UnitHealthMax" - end - end, doc = L["Return the current health of unit, will use MobHealth if found"], example = ('[HP] => "%d"'):format(UnitHealthMax("player")*.758), category = L["Health"], @@ -91,50 +140,9 @@ DogTag:AddTag("Unit", "HP", { DogTag:AddTag("Unit", "MaxHP", { code = function(args) - if LibMobHealth then - return [=[local maxhp, found = LibMobHealth:GetUnitMaxHP(${unit}) - if ${known} and not found then - return nil - else - return maxhp - end]=] - elseif MobHealth3 then - return [=[local maxValue = UnitHealthMax(${unit}) - if not UnitIsFriend("player", ${unit}) then - local curr, max, MHfound = MobHealth3:GetUnitHealth(${unit}, 1, maxValue) - if MHfound then - maxValue = max - elseif ${known} then - maxValue = nil - end - elseif ${known} and maxValue == 100 then - maxValue = nil - end - return maxValue]=] - elseif MobHealth_PPP then - return [=[local maxValue = UnitHealthMax(${unit}) - if not UnitIsFriend("player", ${unit}) then - local name = UnitName(${unit}) - local level = UnitLevel(${unit}) - local ppp = MobHealth_PPP(name..":"..level) - if ppp > 0 then - maxValue = math_floor(100 * ppp + 0.5) - elseif ${known} then - maxValue = nil - end - elseif ${known} and maxValue == 100 then - maxValue = nil - end - return maxValue]=] - else - return [=[local maxhp = UnitHealthMax(${unit}) - if ${known} and maxhp == 100 then - return nil - else - return maxhp - end]=] - end + return MaxHP_func end, + dynamicCode = true, arg = { 'unit', 'string', '@req', 'known', 'boolean', false, @@ -147,31 +155,21 @@ DogTag:AddTag("Unit", "MaxHP", { end end, events = "UNIT_HEALTH#$unit;UNIT_MAXHEALTH#$unit", - globals = function(args) - if LibMobHealth then - return "LibMobHealth-4.0" - elseif MobHealth3 then - return "UnitIsFriend;UnitHealthMax;MobHealth3" - elseif MobHealth_PPP then - return "UnitHealthMax;UnitIsFriend;UnitName;UnitLevel;MobHealth_PPP;math.floor" - else - return "UnitHealthMax" - end - end, doc = L["Return the maximum health of unit, will use MobHealth if found"], example = ('[MaxHP] => "%d"'):format(UnitHealthMax("player")), category = L["Health"], }) DogTag:AddTag("Unit", "PercentHP", { - code = [=[return math_floor(UnitHealth(${unit})/UnitHealthMax(${unit}) * 1000+0.5) / 10]=], + code = function(unit) + return math.floor(UnitHealth(unit)/UnitHealthMax(unit)*1000 + 0.5) / 10 + end, fakeAlias = "[CurHP / MaxHP * 100]:Round(1)", arg = { 'unit', 'string', '@req', }, ret = "number", events = "UNIT_HEALTH#$unit;UNIT_MAXHEALTH#$unit", - globals = "UnitHealth;UnitHealthMax;math.floor", doc = L["Return the percentage health of unit"], example = '[PercentHP] => "75.8"; [PercentHP:Percent] => "75.8%"', category = L["Health"], @@ -202,58 +200,60 @@ DogTag:AddTag("Unit", "FractionalHP", { }) DogTag:AddTag("Unit", "IsMaxHP", { - code = [=[return UnitHealth(${unit}) == UnitHealthMax(${unit})]=], + code = function(unit) + return UnitHealth(unit) == UnitHealthMax(unit) + end, arg = { 'unit', 'string', '@req', }, ret = "boolean", - globals = "UnitHealth;UnitHealthMax", doc = L["Return True if unit is at full health"], example = ('[IsMaxHP] => %q; [IsMaxHP] => ""'):format(L["True"]), category = L["Health"] }) DogTag:AddTag("Unit", "HPColor", { - code = [=[local perc = UnitHealth(${unit}) / UnitHealthMax(${unit}) - local r1, g1, b1 - local r2, g2, b2 - if perc <= 0.5 then - perc = perc * 2 - r1, g1, b1 = unpack(colors.minHP) - r2, g2, b2 = unpack(colors.midHP) - else - perc = perc * 2 - 1 - r1, g1, b1 = unpack(colors.midHP) - r2, g2, b2 = unpack(colors.maxHP) - end - local r, g, b = r1 + (r2 - r1)*perc, g1 + (g2 - g1)*perc, b1 + (b2 - b1)*perc - if r < 0 then - r = 0 - elseif r > 1 then - r = 1 - end - if g < 0 then - g = 0 - elseif g > 1 then - g = 1 - end - if b < 0 then - b = 0 - elseif b > 1 then - b = 1 - end - if ${value} then - return ("|cff%02x%02x%02x%s|r"):format(r*255, g*255, b*255, ${value}) - else - return ("|cff%02x%02x%02x"):format(r*255, g*255, b*255) - end]=], + code = function(value, unit) + local perc = UnitHealth(unit) / UnitHealthMax(unit) + local r1, g1, b1 + local r2, g2, b2 + if perc <= 0.5 then + perc = perc * 2 + r1, g1, b1 = unpack(DogTag.__colors.minHP) + r2, g2, b2 = unpack(DogTag.__colors.midHP) + else + perc = perc * 2 - 1 + r1, g1, b1 = unpack(DogTag.__colors.midHP) + r2, g2, b2 = unpack(DogTag.__colors.maxHP) + end + local r, g, b = r1 + (r2 - r1)*perc, g1 + (g2 - g1)*perc, b1 + (b2 - b1)*perc + if r < 0 then + r = 0 + elseif r > 1 then + r = 1 + end + if g < 0 then + g = 0 + elseif g > 1 then + g = 1 + end + if b < 0 then + b = 0 + elseif b > 1 then + b = 1 + end + if value then + return ("|cff%02x%02x%02x%s|r"):format(r*255, g*255, b*255, value) + else + return ("|cff%02x%02x%02x"):format(r*255, g*255, b*255) + end + end, arg = { 'value', 'string;undef', "@undef", 'unit', 'string', '@req', }, ret = "string", events = "UNIT_HEALTH#$unit;UNIT_MAXHEALTH#$unit", - globals = "UnitHealth;UnitHealthMax", doc = L["Return the color or wrap value with the health color of unit"], example = '[Text(Hello):HPColor] => "|cffff7f00Hello|r"; [Text([HPColor]Hello)] => "|cffff7f00Hello"', category = L["Health"] diff --git a/Categories/Power.lua b/Categories/Power.lua index f97fa46..3274165 100644 --- a/Categories/Power.lua +++ b/Categories/Power.lua @@ -10,26 +10,24 @@ DogTag_Unit_funcs[#DogTag_Unit_funcs+1] = function(DogTag_Unit, DogTag) local L = DogTag_Unit.L DogTag:AddTag("Unit", "MP", { - code = [[return UnitMana(${unit})]], - arg { + code = UnitMana, + arg = { 'unit', 'string', '@req', }, ret = "number", events = "UNIT_MANA#$unit;UNIT_RAGE#$unit;UNIT_FOCUS#$unit;UNIT_ENERGY#$unit;UNIT_MAXMANA#$unit;UNIT_MAXRAGE#$unit;UNIT_MAXFOCUS#$unit;UNIT_MAXENERGY#$unit;UNIT_DISPLAYPOWER#$unit", - globals = "UnitMana", doc = L["Return the current mana/rage/energy of unit"], example = ('[MP] => "%d"'):format(UnitManaMax("player")*.632), category = L["Power"] }) DogTag:AddTag("Unit", "MaxMP", { - code = [[return UnitManaMax(${unit})]], - arg { + code = UnitManaMax, + arg = { 'unit', 'string', '@req', }, ret = "number", events = "UNIT_MANA#$unit;UNIT_RAGE#$unit;UNIT_FOCUS#$unit;UNIT_ENERGY#$unit;UNIT_MAXMANA#$unit;UNIT_MAXRAGE#$unit;UNIT_MAXFOCUS#$unit;UNIT_MAXENERGY#$unit;UNIT_DISPLAYPOWER#$unit", - globals = "UnitManaMax", doc = L["Return the maximum mana/rage/energy of unit"], example = ('[MaxMP] => "%d"'):format(UnitManaMax("player")), category = L["Power"] @@ -37,7 +35,7 @@ DogTag:AddTag("Unit", "MaxMP", { DogTag:AddTag("Unit", "PercentMP", { alias = "[MP(unit=unit) / MaxMP(unit=unit) * 100]:Round(1)", - arg { + arg = { 'unit', 'string', '@req', }, doc = L["Return the percentage mana/rage/energy of unit"], @@ -47,7 +45,7 @@ DogTag:AddTag("Unit", "PercentMP", { DogTag:AddTag("Unit", "MissingMP", { alias = "MaxMP(unit=unit) - CurMP(unit=unit)", - arg { + arg = { 'unit', 'string', '@req', }, doc = L["Return the missing mana/rage/energy of unit"], @@ -57,7 +55,7 @@ DogTag:AddTag("Unit", "MissingMP", { DogTag:AddTag("Unit", "FractionalMP", { alias = "Concatenate(MP(unit=unit), '/', MaxMP(unit=unit))", - arg { + arg = { 'unit', 'string', '@req', }, doc = L["Return the current and maximum mana/rage/energy of unit"], @@ -66,22 +64,23 @@ DogTag:AddTag("Unit", "FractionalMP", { }) DogTag:AddTag("Unit", "TypePower", { - ([[local p = UnitPowerType(${unit}) - if p == 1 then - return %q - elseif p == 2 then - return %q - elseif p == 3 then - return %q - else - return %q - end]]):format(L["Rage"], L["Focus"], L["Energy"], L["Mana"]), - arg { + code = function(unit) + local p = UnitPowerType(unit) + if p == 1 then + return L["Rage"] + elseif p == 2 then + return L["Focus"] + elseif p == 3 then + return L["Energy"] + else + return L["Mana"] + end + end, + arg = { 'unit', 'string', '@req', }, ret = "string", events = "UNIT_DISPLAYPOWER#$unit", - globals = "UnitPowerType", doc = L["Return whether unit currently uses Rage, Focus, Energy, or Mana"], example = ('[TypePower] => %q; [TypePower] => %q'):format(L["Rage"], L["Mana"]), category = L["Power"] @@ -95,7 +94,6 @@ DogTag:AddTag("Unit", "IsPowerType", { }, ret = "boolean", events = "UNIT_DISPLAYPOWER#$unit", - globals = "UnitPowerType", doc = L["Return True if unit currently uses the power of argument"], example = ('[HasPower(%q)] => %q; [HasPower(%q)] => ""'):format(L["Rage"], L["True"], L["Mana"]), category = L["Power"] @@ -162,31 +160,32 @@ DogTag:AddTag("Unit", "HasMP", { }) DogTag:AddTag("Unit", "PowerColor", { - code = [[local powerType = UnitPowerType(${unit}) - local r,g,b - if powerType == 0 then - r,g,b = unpack(colors.mana) - elseif powerType == 1 then - r,g,b = unpack(colors.rage) - elseif powerType == 2 then - r,g,b = unpack(colors.focus) - elseif powerType == 3 then - r,g,b = unpack(colors.energy) - else - r,g,b = unpack(colors.unknown) - end - if ${value} then - return ("|cff%02x%02x%02x%s|r"):format(r * 255, g * 255, b * 255, ${value}) - else - return ("|cff%02x%02x%02x"):format(r * 255, g * 255, b * 255) - end]], + code = function(value, unit) + local powerType = UnitPowerType(unit) + local r,g,b + if powerType == 0 then + r,g,b = unpack(colors.mana) + elseif powerType == 1 then + r,g,b = unpack(colors.rage) + elseif powerType == 2 then + r,g,b = unpack(colors.focus) + elseif powerType == 3 then + r,g,b = unpack(colors.energy) + else + r,g,b = unpack(colors.unknown) + end + if value then + return ("|cff%02x%02x%02x%s|r"):format(r * 255, g * 255, b * 255, value) + else + return ("|cff%02x%02x%02x"):format(r * 255, g * 255, b * 255) + end + end, arg = { 'value', 'string;undef', '@undef', 'unit', 'string', '@req', }, ret = "string", events = "UNIT_DISPLAYPOWER#$unit", - globals = "UnitPowerType", doc = L["Return the color or wrap value with current power color of unit, whether rage, mana, or energy"], example = '["Hello":PowerColor] => "|cff3071bfHello|r"; [PowerColor "Hello"] => "|cff3071bfHello"', category = L["Power"] diff --git a/Categories/Reputation.lua b/Categories/Reputation.lua index d8257ee..8666fa2 100644 --- a/Categories/Reputation.lua +++ b/Categories/Reputation.lua @@ -10,60 +10,48 @@ DogTag_Unit_funcs[#DogTag_Unit_funcs+1] = function(DogTag_Unit, DogTag) local L = DogTag_Unit.L DogTag:AddTag("Unit", "Reputation", { - code = [=[local _, name, min, value - if not ${faction} then - name, _, min, _, value = GetWatchedFactionInfo() - else - for i = 1, GetNumFactions() do - local n - n, _, _, min, _, value = GetFactionInfo(i) - if ${faction} == n then - name = n - break + code = function(faction) + if not faction then + local _, _, min, _, value = GetWatchedFactionInfo() + return value - min + else + for i = 1, GetNumFactions() do + local name, _, _, min, _, value = GetFactionInfo(i) + if faction == n then + return value - min + end end end - end - if name then - return value - min - else - return nil - end]=], + end, arg = { 'faction', 'string;undef', "@undef" }, ret = "number;nil", events = "UNIT_FACTION", - globals = "GetWatchedFactionInfo;GetNumFactions;GetFactionInfo", doc = L["Return the current reputation of the watched faction or specified"], example = ('[Reputation] => "1234"; [Reputation(%s)] => "2345"'):format(L["Exodar"]), category = L["Reputation"] }) DogTag:AddTag("Unit", "MaxReputation", { - code = [=[local _, name, min, max - if not ${faction} then - name, _, min, max = GetWatchedFactionInfo() - else - for i = 1, GetNumFactions() do - local n - n, _, _, min, max = GetFactionInfo(i) - if ${faction} == n then - name = n - break + code = function(faction) + if not faction then + local _, _, min, max = GetWatchedFactionInfo() + return max - min + else + for i = 1, GetNumFactions() do + local name, _, _, min, max = GetFactionInfo(i) + if faction == n then + return max - min + end end end - end - if name then - return max - min - else - return nil - end]=], + end, arg = { 'faction', 'string;undef', "@undef" }, ret = "number;nil", events = "UNIT_FACTION", - globals = "GetWatchedFactionInfo;GetNumFactions;GetFactionInfo", doc = L["Return the maximum reputation of the watched faction or specified"], example = ('[MaxReputation] => "12000"; [MaxReputation(%s)] => "21000"'):format(L["Exodar"]), category = L["Reputation"] @@ -100,9 +88,8 @@ DogTag:AddTag("Unit", "MissingReputation", { }) DogTag:AddTag("Unit", "ReputationName", { - code = [=[return GetWatchedFactionInfo()]=], + code = GetWatchedFactionInfo, ret = "string;nil", - globals = "GetWatchedFactionInfo", events = "UNIT_FACTION", doc = L["Return the name of the currently watched faction"], example = ('[ReputationName] => %q'):format(L["Exodar"]), @@ -110,29 +97,23 @@ DogTag:AddTag("Unit", "ReputationName", { }) DogTag:AddTag("Unit", "ReputationReaction", { - code = [=[local _, name, reaction - if not ${faction} then - name, reaction = GetWatchedFactionInfo() - else - for i = 1, GetNumFactions() do - local n - n, _, reaction = GetFactionInfo(i) - if ${faction} == n then - name = n - break + code = function(faction) + if not faction then + local _, reaction = GetWatchedFactionInfo() + return _G["FACTION_STANDING_LABEL" .. reaction] + else + for i = 1, GetNumFactions() do + local name, _, reaction = GetFactionInfo(i) + if faction == name then + return _G["FACTION_STANDING_LABEL" .. reaction] + end end end - end - if name then - return _G["FACTION_STANDING_LABEL" .. reaction] - else - return nil - end]=], + end, arg = { 'faction', 'string;undef', "@undef", }, ret = "string;nil", - globals = "GetWatchedFactionInfo;GetNumFactions;GetFactionInfo", events = "UNIT_FACTION", doc = L["Return your current reputation rank with the watched faction or argument"], example = ('[ReputationReaction] => %q; [ReputationReaction(%s)] => %q'):format(_G.FACTION_STANDING_LABEL5, "Exodar", _G.FACTION_STANDING_LABEL6), @@ -140,35 +121,36 @@ DogTag:AddTag("Unit", "ReputationReaction", { }) DogTag:AddTag("Unit", "ReputationColor", { - code = [=[local _, name, reaction - if not ${faction} then - name, reaction = GetWatchedFactionInfo() - else - for i = 1, GetNumFactions() do - local n - n, _, reaction = GetFactionInfo(i) - if ${faction} == n then - name = n - break + code = function(value, faction) + local _, name, reaction + if not faction then + name, reaction = GetWatchedFactionInfo() + else + for i = 1, GetNumFactions() do + local n + n, _, reaction = GetFactionInfo(i) + if faction == n then + name = n + break + end end end - end - if name then - local color = FACTION_BAR_COLORS[reaction] - if ${value} then - return ("|cff%02x%02x%02x%s|r"):format(color.r * 255, color.g * 255, color.b * 255, ${value}) + if name then + local color = FACTION_BAR_COLORS[reaction] + if value then + return ("|cff%02x%02x%02x%s|r"):format(color.r * 255, color.g * 255, color.b * 255, value) + else + return ("|cff%02x%02x%02x"):format(color.r * 255, color.g * 255, color.b * 255) + end else - return ("|cff%02x%02x%02x"):format(color.r * 255, color.g * 255, color.b * 255) + return value end - else - return ${value} - end]=], + end, arg = { 'value', 'string;undef', '@undef', 'faction', 'string;undef', "@undef", }, ret = "string;nil", - globals = "GetWatchedFactionInfo;GetNumFactions;GetFactionInfo;FACTION_BAR_COLORS", events = "UNIT_FACTION", doc = L["Return the color or wrap value with the color associated with either the currently watched faction or the given argument"], example = ('["Hello":ReputationColor] => "|cff7f0000Hello|r"; ["Hello":ReputationColor(%s)] => "|cff007f00Hello|r"; [ReputationColor(faction=%s) "Hello")] => "|cff007f00Hello"'):format(L["Exodar"], L["Exodar"]), diff --git a/Categories/Status.lua b/Categories/Status.lua new file mode 100644 index 0000000..5a6e5cd --- /dev/null +++ b/Categories/Status.lua @@ -0,0 +1,628 @@ +local MAJOR_VERSION = "LibDogTag-Unit-3.0" +local MINOR_VERSION = tonumber(("$Revision$"):match("%d+")) or 0 + +if MINOR_VERSION > _G.DogTag_Unit_MINOR_VERSION then + _G.DogTag_Unit_MINOR_VERSION = MINOR_VERSION +end + +DogTag_Unit_funcs[#DogTag_Unit_funcs+1] = function(DogTag_Unit, DogTag) + +local L = DogTag_Unit.L +local GetNameServer = DogTag_Unit.GetNameServer + +local offlineTimes = {} +local afkTimes = {} +local deadTimes = {} + +local iterateGroupMembers +local iterateGroupMembers__t = {} +do + function iterateGroupMembers() + return pairs(iterateGroupMembers__t) + end +end + +local tmp = {} +DogTag:AddEventHandler("PARTY_MEMBERS_CHANGED", function(event) + local prefix, min, max = "raid", 1, GetNumRaidMembers() + if max == 0 then + prefix, min, max = "party", 0, GetNumPartyMembers() + end + + for i = min, max do + local unit + if i == 0 then + unit = 'player' + else + unit = prefix .. i + end + + if not UnitExists(unit) then + break + end + + iterateGroupMembers__t[unit] = UnitGUID(unit) + end + + for unit, guid in iterateGroupMembers() do + tmp[guid] = true + + if not UnitIsConnected(unit) then + if not offlineTimes[guid] then + offlineTimes[guid] = GetTime() + end + afkTimes[guid] = nil + else + offlineTimes[guid] = nil + if UnitIsAFK(unit) then + if not afkTimes[guid] then + afkTimes[guid] = GetTime() + end + else + afkTimes[guid] = nil + end + end + if UnitIsDeadOrGhost(unit) then + if not deadTimes[guid] then + deadTimes[guid] = GetTime() + end + else + deadTimes[guid] = nil + end + end + + for guid in pairs(offlineTimes) do + if not tmp[guid] then + offlineTimes[guid] = nil + end + end + for guid in pairs(deadTimes) do + if not tmp[guid] then + deadTimes[guid] = nil + end + end + for guid in pairs(afkTimes) do + if not tmp[guid] then + afkTimes[guid] = nil + end + end + for guid in pairs(tmp) do + tmp[guid] = nil + end +end) + +DogTag:AddTimerHandler(function(currentTime, num) + for guid in pairs(offlineTimes) do + for unit in DogTag_Unit.IterateUnitsWithGUID(guid) do + DogTag:FireEvent("OfflineDuration", unit) + end + end + for unit, guid in iterateGroupMembers() do + if UnitIsDeadOrGhost(unit) then + if not deadTimes[guid] then + deadTimes[guid] = GetTime() + end + else + deadTimes[guid] = nil + end + + if UnitIsAFK(unit) then + if not afkTimes[guid] then + afkTimes[guid] = GetTime() + end + else + afkTimes[guid] = nil + end + end + for guid in pairs(deadTimes) do + for unit in DogTag_Unit.IterateUnitsWithGUID(guid) do + DogTag:FireEvent("DeadDuration", unit) + end + end + for guid in pairs(afkTimes) do + for unit in DogTag_Unit.IterateUnitsWithGUID(guid) do + DogTag:FireEvent("AFKDuration", unit) + end + end +end) + +DogTag:AddTag("Unit", "OfflineDuration", { + code = function(unit) + local t = offlineTimes[UnitGUID(unit)] + if not t then + return nil + else + return GetTime() - t + end + end, + arg = { + 'unit', 'string', '@req', + }, + ret = "number;nil", + events = "OfflineDuration#$unit", + doc = L["Return the duration offline if unit is offline"], + example = ('[OfflineDuration] => "110"; [OfflineDuration:FormatDuration] => "1:50"'), + category = L["Status"] +}) + +DogTag:AddTag("Unit", "Offline", { + alias = ("Concatenate(%q, ' ', OfflineDuration:FormatDuration:Paren)"):format(L["Offline"]), + doc = L["Return Offline and the time offline if unit is offline"], + example = ('[Offline] => "%s (2:45)"; [Offline] => ""'):format(L["Offline"]), + category = L["Status"] +}) + +DogTag:AddTag("Unit", "DeadDuration", { + code = function(unit) + local t = deadTimes[UnitGUID(unit)] + if not t then + return nil + else + return GetTime() - t + end + end, + arg = { + 'unit', 'string', '@req', + }, + ret = "number;nil", + events = "DeadDuration#$unit", + doc = L["Return the duration dead if unit is dead and time is known, unit can be dead and have an unknown time of death"], + example = ('[DeadDuration] => "110"; [DeadDuration:FormatDuration] => "1:50"'), + category = L["Status"] +}) + +DogTag:AddTag("Unit", "DeadType", { + code = function(unit) + if UnitIsGhost(unit) then + return L["Ghost"] + elseif UnitIsDead(unit) then + return L["Dead"] + else + return nil + end + end, + arg = { + 'unit', 'string', '@req', + }, + ret = "string;nil", + events = "DeadDuration#$unit", + doc = L["Return Dead or Ghost if unit is dead"], + example = ('[DeadType] => "%s"; [DeadType] => "%s"; [DeadType] => ""'):format(L["Dead"], L["Ghost"]), + category = L["Status"], +}) + +DogTag:AddTag("Unit", "Dead", { + alias = "DeadType Concatenate(' ', DeadDuration:FormatDuration:Paren))", + doc = L["Return Dead or Ghost and the duration dead if unit is dead"], + example = ('[Dead] => "%s (1:34)"; [Dead] => "%s"; [Dead] => ""'):format(L["Dead"], L["Ghost"]), + category = L["Status"] +}) + +DogTag:AddTag("Unit", "AFKDuration", { + code = function(unit) + local t = afkTimes[UnitGUID(unit)] + if not t then + return nil + else + return GetTime() - t + end + end, + arg = { + 'unit', 'string', '@req', + }, + ret = "number;nil", + events = "AFKDuration#$unit", + doc = L["Return the duration AFK if unit is AFK"], + example = ('[AFKDuration] => "110"; [AFKDuration:FormatDuration] => "1:50"'), + category = L["Status"] +}) + +DogTag:AddTag("Unit", "AFK", { + alias = ("Concatenate(%q, ' ', AFKDuration:FormatDuration:Paren)"):format(L["AFK"]), + doc = L["Return AFK and the time AFK if unit is AFK"], + example = ('[AFK] => "%s (2:12)"; [AFK] => ""'):format(L["AFK"]), + category = L["Status"] +}) + +DogTag:AddTag("Unit", "DND", { + code = function(unit) + if UnitIsDND(unit) then + return L["DND"] + else + return nil + end + end, + arg = { + 'unit', 'string', '@req', + }, + ret = "string;nil", + events = "PLAYER_FLAGS_CHANGED#$unit", + doc = L["Return DND if the unit has specified DND"], + example = ('[DND] => %q; [DND] => ""'):format(L["DND"]), + category = L["Status"] +}) + +DogTag:AddTag("Unit", "PvP", { + code = function(unit) + if UnitIsPVPFreeForAll(unit) then + return L["FFA"] + elseif UnitIsPVP(unit) then + return L["PvP"] + else + return nil + end + end, + arg = { + 'unit', 'string', '@req', + }, + ret = "string;nil", + doc = L["Return PvP or FFA if the unit is PvP-enabled"], + example = ('[PvP] => %q; [PvP] => %q; [PvP] => ""'):format(L["PvP"], L["FFA"]), + category = L["Status"] +}) + +DogTag:AddTag("Unit", "IsResting", { + code = IsResting, + ret = "boolean", + events = "PLAYER_UPDATE_RESTING", + doc = L["Return True if you are in an inn or capital city"], + example = ('[IsResting] => %q; [IsResting] => ""'):format(L["True"]), + category = L["Status"] +}) + +DogTag:AddTag("Unit", "IsLeader", { + code = UnitIsPartyLeader, + arg = { + 'unit', 'string', '@req', + }, + ret = "boolean", + doc = L["Return True if unit is a party leader"], + example = ('[IsResting] => %q; [IsResting] => ""'):format(L["True"]), + category = L["Status"] +}) + +DogTag:AddTag("Unit", "HappyNum", { + code = function() + return GetPetHappiness() or 0 + end, + ret = "number", + events = "UNIT_HAPPINESS", + doc = L["Return the happiness number of your pet"], + example = '[HappyNum] => "3"', + category = L["Status"] +}) + +DogTag:AddTag("Unit", "HappyText", { + code = function() + return _G["PET_HAPPINESS" .. (GetPetHappiness() or 0)] + end, + ret = "number", + events = "UNIT_HAPPINESS", + doc = L["Return a description of how happy your pet is"], + example = ('[HappyText] => %q'):format(_G.PET_HAPPINESS3), + category = L["Status"] +}) + +DogTag:AddTag("Unit", "HappyIcon", { + code = function(happy, content, unhappy) + local num = GetPetHappiness() + if num == 3 then + return happy + elseif num == 2 then + return content + elseif num == 1 then + return unhappy + end + end, + arg = { + 'happy', 'string', ':D', + 'content', 'string', ':I', + 'unhappy', 'string', 'B(', + }, + ret = "string;nil", + events = "UNIT_HAPPINESS", + doc = L["Return an icon representative of how happy your pet is"], + example = ('[HappyIcon] => ":D"; [HappyIcon] => ":I"; [HappyIcon] => "B("'), + category = L["Status"] +}) + +DogTag:AddTag("Unit", "IsTappedByMe", { + code = UnitIsTappedByPlayer, + arg = { + 'unit', 'string', '@req', + }, + ret = "boolean", + events = "Update", + doc = L["Return True if unit is tapped by you"], + example = '[IsTappedByMe] => "True"; [IsTappedByMe] => ""', + category = L["Status"] +}) + +DogTag:AddTag("Unit", "IsTapped", { + code = function(unit) + return UnitIsTapped(unit) and not UnitIsTappedByPlayer(unit) + end, + arg = { + 'unit', 'string', '@req', + }, + ret = "boolean", + events = "Update", + doc = L["Return * if unit is tapped, but not by you"], + example = ('[IsTapped] => %q; [IsTapped] => ""'):format(L["True"]), + category = L["Status"] +}) + +DogTag:AddTag("Unit", "InCombat", { + code = UnitAffectingCombat, + arg = { + 'unit', 'string', '@req', + }, + ret = "boolean", + events = "Update", + doc = L["Return True if unit is in combat"], + example = ('[InCombat] => %q; [InCombat] => ""'):format(L["True"]), + category = L["Status"] +}) + +DogTag:AddTag("Unit", "FKey", { + code = function(unit) + local fkey + if UnitIsUnit(unit, "player") then + return "F1" + else + for i = 1, 4 do + if UnitIsUnit(unit, "party" .. i) then + return "F" .. (i+1) + end + end + end + return nil + end, + arg = { + 'unit', 'string', '@req', + }, + ret = "string;nil", + doc = L["Return the function key to press to select unit"], + example = '[FKey] => "F5"', + category = L["Status"] +}) + +DogTag:AddTag("Unit", "RaidGroup", { + code = function(unit) + local n, s = UnitName(unit) + if s and s ~= "" then + n = n .. "-" .. s + end + for i = 1, GetNumRaidMembers() do + local name, rank, subgroup = GetRaidRosterInfo(i) + if name == n then + return subgroup + end + end + return nil + end, + arg = { + 'unit', 'string', '@req', + }, + ret = "number;nil", + doc = L["Return the raid group that unit is in"], + example = '[RaidGroup] => "3"', + category = L["Status"] +}) + +DogTag:AddTag("Unit", "IsMasterLooter", { + code = function(unit) + local n, s = UnitName(unit) + if s and s ~= "" then + n = n .. "-" .. s + end + for i = 1, GetNumRaidMembers() do + local name, rank, subgroup, level, class, fileName, zone, online, isDead, role, isML = GetRaidRosterInfo(i) + if name == n then + return true + end + end + return false + end, + arg = { + 'unit', 'string', '@req', + }, + ret = "boolean", + doc = L["Return True if unit is the master looter for your raid"], + example = ('[IsMasterLooter] => %q; [IsMasterLooter] => ""'):format(L["True"]), + category = L["Status"] +}) + +DogTag:AddTag("Unit", "Target", { + code = function(unit) + if unit == "player" then + return "target" + else + return unit .. "target" + end + end, + arg = { + 'unit', 'string', '@req', + }, + ret = "string", + doc = L["Return the unit id of unit's target"], + example = '[Target] => "party1target"; [HP(unit=Target)] => "1000"', + category = L["Status"] +}) + +DogTag:AddTag("Unit", "Pet", { + code = function(unit) + if unit == "player" then + return "pet" + elseif unit:match("^party%d$") then + return "partypet" .. unit:match("(%d+)") + elseif unit:match("^raid%d$") then + return "raidpet" .. unit:match("(%d+)") + else + return nil + end + end, + arg = { + 'unit', 'string', '@req', + }, + ret = "string;nil", + doc = L["Return the unit id of unit's pet"], + example = '[Pet] => "partypet1"; [HP(unit=Pet)] => "500"', + category = L["Status"] +}) + +DogTag:AddTag("Unit", "NumTargeting", { + code = function(unit) + local num = 0 + for u in iterateGroupMembers() do + if UnitIsUnit(u .. "target", unit) then + num = num + 1 + end + end + return num + end, + arg = { + 'unit', 'string', '@req', + }, + ret = "number", + events = "UNIT_TARGET;Update", + doc = L["Return the number of group members currently targeting unit"], + example = '[NumTargeting] => "2"', + category = L["Status"] +}) + +local t = {} +DogTag:AddTag("Unit", "TargetingList", { + code = function(unit) + for u in iterateGroupMembers() do + if UnitIsUnit(u .. "target", unit) then + local name = GetNameServer(u) + t[#t+1] = name + end + end + table.sort(t) + local s = table.concat(t, ", ") + for k in pairs(t) do + t[k] = nil + end + return s + end, + arg = { + 'unit', 'string', '@req', + }, + ret = "string;nil", + events = "UNIT_TARGET;Update", + doc = L["Return an alphabetized, comma-separated list of group members currently targeting unit"], + example = '[TargetingList] => "Grommash, Thrall"', + category = L["Status"] +}) + +DogTag:AddTag("Unit", "InGroup", { + code = function() + return GetNumRaidMembers() > 0 or GetNumPartyMembers() > 0 + end, + ret = "boolean", + doc = L["Return True if you are in a party or raid"], + example = ('[InGroup] => %q; [InGroup] => ""'):format(L["True"]), + category = L["Status"] +}) + +DogTag:AddTag("Unit", "IsUnit", { + code = UnitIsUnit, + arg = { + 'unit', 'string', '@req', + 'other', 'string', '@req', + }, + ret = "boolean", + events = "UNIT_FACTION#$unit", + doc = L["Return True if unit is the same as argument"], + example = ('[IsUnit("target")] => %q; [IsUnit("party1")] => ""'):format(L["True"]), + category = L["Status"] +}) + +DogTag:AddTag("Unit", "IsCharmed", { + code = UnitIsCharmed, + arg = { + 'unit', 'string', '@req', + }, + ret = "boolean", + events = "UNIT_FACTION#$unit", + doc = L["Return True if unit is under mind control"], + example = ('[IsCharmed] => %q; [IsCharmed] => ""'):format(L["True"]), + category = L["Status"] +}) + +DogTag:AddTag("Unit", "IsVisible", { + code = UnitIsVisible, + arg = { + 'unit', 'string', '@req', + }, + ret = "boolean", + events = "UNIT_PORTRAIT_UPDATE", + doc = L["Return True if unit is in visible range"], + example = ('[IsVisible] => %q; [IsVisible] => ""'):format(L["True"]), + category = L["Status"] +}) + + +DogTag:AddTag("Unit", "StatusColor", { + code = function(value, unit) + local r, g, b + if not UnitIsConnected(unit) then + r, g, b = unpack(DogTag.__colors.disconnected) + elseif UnitIsDeadOrGhost(unit) then + r, g, b = unpack(DogTag.__colors.dead) + end + if r then + if value then + return ("|cff%02x%02x%02x%s|r"):format(r * 255, g * 255, b * 255, value) + else + return ("|cff%02x%02x%02x"):format(r * 255, g * 255, b * 255) + end + else + return value + end + end, + arg = { + 'value', 'string;undef', '@undef', + 'unit', 'string', '@req', + }, + ret = "string;nil", + events = "DeadDuration#$unit", + doc = L["Return the color or wrap value with the color associated with unit's current status"], + example = '[Text(Hello):StatusColor] => "|cff7f7f7fHello|r"; [Text([StatusColor]Hello)] => "|cff7f7f7fHello"', + category = L["Status"] +}) + +DogTag:AddTag("Unit", "HappyColor", { + code = function(value) + local x = GetPetHappiness() + local r,g,b + if x == 3 then + r,g,b = unpack(colors.petHappy) + elseif x == 2 then + r,g,b = unpack(colors.petNeutral) + elseif x == 1 then + r,g,b = unpack(colors.petAngry) + end + if r then + if value then + return ("|cff%02x%02x%02x%s|r"):format(r * 255, g * 255, b * 255, value) + else + return ("|cff%02x%02x%02x"):format(r * 255, g * 255, b * 255) + end + else + return value + end + end, + arg = { + 'value', 'string;undef', "@undef", + }, + ret = "nil;string", + events = "UNIT_HAPPINESS", + doc = L["Return the color or wrap value with the color associated with your pet's happiness"], + example = '[Text(Hello):HappyColor] => "|cff00ff00Hello|r"; [Text([HappyColor]Hello)] => "|cff00ff00Hello"', + category = L["Status"] +}) + +end \ No newline at end of file diff --git a/Cleanup.lua b/Cleanup.lua index 5b3fa35..349f262 100644 --- a/Cleanup.lua +++ b/Cleanup.lua @@ -7,7 +7,9 @@ if MINOR_VERSION > _G.DogTag_Unit_MINOR_VERSION then end local DogTag_Unit, oldMinor = LibStub:NewLibrary(MAJOR_VERSION, MINOR_VERSION) +_G.DogTag_Unit_MINOR_VERSION = nil if not DogTag_Unit then + _G.DogTag_Unit_funcs = nil return end diff --git a/LibDogTag-Unit-3.0.lua b/LibDogTag-Unit-3.0.lua index f978f39..4c44b4a 100644 --- a/LibDogTag-Unit-3.0.lua +++ b/LibDogTag-Unit-3.0.lua @@ -45,6 +45,18 @@ frame:SetScript("OnEvent", function(this, event, ...) end end) +local function GetNameServer(unit) + local name, realm = UnitName(unit) + if name then + if realm and realm ~= "" then + return name .. "-" .. realm + else + return name + end + end +end +DogTag_Unit.GetNameServer = GetNameServer + local UnitToLocale = {player = L["Player"], target = L["Target"], pet = L["%s's pet"]:format(L["Player"]), focus = L["Focus-target"], mouseover = L["Mouse-over"]} setmetatable(UnitToLocale, {__index=function(self, unit) if unit:find("pet$") then @@ -110,6 +122,32 @@ end, __call = function(self, key) return self[key] end}) +local unitToGUID = {} +local function refreshGUIDs(unit) + if not unit then + for unit in pairs(IsNormalUnit) do + unitToGUID[unit] = UnitGUID(unit) + end + else + unitToGUID[unit] = UnitGUID(unit) + end +end + +DogTag:AddEventHandler("PARTY_MEMBERS_CHANGED", refreshGUIDs) + +local t = {} +local function IterateUnitsWithGUID(guid) + for k in pairs(t) do + t[k] = nil + end + for unit, g in pairs(unitToGUID) do + if g == guid then + t[unit] = true + end + end + return pairs(t) +end +DogTag_Unit.IterateUnitsWithGUID = IterateUnitsWithGUID local function searchForNameTag(ast) if type(ast) ~= "table" then @@ -174,18 +212,40 @@ DogTag:AddCompilationStep("Unit", "tag", function(ast, t, tag, tagData, kwargs, t[#t+1] = [=[end;]=] end end + if tag == "IsUnit" then + if type(kwargs["other"]) ~= "table" then + if not IsLegitimateUnit[kwargs["other"]] then + t[#t+1] = [=[do return ]=] + t[#t+1] = [=[("Bad unit: %q"):format(tostring(]=] + t[#t+1] = compiledKwargs["other"][1] + t[#t+1] = [=[));]=] + t[#t+1] = [=[end;]=] + end + else + t[#t+1] = [=[if not DogTag.IsLegitimateUnit[]=] + t[#t+1] = compiledKwargs["other"][1] + t[#t+1] = [=[] then return ]=] + t[#t+1] = [=[("Bad unit: %q"):format(tostring(]=] + t[#t+1] = compiledKwargs["other"][1] + t[#t+1] = [=[));]=] + t[#t+1] = [=[end;]=] + end + end end) DogTag:AddEventHandler("PLAYER_TARGET_CHANGED", function(event, ...) + refreshGUIDs("target") DogTag:FireEvent("UnitChanged", "target") DogTag:FireEvent("UnitChanged", "playertarget") end) DogTag:AddEventHandler("PLAYER_FOCUS_CHANGED", function(event, ...) + refreshGUIDs("focus") DogTag:FireEvent("UnitChanged", "focus") end) DogTag:AddEventHandler("PLAYER_PET_CHANGED", function(event, ...) + refreshGUIDs("pet") DogTag:FireEvent("UnitChanged", "pet") end) @@ -194,12 +254,15 @@ DogTag:AddEventHandler("UNIT_TARGET", function(event, unit) end) DogTag:AddEventHandler("UNIT_PET", function(event, unit) - DogTag:FireEvent("UnitChanged", unit .. "pet") + local unit_pet = unit .. "pet" + refreshGUIDs(unit_pet) + DogTag:FireEvent("UnitChanged", unit_pet) end) local inMouseover = false DogTag:AddEventHandler("UPDATE_MOUSEOVER_UNIT", function(event, ...) inMouseover = true + refreshGUIDs("mouseover") DogTag:FireEvent("UnitChanged", "mouseover") end) diff --git a/lib.xml b/lib.xml index 6e292a6..4f89c31 100644 --- a/lib.xml +++ b/lib.xml @@ -4,8 +4,10 @@