Jump to content

How do you create a Custom Event?


Recommended Posts

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

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

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 by dylbill
Link to comment
Share on other sites

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 by revenant0713
Link to comment
Share on other sites

@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

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

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

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

  • Recently Browsing   0 members

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