--[[ MCom A set of utility functions to simplify addon creation By: Mugendai Contact: mugekun@gmail.com MCom provides several functions designed to lower the amount of code required to make an addon be configurable. It helps to handle the things that need to go on to handle user input, either via console or via some GUI(like Cosmos or Khaos). It aims mainly at tasks that are repeated in multiple places in every addon. Any addon that wants to have chat commands needs a chat handler, and functions for each command it can accept. It also needs functions for updating the variables that have to do with configuration. Addons may also need wrapper functions for a GUI interface. They may also need to have multiple registers to support multiple GUIs, such as Cosmos and Khaos. These things are all handled by MCom either by registering with it for such functions, or by calling functions that do the repetative part. $Id: MCom.lua 2641 2005-10-17 09:26:21Z mugendai $ $Rev: 2641 $ $LastChangedBy: mugendai $ $Date: 2005-10-17 04:26:21 -0500 (Mon, 17 Oct 2005) $ ]]-- --If we should update/declare MCom, then do so now if (MCom_Update) then if (not Khaos) then -- Provide Khaos config keywords for MCom mods for when Khaos isn't around K_TEXT = "text"; K_CHECKBOX = "text"; -- Not a typo. Checkboxes use the "text" type to describe their right-side K_BUTTON = "button"; K_SLIDER = "slider"; K_EDITBOX = "editbox"; K_PULLDOWN = "pulldown"; K_COLORPICKER = "colorpicker"; K_HEADER = "separator"; end if (not myAddOnsList) then MYADDONS_CATEGORY_BARS = "Bars"; MYADDONS_CATEGORY_CHAT = "Chat"; MYADDONS_CATEGORY_CLASS = "Class"; MYADDONS_CATEGORY_COMBAT = "Combat"; MYADDONS_CATEGORY_COMPILATIONS = "Compilations"; MYADDONS_CATEGORY_GUILD = "Guild"; MYADDONS_CATEGORY_INVENTORY = "Inventory"; MYADDONS_CATEGORY_MAP = "Map"; MYADDONS_CATEGORY_OTHERS = "Others"; MYADDONS_CATEGORY_PROFESSIONS = "Professions"; MYADDONS_CATEGORY_QUESTS = "Quests"; MYADDONS_CATEGORY_RAID = "Raid"; end -------------------------------------------------- -- -- Public Library Functions -- -------------------------------------------------- --[[ registerSmart ( {reglist} ) A single function that can register a chat command, and a UI variable at the same time. You pass only the data you need to, and it will do anything it can with that data. If you pass enough data to register a UI command and callback, a slash command, a super slash command, and a sub slash command, this will do all of those things. Args: reglist - the table of options, some options will be listed more than once to show when they are needed, but only set them once { Data required to register a Cosmos or Khaos command: (string) uivar - the name of the UI variable (string) uitype - the type of UI variable (string) uilabel - the label of the UI variable Data required to register a Khaos command: (string) uisec - the ID of the Khaos set to put the option in Optional data for Cosmos or Khaos options: (function) func - the function to call when this variable changes, see addSlashCommand for further details on the function if this is not passed, a generic callback will be provided for you (string) varbool - the name of the boolean variable to use in the generic setter (string) varnum - the name of the number variable to use in the generic setter (string) varstring - the name of the editbox variable to use in the generic setter (string) varchoice - the name of the pulldown variable to use in the generic setter (string) varcolor - the name of the color variable to use in the generic setter (function) update - this function will be called when using the generic setter, and the variable is updated (function) noupdate - this function will be called when using the generic setter, and the variable is not updated (function) anyupdate - this function will be called when using the generic setter, whether the variable is updated or not (boolean) hasbool - set to true if this option has a checkbox in it (table) uioption - this can either be a table in the form of a Cosmos registration, or a KhaosOption. If it is passed then it will be used to pull as much data as MCom can make use of out of it. This can allow you to pass a Cosmos style option, that registers a Khaos option, for instance. It also allows you to set anything in the Khaos option that MCom doesn't have an argument for. If this is a Khaos option, it can include an entry called mcopts, which is a table of MCom options to set for the option (string) uisec - the ID of the section/set to put the option in, if the section/set already exists, the option wil be added to it, if it doesn't exist, it will be created (string) uiseclabel - the name of the section/set to put the option in (string) uisecdesc - the description of the section/set to put the option in NOTE: Once passed, the uisec variables will be stored as defaults for further commands (string) uisep - the ID of the separator/header to put the option in, if the separator/header already exists, then the option will be added after it, if it doesn't exist, it will be created NOTE: Once passed, the uisep variable will be stored as default for further commands (string) uiseplabel - the name of the separator/header to put the option in (string) uisepdesc - the description of the separator/header to put the option in (string) uidesc - the description of the UI variable (number) uicheck - the default value for a checkbox, 1 or 0 (number) uislider - the default value for a slider (number) uimin - the minimum value for a slider (number) uimax - the maximum value for a slider (string) uitext - the text to show on a UI control (number) uistep - the increment to use for a slider (number) uitexton - whether to show the text for the control or not, 1 or 0 (string) uisuffix - the suffix to show at the end of the slider text (number) uimul - how much to multiple the slider value by when displaying it Optional data for Khaos only options: (table) uiset - this can be an entire KhaosSet, and if it is, the whole thing will be MCom registered (string) uifolder - the Khaos folder to put the option in, if you don't pass this, and uicat is passed with a compatible type, uicat will be used NOTE: Once passed, the uifolder variable will be stored as default for further commands (string) uisecdiff - the difficulty of the set to put the option in (string) uiseccall - the callback of the set to put the option in (string) uisecdef - the default of the set to put the option in (string) uiseccom - the commands list of the set to put the option in NOTE: Once passed, the uisec variables will be stored as defaults for further commands (string) uisepdiff - the difficulty of the header to put the option in (string) uisepcall - the callback of the header to put the option in (string) uisepdef - the default of the header to put the option in (string) uikey - the key to use for the option (string) uivalue - the value to use for the option (number) uidiff - the difficulty of the option { key = { value = requirement } } uidep - A table listing what key's in a Khaos option set need to have what value set to what requirement for the option to be enabled (boolean) uiradio - set to true if the option has a radio control (function) uifeedback - the function to call to show feedback data (table) uisetup - the control setup structure (string) uisliderlow - the text to show on the lower potion of the slider control (string) uisliderhigh - the text to show on the higher potion of the slider control (function) uisliderfunc - the function to use to setup the text to show on the slider { string = value, ... } choices - A list of choices and values to use when using a pulldown, string is the string shown in the pulldown and value is the value that should be associated with that string. (boolean) multichoice - set to true if more than one option can be selected in a pulldown (boolean) hasopacity - set to true if a colorpicker should also have an opacity slider (color) uicolor - the default color to use in a color picker (string/table) uichoice - the default option(s) to be selected in a pulldown (string) uistring - the default string to be set in a textbox (table) uicallon - the default string to be set in a textbox (boolean) uidischeck - the value of a checkbox when the option set is disabled (number) uidisslider - the value of a slider when the option set is disabled (color) uidiscolor - the value of a color picker when the option set is disabled (string/table) uidischoice - the value of a pulldown when the option set is disabled (string) uidisstring - the value of a text box when the option set is disabled NOTE: Disabled options will use default settings, if they are not passed or nil Data required to register with myAddOns NOTE: You do not have to wait for VARIABLES_LOADED to register for myAddOns via MCom Also, if you have set any section info for a Khaos or Cosmos section, that will be used with myAddOns (string) addonname - This must be the exact same as the title in the toc file. Defaults to uisec. or (string) uisec - Where to place the addon in the myAddOnsList, defaults to uiseclabel or (string) uiseclabel - The name to show in myAddOns, defaults to uisec Optional data for registering with myAddOns (string) uisec - Where to place the addon in the myAddOnsList, defaults to uiseclabel (string) uiseclabel - The name to show in myAddOns, defaults to uisec (string) uisecdesc - NO LONGER USED BY myAddOns - The description to show in myAddOns, defaults to uiseclabel (string or number) uiver - The version to show in the UI (string) uidate - The date this version of the addon was released (string) uiauthor - The name of the author of the addon (string) uiwww - The website the addon can be found at, if any (string) uimail - The email address the author can be reached at (string) uicat - The category to place the addon in, if you don't pass this, and uifolder is passed with a compatible type, uifolder will be used (string) uiframe - NO LONGER USED BY myAddOns - The name of the frame used to detect if your addon is loaded (string) uioptionsframe - The name of the frame to show when the myAddOns options button is pressed for this Addon. If this is not passed, and you are registering a Cosmos or Khaos option at the same time as this, then Cosmos or Khaos will be set as the options frame. This will also add the frame to UIPanelWindows ( string or {string} ) uihelp - The help text to display in myAddOns and in slash command, and Khaos help. If it is a table, each entry is a page. Data required to register a standard slash command: (string) command - the name of the slash command Ex: "/command", or {"/command", "/com"} (string) comtype - [Required if uitype is not passed, takes precidence over uitype] the type of data you are expecting from this slash command MCOM_BOOLT - Expects boolean data, an on, off, 1, or 0 MCOM_NUMT - Expects a number value MCOM_MULTIT - Expects a boolean and then a number value, Ex: "/command on 3", this has been surplanted via simply using hasbool with MCOM_NUMT MCOM_STRINGT - Expects any string MCOM_COLORT - Expects a color setup, and optionally opacity MCOM_CHOICET - Expects a choice from a list of choices, or optionaly multiple choices MCOM_SIMPLET - No input needed, just calls the function Optional data for a standard slash command, or sub command: (function) func - the function to call when this variable changes, see addSlashCommand for further details on the function if this is not passed, a generic callback will be provided for you (boolean) hasbool - set to true if this option has a boolean portion (string) varbool - the name of the boolean variable to use in the generic setter (string) varnum - the name of the number variable to use in the generic setter (string) varstring - the name of the string variable to use in the generic setter (string) varchoice - the name of the choice variable to use in the generic setter (string) varcolor - the name of the color variable to use in the generic setter (number) varmin - the minimum value the number variable can be set to when using the generic setter if not passed, and uimin is passed, uimin will be used (number) varmax - the maximum value the number variable can be set to when using the generic setter if not passed, and uimax is passed, uimax will be used (function) update - this function will be called when using the generic setter, and the variable is updated (function) noupdate - this function will be called when using the generic setter, and the variable is not updated (function) anyupdate - this function will be called when using the generic setter, whether the variable is updated or not (string) textname - specifies the name of the option to display when printing status changes without a UI, only used if textbool/num/string/choice/color aren't (string) textbool, textnum, textstring, textchoice, textcolor - the string to print for the corrisponding portion, when not using a UI, and the variable has been updated in the generic setter. If this string contains a %s, then it will be replaced with the value its updated to. (boolean) textshow - if this is true, then the text will be printed on update, whether or not a UI is around(when using the generic setter) (number) commul - the value to multiply the number by when showing it's status (number) cominmul - the value to multiply the number by when it is passed in by the user (string) comaction - The action to perform, see Sky documentation for further details (number) comsticky - Whether the command is sticky or not(1 or 0), see Sky documentation for further details (boolean) multichoice - set to true if more than one option can be selected in an MCOM_CHOICET (boolean) hasopacity - set to true if an MCOM_COLORT should also have an opacity setting Optional data for a standard slash command only: (string) comhelp - What message to display as help in Sky for this command, see Sky documentation for further details ({string}) extrahelp - A table of extra help messages to display, each line in the table is a separate line when printed. Data required to register a super slash command: (string) supercom - the name of the super slash command Ex: "/command", or {"/command", "/com"} Optional data for a super slash command: (string) comaction - The action to perform, see Sky documentation for further details (number) comsticky - Whether the command is sticky or not(1 or 0), see Sky documentation for further details (string) comhelp - What message to display as help in Sky for this command, see Sky documentation for further details ({string}) extrahelp - A table of extra help messages to display, each line in the table is a separate line when printed. Data required to register a sub slash command: (string) supercom - the name of the super slash command to use for this sub slash command Ex: "/command", or {"/command", "/com"} (string) subcom - the name of the sub command, Ex: "command", or {"command", "com"} (string) comtype - [Required if uitype is not passed], see above for details Optional data for a sub command only: (string) subhelp - What message to display next to the sub command when listing sub commands in the help output. NOTE: if this is an MCOM_CHOICET then if you put a %s in this string, it will be replaced with a list of the choices you passed. Data required for a slash command to update a Cosmos or Khaos variable: (string) uivar - The UI variable that should be updated Data required for a slash command to update a Cosmos or Khaos variable, if func does not return a value: (string) varbool - The variable that the UI variable should be set by This should be a string containing the name of the variable to update, this can include .'s for tables, Ex: "Something.Value" When type is MULTI, this specifies the bool variable (string) varnum - The same as comnum, but used to specify the number variable when type is MULTI, only used for MULTI type Data required for a slash command to update a Khaos variable: (string) uisec - The option set ID that the uivar is found in Data required for a slash command to when type is MCOM_CHOICET: { string = value, ... } choices - A list of choices and values to use when using a MCOM_CHOICET, string is the string passed in from the console and value is the value that should be associated with that string. Data required for help window: ( string or {string} ) infotext - If this is passed the text will be shown in a help window then the slash command help is used, or when the help button is pressed in Khaos or Cosmos, this is also used for myAddOns help if uihelp was not passed. If it is a table, each entry is a page. Optional data for help window: (string) name - Sets the name to refer to the addon as in the help window (string) infotitle - Sets the title of the help window, if not passed, then name is used with a default string, Ex. "AddonName Help" } ]]-- MCom.registerSmart = function ( inreglist ) --Get a copy of the registration table local reglist; if ( type(inreglist) == "table" ) then reglist = MCom.table.copy(inreglist); end --Make sure reglist is here, and a table if (type(reglist) == "table") then --Register the Khaos options set if it has been passed if ( type(reglist.uiset) == "table" ) then MCom.uisec = reglist.uiset.id; MCom.uiseclabel = reglist.uiset.text; MCom.uisecdesc = reglist.uiset.helptext; MCom.uisecdiff = reglist.uiset.difficulty; MCom.uisecdef = reglist.uiset.default; MCom.uiseccall = reglist.uiset.callback; MCom.uiseccom = reglist.uiset.commands; --Register each option in the list if ( type(reglist.uiset.options) == "table" ) then for curOption = 1, getn(reglist.uiset.options) do local newMComSet = MCom.table.copy(reglist); newMComSet.uiset = nil; newMComSet.uioption = reglist.uiset.options[curOption]; MCom.registerSmart( newMComSet ); end end end --Support for old sytax variables if (reglist.comvar) then reglist.varbool = reglist.comvar; end if (reglist.comvarmulti) then reglist.varnum = reglist.comvarmulti; end --This will be set to true if we find that uioption is in Khaos format. local isKhaosOption = nil; --If option data has been passed use any of it, as needed if ( type(reglist.uioption) == "table" ) then --If the option data seems to be Khaos style, then parse it as such if ( (reglist.uioption.id ~= nil) or (reglist.uioption.key ~= nil) or (reglist.uioption.value ~= nil) or (reglist.uioption.text ~= nil) or (reglist.uioption.diificulty ~= nil) or (reglist.uioption.helptext ~= nil) or (reglist.uioption.callback ~= nil) or (reglist.uioption.feedback ~= nil) or (reglist.uioption.check ~= nil) or (reglist.uioption.radio ~= nil) or (reglist.uioption.type ~= nil) or (reglist.uioption.setup ~= nil) or (reglist.uioption.default ~= nil) or (reglist.uioption.disabled ~= nil) or (reglist.uioption.dependencies ~= nil) or (reglist.uioption.mcopts ~= nil) ) then isKhaosOption = true; if (reglist.uivar == nil) then reglist.uivar = reglist.uioption.id; end if (reglist.uikey == nil) then reglist.uikey = reglist.uioption.key; end if (reglist.uivalue == nil) then reglist.uivalue = reglist.uioption.value; end if (reglist.uilabel == nil) then reglist.uilabel = reglist.uioption.text; end if (reglist.uidiff == nil) then reglist.uidiff = reglist.uioption.difficulty; end if (reglist.uidesc == nil) then reglist.uidesc = reglist.uioption.helptext; end if (reglist.uifunc == nil) then reglist.uifunc = reglist.uioption.callback; --If this is a Khaos style function, going into Cosmos, then convert the values to Cosmos style if ((not Khaos) and CosmosMaster_Init and reglist.uifunc) then reglist.uifunc = function (check, value) reglist.uioption.callback({ checked = (check == 1); slider = value; }); end; end end if (reglist.hasbool == nil) then reglist.hasbool = reglist.uioption.check; end if (reglist.uiradio == nil) then reglist.uiradio = reglist.uioption.radio; end if (reglist.uitype == nil) then reglist.uitype = reglist.uioption.type; end if ( type(reglist.uioption.setup) == "table" ) then if (reglist.uisetup == nil) then reglist.uisetup = reglist.uioption.setup; end if (reglist.uitext == nil) then if ( (reglist.uitype == K_BUTTON) or (reglist.uitype == "BUTTON") ) then reglist.uitext = reglist.uioption.setup.buttonText; elseif ( (reglist.uitype == K_SLIDER) or (reglist.uitype == "SLIDER") or (reglist.uitype == "BOTH") ) then reglist.uitext = reglist.uioption.setup.sliderText; end end if (reglist.uimin == nil) then reglist.uimin = reglist.uioption.setup.sliderMin; end if (reglist.uimax == nil) then reglist.uimax = reglist.uioption.setup.sliderMax; end if (reglist.uistep == nil) then reglist.uistep = reglist.uioption.setup.sliderStep; end if (reglist.uisliderlow == nil) then reglist.uisliderlow = reglist.uioption.setup.sliderLowText; end if (reglist.uisliderhigh == nil) then reglist.uisliderhigh = reglist.uioption.setup.sliderHighText; end if (reglist.uisliderfunc == nil) then reglist.uisliderfunc = reglist.uioption.setup.sliderDisplayFunc; end if (reglist.choices == nil) then reglist.choices = reglist.uioption.setup.options; end if (reglist.multichoice == nil) then reglist.multichoice = reglist.uioption.setup.multiSelect; end if (reglist.hasopacity == nil) then reglist.hasopacity = reglist.uioption.setup.hasOpacity; end if (reglist.uicallon == nil) then reglist.uicallon = reglist.uioption.setup.callOn; end end if (reglist.uifeedback == nil) then reglist.uifeedback = reglist.uioption.feedback; end if ( type(reglist.uioption.default) == "table" ) then if (reglist.uicheck == nil) then reglist.uicheck = reglist.uioption.default.checked; if (reglist.uicheck) then reglist.uicheck = 1; else reglist.uicheck = 0; end end if (reglist.uislider == nil) then reglist.uislider = reglist.uioption.default.slider; end if (reglist.uicolor == nil) then reglist.uicolor = reglist.uioption.default.color; end if (reglist.uitype == K_EDITBOX) then if (reglist.uistring == nil) then reglist.uistring = reglist.uioption.default.value; end end if (reglist.uitype == K_PULLDOWN) then if (reglist.uichoice == nil) then reglist.uichoice = reglist.uioption.default.value; end end end if ( type(reglist.uioption.disabled) == "table" ) then if (reglist.uidischeck == nil) then reglist.uidischeck = reglist.uioption.disabled.checked; if (reglist.uidischeck) then reglist.uidischeck = 1; else reglist.uidischeck = 0; end end if (reglist.uidisslider == nil) then reglist.uidisslider = reglist.uioption.disabled.slider; end if (reglist.uidiscolor == nil) then reglist.uidiscolor = reglist.uioption.disabled.color; end if (reglist.uitype == K_EDITBOX) then if (reglist.uidisstring == nil) then reglist.uidisstring = reglist.uioption.disabled.value; end end if (reglist.uitype == K_PULLDOWN) then if (reglist.uidischoice == nil) then reglist.uidischoice = reglist.uioption.disabled.value; end end end if (reglist.uidep == nil) then reglist.uidep = reglist.uioption.dependencies; end --If an MCom option set is in here, then use it if ( type(reglist.uioption.mcopts) == "table" ) then for curOpt in reglist.uioption.mcopts do reglist[curOpt] = reglist.uioption.mcopts[curOpt]; end end else --If it's not Khaos style, we treat it as Cosmos style if (reglist.uivar == nil) then reglist.uivar = reglist.uioption[1]; end if (reglist.uitype == nil) then reglist.uitype = reglist.uioption[2]; end if (reglist.uilabel == nil) then reglist.uilabel = reglist.uioption[3]; end if (reglist.uidesc == nil) then reglist.uidesc = reglist.uioption[4]; end if (reglist.uifunc == nil) then reglist.uifunc = reglist.uioption[5]; --If it's a Cosmos style function, being used in Khaos then convert the arguments to match if (Khaos and (not CosmosMaster_Init) and reglist.uifunc) then local checkFunc = function (check) if (check) then return 1; else return 0; end end reglist.uifunc = function (state) reglist.uioption[5]( checkFunc(state.checked) , state.slider); end; if ( reglist.func == nil ) then if (reglist.uitype == "SLIDER") then reglist.func = function (value) reglist.uioption[5](0,value); end; else reglist.func = function (bool, value) reglist.uioption[5](bool,value); end; end end end end if (reglist.uicheck == nil) then reglist.uicheck = reglist.uioption[6]; end if (reglist.uislider == nil) then reglist.uislider = reglist.uioption[7]; end if (reglist.uimin == nil) then reglist.uimin = reglist.uioption[8]; end if (reglist.uimax == nil) then reglist.uimax = reglist.uioption[9]; end if (reglist.uitext == nil) then reglist.uitext = reglist.uioption[10]; end if (reglist.uistep == nil) then reglist.uistep = reglist.uioption[11]; end if (reglist.uitexton == nil) then reglist.uitexton = reglist.uioption[12]; end if (reglist.uisuffix == nil) then reglist.uisuffix = reglist.uioption[13]; end if (reglist.uimul == nil) then reglist.uimul = reglist.uioption[14]; end end end --Default our regtype to nil local regtype = nil; --If we have uitype, then figure out the MCOM type for it if (reglist.uitype) then --If we are doing Khaos, then use it's types, and convert Cosmos types --to Khaos types if (Khaos) then if ( reglist.uitype == K_TEXT ) then if (reglist.hasbool == true) then regtype = MCOM_BOOLT; end elseif ( reglist.uitype == K_SLIDER ) then regtype = MCOM_NUMT; elseif ( reglist.uitype == K_EDITBOX ) then regtype = MCOM_STRINGT; elseif ( reglist.uitype == K_BUTTON ) then regtype = MCOM_SIMPLET; elseif ( reglist.uitype == K_PULLDOWN ) then regtype = MCOM_CHOICET; elseif ( reglist.uitype == K_COLORPICKER ) then regtype = MCOM_COLORT; elseif (reglist.uitype == "CHECKBOX") then reglist.uitype = K_TEXT; regtype = MCOM_BOOLT; reglist.hasbool = true; elseif (reglist.uitype == "SLIDER") then reglist.uitype = K_SLIDER; regtype = MCOM_NUMT; elseif (reglist.uitype == "BOTH") then reglist.uitype = K_SLIDER; reglist.hasbool = true; regtype = MCOM_MULTIT; elseif (reglist.uitype == "BUTTON") then reglist.uitype = K_BUTTON; regtype = MCOM_SIMPLET; elseif (reglist.uitype == "SEPARATOR") then reglist.uitype = K_HEADER; end else --If we are doing Cosmos, then use it's types, and convert Khaos types --to Cosmos types if ( reglist.uitype == K_TEXT ) then if (reglist.hasbool == true) then regtype = MCOM_BOOLT; reglist.uitype = "CHECKBOX"; end elseif ( reglist.uitype == K_SLIDER ) then regtype = MCOM_NUMT; reglist.uitype = "SLIDER"; if (reglist.hasbool == true) then reglist.uitype = "BOTH"; end elseif ( reglist.uitype == K_EDITBOX ) then regtype = MCOM_STRINGT; elseif ( reglist.uitype == K_BUTTON ) then regtype = MCOM_SIMPLET; reglist.uitype = "BUTTON"; elseif ( reglist.uitype == K_PULLDOWN ) then regtype = MCOM_CHOICET; elseif ( reglist.uitype == K_COLORPICKER ) then regtype = MCOM_COLORT; elseif (reglist.uitype == K_HEADER) then reglist.uitype = "SEPARATOR"; elseif (reglist.uitype == "CHECKBOX") then regtype = MCOM_BOOLT; reglist.hasbool = true; elseif (reglist.uitype == "SLIDER") then regtype = MCOM_NUMT; elseif (reglist.uitype == "BOTH") then regtype = MCOM_MULTIT; elseif (reglist.uitype == "BUTTON") then regtype = MCOM_SIMPLET; end end end --If we have the comtype, use it instead of the uitype if (reglist.comtype) then regtype = reglist.comtype; end --If regtype is not set, and we have check set, then set type is BOOLT. if ( (regtype == nil) and (reglist.hasbool == true) ) then regtype = MCOM_BOOLT; end --If regtype is BOOLT, and we dont have check set, then set it. if ( (regtype == MCOM_BOOLT) and (not reglist.hasbool) ) then reglist.hasbool = true; end --If regtype is MULTIT, and we dont have check set, then set it. if ( (regtype == MCOM_MULTIT) and (not reglist.hasbool) ) then reglist.hasbool = true; end --If no min, max, or mul were provided for the setter, but was provided for the UI, then use the ui values --and visa versa if ( reglist.uimin and (not reglist.varmin) ) then reglist.varmin = reglist.uimin; elseif ( reglist.varmin and (not reglist.uimin) ) then reglist.uimin = reglist.varmin; end if ( reglist.uimax and (not reglist.varmax) ) then reglist.varmax = reglist.uimax; elseif ( reglist.varmax and (not reglist.uimax) ) then reglist.uimax = reglist.varmax; end if ( reglist.uimul and (not reglist.commul) ) then reglist.commul = reglist.uimul; elseif ( reglist.commul and (not reglist.uimul) ) then reglist.uimul = reglist.commul; end if ( not reglist.uimul ) then reglist.uimul = 1; end if ( reglist.commul and ( not reglist.cominmul ) ) then reglist.cominmul = 1 / reglist.commul; end if ( not reglist.commul ) then reglist.commul = 1; end if ( not reglist.cominmul ) then reglist.cominmul = 1; end if (not reglist.func) then if (reglist.uifunc) then --If there was no function passed, but a ui func was passed, use the uifunc reglist.func = reglist.uifunc; else --If textname wasn't passed, try and make it from other data if (not reglist.textname) then reglist.textname = reglist.uilabel; end if (not reglist.textname) then if ( type(reglist.subcom) == "table" ) then reglist.textname = reglist.subcom[1]; else reglist.textname = reglist.subcom; end end if (not reglist.textname) then if ( type(reglist.command) == "table" ) then reglist.textname = reglist.command[1]; else reglist.textname = reglist.command; end end --Generate defaults for the text strings if none are passed if (reglist.textname) then if (not reglist.textbool) then reglist.textbool = string.format(MCOM_CHAT_STATUS_B, reglist.textname); end if (not reglist.textnum) then reglist.textnum = string.format(MCOM_CHAT_STATUS_N, reglist.textname); end if (not reglist.textstring) then reglist.textstring = string.format(MCOM_CHAT_STATUS_S, reglist.textname); end if (not reglist.textchoice) then reglist.textchoice = string.format(MCOM_CHAT_STATUS_C, reglist.textname); end if (not reglist.textcolor) then reglist.textcolor = string.format(MCOM_CHAT_STATUS_K, reglist.textname); end end --If there was no function passed, then provide our own generic function if ((regtype == MCOM_BOOLT) and reglist.varbool) then reglist.func = function (checked) if (MCom.updateVar(reglist.varbool, checked, MCOM_BOOLT)) then --If there is a function to run on an update, call it if (reglist.update and (type(reglist.update) == "function")) then reglist.update(reglist.varbool); end if (reglist.textbool) then --Print output to let the player know the command succeeded, if there is no UI MCom.printStatus(reglist.textbool, MCom.getStringVar(reglist.varbool), true, reglist.textshow); end else --If there is a function to run on an attempted update, that resulted in no change, then run it if (reglist.noupdate and (type(reglist.noupdate) == "function")) then reglist.noupdate(reglist.varbool); end end --If there is a function to run on any update, then run it if (reglist.anyupdate and (type(reglist.anyupdate) == "function")) then reglist.anyupdate(reglist.varbool); end end; elseif ( ( (regtype == MCOM_NUMT) and (not reglist.hasbool) ) and reglist.varnum ) then reglist.func = function (value) if (MCom.updateVar(reglist.varnum, value, MCOM_NUMT, reglist.varmin, reglist.varmax)) then --If there is a function to run on an update, call it if (reglist.update and (type(reglist.update) == "function")) then reglist.update(reglist.varnum); end if (reglist.textnum) then --Print output to let the player know the command succeeded, if there is no UI if (value and reglist.commul and MCom.getStringVar(reglist.varnum)) then value = MCom.math.round( ( MCom.getStringVar(reglist.varnum) * reglist.commul ) * 100 ) / 100; else value = MCom.getStringVar(reglist.varnum); end MCom.printStatus(reglist.textnum, value, nil, reglist.textshow); end else --If there is a function to run on an attempted update, that resulted in no change, then run it if (reglist.noupdate and (type(reglist.noupdate) == "function")) then reglist.noupdate(reglist.varnum); end end --If there is a function to run on any update, then run it if (reglist.anyupdate and (type(reglist.anyupdate) == "function")) then reglist.anyupdate(reglist.varnum); end end; elseif ( ( (regtype == MCOM_STRINGT) and (not reglist.hasbool) ) and reglist.varstring ) then reglist.func = function (value) if (MCom.updateVar(reglist.varstring, value, MCOM_STRINGT)) then --If there is a function to run on an update, call it if (reglist.update and (type(reglist.update) == "function")) then reglist.update(reglist.varstring); end if (reglist.textstring) then --Print output to let the player know the command succeeded, if there is no UI MCom.printStatus(reglist.textstring, MCom.getStringVar(reglist.varstring), nil, reglist.textshow); end else --If there is a function to run on an attempted update, that resulted in no change, then run it if (reglist.noupdate and (type(reglist.noupdate) == "function")) then reglist.noupdate(reglist.varstring); end end --If there is a function to run on any update, then run it if (reglist.anyupdate and (type(reglist.anyupdate) == "function")) then reglist.anyupdate(reglist.varstring); end end; elseif ( ( (regtype == MCOM_CHOICET) and (not reglist.hasbool) ) and reglist.varchoice ) then reglist.func = function (value, name) if (MCom.updateVar(reglist.varchoice, value, MCOM_CHOICET)) then --If there is a function to run on an update, call it if (reglist.update and (type(reglist.update) == "function")) then reglist.update(reglist.varchoice); end if (reglist.textchoice) then --Print output to let the player know the command succeeded, if there is no UI MCom.printStatus(reglist.textchoice, name, nil, reglist.textshow); end else --If there is a function to run on an attempted update, that resulted in no change, then run it if (reglist.noupdate and (type(reglist.noupdate) == "function")) then reglist.noupdate(reglist.varchoice); end end --If there is a function to run on any update, then run it if (reglist.anyupdate and (type(reglist.anyupdate) == "function")) then reglist.anyupdate(reglist.varchoice); end end; elseif ( ( (regtype == MCOM_COLORT) and (not reglist.hasbool) ) and reglist.varcolor ) then reglist.func = function (value) if (MCom.updateVar(reglist.varcolor, value, MCOM_COLORT)) then --If there is a function to run on an update, call it if (reglist.update and (type(reglist.update) == "function")) then reglist.update(reglist.varcolor); end if (reglist.textcolor) then --Build a color string local curColor = MCom.getStringVar(reglist.varstring); local curColString = ""; if ( type(curColor) == "table" ) then if (curColor.r) then curColString = string.format(MCOM_CHAT_COM_K_R, MCom.math.round(curColor.r * 100)); end if (curColor.g) then if ( curColString ~= "" ) then curColString = curColString..", "; end curColString = curColString..string.format(MCOM_CHAT_COM_K_G, MCom.math.round(curColor.g * 100)); end if (curColor.b) then if ( curColString ~= "" ) then curColString = curColString..", "; end curColString = curColString..string.format(MCOM_CHAT_COM_K_B, MCom.math.round(curColor.b * 100)); end if (reglist.hasopacity) then local displayOpacity = 1; if (curColor.opacity) then displayOpacity = curColor.opacity; end if ( curColString ~= "" ) then curColString = curColString..", "; end curColString = curColString..string.format(MCOM_CHAT_COM_K_O, MCom.math.round(displayOpacity * 100)); end end --Print output to let the player know the command succeeded, if there is no UI MCom.printStatus(reglist.textcolor, curColString, nil, reglist.textshow); end else --If there is a function to run on an attempted update, that resulted in no change, then run it if (reglist.noupdate and (type(reglist.noupdate) == "function")) then reglist.noupdate(reglist.varcolor); end end --If there is a function to run on any update, then run it if (reglist.anyupdate and (type(reglist.anyupdate) == "function")) then reglist.anyupdate(reglist.varcolor); end end; elseif ( ( (regtype == MCOM_MULTIT) or ( (regtype == MCOM_NUMT) and reglist.hasbool ) ) and reglist.varbool and reglist.varnum ) then reglist.func = function (checked, value) if (MCom.updateVar(reglist.varbool, checked, MCOM_BOOLT)) then --If there is a function to run on an update, call it if (reglist.update and (type(reglist.update) == "function")) then reglist.update(reglist.varbool); end if (reglist.textbool) then --Print output to let the player know the command succeeded, if there is no UI MCom.printStatus(reglist.textbool, MCom.getStringVar(reglist.varbool), true, reglist.textshow); end else --If there is a function to run on an attempted update, that resulted in no change, then run it if (reglist.noupdate and (type(reglist.noupdate) == "function")) then reglist.noupdate(reglist.varbool); end end --If there is a function to run on any update, then run it if (reglist.anyupdate and (type(reglist.anyupdate) == "function")) then reglist.anyupdate(reglist.varbool); end --If no value was passed, then don't set it if (value) then if (MCom.updateVar(reglist.varnum, value, MCOM_NUMT, reglist.varmin, reglist.varmax)) then --If there is a function to run on an update, call it if (reglist.update and (type(reglist.update) == "function")) then reglist.update(reglist.varnum); end if (reglist.textnum) then --Print output to let the player know the command succeeded, if there is no UI if (value and reglist.commul and MCom.getStringVar(reglist.varnum)) then value = MCom.math.round( ( MCom.getStringVar(reglist.varnum) * reglist.commul ) * 100 ) / 100; else value = MCom.getStringVar(reglist.varnum); end MCom.printStatus(reglist.textnum, value, nil, reglist.textshow); end else --If there is a function to run on an attempted update, that resulted in no change, then run it if (reglist.noupdate and (type(reglist.noupdate) == "function")) then reglist.noupdate(reglist.varnum); end end end --If there is a function to run on any update, then run it if (reglist.anyupdate and (type(reglist.anyupdate) == "function")) then reglist.anyupdate(reglist.varnum); end end; elseif ( ( ( (regtype == MCOM_STRINGT) and reglist.hasbool ) ) and reglist.varbool and reglist.varstring ) then reglist.func = function (checked, value) if (MCom.updateVar(reglist.varbool, checked, MCOM_BOOLT)) then --If there is a function to run on an update, call it if (reglist.update and (type(reglist.update) == "function")) then reglist.update(reglist.varbool); end if (reglist.textbool) then --Print output to let the player know the command succeeded, if there is no UI MCom.printStatus(reglist.textbool, MCom.getStringVar(reglist.varbool), true, reglist.textshow); end else --If there is a function to run on an attempted update, that resulted in no change, then run it if (reglist.noupdate and (type(reglist.noupdate) == "function")) then reglist.noupdate(reglist.varbool); end end --If there is a function to run on any update, then run it if (reglist.anyupdate and (type(reglist.anyupdate) == "function")) then reglist.anyupdate(reglist.varbool); end --If no value was passed, then don't set it if (value) then if (MCom.updateVar(reglist.varstring, value, MCOM_STRINGT)) then --If there is a function to run on an update, call it if (reglist.update and (type(reglist.update) == "function")) then reglist.update(reglist.varstring); end if (reglist.textstring) then --Print output to let the player know the command succeeded, if there is no UI MCom.printStatus(reglist.textstring, MCom.getStringVar(reglist.varstring), nil, reglist.textshow); end else --If there is a function to run on an attempted update, that resulted in no change, then run it if (reglist.noupdate and (type(reglist.noupdate) == "function")) then reglist.noupdate(reglist.varstring); end end end --If there is a function to run on any update, then run it if (reglist.anyupdate and (type(reglist.anyupdate) == "function")) then reglist.anyupdate(reglist.varstring); end end; elseif ( ( ( (regtype == MCOM_CHOICET) and reglist.hasbool ) ) and reglist.varbool and reglist.varchoice ) then reglist.func = function (checked, value, name) if (MCom.updateVar(reglist.varbool, checked, MCOM_BOOLT)) then --If there is a function to run on an update, call it if (reglist.update and (type(reglist.update) == "function")) then reglist.update(reglist.varbool); end if (reglist.textbool) then --Print output to let the player know the command succeeded, if there is no UI MCom.printStatus(reglist.textbool, MCom.getStringVar(reglist.varbool), true, reglist.textshow); end else --If there is a function to run on an attempted update, that resulted in no change, then run it if (reglist.noupdate and (type(reglist.noupdate) == "function")) then reglist.noupdate(reglist.varbool); end end --If there is a function to run on any update, then run it if (reglist.anyupdate and (type(reglist.anyupdate) == "function")) then reglist.anyupdate(reglist.varbool); end --If no value was passed, then don't set it if (value) then if (MCom.updateVar(reglist.varchoice, value, MCOM_CHOICET)) then --If there is a function to run on an update, call it if (reglist.update and (type(reglist.update) == "function")) then reglist.update(reglist.varchoice); end if (reglist.textchoice) then --Print output to let the player know the command succeeded, if there is no UI MCom.printStatus(reglist.textchoice, name, nil, reglist.textshow); end else --If there is a function to run on an attempted update, that resulted in no change, then run it if (reglist.noupdate and (type(reglist.noupdate) == "function")) then reglist.noupdate(reglist.varchoice); end end end --If there is a function to run on any update, then run it if (reglist.anyupdate and (type(reglist.anyupdate) == "function")) then reglist.anyupdate(reglist.varchoice); end end; elseif ( ( ( (regtype == MCOM_COLORT) and reglist.hasbool ) ) and reglist.varbool and reglist.varcolor ) then reglist.func = function (checked, value) if (MCom.updateVar(reglist.varbool, checked, MCOM_BOOLT)) then --If there is a function to run on an update, call it if (reglist.update and (type(reglist.update) == "function")) then reglist.update(reglist.varbool); end if (reglist.textbool) then --Print output to let the player know the command succeeded, if there is no UI MCom.printStatus(reglist.textbool, MCom.getStringVar(reglist.varbool), true, reglist.textshow); end else --If there is a function to run on an attempted update, that resulted in no change, then run it if (reglist.noupdate and (type(reglist.noupdate) == "function")) then reglist.noupdate(reglist.varbool); end end --If there is a function to run on any update, then run it if (reglist.anyupdate and (type(reglist.anyupdate) == "function")) then reglist.anyupdate(reglist.varbool); end --If no value was passed, then don't set it if (value) then if (MCom.updateVar(reglist.varcolor, value, MCOM_COLORT)) then --If there is a function to run on an update, call it if (reglist.update and (type(reglist.update) == "function")) then reglist.update(reglist.varcolor); end if (reglist.textcolor) then --Build a color string local curColor = MCom.getStringVar(reglist.varstring); local curColString = ""; if ( type(curColor) == "table" ) then if (curColor.r) then curColString = string.format(MCOM_CHAT_COM_K_R, MCom.math.round(curColor.r * 100)); end if (curColor.g) then if ( curColString ~= "" ) then curColString = curColString..", "; end curColString = curColString..string.format(MCOM_CHAT_COM_K_G, MCom.math.round(curColor.g * 100)); end if (curColor.b) then if ( curColString ~= "" ) then curColString = curColString..", "; end curColString = curColString..string.format(MCOM_CHAT_COM_K_B, MCom.math.round(curColor.b * 100)); end if (reglist.hasopacity) then local displayOpacity = 1; if (curColor.opacity) then displayOpacity = curColor.opacity; end if ( curColString ~= "" ) then curColString = curColString..", "; end curColString = curColString..string.format(MCOM_CHAT_COM_K_O, MCom.math.round(displayOpacity * 100)); end end --Print output to let the player know the command succeeded, if there is no UI MCom.printStatus(reglist.textcolor, curColString, nil, reglist.textshow); end else --If there is a function to run on an attempted update, that resulted in no change, then run it if (reglist.noupdate and (type(reglist.noupdate) == "function")) then reglist.noupdate(reglist.varcolor); end end end --If there is a function to run on any update, then run it if (reglist.anyupdate and (type(reglist.anyupdate) == "function")) then reglist.anyupdate(reglist.varcolor); end end; end end end --If uifolder was not passed, see if there is a compatable uicat for it if (not reglist.uifolder) then if (reglist.uicat == MYADDONS_CATEGORY_BARS) then reglist.uifolder = "bars"; elseif (reglist.uicat == MYADDONS_CATEGORY_CHAT) then reglist.uifolder = "chat"; elseif (reglist.uicat == MYADDONS_CATEGORY_COMBAT) then reglist.uifolder = "combat"; elseif (reglist.uicat == MYADDONS_CATEGORY_INVENTORY) then reglist.uifolder = "inventory"; elseif (reglist.uicat == MYADDONS_CATEGORY_QUESTS) then reglist.uifolder = "quest"; end end if (reglist.uitype == "SECTION") then --If a Cosmos section has been passed, then we need to store it's data so that --when we are ready to register an option, we can then create the option set --based on the section data MCom.uifolder = reglist.uifolder; MCom.uisec = reglist.uisec; MCom.uisecabel = reglist.uiseclabel; MCom.uisecdesc = reglist.uisecdesc; MCom.uisecdiff = reglist.uisecdiff; MCom.uiseccall = reglist.uiseccall; MCom.uisecdef = reglist.uisecdef; MCom.uiseccom = reglist.uiseccom; if (not reglist.uisec) then reglist.uisec = reglist.uivar; MCom.uisec = reglist.uivar; end if (not reglist.uiseclabel) then MCom.uiseclabel = reglist.uilabel; end if (not reglist.uisecdesc) then MCom.uisecdesc = reglist.uidesc; end end --If no set was passed, then use the previously stored one if (not reglist.uisec) then reglist.uisec = MCom.uisec; end --If the previously stored set exists, and is the same as the one passed, then pull --the data from it if ( MCom.uisec and (MCom.uisec == reglist.uisec) ) then if (not reglist.uiseclabel) then reglist.uiseclabel = MCom.uiseclabel; end if (not reglist.uisecdesc) then reglist.uisecdesc = MCom.uisecdesc; end if (not reglist.uisecdiff) then reglist.uisecdiff = MCom.uisecdiff; end if (not reglist.uiseccall) then reglist.uiseccall = MCom.uiseccall; end if (not reglist.uisecdef) then reglist.uisecdef = MCom.uisecdef; end if (not reglist.uiseccom) then reglist.uiseccom = MCom.uiseccom; end end --Setup stored set with current data MCom.uisec = reglist.uisec; MCom.uiseclabel = reglist.uiseclabel; MCom.uisecdesc = reglist.uisecdesc; MCom.uisecdiff = reglist.uisecdiff; MCom.uiseccall = reglist.uiseccall; MCom.uisecdef = reglist.uisecdef; MCom.uiseccom = reglist.uiseccom; --If MyAddOns is loaded, then try to register with it if ( myAddOnsList and (MCom.uisec or MCom.uiseclabel or reglist.addonname) ) then --Figure out an entry, label, and description local addonEntry = MCom.uisec; if (not addonEntry) then addonEntry = reglist.addonname; end if (not addonEntry) then addonEntry = MCom.uilabel; end local addonName = reglist.addonname; if (not addonName) then addonName = addonEntry; end if (not addonName) then addonName = reglist.uiseclabel; end if ( (not myAddOnsFrame_Register) and MCom.uiseclabel ) then addonName = MCom.uiseclabel; end local addonDesc = reglist.uisecdesc; if (not addonDesc) then addonDesc = addonName; end if (not MCom.MyAddOnsList) then MCom.MyAddOnsList = {}; end --Default the addon list to an internal one that MCom keeps, until loading is done local addonList = MCom.MyAddOnsList; --If we have finished loading MyAddOns, then go ahead and use its list if (MCom.MyAddOnsLoaded) then addonList = myAddOnsList; elseif (not MCom.MyAddonsHooked) then --If variables haven't loaded yet, then store the registered addons in a temporary list --that will will use to add to the real list once variables have loaded MCom.MyAddonsHooked = true; --Hook the MyAddOns event function so we know when variables have loaded MCom.util.hook("myAddOnsFrame_OnEvent", "MCom.myAddOnsFrame_OnEvent", "after"); end --Only add this to the list if it isn't already there if ( not addonList[addonEntry] ) then --If category wasn't passed see if a compatable folder was passed if (not reglist.uicat) then if (reglist.uifolder == "bars") then reglist.uicat = MYADDONS_CATEGORY_BARS; elseif (reglist.uifolder == "chat") then reglist.uicat = MYADDONS_CATEGORY_CHAT; elseif (reglist.uifolder == "combat") then reglist.uicat = MYADDONS_CATEGORY_COMBAT; elseif (reglist.uifolder == "inventory") then reglist.uicat = MYADDONS_CATEGORY_INVENTORY; elseif (reglist.uifolder == "quest") then reglist.uicat = MYADDONS_CATEGORY_QUESTS; else reglist.uicat = MYADDONS_CATEGORY_OTHERS; end end --If no options frame was passed, and this is a Cosmos or Khaos registration, then set --the options frame to be the Khaos or Cosmos options frame if (not reglist.uioptionsframe) then if (Khaos and reglist.uivar and reglist.uitype and reglist.uilabel) then reglist.uioptionsframe = "KhaosFrame"; elseif (CosmosMaster_Init and reglist.uivar and reglist.uitype and reglist.uilabel ) then reglist.uioptionsframe = "CosmosMasterFrame"; end end --If an options frame was passed, and it isn't in the UIPanel's list, then add it if (reglist.uioptionsframe and ( not UIPanelWindows[reglist.uioptionsframe] ) ) then UIPanelWindows[reglist.uioptionsframe] = {area = "center", pushable = 0}; end --If uihelp wasn't passed, use infotext if (not reglist.uihelp) then reglist.uihelp = reglist.infotext; end --Make usre uihelp is a table or boolean if (reglist.uihelp and (type(reglist.uihelp) ~= "table") and (type(reglist.uihelp) ~= "boolean") ) then reglist.uihelp = { reglist.uihelp }; end --Add the addon to the list addonList[addonEntry] = { details = { name = addonName; description = addonDesc; version = reglist.uiver; releaseDate = reglist.uidate, author = reglist.uiauthor, email = reglist.uimail, website = reglist.uiwww, category = reglist.uicat; frame = reglist.uiframe; optionsframe = reglist.uioptionsframe; }; help = reglist.uihelp; supercom = reglist.supercom; }; end end --If the variable name is not prefixed with COS_ and cosmos is the UI then put it on there if ( reglist.uivar and CosmosMaster_Init and (not Khaos) ) then if ( (string.len(reglist.uivar) < 4) or (string.sub(reglist.uivar, 1, 4) ~= "COS_") ) then reglist.uivar = "COS_"..reglist.uivar; end end if (Khaos and reglist.uivar and reglist.uitype and reglist.uilabel) then --If we have Khaos and the data needed to register with it, then try to work that out if (reglist.uitype ~= "SECTION") then --Only work with valid Khaos types if ( (reglist.uitype == K_HEADER) or (reglist.uitype == K_TEXT) or (reglist.uitype == K_CHECKBOX) or (reglist.uitype == K_BUTTON) or (reglist.uitype == K_SLIDER) or (reglist.uitype == K_EDITBOX) or (reglist.uitype == K_PULLDOWN) or (reglist.uitype == K_COLORPICKER) ) then --We have now go through the proccess of preparing a Khaos option, then we will register it --If a folder has been passed then store it for use now, and for future registers if (reglist.uifolder) then MCom.uifolder = reglist.uifolder; end --If a separator has been passed then store it for use now, and for future registers if (reglist.uisep) then MCom.uisep = reglist.uisep; end if (reglist.uitype == K_HEADER) then MCom.uisep = reglist.uivar; end --If we don't have a uifunc yet, then wrap the func if ( (not reglist.uifunc) and reglist.func ) then --Wrap it for Khaos reglist.uifunc = function (state, keypressed) MCom.SetFromKUI(reglist.uivar, state, keypressed, reglist.choices); end; --Add the function to the list of callback functions if (reglist.uitype) then --Only do this for UI elements that have options if ((reglist.uitype == K_SLIDER) or (reglist.uitype == K_PULLDOWN) or (reglist.uitype == K_EDITBOX) or (reglist.uitype == K_COLORPICKER) or (reglist.uitype == K_BUTTON) or ( (reglist.uitype == K_TEXT) and (reglist.hasbool) ) ) then --If there is no function list yet, then make it if (not MCom.UIFuncList) then MCom.UIFuncList = {}; end --If this function is not yet in the list, then make it if (not MCom.UIFuncList[reglist.uivar]) then MCom.UIFuncList[reglist.uivar] = {}; end MCom.UIFuncList[reglist.uivar].func = reglist.func; MCom.UIFuncList[reglist.uivar].uitype = reglist.uitype; MCom.UIFuncList[reglist.uivar].hasbool = reglist.hasbool; end end end --Make our option structure local kOption = {}; --If uioption is a Khaos style option, use it as our option structure if (isKhaosOption) then kOption = reglist.uioption; end --Setup the varying parts of the option with MCom data kOption.id = reglist.uivar; kOption.key = reglist.uikey; kOption.value = reglist.uivalue; kOption.text = reglist.uilabel; kOption.difficulty = reglist.uidiff; kOption.helptext = reglist.uidesc; kOption.callback = reglist.uifunc; if ( reglist.hasbool == nil ) then if ( (regtype == MCOM_BOOLT) or (regtype == MCOM_MULTIT) ) then reglist.hasbool = true; end end kOption.check = reglist.hasbool; kOption.radio = reglist.uiradio; kOption.type = reglist.uitype; --Setup the setup structure if ( type(reglist.uisetup) == "table" ) then kOption.setup = reglist.uisetup; else kOption.setup = {}; end if (reglist.uitype == K_BUTTON) then kOption.setup.buttonText = reglist.uitext; end --Setup the slider if (reglist.uitype == K_SLIDER) then kOption.setup.sliderMin = reglist.uimin; kOption.setup.sliderMax = reglist.uimax; kOption.setup.sliderStep = reglist.uistep; --If no slider display func has been passed, then make a generic one, that behaves the same --as the one in Cosmos kOption.setup.sliderLowText = reglist.uisliderlow; kOption.setup.sliderHighText = reglist.uisliderhigh; kOption.setup.sliderText = reglist.text; if (not reglist.uisuffix) then reglist.uisuffix = ""; end sliderDisplayFunc = reglist.uisliderfunc; if (sliderDisplayFunc == nil) then kOption.setup.sliderDisplayFunc = function ( value ) return ( MCom.math.round( ( value * reglist.uimul ) * 100 ) / 100 )..reglist.uisuffix; end; end end kOption.setup.options = reglist.choices; kOption.setup.multiSelect = reglist.multichoice; kOption.setup.hasOpacity = reglist.hasopacity; kOption.setup.callOn = reglist.uicallon; kOption.feedback = reglist.uifeedback; --If no feedback has been passed, then make a generic feedback function if (not kOption.feedback) then if ( reglist.uitype ~= K_HEADER and reglist.uitype ~= K_BUTTON ) then kOption.feedback = function(state) local retString; --The string to return --If it is has a check or radio then set the return string up for that if (kOption.check ) then if ( state.checked ) then retString = string.format(MCOM_FEEDBACK_CHECK, kOption.text, MCOM_CHAT_ENABLED); else retString = string.format(MCOM_FEEDBACK_CHECK, kOption.text, MCOM_CHAT_DISABLED); end elseif (kOption.radio ) then if ( state.value ) then retString = string.format(MCOM_FEEDBACK_RADIO, kOption.text, state.value); end end --If it has a slider then set the string up for that if (reglist.uitype == K_SLIDER) then if ( state.slider ) then if (not retString) then retString = string.format(MCOM_FEEDBACK_SLIDER, kOption.text, kOption.setup.sliderDisplayFunc(state.slider) ); else --If we also have a check or radio, then use a version that displays both that, and this retString = string.format(MCOM_FEEDBACK_SLIDER_M, retString, kOption.setup.sliderDisplayFunc(state.slider) ); end end end if (reglist.uitype == K_EDITBOX) then if ( state.value ) then if (not retString) then retString = string.format(MCOM_FEEDBACK_EDITBOX, kOption.text, state.value); else --If we also have a check or radio, then use a version that displays both that, and this retString = string.format(MCOM_FEEDBACK_EDITBOX_M, retString, state.value); end end end if (reglist.uitype == K_COLORPICKER) then if ( state.color ) then if (not retString) then retString = string.format(MCOM_FEEDBACK_COLOR, MCom.string.colorToString(state.color), kOption.text); else --If we also have a check or radio, then use a version that displays both that, and this retString = string.format(MCOM_FEEDBACK_COLOR_M, MCom.string.colorToString(state.color), retString); end end end if (reglist.uitype == K_CHOICE) then if ( state.value ) then --Create a text list of options local options; if ( type(state.value) == "table" ) then for curOption = 1, table.getn(state.value) do if (options) then options = options..", "..state.value[curOption]; else options = state.value[curOption]; end end else options = state.value; end if (not retString) then retString = string.format(MCOM_FEEDBACK_CHOICE, kOption.text, options); else --If we also have a check or radio, then use a version that displays both that, and this retString = string.format(MCOM_FEEDBACK_CHOICE_M, retString, options); end end end return retString; end end end --Convert the default check state to Khaos style if ( reglist.uicheck and ( (reglist.uicheck == 1) or (reglist.uicheck == true) ) ) then reglist.uicheck = true; else reglist.uicheck = false; end --Convert the disabled check to Khaos format if ( reglist.uidischeck and ( (reglist.uidischeck == 1) or (reglist.uidischeck == true) ) ) then reglist.uidischeck = true; elseif (reglist.uidischeck == 0) then reglist.uidischeck = false; end --Setup the default structure kOption.default = {}; if (reglist.hasbool) then kOption.default.checked = reglist.uicheck; end if (reglist.uitype == K_SLIDER) then kOption.default.slider = reglist.uislider; if (kOption.default.slider == nil) then kOption.default.slider = reglist.uimax; end if (kOption.default.slider == nil) then kOption.default.slider = reglist.uimin; end if (kOption.default.slider == nil) then kOption.default.slider = 1; end end if (reglist.uitype == K_COLORPICKER) then kOption.default.color = reglist.uicolor; end if ( (reglist.uitype == K_PULLDOWN) ) then kOption.default.value = reglist.uichoice; end if ( (reglist.uitype == K_EDITBOX) ) then kOption.default.value = reglist.uistring; end --Setup the disabled structure --fallback to default, if disabled is not passed kOption.disabled = {}; if (reglist.hasbool) then kOption.disabled.checked = reglist.uidischeck; if (kOption.disabled.checked == nil) then kOption.disabled.checked = reglist.uicheck; end end if (reglist.uitype == K_SLIDER) then kOption.disabled.slider = reglist.uidisslider; if (kOption.disabled.slider == nil) then kOption.disabled.slider = reglist.uislider; end if (kOption.disabled.slider == nil) then kOption.disabled.slider = reglist.uimax; end if (kOption.disabled.slider == nil) then kOption.disabled.slider = reglist.uimin; end if (kOption.disabled.slider == nil) then kOption.disabled.slider = 1; end end if (reglist.uitype == K_COLORPICKER) then kOption.disabled.color = reglist.uidiscolor; if (kOption.disabled.color == nil) then kOption.disabled.color = reglist.uicolor; end end if ( (reglist.uitype == K_PULLDOWN) ) then kOption.disabled.value = reglist.uidisstring; if (kOption.disabled.value == nil) then kOption.disabled.value = reglist.uistring; end end if ( (reglist.uitype == K_EDITBOX) ) then kOption.disabled.value = reglist.uidischoice; if (kOption.disabled.value == nil) then kOption.disabled.value = reglist.uichoice; end end --Setup the option dependencies kOption.dependencies = reglist.uidep; --Pull the option set from Khaos local optionSet = KhaosData.configurationSets[MCom.uisec]; --Will be set to true if we need to register this set(as in, it has not yet been registered) local needsReg = false; --If the set didn't yet exist, then create it if (not optionSet) then needsReg = true; --New set, so we need to register it optionSet = { id = reglist.uisec; text = reglist.uiseclabel; helptext = reglist.uisecdesc; difficulty = reglist.uisecdiff; callback = reglist.uiseccall; default = reglist.uisecdef; commands = reglist.uiseccom }; end --If there is no option structure in this set yet, then make one if (not optionSet.options) then optionSet.options = {}; end --Check that this option does not already exist local alreadyExists = false; for curOpt = 1, table.getn(optionSet.options) do if (optionSet.options[curOpt].id == reglist.uivar) then alreadyExists = true; break; end end --Only proceed further if the option doesn't already exist if (not alreadyExists) then --Default the option insertion position to the end of the option list local optionPos = table.getn(optionSet.options); --If we have a header specified, then try to find the last position after it --and if it doesn't exist yet.. then make it if (MCom.uisep) then local foundHeader = false; --Set true if we find the header --Try to find the header for curOpt = 1, table.getn(optionSet.options) do --If we have found the header, and we have made it to the next header --then break here, to put the option just before this header if (foundHeader) then if (optionSet.options[curOpt].type == K_HEADER) then break; end end --If we found the header, set foundHeader if (optionSet.options[curOpt].id == MCom.uisep) then foundHeader = true; end --Set the current option position to this postition optionPos = curOpt; end --If we didn't find the passed header, then make it, at the last spot in the list if (not foundHeader) then --Make sure a header was passed if (reglist.uisep) then --If no label was passed for the header, use the header variable name if (not reglist.uiseplabel) then reglist.uiseplabel = reglist.uisep; end --If no description was passed for the header, use the header label if (not reglist.uisepdesc) then reglist.uisepdesc = reglist.uiseplabel; end --Make the header option structure local hOption = { id = reglist.uisep; text = reglist.uiseplabel; helptext = reglist.uisepdesc; type = K_HEADER; difficulty = reglist.uisepdiff; }; --Itterate the option position up one optionPos = optionPos + 1; --Shove the header in the last slot in the list table.insert(optionSet.options, optionPos, hOption); else --If we didn't find the header, and there wasn't one passed... then clean out the --stored header MCom.uisep = nil; end end end --Shove the option into the next spot in the table table.insert(optionSet.options, optionPos + 1, kOption); if (needsReg) then --If the option set hasn't been registered yet.. then register it Khaos.registerOptionSet(MCom.uifolder, optionSet); else --If the option set has been registered, then we need to validate it, to make sure it's kuhl Khaos.validateOptionSet(optionSet); end end end end elseif (CosmosMaster_Init and reglist.uivar and reglist.uitype and reglist.uilabel ) then --Only register valid Cosmos types if ( (reglist.uitype == "SECTION") or (reglist.uitype == "SEPARATOR") or (reglist.uitype == "BUTTON") or (reglist.uitype == "CHECKBOX") or (reglist.uitype == "SLIDER") or (reglist.uitype == "BOTH") ) then --If we don't have Khaos, but do have Cosmos, then register for Cosmos --If the section has been passed, then register it if (reglist.uisec) then --If the section variable name is not prefixed with COS_ then put it on there if ( (string.len(reglist.uisec) < 4) or (string.sub(reglist.uisec, 1, 4) ~= "COS_") ) then reglist.uisec = "COS_"..reglist.uisec; end --Register the section Cosmos_RegisterConfiguration(reglist.uisec, "SECTION", reglist.uiseclabel, reglist.uisecdesc); end --If the separator has been passed, then register it if (reglist.uisep) then --If the separator variable name is not prefixed with COS_ then put it on there if ( (string.len(reglist.uisep) < 4) or (string.sub(reglist.uisep, 1, 4) ~= "COS_") ) then reglist.uisep = "COS_"..reglist.uisep; end --If no label is passed for the separator, then use the variable name if (not reglist.uiseplabel) then reglist.uiseplabel = reglist.uisep; end --If no description is passed for the separator, then use the label if (not reglist.uisepdesc) then reglist.uisepdesc = reglist.uiseplabel; end --Register the seperator Cosmos_RegisterConfiguration(reglist.uisep, "SEPARATOR", reglist.uiseplabel, reglist.uisepdesc); end --If we don't have a uifunc yet, then wrap the func if ( (not reglist.uifunc) and reglist.func ) then reglist.uifunc = function (checked, value) MCom.SetFromUI(reglist.uivar, checked, value); end; --Add the function to the list of callback functions if (reglist.uitype) then --Only do this for UI elements that have options if ((reglist.uitype == "CHECKBOX") or (reglist.uitype == "SLIDER") or (reglist.uitype == "BOTH") or (reglist.uitype == "BUTTON")) then if (not MCom.UIFuncList) then MCom.UIFuncList = {}; end if (not MCom.UIFuncList[reglist.uivar]) then MCom.UIFuncList[reglist.uivar] = {}; end MCom.UIFuncList[reglist.uivar].func = reglist.func; MCom.UIFuncList[reglist.uivar].uitype = reglist.uitype; MCom.UIFuncList[reglist.uivar].hasbool = reglist.hasbool; end end end --Convert the default check state to Cosmos style if ( reglist.uicheck and ( (reglist.uicheck == 1) or (reglist.uicheck == true) ) ) then reglist.uicheck = 1; else reglist.uicheck = 0; end --Register with Cosmos if available Cosmos_RegisterConfiguration(reglist.uivar, reglist.uitype, reglist.uilabel, reglist.uidesc, reglist.uifunc, reglist.uicheck, reglist.uislider, reglist.uimin, reglist.uimax, reglist.uitext, reglist.uistep, reglist.uitexton, reglist.uisuffix, reglist.uimul ); end end --If we have enough data to register a slash command, then do it --We need to make sure to pass the right ordered var data to the function local comVar = reglist.varbool; local comVarMulti = reglist.varnum; if (regtype == MCOM_STRINGT) then comVarMulti = reglist.varstring; elseif (regtype == MCOM_CHOICET) then comVarMulti = reglist.varchoice; elseif (regtype == MCOM_COLORT) then comVarMulti = reglist.varcolor; end if (not comVar) then comVar = comVarMulti; comVarMulti = nil; end if (reglist.command and reglist.func) then --If no command help was passed, but a ui description was, then use the ui description if ( ( not reglist.bomhelp ) and ( reglist.uidesc ) ) then reglist.bomhelp = reglist.uidesc; end MCom.addSlashCom(reglist.command, reglist.func, reglist.comaction, reglist.comsticky, reglist.comhelp, regtype, reglist.uisec, reglist.uivar, comVar, comVarMulti, reglist.varmin, reglist.varmax, reglist.commul, reglist.cominmul, reglist.hasbool, reglist.choices, reglist.multichoice, reglist.hasopacity, reglist.extrahelp); end --If we have enough data to register a super slash command, then do it if (reglist.supercom) then MCom.addSlashSuperCom(reglist.supercom, reglist.comaction, reglist.comsticky, reglist.comhelp, reglist.extrahelp); end --If we have enough data to register a sub slash command, then do it if (reglist.supercom and reglist.subcom and reglist.func) then --If no sub command help was passed, but a ui description was, then use the ui description if ( ( not reglist.subhelp ) and ( reglist.uidesc ) ) then reglist.subhelp = reglist.uidesc; end MCom.addSlashSubCom(reglist.supercom, reglist.subcom, reglist.func, reglist.subhelp, regtype, reglist.uisec, reglist.uivar, comVar, comVarMulti, reglist.varmin, reglist.varmax, reglist.commul, reglist.cominmul, reglist.hasbool, reglist.choices, reglist.multichoice, reglist.hasopacity); end --If we should be adding an info option, then handle this now if (reglist.infotext) then --Setup a function to display addon information, if data is available for it local infofunc = nil; if (reglist.infotext) then --If reglist.infotext isn't already a table, then turn it into one if (type(reglist.infotext) ~= "table") then reglist.infotext = { reglist.infotext }; end --Setup a default info title if we dont have one local curInfoTitle = reglist.infotitle; if (not curInfoTitle) then curInfoTitle = MCOM_HELP_GENERIC_TITLE; if (reglist.name) then curInfoTitle = string.format(MCOM_HELP_TITLE, reglist.name); end end --If this is not a boolean, then add the slash command info to the end of the text as a new page if ( type(reglist.infotext) ~= "boolean" ) then infofunc = function () --Get the info text and title local infotext = MCom.table.copy(reglist.infotext); local infotitle = curInfoTitle; --If the text isn't a table turn it into one if (type(infotext) ~= "table" ) then infotext = { infotext }; end if (reglist.supercom) then --Add the slash command info on to it infotext[table.getn(infotext) + 1] = MCom.PrintSlashCommandInfo(MCom.getComID(reglist.supercom), true); end --Show the text frame MCom.textFrame( { text = infotext; title = infotitle; } ); end; elseif ( reglist.supercom ) then infofunc = function () --Set the text as the slash command info local infotext = MCom.PrintSlashCommandInfo(MCom.getComID(reglist.supercom), true); local infotitle = curInfoTitle; --Show the text frame MCom.textFrame( { text = infotext; title = infotitle; } ); end; end end --If we have an info function, then add options to access it if (infofunc) then --Use the generic description local infoDesc = MCOM_HELP_GENERIC; --If a name has been passed for this mod, then use it in the description if (reglist.name) then infoDesc = string.format(MCOM_HELP_CONFIG_INFO, reglist.name); end --If we have Khaos or Cosmos then register with them if (Khaos or CosmosMaster_Init and reglist.name) then --Setup the difficulty of the help button local infodiff = reglist.uisecdiff; if (not infodiff) then infodiff = reglist.uidiff; end if (not infodiff) then infodiff = 1; end --Setup the name to display local infoName = string.format(MCOM_HELP_CONFIG, reglist.name); --Register the option MCom.registerSmart( { uivar = reglist.name.."MComInfo"; --The option name for the UI uitype = K_BUTTON; --The option type for the UI uilabel = infoName; --The label to use for the checkbox in the UI uidesc = infoDesc; --The description to use for the checkbox in the UI uidiff = infodiff; --The option's difficulty in Khaos uifunc = infofunc; --The function to call uitext = MCOM_HELP_GENERIC_TITLE; --The text to show on the button } ); end --Register the sub slash command if ( reglist.supercom ) then MCom.registerSmart( { supercom = reglist.supercom; subcom = MCOM_HELP_COMMAND; subhelp = infoDesc; comtype = MCOM_SIMPLET; func = infofunc; } ); end end end end end; --[[ getStringVar ( string value ) Accepts a variable as a string, and returns the value. However this can parse complex variable names that contain . such as "Something.Variable" It does not handle "Something['Variable']".. Just use the . format instead. This also works for number indexes. Args: varString - the variable to get, encapsulated in a string, ex: "Something.Variable.Monkey.Hippo" Returns: the contents of the variable in the passed string ]]-- MCom.getStringVar = function (varString) if (Sea and Sea.util and Sea.util.getValue) then return Sea.util.getValue(varString); else --Legorols get string var code, no GCs, and no need to store each entry if ( type(varString) ~= "string" ) then return nil; end; -- Table we reuse with calls to split if ( not MCom.valueTable ) then MCom.valueTable = {}; end -- Split the variable name at ".", first field is a global name local fields = MCom.util.split(varString, ".", MCom.valueTable); local encloser, member = getglobal(fields[1]), fields[2]; -- If encloser is the only field, it's a global, return its value if ( not member ) then return encloser; end -- If there are subsequent fields present, get to deeper levels for i = 3, table.getn(fields) do if ( type(encloser) ~= "table" ) then return nil; end encloser = encloser[member]; member = fields[i]; end -- Encloser is now the last but one field, member is the last field if ( type(encloser) == "table" ) then return encloser[member]; end -- Error occured, encloser is not a table, return nil end end; --Alias for compatability MCom.stringToVar = MCom.getStringVar; --[[ stringVarToGetFunc ( string varString ) Accepts a variable as a string, and returns a function that returns the value. However this can parse complex variable names that contain . such as "Something.Variable" This is alot like getStringVar. However, getStringVar has to generate several objects that will need to be garbage collected. The function returned by stringVarToFunc does not generate any amount of GCs worth worying about. So if you are needing to do this very often, like OnUpdate, then it is best to use this function to convert to a function, and simply call that functin to get the data you need. It does not handle "Something['Variable']".. Just use the . format instead. This also works for number indexes. Args: varString - the variable to get, encapsulated in a string, ex: "Something.Variable.Monkey.Hippo" Returns: a function that when called will return the data in the passed variable ]]-- MCom.stringVarToGetFunc = function (varString) if ( type(varString) == "string" ) then --Seperate the variable by the .'s into a list local valList = MCom.util.split(varString, "."); --The function we will return local varFunc; --Only proceed if we have a variable to work with if (valList and valList[1]) then --If it's a table make it a function that will parse the parts if (getn(valList) > 1) then --Create the function varFunc = function () --Get the global variable local value = getglobal(valList[1]); --Go through each entry in the table and get that variable for curPart = 2, getn(valList) do --Only get the variable if it is a table if ( ( type(value) == "table" ) and value[ valList[curPart] ] ) then --Get the variable value = value[ valList[curPart] ]; else --Something was invalid, return nil return; end end --We got the value, so return it return value; end; else --This is a simple variable, so just return the global varFunc = function () return getglobal(valList[1]); end; end end --Return the function return varFunc; end end; --[[ setStringVar ( string varString, value ) Sets a variable, specified by a string, to a value. However this can parse complex variable names that contain . such as "Something.Variable" It does not handle "Something['Variable']".. Just use the . format instead. This also works for number indexes. Args: varString - the variable to set, encapsulated in a string, ex: "Something.Variable.Monkey.Hippo" value - the value to set the variable to, can be any type ]]-- MCom.setStringVar = function (varString, value) if (Sea and Sea.util and Sea.util.setValue) then return Sea.util.setValue(varString, value); else --Legorols set string var code, no GCs, and no need to store each entry if ( type(varString) ~= "string" ) then return false; end; -- Table we reuse with calls to split if ( not MCom.valueTable ) then MCom.valueTable = {}; end -- Split the variable name at ".", first field is a global name local fields = MCom.util.split(varString, ".", MCom.valueTable); local encloser, member = getglobal(fields[1]), fields[2]; -- If encloser is the only field, variable is a global, set its value if ( not member ) then setglobal(varString, value); return true; end -- If there are subsequent fields present, get to deeper levels for i = 3, table.getn(fields) do if ( type(encloser) ~= "table" ) then return false; end encloser = encloser[member]; member = fields[i]; end -- Encloser is now the last but one field, member is the last field if ( type(encloser) == "table" ) then encloser[member] = value; return true; end -- Error occured, encloser is not a table return false; end end; --[[ stringVarToSetFunc ( string varString ) Returns a function that can be used to set the passed string to a value. However this can parse complex variable names that contain . such as "Something.Variable" This is alot like setStringVar. However, setStringVar has to generate several objects that will need to be garbage collected. The function returned by stringVarToSetFunc does not generate any amount of GCs worth worying about. So if you are needing to do this very often, like OnUpdate, then it is best to use this function to convert to a function, and simply call that functin to set the data you need. It does not handle "Something['Variable']".. Just use the . format instead. This also works for number indexes. Args: varString - the variable to set, encapsulated in a string, ex: "Something.Variable.Monkey.Hippo" Returns: function ( number value) - a function that when called will set the string passed here, to the value passed to the function. ]]-- MCom.stringVarToSetFunc = function (varString) if ( type(varString) == "string" ) then --Seperate the variable by the .'s into a list local valList = MCom.util.split(varString, "."); --The function we will return local varFunc; --Only proceed if we have a variable to work with if (valList and valList[1]) then --If it's a table make it a function that will parse the parts if (getn(valList) > 1) then --Create the function varFunc = function (value) --Get the global variable local var = getglobal(valList[1]); --Go through each entry in the table and get that variable for curPart = 2, getn(valList) do --If we have reached the last entry in the list, then set it if ( curPart == getn(valList) ) then if ( type(var) == "table" ) then var[ valList[curPart] ] = value; else return; end else --Only get the variable if it is a table if ( ( type(var) == "table" ) and var[ valList[curPart] ] ) then --Get the variable var = var[ valList[curPart] ]; else --Something was invalid, return nil return; end end end end; else --This is a simple variable, so just return the global varFunc = function (value) setglobal(valList[1], value); end; end end --Return the function return varFunc; end end; --[[ updateVar ( string varname, value [, string vartype, number varmin, number varmax] ) updates the variable contained in varname, to value. Handles things different based on the type of var varname is. If it should be a bool, then it only accepts 1 and 0, or -1 to invert the current setting. For number, it makes sure it is in the range varmin and varmax. Args: varname - name of the variable to update, wrapped in a string, can be complex like "Something.Variable" value - what to set it to, should be 1, 0, or -1 for bool, any number for number type, or any string for string type Optional: vartype - should be one of the MCOM_ types varmin - specifies the minimum value for a number type varmax - specifies the maximum value for a number type Returns: if the value changed from its origional value, returns true ]]-- MCom.updateVar = function (varname, value, vartype, varmin, varmax) if (varname and value) then -- store the old value of the variable local oldValue = MCom.getStringVar(varname); if (vartype == MCOM_BOOLT) then --If a -1 is passed, invert the value if (value and (value == -1)) then if (oldValue == 1) then value = 0; else value = 1; end end --Update the value if (value and (value==1)) then value = 1; else value = 0; end elseif (vartype == MCOM_NUMT) then --if its a number and max/min were specified, make sure it's in range if (varmin and (value < varmin)) then value = varmin; end if (varmax and (value > varmax)) then value = varmax; end end local didUpdate = false; if (vartype == MCOM_COLORT) then --If we don't have an old value, then make one if ( not oldValue ) then didUpdate = true; oldValue = {}; end --if its a color then make sure the color parts are in range if (value.r) then if (value.r > 1) then value.r = 1; end if (value.r < 0) then value.r = 0; end if (oldValue.r ~= value.r) then didUpdate = true; end else value.r = oldValue.r; end if (value.g) then if (value.g > 1) then value.g = 1; end if (value.g < 0) then value.g = 0; end if (oldValue.g ~= value.g) then didUpdate = true; end else value.g = oldValue.g; end if (value.b) then if (value.b > 1) then value.b = 1; end if (value.b < 0) then value.b = 0; end if (oldValue.b ~= value.b) then didUpdate = true; end else value.b = oldValue.b; end if (value.opacity) then if (value.opacity > 1) then value.opacity = 1; end if (value.opacity < 0) then value.opacity = 0; end if (oldValue.opacity ~= value.opacity) then didUpdate = true; end else value.opacity = oldValue.opacity; end else --if the value changed, return true if (value ~= oldValue) then didUpdate = true; end end if (didUpdate) then MCom.setStringVar(varname, value); return true; end end end; --[[ printStatus ( string text, [string/number/bool] value, bool isbool, bool show ) If Cosmos is not found printStatus will print out a status message, intended to let user know when an option has been changed, when there is no GUI available. Args: text - the text to print, this can include a %s, and value(or enabled/disabled for bool) will be put in place of the %s Ex: "This option has been %s" for bool, or "This option has been set to %s" for number or string Optional: value - what value to display, can be a string, a number, or a bool isbool - if this is true, then the value will be treated as a bool, and if true(or 1) then the %s will contain the world "Enabled" or "Disabled" for false(or 0) show - if this is true, then the text will be printed whether there is a UI or not ]]-- MCom.printStatus = function (text, value, isbool, show) if ( ( not MCom.hasUI() ) or show ) then --Convert to string if (type(value) == "number") then value = tostring(value); end --If it's boolean or nill convert to 1 or 0 if ((type(value) == "boolean") or (type(value) == "nil")) then if (value) then value = "1"; else value = "0"; end end if (type(value) == "string") then local outText = value; --If it's a bool convert to Enabled/Disabled if (isbool) then outText = MCOM_CHAT_DISABLED; if (value == "1") then outText = MCOM_CHAT_ENABLED; end end --Format and print the message local msg = string.format(text, outText); MCom.IO.printc(ChatTypeInfo["SYSTEM"], msg); end end end; --[[ hasUI ( ) Tells whether or not a UI, like Cosmos or Khaos is present. Returns: true - there is a UI false - there is no UI ]]-- MCom.hasUI = function (varString) local hasUI = true; if ( ( CosmosMaster_Init == nil ) and ( Khaos == nil ) ) then hasUI = false; end return hasUI; end; --[[ updateUI ( string slashcom, string subcom ) Updates the UI(Cosmos or Khaos) with the values of the variable associated with the slash command passed to the function. If this is done on a super slash command, then all sub commands will be updated, unless a specific on is specified. Args: slashcom - The slash commmand, or super slash command to update the variable from. Optional: subcom - If slashcom is a super slash command, you can use this to specify which slash command to update. ]]-- MCom.updateUI = function (slashcom, subcom) if (MCom.SlashComs) then --Get the command IDs local comid, subcomid = MCom.getComID(slashcom, subcom); if (comid) then --Get the command local command = MCom.SlashComs[comid]; --If we have a subcommand, then lets use it if (subcomid) then command = { command.commands[subcomid] }; elseif (command.commands) then command = command.commands; end --If command isnt a table, then turn it into one if (type(command) ~= "table") then command = { command }; end local didUpdate = nil; if (KhaosData and KhaosData.configurationSets) then --If we have Khaos around, then lets update for it local curCom = nil; local newValMulti = nil; local newVal = nil; --Go trhough all commands and update them for curComID in command do --Grab the current command structure curCom = command[curComID]; if (curCom.uisec and KhaosData.configurationSets[curCom.uisec] and curCom.uivar and curCom.comvar) then --get the value of the variable newVal = MCom.getStringVar(curCom.comvar); if (newVal) then --Grab the second variable, if there is one newValMulti = MCom.getStringVar(curCom.comvarmulti); --Deault param to change is value local param = "value"; --If it's a boolean, or we have a boolean as well.. then update the boolean part if ( (curCom.comtype == MCOM_BOOLT) or (curCom.comtype == MCOM_MULTIT) or curCom.hasbool) then --Make sure the value is in true/false form if (newVal == 1) then newVal = true; else newVal = false; end --Update the value Khaos.setSetKeyParameter(curCom.uisec, curCom.uivar, "checked", newVal); end --If it isn't a boolean type then proccess either the other types, or secondary part if ( curCom.comtype ~= MCOM_BOOLT ) then --If we have a second part variable, then use it now if (newValMulti) then newVal = newValMulti; end --Handle number types as sliders if ( (curCom.comtype == MCOM_NUMT) or (curCom.comtype == MCOM_MULTIT) ) then param = "slider"; end --Handle color types as color pickers if (curCom.comtype == MCOM_COLORT) then param = "color"; end --Update the value Khaos.setSetKeyParameter(curCom.uisec, curCom.uivar, param, newVal); end didUpdate = true; end end end --If we updated something, then update the Khaos display if (didUpdate) then Khaos.refresh(); end else --We only need to update Cosmos if it exists if (CosmosMaster_Init) then local curCom = nil; local newValMulti = nil; local newVal = nil; --Go trhough all commands and update them for curComID in command do curCom = command[curComID]; if (curCom.uivar and curCom.comvar) then --get the value of the variable newVal = MCom.getStringVar(curCom.comvar); if (newVal) then newValMulti = MCom.getStringVar(curCom.comvarmulti); if ((curCom.comtype ~= MCOM_MULTIT) or ((curCom.comtype == MCOM_MULTIT) and newValMulti)) then --if its a boolean, then set the checkbox if ((curCom.comtype == MCOM_BOOLT) or (curCom.comtype == MCOM_MULTIT)) then Cosmos_UpdateValue(curCom.uivar, CSM_CHECKONOFF, newVal); didUpdate = true; end --if its a number, then set the slider if ((curCom.comtype == MCOM_NUMT) or (curCom.comtype == MCOM_MULTIT)) then if (curCom.comtype == MCOM_MULTIT) then newVal = newValMulti; end Cosmos_UpdateValue(curCom.uivar, CSM_SLIDERVALUE, newVal); didUpdate = true; end end end end end --If we updated something, then update the Cosmos display if (didUpdate) then CosmosMaster_DrawData(); end end end end end end; --[[ getComID ( [string/number] slashcom, string subcom ) Gets the ID of the slashcom in the slash commands list, as well as a sub slash command, if you specify that you want a sub commands ID. Args: slashcom - The slash commmand, or super slash command to get the ID of. If you pass the ID itself, that ID will be used when getting the sub command. This can be a list of commands, instead of just one, in which case, it will return the first one in the list that it finds. Don't forget the / ex. "/command" Optional: slashcom - The sub command you want to get, if you want one. This can be a list instead of just one command, the first one found will be used. Returns: commandid - If it finds the command, it returns the ID, otherwise it returns nil. subcommand - If it finds the subcommand it also returns that, otherwise, nil. ]]-- MCom.getComID = function (command, subcom) local commandid = nil; local subcommandid = nil; if (MCom.SlashComs) then --If the ID was passed, then use it if ((type(command) == "number") and MCom.SlashComs[command]) then commandid = command; else --make sure command is a table if (type(command) ~= "table") then command = {command}; end --find the command in the table for curCom in command do for curListCom in MCom.SlashComs do if (MCom.SlashComs[curListCom].basecommand) then for curBaseCom in MCom.SlashComs[curListCom].basecommand do if (MCom.SlashComs[curListCom].basecommand[curBaseCom] == command[curCom]) then commandid = curListCom; break; end end if (commandid) then break; end end end end end if (commandid and subcom) then --make sure sub command is a table if (type(subcom) ~= "table") then subcom = {subcom}; end --Try and find the subcommand in the list for curSub in subcom do for curCom in MCom.SlashComs[commandid].commands do if (MCom.SlashComs[commandid].commands[curCom].command) then for curComCom in MCom.SlashComs[commandid].commands[curCom].command do if (MCom.SlashComs[commandid].commands[curCom].command[curComCom] == subcom[curSub]) then subcommandid = curCom; break; end end if (subcommandid) then break; end end end end end end return commandid, subcommandid; end; --[[ saveConfig ( {reglist} ) This will store all of the variables you want into a per realm, per character table(MComStorage) inside the passed variable. This is meant to facilatate storing/loading variables on a per realm, per character basis. You must register the passed variable for saving, yourself. Args: reglist - This contains all options for this save procedure { Required: (string) configVar - The name of the config variable, this should have been registered for save by you, and must be a table with a simple variable name. IE no .'s or []'s Optional: (string) storeVar - The name of the variable to load/store the data in. If not passed then configVar.MComStorage is used. Remember to register it for saving. (string) exactVar - If you pass this, then data will be stored in this var, regardless of realm/character. It will go into this exact var. This takes precidence over storeVar. (string) realm - This allows you to specify the realm to store to, if not passed, then the current realm will be used. (string) character - This allows you to specify the character to store to, if not passed, then the current character will be used. NOTE: For all the following, this will only work on root level variables. I.E. Whatever_Config.Variable. For this you would pass "Variable" (string or table) saveList - The names of all variables in the config to be stored, if this is not passed, then MCom will try to store all variables except the MComStorage variable. (string or table) ignoreList - The names of any variables that you want MCom to not store. (string or table) uiList - These variables will only be stored if there is no UI available. Any options that you have the UI controlling should be included in here, so you can leave it up to the UI to properly load/save them. (string or table) nonUIList - If this list is declared, then uiList will be ignored, and all variables, except these, will be considered UI variables. (string or table) forceList - After going through the normal vars, MCom will go through and save these vars, even if they are nil. This list is affected by the rules set by the above lists as well. } Returns: true - Some data was saved false - No data was saved ]]-- MCom.saveConfig = function ( reglist ) --We will set this true, if we saved any data local didSave = false; --Make sure we have the required info in the right form if ( reglist and ( type(reglist) == "table" ) and reglist.configVar ) then --Get the config variable table local varTable = MCom.getStringVar(reglist.configVar); --Only proceed if the config variable is a table if ( type(varTable) == "table" ) then --Get the realm and character name local realm = reglist.realm; if (not realm) then realm = GetCVar("RealmName"); end local character = reglist.character; if (not character) then character = UnitName("player") end --Setup the variable to store data in. local storeVar = MCom.getStringVar(reglist.exactVar); --If we don't have an exactVar and we have the server and character name then generate the storeVar if ( (not storeVar) and realm and character and ( ( character ~= UKNOWNBEING ) and ( character ~= UNKNOWNOBJECT ) ) ) then --Get the storage var if one was passed storeVar = MCom.getStringVar(reglist.storeVar); if (not storeVar) then --If the MComStorage variable isn't there yet, or isn't a table, then set it as an empty table if (type(varTable.MComStorage) ~= "table") then varTable.MComStorage = {}; end storeVar = varTable.MComStorage; end --If this realm doesn't exist, then create it if (not storeVar[realm]) then storeVar[realm] = {}; end --If this character doesn't exist, then create it if (not storeVar[realm][character]) then storeVar[realm][character] = {}; end --Set storeVar to use the current realm/char storeVar = storeVar[realm][character]; end --If we have the variable to store to, then we are good to go if (storeVar) then --Go through all the variables in the table for curVar in varTable do --Ignore the MComStorage variable if (curVar ~= "MComStorage") then --This will become true if we shouldn't store this variable local doIgnore = false; --If we have a list of vars to save, then go through them, and if this var is not in there, then ignore it if (reglist.saveList) then --Default to ignoring now doIgnore = true; --Make sure the saveList is a table if (type(reglist.saveList) ~= "table") then reglist.saveList = { reglist.saveList }; end --Go through the list and see if we find the variable, if we do, then we don't ignore it for i, curSaveCheck in reglist.saveList do if (curVar == curSaveCheck) then doIgnore = false; break; end end end --If we are supposed to ignore this guy, then do so now if (not doIgnore) then --If we have a list of vars to ignore, then go through them, and if this var is in there, then ignore it if (reglist.ignoreList) then --Make sure the ignoreList is a table if (type(reglist.ignoreList) ~= "table") then reglist.ignoreList = { reglist.ignoreList }; end --Go through the list and see if we find the variable, if we do, then ignore it for i, curIgnoreCheck in reglist.ignoreList do if (curVar == curIgnoreCheck) then doIgnore = true; break; end end end --If we are supposed to ignore this guy, then do so now if (not doIgnore) then if (reglist.nonUIList) then --Since these are UI vars, then we should only be ignoring them if the UI is around if ( MCom.hasUI() ) then --Unless we find this in the list, we should be ignoring it doIgnore = true; --Make sure the nonUIList is a table if (type(reglist.nonUIList) ~= "table") then nonUIList = { reglist.nonUIList }; end --Go through the list and see if we find the variable, if we do, then don't ignore it for i, curUICheck in reglist.nonUIList do if (curVar == curUICheck) then doIgnore = false; break; end end end else if (reglist.uiList) then --Since these are UI vars, then we should only be ignoring them if the UI is around if ( MCom.hasUI() ) then --Make sure the uiList is a table if (type(reglist.uiList) ~= "table") then uiList = { reglist.uiList }; end --Go through the list and see if we find the variable, if we do, then ignore it for i, curUICheck in reglist.uiList do if (curVar == curUICheck) then doIgnore = true; break; end end end end end --If we are supposed to ignore this guy, then do so now if (not doIgnore) then --Store the variable storeVar[curVar] = varTable[curVar]; --Set that we saved data didSave = true; end end end end end --If a forced list has been passed, then go through it if (reglist.forceList) then --Make sure it is a table if ( type(reglist.forceList) ~= "table" ) then reglist.forceList = { reglist.forceList }; end --Go through all the variables in the table for i, curVar in reglist.forceList do --Ignore the MComStorage variable if (curVar ~= "MComStorage") then --This will become true if we shouldn't store this variable local doIgnore = false; --If we have a list of vars to save, then go through them, and if this var is not in there, then ignore it if (reglist.saveList) then --Default to ignoring now doIgnore = true; --Make sure the saveList is a table if (type(reglist.saveList) ~= "table") then reglist.saveList = { reglist.saveList }; end --Go through the list and see if we find the variable, if we do, then we don't ignore it for i, curSaveCheck in reglist.saveList do if (curVar == curSaveCheck) then doIgnore = false; break; end end end --If we are supposed to ignore this guy, then do so now if (not doIgnore) then --If we have a list of vars to ignore, then go through them, and if this var is in there, then ignore it if (reglist.ignoreList) then --Make sure the ignoreList is a table if (type(reglist.ignoreList) ~= "table") then reglist.ignoreList = { reglist.ignoreList }; end --Go through the list and see if we find the variable, if we do, then ignore it for i, curIgnoreCheck in reglist.ignoreList do if (curVar == curIgnoreCheck) then doIgnore = true; break; end end end --If we are supposed to ignore this guy, then do so now if (not doIgnore) then if (reglist.nonUIList) then --Since these are UI vars, then we should only be ignoring them if the UI is around if ( MCom.hasUI() ) then --Unless we find this in the list, we should be ignoring it doIgnore = true; --Make sure the nonUIList is a table if (type(reglist.nonUIList) ~= "table") then nonUIList = { reglist.nonUIList }; end --Go through the list and see if we find the variable, if we do, then don't ignore it for i, curUICheck in reglist.nonUIList do if (curVar == curUICheck) then doIgnore = false; break; end end end else if (reglist.uiList) then --Since these are UI vars, then we should only be ignoring them if the UI is around if ( MCom.hasUI() ) then --Make sure the uiList is a table if (type(reglist.uiList) ~= "table") then uiList = { reglist.uiList }; end --Go through the list and see if we find the variable, if we do, then ignore it for i, curUICheck in reglist.uiList do if (curVar == curUICheck) then doIgnore = true; break; end end end end end --If we are supposed to ignore this guy, then do so now if (not doIgnore) then --Store the variable storeVar[curVar] = varTable[curVar]; --Set that we saved data didSave = true; end end end end end end end end end --Return if we saved data or not return didSave; end; --[[ loadConfig ( {reglist} ) This will load all variables stored in the passed table in MComStorage. This only works on variables that have stored the data using MCom.saveConfig Args: reglist - This contains all options for this load procedure { Required: (string) configVar - The name of the config variable, this should have been registered for save by you, and must be a table with a simple variable name. IE no .'s or []'s Optional: (string) storeVar - The name of the variable to load/store the data in. If not passed then configVar.MComStorage is used. Remember to register it for saving. (string) exactVar - If you pass this, then data will be loaded from this var, regardless of realm/character. It will get from this exact var. This takes precidence over storeVar. (string) realm - This allows you to specify the realm to load from, if not passed, then the current realm will be used. (string) character - This allows you to specify the character to load from, if not passed, then the current character will be used. NOTE: For all the following, this will only work on root level variables. I.E. Whatever_Config.Variable. For this you would pass "Variable" (string or table) loadList - The names of all variables in the config to be loaded, if this is not passed, then MCom will try to load all variables except the MComStorage variable. (string or table) ignoreList - The names of any variables that you want MCom to not load. (string or table) uiList - These variables will only be loaded if there is no UI available. Any options that you have the UI controlling should be included in here, so you can leave it up to the UI to properly load/save them. (string or table) nonUIList - If this list is declared, then uiList will be ignored, and all variables, except these, will be considered UI variables. (string or table) forceList - After going through the normal vars, MCom will go through and load these vars, even if they are nil. is affected by the rules set by the above lists as well. } Returns: true - Some data was loaded false - No data was loaded ]]-- MCom.loadConfig = function ( reglist ) --We will set this true, if we loaded any data local didLoad = false; --Make sure we have the required info in the right form if ( reglist and ( type(reglist) == "table" ) and reglist.configVar ) then --Get the config variable table local varTable = MCom.getStringVar(reglist.configVar); --Only proceed if the config variable is a table if ( type(varTable) == "table" ) then --Get the realm and character name local realm = reglist.realm; if (not realm) then realm = GetCVar("RealmName"); end local character = reglist.character; if (not character) then character = UnitName("player") end --Setup the variable to load data from local storeVar = MCom.getStringVar(reglist.exactVar); --If we don't have an exactVar and we have the server and character name then generate the storeVar if ( (not storeVar) and realm and character and ( ( character ~= UKNOWNBEING ) and ( character ~= UNKNOWNOBJECT ) ) ) then --Get the storage var if one was passed storeVar = MCom.getStringVar(reglist.storeVar); if (not storeVar) then --If the MComStorage variable isn't there yet, or isn't a table, then set it as an empty table if (type(varTable.MComStorage) ~= "table") then varTable.MComStorage = {}; end storeVar = varTable.MComStorage; end --If this realm doesn't exist, then create it if (not storeVar[realm]) then storeVar[realm] = {}; end --If this character doesn't exist, then create it if (not storeVar[realm][character]) then storeVar[realm][character] = {}; end --Set storeVar to use the current realm/char storeVar = storeVar[realm][character]; end --If we have the variable to load from, then we are good to go if (storeVar) then --Go through all the variables in the table for curVar in storeVar do --This will become true if we shouldn't load this variable local doIgnore = false; --If we have a list of vars to load, then go through them, and if this var is not in there, then ignore it if (reglist.loadList) then --Default to ignoring now doIgnore = true; --Make sure the loadList is a table if (type(reglist.loadList) ~= "table") then reglist.loadList = { reglist.loadList }; end --Go through the list and see if we find the variable, if we do, then we don't ignore it for i, curLoadCheck in reglist.loadList do if (curVar == curLoadCheck) then doIgnore = false; break; end end end --If we are supposed to ignore this guy, then do so now if (not doIgnore) then --If we have a list of vars to ignore, then go through them, and if this var is in there, then ignore it if (reglist.ignoreList) then --Make sure the ignoreList is a table if (type(reglist.ignoreList) ~= "table") then reglist.ignoreList = { reglist.ignoreList }; end --Go through the list and see if we find the variable, if we do, then ignore it for i, curIgnoreCheck in reglist.ignoreList do if (curVar == curIgnoreCheck) then doIgnore = true; break; end end end --If we are supposed to ignore this guy, then do so now if (not doIgnore) then if (reglist.nonUIList) then --Since these are UI vars, then we should only be ignoring them if the UI is around if ( MCom.hasUI() ) then --Unless we find this in the list, we should be ignoring it doIgnore = true; --Make sure the nonUIList is a table if (type(reglist.nonUIList) ~= "table") then nonUIList = { reglist.nonUIList }; end --Go through the list and see if we find the variable, if we do, then don't ignore it for i, curUICheck in reglist.nonUIList do if (curVar == curUICheck) then doIgnore = false; break; end end end else if (reglist.uiList) then --Since these are UI vars, then we should only be ignoring them if the UI is around if ( MCom.hasUI() ) then --Make sure the uiList is a table if (type(reglist.uiList) ~= "table") then uiList = { reglist.uiList }; end --Go through the list and see if we find the variable, if we do, then ignore it for i, curUICheck in reglist.uiList do if (curVar == curUICheck) then doIgnore = true; break; end end end end end --If we are supposed to ignore this guy, then do so now if (not doIgnore) then --Load the variable varTable[curVar] = storeVar[curVar]; --Set that we loaded data didLoad = true; end end end end --If a forced list has been passed, then go through it if (reglist.forceList) then --Make sure it is a table if ( type(reglist.forceList) ~= "table" ) then reglist.forceList = { reglist.forceList }; end --Go through all the variables in the table for i, curVar in reglist.forceList do --This will become true if we shouldn't load this variable local doIgnore = false; --If we have a list of vars to load, then go through them, and if this var is not in there, then ignore it if (reglist.loadList) then --Default to ignoring now doIgnore = true; --Make sure the loadList is a table if (type(reglist.loadList) ~= "table") then reglist.loadList = { reglist.loadList }; end --Go through the list and see if we find the variable, if we do, then we don't ignore it for i, curLoadCheck in reglist.loadList do if (curVar == curLoadCheck) then doIgnore = false; break; end end end --If we are supposed to ignore this guy, then do so now if (not doIgnore) then --If we have a list of vars to ignore, then go through them, and if this var is in there, then ignore it if (reglist.ignoreList) then --Make sure the ignoreList is a table if (type(reglist.ignoreList) ~= "table") then reglist.ignoreList = { reglist.ignoreList }; end --Go through the list and see if we find the variable, if we do, then ignore it for i, curIgnoreCheck in reglist.ignoreList do if (curVar == curIgnoreCheck) then doIgnore = true; break; end end end --If we are supposed to ignore this guy, then do so now if (not doIgnore) then if (reglist.nonUIList) then --Since these are UI vars, then we should only be ignoring them if the UI is around if ( MCom.hasUI() ) then --Unless we find this in the list, we should be ignoring it doIgnore = true; --Make sure the nonUIList is a table if (type(reglist.nonUIList) ~= "table") then nonUIList = { reglist.nonUIList }; end --Go through the list and see if we find the variable, if we do, then don't ignore it for i, curUICheck in reglist.nonUIList do if (curVar == curUICheck) then doIgnore = false; break; end end end else if (reglist.uiList) then --Since these are UI vars, then we should only be ignoring them if the UI is around if ( MCom.hasUI() ) then --Make sure the uiList is a table if (type(reglist.uiList) ~= "table") then uiList = { reglist.uiList }; end --Go through the list and see if we find the variable, if we do, then ignore it for i, curUICheck in reglist.uiList do if (curVar == curUICheck) then doIgnore = true; break; end end end end end --If we are supposed to ignore this guy, then do so now if (not doIgnore) then --Load the variable varTable[curVar] = storeVar[curVar]; --Set that we loaded data didLoad = true; end end end end end end end end --Return if we loaded data or not return didLoad; end; --[[ safeLoad ( configVar ) Used to ensure that when variables are loaded into a table based variable, that none of the defaults are niled out. Call this after you have setup the defaults for your table, but before VARIABLES_LOADED occurs. When the variables are loaded, anything that is missing will be filled in with the defaults. Args: Required: (string) configVar - The name of the config variable, this should have been registered for save by you, and must be a table with a simple variable name. IE no .'s or []'s ]]-- MCom.safeLoad = function ( configVar ) if (not MCom.didVarsLoaded) then --Get the actual config table local varTable = MCom.getStringVar(configVar); if ( type(varTable) == "table" ) then --If we don't have a table of safe loads yet, then make one if (not MCom.safeLoads) then MCom.safeLoads = {}; end if (not MCom.safeLoads.addonLoaded) then MCom.safeLoads.addonLoaded = {}; end if (not MCom.safeLoads.varsLoaded) then MCom.safeLoads.varsLoaded = {}; end --Store this config for loading later MCom.safeLoads.addonLoaded[configVar] = varTable; --Hook for the VARIABLES_LOADED event if (not MCom.HookedOnEvent) then MCom.HookedOnEvent = true; MCom.util.hook("UIParent_OnEvent", "MCom.UIParent_OnEvent", "after"); end --Hook for the ADDON_LOADED event if (not MCom.RegisteredAddonLoaded) then UIParent:RegisterEvent("ADDON_LOADED"); end end end end; --[[ varsLoaded This will simply check to see if the variables needed to be able to use MCom.loadConfig have been loaded. To use this properly you must have an OnEvent function. You must have registered for the "UNIT_NAME_UPDATE" event. In your OnEvent handler you need to check if that event has occured, and if it has if the arg1 is player. You should also have a variable that keeps up with whether or not you have loaded your config, and only try to do so if it hasn't loaded. Ex (somewhere in the OnLoad handler) this will either register with the UI to call ModName.LoadConfig when they load their configuration, or it will register a "UNIT_NAME_UPDATE" event for you: MCom.registerForLoad(ModName.LoadConfig); Ex (somewhere in the OnEvent handler) this will handle waiting till the right vars are loaded before calling the config, when there is no UI around: if (( event == "UNIT_NAME_UPDATE" ) and (arg1 == "player") and (not ModName.VarsLoaded)) then if ( MCom.varsLoaded() ) then ModName.VarsLoaded = true; ModName.LoadConfig(); end end NOTE: Make sure you're LoadConfig function only loads the config once, as some UIs might call the function more than once. Returns: true - the variables needed to load the config are present and proper false - the variables needed to load the config are not present or not proper ]]-- MCom.varsLoaded = function () --Get the realm and character names local realm = GetCVar("RealmName"); local character = UnitName("player"); --If we have the needed data, in proper format, then return true, otherwise return false if ( realm and character and ( character ~= UKNOWNBEING ) and ( character ~= UNKNOWNOBJECT ) ) then return true; end return false; end; --[[ registerVarsLoaded ( function callback ) This will call the passed function back when the variables have been loaded by the game, or the UI. This would be an optimal time to load Args: callback( vltype ) - the function to be called when the variables have been loaded Args: (string) vltype - indicates what kind of load has occured, "UIParent" for normal, "Khaos", or "Cosmos" ]]-- MCom.registerVarsLoaded = function ( callback ) --Add this callback to the list if (not MCom.varsLoadedList) then MCom.varsLoadedList = {}; end table.insert(MCom.varsLoadedList, callback); --Only register for the load notice once if (not MCom.LoadNoticeRegistered) then MCom.LoadNoticeRegistered = true; --Try to register with Khaos if (Khaos) then Khaos.registerConfigurationLoadNotice( { onConfigurationChange = MCom.VariablesLoaded; id = "MCom"; description = "Handles all MCom registered load notices"; } ); elseif (Cosmos_RegisterVarsLoaded) then --Try to register with Cosmos Cosmos_RegisterVarsLoaded( MCom.VariablesLoaded ); else --Hook the event function of UIParent so we know when VARS_LOADED occurs if (not MCom.HookedOnEvent) then MCom.HookedOnEvent = true; MCom.util.hook("UIParent_OnEvent", "MCom.UIParent_OnEvent", "after"); end MCom.UseVarsLoadedEvent = true; end end end; --[[ DEPRICATED! For Backward compatability only. USE MCom.registerVarsLoaded ]]-- MCom.registerForLoad = function ( callback ) --Try to register with Khaos if (Khaos and this:GetName()) then Khaos.registerConfigurationLoadNotice( { onConfigurationChange = callback; id = this:GetName(); description = ""; } ); elseif (Cosmos_RegisterVarsLoaded) then --Try to register with Cosmos Cosmos_RegisterVarsLoaded( callback ); else --No UI around, so we register the event this:RegisterEvent( "UNIT_NAME_UPDATE" ); end return false; end; --[[ addSlashCom ( [string/{string, ...}] command, function comfunc, string comaction, bool comsticky, string comhelp, string comtype, string uisec, string uivar, string comvar, string comvarmulti, number commin, number commax, number commul, number cominmul, bool hasbool, {string = string, ...} choices, bool multichoice, bool hasopacity, {string, ...} extrahelp ) Registers a standard slash command. This will register with Sky, if it exists. addSlashCom makes its own chat handler function. The function expects a particular kind of input, specified by comtype. For boolean input, it will require that the user pass on, off, 1, or 0, to consider the command valid. It will then call the function you pass, and will pass a 1, 0, or a -1, standing for True, False, and no input(I suggest you make it invert the current value in this case). If Cosmos is loaded, and you have passed uivar and comvar, it will update the cosmos variable after the function has completed. If the slash command is already registered with MCom, nothing will happen. Args: command - The slash command(s) you want to register. Ex: "/command". This can be a string or a table of strings if you want more than one command. comfunc - The function that the should be called when the slash command is used, and valid. If the function returns a value that value will be used to update a cosmos variable, if uivar has been passed. You don't have to return a value to do this, but if you don't then you need to use comvar, and comvarmulti(for multi type). For multi type it should return the bool then the value, like so: "return enabled, value;" BOOL - function (bool enabled) NUMBER - function (number value) MULTI - function (bool enabled, number value) STRING - function (string value) SIMPLE - function () Optional: comaction - The action to perform, see Sky documentation for further details comsticky - Whether the command is sticky or not(1 or 0), see Sky documentation for further details comhelp - What message to display as help in Sky for this command, see Sky documentation for further details comtype - the type of data you are expecting from this slash command MCOM_BOOLT - Expects boolean data, an on, off, 1, or 0 MCOM_NUMT - Expects a number value MCOM_MULTIT - Expects a boolean and then a number value, Ex: "/command on 3" MCOM_STRINGT - Expects any string MCOM_SIMPLET - No input needed, just calls the function commin - the minimum value the number variable can be set to, for help display only commax - the maximum value the number variable can be set to, for help display only commul - the value to multiply the number by when showing it's status cominmul - A value to multiply the number passed in by the user(for number types only) hasbool - If this option has a boolean part, set this to true multichoice - Set this true if this is a choice type and can have multiple choices selected hasopacity - Set this true if this is a color type that should also have an opacity setting extrahelp - A table of extra help messages to display, each line is printed on a seperate line These are required if you want to update a Cosmos or Khaos variable: uivar - The Cosmos variable that should be updated, if you want this slash command to update a cosmos variable These are required if you want to update a Cosmos or Khaos variable, and your function doesn't return the updated value: comvar - The variable that the cosmos variable should be set by, if you want this slash command to update a cosmos variable This should be a string containing the name of the variable to update, this can include .'s for tables, Ex: "Something.Value" When type is MULTI, this specifies the bool variable comvarmulti - The same as comvar, but used to specify the number variable when type is MULTI, only used for MULTI type This is required if you want to update a Khaos variable: uisec - The option set ID that the uivar is found in This is required is you are using a MCOM_CHOICET type: choices - The list of choices ]]-- MCom.addSlashCom = function (command, comfunc, comaction, comsticky, comhelp, comtype, uisec, uivar, comvar, comvarmulti, commin, commax, commul, cominmul, hasbool, choices, multichoice, hasopacity, extrahelp) --We need at bare minimum command, and comfunc if (command and comfunc) then --If we dont have our chat command list yet, make one if (not MCom.SlashComs) then MCom.SlashComs = {}; end --make sure command is a table if (type(command) ~= "table") then command = {command}; end --If the command is not in the list yet, then add it if (not MCom.getComID(command)) then table.insert(MCom.SlashComs, {}); local commandid = getn(MCom.SlashComs); --Set the commands various elements MCom.SlashComs[commandid].basecommand = command; MCom.SlashComs[commandid].comfunc = comfunc; if (comtype) then MCom.SlashComs[commandid].comtype = comtype; elseif (MCom.SlashComs[commandid].comtype == nil) then --Default to simple type MCom.SlashComs[commandid].comtype = MCOM_SIMPLET; end if (uisec) then MCom.SlashComs[commandid].uisec = uisec; end if (uivar) then MCom.SlashComs[commandid].uivar = uivar; end if (comvar) then MCom.SlashComs[commandid].comvar = comvar; end if (comvarmulti) then MCom.SlashComs[commandid].comvarmulti = comvarmulti; end if (commim) then MCom.SlashComs[commandid].commin = commin; end if (commax) then MCom.SlashComs[commandid].commax = commax; end if (commul) then MCom.SlashComs[commandid].commul = commul; end if (cominmul) then MCom.SlashComs[commandid].cominmul = cominmul; end if (extrahelp) then MCom.SlashComs[commandid].extrahelp = extrahelp; end if (hasbool) then MCom.SlashComs[commandid].hasbool = hasbool; end if (choices) then MCom.SlashComs[commandid].choices = choices; end if (multichoice) then MCom.SlashComs[commandid].multichoice = multichoice; end if (hasopacity) then MCom.SlashComs[commandid].hasopacity = hasopacity; end --Register the command with Sky, or the default method if ( Sky ) then --Register the command with Sky Sky.registerSlashCommand( { id=string.upper(command[1]).."_COMMAND"; commands = command; onExecute = function (msg) MCom.SlashCommandHandler(commandid, msg); end; action = comaction; sticky = comsticky; helpText = comhelp; } ); else SlashCmdList[string.upper(string.sub(command[1], 2))] = function (msg) MCom.SlashCommandHandler(commandid, msg); end; for curCom = 1, getn(command) do setglobal("SLASH_"..string.upper(string.sub(command[1], 2))..curCom, command[curCom]); end end end end end; --[[ addSlashSuperCom ( [string/{string, ...}] command, string comaction, number comsticky, string comhelp ) This registers a slash command that will have sub commands in it. See addSlashSubCom for more details on sub commands. If the slash command is already registered with MCom, nothing will happen. Args: command - The slash command(s) you want to register. Ex: "/command". This can be a string or a table of strings if you want more than one command. Optional: comaction - The action to perform, see Sky documentation for further details comsticky - Whether the command is sticky or not(1 or 0), see Sky documentation for further details comhelp - What message to display as help in Sky for this command, see Sky documentation for further details extrahelp - A table of extra help messages to display, each line is printed on a seperate line ]]-- MCom.addSlashSuperCom = function (command, comaction, comsticky, comhelp, extrahelp) --We need at bare minimum command if (command) then --If we dont have our chat command list yet, make one if (not MCom.SlashComs) then MCom.SlashComs = {}; end --make sure command is a table if (type(command) ~= "table") then command = {command}; end --If the command is not in the list yet, then add it if (not MCom.getComID(command)) then table.insert(MCom.SlashComs, {}); local commandid = getn(MCom.SlashComs); MCom.SlashComs[commandid].basecommand = command; if (extrahelp) then MCom.SlashComs[commandid].extrahelp = extrahelp; end --Register the command with Sky, or the default method if ( Sky ) then Sky.registerSlashCommand( { id=string.upper(command[1]).."_COMMAND"; commands = command; onExecute = function (msg) MCom.SlashCommandHandler(commandid, msg); end; action = comaction; sticky = comsticky; helpText = comhelp; } ); else SlashCmdList[string.upper(string.sub(command[1], 2))] = function (msg) MCom.SlashCommandHandler(commandid, msg); end; for curCom = 1, getn(command) do setglobal("SLASH_"..string.upper(string.sub(command[1], 2))..curCom, command[curCom]); end end end end end; --[[ addSlashSubCom ( [string/{string, ...}] basecommand, [string/{string, ...}] subcommand, function comfunc, string comhelp, string comtype, string uisec, string uivar, string comvar, string comvarmulti, number commin, number commax, number commul, number cominmul, bool hasbool, {string = string, ...} choices, bool multichoice, bool hasopacity) This is like addSlashCom, but it registers a sub command to be used with a super command. A sub command is one that is entered after the super command is entered. Example: Normal command: "/modcommand on" Sub command, with super command of mod: "/mod command on" Using super and sub commands allows you to register only one actual real command, which helps to clean up the listing of slash commands, and helps to prevent using a slash command that may already be there. It also makes it easier for the user to remember and use, as if the user simply types the super command by itself they will get a listing of all sub commands, and usage. If the slash command is already registered with MCom, nothing will happen. Args: basecommand - The super command that this sub command goes with. Can be a single command or a list of commands. subcommand - The sub command(s) you want to register. Ex: "command". This can be a string or a table of strings if you want more than one command. comfunc - The function that the should be called when the slash command is used, and valid. If the function returns a value that value will be used to update a cosmos variable, if uivar has been passed. You don't have to return a value to do this, but if you don't then you need to use comvar, and comvarmulti(for multi type). For multi type it should return the bool then the value, like so: "return enabled, value;" BOOL - function (bool enabled) NUMBER - function (number value) MULTI - function (bool enabled, number value) STRING - function (string value) SIMPLE - function () Optional: comhelp - What message to display next to the sub command when listing sub commands in the help output. NOTE: if this is an MCOM_CHOICET then if you put a %s in this string, it will be replaces with a list of the choices you passed. comtype - the type of data you are expecting from this slash command MCOM_BOOLT - Expects boolean data, an on, off, 1, or 0 MCOM_NUMT - Expects a number value MCOM_MULTIT - Expects a boolean and then a number value, Ex: "/command on 3" MCOM_STRINGT - Expects any string MCOM_SIMPLET - No input needed, just calls the function commin - the minimum value the number variable can be set to, for help display only commax - the maximum value the number variable can be set to, for help display only commul - the value to multiply the number by when showing it's status cominmul - A value to multiply the number passed in by the user(for number types only) hasbool - If this option has a boolean part, set this to true multichoice - Set this true if this is a choice type and can have multiple choices selected hasopacity - Set this true if this is a color type that should also have an opacity setting These are required if you want to update a Cosmos variable: uivar - The Cosmos variable that should be updated, if you want this slash command to update a cosmos variable These are required if you want to update a Cosmos variable, and your function doesn't return the updated value: comvar - The variable that the cosmos variable should be set by, if you want this slash command to update a cosmos variable This should be a string containing the name of the variable to update, this can include .'s for tables, Ex: "Something.Value" When type is MULTI, this specifies the bool variable comvarmulti - The same as comvar, but used to specify the number variable when type is MULTI, only used for MULTI type This is required if you want to update a Khaos variable: uisec - The option set ID that the uivar is found in This is required is you are using a MCOM_CHOICET type: choices - The list of choices ]]-- MCom.addSlashSubCom = function (basecommand, subcommand, comfunc, comhelp, comtype, uisec, uivar, comvar, comvarmulti, commin, commax, commul, cominmul, hasbool, choices, multichoice, hasopacity) --We need at bare minimum commandid, subcommand, and comfunc if (basecommand and subcommand and comfunc) then --If we don't have a chat com list, then we shouldn't do anything if (MCom.SlashComs) then --Make sure basecommand is a table if (type(basecommand) ~= "table") then basecommand = {basecommand}; end --get the ID of the super command, if it is in the list local commandid = MCom.getComID(basecommand); --no commandid means no nothing if (commandid) then --If this super command doesn't have a list of sub commands yet, then make one if (not MCom.SlashComs[commandid].commands) then MCom.SlashComs[commandid].commands = {}; end --If the sub command isn't a table turn it to one if (type(subcommand) ~= "table") then subcommand = {subcommand}; end --Try and find the subcommand in the list local monkey, subcommandid = MCom.getComID(commandid, subcommand); --Make sure this sub command doesn't already exist if (not subcommandid) then --Make the sub command table.insert(MCom.SlashComs[commandid].commands, {}); subcommandid = getn(MCom.SlashComs[commandid].commands); --Setup the sub commands elements MCom.SlashComs[commandid].commands[subcommandid].command = subcommand; MCom.SlashComs[commandid].commands[subcommandid].comfunc = comfunc; if (comhelp) then MCom.SlashComs[commandid].commands[subcommandid].comhelp = comhelp; end if (comtype) then MCom.SlashComs[commandid].commands[subcommandid].comtype = comtype; elseif (MCom.SlashComs[commandid].commands[subcommandid].comtype == nil) then --Default to simple type MCom.SlashComs[commandid].commands[subcommandid].comtype = MCOM_SIMPLET; end if (uisec) then MCom.SlashComs[commandid].commands[subcommandid].uisec = uisec; end if (uivar) then MCom.SlashComs[commandid].commands[subcommandid].uivar = uivar; end if (comvar) then MCom.SlashComs[commandid].commands[subcommandid].comvar = comvar; end if (comvarmulti) then MCom.SlashComs[commandid].commands[subcommandid].comvarmulti = comvarmulti; end if (commin) then MCom.SlashComs[commandid].commands[subcommandid].commin = commin; end if (commax) then MCom.SlashComs[commandid].commands[subcommandid].commax = commax; end if (commul) then MCom.SlashComs[commandid].commands[subcommandid].commul = commul; end if (cominmul) then MCom.SlashComs[commandid].commands[subcommandid].cominmul = cominmul; end if (hasbool) then MCom.SlashComs[commandid].commands[subcommandid].hasbool = hasbool; end if (choices) then MCom.SlashComs[commandid].commands[subcommandid].choices = choices; end if (multichoice) then MCom.SlashComs[commandid].commands[subcommandid].multichoice = multichoice; end if (hasopacity) then MCom.SlashComs[commandid].commands[subcommandid].hasopacity = hasopacity; end end end end end end; --[[ callHook ( (string) hook, (any) a1..a20 ) Calls the origional hooked function. Args: (string) hook - The name of the origional function to call (any) a1..a20 - Any variables that need to be passed to the function Returns: Whatever the passed function returns ]]-- MCom.callHook = function ( hook, a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12,a13,a14,a15,a16,a17,a18,a19,a20 ) --Make sure we have a hook if ( hook ) then --If we can use Sea, then do so if ( Sea ) then if ( Sea.util and Sea.util.Hooks and Sea.util.Hooks[hook] and Sea.util.Hooks[hook].orig ) then return Sea.util.Hooks[hook].orig(a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12,a13,a14,a15,a16,a17,a18,a19,a20); end elseif ( MCom.util.Hooks and MCom.util.Hooks[hook] and MCom.util.Hooks[hook].orig ) then --Use the MCom list if Sea isn't available return MCom.util.Hooks[hook].orig(a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12,a13,a14,a15,a16,a17,a18,a19,a20); end end end; --[[ textFrame ( { reglist } ) Displays the passed text in a multipage scrollable frame. This will not be available if the ItemTextFrame has been opened by the game. Args: reglist - Either a table with the options, or a string or list of strings to display as the text. { Required: (string or table) text - The text you want to display, if this is a table, then each numbered entry will be a page. Optional: (string) title - The title to display at the top of the frame. (string) material - The appearance to use for the frame, can be "Stone", "Parchment", "Marble", "Silver", or "Bronze", defaults to "Stone" font with a black background. (number) textscale - What size to scale the text to, relative to normal (Ex. 1 is normal, 0.5 is half), defaults to 0.85 } Returns: true - The text frame was displayed true - The text frame was not displayed ]]-- MCom.textFrame = function ( reglist ) --We have to have a reglist if (reglist) then --We need to hook some of the functions of the ItemTextFrame so we can have it --behave properly for this usage. local TextFrame = "MComText"; if ( not getglobal(TextFrame.."Frame") ) then TextFrame = "ItemText"; if (not MCom.HasHookedText) then MCom.HasHookedText = true; MCom.util.hook("ItemTextNextPage", "MCom.ItemTextNextPage", "after"); MCom.util.hook("ItemTextPrevPage", "MCom.ItemTextPrevPage", "after"); MCom.util.hook("CloseItemText", "MCom.CloseItemText", "after"); MCom.util.hook("ItemTextFrame_OnEvent", "MCom.ItemTextFrame_OnEvent", "before"); end end --Only display the frame if it isn't already visible if ( (not MCom.NoTextAvail) and ( not getglobal(TextFrame.."Frame"):IsVisible() ) ) then --If this isn't a table, then turn it into one if ( type(reglist) ~= "table" ) then reglist = { text = { reglist }; }; end --If this is a table of strings, then move the strings into text if ( ( not reglist.text ) and reglist[1] ) then reglist.text = {}; for curPage = 1, table.getn(reglist) do reglist.text[curPage] = reglist[curPage]; reglist[curPage] = nil; end end --If text isn't a table then make it one if ( type(reglist.text) ~= "table" ) then reglist.text = { reglist.text }; end --Set the current text and page, to what was passed MCom.CurText = reglist.text; MCom.CurTextPage = 1; --If there was no title passed, set it as an empty string if (not reglist.title) then reglist.title = ""; end --Got through all the pages and add some extra fluff new lines to let the user scroll down further for curPage in MCom.CurText do if (MCom.CurText[curPage]) then MCom.CurText[curPage] = MCom.CurText[curPage].."\n\n\n\n"; end end --Set the title of the frame getglobal(TextFrame.."TitleText"):SetText(reglist.title); --Hide the scrollframe and status bar getglobal(TextFrame.."ScrollFrame"):Hide(); getglobal(TextFrame.."StatusBar"):Hide(); --Setup the look of the frame to the passed look local material = Stone; --Make sure the material is one of the available materials local textColor = {1,1,1}; if ( reglist.material and MATERIAL_TEXT_COLOR_TABLE[reglist.material] ) then material = reglist.material; textColor = MATERIAL_TEXT_COLOR_TABLE[material]; end getglobal(TextFrame.."PageText"):SetTextColor(textColor[1], textColor[2], textColor[3]); if (not material) then if (MComTextFrame) then MComTextTopLeft:Show(); MComTextTop:Show(); MComTextTopRight:Show(); MComTextBotLeft:Show(); MComTextBot:Show(); MComTextBotRight:Show(); MComItemTextTopLeft:Hide(); MComItemTextTopRight:Hide(); MComItemTextBotLeft:Hide(); MComItemTextBotRight:Hide(); getglobal(TextFrame.."MaterialTopLeft"):Hide(); getglobal(TextFrame.."MaterialTopRight"):Hide(); getglobal(TextFrame.."MaterialBotLeft"):Hide(); getglobal(TextFrame.."MaterialBotRight"):Hide(); MComSpellBookIcon:Hide(); MComTextFrame:SetWidth(512); MComTextCloseButton:SetPoint("CENTER", MComTextFrame, "TOPRIGHT", -58, -19); MComTextScrollFrame:SetPoint("TOPRIGHT", MComTextFrame, "TOPRIGHT", -82, -58); MComTextScrollFrame:SetWidth(408); MComTextScrollFrame:SetHeight(406); MComTextScrollFrameMiddle:Show(); MComTextTitleText:SetPoint("CENTER", MComTextFrame, "CENTER", -14, 230); MComTextCurrentPage:SetPoint("TOP", MComTextFrame, "TOP", -14, -34); MComTextNextPageButton:SetPoint("CENTER", MComTextFrame, "TOPRIGHT", -86, -32); MComTextPrevPageButton:SetPoint("CENTER", MComTextFrame, "TOPLEFT", 32, -32); MComTextPageText:SetWidth(400); else getglobal(TextFrame.."MaterialTopLeft"):SetVertexColor(0,0,0); getglobal(TextFrame.."MaterialTopRight"):SetVertexColor(0,0,0); getglobal(TextFrame.."MaterialBotLeft"):SetVertexColor(0,0,0); getglobal(TextFrame.."MaterialBotRight"):SetVertexColor(0,0,0); end else if (MComTextFrame) then MComTextTopLeft:Hide(); MComTextTop:Hide(); MComTextTopRight:Hide(); MComTextBotLeft:Hide(); MComTextBot:Hide(); MComTextBotRight:Hide(); MComItemTextTopLeft:Show(); MComItemTextTopRight:Show(); MComItemTextBotLeft:Show(); MComItemTextBotRight:Show(); MComSpellBookIcon:Show(); MComTextFrame:SetWidth(384); MComTextCloseButton:SetPoint("CENTER", MComTextFrame, "TOPRIGHT", -45, -26); MComTextScrollFrame:SetPoint("TOPRIGHT", MComTextFrame, "TOPRIGHT", -66, -76); MComTextScrollFrame:SetWidth(280); MComTextScrollFrame:SetHeight(355); MComTextScrollFrameMiddle:Hide(); MComTextTitleText:SetPoint("CENTER", MComTextFrame, "CENTER", 6, 230); MComTextCurrentPage:SetPoint("TOP", MComTextFrame, "TOP", 10, -50); MComTextNextPageButton:SetPoint("CENTER", MComTextFrame, "TOPRIGHT", -55, -56); MComTextPrevPageButton:SetPoint("CENTER", MComTextFrame, "TOPLEFT", 90, -56); MComTextPageText:SetWidth(270); end getglobal(TextFrame.."MaterialTopLeft"):SetVertexColor(1,1,1); getglobal(TextFrame.."MaterialTopRight"):SetVertexColor(1,1,1); getglobal(TextFrame.."MaterialBotLeft"):SetVertexColor(1,1,1); getglobal(TextFrame.."MaterialBotRight"):SetVertexColor(1,1,1); end --If the look is parchment, then hide the extra textures if ( material == "Parchment" ) then getglobal(TextFrame.."MaterialTopLeft"):Hide(); getglobal(TextFrame.."MaterialTopRight"):Hide(); getglobal(TextFrame.."MaterialBotLeft"):Hide(); getglobal(TextFrame.."MaterialBotRight"):Hide(); elseif (material) then getglobal(TextFrame.."MaterialTopLeft"):Show(); getglobal(TextFrame.."MaterialTopRight"):Show(); getglobal(TextFrame.."MaterialBotLeft"):Show(); getglobal(TextFrame.."MaterialBotRight"):Show(); getglobal(TextFrame.."MaterialTopLeft"):SetTexture("Interface\\ItemTextFrame\\ItemText-"..material.."-TopLeft"); getglobal(TextFrame.."MaterialTopRight"):SetTexture("Interface\\ItemTextFrame\\ItemText-"..material.."-TopRight"); getglobal(TextFrame.."MaterialBotLeft"):SetTexture("Interface\\ItemTextFrame\\ItemText-"..material.."-BotLeft"); getglobal(TextFrame.."MaterialBotRight"):SetTexture("Interface\\ItemTextFrame\\ItemText-"..material.."-BotRight"); end --Default the scrollbar positions for all pages to the top MCom.CurText.Scroll = {}; for curPage in MCom.CurText do MCom.CurText.Scroll[curPage] = { Value = 0; }; end --Resize the text if (not reglist.textscale) then reglist.textscale = 0.85; if (MComTextFrame) then reglist.textscale = 1; end end MCom.PageWidth = getglobal(TextFrame.."PageText"):GetWidth(); MCom.PageScale = getglobal(TextFrame.."PageText"):GetScale(); getglobal(TextFrame.."PageText"):SetWidth(MCom.PageWidth / reglist.textscale); getglobal(TextFrame.."PageText"):SetScale(MCom.PageScale * reglist.textscale); --Update it with the new text MCom.UpdateTextPage(); --Show the frame getglobal(TextFrame.."Frame"):Show(); return true; end end return false; end -------------------------------------------------- -- -- Private Library Functions -- -------------------------------------------------- --[[ Updates the text in the text frame ]]-- MCom.UpdateTextPage = function () --Only do this if CurText is a table if ( type(MCom.CurText) == "table" ) then local TextFrame = "MComText"; if ( not getglobal(TextFrame.."Frame") ) then TextFrame = "ItemText"; end --If there is more than one page then setup the frame for that if ( table.getn(MCom.CurText) > 1 ) then --Show the text that shows the current page number local pageText = string.format(MCOM_PAGE_TEXT, MCom.CurTextPage, table.getn(MCom.CurText)); if (pageText) then getglobal(TextFrame.."CurrentPage"):SetText(pageText); getglobal(TextFrame.."CurrentPage"):Show(); else getglobal(TextFrame.."CurrentPage"):Hide(); end --If we have gone passed the first page, then enable the previous page button if ( MCom.CurTextPage > 1 ) then getglobal(TextFrame.."PrevPageButton"):Show(); else getglobal(TextFrame.."PrevPageButton"):Hide(); end --If we are not on the last page, then enable the next page button if ( MCom.CurTextPage < table.getn(MCom.CurText) ) then getglobal(TextFrame.."NextPageButton"):Show(); else getglobal(TextFrame.."NextPageButton"):Hide(); end else --There is only one page, so hide the page controls getglobal(TextFrame.."CurrentPage"):Hide(); getglobal(TextFrame.."PrevPageButton"):Hide(); getglobal(TextFrame.."NextPageButton"):Hide(); end --Hide the scroll frame getglobal(TextFrame.."ScrollFrame"):Hide(); --Set the text for this page getglobal(TextFrame.."PageText"):SetText(MCom.CurText[MCom.CurTextPage]); --Update the scrollframe and show if neccisary getglobal(TextFrame.."ScrollFrame"):UpdateScrollChildRect(); getglobal(TextFrame.."ScrollFrame"):Show(); --Reset the scroll bar position to the one stored for this page getglobal(TextFrame.."ScrollFrameScrollBar"):SetValue(MCom.CurText.Scroll[MCom.CurTextPage].Value); else MCom.CurText = nil; end end; --[[ Adds any entry missing in the toTable from the fromTable ]]-- MCom.LoadSafeTable = function (toTable, fromTable) --Make sure we have tables to work with if ( ( type(toTable) == "table" ) and ( type(fromTable) == "table" ) ) then --Go through each entry in the from table for curEntry in fromTable do --If the from entry is a table, then we need to parse each of its entries if ( type( fromTable[curEntry] ) == "table" ) then --If the to table is not already a table, then turn it into one if ( type( toTable[curEntry] ) ~= "table" ) then toTable[curEntry] = {}; end --Load the entries from the current from table entry into the current to table entry MCom.LoadSafeTable( toTable[curEntry], fromTable[curEntry] ); elseif ( toTable[curEntry] == nil ) then --If this entry is not a table, and it is nil, then load from the from table toTable[curEntry] = fromTable[curEntry]; end end end end; --[[ Calls all frames registered for variables loaded notification ]]-- MCom.VariablesLoaded = function () --Only proceed if we have a list of callbacks if ( type(MCom.varsLoadedList) == "table" ) then --Figure out what type of load notice was used local regType = "UIParent"; if (Khaos) then regType = "Khaos"; elseif (Cosmos_RegisterVarsLoaded) then regType = "Cosmos"; end --Call all the callbacks, and pass the type of load notice for i = 1, table.getn(MCom.varsLoadedList) do if ( type(MCom.varsLoadedList[i]) == "function" ) then MCom.varsLoadedList[i](regType); end end end end; --[[ Parses a boolean command ]]-- MCom.ParseBoolCommand = function (value) --If it's a boolean then treat it as one if (value) then value = string.upper(value); if ( string.find(value, string.upper(MCOM_CHAT_ON) ) ) then value = 1; else if ( string.find(value, string.upper(MCOM_CHAT_OFF) ) ) then value = 0; else if ( string.find(value, "1") ) then value = 1; else if ( string.find(value, "0") ) then value = 0; else value = nil; end end end end else --If there was no data passed for this boolean, then send -1 to the functions value = -1; end return value; end; --[[ Parses a number command ]]-- MCom.ParseNumCommand = function (cominmul, value) if (value) then --Get the valid decimal portion only local dump, dump1; dump, dump1, value = string.find(value, "(%d*%.*%d+)"); --If we got a valid decimal, multiply it by cominmul if (value) then if (not cominmul) then cominmul = 1; end value = value * cominmul; end end return value; end; --[[ Parses a choice command ]]-- MCom.ParseChoiceCommand = function (choices, multichoice, value) retVal = nil; name = nil; --Make sure we have the needed data if (choices and value) then --Split the list by spaces value = MCom.util.split(value, " "); --Make sure it is in table format if (type(value) ~= "table") then value = {value}; end --Go through all passed choices, and keep any that are in the available list for choice in value do local curChoice = value[choice]; --If this isn't a viable choice, then see if there is one with any capitalization if (not choices[curChoice]) then for curCheck in choices do if ( string.lower(curChoice) == string.lower( curCheck ) ) then curChoice = curCheck; break; end end end --Make sure we have a good choice if ( choices[curChoice] ) then --If it is multichoice, add it to the list if (multichoice) then if (retVal == nil) then retVal = {}; end table.insert(retVal, choices[curChoice]); --Make a named list of the selected choices if (name) then name = name..", "..curChoice; else name = curChoice; end else --If it's single choice, then return it retVal = choices[curChoice]; name = curChoice; break; end end end end return retVal, name; end; --[[ Parses a color command ]]-- MCom.ParseColorCommand = function (hasopacity, value1, value2, value3, value4) local value = nil; local dump, dump1; --Make sure we have atleast the R the G and the B if (value1 and value2 and value3) then --Get valid decimals for all three values, and divide them to a percent format value = {}; dump, dump1, value1 = string.find(value1, "(%d*%.*%d+)"); if (value1) then value.r = value1/100; end dump, dump1, value2 = string.find(value2, "(%d*%.*%d+)"); if (value1) then value.g = value2/100; end dump, dump1, value3 = string.find(value3, "(%d*%.*%d+)"); if (value3) then value.b = value3/100; end if (hasopacity and value4) then --If we are supposed to have an opacity part then --Get a valid decimal for opacity, and divide it to a percent format dump, dump1, value3 = string.find(value4, "(%d*%.*%d+)"); if (value4) then value.opacity = value4/100; end end --If we didn't have all three values, then return nil if ( not (value1 and value2 and value3) ) then value = nil; end --If we are supposed to have opacity, and it wasn't passed, then return nil if (hasopacity and (not value4) ) then value = nil; end end return value; end; --[[ The slash command handler used by MCom slash commands ]]-- MCom.SlashCommandHandler = function (commandid, msg) --Only works if we have some registered slash commands if (MCom.SlashComs and MCom.SlashComs[commandid]) then --Get a shorthand for the current command curCommand = MCom.SlashComs[commandid]; --Only proccess the message if there is one if ((msg and (msg ~= "")) or ((curCommand.comtype) and (curCommand.comtype == MCOM_BOOLT))) then local subcommand, value; local isSimple = true; --Set true if the command is a standard, not super, slash command local comType = nil; --Stores the type of command local badCommand = nil; --Set true if the data for the command turns out bad if (not curCommand.commands) then --This is simple so unpack it to the values if (msg) then value = MCom.util.split(msg, " "); end else --This is a super command, so unpack the subcommand and values isSimple = nil; --Get the position of the subcommand, and the rest goes into msg2 local first, last, msg2 = string.find(msg, " (.*)"); --If we got the subcommand position then get that portion to the subcommand if (first) then subcommand = string.sub(msg, 1, first - 1); else --If we didn't find a position then we have only the subcommand subcommand = msg; end --Move the rest of the values into msg msg = msg2; --If we have values in msg, then parse them out if (msg) then value = MCom.util.split(msg, " "); end if (subcommand) then --Try and find an exact match of the subcommand in the list local subcommandid = nil; for curCom in MCom.SlashComs[commandid].commands do if (MCom.SlashComs[commandid].commands[curCom].command) then for curComCom in MCom.SlashComs[commandid].commands[curCom].command do if (MCom.SlashComs[commandid].commands[curCom].command[curComCom] == subcommand) then subcommandid = curCom; break; end end if (subcommandid) then break; end end end if (not subcommandid) then --Try and find a similar match of the subcommand in the list for curCom in MCom.SlashComs[commandid].commands do if (MCom.SlashComs[commandid].commands[curCom].command) then for curComCom in MCom.SlashComs[commandid].commands[curCom].command do if (string.find(MCom.SlashComs[commandid].commands[curCom].command[curComCom], subcommand)) then subcommandid = curCom; break; end end if (subcommandid) then break; end end end end if (not subcommandid) then --We didn't find the sub command, so we've got a bad command badCommand = true; else --We found the sub command so change curCommand to point at it curCommand = curCommand.commands[subcommandid]; end else --No subcommand passed, so thats a bad command badCommand = true; end end --We only want to continue if the command was good if (not badCommand) then --Get the command type if (curCommand.comtype) then comType = curCommand.comtype; end local retVal, retVal2; if ( ( (comType == MCOM_BOOLT) or curCommand.hasbool ) and (value == nil) ) then --If nothing was passed and its a bool command then invert it curCommand.comfunc(-1); elseif ( (comType ~= MCOM_SIMPLET) ) then --If it's not a simply command parse the data if we have data if (value) then --Setup a list of variables to use for checking the passed data local checkVal = value[1]; local checkVal2 = value[2]; local checkVal3 = value[3]; local checkVal4 = value[4]; --This stores the boolean portion of the command, if it has two parts local boolVal = value; --This stores the display name for choice types local name = nil; if ( (comType == MCOM_MULTIT) or (curCommand.hasbool and (comType ~= MCOM_BOOLT)) ) then --Since the first value was the boolean, move the other values down in the list checkVal = value[2]; checkVal2 = value[3]; checkVal3 = value[4]; checkVal4 = value[5]; --Remove the boolean part of the message local dump1, dump2; dump1, dump2, msg = string.find(msg, " (.*)"); end --If it is a multi part, or a boolean, then parse the first value as boolean if ( (comType == MCOM_BOOLT) or (comType == MCOM_MULTIT) or curCommand.hasbool ) then boolVal = MCom.ParseBoolCommand(value[1]); value = boolVal; end --Parse the value, or secondary as the appropriate type if ( (comType == MCOM_NUMT) or (comType == MCOM_MULTIT) ) then value = MCom.ParseNumCommand(curCommand.cominmul, checkVal); elseif (comType == MCOM_STRINGT) then --For string we pass the message so spaces can be included value = msg; elseif (comType == MCOM_CHOICET) then --For choice we pass the message so as many passed choices as are passed can be used on a multichoice value, name = MCom.ParseChoiceCommand(curCommand.choices, curCommand.multichoice, msg); elseif (comType == MCOM_COLORT) then value = MCom.ParseColorCommand(curCommand.hasopacity, checkVal, checkVal2, checkVal3, checkVal4); end if ( (comType == MCOM_MULTIT) or (curCommand.hasbool and (comType ~= MCOM_BOOLT)) ) then --Handle the two part commands if (boolVal or value) then --Call the function retVal, retVal2 = curCommand.comfunc(boolVal, value, name); else --We got bad data badCommand = true; end else --Handle the one part commands if (value) then --Call the function retVal = curCommand.comfunc(value, name); else --We got bad data badCommand = true; end end else badCommand = true; end else --It's a simple type, so just call it and quit curCommand.comfunc(); return; end if (not badCommand) then --If Khaos is around, then we update the variable with it, if possible if (Khaos and (curCommand.comvar or retVal) and curCommand.uivar and curCommand.uisec) then --Make sure the passed set exists if ( KhaosData.configurationSets and (KhaosData.configurationSets[curCommand.uisec]) ) then --get the value of the variable local newVal = MCom.getStringVar(curCommand.comvar); --If a value was returned from the setter function, then use it if (retVal) then newVal = retVal; end if (newVal) then --Get the second part variable if there is one local newValMulti = MCom.getStringVar(curCommand.comvarmulti); --If a value was returned from the setter function from the second part, then use it if (retVal2) then newValMulti = retVal2; end --Default param type is value local param = "value"; --If we have a boolean type, or boolean portion, then update that if ( (comType == MCOM_BOOLT) or (comType == MCOM_MULTIT) or curCommand.hasbool) then --Make sure its in true/false format if (newVal == 1) then newVal = true; else newVal = false; end --Update the boolean variable Khaos.setSetKeyParameter(curCommand.uisec, curCommand.uivar, "checked", newVal); end --If it isn't a boolean type, then update the other types, or secondary variable if ( comType ~= MCOM_BOOLT ) then --If we have a secondary variable, then switch to using it if (newValMulti) then newVal = newValMulti; end --Treat number types as sliders if ( (comType == MCOM_NUMT) or (comType == MCOM_MULTIT) ) then param = "slider"; end --Treat color types as color pickers if (comType == MCOM_COLORT) then param = "color"; end --Update the variable Khaos.setSetKeyParameter(curCommand.uisec, curCommand.uivar, param, newVal); end end end else if(CosmosMaster_Init and (curCommand.comvar or retVal) and curCommand.uivar) then --get the value of the variable local newVal = MCom.getStringVar(curCommand.comvar); if (retVal) then newVal = retVal; end if (newVal) then local newValMulti = MCom.getStringVar(curCommand.comvarmulti); if (retVal2) then newValMulti = retVal2; end if (((comType ~= MCOM_MULTIT) and (not ((comType ~= MCOM_BOOLT) and curCommand.hasbool))) or (((comType == MCOM_MULTIT) or ((comType ~= MCOM_BOOLT) and curCommand.hasbool)) and newValMulti)) then --if its a boolean, then set the checkbox if ((comType == MCOM_BOOLT) or (comType == MCOM_MULTIT)) then Cosmos_UpdateValue(curCommand.uivar, CSM_CHECKONOFF, newVal); end --if its a number, then set the slider if ((comType == MCOM_NUMT) or (comType == MCOM_MULTIT)) then if (comType == MCOM_MULTIT) then newVal = newValMulti; end Cosmos_UpdateValue(curCommand.uivar, CSM_SLIDERVALUE, newVal); end end end end end return; end end elseif ((curCommand.comtype) and (curCommand.comtype == MCOM_SIMPLET)) then --If the command is a standard simple command, then just execute it curCommand.comfunc(); return; end --If we didn't find any valid commands we print out the help local infoText = MCom.PrintSlashCommandInfo(commandid, true); MCom.textFrame( { text = infoText; title = MCOM_HELP_GENERIC_TITLE; } ); end end; --[[ Either prints out, or adds to a string the current chat line ]]-- MCom.PrintSlashCommandLine = function ( asString, chatLine, extraLine ) --If it's supposed to be in a string then add this to the string if ( asString ) then --If it isn't a string yet, then just set it to this line if ( type(asString) ~= "string" ) then asString = chatLine; else --It's already a string so add a newline and then this line if (extraLine) then asString = asString.."\n\n"..chatLine else asString = asString.."\n"..chatLine end end --Return the string return asString; else --Print out the chat line MCom.IO.printc(ChatTypeInfo["SYSTEM"], chatLine); end end --[[ Prints the help for a chat command ]]-- MCom.PrintSlashCommandInfo = function (commandid, asString) if (MCom.SlashComs[commandid]) then local chatLine = ""; --The current line of text to be printed local basecommand = MCom.SlashComs[commandid].basecommand[1]; --Construct a list of the aliases for the command, if any local aliasList = ""; if (getn(MCom.SlashComs[commandid].basecommand) > 1) then for curCom = 2, getn(MCom.SlashComs[commandid].basecommand) do if (aliasList ~= "") then aliasList = aliasList..", "; else aliasList = basecommand..", "; end aliasList = aliasList..MCom.SlashComs[commandid].basecommand[curCom]; end end --Print list of aliases, if there are any if (aliasList ~= "") then chatLine = string.format(MCOM_CHAT_COM_ALIAS, aliasList); asString = MCom.PrintSlashCommandLine(asString, chatLine, true); end local isSimple = true; --Set true if this command does not have sub commands local eSample = nil; --Set to something if a simple command is found local bSample = nil; --Set to something if a bool command is found local nSample = nil; --Set to something if a num command is found local nSampleV = nil; --Set to and example value for a number command local sSample = nil; --Set to something if a string command is found local cSample = nil; --Set to something if a choice command is found local cnSampleV = nil; --Set to and example value for a choice command local cmSample = nil; --Set to something if a multi choice command is found local cmnSampleV = nil; --Set to and example value for a multi choice command local koSample = nil; --Set to something if a color with opacity command is found local bnSample = nil; --Set to something if a bool and num command is found local bnSampleV = nil; --Set to and example value for a bool and number command local bsSample = nil; --Set to something if a bool and string command is found local bcSample = nil; --Set to something if a bool and choice command is found local bcnSampleV = nil; --Set to and example value for a bool and choice command local bcmSample = nil; --Set to something if a bool and multi choice command is found local bcmnSampleV = nil; --Set to and example value for a bool and multi choice command local bkoSample = nil; --Set to something if a bool and color with opacity command is found --If this command has sub commands, then print a list of them if (MCom.SlashComs[commandid].commands) then asString = MCom.PrintSlashCommandLine(asString, MCOM_CHAT_COM_COMMANDS, true); isSimple = nil; --This is not a simple command, lets remember that for curCom = 1, getn(MCom.SlashComs[commandid].commands) do local curComType = MCOM_SIMPLET; --Default our type to simple local curComBool = false; --Default has bool to false local curComChoices = nil; --The choices for a choice type local curComMulti = false; --Default multi choice to false local curComOpacity = false; --Default has opacity to false local curComValue = nil; --The value of the variable associated with the command local curComValueMulti = nil; --The value of the multi variable associated with the command local curComMin = nil; --The minimum a value can be set to local curComMax = nil; --The maximum a value can be set to local curComMul = 1; --The value to multiply numbers by when showing status --If a type is specified look it up if (MCom.SlashComs[commandid].commands[curCom].comtype) then curComType = MCom.SlashComs[commandid].commands[curCom].comtype; end --If a hasbool is specified look it up if (MCom.SlashComs[commandid].commands[curCom].hasbool) then curComBool = true; end --If choices are specified look them up if (MCom.SlashComs[commandid].commands[curCom].choices) then curComChoices = MCom.SlashComs[commandid].commands[curCom].choices; end --If a multichoioce is specified look it up if (MCom.SlashComs[commandid].commands[curCom].multichoice) then curComMulti = true; end --If a hasopacity is specified look it up if (MCom.SlashComs[commandid].commands[curCom].hasopacity) then curComOpacity = MCom.SlashComs[commandid].commands[curCom].hasopacity; end --If a comvar is specified look it up if (MCom.SlashComs[commandid].commands[curCom].comvar ~= nil) then curComValue = MCom.getStringVar(MCom.SlashComs[commandid].commands[curCom].comvar); end --If a comvarmulti is specified look it up if (MCom.SlashComs[commandid].commands[curCom].comvarmulti ~= nil) then curComValueMulti = MCom.getStringVar(MCom.SlashComs[commandid].commands[curCom].comvarmulti); end --If a commin is specified look it up if (MCom.SlashComs[commandid].commands[curCom].commin ~= nil) then curComMin = MCom.SlashComs[commandid].commands[curCom].commin; end --If a commax is specified look it up if (MCom.SlashComs[commandid].commands[curCom].commax ~= nil) then curComMax = MCom.SlashComs[commandid].commands[curCom].commax; end --If a commul is specified look it up if (MCom.SlashComs[commandid].commands[curCom].commul ~= nil) then curComMul = MCom.SlashComs[commandid].commands[curCom].commul; end --Store this command as a sample of whatever type it is if ((not eSample) and (curComType == MCOM_SIMPLET)) then eSample = MCom.SlashComs[commandid].commands[curCom].command[1]; end if ((not bSample) and (curComType == MCOM_BOOLT)) then bSample = MCom.SlashComs[commandid].commands[curCom].command[1]; end if (not curComBool) then if ((not nSample) and (curComType == MCOM_NUMT)) then nSample = MCom.SlashComs[commandid].commands[curCom].command[1]; --Get a valid sample number nSampleV = curComMin; if (not nSampleV) then nSampleV = curComMax; end if (not nSampleV) then nSampleV = MCOM_CHAT_COM_EXAMPLE_O_N; end end if ((not sSample) and (curComType == MCOM_STRINGT)) then sSample = MCom.SlashComs[commandid].commands[curCom].command[1]; end if (not curComMulti) then if ((not cSample) and (curComType == MCOM_CHOICET)) then cSample = MCom.SlashComs[commandid].commands[curCom].command[1]; --Get a valid sample choice for sampleV in curComChoices do cSampleV = sampleV; break; end end else if ((not cmSample) and (curComType == MCOM_CHOICET)) then cmSample = MCom.SlashComs[commandid].commands[curCom].command[1]; --Get a valid sample choice local count = 0; --Construct an example with two valid choices for sampleV in curComChoices do count = count + 1; if (cmSampleV) then cmSampleV = cmSampleV.." "..sampleV; else cmSampleV = sampleV; end if (count > 1) then break; end end end end if (not curComOpacity) then if ((not kSample) and (curComType == MCOM_COLORT)) then kSample = MCom.SlashComs[commandid].commands[curCom].command[1]; end else if ((not koSample) and (curComType == MCOM_COLORT)) then koSample = MCom.SlashComs[commandid].commands[curCom].command[1]; end end else if ((not bnSample) and ((curComType == MCOM_NUMT) or (curComType == MCOM_MULTIT))) then bnSample = MCom.SlashComs[commandid].commands[curCom].command[1]; --Get a valid sample number bnSampleV = curComMin; if (not bnSampleV) then bnSampleV = curComMax; end if (not bnSampleV) then bnSampleV = MCOM_CHAT_COM_EXAMPLE_O_N; end end if ((not bsSample) and (curComType == MCOM_STRINGT)) then bsSample = MCom.SlashComs[commandid].commands[curCom].command[1]; end if (not curComMulti) then if ((not bcSample) and (curComType == MCOM_CHOICET)) then bcSample = MCom.SlashComs[commandid].commands[curCom].command[1]; --Get a valid sample choice for sampleV in curComChoices do bcSampleV = sampleV; break; end end else if ((not bcmSample) and (curComType == MCOM_CHOICET)) then bcmSample = MCom.SlashComs[commandid].commands[curCom].command[1]; --Get a valid sample choice local count = 0; --Construct an example with two valid choices for sampleV in curComChoices do count = count + 1; if (bcmSampleV) then bcmSampleV = bcmSampleV.." "..sampleV; else bcmSampleV = sampleV; end if (count > 1) then break; end end end end if (not curComOpacity) then if ((not bkSample) and (curComType == MCOM_COLORT)) then bkSample = MCom.SlashComs[commandid].commands[curCom].command[1]; end else if ((not bkoSample) and (curComType == MCOM_COLORT)) then bkoSample = MCom.SlashComs[commandid].commands[curCom].command[1]; end end end --If help was specified look it up local curHelp = MCOM_CHAT_COM_NOINFO; if (MCom.SlashComs[commandid].commands[curCom].comhelp) then curHelp = MCom.SlashComs[commandid].commands[curCom].comhelp; end --If we have a choice type, then make a list of the choices, and tack that onto the help if ( curComType == MCOM_CHOICET ) then if (curHelp == MCOM_CHAT_COM_NOINFO) then curHelp = MCOM_CHAT_COM_CLIST; end local curChoices = nil; for curChoice in curComChoices do if (curChoices) then curChoices = curChoices..", "..curChoice; else curChoices = curChoice; end end curHelp = string.format(curHelp, curChoices); end --If we have aliases for this sub command then make a list local comList = MCom.SlashComs[commandid].commands[curCom].command[1]; if (getn(MCom.SlashComs[commandid].commands[curCom].command) > 1) then for curAlias = 2, getn(MCom.SlashComs[commandid].commands[curCom].command) do comList = comList.."/"..MCom.SlashComs[commandid].commands[curCom].command[curAlias]; end end --Prepare the type string local curComTypeString = curComType; if ( curComType == MCOM_MULTIT ) then curComTypeString = MCOM_NUMT; end if ( curComMulti and (curComType == MCOM_CHOICET) ) then curComTypeString = MCOM_CHAT_C_M; end if ( curComOpacity and (curComType == MCOM_COLORT) ) then curComTypeString = MCOM_CHAT_K_O; end if ( curComBool and (not (curComType == MCOM_BOOLT) ) ) then curComTypeString = MCOM_BOOLT..curComTypeString; end --If we have a number type, then display the min and max values if ( ( curComType == MCOM_NUMT ) or ( curComType == MCOM_MULTIT ) ) then local curRangeString = nil; if (curComMin) then curRangeString = string.format(MCOM_CHAT_COM_N_MIN, curComMin * curComMul); end if (curComMax) then if (curRangeString) then curRangeString = curRangeString..", "; else curRangeString = ""; end curRangeString = curRangeString..string.format(MCOM_CHAT_COM_N_MAX, curComMax * curComMul); end if (curRangeString) then curComTypeString = curComTypeString..string.format(MCOM_CHAT_COM_N_RANGE, curRangeString); end end --Prepare the command info local curValString = nil; if ( ( curComType == MCOM_SIMPLET ) or ( curComValue == nil ) ) then chatLine = string.format(MCOM_CHAT_COM_SUBCOMMAND_S, comList, curComTypeString, curHelp); elseif ( curComValue ~= nil ) then --If it is a bool, or has a bool, then get the boolean part if ( curComBool or ( curComType == MCOM_BOOLT ) ) then if ( curComValue == 1 ) then curValString = MCOM_CHAT_ON; else curValString = MCOM_CHAT_OFF; end end --If this doesn't have a boolean part, then handle curcomvalue if (not curComBool) then --Handle number type if ( ( curComType == MCOM_NUMT ) or ( curComType == MCOM_MULTIT ) ) then curValString = ( MCom.math.round( ( curComValue * curComMul ) * 100 ) / 100 ); end --Handle string type if ( curComType == MCOM_STRINGT ) then curValString = curComValue; end --If it's a choice type, then handle the one choice, or a list of choices if (curComType == MCOM_CHOICET) then --If we don't have a table of choices, then just use the values if ( type(curComChoices) ~= "table" ) then --If this can not have multiple choices, then use just the one if (not curComMulti) then curValString = curComValue; elseif ( type(curComValue) == "table" ) then --This is a multi choice selection, so make a list of selected choices curValString = curComValue[1]; if ( curValString ~= nil ) then for curVal = 2, table.getn(curComValue) do if ( curComValue[curVal] ~= nil ) then curValString = curValString..", "..curComValue[curVal]; end end end end else --If we have a table of choices, then make a table indexed by value local curChoiceDex = {}; for curChoice in curComChoices do curChoiceDex[curComChoices[curChoice]] = curChoice; end --If this can not have multiple choices, then use just the one if (not curComMulti) then curValString = curChoiceDex[curComValue]; elseif ( type(curComValue) == "table" ) then --This is a multi choice selection, so make a list of selected choices curValString = curChoiceDex[curComValue[1]]; if ( curValString ~= nil ) then for curVal = 2, table.getn(curComValue) do if ( ( curComValue[curVal] ~= nil ) and ( curChoiceDex[curComValue[curVal]] ~= nil ) ) then curValString = curValString..", "..curChoiceDex[curComValue[curVal]]; end end end end end end --If it's a color type, then handle the color parts if (curComType == MCOM_COLORT) then if ( type(curComValue) == "table" ) then local curColString = ""; if (curComValue.r) then curColString = string.format(MCOM_CHAT_COM_K_R, MCom.math.round(curComValue.r * 100)); end if (curComValue.g) then if ( curColString ~= "" ) then curColString = curColString..", "; end curColString = curColString..string.format(MCOM_CHAT_COM_K_G, MCom.math.round(curComValue.g * 100)); end if (curComValue.b) then if ( curColString ~= "" ) then curColString = curColString..", "; end curColString = curColString..string.format(MCOM_CHAT_COM_K_B, MCom.math.round(curComValue.b * 100)); end if (curComOpacity) then local displayOpacity = 1; if (curComValue.opacity) then displayOpacity = curComValue.opacity; end if ( curColString ~= "" ) then curColString = curColString..", "; end curColString = curColString..string.format(MCOM_CHAT_COM_K_O, MCom.math.round(displayOpacity * 100)); end if ( curColString ~= "" ) then curColString = curColString..", "; end curColString = curColString..string.format(MCOM_CHAT_COM_K_X, MCom.string.colorToString(curComValue)); curValString = curColString; end end elseif ( curComValueMulti ~= nil ) then --If we have a second variable, then prepare the second part of the string if ( curValString == nil ) then curValString = ""; else curValString = curValString..", "; end --Handle number type if ( ( curComType == MCOM_NUMT ) or ( curComType == MCOM_MULTIT ) ) then curValString = curValString..( MCom.math.round( ( curComValueMulti * curComMul ) * 100 ) / 100 ); end --Handle string type if ( curComType == MCOM_STRINGT ) then curValString = curValString..curComValueMulti; end --If it's a choice type, then handle the one choice, or a list of choices if (curComType == MCOM_CHOICET) then --If we don't have a table of choices, then just use the values if ( type(curComChoices) ~= "table" ) then --If this can not have multiple choices, then use just the one if (not curComMulti) then curValString = curValString..curComValueMulti; elseif ( type(curComValueMulti) == "table" ) then --This is a multi choice selection, so make a list of selected choices curValString = curValString..curComValueMulti[1]; if ( curComValueMulti[1] ~= nil ) then for curVal = 2, table.getn(curComValueMulti) do if ( curComValueMulti[curVal] ~= nil ) then curValString = curValString..", "..curComValueMulti[curVal]; end end end end else --If we have a table of choices, then make a table indexed by value local curChoiceDex = {}; for curChoice in curComChoices do curChoiceDex[curComChoices[curChoice]] = curChoice; end --If this can not have multiple choices, then use just the one if (not curComMulti) then curValString = curValString..curChoiceDex[curComValueMulti]; elseif ( type(curComValueMulti) == "table" ) then --This is a multi choice selection, so make a list of selected choices curValString = curValString..curChoiceDex[curComValueMulti[1]]; if ( curChoiceDex[curComValueMulti[1]] ~= nil ) then for curVal = 2, table.getn(curComValueMulti) do if ( ( curComValueMulti[curVal] ~= nil ) and ( curChoiceDex[curComValueMulti[curVal]] ~= nil ) ) then curValString = curValString..", "..curChoiceDex[curComValueMulti[curVal]]; end end end end end end --If it's a color type, then handle the color parts if (curComType == MCOM_COLORT) then if ( type(curComValueMulti) == "table" ) then local curColString = ""; if (curComValueMulti.r) then curColString = string.format(MCOM_CHAT_COM_K_R, MCom.math.round(curComValueMulti.r * 100)); end if (curComValueMulti.g) then if ( curColString ~= "" ) then curColString = curColString.." "; end curColString = curColString..string.format( MCOM_CHAT_COM_K_G, MCom.math.round(curComValueMulti.g * 100)); end if (curComValueMulti.b) then if ( curColString ~= "" ) then curColString = curColString.." "; end curColString = curColString..string.format(MCOM_CHAT_COM_K_B, MCom.math.round(curComValueMulti.b * 100)); end if (curComOpacity) then if (curComValueMulti.opacity) then if ( curColString ~= "" ) then curColString = curColString.." "; end curColString = curColString..string.format(MCOM_CHAT_COM_K_O, MCom.math.round(curComValueMulti.opacity * 100)); end end if ( curColString ~= "" ) then curColString = curColString..", "; end curColString = curColString..string.format(MCOM_CHAT_COM_K_X, MCom.string.colorToString(curComValueMulti)); curValString = curValString..curColString; end end end if ( ( curValString ~= nil ) and ( curValString ~= "" ) and ( curValString ~= ", " ) ) then chatLine = string.format(MCOM_CHAT_COM_SUBCOMMAND, comList, curComTypeString, curValString, curHelp); else chatLine = string.format(MCOM_CHAT_COM_SUBCOMMAND_S, comList, curComTypeString, curHelp); end end --Print out the command info asString = MCom.PrintSlashCommandLine(asString, chatLine, true); end else --This is a simple command, find out what type it is, and set the correct sample if (MCom.SlashComs[commandid].comtype == MCOM_BOOLT) then bSample = true; else if (not MCom.SlashComs[commandid].hasbool) then if (MCom.SlashComs[commandid].comtype == MCOM_NUMT) then nSample = true; --Get a valid sample number nSampleV = MCom.SlashComs[commandid].commin; if (not nSampleV) then nSampleV = MCom.SlashComs[commandid].commax; end if (not nSampleV) then nSampleV = MCOM_CHAT_COM_EXAMPLE_O_N; end elseif (MCom.SlashComs[commandid].comtype == MCOM_STRINGT) then sSample = true; elseif (MCom.SlashComs[commandid].comtype == MCOM_CHOICET) then if (not MCom.SlashComs[commandid].multichoice) then cSample = true; --Get a valid sample choice for sampleV in MCom.SlashComs[commandid].choices do cSampleV = sampleV; break; end else cmSample = true; --Get a valid sample choice local count = 0; --Construct an example with two valid choices for sampleV in MCom.SlashComs[commandid].choices do count = count + 1; if (cmSampleV) then cmSampleV = cmSampleV.." "..sampleV; else cmSampleV = sampleV; end if (count > 1) then break; end end end elseif (MCom.SlashComs[commandid].comtype == MCOM_COLORT) then if (not MCom.SlashComs[commandid].hasopacity) then kSample = true; else okSample = true; end else eSample = true; end else if (MCom.SlashComs[commandid].comtype == MCOM_NUMT) then bnSample = true; elseif (MCom.SlashComs[commandid].comtype == MCOM_MULTIT) then bnSample = true; --Get a valid sample number bnSampleV = MCom.SlashComs[commandid].commin; if (not bnSampleV) then bnSampleV = MCom.SlashComs[commandid].commax; end if (not bnSampleV) then bnSampleV = MCOM_CHAT_COM_EXAMPLE_O_N; end elseif (MCom.SlashComs[commandid].comtype == MCOM_STRINGT) then bsSample = true; elseif (MCom.SlashComs[commandid].comtype == MCOM_CHOICET) then if (not MCom.SlashComs[commandid].multichoice) then bcSample = true; --Get a valid sample choice for sampleV in MCom.SlashComs[commandid].choices do bcSampleV = sampleV; break; end else bcmSample = true; --Get a valid sample choice local count = 0; --Construct an example with two valid choices for sampleV in MCom.SlashComs[commandid].choices do count = count + 1; if (bcmSampleV) then bcmSampleV = bcmSampleV.." "..sampleV; else bcmSampleV = sampleV; end if (count > 1) then break; end end end elseif (MCom.SlashComs[commandid].comtype == MCOM_COLORT) then if (not MCom.SlashComs[commandid].hasopacity) then bkSample = true; else bokSample = true; end else eSample = true; end end end end --Print basic usage info local usageLine = MCOM_CHAT_COM_USAGE; if (bSample or bnSample or bsSample or bcSample or bcmSample or bkSample or bkoSample) then usageLine = usageLine.."\n\n"..MCOM_CHAT_COM_USAGE_B; end if (bnSample) then usageLine = usageLine.."\n\n"..string.format(MCOM_CHAT_COM_USAGE_B_M, MCOM_NUMT, MCOM_CHAT_COM_USAGE_B_N); elseif (bsSample) then usageLine = usageLine.."\n\n"..string.format(MCOM_CHAT_COM_USAGE_B_M, MCOM_STRINGT, MCOM_CHAT_COM_USAGE_B_S); elseif (bcSample or bcmSample) then usageLine = usageLine.."\n\n"..string.format(MCOM_CHAT_COM_USAGE_B_M, MCOM_CHOICET, MCOM_CHAT_COM_USAGE_B_C); elseif (bkSample or bkoSample) then usageLine = usageLine.."\n\n"..string.format(MCOM_CHAT_COM_USAGE_B_M, MCOM_COLORT, MCOM_CHAT_COM_USAGE_B_K); end asString = MCom.PrintSlashCommandLine(asString, usageLine, true); --Print detailed usage info if (isSimple) then --If its simple we print the simple versions of the usage info, but only for the command type if (eSample) then chatLine = string.format(MCOM_CHAT_COM_USAGE_S_E, basecommand); asString = MCom.PrintSlashCommandLine(asString, chatLine, true); end if (bSample) then chatLine = string.format(MCOM_CHAT_COM_USAGE_S_S, basecommand, MCOM_CHAT_COM_B); asString = MCom.PrintSlashCommandLine(asString, chatLine, true); end if (nSample) then chatLine = string.format(MCOM_CHAT_COM_USAGE_S_S, basecommand, MCOM_CHAT_COM_N); asString = MCom.PrintSlashCommandLine(asString, chatLine, true); end if (sSample) then chatLine = string.format(MCOM_CHAT_COM_USAGE_S_S, basecommand, MCOM_CHAT_COM_S); asString = MCom.PrintSlashCommandLine(asString, chatLine, true); end if (cSample) then chatLine = string.format(MCOM_CHAT_COM_USAGE_S_S, basecommand, MCOM_CHAT_COM_C); asString = MCom.PrintSlashCommandLine(asString, chatLine, true); end if (cmSample) then chatLine = string.format(MCOM_CHAT_COM_USAGE_S_S, basecommand, MCOM_CHAT_COM_C_M); asString = MCom.PrintSlashCommandLine(asString, chatLine, true); end if (kSample) then chatLine = string.format(MCOM_CHAT_COM_USAGE_S_S, basecommand, MCOM_CHAT_COM_K); asString = MCom.PrintSlashCommandLine(asString, chatLine, true); end if (koSample) then chatLine = string.format(MCOM_CHAT_COM_USAGE_S_S, basecommand, MCOM_CHAT_COM_K_O); asString = MCom.PrintSlashCommandLine(asString, chatLine, true); end if (bnSample) then chatLine = string.format(MCOM_CHAT_COM_USAGE_S_M, basecommand, MCOM_CHAT_COM_N); asString = MCom.PrintSlashCommandLine(asString, chatLine, true); end if (bsSample) then chatLine = string.format(MCOM_CHAT_COM_USAGE_S_M, basecommand, MCOM_CHAT_COM_S); asString = MCom.PrintSlashCommandLine(asString, chatLine, true); end if (bcSample) then chatLine = string.format(MCOM_CHAT_COM_USAGE_S_M, basecommand, MCOM_CHAT_COM_C); asString = MCom.PrintSlashCommandLine(asString, chatLine, true); end if (bcmSample) then chatLine = string.format(MCOM_CHAT_COM_USAGE_S_M, basecommand, MCOM_CHAT_COM_C_M); asString = MCom.PrintSlashCommandLine(asString, chatLine, true); end if (bkSample) then chatLine = string.format(MCOM_CHAT_COM_USAGE_S_M, basecommand, MCOM_CHAT_COM_K); asString = MCom.PrintSlashCommandLine(asString, chatLine, true); end if (bkoSample) then chatLine = string.format(MCOM_CHAT_COM_USAGE_S_M, basecommand, MCOM_CHAT_COM_K_O); asString = MCom.PrintSlashCommandLine(asString, chatLine, true); end else --If its not simple then we print usage info for any type of subcommand used if (eSample) then chatLine = string.format(MCOM_CHAT_COM_USAGE_E, basecommand); asString = MCom.PrintSlashCommandLine(asString, chatLine, true); end if (bSample) then chatLine = string.format(MCOM_CHAT_COM_USAGE_S, MCOM_BOOLT, basecommand, MCOM_CHAT_COM_B); asString = MCom.PrintSlashCommandLine(asString, chatLine, true); end if (nSample) then chatLine = string.format(MCOM_CHAT_COM_USAGE_S, MCOM_NUMT, basecommand, MCOM_CHAT_COM_N); asString = MCom.PrintSlashCommandLine(asString, chatLine, true); end if (sSample) then chatLine = string.format(MCOM_CHAT_COM_USAGE_S, MCOM_STRINGT, basecommand, MCOM_CHAT_COM_S); asString = MCom.PrintSlashCommandLine(asString, chatLine, true); end if (cSample) then chatLine = string.format(MCOM_CHAT_COM_USAGE_S, MCOM_CHOICET, basecommand, MCOM_CHAT_COM_C); asString = MCom.PrintSlashCommandLine(asString, chatLine, true); end if (cmSample) then chatLine = string.format(MCOM_CHAT_COM_USAGE_S, MCOM_CHAT_C_M, basecommand, MCOM_CHAT_COM_C_M); asString = MCom.PrintSlashCommandLine(asString, chatLine, true); end if (kSample) then chatLine = string.format(MCOM_CHAT_COM_USAGE_S, MCOM_COLORT, basecommand, MCOM_CHAT_COM_K); asString = MCom.PrintSlashCommandLine(asString, chatLine, true); end if (koSample) then chatLine = string.format(MCOM_CHAT_COM_USAGE_S, MCOM_CHAT_K_O, basecommand, MCOM_CHAT_COM_K_O); asString = MCom.PrintSlashCommandLine(asString, chatLine, true); end if (bnSample) then chatLine = string.format(MCOM_CHAT_COM_USAGE_M, MCOM_BOOLT..MCOM_NUMT, basecommand, MCOM_CHAT_COM_N); asString = MCom.PrintSlashCommandLine(asString, chatLine, true); end if (bsSample) then chatLine = string.format(MCOM_CHAT_COM_USAGE_M, MCOM_BOOLT..MCOM_STRINGT, basecommand, MCOM_CHAT_COM_S); asString = MCom.PrintSlashCommandLine(asString, chatLine, true); end if (bcSample) then chatLine = string.format(MCOM_CHAT_COM_USAGE_M, MCOM_BOOLT..MCOM_CHOICET, basecommand, MCOM_CHAT_COM_C); asString = MCom.PrintSlashCommandLine(asString, chatLine, true); end if (bcmSample) then chatLine = string.format(MCOM_CHAT_COM_USAGE_M, MCOM_BOOLT..MCOM_CHAT_C_M, basecommand, MCOM_CHAT_COM_C_M); asString = MCom.PrintSlashCommandLine(asString, chatLine, true); end if (bkSample) then chatLine = string.format(MCOM_CHAT_COM_USAGE_M, MCOM_BOOLT..MCOM_COLORT, basecommand, MCOM_CHAT_COM_K); asString = MCom.PrintSlashCommandLine(asString, chatLine, true); end if (bkoSample) then chatLine = string.format(MCOM_CHAT_COM_USAGE_M, MCOM_BOOLT..MCOM_CHAT_K_O, basecommand, MCOM_CHAT_COM_K_M); asString = MCom.PrintSlashCommandLine(asString, chatLine, true); end end --Print extra help for the command if (MCom.SlashComs[commandid].extrahelp) then if (type(MCom.SlashComs[commandid].extrahelp) ~= "table") then MCom.SlashComs[commandid].extrahelp = { MCom.SlashComs[commandid].extrahelp }; end --Add an extra line before the extra help if (asString) then asString = asString.."\n"; end for curHelp in MCom.SlashComs[commandid].extrahelp do asString = MCom.PrintSlashCommandLine(asString, MCom.SlashComs[commandid].extrahelp[curHelp]); end end --Print example usage asString = MCom.PrintSlashCommandLine(asString, MCOM_CHAT_COM_EXAMPLE, true); if (isSimple) then --If it's simple we print an example for the appropriate type if (eSample) then chatLine = string.format(MCOM_CHAT_COM_EXAMPLE_S_E, basecommand); asString = MCom.PrintSlashCommandLine(asString, chatLine); end if (bSample) then chatLine = string.format(MCOM_CHAT_COM_EXAMPLE_S_S, basecommand, MCOM_CHAT_COM_EXAMPLE_O_B); asString = MCom.PrintSlashCommandLine(asString, chatLine); end if (nSample) then chatLine = string.format(MCOM_CHAT_COM_EXAMPLE_S_S, basecommand, nSampleV); asString = MCom.PrintSlashCommandLine(asString, chatLine); end if (sSample) then chatLine = string.format(MCOM_CHAT_COM_EXAMPLE_S_S, basecommand, MCOM_CHAT_COM_EXAMPLE_O_S); asString = MCom.PrintSlashCommandLine(asString, chatLine); end if (cSample) then chatLine = string.format(MCOM_CHAT_COM_EXAMPLE_S_S, basecommand, cSampleV); asString = MCom.PrintSlashCommandLine(asString, chatLine); end if (cmSample) then chatLine = string.format(MCOM_CHAT_COM_EXAMPLE_S_S, basecommand, cmSampleV); asString = MCom.PrintSlashCommandLine(asString, chatLine); end if (kSample) then chatLine = string.format(MCOM_CHAT_COM_EXAMPLE_S_S, basecommand, MCOM_CHAT_COM_EXAMPLE_O_K); asString = MCom.PrintSlashCommandLine(asString, chatLine); end if (koSample) then chatLine = string.format(MCOM_CHAT_COM_EXAMPLE_S_S, basecommand, MCOM_CHAT_COM_EXAMPLE_O_K_O); asString = MCom.PrintSlashCommandLine(asString, chatLine); end if (bnSample) then chatLine = string.format(MCOM_CHAT_COM_EXAMPLE_S_M, basecommand, bnSampleV); asString = MCom.PrintSlashCommandLine(asString, chatLine); end if (bsSample) then chatLine = string.format(MCOM_CHAT_COM_EXAMPLE_S_M, basecommand, MCOM_CHAT_COM_EXAMPLE_O_S); asString = MCom.PrintSlashCommandLine(asString, chatLine); end if (bcSample) then chatLine = string.format(MCOM_CHAT_COM_EXAMPLE_S_M, basecommand, bcSampleV); asString = MCom.PrintSlashCommandLine(asString, chatLine); end if (bcmSample) then chatLine = string.format(MCOM_CHAT_COM_EXAMPLE_S_M, basecommand, bcmSampleV); asString = MCom.PrintSlashCommandLine(asString, chatLine); end if (bkSample) then chatLine = string.format(MCOM_CHAT_COM_EXAMPLE_S_M, basecommand, MCOM_CHAT_COM_EXAMPLE_O_K); asString = MCom.PrintSlashCommandLine(asString, chatLine); end if (bkoSample) then chatLine = string.format(MCOM_CHAT_COM_EXAMPLE_S_M, basecommand, MCOM_CHAT_COM_EXAMPLE_O_K_O); asString = MCom.PrintSlashCommandLine(asString, chatLine); end else --If it's not simple we print an example for each type used if (eSample) then chatLine = string.format(MCOM_CHAT_COM_EXAMPLE_E, basecommand, eSample); asString = MCom.PrintSlashCommandLine(asString, chatLine); end if (bSample) then chatLine = string.format(MCOM_CHAT_COM_EXAMPLE_S, basecommand, bSample, MCOM_CHAT_COM_EXAMPLE_O_B); asString = MCom.PrintSlashCommandLine(asString, chatLine); end if (nSample) then chatLine = string.format(MCOM_CHAT_COM_EXAMPLE_S, basecommand, nSample, nSampleV); asString = MCom.PrintSlashCommandLine(asString, chatLine); end if (sSample) then chatLine = string.format(MCOM_CHAT_COM_EXAMPLE_S, basecommand, sSample, MCOM_CHAT_COM_EXAMPLE_O_S); asString = MCom.PrintSlashCommandLine(asString, chatLine); end if (cSample) then chatLine = string.format(MCOM_CHAT_COM_EXAMPLE_S, basecommand, cSample, cSampleV); asString = MCom.PrintSlashCommandLine(asString, chatLine); end if (cmSample) then chatLine = string.format(MCOM_CHAT_COM_EXAMPLE_S, basecommand, cmSample, cmSampleV); asString = MCom.PrintSlashCommandLine(asString, chatLine); end if (kSample) then chatLine = string.format(MCOM_CHAT_COM_EXAMPLE_S, basecommand, kSample, MCOM_CHAT_COM_EXAMPLE_O_K); asString = MCom.PrintSlashCommandLine(asString, chatLine); end if (koSample) then chatLine = string.format(MCOM_CHAT_COM_EXAMPLE_S, basecommand, koSample, MCOM_CHAT_COM_EXAMPLE_O_K_O); asString = MCom.PrintSlashCommandLine(asString, chatLine); end if (bnSample) then chatLine = string.format(MCOM_CHAT_COM_EXAMPLE_M, basecommand, bnSample, bnSampleV); asString = MCom.PrintSlashCommandLine(asString, chatLine); end if (bsSample) then chatLine = string.format(MCOM_CHAT_COM_EXAMPLE_M, basecommand, bsSample, MCOM_CHAT_COM_EXAMPLE_O_S); asString = MCom.PrintSlashCommandLine(asString, chatLine); end if (bcSample) then chatLine = string.format(MCOM_CHAT_COM_EXAMPLE_M, basecommand, bcSample, bcSampleV); asString = MCom.PrintSlashCommandLine(asString, chatLine); end if (bcmSample) then chatLine = string.format(MCOM_CHAT_COM_EXAMPLE_M, basecommand, bcmSample, bcmSampleV); asString = MCom.PrintSlashCommandLine(asString, chatLine); end if (bkSample) then chatLine = string.format(MCOM_CHAT_COM_EXAMPLE_M, basecommand, bkSample, MCOM_CHAT_COM_EXAMPLE_O_K); asString = MCom.PrintSlashCommandLine(asString, chatLine); end if (bkoSample) then chatLine = string.format(MCOM_CHAT_COM_EXAMPLE_M, basecommand, bkoSample, MCOM_CHAT_COM_EXAMPLE_O_K_O); asString = MCom.PrintSlashCommandLine(asString, chatLine); end end end --Return the string return asString; end; --[[ The Cosmos callback function handler ]]-- MCom.SetFromUI = function (option, checked, value) if (not MCom.UIFuncList) then MCom.UIFuncList = {}; end --Get the info for this function local funcInfo = MCom.UIFuncList[option]; if (funcInfo) then local func = funcInfo.func; local funcType = funcInfo.uitype; --Call the appropriate kind of function for this kind of element if (func and funcType) then if (funcType == "CHECKBOX") then func(checked); elseif (funcType == "SLIDER") then func(value); elseif (funcType == "BOTH") then func(checked, value); else func(); end end end end; --[[ The Khaos callback function handler ]]-- MCom.SetFromKUI = function (option, state, keypressed, choices) if (not MCom.UIFuncList) then MCom.UIFuncList = {}; end --Get the info for this function local funcInfo = MCom.UIFuncList[option]; if (funcInfo) then local func = funcInfo.func; local funcType = funcInfo.uitype; --split into hasbool and not hasbool sections. --Call the appropriate kind of function for this kind of element if (func and funcType) then local checked = nil; if (funcInfo.hasbool) then checked = 0; if (state and state.checked) then checked = 1; end end local value = nil; local name = nil; --If it's a bool then call it as such if ((funcType == K_TEXT) and funcInfo.hasbool) then func(checked); else --Handle the value from the right variable for this type if (funcType == K_SLIDER) then value = state.slider; elseif ( funcType == K_EDITBOX ) then value = state.value; elseif (funcType == K_PULLDOWN) then value = state.value; --If we don't have a table of choices, then just use the values if ( type(choices) ~= "table" ) then --If this can not have multiple choices, then use just the one if ( type(value) ~= "table" ) then name = value; else --This is a multi choice selection, so make a list of selected choices name = value[1]; if ( name ~= nil ) then for curVal = 2, table.getn(value) do if ( value[curVal] ~= nil ) then name = name..", "..value[curVal]; end end end end else --If we have a table of choices, then make a table indexed by value local curChoiceDex = {}; for curChoice in choices do curChoiceDex[choices[curChoice]] = curChoice; end --If this can not have multiple choices, then use just the one if ( type(value) ~= "table" ) then name = curChoiceDex[value]; else --This is a multi choice selection, so make a list of selected choices name = curChoiceDex[value[1]]; if ( name ~= nil ) then for curVal = 2, table.getn(value) do if ( ( value[curVal] ~= nil ) and ( curChoiceDex[value[curVal]] ~= nil ) ) then name = name..", "..curChoiceDex[value[curVal]]; end end end end end elseif (funcType == K_COLORPICKER) then value = state.color; end --If it's a button, then just call it if (funcType == K_BUTTON) then func(); else --If it has a bool call it with the bool, and the value, otherwise, just the value if (funcInfo.hasbool) then func(checked, value, name); else func(value, name); end end end end end end; -------------------------------------------------- -- -- Hooked Functions -- -------------------------------------------------- MCom.ItemTextPrevPage = function () --Switch to the previous page if there is one if ( type(MCom.CurText) == "table" ) then local TextFrame = "MComText"; if ( not getglobal(TextFrame.."Frame") ) then TextFrame = "ItemText"; end if ( MCom.CurTextPage > 1 ) then --Store the current position and range of the scrollbar so we can restore this, the next time the page is visited MCom.CurText.Scroll[MCom.CurTextPage].Value = getglobal(TextFrame.."ScrollFrameScrollBar"):GetValue(); MCom.CurText.Scroll[MCom.CurTextPage].Range = getglobal(TextFrame.."ScrollFrame"):GetVerticalScrollRange(); --Flip the page MCom.CurTextPage = MCom.CurTextPage - 1; --If a scroll range was recorded for this page, then adjust to those values if (MCom.CurText.Scroll[MCom.CurTextPage].Range) then getglobal(TextFrame.."ScrollFrameScrollBar"):SetMinMaxValues(0, MCom.CurText.Scroll[MCom.CurTextPage].Range); end --Update the page MCom.UpdateTextPage(); end else MCom.CurText = nil; end end; MCom.ItemTextNextPage = function () --Switch to the previous page if there is one if ( type(MCom.CurText) == "table" ) then local TextFrame = "MComText"; if ( not getglobal(TextFrame.."Frame") ) then TextFrame = "ItemText"; end if ( MCom.CurTextPage < table.getn(MCom.CurText) ) then --Store the current position and range of the scrollbar so we can restore this, the next time the page is visited MCom.CurText.Scroll[MCom.CurTextPage].Value = getglobal(TextFrame.."ScrollFrameScrollBar"):GetValue(); MCom.CurText.Scroll[MCom.CurTextPage].Range = getglobal(TextFrame.."ScrollFrame"):GetVerticalScrollRange(); --Flip the page MCom.CurTextPage = MCom.CurTextPage + 1; --If a scroll range was recorded for this page, then adjust to those values if (MCom.CurText.Scroll[MCom.CurTextPage].Range) then getglobal(TextFrame.."ScrollFrameScrollBar"):SetMinMaxValues(0, MCom.CurText.Scroll[MCom.CurTextPage].Range); end --Update the page MCom.UpdateTextPage(); end else MCom.CurText = nil; end end; --When the item text is closed, let's reset it to normal, and confirm that MCom --can now make use of it MCom.CloseItemText = function () local TextFrame = "MComText"; if ( not getglobal(TextFrame.."Frame") ) then TextFrame = "ItemText"; end MCom.CurText = nil; MCom.NoTextAvail = nil; --Remove the vertex color getglobal(TextFrame.."MaterialTopLeft"):SetVertexColor(1,1,1); getglobal(TextFrame.."MaterialTopRight"):SetVertexColor(1,1,1); getglobal(TextFrame.."MaterialBotLeft"):SetVertexColor(1,1,1); getglobal(TextFrame.."MaterialBotRight"):SetVertexColor(1,1,1); --Resize the text to normal if (MCom.PageWidth and MCom.PageScale) then getglobal(TextFrame.."PageText"):SetWidth(MCom.PageWidth); getglobal(TextFrame.."PageText"):SetScale(MCom.PageScale); end end; MCom.ItemTextFrame_OnEvent = function (event) --If the game is doing something with the text frame, then clear the MCom text --and set the frame as unavailable for MCom to use if ( ( event == "ITEM_TEXT_BEGIN" ) or ( event == "ITEM_TEXT_TRANSLATION" ) or ( event == "ITEM_TEXT_READY" ) ) then local TextFrame = "MComText"; if ( not getglobal(TextFrame.."Frame") ) then TextFrame = "ItemText"; MCom.CurText = nil; MCom.NoTextAvail = true; --Remove the vertex color getglobal(TextFrame.."MaterialTopLeft"):SetVertexColor(1,1,1); getglobal(TextFrame.."MaterialTopRight"):SetVertexColor(1,1,1); getglobal(TextFrame.."MaterialBotLeft"):SetVertexColor(1,1,1); getglobal(TextFrame.."MaterialBotRight"):SetVertexColor(1,1,1); --Resize the text to normal if (MCom.PageWidth and MCom.PageScale) then getglobal(TextFrame.."PageText"):SetWidth(MCom.PageWidth); getglobal(TextFrame.."PageText"):SetScale(MCom.PageScale); end end end end; MCom.myAddOnsFrame_OnEvent = function () --If this is variables loaded, then load in the MCom registered addons if (event == "VARIABLES_LOADED") then MCom.MyAddOnsLoaded = true; --If this vesion of myAddons supports the registration method, then use it if(myAddOnsFrame_Register) then for curAddon in MCom.MyAddOnsList do local help = nil; --If we have a table of help, then get a copy of it, and add the slash command help if available if ( type(MCom.MyAddOnsList[curAddon].help) == "table" ) then help = MCom.table.copy(MCom.MyAddOnsList[curAddon].help); if (MCom.MyAddOnsList[curAddon].supercom) then --Add the slash command info on to it help[table.getn(help) + 1] = MCom.PrintSlashCommandInfo(MCom.getComID(MCom.MyAddOnsList[curAddon].supercom), true); end elseif ( ( MCom.MyAddOnsList[curAddon].help == "boolean" ) and MCom.MyAddOnsList[curAddon].help and MCom.MyAddOnsList[curAddon].supercom ) then --If help is a boolean and we have slash command info, then generate the help from the slash command info help = MCom.PrintSlashCommandInfo(MCom.getComID(MCom.MyAddOnsList[curAddon].supercom), true); end -- Register the addon in myAddOns myAddOnsFrame_Register(MCom.MyAddOnsList[curAddon].details, help); end else --Use the old method of adding an addon to the list for curAddon in MCom.MyAddOnsList do myAddOnsList[curAddon] = MCom.MyAddOnsList[curAddon].details; end end end end; MCom.UIParent_OnEvent = function () if ( event == "VARIABLES_LOADED" ) then if (not MCom.didVarsLoaded) then MCom.didVarsLoaded = true; --If we have anything that needs to be safe loaded, then load it now if ( type(MCom.safeLoads) == "table" ) then local curConfig; if ( type(MCom.safeLoads.varsLoaded) == "table" ) then --Load any safe load that has changed for curLoad in MCom.safeLoads.varsLoaded do --Get the variable for the current safe load curConfig = MCom.getStringVar(curLoad); --Load the stored data into the empty entries of the current config if the table has been replaced if ( ( type(curConfig) == "table" ) and ( curConfig ~= MCom.safeLoads.varsLoaded[curLoad] ) ) then MCom.LoadSafeTable( curConfig, MCom.safeLoads.varsLoaded[curLoad] ); end end end --Deal with any old style entries for curLoad in MCom.safeLoads do if ( ( curLoad ~= "addonLoaded" ) and ( curLoad ~= "varsLoaded" ) ) then --Get the variable for the current safe load curConfig = MCom.getStringVar(curLoad); --Load the stored data into the empty entries of the current config if ( ( type(curConfig) == "table" ) ) then MCom.LoadSafeTable( curConfig, MCom.safeLoads[curLoad] ); end end end end --Clear the safe loads table MCom.safeLoads = nil; --If we are using this as the vars loaded event, then call the vars loaded callbacks if (MCom.UseVarsLoadedEvent) then MCom.VariablesLoaded(); end end end if ( event == "ADDON_LOADED" ) then --If we have anything that needs to be safe loaded, then load it now if ( type(MCom.safeLoads) == "table" ) then local curConfig; if ( type(MCom.safeLoads.addonLoaded) == "table" ) then --Load any safe load that has changed for curLoad in MCom.safeLoads.addonLoaded do --Get the variable for the current safe load curConfig = MCom.getStringVar(curLoad); --Load the stored data into the empty entries of the current config if the table has been replaced if ( ( type(curConfig) == "table" ) and ( curConfig ~= MCom.safeLoads.addonLoaded[curLoad] ) ) then MCom.LoadSafeTable( curConfig, MCom.safeLoads.addonLoaded[curLoad] ); --Move the entry to the variables loaded table to be checked for loading once more MCom.safeLoads.varsLoaded[curLoad] = MCom.safeLoads.addonLoaded[curLoad]; MCom.safeLoads.addonLoaded[curLoad] = nil; end end end --Deal with any old style entries for curLoad in MCom.safeLoads do if ( ( curLoad ~= "addonLoaded" ) and ( curLoad ~= "varsLoaded" ) ) then --Get the variable for the current safe load curConfig = MCom.getStringVar(curLoad); --Load the stored data into the empty entries of the current config if ( ( type(curConfig) == "table" ) ) then MCom.LoadSafeTable( curConfig, MCom.safeLoads[curLoad] ); end end end end end end -------------------------------------------------- -- -- Sea Wrapper Functions -- -------------------------------------------------- --Wrappers used to ensure MCom functions without Sea, for those who just --absolutely refuse to use Sea MCom.math = {}; MCom.math.round = function (x) if (Sea and Sea.math and Sea.math.round) then --Call origional return Sea.math.round(x); else --Same as origional if(x - math.floor(x) > 0.5) then x = x + 0.5; end return math.floor(x); end end; MCom.math.hexFromInt = function (intval, minlength) if (Sea and Sea.math and Sea.math.hexFromInt) then --Call origional return Sea.math.hexFromInt(intval, minlength); else --Same as origional if ( minlength == nil ) then minlength = "2"; end return string.format("%"..minlength.."x", intval ); end end; MCom.table = {}; MCom.table.copy = function ( t, recursionList ) if (Sea and Sea.table and Sea.table.copy) then --Call origional return Sea.table.copy(t, recursionList); else --Same as origional if ( not recursionList ) then recursionList = {} end; if ( type(t) ~= "table" ) then return t; end local newTable = {}; if ( recursionList[t] ) then return recursionList[t]; else recursionList[t] = newTable; for k,v in t do --If it's a table we want to recurse. But the second half of this if checks to see if it --is a reference to a frame, which looks like a table, and does a normal copy in such a --case if ( ( type(v) == "table" ) and not ( v[0] and ( type(v[0]) == "userdata" ) ) ) then newTable[k] = MCom.table.copy(v, recursionList); else newTable[k] = v; end end return newTable; end end end; MCom.table.push = function ( table, val ) if (Sea and Sea.table and Sea.table.copy) then --Call origional return Sea.table.push(table, val); else --Same as origional if(not table or not table.n) then return nil; end table.n = table.n+1; table[table.n] = val; end end; MCom.IO = {}; MCom.IO.printc = function ( color, pString ) if (Sea and Sea.IO and Sea.IO.printc) then --Call origional Sea.IO.printc(color, pString); else --Simple colored print, not as capable as Sea's functions if ( color == nil ) then color = NORMAL_FONT_COLOR; end ChatFrame1:AddMessage(pString, color.r, color.g, color.b); end end; MCom.util = {}; MCom.util.split = function ( text, separator, oldTable, noPurge ) if (Sea and Sea.util and Sea.util.split and Sea.version) then --Call origional return Sea.util.split( text, separator, oldTable, noPurge ); else --Using Legorols version local value; local init, mstart, mend = 1; local t, oldn = oldTable, 0; if ( not t ) then t = {}; else oldn = table.getn(t); table.setn(t, 0); end -- Using string.find instead of string.gfind to avoid garbage generation repeat mstart, mend, value = string.find(text, "([^"..separator.."]+)", init); if ( value ) then table.insert(t, value) init = mend + 1; end until not value; if ( not noPurge ) then for i = table.getn(t)+1, oldn do t[i] = nil; end end return t; end end; MCom.util.hook = function (orig, new, hooktype, scriptElementName) if (Sea and Sea.util and Sea.util.hook and Sea.version and ( Sea.version >= 1.05 ) ) then Sea.util.hook(orig, new, hooktype, scriptElementName); else --Modified hook function from origional, uses Sea's hook list if available if (not MCom.util.Hooks) then MCom.util.Hooks = {}; end local hookList = MCom.util.Hooks; --If Sea is around, then use it's list if (Sea and Sea.util and Sea.util.hook) then if(not Sea.util.Hooks) then Sea.util.Hooks = {}; end hookList = Sea.util.Hooks; end local origCopy = orig; if (scriptElementName) then orig = orig.."."..scriptElementName; end if(not hooktype) then hooktype = "before"; end if(not hookList[orig]) then hookList[orig] = {}; hookList[orig].before = {}; hookList[orig].before.n = 0; hookList[orig].after = {}; hookList[orig].after.n = 0; hookList[orig].hide = {}; hookList[orig].hide.n = 0; hookList[orig].replace = {}; hookList[orig].replace.n = 0; hookList[orig].orig = MCom.getStringVar(orig); -- Set up the hook the first time if (scriptElementName) then hookList[orig].orig = MCom.getStringVar(origCopy):GetScript(scriptElementName); MCom.getStringVar(origCopy):SetScript(scriptElementName, function(a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12,a13,a14,a15,a16,a17,a18,a19,a20) return MCom.util.hookHandler(orig,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12,a13,a14,a15,a16,a17,a18,a19,a20); end); else hookList[orig].orig = MCom.getStringVar(orig); MCom.setStringVar(orig,function(a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12,a13,a14,a15,a16,a17,a18,a19,a20) return MCom.util.hookHandler(orig,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12,a13,a14,a15,a16,a17,a18,a19,a20); end); end else for key,value in hookList[orig][hooktype] do -- NOTE THIS SHOULD BE VALUE! VALUE! *NOT* KEY! if(value == MCom.getStringVar(new)) then return; end end end -- intentionally will error if bad type is passed MCom.table.push(hookList[orig][hooktype], MCom.getStringVar(new)); end end; MCom.util.unhook = function (orig, new, hooktype, scriptElementName) if (Sea and Sea.util and Sea.util.unhook and Sea.version and ( Sea.version >= 1.05 ) ) then Sea.util.unhook(orig, new, hooktype, scriptElementName); else --Modified unhook function from origional, uses Sea's hook list if available if (not MCom.util.Hooks) then MCom.util.Hooks = {}; end local hookList = MCom.util.Hooks; --If Sea is around, then use it's list if (Sea and Sea.util and Sea.util.hook) then if(not Sea.util.Hooks) then Sea.util.Hooks = {}; end hookList = Sea.util.Hooks; end if(not hooktype) then hooktype = "before"; end local l,g; local origCopy = orig; if (scriptElementName) then orig = orig.."."..scriptElementName; end if(not hookList[orig]) then hookList[orig] = {}; hookList[orig].before = {}; hookList[orig].before.n = 0; hookList[orig].after = {}; hookList[orig].after.n = 0; hookList[orig].hide = {}; hookList[orig].hide.n = 0; hookList[orig].replace = {}; hookList[orig].replace.n = 0; if (scriptElementName) then hookList[orig].orig = MCom.getStringVar(origCopy):GetScript(scriptElementName); MCom.getStringVar(origCopy):SetScript(scriptElementName, function(a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12,a13,a14,a15,a16,a17,a18,a19,a20) return MCom.util.hookHandler(orig,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12,a13,a14,a15,a16,a17,a18,a19,a20); end); else hookList[orig].orig = MCom.getStringVar(orig); MCom.setStringVar(orig,function(a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12,a13,a14,a15,a16,a17,a18,a19,a20) return MCom.util.hookHandler(orig,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12,a13,a14,a15,a16,a17,a18,a19,a20); end); end end l = hookList[orig][hooktype]; g = MCom.getStringVar(new); if ( l ) then for key,value in l do if(value == g) then l[key] = nil; return; end end end end end; if (Sea and Sea.util and Sea.util.hookHandler and Sea.version) then MCom.util.hookHandler = Sea.util.hookHandler; else MCom.util.hookHandler = function (name,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12,a13,a14,a15,a16,a17,a18,a19,a20) local called = false; local continue = true; local retval = nil; local ra1,ra2,ra3,ra4,ra5,ra6,ra7,ra8,ra9,ra10,ra11,ra12,ra13,ra14,ra15,ra16,ra17,ra18,ra19,ra20; local hookList = MCom.util.Hooks; --If Sea is around, then use it's list if (Sea and Sea.util and Sea.util.hook) then hookList = Sea.util.Hooks; end if ( not hookList[name] ) then hookList[name] = {}; hookList[name].before = {}; hookList[name].before.n = 0; hookList[name].after = {}; hookList[name].after.n = 0; hookList[name].hide = {}; hookList[name].hide.n = 0; hookList[name].replace = {}; hookList[name].replace.n = 0; end for key,value in hookList[name].hide do if(type(value) == "function") then if(not value(a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12,a13,a14,a15,a16,a17,a18,a19,a20)) then continue = false; end called = true; end end if(not continue) then return; end for key,value in hookList[name].before do if(type(value) == "function") then value(a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12,a13,a14,a15,a16,a17,a18,a19,a20); called = true; end end continue = false; local replacedFunction = false; for key,value in hookList[name].replace do if(type(value) == "function") then replacedFunction = true; local callOrig = false; callOrig,ra1,ra2,ra3,ra4,ra5,ra6,ra7,ra8,ra9,ra10,ra11,ra12,ra13,ra14,ra15,ra16,ra17,ra18,ra19,ra20 = value(a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12,a13,a14,a15,a16,a17,a18,a19,a20); if(callOrig) then continue = true; else retval = true; end called = true; end end if(continue or (not replacedFunction)) then if (hookList[name].orig) then ra1,ra2,ra3,ra4,ra5,ra6,ra7,ra8,ra9,ra10,ra11,ra12,ra13,ra14,ra15,ra16,ra17,ra18,ra19,ra20 = hookList[name].orig(a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12,a13,a14,a15,a16,a17,a18,a19,a20); end retval = true; end for key,value in hookList[name].after do if(type(value) == "function") then value(a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12,a13,a14,a15,a16,a17,a18,a19,a20); called = true; end end if(not called) then --[[ Disabled Complete Unhhoking Sept 17, 2005 - Incompatible with Frame Script Element Hooks - Liable to erase hooks loaded after the first hook. MCom.setStringVar(name,hookList[name].orig); hookList[name] = nil; ]]-- end if (retval) then if (type(ra1) == "table") then return unpack(ra1); else return ra1,ra2,ra3,ra4,ra5,ra6,ra7,ra8,ra9,ra10,ra11,ra12,ra13,ra14,ra15,ra16,ra17,ra18,ra19,ra20; end end end; end; MCom.wow = { tooltip = {}; }; MCom.wow.tooltip.get = function ( tooltip, row, value ) if (Sea and Sea.wow and Sea.wow.tooltip and Sea.wow.tooltip.get) then --Call origional return Sea.wow.tooltip.get( tooltip, row, value ); else --Default to GameTooltip if (not tooltip) then tooltip = "GameTooltip"; end --Default to first row if (not row) then row = 1; end local text, left, right, leftRed, leftGreen, leftBlue, leftAlpha, rightRed, rightGreen, rightBlue, rightAlpha; --Get the left tooltip if ( ( value == nil ) or ( value == "left" ) or ( value == "leftColor" ) ) then text = getglobal(tooltip.."TextLeft"..row); --Get the left tooltip text if ( ( value == nil ) or ( value == "left" ) ) then if ( text and text:IsVisible() ) then left = text:GetText(); end --If this is all they want, then return it now if ( value == "left" ) then return left; end end --Get the left tooltip color if ( ( value == nil ) or ( value == "leftColor" ) ) then if ( text and text:IsVisible() ) then leftRed, leftGreen, leftBlue, leftAlpha = text:GetTextColor(); end --If this is all they want, then return it now if ( value == "leftColor" ) then return leftRed, leftGreen, leftBlue, leftAlpha; end end end --Get the right tooltip if ( ( value == nil ) or ( value == "right" ) or ( value == "rightColor" ) ) then text = getglobal(tooltip.."TextRight"..row); --Get the right tooltip text if ( ( value == nil ) or ( value == "right" ) ) then if ( text and text:IsVisible() ) then right = text:GetText(); end --If this is all they want, then return it now if ( value == "right" ) then return right; end end --Get the right tooltip color if ( ( value == nil ) or ( value == "rightColor" ) ) then if ( text and text:IsVisible() ) then rightRed, rightGreen, rightBlue, rightAlpha = text:GetTextColor(); end --If this is all they want, then return it now if ( value == "rightColor" ) then return rightRed, rightGreen, rightBlue, rightAlpha; end end end --If no individual value was specified, return the entire row return left, right, leftRed, leftGreen, leftBlue, leftAlpha, rightRed, rightGreen, rightBlue, rightAlpha; end end; MCom.string = {}; MCom.string.colorToString = function ( color ) if (Sea and Sea.string and Sea.string.colorToString) then --Call origional return Sea.string.colorToString(color); else if ( not color ) then return "FFFFFFFF"; end local rString = MCom.math.hexFromInt(math.floor(255*color.r)); local gString = MCom.math.hexFromInt(math.floor(255*color.g)); local bString = MCom.math.hexFromInt(math.floor(255*color.b)); local aString; if ( color.a ) then aString = MCom.math.hexFromInt(math.floor(255*color.a)); elseif ( color.opacity ) then aString = MCom.math.hexFromInt(math.floor(255*color.opacity)); end if ( aString ) then return aString..rString..gString..bString; else return rString..gString..bString; end; end end; end