EddieTheEagle Posted August 13, 2017 Share Posted August 13, 2017 (edited) I want to make a MCM menu for my mod, but I'm not sure if there will be any issues when converting the mod to SSE.Just curious I've never worked with it and I don't want to start messing with it if will break stuff for SSE. Do I have to remove stuff or will it load in fine in SSE without changing anything? Edited August 13, 2017 by EddieTheEagle Link to comment Share on other sites More sharing options...
Elias555 Posted August 13, 2017 Share Posted August 13, 2017 The 'mod configuration menu menu' requires SkyUI. SkyUI requires SKSE. Are they out yet for SSE? Link to comment Share on other sites More sharing options...
drewsbrew Posted August 13, 2017 Share Posted August 13, 2017 At the moment, there is no MCM menu in Skyrim SE. For that, there needs to be an SKSE for Skyrim SE (SKSE64) and unfortunately, SKSE64 is not done yet and there is some speculation that it may never get finished, but there is no definite word yet one way or the other. The next thing needed for an MCM menu would be SkyUI, which requires SKSE, so basically, the TL;DR here is there is no MCM in Skyrim SE, and at the very least, it'll be a while before there is one. In the meantime, mod authors usually will add a power to the game that will bring up a configuration menu for the mods that need one, though I don't know how that is done. I don't know much about scripting at the moment. Link to comment Share on other sites More sharing options...
EddieTheEagle Posted August 13, 2017 Author Share Posted August 13, 2017 At the moment, there is no MCM menu in Skyrim SE. For that, there needs to be an SKSE for Skyrim SE (SKSE64) and unfortunately, SKSE64 is not done yet and there is some speculation that it may never get finished, but there is no definite word yet one way or the other. The next thing needed for an MCM menu would be SkyUI, which requires SKSE, so basically, the TL;DR here is there is no MCM in Skyrim SE, and at the very least, it'll be a while before there is one. In the meantime, mod authors usually will add a power to the game that will bring up a configuration menu for the mods that need one, though I don't know how that is done. I don't know much about scripting at the moment. I know it requires SkyUI and SKSE. I also know they are not available for SSE. I already have the power spell made with a working config but I also wanted to do the MCM menu for Classic.I'm just wondering it would cause issues if you load in a mod that requires SkyUI and SKSE in SSE. Link to comment Share on other sites More sharing options...
cdcooley Posted August 13, 2017 Share Posted August 13, 2017 If you've constructed your mod correctly there's no problem leaving the MCM quest and scripts in place when porting to SSE. The game will fail to load the MCM scripts and generate an error in the Papyrus log but nothing bad will happen. It's the same as trying to run the mod in the original game if you disable SkyUI (and that's the easiest way to test that everything is good). Constructing the mod correctly means that nothing in your mod can depend on those MCM scripts. If you already have a mod working without the MCM (and configurable in some other way) then everything should be fine. Just make sure that the MCM is checking and setting global variables, properties from other scripts, or detecting other things from your mod instead of having the other scripts check properties in the MCM script. Here's an example MCM showing how to do the sort of optional MCM configuration you're talking about. ScriptName InigoMCMScriptDemo extends SKI_ConfigBase {Example MCM menu based on InigoMCM mod code. Values set by the MCM are either ActorValues of Inigo himself or properties in some script, could have been GlobalVariables or even local variables.} ; Properties to access various external objects and scripts. WorldSpace Property Tamriel Auto Actor Property PlayerRef Auto Actor Property InigoRef Auto ; this is used enough to make it worth setting as its own property InigoStatusQuestScript Property InigoStatus Auto {The status script holds lots of useful properties and functions that can be tweaked from the MCM.} InigoExtrasScript Property InigoExtras Auto {A script holding extra features like whistle hotkey and Mr. Dragonfly options that are not in the main Inigo mod.} ; These dynamic values must be checked each time the MCM is opened amd unfortunately ; the values are needed in multiple functions so they have to be declared here Actor SteedRef ; may be null Form CurrentWorld ; either a world or cell so never null bool IsSteedAllowedHere ; based on current contents of the formlist and this location ; I do not need an OnConfigInit() function, but that works just like the basic version of the MCM tutorial. Function OnPageReset(String a_page) ; Gather some information before showing the page because somethings get disabled if they are not appropriate ; Get current steed from its alias, if he has one. SteedRef = InigoStatus.SteedAlias.GetReference() as Actor CurrentWorld = PlayerRef.GetWorldSpace() if !CurrentWorld CurrentWorld = PlayerRef.GetParentCell() endif ; There is a formlist with all of the places Inigo is allowed to ride, see if we are in it. IsSteedAllowedHere = CurrentWorld && InigoStatus.InigoSteedAllowed && InigoStatus.InigoSteedAllowed.HasForm(CurrentWorld) ; Now show the menu (a_page variable is not used because all of the options fit on one page) SetCursorFillMode(TOP_TO_BOTTOM) ; This one is a key remap that allows the key to be completely unmapped. AddKeyMapOptionST("Whistle", "Whistle Hotkey", InigoExtras.WhistleKeyCode, OPTION_FLAG_WITH_UNMAP) ; This one is a multiple option toggle implemented with a TextOption field. There is another control specifically for that but I did not use it. AddTextOptionST("ShowMrD", "Show Mr Dragonfly", ShowMrDTxt(InigoExtras.MrDVisible.ShowMrD)) SetCursorPosition(1) AddToggleOptionST("SteedAllowed", "Steed Allowed Here", IsSteedAllowedHere) if SteedRef AddSliderOptionST("SteedSpeedMult", "Trusty Steed's Speed", SteedRef.GetActorValue("SpeedMult"), "{0}%") else ; I think it looks nicer to show a disabled text box if he does not have a steed AddTextOptionST("SteedSpeedMult", "Trusty Steed's Speed", "", OPTION_FLAG_DISABLED) endif SetCursorPosition(6) AddHeaderOption("Advanced Options") ; I wanted it to be clear that some of these are percentage values so they have custom formatting. ; These in this group all modify actor values on Inigo himself. AddSliderOptionST("SpeedMult", "Inigo's Speed", InigoRef.GetActorValue("SpeedMult"), "{0}%") AddSliderOptionST("CarryWeight", "Inigo's Carry Capacity", InigoRef.GetActorValue("CarryWeight"), "{0}") AddSliderOptionST("AttackDamageMult", "Inigo's Attack Damage", InigoRef.GetActorValue("AttackDamageMult")*100.0, "{0}%") ; real value is a simple multipler AddSliderOptionST("DamageResist", "Inigo's Damage Resistance", InigoRef.GetActorValue("DamageResist"), "{0}") SetCursorPosition(7) AddHeaderOption("Emergency Use Only") ; These TextOptions are being used as buttons AddTextOptionST("SummonInigoNow", "Summon Inigo Now", "") AddTextOptionST("SummonMrD", "Summon Mr Dragonfly", "") AddTextOptionST("RecoverBow", "Recover Inigo's Bow", "") AddTextOptionST("RecoverBooks", "Recover Inigo's Books", "") EndFunction string Function ShowMrDTxt(int val) {Simple utility function to translate the ShowMrD variable values into matching text for the button.} if val == 1 return "Large Jar" elseif val == 2 return "Small Jar" elseif val == 3 return "Front Jar" else return "No" endif EndFunction ;Here are the various states needed to implement everything above (in reverse order) State RecoverBooks Event OnHighlightST() SetInfoText("Recover Inigo's missing books.\n(They'll be added to his inventory not yours.)") EndEvent ; Implements a button to perform an action Event OnSelectST() SetOptionFlagsST(OPTION_FLAG_DISABLED) if InigoRef.GetItemCount(InigoExtras.InigoJournal) < 1 && PlayerRef.GetItemCount(InigoExtras.InigoJournal) < 1 InigoRef.AddItem(InigoExtras.InigoJournal, 1) endif if InigoRef.GetItemCount(InigoExtras.InigoBrave) < 1 && PlayerRef.GetItemCount(InigoExtras.InigoBrave) < 1 InigoRef.AddItem(InigoExtras.InigoBrave, 1) endif if PlayerRef.HasSpell(InigoExtras.WhistlePower) if InigoRef.GetItemCount(InigoExtras.WBook) < 1 && PlayerRef.GetItemCount(InigoExtras.WBook) < 1 InigoRef.AddItem(InigoExtras.WBook, 1) endif endif if (InigoExtras.InigoBadVibrationsQuest.IsStageDone(180) if InigoRef.GetItemCount(InigoExtras.DVJournal) < 1 && PlayerRef.GetItemCount(InigoExtras.DVJournal) < 1 InigoRef.AddItem(InigoExtras.DVJournal, 1) endif if InigoRef.GetItemCount(InigoExtras.Champion1) < 1 && PlayerRef.GetItemCount(InigoExtras.Champion1) < 1 InigoRef.AddItem(InigoExtras.Champion1, 1) endif if InigoRef.GetItemCount(InigoExtras.Champion2) < 1 && PlayerRef.GetItemCount(InigoExtras.Champion1) < 1 InigoRef.AddItem(InigoExtras.Champion2, 1) endif endif EndEvent EndState State RecoverBow Event OnHighlightST() SetInfoText("Recover Inigo's bow if you've lost it.\n(It will be added to his inventory not yours.)") EndEvent Event OnSelectST() SetOptionFlagsST(OPTION_FLAG_DISABLED) if InigoRef.GetItemCount(InigoExtras.Bow) < 1 && PlayerRef.GetItemCount(InigoExtras.Bow) < 1 InigoRef.AddItem(InigoExtras.Bow, 1) InigoRef.EquipItem(InigoExtras.Bow) ; Equip it so the player knows this function worked. endif EndEvent EndState State SummonMrD Event OnHighlightST() SetInfoText("Summon Mr. Dragonfly to the player.") EndEvent Event OnSelectST() SetOptionFlagsST(OPTION_FLAG_DISABLED) InigoExtras.MrD.MoveTo(PlayerRef, 80.0*Math.sin(PlayerRef.GetAngleZ()), 80.0*Math.cos(PlayerRef.GetAngleZ()), 10.0, 0) EndEvent EndState State SummonInigoNow Event OnHighlightST() SetInfoText("Bring Inigo to the player. This could break his quests!") EndEvent Event OnSelectST() SetOptionFlagsST(OPTION_FLAG_DISABLED) ; position him directly in front of the player and turn him to face the player. ; enabling and disabling can fix many game glitches float az = PlayerRef.GetAngleZ() InigoRef.MoveTo(PlayerRef, 80.0*Math.sin(az), 80.0*Math.cos(az), 10.0, 0.0) InigoRef.Disable() InigoRef.SetAngle(0.0, 0.0, az + 180.0) InigoRef.Enable() EndEvent EndState State AttackDamageMult Event OnHighlightST() SetInfoText("Inigo's Attack Damage compared to other NPCs. [default = 100%]") EndEvent Event OnSliderAcceptST(float value) InigoRef.ForceActorValue("AttackDamageMult", value/100.0) ; real value is a multipler, so convert percent back to decimal SetSliderOptionValueST(value) EndEvent Event OnSliderOpenST() SetSliderDialogStartValue(InigoRef.GetActorValue("AttackDamageMult")*100.0) ; real value isn't a percent, so make it one SetSliderDialogDefaultValue(100.0) SetSliderDialogRange(10.0, 1000.0) SetSliderDialogInterval(10.0) EndEvent EndState State DamageResist Event OnHighlightST() SetInfoText("Inigo's Damage Resistance (including benefits from any armor he may be wearing). [default = 0]") EndEvent Event OnSliderAcceptST(float value) InigoRef.ForceActorValue("DamageResist", value) SetSliderOptionValueST(value) EndEvent Event OnSliderOpenST() SetSliderDialogStartValue(InigoRef.GetActorValue("DamageResist")) SetSliderDialogDefaultValue(0.0) SetSliderDialogRange(0.0, 1000.0) SetSliderDialogInterval(1.0) EndEvent EndState State CarryWeight Event OnHighlightST() SetInfoText("Inigo's current carry capcity (possibly modified by spells or enchantments). [default = 300]") EndEvent Event OnSliderAcceptST(float value) InigoRef.ForceActorValue("CarryWeight", value) SetSliderOptionValueST(value) EndEvent Event OnSliderOpenST() SetSliderDialogStartValue(InigoRef.GetActorValue("CarryWeight")) SetSliderDialogDefaultValue(300.0) SetSliderDialogRange(100.0, 900.0) SetSliderDialogInterval(5.0) EndEvent EndState State SpeedMult Event OnHighlightST() SetInfoText("Inigo's current speed compared to the game default speed for NPCs. [default = 115%]") EndEvent Event OnSliderAcceptST(float value) InigoRef.ForceActorValue("SpeedMult", value) SetSliderOptionValueST(value) EndEvent Event OnSliderOpenST() SetSliderDialogStartValue(InigoRef.GetActorValue("SpeedMult")) SetSliderDialogDefaultValue(115.0) SetSliderDialogRange(50.0, 200.0) SetSliderDialogInterval(5.0) EndEvent EndState State SteedSpeedMult Event OnHighlightST() SetInfoText("Inigo's steed's current speed compared to the game default speed for horses. [default = 100%]") EndEvent Event OnSliderAcceptST(float value) SteedRef.ForceActorValue("SpeedMult", value) SetSliderOptionValueST(value) EndEvent Event OnSliderOpenST() SetSliderDialogStartValue(SteedRef.GetActorValue("SpeedMult")) SetSliderDialogDefaultValue(100.0) SetSliderDialogRange(50.0, 200.0) SetSliderDialogInterval(5.0) EndEvent EndState State SteedAllowed Event OnHighlightST() SetInfoText("Should Inigo be allowed to ride his trusty steed in this location?\nThis also summons or dismisses his current steed if possible.") EndEvent Event OnDefaultST() IsSteedAllowedHere = true OnSelectST() EndEvent Event OnSelectST() SetOptionFlagsST(OPTION_FLAG_DISABLED) IsSteedAllowedHere = !IsSteedAllowedHere if CurrentWorld != Tamriel ; Riding is always allowed in Tamriel if IsSteedAllowedHere InigoStatus.Steed = "Allow" else InigoStatus.Steed = "Forbid" endif endif if SteedRef && !SteedRef.IsBeingRidden() if IsSteedAllowedHere || (CurrentWorld == Tamriel && PlayerRef.GetDistance(SteedRef) > 900) InigoStatus.Steed = "Summon" else InigoStatus.Steed = "Stable" InigoStatus.Steed = "Follow" endif endif EndEvent EndState State ShowMrD Event OnHighlightST() SetInfoText("Should Inigo wear Mr Dragonfly in a jar on his belt and if so how?\nOptions: No (the default), in a full-sized jar, in a small jar, and in a small jar in front") EndEvent Event OnSelectST() int pr = InigoExtras.MrDVisible.ShowMrD + 1 ; cycle to the next option InigoExtras.MrDVisible.ShowMrD = pr ;the custom property ShowMrD handles everything important SetTextOptionValueST(ShowMrDTxt(pr)) EndEvent Event OnDefaultST() InigoExtras.MrDVisible.ShowMrD = 0 SetTextOptionValueST(ShowMrDTxt(0)) EndEvent EndState State Whistle Event OnHighlightST() SetInfoText("After learning to Whistle to Inigo you can use this key instead of the power.") EndEvent Event OnDefaultST() OnKeyMapChangeST(45,"","") ; X is the default EndEvent Event OnKeyMapChangeST(int keyCode, string conflictControl, string conflictName) if keyCode == 1 || (keyCode > 255 && !Game.UsingGamepad()) ShowMessage("$SKI_MSG1", false, "$OK", "$Cancel") return endif InigoExtras.UnregisterForKey(InigoExtras.WhistleKeyCode) InigoExtras.WhistleKeyCode = keyCode if keyCode > 0 InigoExtras.RegisterForKey(keyCode) endif SetKeyMapOptionValueST(InigoExtras.WhistleKeyCode, false, "") EndEvent EndState Link to comment Share on other sites More sharing options...
EddieTheEagle Posted August 13, 2017 Author Share Posted August 13, 2017 Ok thanks CDCooley :) Guess I will work on it if it works fine. Link to comment Share on other sites More sharing options...
Recommended Posts