Jump to content

Alternatives to ShowGiftMenu()?


Haravikk

Recommended Posts

So I was hoping to add the ability for the player to give an NPC any item they wish as a "gift" (they're actually trading for something, just not money), but Fallout 4 appears to lack the Actor.ShowGiftMenu() function from Skyrim, so I'm wondering what the alternatives are?

 

Actor.OpenInventory(True) won't work on its own because this would allow the player to also take items which isn't what I want.

 

The only alternative I've thought of so far is to use a hidden actor or container object and use OnItemAdded() to detect items and remove them (after calculating some score), would that be the best way to do this? A hidden actor would allow me to use .OpenInventory(True), but I'm assuming a container triggered using .Activate(Player) ought to work as well (and might be easier)? The downside is that this doesn't seem like it would allow me to do any filtering of what items can be given (unless I return "rejected" items)?

 

Here's what I'm thinking of doing (probably contains typos, I write all my scripts outside of CK and haven't had a chance to test yet):

ScriptName GenerositySimulator Extends Quest

CustomEvent OnGiftsReceived
    {Event fired once gifts have been given with Var[] args of: [0]:Actor, [1]:Int=Total items, [2]:Int=Total value}

ReferenceAlias Property GiftsContainer Auto Const Mandatory
    {Alias pointing at the container that the player will transfer gifts into for processing}

Int Property TimerGifts = 1 AutoReadOnly

Actor _GiftsActor = None

Function ShowGiftMenu(Actor akActor)
	If akActor
		_GiftsActor = akActor

		StartTimer(0.5, TimerGifts) ; Inventory menu should pause game
		akGifts.Activate()
	EndIf
EndFunction
	{Opens a menu to allow the player to give items that will be transferred to akActor}

Event ObjectReference.OnItemAdded(ObjectReference akSender, Form akBaseItem, Int auiItemCount, ObjectReference akItemReference, ObjectReference akSourceContainer)
	If !_GiftsActor || (akSourceContainer != PlayerRef)
		; No longer accepting gifts, return item(s)
		If akItemReference
			akSender.RemoveItem(akItemReference, 1, False, akSourceContainer)
		ElseIf akBaseItem && (auiItemCount > 0)
			akSender.RemoveItem(akBaseItem, auiItemCount, False, akSourceContainer)
		EndIf
	EndIf
EndEvent

Event OnQuestInit()
	RegisterRemoteEvent(GiftsContainer.GetReference(), "OnItemAdded")
EndEvent

Event OnTimerEvent(Int aiTimerID)
;	If aiTimerID == TimerGifts
		ObjectReference akGiftsContainer = GiftsContainer.GetReference()
		If _GiftsActor
			Int auiCount = 0
			Int auiValue = 0
			
			; Process the gift(s) given
			Int auiIndex = 0
			Form[] akGifts = akGiftsContainer.GetInventoryItems()
			While auiIndex < akGifts.Length
				Form akGift = akGifts[auiIndex]
				Int auiItemValue = akGift.GetGoldValue()
				auiIndex += 1
				
				; If the item is a reference, use base object if needed for value
				ObjectReference akItemReference = akGift as ObjectReference
				If akItemReference && auiItemValue <= 0
					auiItemValue = akItemReference.GetBaseObject().GetGoldValue()
				EndIf
					
				Int auiItemCount = akGiftsContainer.GetItemCount(akGift)
				If (auiItemCount > 0) && (auiItemValue > 0)
					akGiftsContainer.RemoveItem(akGift, auiItemCount, True, _GiftsActor)
					auiCount += auiItemCount
					auiValue += auiItemValue * auiItemCount
				EndIf
			EndWhile
		
			Var[] akArgs = new Var[3]
			akArgs[0] = akActor as Var
			akArgs[1] = auiCount as Var
			akArgs[2] = auiValue as Var

			SendCustomEvent("OnGiftsReceived", akArgs)
		EndIf
		
		; Return anything left in the container
		akGiftsContainer.RemoveAllItems(PlayerRef, True)

		_GiftsActor = None
;	EndIf
EndEvent

Basically the idea is that ShowMenu() uses Activate() to bring up the container inventory (which should be empty), and starts a short timer (which should be frozen by the menu) and when the timer expires it uses the F4SE GetInventoryItems() function to process the entire contents, sending anything valuable to the target actor and returning everything else to the player and firing an event.

Edited by Haravikk
Link to comment
Share on other sites

  • Recently Browsing   0 members

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