Haravikk Posted January 21, 2023 Share Posted January 21, 2023 (edited) 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 EndEventBasically 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 January 21, 2023 by Haravikk Link to comment Share on other sites More sharing options...
Recommended Posts