• This is a read only backup of the old Emudevs forum. If you want to have anything removed, please message me on Discord: KittyKaev

[SOLVED] Donation Vendor

Status
Not open for further replies.

uDev

Illustrious Member
Does anyone have some script or anything for TrinityCore for donation vendor?
 

uDev

Illustrious Member
Is there some script or anything to have donation vendor ? so user cant buy from vendor items only to see them?
 

Jpp

Administrator
Is there some script or anything to have donation vendor ? so user cant buy from vendor items only to see them?

In that case, I haven't seen anything like that released.

You'll either have to make a custom extended cost and make the item cost that custom extended cost(hack fix), or do a core mod.

You'll probably find it easier to do the extended cost way.

- - - Updated - - -


Interesting way of doing it. I guess this is a better option if you don't want to do a core mod.
 

Rochet2

Moderator / Eluna Dev
The way the script I posted works is that it sends the packet to show the items to the player and when a player buys the item they want, the core checks if the item is real and since its sort of a hacking attempt by the player to try to buy non existing items, the transaction is stopped.
Need to just make sure the NPC doesnt have vendor data in npc_vendor.

The extendedcost would be a nice thing for someone who doesnt want to use c++
 

uDev

Illustrious Member
I'm compiling now with Rochet2 script, gonna test it how it works, since I'm making repack i will use his version :)
 

Dmzll

Emulation Addict
The way the script I posted works is that it sends the packet to show the items to the player and when a player buys the item they want, the core checks if the item is real and since its sort of a hacking attempt by the player to try to buy non existing items, the transaction is stopped.
Need to just make sure the NPC doesnt have vendor data in npc_vendor.

Multivendor?
One item preview option and one option that allows players flagged as donator ('1') to access the vendor.
Then make a column in your char or acc db and make it '0' by default. Then just mess around with the donation script to add a '1' in that column if the player donated.

Or just add each item to the multivendor menu (additem) then you can have diffrent donator ranks depending on how much they donated for example:
'1' = 10USD
'1.5' =15USD
'2' = 20USD

To get item#1 rank '1' is required.

This will require a custom donnor php system, abit to much for a repack? :santaclaus:
 
Last edited:

slp13at420

Mad Scientist
you could also :
create custom currency. something like "donor point".
create a vendor with an ItemExtendedCost using the custom currency.
label the vendor "Web Donor Items"
then you could either let them donate for the currency . if they have the custom currency then they can buy on the spot or they can review items and purchase on website.
 
Last edited:

uDev

Illustrious Member
I'm getting some errors on Rochet2 C++ script on compile :/ Gonna make custom currencie and such :O
 

Jpp

Administrator
The way the script I posted works is that it sends the packet to show the items to the player and when a player buys the item they want, the core checks if the item is real and since its sort of a hacking attempt by the player to try to buy non existing items, the transaction is stopped.
Need to just make sure the NPC doesnt have vendor data in npc_vendor.

The extendedcost would be a nice thing for someone who doesnt want to use c++

I see.

My way of doing it would be to alter the current vendor system. I did something similar a while back and will eventually release it once I get some time to fix the code. Here is a small preview though
DB:
ub7nvVE.png


In-game when you try to buy the item:
Y3bpUe9.jpg
 

uDev

Illustrious Member
nah i will wait for rochet2 to fix whole script when he has time :) I'm completed with currencies anyway just to make patch
 

Tommy

Founder
Fixed:

I recommend looking at this: http://emudevs.com/showthread.php/151-Explaining-TrinityCore-s-Logging-define-directives

Code:
// Scriptname to put into creature_template: PreviewVendor
// dont forget to add vendor flags to the NPC (128)

static UNORDERED_MAP<uint32, std::vector<uint32> > itemList; // holds items from DB after startup

class PreviewLoader : public WorldScript // script that loads items from DB so you can customize the vendors without recompile and restart
{
public:
    PreviewLoader() : WorldScript("PreviewLoader") { }

    void OnStartup()
    {
        itemList.clear(); // reload
        QueryResult result = WorldDatabase.Query("SELECT entry, item FROM npc_vendor_preview");
        if (!result)
            return;
        do
        {
            uint32 entry = (*result)[0].GetUInt32();
            uint32 item = (*result)[1].GetUInt32();
            if (sObjectMgr->GetItemTemplate(item))
                itemList[entry].push_back(item);
        } while (result->NextRow());
    }

    // you can reload config to reload the items.
    // Too lazy to make a command since all the RBAC stuff changes all the time now and not sure how you have it
    void OnConfigLoad(bool reload)
    {
        if (reload)
            OnStartup();
    }
};


class PreviewVendor : public CreatureScript
{
public:
    PreviewVendor() : CreatureScript("PreviewVendor") { }

    bool OnGossipHello(Player* player, Creature* creature)
    {
        CustomSendListInventory(player, creature->GetGUID());
        return true; // stop normal actions
    }

    void CustomSendListInventory(Player* player, uint64 vendorGuid)
    {
        TC_LOG_DEBUG("misc", "WORLD: Sent custom SMSG_LIST_INVENTORY");

        WorldSession* session = player->GetSession();

        Creature* vendor = player->GetNPCIfCanInteractWith(vendorGuid, UNIT_NPC_FLAG_VENDOR);
        if (!vendor)
        {
            TC_LOG_DEBUG("network", "WORLD: SendListInventory - Unit (GUID: %u) not found or you can not interact with him.", uint32(GUID_LOPART(vendorGuid)));
            player->SendSellError(SELL_ERR_CANT_FIND_VENDOR, NULL, 0);
            return;
        }

        // remove fake death
        if (player->HasUnitState(UNIT_STATE_DIED))
            player->RemoveAurasByType(SPELL_AURA_FEIGN_DEATH);

        // Stop the npc if moving
        if (vendor->HasUnitState(UNIT_STATE_MOVING))
            vendor->StopMoving();

        // VendorItemData const* items = vendor->GetVendorItems();
        if (itemList.find(vendor->GetEntry()) == itemList.end())
        {
            WorldPacket data(SMSG_LIST_INVENTORY, 8 + 1 + 1);
            data << uint64(vendorGuid);
            data << uint8(0);                                   // count == 0, next will be error code
            data << uint8(0);                                   // "Vendor has no inventory"
            session->SendPacket(&data);
            return;
        }

        std::vector<uint32> items = itemList[vendor->GetEntry()];
        uint8 itemCount = items.size();
        uint8 count = 0;

        WorldPacket data(SMSG_LIST_INVENTORY, 8 + 1 + itemCount * 8 * 4);
        data << uint64(vendorGuid);

        size_t countPos = data.wpos();
        data << uint8(count);

        // float discountMod = player->GetReputationPriceDiscount(vendor);

        for (uint8 slot = 0; slot < itemCount; ++slot)
        {
            if (ItemTemplate const* itemTemplate = sObjectMgr->GetItemTemplate(items[slot]))
            {
                if (!(itemTemplate->AllowableClass & player->getClassMask()) && itemTemplate->Bonding == BIND_WHEN_PICKED_UP && !player->IsGameMaster())
                    continue;
                // Only display items in vendor lists for the team the
                // player is on. If GM on, display all items.
                if (!player->IsGameMaster() && ((itemTemplate->Flags2 & ITEM_FLAGS_EXTRA_HORDE_ONLY && player->GetTeam() == ALLIANCE) || (itemTemplate->Flags2 == ITEM_FLAGS_EXTRA_ALLIANCE_ONLY && player->GetTeam() == HORDE)))
                    continue;

                // Items sold out are not displayed in list
                // uint32 leftInStock = !item->maxcount ? 0xFFFFFFFF : vendor->GetVendorItemCurrentCount(item);
                // if (!player->IsGameMaster() && !leftInStock)
                //     continue;
                uint32 leftInStock = 0xFFFFFFFF; // show all items

                ConditionList conditions = sConditionMgr->GetConditionsForNpcVendorEvent(vendor->GetEntry(), items[slot]);
                if (!sConditionMgr->IsObjectMeetToConditions(player, vendor, conditions))
                {
                    TC_LOG_DEBUG("misc", "SendListInventory: conditions not met for creature entry %u item %u", vendor->GetEntry(), items[slot]);
                    continue;
                }

                // reputation discount
                // int32 price = item->IsGoldRequired(itemTemplate) ? uint32(floor(itemTemplate->BuyPrice * discountMod)) : 0;
                int32 price = 0;

                data << uint32(slot + 1);       // client expects counting to start at 1
                data << uint32(items[slot]);
                data << uint32(itemTemplate->DisplayInfoID);
                data << int32(leftInStock); // left in stock
                data << uint32(price); // price
                data << uint32(itemTemplate->MaxDurability);
                data << uint32(itemTemplate->BuyCount);
                data << uint32(0); // extended cost

                if (++count >= MAX_VENDOR_ITEMS)
                    break;
            }
        }

        if (count == 0)
        {
            data << uint8(0);
            session->SendPacket(&data);
            return;
        }

        data.put<uint8>(countPos, count);
        session->SendPacket(&data);
    }
};

void AddSC_PreviewVendor()
{
    new PreviewLoader;
    new PreviewVendor;
}
 

Jameyboor

Retired Staff
Code:
// Scriptname to put into creature_template: PreviewVendor
// dont forget to add vendor flags to the NPC (128)

static UNORDERED_MAP<uint32, std::vector<uint32> > itemList; // holds items from DB after startup

class PreviewLoader : public WorldScript // script that loads items from DB so you can customize the vendors without recompile and restart
{
public:
    PreviewLoader() : WorldScript("PreviewLoader") { }

    void OnStartup()
    {
        itemList.clear(); // reload
        QueryResult result = WorldDatabase.Query("SELECT entry, item FROM npc_vendor_preview");
        if (!result)
            return;
        do
        {
            uint32 entry = (*result)[0].GetUInt32();
            uint32 item = (*result)[1].GetUInt32();
            if (sObjectMgr->GetItemTemplate(item))
                itemList[entry].push_back(item);
        } while (result->NextRow());
    }

    // you can reload config to reload the items.
    // Too lazy to make a command since all the RBAC stuff changes all the time now and not sure how you have it
    void OnConfigLoad(bool reload)
    {
        if (reload)
            OnStartup();
    }
};


class PreviewVendor : public CreatureScript
{
public:
    PreviewVendor() : CreatureScript("PreviewVendor") { }

    bool OnGossipHello(Player* player, Creature* creature)
    {
        CustomSendListInventory(player, creature->GetGUID());
        return true; // stop normal actions
    }

    void CustomSendListInventory(Player* player, uint64 vendorGuid)
    {
        TC_LOG_DEBUG("misc", "WORLD: Sent custom SMSG_LIST_INVENTORY");

        WorldSession* session = player->GetSession();

        Creature* vendor = player->GetNPCIfCanInteractWith(vendorGuid, UNIT_NPC_FLAG_VENDOR);
        if (!vendor)
        {
            TC_LOG_DEBUG("network", "WORLD: SendListInventory - Unit (GUID: %u) not found or you can not interact with him.", uint32(GUID_LOPART(vendorGuid)));
            player->SendSellError(SELL_ERR_CANT_FIND_VENDOR, NULL, 0, 0);
            return;
        }

        // remove fake death
        if (player->HasUnitState(UNIT_STATE_DIED))
            player->RemoveAurasByType(SPELL_AURA_FEIGN_DEATH);

        // Stop the npc if moving
        if (vendor->HasUnitState(UNIT_STATE_MOVING))
            vendor->StopMoving();

        // VendorItemData const* items = vendor->GetVendorItems();
        if (itemList.find(vendor->GetEntry()) == itemList.end())
        {
            WorldPacket data(SMSG_LIST_INVENTORY, 8 + 1 + 1);
            data << uint64(vendorGuid);
            data << uint8(0);                                   // count == 0, next will be error code
            data << uint8(0);                                   // "Vendor has no inventory"
            session->SendPacket(&data);
            return;
        }

        std::vector<uint32> items = itemList[vendor->GetEntry()];
        uint8 itemCount = items.size();
        uint8 count = 0;

        WorldPacket data(SMSG_LIST_INVENTORY, 8 + 1 + itemCount * 8 * 4);
        data << uint64(vendorGuid);

        size_t countPos = data.wpos();
        data << uint8(count);

        // float discountMod = player->GetReputationPriceDiscount(vendor);

        for (uint8 slot = 0; slot < itemCount; ++slot)
        {
            if (ItemTemplate const* itemTemplate = sObjectMgr->GetItemTemplate(items[slot]))
            {
                if (!(itemTemplate->AllowableClass & player->getClassMask()) && itemTemplate->Bonding == BIND_WHEN_PICKED_UP && !player->IsGameMaster())
                    continue;
                // Only display items in vendor lists for the team the
                // player is on. If GM on, display all items.
                if (!player->IsGameMaster() && ((itemTemplate->Flags2 & ITEM_FLAGS_EXTRA_HORDE_ONLY && player->GetTeam() == ALLIANCE) || (itemTemplate->Flags2 == ITEM_FLAGS_EXTRA_ALLIANCE_ONLY && player->GetTeam() == HORDE)))
                    continue;

                // Items sold out are not displayed in list
                // uint32 leftInStock = !item->maxcount ? 0xFFFFFFFF : vendor->GetVendorItemCurrentCount(item);
                // if (!player->IsGameMaster() && !leftInStock)
                //     continue;
                uint32 leftInStock = 0xFFFFFFFF; // show all items

                ConditionList conditions = sConditionMgr->GetConditionsForNpcVendorEvent(vendor->GetEntry(), items[slot]);
                if (!sConditionMgr->IsObjectMeetToConditions(player, vendor, conditions))
                {
                    TC_LOG_DEBUG("misc", "SendListInventory: conditions not met for creature entry %u item %u", vendor->GetEntry(), items[slot]);
                    continue;
                }

                // reputation discount
                // int32 price = item->IsGoldRequired(itemTemplate) ? uint32(floor(itemTemplate->BuyPrice * discountMod)) : 0;
                int32 price = 0;

                data << uint32(slot + 1);       // client expects counting to start at 1
                data << uint32(items[slot]);
                data << uint32(itemTemplate->DisplayInfoID);
                data << int32(leftInStock); // left in stock
                data << uint32(price); // price
                data << uint32(itemTemplate->MaxDurability);
                data << uint32(itemTemplate->BuyCount);
                data << uint32(0); // extended cost

                if (++count >= MAX_VENDOR_ITEMS)
                    break;
            }
        }

        if (count == 0)
        {
            data << uint8(0);
            session->SendPacket(&data);
            return;
        }

        data.put<uint8>(countPos, count);
        session->SendPacket(&data);
    }
};

void AddSC_PreviewVendor()
{
    new PreviewLoader;
    new PreviewVendor;
}

There you go.
 
Status
Not open for further replies.
Top