Language:
Lua     Change language:
Pastebin: 73636
Author: Kandoko
Subject: Re: Temp AucAdvance fix for Reagent cost
Created: 2007-09-09 17:08:45
Download and save
Toggle line numbers
1------------------------------------------------------ 
2--Fizzwidget Reagent Cost 
3--by Gazmik Fizzwidget 
4--http://fizzwidget.com/reagentcost 
5--Temporary fix to work with AucAdvance by kandoko  
6 
7------------------------------------------------------ 
8 
9FRC_Config = { }
10FRC_Config.Enabled = true
11FRC_Config.MinProfitRatio = 0
12FRC_Config.MinProfitMoney = nil
13FRC_Config.AutoLoadPriceSource = nil
14 
15FRC_ReagentLinks = { }
16 
17local MIN_SCANS = 35; -- times an item must be seen at auction to be considered a good sample (equates to 100% on our confidence scale) 
18local MIN_CONFIDENCE = 5; -- cutoff so we don't report items we have little data on as potentially profitable 
19local MIN_OVERRIDE_CONFIDENCE = 90; -- cutoff for trusting an item's market price versus the price of its components 
20 
21-- Anti-freeze code borrowed from ReagentInfo (in turn, from Quest-I-On): 
22-- keeps WoW from locking up if we try to scan the tradeskill window too fast. 
23FRC_TradeSkillLock = { }
24FRC_TradeSkillLock.NeedScan = false
25FRC_TradeSkillLock.Locked = false
26FRC_TradeSkillLock.EventTimer = 0
27FRC_TradeSkillLock.EventCooldown = 0
28FRC_TradeSkillLock.EventCooldownTime = 1
29FRC_CraftLock = { }
30FRC_CraftLock.NeedScan = false
31FRC_CraftLock.Locked = false
32FRC_CraftLock.EventTimer = 0
33FRC_CraftLock.EventCooldown = 0
34FRC_CraftLock.EventCooldownTime = 1
35 
36function FRC_CraftFrame_SetSelection(id) 
37    FRC_Orig_CraftFrame_SetSelection(id); 
38 
39    if ( not id ) then 
40        return
41    end 
42    local name, rank, maxRank = GetCraftDisplaySkillLine(); 
43    if not (name) then 
44        return
45    end 
46    local craftName, craftSubSpellName, craftType, numAvailable, isExpanded, trainingPointCost, requiredLevel = GetCraftInfo(id); 
47    if ( trainingPointCost and trainingPointCost > 0 ) then 
48        return
49    end 
50    if ( craftType == "header" ) then 
51        return
52    end 
53 
54    local costText; 
55    if (FRC_Config.Enabled) then 
56        local itemLink = GetCraftItemLink(id); 
57        if (itemLink == nil) then return; end 
58        local _, _, enchantLink = string.find(itemLink, "(enchant:%d+)"); 
59        local _, _, itemID = string.find(itemLink, "item:(%d+)"); 
60        if (itemID) then 
61            itemID = tonumber(itemID); 
62            identifier = itemID; 
63        elseif (enchantLink) then 
64            identifier = enchantLink; 
65        else 
66            GFWUtils.Print("ReagentCost: Can't parse link "..itemLink.." for recipe "..craftName); 
67            return
68        end 
69 
70        local materialsTotal, confidenceScore = FRC_MaterialsCost(name, identifier); 
71        costText = GFWUtils.LtY("(Total cost: "); 
72        if (materialsTotal == nil) then 
73            if (FRC_PriceSource == "Auctioneer" and not IsAddOnLoaded("Auc-Advanced")) then 
74                costText = costText .. GFWUtils.Gray("[Auctioneer not loaded]"); 
75            else 
76                costText = costText .. GFWUtils.Gray("Unknown [insufficient data]"); 
77            end 
78        else 
79            costText = costText .. GFWUtils.TextGSC(materialsTotal) ..GFWUtils.Gray(" Confidence: "..confidenceScore.."%"); 
80        end 
81        costText = costText ..GFWUtils.LtY(")"); 
82 
83        CraftReagentLabel:SetText(SPELL_REAGENTS.." "..costText); 
84        CraftReagentLabel:Show(); 
85    end 
86 
87end 
88 
89function FRC_TradeSkillFrame_SetSelection(id) 
90    FRC_Orig_TradeSkillFrame_SetSelection(id); 
91 
92    if ( not id ) then 
93        return
94    end 
95    local skillName, skillType, numAvailable, isExpanded = GetTradeSkillInfo(id); 
96    if ( skillType == "header" ) then 
97        return
98    end 
99    local skillLineName, skillLineRank, skillLineMaxRank = GetTradeSkillLine(); 
100 
101    local costText; 
102    if (FRC_Config.Enabled) then 
103        local link = GetTradeSkillItemLink(id); 
104        if (link == nil) then return; end 
105        local _, _, itemID = string.find(link, "item:(%d+)"); 
106        itemID = tonumber(itemID); 
107 
108        local materialsTotal, confidenceScore = FRC_MaterialsCost(skillLineName, itemID); 
109        costText = GFWUtils.LtY("(Total cost: "); 
110        if (materialsTotal == nil) then 
111            if (FRC_PriceSource == "Auctioneer" and not IsAddOnLoaded("Auc-Advanced")) then 
112                costText = costText .. GFWUtils.Gray("[Auctioneer not loaded]"); 
113            else 
114                costText = costText .. GFWUtils.Gray("Unknown [insufficient data]"); 
115            end 
116        else 
117            costText = costText .. GFWUtils.TextGSC(materialsTotal) ..GFWUtils.Gray(" Confidence: "..confidenceScore.."%"); 
118        end 
119        costText = costText ..GFWUtils.LtY(")"); 
120 
121        TradeSkillReagentLabel:SetText(SPELL_REAGENTS.." "..costText); 
122        TradeSkillReagentLabel:Show(); 
123    end 
124 
125end 
126 
127function FRC_TradeSkillFrame_Update() 
128    FRC_Orig_TradeSkillFrame_Update(); 
129 
130    FRC_ScanTradeSkill(); 
131end 
132 
133function FRC_CraftFrame_Update() 
134    FRC_Orig_CraftFrame_Update(); 
135 
136    FRC_ScanCraft(); 
137end 
138 
139function FRC_OnLoad() 
140 
141    local name, title, notes, enabled, loadable, reason, security = GetAddOnInfo("Auc-Advanced"); 
142    if (loadable or IsAddOnLoaded("Auc-Advanced")) then 
143        FRC_PriceSource = "Auctioneer"
144    --elseif (KC_Auction) then 
145    -- FRC_PriceSource = "KC_Items"; 
146    --elseif (AuctionMatrix_Version) then           
147    -- FRC_PriceSource = "AuctionMatrix"; 
148    --elseif (WOWEcon_Enabled) then 
149    -- FRC_PriceSource = "WOWEcon_PriceMod"; 
150    end 
151 
152    -- Register Slash Commands 
153    SLASH_FRC1 = "/reagentcost"
154    SLASH_FRC2 = "/rc"
155    SlashCmdList["FRC"] = function(msg) 
156        FRC_ChatCommandHandler(msg); 
157    end 
158 
159    this:RegisterEvent("CRAFT_SHOW"); 
160    this:RegisterEvent("CRAFT_UPDATE"); 
161    this:RegisterEvent("TRADE_SKILL_SHOW"); 
162    this:RegisterEvent("TRADE_SKILL_UPDATE"); 
163    this:RegisterEvent("ADDON_LOADED"); 
164    this:RegisterEvent("VARIABLES_LOADED"); 
165 
166end 
167 
168function FRC_OnUpdate(elapsed) 
169    -- If it's been more than a second since our last tradeskill update, 
170    -- we can allow the event to process again. 
171    FRC_TradeSkillLock.EventTimer = FRC_TradeSkillLock.EventTimer + elapsed; 
172    if (FRC_TradeSkillLock.Locked) then 
173        FRC_TradeSkillLock.EventCooldown = FRC_TradeSkillLock.EventCooldown + elapsed; 
174        if (FRC_TradeSkillLock.EventCooldown > FRC_TradeSkillLock.EventCooldownTime) then 
175 
176            FRC_TradeSkillLock.EventCooldown = 0
177            FRC_TradeSkillLock.Locked = false
178        end 
179    end 
180    FRC_CraftLock.EventTimer = FRC_CraftLock.EventTimer + elapsed; 
181    if (FRC_CraftLock.Locked) then 
182        FRC_CraftLock.EventCooldown = FRC_CraftLock.EventCooldown + elapsed; 
183        if (FRC_CraftLock.EventCooldown > FRC_CraftLock.EventCooldownTime) then 
184 
185            FRC_CraftLock.EventCooldown = 0
186            FRC_CraftLock.Locked = false
187        end 
188    end 
189 
190    if (FRC_TradeSkillLock.NeedScan) then 
191        FRC_TradeSkillLock.NeedScan = false
192        FRC_ScanTradeSkill(); 
193    end 
194    if (FRC_CraftLock.NeedScan) then 
195        FRC_CraftLock.NeedScan = false
196        FRC_ScanCraft(); 
197    end 
198end 
199 
200function FRC_OnEvent(event) 
201 
202    if (event == "ADDON_LOADED" and (arg1 == "Blizzard_CraftUI" or IsAddOnLoaded("Blizzard_CraftUI"))) then 
203        if (FRC_Orig_CraftFrame_SetSelection == nil) then 
204            -- Overrides for displaying info in CraftFrame 
205            FRC_Orig_CraftFrame_SetSelection = CraftFrame_SetSelection; 
206            CraftFrame_SetSelection = FRC_CraftFrame_SetSelection; 
207 
208            -- And for scanning, since it looks like doing it in event handlers is crashy/unreliable now. 
209            FRC_Orig_CraftFrame_Update = CraftFrame_Update; 
210            CraftFrame_Update = FRC_CraftFrame_Update; 
211 
212            --GFWUtils.Print("ReagentCost CraftFrame hooks installed."); 
213        end 
214    end 
215 
216    if (event == "ADDON_LOADED" and (arg1 == "Blizzard_TradeSkillUI" or IsAddOnLoaded("Blizzard_TradeSkillUI"))) then 
217        if (FRC_Orig_TradeSkillFrame_SetSelection == nil) then 
218            -- Overrides for displaying info in TradeSkillFrame 
219            FRC_Orig_TradeSkillFrame_SetSelection = TradeSkillFrame_SetSelection; 
220            TradeSkillFrame_SetSelection = FRC_TradeSkillFrame_SetSelection; 
221 
222            -- And for scanning, since it looks like doing it in event handlers is crashy/unreliable now. 
223            FRC_Orig_TradeSkillFrame_Update = TradeSkillFrame_Update; 
224            TradeSkillFrame_Update = FRC_TradeSkillFrame_Update; 
225 
226            --GFWUtils.Print("ReagentCost TradeSkillFrame hooks installed."); 
227        end 
228    end 
229 
230    if ( event == "VARIABLES_LOADED" or event == "ADDON_LOADED" ) then 
231 
232        if (FRC_Config == nil) then 
233            FRC_Config = {}
234            FRC_Config.Enabled = true
235            FRC_Config.MinProfitRatio = 0
236        end 
237        local name, title, notes, enabled, loadable, reason, security = GetAddOnInfo("Auc-Advanced"); 
238        if ((loadable or IsAddOnLoaded("Auc-Advanced")) and FRC_PriceSource == nil) then 
239            FRC_PriceSource = "Auctioneer"
240        end 
241        --[[if (AUCTIONEER_VERSION) then 
242            local _, _, major, minor = string.find(AUCTIONEER_VERSION, "^(%d+)%.(%d+)"); 
243            major, minor = tonumber(major), tonumber(minor); 
244            if (major and major >= 3 and minor and minor >= 1) then 
245                FRC_PriceSource = "Auctioneer"; 
246            end 
247        end]] 
248        return
249    end 
250 
251    if ( event == "TRADE_SKILL_SHOW" or event == "CRAFT_SHOW" and FRC_Config.Enabled) then 
252 
253        if (event == "CRAFT_SHOW" and GetCraftDisplaySkillLine() == nil) then 
254            -- Beast Training uses the CraftFrame; we can tell when it's up because it doesn't have a skill-level bar. 
255            -- We don't have anything to do in that case, so let's not try loading Auctioneer and stuff. 
256            return
257        end 
258 
259        local name, title, notes, enabled, loadable, reason, security = GetAddOnInfo("Auc-Advanced"); 
260        if ((loadable or IsAddOnLoaded("Auc-Advanced")) and FRC_PriceSource == nil) then 
261            FRC_PriceSource = "Auctioneer"
262        end 
263        if ( FRC_PriceSource == "Auctioneer" and FRC_Config and FRC_Config.AutoLoadPriceSource) then 
264            if (not IsAddOnLoaded("Auc-Advanced")) then 
265                local loaded, reason = LoadAddOn("Auc-Advanced"); 
266                if (not loaded) then 
267                    GFWUtils.Print("Can't load Auctioneer: "..reason); 
268                    return
269                end 
270            end 
271        end 
272        if ( FRC_PriceSource == nil) then 
273            GFWUtils.Print("ReagentCost: missing required dependency. Can't find Auctioneer, KC_Items, or AuctionMatrix."); 
274            return
275        end 
276    end 
277 
278    if ( event == "TRADE_SKILL_SHOW" or event == "TRADE_SKILL_UPDATE" ) then 
279 
280        FRC_ScanTradeSkill(); 
281 
282    elseif ( event == "CRAFT_SHOW" or event == "CRAFT_UPDATE" ) then 
283 
284        FRC_ScanCraft(); 
285 
286    end 
287 
288end 
289 
290function FRC_ChatCommandHandler(msg) 
291 
292    if (FRC_PriceSource == nil) then 
293        GFWUtils.Print("Fizzwidget Reagent Cost is installed but non-functional; can't find Auctioneer, KC_Items (with auction module), or AuctionMatrix."); 
294        return
295    end 
296 
297    -- Print Help 
298    if ( msg == "help" ) or ( msg == "" ) then 
299        local version = GetAddOnMetadata("GFW_ReagentCost", "Version"); 
300        GFWUtils.Print("Fizzwidget Reagent Cost "..version..":"); 
301        GFWUtils.Print("/reagentcost (or /rc) <command>"); 
302        GFWUtils.Print("- "..GFWUtils.Hilite("help").." - Print this helplist."); 
303        GFWUtils.Print("- "..GFWUtils.Hilite("status").." - Check current settings."); 
304        GFWUtils.Print("- "..GFWUtils.Hilite("reset").." - Reset to default settings."); 
305        GFWUtils.Print("- "..GFWUtils.Hilite("on").." | "..GFWUtils.Hilite("off").." - Toggle displaying info in tradeskill windows."); 
306        if (FRC_PriceSource == "Auctioneer") then 
307            GFWUtils.Print("- "..GFWUtils.Hilite("autoload on").." | "..GFWUtils.Hilite("off").." - Control whether to automatically load Auctioneer when showing tradeskill windows."); 
308        end 
309        GFWUtils.Print("- "..GFWUtils.Hilite("report [<skillname>]").." - Output a list of the most profitable tradeskill items you can make. (Or only those produced through <skillname>.)"); 
310        GFWUtils.Print("- "..GFWUtils.Hilite("minprofit <number>").." - When reporting, only show items whose estimated profit is <number> or greater. (In copper, so 1g == 10000.)"); 
311        GFWUtils.Print("- "..GFWUtils.Hilite("minprofit <number>%").." - When reporting, only show items whose estimated profit exceeds its cost of materials by <number> percent or more."); 
312        return
313    end 
314 
315    if (msg == "version") then 
316        local version = GetAddOnMetadata("GFW_ReagentCost", "Version"); 
317        GFWUtils.Print("Fizzwidget Reagent Cost "..version); 
318        return
319    end 
320 
321    -- Check Status 
322    if ( msg == "status" ) then 
323        if (FRC_Config.Enabled) then 
324            GFWUtils.Print("Reagent Cost "..GFWUtils.Hilite("is").." displaying materials cost in tradeskill windows."); 
325            if (FRC_Config.AutoLoadPriceSource) then 
326                GFWUtils.Print("Reagent Cost "..GFWUtils.Hilite("will").." automatically load Auctioneer to show prices in tradeskill windows."); 
327            else 
328                GFWUtils.Print("Reagent Cost "..GFWUtils.Hilite("will not").." automatically load Auctioneer; prices will not be shown in tradeskill windows until Auctioner is loaded some other way."); 
329            end 
330        else 
331            GFWUtils.Print("Reagent Cost "..GFWUtils.Hilite("is not").." displaying materials cost in tradeskill windows."); 
332        end 
333        if (FRC_Config.MinProfitMoney == nil) then 
334            GFWUtils.Print("Reports will only include items whose estimated profit exceeds materials cost by "..GFWUtils.Hilite(FRC_Config.MinProfitRatio.."%").." or more."); 
335        else 
336            GFWUtils.Print("Reports will only include items whose estimated profit is "..GFWUtils.TextGSC(FRC_Config.MinProfitMoney).." or greater."); 
337        end 
338        return
339    end 
340 
341    -- Reset Variables 
342    if ( msg == "reset" ) then 
343        FRC_Config.Enabled = true
344        FRC_Config.MinProfitRatio = 0
345        FRC_Config.MinProfitMoney = nil
346        GFWUtils.Print("Reagent Cost configuration reset."); 
347        FRC_ChatCommandHandler("status"); 
348        return
349    end 
350 
351    -- Turn trade info gathering on 
352    if ( msg == "on" ) then 
353        FRC_Config.Enabled = true
354        GFWUtils.Print("Reagent Cost "..GFWUtils.Hilite("is").." displaying materials cost in tradeskill windows."); 
355        return
356    end 
357 
358    -- Turn trade info gathering Off 
359    if ( msg == "off" ) then 
360        FRC_Config.Enabled = false
361        GFWUtils.Print("Reagent Cost "..GFWUtils.Hilite("is not").." displaying materials cost in tradeskill windows."); 
362        return
363    end 
364 
365    if ( msg == "autoload on" ) then 
366        FRC_Config.AutoLoadPriceSource = true
367        GFWUtils.Print("Reagent Cost "..GFWUtils.Hilite("will").." automatically load Auctioneer to show prices in tradeskill windows."); 
368        return
369    end 
370    if ( msg == "autoload off" ) then 
371        FRC_Config.AutoLoadPriceSource = nil
372        GFWUtils.Print("Reagent Cost "..GFWUtils.Hilite("will not").." automatically load Auctioneer; prices will not be shown in tradeskill windows until Auctioner is loaded some other way."); 
373        return
374    end 
375 
376    local _, _, cmd, args = string.find(msg, "(%w+) *(.*)"); 
377    if ( cmd == "minprofit" ) then 
378 
379        local _, _, number, isPercent = string.find(msg, "minprofit (-*%d+)(%%*)"); 
380        if (number == nil) then 
381            GFWUtils.Print("Usage: "..GFWUtils.Hilite("/rc minprofit <number>[%]")); 
382            return
383        end 
384        if (isPercent == "%") then 
385            FRC_Config.MinProfitRatio = tonumber(number); 
386            FRC_Config.MinProfitMoney = nil
387            GFWUtils.Print("Reports will only include items whose estimated profit exceeds materials cost by "..GFWUtils.Hilite(FRC_Config.MinProfitRatio.."%").." or more."); 
388        else 
389            FRC_Config.MinProfitRatio = nil
390            FRC_Config.MinProfitMoney = tonumber(number); 
391            GFWUtils.Print("Reports will only include items whose estimated profit is "..GFWUtils.TextGSC(FRC_Config.MinProfitMoney).." or greater."); 
392        end 
393        return
394    end 
395 
396    if ( cmd == "reagents" or cmd == "report" ) then 
397 
398        if (FRC_PriceSource == "Auctioneer") then 
399            if (not IsAddOnLoaded("Auc-Advanced")) then 
400                local loaded, reason = LoadAddOn("Auc-Advanced"); 
401                if (not loaded) then 
402                    GFWUtils.Print("Can't load Auctioneer: "..reason); 
403                    return
404                end 
405            end 
406        end 
407 
408        -- check second arg 
409        local _, _, arg1, moreArgs = string.find(args, "(%w+) *(.*)"); 
410        local scope = "toon"
411        if (arg1 == "all") then 
412            scope = "realm"
413            args = moreArgs; 
414        elseif (arg1 == "allrealms") then 
415            scope = "all"
416            args = moreArgs; 
417        end 
418 
419        -- parse skill names from args 
420        local mySkills = { }
421        if (args and args ~= "") then 
422            for word in string.gmatch(args, "[^%s]+") do 
423                local niceWord = string.upper(string.sub(word, 1, 1))..string.sub(word, 2); 
424                table.insert(mySkills, niceWord); 
425            end 
426        end 
427 
428        -- if no args, use the skills this character knows 
429        if (table.getn(mySkills) == 0) then 
430            for skillIndex = 1, GetNumSkillLines() do 
431                local skillName, _, _, _, _, _, _, isAbandonable = GetSkillLineInfo(skillIndex); 
432                if (isAbandonable) then 
433                    table.insert(mySkills, skillName); 
434                end 
435            end 
436        end 
437 
438        local printList; 
439        if (cmd == "report") then 
440            printList = FRC_ReportForSkill; 
441        elseif (cmd == "reagents") then 
442            printList = FRC_ListAllReagents; 
443        end 
444        for _, skillName in pairs(mySkills) do 
445            printList(skillName, scope); 
446        end 
447 
448        return
449    end 
450 
451    local linksFound; 
452    for itemLink in string.find(msg, "(|c%x+|Hitem:[-%d:]+|h%[.-%]|h|r)") do 
453        linksFound = true
454        local _, _, itemID = string.find(itemLink, "item:([-%d]+)"); 
455        itemID = tonumber(itemID); 
456 
457        if (FRC_PriceSource == "Auctioneer" and not IsAddOnLoaded("Auc-Advanced")) then 
458            local loaded, reason = LoadAddOn("Auc-Advanced"); 
459            if (not loaded) then 
460                GFWUtils.Print("Can't load Auctioneer: "..reason); 
461                return
462            end 
463        end 
464 
465        local found = false
466        for skillName, skillTable in pairs(FRC_ReagentLinks) do 
467            if (skillTable[itemID]) then 
468                for recipe, reagentList in pairs(skillTable[itemID]) do 
469 
470                    -- differentiate cases where an item can be made by multiple recipes 
471                    -- by checking to see if the name of the recipe matches the name of the item 
472                    if (string.find(itemLink, "%["..recipe.."%]")) then 
473                        GFWUtils.Print(itemLink.." ("..skillName.."):"); 
474                    else 
475                        GFWUtils.Print(itemLink.." ("..skillName.." - "..recipe.."):"); 
476                    end 
477                    found = true
478                    for _, reagentInfo in pairs(reagentList) do 
479                        if (type(reagentInfo) == "table") then 
480                            local price, confidence, isAdjusted = FRC_AdjustedCost(skillName, reagentInfo.id); 
481                            local adjustedText, confidenceText; 
482                            if (isAdjusted) then 
483                                adjustedText = "(based on component prices)"
484                            else 
485                                adjustedText = ""
486                            end 
487                            if (confidence < 0) then 
488                                confidenceText = "from vendor"
489                            else 
490                                confidenceText = confidence.."%" 
491                            end 
492                            if (price) then 
493                                GFWUtils.Print(GFWUtils.Hilite(reagentInfo.count.."x ")..reagentInfo.id..": "..GFWUtils.TextGSC(price * reagentInfo.count)..GFWUtils.Gray(" ("..confidenceText..") ")..adjustedText); 
494                            else 
495                                GFWUtils.Print(GFWUtils.Hilite(reagentInfo.count.."x ")..reagentInfo.id..": No price data"); 
496                            end 
497                        end 
498                    end 
499 
500                    local itemPrice, itemConfidence = FRC_TypicalItemPrice(itemID); 
501                    local materialsCost, matsConfidence = FRC_MaterialsCostForRecipe(skillName, itemID, recipe); 
502                    local profit = itemPrice - materialsCost; 
503                    local profitText; 
504                    if (profit > 0) then 
505                        profitText = "profit ".. GFWUtils.TextGSC(profit); 
506                    elseif (profit == 0) then 
507                        profitText = GFWUtils.Hilite("(break-even)"); 
508                    else 
509                        profitText = GFWUtils.Red("loss ").. GFWUtils.TextGSC(math.abs(profit)); 
510                    end 
511                    if (materialsCost) then 
512                        GFWUtils.Print("Total materials: "..GFWUtils.TextGSC(materialsCost)..GFWUtils.Gray("("..matsConfidence..")")); 
513                    else 
514                        GFWUtils.Print("Total materials: data not available for one or more reagents"); 
515                    end 
516                    if (itemPrice) then 
517                        GFWUtils.Print("Auction price: "..GFWUtils.TextGSC(itemPrice)..GFWUtils.Gray("("..itemConfidence..")").."; "..profitText); 
518                    else 
519                        GFWUtils.Print("Auction price: data not available"); 
520                    end 
521                end 
522            end 
523        end 
524        if (not found) then 
525            GFWUtils.Print(itemLink.." not found in tradeskill data."); 
526        end 
527    end 
528 
529    -- If we get down to here, we got bad input. 
530    if (not linksFound) then 
531        FRC_ChatCommandHandler("help"); 
532    end 
533end 
534 
535function FRC_ListAllReagents(skillName, scope) 
536    local itemsTable = FRC_ReagentLinks[skillName]; 
537    if (itemsTable == nil) then 
538        if (ReagentData == nil) then 
539            GFWUtils.Print("Nothing for "..GFWUtils.Hilite(skillName).."."); 
540        elseif (ReagentData['reversegathering'][skillName]) then 
541            -- do nothing; don't want to barf errors about gathering skills... 
542        elseif (ReagentData['reverseprofessions'][skillName]) then 
543            GFWUtils.Print("ReagentCost doesn't have information on "..GFWUtils.Hilite(skillName)..". Please open your "..GFWUtils.Hilite(skillName).." window before requesting a report."); 
544        else 
545            GFWUtils.Print(GFWUtils.Hilite(skillName).." is not a known profession."); 
546        end 
547    else 
548        local realm = GetRealmName(); 
549        local player = UnitName("player"); 
550        for anItem, recipesTable in pairs(itemsTable) do 
551            for recipe, reagentList in pairs(recipesTable) do 
552                local known; 
553                if (scope == "toon") then 
554                    if (FRC_KnownRecipes and FRC_KnownRecipes[realm] and FRC_KnownRecipes[realm][player]) then 
555                        for skillLine, items in pairs(FRC_KnownRecipes[realm][player]) do 
556                            if (GFWTable.KeyOf(items, anItem)) then 
557                                known = true
558                                break
559                            end 
560                        end 
561                    end 
562                elseif (scope == "realm") then 
563                    if (FRC_KnownRecipes and FRC_KnownRecipes[realm]) then 
564                        for player, skillLines in pairs(FRC_KnownRecipes[realm]) do 
565                            for skillLine, items in pairs(skillLine) do 
566                                if (GFWTable.KeyOf(items, anItem)) then 
567                                    known = true
568                                    break
569                                end 
570                            end 
571                        end 
572                    end 
573                else 
574                    known = true
575                end 
576 
577                if (known) then 
578                    local itemString; 
579                    if (type(anItem) == "number") then 
580                        itemString = FRC_GetItemLink(anItem)..": "
581                    else 
582                        itemString = recipe..": "
583                    end 
584                    for _, aReagent in pairs(reagentsTable) do 
585                        itemString = itemString.. aReagent.count .. "x" .. aReagent.id .. ", "
586                    end 
587                    itemString = string.gsub(itemString, ", $", ""); 
588                    GFWUtils.Print(itemString); 
589                end 
590            end 
591        end 
592    end 
593end 
594 
595function FRC_ReportForSkill(skillName, scope) 
596    local knownItems = 0
597    local reliableItems = 0
598    local shownItems = 0
599    local itemsTable = FRC_ReagentLinks[skillName]; 
600 
601    if (itemsTable == nil) then 
602        if (ReagentData == nil) then 
603            GFWUtils.Print("Nothing for "..GFWUtils.Hilite(skillName).."."); 
604        elseif (ReagentData['reversegathering'][skillName]) then 
605            -- do nothing; don't want to barf errors about gathering skills... 
606            if (skillName == ReagentData['gathering']['mining']) then 
607                -- ...except for Mining, which is also a production skill as far as we're concerned. 
608                GFWUtils.Print("ReagentCost doesn't have information on "..GFWUtils.Hilite(skillName)..". Please open your "..GFWUtils.Hilite(skillName).." window before requesting a report."); 
609            end 
610        elseif (ReagentData['reverseprofessions'][skillName]) then 
611            GFWUtils.Print("ReagentCost doesn't have information on "..GFWUtils.Hilite(skillName)..". Please open your "..GFWUtils.Hilite(skillName).." window before requesting a report."); 
612        else 
613            GFWUtils.Print(GFWUtils.Hilite(skillName).." is not a known profession."); 
614        end 
615        return
616    end 
617 
618    local reportTable = { }; -- separate report for each skill 
619 
620    -- first, build a table that includes current Auctioneer prices for composite items 
621    local realm = GetRealmName(); 
622    local player = UnitName("player"); 
623    for anItem in pairs(itemsTable) do 
624        local known; 
625        if (scope == "toon") then 
626            if (FRC_KnownRecipes and FRC_KnownRecipes[realm] and FRC_KnownRecipes[realm][player]) then 
627                for skillLine, items in pairs(FRC_KnownRecipes[realm][player]) do 
628                    if (GFWTable.KeyOf(items, anItem)) then 
629                        known = true
630                        break
631                    end 
632                end 
633            end 
634        elseif (scope == "realm") then 
635            if (FRC_KnownRecipes and FRC_KnownRecipes[realm]) then 
636                for player, skillLines in pairs(FRC_KnownRecipes[realm]) do 
637                    for skillLine, items in pairs(skillLine) do 
638                        if (GFWTable.KeyOf(items, anItem)) then 
639                            known = true
640                            break
641                        end 
642                    end 
643                end 
644            end 
645        else 
646            known = true
647        end 
648 
649        if (known and type(anItem) == "number") then 
650            -- it's an item, not an enchant (which isn't auctionable, and thus doesn't have a price to compare) 
651            local itemID = anItem; 
652            for recipe in pairs(FRC_ReagentLinks[skillName][itemID]) do 
653                knownItems = knownItems + 1
654                local itemPrice, itemConfidence = FRC_TypicalItemPrice(itemID); 
655                local materialsCost, matsConfidence = FRC_MaterialsCostForRecipe(skillName, itemID, recipe); 
656 
657                if (itemConfidence == nil) then itemConfidence = 0; end 
658                if (matsConfidence == nil) then matsConfidence = 0; end 
659 
660                if (itemConfidence >= MIN_CONFIDENCE and matsConfidence >= MIN_CONFIDENCE) then 
661                    reliableItems = reliableItems + 1
662                    local profit = itemPrice - materialsCost; 
663                    local itemLink = FRC_GetItemLink(itemID); 
664                    table.insert(reportTable, {link=itemLink, recipe=recipe, matsCost=materialsCost, matsConf=matsConfidence, itemPrice=itemPrice, itemConf=itemConfidence, profit=profit}); 
665                end 
666            end 
667        end 
668    end 
669 
670 
671    if (knownItems == 0) then 
672        GFWUtils.Print("ReagentCost doesn't know of any items you can make with "..GFWUtils.Hilite(skillName)..". Please open your "..GFWUtils.Hilite(skillName).." window before requesting a report."); 
673        return
674    end 
675 
676    if (reliableItems == 0) then 
677        GFWUtils.Print("None of the "..GFWUtils.Hilite(knownItems).." items you can make with "..GFWUtils.Hilite(skillName).." have reliable auction price data. (They may not be tradeable.)"); 
678        return
679    end 
680 
681    GFWUtils.Print("Most profitable recipes for "..GFWUtils.Hilite(skillName)..":"); 
682 
683    if (reliableItems > 1) then 
684        table.sort(reportTable, FRC_SortProfit); 
685    end 
686 
687    -- and report those that meet our minimum requirements 
688    for _, reportInfo in pairs(reportTable) do 
689        if (FRC_Config.MinProfitRatio and (reportInfo.profit / reportInfo.matsCost * 100) >= FRC_Config.MinProfitRatio) then 
690            shownItems = shownItems + 1
691            FRC_PrintReportLine(reportInfo); 
692        elseif (FRC_Config.MinProfitMoney and reportInfo.profit >= FRC_Config.MinProfitMoney) then 
693            shownItems = shownItems + 1
694            FRC_PrintReportLine(reportInfo); 
695        end 
696    end 
697    GFWUtils.Print(GFWUtils.Hilite(knownItems).." recipes known, "..GFWUtils.Hilite(reliableItems).." with auction data, "..GFWUtils.Hilite(shownItems).." above profit threshold."); 
698 
699end 
700 
701function FRC_ScanTradeSkill() 
702    if (not TradeSkillFrame or not TradeSkillFrame:IsVisible() or FRC_TradeSkillLock.Locked) then return; end 
703    -- This prevents further update events from being handled if we're already processing one. 
704    -- This is done to prevent the game from freezing under certain conditions. 
705    FRC_TradeSkillLock.Locked = true
706 
707    local skillLineName, skillLineRank, skillLineMaxRank = GetTradeSkillLine(); 
708    if not (skillLineName) then 
709        FRC_TradeSkillLock.NeedScan = true
710        return; -- apparently sometimes we're called too early, this is nil, and all hell breaks loose. 
711    end 
712    if (FRC_ReagentLinks == nil) then 
713        FRC_ReagentLinks = { }
714    end 
715    if (FRC_ReagentLinks[skillLineName] == nil) then 
716        FRC_ReagentLinks[skillLineName] = { }
717    end 
718 
719    local realm = GetRealmName(); 
720    local player = UnitName("player"); 
721    if (FRC_KnownRecipes == nil) then 
722        FRC_KnownRecipes = {}
723    end 
724    if (FRC_KnownRecipes[realm] == nil) then 
725        FRC_KnownRecipes[realm] = {}
726    end 
727    if (FRC_KnownRecipes[realm][player] == nil) then 
728        FRC_KnownRecipes[realm][player] = {}
729    end 
730    if (GetTradeSkillItemNameFilter() == nil and not TradeSkillFrameAvailableFilterCheckButton:GetChecked()) then 
731        -- only start from zero if we're sure the tradeskill window currently shows everything known 
732        FRC_KnownRecipes[realm][player][skillLineName] = {}
733    end 
734    if (FRC_ItemInfoCache == nil) then 
735        FRC_ItemInfoCache = {}
736    end 
737    for id = GetNumTradeSkills(), 1, -1 do 
738        -- loop from the bottom up, since the reagents we make for compound items are usually below the recipes that need them 
739        local skillName, skillType, numAvailable, isExpanded = GetTradeSkillInfo(id); 
740        if ( skillType ~= "header" ) then 
741            local itemLink = GetTradeSkillItemLink(id); 
742            if (itemLink == nil) then 
743                FRC_TradeSkillLock.NeedScan = true
744            else 
745                local numReagents = GetTradeSkillNumReagents(id); 
746                if (numReagents == nil) then 
747                    FRC_TradeSkillLock.NeedScan = true
748                    break
749                end 
750 
751                local reagentInfo = {}
752                for i=1, numReagents do 
753                    local link = GetTradeSkillReagentItemLink(id, i); 
754                    if (link == nil) then 
755                        FRC_TradeSkillLock.NeedScan = true
756                        break
757                    else 
758                        local _, _, reagentID = string.find(link, "item:(%d+)"); 
759                        reagentID = tonumber(reagentID); 
760                        FRC_AddItemInfo(reagentID); 
761 
762                        local reagentName, reagentTexture, reagentCount, playerReagentCount = GetTradeSkillReagentInfo(id, i); 
763                        table.insert(reagentInfo, {id=reagentID, count=reagentCount}); 
764                    end 
765                end 
766                if (#reagentInfo > 0) then 
767                    FRC_AddReagentInfo(skillLineName, skillName, itemLink, reagentInfo); 
768                end 
769            end 
770        end 
771    end 
772 
773end 
774 
775function FRC_ScanCraft() 
776    if (not CraftFrame or not CraftFrame:IsVisible() or FRC_CraftLock.Locked) then return; end 
777    -- This prevents further update events from being handled if we're already processing one. 
778    -- This is done to prevent the game from freezing under certain conditions. 
779    FRC_CraftLock.Locked = true
780 
781    -- This is used only for Enchanting 
782    local skillLineName, rank, maxRank = GetCraftDisplaySkillLine(); 
783    if not (skillLineName) then 
784        return; -- Hunters' Beast Training also uses the CraftFrame, but doesn't have a SkillLine. 
785    end 
786    if (FRC_ReagentLinks == nil) then 
787        FRC_ReagentLinks = { }
788    end 
789    if (FRC_ReagentLinks[skillLineName] == nil) then 
790        FRC_ReagentLinks[skillLineName] = { }
791    end 
792 
793    local realm = GetRealmName(); 
794    local player = UnitName("player"); 
795    if (FRC_KnownRecipes == nil) then 
796        FRC_KnownRecipes = {}
797    end 
798    if (FRC_KnownRecipes[realm] == nil) then 
799        FRC_KnownRecipes[realm] = {}
800    end 
801    if (FRC_KnownRecipes[realm][player] == nil) then 
802        FRC_KnownRecipes[realm][player] = {}
803    end 
804    if (GetCraftItemNameFilter() == nil and not CraftFrameAvailableFilterCheckButton:GetChecked()) then 
805        -- only start from zero if we're sure the craft window currently shows everything known 
806        FRC_KnownRecipes[realm][player][skillLineName] = {}
807    end 
808    if (FRC_ItemInfoCache == nil) then 
809        FRC_ItemInfoCache = {}
810    end 
811    for id = GetNumCrafts(), 1, -1 do 
812        if ( craftType ~= "header" ) then 
813            craftName, craftSubSpellName, craftType, numAvailable, isExpanded, trainingPointCost, requiredLevel = GetCraftInfo(id); 
814            local itemLink = GetCraftItemLink(id); 
815            if (itemLink == nil) then 
816                FRC_TradeSkillLock.NeedScan = true
817            else 
818                local numReagents = GetCraftNumReagents(id); 
819                if (numReagents == nil) then 
820                    FRC_CraftLock.NeedScan = true
821                    break
822                end 
823 
824                local reagentInfo = {}
825                for i=1, numReagents do 
826                    local link = GetCraftReagentItemLink(id, i); 
827                    if (link == nil) then 
828                        FRC_CraftLock.NeedScan = true
829                        break
830                    else 
831                        local _, _, reagentID = string.find(link, "item:(%d+)"); 
832                        reagentID = tonumber(reagentID); 
833                        FRC_AddItemInfo(reagentID); 
834 
835                        local reagentName, reagentTexture, reagentCount, playerReagentCount = GetCraftReagentInfo(id, i); 
836                        table.insert(reagentInfo, {id=reagentID, count=reagentCount}); 
837                    end 
838                end 
839                if (#reagentInfo > 0) then 
840                    FRC_AddReagentInfo(skillLineName, craftName, itemLink, reagentInfo); 
841                end 
842            end 
843        end 
844    end 
845end 
846 
847function FRC_AddReagentInfo(tradeskill, recipe, link, reagentInfo) 
848    local realm = GetRealmName(); 
849    local player = UnitName("player"); 
850    local identifier; 
851 
852    local _, _, itemID = string.find(link, "item:(%d+)"); 
853    local _, _, enchantLink = string.find(link, "(enchant:%d+)"); 
854    if (itemID) then 
855        itemID = tonumber(itemID); 
856        FRC_AddItemInfo(itemID); 
857        identifier = itemID; 
858    elseif (enchantLink) then 
859        identifier = enchantLink; 
860    else 
861        GFWUtils.Print("ReagentCost: Can't parse link "..link.." for recipe "..recipe); 
862        return
863    end 
864 
865    table.insert(FRC_KnownRecipes[realm][player][tradeskill], identifier); 
866    FRC_ReagentLinks[tradeskill][identifier] = { }
867    FRC_ReagentLinks[tradeskill][identifier][recipe] = { }
868    for _, reagent in pairs(reagentInfo) do 
869        table.insert(FRC_ReagentLinks[tradeskill][identifier][recipe], reagent); 
870    end 
871end 
872 
873function FRC_AddItemInfo(itemID) 
874    if (FRC_ItemInfoCache[itemID] == nil) then 
875        local name, _, quality = GetItemInfo(itemID); 
876        FRC_ItemInfoCache[itemID] = { n=name, q=quality }
877    end 
878end 
879 
880function FRC_SortProfit(a, b) 
881    -- sort by ratio or actual amount based on which we're using as cutoff 
882    if (FRC_Config.MinProfitRatio) then 
883        return (a.profit / a.matsCost) > (b.profit / b.matsCost); 
884    else 
885        return a.profit > b.profit; 
886    end 
887end 
888 
889function FRC_PrintReportLine(reportInfo) 
890    local reportLine; 
891    if (string.find(reportInfo.link, "%["..reportInfo.recipe.."%]")) then 
892        reportLine = reportInfo.link..": "
893    else 
894        reportLine = reportInfo.link.." ("..reportInfo.recipe.."): "
895    end 
896    reportLine = reportLine .."mats ".. GFWUtils.TextGSC(reportInfo.matsCost) ..GFWUtils.Gray(" ("..reportInfo.matsConf.."%)")..", " 
897    reportLine = reportLine .."AH ".. GFWUtils.TextGSC(reportInfo.itemPrice) ..GFWUtils.Gray(" ("..reportInfo.itemConf.."%)")..", " 
898    if (reportInfo.profit >= 0) then 
899        reportLine = reportLine .."profit ".. GFWUtils.TextGSC(reportInfo.profit); 
900    else 
901        reportLine = reportLine ..GFWUtils.Red("loss ").. GFWUtils.TextGSC(reportInfo.profit); 
902    end 
903    GFWUtils.Print(reportLine); 
904end 
905 
906function FRC_AdjustedCost(skillName, itemID) 
907 
908    local itemPrice, itemConfidence = FRC_TypicalItemPrice(itemID); 
909    if (FRC_RecursiveItems == nil) then 
910        FRC_RecursiveItems = {}
911    end 
912    if (GFWTable.KeyOf(FRC_RecursiveItems, itemID)) then 
913        -- avoid infinite recursion 
914        FRC_RecursiveItems = nil
915        return itemPrice, itemConfidence, false
916    else 
917        table.insert(FRC_RecursiveItems, itemID); 
918    end 
919 
920    -- don't calculate sub-reagent prices for the likes of alchemical transumutes 
921    -- (recipes that take one reagent also produced by the same skill and produce one other such reagent) 
922    if (FRC_ReagentLinks[skillName] and FRC_ReagentLinks[skillName][itemID]) then 
923        for recipe, reagentsList in pairs(FRC_ReagentLinks[skillName][itemID]) do 
924            if (table.getn(reagentsList) == 1 ) then 
925                local reagentInfo = reagentsList[1]; 
926                if (reagentInfo.count == 1 and FRC_ReagentLinks[skillName][reagentInfo.id]) then 
927                    return itemPrice, itemConfidence, false
928                end 
929            end 
930        end 
931    end 
932 
933    -- for all other recipes, calculate total cost of reagents which might be produced by the same skill, 
934    -- and use that amount if it's more reliable.  
935    -- (e.g. engineering parts -> base reagents, bolts of cloth -> pieces of cloth) 
936    local subReagentsPrice, subReagentsConfidence = FRC_MaterialsCost(skillName, itemID); 
937    if (subReagentsPrice and subReagentsConfidence) then 
938        if (not (itemPrice and itemConfidence)) then 
939            return subReagentsPrice, subReagentsConfidence, true
940        end 
941        if (subReagentsConfidence >= itemConfidence and itemConfidence < MIN_OVERRIDE_CONFIDENCE and subReagentsPrice < itemPrice) then 
942            return subReagentsPrice, subReagentsConfidence, true
943        end 
944    end 
945    return itemPrice, itemConfidence, false
946end 
947 
948function FRC_MaterialsCost(skillName, itemID) 
949    if (FRC_ReagentLinks[skillName] == nil) then 
950        return nil, nil
951    end 
952    if (FRC_ReagentLinks[skillName][itemID] == nil) then 
953        return nil, nil
954    end 
955 
956    local pricesPerRecipe = {}
957    for recipe in pairs(FRC_ReagentLinks[skillName][itemID]) do 
958        if (type(recipe) == "string") then 
959            local cost, confidence = FRC_MaterialsCostForRecipe(skillName, itemID, recipe); 
960            if (cost) then 
961                table.insert(pricesPerRecipe, {cost=cost, confidence=confidence}); 
962            end 
963        end 
964    end 
965    if (table.getn(pricesPerRecipe) == 0) then 
966        return nil, nil
967    end 
968 
969    local sortCost = function(a,b) 
970        return a.cost < b.cost; 
971    end 
972    local sortConfidence = function(a,b) 
973        return a.confidence > b.confidence; 
974    end 
975    table.sort(pricesPerRecipe, sortConfidence); 
976    table.sort(pricesPerRecipe, sortCost); 
977 
978    return pricesPerRecipe[1].cost, pricesPerRecipe[1].confidence; 
979 
980end 
981 
982function FRC_MaterialsCostForRecipe(skillName, itemID, recipeName) 
983    local materialsTotal = 0
984    local totalConfidence = 0
985    local numAuctionReagents = 0
986 
987    if (FRC_ReagentLinks[skillName] == nil) then 
988        return nil, nil
989    end 
990    if (FRC_ReagentLinks[skillName][itemID] == nil) then 
991        return nil, nil
992    end 
993    if (FRC_ReagentLinks[skillName][itemID][recipeName] == nil) then 
994        return nil, nil
995    end 
996 
997    for _, reagentInfo in pairs(FRC_ReagentLinks[skillName][itemID][recipeName]) do 
998        local price, confidence = FRC_AdjustedCost(skillName, reagentInfo.id); 
999        if (price == nil) then 
1000            return nil, nil; -- if any of the reagents is missing price info, we can't calculate a total. 
1001        end 
1002        materialsTotal = materialsTotal + (price * reagentInfo.count); 
1003        if (confidence >= 0) then 
1004            totalConfidence = totalConfidence + confidence; 
1005            numAuctionReagents = numAuctionReagents + 1
1006        end 
1007    end 
1008    local confidenceScore = math.floor(totalConfidence / numAuctionReagents); 
1009 
1010    return materialsTotal, confidenceScore; 
1011 
1012end 
1013 
1014function FRC_TypicalItemPrice(itemID) 
1015    if (itemID == nil) then 
1016        return nil
1017    end 
1018    if (FRC_PriceSource == "Auctioneer") then 
1019        if (not IsAddOnLoaded("Auc-Advanced")) then 
1020            if (FRC_Config.AutoLoadPriceSource) then 
1021                local loaded, reason = LoadAddOn("Auc-Advanced"); 
1022                if (not loaded) then 
1023                    GFWUtils.Print("Can't load Auctioneer: "..reason); 
1024                    return nil
1025                end 
1026            else 
1027                return nil
1028            end 
1029        end 
1030        return FRC_AuctioneerItemPrice(itemID); 
1031    elseif (FRC_PriceSource == "KC_Items") then 
1032        return FRC_KCItemPrice(itemID); 
1033    elseif (FRC_PriceSource == "AuctionMatrix") then 
1034        return FRC_AuctionMatrixItemPrice(itemID); 
1035    elseif (FRC_PriceSource == "WOWEcon_PriceMod") then 
1036        return FRC_WOWEcon_PriceModItemPrice(itemID); 
1037    else 
1038        return nil
1039    end 
1040end 
1041 
1042function FRC_AuctioneerItemPrice(itemID) 
1043    if itemID == nil then return end 
1044 
1045    local itemLink = FRC_GetItemLink(itemID); 
1046    local Realm = GetCVar("realmName"
1047    local Faction, _= UnitFactionGroup("player"
1048    local serverKey = Realm.."-"..Faction 
1049    local medianPrice, medianCount, getVendorSellPrice; 
1050 
1051 
1052    medianPrice, medianCount, _ = AucAdvanced.API.GetMarketValue(itemLink,serverKey) 
1053 
1054   getVendorSellPrice = GetSellValue(itemId) 
1055 
1056    if (medianCount == nil) then medianCount = 0 end 
1057 
1058    local buyFromVendorPrice = 0
1059    if (FRC_VendorPrices[itemID]) then 
1060       buyFromVendorPrice = FRC_VendorPrices[itemID].b; 
1061    end 
1062 
1063    if (buyFromVendorPrice > 0) then 
1064        return buyFromVendorPrice, -1; -- FRC_VendorPrices lists only the primarily-vendor-bought tradeskill items 
1065    elseif (medianCount == 0 or medianPrice == nil) then 
1066        local sellToVendorPrice = 0
1067        if (getVendorSellPrice) then 
1068            sellToVendorPrice = getVendorSellPrice(itemID) or 0
1069        end 
1070        if (sellToVendorPrice == 0 and FRC_VendorPrices[itemID]) then 
1071            sellToVendorPrice = FRC_VendorPrices[itemID].s; 
1072       end 
1073        return sellToVendorPrice * 3, 0; -- generally a good guess for auction price if we don't have real auction data 
1074    else 
1075        return medianPrice, math.floor(math.min(medianCount, MIN_SCANS) / MIN_SCANS * 100); 
1076   end 
1077 
1078end 
1079 
1080-- TODO: update KC_Items import, check whether it can use just itemID 
1081function FRC_KCItemPrice(itemLink) 
1082    local itemCode = KC_Common:GetCode(itemLink); 
1083    local seen, avgstack, min, bidseen, bid, buyseen, buy = KC_Auction:GetItemData(itemCode); 
1084    local _, _, itemID  = string.find(itemLink, ".Hitem:(%d+):%d+:%d+:%d+.h%[[^]]+%].h"); 
1085    itemID = tonumber(itemID) or 0
1086 
1087    local buyFromVendorPrice = 0
1088    local sellToVendorPrice = 0
1089    if (FRC_VendorPrices[itemID]) then 
1090        buyFromVendorPrice = FRC_VendorPrices[itemID].b; 
1091        sellToVendorPrice = FRC_VendorPrices[itemID].s; 
1092    end 
1093    if (sellToVendorPrice == 0 and KC_SellValue) then 
1094        sellToVendorPrice = (KC_Common:GetItemPrices(itemCode) or 0); 
1095    end 
1096 
1097    --DevTools_Dump({itemLink=itemLink, itemID=itemID, buy=buy, buyseen=buyseen, buyFromVendorPrice=buyFromVendorPrice, sellToVendorPrice=sellToVendorPrice}); 
1098 
1099    if (buyFromVendorPrice and buyFromVendorPrice > 0) then 
1100        return buyFromVendorPrice, -1; -- FRC_VendorPrices lists only the primarily-vendor-bought tradeskill items 
1101    elseif (buy and buy > 0) then 
1102        return buy, math.floor((math.min(buyseen, MIN_SCANS) / MIN_SCANS) * 1000) / 10
1103    elseif (sellToVendorPrice and sellToVendorPrice > 0) then 
1104        return sellToVendorPrice * 3, 0; -- generally a good guess for auction price if we don't have real auction data 
1105    else 
1106        GFWUtils.DebugLog(itemLink.." not found in KC_Auction or vendor-reagent prices list"); 
1107        return nil, 0
1108    end 
1109end 
1110 
1111-- TODO: replace AuctionMatrix import with AuctionSync 
1112function FRC_AuctionMatrixItemPrice(itemLink) 
1113    local _, _, itemID, itemName  = string.find(itemLink, ".Hitem:(%d+):%d+:%d+:%d+.h%[([^]]+)%].h"); 
1114    local buyFromVendorPrice = 0
1115    local sellToVendorPrice = 0
1116    itemID = tonumber(itemID) or 0
1117    if (FRC_VendorPrices[itemID]) then 
1118        buyFromVendorPrice = FRC_VendorPrices[itemID].b; 
1119        sellToVendorPrice = FRC_VendorPrices[itemID].s; 
1120    end 
1121 
1122    local buyout, times, storeStack; 
1123    if (itemName and itemName ~= "" and AMDB[itemName]) then 
1124        buyout = tonumber(AM_GetMedian(itemName, "abuyout")); 
1125        if (buyout == nil) then 
1126            buyout = tonumber(AuctionMatrix_GetData(itemName, "abuyout")); 
1127        end 
1128        times = tonumber(AuctionMatrix_GetData(itemName, "times")); 
1129        storeStack = tonumber(AuctionMatrix_GetData(itemName, "stack")); 
1130        if (sellToVendorPrice == 0) then 
1131            sellToVendorPrice = tonumber(AuctionMatrix_GetData(itemName, "vendor")); 
1132        end 
1133    end 
1134 
1135    --DevTools_Dump({itemLink=itemLink, buyout=buyout, times=times, buyFromVendorPrice=buyFromVendorPrice, sellToVendorPrice=sellToVendorPrice}); 
1136 
1137    if (buyFromVendorPrice and buyFromVendorPrice > 0) then 
1138        return buyFromVendorPrice, -1; -- FRC_VendorPrices lists only the primarily-vendor-bought tradeskill items 
1139    elseif (buyout and times and buyout > 0) then 
1140        local buyoutForOne = buyout; 
1141        if (storeStack and storeStack > 0) then 
1142            buyoutForOne = math.floor(buyout/storeStack); 
1143        end 
1144        return buyoutForOne, math.floor((math.min(times, MIN_SCANS) / MIN_SCANS) * 1000) / 10
1145    elseif (sellToVendorPrice and sellToVendorPrice > 0) then 
1146        return sellToVendorPrice * 3, 0; -- generally a good guess for auction price if we don't have real auction data 
1147    end 
1148 
1149    GFWUtils.DebugLog(itemLink.." not found in AuctionMatrix or vendor-reagent prices list"); 
1150    return nil, 0
1151end 
1152 
1153-- TODO: check whether WoWEcon can use just itemID 
1154function FRC_WOWEcon_PriceModItemPrice(itemLink) 
1155    local medianPrice, medianCount, serverData = WOWEcon_GetAuctionPrice_ByLink(itemLink); 
1156    if (medianCount == nil) then 
1157        medianCount = 0
1158    end 
1159 
1160    local _, _, itemID  = string.find(itemLink, ".Hitem:(%d+):%d+:%d+:%d+.h%[[^]]+%].h"); 
1161    itemID = tonumber(itemID) or 0
1162 
1163    local buyFromVendorPrice = 0
1164    local sellToVendorPrice = 0
1165    if (FRC_VendorPrices[itemID]) then 
1166        buyFromVendorPrice = FRC_VendorPrices[itemID].b; 
1167        sellToVendorPrice = FRC_VendorPrices[itemID].s; 
1168    end 
1169 
1170    if (sellToVendorPrice == 0) then 
1171        sellToVendorPrice = WOWEcon_GetVendorPrice_ByLink(itemLink); 
1172    end 
1173 
1174    if (sellToVendorPrice == nil) then sellToVendorPrice = 0 end 
1175 
1176    if (buyFromVendorPrice > 0) then 
1177        return buyFromVendorPrice, -1; -- FRC_VendorPrices lists only the primarily-vendor-bought tradeskill items 
1178    elseif (medianCount == 0 or medianPrice == nil) then 
1179        return sellToVendorPrice * 3, 0; -- generally a good guess for auction price if we don't have real auction data 
1180    else 
1181        return medianPrice, math.floor((math.min(medianCount, MIN_SCANS) / MIN_SCANS) * 1000) / 10
1182    end 
1183end 
1184 
1185function FRC_GetItemInfo(itemID) 
1186    local name, link, quality = GetItemInfo(itemID); 
1187    local isCached = (name ~= nil); 
1188    if (name == nil and FRC_ItemInfoCache[itemID]) then 
1189        name = FRC_ItemInfoCache[itemID].n; 
1190        quality = FRC_ItemInfoCache[itemID].q; 
1191        link = "item:"..itemID; 
1192    end 
1193    return name, link, quality, isCached; 
1194end 
1195 
1196function FRC_GetItemLink(itemID) 
1197    local name, link, quality, isCached = FRC_GetItemInfo(itemID); 
1198    if (string.find(link, "|c%x+|Hitem:[-%d:]+|h%[.-%]|h|r")) then 
1199        return link; 
1200    elseif (isCached) then 
1201        local _, _, _, color = GetItemQualityColor(quality); 
1202        local linkFormat = "%s|H%s|h[%s]|h|r"
1203        return string.format(linkFormat, color, link, name); 
1204    else 
1205        local _, _, _, color = GetItemQualityColor(quality); 
1206        return color..name..FONT_COLOR_CODE_CLOSE; 
1207    end 
1208end 
1209 
Download and save
Toggle line numbers
Thread:
[73636] Re: Temp AucAdvance fix for Reagent cost by Kandoko at 2007-09-09 17:08:45
Tip: Click the line numbers to toggle highliting on that line.

Paste followup:

Language:
Author:
Subject:


    Tabstop:     bigger biggest
Note: You can prefix a line with "@@@" to highlight it.