local _ , WBT = ... ;
local Options = { } ;
WBT.Options = Options ;
local GUI = WBT.GUI ;
local Util = WBT.Util ;
local BossData = WBT.BossData ;
local Sound = WBT.Sound ;
Options.NUM_CYCLES_TO_SHOW_MAX = 5 ;
----- Setters and Getters for options -----
local OptionsItem = { } ;
function OptionsItem . CreateDefaultGetter ( var_name )
local function getter ( )
return WBT.db . global [ var_name ] ;
end
return getter ;
end
function OptionsItem . CreateDefaultSetter ( var_name )
local function setter ( state )
WBT.db . global [ var_name ] = state ;
WBT.GUI : Rebuild ( ) ;
end
return setter ;
end
function OptionsItem : New ( var_name , status_msg )
local ci = {
get = OptionsItem.CreateDefaultGetter ( var_name ) ;
set = OptionsItem.CreateDefaultSetter ( var_name ) ;
msg = status_msg ,
} ;
setmetatable ( ci , self ) ;
self.__index = self ;
return ci ;
end
local ToggleItem = { } ;
function ToggleItem : New ( var_name , status_msg )
local ti = OptionsItem : New ( var_name , status_msg ) ;
setmetatable ( ti , self ) ;
self.__index = self ;
return ti ;
end
function ToggleItem . GetColoredStatus ( status_var )
local color = Util.COLOR_RED ;
local status = " disabled " ;
if status_var then
color = Util.COLOR_GREEN ;
status = " enabled " ;
end
return color .. status .. Util.COLOR_DEFAULT ;
end
function ToggleItem : PrintFormattedStatus ( status_var )
if self.msg then
WBT : Print ( self.msg .. " " .. self.GetColoredStatus ( status_var ) .. " . " ) ;
end
end
function ToggleItem : Toggle ( )
local new_state = not self.get ( ) ;
self.set ( new_state ) ;
-- FIXME: Commented out for now. Was intended for when called from CLI.
-- self:PrintFormattedStatus(new_state);
WBT.GUI : Update ( ) ;
end
local SelectItem = { } ;
function SelectItem : OverrideGetter ( default_key )
local default_getter_fptr = self.get ;
self.get = function ( )
local key = default_getter_fptr ( ) ;
if key == nil then
return default_key ;
end
return key ;
end
end
function SelectItem : New ( var_name , status_msg , mkt , mkt_options_key , mkt_values_key , default_key )
local si = OptionsItem : New ( var_name , status_msg ) ;
si.mkt = mkt ; -- MultiKeyTable
si.mkt_options_key = mkt_options_key ;
si.mkt_values_key = mkt_values_key ;
si.options = si.mkt : GetAllSubVals ( si.mkt_options_key ) ;
setmetatable ( si , self ) ;
self.__index = self ;
si : OverrideGetter ( default_key ) ;
return si ;
end
function SelectItem : Key ( )
return self : get ( ) ;
end
function SelectItem : Value ( )
local subtbl = self.mkt : GetSubtbl ( self.mkt_options_key , self : Key ( ) ) ;
return subtbl [ self.mkt_values_key ] ;
end
local RangeItem = { } ;
function RangeItem : OverrideGetter ( default_val )
local default_getter = self.get ;
self.get = function ( )
local val = default_getter ( ) ;
if val == nil then
return default_val ;
end
return val ;
end
end
function RangeItem : New ( var_name , status_msg , default_val )
local si = OptionsItem : New ( var_name , status_msg ) ;
setmetatable ( si , self ) ;
self.__index = self ;
si : OverrideGetter ( default_val ) ;
return si ;
end
local function ShowGUI ( show )
local gui = GUI ;
if show then
WBT.db . global.hide_gui = false ;
if gui : ShouldShow ( ) then
gui : Show ( ) ;
else
WBT : Print ( " The GUI will show when next you enter a boss zone. " ) ;
end
else
WBT.db . global.hide_gui = true ;
gui : Hide ( ) ;
end
gui : Update ( ) ;
end
function Options . InitializeItems ( )
local logger_opts = WBT.Logger . options_tbl ;
local sound_opts = Sound.sound_tbl ;
Options.show_gui = ToggleItem : New ( " show_gui " , nil ) ;
Options.show_boss_zone_only = ToggleItem : New ( " show_boss_zone_only " , " Only show GUI in boss zone mode is now " ) ;
Options.lock = ToggleItem : New ( " lock " , " GUI lock is now " ) ;
Options.global_gui_position = ToggleItem : New ( " global_gui_position " , nil ) ;
Options.sound = ToggleItem : New ( " sound_enabled " , " Sound is now " ) ;
Options.assume_realm_keeps_shard = ToggleItem : New ( " assume_realm_keeps_shard " , " Option to assume realms do not change shards is now " ) ;
Options.multi_realm = ToggleItem : New ( " multi_realm " , " Option to show timers for other shards is now " ) ;
Options.highlight = ToggleItem : New ( " highlight " , " Highlighting of current zone is now " ) ;
Options.show_saved = ToggleItem : New ( " show_saved " , " Showing if saved on boss (on timer) is now " ) ;
Options.show_realm = ToggleItem : New ( " show_realm " , " Showing realm on which timer was recorded is now " ) ;
Options.dev_silent = ToggleItem : New ( " dev_silent " , " Silent mode is now " ) ;
Options.log_level = SelectItem : New ( " log_level " , " Log level is now " , logger_opts.tbl , logger_opts.keys . option , logger_opts.keys . log_level , WBT.defaults . global.log_level ) ;
Options.spawn_alert_sound = SelectItem : New ( " spawn_alert_sound " , " Spawn alert sound is now " , sound_opts.tbl , sound_opts.keys . option , sound_opts.keys . file_id , WBT.defaults . global.spawn_alert_sound ) ;
Options.spawn_alert_sec_before = RangeItem : New ( " spawn_alert_sec_before " , " Spawn alert sound sec before is now " , WBT.defaults . global.spawn_alert_sec_before ) ;
Options.cyclic = ToggleItem : New ( " cyclic " , " Cyclic mode is now " ) ;
Options.num_cycles_to_show = RangeItem : New ( " num_cycles_to_show " , " Number of cycles that expired timers are shown is now " , WBT.defaults . global.max_num_cycles ) ;
-- Wrapping in 'play sound file when selected'.
local spawn_alert_sound_set_temp = Options.spawn_alert_sound . set ;
Options.spawn_alert_sound . set = function ( state )
spawn_alert_sound_set_temp ( state ) ;
Util.PlaySoundAlert ( Options.spawn_alert_sound : Value ( ) ) ;
end
-- Overriding setter for log_level to use same method as from CLI:
Options.log_level . set = function ( state )
WBT.Logger . SetLogLevel ( state ) ;
end
-- Needs to update window position.
local global_gui_position_set_temp = Options.global_gui_position . set ;
Options.global_gui_position . set = function ( state )
WBT.GUI : SaveGUIPosition ( ) ;
global_gui_position_set_temp ( state ) ;
WBT.GUI : InitPosition ( ) ;
end
-- Option show_gui is a bit complicated. Override overything:
Options.show_gui . set = function ( state )
ShowGUI ( state ) ; -- Makes the option more snappy.
end
Options.show_gui . get = function ( )
return not WBT.db . global.hide_gui ; -- I don't want to rename db variable, so just negate (hide -> show).
end
end
----- Slash commands -----
local function PrintHelp ( )
WBT.AceConfigDialog : Open ( WBT.addon_name ) ;
local indent = " " ;
WBT : Print ( " WorldBossTimers slash commands: " ) ;
WBT : Print ( " /wbt reset " .. " --> Reset all timers " ) ;
WBT : Print ( " /wbt gui-reset " .. " --> Reset the position of the timers window " ) ;
WBT : Print ( " /wbt saved " .. " --> Print your saved bosses " ) ;
WBT : Print ( " /wbt show " .. " --> Show the timers window " ) ;
WBT : Print ( " /wbt hide " .. " --> Hide the timers window " ) ;
WBT : Print ( " /wbt gui-toggle " .. " --> Toggle visibility of the timers window " ) ;
WBT : Print ( " /wbt log <level> " .. " --> Set log level for debug purposes " ) ;
end
function Options . SlashHandler ( input )
local arg1 , arg2 = strsplit ( " " , input ) ;
if arg1 then
arg1 = arg1 : lower ( ) ;
end
if arg1 == " hide " then
ShowGUI ( false ) ;
elseif arg1 == " show " then
ShowGUI ( true ) ;
elseif arg1 == " gui-toggle " then
Options.show_gui : Toggle ( ) ;
elseif arg1 == " share " then
WBT.Functions . AnnounceTimerInChat ( ) ;
elseif arg1 == " r "
or arg1 == " reset "
or arg1 == " restart " then
WBT.ResetKillInfo ( ) ;
elseif arg1 == " s "
or arg1 == " saved "
or arg1 == " save " then
WBT.PrintKilledBosses ( ) ;
elseif arg1 == " request " then
WBT.RequestKillData ( ) ;
elseif arg1 == " sound " then
local sound_type_args = { Sound.SOUND_CLASSIC , Sound.SOUND_FANCY } ;
if Util.SetUtil . ContainsValue ( sound_type_args , arg2 ) then
WBT.db . global.sound_type = arg2 ;
WBT : Print ( " SoundType: " .. arg2 ) ;
else
Options.sound : Toggle ( ) ;
end
elseif arg1 == " cyclic " then
Options.cyclic : Toggle ( ) ;
elseif arg1 == " multi " then
Options.multi_realm : Toggle ( ) ;
elseif arg1 == " zone " then
Options.show_boss_zone_only : Toggle ( ) ;
elseif arg1 == " lock " then
Options.lock : Toggle ( ) ;
elseif arg1 == " gui-reset " then
WBT.GUI : ResetPosition ( ) ;
elseif arg1 == " log " then
WBT.Logger . SetLogLevel ( arg2 ) ;
else
PrintHelp ( ) ;
end
end
-- Counter so I don't have to increment order all the time.
-- Option items are ordered as they are inserted.
local t_cnt = { 0 } ;
function t_cnt : plusplus ( )
self [ 1 ] = self [ 1 ] + 1 ;
return self [ 1 ] ;
end
----- Options table -----
function Options . InitializeOptionsTable ( )
local desc_toggle = " Enable/Disable " ;
Options.optionsTable = {
type = " group " ,
childGroups = " select " ,
args = {
hints = {
name = -- Hint_1
Util.ColoredString ( Util.COLOR_ORANGE , " Hint: " ) ..
" Control-click a timer that is shown in " .. Util.ColoredString ( Util.COLOR_RED , " red " ) .. " to reset it. \n " ..
-- Hint_2
Util.ColoredString ( Util.COLOR_ORANGE , " Hint: " ) ..
" Control-shift-click to reset any timer. \n " ,
order = t_cnt : plusplus ( ) ,
type = " description " ,
fontSize = " medium " ,
width = " full " ,
} ,
_add_distance_to_next_option = {
name = " " ,
order = t_cnt : plusplus ( ) ,
type = " description " ,
width = " full " ,
} ,
show = {
name = " Show GUI " ,
order = t_cnt : plusplus ( ) ,
desc = desc_toggle ,
type = " toggle " ,
width = " full " ,
set = function ( info , val ) Options.show_gui : Toggle ( ) ; end ,
get = function ( info ) return Options.show_gui . get ( ) ; end ,
} ,
show_boss_zone_only = {
name = " Only show GUI in boss zones " ,
order = t_cnt : plusplus ( ) ,
desc = desc_toggle ,
type = " toggle " ,
width = " full " ,
set = function ( info , val ) Options.show_boss_zone_only : Toggle ( ) ; end ,
get = function ( info ) return Options.show_boss_zone_only . get ( ) ; end ,
} ,
lock = {
name = " Lock GUI " ,
order = t_cnt : plusplus ( ) ,
desc = " Toggle if the GUI should be locked or movable " ,
type = " toggle " ,
width = " full " ,
set = function ( info , val ) Options.lock : Toggle ( ) ; end ,
get = function ( info ) return Options.lock . get ( ) end ,
} ,
global_gui_position = {
name = " Account-wide GUI position " ,
order = t_cnt : plusplus ( ) ,
desc = " When enabled the GUI position is the same for characters " ,
type = " toggle " ,
width = " full " ,
set = function ( info , val ) Options.global_gui_position : Toggle ( ) ; end ,
get = function ( info ) return Options.global_gui_position . get ( ) ; end ,
} ,
sound = {
name = " Sound " ,
order = t_cnt : plusplus ( ) ,
desc = desc_toggle ,
type = " toggle " ,
width = " full " ,
set = function ( info , val ) Options.sound : Toggle ( ) ; end ,
get = function ( info ) return Options.sound . get ( ) ; end ,
} ,
assume_realm_keeps_shard = {
name = " Assume realms do not change shards " ,
order = t_cnt : plusplus ( ) ,
desc = " Uses the last known shard ID for this realm when the current shard ID is unknown. " ..
" This may lead to incorrect timers. " ,
type = " toggle " ,
width = " full " ,
set = function ( info , val ) Options.assume_realm_keeps_shard : Toggle ( ) ; end ,
get = function ( info ) return Options.assume_realm_keeps_shard . get ( ) ; end ,
} ,
multi_realm = { -- NOTE: Should be named multi_shard, but to keep user set option values, it was not renamed.
name = " Show timers for other shards " ,
order = t_cnt : plusplus ( ) ,
desc = " Shows timers for other shards " ,
type = " toggle " ,
width = " full " ,
set = function ( info , val ) Options.multi_realm : Toggle ( ) ; end ,
get = function ( info ) return Options.multi_realm . get ( ) ; end ,
} ,
highlight = {
name = " Highlight boss in current zone " ,
order = t_cnt : plusplus ( ) ,
desc = " The boss in your current zone will have a different color if the current shard ID matches the timer: \n " ..
Util.ColoredString ( Util.COLOR_LIGHTGREEN , " Green " ) .. " if timer not expired \n " ..
Util.ColoredString ( Util.COLOR_YELLOW , " Yellow " ) .. " if timer expired (with Cyclic mode) " ,
type = " toggle " ,
width = " full " ,
set = function ( info , val ) Options.highlight : Toggle ( ) ; end ,
get = function ( info ) return Options.highlight . get ( ) ; end ,
} ,
show_saved = {
name = " Show if saved " ,
order = t_cnt : plusplus ( ) ,
desc = " Appends a colored 'X' ( " .. Util.ColoredString ( Util.COLOR_RED , " X " ) .. " / " .. Util.ColoredString ( Util.COLOR_GREEN , " X " ) .. " ) " ..
" after the timer if you are saved for the boss. \n " ..
" NOTE: The color of the 'X' has no special meaning, it's just for improved visibility. " ,
type = " toggle " ,
width = " full " ,
set = function ( info , val ) Options.show_saved : Toggle ( ) ; end ,
get = function ( info ) return Options.show_saved . get ( ) ; end ,
} ,
show_realm = {
name = " Show realm " ,
order = t_cnt : plusplus ( ) ,
desc = " Shows the first three characters of the realm on which the timer was recorded. " ,
type = " toggle " ,
width = " full " ,
set = function ( info , val ) Options.show_realm : Toggle ( ) ; end ,
get = function ( info ) return Options.show_realm . get ( ) ; end ,
} ,
cyclic = {
name = " Cyclic (show expired) " ,
order = t_cnt : plusplus ( ) ,
desc = " If you missed a kill, the timer will wrap around and will now have a red color " ,
type = " toggle " ,
width = " normal " ,
set = function ( info , val ) Options.cyclic : Toggle ( ) ; end ,
get = function ( info ) return Options.cyclic . get ( ) ; end ,
} ,
num_cycles_to_show = {
name = " Number of cycles to show " ,
order = t_cnt : plusplus ( ) ,
desc = " If set to the max value, then expired timers will always be shown " ,
type = " range " ,
min = 0 ,
max = Options.NUM_CYCLES_TO_SHOW_MAX ,
softMin = 0 ,
softMax = Options.NUM_CYCLES_TO_SHOW_MAX ,
bigStep = 1 ,
isPercent = false ,
width = " normal " ,
set = function ( info , val ) Options.num_cycles_to_show . set ( val ) ; end ,
get = function ( info ) return Options.num_cycles_to_show . get ( ) ; end ,
} ,
_fill_rest_of_line = {
name = " " ,
order = t_cnt : plusplus ( ) ,
type = " description " ,
width = " full " ,
} ,
log_level = {
name = " Log level " ,
order = t_cnt : plusplus ( ) ,
desc = " Log level " ,
type = " select " ,
style = " dropdown " ,
width = " normal " ,
values = Options.log_level . options ,
set = function ( info , val ) Options.log_level . set ( val ) ; end ,
get = function ( info ) return Options.log_level . get ( ) ; end ,
} ,
spawn_alert_sound = {
name = " Spawn alert sound " ,
order = t_cnt : plusplus ( ) ,
desc = " Sound alert that plays when boss spawns " ,
type = " select " ,
style = " dropdown " ,
width = " normal " ,
values = Options.spawn_alert_sound . options ,
set = function ( info , val ) Options.spawn_alert_sound . set ( val ) ; end ,
get = function ( info ) return Options.spawn_alert_sound . get ( ) ; end ,
} ,
spawn_alert_sec_before = {
name = " Alert sec before spawn " ,
order = t_cnt : plusplus ( ) ,
desc = " How many seconds before boss spawn the alert will happen " ,
type = " range " ,
min = 0 ,
max = 60 * 5 ,
softMin = 0 ,
softMax = 30 ,
bigStep = 1 ,
isPercent = false ,
width = " normal " ,
set = function ( info , val ) Options.spawn_alert_sec_before . set ( val ) ; end ,
get = function ( info ) return Options.spawn_alert_sec_before . get ( ) ; end ,
} ,
}
}
end
function Options . Initialize ( )
Options.InitializeItems ( ) ;
Options.InitializeOptionsTable ( ) ;
end