Advertisement
Rochet2

preview vendor

Jun 13th, 2016
415
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. // Scriptname to put into creature_template: PreviewVendor
  2. // dont forget to add vendor flags to the NPC (128)
  3.  
  4. #include "Common.h"
  5. #include "ScriptMgr.h"
  6. #include "Player.h"
  7. #include "Creature.h"
  8. #include "ObjectGuid.h"
  9. #include "WorldPacket.h"
  10. #include "WorldSession.h"
  11.  
  12. static std::unordered_map<uint32, std::vector<uint32> > itemList; // holds items from DB after startup
  13.  
  14. class PreviewLoader : public WorldScript // script that loads items from DB so you can customize the vendors without recompile and restart
  15. {
  16. public:
  17.     PreviewLoader() : WorldScript("PreviewLoader") { }
  18.  
  19.     void OnStartup()
  20.     {
  21.         itemList.clear(); // reload
  22.         QueryResult result = WorldDatabase.Query("SELECT entry, item FROM npc_vendor_preview");
  23.         if (!result)
  24.             return;
  25.         do
  26.         {
  27.             uint32 entry = (*result)[0].GetUInt32();
  28.             uint32 item = (*result)[1].GetUInt32();
  29.             if (sObjectMgr->GetItemTemplate(item))
  30.                 itemList[entry].push_back(item);
  31.         } while (result->NextRow());
  32.     }
  33.  
  34.     // you can reload config to reload the items.
  35.     // Too lazy to make a command since all the RBAC stuff changes all the time now and not sure how you have it
  36.     void OnConfigLoad(bool reload)
  37.     {
  38.         if (reload)
  39.             OnStartup();
  40.     }
  41. };
  42.  
  43.  
  44. class PreviewVendor : public CreatureScript
  45. {
  46. public:
  47.     PreviewVendor() : CreatureScript("PreviewVendor") { }
  48.  
  49.     bool OnGossipHello(Player* player, Creature* creature)
  50.     {
  51.         CustomSendListInventory(player, creature->GetGUID());
  52.         return true; // stop normal actions
  53.     }
  54.  
  55.     void CustomSendListInventory(Player* player, ObjectGuid vendorGuid)
  56.     {
  57.         TC_LOG_DEBUG("network", "WORLD: Sent custom SMSG_LIST_INVENTORY");
  58.  
  59.         WorldSession* session = player->GetSession();
  60.  
  61.         Creature* vendor = player->GetNPCIfCanInteractWith(vendorGuid, UNIT_NPC_FLAG_VENDOR);
  62.         if (!vendor)
  63.         {
  64.             TC_LOG_DEBUG("network", "WORLD: SendListInventory - %s not found or you can not interact with him.", vendorGuid.ToString().c_str());
  65.             player->SendSellError(SELL_ERR_CANT_FIND_VENDOR, NULL, ObjectGuid::Empty, 0);
  66.             return;
  67.         }
  68.  
  69.         // remove fake death
  70.         if (player->HasUnitState(UNIT_STATE_DIED))
  71.             player->RemoveAurasByType(SPELL_AURA_FEIGN_DEATH);
  72.  
  73.         // Stop the npc if moving
  74.         if (vendor->HasUnitState(UNIT_STATE_MOVING))
  75.             vendor->StopMoving();
  76.  
  77.         // VendorItemData const* items = vendor->GetVendorItems();
  78.         if (itemList.find(vendor->GetEntry()) == itemList.end())
  79.         {
  80.             WorldPacket data(SMSG_LIST_INVENTORY, 8 + 1 + 1);
  81.             data << uint64(vendorGuid);
  82.             data << uint8(0);                                   // count == 0, next will be error code
  83.             data << uint8(0);                                   // "Vendor has no inventory"
  84.             session->SendPacket(&data);
  85.             return;
  86.         }
  87.  
  88.         std::vector<uint32> items = itemList[vendor->GetEntry()];
  89.         uint8 itemCount = items.size();
  90.         uint8 count = 0;
  91.  
  92.         WorldPacket data(SMSG_LIST_INVENTORY, 8 + 1 + itemCount * 8 * 4);
  93.         data << uint64(vendorGuid);
  94.  
  95.         size_t countPos = data.wpos();
  96.         data << uint8(count);
  97.  
  98.         // float discountMod = player->GetReputationPriceDiscount(vendor);
  99.  
  100.         for (uint8 slot = 0; slot < itemCount; ++slot)
  101.         {
  102.             if (ItemTemplate const* itemTemplate = sObjectMgr->GetItemTemplate(items[slot]))
  103.             {
  104.                 if (!(itemTemplate->AllowableClass & player->getClassMask()) && itemTemplate->Bonding == BIND_WHEN_PICKED_UP && !player->IsGameMaster())
  105.                     continue;
  106.                 // Only display items in vendor lists for the team the
  107.                 // player is on. If GM on, display all items.
  108.                 if (!player->IsGameMaster() && ((itemTemplate->Flags2 & ITEM_FLAGS_EXTRA_HORDE_ONLY && player->GetTeam() == ALLIANCE) || (itemTemplate->Flags2 == ITEM_FLAGS_EXTRA_ALLIANCE_ONLY && player->GetTeam() == HORDE)))
  109.                     continue;
  110.  
  111.                 // Items sold out are not displayed in list
  112.                 // uint32 leftInStock = !item->maxcount ? 0xFFFFFFFF : vendor->GetVendorItemCurrentCount(item);
  113.                 // if (!player->IsGameMaster() && !leftInStock)
  114.                 //     continue;
  115.                 uint32 leftInStock = 0xFFFFFFFF; // show all items
  116.  
  117.                 if (!sConditionMgr->IsObjectMeetingVendorItemConditions(vendor->GetEntry(), items[slot], player, vendor))
  118.                 {
  119.                     TC_LOG_DEBUG("condition", "SendListInventory: conditions not met for creature entry %u item %u", vendor->GetEntry(), items[slot]);
  120.                     continue;
  121.                 }
  122.  
  123.                 // reputation discount
  124.                 // int32 price = item->IsGoldRequired(itemTemplate) ? uint32(floor(itemTemplate->BuyPrice * discountMod)) : 0;
  125.                 int32 price = 0;
  126.  
  127.                 data << uint32(slot + 1);       // client expects counting to start at 1
  128.                 data << uint32(items[slot]);
  129.                 data << uint32(itemTemplate->DisplayInfoID);
  130.                 data << int32(leftInStock); // left in stock
  131.                 data << uint32(price); // price
  132.                 data << uint32(itemTemplate->MaxDurability);
  133.                 data << uint32(itemTemplate->BuyCount);
  134.                 data << uint32(0); // extended cost
  135.  
  136.                 if (++count >= MAX_VENDOR_ITEMS)
  137.                     break;
  138.             }
  139.         }
  140.  
  141.         if (count == 0)
  142.         {
  143.             data << uint8(0);
  144.             session->SendPacket(&data);
  145.             return;
  146.         }
  147.  
  148.         data.put<uint8>(countPos, count);
  149.         session->SendPacket(&data);
  150.     }
  151. };
  152.  
  153. void AddSC_PreviewVendor()
  154. {
  155.     new PreviewLoader;
  156.     new PreviewVendor;
  157. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement