init
This commit is contained in:
@@ -0,0 +1,185 @@
|
||||
-- ------------------------------------------------------------------------------ --
|
||||
-- TradeSkillMaster_AuctionDB --
|
||||
-- http://www.curse.com/addons/wow/tradeskillmaster_auctiondb --
|
||||
-- --
|
||||
-- A TradeSkillMaster Addon (http://tradeskillmaster.com) --
|
||||
-- All Rights Reserved* - Detailed license information included with addon. --
|
||||
-- ------------------------------------------------------------------------------ --
|
||||
|
||||
-- load the parent file (TSM) into a local variable and register this file as a module
|
||||
local TSM = select(2, ...)
|
||||
local GUI = TSM:NewModule("GUI")
|
||||
local L = LibStub("AceLocale-3.0"):GetLocale("TradeSkillMaster_AuctionDB") -- loads the localization table
|
||||
|
||||
local private = {}
|
||||
|
||||
function GUI:Show(frame)
|
||||
private.statusBar = private.statusBar or private:CreateStatusBar(frame.content)
|
||||
private.statusBar:Show()
|
||||
GUI:UpdateStatus("", 0, 0)
|
||||
|
||||
private.startScanContent = private.startScanContent or private:CreateStartScanContent(frame)
|
||||
private.startScanContent:Show()
|
||||
end
|
||||
|
||||
function GUI:Hide()
|
||||
private.statusBar:Hide()
|
||||
private.startScanContent:Hide()
|
||||
|
||||
TSM.Scan:DoneScanning()
|
||||
TSMAPI.AuctionScan:StopScan()
|
||||
end
|
||||
|
||||
function GUI:UpdateStatus(text, major, minor)
|
||||
if text then
|
||||
private.statusBar:SetStatusText(text)
|
||||
end
|
||||
if major or minor then
|
||||
private.statusBar:UpdateStatus(major, minor)
|
||||
end
|
||||
end
|
||||
|
||||
function private:CreateStatusBar(parent)
|
||||
local frame = TSMAPI.GUI:CreateStatusBar(parent, "TSMAuctionDBStatusBar")
|
||||
TSMAPI.GUI:CreateHorizontalLine(frame, -30, parent)
|
||||
|
||||
return frame
|
||||
end
|
||||
|
||||
function private:CreateStartScanContent(parent)
|
||||
local frame = CreateFrame("Frame", nil, parent)
|
||||
frame:SetAllPoints(parent)
|
||||
frame:Hide()
|
||||
|
||||
local function UpdateGetAllButton()
|
||||
if TSM.Scan.isScanning then
|
||||
frame:Disable()
|
||||
elseif not select(2, CanSendAuctionQuery()) then
|
||||
local previous = TSM.db.profile.lastGetAll or time()
|
||||
if previous > (time() - 15*60) then
|
||||
local diff = previous + 15*60 - time()
|
||||
local diffMin = math.floor(diff/60)
|
||||
local diffSec = diff - diffMin*60
|
||||
frame.getAllStatusText:SetText("|cff990000"..format(L["Ready in %s min and %s sec"], diffMin, diffSec))
|
||||
else
|
||||
frame.getAllStatusText:SetText("|cff990000"..L["Not Ready"])
|
||||
end
|
||||
frame:Enable()
|
||||
frame.startGetAllButton:Disable()
|
||||
else
|
||||
frame:Enable()
|
||||
frame.getAllStatusText:SetText("|cff009900"..L["Ready"])
|
||||
frame.startGetAllButton:Enable()
|
||||
end
|
||||
end
|
||||
|
||||
frame:SetScript("OnShow", function(self)
|
||||
TSMAPI:CreateTimeDelay("auctionDBGetAllStatus", 0, UpdateGetAllButton, 0.2)
|
||||
end)
|
||||
|
||||
frame:SetScript("OnHide", function(self)
|
||||
TSMAPI:CancelFrame("auctionDBGetAllStatus")
|
||||
end)
|
||||
|
||||
frame.Enable = function(self)
|
||||
self.startGetAllButton:Enable()
|
||||
self.startFullScanButton:Enable()
|
||||
self.startGroupScanButton:Enable()
|
||||
end
|
||||
|
||||
frame.Disable = function(self)
|
||||
self.startGetAllButton:Disable()
|
||||
self.startFullScanButton:Disable()
|
||||
self.startGroupScanButton:Disable()
|
||||
end
|
||||
|
||||
-- top row (auto updater)
|
||||
local text = TSMAPI.GUI:CreateLabel(frame)
|
||||
text:SetFont(TSMAPI.Design:GetContentFont(), 24)
|
||||
text:SetPoint("TOP", 0, -24)
|
||||
text:SetHeight(24)
|
||||
text:SetJustifyH("CENTER")
|
||||
text:SetJustifyV("CENTER")
|
||||
text:SetText(TSMAPI.Design:GetInlineColor("link").."TSM_AuctionDB")
|
||||
local ag = text:CreateAnimationGroup()
|
||||
local a1 = ag:CreateAnimation("Alpha")
|
||||
a1:SetChange(-.5)
|
||||
a1:SetDuration(.5)
|
||||
ag:SetLooping("BOUNCE")
|
||||
ag:Play()
|
||||
|
||||
local content = CreateFrame("Frame", nil, frame)
|
||||
content:SetAllPoints(parent.content)
|
||||
TSMAPI.Design:SetFrameBackdropColor(content)
|
||||
|
||||
-- group tree
|
||||
local container = CreateFrame("Frame", nil, content)
|
||||
container:SetPoint("TOPLEFT", 5, -35)
|
||||
container:SetPoint("BOTTOMRIGHT", -205, 5)
|
||||
TSMAPI.Design:SetFrameColor(container)
|
||||
frame.groupTree = TSMAPI:CreateGroupTree(container, nil, "AuctionDB")
|
||||
|
||||
local bar = TSMAPI.GUI:CreateVerticalLine(content, 0)
|
||||
bar:ClearAllPoints()
|
||||
bar:SetPoint("TOPRIGHT", -200, -30)
|
||||
bar:SetPoint("BOTTOMRIGHT", -200, 0)
|
||||
|
||||
local buttonFrame = CreateFrame("Frame", nil, content)
|
||||
buttonFrame:SetPoint("TOPLEFT", content, "TOPRIGHT", -200, 0)
|
||||
buttonFrame:SetPoint("BOTTOMRIGHT")
|
||||
|
||||
-- first row (getall scan)
|
||||
local btn = TSMAPI.GUI:CreateButton(buttonFrame, 18)
|
||||
btn:SetPoint("TOPLEFT", 6, -50)
|
||||
btn:SetPoint("TOPRIGHT", -6, -50)
|
||||
btn:SetHeight(22)
|
||||
btn:SetScript("OnClick", TSM.Scan.StartGetAllScan)
|
||||
btn:SetText(L["Run GetAll Scan"])
|
||||
btn.tooltip = L["A GetAll scan is the fastest in-game method for scanning every item on the auction house. However, there are many possible bugs on Blizzard's end with it including the chance for it to disconnect you from the game. Also, it has a 15 minute cooldown."]
|
||||
frame.startGetAllButton = btn
|
||||
|
||||
local text = TSMAPI.GUI:CreateLabel(buttonFrame)
|
||||
text:SetPoint("TOPLEFT", btn, "BOTTOMLEFT", 0, -3)
|
||||
text:SetPoint("TOPRIGHT", btn, "BOTTOMRIGHT", 0, -3)
|
||||
text:SetHeight(16)
|
||||
text:SetJustifyH("CENTER")
|
||||
text:SetJustifyV("CENTER")
|
||||
frame.getAllStatusText = text
|
||||
|
||||
TSMAPI.GUI:CreateHorizontalLine(buttonFrame, -110)
|
||||
|
||||
-- second row (full scan)
|
||||
local btn = TSMAPI.GUI:CreateButton(buttonFrame, 18)
|
||||
btn:SetPoint("TOPLEFT", 6, -150)
|
||||
btn:SetPoint("TOPRIGHT", -6, -150)
|
||||
btn:SetHeight(22)
|
||||
btn:SetScript("OnClick", TSM.Scan.StartFullScan)
|
||||
btn:SetText(L["Run Full Scan"])
|
||||
btn.tooltip = L["A full auction house scan will scan every item on the auction house but is far slower than a GetAll scan. Expect this scan to take several minutes or longer."]
|
||||
frame.startFullScanButton = btn
|
||||
|
||||
TSMAPI.GUI:CreateHorizontalLine(buttonFrame, -200)
|
||||
|
||||
-- third row (group scan)
|
||||
local btn = TSMAPI.GUI:CreateButton(buttonFrame, 18)
|
||||
btn:SetPoint("TOPLEFT", 6, -225)
|
||||
btn:SetPoint("TOPRIGHT", -6, -225)
|
||||
btn:SetHeight(22)
|
||||
btn:SetScript("OnClick", GUI.StartGroupScan)
|
||||
btn:SetText(L["Scan Selected Groups"])
|
||||
btn.tooltip = L["This will do a slow auction house scan of every item in the selected groups and update their AuctionDB prices. This may take several minutes."]
|
||||
frame.startGroupScanButton = btn
|
||||
|
||||
return frame
|
||||
end
|
||||
|
||||
function GUI:StartGroupScan()
|
||||
local items = {}
|
||||
for groupName, data in pairs(private.startScanContent.groupTree:GetSelectedGroupInfo()) do
|
||||
groupName = TSMAPI:FormatGroupPath(groupName, true)
|
||||
for itemString in pairs(data.items) do
|
||||
tinsert(items, itemString)
|
||||
end
|
||||
end
|
||||
TSM.Scan:StartGroupScan(items)
|
||||
end
|
||||
@@ -0,0 +1,229 @@
|
||||
-- ------------------------------------------------------------------------------ --
|
||||
-- TradeSkillMaster_AuctionDB --
|
||||
-- http://www.curse.com/addons/wow/tradeskillmaster_auctiondb --
|
||||
-- --
|
||||
-- A TradeSkillMaster Addon (http://tradeskillmaster.com) --
|
||||
-- All Rights Reserved* - Detailed license information included with addon. --
|
||||
-- ------------------------------------------------------------------------------ --
|
||||
|
||||
-- load the parent file (TSM) into a local variable and register this file as a module
|
||||
local TSM = select(2, ...)
|
||||
local Scan = TSM:NewModule("Scan", "AceEvent-3.0")
|
||||
local L = LibStub("AceLocale-3.0"):GetLocale("TradeSkillMaster_AuctionDB") -- loads the localization table
|
||||
|
||||
Scan.groupScanData = {}
|
||||
Scan.filterList = {}
|
||||
Scan.numFilters = 0
|
||||
|
||||
|
||||
local function ScanCallback(event, ...)
|
||||
if event == "SCAN_PAGE_UPDATE" then
|
||||
local page, total = ...
|
||||
TSM.GUI:UpdateStatus(format(L["Scanning page %s/%s"], page, total), page*100/total)
|
||||
elseif event == "SCAN_COMPLETE" then
|
||||
local data = ...
|
||||
Scan:ProcessScanData(data)
|
||||
Scan:DoneScanning()
|
||||
elseif event == "INTERRUPTED" then
|
||||
Scan:DoneScanning()
|
||||
end
|
||||
end
|
||||
|
||||
function Scan.ProcessGetAllScan(self)
|
||||
local temp = 0
|
||||
while true do
|
||||
temp = min(temp + 1, 100)
|
||||
self:Sleep(0.2)
|
||||
if not Scan.isScanning then return end
|
||||
if Scan.getAllLoaded then
|
||||
break
|
||||
end
|
||||
TSM.GUI:UpdateStatus(L["Running query..."], nil, temp)
|
||||
end
|
||||
|
||||
local data = {}
|
||||
for i=1, Scan.getAllLoaded do
|
||||
TSM.GUI:UpdateStatus(format(L["Scanning page %s/%s"], 1, 1), i*100/Scan.getAllLoaded)
|
||||
if i % 100 == 0 then
|
||||
self:Yield()
|
||||
if GetNumAuctionItems("list") ~= Scan.getAllLoaded then
|
||||
--TSM:Print(L["GetAll scan did not run successfully due to issues on Blizzard's end. Using the TSM application for your scans is recommended."])
|
||||
TSM:Print("GetAll scan did not run successfully.")
|
||||
Scan:DoneScanning()
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
local itemID = TSMAPI:GetItemID(GetAuctionItemLink("list", i))
|
||||
--local _, _, count, _, _, _, _, _, _, buyout = GetAuctionItemInfo("list", i)
|
||||
local _, _, count, _, _, _, _, _, buyout = GetAuctionItemInfo("list", i)
|
||||
if itemID and buyout and buyout > 0 then
|
||||
data[itemID] = data[itemID] or {records={}, minBuyout=math.huge, quantity=0}
|
||||
data[itemID].minBuyout = min(data[itemID].minBuyout, floor(buyout/count))
|
||||
data[itemID].quantity = data[itemID].quantity + count
|
||||
for j=1, count do
|
||||
tinsert(data[itemID].records, floor(buyout/count))
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
TSM.db.factionrealm.lastCompleteScan = time()
|
||||
TSM.Data:ProcessData(data)
|
||||
|
||||
TSM.GUI:UpdateStatus(L["Processing data..."])
|
||||
while TSM.processingData do
|
||||
self:Sleep(0.2)
|
||||
end
|
||||
|
||||
TSM:Print(L["It is strongly recommended that you reload your ui (type '/reload') after running a GetAll scan. Otherwise, any other scans (Post/Cancel/Search/etc) will be much slower than normal."])
|
||||
end
|
||||
|
||||
function Scan:AUCTION_ITEM_LIST_UPDATE()
|
||||
Scan:UnregisterEvent("AUCTION_ITEM_LIST_UPDATE")
|
||||
local num, total = GetNumAuctionItems("list")
|
||||
|
||||
--if num ~= total or num == 0 then
|
||||
if num == 0 then
|
||||
--TSM:Print(L["GetAll scan did not run successfully due to issues on Blizzard's end. Using the TSM application for your scans is recommended."])
|
||||
TSM:Print("GetAll scan did not run successfully.")
|
||||
Scan:DoneScanning()
|
||||
return
|
||||
end
|
||||
Scan.getAllLoaded = num
|
||||
end
|
||||
|
||||
function Scan:GetAllScanQuery()
|
||||
local canScan, canGetAll = CanSendAuctionQuery()
|
||||
if not canGetAll then return TSM:Print(L["Can't run a GetAll scan right now."]) end
|
||||
if not canScan then return TSMAPI:CreateTimeDelay(0.5, Scan.GetAllScanQuery) end
|
||||
QueryAuctionItems("", nil, nil, nil, nil, nil, nil, nil, nil, true)
|
||||
Scan:RegisterEvent("AUCTION_ITEM_LIST_UPDATE")
|
||||
TSMAPI.Threading:Start(Scan.ProcessGetAllScan, 1, function() Scan:DoneScanning() end)
|
||||
end
|
||||
|
||||
local function GroupScanCallback(event, ...)
|
||||
if event == "QUERY_COMPLETE" then
|
||||
local filterList = ...
|
||||
local numItems = 0
|
||||
for _, v in ipairs(filterList) do
|
||||
numItems = numItems + #v.items
|
||||
end
|
||||
Scan.filterList = filterList
|
||||
Scan.numFilters = #filterList
|
||||
Scan:ScanNextGroupFilter()
|
||||
elseif event == "QUERY_UPDATE" then
|
||||
local current, total = ...
|
||||
TSM.GUI:UpdateStatus(format(L["Preparing Filter %d / %d"], current, total))
|
||||
elseif event == "SCAN_INTERRUPTED" then
|
||||
Scan:DoneScanning()
|
||||
elseif event == "SCAN_TIMEOUT" then
|
||||
tremove(Scan.filterList, 1)
|
||||
Scan:ScanNextGroupFilter()
|
||||
elseif event == "SCAN_PAGE_UPDATE" then
|
||||
local page, total = ...
|
||||
TSM.GUI:UpdateStatus(format(L["Scanning %d / %d (Page %d / %d)"], Scan.numFilters-#Scan.filterList, Scan.numFilters, page+1, total), nil, page*100/total)
|
||||
elseif event == "SCAN_COMPLETE" then
|
||||
local data = ...
|
||||
for _, itemString in ipairs(Scan.filterList[1].items) do
|
||||
if not Scan.groupScanData[itemString] then
|
||||
Scan.groupScanData[itemString] = data[itemString]
|
||||
end
|
||||
end
|
||||
tremove(Scan.filterList, 1)
|
||||
Scan:ScanNextGroupFilter()
|
||||
end
|
||||
end
|
||||
|
||||
function Scan:ScanNextGroupFilter(data)
|
||||
if #Scan.filterList == 0 then
|
||||
Scan:ProcessScanData(Scan.groupScanData)
|
||||
Scan:DoneScanning()
|
||||
return
|
||||
end
|
||||
TSM.GUI:UpdateStatus(format(L["Scanning %d / %d (Page %d / %d)"], Scan.numFilters-#Scan.filterList, Scan.numFilters, 1, 1), (Scan.numFilters-#Scan.filterList)*100/Scan.numFilters)
|
||||
TSMAPI.AuctionScan:RunQuery(Scan.filterList[1], GroupScanCallback)
|
||||
end
|
||||
|
||||
function Scan:StartGroupScan(items)
|
||||
Scan.isScanning = "Group"
|
||||
Scan.isBuggedGetAll = nil
|
||||
Scan.groupItems = items
|
||||
wipe(Scan.filterList)
|
||||
wipe(Scan.groupScanData)
|
||||
Scan.numFilters = 0
|
||||
TSMAPI.AuctionScan:StopScan()
|
||||
TSMAPI:GenerateQueries(items, GroupScanCallback)
|
||||
TSM.GUI:UpdateStatus(L["Preparing Filters..."])
|
||||
end
|
||||
|
||||
function Scan:StartFullScan()
|
||||
Scan.isScanning = "Full"
|
||||
TSM.GUI:UpdateStatus(L["Running query..."])
|
||||
Scan.isBuggedGetAll = nil
|
||||
Scan.groupItems = nil
|
||||
TSMAPI.AuctionScan:StopScan()
|
||||
TSMAPI.AuctionScan:RunQuery({name=""}, ScanCallback)
|
||||
end
|
||||
|
||||
function Scan:StartGetAllScan()
|
||||
TSM.db.profile.lastGetAll = time()
|
||||
Scan.isScanning = "GetAll"
|
||||
Scan.isBuggedGetAll = nil
|
||||
Scan.groupItems = nil
|
||||
TSMAPI.AuctionScan:StopScan()
|
||||
Scan:GetAllScanQuery()
|
||||
end
|
||||
|
||||
function Scan:DoneScanning()
|
||||
TSM.GUI:UpdateStatus(L["Done Scanning"], 100)
|
||||
Scan.isScanning = nil
|
||||
Scan.getAllLoaded = nil
|
||||
end
|
||||
|
||||
function Scan:ProcessScanData(scanData)
|
||||
local data = {}
|
||||
|
||||
for itemString, obj in pairs(scanData) do
|
||||
if TSMAPI:GetBaseItemString(itemString) == itemString then
|
||||
local itemID = obj:GetItemID()
|
||||
local quantity, minBuyout = 0, 0
|
||||
local records = {}
|
||||
for _, record in ipairs(obj.records) do
|
||||
local itemBuyout = record:GetItemBuyout()
|
||||
if itemBuyout and (itemBuyout < minBuyout or minBuyout == 0) then
|
||||
minBuyout = itemBuyout
|
||||
end
|
||||
quantity = quantity + record.count
|
||||
for i=1, record.count do
|
||||
tinsert(records, itemBuyout)
|
||||
end
|
||||
end
|
||||
data[itemID] = {records=records, minBuyout=minBuyout, quantity=quantity}
|
||||
end
|
||||
end
|
||||
|
||||
if Scan.isScanning ~= "group" then
|
||||
TSM.db.factionrealm.lastCompleteScan = time()
|
||||
end
|
||||
TSM.Data:ProcessData(data, Scan.groupItems)
|
||||
end
|
||||
|
||||
function Scan:ProcessImportedData(auctionData)
|
||||
local data = {}
|
||||
for itemID, auctions in pairs(auctionData) do
|
||||
local quantity, minBuyout, records = 0, 0, {}
|
||||
for _, auction in ipairs(auctions) do
|
||||
local itemBuyout, count = unpack(auction)
|
||||
if itemBuyout and (itemBuyout < minBuyout or minBuyout == 0) then
|
||||
minBuyout = itemBuyout
|
||||
end
|
||||
quantity = quantity + count
|
||||
for i=1, count do
|
||||
tinsert(records, itemBuyout)
|
||||
end
|
||||
end
|
||||
data[itemID] = {records=records, minBuyout=minBuyout, quantity=quantity}
|
||||
end
|
||||
TSM.db.factionrealm.lastCompleteScan = time()
|
||||
TSM.Data:ProcessData(data)
|
||||
end
|
||||
@@ -0,0 +1,489 @@
|
||||
-- ------------------------------------------------------------------------------ --
|
||||
-- TradeSkillMaster_AuctionDB --
|
||||
-- http://www.curse.com/addons/wow/tradeskillmaster_auctiondb --
|
||||
-- --
|
||||
-- A TradeSkillMaster Addon (http://tradeskillmaster.com) --
|
||||
-- All Rights Reserved* - Detailed license information included with addon. --
|
||||
-- ------------------------------------------------------------------------------ --
|
||||
|
||||
-- load the parent file (TSM) into a local variable and register this file as a module
|
||||
local TSM = select(2, ...)
|
||||
local Config = TSM:NewModule("Config", "AceHook-3.0")
|
||||
local AceGUI = LibStub("AceGUI-3.0")
|
||||
local L = LibStub("AceLocale-3.0"):GetLocale("TradeSkillMaster_AuctionDB") -- loads the localization table
|
||||
|
||||
local searchPage = 0
|
||||
local filter = { text = nil, class = nil, subClass = nil }
|
||||
local items = {}
|
||||
|
||||
-- options page
|
||||
function Config:Load(parent)
|
||||
filter = {}
|
||||
|
||||
local tg = AceGUI:Create("TSMTabGroup")
|
||||
tg:SetLayout("Fill")
|
||||
tg:SetFullHeight(true)
|
||||
tg:SetFullWidth(true)
|
||||
tg:SetTabs({ { value = 1, text = SEARCH }, { value = 2, text = L["Options"] } })
|
||||
tg:SetCallback("OnGroupSelected", function(self, _, value)
|
||||
tg:ReleaseChildren()
|
||||
parent:DoLayout()
|
||||
|
||||
if value == 1 then
|
||||
Config:LoadSearch(tg)
|
||||
elseif value == 2 then
|
||||
Config:LoadOptions(tg)
|
||||
end
|
||||
tg.children[1]:DoLayout()
|
||||
end)
|
||||
parent:AddChild(tg)
|
||||
tg:SelectTab(1)
|
||||
end
|
||||
|
||||
function Config:UpdateItems()
|
||||
wipe(items)
|
||||
local cache = {}
|
||||
local sortMethod = TSM.db.profile.resultsSortMethod
|
||||
local fClass = filter.class and select(filter.class, GetAuctionItemClasses())
|
||||
local fSubClass = filter.subClass and select(filter.subClass, GetAuctionItemSubClasses(filter.class))
|
||||
if filter.text or fClass then
|
||||
for itemID, data in pairs(TSM.data) do
|
||||
TSM:DecodeItemData(itemID)
|
||||
local name, _, rarity, ilvl, minlvl, class, subClass = GetItemInfo(itemID)
|
||||
if (name and filter.text and strfind(strlower(name), strlower(filter.text))) and (not fClass or (class == fClass and (not fSubClass or subClass == fSubClass))) and (not TSM.db.profile.hidePoorQualityItems or rarity > 0) then
|
||||
tinsert(items, itemID)
|
||||
if sortMethod == "name" then
|
||||
cache[itemID] = name
|
||||
elseif sortMethod == "ilvl" then
|
||||
cache[itemID] = ilvl
|
||||
elseif sortMethod == "minlvl" then
|
||||
cache[itemID] = minlvl
|
||||
elseif sortMethod == "marketvalue" then
|
||||
cache[itemID] = data.marketValue
|
||||
elseif sortMethod == "minbuyout" then
|
||||
cache[itemID] = data.minBuyout
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if TSM.db.profile.resultsSortOrder == "ascending" then
|
||||
sort(items, function(a, b) return (cache[a] or math.huge) < (cache[b] or math.huge) end)
|
||||
else
|
||||
sort(items, function(a, b) return (cache[a] or 0) > (cache[b] or 0) end)
|
||||
end
|
||||
end
|
||||
|
||||
function Config:LoadSearch(container)
|
||||
local searchDataTmp = Config:GetSearchData()
|
||||
local results = {}
|
||||
local totalResults = #items
|
||||
local minIndex = searchPage * TSM.db.profile.resultsPerPage + 1
|
||||
local maxIndex = min(TSM.db.profile.resultsPerPage * (searchPage + 1), totalResults)
|
||||
if totalResults == 0 then
|
||||
if filter.text then
|
||||
results = {
|
||||
{
|
||||
type = "Spacer",
|
||||
quantity = 2,
|
||||
},
|
||||
{
|
||||
type = "Label",
|
||||
relativeWidth = 0.4
|
||||
},
|
||||
{
|
||||
type = "Label",
|
||||
relativeWidth = 0.6,
|
||||
text = L["No items found"],
|
||||
fontObject = GameFontNormalLarge,
|
||||
},
|
||||
}
|
||||
else
|
||||
results = {
|
||||
{
|
||||
type = "Spacer",
|
||||
quantity = 2,
|
||||
},
|
||||
{
|
||||
type = "Label",
|
||||
relativeWidth = 0.05
|
||||
},
|
||||
{
|
||||
type = "Label",
|
||||
relativeWidth = 0.949,
|
||||
text = "|cffffffff" .. L["Use the search box and category filters above to search the AuctionDB data."] .. "|r",
|
||||
fontObject = GameFontNormalLarge,
|
||||
},
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
local classes, subClasses = {}, {}
|
||||
for i, className in ipairs({ GetAuctionItemClasses() }) do
|
||||
classes[i] = className
|
||||
subClasses[i] = {}
|
||||
for j, subClassName in ipairs({ GetAuctionItemSubClasses(i) }) do
|
||||
subClasses[i][j] = subClassName
|
||||
end
|
||||
tinsert(subClasses[i], "")
|
||||
end
|
||||
tinsert(classes, "")
|
||||
|
||||
local lastScanInfo
|
||||
if TSM.db.factionrealm.lastCompleteScan > 0 then
|
||||
if TSM.db.factionrealm.lastCompleteScan == TSM.db.factionrealm.appDataUpdate then
|
||||
lastScanInfo = format(L["Last updated from the TSM Application %s ago."], SecondsToTime(time() - TSM.db.factionrealm.appDataUpdate))
|
||||
else
|
||||
lastScanInfo = format(L["Last updated from in-game scan %s ago."], SecondsToTime(time() - TSM.db.factionrealm.lastCompleteScan))
|
||||
end
|
||||
else
|
||||
lastScanInfo = L["No scans found."]
|
||||
end
|
||||
|
||||
local page = {
|
||||
{
|
||||
type = "SimpleGroup",
|
||||
layout = "Flow",
|
||||
fullHeight = true,
|
||||
children = {
|
||||
{
|
||||
type = "Label",
|
||||
text = L["You can use this page to lookup an item or group of items in the AuctionDB database. Note that this does not perform a live search of the AH."],
|
||||
relativeWidth = 1,
|
||||
},
|
||||
{
|
||||
type = "Label",
|
||||
text = lastScanInfo,
|
||||
relativeWidth = 1,
|
||||
},
|
||||
{
|
||||
type = "HeadingLine",
|
||||
},
|
||||
{
|
||||
type = "EditBox",
|
||||
label = SEARCH,
|
||||
settingInfo = {filter, "text"},
|
||||
relativeWidth = 0.49,
|
||||
callback = function(_, _, value)
|
||||
searchPage = 0
|
||||
container:ReloadTab()
|
||||
end,
|
||||
tooltip = L["Any items in the AuctionDB database that contain the search phrase in their names will be displayed."],
|
||||
},
|
||||
{
|
||||
type = "Dropdown",
|
||||
label = L["Item Type Filter"],
|
||||
list = classes,
|
||||
value = filter.class or #classes,
|
||||
relativeWidth = 0.25,
|
||||
callback = function(self, _, value)
|
||||
filter.text = TSMAPI:StrEscape(filter.text or "")
|
||||
if value ~= filter.class then
|
||||
filter.subClass = nil
|
||||
end
|
||||
if value == #classes then
|
||||
filter.class = nil
|
||||
else
|
||||
filter.class = value
|
||||
end
|
||||
searchPage = 0
|
||||
container:ReloadTab()
|
||||
end,
|
||||
tooltip = L["You can filter the results by item type by using this dropdown. For example, if you want to search for all herbs, you would select \"Trade Goods\" in this dropdown and \"Herbs\" as the subtype filter."],
|
||||
},
|
||||
{
|
||||
type = "Dropdown",
|
||||
label = L["Item SubType Filter"],
|
||||
disabled = filter.class == nil or (subClasses[filter.class] and #subClasses[filter.class] == 0),
|
||||
list = subClasses[filter.class or 0],
|
||||
value = filter.subClass or #(subClasses[filter.class or 0] or {}),
|
||||
relativeWidth = 0.25,
|
||||
callback = function(_, _, value)
|
||||
if value == #subClasses[filter.class] then
|
||||
filter.subClass = nil
|
||||
else
|
||||
filter.subClass = value
|
||||
end
|
||||
searchPage = 0
|
||||
container:ReloadTab()
|
||||
end,
|
||||
tooltip = L["You can filter the results by item subtype by using this dropdown. For example, if you want to search for all herbs, you would select \"Trade Goods\" in the item type dropdown and \"Herbs\" in this dropdown."],
|
||||
},
|
||||
{
|
||||
type = "Label",
|
||||
relativeWidth = 0.15
|
||||
},
|
||||
{
|
||||
type = "Button",
|
||||
text = REFRESH,
|
||||
relativeWidth = 0.2,
|
||||
callback = function()
|
||||
searchPage = 0
|
||||
Config:UpdateItems()
|
||||
container:ReloadTab()
|
||||
container:DoLayout()
|
||||
end,
|
||||
tooltip = L["Refreshes the current search results."],
|
||||
},
|
||||
{
|
||||
type = "Label",
|
||||
relativeWidth = 0.15
|
||||
},
|
||||
{
|
||||
type = "Icon",
|
||||
image = "Interface\\Buttons\\UI-SpellbookIcon-PrevPage-Up",
|
||||
width = 24,
|
||||
imageWidth = 24,
|
||||
imageHeight = 24,
|
||||
disabled = minIndex == 1,
|
||||
callback = function(self)
|
||||
searchPage = searchPage - 1
|
||||
container:ReloadTab()
|
||||
end,
|
||||
tooltip = L["Previous Page"],
|
||||
},
|
||||
{
|
||||
type = "Label",
|
||||
relativeWidth = 0.03
|
||||
},
|
||||
{
|
||||
type = "Label",
|
||||
text = format(L["Items %s - %s (%s total)"], minIndex, maxIndex, totalResults),
|
||||
relativeWidth = 0.35,
|
||||
},
|
||||
{
|
||||
type = "Icon",
|
||||
image = "Interface\\Buttons\\UI-SpellbookIcon-NextPage-Up",
|
||||
width = 24,
|
||||
imageWidth = 24,
|
||||
imageHeight = 24,
|
||||
disabled = maxIndex == totalResults,
|
||||
callback = function(self)
|
||||
searchPage = searchPage + 1
|
||||
container:ReloadTab()
|
||||
end,
|
||||
tooltip = L["Next Page"],
|
||||
},
|
||||
{
|
||||
type = "HeadingLine"
|
||||
},
|
||||
{
|
||||
type = "SimpleGroup",
|
||||
fullHeight = true,
|
||||
layout = "Flow",
|
||||
children = results,
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
TSMAPI:BuildPage(container, page)
|
||||
|
||||
local stParent = container.children[1].children[#container.children[1].children].frame
|
||||
|
||||
if not Config.st then
|
||||
local stCols = {
|
||||
{
|
||||
name = L["Item Link"],
|
||||
width = 0.40,
|
||||
},
|
||||
{
|
||||
name = L["Minimum Buyout"],
|
||||
width = 0.19,
|
||||
},
|
||||
{
|
||||
name = L["Market Value"],
|
||||
width = 0.19,
|
||||
},
|
||||
{
|
||||
name = L["Last Scanned"],
|
||||
width = 0.22,
|
||||
},
|
||||
}
|
||||
local handlers = {
|
||||
OnClick = function(_, data, _, button)
|
||||
if data and IsShiftKeyDown() and button == "RightButton" then
|
||||
TSM.data[data.itemID] = nil
|
||||
TSM:Printf(L["Removed %s from AuctionDB."], select(2, GetItemInfo(data.itemID)) or data.itemID)
|
||||
end
|
||||
end,
|
||||
OnEnter = function(_, data, self)
|
||||
GameTooltip:SetOwner(self, "ANCHOR_RIGHT")
|
||||
GameTooltip:SetHyperlink("item:" .. data.itemID)
|
||||
GameTooltip:AddLine("\n")
|
||||
GameTooltip:AddLine(TSMAPI.Design:GetInlineColor("link2") .. L["Shift-Right-Click to clear all data for this item from AuctionDB."] .. "|r")
|
||||
GameTooltip:Show()
|
||||
end,
|
||||
OnLeave = function()
|
||||
GameTooltip:ClearLines()
|
||||
GameTooltip:Hide()
|
||||
end
|
||||
}
|
||||
Config.st = TSMAPI:CreateScrollingTable(stParent, stCols, handlers)
|
||||
Config.st:EnableSorting(true)
|
||||
end
|
||||
|
||||
Config:UnhookAll()
|
||||
Config:HookScript(stParent, "OnHide", function() Config:UnhookAll() Config.st:Hide() end)
|
||||
Config.st:Show()
|
||||
Config.st:SetParent(stParent)
|
||||
Config.st:SetAllPoints()
|
||||
Config.st:SetData(searchDataTmp)
|
||||
end
|
||||
|
||||
function Config:GetSearchData()
|
||||
Config:UpdateItems()
|
||||
local stData = {}
|
||||
|
||||
local totalResults = #items
|
||||
local minIndex = searchPage * TSM.db.profile.resultsPerPage + 1
|
||||
local maxIndex = min(TSM.db.profile.resultsPerPage * (searchPage + 1), totalResults)
|
||||
if totalResults > 0 then
|
||||
for i = minIndex, maxIndex do
|
||||
local itemID = items[i]
|
||||
TSM:DecodeItemData(itemID)
|
||||
local data = TSM.data[itemID]
|
||||
local timeDiff = data.lastScan and SecondsToTime(time() - data.lastScan)
|
||||
local name, link = GetItemInfo(itemID)
|
||||
tinsert(stData, {
|
||||
cols = {
|
||||
{
|
||||
value = link or "???",
|
||||
sortArg = name or "",
|
||||
},
|
||||
{
|
||||
value = TSMAPI:FormatTextMoney(data.minBuyout, "|cffffffff") or "---",
|
||||
sortArg = data.minBuyout or 0,
|
||||
},
|
||||
{
|
||||
value = TSMAPI:FormatTextMoney(data.marketValue, "|cffffffff") or "---",
|
||||
sortArg = data.marketValue or 0,
|
||||
},
|
||||
{
|
||||
value = (timeDiff and TSMAPI.Design:GetInlineColor("link2") .. format(L["%s ago"], timeDiff) .. "|r" or TSMAPI.Design:GetInlineColor("link2") .. "---|r"),
|
||||
sortArg = data.lastScan and (time() - data.lastScan) or 0,
|
||||
},
|
||||
},
|
||||
itemID = itemID,
|
||||
})
|
||||
end
|
||||
end
|
||||
|
||||
return stData
|
||||
end
|
||||
|
||||
function Config:LoadOptions(container)
|
||||
local page = {
|
||||
{
|
||||
type = "ScrollFrame",
|
||||
layout = "Flow",
|
||||
children = {
|
||||
{
|
||||
type = "InlineGroup",
|
||||
title = "General Options",
|
||||
layout = "Flow",
|
||||
children = {
|
||||
{
|
||||
type = "CheckBox",
|
||||
label = L["Show AuctionDB AH Tab (Requires Reload)"],
|
||||
settingInfo = { TSM.db.profile, "showAHTab" },
|
||||
relativeWidth = 0.5,
|
||||
tooltip = L["If checked, AuctionDB will add a tab to the AH to allow for in-game scans. If you are using the TSM app exclusively for your scans, you may want to hide it by unchecking this option. This option requires a reload to take effect."],
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
type = "InlineGroup",
|
||||
title = L["Search Options"],
|
||||
layout = "Flow",
|
||||
children = {
|
||||
{
|
||||
type = "EditBox",
|
||||
label = L["Items per page"],
|
||||
value = TSM.db.profile.resultsPerPage,
|
||||
relativeWidth = 0.2,
|
||||
callback = function(_, _, value)
|
||||
value = tonumber(value)
|
||||
if value and value <= 500 and value >= 5 then
|
||||
TSM.db.profile.resultsPerPage = value
|
||||
else
|
||||
TSM:Print(L["Invalid value entered. You must enter a number between 5 and 500 inclusive."])
|
||||
end
|
||||
end,
|
||||
tooltip = L["This determines how many items are shown per page in results area of the \"Search\" tab of the AuctionDB page in the main TSM window. You may enter a number between 5 and 500 inclusive. If the page lags, you may want to decrease this number."],
|
||||
},
|
||||
{
|
||||
type = "Label",
|
||||
relativeWidth = 0.1
|
||||
},
|
||||
{
|
||||
type = "Dropdown",
|
||||
label = L["Sort items by"],
|
||||
list = { ["name"] = NAME, ["rarity"] = RARITY, ["ilvl"] = STAT_AVERAGE_ITEM_LEVEL, ["minlvl"] = L["Item MinLevel"], ["marketvalue"] = L["Market Value"], ["minbuyout"] = L["Minimum Buyout"] },
|
||||
settingInfo = {TSM.db.profile, "resultsSortMethod"},
|
||||
relativeWidth = 0.34,
|
||||
tooltip = L["Select how you would like the search results to be sorted. After changing this option, you may need to refresh your search results by hitting the \"Refresh\" button."],
|
||||
},
|
||||
{
|
||||
type = "Label",
|
||||
relativeWidth = 0.02
|
||||
},
|
||||
{
|
||||
type = "Dropdown",
|
||||
label = L["Result Order:"],
|
||||
settingInfo = {TSM.db.profile, "resultsSortOrder"},
|
||||
list = { ascending = L["Ascending"], descending = L["Descending"] },
|
||||
relativeWidth = 0.3,
|
||||
tooltip = L["Select whether to sort search results in ascending or descending order."],
|
||||
},
|
||||
{
|
||||
type = "CheckBox",
|
||||
label = L["Hide poor quality items"],
|
||||
settingInfo = { TSM.db.profile, "hidePoorQualityItems" },
|
||||
tooltip = L["If checked, poor quality items won't be shown in the search results."],
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
TSMAPI:BuildPage(container, page)
|
||||
end
|
||||
|
||||
function Config:LoadTooltipOptions(container)
|
||||
local page = {
|
||||
{
|
||||
type = "SimpleGroup",
|
||||
layout = "Flow",
|
||||
fullHeight = true,
|
||||
children = {
|
||||
{
|
||||
type = "CheckBox",
|
||||
label = L["Enable display of AuctionDB data in tooltip."],
|
||||
relativeWidth = 1,
|
||||
settingInfo = { TSM.db.profile, "tooltip" },
|
||||
callback = function(_, _, value)
|
||||
container:ReloadTab()
|
||||
end,
|
||||
},
|
||||
{
|
||||
type = "CheckBox",
|
||||
label = L["Display market value in tooltip."],
|
||||
disabled = not TSM.db.profile.tooltip,
|
||||
settingInfo = { TSM.db.profile, "marketValueTooltip" },
|
||||
tooltip = L["If checked, the market value of the item will be displayed"],
|
||||
},
|
||||
{
|
||||
type = "CheckBox",
|
||||
label = L["Display lowest buyout value seen in the last scan in tooltip."],
|
||||
disabled = not TSM.db.profile.tooltip,
|
||||
settingInfo = { TSM.db.profile, "minBuyoutTooltip" },
|
||||
tooltip = L["If checked, the lowest buyout value seen in the last scan of the item will be displayed."],
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
TSMAPI:BuildPage(container, page)
|
||||
end
|
||||
@@ -0,0 +1,225 @@
|
||||
-- ------------------------------------------------------------------------------ --
|
||||
-- TradeSkillMaster_AuctionDB --
|
||||
-- http://www.curse.com/addons/wow/tradeskillmaster_auctiondb --
|
||||
-- --
|
||||
-- A TradeSkillMaster Addon (http://tradeskillmaster.com) --
|
||||
-- All Rights Reserved* - Detailed license information included with addon. --
|
||||
-- ------------------------------------------------------------------------------ --
|
||||
|
||||
-- load the parent file (TSM) into a local variable and register this file as a module
|
||||
local TSM = select(2, ...)
|
||||
local Data = TSM:NewModule("Data")
|
||||
|
||||
-- weight for the market value from X days ago (where X is the index of the table)
|
||||
local WEIGHTS = {[0] = 132, [1] = 125, [2] = 100, [3] = 75, [4] = 45, [5] = 34, [6] = 33,
|
||||
[7] = 38, [8] = 28, [9] = 21, [10] = 15, [11] = 10, [12] = 7, [13] = 5, [14] = 4}
|
||||
local MIN_PERCENTILE = 0.15 -- consider at least the lowest 15% of auctions
|
||||
local MAX_PERCENTILE = 0.30 -- consider at most the lowest 30% of auctions
|
||||
local MAX_JUMP = 1.2 -- between the min and max percentiles, any increase in price over 120% will trigger a discard of remaining auctions
|
||||
|
||||
function Data:ConvertScansToAvg(scans)
|
||||
if not scans then return end
|
||||
-- do a sanity check
|
||||
if type(scans) == "number" then
|
||||
scans = {scans}
|
||||
end
|
||||
if not scans.avg then
|
||||
local total, num = 0, 0
|
||||
for _, value in ipairs(scans) do
|
||||
total = total + value
|
||||
num = num + 1
|
||||
end
|
||||
scans.avg = floor(total/num+0.5)
|
||||
scans.count = num
|
||||
end
|
||||
return scans
|
||||
end
|
||||
|
||||
function Data:GetDay(t)
|
||||
t = t or time()
|
||||
return floor(t / (60*60*24))
|
||||
end
|
||||
|
||||
-- Updates all the market values
|
||||
function Data:UpdateMarketValue(itemData)
|
||||
local day = Data:GetDay()
|
||||
|
||||
local scans = CopyTable(itemData.scans)
|
||||
itemData.scans = {}
|
||||
for i=0, 14 do
|
||||
if i <= TSM.MAX_AVG_DAY then
|
||||
if type(scans[day-i]) == "number" then
|
||||
scans[day-i] = {avg=scans[day-i], count=1}
|
||||
end
|
||||
itemData.scans[day-i] = scans[day-i] and CopyTable(scans[day-i])
|
||||
else
|
||||
local dayScans = scans[day-i]
|
||||
if type(dayScans) == "table" then
|
||||
if dayScans.avg then
|
||||
itemData.scans[day-i] = dayScans.avg
|
||||
else
|
||||
-- old method
|
||||
itemData.scans[day-i] = Data:GetAverage(dayScans)
|
||||
end
|
||||
elseif dayScans then
|
||||
itemData.scans[day-i] = dayScans
|
||||
end
|
||||
end
|
||||
end
|
||||
itemData.marketValue = Data:GetMarketValue(itemData.scans)
|
||||
end
|
||||
|
||||
-- gets the average of a list of numbers
|
||||
-- DEPRECATED
|
||||
function Data:GetAverage(data)
|
||||
local total, num = 0, 0
|
||||
for _, marketValue in ipairs(data) do
|
||||
total = total + marketValue
|
||||
num = num + 1
|
||||
end
|
||||
|
||||
return num > 0 and floor((total / num) + 0.5)
|
||||
end
|
||||
|
||||
-- gets the market value given a set of scans
|
||||
function Data:GetMarketValue(scans)
|
||||
local day = Data:GetDay()
|
||||
local totalAmount, totalWeight = 0, 0
|
||||
|
||||
for i=0, 14 do
|
||||
local dayScans = scans[day-i]
|
||||
if dayScans then
|
||||
local dayMarketValue
|
||||
if type(dayScans) == "table" then
|
||||
if dayScans.avg then
|
||||
dayMarketValue = dayScans.avg
|
||||
else
|
||||
-- old method
|
||||
dayMarketValue = Data:GetAverage(scans)
|
||||
end
|
||||
else
|
||||
dayMarketValue = dayScans
|
||||
end
|
||||
if dayMarketValue then
|
||||
totalAmount = totalAmount + (WEIGHTS[i] * dayMarketValue)
|
||||
totalWeight = totalWeight + WEIGHTS[i]
|
||||
end
|
||||
end
|
||||
end
|
||||
for i in ipairs(scans) do
|
||||
if i < day - 14 then
|
||||
scans[i] = nil
|
||||
end
|
||||
end
|
||||
|
||||
return totalWeight > 0 and floor(totalAmount / totalWeight + 0.5) or 0
|
||||
end
|
||||
|
||||
function Data:ProcessData(scanData, groupItems)
|
||||
if TSM.processingData then return TSMAPI:CreateTimeDelay(0.2, function() Data:ProcessData(scanData, groupItems) end) end
|
||||
|
||||
|
||||
-- wipe all the minBuyout data
|
||||
if groupItems then
|
||||
for itemString in pairs(groupItems) do
|
||||
local itemID = TSMAPI:GetItemID(itemString)
|
||||
if TSM.data[itemID] then
|
||||
TSM:DecodeItemData(itemID)
|
||||
TSM.data[itemID].minBuyout = nil
|
||||
TSM:EncodeItemData(itemID)
|
||||
end
|
||||
end
|
||||
else
|
||||
for itemID, data in pairs(TSM.data) do
|
||||
TSM:DecodeItemData(itemID)
|
||||
data.minBuyout = nil
|
||||
TSM:EncodeItemData(itemID)
|
||||
end
|
||||
end
|
||||
|
||||
local scanDataList = {}
|
||||
for itemID, data in pairs(scanData) do
|
||||
tinsert(scanDataList, {itemID, data})
|
||||
end
|
||||
|
||||
-- go through each item and figure out the market value / update the data table
|
||||
local index = 1
|
||||
local day = Data:GetDay()
|
||||
local function DoDataProcessing()
|
||||
for i = 1, 500 do
|
||||
if index > #scanDataList then
|
||||
TSMAPI:CancelFrame("adbProcessDelay")
|
||||
TSM.processingData = nil
|
||||
break
|
||||
end
|
||||
|
||||
local itemID, data = unpack(scanDataList[index])
|
||||
TSM:DecodeItemData(itemID)
|
||||
TSM.data[itemID] = TSM.data[itemID] or {scans={}, lastScan = 0}
|
||||
local marketValue = Data:CalculateMarketValue(data.records)
|
||||
|
||||
local scanData = TSM.data[itemID].scans
|
||||
scanData[day] = scanData[day] or {avg=0, count=0}
|
||||
if type(scanData[day]) == "number" then
|
||||
-- this should never happen...
|
||||
scanData[day] = {scanData[day]}
|
||||
end
|
||||
scanData[day].avg = scanData[day].avg or 0
|
||||
scanData[day].count = scanData[day].count or 0
|
||||
if #scanData[day] > 0 then
|
||||
scanData[day] = Data:ConvertScansToAvg(scanData[day])
|
||||
end
|
||||
scanData[day].avg = floor((scanData[day].avg * scanData[day].count + marketValue) / (scanData[day].count + 1) + 0.5)
|
||||
scanData[day].count = scanData[day].count + 1
|
||||
|
||||
TSM.data[itemID].lastScan = TSM.db.factionrealm.lastCompleteScan
|
||||
TSM.data[itemID].minBuyout = data.minBuyout > 0 and data.minBuyout or nil
|
||||
TSM.data[itemID].quantity = data.quantity
|
||||
Data:UpdateMarketValue(TSM.data[itemID])
|
||||
TSM:EncodeItemData(itemID)
|
||||
|
||||
index = index + 1
|
||||
end
|
||||
end
|
||||
|
||||
TSM.processingData = true
|
||||
TSMAPI:CreateTimeDelay("adbProcessDelay", 0, DoDataProcessing, 0.1)
|
||||
end
|
||||
|
||||
function Data:CalculateMarketValue(records)
|
||||
local totalNum, totalBuyout = 0, 0
|
||||
local numRecords = #records
|
||||
|
||||
for i=1, numRecords do
|
||||
totalNum = i - 1
|
||||
if i ~= 1 and i > numRecords*MIN_PERCENTILE and (i > numRecords*MAX_PERCENTILE or records[i] >= MAX_JUMP*records[i-1]) then
|
||||
break
|
||||
end
|
||||
|
||||
totalBuyout = totalBuyout + records[i]
|
||||
if i == numRecords then
|
||||
totalNum = i
|
||||
end
|
||||
end
|
||||
|
||||
local uncorrectedMean = totalBuyout / totalNum
|
||||
local varience = 0
|
||||
|
||||
for i=1, totalNum do
|
||||
varience = varience + (records[i]-uncorrectedMean)^2
|
||||
end
|
||||
|
||||
local stdDev = sqrt(varience/totalNum)
|
||||
local correctedTotalNum, correctedTotalBuyout = 1, uncorrectedMean
|
||||
|
||||
for i=1, totalNum do
|
||||
if abs(uncorrectedMean - records[i]) < 1.5*stdDev then
|
||||
correctedTotalNum = correctedTotalNum + 1
|
||||
correctedTotalBuyout = correctedTotalBuyout + records[i]
|
||||
end
|
||||
end
|
||||
|
||||
local correctedMean = floor(correctedTotalBuyout / correctedTotalNum + 0.5)
|
||||
|
||||
return correctedMean
|
||||
end
|
||||
Reference in New Issue
Block a user