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