Advertisement
Rochet2

Transmogrification.cpp

Jun 26th, 2012
304
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 7.67 KB | None | 0 0
  1. /*
  2. Transmogrification 3.3.5a - Gossip Menu
  3. By Rochet2
  4. Now with DB implemented
  5.  
  6. ScriptName for NPC:
  7. NPC_Transmogrify
  8.  
  9. ScriptLoader.cpp:
  10. void AddSC_NPC_Transmogrify();
  11. AddSC_NPC_Transmogrify();
  12. */
  13.  
  14. #include "ScriptPCH.h"
  15.  
  16. class NPC_Transmogrify : public CreatureScript
  17. {
  18. public:
  19.     NPC_Transmogrify() : CreatureScript("NPC_Transmogrify") { }
  20.  
  21.     bool OnGossipHello(Player* pPlayer, Creature* pUnit)
  22.     {
  23.         pPlayer->PlayerTalkClass->ClearMenus();
  24.         for (uint8 Slot = EQUIPMENT_SLOT_START; Slot < EQUIPMENT_SLOT_END; Slot++)
  25.         {
  26.             if (Item* pItem = pPlayer->GetItemByPos(INVENTORY_SLOT_BAG_0, Slot))
  27.             {
  28.                 uint32 Quality = pItem->GetTemplate()->Quality;
  29.                 if(Quality == ITEM_QUALITY_UNCOMMON || Quality == ITEM_QUALITY_RARE || Quality == ITEM_QUALITY_EPIC || Quality == ITEM_QUALITY_HEIRLOOM)
  30.                     if(char* SlotName = GetSlotName(Slot))
  31.                         pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_TRAINER, SlotName, EQUIPMENT_SLOT_END, Slot);
  32.             }
  33.         }
  34.         pPlayer->ADD_GOSSIP_ITEM_EXTENDED(GOSSIP_ICON_INTERACT_1, "Remove transmogrifications", EQUIPMENT_SLOT_END+3, 0, "Remove transmogrifications from all equipped items?", 0, false);
  35.         pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_TALK, "Update Menu", EQUIPMENT_SLOT_END+1, 0);
  36.         pPlayer->SEND_GOSSIP_MENU(DEFAULT_GOSSIP_MESSAGE, pUnit->GetGUID());        
  37.         return true;
  38.     }
  39.  
  40.     bool OnGossipSelect(Player* pPlayer, Creature* pUnit, uint32 sender, uint32 uiAction)
  41.     {
  42.         pPlayer->PlayerTalkClass->ClearMenus();
  43.         if(sender == EQUIPMENT_SLOT_END)
  44.         {
  45.             if (Item* OLD = pPlayer->GetItemByPos(INVENTORY_SLOT_BAG_0, uiAction))
  46.             {
  47.                 uint32 GUID = pPlayer->GetGUIDLow();
  48.                 Items[GUID].clear();
  49.                 uint32 limit = 0;
  50.                 for (uint8 i = INVENTORY_SLOT_ITEM_START; i < INVENTORY_SLOT_ITEM_END; i++)
  51.                 {
  52.                     if(limit > 30)
  53.                         break;
  54.                     if (Item* pItem = pPlayer->GetItemByPos(INVENTORY_SLOT_BAG_0, i))
  55.                         if(IsSuitable(pItem, OLD, pPlayer))
  56.                             if(Items[GUID].find(pItem->GetTemplate()->DisplayInfoID) == Items[GUID].end())
  57.                             {
  58.                                 limit++;
  59.                                 Items[GUID][pItem->GetTemplate()->DisplayInfoID] = pItem;
  60.                                 pPlayer->ADD_GOSSIP_ITEM_EXTENDED(GOSSIP_ICON_INTERACT_1, pItem->GetTemplate()->Name1, uiAction, pItem->GetTemplate()->DisplayInfoID, AreYouSure(uiAction, pItem), 0, false);
  61.                             }
  62.                 }
  63.  
  64.                 for (uint8 i = INVENTORY_SLOT_BAG_START; i < INVENTORY_SLOT_BAG_END; i++)
  65.                 {
  66.                     if (Bag* pBag = pPlayer->GetBagByPos(i))
  67.                         for (uint32 j = 0; j < pBag->GetBagSize(); j++)
  68.                         {
  69.                             if(limit > 30)
  70.                                 break;
  71.                             if (Item* pItem = pPlayer->GetItemByPos(i, j))
  72.                                 if(IsSuitable(pItem, OLD, pPlayer))
  73.                                     if(Items[GUID].find(pItem->GetTemplate()->DisplayInfoID) == Items[GUID].end())
  74.                                     {
  75.                                         limit++;
  76.                                         Items[GUID][pItem->GetTemplate()->DisplayInfoID] = pItem;
  77.                                         pPlayer->ADD_GOSSIP_ITEM_EXTENDED(GOSSIP_ICON_INTERACT_1, pItem->GetTemplate()->Name1, uiAction, pItem->GetTemplate()->DisplayInfoID, AreYouSure(uiAction, pItem), 0, false);
  78.                                     }
  79.                         }
  80.                 }
  81.  
  82.                 if(Items[GUID].empty())
  83.                 {
  84.                     pPlayer->GetSession()->SendNotification("You have no suitable items in your inventory");
  85.                     OnGossipHello(pPlayer, pUnit);
  86.                     return true;
  87.                 }
  88.                 pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_TALK, "Back..", EQUIPMENT_SLOT_END+1, 0);
  89.                 pPlayer->SEND_GOSSIP_MENU(DEFAULT_GOSSIP_MESSAGE, pUnit->GetGUID());
  90.             }
  91.             else
  92.                 OnGossipHello(pPlayer, pUnit);
  93.         }
  94.         else if(sender == EQUIPMENT_SLOT_END+1)
  95.             OnGossipHello(pPlayer, pUnit);
  96.         else if(sender == EQUIPMENT_SLOT_END+2)
  97.             pPlayer->PlayerTalkClass->SendCloseGossip();
  98.         else if(sender == EQUIPMENT_SLOT_END+3)
  99.         {
  100.             for (uint8 Slot = EQUIPMENT_SLOT_START; Slot < EQUIPMENT_SLOT_END; Slot++)
  101.                 if (Item* pItem = pPlayer->GetItemByPos(INVENTORY_SLOT_BAG_0, Slot))
  102.                 {
  103.                     if(pItem->FakeEntry || pItem->FakeOwner)
  104.                     {
  105.                         CharacterDatabase.PExecute("UPDATE item_instance SET FakeEntry = 0, FakeOwner = 0 WHERE guid = %u", pItem->GetGUIDLow());
  106.                         pItem->FakeEntry = NULL;
  107.                         pItem->FakeOwner = NULL;
  108.                     }
  109.                     pPlayer->SetUInt32Value(PLAYER_VISIBLE_ITEM_1_ENTRYID + (Slot * 2), pItem->GetEntry());
  110.                 }
  111.                 OnGossipHello(pPlayer, pUnit);
  112.         }
  113.         else
  114.         {
  115.             uint32 GUID = pPlayer->GetGUIDLow();
  116.             Item* OLD = pPlayer->GetItemByPos(INVENTORY_SLOT_BAG_0, sender);
  117.             if(!OLD || Items[GUID].find(uiAction) == Items[GUID].end() || !IsSuitable(Items[GUID][uiAction], OLD, pPlayer))
  118.                 pPlayer->GetSession()->SendNotification("There is no suitable item in the slot");
  119.             else
  120.             {
  121.                 uint32 FakeEntry = Items[GUID][uiAction]->GetEntry();
  122.                 CharacterDatabase.PExecute("UPDATE item_instance SET FakeEntry = %u, FakeOwner = %u WHERE guid = %u", FakeEntry, pPlayer->GetGUIDLow(), OLD->GetGUIDLow());
  123.                 OLD->FakeEntry = FakeEntry;
  124.                 OLD->FakeOwner = pPlayer->GetGUIDLow();
  125.                 // pPlayer->SetVisibleItemSlot(sender, OLD); // No need to use this, useless checking
  126.                 pPlayer->UpdateUInt32Value(PLAYER_VISIBLE_ITEM_1_ENTRYID + (sender * 2), FakeEntry); // use this instead
  127.                 pPlayer->GetSession()->SendAreaTriggerMessage("%s transmogrified", GetSlotName(sender));
  128.             }
  129.             Items[GUID].clear();
  130.             OnGossipHello(pPlayer, pUnit);
  131.         }
  132.         return true;
  133.     }
  134. private:
  135.     std::map<uint64, std::map<uint32, Item*> > Items; // Items[GUID][DISPLAY] = item
  136.  
  137.     char * GetSlotName(uint8 slot)
  138.     {
  139.         switch(slot)
  140.         {
  141.         case EQUIPMENT_SLOT_HEAD      : return "Head";
  142.         case EQUIPMENT_SLOT_SHOULDERS : return "Shoulders";
  143.         case EQUIPMENT_SLOT_BODY      : return "Shirt";
  144.         case EQUIPMENT_SLOT_CHEST     : return "Chest";
  145.         case EQUIPMENT_SLOT_WAIST     : return "Waist";
  146.         case EQUIPMENT_SLOT_LEGS      : return "Legs";
  147.         case EQUIPMENT_SLOT_FEET      : return "Feet";
  148.         case EQUIPMENT_SLOT_WRISTS    : return "Wrists";
  149.         case EQUIPMENT_SLOT_HANDS     : return "Hands";
  150.         case EQUIPMENT_SLOT_BACK      : return "Back";
  151.         case EQUIPMENT_SLOT_MAINHAND  : return "Main hand";
  152.         case EQUIPMENT_SLOT_OFFHAND   : return "Off hand";
  153.         case EQUIPMENT_SLOT_RANGED    : return "Ranged";
  154.         case EQUIPMENT_SLOT_TABARD    : return "Tabard";
  155.         default: return NULL;
  156.         }
  157.     }
  158.  
  159.     bool IsSuitable(Item* pItem, Item* OLD, Player* pPlayer)
  160.     {
  161.         if(pItem->GetTemplate()->DisplayInfoID != OLD->GetTemplate()->DisplayInfoID)
  162.             if(pPlayer->CanUseItem(pItem, false) == EQUIP_ERR_OK)
  163.             {
  164.                 uint32 Quality = pItem->GetTemplate()->Quality;
  165.                 if(Quality == ITEM_QUALITY_UNCOMMON || Quality == ITEM_QUALITY_RARE || Quality == ITEM_QUALITY_EPIC || Quality == ITEM_QUALITY_HEIRLOOM) // Heirlooms also accepted? Remember to change in Gossip Hello too!
  166.                 {
  167.                     uint32 NClass = pItem->GetTemplate()->Class;
  168.                     uint32 OClass = OLD->GetTemplate()->Class;
  169.                     uint32 NSubClass = pItem->GetTemplate()->SubClass;
  170.                     uint32 OSubClass = OLD->GetTemplate()->SubClass;
  171.                     if(NClass == OClass) // not possibly the best structure here, but atleast I got my head around this
  172.                         if(NClass == ITEM_CLASS_WEAPON)
  173.                         {
  174.                             if(NSubClass == OSubClass || ((NSubClass == ITEM_SUBCLASS_WEAPON_BOW || NSubClass == ITEM_SUBCLASS_WEAPON_GUN || NSubClass == ITEM_SUBCLASS_WEAPON_CROSSBOW) && (OSubClass == ITEM_SUBCLASS_WEAPON_BOW || OSubClass == ITEM_SUBCLASS_WEAPON_GUN || OSubClass == ITEM_SUBCLASS_WEAPON_CROSSBOW)))
  175.                             {
  176.                                 return true;
  177.                             }
  178.                         }
  179.                         else if(NClass == ITEM_CLASS_ARMOR)
  180.                             if(NSubClass == OSubClass && pItem->GetTemplate()->InventoryType == OLD->GetTemplate()->InventoryType)
  181.                             {
  182.                                 return true;
  183.                             }
  184.                 }
  185.             }
  186.             return false;
  187.     }
  188.     std::string AreYouSure(uint8 slot, Item* pItem)
  189.     {
  190.         std::string msg = "Transmogrify ";
  191.         msg += GetSlotName(slot);
  192.         msg += "\nTo ";
  193.         msg += pItem->GetTemplate()->Name1;
  194.         return msg;
  195.     }
  196. };
  197.  
  198. void AddSC_NPC_Transmogrify()
  199. {
  200.     new NPC_Transmogrify();
  201. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement