Skip to content

I need help with a Vendor/Merchant Script please.

I couldn't find anything in LS's Script Generator that would help me with this particular thing with a Vendor/Merchant. I need the vendor to only buy special items identified as commodities. Such as COMM_PAINTING_001. I have about 55 of these commodities. Most are Misc. Small, Misc. Medium 1 & 2. I wanted the vendor/merchant to only buy these specific items, not the categories they're in.

I also need it to buy each of these items for different prices, and destroy the items bought from the player.

Thanks in advance!

Comments

  • Ugly_DuckUgly_Duck Member Posts: 179
    You don't need to include all 55 items. If you could do a few like 2 or 3 and show me how to replicate this, that would be fine.
  • TarotRedhandTarotRedhand Member Posts: 1,481
    edited March 2022
    Try marking the items, you don't want them to buy, as stolen and mark the merchant as not buying stolen goods.

    TR
  • Ugly_DuckUgly_Duck Member Posts: 179
    edited March 2022
    I want the vendor to buy only the commodities. Would i have to mark "every" single item in the palette then?
  • Ugly_DuckUgly_Duck Member Posts: 179
    The options for Don't Want and Do Want are by categories in the palette. No option that i could find to only buy the commodities. Unless I'm confused (which is the usual lol).
  • Ugly_DuckUgly_Duck Member Posts: 179
    I don't think there's a way to pick individual items separately, for either Do Buy or Don't Buy
  • meaglynmeaglyn Member Posts: 146
    You could make a copy of the baseitem row(s) for the items you need and recreate them using those baseitem types. Then you can use the built in ability to allow/deny by baseitem type. Otherwise, you will need to have the merchant work from scripts and a convo I think.
  • NeverwinterWightsNeverwinterWights Member Posts: 339
    edited March 2022
    To do this strictly via scripting you could do something like the following in the OnOpened event of the shop:
    //On store open
    void main()
    {
        object oPC = GetLastOpenedBy();
        //object oPC = GetLastUsedBy();//test line
        string sTag;
        object oItem = GetFirstItemInInventory(oPC);
        while (GetIsObjectValid(oItem))
        {
            sTag = GetTag(oItem);
            //Add all exclusionary tags here
            if (sTag != "DILLY_DAGGER" &&
                sTag != "tag of item2" &&
                sTag != "tag of item3" &&
                sTag != "tag of item4" &&
                sTag != "tag of item5")//etc...
            {
                if (!GetStolenFlag(oItem))
                {
                    SetLocalInt(oItem, "TEMP_STOLEN_FLAG", 1);
                    SetStolenFlag(oItem, TRUE);
                }
            }
            oItem = GetNextItemInInventory(oPC);
        }
    
        int iSlot;
        for (iSlot = 0; iSlot < NUM_INVENTORY_SLOTS; iSlot ++)
        {
            oItem = GetItemInSlot(iSlot, oPC);
            if (GetIsObjectValid(oItem))
            {
                if (!GetStolenFlag(oItem))
                {
                    SetLocalInt(oItem, "TEMP_STOLEN_FLAG", 1);
                    SetStolenFlag(oItem, TRUE);
                }
            }
        }
    }
    

    And like so in the OnClosed event of the store:
    //On store closed
    void main()
    {
        object oPC = GetLastClosedBy();
        //object oPC = GetLastUsedBy();//test line
        object oItem = GetFirstItemInInventory(oPC);
        while (GetIsObjectValid(oItem))
        {
            if (GetStolenFlag(oItem))
            {
                if (GetLocalInt(oItem, "TEMP_STOLEN_FLAG"))
                {
                    SetLocalInt(oItem, "TEMP_STOLEN_FLAG", 0);
                    SetStolenFlag(oItem, FALSE);
                }
            }
    
            oItem = GetNextItemInInventory(oPC);
        }
    
        int iSlot;
        for (iSlot = 0; iSlot < NUM_INVENTORY_SLOTS; iSlot ++)
        {
            oItem = GetItemInSlot(iSlot, oPC);
            if (GetIsObjectValid(oItem))
            {
                if (GetLocalInt(oItem, "TEMP_STOLEN_FLAG"))
                {
                    SetLocalInt(oItem, "TEMP_STOLEN_FLAG", 0);
                    SetStolenFlag(oItem, FALSE);
                }
            }
        }
    }
    

    As per @TarotRedhand suggestion, the first script would make every item in your inventory and everything equipped, flagged as "stolen" and set a variable on each of said items, except anything with an exclusionary tag (the only items you want the merchant to buy) or anything that was already flagged as stolen (a regular stolen item). The second script would then return all the temporarily flagged stolen items back to normal as soon as the store closes. And of course you would just make sure that merchant can't buy stolen goods.
    I believe you could also do this same thing by temporarily flagging everything as a "plot" item as well.
    In testing it works so far. However I'm not sure if any bugs might show up if weird things happen like the store not properly closing.

    EDIT: Redundant code. I forgot GetFirst/GetNextInventoryItem already searches item containers. Scripts shortened.
    Post edited by NeverwinterWights on
  • Ugly_DuckUgly_Duck Member Posts: 179
    This works great, thank you! How do I set the buy price for each of the special commodity items? The price the shop keeper pays the player for each item?
  • NeverwinterWightsNeverwinterWights Member Posts: 339
    Ugly_Duck wrote: »
    This works great, thank you! How do I set the buy price for each of the special commodity items? The price the shop keeper pays the player for each item?

    That would be in the item properties of the items themselves. You can add additional costs and what not.
  • MelkiorMelkior Member Posts: 179
    There's an alternate way of doing what you want, but you won't be able to use the default merchant/store. It's far more tedious to script, but it should work, and it has the advantage that you don't need to fiddle with flags and risk messing things up if the flag reversal doesn't work for some reason.

    Sell through a conversation.

    In the merchant's opening greeting, the "Actions Taken" script needs to scan the PC Speaker for all saleable items and make a temporary list on the merchant of everything the PC has which the merchant will buy (possibly including stack sizes and maybe recording not only the tag of each item but the actual item object ID with SetLocalObject)

    If you only want the PC to be able to sell a single item out of a stack at a time, that makes the rest of the conversation and the scripting easier, but still not "easy" as such. You may need to code the conversation so that the PC can switch pages of conversation in order to access the entire list of saleable items, and you'll have to make the conversation change as items are sold so that the player can't attempt to re-sell already sold items.

    I could probably script all of that, but it's not a short or simple job. I know from the experience of coding something similar to handle player accounts during the "no master server for 1.69" era.

    On the other hand, it worked, and when I went back and looked at the script-set and conversation later, I thought to myself, "did I really code that? Wow!" :D

    Just a thought, but are these items exclusively in the game in order to be sold? Because if they have no purpose other than to be sold, you can get away with a far simpler conversation and script. Just a "I want to sell all my X items" conversation choice and an action script which scans all items on the PC Speaker and removes all the "sell only" items, adding the appropriate amount of gold for each item to the PC as it goes.
Sign In or Register to comment.