Jump to content

Need help adding hotkeys to MCM


Recommended Posts

Yeah, not sure where to go with it at this point. The hotkeys were an afterthought, maybe I just abandon them.

 

Recompiled with the script I posted with the added bool and modified OnKeyDown and State and took out any registering of keys that could happen without doing it, COC Riverwood and messed around about 25 mins without going into the MCM or anything, no problems. Went into MCM and exited without touching anything, messed around with using Mod spells and features for about 25 mins, no problem, went into MCM and added one hotkey, 6 mins and the game froze - never even hit the hotkey and was sitting on a mount spinning just to make sure nothing from the Mod was being used.

 

Loaded up the version with no hotkeys on a fully modded game, played around using mod features and stuff for over an hour, no issues.

 

Went back to the minimal build that has the current version with hotkeys, COC Riverwood, went into MCM and assigned a hotkey and then just stood there, didn't touch anything and it froze before it started spinning.

 

Maybe hotkeys just weren't meant to be. Really frustrating though. I feel like I'm SO close LOL.

 

-IA710

Link to comment
Share on other sites

Post the code as you have it now.

 

One option to consider, rewrite the MCM to utilize its state method (example of that can be seen in my Inventory management mod). The state method puts all events for a given option into a single state. No long lists of ElseIf statements to get lost in when wanting to modify a single option. Plus adding new options gets easier as an existing state can be copied, pasted and then adjusted as needed.

Link to comment
Share on other sites

Ok, I'm not giving up - here it is as it sits right now:

 

 

 

Scriptname IA710_HandyCrafting_MCM_Script extends SKI_ConfigBase  

IA710_HandyCraftingScript Property HandyCrafting Auto

;These need to be filled with the formlists and container references.
FormList Property IA710_flAllIngredients Auto
{Holds all of the ingredients from the other lists.}
ObjectReference Property IA710_cIngredientStorageRef Auto
{Master container hold all the stored ingredients.}
ObjectReference Property IA710_cTemporaryHoldingRef Auto
{Container that holds Protected ingredients while the player is crafting.}
ObjectReference Property IA710_cCappingChestRef Auto
{Container tha holds the Capping ingredients list.}
FormList[] Property IngredientsList Auto
{Contains all the vanilla ingredient lists}
ObjectReference[] Property IngredientContainerRef Auto
{The containers for each of the corresponding ingredient lists}

; Miscelaneous properties
Message Property IA710_mUninstallMessage  Auto  
{Final instructions to follow to complete uninstallation.}
Spell Property IA710_spFortifyCraftingWeight  Auto  
{Used to remove the spell from the player, in case something went wrong.}
String Property ThousandsSeperator = "," Auto
{The thousands seperator used in formatting the item count numbers. Default: ,}
ObjectReference Property IA710_cRetrieveStorageRef Auto
{Temprarily Holds list specific ingredients while retrieving them}
ObjectReference Property IA710_cBagofHoldingREF Auto
{Container Ref that holds Bag of Holding stored items}
Spell[] Property HandySpellsList Auto
; Handy Spell List is
; [0] = Handy Store and Retrieve Spell
; [1] = Handy Conjure Ghost Mount Spell
; [2] = Handy Teleport Spell
; [3] = Handy Bag of Holding Spell

Actor PlayerRef					; To keep from making repeated calls to Game.GetPlayer()
int current_version = 0
Int[] IngrdientEntryID			; ID numbers to access each of the vanilla ingredient lists/containers
Int OpenCappingContainerID		; ID number to access the Capping container
Int OpenStorageContainerID		; ID number to access the storage container
Int StoreAllIngredientsID		; ID number to start the Store All Ingredients function
Int IsEnabledID					; ID number to enable/disable Handy Crafting
Int EnabledWeightBuffID			; ID number to enable/disable the carry weight buff
Int EnableIngredientCappingID	; ID number to enable/disable ingredient Capping
Int AlwaysShowMessagesID		; ID number to enable/disable container message always showing
Int UninstallHandyCraftingID			; ID number to start uninstalling Handy Crafting
Int RefreshListsID				; ID number to start the Refresh All of the Ingredient Lists
Int AllowInDungeonsID			; ID number to allow Handy Crafting to work on crafting stations in dungeons/wilderness
Int AddStoreIngredientsSpellID	; ID number to add/remove the "Handy Store and Retrieve" spell.
Int AddHandyTeleportSpellID	; ID number to add/remove the "Handy Teleport" spell.
Int AddHandyGhostMountSpellID	; ID number to add/remove the "Handy Conjure Ghost Mount" spell.
Int AddHandyBOHSpellID			; ID number to add/remove the "Handy Bag of Holding" spell.
Int RetrieveAllStoredID		; ID Number to Retrieve all items from all storage main and temporay storage, leaves capping, protected and custom added
int[] HSKeyDefault
int[] HSKeyMap
int[] OID_Hotkey
int HSLMax

; IngredientEntryID indices are
; 0 = Alchemy
; 1 = Carpetnry
; 2 = Cooking
; 3 = Enchanting
; 4 = Milling
; 5 = Smelting
; 6 = Smithing
; 7 = Tanning
; 8 = Tempering
; 9 = Protected

Int Function GetVersion()
	Return 1
EndFunction

String Function GetCustomControl(int keyCode)
	int idx = 0
	while idx < HSLMax
		if (HSKeyMap[idx] == keyCode)
			return "Handy Crafting: " + HandySpellsList[idx].GetName()
		EndIf
		idx += 1
	EndWhile
	return ""
EndFunction

String Function FormatNumber(Int aiNumToFormat)
	String FormattedNumber = aiNumToFormat

	If aiNumToFormat > 0
		If StringUtil.GetLength(FormattedNumber) > 3
			FormattedNumber = StringUtil.SubString(FormattedNumber, 0, StringUtil.GetLength(FormattedNumber) - 3) + ThousandsSeperator + StringUtil.SubString(FormattedNumber, StringUtil.GetLength(FormattedNumber) - 3, 3)
			If StringUtil.GetLength(FormattedNumber) > 7
				FormattedNumber = StringUtil.SubString(FormattedNumber, 0, StringUtil.GetLength(FormattedNumber) - 7) + ThousandsSeperator + StringUtil.SubString(FormattedNumber, StringUtil.GetLength(FormattedNumber) - 7, 7)
			EndIf
		EndIf
		Return FormattedNumber
	Else
		Return ""
	EndIf
EndFunction


; Closes the MCM and System menus. Brings the player back to game mode.
Function CloseMCM()
	UI.Invoke("Journal Menu", "_root.QuestJournalFader.Menu_mc.ConfigPanelClose")
	UI.Invoke("Journal Menu", "_root.QuestJournalFader.Menu_mc.CloseMenu")
	Utility.Wait(0.5)
EndFunction


; Refreshes a formlist with it's associated container
; Used to make sure the formlist contains valid objects
Function RefreshList(FormList aflIngredientList, ObjectReference aorIngredientContainer)
	Int idx = aorIngredientContainer.GetNumItems()
	Form[] ContainerContents = Utility.CreateFormArray(idx)

	While idx > 0
		idx -= 1
		ContainerContents[idx] = aorIngredientContainer.GetNthForm(idx)
	EndWhile
	aflIngredientList.Revert()
	aflIngredientList.Addforms(ContainerContents)
EndFunction


; Returns the total number of items inside a container
Int Function MergeIngredientLists(FormList aflIngredientList)
	Int idx = IngredientsList.Length
	Form[] ConvertedFormlist

	aflIngredientList.Revert()
	While idx > 0
		idx -= 1
		ConvertedFormlist = IngredientsList[idx].ToArray()
		aflIngredientList.AddForms(ConvertedFormlist)
	EndWhile
	Return IA710_cIngredientStorageRef.GetItemCount(aflIngredientList)
EndFunction


event OnVersionUpdate(int version)
	if (version > current_version)
		Debug.Trace(self + ": Updating script to version " + version)
		OnConfigInit()
	endIf
endEvent

Event OnConfigInit()
;	Pages = new string[3]
	Pages[0] = "List Maintenance"
	Pages[1] = "Configuration"
	Pages[2] = "Uninstall"

	PlayerRef = Game.GetPlayer()
	; To keep from making repeated calls to Game.GetPlayer()
	IngrdientEntryID = Utility.CreateIntArray(IngredientsList.Length)
	; Just in case I decide to add or remove ingredient lists
	Int idx = IngredientsList.Length - 1
	; Skip adding Protected Ingredients to the large list.
	Form[] ConvertedFormlist

	IA710_flAllIngredients.Revert()
	While idx > 0
		idx -= 1
		ConvertedFormlist = IngredientsList[idx].ToArray()
		IA710_flAllIngredients.AddForms(ConvertedFormlist)
	EndWhile

	PlayerRef.AddSpell(HandySpellsList[0], abVerbose = False)
	PlayerRef.AddSpell(HandySpellsList[1], abVerbose = False)
	PlayerRef.AddSpell(HandySpellsList[2], abVerbose = False)
	PlayerRef.AddSpell(HandySpellsList[3], abVerbose = False)
	
	; Initialize Hotkey Stuff
	HSLMax = HandySpellsList.Length
	OID_Hotkey = Utility.CreateIntArray(HSLMax, 0)
	int[] tempkeyholding
	; Unregister all keys
	UnregisterForAllKeys()
	; Set Key Defaults
	If (!HSKeyDefault || HSKeyDefault.Length != HSLMax)
		HSKeyDefault = Utility.CreateIntArray(HSLMax, -1)
	endif
	; if HSKeyMap doesn't exist, initialize it, 
	; if it already exists but is the wrong length, preserve the values we can, reinit and fill with old values
	if !HSKeyMap
		HSKeyMap = Utility.CreateIntArray(HSLMax, -1)
	elseIf HSKeyMap.Length != HSLMax
;		TempKeyHolding = Utility.CreateIntArray(HSLMax, -1)
;		idx = HSLMax
;		while idx > 0
;			idx -= 1
;			if idx < HSKeyMap.length
;				TempKeyHolding[idx] = HSKeyMap[idx]
;			else
;				TempKeyHolding[idx] = HSKeyDefault[idx]
;			endif
;		endWhile
		HSKeyMap = Utility.CreateIntArray(HSLMax, -1)
;		HSKeyMap = TempKeyHolding
	endIf
	; Register the hotkeys
;	idx = HSLMax
;	while idx > 0
;		idx -= 1
;		if HSKeyMap[idx] > 1
;			RegisterForKey(HSKeyMap[idx])
;		endIf
;	endwhile
	
	current_version = GetVersion()
	Debug.Notification("Handy Crafting and Spells Initilization Complete")

EndEvent


Event OnGameReload()
	Int idx = IngredientsList.Length
	Form CurrentIngredient

	Parent.OnGameReload()
	While idx > 0
		idx -= 1
		RefreshList(IngredientsList[idx], IngredientContainerRef[idx])
	EndWhile
	idx = IA710_cCappingChestRef.GetNumItems()
	HandyCrafting.CappedIngredientsNum
	HandyCrafting.CappedIngredientsRef = Utility.CreateFormArray(idx)
	HandyCrafting.CappedIngredientsQty = Utility.CreateIntArray(idx)
	While idx > 0
		idx -= 1
		CurrentIngredient = IA710_cCappingChestRef.GetNthForm(idx)
		HandyCrafting.CappedIngredientsRef[idx] = CurrentIngredient
		HandyCrafting.CappedIngredientsQty[idx] = IA710_cCappingChestRef.GetItemCount(CurrentIngredient)
	EndWhile
EndEvent


Event OnConfigOpen()
	Int idx = IngredientsList.Length - 1
	; Skip adding Protected Ingredients to the large list.
	Form[] ConvertedFormlist

	; Merges all of the ingredient formlists into one large list.
	; This is used to quickly store all ingreidents and display how many ingredients are in the storage container.
	IA710_flAllIngredients.Revert()
	While idx > 0
		idx -= 1
		ConvertedFormlist = IngredientsList[idx].ToArray()
		IA710_flAllIngredients.AddForms(ConvertedFormlist)
	EndWhile
	; Some basic maintenance.
	PlayerRef.RemoveSpell(IA710_spFortifyCraftingWeight)
	; Remove the carry weight buff if the player has it on him/her
	IA710_cTemporaryHoldingRef.RemoveAllItems(PlayerRef)
	; This container should always be empty, but just to be safe
	IA710_cRetrieveStorageRef.RemoveAllItems(PlayerRef)
	; This container should also always be empty, but just to be safe
EndEvent


Event OnPageReset(String a_Page)
	If (a_page == "")
		OnPageReset("List Maintenance")
		; Load List Maintenance page
	ElseIf	(a_page == "List Maintenance")
		SetCursorFillMode (LEFT_TO_RIGHT)
		SetTitleText("$The_HandyCrafting_Title")
		Utility.WaitMenuMode(0.1)
		; Show all the ingredient lists on the left side of the page, maintenance and options on the right side.
		; The two sides are mixed together, so good luck trying to make sense of it. :P - I created several pages and split it -IA710
		AddHeaderOption("$Ingredients_Lists")
		AddHeaderOption("$Maintenance")
		IngrdientEntryID[0] = AddTextOption("$Alchemy_Ingredients", FormatNumber(IngredientContainerRef[0].GetNumItems()))
		OpenStorageContainerID = AddTextOption("$Open_Storage_Container", FormatNumber(IA710_cIngredientStorageRef.GetItemCount( IA710_flAllIngredients)))
		IngrdientEntryID[1] = AddTextOption("$Carpentry_Ingredients", FormatNumber(IngredientContainerRef[1].GetNumItems()))
		StoreAllIngredientsID = AddTextOption("$Store_All_Ingredients", "")
		IngrdientEntryID[2] = AddTextOption("$Cooking_Ingredients", FormatNumber(IngredientContainerRef[2].GetNumItems()))
		RetrieveAllStoredID = AddTextOption("$Retrieve_All_Items", "")
		SetCursorFillMode (TOP_TO_BOTTOM)
		IngrdientEntryID[3] = AddTextOption("$Enchanting_Ingredients", FormatNumber(IngredientContainerRef[3].GetNumItems()))
		IngrdientEntryID[4] = AddTextOption("$Milling_Ingredients", FormatNumber(IngredientContainerRef[4].GetNumItems()))
		IngrdientEntryID[5] = AddTextOption("$Smelting_Ingredients", FormatNumber(IngredientContainerRef[5].GetNumItems()))
		IngrdientEntryID[6] = AddTextOption("$Smithing_Ingredients", FormatNumber(IngredientContainerRef[6].GetNumItems()))
		IngrdientEntryID[7] = AddTextOption("$Tanning_Ingredients", FormatNumber(IngredientContainerRef[7].GetNumItems()))
		IngrdientEntryID[8] = AddTextOption("$Tempering_Ingredients", FormatNumber(IngredientContainerRef[8].GetNumItems()))
		IngrdientEntryID[9] = AddTextOption("$Protected_Ingredients", FormatNumber(IngredientContainerRef[9].GetNumItems()))
		OpenCappingContainerID = AddTextOption("$Capped_Ingredients", FormatNumber(IA710_cCappingChestRef.GetNumItems()))

	ElseIf (a_page == "Configuration")
		SetCursorFillMode (LEFT_TO_RIGHT)
		SetTitleText("$The_HandyCrafting_Title")
		AddHeaderOption("$Options")
		AddHeaderOption ("$Add_Spells_Header")
		IsEnabledID = AddToggleOption("$Enable_HandyCrafting", HandyCrafting.HandyCraftingEnabled)
		AddStoreIngredientsSpellID = AddToggleOption("$Add_Store_Ingredients_Power", PlayerRef.HasSpell(HandySpellsList[0]))
		AllowInDungeonsID = AddToggleOption("$Restricted_Mode", !HandyCrafting.AllowInDungeons)
		AddHandyGhostMountSpellID = AddToggleOption ("$Add_Handy_Mount_Spell", PlayerRef.HasSpell(HandySpellsList[1]))
		EnableIngredientCappingID = AddToggleOption("$Enable_Capping", HandyCrafting.EnableCapping)
		AddHandyTeleportSpellID = AddToggleOption("$Add_Handy_Teleport_Spell", PlayerRef.HasSpell(HandySpellsList[2]))
		EnabledWeightBuffID = AddToggleOption("$Increase_Carry_Weight_while_Crafting", HandyCrafting.CraftingWeightBuffEnabled)
		AddHandyBOHSpellID = AddToggleOption("$Add_Handy_BOH_Spell", PlayerRef.HasSpell(HandySpellsList[3]))
		AlwaysShowMessagesID = AddToggleOption("$Always_Show_Messages", HandyCrafting.AlwaysShowMessages)
		SetCursorFillMode(TOP_TO_BOTTOM)
		AddEmptyOption()
		AddHeaderOption("$Add_Handy_Hotkeys")
		int idx = 0
		while (idx < HSLMax)
			OID_Hotkey[idx] = AddKeyMapOption(HandySpellsList[idx].GetName() + " Hotkey", HSKeyMap[idx])
			idx += 1
		endwhile

	ElseIf (a_page == "Uninstall")
		SetCursorFillMode (TOP_TO_BOTTOM)
		SetTitleText("$The_HandyCrafting_Title")	
		AddHeaderOption("$Uninstall")
		UninstallHandyCraftingID = AddTextOption("$Uninstall_HandyCrafting", "")		
		AddEmptyOption()
		AddHeaderOption("Troubleshooting")
		RefreshListsID = AddTextOption("Reinitialize and Refresh all lists", "")
	EndIf
EndEvent


Event OnOptionHighlight(Int OptionID)
	If OptionID == IngrdientEntryID[0]
		SetInfoText("$Alchemy_Description")
	ElseIf OptionID == IngrdientEntryID[1]
		SetInfoText("$Carpentry_Description")
	ElseIf OptionID == IngrdientEntryID[2]
		SetInfoText("$Cooking_Description")
	ElseIf OptionID == IngrdientEntryID[3]
		SetInfoText("$Enchanting_Description")
	ElseIf OptionID == IngrdientEntryID[4]
		SetInfoText("$Milling_Description")
	ElseIf OptionID == IngrdientEntryID[5]
		SetInfoText("$Smelting_Description")
	ElseIf OptionID == IngrdientEntryID[6]
		SetInfoText("$Smithing_Description")
	ElseIf OptionID == IngrdientEntryID[7]
		SetInfoText("$Tanning_Description")
	ElseIf OptionID == IngrdientEntryID[8]
		SetInfoText("$Tempering_Description")
	ElseIf OptionID == IngrdientEntryID[9]
		SetInfoText("$Protected_Description")
	ElseIf OptionID == OpenCappingContainerID
		SetInfoText("$Capped_Description")
	ElseIf OptionID == OpenStorageContainerID
		SetInfoText("$Open_Storage_Container_Description")
	ElseIf OptionID == StoreAllIngredientsID
		SetInfoText("$Store_All_Ingredients_Description")
	ElseIf OptionID == IsEnabledID
		SetInfoText("$Enable/Disable_Description")
	ElseIF OptionID == AllowInDungeonsID
		SetInfoText("$Restricted_Mode_Description")
	ElseIf OptionID == EnableIngredientCappingID
		SetInfoText("$Enable_Capping_Description")
	ElseIf OptionID == AlwaysShowMessagesID
		SetInfoText("$Always_Show_Messages_Description")
	Elseif OptionID == EnabledWeightBuffID
		SetInfoText("$Enable_Weight_Buff_Description")
	ElseIf OptionID == UninstallHandyCraftingID
		SetInfoText("$Uninstall_Description")
	ElseIf OptionID == AddStoreIngredientsSpellID
		SetInfoText("$Add_Store_Ingedients_Power_Description")
	ElseIf OptionID == AddHandyTeleportSpellID
		SetInfoText("$Add_Handy_Teleport_Spell_Description")
	ElseIf OptionID == AddHandyGhostMountSpellID
		SetInfoText("$Add_Handy_Mount_Spell_Description")
	ElseIf OptionID == AddHandyBOHSpellID
		SetInfoText("$Add_Handy_BOH_Spell_Description")
	ElseIf OptionID == RetrieveAllStoredID
		SetInfoText("$Retrieve_All_Items_Description")
	Else
		int idx = 0
		while idx < HSLMax
			If (OptionID == OID_Hotkey[idx])
				SetInfoText("$Set_Handy_Hotkey")
			EndIf
			idx += 1
		EndWhile
	EndIf
EndEvent


Event  OnOptionDefault(Int OptionID)
	If OptionID == IsEnabledID
		HandyCrafting.HandyCraftingEnabled = True
		SetToggleOptionValue(OptionID, HandyCrafting.HandyCraftingEnabled)
	ElseIf OptionID == AllowInDungeonsID
		HandyCrafting.AllowInDungeons = True
		SetToggleOptionValue(OptionID, !HandyCrafting.AllowInDungeons)
	ElseIf OptionID == EnabledWeightBuffID
		HandyCrafting.CraftingWeightBuffEnabled = True
		SetToggleOptionValue(OptionID, HandyCrafting.CraftingWeightBuffEnabled)
	ElseIf OptionID == EnableIngredientCappingID
		HandyCrafting.EnableCapping = True
		SetToggleOptionValue(OptionID, HandyCrafting.EnableCapping)
	ElseIf OptionID == AlwaysShowMessagesID
		HandyCrafting.AlwaysShowMessages = True
		SetToggleOptionValue(OptionID, HandyCrafting.AlwaysShowMessages)
	ElseIf OptionID == AddStoreIngredientsSpellID
		If !PlayerRef.HasSpell(HandySpellsList[0])
			PlayerRef.AddSpell(HandySpellsList[0])
		EndIf
		SetToggleOptionValue(AddStoreIngredientsSpellID, True)
	ElseIf OptionID == AddHandyTeleportSpellID
		If !PlayerRef.HasSpell(HandySpellsList[2])
			PlayerRef.AddSpell(HandySpellsList[2])
		EndIf
		SetToggleOptionValue(AddHandyTeleportSpellID, True)
	ElseIf OptionID == AddHandyGhostMountSpellID
		If !PlayerRef.HasSpell(HandySpellsList[1])
			PlayerRef.AddSpell(HandySpellsList[1])
		EndIf
		SetToggleOptionValue(AddHandyGhostMountSpellID, True)
	ElseIf OptionID == AddHandyBOHSpellID
		If !PlayerRef.HasSpell(HandySpellsList[3])
			PlayerRef.AddSpell(HandySpellsList[3])
		EndIf
		SetToggleOptionValue(AddHandyBOHSpellID, True)
	Else
		int idx = 0
		while idx < HSLMax
			If (OptionID == OID_Hotkey[idx])
				UnregisterForKey(HSKeyMap[idx])
				SetKeyMapOptionValue(OptionID, -1)
				HSKeyMap[idx] = -1
			EndIf
			idx += 1
		EndWhile
	EndIf
EndEvent


Event OnOptionSelect(Int OptionID)
	Int idx
	Form IngredientToCap
	Int QuantityToCap
	Form CurrentIngredient

	If OptionID == UninstallHandyCraftingID
	; Handle the uninstall option
		If ShowMessage("$Confirm_Uninstall")
			CloseMCM()
			HandyCrafting.ShutDown()
			UnregisterForAllKeys()
			PlayerRef.RemoveSpell(HandySpellsList[2])
			PlayerRef.RemoveSpell(HandySpellsList[3])
			IA710_cBagofHoldingREF.RemoveAllItems(PlayerRef)
			PlayerRef.RemoveSpell(HandySpellsList[1])	
			PlayerRef.RemoveSpell(HandySpellsList[0])
			IA710_cRetrieveStorageRef.RemoveAllItems(PlayerRef)
			IA710_cIngredientStorageRef.RemoveAllItems(PlayerRef)
			IA710_cTemporaryHoldingRef.RemoveAllItems(PlayerRef)
			idx = IngredientContainerRef.Length
			While idx > 0
				idx -= 1
				IngredientContainerRef[idx].RemoveAllItems()
			EndWhile
			IA710_mUninstallMessage.Show()
			Self.Stop()
		EndIf
	; Handle Troubleshooting
	ElseIf OptionID == RefreshListsID
		OnConfigInit()
		idx = IngredientsList.Length
		While idx > 0
			idx -= 1
			RefreshList(IngredientsList[idx], IngredientContainerRef[idx])
		EndWhile
		idx = IA710_cCappingChestRef.GetNumItems()
		HandyCrafting.CappedIngredientsNum
		HandyCrafting.CappedIngredientsRef = Utility.CreateFormArray(idx)
		HandyCrafting.CappedIngredientsQty = Utility.CreateIntArray(idx)
		While idx > 0
			idx -= 1
			CurrentIngredient = IA710_cCappingChestRef.GetNthForm(idx)
			HandyCrafting.CappedIngredientsRef[idx] = CurrentIngredient
			HandyCrafting.CappedIngredientsQty[idx] = IA710_cCappingChestRef.GetItemCount(CurrentIngredient)
		EndWhile
		OnConfigOpen()
		ShowMessage("Reinitialized MCM and Refreshed all lists.", False)
	; Handle the toggled options
	ElseIf OptionID == IsEnabledID
		HandyCrafting.HandyCraftingEnabled = !HandyCrafting.HandyCraftingEnabled
		SetToggleOptionValue(OptionID, HandyCrafting.HandyCraftingEnabled)
	ElseIf OptionID == AllowInDungeonsID
	; Handle the Allow in Dungeons/Wilderness option
		HandyCrafting.AllowInDungeons = !HandyCrafting.AllowInDungeons
		SetToggleOptionValue(OptionID, !HandyCrafting.AllowInDungeons)
	ElseIf OptionID == EnabledWeightBuffID
		HandyCrafting.CraftingWeightBuffEnabled = !HandyCrafting.CraftingWeightBuffEnabled
		SetToggleOptionValue(OptionID, HandyCrafting.CraftingWeightBuffEnabled)
	ElseIf OptionID == EnableIngredientCappingID
		HandyCrafting.EnableCapping = !HandyCrafting.EnableCapping
		SetToggleOptionValue(OptionID, HandyCrafting.EnableCapping)
	ElseIf OptionID == AlwaysShowMessagesID
		HandyCrafting.AlwaysShowMessages = !HandyCrafting.AlwaysShowMessages
		SetToggleOptionValue(OptionID, HandyCrafting.AlwaysShowMessages)
	ElseIf OptionID == AddStoreIngredientsSpellID
		If !PlayerRef.HasSpell(HandySpellsList[0])
			PlayerRef.AddSpell(HandySpellsList[0], abVerbose = False)
		Else
			PlayerRef.RemoveSpell(HandySpellsList[0])
			IA710_cRetrieveStorageRef.RemoveAllItems(PlayerRef)
		EndIf
		SetToggleOptionValue(AddStoreIngredientsSpellID, PlayerRef.HasSpell(HandySpellsList[0]))
	ElseIf OptionID == AddHandyTeleportSpellID
		If !PlayerRef.HasSpell(HandySpellsList[2])
			PlayerRef.AddSpell(HandySpellsList[2], abVerbose = False)
		Else
			PlayerRef.RemoveSpell(HandySpellsList[2])
		EndIf
		SetToggleOptionValue(AddHandyTeleportSpellID, PlayerRef.HasSpell(HandySpellsList[2]))
	ElseIf OptionID == AddHandyGhostMountSpellID
		If !PlayerRef.HasSpell(HandySpellsList[1])
			PlayerRef.AddSpell(HandySpellsList[1], abVerbose = False)
		Else
			PlayerRef.RemoveSpell(HandySpellsList[1])
		EndIf
		SetToggleOptionValue(AddHandyGhostMountSpellID, PlayerRef.HasSpell(HandySpellsList[1]))
	ElseIf OptionID == AddHandyBOHSpellID
		If !PlayerRef.HasSpell(HandySpellsList[3])
			PlayerRef.AddSpell(HandySpellsList[3], abVerbose = False)
		Else
			PlayerRef.RemoveSpell(HandySpellsList[3])
			IA710_cBagofHoldingREF.RemoveAllItems(PlayerRef)
		EndIf
		SetToggleOptionValue(AddHandyBOHSpellID, PlayerRef.HasSpell(HandySpellsList[3]))
	ElseIf OptionID == OpenCappingContainerID	
	; Handle accessing the Capping container
		CloseMCM()
		IA710_cCappingChestRef.AddInventoryEventFilter(IA710_flAllIngredients)
		IA710_cCappingChestRef.Activate(PlayerRef)
	ElseIf OptionID == OpenStorageContainerID
	; Handle accessing the storage container
		CloseMCM()
		IA710_cIngredientStorageRef.Activate(PlayerRef)
	ElseIf OptionID == StoreAllIngredientsID
	; Handle the Store All Ingredients option
		; Retreive all the items in the storage container
		IA710_cIngredientStorageRef.RemoveAllItems(PlayerRef)
		; Store any Protected ingredients in the temporary container
		PlayerRef.RemoveItem(IngredientsList[9], PlayerRef.GetItemCount(IngredientsList[9]), abSilent = True, akOtherContainer = IA710_cTemporaryHoldingRef)
		; Search through the capped ingredients list for excess ingredients in the player's inventory
		idx = IA710_cCappingChestRef.GetNumItems()
		While idx > 0
			idx -= 1
			IngredientToCap = IA710_cCappingChestRef.GetNthForm(idx)
			QuantityToCap = PlayerRef.GetItemCount(IngredientToCap) - IA710_cCappingChestRef.GetItemCount(IngredientToCap)
			; Set any excess ingredients aside in the temporary holding container
			If QuantityToCap > 0
				PlayerRef.RemoveItem(IngredientToCap, QuantityToCap, abSilent = True, akOtherContainer = IA710_cTemporaryHoldingRef)
			EndIf
		EndWhile
		; Store all the remaining ingredients 
		PlayerRef.RemoveItem(IA710_flAllIngredients, PlayerRef.GetItemCount(IA710_flAllIngredients), abSilent = True, akOtherContainer = IA710_cIngredientStorageRef)
		; Retreive the Protected items from the temporary holding container
		IA710_cTemporaryHoldingRef.RemoveAllItems(PlayerRef)
		ShowMessage("$Ingredients_Stored", False)
		SetTextOptionValue(OpenStorageContainerID, FormatNumber(IA710_cIngredientStorageRef.GetItemCount(IA710_flAllIngredients)))
	ElseIf OptionID == RetrieveAllStoredID
		IA710_cBagofHoldingREF.RemoveAllItems(PlayerRef)
		IA710_cRetrieveStorageRef.RemoveAllItems(PlayerRef)
		IA710_cIngredientStorageRef.RemoveAllItems(PlayerRef)
		IA710_cTemporaryHoldingRef.RemoveAllItems(PlayerRef)
		SetTextOptionValue(OpenStorageContainerID, FormatNumber(IA710_cIngredientStorageRef.GetItemCount(IA710_flAllIngredients)))
		ShowMessage("$All_Items_Retrieved", False)
	; Handle accessing the ingredient containers
	Else
		idx = IngredientsList.Length
		While idx > 0
			idx -= 1
			If OptionID == IngrdientEntryID[idx]
				CloseMCM()
				IngredientContainerRef[idx].Activate(PlayerRef)
				idx = 0
			EndIf
		EndWhile
	EndIf
EndEvent

event OnOptionKeyMapChange(int option, int keyCode, string conflictControl, string conflictName)
	{Called when a key has been remapped}
	int idx = 0
	while idx < HSLMax
		If (option == OID_Hotkey[idx])
			bool continue = true
			if (keyCode != 1 && conflictControl != "")
				string msg
				if (conflictName != "")
					msg = "This key is already mapped to:\n\"" + conflictControl + "\"\n(" + conflictName + ")\n\nAre you sure you want to continue?"
				else
					msg = "This key is already mapped to:\n\"" + conflictControl + "\"\n\nAre you sure you want to continue?"
				endIf

				continue = ShowMessage(msg, true, "$Yes", "$No")
			endIf
			
			If continue
				UnregisterForKey(HSKeyMap[idx])
				if keyCode != 1
					RegisterForKey(keyCode)
					HSKeyMap[idx] = keyCode
				EndIf
				SetKeyMapOptionValue(option, keyCode)
			EndIf
		EndIf
		idx += 1
	EndWhile
endEvent

Event OnKeyDown(int keycode)
  if (keyCode != 1 && SafeProcess() == True)
    int idx = 0
    while idx < HSLMax
      GoToState("Busy") ; prevent the event from piling up with multiple key presses
      If (keyCode == HSKeyMap[idx])
        ; Debug.Notification("HCaS Casting: " + HandySpellsList[idx].GetName())
        HandySpellsList[idx].Cast(PlayerRef)
        idx = HSLMax ; got what we need - get out
        GoToState("") ; return to the empty state
      EndIf
      idx += 1
    endWhile
  EndIf
EndEvent
 
Bool Function SafeProcess()
  If (!Utility.IsInMenuMode()) \
  && (!UI.IsMenuOpen("Dialogue Menu")) \
  && (!UI.IsMenuOpen("Console")) \
  && (!UI.IsMenuOpen("Crafting Menu")) \
  && (!UI.IsMenuOpen("MessageBoxMenu")) \
  && (!UI.IsMenuOpen("ContainerMenu")) \
  && (!UI.IsTextInputEnabled()) \
  && (!PlayerRef.IsOnMount())
    ;IsInMenuMode to block when game is paused with menus open
    ;Dialogue Menu check to block when dialog is open
    ;Console check to block when console is open - console does not trigger IsInMenuMode and thus needs its own check
    ;Crafting Menu check to block when crafting menus are open - game is not paused so IsInMenuMode does not work
    ;MessageBoxMenu check to block when message boxes are open - while they pause the game, they do not trigger IsInMenuMode
    ;ContainerMenu check to block when containers are accessed - while they pause the game, they do not trigger IsInMenuMode
    ;IsTextInputEnabled check to block when editable text fields are open
    ;IsInCombat check to block when combat is going on.
    ;IsOnMount check to block when riding a horse
    Return True
  Else
    Debug.Notification("Unable to process mod hot key at this time.")
    Return False
  EndIf
EndFunction
 
State Busy
  Event OnKeyDown(int keycode)
    ;do nothing
  EndEvent
EndState

 

 

 

I have a lot of stuff in the onconfiginit commented out that I may want to re--enable if we get this working so assigned keys would be preserved on version update, I commented it for the last test to just make sure the variables inited correctly.

 

You are so kind to help me, I can't thank you enough!

 

-IA710

Link to comment
Share on other sites

Well, I want to thank you for all the help and examples you've given me, I'm better for it, and I can't thank you enough.

 

I'm going to keep messing with it, maybe implement the state method on the MCM script and see how that effects it. I may downgrade AE to 1.5.97 on my laptop and try it on it to rule out something funny with my install on this machine. I'm mid-playthrough on the install on this machine and so have it frozen, maybe it's something peculiar to this machine?

 

I'll let you know if I figure anything out.

 

Thank you!

 

-IA710

Link to comment
Share on other sites

IA710 wrote: "Went back to the minimal build that has the current version with hotkeys, COC Riverwood, went into MCM and assigned a hotkey and then just stood there, didn't touch anything and it froze before it started spinning. Maybe hotkeys just weren't meant to be. Really frustrating though."

 

Its importent to understand that Skyrim SE and Skyrim AE require a different version of SKSE64. There are enough threads here in forums on Skyrim Nexus.

 

About your MCM script. Try to avoid redundancy in code to make it better maintanable. Use more functions to compact your event codes. The following script is made for studying, not compiled yet.

 

IA710_HandyCrafting_MCM_Script

 

Scriptname IA710_HandyCrafting_MCM_Script extends SKI_ConfigBase
; https://forums.nexusmods.com/index.php?/topic/10792698-need-help-adding-hotkeys-to-mcm/page-2

  IA710_HandyCraftingScript PROPERTY HandyCrafting auto      ; pointer to script "IA710_HandyCraftingScript.psc"

  Message PROPERTY IA710_mUninstallMessage       auto        ; {Final instructions to follow to complete uninstallation.}
  Spell   PROPERTY IA710_spFortifyCraftingWeight auto        ; {Used to remove the spell from the player, in case something went wrong.}

  Spell[] PROPERTY HandySpellsList auto                      ; Array with spell lists as follow:
    ; [0] = Handy Store and Retrieve Spell
    ; [1] = Handy Conjure Ghost Mount Spell
    ; [2] = Handy Teleport Spell
    ; [3] = Handy Bag of Holding Spell

;These need to be filled with the formlists and container references.

  FormList   PROPERTY IA710_flAllIngredients auto            ; {Holds all of the ingredients from the other lists.}
  FormList[] PROPERTY IngredientsList        auto            ; {Contains all the vanilla ingredient lists}

  ObjectReference PROPERTY IA710_cIngredientStorageRef auto    ; {Master container hold all the stored ingredients.}
  ObjectReference PROPERTY IA710_cTemporaryHoldingRef  auto    ; {Container that holds Protected ingredients while the player is crafting.}
  ObjectReference PROPERTY IA710_cCappingChestRef      auto    ; {Container tha holds the Capping ingredients list.}

  ObjectReference PROPERTY IA710_cBagofHoldingREF      auto    ; {Container Ref that holds Bag of Holding stored items}
  ObjectReference PROPERTY IA710_cRetrieveStorageRef   auto    ; {Temprarily Holds list specific ingredients while retrieving them}

  ObjectReference[] PROPERTY IngredientContainerRef auto       ; {The containers for each of the corresponding ingredient lists}

  String PROPERTY ThousandsSeperator = "," auto                ; {The thousands seperator used in formatting the item count numbers. Default: ,}

; ID numbers to
  Int OpenCappingContainerID        ; access the Capping container
  Int OpenStorageContainerID        ; access the storage container

  Int IsEnabledID                   ; enable/disable Handy Crafting
  Int EnabledWeightBuffID           ; enable/disable the carry weight buff
  Int EnableIngredientCappingID     ; enable/disable ingredient Capping
  Int AlwaysShowMessagesID          ; enable/disable container message always showing

  Int AllowInDungeonsID             ; allow Handy Crafting to work on crafting stations in dungeons/wilderness
  Int AddStoreIngredientsSpellID    ; add/remove the "Handy Store and Retrieve" spell.
  Int AddHandyTeleportSpellID       ; add/remove the "Handy Teleport" spell.
  Int AddHandyGhostMountSpellID     ; add/remove the "Handy Conjure Ghost Mount" spell.
  Int AddHandyBOHSpellID            ; add/remove the "Handy Bag of Holding" spell.

  Int RefreshListsID                ; start the Refresh All of the Ingredient Lists
  Int StoreAllIngredientsID         ; start the Store All Ingredients function
  Int UninstallHandyCraftingID      ; start uninstalling Handy Crafting
  Int RetrieveAllStoredID           ; retrieve all items from all storage main and temporay storage, leaves capping, protected and custom added

  Int[] HSKeyDefault
  Int[] HSKeyMap
  Int[] OID_Hotkey

  Int[] IngrdientEntryID            ; ID numbers to access each of the vanilla ingredient lists/containers
    ; IngredientEntryID indices are
    ; 0 = Alchemy
    ; 1 = Carpentry
    ; 2 = Cooking
    ; 3 = Enchanting
    ; 4 = Milling
    ; 5 = Smelting
    ; 6 = Smithing
    ; 7 = Tanning
    ; 8 = Tempering
    ; 9 = Protected

  Int HSLMax
  Int current_version = 0

 ;Actor PlayerRef                    ; to keep from making repeated calls to Game.GetPlayer()


;------------------------
Int FUNCTION GetVersion()
;------------------------
    RETURN 1
ENDFUNCTION


;------------------
FUNCTION CloseMCM()  ; Closes the MCM and System menus. Brings the player back to game mode.
;------------------
    UI.Invoke("Journal Menu", "_root.QuestJournalFader.Menu_mc.ConfigPanelClose")
    UI.Invoke("Journal Menu", "_root.QuestJournalFader.Menu_mc.CloseMenu")

    Utility.Wait(0.5)
ENDFUNCTION


; -- EVENTs -- 10 + "Busy"

EVENT OnVersionUpdate(Int version)
;====================
IF (version > current_version)
    Debug.Trace(" OnVersionUpdate() - is updating the script to version " +version+ " -- " +self)
    OnConfigInit()
ENDIF
ENDEVENT


EVENT OnConfigInit()
;=================
;    Pages = new string[3]
    Pages[0] = "List Maintenance"
    Pages[1] = "Configuration"
    Pages[2] = "Uninstall"

; Just in case I decide to add or remove ingredient lists

    IngrdientEntryID = Utility.CreateIntArray( IngredientsList.Length )    
    myF_Revert()

    actor player = Game.GetPlayer()
    player.AddSpell(HandySpellsList[0], abVerbose = False)
    player.AddSpell(HandySpellsList[1], abVerbose = False)
    player.AddSpell(HandySpellsList[2], abVerbose = False)
    player.AddSpell(HandySpellsList[3], abVerbose = False)

; Unregister all keys
    UnregisterForAllKeys()

; Initialize Hotkey Stuff
    HSLMax     = HandySpellsList.Length
    OID_Hotkey = Utility.CreateIntArray(HSLMax, 0)

; Set Key Defaults
    IF (!HSKeyDefault) || (HSLMax != HSKeyDefault.Length)
        HSKeyDefault = Utility.CreateIntArray(HSLMax, -1)
    ENDIF

; if HSKeyMap does not exist, initialize it,
; if it already exists but is the wrong length, preserve the values we can, reinit and fill with old values

    IF ( !HSKeyMap )
        HSKeyMap = Utility.CreateIntArray(HSLMax, -1)

    ELSEIF (HSKeyMap.Length != HSLMax)
;---------
;        int[] tempkeyholding
;        TempKeyHolding = Utility.CreateIntArray(HSLMax, -1)
;        i = HSLMax
;        while i > 0
;            i -= 1
;            if i < HSKeyMap.length
;                TempKeyHolding[i] = HSKeyMap[i]
;            else
;                TempKeyHolding[i] = HSKeyDefault[i]
;            endif
;        endWhile
;         HSKeyMap = TempKeyHolding
;---------
        HSKeyMap = Utility.CreateIntArray(HSLMax, -1)
    ENDIF

; Register the hotkeys
;    i = HSLMax
;    while i > 0
;        i -= 1
;        if HSKeyMap[i] > 1
;            RegisterForKey(HSKeyMap[i])
;        endIf
;    endwhile
    
    current_version = GetVersion()
    Debug.Notification("Handy Crafting and Spells Initilization Complete")
ENDEVENT


EVENT OnConfigOpen()
;=================
; Merges all of the ingredient formlists into one large list.
; This is used to quickly store all ingredients and display how many ingredients are in the storage container.
    myF_Revert()

; Some basic maintenance.
    actor player = Game.GetPlayer()
    player.RemoveSpell(IA710_spFortifyCraftingWeight)    ; Remove the carry weight buff if the player has it on him/her
    IA710_cTemporaryHoldingRef.RemoveAllItems(player)    ; This container should always be empty, but just to be safe
    IA710_cRetrieveStorageRef.RemoveAllItems(player)     ; This container should also always be empty, but just to be safe
ENDEVENT


EVENT OnGameReload()
;=================
    parent.OnGameReload()        ; see "SKI_ConfigBase.psc"
    myF_Refresh()
ENDEVENT


EVENT OnPageReset(String a_Page)
;================
IF (a_page == "")
    OnPageReset("List Maintenance")
    RETURN    ; - STOP -    recursive call with "Maintenance page"
ENDIF
;---------------------
IF (a_page == "List Maintenance")
    SetCursorFillMode (LEFT_TO_RIGHT)
    SetTitleText("$The_HandyCrafting_Title")
    Utility.WaitMenuMode(0.1)

    ; Show all the ingredient lists on the left side of the page, maintenance and options on the right side.
    ; The two sides are mixed together, so good luck trying to make sense of it. :P - I created several pages and split it -IA710

    AddHeaderOption("$Ingredients_Lists")
    AddHeaderOption("$Maintenance")

    IngrdientEntryID[0] = AddTextOption("$Alchemy_Ingredients", FormatNumber( IngredientContainerRef[0].GetNumItems() ))
    OpenStorageContainerID = AddTextOption("$Open_Storage_Container", FormatNumber(IA710_cIngredientStorageRef.GetItemCount( IA710_flAllIngredients )))

    IngrdientEntryID[1] = AddTextOption("$Carpentry_Ingredients", FormatNumber(IngredientContainerRef[1].GetNumItems()))
    StoreAllIngredientsID = AddTextOption("$Store_All_Ingredients", "")

    IngrdientEntryID[2] = AddTextOption("$Cooking_Ingredients", FormatNumber(IngredientContainerRef[2].GetNumItems()))
    RetrieveAllStoredID = AddTextOption("$Retrieve_All_Items", "")
    SetCursorFillMode (TOP_TO_BOTTOM)

    IngrdientEntryID[3] = AddTextOption("$Enchanting_Ingredients",FormatNumber(IngredientContainerRef[3].GetNumItems()))
    IngrdientEntryID[4] = AddTextOption("$Milling_Ingredients",   FormatNumber(IngredientContainerRef[4].GetNumItems()))
    IngrdientEntryID[5] = AddTextOption("$Smelting_Ingredients",  FormatNumber(IngredientContainerRef[5].GetNumItems()))
    IngrdientEntryID[6] = AddTextOption("$Smithing_Ingredients",  FormatNumber(IngredientContainerRef[6].GetNumItems()))
    IngrdientEntryID[7] = AddTextOption("$Tanning_Ingredients",   FormatNumber(IngredientContainerRef[7].GetNumItems()))
    IngrdientEntryID[8] = AddTextOption("$Tempering_Ingredients", FormatNumber(IngredientContainerRef[8].GetNumItems()))
    IngrdientEntryID[9] = AddTextOption("$Protected_Ingredients", FormatNumber(IngredientContainerRef[9].GetNumItems()))

    OpenCappingContainerID = AddTextOption("$Capped_Ingredients", FormatNumber( IA710_cCappingChestRef.GetNumItems() ))
    RETURN    ; - STOP -
ENDIF
;---------------------
IF (a_page == "Configuration")
    SetCursorFillMode (LEFT_TO_RIGHT)
    SetTitleText("$The_HandyCrafting_Title")
    AddHeaderOption("$Options")
    AddHeaderOption ("$Add_Spells_Header")

    actor player = Game.GetPlayer()

    IsEnabledID                = AddToggleOption("$Enable_HandyCrafting", HandyCrafting.HandyCraftingEnabled)
    AddStoreIngredientsSpellID = AddToggleOption("$Add_Store_Ingredients_Power", player.HasSpell(HandySpellsList[0]))
    AllowInDungeonsID          = AddToggleOption("$Restricted_Mode", !HandyCrafting.AllowInDungeons)
    AddHandyGhostMountSpellID  = AddToggleOption("$Add_Handy_Mount_Spell", player.HasSpell(HandySpellsList[1]))
    EnableIngredientCappingID  = AddToggleOption("$Enable_Capping", HandyCrafting.EnableCapping)
    AddHandyTeleportSpellID    = AddToggleOption("$Add_Handy_Teleport_Spell", player.HasSpell(HandySpellsList[2]))
    EnabledWeightBuffID        = AddToggleOption("$Increase_Carry_Weight_while_Crafting", HandyCrafting.CraftingWeightBuffEnabled)
    AddHandyBOHSpellID         = AddToggleOption("$Add_Handy_BOH_Spell", player.HasSpell(HandySpellsList[3]))
    AlwaysShowMessagesID       = AddToggleOption("$Always_Show_Messages", HandyCrafting.AlwaysShowMessages)
    SetCursorFillMode(TOP_TO_BOTTOM)

    AddEmptyOption()
    AddHeaderOption("$Add_Handy_Hotkeys")

    int i = 0
    WHILE (i < HSLMax)
        OID_Hotkey[i] = AddKeyMapOption(HandySpellsList[i].GetName() + " Hotkey", HSKeyMap[i])
        i = i + 1
    ENDWHILE
    RETURN    ; - STOP -
ENDIF
;---------------------
IF (a_page == "Uninstall")
    SetCursorFillMode (TOP_TO_BOTTOM)
    SetTitleText("$The_HandyCrafting_Title")    
    AddHeaderOption("$Uninstall")

    UninstallHandyCraftingID = AddTextOption("$Uninstall_HandyCrafting", "")        
    AddEmptyOption()
    AddHeaderOption("Troubleshooting")
    RefreshListsID = AddTextOption("Reinitialize and Refresh all lists", "")
ENDIF
ENDEVENT


EVENT OnOptionSelect(Int OptionID)
;===================
    actor player = Game.GetPlayer()
    int  i

IF OptionID == UninstallHandyCraftingID                    ; Handle the uninstall option
    IF ShowMessage("$Confirm_Uninstall")
        CloseMCM()
        HandyCrafting.ShutDown()
        UnregisterForAllKeys()

        player.RemoveSpell(HandySpellsList[3])
        player.RemoveSpell(HandySpellsList[2])
        player.RemoveSpell(HandySpellsList[1])
        player.RemoveSpell(HandySpellsList[0])

        IA710_cBagofHoldingREF.RemoveAllItems(player)
        IA710_cRetrieveStorageRef.RemoveAllItems(player)
        IA710_cIngredientStorageRef.RemoveAllItems(player)
        IA710_cTemporaryHoldingRef.RemoveAllItems(player)

        i = IngredientContainerRef.Length
        WHILE (i > 0)
            i = i - 1
            IngredientContainerRef[i].RemoveAllItems()
        ENDWHILE

        IA710_mUninstallMessage.Show()
        self.Stop()                                      ; STOP the QUEST
    ENDIF
    RETURN    ; - STOP -
ENDIF
;---------------------
IF OptionID == RefreshListsID                            ; Handle Troubleshooting
    OnConfigInit()
    myF_Refresh()
    OnConfigOpen()
    ShowMessage("Reinitialized MCM and Refreshed all lists.", False)
    RETURN    ; - STOP -
ENDIF
;---------------------
; Handle the toggled options

IF OptionID == IsEnabledID
    HandyCrafting.HandyCraftingEnabled = !HandyCrafting.HandyCraftingEnabled
    SetToggleOptionValue(OptionID, HandyCrafting.HandyCraftingEnabled)
    RETURN    ; - STOP -
ENDIF
;---------------------
; Handle the Allow in Dungeons/Wilderness option

IF OptionID == AllowInDungeonsID
    HandyCrafting.AllowInDungeons = !HandyCrafting.AllowInDungeons
    SetToggleOptionValue(OptionID, !HandyCrafting.AllowInDungeons)
    RETURN    ; - STOP -
ENDIF
;---------------------
IF OptionID == EnabledWeightBuffID
    HandyCrafting.CraftingWeightBuffEnabled = !HandyCrafting.CraftingWeightBuffEnabled
    SetToggleOptionValue(OptionID, HandyCrafting.CraftingWeightBuffEnabled)
    RETURN    ; - STOP -
ENDIF
;---------------------
IF OptionID == EnableIngredientCappingID
    HandyCrafting.EnableCapping = !HandyCrafting.EnableCapping
    SetToggleOptionValue(OptionID, HandyCrafting.EnableCapping)
    RETURN    ; - STOP -
ENDIF
;---------------------
IF OptionID == AlwaysShowMessagesID
    HandyCrafting.AlwaysShowMessages = !HandyCrafting.AlwaysShowMessages
    SetToggleOptionValue(OptionID, HandyCrafting.AlwaysShowMessages)
    RETURN    ; - STOP -
ENDIF
;---------------------
IF OptionID == AddStoreIngredientsSpellID
    myF_SelectSpell(OptionID, 0)
;;;    If !layer.HasSpell(HandySpellsList[0])
;;;        player.AddSpell(HandySpellsList[0], abVerbose = False)
;;;    Else
;;;        player.RemoveSpell(HandySpellsList[0])
;;;        IA710_cRetrieveStorageRef.RemoveAllItems(player)
;;;    EndIf
;;;    SetToggleOptionValue(OptionID, player.HasSpell(HandySpellsList[0]))
    RETURN    ; - STOP -
ENDIF
;---------------------
IF OptionID == AddHandyGhostMountSpellID
    myF_SelectSpell(OptionID, 1)
;;;    If !player.HasSpell(HandySpellsList[1])
;;;        player.AddSpell(HandySpellsList[1], abVerbose = False)
;;;    Else
;;;        player.RemoveSpell(HandySpellsList[1])
;;;    EndIf
;;;    SetToggleOptionValue(OptionID, player.HasSpell(HandySpellsList[1]))
    RETURN    ; - STOP -
ENDIF
;---------------------
IF OptionID == AddHandyTeleportSpellID
    myF_SelectSpell(OptionID, 2)
;;;    If !player.HasSpell(HandySpellsList[2])
;;;        player.AddSpell(HandySpellsList[2], abVerbose = False)
;;;    Else
;;;        player.RemoveSpell(HandySpellsList[2])
;;;    EndIf
;;;    SetToggleOptionValue(OptionID, player.HasSpell(HandySpellsList[2]))
    RETURN    ; - STOP -
ENDIF
;---------------------
IF OptionID == AddHandyBOHSpellID
    myF_SelectSpell(OptionID, 3)
;;;    If !player.HasSpell(HandySpellsList[3])
;;;        player.AddSpell(HandySpellsList[3], abVerbose = False)
;;;    Else
;;;        player.RemoveSpell(HandySpellsList[3])
;;;        IA710_cBagofHoldingREF.RemoveAllItems(player)
;;;    EndIf
;;;    SetToggleOptionValue(OptionID, player.HasSpell(HandySpellsList[3]))
    RETURN    ; - STOP -
ENDIF
;---------------------
; Handle accessing the Capping container

IF OptionID == OpenCappingContainerID    
    CloseMCM()
    IA710_cCappingChestRef.AddInventoryEventFilter(IA710_flAllIngredients)
    IA710_cCappingChestRef.Activate(player as ObjectReference)
    RETURN    ; - STOP -
ENDIF
;---------------------
; Handle accessing the storage container

IF OptionID == OpenStorageContainerID
    CloseMCM()
    IA710_cIngredientStorageRef.Activate(player as ObjectReference)
    RETURN    ; - STOP -
ENDIF
;---------------------
; Handle the Store All Ingredients option

IF OptionID == StoreAllIngredientsID
    ; Retreive all the items in the storage container
    IA710_cIngredientStorageRef.RemoveAllItems(player)

    ; Store any Protected ingredients in the temporary container
    player.RemoveItem(IngredientsList[9], player.GetItemCount(IngredientsList[9]), abSilent = True, akOtherContainer = IA710_cTemporaryHoldingRef)

    ; Search through the capped ingredients list for excess ingredients in the players inventory
    i = IA710_cCappingChestRef.GetNumItems()
    WHILE (i > 0)
        i = i - 1
        form fm = IA710_cCappingChestRef.GetNthForm(i)                                    ; fm = IngredientToCap
        
        int QuantityToCap = player.GetItemCount(fm) - IA710_cCappingChestRef.GetItemCount(fm)
        ; Set any excess ingredients aside in the temporary holding container
        IF (QuantityToCap > 0)
            player.RemoveItem(fm, QuantityToCap, abSilent = True, akOtherContainer = IA710_cTemporaryHoldingRef)
        ENDIF
    ENDWHILE

    ; Store all the remaining ingredients
    player.RemoveItem(IA710_flAllIngredients, player.GetItemCount(IA710_flAllIngredients), abSilent = True, akOtherContainer = IA710_cIngredientStorageRef)

    ; Retreive the Protected items from the temporary holding container
    IA710_cTemporaryHoldingRef.RemoveAllItems(layer)
    ShowMessage("$Ingredients_Stored", False)
    SetTextOptionValue(OpenStorageContainerID, FormatNumber(IA710_cIngredientStorageRef.GetItemCount(IA710_flAllIngredients)))
    RETURN    ; - STOP -
ENDIF
;---------------------
IF OptionID == RetrieveAllStoredID
    IA710_cBagofHoldingREF.RemoveAllItems(player)
    IA710_cRetrieveStorageRef.RemoveAllItems(player)
    IA710_cIngredientStorageRef.RemoveAllItems(player)
    IA710_cTemporaryHoldingRef.RemoveAllItems(player)
    SetTextOptionValue(OpenStorageContainerID, FormatNumber(IA710_cIngredientStorageRef.GetItemCount(IA710_flAllIngredients)))
    ShowMessage("$All_Items_Retrieved", False)
    RETURN    ; - STOP -
ENDIF
;---------------------
; Handle accessing the ingredient containers

    i = IngredientsList.Length
    WHILE (i)
        i = i - 1
        IF (OptionID == IngrdientEntryID[i])
            CloseMCM()
            IngredientContainerRef[i].Activate(player as ObjectReference)
            i = 0
        ENDIF
    ENDWHILE
ENDEVENT

;--------------------------------------------
FUNCTION myF_SelectSpell(Int OptionID, Int i)
;--------------------------------------------
    actor player = Game.GetPlayer()
    bool  b      = player.HasSpell( HandySpellsList[i] )

    IF ( b )
        player.RemoveSpell( HandySpellsList[i] )
        IF (i == 0)
            IA710_cRetrieveStorageRef.RemoveAllItems(player)    ; option: AddStoreIngredientsSpellID
        ENDIF
        IF (i == 3)
            IA710_cBagofHoldingREF.RemoveAllItems(player)       ; option: AddHandyBOHSpellID
        ENDIF
    ELSE
        player.AddSpell(HandySpellsList[i], abVerbose = False)
    ENDIF

    SetToggleOptionValue(OptionID, !b)
ENDFUNCTION


EVENT  OnOptionDefault(Int OptionID)
;=====================
IF OptionID == IsEnabledID
    HandyCrafting.HandyCraftingEnabled = TRUE                                  ; TRUE
    SetToggleOptionValue(OptionID, HandyCrafting.HandyCraftingEnabled)         ; enabled
    RETURN    ; - STOP -
ENDIF
;---------------------
IF OptionID == AllowInDungeonsID
    HandyCrafting.AllowInDungeons = TRUE                                       ; TRUE
    SetToggleOptionValue(OptionID, !HandyCrafting.AllowInDungeons)             ; opposite here ??
    RETURN    ; - STOP -
ENDIF
;---------------------
IF OptionID == EnabledWeightBuffID
    HandyCrafting.CraftingWeightBuffEnabled = TRUE                             ; TRUE
    SetToggleOptionValue(OptionID, HandyCrafting.CraftingWeightBuffEnabled)    ; enabled
    RETURN    ; - STOP -
ENDIF
;---------------------
IF OptionID == EnableIngredientCappingID
    HandyCrafting.EnableCapping = TRUE                                         ; TRUE
    SetToggleOptionValue(OptionID, HandyCrafting.EnableCapping)                ; enable
    RETURN    ; - STOP -
ENDIF
;---------------------
IF OptionID == AlwaysShowMessagesID
    HandyCrafting.AlwaysShowMessages = TRUE                                    ; TRUE
    SetToggleOptionValue(OptionID, HandyCrafting.AlwaysShowMessages)           ; always show messages
    RETURN    ; - STOP -
ENDIF
;---------------------
IF OptionID == AddStoreIngredientsSpellID
    myF_AddSpell(0)
;;;    If !PlayerRef.HasSpell(HandySpellsList[0])
;;;        PlayerRef.AddSpell(HandySpellsList[0])
;;;    EndIf
    SetToggleOptionValue(OptionID, TRUE)
    RETURN    ; - STOP -
ENDIF
;---------------------
IF OptionID == AddHandyGhostMountSpellID
    myF_AddSpell(1)
    SetToggleOptionValue(OptionID, TRUE)
    RETURN    ; - STOP -
ENDIF
;---------------------
IF OptionID == AddHandyTeleportSpellID
    myF_AddSpell(2)
    SetToggleOptionValue(OptionID, TRUE)
    RETURN    ; - STOP -
ENDIF
;---------------------
IF OptionID == AddHandyBOHSpellID
    myF_AddSpell(3)
    SetToggleOptionValue(OptionID, TRUE)
    RETURN    ; - STOP -
ENDIF
;---------------------
    int i = 0
    WHILE (i < HSLMax)
        IF (OptionID == OID_Hotkey[i])
            UnregisterForKey( HSKeyMap[i] )
            SetKeyMapOptionValue(OptionID, -1)
            HSKeyMap[i] = -1
            i = HSLMax                        ; break loop here    *** added by ReDragon ***
        ENDIF
        i = i + 1
    ENDWHILE
ENDEVENT

;---------------------------
FUNCTION myF_AddSpell(Int i)
;---------------------------
    actor player = Game.GetPlayer()
IF player.HasSpell( HandySpellsList[i] )
    RETURN    ; - STOP -
ENDIF
;---------------------
    player.AddSpell( HandySpellsList[i] )
ENDFUNCTION


EVENT OnOptionHighlight(Int OptionID)
;======================
IF OptionID == IngrdientEntryID[0]
    SetInfoText("$Alchemy_Description")
    RETURN    ; - STOP -
ENDIF
;---------------------
IF OptionID == IngrdientEntryID[1]
    SetInfoText("$Carpentry_Description")
    RETURN    ; - STOP -
ENDIF
;---------------------
IF OptionID == IngrdientEntryID[2]
    SetInfoText("$Cooking_Description")
    RETURN    ; - STOP -
ENDIF
;---------------------
IF OptionID == IngrdientEntryID[3]
    SetInfoText("$Enchanting_Description")
    RETURN    ; - STOP -
ENDIF
;---------------------
IF OptionID == IngrdientEntryID[4]
    SetInfoText("$Milling_Description")
    RETURN    ; - STOP -
ENDIF
;---------------------
IF OptionID == IngrdientEntryID[5]
    SetInfoText("$Smelting_Description")
    RETURN    ; - STOP -
ENDIF
;---------------------
IF OptionID == IngrdientEntryID[6]
    SetInfoText("$Smithing_Description")
    RETURN    ; - STOP -
ENDIF
;---------------------
IF OptionID == IngrdientEntryID[7]
    SetInfoText("$Tanning_Description")
    RETURN    ; - STOP -
ENDIF
;---------------------
IF OptionID == IngrdientEntryID[8]
    SetInfoText("$Tempering_Description")
    RETURN    ; - STOP -
ENDIF
;---------------------
IF OptionID == IngrdientEntryID[9]
    SetInfoText("$Protected_Description")
    RETURN    ; - STOP -
ENDIF
;---------------------
IF OptionID == OpenCappingContainerID
    SetInfoText("$Capped_Description")
    RETURN    ; - STOP -
ENDIF
;---------------------
IF OptionID == OpenStorageContainerID
    SetInfoText("$Open_Storage_Container_Description")
    RETURN    ; - STOP -
ENDIF
;---------------------
IF OptionID == StoreAllIngredientsID
    SetInfoText("$Store_All_Ingredients_Description")
    RETURN    ; - STOP -
ENDIF
;---------------------
IF OptionID == IsEnabledID
    SetInfoText("$Enable/Disable_Description")
    RETURN    ; - STOP -
ENDIF
;---------------------
IF OptionID == AllowInDungeonsID
    SetInfoText("$Restricted_Mode_Description")
    RETURN    ; - STOP -
ENDIF
;---------------------
IF OptionID == EnableIngredientCappingID
    SetInfoText("$Enable_Capping_Description")
    RETURN    ; - STOP -
ENDIF
;---------------------
IF OptionID == AlwaysShowMessagesID
    SetInfoText("$Always_Show_Messages_Description")
    RETURN    ; - STOP -
ENDIF
;---------------------
IF OptionID == EnabledWeightBuffID
    SetInfoText("$Enable_Weight_Buff_Description")
    RETURN    ; - STOP -
ENDIF
;---------------------
IF OptionID == UninstallHandyCraftingID
    SetInfoText("$Uninstall_Description")
    RETURN    ; - STOP -
ENDIF
;---------------------
IF OptionID == AddStoreIngredientsSpellID
    SetInfoText("$Add_Store_Ingedients_Power_Description")
    RETURN    ; - STOP -
ENDIF
;---------------------
IF OptionID == AddHandyTeleportSpellID
    SetInfoText("$Add_Handy_Teleport_Spell_Description")
    RETURN    ; - STOP -
ENDIF
;---------------------
IF OptionID == AddHandyGhostMountSpellID
    SetInfoText("$Add_Handy_Mount_Spell_Description")
    RETURN    ; - STOP -
ENDIF
;---------------------
IF OptionID == AddHandyBOHSpellID
    SetInfoText("$Add_Handy_BOH_Spell_Description")
    RETURN    ; - STOP -
ENDIF
;---------------------
IF OptionID == RetrieveAllStoredID
    SetInfoText("$Retrieve_All_Items_Description")
    RETURN    ; - STOP -
ENDIF
;---------------------
    int i = HSLMax
    WHILE (i)            ; (i != 0)
        i = i - 1
        IF (OptionID == OID_Hotkey[i])
            SetInfoText("$Set_Handy_Hotkey")
        ENDIF
    ENDWHILE
ENDEVENT


EVENT OnOptionKeyMapChange(Int option, Int keyCode, String conflictControl, String conflictName)  ; {Called when a key has been remapped}
;=========================
    int i = 0
    WHILE (i < HSLMax)
        IF (option == OID_Hotkey[i])

            bool bOK = TRUE                                                              ; bOK = continue
            IF (keyCode != 1) && (conflictControl != "")
                string s = "This key is already mapped to:\n\"" + conflictControl        ; s = msg
                
                IF (conflictName == "")
                    s = s + "\"\n\nAre you sure you want to continue?"
                ELSE
                    s = s + "\"\n(" + conflictName + ")\n\nAre you sure you want to continue?"
                ENDIF

                bOK = ShowMessage(s, TRUE, "$Yes", "$No")
            ENDIF
            
            IF ( bOK )
                UnregisterForKey( HSKeyMap[i] )

                IF (keyCode != 1)
                    RegisterForKey(keyCode)
                    HSKeyMap[i] = keyCode
                ENDIF

                SetKeyMapOptionValue(option, keyCode)
            ENDIF

        ENDIF
        i = i + 1
    ENDWHILE
ENDEVENT


;======================================
State Busy
;=========
    EVENT OnKeyDown(Int keycode)
    ENDEVENT
;=======
endState


EVENT OnKeyDown(Int keycode)
;==============
IF (keyCode == 1)
    RETURN    ; - STOP -
ENDIF
;---------------------
    gotoState("Busy")                ; ### STATE ### prevent the event from piling up with multiple keypress
    myF_Process(keycode)
    gotoState("")                    ; ### STATE ### back to normal
ENDEVENT


; -- FUNCTIONs -- (2) + (2) + 7

;--------------------------------
FUNCTION myF_Process(Int keycode)
;-------------------------------- 1
    int i

IF Utility.IsInMenuMode()
                                        i = 1    ; IsInMenuMode to block when game is paused with menus open
ELSEIF UI.IsMenuOpen("Dialogue Menu")
                                        i = 2    ; Dialogue Menu check to block when dialog is open
ELSEIF UI.IsMenuOpen("Console")
                                        i = 3    ; Console check to block when console is open - console does not trigger IsInMenuMode and thus needs its own check
ELSEIF UI.IsMenuOpen("Crafting Menu")
                                        i = 4    ; Crafting Menu check to block when crafting menus are open - game is not paused so IsInMenuMode does not work
ELSEIF UI.IsMenuOpen("MessageBoxMenu")
                                        i = 5    ; MessageBoxMenu check to block when message boxes are open - while they pause the game, they do not trigger IsInMenuMode
ELSEIF UI.IsMenuOpen("ContainerMenu")
                                        i = 6    ; ContainerMenu check to block when containers are accessed - while they pause the game, they do not trigger IsInMenuMode
ELSEIF UI.IsTextInputEnabled()
                                        i = 7    ; IsTextInputEnabled check to block when editable text fields are open
ELSEIF Game.GetPlayer().IsOnMount()
                                        i = 8    ; IsOnMount check to block when riding a horse
;ELSEIF Game.GetPlayer().IsInCombat()
;                                        i = 9   ; IsInCombat check to block when combat is going on.
ENDIF
    
IF (i > 0)
    Debug.Notification("Unable to process mod hotkey at this time. " +i)
    RETURN    ; - STOP -
ENDIF
;---------------------
    i = HSKeyMap.Find(keyCode)
IF (i < 0)
    RETURN    ; - STOP -    key not found!
ENDIF
;---------------------
;;    Debug.Notification("HCaS Casting: " + HandySpellsList[i].GetName())
    HandySpellsList[i].Cast(Game.GetPlayer() as ObjectReference)
ENDFUNCTION


;--------------------------------------------
String FUNCTION GetCustomControl(Int keyCode)  ; UnUSED internal
;-------------------------------------------- 2
    string s = ""

    int i = 0
    WHILE (i < HSLMax)
        IF (HSKeyMap[i] == keyCode)
            s = "Handy Crafting: " + HandySpellsList[i].GetName()
            i = HSLMax        ; abort loop
        ENDIF
        i = i + 1
    ENDWHILE

    RETURN s
ENDFUNCTION


;----------------------------------------------
String FUNCTION FormatNumber(Int aiNumToFormat)
;---------------------------------------------- 3
    string s = ""                                                ; s = FormattedNumber

IF (aiNumToFormat <= 0)
    RETURN s
ENDIF
;---------                                ; 1000000 -> 1,000,000   > 7
    s = aiNumToFormat as String           ;    1000 ->     1,000   > 3

    int i = StringUtil.GetLength(s)
    IF (i > 3)
        s = StringUtil.SubString(s, 0, (i - 3)) +ThousandsSeperator+ StringUtil.SubString(s, (i - 3), 3)
        i = StringUtil.GetLength(s)
        IF (i > 7)
            s = StringUtil.SubString(s, 0, (i - 7)) +ThousandsSeperator+ StringUtil.SubString(s, (i - 7), 7)
        ENDIF
    ENDIF
    RETURN s
ENDFUNCTION


;---------------------
FUNCTION myF_Refresh()
;--------------------- 4
    int i = IngredientsList.Length
    WHILE (i > 0)
        i = i - 1
        RefreshList(IngredientsList[i], IngredientContainerRef[i])
    ENDWHILE
    i = IA710_cCappingChestRef.GetNumItems()

    HandyCrafting.CappedIngredientsNum                            ; ???

    HandyCrafting.CappedIngredientsRef = Utility.CreateFormArray(i)
    HandyCrafting.CappedIngredientsQty = Utility.CreateIntArray(i)

    WHILE (i > 0)
        i = i - 1
        form fm = IA710_cCappingChestRef.GetNthForm(i)            ; fm = CurrentIngredient
        HandyCrafting.CappedIngredientsRef[i] = fm
        HandyCrafting.CappedIngredientsQty[i] = IA710_cCappingChestRef.GetItemCount(fm)
    ENDWHILE
ENDFUNCTION

;---------------------------------------------------------------------------------------
FUNCTION RefreshList(FormList aflIngredientList, ObjectReference aorIngredientContainer)  ; helper, see myF_Refresh()
;--------------------------------------------------------------------------------------- 5
; Refreshes a formlist with its associated container
; Used to make sure the formlist contains valid objects

    int i = aorIngredientContainer.GetNumItems()
    form[] a = Utility.CreateFormArray(i)                ; a = ContainerContents

    WHILE (i > 0)
        i = i - 1
        a[i] = aorIngredientContainer.GetNthForm(i)
    ENDWHILE

    aflIngredientList.Revert()                           ; clear formlist entries made by script
    aflIngredientList.Addforms(a)                        ; add new entries
ENDFUNCTION


;--------------------
FUNCTION myF_Revert()
;-------------------- 6
    form[] a                                             ; a = ConvertedFormlist
    IA710_flAllIngredients.Revert()

    i = IngredientsList.Length - 1                       ; Skip adding Protected Ingredients to the large list.
    WHILE (i > 0)
        i = i - 1
        a = IngredientsList[i].ToArray()
        IA710_flAllIngredients.AddForms(a)
    ENDWHILE
ENDFUNCTION


;------------------------------------------------------------
Int FUNCTION MergeIngredientLists(FormList aflIngredientList)  ; UnUSED internal
;------------------------------------------------------------ 7
; Returns the total number of items inside a container

    form[] a                                            ; a = ConvertedFormlist
    aflIngredientList.Revert()

    int i = IngredientsList.Length
    WHILE (i > 0)
        i = i - 1
        a = IngredientsList[i].ToArray()
        aflIngredientList.AddForms(a)
    ENDWHILE

    i = IA710_cIngredientStorageRef.GetItemCount(aflIngredientList)
    RETURN i
ENDFUNCTION

 

 

    HandyCrafting.CappedIngredientsNum                            ; ???
Edited by ReDragon2013
Link to comment
Share on other sites

All,

 

I've learned a lot from all of this.

 

I'm going to try several things over the next few weeks, but I have only an hour or two a day at most to spend on it for a while due to some other obligations, but I will post back to this thread as I try things and truly appreciate all your help.

 

Ishra, Sphered I'll try to use the template provided to use states + Ishra's recomendations regarding onconfigclose and onupdate, thank you!

 

ReDragon2013 - Yeah, the AE install is on a different machine and has the correct version of SKSE. Thank you so much for the code sample, I had every intention of tightening it up once I had it working right, but most likely should have done that from the beginning. Your example compiled (with a couple of tweaks), but the issue persists. The HandCrafting.CappedIngreditensNum was leftover from something else and not required. Thank you again.

 

I am starting to think it's an issue with my system and am going to look at that next.

 

Thank you all, I will let you know how it goes!

 

-IA710

Link to comment
Share on other sites

Ishara, Sphered and ReDragon2013,

 

I am trying to implement everything everyone has suggested (maybe not the best idea, but I like all of your examples), and so have tried to do something like what all of you have described.

 

Switched to MCM 2.0 State based format.

Got rid of OnGameReload weird piece, and replaced it with OnPlayerLoadGame event, and moved the OnConfigOpen to OnPlayerLoadGame because that's really where it belonged anyways in an effort to decrease the total number of events.

Used/Created more functions (some ReDragon2013 provided, some I did as I was converting it) for obvious reasons.

 

The example below is where I am at on it. It compiles and everything seems to work fine, and I was able to run it longer than before. I know that Ishara recommended to us OnConfigClose to register for a single update and then update everything at one time, but really I'm not positive that would help much with my situation, or what all I would wait to process (maybe just keymaping?). So that's one thing that I will look further at. Ishara, the reference mod you mentioned moved some of the onkeydown stuff to a separate script, should I be considering that too?

 

Here's where I'm at:

 

 

 

Scriptname IA710_HandyCrafting_MCM_Script extends SKI_ConfigBase


  IA710_HandyCraftingScript PROPERTY HandyCrafting auto      ; pointer to script "IA710_HandyCraftingScript.psc"

  Message PROPERTY IA710_mUninstallMessage       auto        ; {Final instructions to follow to complete uninstallation.}
  Spell   PROPERTY IA710_spFortifyCraftingWeight auto        ; {Used to remove the spell from the player, in case something went wrong.}

  Spell[] PROPERTY HandySpellsList auto                      ; Array with spell lists as follow:
    ; [0] = Handy Store and Retrieve Spell
    ; [1] = Handy Conjure Ghost Mount Spell
    ; [2] = Handy Teleport Spell
    ; [3] = Handy Bag of Holding Spell

;These need to be filled with the formlists and container references.

  FormList   PROPERTY IA710_flAllIngredients auto            ; {Holds all of the ingredients from the other lists.}
  FormList[] PROPERTY IngredientsList        auto            ; {Contains all the vanilla ingredient lists}
    ; 0 = Alchemy
    ; 1 = Carpentry
    ; 2 = Cooking
    ; 3 = Enchanting
    ; 4 = Milling
    ; 5 = Smelting
    ; 6 = Smithing
    ; 7 = Tanning
    ; 8 = Tempering
    ; 9 = Protected
  ObjectReference PROPERTY IA710_cIngredientStorageRef auto    ; {Master container hold all the stored ingredients.}
  ObjectReference PROPERTY IA710_cTemporaryHoldingRef  auto    ; {Container that holds Protected ingredients while the player is crafting.}
  ObjectReference PROPERTY IA710_cCappingChestRef      auto    ; {Container tha holds the Capping ingredients list.}

  ObjectReference PROPERTY IA710_cBagofHoldingREF      auto    ; {Container Ref that holds Bag of Holding stored items}
  ObjectReference PROPERTY IA710_cRetrieveStorageRef   auto    ; {Temprarily Holds list specific ingredients while retrieving them}

  ObjectReference[] PROPERTY IngredientContainerRef auto       ; {The containers for each of the corresponding ingredient lists}

  String PROPERTY ThousandsSeperator = "," auto                ; {The thousands seperator used in formatting the item count numbers. Default: ,}

  Int[] HSKeyDefault
  Int[] HSKeyMap


  Int HSLMax
  Int current_version = 0

;  actor player = Game.GetPlayer()
 ;Actor PlayerRef                    ; to keep from making repeated calls to Game.GetPlayer()


;------------------------
Int FUNCTION GetVersion()
;------------------------
    RETURN 1
ENDFUNCTION


;------------------
FUNCTION CloseMCM()  ; Closes the MCM and System menus. Brings the player back to game mode.
;------------------
    UI.Invoke("Journal Menu", "_root.QuestJournalFader.Menu_mc.ConfigPanelClose")
    UI.Invoke("Journal Menu", "_root.QuestJournalFader.Menu_mc.CloseMenu")

    Utility.Wait(0.5)
ENDFUNCTION


; -- EVENTs -- 10 + "Busy"

EVENT OnVersionUpdate(Int version)
;====================
    IF (version > current_version)
        Debug.Trace(" OnVersionUpdate() - is updating the script to version " +version+ " -- " +self)
        OnConfigInit()
    ENDIF

ENDEVENT


EVENT OnConfigInit()
;=================
;    Pages = new string[3]
    Pages[0] = "List Maintenance"
    Pages[1] = "Configuration"
    Pages[2] = "Uninstall"

    myF_Revert()

    actor player = Game.GetPlayer()
    player.AddSpell(HandySpellsList[0], abVerbose = False)
    player.AddSpell(HandySpellsList[1], abVerbose = False)
    player.AddSpell(HandySpellsList[2], abVerbose = False)
    player.AddSpell(HandySpellsList[3], abVerbose = False)

; Unregister all keys
    UnregisterForAllKeys()

; Initialize Hotkey Stuff
    HSLMax     = HandySpellsList.Length

; Set Key Defaults
    IF (!HSKeyDefault) || (HSLMax != HSKeyDefault.Length)
        HSKeyDefault = Utility.CreateIntArray(HSLMax, -1)
    ENDIF

; if HSKeyMap does not exist, initialize it,
; if it already exists but is the wrong length, preserve the values we can, reinit and fill with old values

    IF ( !HSKeyMap )
        HSKeyMap = Utility.CreateIntArray(HSLMax, -1)

    ELSEIF (HSKeyMap.Length != HSLMax)
;---------
;        int[] tempkeyholding
;        TempKeyHolding = Utility.CreateIntArray(HSLMax, -1)
;        i = HSLMax
;        while i > 0
;            i -= 1
;            if i < HSKeyMap.length
;                TempKeyHolding[i] = HSKeyMap[i]
;            else
;                TempKeyHolding[i] = HSKeyDefault[i]
;            endif
;        endWhile
;         HSKeyMap = TempKeyHolding
;---------
        HSKeyMap = Utility.CreateIntArray(HSLMax, -1)
    ENDIF

; Register the hotkeys
;    i = HSLMax
;    while i > 0
;        i -= 1
;        if HSKeyMap[i] > 1
;            RegisterForKey(HSKeyMap[i])
;        endIf
;    endwhile
    
    current_version = GetVersion()
    Debug.Notification("Handy Crafting and Spells Initilization Complete")
ENDEVENT


;EVENT OnConfigOpen()
;=================
; Merges all of the ingredient formlists into one large list.
; This is used to quickly store all ingredients and display how many ingredients are in the storage container.
;    myF_Revert()

; Some basic maintenance.
;    actor player = Game.GetPlayer()
;    player.RemoveSpell(IA710_spFortifyCraftingWeight)    ; Remove the carry weight buff if the player has it on him/her
;    IA710_cTemporaryHoldingRef.RemoveAllItems(player)    ; This container should always be empty, but just to be safe
;    IA710_cRetrieveStorageRef.RemoveAllItems(player)     ; This container should also always be empty, but just to be safe
;ENDEVENT


EVENT OnPlayerLoadGame()
;=================
;    parent.OnGameReload()        ; see "SKI_ConfigBase.psc"
    myF_Refresh()
    myF_Revert()

; Some basic maintenance.
    actor player = Game.GetPlayer()
    player.RemoveSpell(IA710_spFortifyCraftingWeight)    ; Remove the carry weight buff if the player has it on him/her
    IA710_cTemporaryHoldingRef.RemoveAllItems(player)    ; This container should always be empty, but just to be safe
    IA710_cRetrieveStorageRef.RemoveAllItems(player)     ; This container should also always be empty, but just to be safe
ENDEVENT


EVENT OnPageReset(String a_Page)
;================
;IF (a_page == "")
;    OnPageReset("List Maintenance")
;    RETURN    ; - STOP -    recursive call with "Maintenance page"
;ENDIF
;---------------------
IF (a_page == "List Maintenance")
    SetCursorFillMode (TOP_TO_BOTTOM)
    SetTitleText("$The_HandyCrafting_Title")
    Utility.WaitMenuMode(0.1)
    ; Show all the ingredient lists on the left side of the page, maintenance and options on the right side.
    AddHeaderOption("$Ingredients_Lists")
    AddTextOptionST("IngredientEntryIDState" + 0, "$Alchemy_Ingredients", FormatNumber( IngredientContainerRef[0].GetNumItems() ))
    AddTextOptionST("IngredientEntryIDState" + 1, "$Carpentry_Ingredients", FormatNumber( IngredientContainerRef[1].GetNumItems() ))
    AddTextOptionST("IngredientEntryIDState" + 2, "$Cooking_Ingredients", FormatNumber( IngredientContainerRef[2].GetNumItems() ))
    AddTextOptionST("IngredientEntryIDState" + 3, "$Enchanting_Ingredients", FormatNumber( IngredientContainerRef[3].GetNumItems() ))
    AddTextOptionST("IngredientEntryIDState" + 4, "$Milling_Ingredients", FormatNumber( IngredientContainerRef[4].GetNumItems() ))
    AddTextOptionST("IngredientEntryIDState" + 5, "$Smelting_Ingredients", FormatNumber( IngredientContainerRef[5].GetNumItems() ))
    AddTextOptionST("IngredientEntryIDState" + 6, "$Smithing_Ingredients", FormatNumber( IngredientContainerRef[6].GetNumItems() ))
    AddTextOptionST("IngredientEntryIDState" + 7, "$Tanning_Ingredients", FormatNumber( IngredientContainerRef[7].GetNumItems() ))
    AddTextOptionST("IngredientEntryIDState" + 8, "$Tempering_Ingredients", FormatNumber( IngredientContainerRef[8].GetNumItems() ))
    AddTextOptionST("IngredientEntryIDState" + 9, "$Protected_Ingredients", FormatNumber( IngredientContainerRef[9].GetNumItems() ))
    AddTextOptionST("OpenCappingContainerState", "$Capped_Ingredients", FormatNumber( IA710_cCappingChestRef.GetNumItems() ))

    SetCursorPosition(1)
    AddHeaderOption("$Maintenance")
    AddTextOptionST("OpenStorageContainerState", "$Open_Storage_Container", FormatNumber(IA710_cIngredientStorageRef.GetItemCount( IA710_flAllIngredients )))
    AddTextOptionST("StoreAllIngredientsState", "$Store_All_Ingredients", "")
    AddTextOptionST("RetrieveAllStoredState", "$Retrieve_All_Items", "")
    RETURN    ; - STOP -
ENDIF
;---------------------
IF (a_page == "Configuration")

    SetTitleText("$The_HandyCrafting_Title")

    SetCursorFillMode (TOP_TO_BOTTOM)
    AddHeaderOption("$Options")

    actor player = Game.GetPlayer()

    AddToggleOptionST("HCIsEnabledState", "$Enable_HandyCrafting", HandyCrafting.HandyCraftingEnabled)
    AddToggleOptionST("AllowInDungeonsState", "$Restricted_Mode", !HandyCrafting.AllowInDungeons)
    AddToggleOptionST("EnableIngCappingState", "$Enable_Capping", HandyCrafting.EnableCapping)
    AddToggleOptionST("EnabledWeightBuffState","$Increase_Carry_Weight_while_Crafting", HandyCrafting.CraftingWeightBuffEnabled)
    AddToggleOptionST("AlwaysShowMessagesState", "$Always_Show_Messages", HandyCrafting.AlwaysShowMessages)

    SetCursorPosition(1)
    AddHeaderOption ("$Add_Spells_Header")
    AddToggleOptionST("AddStoreSpellState", "$Add_Store_Ingredients_Power", player.HasSpell(HandySpellsList[0]))
    AddToggleOptionST("AddMountSpellState", "$Add_Handy_Mount_Spell", player.HasSpell(HandySpellsList[1]))
    AddToggleOptionST("AddTeleportSpellState", "$Add_Handy_Teleport_Spell", player.HasSpell(HandySpellsList[2]))
    AddToggleOptionST("AddBOHSpellState", "$Add_Handy_BOH_Spell", player.HasSpell(HandySpellsList[3]))

    AddEmptyOption()
    AddHeaderOption("$Add_Handy_Hotkeys")
    int i = 0
    WHILE (i < HSLMax)
        AddKeyMapOptionST("HSKeyState" + i, HandySpellsList[i].GetName() + " Hotkey", HSKeyMap[i])
        i = i + 1
    ENDWHILE
    RETURN    ; - STOP -
ENDIF
;---------------------
IF (a_page == "Uninstall")
    SetCursorFillMode (TOP_TO_BOTTOM)
    SetTitleText("$The_HandyCrafting_Title")    
    AddHeaderOption("$Uninstall")
    AddTextOptionST("UninstallState", "$Uninstall_HandyCrafting", "")

    AddEmptyOption()
    AddHeaderOption("Troubleshooting")
    AddTextOptionST("RefreshListsState", "Reinitialize and Refresh all lists", "")
    RETURN
ENDIF
ENDEVENT


;--------------------------------------------
FUNCTION myF_SelectSpell(Int i)
;--------------------------------------------
    actor player = Game.GetPlayer()
    bool  b      = player.HasSpell( HandySpellsList[i] )

    IF ( b )
        player.RemoveSpell( HandySpellsList[i] )
        IF (i == 0)
            IA710_cRetrieveStorageRef.RemoveAllItems(player)    ; option: AddStoreSpellState
        ENDIF
        IF (i == 3)
            IA710_cBagofHoldingREF.RemoveAllItems(player)       ; option: AddBOHSpellState
        ENDIF
    ELSE
        player.AddSpell(HandySpellsList[i], abVerbose = False)
    ENDIF

ENDFUNCTION


;---------------------------
FUNCTION myF_AddSpell(Int i)
;---------------------------
    actor player = Game.GetPlayer()
IF player.HasSpell( HandySpellsList[i] )
    RETURN    ; - STOP -
ENDIF
;---------------------
    player.AddSpell( HandySpellsList[i] )
ENDFUNCTION


FUNCTION myF_OnOptionKeyMapChange(Int option, Int keyCode, String conflictControl, String conflictName)  ; {Called when a key has been remapped}
;=========================

            bool bOK = TRUE                                                              ; bOK = continue
            IF (keyCode != 1) && (conflictControl != "")
                string s = "This key is already mapped to:\n\"" + conflictControl        ; s = msg
                
                IF (conflictName == "")
                    s = s + "\"\n\nAre you sure you want to continue?"
                ELSE
                    s = s + "\"\n(" + conflictName + ")\n\nAre you sure you want to continue?"
                ENDIF

                bOK = ShowMessage(s, TRUE, "$Yes", "$No")
            ENDIF
            
            IF ( bOK )
                UnregisterForKey( HSKeyMap[option] )

                IF (keyCode != 1)
                    RegisterForKey(keyCode)
                    HSKeyMap[option] = keyCode
                ENDIF

                SetKeyMapOptionValueST(keyCode, False, "HSKeyState" + option)
            ENDIF

ENDFUNCTION


;======================================
State Busy
;=========
    EVENT OnKeyDown(Int keycode)
    ENDEVENT
;=======
endState


EVENT OnKeyDown(Int keycode)
;==============
IF (keyCode == 1)
    RETURN    ; - STOP -
ENDIF
;---------------------
    gotoState("Busy")                ; ### STATE ### prevent the event from piling up with multiple keypress
    myF_Process(keycode)
    gotoState("")                    ; ### STATE ### back to normal
ENDEVENT


; -- FUNCTIONs -- (2) + (2) + 7

;--------------------------------
FUNCTION myF_Process(Int keycode)
;-------------------------------- 1
    int i

IF Utility.IsInMenuMode()
                                        i = 1    ; IsInMenuMode to block when game is paused with menus open
ELSEIF UI.IsMenuOpen("Dialogue Menu")
                                        i = 2    ; Dialogue Menu check to block when dialog is open
ELSEIF UI.IsMenuOpen("Console")
                                        i = 3    ; Console check to block when console is open - console does not trigger IsInMenuMode and thus needs its own check
ELSEIF UI.IsMenuOpen("Crafting Menu")
                                        i = 4    ; Crafting Menu check to block when crafting menus are open - game is not paused so IsInMenuMode does not work
ELSEIF UI.IsMenuOpen("MessageBoxMenu")
                                        i = 5    ; MessageBoxMenu check to block when message boxes are open - while they pause the game, they do not trigger IsInMenuMode
ELSEIF UI.IsMenuOpen("ContainerMenu")
                                        i = 6    ; ContainerMenu check to block when containers are accessed - while they pause the game, they do not trigger IsInMenuMode
ELSEIF UI.IsTextInputEnabled()
                                        i = 7    ; IsTextInputEnabled check to block when editable text fields are open
ELSEIF Game.GetPlayer().IsOnMount()
                                        i = 8    ; IsOnMount check to block when riding a horse
;ELSEIF Game.GetPlayer().IsInCombat()
;                                        i = 9   ; IsInCombat check to block when combat is going on.
ENDIF
    
IF (i > 0)
    Debug.Notification("Unable to process Handy hotkey at this time. " +i)
    RETURN    ; - STOP -
ENDIF
;---------------------
    i = HSKeyMap.Find(keyCode)
IF (i < 0)
    RETURN    ; - STOP -    key not found!
ENDIF
;---------------------
;;    Debug.Notification("HCaS Casting: " + HandySpellsList[i].GetName())
    HandySpellsList[i].Cast(Game.GetPlayer() as ObjectReference)
ENDFUNCTION


;--------------------------------------------
String FUNCTION GetCustomControl(Int keyCode)  ; UnUSED internal
;-------------------------------------------- 2
    string s = ""

    int i = 0
    WHILE (i < HSLMax)
        IF (HSKeyMap[i] == keyCode)
            s = "Handy Crafting: " + HandySpellsList[i].GetName()
            i = HSLMax        ; abort loop
        ENDIF
        i = i + 1
    ENDWHILE

    RETURN s
ENDFUNCTION


;----------------------------------------------
String FUNCTION FormatNumber(Int aiNumToFormat)
;---------------------------------------------- 3
    string s = ""                                                ; s = FormattedNumber

IF (aiNumToFormat <= 0)
    RETURN s
ENDIF
;---------                                ; 1000000 -> 1,000,000   > 7
    s = aiNumToFormat as String           ;    1000 ->     1,000   > 3

    int i = StringUtil.GetLength(s)
    IF (i > 3)
        s = StringUtil.SubString(s, 0, (i - 3)) +ThousandsSeperator+ StringUtil.SubString(s, (i - 3), 3)
        i = StringUtil.GetLength(s)
        IF (i > 7)
            s = StringUtil.SubString(s, 0, (i - 7)) +ThousandsSeperator+ StringUtil.SubString(s, (i - 7), 7)
        ENDIF
    ENDIF
    RETURN s
ENDFUNCTION


;---------------------
FUNCTION myF_Refresh()
;--------------------- 4
    int i = IngredientsList.Length
    WHILE (i > 0)
        i = i - 1
        RefreshList(IngredientsList[i], IngredientContainerRef[i])
    ENDWHILE
    i = IA710_cCappingChestRef.GetNumItems()

    HandyCrafting.CappedIngredientsNum                            ; ???

    HandyCrafting.CappedIngredientsRef = Utility.CreateFormArray(i)
    HandyCrafting.CappedIngredientsQty = Utility.CreateIntArray(i)

    WHILE (i > 0)
        i = i - 1
        form fm = IA710_cCappingChestRef.GetNthForm(i)            ; fm = CurrentIngredient
        HandyCrafting.CappedIngredientsRef[i] = fm
        HandyCrafting.CappedIngredientsQty[i] = IA710_cCappingChestRef.GetItemCount(fm)
    ENDWHILE
ENDFUNCTION

;---------------------------------------------------------------------------------------
FUNCTION RefreshList(FormList aflIngredientList, ObjectReference aorIngredientContainer)  ; helper, see myF_Refresh()
;--------------------------------------------------------------------------------------- 5
; Refreshes a formlist with its associated container
; Used to make sure the formlist contains valid objects

    int i = aorIngredientContainer.GetNumItems()
    form[] a = Utility.CreateFormArray(i)                ; a = ContainerContents

    WHILE (i > 0)
        i = i - 1
        a[i] = aorIngredientContainer.GetNthForm(i)
    ENDWHILE

    aflIngredientList.Revert()                           ; clear formlist entries made by script
    aflIngredientList.Addforms(a)                        ; add new entries
ENDFUNCTION


;--------------------
FUNCTION myF_Revert()
;-------------------- 6
    form[] a                                             ; a = ConvertedFormlist
    IA710_flAllIngredients.Revert()

    int i = IngredientsList.Length - 1                       ; Skip adding Protected Ingredients to the large list.
    WHILE (i > 0)
        i = i - 1
        a = IngredientsList[i].ToArray()
        IA710_flAllIngredients.AddForms(a)
    ENDWHILE
ENDFUNCTION


;------------------------------------------------------------
Int FUNCTION MergeIngredientLists(FormList aflIngredientList)  ; UnUSED internal
;------------------------------------------------------------ 7
; Returns the total number of items inside a container

    form[] a                                            ; a = ConvertedFormlist
    aflIngredientList.Revert()

    int i = IngredientsList.Length
    WHILE (i > 0)
        i = i - 1
        a = IngredientsList[i].ToArray()
        aflIngredientList.AddForms(a)
    ENDWHILE

    i = IA710_cIngredientStorageRef.GetItemCount(aflIngredientList)
    RETURN i
ENDFUNCTION

STATE IngredientEntryIDState0
    EVENT OnSelectST()
        actor player = Game.GetPlayer()
        CloseMCM()
        IngredientContainerRef[0].Activate(player as ObjectReference)
    ENDEVENT
    EVENT OnHighlightST()
        SetInfoText("$Alchemy_Description")
    ENDEVENT
ENDSTATE

STATE IngredientEntryIDState1
    EVENT OnSelectST()
        actor player = Game.GetPlayer()
        CloseMCM()
        IngredientContainerRef[1].Activate(player as ObjectReference)
    ENDEVENT
    EVENT OnHighlightST()
        SetInfoText("$Carpentry_Description")
    ENDEVENT
ENDSTATE

STATE IngredientEntryIDState2
    EVENT OnSelectST()
        actor player = Game.GetPlayer()
        CloseMCM()
        IngredientContainerRef[2].Activate(player as ObjectReference)
    ENDEVENT
    EVENT OnHighlightST()
        SetInfoText("$Cooking_Description")
    ENDEVENT
ENDSTATE

STATE IngredientEntryIDState3
    EVENT OnSelectST()
        actor player = Game.GetPlayer()
        CloseMCM()
        IngredientContainerRef[3].Activate(player as ObjectReference)
    ENDEVENT
    EVENT OnHighlightST()
        SetInfoText("$Enchanting_Description")
    ENDEVENT
ENDSTATE

STATE IngredientEntryIDState4
    EVENT OnSelectST()
        actor player = Game.GetPlayer()
        CloseMCM()
        IngredientContainerRef[4].Activate(player as ObjectReference)
    ENDEVENT
    EVENT OnHighlightST()
        SetInfoText("$Milling_Description")
    ENDEVENT
ENDSTATE

STATE IngredientEntryIDState5
    EVENT OnSelectST()
        actor player = Game.GetPlayer()
        CloseMCM()
        IngredientContainerRef[5].Activate(player as ObjectReference)
    ENDEVENT
    EVENT OnHighlightST()
        SetInfoText("$Smelting_Description")
    ENDEVENT
ENDSTATE

STATE IngredientEntryIDState6
    EVENT OnSelectST()
        actor player = Game.GetPlayer()
        CloseMCM()
        IngredientContainerRef[6].Activate(player as ObjectReference)
    ENDEVENT
    EVENT OnHighlightST()
        SetInfoText("$Smithing_Description")
    ENDEVENT
ENDSTATE

STATE IngredientEntryIDState7
    EVENT OnSelectST()
        actor player = Game.GetPlayer()
        CloseMCM()
        IngredientContainerRef[7].Activate(player as ObjectReference)
    ENDEVENT
    EVENT OnHighlightST()
        SetInfoText("$Tanning_Description")
    ENDEVENT
ENDSTATE

STATE IngredientEntryIDState8
    EVENT OnSelectST()
        actor player = Game.GetPlayer()
        CloseMCM()
        IngredientContainerRef[8].Activate(player as ObjectReference)
    ENDEVENT
    EVENT OnHighlightST()
        SetInfoText("$Tempering_Description")
    ENDEVENT
ENDSTATE

STATE IngredientEntryIDState9
    EVENT OnSelectST()
        actor player = Game.GetPlayer()
        CloseMCM()
        IngredientContainerRef[9].Activate(player as ObjectReference)
    ENDEVENT
    EVENT OnHighlightST()
        SetInfoText("$Protected_Description")
    ENDEVENT
ENDSTATE

STATE OpenCappingContainerState
    EVENT OnSelectST()
        actor player = Game.GetPlayer()
        CloseMCM()
        IA710_cCappingChestRef.AddInventoryEventFilter(IA710_flAllIngredients)
        IA710_cCappingChestRef.Activate(player as ObjectReference)
    ENDEVENT
    EVENT OnHighlightST()
        SetInfoText("$Capped_Description")
    ENDEVENT
ENDSTATE

STATE OpenStorageContainerState
    EVENT OnSelectST()
        actor player = Game.GetPlayer()
        CloseMCM()
        IA710_cIngredientStorageRef.Activate(player as ObjectReference)
    ENDEVENT
    EVENT OnHighlightST()
        SetInfoText("$Open_Storage_Container_Description")
    ENDEVENT
ENDSTATE

STATE StoreAllIngredientsState
    EVENT OnSelectST()
        actor player = Game.GetPlayer()
        IA710_cIngredientStorageRef.RemoveAllItems(player)
        ; Store any Protected ingredients in the temporary container
        player.RemoveItem(IngredientsList[9], player.GetItemCount(IngredientsList[9]), abSilent = True, akOtherContainer = IA710_cTemporaryHoldingRef)
        ; Search through the capped ingredients list for excess ingredients in the players inventory
        int i = IA710_cCappingChestRef.GetNumItems()
        WHILE (i > 0)
            i = i - 1
            form fm = IA710_cCappingChestRef.GetNthForm(i)                                    ; fm = IngredientToCap
            
            int QuantityToCap = player.GetItemCount(fm) - IA710_cCappingChestRef.GetItemCount(fm)
            ; Set any excess ingredients aside in the temporary holding container
            IF (QuantityToCap > 0)
                player.RemoveItem(fm, QuantityToCap, abSilent = True, akOtherContainer = IA710_cTemporaryHoldingRef)
            ENDIF
        ENDWHILE
        ; Store all the remaining ingredients
        player.RemoveItem(IA710_flAllIngredients, player.GetItemCount(IA710_flAllIngredients), abSilent = True, akOtherContainer = IA710_cIngredientStorageRef)
        ; Retreive the Protected items from the temporary holding container
        IA710_cTemporaryHoldingRef.RemoveAllItems(player)
        ShowMessage("$Ingredients_Stored", False)
        SetTextOptionValueST(FormatNumber(IA710_cIngredientStorageRef.GetItemCount(IA710_flAllIngredients)), False, "OpenStorageContainerState")
    ENDEVENT
    EVENT OnHighlightST()
        SetInfoText("$Store_All_Ingredients_Description")
    ENDEVENT
ENDSTATE

STATE RetrieveAllStoredState
    EVENT OnSelectST()
        actor player = Game.GetPlayer()
        IA710_cBagofHoldingREF.RemoveAllItems(player)
        IA710_cRetrieveStorageRef.RemoveAllItems(player)
        IA710_cIngredientStorageRef.RemoveAllItems(player)
        IA710_cTemporaryHoldingRef.RemoveAllItems(player)
        SetTextOptionValueST(FormatNumber(IA710_cIngredientStorageRef.GetItemCount(IA710_flAllIngredients)), False, "OpenStorageContainerState")
        ShowMessage("$All_Items_Retrieved", False)
    ENDEVENT
    EVENT OnHighlightST()
        SetInfoText("$Retrieve_All_Items_Description")
    ENDEVENT
ENDSTATE

STATE HCIsEnabledState
    EVENT OnSelectST()
        HandyCrafting.HandyCraftingEnabled = !HandyCrafting.HandyCraftingEnabled
        SetToggleOptionValueST(HandyCrafting.HandyCraftingEnabled)
    ENDEVENT
    EVENT OnDefaultST()
        HandyCrafting.HandyCraftingEnabled = TRUE                                  ; TRUE
        SetToggleOptionValueST(HandyCrafting.HandyCraftingEnabled)               ; enabled
    ENDEVENT
    EVENT OnHighlightST()
        SetInfoText("$WeightlessInfo")
    ENDEVENT
ENDSTATE

STATE AllowInDungeonsState
    EVENT OnSelectST()
        HandyCrafting.AllowInDungeons = !HandyCrafting.AllowInDungeons
        SetToggleOptionValueST(!HandyCrafting.AllowInDungeons)
    ENDEVENT
    EVENT OnDefaultST()
        HandyCrafting.AllowInDungeons = TRUE                                       ; TRUE
        SetToggleOptionValueST(!HandyCrafting.AllowInDungeons)             ; opposite here 
    ENDEVENT
    EVENT OnHighlightST()
        SetInfoText("$Restricted_Mode_Description")
    ENDEVENT
ENDSTATE

STATE EnableIngCappingState
    EVENT OnSelectST()
        HandyCrafting.EnableCapping = !HandyCrafting.EnableCapping
        SetToggleOptionValueST(HandyCrafting.EnableCapping)
    ENDEVENT
    EVENT OnDefaultST()
        HandyCrafting.EnableCapping = TRUE                                         ; TRUE
        SetToggleOptionValueST(HandyCrafting.EnableCapping)                ; enable
    ENDEVENT
    EVENT OnHighlightST()
        SetInfoText("$Enable_Capping_Description")
    ENDEVENT
ENDSTATE

STATE EnabledWeightBuffState
    EVENT OnSelectST()
        HandyCrafting.CraftingWeightBuffEnabled = !HandyCrafting.CraftingWeightBuffEnabled
        SetToggleOptionValueST(HandyCrafting.CraftingWeightBuffEnabled)
    ENDEVENT
    EVENT OnDefaultST()
        HandyCrafting.CraftingWeightBuffEnabled = TRUE                             ; TRUE
        SetToggleOptionValueST(HandyCrafting.CraftingWeightBuffEnabled)    ; enabled
    ENDEVENT
    EVENT OnHighlightST()
        SetInfoText("$Enable_Weight_Buff_Description")
    ENDEVENT
ENDSTATE

STATE AlwaysShowMessagesState
    EVENT OnSelectST()
        HandyCrafting.AlwaysShowMessages = !HandyCrafting.AlwaysShowMessages
        SetToggleOptionValueST(HandyCrafting.AlwaysShowMessages)
    ENDEVENT
    EVENT OnDefaultST()
        HandyCrafting.AlwaysShowMessages = TRUE                                    ; TRUE
        SetToggleOptionValueST(HandyCrafting.AlwaysShowMessages)           ; always show messages
    ENDEVENT
    EVENT OnHighlightST()
        SetInfoText("$Always_Show_Messages_Description")
    ENDEVENT
ENDSTATE

STATE AddStoreSpellState
    EVENT OnSelectST()
        actor player = Game.GetPlayer()
        myF_SelectSpell(0)
        SetToggleOptionValueST(player.HasSpell(HandySpellsList[0]))
    ENDEVENT
    EVENT OnDefaultST()
        myF_AddSpell(0)
        SetToggleOptionValueST(True)
    ENDEVENT
    EVENT OnHighlightST()
        SetInfoText("$Add_Store_Ingedients_Power_Description")
    ENDEVENT
ENDSTATE

STATE AddMountSpellState
    EVENT OnSelectST()
        actor player = Game.GetPlayer()
        myF_SelectSpell(1)
        SetToggleOptionValueST(player.HasSpell(HandySpellsList[1]))
    ENDEVENT
    EVENT OnDefaultST()
        myF_AddSpell(1)
        SetToggleOptionValueST(True)
    ENDEVENT
    EVENT OnHighlightST()
        SetInfoText("$Add_Handy_Mount_Spell_Description")
    ENDEVENT
ENDSTATE

STATE AddTeleportSpellState
    EVENT OnSelectST()
        actor player = Game.GetPlayer()
        myF_SelectSpell(2)
        SetToggleOptionValueST(player.HasSpell(HandySpellsList[2]))
    ENDEVENT
    EVENT OnDefaultST()
        myF_AddSpell(2)
        SetToggleOptionValueST(True)
    ENDEVENT
    EVENT OnHighlightST()
        SetInfoText("$Add_Handy_Teleport_Spell_Description")
    ENDEVENT
ENDSTATE

STATE AddBOHSpellState
    EVENT OnSelectST()
        actor player = Game.GetPlayer()
        myF_SelectSpell(3)
        SetToggleOptionValueST(player.HasSpell(HandySpellsList[3]))
    ENDEVENT
    EVENT OnDefaultST()
        myF_AddSpell(3)
        SetToggleOptionValueST(True)
    ENDEVENT
    EVENT OnHighlightST()
        SetInfoText("$Add_Handy_BOH_Spell_Description")
    ENDEVENT
ENDSTATE

STATE HSKeyState0
    EVENT OnKeyMapChangeST(Int keyCode, String conflictControl, String conflictName)
        myF_OnOptionKeyMapChange(0, keycode, conflictControl, conflictName)
    ENDEVENT
    EVENT OnDefaultST()
        UnregisterForKey(HSKeyMap[0])
        HSKeyMap[0] = HSKeyDefault[0]
        SetKeyMapOptionValueST(-1)
    ENDEVENT
    EVENT OnHighlightST()
        SetInfoText("$Set_Handy_Hotkey")
    ENDEVENT
ENDSTATE

STATE HSKeyState1
    EVENT OnKeyMapChangeST(Int keyCode, String conflictControl, String conflictName)
        myF_OnOptionKeyMapChange(1, keycode, conflictControl, conflictName)
    ENDEVENT
    EVENT OnDefaultST()
        UnregisterForKey(HSKeyMap[1])
        HSKeyMap[1] = HSKeyDefault[1]
        SetKeyMapOptionValueST(-1)
    ENDEVENT
    EVENT OnHighlightST()
        SetInfoText("$Set_Handy_Hotkey")
    ENDEVENT
ENDSTATE

STATE HSKeyState2
    EVENT OnKeyMapChangeST(Int keyCode, String conflictControl, String conflictName)
        myF_OnOptionKeyMapChange(2, keycode, conflictControl, conflictName)
    ENDEVENT
    EVENT OnDefaultST()
        UnregisterForKey(HSKeyMap[2])
		HSKeyMap[2] = HSKeyDefault[2]
        SetKeyMapOptionValueST(-1)
    ENDEVENT
    EVENT OnHighlightST()
        SetInfoText("$Set_Handy_Hotkey")
    ENDEVENT
ENDSTATE

STATE HSKeyState3
    EVENT OnKeyMapChangeST(Int keyCode, String conflictControl, String conflictName)
        myF_OnOptionKeyMapChange(3, keycode, conflictControl, conflictName)
    ENDEVENT
    EVENT OnDefaultST()
        UnregisterForKey(HSKeyMap[3])
        HSKeyMap[3] = HSKeyDefault[3]
        SetKeyMapOptionValueST(-1)
    ENDEVENT
    EVENT OnHighlightST()
        SetInfoText("$Set_Handy_Hotkey")
    ENDEVENT
ENDSTATE

STATE UninstallState
    EVENT OnSelectST()
        IF ShowMessage("$Confirm_Uninstall")
            actor player = Game.GetPlayer()
            CloseMCM()
            HandyCrafting.ShutDown()
            UnregisterForAllKeys()

            player.RemoveSpell(HandySpellsList[3])
            player.RemoveSpell(HandySpellsList[2])
            player.RemoveSpell(HandySpellsList[1])
            player.RemoveSpell(HandySpellsList[0])

            IA710_cBagofHoldingREF.RemoveAllItems(player)
            IA710_cRetrieveStorageRef.RemoveAllItems(player)
            IA710_cIngredientStorageRef.RemoveAllItems(player)
            IA710_cTemporaryHoldingRef.RemoveAllItems(player)

            int i = IngredientContainerRef.Length
            WHILE (i > 0)
                i = i - 1
                IngredientContainerRef[i].RemoveAllItems()
            ENDWHILE

            IA710_mUninstallMessage.Show()
            self.Stop()                                      ; STOP the QUEST
        ENDIF
    ENDEVENT
    EVENT OnHighlightST()
        SetInfoText("$Uninstall_Description")
    ENDEVENT
ENDSTATE

STATE RefreshListsState
    EVENT OnSelectST()
        OnConfigInit()
        myF_Refresh()
        myF_Revert()
        ShowMessage("Reinitialized MCM and Refreshed all lists.", False)
    ENDEVENT
    EVENT OnHighlightST()
        SetInfoText("Selecting this option will reinitialize the MCM and refresh all lists")
    ENDEVENT
ENDSTATE

 

 

 

Still a WIP, but please let me know of any issues you notice.

 

Once again, I can't thank you all enough.

 

-IA710

 

EDIT - removed an errant " for readability from code

Edited by ItsAlways710
Link to comment
Share on other sites

OnPlayerLoadGame event can only be ran on a player alias script. It will not function on any other script even though it will compile. If you wish to use this event, you'll need to set up a player alias and then you could, if you wish, shift the OnKeyDown event to that script as well. You could use a global variable for the key value and update it that way. It would also be useful to use an SKSE mod event to tell the player alias script to unregister and register for the key each time the player might update it in the MCM (example of that also in the mod I previously mentioned).

 

Most of what your MCM is doing doesn't need to be put off until the end because the original author devised a way to force close the MCM. However, it is something to keep in mind. Especially if you end up doing an MCM where an option is intended to start a quest. Quests won't start until the menu is closed and from personal experience an option that starts a quest while in the MCM will cause the next mod's MCM menu to hang up.

Link to comment
Share on other sites

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...