Broker Everything

Broker Everything

588k Downloads

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

Aes-Seda opened this issue ยท 2 comments

commented

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

commented

--[[ 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;

commented

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