diff ReagentMaker.lua @ 98:b980c00affcd

Added a button to cast a campfire I got a problem with newlines and merging with a non-Mercurial repository, I hope noting broke...
author contrebasse
date Fri, 20 May 2011 18:32:43 +0200
parents c369a2e16ab6
children 060f5d0f7a35
line wrap: on
line diff
--- a/ReagentMaker.lua	Fri May 20 00:54:15 2011 +0200
+++ b/ReagentMaker.lua	Fri May 20 18:32:43 2011 +0200
@@ -1,297 +1,303 @@
-local addonName, A = ...
-
--- @todo clean the A table
--- @todo check local copy of globals functions
--- @todo add support for dez ?
--- @todo add support for hidden recipes, removing filtering
--- @todo add support for cross tradeskill, like mining + forge/ingé
--- @todo when a reagent can not be crafted and the recipe has many reagents, do like ReverseEngeneering and go to this recipe (with a one step return button)
--- @todo scroll to the selected recipe on opening (usefull also for the previous todo)
--- @todo shift+clic on a reagent name while the serachbar is focused fills the serachbar with the reagent name (idem with the crafted item)
--- @todo add a button to clear search
--- @todo add a button to cast a campfire when coocking
-
----------------------------------------------------
--- Variables
----------------------------------------------------
--- Used by findglobals
--- GLOBALS: _G, CreateFrame, DEFAULT_CHAT_FRAME
-
--- Lua functions
-
--- Wow functions
-
--- constant vars
-
----------------------------------------------------
--- Manage events
----------------------------------------------------
-A.EventsFrame = CreateFrame("Frame")
-
-local SCAN_DELAY = 0.2
-local t_throttle = SCAN_DELAY
-local function throttleScan(self, t_elapsed)
-	t_throttle = t_throttle - t_elapsed
-	if t_throttle<0 then
-		self:SetScript("OnUpdate", nil)
-
-		-- Close the external window if the tradeskill changed
-		if A.currentTradeSkill ~= GetTradeSkillLine() then
-			A.MenuFrame:Hide()
-		end
-		if IsTradeSkillGuild() or IsTradeSkillLinked() then
-			A.MenuFrame:Hide()
-			return
-		end
-
-		-- Scan availabe recipes
-		-- Rescan in case of problem
-		if not A:ScanSimpleRecipes() then
-			t_throttle = SCAN_DELAY
-			self:SetScript("OnUpdate", throttleScan)
-		end
-
-		-- Show makables reagents
-		A.updateCounts(GetTradeSkillSelectionIndex())
-	end
-end
-A.EventsFrame:SetScript("OnEvent", function(self, event)
-	if event == "TRADE_SKILL_UPDATE" then
-		t_throttle = SCAN_DELAY
-		self:SetScript("OnUpdate", throttleScan)
-
-	elseif event == "TRADE_SKILL_SHOW" then
-		A:Initialize()
-		A.EventsFrame:UnregisterEvent("TRADE_SKILL_SHOW")
-	end -- if
-end) -- function
-A.EventsFrame:RegisterEvent("TRADE_SKILL_SHOW")
-A.EventsFrame:RegisterEvent("TRADE_SKILL_UPDATE")
-
----------------------------------------------------
--- Initialize
----------------------------------------------------
-function A:Initialize()
-
-	-- Register clics on reagent's buttons
-	for i=1,7 do
-		local btn = _G["TradeSkillReagent"..i]
-		btn:HookScript("OnDoubleClick", A.ProcessReagent)
-		btn:HookScript("OnEnter", A.btnEntered)
-		btn:HookScript("OnLeave", A.btnLeft)
-		btn.SplitStack = A.SplitStack
-
-		local textureHighlight = btn:CreateTexture()
-		textureHighlight:Hide()
-		textureHighlight:SetTexture("Interface\\BUTTONS\\CheckButtonHilight")
-		textureHighlight:SetBlendMode("ADD")
-		textureHighlight:SetAllPoints("TradeSkillReagent"..i.."IconTexture")
-		btn.textureHighlight = textureHighlight
-
-		local label = btn:CreateFontString(nil,"ARTWORK","GameFontHighlight")
-		label:SetSize(100,20)
-		label:SetPoint("TOPLEFT",btn,"TOPLEFT",4,-4)
-		label:SetJustifyH("LEFT")
-		label:SetJustifyV("TOP")
-		label:SetFont("Fonts\\FRIZQT__.TTF", 10, "OUTLINE")
-		btn.label = label
-	end -- for
-
-	-- Secondary Tooltip
-	A.tooltipRecipe = CreateFrame("GameTooltip", "ReagentMaker_tooltipRecipe",UIParent, "GameTooltipTemplate")
-	A.tooltipRecipe:SetFrameStrata("TOOLTIP")
-	A.tooltipRecipe:Hide()
-	
-	-- Button for enchanting directy on a scroll
-	A.LoadEnchantOnScroll()
-end -- function
-
--- Function run after selecting a item in the tradeskill window
-function A.ProcessReagent(btn, ...)
-
-	-- Do not manage guild tradeskill
-	if IsTradeSkillGuild() or IsTradeSkillLinked() then return end
-
-	-- We want no modifiers, or shift to choose the number of reagent to craft
-	if IsModifierKeyDown() and not IsShiftKeyDown() then return end
-	local chooseNumberToCraft = IsShiftKeyDown()
-
-	-- Index of the reagent in the recipe, taken from the button name
-	local reagentRecipeIndex = A.buttonNumber(btn)
-
-	-- ID of the reagent we want to craft
-	local recipeIndex = GetTradeSkillSelectionIndex()
-	local reagentID = A.link2ID(GetTradeSkillReagentItemLink(recipeIndex, reagentRecipeIndex))
-
-	-- Continue only if the reagent is known
-	if not reagentID or not A.data[reagentID] then return end
-
-	-- If only one recipe is known for the reagent, use it
-	if #(A.data[reagentID]) == 1 and not A.data[reagentID][1].macro then
-		if A.data[reagentID][1].spellName and A.data[reagentID][1].spellName ~= GetTradeSkillLine() then
-			A.Error(A.L["The recipe to make this reagent is in another tradeskill. Currently ReagentMaker can not manage such a case, sorry."])
-			return
-		end
-
-		local numMakable, reagentIndex = A.numMakable(reagentID)
-
-		-- Try to show the recipe by removing filters once if it was not found
-		if not reagentIndex then
-			A.SaveActiveFilters(A.data[reagentID][1].header)
-			numMakable, reagentIndex = A.numMakable(reagentID)
-		end
-
-		if not numMakable then
-			A.Error(A.L["The recipe to make the reagent seems to be hidden, it is not makable. Try to remove the filters on the recipes."])
-			return
-		end
-		if numMakable>0 then
-			A.craft(recipeIndex,reagentRecipeIndex,reagentIndex,numMakable,chooseNumberToCraft)
-			return
-		end
-
-		-- If we can make the item needed to make the reagent, open a window to make it
-		-- one step recursion, enables to mill to create an ink
-		if A.data[reagentID][1][1] and A.data[A.data[reagentID][1][1]] then
-			if A.externalCraftWindow(A.data[reagentID][1][1],reagentID) ~= false then
-				return
-			end
-		end
-
-		A.Error(A.L["You do not have enough reagents to craft [%s]"]:format(GetItemInfo(reagentID) or "item #"..reagentID))
-		return
-	else
-		A.externalCraftWindow(reagentID)
-	end -- if
-	--A.RestoreActiveFilters()
-end -- function
-
-
----------------------------------------------------
--- Craft items
----------------------------------------------------
--- function used after choosing the number of reagent to craft
-function A.SplitStack(owner,split)
-	DoTradeSkill(owner.ReagentMaker_reagentIndex,tonumber(split))
-	owner.ReagentMaker_reagentIndex = nil
-end
-
--- Craft the reagent of an item, given it's position in the recipe
-function A.craft(recipeIndex,reagentRecipeIndex,reagentIndex,numReagentMakable,chooseNumber)
-	-- Look at how many we need to make one item for the selected recipe
-	local numToMake = 1
-	local _, _, reagentCount, playerReagentCount = GetTradeSkillReagentInfo(recipeIndex, reagentRecipeIndex)
-	-- make enough reagents to craft one more item
-	numToMake = math.min(math.floor(playerReagentCount/reagentCount+1)*reagentCount-playerReagentCount,numReagentMakable)
-
-	-- take into account that some recipe craft more than one item
-	-- use the mean between min and max, but make at least one...
-	local minMade, maxMade = GetTradeSkillNumMade(reagentIndex)
-	numToMake = math.max(math.floor(2*numToMake/(maxMade+minMade)),1)
-	
-	-- Choose number or craft directly
-	if chooseNumber then
-		-- the dialog window is linked to the reagent button
-		local btn = _G["TradeSkillReagent"..reagentRecipeIndex]
-
-		-- Store info to be able to run the function later
-		btn.ReagentMaker_reagentIndex = reagentIndex
-
-		-- Open dialog
-		OpenStackSplitFrame(numReagentMakable, btn, "TOP", "BOTTOM")
-
-		-- Fill in the number to make
-		numToMake = tostring(numToMake)
-		for i = 1,numToMake:len() do
-			StackSplitFrame_OnChar(StackSplitFrame,numToMake:gsub(i,i))
-		end
-		StackSplitFrame.typing = 0 -- reinit the frame so tha the entered value will be erased on text entry
-	else
-		DoTradeSkill(reagentIndex,numToMake)
-	end -- if
-end -- function
-
-
--- Button hovering
-function A.btnEntered(btn)
-	-- Do not manage guild tradeskill
-	if IsTradeSkillGuild() or IsTradeSkillLinked() then return end
-
-	-- Index of the reagent in the recipe, taken from the button name
-	local reagentRecipeIndex = A.buttonNumber(btn)
-
-	-- ID of the reagent we want to craft
-	local reagentLink = GetTradeSkillReagentItemLink(GetTradeSkillSelectionIndex(), reagentRecipeIndex)
-	local reagentID = A.link2ID(reagentLink)
-
-	-- Continue only if the reagent is known
-	if not reagentID or not A.data[reagentID] then return end
-
-	btn.textureHighlight:Show()
-
-	-- Check if the item is made by only one recipe. If not, return
-	if not A.isRecipeUnique(A.data[reagentID]) then return end
-
-	-- Tooltips
-	local link = A.data[reagentID][1].spellLink
-	if link then
-		A.tooltipRecipe:SetOwner(btn)
-		A.tooltipRecipe:SetHyperlink(link)
-		A.tooltipRecipe:Show()
-		A.tooltipRecipe:ClearAllPoints()
-		A.tooltipRecipe:SetPoint("BOTTOMLEFT",GameTooltip,"BOTTOMRIGHT")
-	end
-end
-
-function A.btnLeft(btn)
-	btn.textureHighlight:Hide()
-	A.tooltipRecipe:Hide()
-end -- function
-
-function A.updateCounts(recipeIndex)
-	-- Needs an argument
-	if not recipeIndex then return end
-
-	-- Do not manage guild tradeskill
-	if IsTradeSkillGuild() or IsTradeSkillLinked() then
-		for reagentRecipeIndex = 1,GetTradeSkillNumReagents(recipeIndex) do
-			-- If the normal tradeskill hasn't been opened yet, the field 'label' doesn't exists yet
-			local label = _G["TradeSkillReagent"..reagentRecipeIndex].label
-			if label then
-				label:Hide()
-			end
-		end
-		return
-	end
-
-	-- Count makable items and show it
-	for reagentRecipeIndex = 1,GetTradeSkillNumReagents(recipeIndex) do
-		-- ID of the reagent we want to craft
-		local reagentLink = GetTradeSkillReagentItemLink(recipeIndex, reagentRecipeIndex)
-		local reagentID = A.link2ID(reagentLink)
-
-		local label = _G["TradeSkillReagent"..reagentRecipeIndex].label
-		if not label then break end -- Shouldn't happen...
-
-		-- Continue only if the reagent is known
-		if not reagentID or not A.data[reagentID] then
-			label:Hide()
-		else
-			-- Count and show
-			local numMakable = A.numMakable(reagentID)
-			if not numMakable or #(A.data[reagentID]) ~= 1 or A.data[reagentID][1].macro then
-				label:SetText("?")
-				label:SetTextColor(0, 0.5, 1, 1) -- blue
-			else
-				label:SetText(numMakable)
-				if numMakable==0 then
-					label:SetTextColor(1, 0, 0, 1) -- red
-				else
-					label:SetTextColor(0, 1, 0, 1) -- green
-				end
-			end -- if
-			label:Show()
-		end -- if
-	end -- for
-end -- function
-hooksecurefunc("SelectTradeSkill",A.updateCounts)
+local addonName, A = ...
+
+-- @todo clean the A table
+-- @todo check local copy of globals functions
+-- @todo add support for dez ?
+-- @todo add support for hidden recipes, removing filtering
+-- @todo add support for cross tradeskill, like mining + forge/ingé
+-- @todo when a reagent can not be crafted and the recipe has many reagents, do like ReverseEngeneering and go to this recipe (with a one step return button)
+-- @todo scroll to the selected recipe on opening (usefull also for the previous todo)
+-- @todo shift+clic on a reagent name while the serachbar is focused fills the serachbar with the reagent name (idem with the crafted item)
+-- @todo add a button to clear search
+-- @todo add a button to cast a campfire when coocking
+
+---------------------------------------------------
+-- Variables
+---------------------------------------------------
+-- Used by findglobals
+-- GLOBALS: _G, CreateFrame, DEFAULT_CHAT_FRAME
+
+-- Lua functions
+
+-- Wow functions
+
+-- constant vars
+
+---------------------------------------------------
+-- Manage events
+---------------------------------------------------
+A.EventsFrame = CreateFrame("Frame")
+
+local SCAN_DELAY = 0.2
+local t_throttle = SCAN_DELAY
+local function throttleScan(self, t_elapsed)
+	t_throttle = t_throttle - t_elapsed
+	if t_throttle<0 then
+		self:SetScript("OnUpdate", nil)
+
+		-- Close the external window if the tradeskill changed
+		if A.currentTradeSkill ~= GetTradeSkillLine() then
+			A.MenuFrame:Hide()
+		end
+		if IsTradeSkillGuild() or IsTradeSkillLinked() then
+			A.MenuFrame:Hide()
+			return
+		end
+
+		-- Scan availabe recipes
+		-- Rescan in case of problem
+		if not A:ScanSimpleRecipes() then
+			t_throttle = SCAN_DELAY
+			self:SetScript("OnUpdate", throttleScan)
+		end
+
+		-- Show makables reagents
+		A.updateCounts(GetTradeSkillSelectionIndex())
+	end
+end
+A.EventsFrame:SetScript("OnEvent", function(self, event)
+	A.ManageCampFireBtn()
+	if event == "TRADE_SKILL_UPDATE" then
+		t_throttle = SCAN_DELAY
+		self:SetScript("OnUpdate", throttleScan)
+
+	elseif event == "TRADE_SKILL_SHOW" then
+		A:Initialize()
+		A.EventsFrame:UnregisterEvent("TRADE_SKILL_SHOW")
+	end -- if
+end) -- function
+A.EventsFrame:RegisterEvent("TRADE_SKILL_SHOW")
+A.EventsFrame:RegisterEvent("TRADE_SKILL_UPDATE")
+A.EventsFrame:RegisterEvent("PLAYER_REGEN_ENABLED")
+A.EventsFrame:RegisterEvent("PLAYER_REGEN_DISABLED")
+
+---------------------------------------------------
+-- Initialize
+---------------------------------------------------
+function A:Initialize()
+
+	-- Register clics on reagent's buttons
+	for i=1,7 do
+		local btn = _G["TradeSkillReagent"..i]
+		btn:HookScript("OnDoubleClick", A.ProcessReagent)
+		btn:HookScript("OnEnter", A.btnEntered)
+		btn:HookScript("OnLeave", A.btnLeft)
+		btn.SplitStack = A.SplitStack
+
+		local textureHighlight = btn:CreateTexture()
+		textureHighlight:Hide()
+		textureHighlight:SetTexture("Interface\\BUTTONS\\CheckButtonHilight")
+		textureHighlight:SetBlendMode("ADD")
+		textureHighlight:SetAllPoints("TradeSkillReagent"..i.."IconTexture")
+		btn.textureHighlight = textureHighlight
+
+		local label = btn:CreateFontString(nil,"ARTWORK","GameFontHighlight")
+		label:SetSize(100,20)
+		label:SetPoint("TOPLEFT",btn,"TOPLEFT",4,-4)
+		label:SetJustifyH("LEFT")
+		label:SetJustifyV("TOP")
+		label:SetFont("Fonts\\FRIZQT__.TTF", 10, "OUTLINE")
+		btn.label = label
+	end -- for
+
+	-- Secondary Tooltip
+	A.tooltipRecipe = CreateFrame("GameTooltip", "ReagentMaker_tooltipRecipe",UIParent, "GameTooltipTemplate")
+	A.tooltipRecipe:SetFrameStrata("TOOLTIP")
+	A.tooltipRecipe:Hide()
+	
+	-- Button for enchanting directy on a scroll
+	A.LoadEnchantOnScroll()
+	
+	-- Button to cast a campfire
+	A.InitialiseCampFireBtn()
+end -- function
+
+-- Function run after selecting a item in the tradeskill window
+function A.ProcessReagent(btn, ...)
+
+	-- Do not manage guild tradeskill
+	if IsTradeSkillGuild() or IsTradeSkillLinked() then return end
+
+	-- We want no modifiers, or shift to choose the number of reagent to craft
+	if IsModifierKeyDown() and not IsShiftKeyDown() then return end
+	local chooseNumberToCraft = IsShiftKeyDown()
+
+	-- Index of the reagent in the recipe, taken from the button name
+	local reagentRecipeIndex = A.buttonNumber(btn)
+
+	-- ID of the reagent we want to craft
+	local recipeIndex = GetTradeSkillSelectionIndex()
+	local reagentID = A.link2ID(GetTradeSkillReagentItemLink(recipeIndex, reagentRecipeIndex))
+
+	-- Continue only if the reagent is known
+	if not reagentID or not A.data[reagentID] then return end
+
+	-- If only one recipe is known for the reagent, use it
+	if #(A.data[reagentID]) == 1 and not A.data[reagentID][1].macro then
+		if A.data[reagentID][1].spellName and A.data[reagentID][1].spellName ~= GetTradeSkillLine() then
+			A.Error(A.L["The recipe to make this reagent is in another tradeskill. Currently ReagentMaker can not manage such a case, sorry."])
+			return
+		end
+
+		local numMakable, reagentIndex = A.numMakable(reagentID)
+
+		-- Try to show the recipe by removing filters once if it was not found
+		if not reagentIndex then
+			A.SaveActiveFilters(A.data[reagentID][1].header)
+			numMakable, reagentIndex = A.numMakable(reagentID)
+		end
+
+		if not numMakable then
+			A.Error(A.L["The recipe to make the reagent seems to be hidden, it is not makable. Try to remove the filters on the recipes."])
+			return
+		end
+		if numMakable>0 then
+			A.craft(recipeIndex,reagentRecipeIndex,reagentIndex,numMakable,chooseNumberToCraft)
+			return
+		end
+
+		-- If we can make the item needed to make the reagent, open a window to make it
+		-- one step recursion, enables to mill to create an ink
+		if A.data[reagentID][1][1] and A.data[A.data[reagentID][1][1]] then
+			if A.externalCraftWindow(A.data[reagentID][1][1],reagentID) ~= false then
+				return
+			end
+		end
+
+		A.Error(A.L["You do not have enough reagents to craft [%s]"]:format(GetItemInfo(reagentID) or "item #"..reagentID))
+		return
+	else
+		A.externalCraftWindow(reagentID)
+	end -- if
+	--A.RestoreActiveFilters()
+end -- function
+
+
+---------------------------------------------------
+-- Craft items
+---------------------------------------------------
+-- function used after choosing the number of reagent to craft
+function A.SplitStack(owner,split)
+	DoTradeSkill(owner.ReagentMaker_reagentIndex,tonumber(split))
+	owner.ReagentMaker_reagentIndex = nil
+end
+
+-- Craft the reagent of an item, given it's position in the recipe
+function A.craft(recipeIndex,reagentRecipeIndex,reagentIndex,numReagentMakable,chooseNumber)
+	-- Look at how many we need to make one item for the selected recipe
+	local numToMake = 1
+	local _, _, reagentCount, playerReagentCount = GetTradeSkillReagentInfo(recipeIndex, reagentRecipeIndex)
+	-- make enough reagents to craft one more item
+	numToMake = math.min(math.floor(playerReagentCount/reagentCount+1)*reagentCount-playerReagentCount,numReagentMakable)
+
+	-- take into account that some recipe craft more than one item
+	-- use the mean between min and max, but make at least one...
+	local minMade, maxMade = GetTradeSkillNumMade(reagentIndex)
+	numToMake = math.max(math.floor(2*numToMake/(maxMade+minMade)),1)
+	
+	-- Choose number or craft directly
+	if chooseNumber then
+		-- the dialog window is linked to the reagent button
+		local btn = _G["TradeSkillReagent"..reagentRecipeIndex]
+
+		-- Store info to be able to run the function later
+		btn.ReagentMaker_reagentIndex = reagentIndex
+
+		-- Open dialog
+		OpenStackSplitFrame(numReagentMakable, btn, "TOP", "BOTTOM")
+
+		-- Fill in the number to make
+		numToMake = tostring(numToMake)
+		for i = 1,numToMake:len() do
+			StackSplitFrame_OnChar(StackSplitFrame,numToMake:gsub(i,i))
+		end
+		StackSplitFrame.typing = 0 -- reinit the frame so tha the entered value will be erased on text entry
+	else
+		DoTradeSkill(reagentIndex,numToMake)
+	end -- if
+end -- function
+
+
+-- Button hovering
+function A.btnEntered(btn)
+	-- Do not manage guild tradeskill
+	if IsTradeSkillGuild() or IsTradeSkillLinked() then return end
+
+	-- Index of the reagent in the recipe, taken from the button name
+	local reagentRecipeIndex = A.buttonNumber(btn)
+
+	-- ID of the reagent we want to craft
+	local reagentLink = GetTradeSkillReagentItemLink(GetTradeSkillSelectionIndex(), reagentRecipeIndex)
+	local reagentID = A.link2ID(reagentLink)
+
+	-- Continue only if the reagent is known
+	if not reagentID or not A.data[reagentID] then return end
+
+	btn.textureHighlight:Show()
+
+	-- Check if the item is made by only one recipe. If not, return
+	if not A.isRecipeUnique(A.data[reagentID]) then return end
+
+	-- Tooltips
+	local link = A.data[reagentID][1].spellLink
+	if link then
+		A.tooltipRecipe:SetOwner(btn)
+		A.tooltipRecipe:SetHyperlink(link)
+		A.tooltipRecipe:Show()
+		A.tooltipRecipe:ClearAllPoints()
+		A.tooltipRecipe:SetPoint("BOTTOMLEFT",GameTooltip,"BOTTOMRIGHT")
+	end
+end
+
+function A.btnLeft(btn)
+	btn.textureHighlight:Hide()
+	A.tooltipRecipe:Hide()
+end -- function
+
+function A.updateCounts(recipeIndex)
+	-- Needs an argument
+	if not recipeIndex then return end
+
+	-- Do not manage guild tradeskill
+	if IsTradeSkillGuild() or IsTradeSkillLinked() then
+		for reagentRecipeIndex = 1,GetTradeSkillNumReagents(recipeIndex) do
+			-- If the normal tradeskill hasn't been opened yet, the field 'label' doesn't exists yet
+			local label = _G["TradeSkillReagent"..reagentRecipeIndex].label
+			if label then
+				label:Hide()
+			end
+		end
+		return
+	end
+
+	-- Count makable items and show it
+	for reagentRecipeIndex = 1,GetTradeSkillNumReagents(recipeIndex) do
+		-- ID of the reagent we want to craft
+		local reagentLink = GetTradeSkillReagentItemLink(recipeIndex, reagentRecipeIndex)
+		local reagentID = A.link2ID(reagentLink)
+
+		local label = _G["TradeSkillReagent"..reagentRecipeIndex].label
+		if not label then break end -- Shouldn't happen...
+
+		-- Continue only if the reagent is known
+		if not reagentID or not A.data[reagentID] then
+			label:Hide()
+		else
+			-- Count and show
+			local numMakable = A.numMakable(reagentID)
+			if not numMakable or #(A.data[reagentID]) ~= 1 or A.data[reagentID][1].macro then
+				label:SetText("?")
+				label:SetTextColor(0, 0.5, 1, 1) -- blue
+			else
+				label:SetText(numMakable)
+				if numMakable==0 then
+					label:SetTextColor(1, 0, 0, 1) -- red
+				else
+					label:SetTextColor(0, 1, 0, 1) -- green
+				end
+			end -- if
+			label:Show()
+		end -- if
+	end -- for
+end -- function
+hooksecurefunc("SelectTradeSkill",A.updateCounts)