SevenBlue Posted May 29, 2019 Share Posted May 29, 2019 (edited) So I'm scripting a leveling system for a tailor mod I'm making, and the system works fine, the only problem I'm having is the OnMenuClose event not firing when the player closes the menu. If anyone could shed some light on why I'd be much obliged! State Tailor Event OnBeginState() Debug.Notification("Initialized Tailor State") AddInventoryEventFilter(SB_Clothing_Tier01) AddInventoryEventFilter(SB_Clothing_Tier02) AddInventoryEventFilter(SB_Clothing_Tier03) RegisterForMenu("Crafting Menu") EndEvent Event OnItemAdded(Form akBaseItem, Int aiItemCount, ObjectReference akItemReference, ObjectReference akSourceContainer) if SB_Clothing_Tier01.HasForm(akBaseItem) EXP = 5 Debug.Notification("5 exp") ElseIf SB_Clothing_Tier02.HasForm(akBaseItem) Exp = 15 Debug.Notification("15 exp") ElseIf SB_Clothing_Tier03.HasForm(akBaseItem) Exp = 25 Debug.Notification("25 exp") Else Exp = 0 EndIf TailorEXP = (TailorEXP + Exp) as int If TailorEXP >= 25 && Level01Val == false; SB_Level01Msg.show() SB_Level01.SetValue(1) Level01Val = true; EndIf If TailorEXP >= 125 && Level02Val == false; SB_Level02Msg.show() SB_Level02.SetValue(1) Level02Val = true; EndIf If TailorEXP >= 250 && Level03Val == false; SB_Level03Msg.show() SB_Level03.SetValue(1) Level03Val = true; EndIf EndEvent Event OnMenuClose(String MenuName) SB_TailorEXP.SetValue(TailorEXP) Debug.Notification("Closing Tailor State") GoToState("") EndEvent Event OnEndState() Debug.Notification("Leaving the running state!") EndEvent EndState Edited May 29, 2019 by SevenBlue Link to comment Share on other sites More sharing options...
IsharaMeradin Posted May 29, 2019 Share Posted May 29, 2019 (edited) I haven't used OnMenuClose inside any state other than the default empty state. So there might be something there. You could try registering in the empty state via an OnInit() event. It should still remain registered even when in a different state. The other thing is that you are registering for the Crafting Menu. This menu is called with every workstation type. So it will trigger even if a workstation used is not the one you intend. If you wish it to only run with a specific workstation, you may need to utilize a bool variable. Set it to false by default and set it to true when items added while the crafting menu is open happen to be ones that are results of the system you are working with. Example using your code above: Event OnInit() RegisterForMenu("Crafting Menu") EndEvent State Tailor Event OnBeginState() Debug.Notification("Initialized Tailor State") AddInventoryEventFilter(SB_Clothing_Tier01) AddInventoryEventFilter(SB_Clothing_Tier02) AddInventoryEventFilter(SB_Clothing_Tier03) EndEvent Bool isTailor = false Event OnItemAdded(Form akBaseItem, Int aiItemCount, ObjectReference akItemReference, ObjectReference akSourceContainer) If UI.IsMenuOpen("Crafting Menu") if SB_Clothing_Tier01.HasForm(akBaseItem) isTailor = true EXP = 5 Debug.Notification("5 exp") ElseIf SB_Clothing_Tier02.HasForm(akBaseItem) isTailor = true Exp = 15 Debug.Notification("15 exp") ElseIf SB_Clothing_Tier03.HasForm(akBaseItem) isTailor = true Exp = 25 Debug.Notification("25 exp") Else isTailor = false Exp = 0 EndIf EndIf TailorEXP = (TailorEXP + Exp) as int If TailorEXP >= 25 && Level01Val == false; SB_Level01Msg.show() SB_Level01.SetValue(1) Level01Val = true; EndIf If TailorEXP >= 125 && Level02Val == false; SB_Level02Msg.show() SB_Level02.SetValue(1) Level02Val = true; EndIf If TailorEXP >= 250 && Level03Val == false; SB_Level03Msg.show() SB_Level03.SetValue(1) Level03Val = true; EndIf EndEvent Event OnMenuClose(String MenuName) If isTailor == true SB_TailorEXP.SetValue(TailorEXP) Debug.Notification("Closing Tailor State") GoToState("") EndIf EndEvent Event OnEndState() Debug.Notification("Leaving the running state!") EndEvent EndState Edited May 29, 2019 by IsharaMeradin Link to comment Share on other sites More sharing options...
SevenBlue Posted May 29, 2019 Author Share Posted May 29, 2019 (edited) I got it working! The problem was I was pushing the entirety of my code on a OnEquip event when the player used the sewing kit in their inventory. I split off the leveling functionality into a reference alias on a quest and it worked like a charm! Code below for any future googlers. Scriptname SB_Tailor_Script Extends ReferenceAlias Formlist Property SB_Clothing_Tier01 Auto Formlist Property SB_Clothing_Tier02 Auto Formlist Property SB_Clothing_Tier03 Auto GlobalVariable Property SB_TailorEXP Auto GlobalVariable Property SB_Level01 Auto GlobalVariable Property SB_Level02 Auto GlobalVariable Property SB_Level03 Auto Message Property SB_Level01Msg Auto Message Property SB_Level02Msg Auto Message Property SB_Level03Msg Auto Int EXP Int TailorEXP Bool Level01Val = False; Bool Level02Val = False; Bool Level03Val = False; Bool isTailor = False; Event OnInit() AddInventoryEventFilter(SB_Clothing_Tier01) AddInventoryEventFilter(SB_Clothing_Tier02) AddInventoryEventFilter(SB_Clothing_Tier03) RegisterForMenu("Crafting Menu") EndEvent Event OnMenuOpen(string MenuName) If UI.IsMenuOpen("Crafting Menu") TailorEXP = SB_TailorEXP.GetValue() as int GoToState("Tailor") EndIf EndEvent State Tailor Event OnBeginState() Debug.Notification("Initialized Tailor State") EndEvent Event OnItemAdded(Form akBaseItem, Int aiItemCount, ObjectReference akItemReference, ObjectReference akSourceContainer) if SB_Clothing_Tier01.HasForm(akBaseItem) isTailor = true EXP = 5 ElseIf SB_Clothing_Tier02.HasForm(akBaseItem) isTailor = true Exp = 15 ElseIf SB_Clothing_Tier03.HasForm(akBaseItem) isTailor = true Exp = 25 Else Exp = 0 isTailor = false EndIf TailorEXP = (TailorEXP + Exp) as int If TailorEXP >= 25 && Level01Val == false; SB_Level01Msg.show() SB_Level01.SetValue(1) Level01Val = true; EndIf If TailorEXP >= 125 && Level02Val == false; SB_Level02Msg.show() SB_Level02.SetValue(1) Level02Val = true; EndIf If TailorEXP >= 250 && Level03Val == false; SB_Level03Msg.show() SB_Level03.SetValue(1) Level03Val = true; EndIf EndEvent Event OnMenuClose(String MenuName) GoToState("") SB_TailorEXP.SetValue(TailorEXP) Debug.Notification("Closing Tailor State") EndEvent EndState Edited May 29, 2019 by SevenBlue Link to comment Share on other sites More sharing options...
ReDragon2013 Posted May 30, 2019 Share Posted May 30, 2019 Well you got it working.. like IsharaMeradin wrote, you took a wrong place for function RegisterForMenu(), next is the right: Event OnInit() RegisterForMenu("Crafting Menu") EndEventto make your script a bit smaller and maybe better to maintain you could use next changes I made:SB_Tailor_AliasScript Scriptname SB_Tailor_AliasScript extends ReferenceAlias ; https://forums.nexusmods.com/index.php?/topic/7684428-papyrusskse-onmenuclose-not-firing/ GlobalVariable PROPERTY SB_TailorEXP auto GlobalVariable PROPERTY SB_Level auto ; (0, 1, 2, 3) Message PROPERTY SB_Level01Msg auto Message PROPERTY SB_Level02Msg auto Message PROPERTY SB_Level03Msg auto FormList[] PROPERTY myLists auto ; use array and fill with "SB_Clothing_Tier01", "SB_Clothing_Tier02", "SB_Clothing_Tier03" ;Formlist PROPERTY SB_Clothing_Tier01 auto ;Formlist PROPERTY SB_Clothing_Tier02 auto ;Formlist PROPERTY SB_Clothing_Tier03 auto Float TailorEXP ; [default=0.0] ; -- EVENTs -- ; https://www.creationkit.com/index.php?title=RegisterForMenu_-_Form ; https://www.creationkit.com/index.php?title=IsMenuOpen_-_UI ; https://www.creationkit.com/index.php?title=OnMenuOpen_-_Form ; https://www.creationkit.com/index.php?title=UnregisterForAllMenus_-_Form --> UnregisterForAllMenus() EVENT OnInit() int i = myLists.Length WHILE (i) i = i - 1 self.AddInventoryEventFilter( myLists[i] ) ENDWHILE RegisterForMenu("Crafting Menu") ; you have to register to trigger OnMenuOpen() and OnMenuClose() ENDEVENT EVENT OnMenuOpen(String MenuName) ; SKSE required ;IF UI.IsMenuOpen("Crafting Menu") TailorEXP = SB_TailorEXP.GetValue() ; *I* get current XP value from globalVar gotoState("Tailor") ; ### STATE ### ;ENDIF ENDEVENT EVENT OnMenuClose(String MenuName) ENDEVENT ;================================ State Tailor ; will be active, if player has opened the crafting menu ;=========== EVENT OnMenuOpen(String MenuName) ENDEVENT EVENT OnMenuClose(String MenuName) ; SKSE required SB_TailorEXP.SetValue(TailorEXP) ; *** set new current XP value to GlobalVar gotoState("") ; ### STATE ### ENDEVENT EVENT OnItemAdded(Form akBaseItem, Int aiItemCount, ObjectReference akItemReference, ObjectReference akSourceContainer) myF_Test(akBaseItem, aiItemCount) ENDEVENT ;======= endState ; -- FUNCTIONs -- 2 ;-------------------------------------------------- FUNCTION myF_Test(Form akBaseItem, Int aiItemCount) ;-------------------------------------------------- IF myLists[0].HasForm(akBaseItem) ; SB_Clothing_Tier01 myF_GainXP(5.0 * aiItemCount) RETURN ; - STOP - ENDIF ;--------------------- IF myLists[1].HasForm(akBaseItem) ; SB_Clothing_Tier02 myF_GainXP(15.0 * aiItemCount) RETURN ; - STOP - ENDIF ;--------------------- ;IF myLists[2].HasForm(akBaseItem) ; SB_Clothing_Tier03, cause of AddInventoryEventFilter() this have to be TRUE myF_GainXP(25.0 * aiItemCount) ;ENDIF ENDFUNCTION ;---------------------------- FUNCTION myF_GainXP(Float xp) ; internal helper ;---------------------------- TailorEXP += xp ; *** update XP value float f = SB_Level.GetValue() IF (f == 0) IF (TailorEXP >= 25) SB_Level.SetValue(1) ; 1.0 SB_Level01Msg.show() ENDIF ELSEIF (f == 1) IF (TailorEXP >= 125) SB_Level.SetValue(2) ; 2.0 SB_Level02Msg.show() ENDIF ELSEIF (f == 2) IF (TailorEXP >= 250) SB_Level.SetValue(3) ; 3.0 SB_Level03Msg.show() ENDIF ENDIF ENDFUNCTION Link to comment Share on other sites More sharing options...
SevenBlue Posted June 1, 2019 Author Share Posted June 1, 2019 Well you got it working.. like IsharaMeradin wrote, you took a wrong place for function RegisterForMenu(), next is the right: Event OnInit() RegisterForMenu("Crafting Menu") EndEventto make your script a bit smaller and maybe better to maintain you could use next changes I made: SB_Tailor_AliasScript Scriptname SB_Tailor_AliasScript extends ReferenceAlias ; https://forums.nexusmods.com/index.php?/topic/7684428-papyrusskse-onmenuclose-not-firing/ GlobalVariable PROPERTY SB_TailorEXP auto GlobalVariable PROPERTY SB_Level auto ; (0, 1, 2, 3) Message PROPERTY SB_Level01Msg auto Message PROPERTY SB_Level02Msg auto Message PROPERTY SB_Level03Msg auto FormList[] PROPERTY myLists auto ; use array and fill with "SB_Clothing_Tier01", "SB_Clothing_Tier02", "SB_Clothing_Tier03" ;Formlist PROPERTY SB_Clothing_Tier01 auto ;Formlist PROPERTY SB_Clothing_Tier02 auto ;Formlist PROPERTY SB_Clothing_Tier03 auto Float TailorEXP ; [default=0.0] ; -- EVENTs -- ; https://www.creationkit.com/index.php?title=RegisterForMenu_-_Form ; https://www.creationkit.com/index.php?title=IsMenuOpen_-_UI ; https://www.creationkit.com/index.php?title=OnMenuOpen_-_Form ; https://www.creationkit.com/index.php?title=UnregisterForAllMenus_-_Form --> UnregisterForAllMenus() EVENT OnInit() int i = myLists.Length WHILE (i) i = i - 1 self.AddInventoryEventFilter( myLists[i] ) ENDWHILE RegisterForMenu("Crafting Menu") ; you have to register to trigger OnMenuOpen() and OnMenuClose() ENDEVENT EVENT OnMenuOpen(String MenuName) ; SKSE required ;IF UI.IsMenuOpen("Crafting Menu") TailorEXP = SB_TailorEXP.GetValue() ; *I* get current XP value from globalVar gotoState("Tailor") ; ### STATE ### ;ENDIF ENDEVENT EVENT OnMenuClose(String MenuName) ENDEVENT ;================================ State Tailor ; will be active, if player has opened the crafting menu ;=========== EVENT OnMenuOpen(String MenuName) ENDEVENT EVENT OnMenuClose(String MenuName) ; SKSE required SB_TailorEXP.SetValue(TailorEXP) ; *** set new current XP value to GlobalVar gotoState("") ; ### STATE ### ENDEVENT EVENT OnItemAdded(Form akBaseItem, Int aiItemCount, ObjectReference akItemReference, ObjectReference akSourceContainer) myF_Test(akBaseItem, aiItemCount) ENDEVENT ;======= endState ; -- FUNCTIONs -- 2 ;-------------------------------------------------- FUNCTION myF_Test(Form akBaseItem, Int aiItemCount) ;-------------------------------------------------- IF myLists[0].HasForm(akBaseItem) ; SB_Clothing_Tier01 myF_GainXP(5.0 * aiItemCount) RETURN ; - STOP - ENDIF ;--------------------- IF myLists[1].HasForm(akBaseItem) ; SB_Clothing_Tier02 myF_GainXP(15.0 * aiItemCount) RETURN ; - STOP - ENDIF ;--------------------- ;IF myLists[2].HasForm(akBaseItem) ; SB_Clothing_Tier03, cause of AddInventoryEventFilter() this have to be TRUE myF_GainXP(25.0 * aiItemCount) ;ENDIF ENDFUNCTION ;---------------------------- FUNCTION myF_GainXP(Float xp) ; internal helper ;---------------------------- TailorEXP += xp ; *** update XP value float f = SB_Level.GetValue() IF (f == 0) IF (TailorEXP >= 25) SB_Level.SetValue(1) ; 1.0 SB_Level01Msg.show() ENDIF ELSEIF (f == 1) IF (TailorEXP >= 125) SB_Level.SetValue(2) ; 2.0 SB_Level02Msg.show() ENDIF ELSEIF (f == 2) IF (TailorEXP >= 250) SB_Level.SetValue(3) ; 3.0 SB_Level03Msg.show() ENDIF ENDIF ENDFUNCTION I'll have to do some reading to understand all the changes you made but I'll certainly take it under advisement, thank you! Link to comment Share on other sites More sharing options...
Recommended Posts