HizurosWoWAddOns / Broker_Everything

A collection of module to display informations about own character, friends, guild and more on minimap or panel addons like Bazooka, ChcolateBar, TitanPanel and more.
GNU General Public License v3.0
10 stars 6 forks source link

[FEATURE]: gps.lua - Timewalker's Hearthstone #3

Closed Aes-Seda closed 2 years ago

Aes-Seda commented 2 years ago

Description

Hi anyone who can fix the gps.lua will be appreciated. Please include the Timewalker's Hearthstone --- toy for buying the new expansion. TIA

Additional Information

No response

Aes-Seda commented 2 years ago

--[[ 3 in 1 module ]]--

-- module independent variables --

local addon, ns = ... local C, L, I, _ = ns.LC.color, ns.L, ns.I

-- module own local variables and local cached functions --

local name0 = "GPS / Location / ZoneText"; L[name0] = ("%s / %s / %s"):format(L["GPS"],L["Location"],L["ZoneText"]); local name1 = "GPS"; -- L["GPS"] L["ModDesc-GPS"] local name2 = "Location"; -- L["Location"] L["ModDesc-Location"] local name3 = "ZoneText"; -- L["ZoneText"] L["ModDesc-ZoneText"] local updateinterval,module1,module2,module3 = 0.12; local ttName1, ttName2, ttName3, ttName4 = name1.."TT", name2.."TT", name3.."TT", "TransportMenuTT"; local ttColumns,ttColumns4,onleave,tt4Params = 3,5; local tt1, tt2, tt3, tt4, items; local zoneRed, zoneOrange, zoneYellow, zoneGreen,zoneBlue = C("red","%s"),C("orange","%s"),C("dkyellow","%s"),C("ltgreen","%s"),C("ltblue","%s"); local tt5positions = { ["LEFT"] = {edgeSelf = "RIGHT", edgeParent = "LEFT", x = -2, y = 0}, ["RIGHT"] = {edgeSelf = "LEFT", edgeParent = "RIGHT", x = 2, y = 0}, } local iStr16,iStr32 = "|T%s:16:16:0:0|t","|T%s:32:32:0:0|t"; local gpsLoc = {zone=" ",color="white",pvp="contested",pos=""} local zoneDisplayValues = { ["1"] = ZONE, ["2"] = L["Subzone"], ["3"] = ZONE..CHAT_HEADER_SUFFIX..L["Subzone"], ["4"] = ("%s (%s)"):format(ZONE,L["Subzone"]), ["5"] = ("%s (%s)"):format(L["Subzone"],ZONE), } local foundItems, foundToys, foundToysNum, teleports, portals, spells, hearthstoneLocation = {},{},0,{},{},{}; local _classSpecialSpellIds,_teleportIds,_portalIds,_itemIds,_toyIds,_hearthstones,_itemMustBeEquipped,_itemFactions,_namelessToys = {},{},{},{},{},{},{},{},{}; local sharedclickOptionsRename = { ["1_open_world_map"] = "worldmap", ["2_open_transport_menu"] = "transport", ["3_open_menu"] = "menu" }; local sharedclickOptions = { ["worldmap"] = {"World map","call",{"ToggleWorldMap"}}, ["transport"] = {"Transport menu","module","transportMenu"}, ["menu"] = "OptionMenu" }; local sharedclickOptionsDefaults = { worldmap = "_LEFT", transport = "_RIGHT", menu = "__NONE" }; local sharedMisc = { shortMenu={ type="toggle", name=L["Short transport menu"], desc=L["Display the transport menu without names of spells and items behind the icons."]}, coordsFormat={ type="select", name = L["Coordination format"], desc = L["How would you like to view coordinations."], values = { ["%s, %s"] = "10.3, 25.4", ["%s / %s"] = "10.3 / 25.4", ["%s/%s"] = "10.3/25.4", ["%s | %s"] = "10.3 | 25.4", ["%s||%s"] = "10.3||25.4" }, }, precision={ type="range", name=L["Precision"], desc=L["Change how much digits display after the dot."], min=0, max=3, step=1 } }

-- register icon names and default files --

I[name1] = {iconfile="Interface\Addons\"..addon.."\media\gps"} --IconName::GPS-- I[name2] = {iconfile="Interface\Addons\"..addon.."\media\gps"} --IconName::Location-- I[name3] = {iconfile=134269,coords={0.05,0.95,0.05,0.95}} --IconName::ZoneText--

-- some local functions --

local function setSpell(tb,id) if IsSpellKnown(id) then local sName, , icon, , , , , , _ = GetSpellInfo(id); table.insert(tb,{id=id,icon=icon,name=sName,name2=sName}); end end

local function updateSpells() wipe(teleports); wipe(portals); wipe(spells); if (ns.player.class=="MAGE") then for i=1, #_teleportIds do setSpell(teleports,_teleportIds[i]) end for i=1, #_portalIds do setSpell(portals,_portalIds[i]) end end for i=1, #_classSpecialSpellIds do setSpell(spells,_classSpecialSpellIds[i]) end end

local function itemIsHearthstone(id) if _hearthstones[id] then return true, hearthstoneLocation; end return false,""; end

local function addToy(id) if not foundToys[id] and PlayerHasToy then local toyName, , , , , , , , , toyIcon = GetItemInfo(id); local hasToy = PlayerHasToy(id); local canUse = C_ToyBox.IsToyUsable(id); if toyName and hasToy and canUse then local isHS, hsLoc = itemIsHearthstone(id); foundToys[id] = { id=id, icon=toyIcon, name=toyName, name2=isHS and toyName..hsLoc or toyName }; foundToysNum = foundToysNum + 1; if _namelessToys[id] then _namelessToys[id] = nil; end elseif not toyName then return false; end end return true; end

local function addToyOnCallback(toyID,toyIcon,toyName) local isHS, hsLoc = itemIsHearthstone(toyID); foundToys[toyID] = { id=toyID, icon=toyIcon, name=toyName, name2=isHS and toyName..hsLoc or toyName }; foundToysNum = foundToysNum + 1; if _namelessToys[toyID] then _namelessToys[toyID] = nil; end end

local function updateItems() -- update hearthstone location string hearthstoneLocation = " "..C("ltblue","("..GetBindLocation()..")");

-- update foundItems table
wipe(foundItems);
for i=1, #_itemIds do
    local id = _itemIds[i];
    if ns.items.byID[id] then
        for sharedSlot,item in pairs(ns.items.byID[id]) do
            local isHS,hsLoc = itemIsHearthstone(id);
            local obj = {id=id};
            obj.name, _, _, _, _, _, _, _, _, obj.icon = GetItemInfo(item.link);
            if obj.name then
                obj.name2 = isHS and obj.name..hsLoc or obj.name;
                if _itemMustBeEquipped[id] then
                    obj.mustBeEquipped = true;
                    obj.equipped = item.bag==-1;
                end
                tinsert(foundItems,obj);
            end
        end
    end
end

-- update foundToys table;
if ns.client_version>=2 then
    for i=1, #_toyIds do
        if addToy(_toyIds[i]) then
            _namelessToys[_toyIds[i]] = true;
        end
    end
end

end

local function position(name) local p, f, pf = ns.profile[name].precision or 0, ns.profile[name].coordsFormat or "%s, %s"; local x, y = 0,0; local mapID = C_Map.GetBestMapForUnit("player"); if mapID then local obj = C_Map.GetPlayerMapPosition(C_Map.GetBestMapForUnit("player"),"player"); if obj and obj.GetXY then x,y = obj:GetXY(); end end if not x or (x==0 and y==0) then local pX = p==0 and "−" or "−."..strrep("−",p); return f:format(pX,pX); else return f:format("%."..p.."f","%."..p.."f"):format(x100, y100); end end

local function zone(byName) local subZone = GetSubZoneText() or ""; local zone = GetRealZoneText() or ""; local types = {"%s: %s","%s (%s)"}; local mode = "2";

if ns.profile[byName]==nil then
    ns.profile[byName]={};
end
if ns.profile[byName].bothZones==nil then
    ns.profile[byName].bothZones = mode;
else
    mode = ns.profile[byName].bothZones;
end

if mode=="2" and subZone~="" then
    return subZone
elseif mode=="3" and subZone~="" then
    return subZone and types[1]:format(zone,subZone or "")
elseif mode=="4" and subZone~="" then
    return subZone and types[2]:format(zone,subZone)
elseif mode=="5" and subZone~="" then
    return subZone and types[2]:format(subZone,zone)
end

return zone

end

local function GetZoneInfo() local zoneColor,zoneLabel,zoneType, _, f = "white","",GetZonePVPInfo()

if zoneType == "combat" or zoneType == "arena" or zoneType == "hostile" then
    zoneColor,zoneLabel = zoneRed,HOSTILE;
elseif zoneType == "contested" or zoneType == nil then
    zoneColor,zoneLabel,zoneType = zoneYellow,L["Contested"],"contested"
elseif zoneType == "friendly" then
    zoneColor,zoneLabel = zoneGreen,FRIENDLY;
elseif zoneType == "sanctuary" then
    zoneColor,zoneLabel = zoneBlue,L["Sanctuary"];
end
return zoneColor,zoneLabel,zoneType;

end

-- shared tooltip for modules Location, GPS and ZoneText local function createTooltip(tt,ttName,modName) if not (tt and tt.key and tt.key==ttName) then return end -- don't override other LibQTip tooltips...

local zoneColor,zoneLabel,zoneType = GetZoneInfo()
local line, column

if buttonFrame then buttonFrame:ClearAllPoints() buttonFrame:Hide() end

if tt.lines~=nil then tt:Clear(); end

tt:AddHeader(C("dkyellow",L[modName]))

tt:AddSeparator()

local lst = {
    {C("ltyellow",ZONE .. HEADER_COLON),GetRealZoneText()},
    {C("ltyellow",L["Subzone"] .. HEADER_COLON),GetSubZoneText()},
    {C("ltyellow",L["Zone status"] .. HEADER_COLON),zoneColor:format(zoneLabel)},
    {C("ltyellow",L["Coordinates"] .. HEADER_COLON),position(modName) or C(gpsLoc.posColor or gpsLoc.color,gpsLoc.pos)}
}

for _, d in pairs(lst) do
    line, column = tt:AddLine()
    tt:SetCell(line,1,d[1],nil,nil,2)
    tt:SetCell(line,3,d[2],nil,nil,1)
end

if gpsLoc.posColor then
    line,column = tt:AddLine()
    tt:SetCell(line,1,C(gpsLoc.posColor,gpsLoc.posInfo),nil,"CENTER",3)
end

tt:AddSeparator()

line, column = tt:AddLine()
tt:SetCell(line,1,C("ltyellow",L["Inn"]..HEADER_COLON),nil,nil,1)
tt:SetCell(line,2,GetBindLocation(),nil,nil,2)

if ns.profile.GeneralOptions.showHints then
    tt:AddSeparator(4,0,0,0,0)
    ns.ClickOpts.ttAddHints(tt,modName);
end
ns.roundupTooltip(tt);

end

local function createTooltip3(_,data) if not (data.tooltip and data.tooltip.parent and data.tooltip.parent:IsShown()) then return end GameTooltip:SetOwner(data.tooltip.parent,"ANCHOR_NONE"); GameTooltip:SetPoint(ns.GetTipAnchor(data.tooltip.parent,"horizontal")); GameTooltip:SetHyperlink(data.tooltip.type..HEADER_COLON..data.tooltip.id); GameTooltip:Show(); end

local transportMenu local function updateTPM() if tt4Params then --C_Timer.After(0.2,function() transportMenu(unpack(tt4Params)) end); transportMenu(unpack(tt4Params)); end end

-- tooltip as transport menu local function tpmOnEnter(self,info) local parent, v, t = unpack(info); local data = { attributes={type=t,[t]=v.name}, tooltip={parent=tt4,type=t,id=v.id}, OnEnter=createTooltip3, OnLeave=GameTooltip_Hide, --OnClick=updateTPM }; ns.secureButton(self,data); end

local function transportMenuOnHide() tt4Params = nil; end

local function transportMenuDoUpdate() if tt4Params then transportMenu(unpack(tt4Params)); end end

local function tpmAddObject(tt,p,l,c,v,t,name) if ns.profile[name].shortMenu then if c<ttColumns4 and l~=nil then c=c+1; else c=1; l=tt:AddLine(); end tt:SetCell(l, c, iStr32:format(v.icon), nil, nil, 1); tt:SetCellScript(l,c,"OnEnter",tpmOnEnter, {p,v,t}); return l,c; else local info,doUpdate = ""; if v.mustBeEquipped==true and v.equipped==false then info = " "..C("orange","(click to equip)"); doUpdate=true end l = tt:AddLine(iStr16:format(v.icon)..(v.name2 or v.name)..info, "1","2","3"); tt:SetLineScript(l,"OnEnter",tpmOnEnter,{p,v,t}); end end

function transportMenu(self,button,name) if InCombatLockdown() then return; end if (tt1~=nil) then tt1=ns.hideTooltip(tt1); end if (tt2~=nil) then tt2=ns.hideTooltip(tt2); end if (tt3~=nil) then tt3=ns.hideTooltip(tt3); end

updateItems();
updateSpells();

local columns = 5;
ttColumns4 = ns.profile[name].shortMenu and columns or 1;
if not (tt4 and tt4.key and tt4.key==ttName4) then
    tt4 = ns.acquireTooltip({ttName4, ttColumns4, "LEFT","LEFT","LEFT","LEFT","LEFT"},{false},{self},{OnHide=transportMenuOnHide});
    tt4Params = {self,button,name};
end

local pts,ipts,tls,itls = {},{},{},{}
local line, column,cellcount = nil,nil,5

tt4:Clear()

-- title
if not ns.profile[name].shortMenu then
    tt4:AddHeader(C("dkyellow","Choose your transport"))
end

local counter = 0
local l,c=nil,ttColumns4;

if #teleports>0 or #portals>0 or #spells>0 then
    -- class title
    if not ns.profile[name].shortMenu then
        tt4:AddSeparator(4,0,0,0,0)
        tt4:AddLine(C("ltyellow",ns.player.classLocale))
        tt4:AddSeparator()
    end
    -- class spells
    local t = "spell";
    if ns.player.class=="MAGE" then
        for i,v in ns.pairsByKeys(teleports) do
            l,c = tpmAddObject(tt4,self,l,c,v,t,name);
            counter = counter+1;
        end
        if not ns.profile[name].shortMenu then
            tt4:AddSeparator()
        end
        for i,v in ns.pairsByKeys(portals) do
            l,c = tpmAddObject(tt4,self,l,c,v,t,name);
            counter = counter+1;
        end
    else
        for i,v in ns.pairsByKeys(spells) do
            l,c = tpmAddObject(tt4,self,l,c,v,t,name);
            counter = counter+1;
        end
    end
end

local t = "item";
if #foundItems>0 then
    -- item title
    if not ns.profile[name].shortMenu then
        tt4:AddSeparator(4,0,0,0,0);
        tt4:AddLine(C("ltyellow",ITEMS));
        tt4:AddSeparator();
    end
    -- items
    for i,v in ns.pairsByKeys(foundItems) do
        l,c = tpmAddObject(tt4,self,l,c,v,t,name);
        counter = counter + 1
    end
end

if ns.client_version>=2 and foundToysNum>0 then
    -- toy title
    if not ns.profile[name].shortMenu then
        tt4:AddSeparator(4,0,0,0,0);
        tt4:AddLine(C("ltyellow",TOY_BOX));
        tt4:AddSeparator();
    end
    -- toys
    for id,toy in pairs(foundToys) do
        l,c = tpmAddObject(tt4,self,l,c,toy,t,name);
        counter = counter + 1;
    end
end

if counter==0 then
    tt4:AddSeparator(4,0,0,0,0)
    tt4:AddHeader(C("ltred",L["Sorry"].."!"))
    tt4:AddSeparator(1,1,.4,.4,1)
    tt4:AddLine(C("ltred",L["No spells, items or toys found"].."."))
end
ns.roundupTooltip(tt4);

end

local function posUpdater(name) local gpsLoc,pos = {},position(name) if pos then gpsLoc.pos = pos gpsLoc.posColor = "%s" gpsLoc.posInfo = nil else if gpsLoc.posLast==nil then gpsLoc.posLast=time() elseif time()-gpsLoc.posLast>5 then gpsLoc.posColor = zoneOrange; gpsLoc.posInfo = L["Coordinates indeterminable"] end end return gpsLoc; end

local function updater() if not (ns.profile[name1].enabled or ns.profile[name2].enabled or ns.profile[name3].enabled) then return end local zoneColor,zoneLabel,zoneType = GetZoneInfo();

if ns.profile[name1].enabled and module1.obj then
    local gpsLoc = posUpdater(name1)
    gpsLoc.zone = zone(name1);
    module1.obj.text = zoneColor:format(gpsLoc.zone.." (")..(gpsLoc.poszoneColor and C(gpsLoc.poszoneColor,gpsLoc.pos) or zoneColor:format(gpsLoc.pos))..zoneColor:format(")");
end

if ns.profile[name2].enabled and module2.obj then
    local gpsLoc = posUpdater(name2)
    module2.obj.text = gpsLoc.poszoneColor and C(gpsLoc.poszoneColor,gpsLoc.pos) or zoneColor:format(gpsLoc.pos);
end

if ns.profile[name3].enabled and module3.obj then
    local gpsLoc = posUpdater(name3)
    gpsLoc.zone = zone(name3)
    module3.obj.text = zoneColor:format(gpsLoc.zone);
end

end

local function init() -- spells _classSpecialSpellIds = {50977,18960,556,126892,147420,193753}; _teleportIds = {3561,3562,3563,3565,3566,3567,32271,32272,33690,35715,49358,49359,53140,88342,88344,120145,132621,132627,176248,176242,193759,224869,281403,281404,344587}; _portalIds = {10059,11416,11417,11418,11419,11420,32266,32267,33691,35717,49360,49361,53142,88345,88346,120146,132620,132626,176246,176244,224871,281400,281402,344597};

-- items
_itemIds = {
    17690,17691,17900,17901,17902,17903,17904,17905,17906,17907,17908,17909,21711,22589,22630,22631,22632,24335,29796,32757,34420,35230,36747,37863,38685,40585,
    40586,44934,44935,45688,45689,45690,45691,45705,46874,48954,48955,48956,48957,50287,51557,51558,51559,51560,52251,52576,58487,58964,60273,60374,60407,60498,
    61379,63206,63207,63352,63353,63378,63379,64457,65274,65360,66061,68808,68809,82470,87548,91850,91860,91861,91862,91863,91864,91865,91866,92056,92057,92058,
    92430,92431,92432,92510,95050,95051,103678,104110,104113,107441,110560,116413,117389,118662,118663,118907,118908,119183,128353,128502,128503,129276,132119,
    132120,132122,132517,133755,134058,138448,139541,139590,139599,140192,140319,140493,141013,141014,141015,141016,141017,141605,142469,144391,144392,147870,
    152964,156927,159224,166559,166560,184504,

    -- hearth stones (not toys)
    6948,28585,37118,44314,44315,142298,142543
};

-- toys
_toyIds = {18984,18986,30542,30544,43824,48933,54452,64488,87215,93672,95567,95568,95589,95590,112059,129929,136849,140324,142542,151016,151652,162973,163045,165669,165670,165802,166746,166747,168907,169297,169298,172179,184353,180290,182773,172924,193588};

-- items with hearthstone spell
_hearthstones = {
    [6948]=1, -- Hearthstone
    [28585]=1, -- Ruby Slippers
    [37118]=1, -- Scroll of Recall
    [44314]=1, -- Scroll of Recall II
    [44315]=1, -- Scroll of Recall III
    [54452]=1, -- Toy - Ethereal Portal
    [64488]=1, -- Toy - The Innkeeper's Daughter
    [93672]=1, -- Toy - Dark Portal
    [142298]=1, -- Astonishingly Scarlet Slippers
    [142542]=1, -- Toy - Tome of Town Portal
    [142543]=1, -- Scroll of Town Portal
    [162973]=1, -- Toy - Greatfather Winter's Hearthstone
    [163045]=1, -- Toy - Headless Horseman's Hearthstone
    [165669]=1, -- Toy - Lunar Elder's Hearthstone
    [165670]=1, -- Toy - Peddlefeet's Lovely Hearthstone
    [165802]=1, -- Toy - Noble Gardener's Hearthstone
    [166746]=1, -- Toy - Fire Eater's Hearthstone
    [166747]=1, -- Toy - Brewfest Reveler's Hearthstone
    [168907]=1, -- Toy - Holographic Digitalization Hearthstone
    [172179]=1, -- Toy - Eternal Traveler's Hearthstone
    [184353]=1, -- Toy - Kyrian Hearthstone
    [180290]=1, -- Toy - Night Fae Hearthstone
    [182773]=1, -- Toy - Necrolord Hearthstone
    [193588]=1, -- Toy - Timewalker's Hearthstone
};

--_itemReplacementIds = {64488,28585,6948,44315,44314,37118,142542,142298};
_itemMustBeEquipped = {[32757]=1,[40585]=1,[142298]=1};

-- init ns.items
ns.items.Init("any");
ns.items.RegisterCallback(name1,transportMenuDoUpdate,"any");
ns.items.RegisterCallback(name1,addToyOnCallback,"toys");

C_Timer.After(5,function()
    C_Timer.NewTicker(updateinterval,updater);
    updateItems();
    updateSpells();
end);

end

-- module functions and variables --

module1 = { -- GPS events = {}, config_defaults = { enabled = true, bothZones = "2", precision = 0, coordsFormat = "%s, %s", shortMenu = false }, clickOptions = sharedclickOptions }

module2 = { -- Location events = {}, config_defaults = { enabled = false, precision = 0, coordsFormat = "%s, %s", shortMenu = false }, clickOptions = sharedclickOptions }

module3 = { -- ZoneText events = {}, config_defaults = { enabled = false, bothZones = "2", precision = 0, coordsFormat = "%s, %s", shortMenu = false }, clickOptions = sharedclickOptions }

ns.ClickOpts.addDefaults(module1,sharedclickOptionsDefaults); ns.ClickOpts.addDefaults(module2,sharedclickOptionsDefaults); ns.ClickOpts.addDefaults(module3,sharedclickOptionsDefaults);

module1.transportMenu = transportMenu; module2.transportMenu = transportMenu; module3.transportMenu = transportMenu;

function module1.options() return { broker = { bothZones={ type="select", name=L["Display zone names"], desc=L["Display in broker zone and subzone if exists or one of it."], values=zoneDisplayValues } }, misc = sharedMisc } end

function module2.options() return { broker = nil, misc = sharedMisc } end

function module3.options() return { broker = { bothZones={ type="select", name=L["Display zone names"], desc=L["Display in broker zone and subzone if exists or one of it."], values=zoneDisplayValues } }, misc = sharedMisc } end

function module1.init() if init then init() init=nil end end

function module2.init() if init then init() init=nil end end

function module3.init() if init then init() init=nil end end

local eventActive = false; local function onevent(name,self,event,arg1,...) if event=="BE_UPDATE_CFG" then if arg1 and arg1:find("^ClickOpt") then ns.ClickOpts.update(name); end if not eventActive then eventActive = name; end end end

function module1.onevent(...) onevent(name1,...); end

function module2.onevent(...) onevent(name2,...); end

function module3.onevent(...) onevent(name3,...); end

-- function module1.onmousewheel(self,direction) end -- function module2.onmousewheel(self,direction) end -- function module3.onmousewheel(self,direction) end -- function module1.optionspanel(panel) end -- function module2.optionspanel(panel) end -- function module3.optionspanel(panel) end

function module1.onenter(self) if (ns.tooltipChkOnShowModifier(false)) then return; end tt1 = ns.acquireTooltip({ttName1, ttColumns, "LEFT", "RIGHT", "RIGHT"},{true},{self}); createTooltip(tt1,ttName1,name1); end

function module2.onenter(self) if (ns.tooltipChkOnShowModifier(false)) then return; end tt2 = ns.acquireTooltip({ttName2, ttColumns, "LEFT", "RIGHT", "RIGHT"},{true},{self}); createTooltip(tt2,ttName2,name2); end

function module3.onenter(self) if (ns.tooltipChkOnShowModifier(false)) then return; end tt3 = ns.acquireTooltip({ttName3, ttColumns, "LEFT", "RIGHT", "RIGHT"},{true},{self}); createTooltip(tt3,ttName3,name3); end

-- function module1.onleave(self) end -- function module2.onleave(self) end -- function module3.onleave(self) end -- function module1.onclick(self,button) end -- function module2.onclick(self,button) end -- function module3.onclick(self,button) end -- function module1.ondblclick(self,button) end -- function module2.ondblclick(self,button) end -- function module3.ondblclick(self,button) end

-- final module registration --

ns.modules[name1] = module1; ns.modules[name2] = module2; ns.modules[name3] = module3;

Aes-Seda commented 2 years ago

Here is the updated file. I have checked it out and it works. Thanks for this addon.