You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1122 lines
49 KiB

-- ------------------------------------------------------------------------- --
-- Project: Executive Assistant - Custom To-Do/Task List Manager
-- Author: VincentSDSH
-- Version: 1.4b - w9.0
-- ------------------------------------------------------------------------- --
-- Command: /ea or /exa
--
-- ------------------------------------------------------------------------- --
-- W9.x Notes
-- Blizzard: "Instead of always creating backdrops on every frame, they require each frame to explicitly inherit
-- backdrops. There is no change in functionality, only the default setting has been changed in an effort
-- to improve performance."
-- Adding "BackdropTemplate" as para4 to CreateFrame() to set things back to normal. Might be overkill but it'll save a lot of retesting
--
-- ------------------------------------------------------------------------- --
--
-- Optional
-- See line 72 of ea_Options.lua to change from 60min to 30min time intervals
--
-- [ ] Option for Command Line Target to be Per Character, set per character.
-- Task Resets (Occ Intern) should trigger a LDB Update
-- ------------------------------------------------------------------------- --
local AddonName = ...
ExecAssist = LibStub("AceAddon-3.0"):NewAddon(AddonName, "AceEvent-3.0", "AceTimer-3.0", "AceHook-3.0")
ExecAssist.Dialog = LibStub("AceConfigDialog-3.0")
ExecAssist.debug = function(data, label, colorize) if ExecAssist.db.sv.debug then local r, b, g if not colorize then r=1; g=1; b=.8 elseif (label and data) then r=0; g=1; b=0 else r=1; g=0; b=0 end; local eaColon = ("::"):cf("EAblue"); DEFAULT_CHAT_FRAME:AddMessage( eaColon..("EA_debug"):cf("EAtan")..eaColon .." ".. (label and (label.." is: ") or "").. tostring(data), r, g, b); end end
local debug = ExecAssist.debug
local L = LibStub("AceLocale-3.0"):GetLocale(AddonName)
function ExecAssist:OnInitialize()
self.wowVer = "9.0"
self.FC = "Executive_Assistant_FileCabinet"
-- Extend Plumbing ------------------------------------------------------- --
self:extendStringFunc()
-- Defaults -------------------------------------------------------------- --
self.EventsRegistered = {}; self.prototype = {}
self.prototype.Group = {
["isGroup"] = true,
["id"] = "", -- self handle :: pass (hGroup) rather than (hGroup, groupID) when asking a parent to operate on the child's /reference/ not just the child (e.g., .DO ops, etc)
["p"] = "", -- parent GroupID
["listName"] = "Default New Group Name",
-- ["objbName"] = "Default New Group Name",
["defaultEnabled"] = true, -- ENABLED
["hideDays"] = {}, -- {Sun -> Sat}
["DO"] = {}
}
self.prototype.Task = {
["isTask"] = true,
["id"] = "", -- taskID
["p"] = "", -- parent GroupID
["taskName"] = "Default New Task Name",
-- ["objbName"] = "Default New Task Name",
["defaultEnabled"] = true, -- ENABLED
["resetType"] = "Daily Automatic", -- {Daily, Weekly, Other}
["hideDays"] = {} -- {Sun -> Sat} Primed b/c the multiselect control returns
}
self.icons = {
["defaultLDBIcon"] = ([[Interface\Addons\%s\icons\ExecutiveAssistant_appIcon]]):format(AddonName),
["ldb_Complete"] = ([[Interface\AddOns\%s\icons\ExecutiveAssistant_on]]):format(AddonName),
["ldb_Incomplete"] = ([[Interface\AddOns\%s\icons\ExecutiveAssistant_off]]):format(AddonName),
["enabled"] = ([[Interface\Addons\%s\icons\ExecutiveAssistant_on]]):format(AddonName),
["disabled"] = ([[Interface\Addons\%s\icons\ExecutiveAssistant_off]]):format(AddonName),
["used"] = ([[Interface\Addons\%s\icons\ExecutiveAssistant_used]]):format(AddonName),
["notused"] = ([[Interface\Addons\%s\icons\ExecutiveAssistant_notused]]):format(AddonName),
["used_R"] = ([[Interface\Addons\%s\icons\ExecutiveAssistant_used_reminder]]):format(AddonName),
["notused_R"] = ([[Interface\Addons\%s\icons\ExecutiveAssistant_notused_reminder]]):format(AddonName),
["disabledGroup"] = ([[Interface\Addons\%s\icons\ExecutiveAssistant_disabled]]):format(AddonName),
["twExpanded"] = ([[Interface\Addons\%s\icons\ExecutiveAssistant_twExpanded]]):format(AddonName),
["twCollapsed"] = ([[Interface\Addons\%s\icons\ExecutiveAssistant_twCollapsed]]):format(AddonName),
["ldb_Expanded_h"] = ([[Interface\AddOns\%s\icons\ExecutiveAssistant_Expanded_header]]):format(AddonName),
["ldb_Collapsed_h"] = ([[Interface\AddOns\%s\icons\ExecutiveAssistant_Collapsed_header]]):format(AddonName),
["ldb_Expanded"] = ([[Interface\AddOns\%s\icons\ExecutiveAssistant_Expanded]]):format(AddonName),
["ldb_Collapsed"] = ([[Interface\AddOns\%s\icons\ExecutiveAssistant_Collapsed]]):format(AddonName),
["ldb_OneChar"] = ([[Interface\AddOns\%s\icons\ExecutiveAssistant_showOne]]):format(AddonName),
["ldb_AllChar"] = ([[Interface\AddOns\%s\icons\ExecutiveAssistant_showAll]]):format(AddonName),
["ldb_tt_PGT"] = ([[Interface\AddOns\%s\icons\ExecutiveAssistant_PGT]]):format(AddonName),
["ldb_tt_GTP"] = ([[Interface\AddOns\%s\icons\ExecutiveAssistant_GTP]]):format(AddonName),
["ldb_showGroups"] = ([[Interface\AddOns\%s\icons\ExecutiveAssistant_showGroups]]):format(AddonName),
["ldb_hideGroups"] = ([[Interface\AddOns\%s\icons\ExecutiveAssistant_hideGroups]]):format(AddonName),
["ldb_showALLgroups"] = ([[Interface\AddOns\%s\icons\ExecutiveAssistant_showALLGroups]]):format(AddonName),
["ldb_ShowOnlySelectedGroup"] = ([[Interface\AddOns\%s\icons\ExecutiveAssistant_ShowOnlySelectedGroup]]):format(AddonName),
["tw_config"] = ([[Interface\Addons\%s\icons\ExecAssist_Config]]):format(AddonName),
["tw_config_push"] = ([[Interface\Addons\%s\icons\ExecAssist_Config_push]]):format(AddonName),
}
-- Setup AceDB
self.DBDefaults = {
-- why GLOBAL vs PROFILE or CHAR for charStem data? Profiles coonotate being able to 'change hats' mid-session
-- which would mean 'being someone else' in the context of this addon, making it confusing to say the least,
-- or to swap to different sub-sets of actions, which is understandable but a less-in-control way of doing it.
-- Moreover, I'd still have to dig into the .sv[*] end of the db var to find the other profiles to list out
-- the other characters for the GTP orientation or the full PGT orientation.
-- This same thinking applies to placing the data in Char. It doesn't make accessing it that much easier
-- (though it would be technically faster/more-efficient when only looking at the current character, that
-- measurement is in miniscule fractions of a milisecond second) and I'd still have to traverse the .sv[*]
-- end of the AceDB structure when looking at all chars.
-- Doing it this way means I can have a standard method (charStem vs self.db.char & self.db.sv.char) and
-- have no chance of running afoul of some profile-related giggery-pokery of which I might be unaware.
-- The db.char route is used for things I found a need to be character-specific, depending on the class &
-- addons used, usage might differ (e.g., minimap button position & hide/show; task-window usage & position
-- (heavy user) vs ldb-tooltip (alt with few tasks) )
["char"] = {
["charSpecificCmdLineTarget"] = false,
["DBIconTable"] = { ["hide"] = false },
["useTaskWindow"] = true,
["useDataBrokerTooltip"] = true,
["map"] = {["char"] = nil, ["TW"] = nil, ["GTP"] = nil},
},
["global"] = {
["Options"] = {
["AllowAPI"] = false,
["configConfig"] = {
["scale"] = 1, -- ExecAssist.Dialog.OpenFrames[ExecAssist.opts.f_reg].frame:SetScale(1.2)
["width"] = 800,
["height"] = 700,
},
["ldbLabel"] = L.appName,
["showLoginAlerts"] = false,
["WeeklyResetDay"] = 3,
["DailyResetTime"] = 6,
["cfg_groupColor"] = {["r"] = 1, ["g"] = 1, ["b"] = 0},
["ldbIcon"] = "defaultLDBIcon",
["SaveCollapseMap"] = true,
},
["acctwideStem"] = { -- subbing agg to make space for possible future metadata...
["agg"] = { -- Not /technically/ an agglomeration since only taskID completion tags would be in play
}
},
["charStem"] = {
},
["groupStem"] = {
["garden"] = { -- Starting Point (DO) for Groups (it was this or a hidden faux-'parent')
},
["agg"] = { -- The Great Agglomeration, groupIDs and taskIDs >> groupID.DO = Display Order
["garden"] = { -- Starting Point (DO) for Groups (it was this or a hidden faux-'parent')
["id"] = "garden",
["listName"] = "garden",
["DO"] = {}
},
},
},
["taskWindow"] = {
["locked"] = false,
["hidebuttons"] = false,
["widthMethod"] = false,
["MinWidth_FontString"] = 120,
["FixedWidth_FontString"] = 380,
["useRemembered_toggleState"] = true, -- 0.9.9j
["toggleState_ToggledOff"] = nil, -- 0.9.9j
["useDragFrame"] = true,
["strata"] = "LOW",
["pos"] = {
["idx"] = 1,
["relTW"] = "CENTER",
["posW_rel"] = "CENTER",
["posW_relP"] = "CENTER",
["xOff"] = 0,
["yOff"] = 0,
},
["HideEmptyGroups"] = true,
["defaultCollapse"] = false,
["opacity_mouseover"] = 1,
["opacity_faded"] = 1,
["hideincombat"] = false,
["ButtonPos"] = 2,
["useMouseoverHighlight"] = true,
["useCounts_onHeaders"] = true,
["displayType_onHeaders"] = 1,
["rightMouse_togglesShowChecked"] = true,
["showChecked"] = true,
["enableTooltipTooltips"] = true,
["widthMethod"] = 1,
["style"] = {
["background"] = "Solid", -- "Blizzard Tooltip",
["border"] = "Blizzard Tooltip",
["bgcolor"] = {["r"] = 0.01, ["g"] = 0.01, ["b"] = 0.01, ["a"] = 1},
["bdrcolor"] = {["r"] = 0.01, ["g"] = 0.01, ["b"] = 0.01, ["a"] = 1},
},
["fontshadow"] = {
["shadowcolor"] = {["r"] = 0, ["g"] = 0, ["b"] = 0, ["a"] = .75},
["offset"] = {["x"] = 1, ["y"] = -1}
},
},
["tooltip"] = {
["AutoHideDelay"] = .01, -- seconds before the libQTip disappears
["HideChar_ifNoIncomplete"] = false,
["HideEmptyGroups"] = true,
["defaultCollapse"] = false,
["rightMouse_togglesShowChecked"] = true,
["showChecked"] = true,
["defaultExpandSelf"] = true,
["OnlyCurrentChar"] = true,
["AllChar_GroupCharNames"] = true,
["ShowServerNames"] = true,
["useMouseoverHighlight"] = true,
["default_tooltipType"] = "PGT",
["standard_font"] = "Friz Quadrata TT",
["standard_size"] = 10,
["header_font"] = "Friz Quadrata TT",
["header_size"] = 12,
["snowflake_font"] = "Friz Quadrata TT",
["snowflake_size"] = 9,
["fontshadow"] = {
["shadowcolor"] = {["r"] = 0, ["g"] = 0, ["b"] = 0, ["a"] = .75},
["offset"] = {["x"] = 1, ["y"] = -1}
},
["npc"] = {
["npcColor"] = {["r"] = 0.4, ["g"] = 0.4, ["b"] = 0.4, ["a"] = 1},
},
["tooltipStyle"] = {
["useStyle"] = false,
["bgFile"] = "Solid", -- "Interface/Tooltips/UI-Tooltip-Background"
["edgeFile"] = "Blizzard Tooltip", -- "Interface/Tooltips/UI-Tooltip-Border"
["edgeSize"] = 16,
["insets"] = 4,
["bgcolor"] = {["r"] = 0, ["g"] = 0, ["b"] = 0, ["a"] = 1},
["bdrcolor"] = {["r"] = 0.6, ["g"] = 0.6, ["b"] = 0.6, ["a"] = 1},
},
["useCounts_onHeaders"] = true,
["displayType_onHeaders"] = 1,
["useCounts_onLDB"] = true,
["displayType_onLDB"] = 1,
["default_GroupDisplayMode_PGT"] = 1, -- default & override group display mode
["ShowGroupNames_PGT"] = true, -- group display modes
["ShowAllGroups_PGT"] = true, -- group display modes
["ShowOnlySelectedGroup_PGT"] = true, -- group display modes
["HideGroupNames_PGT"] = true, -- group display modes
["default_GroupDisplayMode_GTP"] = 1, -- default & override group display mode
["ShowAllGroups_GTP"] = true, -- group display modes
["HideGroupNames_GTP"] = true, -- group display modes
["tooltipButtonPos"] = 1,
["color_Group"] = {["r"] = 0.78, ["g"] = 0.61, ["b"] = 0.43},
["color_TaskName"] = {["r"] = 1, ["g"] = 1, ["b"] = 1 },
["color_taskCounts"] = {["r"] = 0.43, ["g"] = 0.61, ["b"] = 0.78},
["enableTooltipTooltips"] = true,
["SM"] = { -- Style Manager
["acctwide"] = {
["useStyle"] = true,
["useText"] = 2,
["useText_text"] = "*",
["useColor"] = 2,
["color"] = {["r"] = 0, ["g"] = 0.94, ["b"] = 0.94},
},
["purgable"] = {
["useStyle"] = true,
["useText"] = 2,
["useText_text"] = "(p)",
["useColor"] = 2,
["color"] = {["r"] = 1, ["g"] = 0, ["b"] = 0.5},
},
["hidden"] = {
["useStyle"] = true,
["useText"] = 2,
["useText_text"] = "(i)",
["useColor"] = 2,
["color"] = {["r"] = 0.73, ["g"] = 0.61, ["b"] = 0.78},
},
["cmdLineTarget"] = {
["useStyle"] = true,
["useText"] = 2,
["useText_text"] = "(c)",
["useColor"] = 2,
["color"] = {["r"] = 0.33, ["g"] = 0.54, ["b"] = 0.52},
},
["snowflake"] = {
["useStyle"] = true,
["useText"] = 2,
["useText_text"] = "[Z]",
["useColor"] = 2,
["color"] = {["r"] = 1, ["g"] = 0.49, ["b"] = 0.4},
},
},
},
-- ["clickmapOrder"] -> local clickmapOrder = {} in ea_Options to allow for safe injection from modules that isn't processed when they are disabled
["clickmap"] = { -- LDB -- since it's not user alterable or put in the sv file, could move the full clickmap into this...but that would make any 3rd-party extensibility problematic at best; easy enough to stuff in for 1-index maint if the API idea is shelved
["CONFIG"] = {
["code"] = nil, ["m"] = false, ["s"] = nil, ["a"] = nil, ["c"] = nil, ["notify"] = true,
["name"] = (L.clickmap_CONFIG_name):format(L.appName),
["desc"] = (L.clickmap_CONFIG_desc):format(L.appName),
["func"] = function() ExecAssist:doLoadConfig() end,
},
["HELP"] = {
["code"] = nil, ["m"] = false, ["s"] = nil, ["a"] = nil, ["c"] = nil, ["notify"] = true,
["name"] = (L.clickmap_HELP_name):format(L.appName),
["desc"] = (L.clickmap_HELP_desc):format(L.appName),
["func"] = function() ExecAssist:doLoadHelp() end,
},
["CLICKMAP"] = {
["code"] = nil, ["m"] = false, ["s"] = nil, ["a"] = nil, ["c"] = nil, ["notify"] = true,
["name"] = L.clickmap_CLICKMAP_name,
["desc"] = L.clickmap_CLICKMAP_desc,
["func"] = function() ExecAssist:doLoadClickMap() end,
},
["TACM"] = {
["code"] = nil, ["m"] = false, ["s"] = nil, ["a"] = nil, ["c"] = nil, ["notify"] = true,
["name"] = L.clickmap_TACM_name,
["desc"] = L.clickmap_TACM_desc,
["func"] = function() ExecAssist:doLoadTaskMaint() end,
},
["STYLEMGR"] = {
["code"] = nil, ["m"] = false, ["s"] = nil, ["a"] = nil, ["c"] = nil, ["notify"] = true,
["name"] = L.clickmap_STYLEMGR_name,
["desc"] = L.clickmap_STYLEMGR_desc,
["func"] = function() ExecAssist:doLoadSyleMgr() end,
},
["TOOLTIP CONFIG"] = {
["code"] = nil, ["m"] = false, ["s"] = nil, ["a"] = nil, ["c"] = nil, ["notify"] = true,
["name"] = L.clickmap_TOOLTIPCONFIG_name,
["desc"] = L.clickmap_TOOLTIPCONFIG_desc,
["func"] = function() ExecAssist:doLoadTooltipConfig() end,
},
["TASKWIN CONFIG"] = {
["code"] = nil, ["m"] = false, ["s"] = nil, ["a"] = nil, ["c"] = nil, ["notify"] = true,
["name"] = L.clickmap_TASKWINCONFIG_name,
["desc"] = L.clickmap_TASKWINCONFIG_desc,
["func"] = function() ExecAssist:doLoadTaskWindow() end,
},
["RESET"] = {
["code"] = nil, ["m"] = false, ["s"] = nil, ["a"] = nil, ["c"] = nil, ["notify"] = true,
["name"] = L.clickmap_RESET_name,
["desc"] = L.clickmap_RESET_desc,
["func"] = function() ExecAssist:doLoadResetOpts() end,
},
["reset_Manual"] = {
["code"] = nil, ["m"] = false, ["s"] = nil, ["a"] = nil, ["c"] = nil, ["notify"] = true,
["name"] = L.clickmap_reset_Manual_name,
["desc"] = L.clickmap_reset_Manual_desc,
["func"] = function() ExecAssist:resetTasks(nil, nil, true) end,
},
["purgePurgables"] = {
["code"] = nil, ["m"] = false, ["s"] = nil, ["a"] = nil, ["c"] = nil, ["notify"] = true,
["name"] = L.clickmap_purgePurgables_name,
["desc"] = (L.clickmap_purgePurgables_desc):format(L.appName),
["func"] = function() ExecAssist:resetTasks(nil, nil, nil, true) end, -- purge purgables
},
["ToggleTaskWindow"] = {
["code"] = nil, ["m"] = false, ["s"] = nil, ["a"] = nil, ["c"] = nil, ["notify"] = true,
["name"] = L.clickmap_ToggleTaskWindow_name,
["desc"] = L.clickmap_ToggleTaskWindow_desc,
["func"] = function() ExecAssist:doToggleTaskWindow() end,
},
["ShowDataBrokerTT"] = {
["code"] = nil, ["m"] = false, ["s"] = nil, ["a"] = nil, ["c"] = nil, ["notify"] = true,
["name"] = L.clickmap_ShowDataBrokerTT_name,
["desc"] = L.clickmap_ShowDataBrokerTT_desc,
["func"] = function() ExecAssist:doShowDataBrokerTooltip() end,
},
["ClickMap_Config"] = {
["code"] = nil, ["m"] = false, ["s"] = nil, ["a"] = nil, ["c"] = nil, ["notify"] = true,
["name"] = L.clickmap_CLICKMAPconfig_name,
["desc"] = L.clickmap_CLICKMAPconfig_desc,
["func"] = function() ExecAssist:configureClickMap() end,
},
["ToggleTooltipTips"]= {
["code"] = nil, ["m"] = false, ["s"] = nil, ["a"] = nil, ["c"] = nil, ["notify"] = true,
["name"] = L.clickmap_ToggleTooltipTips_name,
["desc"] = L.clickmap_ToggleTooltipTips_desc,
["func"] = function() ExecAssist:toggleTooltipTips() end,
},
["ToggleShowTWControlButtons"]= {
["code"] = nil, ["m"] = false, ["s"] = nil, ["a"] = nil, ["c"] = nil, ["notify"] = true,
["name"] = L.clickmap_HideTaskWindowControlButtons_name,
["desc"] = L.clickmap_HideTaskWindowControlButtons_desc,
["func"] = function() ExecAssist:doToggleShowTWControlButtons() end,
},
},
},
}
self.db = LibStub("AceDB-3.0"):New("ExecAssistDB", self.DBDefaults, true)
-- Prime char vars and charStem
self.userCurrent = UnitName("player").." - "..GetRealmName(); self.userConfigDisplay = self.userCurrent
if not self.db.global.charStem[self.userCurrent] then self.db.global.charStem[self.userCurrent] = {["agg"] = {}} end -- new user, establish agglomeration
debug("* Debugging Mode Active *") -- dev sanity check
-- Register Options ------------------------------------------------------ --
self:regOptions()
-- Commandline ----------------------------------------------------------- --
local cmdLine = {
type = "group",
name = "",
args = {
config = {
type = "execute",
name = "",
desc = L.AddonConfiguration,
func = function() ExecAssist:doLoadConfig() end,
order = 0
},
manage = {
type = "execute",
name = "",
desc = L.CommandLineHelp_manage,
func = function() ExecAssist:doLoadTaskMaint() end,
order = 2
},
task = {
type = "execute",
name = "",
desc = L.CommandLineHelp_task,
func = function(...) ExecAssist:doAddPurgableTask(...) end,
order = 3
},
mytask = {
type = "execute",
name = "",
desc = L.CommandLineHelp_mytask,
func = function(...) ExecAssist:doAddPersonalPurgableTask(...) end,
order = 4
},
setgroup = {
type = "execute",
name = "",
desc = L.CommandLineHelp_setgroup,
func = function(...) ExecAssist:doResetTargetGroup(...) end,
order = 5
},
npc = {
type = "execute",
name = "",
desc = "Create an NPC",
func = function(...) ExecAssist:doCreateNPC(...) end,
order = 6
},
debug = {
cmdHidden = true,
type = "execute",
name = "",
desc = "Toggles Debug Mode",
func = function() ExecAssist:doDebuggingMode() end,
order = 30
},
}
}
LibStub("AceConfig-3.0"):RegisterOptionsTable(L.appName.." CmdLine", cmdLine, {"ea", "exa"})
-- libDataBroker and DBIcon ---------------------------------------------- --
self.meatPopcicle = self:ldb_ObjectCreate()
LibStub("LibDBIcon-1.0"):Register(AddonName, self.meatPopcicle, self.db.char.DBIconTable)
end
function ExecAssist:OnEnable()
local sdbg = self.db.global
-- char prime
sdbg.charStem[self.userCurrent].charClass = select(2, UnitClass("player")) -- reset each time in case a char is deleted and remade w/ new class and same name
self:mkCharList() -- make Alphabetized Character List
-- ------------------------------------------------------------------------------------------------------------------------------ --
-- taskTypes Loader
self.taskTypes = L.optsTable_base.TaskTypes
-- iterate intern modules --
self.loadedModules = {}
for name, module in self:IterateModules() do -- module:Enable() is implicit
self.loadedModules[name] = true
self:clickmapExtend(name, module:intern_getClickMap() )
self:amalgamExtend( module:intern_getOptionsPanel() )
self:helpExtend( module:intern_getExtendedHelp() )
self:taskTypeExtend( module:intern_getNewTaskTypes() )
end
-- taskTypes OrderedList (post all loaded modules so any extenders are captured)
self.taskTypes_Index = {}; self.isAvail_taskType = {}
-- stublist keeps consistent order in default internal types
for n = 1,7 do table.insert(self.taskTypes_Index, L.optsTable_base.TaskTypes_stublist[n]); self.isAvail_taskType[L.optsTable_base.TaskTypes_stublist[n]] = true end
for k, v in pairs(self.taskTypes) do if not self.isAvail_taskType[k] then table.insert(self.taskTypes_Index, k); self.isAvail_taskType[k]=true end end
-- add Missing Module to taskType (must NOT be in Index
self.taskTypes[L.optsTable_missingmodule_label] = L.optsTable_missingmodule
-- ------------------------------------------------------------------------------------------------------------------------------ --
-- Load the DB into Options Tables
self:loadGroups_toOptionsTable()
-- Check for Resets & set timer
self.timers = {}
self:doResetCheck()
-- reset At Login tasks
self:resetTasks(nil, nil, nil, nil, true)
-- collapse map
self:pushCollapseMap()
-- Load the Task Window if needed
local sdbc = self.db.char
if sdbc.useTaskWindow then -- useTaskWindow is always char specific; internal settings may or may not be, thus the getHandle
self:CreateTaskWindow()
local twStem = self:getHandle_TaskWindow()
if twStem.hideincombat then self:registerCombatEvents(true) end -- Register Events
if twStem.useRemembered_toggleState and twStem.toggleState_ToggledOff then
self:doToggleTaskWindow(true) -- forceHide=true
else
if twStem.toggleState_ToggledOff then twStem.toggleState_ToggledOff = false end -- If state isn't remembered, _ToggledOff must be false
-- DevNote: should have a rummage and see if .toggleState_ToggledOff has any legacy connections, otherwise
-- if not .useRemembered_toggleState then this shoudln't even be set in the first place.
end
end
-- Update LDB if needed
if sdbg.tooltip.useCounts_onLDB and not self.taskWindow then self:ldb_refreshCounts() end
-- tooltip mode pool
local I = self.icons
self.mode_PGT = sdbg.tooltip.default_GroupDisplayMode_PGT
self.mode_GTP = sdbg.tooltip.default_GroupDisplayMode_GTP
self.modePool = {
[1] = {["b"] = "ShowGroupNames", ["i"] = self:mkLink(I.ldb_showGroups, 16), ["PGT"] = true; ["GTP"] = false},
[2] = {["b"] = "ShowAllGroups", ["i"] = self:mkLink(I.ldb_showALLgroups, 16), ["PGT"] = true; ["GTP"] = true },
[3] = {["b"] = "ShowOnlySelectedGroup", ["i"] = self:mkLink(I.ldb_ShowOnlySelectedGroup, 16), ["PGT"] = true; ["GTP"] = false},
[4] = {["b"] = "HideGroupNames", ["i"] = self:mkLink(I.ldb_hideGroups, 16), ["PGT"] = true; ["GTP"] = true }
}
-- Brand New User, Setup Initial Tasks and Clickmapping
if not sdbg.IsOldHat then
local groupStem = sdbg.groupStem
local groupID = self:AddGroup(L.NewUserTasks, groupStem.agg["garden"])
local hGroup = groupStem.agg[groupID]
hGroup.cmdLineTarget = true
groupStem.cmdLineTarget = hGroup.id
local function newTask(taskName, suppressRefresh_cmdline)
local hTask = self:AddTask(hGroup, nil, suppressRefresh_cmdline)
hTask.taskName = taskName
hTask.resetType = L.Manual
hTask.isAcctWide = true
end
local hTask = sdbg.groupStem.agg[hGroup.DO[1]]
hTask.taskName = L.BrandNewUserTask_0
hTask.resetType = L.Manual
hTask.isAcctWide = true
newTask(L.BrandNewUserTask_1, true)
newTask(L.BrandNewUserTask_2, true)
newTask(L.BrandNewUserTask_3, true)
newTask(L.BrandNewUserTask_4, true)
newTask(L.BrandNewUserTask_5, true)
newTask(L.BrandNewUserTask_6, true)
newTask(L.BrandNewUserTask_7, true)
newTask(L.BrandNewUserTask_8, true)
newTask(L.BrandNewUserTask_9, true)
newTask(L.BrandNewUserTask_10, true)
newTask(L.BrandNewUserTask_11, false) -- initial run has Task Window enabled
-- Update GroupMaintenance var, so new tasks show in the list
self:loadGroups_toOptionsTable()
hGroup.cmdLineTarget = false
groupStem.cmdLineTarget = nil
-- inject defaults into the ClickMap
local cm = self.db.global.clickmap
cm["CONFIG"]["code"] = "Lm"; cm["CONFIG"]["m"] = "LeftButton"; cm["CONFIG"]["notify"] = false
cm["TACM"]["code"] = "Rm"; cm["TACM"]["m"] = "RightButton"; cm["TACM"]["notify"] = false
cm["HELP"]["code"] = "Rms"; cm["HELP"]["m"] = "RightButton"; cm["HELP"]["s"] = true; cm["HELP"]["notify"] = true
cm["ClickMap_Config"]["code"] = "Rmsc"; cm["ClickMap_Config"]["m"] = "RightButton"; cm["ClickMap_Config"]["s"] = true; cm["ClickMap_Config"]["c"] = true; cm["ClickMap_Config"]["notify"] = true
sdbg.IsOldHat = true
end
-- Init quickTaskEntry
self:quickTaskEntry_SingleTask_Setup()
-- establish the ClickMap
self:build_clickmapServiceIndex() -- builds the Service Index (mouse/key combination)
self:build_clickmapOptions() -- builds options dynamically from DBDefaults
end
-- Time and Reset funcs --
function ExecAssist:doResetCheck()
local sdbg = self.db.global
-- Timer Trap -------------------------------------------------------------------------- --
if not sdbg.nextMidnightReset then sdbg.nextMidnightReset = self:happyMidnight(time() ) end
if not sdbg.nextDailyReset then sdbg.nextDailyReset = self:happyDaily( time() ) end
if not sdbg.nextWeeklyReset then sdbg.nextWeeklyReset = self:happyWeekly( time() ) end
-- -------------------------------------------------------------------------- Timer Trap --
-- rc > 0 tasks need to be reset
if time() - sdbg.nextMidnightReset > 0 then self:resetTasks(nil, nil, nil, nil, nil, true, true) end
if time() - sdbg.nextDailyReset > 0 then self:resetTasks(true) end
if time() - sdbg.nextWeeklyReset > 0 then self:resetTasks(nil, true) end
-- reset timer to next Resetcheck (cancel then set next-lowest as next doResetCheck (midnight or daily reset time)
local timerResetCheck = self.timers.doResetCheck
if timerResetCheck then self:CancelTimer(timerResetCheck) end
timerResetCheck = self:ScheduleTimer( "doResetCheck", sdbg.nextMidnightReset < sdbg.nextDailyReset and (sdbg.nextMidnightReset - time()) or (sdbg.nextDailyReset - time()) )
end
-- normalizing the execution-time makes the comparitor a hard-trigger; wonder if there are n-day resetables worth worrying about -- debug( date("%Y-%m-%d %H:%M:%S", timedateObj) )
function ExecAssist:timeWarp(oriTime, daysToWarp) return ( oriTime + (daysToWarp * 86400) ) end -- could have done last+(n*86400) but RHPS
function ExecAssist:happyMidnight(oriTime, Options_SetExplicitDay)
-- returns midnight of the date given -- returns Midnight Tomorrow (00:00am)
local t
if Options_SetExplicitDay then
t = date("*t", oriTime) -- exact time
else
t = date("*t", oriTime + 86400) -- pushes 24hrs
end
t.hour = 0 -- set happy hour
t.min = 0 -- set happy minute
t.sec = 0 -- set happy seconds
return time(t)
end
function ExecAssist:happyWeekly(oriTime) -- Normalizes a time numeric to the last WeeklyResetDay (perfect comparitor)
local real_weeklyDoW = date("*t", oriTime).wday -- find the oriTime day-of-week
local walkbackDays = 0 -- # days that real_ needs to wind back to become perfect_
local WeeklyResetDay = self.db.global.Options.WeeklyResetDay -- get proper weekly reset day
if WeeklyResetDay == real_weeklyDoW then -- today = weekly reset day
walkbackDays = 0
elseif WeeklyResetDay < real_weeklyDoW then
walkbackDays = real_weeklyDoW - WeeklyResetDay -- week has not wrapped
else
walkbackDays = (7-WeeklyResetDay) + real_weeklyDoW -- week has wrapped
end
-- print( tostring( date("*t", time()).wday ).." - "..tostring(ExecAssist.db.global.Options.WeeklyResetDay) )
-- /script print( date("%c",ExecAssist.db.global.nextWeeklyReset))
-- /script print( date("%c",ExecAssist.db.global.nextDailyReset))
return self:happyTime( self:timeWarp(oriTime, (7 - walkbackDays) ) ) -- adjust the requsite # of days, normalize the time of day, then return
end
function ExecAssist:happyDaily(oriTime) -- Normalizes a time numeric to the DailyResetTime (perfect comparitor)
if difftime( time(), self:happyTime(time()) ) > 0 then
return self:happyTime(self:timeWarp(oriTime, 1))
else
return self:happyTime(oriTime)
end
end
function ExecAssist:happyTime(oriTime) -- Inserts the user selected Reset Time into the time numeric
local s_DailyResetTime = self.optValues.ResetTimesList[self.db.global.Options.DailyResetTime]
local t = date("*t", oriTime) -- get a table of Time numeric, time() needs this table structure to reconstruct a time numeric
t.hour = s_DailyResetTime:sub(1, 2) -- set happy hour
t.min = s_DailyResetTime:sub(4) -- set happy minute
t.sec = 0 -- set happy seconds
return time(t) -- return happy time
end
function ExecAssist:resetTasks(resetDaily, resetWeekly, resetManual, purgePurgables, resetAtLogins, resetReminder, resetCalendar)
local sdbg = self.db.global
local charStem_base = sdbg.charStem
local aggStem = sdbg.groupStem.agg
local self_happyMidnightToday = self:happyMidnight(time(), true)
local function sendAlerts()
if resetDaily then self:alert(L.resetAlert_resetDaily) end
if resetWeekly then self:alert(L.resetAlert_resetWeekly) end
if resetManual then self:alert(L.resetAlert_resetManual) end
if purgePurgables then self:alert(L.resetAlert_purgePurgables) end
if resetAtLogins then self:alert(L.resetAlert_resetAtLogins) end
if resetReminder then self:alert(L.resetAlert_resetReminder) end
if resetCalendar then self:alert(L.resetAlert_resetCalendar) end
end
local function reset_ifInScope(hTask_cS, taskID, charName) -- cS=charStem
-- This handles PER-CHARACTER .checked field related activities.
-- DATE-RELATED activties (Calender Automatic, Reminder) are handled AFTER
local hTask = aggStem[taskID]
-- if not hTask then ExecAssist.db.global.problemchild2 = taskID; return end
if hTask_cS.checked then -- uncheck the .checked
if (resetDaily and hTask.resetType == L.DailyAutomatic) or
(resetWeekly and hTask.resetType == L.WeeklyAutomatic) or
(resetManual and hTask.resetType == L.Manual) or
(resetAtLogins and hTask.resetType == L.AtEachLogin) or
(resetReminder and hTask.resetType == L.Reminder) then -- L.Reminder MIGHT be converted from something else and .checked, better safe than sorry
hTask_cS.checked = nil
elseif purgePurgables and hTask.resetType == L.Purgable then
if hTask.isAcctWide then
-- If Account Wide, we kill it now since we're here b/c for AW, checked = ALL CHECKED
self:DeleteTask(hTask, aggStem[hTask.p].G) -- hItem & parent Geneaology for hardPrune()
else
-- Disable for charName (leaving checked in case I ever have to debug an sv file)
hTask_cS.userOverride = 3 -- Disable
hTask_cS.checked = nil -- remove .checked so we don't keep reprocessing it
end
-- -----------------------------------------
elseif resetCalendar and hTask.resetType == L.CalendarAutomatic then
if hTask.resetDate_Next <= self_happyMidnightToday then
hTask_cS.checked = nil
end
-- ------------------------------------------
end
end
end
-- Char Level Scans
for charName, charStem in pairs(charStem_base) do -- character-level completes
for itemID, hItem in pairs(charStem.agg) do -- agg=agglomeration
if itemID:isTask() then
reset_ifInScope(hItem, itemID, charName) -- charStem entries don't carry .id & purged purgables need to find the actual task entry hTask to nix & prune
end
end
end
for itemID, hItem in pairs(sdbg.acctwideStem.agg) do -- account-wide completes (always items)
reset_ifInScope(hItem, itemID)
end
-- Task Level Scans (Date-Related Activities and purgePurgables)
if resetReminder or resetCalendar or purgePurgables then
for itemID, hItem in pairs(aggStem) do -- agg=agglomeration
if itemID:isTask() then
if resetReminder and hItem.resetType ==L.Reminder then -- Reminder
if hItem.resetDate_Next and hItem.resetDate_Next <= self_happyMidnightToday then hItem.resetType = L.Purgable end
elseif resetCalendar and hItem.resetType == L.CalendarAutomatic then -- Calendar Automatic
if hItem.resetDate_Next and hItem.resetDate_Next <= self_happyMidnightToday then
-- Advance the _Next date to one in the future; then set _Last to 'previous cycle'
local paranoia = 0
while (hItem.resetDate_Next <= self_happyMidnightToday) and (paranoia < 100) do
paranoia = paranoia + 1
hItem.resetDate_Next = hItem.resetDate_Next + (86400 * hItem.offsetDays)
end
hItem.resetDate_Last = hItem.resetDate_Next - (86400 * hItem.offsetDays)
if paranoia >= 100 then self:alert(L.paranoia_Alert..hItem.taskName) end
end
elseif purgePurgables and hItem.resetType == L.Purgable then -- purgePurgables
-- hardCheck for Purgables ------------------------------------------------------------------------------------------------
local purge = true
for i=1, #ExecAssist.charList do if self:hasCleanGenes(ExecAssist.charList[i], itemID) then purge = false; break; end end
if purge then self:DeleteTask(hItem, aggStem[hItem.p].G) end -- hItem & parent Geneaology for hardPrune()
-- ------------------------------------------------------------------------------------------------------------------------
end
end
end
end
-- alerts
if ExecAssist.notLoginReset then sendAlerts()
else ExecAssist.notLoginReset = true;
if sdbg.Options.showLoginAlerts then sendAlerts() end
end
-- reset runtimes
if resetDaily then sdbg.nextDailyReset = self:happyDaily( time() ) end
if resetWeekly then sdbg.nextWeeklyReset = self:happyWeekly( time() ) end
if resetReminder or resetCalendar then sdbg.nextMidnightReset = self:happyMidnight( time() ) end
if sdbg.tooltip.useCounts_onLDB then self:ldb_refreshCounts() end
self:UpdateWindow()
-- notify Modules of reset
for name, module in self:IterateModules() do
module:intern_resetHandler(resetDaily, resetWeekly, resetManual, purgePurgables, resetAtLogins, resetReminder, resetCalendar)
end
end
-- Click-Map (active) --
local clickmapServiceIndex = {}
function ExecAssist:get_clickmapService(cmSvcTag) return self.db.global.clickmap[cmSvcTag] end -- used in building options
function ExecAssist:isBusy_clickmapServiceHandle(mouse, shift, alt, ctrl)
return clickmapServiceIndex[self:formatClick(mouse, shift, alt, ctrl)]
end
function ExecAssist:formatClick(mouse, shift, alt, ctrl) return (mouse == "LeftButton" and "Lm" or "Rm")..(shift and "s" or "")..(alt and "a" or "")..(ctrl and "c" or "") end
function ExecAssist:build_clickmapServiceIndex()
local cmStem = self.db.global.clickmap
clickmapServiceIndex = {}
for cmSvcTag, SvcOpts in pairs(cmStem) do
if SvcOpts.m then -- m=add since all click kinda need a mouse
clickmapServiceIndex[self:formatClick(SvcOpts.m, SvcOpts.s, SvcOpts.a, SvcOpts.c)] = cmSvcTag
end
end
end
function ExecAssist:ldbClickMap(mouse, shift, alt, ctrl)
local userRequestedAction
local clickmapService = clickmapServiceIndex[self:formatClick(mouse, shift, alt, ctrl)]
local cm = self.db.global.clickmap
if clickmapService then
userRequestedAction = cm[clickmapService]
if userRequestedAction.func then -- if .func=nil then Service is provided by an Intern or otherwise unloaded module/addon as .func is not saved into the savedvar file.
if cm[clickmapService].notify then self:alert(L.cm_running..userRequestedAction.name) end
userRequestedAction.func()
end
end
end
-- simple actions
function ExecAssist:doDebuggingMode() ExecAssist.db.sv.debug = not ExecAssist.db.sv.debug; ReloadUI() end
function ExecAssist:doUpdateStatusField(subSectionName, isCore)
self.Dialog.OpenFrames[self.opts.f_reg]:SetStatusText(
(L.statusText):cf("cream"):format(
L.StatusField_appName:cf("EAtan", "cream"),
GetAddOnMetadata(AddonName, 'Version'):cf("grass", "cream"),
L.authorName:cf("EAtan"),
(isCore and ("Page"):cf("cyan", "white") or ("Module"):cf("fuglyYellow", "white") ),
subSectionName:cf("grass", "cream")
)
)
end
function ExecAssist:doResetScale()
local dlg = self.aceDlg
if dlg then
dlg.frame:SetScale(dlg.scale)
self:Unhook(dlg.frame, "OnHide")
self.aceDlg = nil
end
end
function ExecAssist:doOpenConfigWindow(pathTable)
PlaySound(SOUNDKIT.IG_MAINMENU_OPTION_CHECKBOX_ON)
self.Dialog:Open(self.opts.f_reg)
-- Ace window scale is 1.0 with no methods to change it; however, you never know when someone's done a universal upscale so...
if not self.aceDlg then
self.aceDlg = { ["frame"] = self.Dialog.OpenFrames[self.opts.f_reg].frame }
local dlg = self.aceDlg; dlg.scale = self.aceDlg.frame:GetScale()
dlg.frame:SetScale(self.db.global.Options.configConfig.scale)
-- Only one hook is needed and many ':doOpenConfigWindow()' calls may be made using diffent ldb click actions before a window close
if not self:IsHooked(dlg.frame, "OnHide") then self:HookScript(dlg.frame, "OnHide", "doResetScale") end -- :IsHooked() should always be nil; but paranoia rules the day
-- ---------------------------------------------------------------------------------------------------------------------------
end
if type(pathTable) == "string" then
self.Dialog:SelectGroup(self.opts.f_reg, pathTable)
else
self.Dialog:SelectGroup(self.opts.f_reg, unpack(pathTable) ); -- table.unpack() is nil but unpack() is a thing...
end
end
function ExecAssist:doLoadConfig() self:doOpenConfigWindow(self.opts.f_MainOpts) end
function ExecAssist:doLoadHelp(subPage, subSubPage) self:doOpenConfigWindow({self.opts.f_Help, subPage, subSubPage}) end
function ExecAssist:doLoadClickMap() self:doOpenConfigWindow(self.opts.f_ClickMap) end
function ExecAssist:doLoadSyleMgr() self:doOpenConfigWindow(self.opts.f_StyleMgr) end
function ExecAssist:doLoadTaskMaint() self:doOpenConfigWindow(self.opts.f_TaskMaint) end
function ExecAssist:doLoadTooltipConfig() self:doOpenConfigWindow(self.opts.f_ToolTip) end
function ExecAssist:doLoadTaskWindow() self:doOpenConfigWindow(self.opts.f_TaskWindow) end
-- self.opts.f_CmdLine Intentionally Left Blank (not in clickmap and no reason it should be)
function ExecAssist:doLoadResetOpts() self:doOpenConfigWindow(self.opts.f_ResetOpts) end
function ExecAssist:doToggleShowTWControlButtons()
local twStem = self:getHandle_TaskWindow()
twStem.hidebuttons = not twStem.hidebuttons
self:UpdateWindow()
end
function ExecAssist:doToggleTaskWindow(forceHide)
local sdbc = self.db.char
if sdbc.useTaskWindow or forceHide then -- forceHide only comes from Options toggle OFF
if self.taskWindow:IsShown() or forceHide then
self.taskWindow:Hide()
self.taskWindow_posAnchor:Hide()
self.taskWindow_dragFrame:Hide()
self:getHandle_TaskWindow().toggleState_ToggledOff = true
else
local twStem = self:getHandle_TaskWindow()
self.taskWindow_posAnchor:Show()
self.taskWindow:Show()
if not twStem.locked and twStem.useDragFrame then self.taskWindow_dragFrame:Show() end
twStem.toggleState_ToggledOff = false
end
else
self:alert(L.TaskWindowNotEnabled, 1, .1, .1)
end
end
function ExecAssist:doShowDataBrokerTooltip()
self:displayTooltip(self.h_meatPopcicle, true)
end
function ExecAssist:toggleTooltipTips() local ttStem = self.db.global.tooltip; ttStem.enableTooltipTooltips = not ttStem.enableTooltipTooltips end
-- libDataBroker create func
function ExecAssist:ldb_ObjectCreate()
local tmpBackdrop, safeBackdrop = {} -- tooltip style handling
local ttsStem = ExecAssist.db.global.tooltip.tooltipStyle
return LibStub("LibDataBroker-1.1"):NewDataObject(AddonName, {
type = 'data source',
label = self.db.global.Options.ldbLabel, -- L.appName
text = "",
icon = self.icons[ExecAssist.db.global.Options.ldbIcon],
-- can have EITHER OnTooltipShow OR OnEnter, not both --> OnTooltipShow = function(tooltip) end
OnEnter = function(self)
if ttsStem.useStyle then
safeBackdrop = GameTooltip:GetBackdrop()
tmpBackdrop.bgFile = AceGUIWidgetLSMlists.background[ttsStem.bgFile]
tmpBackdrop.edgeFile = AceGUIWidgetLSMlists.border[ttsStem.edgeFile]
tmpBackdrop.edgeSize = ttsStem.edgeSize
tmpBackdrop.insets = { left = ttsStem.insets, right = ttsStem.insets, top = ttsStem.insets, bottom = ttsStem.insets }
GameTooltip:SetBackdrop(tmpBackdrop)
GameTooltip:SetBackdropBorderColor(ttsStem.bdrcolor.r, ttsStem.bdrcolor.g, ttsStem.bdrcolor.b, ttsStem.bdrcolor.a)
end
ExecAssist:displayTooltip(self)
end, -- self in this context is the ldbObject
OnLeave = function(self)
-- Restore Border
if ttsStem.useStyle then
GameTooltip:SetBackdrop(safeBackdrop)
GameTooltip:SetBackdropBorderColor(TOOLTIP_DEFAULT_COLOR.r, TOOLTIP_DEFAULT_COLOR.g, TOOLTIP_DEFAULT_COLOR.b);
GameTooltip:SetBackdropColor(TOOLTIP_DEFAULT_BACKGROUND_COLOR.r, TOOLTIP_DEFAULT_BACKGROUND_COLOR.g, TOOLTIP_DEFAULT_BACKGROUND_COLOR.b);
end
end,
OnClick = function(self, button) ExecAssist.h_meatPopcicle = self; ExecAssist:ldbClickMap(button, IsShiftKeyDown(), IsAltKeyDown(), IsControlKeyDown()) end,
})
end
-- Task Window Related Combat Events
function ExecAssist:registerCombatEvents(combatEventsEnabled)
if combatEventsEnabled then
self:Register("PLAYER_REGEN_DISABLED", "EVENT_combatStart")
self:Register("PLAYER_REGEN_ENABLED", "EVENT_combatEnd")
else
self:Unregister("PLAYER_REGEN_DISABLED")
self:Unregister("PLAYER_REGEN_ENABLED")
end
end
function ExecAssist:EVENT_combatStart() if self.taskWindow then self.taskWindow:Hide() end end
function ExecAssist:EVENT_combatEnd() if self.taskWindow then self.taskWindow:Show() end end
-- purgatorium
function ExecAssist:getFreshTaskStem()
local groupStem = self.db.global.groupStem
if groupStem.cmdLineTarget ~= nil then
if groupStem.agg[groupStem.cmdLineTarget] then
local hTask = ExecAssist:AddTask(groupStem.cmdLineTarget, nil, true)
return hTask
else
self:alert(L.cm_unableToFindGroup)
end
else
self:alert(L.cm_NoTagetSelected)
end
end
local function getArgTable(data)
local data, argT, sendTo = data:trim(), {}
local validArgs = {
["+"] = {
["+aw"] = true,
["+daily"] = L.DailyAutomatic,
["+weekly"] = L.WeeklyAutomatic,
["+manual"] = L.Manual,
["+calendar"] = L.CalendarAutomatic,
["+reminder"] = L.Reminder,
["+login"] = L.AtEachLogin
-- Module Injected Keys...
-- Precise Control Name is already added into the Task Types list; would only need a diminutive key (+<...>)
-- The /help/ for it would be the problem, getting it to display in an /ea list. That would mean extending
-- the Localized text (annotating it in fact) Maybe hold off on this...see if there's really a call for it first.
},
[">"] = true
}
local function getNextArg(data)
local nextArg, validArg
local f = data:find(" ")
if f then
nextArg = data:sub(1,f-1)
data = data:sub(f+1):trim()
validArg = true
else
nextArg = data
data = ""
validArg = true
end
return nextArg, data, validArg -- if abort, nextArg is invalid arg
end
local validArg = true
while validArg and #data > 2 and validArgs[data:sub(1,1)] do -- smallest possible arg = 3 (+aw)
local nextArg
nextArg, data, validArg = getNextArg(data)
if validArg then
if nextArg:sub(1,1) == ">" then
local charStem_base = ExecAssist.db.global.charStem
nextArg = nextArg:sub(2):lower()
local CCL = ExecAssist.compressed_charList -- for partial matches
local bits
for comp_charName, charName in pairs(CCL) do
bits = comp_charName:sub(1, nextArg:len()):lower()
if nextArg == bits then
if not sendTo then
sendTo = charName
else -- collision
sendTo = nil
ExecAssist:alert("["..nextArg.."] was not sufficiently unique, unable to establish character name.")
break;
end
end
end
if not sendTo then
ExecAssist:alert("Unable to find Character "..nextArg); validArg = nil;
break;
end
else
if validArgs["+"][nextArg] then
if nextArg == "+aw" then
argT["isAcctWide"] = true
elseif validArgs["+"][nextArg] then -- cheat to check for 3x at once
argT["resetType"] = validArgs["+"][nextArg]
end
else
ExecAssist:alert("Unrecognized argument: "..nextArg); validArg=nil
end
end
else
ExecAssist:alert("Unrecognized argument: "..nextArg); validArg=nil
end
end
return argT, sendTo, data, validArg
end
local function mkTaskExclusive(hTask, charName)
hTask.defaultEnabled = false
local charStem = ExecAssist.db.global.charStem[charName]
if not charStem.agg[hTask.id] then charStem.agg[hTask.id] = {} end
charStem.agg[hTask.id].userOverride = 2
if ExecAssist:isCharIgnored(charName, charStem) then
ExecAssist:alert("Nota Bene: ["..charName.."] is flagged 'Ignore Character' and Task will not be usable", 1, 1, 0)
end
end
function ExecAssist:doAddPurgableTask(aceTable, forceCurrentChar)
local data = aceTable.input:sub(6):trim()
local argT, sendTo, taskName, validArg = getArgTable(data)
local groupStem = self.db.global.groupStem
if validArg then
local hTask = ExecAssist:getFreshTaskStem()
if hTask then
if taskName ~= "" then hTask.taskName = taskName:gsub("//", "|") end -- if no name, it will be default
hTask.resetType = true and argT["resetType"] or L.Purgable
hTask.isAcctWide = argT["isAcctWide"]
if sendTo or forceCurrentChar then mkTaskExclusive(hTask, forceCurrentChar and self.userCurrent or sendTo) end
-- adds default dates and computes default offsets, otherwise the resetter function will have nils-to-numbers headaches
if hTask.resetType==L.Reminder or hTask.resetType==L.CalendarAutomatic then self:primeDateBased_TaskTypes(hTask) end
self:semiSmart_regrow(groupStem.agg[groupStem.cmdLineTarget].G) -- add to options table
self:UpdateWindow() -- since refresh was suppressed in :AddTask()
self:alert( ( (forceCurrentChar and L.personal.." " or "")..L.taskCreated):format(( true and ((taskName ~= nil and taskName ~="") and taskName or nil) or L.DefaultTaskName):cf("EAtan")))
end
end -- msg already delivered
end
function ExecAssist:doAddPersonalPurgableTask(aceTable)
-- easy redirector to make default->sendTo items for the current user
aceTable.input = aceTable.input:sub(2) -- doAdd assumes 6chr of task input
self:doAddPurgableTask(aceTable, true)
end
function ExecAssist:reset_CmdLineTarget(hGroup, mayNotBeNil)
local groupStem = self.db.global.groupStem
if hGroup.id == groupStem.cmdLineTarget then
if not mayNotBeNil then -- mayNotBeNil is passed by command line reset ops to keep to user from accidentally unsetting a target
groupStem.cmdLineTarget = nil
hGroup.cmdLineTarget=false
end
else
if groupStem.cmdLineTarget then
groupStem.agg[groupStem.cmdLineTarget].cmdLineTarget=false -- tell old target they can take the night off
end
hGroup.cmdLineTarget = true -- new sherrif in town
groupStem.cmdLineTarget = hGroup.id -- making it official
end
return groupStem.cmdLineTarget
end
function ExecAssist:doResetTargetGroup(aceTable)
local groupName = aceTable.input:sub(10):trim()
local groupName_lower = groupName:lower()
local groupStem = self.db.global.groupStem
for elementID, hElement in pairs(groupStem.agg) do
if elementID:isGroup() and hElement.listName:lower() == groupName_lower then
if self:reset_CmdLineTarget(hElement, true) then
self:alert( (L.cmdlinetargetsetto):format( hElement.listName:cf("EAtan") ))
end
return
end
end
self:alert( (L.unabletofindgroup):format((groupName):cf("EAtan")))
end
function ExecAssist:doCreateNPC(aceTable)
local charStem = self.db.global.charStem
local npcName = aceTable.input:sub(4):trim()
if npcName == "" then
self:alert( L.NPC_NoNameEntered:cf("hard_red") )
else
if charStem[npcName] then
-- self:alert( (L.unabletofindgroup):format((groupName):cf("EAtan")))
self:alert( L.NPC_openTag:cf("hard_red") .. npcName:cf("white") .. L.NPC_closingTag_Exists:cf("hard_red") )
else
charStem[npcName] = {["agg"] = {}}
self:mkCharList() -- sort
self:alert( L.NPC_openTag:cf("hard_green") .. npcName:cf("white") .. L.NPC_closingTag_Created:cf("hard_green") )
end
end
end