Jump to content

RegisterForMenuOpenCloseEvent("DataMenu"


senterpat

Recommended Posts

So I'm trying to work on something, but for some reason the data menu close only seems to trigger when I close the menu with the "hold to exit" option.

Opening the datamenu with tab allows the debug message to show, but if I close the menu it only fires the debug message once another menu, or the data menu has opened. Upon opening the data menu a second time, I first see the debug message for closing, and then the open debug message is right underneath.

 

The end goal of what I'm doing is to add a keyword when the menu is open to an armor item, and remove it when it closes. Is there a better way to accomplish this?

Below is my current script, trying to get the framework in place:

Keyword Property KeywordToRemove Auto Const

Event OnInit()
  Self.RegisterForMenuOpenCloseEvent("DataMenu")
  Self.RegisterForMenuOpenCloseEvent("InventoryMenu")
EndEvent

Event OnMenuOpenCloseEvent(String asMenuName, Bool abOpening)
	If asMenuName == "DataMenu" && abOpening == True
		If Game.GetPlayer().WornHasKeyword(KeywordToRemove)
			debug.messagebox("haskeyword data open")
			Self.RegisterForMenuOpenCloseEvent("DataMenu") 
			Self.unRegisterForMenuOpenCloseEvent("InventoryMenu")
		endif
	elseIf asMenuName == "DataMenu" && abOpening == False
			debug.messagebox(" haskeyword data close")
			Self.RegisterForMenuOpenCloseEvent("DataMenu") 
			Self.RegisterForMenuOpenCloseEvent("InventoryMenu") 
		
	elseIf asMenuName == "InventoryMenu" && abOpening == True
		If Game.GetPlayer().WornHasKeyword(KeywordToRemove)
			debug.messagebox("haskeyword inventory open")
			Self.RegisterForMenuOpenCloseEvent("DataMenu") 
			Self.unRegisterForMenuOpenCloseEvent("InventoryMenu")
		endif
	elseIf asMenuName == "InventoryMenu" && abOpening == False
			debug.messagebox("haskeyword inventory close")
			Self.RegisterForMenuOpenCloseEvent("DataMenu") 
			Self.RegisterForMenuOpenCloseEvent("InventoryMenu")
	endif						

EndEvent

 

Edited by senterpat
Link to comment
Share on other sites

Here's a quick script that might give you some ideas. I haven't tested it but it should work... maybe with some further development..

Keyword Property myKeyword Auto Const
Armor Property myArmor Auto Const
ObjectMod Property theOMOD Auto Const
{This OMOD should apply the keyword to the InstanceData
of armor instances upon being attached to them.}


Event OnInit()
	; generally, you shouldn't register for two possible overlapping menus without storing their opened states ( i.e., something like IsMenuOpen() with a script variable ) to avoid possible conflicts
	; but of course it depends on testing how the two interacts for you usecase
	; I'd stay away from editing the content of an inventory while it is open or there's a change the script is still processing when it opens so... DataMenu.
	; You can also try use FaderMenu, that loads quite frequently in this game..
	Self.RegisterForMenuOpenCloseEvent("DataMenu")
EndEvent


Event OnMenuOpenCloseEvent(String asMenuName, bool abOpening)
	If abOpening
		If asMenuName == "DataMenu" || asMenuName == "InventoryMenu"	; conditions are not necessary if the script is only registered for the events of these two Menus only
			TryToAttachKeywordToForm(True, myArmor, myKeyword)
		EndIf
	Else
		TryToAttachKeywordToForm(False, myArmor, myKeyword)
	EndIf
EndEvent

Bool Function TryToAttachKeywordToForm(bool abAttach, Armor akArmor, Keyword akKeyword)
	If akArmor != None && akKeyword != None			; some failsafe check to prevent Papyrus log errors if one of appears to be None
		Actor PlayerRef = Game.GetPlayer()			; optimization
		If abAttach == True
			; akArmor not equipped, can be dropped for a very short time
			; the RemoveItem sound is played and it's not an "elegant" or nice way to do this but it's an option
			If PlayerRef.IsEquipped(akArmor) == 0
				ObjectReference ArmorRef = PlayerRef.DropObject(akArmor)
				If ArmorRef
					If ArmorRef.HasKeyword(myKeyword) == False
						ArmorRef.AddKeyword(myKeyword)
					EndIf
					PlayerRef.AddItem(ArmorRef)
				EndIf
			; I'd rather try to add keyword this way; only reliable if PlayerRef has only one item from akArmor in their inventory otherwise you can't know which one "receives" it
			; Use WornHaskeyword only if you know this keyword is surely not attached to an another equipped item
			ElseIf PlayerRef.WornHasKeyword(myKeyword) == 0
				PlayerRef.AttachModToInventoryItem(akArmor, theOMOD)
			EndIf
		Else
			; something similar
		EndIf
	EndIf
EndFunction

 

Link to comment
Share on other sites

Thanks so much! I already tried the OMOD method, sadly when I attach the keyword using that the armors model disappears. I tried doing the reverse and having it start with the keyword and having the OMOD remove it, but that didn't work at all. I never even got to the scripting process when I switched to this method, as I could never get the OMOD on without the armor disappearing, but using a different keyword worked fine.

It's likely due to it being hardcoded, I can manipulate other keywords the same way in testing, but the Armor keyword I was removing let's you hide your space suit whenever the mask would be hidden, but doing so made the inventory really act up, so I wanted to add it back in the menus. Using Add/RemoveKeyword was working, but the triggers were unreliably firing.

I'll keep messing with it but I'm not holding my breath.

Link to comment
Share on other sites

On 11/23/2023 at 5:10 PM, senterpat said:

Thanks so much! I already tried the OMOD method, sadly when I attach the keyword using that the armors model disappears.

Make sure you only have one item of the same type in the inventory. You can use DropObject() or DropFirstObject() for this.

AttachModToInventoryItem(), in some cases, appears to break item instance data if the inventory contains multiple items of the same base object. The VM should log an error, something like "error: singular items are supported" but the function might not exit and break the item. Practically, it can remove all ObjectMods. If you drop the item from the inventory afterward, the item's 3D is reinitialized but the lost ObjectMods won't "reappear". That part of the instance data seems to be unrecoverable.

On 11/23/2023 at 5:10 PM, senterpat said:

It's likely due to it being hardcoded, I can manipulate other keywords the same way in testing, but the Armor keyword I was removing let's you hide your space suit whenever the mask would be hidden, but doing so made the inventory really act up, so I wanted to add it back in the menus. Using Add/RemoveKeyword was working, but the triggers were unreliably firing.

Armors and Weapon have InstanceData that makes the inventory system treat them quite differently. The system relies on events which aren't exposed to Papyrus and calling functions on the items is generally difficult because one needs to find the "right time" to edit their data to avoid issues like that..

I recently finished testing Transfer Inventories (TIN), a new mod I've been working on for a while that will let players export and import any inventories between save games (readable "blueprint files"). I had to decompile the ObjectMod data from reference data and well.. there are quite a few anomalies in the system that's for sure... 🙂

Manipulating references by only editing their inventory item data alone wasn't perfect in Fallout 4 either but "badly" called functions in FO4 could only result in minor 3D glitches and not in a full ObjectMod data purge.. Starfield seems to be a bit worse in this regard.. it really requires making the engine create 3D for the item to handle it safely.

Finally, if you choose to drop the item, make sure to wait until the item's scriptobject (the ItemRef that DropObject() returns) and its 3D are initialized. (Either a simple "If ItemRef != None, then" should do it with some error handling of course). DropObject() should be reliable until you need to process thousands or even millions of items which requires handling stacked items.

Edited by LarannKiar
Link to comment
Share on other sites

  • Recently Browsing   0 members

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