View difference between Paste ID: dp9yvPub and PF4NiPZs
SHOW: | | - or go back to the newest paste.
1
/*
2
Transmogrification
3
By Rochet2
4
*/
5
6
#include "ScriptPCH.h"
7
8
class NPC_Transmogrify : public CreatureScript
9
{
10
public:
11
	NPC_Transmogrify() : CreatureScript("NPC_Transmogrify") { }
12
13
	bool OnGossipHello(Player* pPlayer, Creature* pUnit)
14
	{
15
		pPlayer->PlayerTalkClass->ClearMenus();
16
		for (uint8 Slot = EQUIPMENT_SLOT_START; Slot < EQUIPMENT_SLOT_END; Slot++)
17
			if (Item* pItem = pPlayer->GetItemByPos(INVENTORY_SLOT_BAG_0, Slot))
18
			{
19
				uint32 Quality = pItem->GetTemplate()->Quality;
20
				if(Quality == ITEM_QUALITY_UNCOMMON || Quality == ITEM_QUALITY_RARE || Quality == ITEM_QUALITY_EPIC)
21
					if(char* SlotName = GetSlotName(Slot))
22
						pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_TRAINER, SlotName, EQUIPMENT_SLOT_END, Slot);
23
			}
24
			pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_TALK, "Nevermind..", EQUIPMENT_SLOT_END+2, 0);
25
			pPlayer->SEND_GOSSIP_MENU(DEFAULT_GOSSIP_MESSAGE, pUnit->GetGUID());         
26
			return true;
27
	}
28
29
	bool OnGossipSelect(Player* pPlayer, Creature* pUnit, uint32 sender, uint32 uiAction)
30
	{
31
		pPlayer->PlayerTalkClass->ClearMenus();
32
		if(sender == EQUIPMENT_SLOT_END)
33
		{
34
			if (Item* OLD = pPlayer->GetItemByPos(INVENTORY_SLOT_BAG_0, uiAction))
35
			{
36
				uint64 GUID = pPlayer->GetGUID();
37
				Items[GUID].clear();
38
				for (uint8 i = INVENTORY_SLOT_ITEM_START; i < INVENTORY_SLOT_ITEM_END; i++)
39
					if (Item* pItem = pPlayer->GetItemByPos(INVENTORY_SLOT_BAG_0, i))
40
						if(IsSuitable(pItem, OLD, pPlayer))
41
							if(Items[GUID].find(pItem->GetTemplate()->DisplayInfoID) == Items[GUID].end())
42
								Items[GUID][pItem->GetTemplate()->DisplayInfoID] = pItem, pPlayer->ADD_GOSSIP_ITEM_EXTENDED(GOSSIP_ICON_INTERACT_1, pItem->GetTemplate()->Name1, uiAction, pItem->GetTemplate()->DisplayInfoID, AreYouSure(uiAction, pItem), 0, false);
43
44
				for (uint8 i = INVENTORY_SLOT_BAG_START; i < INVENTORY_SLOT_BAG_END; i++)
45
					if (Bag* pBag = pPlayer->GetBagByPos(i))
46
						for (uint32 j = 0; j < pBag->GetBagSize(); j++)
47
							if (Item* pItem = pPlayer->GetItemByPos(i, j))
48
								if(IsSuitable(pItem, OLD, pPlayer))
49
									if(Items[GUID].find(pItem->GetTemplate()->DisplayInfoID) == Items[GUID].end())
50
										Items[GUID][pItem->GetTemplate()->DisplayInfoID] = pItem, pPlayer->ADD_GOSSIP_ITEM_EXTENDED(GOSSIP_ICON_INTERACT_1, pItem->GetTemplate()->Name1, uiAction, pItem->GetTemplate()->DisplayInfoID, AreYouSure(uiAction, pItem), 0, false);
51
52
				if(Items[GUID].empty())
53
				{
54
					pPlayer->GetSession()->SendNotification("You have no suitable items in your inventory");
55
					OnGossipHello(pPlayer, pUnit);
56
					return true;
57
				}
58
				pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_TALK, "Back..", EQUIPMENT_SLOT_END+1, 0);
59
				pPlayer->SEND_GOSSIP_MENU(DEFAULT_GOSSIP_MESSAGE, pUnit->GetGUID());
60
			}
61
			else
62
				OnGossipHello(pPlayer, pUnit);
63
		}
64
		else if(sender == EQUIPMENT_SLOT_END+1)
65
			OnGossipHello(pPlayer, pUnit);
66
		else if(sender == EQUIPMENT_SLOT_END+2)
67
			pPlayer->PlayerTalkClass->SendCloseGossip();
68
		else
69
		{
70
			uint64 GUID = pPlayer->GetGUID();
71
			Item* OLD = pPlayer->GetItemByPos(INVENTORY_SLOT_BAG_0, sender);
72
			if(!OLD || Items[GUID].find(uiAction) == Items[GUID].end() || !IsSuitable(Items[GUID][uiAction], OLD, pPlayer))
73
			{
74
				pPlayer->GetSession()->SendNotification("There is no suitable item in the slot");
75
				return true;
76
			}
77
			else
78
			{
79
				pPlayer->UpdateUInt32Value(PLAYER_VISIBLE_ITEM_1_ENTRYID + (sender * 2), Items[GUID][uiAction]->GetEntry());
80
				pPlayer->GetSession()->SendAreaTriggerMessage("%s transmogrified", GetSlotName(sender));
81
			}
82
			Items[GUID].clear();
83
			OnGossipHello(pPlayer, pUnit);
84
		}
85
		return true;
86
	}
87
private:
88
	std::map<uint64, std::map<uint32, Item*> > Items; // Items[GUID][DISPLAY] = item
89
90
	char * GetSlotName(uint8 slot)
91
	{
92
		switch(slot)
93
		{
94
		case EQUIPMENT_SLOT_HEAD      : return "Head";
95
		case EQUIPMENT_SLOT_SHOULDERS : return "Shoulders";
96
		case EQUIPMENT_SLOT_BODY      : return "Shirt";
97
		case EQUIPMENT_SLOT_CHEST     : return "Chest";
98
		case EQUIPMENT_SLOT_WAIST     : return "Waist";
99
		case EQUIPMENT_SLOT_LEGS      : return "Legs";
100
		case EQUIPMENT_SLOT_FEET      : return "Feet";
101
		case EQUIPMENT_SLOT_WRISTS    : return "Wrists";
102
		case EQUIPMENT_SLOT_HANDS     : return "Hands";
103
		case EQUIPMENT_SLOT_BACK      : return "Back";
104
		case EQUIPMENT_SLOT_MAINHAND  : return "Main hand";
105
		case EQUIPMENT_SLOT_OFFHAND   : return "Off hand";
106
		case EQUIPMENT_SLOT_RANGED    : return "Ranged";
107
		case EQUIPMENT_SLOT_TABARD    : return "Tabard";
108
		default: return NULL;
109
		}
110
	}
111
112
	bool IsSuitable(Item* pItem, Item* OLD, Player* pPlayer)
113
	{
114
		if(pPlayer->CanUseItem(pItem, false) == EQUIP_ERR_OK)
115
		{
116
			uint32 Quality = pItem->GetTemplate()->Quality;
117
			if(Quality == ITEM_QUALITY_UNCOMMON || Quality == ITEM_QUALITY_RARE || Quality == ITEM_QUALITY_EPIC)
118
			{
119
				uint32 NClass = pItem->GetTemplate()->Class;
120
				uint32 OClass = OLD->GetTemplate()->Class;
121
				uint32 NSubClass = pItem->GetTemplate()->SubClass;
122
				uint32 OSubClass = OLD->GetTemplate()->SubClass;
123
				if(NClass == OClass) // not possibly the best structure here, but atleast I got my head around this
124
					if(NClass == ITEM_CLASS_WEAPON)
125
					{
126
						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)))
127
						{
128
							return true;
129
						}
130
					}
131
					else if(NClass == ITEM_CLASS_ARMOR)
132
						if(NSubClass == OSubClass && pItem->GetTemplate()->InventoryType == OLD->GetTemplate()->InventoryType)
133
						{
134
							return true;
135
						}
136
			}
137
		}
138
		return false;
139
	}
140
	std::string AreYouSure(uint8 slot, Item* pItem)
141
	{
142
		std::string msg = "Transmogrify ";
143
		msg += GetSlotName(slot);
144
		msg += "\nTo ";
145
		msg += pItem->GetTemplate()->Name1;
146
		return msg;
147
	}
148
};
149
150
void AddSC_NPC_Transmogrify()
151
{
152
	new NPC_Transmogrify();
153
}