view ReagentMaker.lua @ 50:67845ab152ce

Playing with .pkgmeta
author contrebasse
date Mon, 09 May 2011 22:43:51 +0200
parents 512660b07eda
children 60871b43531d
line wrap: on
line source
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 use milling and prospecting for chars that really know them
-- @todo show a #, * or ? for item makable by milling or prospecting (hard to know how many are craftables)
-- @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

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

	A.tooltipRecipe = CreateFrame("GameTooltip", "ReagentMaker_tooltipRecipe",UIParent, "GameTooltipTemplate")
	A.tooltipRecipe:SetFrameStrata("TOOLTIP")
	A.tooltipRecipe:Hide()
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()

	--A.SaveActiveFilters()

	-- 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].spell then
		local numMakable, reagentIndex = A.numMakable(reagentID)
		if not numMakable then
			A.Error("The recipe to make the reagent seems to be hidden, it is not makable.")
			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 (not A.data[reagentID].manyReagents) and A.data[A.data[reagentID][1][1]] then
			A.externalCraftWindow(A.data[reagentID][1][1],reagentID)
		else
			A.Error("You do not have enough reagents to craft ["..(GetItemInfo(reagentID) or "item #"..reagentID).."]")
		end
		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()

	-- Tooltips
	local link = A.data[reagentID].spellLink
	if link then
		A.tooltipRecipe:SetOwner(btn)
		A.tooltipRecipe:SetHyperlink(link)
		A.tooltipRecipe:Show()
		A.tooltipRecipe:ClearAllPoints()
		A.tooltipRecipe:SetPoint("BOTTOMLEFT",GameTooltip,"BOTTOMRIGHT")
	else
		-- Shouldn't happend, but just in case...
		A.Error("Recipe link not found for "..reagentID)
	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
			_G["TradeSkillReagent"..reagentRecipeIndex].label:Hide()
		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 return end

		-- Continue only if the reagent is known
		if not reagentID or not A.data[reagentID] or #(A.data[reagentID]) ~= 1 or A.data[reagentID].spell then
			label:Hide()
		else
			-- Count and show
			local numMakable = A.numMakable(reagentID)
			label:SetText(numMakable or "?")
			if not numMakable or numMakable==0 then
				label:SetTextColor(1, 0, 0, 1)
			else
				label:SetTextColor(0, 5, 0, 1)
			end -- if
			label:Show()
		end -- if
	end -- for
end -- function
hooksecurefunc("SelectTradeSkill",A.updateCounts)