changeset 0:eba26c900e99

Initial commit, save state before using secure menus
author contrebasse
date Mon, 28 Mar 2011 22:32:26 +0200
parents
children 5fc29ed07094
files ReagentMaker.lua ReagentMaker.toc SecureMenu.lua data.lua utils.lua
diffstat 5 files changed, 451 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/ReagentMaker.lua	Mon Mar 28 22:32:26 2011 +0200
@@ -0,0 +1,231 @@
+local addonName, A = ...
+
+-- @todo clean the A table
+-- @todo check local copy of globals functions
+-- @todo add support for sub-recipes (like ink plus milling)
+-- @todo show a tooltip
+-- @todo show number of craftable items
+-- @todo show owned items
+-- @todo add support for dez ?
+-- @todo add support for cross tradeskill, like mining + forge/ingé
+-- @todo icon on reagent's button
+
+---------------------------------------------------
+-- Variables
+---------------------------------------------------
+-- Used by findglobals
+-- GLOBALS: _G, CreateFrame, DEFAULT_CHAT_FRAME
+
+-- Lua functions
+
+-- Wow functions
+
+-- constant vars
+
+---------------------------------------------------
+-- Manage events
+---------------------------------------------------
+A.EventsFrame = CreateFrame("Frame")
+
+A.EventsFrame:SetScript("OnEvent", function(self, event)
+	if event == "TRADE_SKILL_SHOW" then
+		A:Initialize()
+	end -- if
+end); -- function
+A.EventsFrame:RegisterEvent("TRADE_SKILL_SHOW")
+
+
+---------------------------------------------------
+-- Initialize
+---------------------------------------------------
+function A:Initialize()
+	-- This part is done the first time only
+	if not self.MenuFrame then
+	-- Prepare the menu
+		self.MenuFrame = CreateFrame("Frame", "ReagentMakerDropDownMenu"); -- Needs a global name
+		self.MenuFrame.displayMode = "MENU";
+		self.MenuFrame.initialize = self.FillMenu;
+		self.MenuFrame.point = "TOPLEFT";
+		self.MenuFrame.relativePoint = "TOPRIGHT";
+
+		-- Register clics on reagent's buttons
+		for i=1,7 do
+			local button = _G["TradeSkillReagent"..i];
+			button:HookScript("OnClick", function() self:ToggleMenu(button, i) end);
+			--button:HookScript("OnEnter", function() self:Entered(button, i) end)
+			--button:HookScript("OnLeave", function() self:Left(button, i) end)
+		end -- for
+	end -- if
+
+	-- Scan availabe recipes
+	A:ScanSimpleRecipes()
+end -- function
+
+
+---------------------------------------------------
+-- Craft items
+---------------------------------------------------
+do
+	-- WoW functions
+	local GetNumTradeSkills = GetNumTradeSkills
+	local GetTradeSkillInfo = GetTradeSkillInfo
+	local GetTradeSkillItemLink = GetTradeSkillItemLink
+
+
+	function A.findSkillIndex(itemID)
+		for i = 1,GetNumTradeSkills() do
+			local skillName, skillType, numAvailable, isExpanded, serviceType, numSkillUps = GetTradeSkillInfo(i)
+			if skillType == "header" then
+			else
+				if skillName then
+					local ID = A.link2ID(GetTradeSkillItemLink(i))
+					if ID and ID == itemID then
+						return i
+					end -- if
+				end -- if
+			end -- if
+		end -- for
+		A.DEBUG("Tradeskill not found")
+	end -- function
+end -- do
+
+
+-- http://www.wowwiki.com/RunSlashCmd
+local _G = _G
+function RunSlashCmd(cmd)
+  local slash, rest = cmd:match("^(%S+)%s*(.-)$")
+  for name, func in pairs(SlashCmdList) do
+     local i, slashCmd = 1
+     repeat
+        slashCmd, i = _G["SLASH_"..name..i], i + 1
+        if slashCmd == slash then
+				A.DEBUG("Spell found !")
+           return true, func(rest)
+        end
+     until not slashCmd
+  end
+A.DEBUG("Spell not found :(")
+end
+
+do
+	-- WoW functions
+	local DoTradeSkill = DoTradeSkill
+
+	local function SplitStack(owner,split)
+		DoTradeSkill(owner.ReagentMakerIndex,tonumber(split))
+	end
+
+	function A.craft(self,itemID, spell)
+		-- self is the menu entry
+		if spell then
+			CastSpellByName("Mouture")
+			RunSlashCmd(spell) --CastSpellByName(spell)
+			--RunSlashCmd("/use "..itemID) --CastSpellByName("/use "..itemID)
+			return
+		end
+		local index = A.findSkillIndex(itemID)
+		if index then
+			local skillName, skillType, numAvailable, isExpanded, serviceType, numSkillUps = GetTradeSkillInfo(index)
+			if IsShiftKeyDown() and numAvailable>1 and not spell then
+				if not self.SplitStack then
+					self.SplitStack = SplitStack
+				end
+				self.ReagentMakerIndex = index
+
+				OpenStackSplitFrame(numAvailable, self, "TOPLEFT", "TOPRIGHT")
+			else
+				DoTradeSkill(index,1)
+			end
+		end
+	end -- function
+end -- do
+
+
+---------------------------------------------------
+-- Manage the popup menu
+---------------------------------------------------
+do
+	-- Lua functions
+	local tonumber = tonumber
+
+	-- WoW functions
+	local IsModifierKeyDown = IsModifierKeyDown
+	local GetTradeSkillReagentItemLink = GetTradeSkillReagentItemLink
+	local GetTradeSkillSelectionIndex = GetTradeSkillSelectionIndex
+	local ToggleDropDownMenu = ToggleDropDownMenu
+
+	-- Toggles the reagent's menu
+	function A:ToggleMenu(button, index)
+		-- We want no modifiers
+		if IsModifierKeyDown() then return end
+
+		local itemID = A.link2ID(GetTradeSkillReagentItemLink(GetTradeSkillSelectionIndex(), index))
+		if itemID and A.data[itemID] then
+			self.MenuFrame.ReagentMakerItemID = itemID
+			ToggleDropDownMenu(1, nil, A.MenuFrame, button,-4,0)
+		end -- if
+	end -- function
+end -- do
+
+do
+	-- Lua functions
+	local type = type
+
+	-- Wow functions
+	local GetItemInfo = GetItemInfo
+	local UIDropDownMenu_AddButton = UIDropDownMenu_AddButton
+
+	-- persistent vars
+	local Minfo = {notCheckable = true, func = A.craft}
+	local Tinfo = {notCheckable = true, isTitle = true}
+
+	-- function to define the menu items
+	function A.FillMenu(self, level)
+		-- Title
+		local itemName, link, quality, iLevel, reqLevel, class, subclass, maxStack, equipSlot, texture, vendorPrice = GetItemInfo(self.ReagentMakerItemID)
+		Tinfo.text = "Make "..link.." with:"
+		UIDropDownMenu_AddButton(Tinfo,level)
+
+		-- Loop over the availible reciepes
+		for spellID,reagents in pairs(A.data[self.ReagentMakerItemID]) do
+			--name, link, quality, iLevel, reqLevel, class, subclass, maxStack, equipSlot, texture, vendorPrice = GetItemInfo(itemID) or GetItemInfo("itemName") or GetItemInfo("itemLink")
+			-- Right now, manage only sub-recipes with only one reagent
+			if type(reagents[1]) == "number" then
+				local name, link, quality, iLevel, reqLevel, class, subclass, maxStack, equipSlot, texture, vendorPrice = GetItemInfo(reagents[1])
+
+				if link then
+					Minfo.text = "|T"..texture..":0|t "..link
+					if #reagents>1 and reagents[2] > 1 then
+						Minfo.text = reagents[2].."x "..Minfo.text
+					end -- if
+
+					--if reagents.spell then
+					--	Minfo.func = RunMacroText
+					--	Minfo.arg1 = reagents.spell..itemName
+					--	Minfo.arg2 = nil
+					--else
+						Minfo.func = A.craft
+						Minfo.arg1 = self.ReagentMakerItemID
+						Minfo.arg2 = reagents.spell
+					--end -- if
+					UIDropDownMenu_AddButton(Minfo,level)
+				else
+					A.DEBUG("Erreur, objet inconnu :"..reagents[1])
+				end -- if
+			end -- if
+		end -- for
+	end -- function
+end -- do
+
+
+---------------------------------------------------
+-- Manage the tradeskill window state
+---------------------------------------------------
+function A:SaveState()
+end
+
+function A:SetState(state)
+end
+
+function A:ExpandAll()
+end
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/ReagentMaker.toc	Mon Mar 28 22:32:26 2011 +0200
@@ -0,0 +1,9 @@
+## Interface: 40000
+## Title: ReagentMaker
+## Author: Nodd
+## Version: 0.1
+## Notes: Creates reagents easily
+
+utils.lua
+data.lua
+ReagentMaker.lua
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/SecureMenu.lua	Mon Mar 28 22:32:26 2011 +0200
@@ -0,0 +1,76 @@
+local addonName, A = ...
+
+-- Create the menu frame
+local MenuFrame = CreateFrame("Frame",nil,UIParent) --, "ReagentMakerDropDownMenu"); -- Needs a global name
+MenuFrame:Hide()
+MenuFrame:SetBackdrop({
+	bgFile = "Interface\\DialogFrame\\UI-DialogBox-Gold-Background",  -- path to the background texture
+	edgeFile = "Interface\\DialogFrame\\UI-DialogBox-Gold-Border",    -- path to the border texture
+	tile = true,      -- true to repeat the background texture to fill the frame, false to scale it
+	tileSize = 32,    -- size (width or height) of the square repeating background tiles (in pixels)
+	edgeSize = 32,    -- thickness of edge segments and square size of edge corners (in pixels)
+	insets = {        -- distance from the edges of the frame to those of the background texture (in pixels)
+		left = 11,
+		right = 12,
+		top = 12,
+		bottom = 11
+	}
+})
+local numActiveEntries = 0
+local menuEntries = {}
+
+function A.menuOpen()
+	if not InCombatLockDown() and numActiveEntries>0 then
+		MenuFrame:Show()
+	end
+end
+function A.menuClose()
+	MenuFrame:Hide()
+	MenuFrame:ClearAllPoints()
+
+	for i=1,numActiveEntries do
+		menuEntries[i]:Hide()
+	end
+end
+
+function A.menuAddItem(text,action,itemID)
+	local btn
+	-- Create a button only if necessary
+	if numActiveEntries >= #menuEntries then
+		btn = CreateFrame("Button", nil, MenuFrame, "SecureActionButtonTemplate")
+		table.insert(menuEntries,btn)
+
+		btn:SetHeight(12)
+
+		-- Set its position
+		if #menuEntries==1 then
+			btn:SetPoint("TOPLEFT",MenuFrame,"TOPLEFT",0,0)
+		else
+			btn:SetPoint("TOPLEFT",menuEntries[#menuEntries-1],"BOTTOMLEFT",0,0)
+		end
+	else
+		btn = menuEntries[numActiveEntries+1]
+	end
+
+	-- Set its text
+	btn:SetText(text or " ")
+
+	-- Set its action
+	if type(action)=="function" then
+		btn:SetScript("OnClick",action)
+		btn:SetAttribute("type", nil)
+		btn:SetAttribute("spell", nil)
+		btn:SetAttribute("target-item",nil)
+	elseif type(action)=="string" then
+		btn:SetScript("OnClick",nil)
+		btn:SetAttribute("type", "spell")
+		btn:SetAttribute("spell", action)
+		btn:SetAttribute("target-item",GetItemInfo(itemID))
+	end -- if
+
+	-- Reposition MenuFrame
+	MenuFrame:SetPoint("BOTTOMRIGHT",btn,"BOTTOMRIGHT",0,0)
+
+	-- Increase she entry number
+	numActiveEntries = numActiveEntries + 1
+end -- function
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/data.lua	Mon Mar 28 22:32:26 2011 +0200
@@ -0,0 +1,114 @@
+local addonName, A = ...
+
+
+A.Mill = "/use "..GetSpellInfo(51005)
+A.data = {
+	-- Mill
+	[39151] = { -- Alabaster Pigment
+		{2447,5, spell = A.Mill}, -- Peacebloom
+		{765,5, spell = A.Mill},  -- Silverleaf
+		{2449,5, spell = A.Mill}}, -- Earthroot
+	[39224] = { -- Dusky Pigment
+		{785,5, spell = A.Mill},  -- Mageroyal
+		{2450,5, spell = A.Mill}, -- Briarthorn
+		{2452,5, spell = A.Mill}, -- Swiftthistle
+		{2453,5, spell = A.Mill}, -- Bruiseweed
+		{3820,5, spell = A.Mill}}, -- Stranglekelp
+	[39338] = { -- Golden Pigment
+		{3369,5, spell = A.Mill}, -- Grave Moss
+		{3355,5, spell = A.Mill}, -- Wild Steelbloom
+		{3356,5, spell = A.Mill}, -- Kingsblood
+		{3357,5, spell = A.Mill}}, -- Liferoot
+	[39339] = { -- Emerald Pigment
+		{3818,5, spell = A.Mill}, -- Fadeleaf
+		{3821,5, spell = A.Mill}, -- Goldthorn
+		{3358,5, spell = A.Mill}, -- Khadgar's Whisker
+		{3819,5, spell = A.Mill}}, -- Dragon's Teeth
+	[39340] = { -- Violet Pigment
+		{4625,5, spell = A.Mill}, -- Firebloom
+		{8831,5, spell = A.Mill}, -- Purple Lotus
+		{8836,5, spell = A.Mill}, -- Arthas' Tears
+		{8838,5, spell = A.Mill}, -- Sungrass
+		{8839,5, spell = A.Mill}, -- Blindweed
+		{8845,5, spell = A.Mill}, -- Ghost Mushroom
+		{8846,5, spell = A.Mill}}, -- Gromsblood
+	[39341] = { -- Silvery Pigment
+		{13464,5, spell = A.Mill}, -- Golden Sansam
+		{13463,5, spell = A.Mill}, -- Dreamfoil
+		{13465,5, spell = A.Mill}, -- Mountain Silversage
+		{13466,5, spell = A.Mill}, -- Sorrowmoss
+		{13467,5, spell = A.Mill}}, -- Icecap
+	[39342] = { -- Nether Pigment
+		{22786,5, spell = A.Mill}, -- Dreaming Glory
+		{22785,5, spell = A.Mill}, -- Felweed
+		{22789,5, spell = A.Mill}, -- Terocone
+		{22787,5, spell = A.Mill}, -- Ragveil
+		{22790,5, spell = A.Mill}, -- Ancient Lichen
+		{22793,5, spell = A.Mill}, -- Mana Thistle
+		{22791,5, spell = A.Mill}, -- Netherbloom
+		{22792,5, spell = A.Mill}}, -- Nightmare Vine
+	[39343] = { -- Azure Pigment
+		{37921,5, spell = A.Mill}, -- Deadnettle
+		{36901,5, spell = A.Mill}, -- Goldclover
+		{36907,5, spell = A.Mill}, -- Talandra's Rose
+		{36904,5, spell = A.Mill}, -- Tiger Lily
+		{39970,5, spell = A.Mill}, -- Fire Leaf
+		{39969,5, spell = A.Mill}, -- Fire Seed
+		{36903,5, spell = A.Mill}, -- Fire Seed
+		{36906,5, spell = A.Mill}, -- Icethorn
+		{36905,5, spell = A.Mill}}, -- Icethorn
+	[61979] = { -- Ashen Pigment
+		{52983,5, spell = A.Mill}, -- Cinderbloom
+		{52985,5, spell = A.Mill}, -- Azshara's Veil
+		{52984,5, spell = A.Mill}, -- Stormvine
+		{52986,5, spell = A.Mill}, -- Heartblossom
+		{52988,5, spell = A.Mill}, -- Whiptail
+		{52987,5, spell = A.Mill}}, -- Twilight Jasmine
+
+	-- To add : pigments, enchants, elementals
+}
+A.data[43103] = A.data[39224] -- Verdant Pigment
+A.data[43104] = A.data[39338] -- Burnt Pigment
+A.data[43105] = A.data[39339] -- Indigo Pigment
+A.data[43106] = A.data[39340] -- Ruby Pigment
+A.data[43107] = A.data[39341] -- Sapphire Pigment
+A.data[43108] = A.data[39342] -- Ebon Pigment
+A.data[43109] = A.data[39343] -- Icy Pigment
+A.data[61980] = A.data[61979] -- Burning Embers
+
+
+-- @todo improve scanning
+-- @todo rescan when a new refipe appears (TRADESKILL_UPDATE ?)
+-- @todo be sure that skillName is unique, or use something else
+-- @todo add support for multi-reagents recipes
+local sfind = string.find
+function A:ScanSimpleRecipes()
+	for i = 1,GetNumTradeSkills() do
+		local skillName, skillType, numAvailable, isExpanded, serviceType, numSkillUps = GetTradeSkillInfo(i)
+		if skillType ~= "header" then
+			if GetTradeSkillNumReagents(i) == 1 then
+				-- item ID
+				local itemID = A.link2ID(GetTradeSkillItemLink(i))
+
+				-- reagent ID
+				local link = GetTradeSkillReagentItemLink(i, 1)
+				local reagentID = A.link2ID(link)
+
+				-- reagent number needed
+				local reagentName, reagentTexture, reagentCount, playerReagentCount = GetTradeSkillReagentInfo(i, 1)
+
+				-- skillName or...???
+				if not reagentID or not reagentCount or not skillName or not itemID then
+					A.DEBUG("Erreur de scan :")
+					print(itemID," ",skillName," ",reagentID," ",reagentCount)
+				end
+
+				if not A.data[itemID] or not A.data[itemID][skillName] then
+					A.data[itemID] = {[skillName] = {reagentID,reagentCount}}
+				end
+			else
+			end -- if
+		end -- if
+	end -- for
+
+end
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/utils.lua	Mon Mar 28 22:32:26 2011 +0200
@@ -0,0 +1,21 @@
+local addonName, A = ...
+
+do
+	-- WoW frames
+	local DEFAULT_CHAT_FRAME = DEFAULT_CHAT_FRAME
+
+	function A.DEBUG(msg)
+		DEFAULT_CHAT_FRAME:AddMessage(msg or "nil",1,0,0)
+	end -- function
+end
+
+do
+	-- Lua functions
+	local select = select
+	local tonumber = tonumber
+	local sfind = string.find
+
+	function A.link2ID(link)
+		return tonumber(select(3,sfind(link or "", "-*:(%d+)[:|].*")) or "")
+	end -- function
+end -- do