Quantcast

Removed calls to modify original tradeskill frame's position.

pschifferer [12-05-09 - 17:29]
Removed calls to modify original tradeskill frame's position.
Fixed some issues with storing reagent information in the character's local store.
Fixed an issue when enabling/disabling the create* buttons when selecting a skill.
Changed the 'logging' (alpha-only) slash-command option to 'debug' and made it a toggle.
Changed some locale strings.  Changed the wording when acquiring intermediate items to specify that items are remaining instead of "X/Y", which seemed to imply that Y was the total value, when it's really what's left.
Added callbacks for spellcasting (start, stop, interrupt, and success) and made the queue update react to the spell success in order to update the queue count.  I think this will be more reliable than reacting to bag updates.
Cleaned up the formatting of some logging calls (alpha-only).
Filename
CauldronMain.lua
CauldronMainUI.lua
CauldronTradeskill.lua
Locale/Cauldron-enUS.lua
Locale/Cauldron-ruRU.lua
diff --git a/CauldronMain.lua b/CauldronMain.lua
index dedf76d..e3d8b2a 100644
--- a/CauldronMain.lua
+++ b/CauldronMain.lua
@@ -77,17 +77,14 @@ function Cauldron:OnInitialize()
 				func = function() self:DisplayVersion() end,
 			},
 			--@alpha@
-			logging = {
-				name = L["Logging"],
-				desc = L["Sets or displays the logging level"],
-				type = 'select',
-				values = {
-					normal = L["Normal logging of warnings and errors"],
-					debug = L["Debug logging (very verbose)"],
-				},
-				get = function() Cauldron:Print(Cauldron:GetLogLevel()); end,
-				set = function(l)
-						if l == "debug" then
+			debug = {
+				name = L["Debug"],
+				desc = L["Toggles whether Cauldron displays debug messages"],
+				type = 'toggle',
+				get = function() return Cauldron:GetLogLevel(); end,
+				set = function(val)
+						self:info("val: "..tostring(val));
+						if val == "debug" then
 							Cauldron:SetLogLevel(Cauldron.logLevels.DEBUG);
 						else
 							Cauldron:SetLogLevel(Cauldron.logLevels.INFO);
@@ -98,9 +95,17 @@ function Cauldron:OnInitialize()
 			--[[
 			forget = {
 				name = L["Forget"],
-				desc = L["Tells Cauldron to a fresh state"],
-				type = 'execute',
-				func = function() self:Forget() end,
+				desc = L["Tells Cauldron to forget information for a character, recipe, or skill"],
+				type = 'input',
+--				get = function() return; end,
+				set = function(info, v)
+						Cauldron:Forget(v);
+					end,
+				usage = L["forget [skill <name>||recipe <name>]"],
+				validate = function(val)
+					end,
+				confirm = L["Forget skills for this character?"],
+--				func = function() self:Forget(arg1) end,
 			},
 			--]]
 			reset = {
@@ -137,13 +142,13 @@ function Cauldron:OnInitialize()
 	--@end-alpha@

 	-- let the user know the addon is loaded
-	self:Print(L["Cauldron loaded; version "],Cauldron.version);
+	self:Print(L["Cauldron loaded; version"],Cauldron.version);
 end

 function Cauldron:InitPlayer()
---@alpha@
+	--@alpha@
 	self:debug("InitPlayer enter");
---@end-alpha@
+	--@end-alpha@

 	if not self.vars.playername then
 		self.vars.playername = UnitName("player");
@@ -233,15 +238,15 @@ function Cauldron:InitPlayer()
 		self.db.realm.userdata[self.vars.playername].reagentMap = nil;
 	end

---@alpha@
+	--@alpha@
 	self:debug("InitPlayer exit");
---@end-alpha@
+	--@end-alpha@
 end

 function Cauldron:OnEnable()
---@alpha@
+	--@alpha@
 	self:debug("OnEnable enter");
---@end-alpha@
+	--@end-alpha@

 	-- set init flag, for some callbacks
 	self.initializing = true;
@@ -278,6 +283,10 @@ function Cauldron:OnEnable()
 	self:RegisterEvent("UI_ERROR_MESSAGE", "OnError");
 	self:RegisterEvent("UNIT_QUEST_LOG_CHANGED", "OnQuestLogChanged");
 	self:RegisterEvent("ACHIEVEMENT_EARNED", "OnAchievementEarned");
+	self:RegisterEvent("UNIT_SPELLCAST_START", "OnSpellcastStart");
+	self:RegisterEvent("UNIT_SPELLCAST_STOP", "OnSpellcastStop");
+	self:RegisterEvent("UNIT_SPELLCAST_SUCCEEDED", "OnSpellcastSucceed");
+	self:RegisterEvent("UNIT_SPELLCAST_INTERRUPTED", "OnSpellcastInterrupt");

 	-- setup hooks for tooltips
 	self:HookTooltips();
@@ -288,25 +297,25 @@ function Cauldron:OnEnable()
 	-- clear init flag
 	self.initializing = false;

---@alpha@
+	--@alpha@
 	self:debug("OnEnable exit");
---@end-alpha@
+	--@end-alpha@
 end

 function Cauldron:OnDisable()
---@alpha@
+	--@alpha@
 	self:debug("OnDisable enter");
---@end-alpha@
+	--@end-alpha@

---@alpha@
+	--@alpha@
 	self:debug("OnDisable exit");
---@end-alpha@
+	--@end-alpha@
 end

 function Cauldron:OnAddonLoaded(event, addon)
---@alpha@
+	--@alpha@
 	self:debug("OnAddonLoaded enter");
---@end-alpha@
+	--@end-alpha@

 	-- show the shopping list?
 	if self.db.profile.showShoppingList then
@@ -317,26 +326,26 @@ function Cauldron:OnAddonLoaded(event, addon)
 		end
 	end

---@alpha@
+	--@alpha@
 	self:debug("OnAddonLoaded exit");
---@end-alpha@
+	--@end-alpha@
 end

 function Cauldron:OnEvent(event, ...)
---@alpha@
+	--@alpha@
 	self:debug("OnEvent enter");
---@end-alpha@
+	--@end-alpha@

-	if ( event == "UNIT_PORTRAIT_UPDATE" ) then
+	if event == "UNIT_PORTRAIT_UPDATE" then
 		local arg1 = ...;
-		if ( arg1 == "player" ) then
+		if arg1 == "player" then
 			SetPortraitTexture(CauldronFramePortrait, "player");
 		end
 	end

---@alpha@
+	--@alpha@
 	self:debug("OnEvent exit");
---@end-alpha@
+	--@end-alpha@
 end

 function Cauldron:OnTradeShow()
@@ -367,30 +376,21 @@ function Cauldron:OnTradeUpdate()
 end

 function Cauldron:OnTradeClose()
---@alpha@
+	--@alpha@
 	self:debug("OnTradeClose enter");
---@end-alpha@
+	--@end-alpha@

 	self:Frame_Hide();

---@alpha@
+	--@alpha@
 	self:debug("OnTradeClose exit");
---@end-alpha@
+	--@end-alpha@
 end

-function Cauldron:OnSkillUpdate()
---@alpha@
+function Cauldron:OnSkillUpdate(event, arg1, arg2)
+	--@alpha@
 	self:debug("OnSkillUpdate enter");
---@end-alpha@
-
---	self:UpdateSkills();
---	self:UpdateSpecializations();
-
---	if not IsTradeSkillLinked() then
---		if (GetTradeSkillLine() ~= "UNKNOWN") then
---			self:ScheduleTimer(self.UpdateKnownRecipes, 1, self);
---		end
---	end
+	--@end-alpha@

 	if CURRENT_TRADESKILL ~= "" then
 		if not Cauldron.db.realm.userdata[Cauldron.vars.playername].skills[CURRENT_TRADESKILL] then
@@ -410,15 +410,15 @@ function Cauldron:OnSkillUpdate()

 	self:Frame_Update();

---@alpha@
+	--@alpha@
 	self:debug("OnSkillUpdate exit");
---@end-alpha@
+	--@end-alpha@
 end

 function Cauldron:OnTradeSkillRecast()
---@alpha@
+	--@alpha@
 	self:debug("OnTradeSkillRecast enter");
---@end-alpha@
+	--@end-alpha@

 	-- keep the processing flag set
 	self.processing = true;
@@ -429,9 +429,9 @@ function Cauldron:OnTradeSkillRecast()

 	self:Frame_Update();

---@alpha@
+	--@alpha@
 	self:debug("OnTradeSkillRecast exit");
---@end-alpha@
+	--@end-alpha@
 end

 function Cauldron:OnBagUpdate(event, bagid)
@@ -475,7 +475,7 @@ function Cauldron:OnBagUpdate(event, bagid)

 				local counts = Cauldron:ReagentCount(item);
 				local amount = math.min(counts.has, intItem.amount);
-				local str = string.format("%s: %s: %d/%d", L["Intermediate"], item, amount, intItem.amount);
+				local str = string.format("%s: %s: %d, %d %s", L["Intermediate"], item, amount, intItem.amount, L["remaining"]);
 				if (counts.has - itemCount) < intItem.amount then
 					UIErrorsFrame:AddMessage(str, 0.0, 0.9, 0.4, 86, 3);
 				end
@@ -485,21 +485,11 @@ function Cauldron:OnBagUpdate(event, bagid)
 					local counts = Cauldron:ReagentCount(item);
 					local amount = math.min(counts.has, rItem.amount);
 					local str = string.format("%s: %s: %d/%d", L["Reagent"], item, amount, rItem.amount);
-					if (counts.has - itemCount) <= rItem.amount then
+					if (counts.has - itemCount) < rItem.amount then
 						UIErrorsFrame:AddMessage(str, 0.0, 0.9, 0.0, 86, 3);
 					end
 				end
 			end
-
-			-- adjust queue, but only if window is open
-			self:debug("adjust queue? item="..item);
-			if CauldronFrame:IsShown() then
-				self:debug("window is open; self.makingItem="..tostring(self.makingItem));
-				if self.makingItem == item then
-					self:debug("OnBagUpdate: adjust queue for item: "..self.makingItem.."; itemCount="..itemCount);
-					CauldronQueue:AdjustItemCount(queue, item, -itemCount);
-				end
-			end
 		end
 	end

@@ -547,33 +537,33 @@ function Cauldron:OnBagUpdate(event, bagid)
 end

 function Cauldron:OnCraftShow()
---@alpha@
+	--@alpha@
 	self:debug("OnCraftShow enter");
---@end-alpha@
+	--@end-alpha@

 --	TODO

---@alpha@
+	--@alpha@
 	self:debug("OnCraftShow exit");
---@end-alpha@
+	--@end-alpha@
 end

 function Cauldron:OnCraftClose()
---@alpha@
+	--@alpha@
 	self:debug("OnCraftClose enter");
---@end-alpha@
+	--@end-alpha@

 --	TODO

---@alpha@
+	--@alpha@
 	self:debug("OnCraftClose exit");
---@end-alpha@
+	--@end-alpha@
 end

 function Cauldron:OnMerchantShow()
---@alpha@
+	--@alpha@
 	self:debug("OnMerchantShow enter");
---@end-alpha@
+	--@end-alpha@

 	-- check if there's anything in the shopping list
 	if CauldronShopping:ContainsItems(Cauldron.db.realm.shopping) then
@@ -584,108 +574,187 @@ function Cauldron:OnMerchantShow()
 		end
 	end

---@alpha@
+	--@alpha@
 	self:debug("OnMerchantShow exit");
---@end-alpha@
+	--@end-alpha@
 end

 function Cauldron:OnMerchantClose()
---@alpha@
+	--@alpha@
 	self:debug("OnMerchantClose enter");
---@end-alpha@
+	--@end-alpha@

 	if not CauldronShopping:ContainsItems(Cauldron.db.realm.shopping) then
 		Cauldron:HideShoppingList();
 	end

---@alpha@
+	--@alpha@
 	self:debug("OnMerchantClose exit");
---@end-alpha@
+	--@end-alpha@
 end

 function Cauldron:OnBankOpened()
---@alpha@
+	--@alpha@
 	self:debug("OnBankOpened enter");
---@end-alpha@
+	--@end-alpha@

 	-- check if there's anything in the shopping list
 	if CauldronShopping:ContainsItems(Cauldron.db.realm.shopping) then
 		Cauldron:ShowShoppingList();
 	end

---@alpha@
+	--@alpha@
 	self:debug("OnBankOpened exit");
---@end-alpha@
+	--@end-alpha@
 end

 function Cauldron:OnBankClosed()
---@alpha@
+	--@alpha@
 	self:debug("OnBankClosed enter");
---@end-alpha@
+	--@end-alpha@

 	if not CauldronShopping:ContainsItems(Cauldron.db.realm.shopping) then
 		Cauldron:HideShoppingList();
 	end

---@alpha@
+	--@alpha@
 	self:debug("OnBankClosed exit");
---@end-alpha@
+	--@end-alpha@
 end

 function Cauldron:OnQuestLogChanged()
---@alpha@
+	--@alpha@
 	self:debug("OnQuestLogChanged enter");
---@end-alpha@
+	--@end-alpha@

 	-- TODO

---@alpha@
+	--@alpha@
 	self:debug("OnQuestLogChanged exit");
---@end-alpha@
+	--@end-alpha@
 end

 function Cauldron:OnAchievementEarned()
---@alpha@
+	--@alpha@
 	self:debug("OnAchievementEarned enter");
---@end-alpha@
+	--@end-alpha@

 	-- update the achievement skill map
 	Cauldron:CreateAchievementSkillMap();
 	Cauldron:UpdateSkillList();

---@alpha@
+	--@alpha@
 	self:debug("OnAchievementEarned exit");
---@end-alpha@
+	--@end-alpha@
+end
+
+function Cauldron:OnSpellcastStart(event, unit, spell, rank)
+	--@alpha@
+	self:debug("OnSpellcastStart enter");
+	--@end-alpha@
+
+-- self:info("spell start - unit: "..tostring(unit).."; spell: "..tostring(spell).."; rank: "..tostring(rank));
+
+	self.processing = true;
+
+	--@alpha@
+	self:debug("OnSpellcastStart exit");
+	--@end-alpha@
+end
+
+function Cauldron:OnSpellcastStop(event, unit, spell, rank)
+	--@alpha@
+	self:debug("OnSpellcastStop enter");
+	--@end-alpha@
+
+-- self:info("spell stop - unit: "..tostring(unit).."; spell: "..tostring(spell).."; rank: "..tostring(rank));
+
+	self.processing = false;
+
+	--@alpha@
+	self:debug("OnSpellcastStop exit");
+	--@end-alpha@
+end
+
+function Cauldron:OnSpellcastSucceed(event, unit, spell, rank)
+	--@alpha@
+	self:debug("OnSpellcastSucceed enter");
+	--@end-alpha@
+
+-- self:info("spell succeed - unit: "..tostring(unit).."; spell: "..tostring(spell).."; rank: "..tostring(rank));
+
+	-- ignore if the unit was not the player
+	if unit ~= "player" then
+		return;
+	end
+
+	local queue = self.db.realm.userdata[self.vars.playername].queue;
+
+	-- adjust queue, but only if window is open
+	--@alpha@
+	self:debug("adjust queue? spell="..spell);
+	--@end-alpha@
+	if CauldronFrame:IsShown() then
+		--@alpha@
+		self:debug("window is open; self.makingItemSpell="..tostring(self.makingItemSpell));
+		--@end-alpha@
+		if self.makingItemSpell == spell then
+			self.processing = false;
+
+			--@alpha@
+			self:debug("OnBagUpdate: adjust queue for item: "..self.makingItem.."; itemCount="..self.makingItemCount);
+			--@end-alpha@
+			CauldronQueue:AdjustItemCount(queue, self.makingItem, -1);
+		end
+	end
+
+	--@alpha@
+	self:debug("OnSpellcastSucceed exit");
+	--@end-alpha@
+end
+
+function Cauldron:OnSpellcastInterrupt(event, unit, spell, rank)
+	--@alpha@
+	self:debug("OnSpellcastInterrupt enter");
+	--@end-alpha@
+
+-- self:info("spell interrupt - unit: "..tostring(unit).."; spell: "..tostring(spell).."; rank: "..tostring(rank));
+
+	self.processing = false;
+
+	--@alpha@
+	self:debug("OnSpellcastInterrupt exit");
+	--@end-alpha@
 end

 function Cauldron:OnError()
---@alpha@
+	--@alpha@
 	self:debug("OnError enter");
---@end-alpha@
+	--@end-alpha@

 --	TODO

---@alpha@
+	--@alpha@
 	self:debug("OnError exit");
---@end-alpha@
+	--@end-alpha@
 end

 function Cauldron:TradeSkillFrame_SetSelection(id)
---@alpha@
+	--@alpha@
 	self:debug("TradeSkillFrame_SetSelection enter");
---@end-alpha@
+	--@end-alpha@

 	-- TODO

---@alpha@
+	--@alpha@
 	self:debug("TradeSkillFrame_SetSelection exit");
---@end-alpha@
+	--@end-alpha@
 end

 function Cauldron:GetSelectedSkill()
---@alpha@
+	--@alpha@
 	self:debug("GetSelectedSkill enter");
---@end-alpha@
+	--@end-alpha@

 	local skillName = CURRENT_TRADESKILL;
 	local baseSkillName = skillName;
@@ -706,17 +775,17 @@ function Cauldron:GetSelectedSkill()
 		end
 	end

---@alpha@
+	--@alpha@
 	self:debug("GetSelectedSkill exit");
---@end-alpha@
+	--@end-alpha@

 	return nil;
 end

 function Cauldron:QueueAllTradeSkillItem()
---@alpha@
+	--@alpha@
 	self:debug("QueueAllTradeSkillItem enter");
---@end-alpha@
+	--@end-alpha@

 	local skillInfo = Cauldron:GetSelectedSkill();
 	local skillData = Cauldron:GetSkillDataForSkill(skillInfo);
@@ -749,15 +818,15 @@ function Cauldron:QueueAllTradeSkillItem()
 		end
 	end

---@alpha@
+	--@alpha@
 	self:debug("QueueAllTradeSkillItem exit");
---@end-alpha@
+	--@end-alpha@
 end

 function Cauldron:QueueTradeSkillItem()
---@alpha@
+	--@alpha@
 	self:debug("QueueTradeSkillItem enter");
---@end-alpha@
+	--@end-alpha@

 	local skillInfo = Cauldron:GetSelectedSkill();

@@ -774,15 +843,15 @@ function Cauldron:QueueTradeSkillItem()
 		Cauldron:UpdateShoppingListFromQueue();
 	end

---@alpha@
+	--@alpha@
 	self:debug("QueueTradeSkillItem exit");
---@end-alpha@
+	--@end-alpha@
 end

 function Cauldron:CreateAllTradeSkillItem()
---@alpha@
+	--@alpha@
 	self:debug("CreateAllTradeSkillItem enter");
---@end-alpha@
+	--@end-alpha@

 	if ( (not PartialPlayTime()) and (not NoPlayTime()) ) then
 		CauldronAmountInputBox:ClearFocus();
@@ -795,15 +864,15 @@ function Cauldron:CreateAllTradeSkillItem()
 		DoTradeSkill(skillData.index, skillData.available);
 	end

---@alpha@
+	--@alpha@
 	self:debug("CreateAllTradeSkillItem exit");
---@end-alpha@
+	--@end-alpha@
 end

 function Cauldron:CreateTradeSkillItem()
---@alpha@
+	--@alpha@
 	self:debug("CreateTradeSkillItem enter");
---@end-alpha@
+	--@end-alpha@

 	if ( (not PartialPlayTime()) and (not NoPlayTime()) ) then
 		CauldronAmountInputBox:ClearFocus();
@@ -815,9 +884,9 @@ function Cauldron:CreateTradeSkillItem()
 		DoTradeSkill(skillData.index, amount);
 	end

---@alpha@
+	--@alpha@
 	self:debug("CreateTradeSkillItem exit");
---@end-alpha@
+	--@end-alpha@
 end

 function Cauldron:ProcessQueue()
@@ -935,32 +1004,46 @@ function Cauldron:SubmitItemToProcess(queueInfo, skillInfo, amount)
 end

 function Cauldron:ProcessItem(skillInfo, queueInfo, amount)
+	--@alpha@
 	self:debug("ProcessItem enter");
+	--@end-alpha@

-	if (not skillInfo) or (amount < 1) then
+	if not skillInfo then
 		self:error("ProcessItem: Missing skill info!");
 		return;
 	end
+	if amount < 1 then
+		self:error("ProcessItem: Invalid amount specified: "..tostring(amount).."!");
+		return;
+	end

 	if ((not PartialPlayTime()) and (not NoPlayTime())) then
 		-- record the item we're making
-		self.makingItem, _ = GetItemInfo(skillInfo.itemLink);
-		self:debug("ProcessItem: self.makingItem="..self.makingItem);
+		self:info("skillInfo.itemLink: "..tostring(skillInfo.itemLink));
+		self.makingItem = Cauldron:GetNameFromLink(queueInfo.link);
+		self:info("makingItem: "..tostring(self.makingItem));
+--		self.makingItemId = Cauldron:GetIdFromLink(skillInfo.itemLink);
+--		self:info("makingItemId: "..tostring(self.makingItemId));
 		self.itemCurrentCount = GetItemCount(skillInfo.itemLink);
-		self:debug("ProcessItem: self.itemCurrentCount="..self.itemCurrentCount);
+
+		self.makingItemSpell = Cauldron:GetNameFromLink(queueInfo.link);
+		self.makingItemCount = amount;
 		self.queueInfo = queueInfo;

 		-- tell the user what we're doing
-		self:Print(string.format(L["Crafting %1$d of %2$s..."], amount, self.makingItem));
+		self:Print(string.format(L["Crafting %1$d of %2$s..."], amount, queueInfo.link));

 		-- do it
 		local skillData = Cauldron:GetSkillDataForSkill(skillInfo);
+		self.processing = true;
 		DoTradeSkill(skillData.index, amount);
 	else
 		-- TODO: notify player?
 	end

+	--@alpha@
 	self:debug("ProcessItem exit");
+	--@end-alpha@
 end

 function Cauldron:RemoveQueueItem(name)
@@ -984,9 +1067,9 @@ function Cauldron:IncreaseItemCount(name)
 end

 function Cauldron:GetQueue(player)
---@alpha@
+	--@alpha@
 	self:debug("GetQueue enter");
---@end-alpha@
+	--@end-alpha@

 	if not player then
 		player = self.vars.playername;
@@ -998,9 +1081,9 @@ function Cauldron:GetQueue(player)
 		self.db.realm.userdata[player].queue = queue;
 	end

---@alpha@
+	--@alpha@
 	self:debug("GetQueue enter");
---@end-alpha@
+	--@end-alpha@

 	return queue;
 end
@@ -1145,6 +1228,9 @@ function Cauldron:AddToTooltip(tooltip, id)
 			end
 		end
 	end
+
+	-- force resize of the tooltip
+	tooltip:Show();
 end

 function filterFavoriteSkills(skillList)
@@ -1440,6 +1526,27 @@ function Cauldron:Disable()
 	Cauldron:Frame_Hide();
 end

+--[==[
+function Cauldron:Forget(param)
+	if not name then
+		return;
+	end
+
+	self:info("param: "..tostring(param));
+
+	for k,v in pairs(name) do
+		self:info("k: "..k.."; v: "..tostring(v));
+		--[[
+		if type(v) == "table" then
+			for k2,v2 in pairs(v) do
+				self:info("k2: "..k2.."; v2: "..tostring(v2));
+			end
+		end
+		--]]
+	end
+end
+--]==]
+
 function Cauldron:Reset()
 	self:Print("Starting reset.");

diff --git a/CauldronMainUI.lua b/CauldronMainUI.lua
index 58b5bc6..5fd4d84 100644
--- a/CauldronMainUI.lua
+++ b/CauldronMainUI.lua
@@ -35,13 +35,14 @@ function Cauldron:Frame_Show()
 			end

 			TradeSkillFrame:SetAlpha(0);
-			TradeSkillFrame:ClearAllPoints();
-			TradeSkillFrame:SetPoint("TOPLEFT", 0, 900);
+--			TradeSkillFrame:ClearAllPoints();
+--			TradeSkillFrame:SetPoint("TOPLEFT", 0, 900);
 			TradeSkillFrame:SetFrameStrata("BACKGROUND");
 			TradeSkillFrame:SetFrameLevel(1);
 			-- set the tradeskill frame's width to match ours
 --			TradeSkillFrame:SetWidth(692);

+			--[[
 			-- remove the tradeskill frame from the special frame list
 			for i,t in ipairs(UISpecialFrames) do
 				if t == TradeSkillFrame:GetName() then
@@ -50,6 +51,7 @@ function Cauldron:Frame_Show()
 				end
 			end
 --			table.remove(
+			--]]

 		end

@@ -82,8 +84,8 @@ function Cauldron:Frame_Hide()

  	if TradeSkillFrame then
  		TradeSkillFrame:SetAlpha(1.0);
- 		TradeSkillFrame:SetFrameStrata(Cauldron.vars.origFrameStrata or "BACKGROUND");
- 		TradeSkillFrame:SetFrameLevel(Cauldron.vars.origFrameLevel or 1);
+ 		TradeSkillFrame:SetFrameStrata(Cauldron.vars.origFrameStrata or "MEDIUM");
+ 		TradeSkillFrame:SetFrameLevel(Cauldron.vars.origFrameLevel or 5);
  	end

 	--@alpha@
@@ -463,19 +465,20 @@ function Cauldron:UpdateSkillList()
 					reagentFrame:Hide();
 				else
 					local reagentInfo = reagents[j];
+					local reagentData = skillData.reagents[j];

 					reagentFrame.skillIndex = skillData.index;
 					reagentFrame.reagentIndex = reagentInfo.index;
-					reagentFrame.link = reagentInfo.link;
+					reagentFrame.link = reagentData.link or reagentInfo.link;

 					local reagentNameFrame = _G["CauldronSkillItem"..i.."ReagentsItemDetail"..j.."Name"];
 					local reagentCountFrame = _G["CauldronSkillItem"..i.."ReagentsItemDetail"..j.."Count"];

 					reagentFrame:Show();
 					SetItemButtonTexture(reagentFrame, reagentInfo.icon);
-					reagentNameFrame:SetText(reagentInfo.name);
+					reagentNameFrame:SetText(reagentData.name or reagentInfo.name);

-					local playerReagentCount = GetItemCount(reagentInfo.name);
+					local playerReagentCount = GetItemCount(reagentData.name or reagentInfo.name);

 					if playerReagentCount < reagentInfo.numRequired then
 						-- Grayout items
@@ -551,9 +554,9 @@ function Cauldron:UpdateSkillList()
 end

 function Cauldron:UpdateButtons()
---@alpha@
+	--@alpha@
 	self:debug("UpdateButtons enter");
---@end-alpha@
+	--@end-alpha@

 	if IsTradeSkillLinked() then
 		CauldronQueueAllButton:Hide();
@@ -579,23 +582,25 @@ function Cauldron:UpdateButtons()
 	end

 	local skillInfo = Cauldron:GetSelectedSkill();
+	local skillData = Cauldron:GetSkillDataForSkill(skillInfo);

-	if skillInfo then
+	if skillInfo and skillData then
+		CauldronCreateButton:SetText(skillInfo.verb or CREATE);
+
+		CauldronQueueAllButton:Enable();
+		CauldronQueueButton:Enable();
+
 		if skillInfo.verb then
-			CauldronQueueAllButton:Hide();
-			CauldronQueueButton:Hide();
 			CauldronCreateAllButton:Hide();
-
-			CauldronCreateButton:Enable();
-			CauldronCreateButton:SetText(skillInfo.verb or CREATE);
 		else
-			CauldronQueueAllButton:Enable();
-			CauldronQueueButton:Enable();
+			CauldronCreateButton:Show();

-			if skillInfo.available then
+			if skillData.available > 0 then
 				CauldronCreateAllButton:Enable();
 				CauldronCreateButton:Enable();
-				CauldronCreateButton:SetText(CREATE);
+			else
+				CauldronCreateAllButton:Disable();
+				CauldronCreateButton:Disable();
 			end
 		end
 	else
@@ -604,18 +609,20 @@ function Cauldron:UpdateButtons()
 		CauldronCreateAllButton:Disable();
 		CauldronCreateButton:Disable();
 	end
-
-	if #CauldronQueue:GetItems(self.db.realm.userdata[self.vars.playername].queue, CURRENT_TRADESKILL) > 0 then
-		CauldronProcessButton:Enable();
-		CauldronClearQueueButton:Enable();
-	else
-		CauldronProcessButton:Disable();
-		CauldronClearQueueButton:Disable();
+
+	if not IsTradeSkillLinked() then
+		if #CauldronQueue:GetItems(self.db.realm.userdata[self.vars.playername].queue, CURRENT_TRADESKILL) > 0 then
+			CauldronProcessButton:Enable();
+			CauldronClearQueueButton:Enable();
+		else
+			CauldronProcessButton:Disable();
+			CauldronClearQueueButton:Disable();
+		end
 	end

---@alpha@
+	--@alpha@
 	self:debug("UpdateButtons exit");
---@end-alpha@
+	--@end-alpha@
 end

 function Cauldron:UpdateQueue()
diff --git a/CauldronTradeskill.lua b/CauldronTradeskill.lua
index 840e984..103ee4f 100644
--- a/CauldronTradeskill.lua
+++ b/CauldronTradeskill.lua
@@ -109,11 +109,35 @@ function Cauldron:UpdateSkills()

 				-- update reagent skill index
 				if skillDB.recipes[name].reagents then
-					for _,r in ipairs(skillDB.recipes[name].reagents) do
+					for j,r in ipairs(skillDB.recipes[name].reagents) do
+						local customName = nil;
+						local customLink = nil;
+						local rName, _, _, _ = GetTradeSkillReagentInfo(i, j);
+						local rLink = GetTradeSkillReagentItemLink(i, j);
+
+						-- compare stored name to this name
+						if self.db.global.recipes[baseSkillName][name] and self.db.global.recipes[baseSkillName][name].reagents[j] then
+							if rName ~= self.db.global.recipes[baseSkillName][name].reagents[j].name then
+								customName = rName;
+								customLink = rLink;
+							end
+						end
+
+						r.name = customName;
+						r.link = customLink;
 						r.skillIndex = i;
 					end
 				else
-					Cauldron:error("No reagent list found for recipe: "..name.."!");
+					-- create the local reagent list
+					skillDB.recipes[name].reagents = {};
+					if self.db.global.recipes[baseSkillName][name] and self.db.global.recipes[baseSkillName][name].reagents then
+						for j=1,#self.db.global.recipes[baseSkillName][name].reagents do
+							table.insert(skillDB.recipes[name].reagents, {
+								['skillIndex'] = skillDB.recipes[name].index,
+							});
+						end
+					end
+--					Cauldron:error("No reagent list found for recipe: "..name.."!");
 				end
 			else
 				-- add the recipe info and other miscellaneous info
@@ -221,9 +245,10 @@ function Cauldron:UpdateSkills()

 					-- add to the global reagent table
 					table.insert(self.db.global.recipes[baseSkillName][name].reagents, r);
+
 					-- add to the local reagent table
 					table.insert(skillDB.recipes[name].reagents, {
-						skillIndex = j,
+						['skillIndex'] = i,
 					});

 					-- add the reagent to the reagent map
diff --git a/Locale/Cauldron-enUS.lua b/Locale/Cauldron-enUS.lua
index d5bbba7..f1a9c8d 100644
--- a/Locale/Cauldron-enUS.lua
+++ b/Locale/Cauldron-enUS.lua
@@ -6,7 +6,7 @@ if not L then return end

 --
 L["Cauldron"] = true
-L["Cauldron loaded; version "] = true
+L["Cauldron loaded; version"] = true
 L["Version "] = true
 L["Date: "] = true
 L["Current log level: "] = true
@@ -19,16 +19,16 @@ L["Menu"] = true
 L["Show Cauldron UI"] = true
 L["Shopping list"] = true
 L["Open shopping list window"] = true
+L["Forget"] = true
+L["Tells Cauldron to remove the skills it knows for a character"] = true
 L["Reset"] = true
 L["Resets Cauldron to a fresh state"] = true
 L["Enable Cauldron"] = true
 L["Use Cauldron as your tradeskill interface"] = true
 L["Disable Cauldron"] = true
 L["Use the standard Blizzard window as your tradeskill interface"] = true
-L["Logging"] = true
-L["Sets or displays the logging level"] = true
-L["Normal logging of warnings and errors"] = true
-L["Debug logging (very verbose)"] = true
+L["Debug"] = true
+L["Toggles whether Cauldron displays debug messages"] = true
 L["enabled"] = true
 L["disabled"] = true
 L["skills"] = true
@@ -117,6 +117,7 @@ L[" (%d in bank)"] = true
 L[", need %d"] = true

 L["Crafting %1$d of %2$s..."] = true
+L["remaining"] = true

 L["Remove this item from the queue"] = true
 L["Increase the priority of this item"] = true
diff --git a/Locale/Cauldron-ruRU.lua b/Locale/Cauldron-ruRU.lua
index 9ca31c1..811faea 100755
--- a/Locale/Cauldron-ruRU.lua
+++ b/Locale/Cauldron-ruRU.lua
@@ -7,7 +7,7 @@ if not L then return end

 --
 L["Cauldron"] = "Cauldron"
-L["Cauldron loaded; version "] = "Cauldron загружен; версия "
+L["Cauldron loaded; version"] = "Cauldron загружен; версия"
 L["Version "] = "Версия"
 L["Date: "] = "Дата: "
 L["Current log level: "] = "Текущий уровень протоколирования: "
@@ -26,10 +26,8 @@ L["Enable Cauldron"] = "Включить Cauldron"
 L["Use Cauldron as your tradeskill interface"] = "Использовать интерфейс Cauldron для окна ремесла"
 L["Disable Cauldron"] = "Отключить Cauldron"
 L["Use the standard Blizzard window as your tradeskill interface"] = "Использовать стандартное окно ремесла"
-L["Logging"] = "Протоколирование"
-L["Sets or displays the logging level"] = "Установить отображать ли уровень протоколирования"
-L["Normal logging of warnings and errors"] = "Обычное протоколирования предупреждений и ошибок"
-L["Debug logging (very verbose)"] = "Отладочное протоколирование (слишком подробная)"
+L["Debug"] = ""
+L["Toggles whether Cauldron displays debug messages"] = ""
 L["enabled"] = "включен"
 L["disabled"] = "отключен"
 L["skills"] = "навыка(ов)"
@@ -118,6 +116,7 @@ L[" (%d in bank)"] = " (В банке: %d)"
 L[", need %d"] = ", нужно %d"

 L["Crafting %1$d of %2$s..."] = "Создание %1$d - %2$s"
+L["remaining"] = ""

 L["Remove this item from the queue"] = "Убрать этот предмет из очереди."
 L["Increase the priority of this item"] = "Увеличить приоритет данного предмета."