Trying to make a MCM Configeration menu

Post » Sun Jul 24, 2016 10:22 am

Creating a new Config Menu


All config menus have to extend SKI_ConfigBase, which is a script provided by us.



So I did download and extracted the files but it seems the source file is Missing for SKI_PlayerLoadGameAlias.



Consequently, to create a new config menu for your mod, you have to


create a new script that will control your config menu. For now, it doesn't have to be more than this:

scriptname MyConfigMenu extends SKI_ConfigBase


create a new quest and attach your script to it.


The first thing you'll want to customize for you new config menu is the name that will be displayed in the control panel. You do this by setting the ModName property of your attached script in the Creation Kit property editor. You might also notice the Pages property while doing that - it can be ignored for now.


There is still one, very important, thing left to do. Each config menu has to run some maintenance code when the game is reloaded. This has to be set up manually:


In the quest you created, select the Quest Aliases tab and add a new reference alias. Name it PlayerAlias.

For Fill Type, select the player reference (Specific Reference, Cell any, Ref PlayerRef).


In the Scripts list, add SKI_PlayerLoadGameAlias. <--- This is where I get an error!!!!


"script file is corrupted and will not be attached" or something like that,



Is this because of the missing source file for SKI_PlayerLoadGameAlias ? What am I doing wrong?
User avatar
Dan Wright
 
Posts: 3308
Joined: Mon Jul 16, 2007 8:40 am

Post » Sun Jul 24, 2016 1:06 am

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.)



Spoiler


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


User avatar
Lily
 
Posts: 3357
Joined: Mon Aug 28, 2006 10:32 am

Post » Sat Jul 23, 2016 10:34 pm

I went here: https://github.com/schlangster/skyui/wiki


Downloaed thier SDK zip. I extracted the files to my skyrim data folder. Then followed the tutorial on how to set up the alias in the CK ...but I got this error once I tried to


add SKI_PlayerLoadGameAlias <--- This is where I get an error!!!!


"script file is corrupted and will not be attached" (or something like that).


So I noticed that the SDK zip file was missing the source file for some of the PEX files (particularly the SKI_PlayerLoadGameAlias script).


Is that why I am getting the error?


It does not say this in the quick start nor the tutorial but do I need to load the skyui esp WITH my esp into the CK (make it dependent on the SkyUI esp)?


I already use SkyUI in my own game so yes I do load it when I play, but that should not be important I guess as this issues is in the CK not the game. Except to say that I do have the other SKUI files in my data Folder (the ones needed to run it in the game).
User avatar
koumba
 
Posts: 3394
Joined: Thu Mar 22, 2007 8:39 pm

Post » Sat Jul 23, 2016 11:43 pm

I deleted ALL the SKUI files, then RE-downloaded and RE-installed them all again and it seems to work now. :shrug:

User avatar
Claire Vaux
 
Posts: 3485
Joined: Sun Aug 06, 2006 6:56 am

Post » Sun Jul 24, 2016 6:03 am

Problem solved.

OP requested a close.

User avatar
Andrew
 
Posts: 3521
Joined: Tue May 08, 2007 1:44 am


Return to V - Skyrim