2010-11-08 14:28:59 +01:00
QuestHelper_File [ " custom.lua " ] = " 4.0.1.$svnversion$ "
2010-10-24 23:17:33 +02:00
QuestHelper_Loadtime [ " custom.lua " ] = GetTime ( )
local search_frame = CreateFrame ( " Button " , nil , UIParent )
search_frame.text = search_frame : CreateFontString ( )
search_frame.text : SetFont ( QuestHelper.font . sans , 15 )
search_frame.text : SetTextColor ( 1 , 1 , 1 )
search_frame.text : SetJustifyH ( " CENTER " )
search_frame.text : SetJustifyV ( " MIDDLE " )
search_frame.text : SetDrawLayer ( " OVERLAY " )
search_frame.text : SetAllPoints ( )
search_frame.text : Show ( )
search_frame.background = search_frame : CreateTexture ( )
search_frame.background : SetTexture ( 0 , 0 , 0 , 0.5 )
search_frame.background : SetDrawLayer ( " BACKGROUND " )
search_frame.background : SetAllPoints ( )
search_frame.background : Show ( )
search_frame : SetPoint ( " CENTER " , UIParent , " CENTER " )
search_frame : Hide ( )
search_frame.results = { }
function search_frame : SetText ( text )
self.text : SetText ( text )
self : SetWidth ( self.text : GetWidth ( ) + 10 )
self : SetHeight ( self.text : GetHeight ( ) + 10 )
end
function search_frame : OnUpdate ( )
if self.routine and coroutine.status ( self.routine ) ~= " dead " then
local no_error , display = coroutine.resume ( self.routine , self , self.query )
if no_error then
self : SetText ( display )
else
QuestHelper : TextOut ( " Searching co-routine just exploded: " .. display )
end
else
self : ShowResults ( )
self.routine = nil
QH_Hook ( self , " OnUpdate " , nil )
self : Hide ( )
end
end
function QuestHelper : PerformCustomSearch ( func )
if not search_frame : GetScript ( " OnUpdate " ) then
search_frame : Show ( )
QH_Hook ( search_frame , " OnUpdate " , func )
end
end
function QuestHelper : StopCustomSearch ( )
if not search_frame.routine then
search_frame : Hide ( )
QH_Hook ( search_frame , " OnUpdate " , nil )
end
end
do return end
-- This next bit of stuff is for fuzzy string comarisons.
local row , prow = { } , { }
local difftable = { }
for i = 65 , 90 do
local a = { }
difftable [ i - 64 ] = a
for j = 65 , 90 do
a [ j - 64 ] = i == j and 0 or 1
end
end
local function setgroup ( a , w )
for i = 1 , string.len ( a ) - 1 do
for j = i + 1 , string.len ( a ) do
local c1 , c2 = string.byte ( a , i ) - 64 , string.byte ( a , j ) - 64
difftable [ c1 ] [ c2 ] = math.min ( w , difftable [ c1 ] [ c2 ] )
difftable [ c2 ] [ c1 ] = math.min ( w , difftable [ c2 ] [ c1 ] )
end
end
end
-- Characters that sound similar. At least in my opinion.
setgroup ( " BCDFGHJKLMNPQRSTVWXZ " , 0.9 )
setgroup ( " AEIOUY " , 0.6 )
setgroup ( " TD " , 0.6 )
setgroup ( " CKQ " , 0.4 )
setgroup ( " MN " , 0.4 )
setgroup ( " EIY " , 0.3 )
setgroup ( " UO " , 0.2 )
setgroup ( " SZ " , 0.6 )
local function diffness ( a , b )
if a >= 65 and a <= 90 then
if b >= 65 and b <= 90 then
return difftable [ a - 64 ] [ b - 64 ]
else
return 1
end
elseif b >= 65 and b <= 90 then
return 1
else
return 0
end
end
local function fuzzyCompare ( a , b )
local m , n = string.len ( a ) , string.len ( b )
if n == 0 or m == 0 then
return n == m and 0 or 1
end
for j = 1 , n + 1 do
row [ j ] = j - 1
end
for i = 1 , m do
row , prow = prow , row
row [ 1 ] = i
for j = 1 , n do
row [ j + 1 ] = math.min ( prow [ j + 1 ] + 1 , row [ j ] + .4 , prow [ j ] + diffness ( string.byte ( a , i ) , string.byte ( b , j ) ) )
end
end
return row [ n + 1 ] / math.max ( n , m )
end
function QuestHelper : ToggleUserObjective ( cat , what )
local objective = self : GetObjective ( cat , what )
if self.user_objectives [ objective ] then
self : TextOut ( QHFormat ( " REMOVED_OBJ " , self.user_objectives [ objective ] ) )
self : RemoveObjectiveWatch ( objective , self.user_objectives [ objective ] )
self.user_objectives [ objective ] = nil
elseif objective : Known ( ) then
local name
if cat == " loc " then
local _ , _ , i , x , y = string.find ( what , " ^(%d+),([%d%.]+),([%d%.]+)$ " )
name = QHFormat ( " USER_OBJ " , self : HighlightText ( QuestHelper_NameLookup [ tonumber ( i ) ] ) .. " : " .. self : HighlightText ( x * 100 ) .. " , " .. self : HighlightText ( y * 100 ) )
else
name = QHFormat ( " USER_OBJ " , self : HighlightText ( string.gsub ( cat , " ^(.) " , string.upper ) ) .. " : " .. self : HighlightText ( what ) )
end
objective.priority = 1
self.user_objectives [ objective ] = name
self : AddObjectiveWatch ( objective , name )
self : TextOut ( QHFormat ( " CREATED_OBJ " , name ) )
else
self : TextOut ( QHText ( " UNKNOWN_OBJ " ) )
end
end
function search_frame : CreateResultItem ( r , menu )
local item
if r.cat == " loc " then
local _ , _ , i , x , y = string.find ( r.what , " ^(%d+),([%d%.]+),([%d%.]+)$ " )
item = QuestHelper : CreateMenuItem ( menu , QuestHelper_NameLookup [ tonumber ( i ) ] .. " : " .. ( x * 100 ) .. " , " .. ( y * 100 ) .. " [ " .. QuestHelper : PercentString ( 1 - r.w ) .. " ] " )
item : AddTexture ( QuestHelper : CreateIconTexture ( item , 6 ) , true )
else
item = QuestHelper : CreateMenuItem ( menu , r.what .. " [ " .. QuestHelper : PercentString ( 1 - r.w ) .. " ] " )
item : AddTexture ( QuestHelper : CreateIconTexture ( item , ( r.cat == " monster " and 1 ) or 2 ) , true )
end
item : SetFunction ( QuestHelper.ToggleUserObjective , QuestHelper , r.cat , r.what )
return item
end
function search_frame : ShowResults ( )
local menu = QuestHelper : CreateMenu ( )
QuestHelper : CreateMenuTitle ( menu , QHText ( " RESULTS_TITLE " ) )
if # self.results == 0 then
QuestHelper : CreateMenuItem ( menu , QHText ( " NO_RESULTS " ) )
else
for i , r in ipairs ( self.results ) do
self : CreateResultItem ( r , menu )
end
end
menu : ShowAtCursor ( )
self : ClearResults ( )
end
function search_frame : ClearResults ( )
while # self.results > 0 do
QuestHelper : ReleaseTable ( table.remove ( self.results ) )
end
end
function search_frame : AddResult ( cat , what , w )
local r = self.results
local mn , mx = 1 , # r + 1
while mn ~= mx do
local m = math.floor ( ( mn + mx ) * 0.5 )
if r [ m ] . w < w then
mn = m + 1
else
mx = m
end
end
if mn <= 20 then
if r [ mn ] and r [ mn ] . cat == cat and r [ mn ] . what == what then
-- Don't add the same item twice.
-- Might miss it if multiple items have the same score. Dont care.
return
end
if # r >= 20 then
QuestHelper : ReleaseTable ( table.remove ( r , 20 ) )
end
local obj = QuestHelper : CreateTable ( )
obj.cat = cat
obj.what = what
obj.w = w
table.insert ( r , mn , obj )
end
end
function search_frame : SearchRoutine ( input )
if input == " " then
for obj in pairs ( QuestHelper.user_objectives ) do
self : AddResult ( obj.cat , obj.obj , 0 )
end
return
end
input = string.upper ( input )
local _ , _ , command , argument = string.find ( input , " ^%s*([^%s]-)%s+(.-)%s*$ " )
local search_item , search_npc , search_loc = false , false , false
if command and argument then
if command == " ITEM " then
search_item , input = true , argument
elseif command == " NPC " or command == " MONSTER " then
search_npc , input = true , argument
elseif command == " LOCATION " or command == " LOC " then
search_loc , input = true , argument
else
search_item , search_npc , search_loc = true , true , true
end
else
search_item , search_npc , search_loc = true , true , true
end
local yield_countdown_max = math.max ( 1 , math.floor ( 2000 / string.len ( input ) + 0.5 ) )
local yield_countdown = yield_countdown_max
if search_item then
local list = QuestHelper_Objectives_Local [ " item " ]
if list then for n in pairs ( list ) do
self : AddResult ( " item " , n , fuzzyCompare ( input , string.upper ( n ) ) )
yield_countdown = yield_countdown - 1
if yield_countdown == 0 then
yield_countdown = yield_countdown_max
coroutine.yield ( QHFormat ( " SEARCHING_STATE " , QHFormat ( " SEARCHING_LOCAL " , QHText ( " SEARCHING_ITEMS " ) ) ) )
end
end end
list = QuestHelper_StaticData [ QuestHelper.locale ] . objective
list = list and list.item
if list then for n in pairs ( list ) do
self : AddResult ( " item " , n , fuzzyCompare ( input , string.upper ( n ) ) )
yield_countdown = yield_countdown - 1
if yield_countdown == 0 then
yield_countdown = yield_countdown_max
coroutine.yield ( QHFormat ( " SEARCHING_STATE " , QHFormat ( " SEARCHING_STATIC " , QHText ( " SEARCHING_ITEMS " ) ) ) )
end
end end
end
if search_npc then
local list = QuestHelper_Objectives_Local [ " monster " ]
if list then for n in pairs ( list ) do
self : AddResult ( " monster " , n , fuzzyCompare ( input , string.upper ( n ) ) )
yield_countdown = yield_countdown - 1
if yield_countdown == 0 then
yield_countdown = yield_countdown_max
coroutine.yield ( QHFormat ( " SEARCHING_STATE " , QHFormat ( " SEARCHING_LOCAL " , QHText ( " SEARCHING_NPCS " ) ) ) )
end
end end
list = QuestHelper_StaticData [ QuestHelper.locale ] . objective
list = list and list.monster
if list then for n in pairs ( list ) do
self : AddResult ( " monster " , n , fuzzyCompare ( input , string.upper ( n ) ) )
yield_countdown = yield_countdown - 1
if yield_countdown == 0 then
yield_countdown = yield_countdown_max
coroutine.yield ( QHFormat ( " SEARCHING_STATE " , QHFormat ( " SEARCHING_STATIC " , QHText ( " SEARCHING_NPCS " ) ) ) )
end
end end
end
if search_loc then
local _ , _ , region , x , y = string.find ( input , " ^%s*([^%d%.]-)%s*([%d%.]+)%s*[,;:]?%s*([%d%.]+)%s*$ " )
if region then
x , y = tonumber ( x ) , tonumber ( y )
if x and y then
x , y = x * 0.01 , y * 0.01
if region == " " then
self : AddResult ( " loc " , string.format ( " %d,%.3f,%.3f " , QuestHelper.i , x , y ) , 0 )
else
for i , name in pairs ( QuestHelper_NameLookup ) do
self : AddResult ( " loc " , string.format ( " %d,%.3f,%.3f " , i , x , y ) , fuzzyCompare ( region , string.upper ( name ) ) )
yield_countdown = yield_countdown - 1
if yield_countdown == 0 then
yield_countdown = yield_countdown_max
coroutine.yield ( QHFormat ( " SEARCHING_STATE " , QHText ( " SEARCHING_ZONES " ) ) )
end
end
end
end
end
end
return QHText ( " SEARCHING_DONE " )
end
local function ReturnArgument ( x )
return x
end
function search_frame : PerformSearch ( input )
QuestHelper : TextOut ( " /qh find is currently disabled. Sorry! I'll get it back in once I can. " )
do return end
if not self.routine then
self.query = string.gsub ( input , " |c.-|H.-|h%[(.-)%]|h|r " , ReturnArgument )
self.routine = coroutine.create ( self.SearchRoutine )
self : Show ( )
QH_Hook ( self , " OnUpdate " , self.OnUpdate )
end
end
function QuestHelper : PerformSearch ( query )
search_frame : PerformSearch ( query )
end
SLASH_QuestHelperFind1 = " /qhfind "
SLASH_QuestHelperFind2 = " /find "
SlashCmdList [ " QuestHelperFind " ] = function ( text ) QuestHelper : PerformSearch ( text ) end