view ReagentMaker.lua @ 103:c8d527a9fb3a v1.0beta11

Better manage combat and secure buttons
author contrebasse
date Sat, 21 May 2011 14:19:33 +0200
parents 060f5d0f7a35
children d64a19e5a47d
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 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)
		A.ManageCampFireBtn()

	elseif event == "PLAYER_REGEN_DISABLED" then
		A.HideCampFireBtn()
	elseif event == "PLAYER_REGEN_ENABLED" then
		A.ManageCampFireBtn()

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