You need the SkyUI SDK for (a version of) the source scripts. The various versions are all linked at https://github.com/schlangster/skyui/wiki.
And you should really be using the state-based version of the options instead of the old way that's demonstrated in their quick start guide and tutorial examples.
Here is an example based on Inigo MCM that shows how to use most of the available options. It also uses my preferred style of storing the actual configuration information in the scripts or other locations that need them and not as local variables in the MCM script or pointless global variables. (Although global variables are sometimes exactly the right place to store things.)
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
I deleted ALL the SKUI files, then RE-downloaded and RE-installed them all again and it seems to work now.