Skip to content

Player Merchant Filter

I am looking for some code that will remove (destroy) X amount of items from a merchant if the inventory count is over a certain number. I have some code implemented on my server but it doesn't work all the time. The code just destroys item if their value is below the average value of all the items so I cant specify how many items to remove.

This is the code that I am using but I would like to specify how many items are removed.
void main()
{
object oShop = OBJECT_SELF;
object oTalker = GetObjectByTag("server_speaker");
int nCount = GetLocalInt(oShop, "itemcount");
int nTotalCost = 0;
object oItem;

if (nCount > 340)
    {
    oItem = GetFirstItemInInventory(oShop);
    while (GetIsObjectValid(oItem))
        {
        nTotalCost = nTotalCost + GetGoldPieceValue(oItem);
        oItem = GetNextItemInInventory(oShop);
        }
    nTotalCost = nTotalCost / nCount;
    oItem = GetFirstItemInInventory(oShop);
    while (GetIsObjectValid(oItem))
        {
        if (GetGoldPieceValue(oItem) < nTotalCost)
            {
            DestroyObject(oItem);
            nCount = nCount - 1;
            }
        oItem = GetNextItemInInventory(oShop);
        }
    AssignCommand (oTalker, ActionSpeakString ("\n<cúú>The PLAYER ITEMS shop inventory has been filtered. Low cost items have been removed.\n", TALKVOLUME_SHOUT));
    SetLocalInt(oShop, "itemcount", nCount);
    }
}

Comments

  • WilliamDracoWilliamDraco Member Posts: 175
    void main()
    {
    object oShop = OBJECT_SELF;
    object oTalker = GetObjectByTag("server_speaker");
    int nCount = GetLocalInt(oShop, "itemcount");
    int nTotalCost = 0;
    int nRemoveCount = 10;
    object oItem;
    
    if (nCount > 340)
        {
        oItem = GetFirstItemInInventory(oShop);
        while (GetIsObjectValid(oItem))
            {
            nTotalCost = nTotalCost + GetGoldPieceValue(oItem);
            oItem = GetNextItemInInventory(oShop);
            }
        nTotalCost = nTotalCost / nCount;
        oItem = GetFirstItemInInventory(oShop);
        while (GetIsObjectValid(oItem) && nRemoveCount > 0)
            {
            if (GetGoldPieceValue(oItem) < nTotalCost)
                {
                DestroyObject(oItem);
                nCount--;
                nRemoveCount--;
                }
            oItem = GetNextItemInInventory(oShop);
            }
        AssignCommand (oTalker, ActionSpeakString ("\n<cúú>The PLAYER ITEMS shop inventory has been filtered. Low cost items have been removed.\n", TALKVOLUME_SHOUT));
        SetLocalInt(oShop, "itemcount", nCount);
        }
    }
    

    Change nRemoveCount up or down from 10 to change the 'x' number of items to remove..
  • 4BOLTMAIN4BOLTMAIN Member Posts: 90
    Thanks for the reply, I figured out that if the shop has a lot of high value items the nTotalCost exceeds the INT limit so I have changed nTotalCost to a float. I think this should solve the problem I am having. I will reply with working code when I have time to test.
  • 4BOLTMAIN4BOLTMAIN Member Posts: 90
    edited April 2020
    I havent added a count for items to be removed because if nRemoveCount is a high number the script will not remove items with a higher gold piece value than the average nTotalCost value... and I just realized that I should use a different int for the average.

    This code has been tested and works as intended but now I have to figure out how to stop the filter if anyone on the server is currently browsing the shop.
    object oTalker = GetObjectByTag("nasher_set");
    int nAverageCost, nCount = GetLocalInt(oShop, "itemcount");
    float fTotalCost = 0.0;
    object oItem;
    string sOldCount = IntToString(nCount);
    string sCount;
    
    if (nCount > 400)
        {
        oItem = GetFirstItemInInventory(oShop);
        while (GetIsObjectValid(oItem))
            {
            fTotalCost = fTotalCost + IntToFloat (GetGoldPieceValue(oItem));
            oItem = GetNextItemInInventory(oShop);
            }
        nAverageCost = FloatToInt (fTotalCost / nCount);
        oItem = GetFirstItemInInventory(oShop);
        while (GetIsObjectValid(oItem))
            {
            if (GetGoldPieceValue(oItem) < nAverageCost)
                {
                DestroyObject(oItem);
                nCount = nCount - 1;
                }
            oItem = GetNextItemInInventory(oShop);
            }
        sCount = IntToString(nCount);
        AssignCommand (oTalker, ActionSpeakString ("The Player Items shop inventory has been filtered. Low cost items have been removed.", TALKVOLUME_SHOUT));
        SetLocalInt(oShop, "itemcount", nCount);
        WriteTimestampedLogEntry("Shop Filter");
        WriteTimestampedLogEntry("Old Count: " + sOldCount);
        WriteTimestampedLogEntry("New Count: " + sCount);
        }
    }
    
  • dunahandunahan Member Posts: 139
    How about setting a custom OnOpenShop/OnCloseShop script? That could set/delete a variable, before the shop opens/closes. WIth that you check that var within your script and stop it before it acts?
    4BOLTMAIN
  • 4BOLTMAIN4BOLTMAIN Member Posts: 90
    That is exactly what I did.

    This is the on open script.
    void main()
    {
    object oShop = OBJECT_SELF;
    int nPlayerOpen = GetLocalInt(oShop, "playeropen");
    nPlayerOpen ++;
    SetLocalInt(oShop, "playeropen", nPlayerOpen);
    }
    

    I added this to the top of the script above for the on close script.
    void main()
    {
    
    object oShop = OBJECT_SELF;
    int nPlayerOpen = GetLocalInt(oShop, "playeropen");
    nPlayerOpen --;
    SetLocalInt(oShop, "playeropen", nPlayerOpen);
    if (nPlayerOpen > 0) return;
    

    My servers been running these scripts for about 2 weeks now and it works as intended.
    dunahan
Sign In or Register to comment.