view ReagentMaker.lua @ 46:40d6886d1966

Correct the number of items to craft (the formulae was wrong and has to take the number of item crafted into account)
author contrebasse
date Sat, 30 Apr 2011 01:31:19 +0200
parents 00c2282f073a
children 512660b07eda
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é

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