vanilla-wow-addons – Rev 1
?pathlinks?
--
-- MI2_Search.lua
--
-- MobInfo module to control the Mob database search feature.
-- Search option settings and actual search algorithm are located in here.
--
--
-- start up defaults for search options settings
MI2_SearchOptions = {}
MI2_SearchOptions.MinLevel = 1
MI2_SearchOptions.MaxLevel = 65
MI2_SearchOptions.Normal = 1
MI2_SearchOptions.Elite = 0
MI2_SearchOptions.Boss = 0
MI2_SearchOptions.MinLoots = 2
MI2_SearchOptions.MobName = ""
MI2_SearchOptions.ItemName = ""
MI2_SearchOptions.CompactResult = 1
MI2_SearchOptions.ListMode = "Mobs"
MI2_SearchOptions.SortMode = "profit"
local MI2_SearchResultList = {}
local MI2_ItemsIdxList = ":"
MI2_NumMobsFound = 0
-----------------------------------------------------------------------------
-- MI2_SearchForItems()
--
-- Search for all items matching the item name entered in the search dialog.
-- Display the list of items in the result list control (if requested).
-----------------------------------------------------------------------------
local function MI2_SearchForItems( itemName, enterItemsIntoList )
MI2_ItemsIdxList = ":"
MI2_NumMobsFound = 0
if enterItemsIntoList then
MI2_SearchResultList = {}
end
if itemName ~= "" or enterItemsIntoList then
for idx in MI2_ItemNameTable do
local itemFound = true
local itemText, itemColor = MI2_GetLootItemString( idx )
if itemName ~= "*" then
itemFound = string.find( string.lower(itemText), string.lower(itemName) ) ~= nil
end
if itemFound then
MI2_ItemsIdxList = MI2_ItemsIdxList..idx..":"
if enterItemsIntoList then
MI2_NumMobsFound = MI2_NumMobsFound + 1
MI2_SearchResultList[MI2_NumMobsFound] = { idx = itemText, val = "", col = itemColor }
end
end
end
end
MI2_DisplaySearchResult( "Items" )
end -- MI2_SearchForItems()
-----------------------------------------------------------------------------
-- MI2_UpdateSearchResultList()
--
-- Update contents of search result list according to current search options
-- settings. This includes starting a new search run, sorting the result and
-- displaying the result in the scrollable result list.
-----------------------------------------------------------------------------
local function MI2_UpdateSearchResultList( updateItems )
local startTime = GetTime()
if updateItems then
local enterItemsIntoList = MI2_SearchOptions.ListMode == "Items"
MI2_SearchForItems( MI2_SearchOptions.ItemName, enterItemsIntoList )
end
if MI2_SearchOptions.ListMode == "Mobs" then
MI2_SearchAndSort( "profit" )
end
MI2_DisplaySearchResult( MI2_SearchOptions.ListMode )
-- chattext( "<MobInfo> total search time = "..(GetTime()-startTime).." seconds" )
end -- MI2_UpdateSearchResultList()
-----------------------------------------------------------------------------
-- MI2_SearchOptionsOnShow()
--
-- OnShow event handler for search options page
-- Write current search option settings into the search option controls.
-- Validate all values and update colors accordingly.
-- Allow Search only if all search options are valid.
-----------------------------------------------------------------------------
function MI2_SearchOptionsOnShow()
MI2_OptSearchMinLevel:SetText( tostring(MI2_SearchOptions.MinLevel) )
MI2_OptSearchMaxLevel:SetText( tostring(MI2_SearchOptions.MaxLevel) )
MI2_OptSearchMinLoots:SetText( tostring(MI2_SearchOptions.MinLoots) )
MI2_OptSearchMobName:SetText( MI2_SearchOptions.MobName )
MI2_OptSearchItemName:SetText( MI2_SearchOptions.ItemName )
MI2_OptSearchNormal:SetChecked( MI2_SearchOptions.Normal )
MI2_OptSearchElite:SetChecked( MI2_SearchOptions.Elite )
MI2_OptSearchBoss:SetChecked( MI2_SearchOptions.Boss )
MI2_UpdateSearchResultList()
end -- MI2_SearchOptionsOnShow()
-----------------------------------------------------------------------------
-- MI2_ValidateSearchOptions()
--
-- Validate all values and update colors accordingly.
-- Allow Search only if all search options are valid.
-----------------------------------------------------------------------------
local function MI2_ValidateSearchOptions()
if MI2_SearchOptions.MinLevel < 1 then
MI2_SearchOptions.MinLevel = 1
if this:GetText() == "0" then
this:SetText( "1" )
end
end
if MI2_SearchOptions.MaxLevel < 1 then
MI2_SearchOptions.MaxLevel = 1
if this:GetText() == "0" then
this:SetText( "1" )
end
end
end -- MI2_ValidateSearchOptions()
-----------------------------------------------------------------------------
-- MI2_SearchCheckboxClicked()
--
-- OnClicked event handler for checkboxes on search options page
-- Store the checkbox state in the corresponding search options variable.
-----------------------------------------------------------------------------
function MI2_SearchCheckboxClicked()
local checkboxName = this:GetName()
local optionName = string.sub( checkboxName, 14 )
local optionValue = this:GetChecked() or 0
MI2_SearchOptions[optionName] = optionValue
MI2_UpdateSearchResultList()
end -- MI2_SearchCheckboxClicked()
-----------------------------------------------------------------------------
-- MI2_SearchValueChanged()
--
-- OnChar event handler for editbox controls on search options page
-- This handler is called whenever the contents of an EditBox control changes.
-- It gets the new value and stores it in the corresponding search options
-- variable
-----------------------------------------------------------------------------
function MI2_SearchValueChanged()
local editboxName = this:GetName()
local optionName = string.sub( editboxName, 14 )
local optionValue = tonumber(this:GetText()) or 0
if MI2_SearchOptions[optionName] ~= optionValue then
MI2_SearchOptions[optionName] = optionValue
MI2_ValidateSearchOptions()
MI2_UpdateSearchResultList()
end
end -- MI2_SearchValueChanged()
-----------------------------------------------------------------------------
-- MI2_SearchTextChanged()
--
-- OnChar event handler for textual editbox controls on search options page
-- This handler is called whenever the contents of an EditBox control changes.
-- It gets the new value and stores it in the corresponding search options
-- variable
-----------------------------------------------------------------------------
function MI2_SearchTextChanged()
local editboxName = this:GetName()
local optionName = string.sub( editboxName, 14 )
if MI2_SearchOptions[optionName] ~= this:GetText() then
MI2_SearchOptions[optionName] = this:GetText()
MI2_UpdateSearchResultList( true )
end
end -- MI2_SearchTextChanged()
-----------------------------------------------------------------------------
-- MI2_CalculateRank()
--
-- Calculate ranking and corresponding actual value for a given mob.
-- Ranking depends on search mode. For search mode "profit" ranking is
-- based on the mobs total profit value plus bonus points for rare loot
-- items. For search mode "itemCount" ranking is identical to the overall
-- items count for the loot items being searched for (in this mode
-- rank and value are identical).
-----------------------------------------------------------------------------
local function MI2_CalculateRank( mobData, mobLevel, sortMode )
local rank, value = 0, 0
if sortMode == "profit" then
-- calculate rank based on mob level and loot items quality
local bonusFactor = mobLevel / 20
if mobData.loots > 0 then
value = (mobData.copper or 0) + (mobData.itemValue or 0)
rank = value + ((mobData.r3 or 0) * 200 * bonusFactor) + ((mobData.r4 or 0) * 1000 * bonusFactor) + ((mobData.r5 or 0) * 2000 * bonusFactor)
rank = ceil( rank / mobData.loots )
value = copper2text( ceil(value / mobData.loots) )
end
elseif sortMode == "item" and mobData.itemList then
for idx, val in mobData.itemList do
local itemFound = string.find( MI2_ItemsIdxList, idx ) ~= nil
if itemFound then rank = rank + val end
end
value = rank.." "
end
return rank, value
end -- MI2_CalculateRank()
-----------------------------------------------------------------------------
-- MI2_CheckMob()
--
-- Check a given Mob against the current search criteria. Return the
-- mob data if the mob matches the criteria, or return nil if the Mob
-- does not match.
-----------------------------------------------------------------------------
local function MI2_CheckMob( mobInfo, mobName, mobLevel )
local levelOk, lootsOk, typeOk, itemsOK, mobData
local nameOk = true
-- check name and level of Mob
if MI2_SearchOptions.MobName ~= "" then
nameOk = string.find(string.lower(mobName),string.lower(MI2_SearchOptions.MobName),1,true) ~= nil
end
if nameOk and mobName ~= "" then
levelOk = mobLevel >= MI2_SearchOptions.MinLevel and mobLevel <= MI2_SearchOptions.MaxLevel
end
-- check mob data related search conditions
if levelOk or mobLevel == -1 then
mobData = {}
MI2_DecodeBasicMobData( mobInfo, mobData )
mobData.loots = mobData.loots or 0
lootsOk = mobData.loots >= MI2_SearchOptions.MinLoots
typeOk = (MI2_SearchOptions.Normal == 1 and mobData.mobType == 1) or (MI2_SearchOptions.Elite == 1 and mobData.mobType == 2) or (MI2_SearchOptions.Boss == 1 and mobData.mobType == 3)
if lootsOk and typeOk then
if MI2_ItemsIdxList ~= ":" then
MI2_DecodeItemList( mobInfo, mobData )
if mobData.itemList then
for idx, val in mobData.itemList do
itemsOK = string.find( MI2_ItemsIdxList, ":"..idx..":" ) ~= nil
if itemsOK then break end
end
end
if not itemsOK then mobData = nil end
end
else
mobData = nil
end
end
return mobData
end -- MI2_CheckMob()
-----------------------------------------------------------------------------
-- MI2_SearchAndSort()
--
-- Search for most valuable mobs by comparing the mobs average total value.
-- The function creates a result list to be displayed in the search results
-- list.
-----------------------------------------------------------------------------
function MI2_SearchAndSort( )
local mobName, mobLevel, insertPos, value, rank, mobIndex, mobInfo
-- initialise search result list
MI2_SearchResultList = {}
MI2_NumMobsFound = 0
-- create a sorted list of mobs matching the search criteria
-- loop across all mobs in the MobInfo database
for mobIndex, mobInfo in MobInfoDB do
mobName, mobLevel = MI2_GetIndexComponents( mobIndex )
mobData = MI2_CheckMob( mobInfo, mobName, mobLevel )
-- if mob is identified as belonging into the search result its
-- search result sorting position is calculated based on a ranking
-- value which in turn is based on the search mode
if mobData then
rank, value = MI2_CalculateRank( mobData, mobLevel, MI2_SearchOptions.SortMode )
MI2_NumMobsFound = MI2_NumMobsFound + 1
-- insert mob at correct sorted position and store all info we need for printing the result list
MI2_SearchResultList[MI2_NumMobsFound] = { idx=mobIndex, val=value, rank=rank }
if mobData.mobType and mobData.mobType > 1 then
MI2_SearchResultList[MI2_NumMobsFound].type = mobData.mobType
end
end
end
if MI2_NumMobsFound > 1 then
table.sort( MI2_SearchResultList, function(a,b) return (a.rank > b.rank) end )
end
end -- MI2_SearchAndSort()
-----------------------------------------------------------------------------
-- MI2_DisplaySearchResult()
--
-- Display the result of a search in the search results scrollable list.
-- The mobs to be displayed depend on the current list scroll position.
-----------------------------------------------------------------------------
function MI2_DisplaySearchResult( resultType )
-- update slider and get slider position
FauxScrollFrame_Update( MI2_SearchResultSlider, MI2_NumMobsFound, 15, 14 );
local sliderPos = FauxScrollFrame_GetOffset(MI2_SearchResultSlider)
if resultType then
MI2_TxtSearchCount:SetText( mifontSubWhite.."("..MI2_NumMobsFound.." "..resultType..")" )
end
-- update 15 search result lines with correct search result data
local resultLine
for i = 1, 15 do
if (i + sliderPos) <= MI2_NumMobsFound then
resultLine = getglobal( "MI2_SearchResult"..i.."Index" )
resultLine:SetText( i + sliderPos )
resultLine = getglobal( "MI2_SearchResult"..i.."Value" )
resultLine:SetText( MI2_SearchResultList[i + sliderPos].val )
resultLine = getglobal( "MI2_SearchResult"..i.."Name" )
local mobName = MI2_SearchResultList[i + sliderPos].idx
if MI2_SearchResultList[i + sliderPos].type then
mobName = mobName.."+"
elseif MI2_SearchResultList[i + sliderPos].col then
mobName = MI2_SearchResultList[i + sliderPos].col..mobName
end
resultLine:SetText( mobName )
else
resultLine = getglobal( "MI2_SearchResult"..i.."Index" )
resultLine:SetText( "" )
resultLine = getglobal( "MI2_SearchResult"..i.."Value" )
resultLine:SetText( "" )
resultLine = getglobal( "MI2_SearchResult"..i.."Name" )
resultLine:SetText( "" )
end
end
end -- MI2_DisplaySearchResult()
-----------------------------------------------------------------------------
-- MI2_SlashAction_SortByValue()
--
-- Sort the search result list by mob profit
-----------------------------------------------------------------------------
function MI2_SlashAction_SortByValue()
MI2_SearchOptions.SortMode = "profit"
MI2_UpdateSearchResultList()
end -- end of MI2_SlashAction_SortByValue()
-----------------------------------------------------------------------------
-- MI2_SlashAction_SortByItem()
--
-- Sort the search result list by mob item count
-----------------------------------------------------------------------------
function MI2_SlashAction_SortByItem()
MI2_SearchOptions.SortMode = "item"
MI2_UpdateSearchResultList()
end -- end of MI2_SlashAction_SortByItem()
-----------------------------------------------------------------------------
-- MI2_SearchResult_Update()
--
-- Update contents of search results list based on current scroll bar
-- position. Update tooltip for selected mob if tooltip is visible.
-----------------------------------------------------------------------------
function MI2_SearchResult_Update()
FauxScrollFrame_Update( MI2_SearchResultSlider, MI2_NumMobsFound, 15, 14 );
MI2_DisplaySearchResult()
end -- end of MI2_SearchResult_Update()
-----------------------------------------------------------------------------
-- MI2_ShowSearchResultTooltip()
--
-- Show mob tooltip for search result mob currently under mouse cursor.
-----------------------------------------------------------------------------
function MI2_ShowSearchResultTooltip()
local sliderPos = FauxScrollFrame_GetOffset(MI2_SearchResultSlider)
local selection = tonumber(string.sub(this:GetName(), 17)) + sliderPos
if selection <= MI2_NumMobsFound then
GameTooltip_SetDefaultAnchor( GameTooltip, UIParent )
if MI2_SearchOptions.ListMode == "Mobs" then
local index = MI2_SearchResultList[selection].idx
local mobName, mobLevel = MI2_GetIndexComponents( index )
local mobCaption = mobName.." L"..mobLevel
if MI2_SearchResultList[selection].type then
mobCaption = mobCaption.."+"
end
-- create Mob data tooltip with full location info
GameTooltip:SetText( mobCaption )
MI2_BuildMobInfoTooltip( mobName, mobLevel, 1 )
elseif MI2_SearchOptions.ListMode == "Items" then
local itemName = MI2_SearchResultList[selection].idx
GameTooltip:SetText( MI2_SearchResultList[selection].col..itemName )
MI2_BuildItemDataTooltip( itemName )
end
GameTooltip:Show()
end
end -- end of MI2_ShowSearchResultTooltip()
-----------------------------------------------------------------------------
-- MI2_SearchTab_OnClick()
--
-- The "OnClick" event handler for the TAB buttons on the search result list.
-- These TAB buttons switch the list content between two modes: mob list
-- and item list
-----------------------------------------------------------------------------
function MI2_SearchTab_OnClick()
PanelTemplates_Tab_OnClick( MI2_SearchResultFrame )
local selected = MI2_SearchResultFrame.selectedTab
if selected == 1 then
MI2_OptSortByValue:Enable()
MI2_OptSortByItem:Enable()
if MI2_NumMobsFound > 0 then
MI2_OptDeleteSearch:Enable()
else
MI2_OptDeleteSearch:Disable()
end
MI2_SearchOptions.ListMode = "Mobs"
MI2_UpdateSearchResultList( true )
elseif selected == 2 then
MI2_OptSortByValue:Disable()
MI2_OptSortByItem:Disable()
MI2_OptDeleteSearch:Disable()
MI2_SearchOptions.ListMode = "Items"
MI2_UpdateSearchResultList( true )
end
end -- MI2_SearchTab_OnClick()
-----------------------------------------------------------------------------
-- MI2_DeleteSearchResultMobs()
--
-- Delete all Mobs in the search result list from the MobInfo database.
-- This function is called when the user confirms the delete.
-----------------------------------------------------------------------------
function MI2_DeleteSearchResultMobs()
for idx, val in MI2_SearchResultList do
local mobIndex = val.idx
MI2_DeleteMobData( mobIndex, true )
end
chattext( mifontLightBlue.."<MobInfo> deleted "..MI2_NumMobsFound.." Mobs from the MobInfo databases" )
MI2_UpdateSearchResultList()
end -- MI2_DeleteSearchResultMobs()