Jump to content

[LE] interacting with merchants and tracking trades?


Sephnroth

Recommended Posts

UPDATE:

 

Just as an update, during my afternoon break today I found Cpsics wonderful beginners tutorial which although basic was plenty to understand how Papyrus works. Roaming through Bethesda's script reference and especially the event reference I'm getting ideas for how I could begin to implement some of the ideas in my head but one thing I am still searching for is a way I could detect transactions with merchants so I can support ALL game merchants (included ones added by other mods!) without instead manually attaching my script to existing merchants in the CK.

 

Ideally I would find a way to tell if the akDestContainer var passed by the OnItemRemoved removed event belonged to a merchant and if so which one (with a ref, so I can alter their avail gold etc - although I do that just by putting in or removing gold coins from the merchant inventory right? IE akDestContainer?) that way I could detect player trades and do it all that way. Thoughts?

 

Original Post:

 

Just having a browse around on my phone and struggling to find information on script based interactions with merchants and trades. I am a programer by trade and have been musing on the idea of creating an economics mod, starting nice and simple, that allows merchants to become richer as they become more successful. So, for example, you take a truck load of stuff to one merchant and sell it all then presumably they will sell it on and take a profit right? It makes no sense they always reset to their default money + investment perk.

 

Would love to make a mod that tracks their weekly (or maybe 48hrly to sync with inventory reset) profit and adds that value to their avail cash.

 

But yeah, I would need to catch the player selling items and see their default value + npc buy price (to work out potential profit), a way to add money to merchants via script (everyone seems to do this manually in CK which is why everything is so static..) and a way to store persistent variables to track it all for the merchants.

 

Not asking for anyone to write this for me but can anyone point me at a good place to start learning how to hook these events? Most promising google result so far led to a forbidden page error!

Edited by Sephnroth
Link to comment
Share on other sites

https://www.creationkit.com/index.php?title=Category:Papyrus

 

everything you need is there. Sounds like something like a script which looks for you to enter the barter menu and then targets the person you are in that barter menu with and totals the value of their stock. Then upon exit, totals it again for the net gain/loss. You could then take that net gain or loss alter a global variable which you start at 100 and drop by 5 for every 10k gold worth of profit they have (or something like that). Then you simply add more leveled lists of more valuable items and even very rare items and more vendor gold in the form of leveled lists which use the global and have "Chance None" (chance the container will not have the item; starts at 100% chance based on your global) set to that global.

 

Anyhoo, that's really just a rough off the top of my head, there are certainly tons of functions that would be helpful for this. and just as a jumping off point, here is a script I developed for a sell cart which you put items in and it sells a random number of stacks between a certain range each day, calculates the gold value and runs a formula to calculate enchanted values, adds it all up and gives you a percentage of the value based on a value which goes up slightly after every so many uses. I'm sure you will find some useful functionality there

 

 

import math

ObjectReference Property SellPile Auto
Float Property TotalSale Auto
Float  Property ValueMod Auto
ObjectReference Property MoneyBox Auto
MiscObject Property Gold001 Auto

Int ItmCnt
Int GoldValue
Int ItemTotal
Int Index
Int RandomItm
Int NumSell
Enchantment E
Form SellItem
Weapon SellWeap
Armor SellArm
GlobalVariable Property SellChestUses Auto
GlobalVariable Property MinSell Auto
GlobalVariable Property MaxSell Auto
Int MinS
Int MaxS


Event OnUpdateGameTime()
    ItemTotal = SellPile.GetNumItems()
    MinS = MinSell.Value as int
    MaxS = MaxSell.Value as int
    NumSell = Utility.RandomInt(MinS, MaxS)
    if NumSell > ItemTotal
        Numsell = ItemTotal
    Endif    
    While NumSell > 0
        NumSell -= 1
        RandomItm = Utility.RandomInt(0, ItemTotal)
        if SellPile.GetNthForm(RandomItm) as weapon
            SellWeap =     SellPile.GetNthForm(RandomItm) as weapon
            ItmCnt = SellPile.GetItemCount(SellWeap)
            if SellWeap.GetEnchantment()
                TotalSale += GetEnchantedGoldValue() * ItmCnt
            Endif
            Int ItemValue = SellWeap.GetGoldValue() * ItmCnt
            TotalSale +=  ItemValue
            Sellpile.Removeitem(SellWeap, ItmCnt)
            ItemTotal = SellPile.GetNumItems()
        Elseif SellPile.GetNthForm(RandomItm) as armor
            SellArm = SellPile.GetNthForm(RandomItm) as armor
            ItmCnt = SellPile.GetItemCount(SellArm)
            if SellArm.GetEnchantment()
                TotalSale += GetEnchantedGoldValue() * ItmCnt
            Endif
            Int ItemValue = SellArm.GetGoldValue() * ItmCnt
            TotalSale +=  ItemValue
            Sellpile.Removeitem(SellArm, ItmCnt)
            ItemTotal = SellPile.GetNumItems()
        Else
            SellItem = SellPile.GetNthForm(RandomItm)
            if SellItem != NONE
                ItmCnt = SellPile.GetItemCount(SellItem)
                Int ItemValue = SellItem.GetGoldValue() * ItmCnt
                TotalSale +=  ItemValue
                Sellpile.Removeitem(SellItem, ItmCnt)
                ItemTotal = SellPile.GetNumItems()
            Endif
        Endif
    EndWhile

    TotalSale *= ValueMod
    MoneyBox.Additem(Gold001, TotalSale as Int)
    TotalSale = 0
if ValueMod < 0.5
    SellChestUses.Value += 1
    if SellChestUses.Value == 10
        Valuemod += 0.02
        SellChestUses.Value = 0
    Endif
Endif
    RegisterForSingleUpdateGameTime(24)
EndEvent

Int Function GetEnchantedGoldValue()
    GoldValue = 0
    if SellPile.GetNthForm(RandomItm) as weapon
        E = SellWeap.GetEnchantment()
    Elseif SellPile.GetNthForm(RandomItm) as Armor
        E = SellArm.GetEnchantment()
    Endif
    Index = 0
    While Index < E.GetNumEffects()
        MagicEffect ME = E.GetNthEffectMagicEffect(Index)
        Float MEBaseCost = ME.GetBaseCost()
        Float Mag = E.GetNthEffectMagnitude(Index)
        Int Dur = E.GetNthEffectDuration(Index)
        Float Calc = Calc + ((MEBaseCost*8) * (pow(Mag,1.1)) * (pow(Dur/10,1.1)  ))
        GoldValue = GoldValue + Calc as int
        Index += 1
    EndWhile
    Return GoldValue
EndFunction
Link to comment
Share on other sites

That's a pretty neat way of doing it! In fact that's a lot more sensible than where I was headed which was to have a an active/inactive state for the script, switch to active when barter is open and assume that any OnItemRemoved events triggered whilst in active state MUST be items sold to a shop and track that items specific value etc. That would allow me in the future to remember what items were sold to an npc and then decide myself when its likely that item has been sold on and if it has NOT been yet then make sure its always in the npc's inventory for a bit of realism but I'm not too worried about that atm - Maybe in the future!

 

I will have a proper look when I'm back at my home office but browsing around wiki on phone I don't see any particular way to detect a barter menu being opened? I see Actor.ShowBarterMenu() but nothing to indicate that the method fires an event for me to catch when it's called. Same for an npc merchants inventory restock - I'm aware in game they happen every 48 hrs but not sure I can catch that (unless its handled by the generic Reset event?). But really that's fine - I shouldn't need that for anything I'm intending if I write my code properly for when a player interacts with a shop.

Link to comment
Share on other sites

  • Recently Browsing   0 members

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