Hjorr Posted May 7, 2020 Share Posted May 7, 2020 Hello everyone, I'm having quite a hard time trying to understand how to create a custom event. My goal would be to create an event that detects when a string name has been changed, namely: UI.GetString("InventoryMenu", "_root.Menu_mc.inventoryLists.itemList.selectedEntry.text") I think that I'm supposed to use the information available here, here and here but I'm not sure how to set up the whole thing. Would it be possible at all? Some help would be much appreciated. Thanks in advance, Link to comment Share on other sites More sharing options...
IsharaMeradin Posted May 7, 2020 Share Posted May 7, 2020 I can give you a working example of a mod event. But I do not think it will help you. Initially the mod registered for a hotkey on one script. To allow users to change it the new value needed to get registered but the change was happening on a separate script. Since the one couldn't recognize the updated value and it is kinda clunky to ask users to press the old key to update to the new one, I devised this method.Script A where the hot key value can be changed. Event OnKeyDown(Int KeyCode) If KeyCode == abim_IMS_ModActKeyGV.GetValue() If OldMAK != KeyCode OldMAK = KeyCode SendModEvent("abim_HotKeyInitiateEvent") Debug.Notification("Initiating secondary script hot key registration") EndIf UnRegisterForAllKeys() EndIf EndEvent Script B where the mod event is registered for in both the OnInit and OnPlayerLoadGame events and where the hotkey officially gets updated and calls the OnKeyDown event for a seamless transition for the player Event OnInit() RegisterForModEvent("abim_HotKeyInitiateEvent","OnHotKeyInitiate") MaintUpdate() EndEvent Event OnPlayerLoadGame() RegisterForModEvent("abim_HotKeyInitiateEvent","OnHotKeyInitiate") RegisterForMenu("ContainerMenu") If VersionUpdate > 0.0 MaintUpdate() EndIf EndEvent Event OnHotKeyInitiate(string eventName, string strArg, float numArg, Form sender) UnregisterForAllKeys() Int MAK = abim_IMS_ModActKeyGV.GetValue() as Int If MAK != -1.0 RegisterForKey(MAK) ; Debug.Notification("Hot key registration complete") OnKeyDown(MAK) EndIf EndEvent All that to say, in order to send a mod event, you have to have some way to monitor the change in the first place. Mod events are a means of having one script trigger something on another script without directly referencing the two scripts. This is useful in framework situations where one mod does the work of determining when an activity is taking place and other mods can pick up on that. In the long run, this would help reduce processing as instead of several mods monitoring for a particular activity only one needs to do that. Link to comment Share on other sites More sharing options...
dylbill Posted May 8, 2020 Share Posted May 8, 2020 (edited) As IsharaMeradin said, you need to use another event to send the custom event. If you're trying to detect when the string is changed, you could use while loop polling while in the menu to detect the change. A script like that would look like this: String selectedEntry Bool InventoryMenuOpen = False Event OnInit() RegisterForMenu("InventoryMenu") EndEvent Event OnMenuOpen(String menuName) InventoryMenuOpen = True selectedEntry = UI.GetString("InventoryMenu", "_root.Menu_mc.inventoryLists.itemList.selectedEntry.text") DetectStringChange() EndEvent Event OnMenuClose(String menuName) InventoryMenuOpen = False EndEvent Function DetectStringChange() While selectedEntry == UI.GetString("InventoryMenu", "_root.Menu_mc.inventoryLists.itemList.selectedEntry.text") && InventoryMenuOpen == true && Utility.IsInMenuMode() ;this while loop pauses the script until the selectedEntry string changes EndWhile Utility.WaitMenuMode(0.1) If InventoryMenuOpen == True && selectedEntry != UI.GetString("InventoryMenu", "_root.Menu_mc.inventoryLists.itemList.selectedEntry.text") selectedEntry = UI.GetString("InventoryMenu", "_root.Menu_mc.inventoryLists.itemList.selectedEntry.text") ;do some stuff, the Entry text has changed DetectStringChange() ;re-runs the function. The function will only run while in the inventory menu. Endif EndFunction Edited May 10, 2020 by dylbill Link to comment Share on other sites More sharing options...
revenant0713 Posted May 8, 2020 Share Posted May 8, 2020 (edited) What is the function supposed to do exactly? Because if the effects of the function do not need the inventory screen open, then you can use OnMenuClose("InventoryMenu") followed by an if <insert condition here checking if the string == the expected string> Then you just set the expected string's value to the actual value of the string after all functions that depend on the "change" are done. edit: coincidentally, I'm fiddling around with OnMenuClose at the moment as well. Edited May 8, 2020 by revenant0713 Link to comment Share on other sites More sharing options...
Hjorr Posted May 10, 2020 Author Share Posted May 10, 2020 @IsharaMeradin Thank you very much for taking the time to explain. I think I get it now and well, it might not be of use right now but at least I've learnt something and that's always worth taking. @dylbill My thanks to you, I used a while loop just like you suggested and I'm very pleased to say that it works like a charm. @revenant0713 I needed to monitor the changes of the highlighted item in the inventory in order to change the "sCantEquipGeneric" game setting string. The reason for that is that I am working on an alternate start mod for Skyrim SE which allows the player to choose from a list of classes at the start of the game. At the moment I'm working on the bard class which among other things allows the player to start playing an instrument by selecting it in the inventory and I wanted to find a way to get rid of the annoying "you cannot equip this item" top-left notification when selecting a lute or a drum. Now thanks to @dylbill, it dynamically changes from you "you cannot equip this item" to "you start playing an instrument". Link to comment Share on other sites More sharing options...
IsharaMeradin Posted May 10, 2020 Share Posted May 10, 2020 Wow! I didn't know changing that string would be possible. Mind sharing the finished code? I've got some misc object items which the player can equip, even just removing rather than replacing the string for those items would be nice. Link to comment Share on other sites More sharing options...
Hjorr Posted May 10, 2020 Author Share Posted May 10, 2020 Sure, here you go :-) Scriptname AYF_BardQuestScript extends Quest import ski_activeeffectswidget import SKI_ConfigBase import SKI_ConfigManager import ski_configmenu import ski_favoritesmanager import ski_main import SKI_PlayerLoadGameAlias import ski_qf_configmanagerinstance import SKI_QuestBase import ski_settingsmanager import ski_widgetbase import ski_widgetmanager MiscObject Property Lute Auto MiscObject Property Flute Auto MiscObject Property Flute01 Auto MiscObject Property DancersFlute Auto MiscObject Property Drum Auto Form ItemForm String ItemName String selectedEntry Bool InventoryMenuOpen = False Event OnInit() RegisterForMenu("InventoryMenu") EndEvent Bool Function IsInstrument() ItemForm = Game.GetFormEx(UI.GetInt("InventoryMenu", "_root.Menu_mc.inventoryLists.itemList.selectedEntry.formId")) ItemName = UI.GetString("InventoryMenu", "_root.Menu_mc.inventoryLists.itemList.selectedEntry.text") If (ItemName == "lute" || ItemName == "flute" || ItemName == "flute01" || ItemName == "drum") return true ElseIf (ItemName!= "lute" || ItemName != "flute" || ItemName != "flute01" || ItemName != "drum") return false EndIf EndFunction Event OnMenuOpen(String menuName) InventoryMenuOpen = True selectedEntry = UI.GetString("InventoryMenu", "_root.Menu_mc.inventoryLists.itemList.selectedEntry.text") DetectStringChange() EndEvent Event OnMenuClose(String menuName) InventoryMenuOpen = False EndEvent Function DetectStringChange() While selectedEntry == UI.GetString("InventoryMenu", "_root.Menu_mc.inventoryLists.itemList.selectedEntry.text") && InventoryMenuOpen == true && Utility.IsInMenuMode() ;this while loop pauses the script until the selectedEntry string changes EndWhile Utility.WaitMenuMode(0.1) If InventoryMenuOpen == True && selectedEntry != UI.GetString("InventoryMenu", "_root.Menu_mc.inventoryLists.itemList.selectedEntry.text") selectedEntry = UI.GetString("InventoryMenu", "_root.Menu_mc.inventoryLists.itemList.selectedEntry.text") && InventoryMenuOpen == true && Utility.IsInMenuMode() If IsInstrument() == true Game.SetGameSettingString("sCantEquipGeneric", "You start playing") Else Game.SetGameSettingString("sCantEquipGeneric", "You cannot equip this item.") EndIf DetectStringChange() ;re-runs the function. The function will only run while in the inventory menu. Endif EndFunction Link to comment Share on other sites More sharing options...
dylbill Posted May 10, 2020 Share Posted May 10, 2020 Hey no prob, glad it's working! I noticed an error in my function though, I was hasty with copy / paste. Change: If InventoryMenuOpen == True && selectedEntry != UI.GetString("InventoryMenu", "_root.Menu_mc.inventoryLists.itemList.selectedEntry.text") selectedEntry = UI.GetString("InventoryMenu", "_root.Menu_mc.inventoryLists.itemList.selectedEntry.text") && InventoryMenuOpen == true && Utility.IsInMenuMode() If IsInstrument() == true Game.SetGameSettingString("sCantEquipGeneric", "You start playing") Else Game.SetGameSettingString("sCantEquipGeneric", "You cannot equip this item.") EndIf DetectStringChange() ;re-runs the function. The function will only run while in the inventory menu. Endif To If InventoryMenuOpen == True && selectedEntry != UI.GetString("InventoryMenu", "_root.Menu_mc.inventoryLists.itemList.selectedEntry.text") selectedEntry = UI.GetString("InventoryMenu", "_root.Menu_mc.inventoryLists.itemList.selectedEntry.text") If IsInstrument() == true Game.SetGameSettingString("sCantEquipGeneric", "You start playing") Else Game.SetGameSettingString("sCantEquipGeneric", "You cannot equip this item.") EndIf DetectStringChange() ;re-runs the function. The function will only run while in the inventory menu. Endif Link to comment Share on other sites More sharing options...
Recommended Posts