Jump to content

Any way to detect if an item is being sold before it is?


Recommended Posts

I can detect once an item is sold to a vendor but is there a way to detect if an item is about to be sold before it is?

 

So that the sale could be stopped or some other action taken before it is.

i.e. pop up a yes/no message box... so sale could be cancelled.

Link to comment
Share on other sites

Not with papyrus alone that is for sure.

 

I don't know if it is possible, but perhaps it is. Maybe an SKSE DLL plugin or Net Framework DLL plugin could intercept the "sell key press" and put up a yes / no prompt. Otherwise, I do not think it is possible.

 

That said, you could reverse the sale.

Use SKSE and register for the barter menu. When the barter menu is open, listen for the OnItemAdded and OnItemRemoved events. Store in a local variable the incoming gold quantity and store in local variables the item that was sold as well as its quantity. Pop up a confirmation box. If the player wants to reverse the sale, remove the item from the merchant's chest and give it back to the player. And remove the gold from the player and send it back to the merchant's chest.

Link to comment
Share on other sites

Hmm... that was the conclusion I came to but thought I would ask just in case I missed something :)

 

I'm not going to attempt a dll :D

 

So I guess the reverse sell will be the way I'll have to go...

I have been playing around with the barter menu, OnItemAdded and OnItemRemoved events... so I'll see what I can do with them...

 

Thanks for the thoughts :)

Link to comment
Share on other sites

You'll want to use states. Register for the menu and use OnMenuOpen in either the empty state or the starting active state. When the menu opens, switch states and have the OnItemAdded and OnItemRemoved events with your code. Put OnMenuClose in this same state and use that to switch out of the "store state". That way your script isn't listening for the OnItemAdded and OnItemRemoved events without reason.

Link to comment
Share on other sites

I have to say I am getting confused trying to get this to work :(

When you say what to do it makes sense until I try and impliment it :(

 

Do you use anything like this in any of your mods I could look at for an example ?

 

 

Origanally was hoping there was a way to intervine in the transaction the same way the game does it if the vendor doesn't have the funds to purchase the goods.

I guess that's hard coded though...

Link to comment
Share on other sites

I think my problem here is I can't find where to actually add the RegisterForMenu("BarterMenu")

I've tried just about every event I can... added debug code with each but nothing ever shows to indicate it has been actioned...

Edited by TheWanderer001
Link to comment
Share on other sites

Register for the menu in the OnInit event. This will run the first time the object holding the script is loaded. New game is probably warranted.

 

You can use the OnPlayerLoadGame event on a player alias script and remotely call a function on whatever other script needs to run the menu events and register for the menu at that time.

Link to comment
Share on other sites

Thanks so much for all you advice but...

 

Got the OnInit event to Register the menu… but I’m just going in circles trying to get anything else to work… so for now I’m going to put trying to make this a vendor game wide generic action on the back burner.

I do have a function already built into the bag that allows the player to sell anything via "The Raven" where I exclude the bag itself… so I’m just going to expand this to include selling the bag the way I’m trying to there.

Having control over the container and the bag makes this so easy :D

Link to comment
Share on other sites

So you're trying to maybe prevent sale to any vendor? If so IsHaraMeradin's advice is good. Here's an example script of how to do that. Put it on a reference alias in a quest that's start game enabled pointing to the player.

 

 

 

MiscObject Property Gold001 Auto 
Formlist Property FormsNotToSell Auto 
Actor Property PlayerRef Auto 
Int Property PlayerGold Auto Hidden
Bool AddOrRemoveItems


Event OnInit() 
    AddInventoryEventFilter(Gold001)
    AddInventoryEventFilter(FormsNotToSell)
    
    RegisterForMenu("BarterMenu") 
    If UI.IsMenuOpen("BarterMenu")
        GoToState("InBarterMenu")
    Else 
        GoToState("Waiting") 
    EndIf
EndEvent 


State Waiting 
    Event OnMenuOpen(String menuName)
        GoToState("InBarterMenu")
    EndEvent
    
    Event OnItemAdded(Form akBaseItem, Int aiItemCount, ObjectReference akItemReference, ObjectReference akSourceContainer)
        ;do nothing
    EndEvent 
    
    Event OnItemRemoved(Form akBaseItem, Int aiItemCount, ObjectReference akItemReference, ObjectReference akDestContainer)
        ;do nothing
    EndEvent
EndState


State InBarterMenu
    Event OnBeginState()
        PlayerGold = PlayerRef.GetItemCount(Gold001) 
        AddOrRemoveItems = False
    EndEvent
    
    Event OnItemRemoved(Form akBaseItem, Int aiItemCount, ObjectReference akItemReference, ObjectReference akDestContainer) 
        If akDestContainer != None && AddOrRemoveItems == False
            If FormsNotToSell.HasForm(akBaseItem) 
                AddOrRemoveItems = True ;prevent OnItemAdded and OnItemRemoved functions from running
                Int GoldDiff = PlayerRef.GetItemCount(Gold001) - PlayerGold 
                akDestContainer.RemoveItem(akBaseItem, aiItemCount, False, PlayerRef) ;give sold items back to player 
                PlayerRef.RemoveItem(Gold001, GoldDiff, True, akDestContainer) ;give gold gained back to trader
                Utility.WaitMenuMode(0.01)
                AddOrRemoveItems = False
                PlayerGold = PlayerRef.GetItemCount(Gold001) 
            Endif
        EndIf
        
        If akBaseItem == Gold001 && AddOrRemoveItems == False
            Utility.WaitMenuMode(0.01)
            PlayerGold = PlayerRef.GetItemCount(Gold001) 
        Endif
    EndEvent
    
    Event OnItemAdded(Form akBaseItem, Int aiItemCount, ObjectReference akItemReference, ObjectReference akSourceContainer) 
        If akBaseItem == Gold001 && AddOrRemoveItems == False 
            Utility.WaitMenuMode(0.01)
            PlayerGold = PlayerRef.GetItemCount(Gold001) 
        Endif
    EndEvent
    
    Event OnMenuClose(String menuName)
        GoToState("Waiting")
    EndEvent
Endstate

 

Link to comment
Share on other sites

Ah... okay thanks... I think I understand it :)

 

Doubt I'd have worked that out... well not without a lot of trial'n'Error.

 

Am I correct in thinking that if I wanted to add a menu instead of just returning it, it would go between the two AddOrRemoveItems

Link to comment
Share on other sites

  • Recently Browsing   0 members

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