candlepin Posted April 3, 2018 Share Posted April 3, 2018 I'm working on the MCM for my mod and I can't seem to fix one final issue. Originally I was using the "old" way of making the MCM and things worked fine, but I've switched to using States as this adds some things I like (more dynamic), seems to cut down on code, and overall is easier to follow (now that I've gotten used to it). Basically I want to have one "master" toggle. When the master toggle is selected then the other options can be set. But when the master toggle is unselected I want the other options grayed out. I can get this to work via SetOptionFlagsST() when you stay in the same MCM page. But these flags are getting reset when I switch between pages. The selected options don't change, only the flags (grayed out or not). This isn't a huge issue, but it sure would be nice to get it fixed. Since my menu is pretty big, I made a very much condensed and generic version of my script. If I can figure out this script, I can apply the changes to mine. Any help would be appreciated! Script: Scriptname MIOS_MCM_quest_script extends SKI_ConfigBase ;========== ; Global Variables | ;========== GlobalVariable Property MIOS_GV_A Auto GlobalVariable Property MIOS_GV_B Auto ;========= ; Toggle States | ;========= Bool BoolA_toggle = true Bool BoolB_toggle = true ;========= ; OnConfigInit | ;========= Event OnConfigInit() Pages = new string[2] Pages[0] = "Dummy Page" Pages[1] = "Options" EndEvent ;========= ; OnPageReset | ;========= Event OnPageReset(string page) ;================== ; MIOS MCM WELCOME PAGE | ;================== If (Page == "") LoadCustomContent("My File Directory") Else UnloadCustomContent() EndIf ;============= ; DUMMY PAGE | ;============= If (Page == "Dummy Page") SetCursorFillMode(TOP_TO_BOTTOM) SetCursorPosition(0) AddHeaderOption("Dummy Page") ;=========== ; OPTIONS | ;=========== ElseIf (Page == "Options") SetCursorFillMode(TOP_TO_BOTTOM) SetCursorPosition(0) AddHeaderOption("Options") AddToggleOptionST("BoolAToggle", "A?", BoolA_toggle) AddToggleOptionST("BoolBToggle", "B?", BoolB_toggle) EndIf EndEvent ;====== ; STATES | ;====== State BoolAToggle Event OnHighlightST() SetInfoText("A?") EndEvent Event OnDefaultST() BoolA_toggle = true OnSelectST() EndEvent Event OnSelectST() BoolA_toggle = !BoolA_toggle SetToggleOptionValueST(BoolA_toggle) If BoolA_toggle == 0 MIOS_GV_A.SetValue(0) SetOptionFlagsST(OPTION_FLAG_DISABLED, false, "BoolBToggle") ShowMessage("Bool A set to false", false, "OK") Else MIOS_GV_A.SetValue(1) SetOptionFlagsST(OPTION_FLAG_NONE, false, "BoolBToggle") ShowMessage("Bool A set to true", false, "OK") EndIf EndEvent EndState State BoolBToggle Event OnHighlightST() SetInfoText("B?") EndEvent Event OnDefaultST() BoolB_toggle = true OnSelectST() EndEvent Event OnSelectST() BoolB_toggle = !BoolB_toggle SetToggleOptionValueST(BoolB_toggle) If BoolB_toggle == 0 MIOS_GV_B.SetValue(0) ShowMessage("Bool B set to false.", false, "OK") Else MIOS_GV_B.SetValue(1) ShowMessage("Bool B set to true.", false, "OK") EndIf EndEvent EndState Link to comment Share on other sites More sharing options...
PeterMartyr Posted April 3, 2018 Share Posted April 3, 2018 What exactly is the Boolean Proposition here? What is it that is True or False in most base form? ExamplesIs Quest RunningDoes player have the itemWhat the globalwhat the StageIs the Bool true or falseWhy use two, doesn't one work you? (A bool private variable & a Global) I need to understand more of what your trying to achieve, but below in A is a simple Toggle base base on what I saw in your code. Scriptname MIOS_MCM_quest_script extends SKI_ConfigBase ;========== ; Global Variables | ;========== GlobalVariable Property MIOS_GV_A Auto ;according to your code, default is false GlobalVariable Property MIOS_GV_B Auto ;========= ; Toggle States | ;========= ;Bool BoolA_toggle = true Why!!!!!!! you don't need it. Bool BoolB_toggle = true ;========= ; OnConfigInit | ;========= Event OnConfigInit() Pages = new string[2] Pages[0] = "Dummy Page" Pages[1] = "Options" EndEvent ;========= ; OnPageReset | ;========= Event OnPageReset(string page) ;================== ; MIOS MCM WELCOME PAGE | ;================== If (Page == "") LoadCustomContent("My File Directory") Else UnloadCustomContent() EndIf ;============= ; DUMMY PAGE | ;============= If (Page == "Dummy Page") SetCursorFillMode(TOP_TO_BOTTOM) SetCursorPosition(0) AddHeaderOption("Dummy Page") ;=========== ; OPTIONS | ;=========== ElseIf (Page == "Options") SetCursorFillMode(TOP_TO_BOTTOM) SetCursorPosition(0) AddHeaderOption("Options") AddToggleOptionST("BoolAToggle", "A?", MIOS_GV_A.GetValue() as Bool) ; Real Game Value, less buggy, way more professional AddToggleOptionST("BoolBToggle", "B?", BoolB_toggle) EndIf EndEvent ;====== ; STATES | ;====== State BoolAToggle Event OnSelectST() Bool BoolA_toggle = MIOS_GV_A.GetValue() BoolA_toggle = !BoolA_toggle SetToggleOptionValueST(BoolA_toggle) ShowMessage("Switching to " + BoolA_toggle, false, "OK") MIOS_GV_A.SetValue(BoolA_toggle as float) EndEvent Event OnDefaultST() Bool BoolA_toggle = MIOS_GV_A.GetValue() If BoolA_toggle OnSelectST() EndIf EndEvent Event OnHighlightST() SetInfoText("A?") EndEvent ;Keep Variables in the event or function where possible Okay EndState State BoolBToggle Event OnHighlightST() SetInfoText("B?") EndEvent Event OnDefaultST() BoolB_toggle = true OnSelectST() EndEvent Event OnSelectST() BoolB_toggle = !BoolB_toggle SetToggleOptionValueST(BoolB_toggle) If BoolB_toggle == 0 MIOS_GV_B.SetValue(0) ShowMessage("Bool B set to false.", false, "OK") Else MIOS_GV_B.SetValue(1) ShowMessage("Bool B set to true.", false, "OK") EndIf EndEvent EndState I hope you can see it. A is mine, B is yours, Example only, not tested. Best of luck with your Scripting, English isn't my 1st language, so my code does the main talking for me. If you have any questions? I do my best to answer them. Link to comment Share on other sites More sharing options...
PeterMartyr Posted April 3, 2018 Share Posted April 3, 2018 Remember a MCM doesn't store information, It gathers & disperses information. CDCooley taught me that. Cheeers Edit if it works when you change pages? try a ForcePageReset() where appropriate. Link to comment Share on other sites More sharing options...
candlepin Posted April 3, 2018 Author Share Posted April 3, 2018 (edited) Maybe I oversimplified my code a bit too much (and didn't provide enough accompanying information). Basically I want the first Toggle to control whether certain items appear in the game (e.g. whether humans drop human hearts). This is achieved by setting a GV (in the above instance MIOS_GV_A), which controls whether the action takes place (via a condition which checks for the global variable). Subsequent Toggles will control the modulation of those items (e.g. rate at which hearts drop, whether they are automatically added to loot or have to be harvested, etc). In my example above I only added one "modulation" (Toggle B) for the sake of simplicity, but I will need roughly 5-6 Toggles to achieve what I want (each Toggle exerting its effects via global variables). Changing these Toggles doesn't make sense if the first Toggle is set to 0/false (i.e. why change if hearts need to be actively harvested if they won't appear?). Thus I'd prefer to have these options grayed out if the first Toggle is set to 0/false. Hopefully this clarifies what I'm trying to do. Btw, I really appreciate the help. Especially with the idea to replace the bools with (GV as bool) in AddToggleOptionST(). Great suggestion, makes perfect sense. Edited April 3, 2018 by candlepin Link to comment Share on other sites More sharing options...
PeterMartyr Posted April 4, 2018 Share Posted April 4, 2018 You maybe need a manual Int property to control the Enable & Disable of the States, depending on the primary Global. This mine for a PapyrusUtil json file MCM back up, It fades(disabled loading if there no BackUp, & Disables it also when a certain quest is running{making a backup}) It will be out of context, I hope you will see what I am trying to say Int nFLAG_QUEST_RUNNING_DISABLED = _FDQ_QUST_D05X.IsRunning() As Int AddHeaderOption("MCM Data Utility") AddTextOptionST("TEXT_SAVE_JSON_BAK_STATE", "Export Data","Click Me", nFLAG_QUEST_RUNNING_DISABLED) Int nFLAG_DATA_EXISTS_NONE = BakDataExists_NONE() As Int AddTextOptionST("TEXT_LOAD_JSON_BAK_STATE", "Import Data", "Click Me", (nFLAG_DATA_EXISTS_NONE || nFLAG_QUEST_RUNNING_DISABLED) As Int) AddTextOptionST("TEXT_CLEAR_JSON_BAK_STATE", "Clear Data", "Click Me", (nFLAG_DATA_EXISTS_NONE || nFLAG_QUEST_RUNNING_DISABLED) As Int) The entire code is in the Event OnPageReset(String a_page) with no Private Variables, just variables contain in the event. So you need to do something with the int property OPTION_FLAG_NONE = 0x00 autoReadonly int property OPTION_FLAG_DISABLED = 0x01 autoReadonly int property OPTION_FLAG_HIDDEN = 0x02 autoReadonly ; @since 3 int property OPTION_FLAG_WITH_UNMAP = 0x04 autoReadonly ; @since 3 to achieve what you want. I understood this, but where was the code? So I worked with I saw. Baby steps. Post the entire Toggle Code that need to be Disable & Enable for a opinion on whats going wrong. Link to comment Share on other sites More sharing options...
PeterMartyr Posted April 4, 2018 Share Posted April 4, 2018 You should notice I "Cast" alot to simplify want I am trying to achieve. Bools into Floats or Ints & vice visa. Also I Cast into Ints into Ints, to get some things to work as I intend, so that they don't add up to Unmap, but just Disable & Enable. Hope you don't find this confusing? Link to comment Share on other sites More sharing options...
candlepin Posted April 4, 2018 Author Share Posted April 4, 2018 Sorry, you lost me with your code. (nFLAG_DATA_EXISTS_NONE || nFLAG_QUEST_RUNNING_DISABLED) As Int The way I read this, this will return a value of 0 if both these ints are 0 and a value of 1 if either of these conditions is 1. But the required parameter here is a flag. I don't get how an integer = a flag. Seems I'm missing something here/misunderstanding something. DO the flags correspond to numbers? If so, that would make my life so much easier.... int property OPTION_FLAG_NONE = 0x00 autoReadonlyint property OPTION_FLAG_DISABLED = 0x01 autoReadonlyint property OPTION_FLAG_HIDDEN = 0x02 autoReadonly ; @since 3int property OPTION_FLAG_WITH_UNMAP = 0x04 autoReadonlyYou really lost me here. For helping with my code, let me expand upon my earlier example: ElseIf (Page == "Options") SetCursorFillMode(TOP_TO_BOTTOM) SetCursorPosition(0) AddHeaderOption("Options") AddToggleOptionST("BoolAToggle", "A?", MIOS_GV_A.GetValue() as Bool) AddToggleOptionST("BoolBToggle", "B?", BoolB_toggle, XXXXXXXXXXX) AddToggleOptionST("BoolCToggle", "C?", BoolC_toggle, XXXXXXXXXXX) AddToggleOptionST("BoolDToggle", "D?", BoolD_toggle, XXXXXXXXXXX) EndIf EndEvent MIOS_GV_A can be either 0 or 1. If it's zero, I'd like Toggles B, C, and D set to disabled, i.e. XXXXXXXXXXX to be set to OPTION_FLAG_DISABLED if MIOS_GV_A == 0. But if MIOS_GV_A == 1, I'd like XXXXXXXXXXX to be set to OPTION_FLAG_NONE. I don't understand how to make XXXXXXXXXXX conditional with text like that. I have a condition within the OnSelectST() of Toggle A that disables and enables the Toggles for B, C, and D when Toggle A is set to 0 or 1, respectively. The problem, however, is that this seems to be forgotten when switching between MCM pages. As you pointed out, I think this is due to me not controlling the flags of these Toggles during the OnPageReset Event. Btw, even though I don't quite get what you're saying (yet!), I really appreciate the help! Link to comment Share on other sites More sharing options...
PeterMartyr Posted April 5, 2018 Share Posted April 5, 2018 Ok lets say on the Global, 0 = false & 1 = true. So it works as a Bool. Very Important!! That doesn't work with SkyUI Options of OPTION_FLAG_NONE = 0 & OPTION_FLAG_DISABLED = 1 So lets create a manual read only property to get what we want. Int Property FLAG_DISABLED_ALL Int Function Get() Bool bIsEnable = MIOS_GV_A.GetValue() If bIsEnable return OPTION_FLAG_NONE EndIf return OPTION_FLAG_DISABLED EndFunction EndProperty Now we use this Int property to Enable or Disable All certain Options at once, depending of the Primary Global of MIOS_GV_A as Boolean ElseIf (Page == "Options") SetCursorFillMode(TOP_TO_BOTTOM) SetCursorPosition(0) AddHeaderOption("Options") AddToggleOptionST("BoolAToggle", "A?", MIOS_GV_A.GetValue() as Bool) AddToggleOptionST("BoolBToggle", "B?", BoolB_toggle, FLAG_DISABLED_ALL) AddToggleOptionST("BoolCToggle", "C?", BoolC_toggle, FLAG_DISABLED_ALL) AddToggleOptionST("BoolDToggle", "D?", BoolD_toggle, FLAG_DISABLED_ALL) EndIf EndEvent Tweak it has you find necessary, but that it. OH navigate to Skyrim\Data\SCRIPTS\Source find: SKI_ConfigBase.pscIt's the source code for extending the MCM, it's were I got those int values from, read it, then go to SKI_SDK website for clarification, or read, or decompile MCM from other Modder's to learn from them. Once again let me apologize for my English, but that should solve your Problem, with my baby step. And you should have a better understanding of is happening, instead of giving this code first time round. Good Luck with everything Sincerely Cloud PeterMartyr. Link to comment Share on other sites More sharing options...
cdcooley Posted April 5, 2018 Share Posted April 5, 2018 (edited) I took too long creating this response (and got distracted for a while while writing it) so PeterMartyr beat me to the real problem in your script. You need to use the 4th parameter for AddToggleOptionST if you're trying to use toggle A as the master switch for all other options. Putting all of the things above together your script can look something like this: Scriptname MIOS_MCM_quest_script extends SKI_ConfigBase ;========== ; Global Variables | ;========== GlobalVariable Property MIOS_GV_A Auto ; Master Toggle blocks all others when not enabled GlobalVariable Property MIOS_GV_B Auto ; example secondary value ;========= ; OnConfigInit | ;========= Event OnConfigInit() Pages = new string[2] Pages[0] = "Dummy Page" Pages[1] = "Options" EndEvent ;========= ; OnPageReset | ;========= Event OnPageReset(string page) ;================== ; MIOS MCM WELCOME PAGE | ;================== If (Page == "") LoadCustomContent("My File Directory") Else UnloadCustomContent() EndIf ;============= ; DUMMY PAGE | ;============= If (Page == "Dummy Page") SetCursorFillMode(TOP_TO_BOTTOM) SetCursorPosition(0) AddHeaderOption("Dummy Page") ;=========== ; OPTIONS | ;=========== ElseIf (Page == "Options") SetCursorFillMode(TOP_TO_BOTTOM) SetCursorPosition(0) AddHeaderOption("Options") int option_flag = OPTION_FLAG_DISABLED ; assume all but master toggle should be disabled by default if MIOS_GV_A.GetValue() as bool ; if master toggle is active then allow setting other values normally option_flag = OPTION_FLAG_NONE endif AddToggleOptionST("BoolAToggle", "A?", MIOS_GV_A.GetValue() as Bool) AddToggleOptionST("BoolBToggle", "B?", MIOS_GV_B.GetValue() as Bool, option_flag) ; AddToggleOptionST("BoolCToggle", "C?", MIOS_GV_C.GetValue() as Bool, option_flag) ; AddToggleOptionST("BoolDToggle", "D?", MIOS_GV_D.GetValue() as Bool, option_flag) EndIf EndEvent ;====== ; STATES | ;====== State BoolAToggle Event OnHighlightST() SetInfoText("A?") EndEvent Event OnDefaultST() MIOS_GV_A.SetValue(1) ; real default is false OnSelectST() EndEvent Event OnSelectST() if MIOS_GV_A.GetValue() as bool MIOS_GV_A.SetValue(0) Else MIOS_GV_A.SetValue(1) EndIf ForcePageReset() ; to update the option_flag value for all of the secondary options EndEvent EndState State BoolBToggle Event OnHighlightST() SetInfoText("B?") EndEvent Event OnDefaultST() MIOS_GV_B.SetValue(1) ; real default is false OnSelectST() EndEvent Event OnSelectST() If MIOS_GV_B.GetValue() as bool MIOS_GV_B.SetValue(0) Else MIOS_GV_B.SetValue(1) EndIf SetToggleOptionValueST(MIOS_GV_B.GetValue() as bool) EndEvent EndState I didn't use a property for my option_flag variable because that would recalculate the value every time you use it. Edited April 5, 2018 by cdcooley Link to comment Share on other sites More sharing options...
PeterMartyr Posted April 5, 2018 Share Posted April 5, 2018 To cdcooleyRespect, I always defer to the master. To candlepinDo what he said. :yes: Link to comment Share on other sites More sharing options...
Recommended Posts