Browse Source

EQ2Emu Merge To Current Date (Requires DB update, will be separate commit)

Fixes #15
Image 4 years ago
parent
commit
b9fc4e7281

+ 85 - 16
EQ2/source/WorldServer/Commands/Commands.cpp

@@ -45,6 +45,7 @@ along with EQ2Emulator.  If not, see <http://www.gnu.org/licenses/>.
 #include "../AltAdvancement/AltAdvancement.h"
 #include "../RaceTypes/RaceTypes.h"
 #include "../classes.h"
+#include "../Transmute.h"
 
 extern WorldDatabase database;
 extern MasterSpellList master_spell_list;
@@ -1315,7 +1316,7 @@ void Commands::Process(int32 index, EQ2_16BitString* command_parms, Client* clie
 				int32 item_index = atoul(sep->arg[0]);
 				Item* item = player->item_list.GetItemFromIndex(item_index);
 				if (item && item->GetItemScript()) {
-					if (item->generic_info.max_charges == 0)
+					if (item->generic_info.max_charges == 0 || item->generic_info.max_charges == 0xFFFF)
 						lua_interface->RunItemScript(item->GetItemScript(), "used", item, player);
 					else {
 						if (item->generic_info.display_charges > 0) {
@@ -3870,7 +3871,7 @@ void Commands::Process(int32 index, EQ2_16BitString* command_parms, Client* clie
 		case SWITCH_AA_PROFILE			: { Switch_AA_Profile(client, sep); break; }
 		case CANCEL_AA_PROFILE			: { Cancel_AA_Profile(client, sep); break; }
 		case SAVE_AA_PROFILE			: { Save_AA_Profile(client, sep); break; }
-
+		case COMMAND_TARGETITEM			: { Command_TargetItem(client, sep); break; }
 
 
 
@@ -5875,9 +5876,9 @@ void Commands::Command_ModifyQuest(Client* client, Seperator* sep)
 
 	// need at least 2 args for a valid command
 
-	if( sep && sep->arg[1] )
+	if (sep && sep->arg[1])
 	{
-		
+
 		if (strcmp(sep->arg[0], "list") == 0)
 		{
 			map<int32, Quest*>* quests = player->GetPlayerQuests();
@@ -5887,13 +5888,13 @@ void Commands::Command_ModifyQuest(Client* client, Seperator* sep)
 				client->Message(CHANNEL_COLOR_YELLOW, "%s has no quests.", client->GetPlayer()->GetName());
 			else
 			{
-				for( itr = quests->begin(); itr != quests->end(); itr++ )
+				for (itr = quests->begin(); itr != quests->end(); itr++)
 				{
 					Quest* quest = itr->second;
 					client->Message(CHANNEL_COLOR_YELLOW, "%u) %s", itr->first, quest->GetName());
 				}
 			}
-		
+
 		}
 
 		else if (strcmp(sep->arg[0], "completed") == 0)
@@ -5906,13 +5907,13 @@ void Commands::Command_ModifyQuest(Client* client, Seperator* sep)
 				client->Message(CHANNEL_COLOR_YELLOW, "%s has no completed quests.", client->GetPlayer()->GetName());
 			else
 			{
-				for( itr = quests->begin(); itr != quests->end(); itr++ )
+				for (itr = quests->begin(); itr != quests->end(); itr++)
 				{
-				Quest* quest = itr->second;
-				client->Message(CHANNEL_COLOR_YELLOW, "%u) %s", itr->first, quest->GetName());
+					Quest* quest = itr->second;
+					client->Message(CHANNEL_COLOR_YELLOW, "%u) %s", itr->first, quest->GetName());
 				}
 			}
-		
+
 		}
 		// Add in a progress step, and a LogWrite() for tracking GM Commands.
 		// LogWrite(LUA__DEBUG, 0, "LUA", "Quest: %s, function: %s", quest->GetName(), function);
@@ -5938,12 +5939,54 @@ void Commands::Command_ModifyQuest(Client* client, Seperator* sep)
 							client->Message(CHANNEL_COLOR_YELLOW, "You have removed the quest %s from %s's journal", quest->GetName(), player->GetName());
 							client->GetCurrentZone()->GetClientBySpawn(player)->Message(CHANNEL_COLOR_YELLOW, "%s has removed the quest %s from your journal", client->GetPlayer()->GetName(), quest->GetName());
 						}
-						LogWrite(COMMAND__INFO, 0, "GM Command", "%s removed the quest %s from %s", client->GetPlayer()->GetName(), quest->GetName(), player->GetName());
-						lua_interface->CallQuestFunction(quest, "Deleted", client->GetPlayer());
+					LogWrite(COMMAND__INFO, 0, "GM Command", "%s removed the quest %s from %s", client->GetPlayer()->GetName(), quest->GetName(), player->GetName());
+					lua_interface->CallQuestFunction(quest, "Deleted", client->GetPlayer());
 				}
 				client->RemovePlayerQuest(quest_id);
 				client->GetCurrentZone()->SendQuestUpdates(client);
-			}	
+			}
+		}
+
+		else if (strcmp(sep->arg[0], "advance") == 0)
+		{
+			int32 quest_id = 0;
+			int32 step = 0;
+
+			if (sep && sep->arg[1] && sep->IsNumber(1))
+			{
+				quest_id = atoul(sep->arg[1]);
+				Quest* quest = client->GetPlayer()->player_quests[quest_id];
+
+				if (sep && sep->arg[2] && sep->IsNumber(1))
+				{
+					step = atoul(sep->arg[2]);
+
+					if (quest_id > 0 && step > 0)
+					{
+						if (player && player->IsPlayer() && quest_id > 0 && step > 0 && (player->player_quests.count(quest_id) > 0))
+						{
+							if (client)
+							{
+								client->AddPendingQuestUpdate(quest_id, step);
+								client->Message(CHANNEL_COLOR_YELLOW, "The quest %s has been advanced one step.", quest->GetName());
+								LogWrite(COMMAND__INFO, 0, "GM Command", "%s advanced the quest %s one step", client->GetPlayer()->GetName(), quest->GetName());
+							}
+						}
+					}
+					else
+					{
+						client->Message(CHANNEL_COLOR_RED, "Quest ID and Step Number must be greater than 0!");
+					}
+				}
+				else
+				{
+					client->Message(CHANNEL_COLOR_RED, "Step Number must be a number!");
+				}
+			}
+			else
+			{
+				client->Message(CHANNEL_COLOR_RED, "Quest ID must be a number!");
+			}
 		}
 
 		else
@@ -5954,12 +5997,13 @@ void Commands::Command_ModifyQuest(Client* client, Seperator* sep)
 
 	else
 	{
-		client->SimpleMessage(CHANNEL_COLOR_RED, "Usage: /modify quest [action] [quest id]");
-		client->SimpleMessage(CHANNEL_COLOR_RED, "Actions: list, completed, remove");
+		client->SimpleMessage(CHANNEL_COLOR_RED, "Usage: /modify quest [action] [quest id] [step number]");
+		client->SimpleMessage(CHANNEL_COLOR_RED, "Actions: list, completed, remove, advance");
 		client->SimpleMessage(CHANNEL_COLOR_RED, "Example: /modify quest list");
 		client->SimpleMessage(CHANNEL_COLOR_RED, "Example: /modify quest remove 156");
+		client->SimpleMessage(CHANNEL_COLOR_RED, "Example: /modify quest advance 50 1");
 	}
-		
+
 }
 
 
@@ -7792,6 +7836,8 @@ void Commands::Command_TellChannel(Client *client, Seperator *sep) {
 }
 
 void Commands::Command_Test(Client* client, EQ2_16BitString* command_parms) {
+	PacketStruct* p = configReader.getStruct("WS_EqTargetItemCmd", client->GetVersion());
+	if (!p) return;
 
 	//Seperator* sep2 = new Seperator(command_parms->data.c_str(), ' ', 50, 500, true);
 	//client->GetCurrentZone()->SendSpellFailedPacket(client, atoi(sep2->arg[0]));
@@ -8693,4 +8739,27 @@ void Commands::Save_AA_Profile(Client* client, Seperator* sep) {
 		PrintSep(sep, "Save_AA_Profile");
 
 	}
+}
+
+void Commands::Command_TargetItem(Client* client, Seperator* sep) {
+	if (!sep || sep->GetArgNumber() < 1 || !client->GetPlayer()) return;
+
+	if (!sep->IsNumber(0)) return;
+
+	int32 request_id = atoul(sep->arg[0]);
+
+	if (!sep->IsNumber(1)) return;
+
+	sint32 item_id = atoi(sep->arg[1]);
+
+	if (client->IsCurrentTransmuteID(request_id)) {
+		Transmute::HandleItemResponse(client, client->GetPlayer(), request_id, reinterpret_cast<int32&>(item_id));
+	}
+	else if (client->IsCurrentTransmuteID(item_id)) {
+		if (!sep->IsSet(2)) return;
+
+		if (sep->IsNumber(2) && atoi(sep->arg[2]) == 1) {
+			Transmute::HandleConfirmResponse(client, client->GetPlayer(), reinterpret_cast<int32&>(item_id));
+		}
+	}
 }

+ 2 - 0
EQ2/source/WorldServer/Commands/Commands.h

@@ -455,6 +455,7 @@ public:
 	void Command_Editor(Client* client, Seperator* sep);
 	void Command_AcceptResurrection(Client* client, Seperator* sep);
 	void Command_DeclineResurrection(Client* client, Seperator* set);
+	void Command_TargetItem(Client* client, Seperator* set);
 
 	// Bot Commands
 	void Command_Bot(Client* client, Seperator* sep);
@@ -856,6 +857,7 @@ private:
 #define COMMAND_ACCEPT_RESURRECTION     312
 #define COMMAND_DECLINE_RESURRECTION    313
 #define COMMAND_WIND					314
+#define COMMAND_TARGETITEM              315
 #define COMMAND_READ					463
 
 #define COMMAND_BOT						500

+ 7 - 0
EQ2/source/WorldServer/Items/Items.cpp

@@ -29,6 +29,7 @@
 #include "../Entity.h"
 #include "../Recipes/Recipe.h"
 #include <algorithm>
+#include <sstream>
 
 extern World world;
 extern MasterSpellList master_spell_list;
@@ -3503,4 +3504,10 @@ int8 EquipmentItemList::GetSlotByItem(Item* item) {
 		}
 	}
 	return slot;
+}
+
+string Item::CreateItemLink(bool bUseUniqueID) {
+	ostringstream ss;
+	ss << "\\aITEM " << details.item_id << ' ' << (bUseUniqueID ? details.unique_id : 0) << ':' << name << "\\/a";
+	return ss.str();
 }

+ 1 - 0
EQ2/source/WorldServer/Items/Items.h

@@ -898,6 +898,7 @@ public:
 	void SetItemScript(string name);
 	const char*	GetItemScript();
 	int32 CalculateRepairCost();
+	string CreateItemLink(bool bUseUniqueID);
 
 	void SetItemType(int8 in_type);
 	void serialize(PacketStruct* packet, bool show_name = false, Player* player = 0, int16 packet_type = 0, int8 subtype = 0, bool loot_item = false);

+ 1 - 1
EQ2/source/WorldServer/Items/ItemsDB.cpp

@@ -1184,7 +1184,7 @@ void WorldDatabase::LoadCharacterItemList(int32 account_id, int32 char_id, Playe
 				else if (strncasecmp(row[0], "APPEARANCE", 10) == 2)
 					ret = player->GetEquipmentList()->AddItem(item->details.slot_id, item);
 				else {
-					if (version < 1209 & item->details.count > 255) {
+					if (version < 1209 && item->details.count > 255) {
 						int stacks = item->details.count / 255;
 						int8 remainder = item->details.count % 255;
 						item->details.count = remainder;

File diff suppressed because it is too large
+ 241 - 240
EQ2/source/WorldServer/LuaFunctions.cpp


+ 7 - 5
EQ2/source/WorldServer/LuaFunctions.h

@@ -1,4 +1,4 @@
-/*
+/*  
     EQ2Emulator:  Everquest II Server Emulator
     Copyright (C) 2007  EQ2EMulator Development Team (http://www.eq2emulator.net)
 
@@ -112,7 +112,7 @@ int EQ2Emu_lua_GetSpellName(lua_State* state);
 
 //Misc
 int EQ2Emu_lua_SpawnSet(lua_State* state);
-int EQ2Emu_lua_KillSpawn(lua_State* state);
+int EQ2Emu_lua_KillSpawn(lua_State* state); 
 int EQ2Emu_lua_KillSpawnByDistance(lua_State* state);
 int EQ2Emu_lua_SpawnSetByDistance(lua_State* state);
 int EQ2Emu_lua_SetRequiredQuest(lua_State* state);
@@ -240,8 +240,8 @@ int EQ2Emu_lua_Harvest(lua_State* state);
 int EQ2Emu_lua_SetCompleteFlag(lua_State* state);
 int EQ2Emu_lua_CanReceiveQuest(lua_State* state);
 
-int EQ2Emu_lua_HasCollectionsToHandIn(lua_State* state);
-int EQ2Emu_lua_HandInCollections(lua_State* state);
+int EQ2Emu_lua_HasCollectionsToHandIn(lua_State *state);
+int EQ2Emu_lua_HandInCollections(lua_State *state);
 
 int EQ2Emu_lua_UseWidget(lua_State* state);
 int EQ2Emu_lua_SummonPet(lua_State* state);
@@ -280,7 +280,7 @@ int EQ2Emu_lua_ToggleFollow(lua_State* state);
 int EQ2Emu_lua_IsFollowing(lua_State* state);
 int EQ2Emu_lua_SetTempVariable(lua_State* state);
 int EQ2Emu_lua_GetTempVariable(lua_State* state);
-int EQ2Emu_lua_GiveQuestItem(lua_State* state);
+int EQ2Emu_lua_GiveQuestItem(lua_State*state);
 int EQ2Emu_lua_SetQuestRepeatable(lua_State* state);
 
 int EQ2Emu_lua_AddWard(lua_State* state);
@@ -407,5 +407,7 @@ int EQ2Emu_lua_GetBoundZoneID(lua_State* state);
 int EQ2Emu_lua_Evac(lua_State* state);
 int EQ2Emu_lua_GetSpellTier(lua_State* state);
 int EQ2Emu_lua_GetSpellID(lua_State* state);
+int EQ2Emu_lua_StartTransmute(lua_State* state);
+int EQ2Emu_lua_CompleteTransmute(lua_State* state);
 int EQ2Emu_lua_ProcHate(lua_State* state);
 #endif

File diff suppressed because it is too large
+ 203 - 202
EQ2/source/WorldServer/LuaInterface.cpp


+ 1 - 0
EQ2/source/WorldServer/Player.cpp

@@ -2022,6 +2022,7 @@ void Player::AddSkill(int32 skill_id, int16 current_val, int16 max_val, bool sav
 	Skill* master_skill = master_skill_list.GetSkill(skill_id);
 	Skill* skill = new Skill(master_skill);
 	skill->current_val = current_val;
+	skill->previous_val = current_val;
 	skill->max_val = max_val;
 	if(save_needed)
 		skill->save_needed = true;

+ 3 - 3
EQ2/source/WorldServer/Skills.cpp

@@ -191,11 +191,11 @@ Skill* PlayerSkillList::GetSkill(int32 skill_id){
 
 void PlayerSkillList::IncreaseSkill(Skill* skill, int16 amount){
 	if(skill){
-		AddSkillUpdateNeeded(skill);
 		skill->previous_val = skill->current_val;
 		skill->current_val += amount;
 		if(skill->current_val > skill->max_val)
 			skill->max_val = skill->current_val;
+		AddSkillUpdateNeeded(skill);
 		skill->save_needed = true;
 	}
 }
@@ -255,8 +255,8 @@ void PlayerSkillList::DecreaseSkillCap(Skill* skill, int16 amount){
 		if(skill->current_val > skill->max_val){
 			skill->previous_val = skill->current_val;
 			skill->current_val = skill->max_val;
-			AddSkillUpdateNeeded(skill);
 		}
+		AddSkillUpdateNeeded(skill);
 		skill->save_needed = true;
 	}
 }
@@ -271,8 +271,8 @@ void PlayerSkillList::SetSkillCap(Skill* skill, int16 value){
 		if(skill->current_val > skill->max_val){
 			skill->previous_val = skill->current_val;
 			skill->current_val = skill->max_val;
-			AddSkillUpdateNeeded(skill);
 		}
+		AddSkillUpdateNeeded(skill);
 		skill->save_needed = true;
 	}
 }

+ 20 - 0
EQ2/source/WorldServer/Skills.h

@@ -25,6 +25,26 @@
 #include "../common/types.h"
 #include "MutexMap.h"
 
+#define SKILL_TYPE_COMBAT 1
+#define SKILL_TYPE_SPELLCASTING 2
+#define SKILL_TYPE_AVOIDANCE 3
+#define SKILL_TYPE_HARVESTING 6
+#define SKILL_TYPE_ARTISAN 7
+#define SKILL_TYPE_CRAFTSMAN 8
+#define SKILL_TYPE_OUTFITTER 9
+#define SKILL_TYPE_SCHOLAR 10
+#define SKILL_TYPE_GENERAL 12
+
+#define SKILL_ID_SCULPTING 1039865549
+#define SKILL_ID_FLETCHING 3076004370
+#define SKILL_ID_ARTISTRY 3881305672
+#define SKILL_ID_TAILORING 2082133324
+#define SKILL_ID_METALSHAPING 3108933728
+#define SKILL_ID_METALWORKING 4032608519
+#define SKILL_ID_SCRIBING 773137566
+#define SKILL_ID_CHEMISTRY 2557647574
+#define SKILL_ID_ARTIFICING 3330500131
+
 /* Each SkillBonus is comprised of multiple possible skill bonus values.  This is so one spell can modify
    more than one skill */
 struct SkillBonusValue {

+ 336 - 0
EQ2/source/WorldServer/Transmute.cpp

@@ -0,0 +1,336 @@
+#include "Transmute.h"
+#include "../common/MiscFunctions.h"
+#include "../common/PacketStruct.h"
+#include "client.h"
+#include "Items/Items.h"
+#include <vector>
+#include <sstream>
+#include "zoneserver.h"
+#include "SpellProcess.h"
+#include "../common/Log.h"
+#include "WorldDatabase.h"
+
+extern ConfigReader configReader;
+extern MasterSpellList master_spell_list;
+
+using namespace std;
+
+int32 Transmute::CreateItemRequest(Client* client, Player* player) {
+	PacketStruct* p = configReader.getStruct("WS_EqTargetItemCmd", client->GetVersion());
+	if (!p) return 0;
+
+	union {
+		sint32 signed_request_id;
+		int32 request_id;
+	};
+
+	do {
+		signed_request_id = MakeRandomInt(-2147483648, 2147483647);
+	} while (signed_request_id == 0);
+
+	map<int32, Item*>* il = player->GetItemList();
+
+	p->setDataByName("request_id", request_id);
+	p->setDataByName("request_type", 1);
+	p->setDataByName("unknownff", 0xff);
+	
+	vector<int32> transmutables;
+
+	for (auto& itr : *il) {
+		if (!itr.second) continue;
+
+		if (ItemIsTransmutable(itr.second)) {
+			transmutables.push_back(itr.first);
+		}
+	}
+
+	p->setArrayLengthByName("item_array_size", transmutables.size());
+
+	for (int i = 0; i < transmutables.size(); i++) {
+		p->setArrayDataByName("item_id", transmutables[i], i);
+	}
+
+	client->QueuePacket(p->serialize());
+
+	delete il;
+	delete p;
+
+	client->SetTransmuteID(request_id);
+
+	return request_id;
+}
+
+bool Transmute::ItemIsTransmutable(Item* item) {
+	//Item level > 0 AND Item is not LORE_EQUP, LORE, NO_VALUE etc AND item rarity is >= 5
+		//(4 is treasured but the rarity used for journeyman spells)
+	//I think flag 16384 is NO-TRANSMUTE but not positive
+	const int32 disqualifyFlags = NO_ZONE | NO_VALUE | TEMPORARY | NO_DESTROY | FLAGS_16384;
+	const int32 disqualityFlags2 = ORNATE;
+	if (item->generic_info.adventure_default_level > 0
+		&& (item->generic_info.item_flags & disqualifyFlags) == 0
+		&& (item->generic_info.item_flags2 & disqualityFlags2) == 0
+		&& item->details.tier >= 5
+		&& item->stack_count <= 1)
+	{
+		return true;
+	}
+
+	return false;
+}
+
+void Transmute::HandleItemResponse(Client* client, Player* player, int32 req_id, int32 item_id) {
+	Item* item = player->item_list.GetItemFromUniqueID(item_id);
+	if (!item) {
+		client->SimpleMessage(CHANNEL_COLOR_RED, "Could not find the item you wish to transmute. Please try again.");
+		return;
+	}
+
+	if (!ItemIsTransmutable(item)) {
+		client->Message(CHANNEL_COLOR_RED, "%s is not transmutable.", item->name.c_str());
+		return;
+	}
+
+	int32 item_level = item->generic_info.adventure_default_level;
+	Skill* skill = player->GetSkillByName("Transmuting");
+
+	int32 required_skill = (std::max<int32>(item_level, 5) - 5) * 5;
+	if (!skill || skill->current_val < required_skill) {
+		client->Message(CHANNEL_COLOR_RED, "You need at least %u Transmuting skill to transmute the %s."
+			" You have %u Transmuting skill.", required_skill, item->name.c_str(), skill ? skill->current_val : 0);
+		return;
+	}
+
+	client->SetTransmuteID(item_id);
+	SendConfirmRequest(client, req_id, item);
+}
+
+void Transmute::SendConfirmRequest(Client* client, int32 req_id, Item* item) {
+	PacketStruct* p = configReader.getStruct("WS_ChoiceWindow", client->GetVersion());
+	if (!p) {
+		client->SimpleMessage(CHANNEL_COLOR_RED, "Struct error for transmutation. Let a dev know.");
+		return;
+	}
+
+	ostringstream ss;
+	ss << "Are you sure you want to transmute the " << item->name << '?';
+	p->setMediumStringByName("text", ss.str().c_str());
+	p->setMediumStringByName("accept_text", "OK");
+	
+	ss.str("");
+	ss << "targetitem " << req_id << ' ' << item->details.unique_id;
+	string cancel_command = ss.str();
+	ss << " 1";
+	string accept_command = ss.str();
+
+	p->setMediumStringByName("accept_command", accept_command.c_str());
+	p->setMediumStringByName("cancel_text", "Cancel");
+	p->setMediumStringByName("cancel_command", cancel_command.c_str());
+
+	client->QueuePacket(p->serialize());
+	delete p;
+}
+
+void Transmute::HandleConfirmResponse(Client* client, Player* player, int32 item_id) {
+	Item* item = player->item_list.GetItemFromUniqueID(item_id);
+	if (!item) {
+		client->SimpleMessage(CHANNEL_COLOR_RED, "Item no longer exists!");
+		return;
+	}
+
+	client->SetTransmuteID(item_id);
+
+	ZoneServer* zone = player->GetZone();
+	if (!zone) return;
+
+	const int32 transmute_item_spell = 5163;
+
+	Spell* spell = master_spell_list.GetSpell(transmute_item_spell, 1);
+
+	if (!spell) {
+		LogWrite(SPELL__ERROR, 0, "Transmute", "Could not find the Transmute Item spell : %u", transmute_item_spell);
+		return;
+	}
+
+	zone->GetSpellProcess()->ProcessSpell(zone, spell, player);
+}
+
+void Transmute::CompleteTransmutation(Client* client, Player* player) {
+	int32 item_id = client->GetTransmuteID();
+	Item* item = player->item_list.GetItemFromUniqueID(item_id);
+	if (!item) {
+		client->SimpleMessage(CHANNEL_COLOR_RED, "Item no longer exists!");
+		return;
+	}
+
+	int32 common_mat_id = 0;
+	int32 rare_mat_id = 0;
+	
+	//Figure out the transmutation tier for our loot roll
+	int32 item_level = item->generic_info.adventure_default_level;
+	vector<TransmutingTier>& tiers = GetTransmutingTiers();
+	for (auto& itr : tiers) {
+		if (itr.min_level <= item_level && itr.max_level >= item_level) {
+			//This is the correct tier
+			int32 tier = item->details.tier;
+
+			if (tier >= ITEM_TAG_FABLED) {
+				common_mat_id = itr.infusion_id;
+				rare_mat_id = itr.mana_id;
+			}
+			else if (tier >= ITEM_TAG_LEGENDARY) {
+				common_mat_id = itr.powder_id;
+				rare_mat_id = itr.infusion_id;
+			}
+			else {
+				common_mat_id = itr.fragment_id;
+				rare_mat_id = itr.powder_id;
+			}
+
+			break;
+		}
+	}
+
+	if (common_mat_id == 0 || rare_mat_id == 0) {
+		client->SimpleMessage(CHANNEL_COLOR_RED, "Could not complete transmutation! Tell a dev!");
+		return;
+	}
+
+	//Do the loot roll
+	const int32 BOTH_ITEMS_CHANCE_PERCENT = 15;
+	//The common/rare roll only applies if the both items roll fails
+	const int32 COMMON_MAT_CHANCE_PERCENT = 75;
+	const int32 RARE_MAT_CHANCE_PERCENT = 25;
+
+	Item* item1 = nullptr;
+	Item* item2 = nullptr;
+
+	int32 roll = MakeRandomInt(1, 100);
+	if (roll <= BOTH_ITEMS_CHANCE_PERCENT) {
+		item1 = master_item_list.GetItem(rare_mat_id);
+		if (item1) item1 = new Item(item1);
+
+		item2 = master_item_list.GetItem(common_mat_id);
+		if (item2) item2 = new Item(item2);
+	}
+	else if (roll <= COMMON_MAT_CHANCE_PERCENT) {
+		item1 = master_item_list.GetItem(common_mat_id);
+		if (item1) item1 = new Item(item1);
+	}
+	else { //rare mat roll
+		item2 = master_item_list.GetItem(rare_mat_id);
+		if (item2) item2 = new Item(item2);
+	}
+
+	client->Message(89, "You transmute %s and create: ", item->CreateItemLink(false).c_str());
+
+	player->item_list.RemoveItem(item, true);
+
+	PacketStruct* packet = configReader.getStruct("WS_QuestComplete", client->GetVersion());
+	if (packet) {
+		packet->setDataByName("title", "Item Transmuted!");
+	}
+
+	if (item1) {
+		item1->details.count = 1;
+		client->Message(89, "     %s", item1->CreateItemLink(false).c_str());
+		client->AddItem(item1);
+
+		if (packet) {
+			packet->setArrayDataByName("reward_id", item1->details.item_id, 0);
+			if (client->GetVersion() < 860)
+				packet->setItemArrayDataByName("item", item1, player, 0, 0, -1);
+			else if (client->GetVersion() < 1193)
+				packet->setItemArrayDataByName("item", item, player);
+			else
+				packet->setItemArrayDataByName("item", item1, player, 0, 0, 2);
+		}
+	}
+
+	if (item2) {
+		item2->details.count = 1;
+		client->Message(89, "     %s", item2->CreateItemLink(false).c_str());
+		client->AddItem(item2);
+
+		if (packet) {
+			int32 dataIndex = 1;
+			if (!item1) {
+				packet->setArrayLengthByName("num_rewards", 1);
+				dataIndex = 0;
+			}
+			packet->setArrayDataByName("reward_id", item2->details.item_id, dataIndex);
+			if (client->GetVersion() < 860)
+				packet->setItemArrayDataByName("item", item2, player, dataIndex, 0, -1);
+			else if (client->GetVersion() < 1193)
+				packet->setItemArrayDataByName("item", item2, player, dataIndex);
+			else
+				packet->setItemArrayDataByName("item", item2, player, dataIndex, 0, 2);
+		}
+	}
+
+	if (packet) {
+		client->QueuePacket(packet->serialize());
+		delete packet;
+	}
+
+	//Check if we need to apply a skill-up
+	Skill* skill = player->GetSkillByName("Transmuting");
+	if (!skill) {
+		//Shouldn't happen, sanity check
+		LogWrite(SKILL__ERROR, 0, "Skill", "Unable to find the transmuting skill for the player %s", player->GetName());
+		return;
+	}
+
+	//Skill up roll
+	int32 max_trans_level = skill->current_val / 5 + 5;
+	int32 level_dif = max_trans_level - item_level;
+	if (level_dif >= 5 || skill->current_val >= skill->max_val) {
+		//No skill up possible
+		LogWrite(SKILL__DEBUG, 7, "Skill", "Transmuting skill up not possible.  level_dif = %u, skill val = %u, skill max val = %u", level_dif, skill->current_val, skill->max_val);
+		return;
+	}
+	
+	//40% Base chance of a skillup at max item level, 20% overall decrease per level difference
+	const int32 SKILLUP_PERCENT_CHANCE_MAX = 40;
+	int32 required_roll = SKILLUP_PERCENT_CHANCE_MAX * (1.f - (item_level <= 5 ?  0.f : (level_dif * .2f)));
+	roll = MakeRandomInt(1, 100);
+	//LogWrite(SKILL__ERROR, 0, "Skill", "Skill up roll results, roll = %u, required_roll = %u", roll, required_roll);
+	if (roll <= required_roll) {
+		player->skill_list.IncreaseSkill(skill, 1);
+	}
+}
+
+void WorldDatabase::LoadTransmuting() {
+	DatabaseResult result;
+	
+	if (!database_new.Select(&result,
+		"SELECT min_level, max_level, fragment, powder, infusion, mana FROM `transmuting`")) {
+		LogWrite(DATABASE__ERROR, 0, "Transmuting", "Error loading transmuting data!");
+		return;
+	}
+
+	Transmute::ProcessDBResult(result);
+}
+
+vector<Transmute::TransmutingTier>& Transmute::GetTransmutingTiers() {
+	static vector<TransmutingTier> gTransmutingTiers;
+	return gTransmutingTiers;
+}
+
+void Transmute::ProcessDBResult(DatabaseResult& result) {
+	vector<TransmutingTier>& tiers = GetTransmutingTiers();
+	tiers.clear();
+	tiers.reserve(result.GetNumRows());
+
+	while (result.Next()) {
+		tiers.emplace_back();
+		TransmutingTier& t = tiers.back();
+
+		int32_t i = 0;
+		t.min_level = result.GetInt32(i++);
+		t.max_level = result.GetInt32(i++);
+		t.fragment_id = result.GetInt32(i++);
+		t.powder_id = result.GetInt32(i++);
+		t.infusion_id = result.GetInt32(i++);
+		t.mana_id = result.GetInt32(i++);
+	}
+}

+ 35 - 0
EQ2/source/WorldServer/Transmute.h

@@ -0,0 +1,35 @@
+#ifndef TRANSMUTE_H
+#define TRANSMUTE_H
+
+#include "../common/types.h"
+#include <vector>
+
+class Client;
+class Player;
+class Item;
+class DatabaseResult;
+
+class Transmute {
+public:
+	static int32 CreateItemRequest(Client* client, Player* player);
+	static void HandleItemResponse(Client* client, Player* player, int32 req_id, int32 item_id);
+	static bool ItemIsTransmutable(Item* item);
+	static void SendConfirmRequest(Client* client, int32 req_id, Item* item);
+	static void HandleConfirmResponse(Client* client, Player* player, int32 item_id);
+	static void CompleteTransmutation(Client* client, Player* player);
+	static void ProcessDBResult(DatabaseResult& res);
+
+private:
+	struct TransmutingTier {
+		int32 min_level;
+		int32 max_level;
+		int32 fragment_id;
+		int32 powder_id;
+		int32 infusion_id;
+		int32 mana_id;
+	};
+
+	static std::vector<TransmutingTier>& GetTransmutingTiers();
+};
+
+#endif

+ 1 - 1
EQ2/source/WorldServer/WorldDatabase.h

@@ -555,7 +555,7 @@ public:
 	string				GetBotList(int32 char_id);
 	void				DeleteBot(int32 char_id, int32 bot_index);
 	void				SetBotStartingItems(Bot* bot, int8 class_id, int8 race_id);
-
+	void                LoadTransmuting();
 private:
 	DatabaseNew			database_new;
 	map<int32, string>	zone_names;

+ 167 - 55
EQ2/source/WorldServer/client.cpp

@@ -115,7 +115,7 @@ extern MasterAAList master_tree_nodes;
 
 using namespace std;
 
-Client::Client(EQStream* ieqs) : pos_update(125), quest_pos_timer(2000), lua_debug_timer(30000){
+Client::Client(EQStream* ieqs) : pos_update(125), quest_pos_timer(2000), lua_debug_timer(30000), transmuteID(0) {
 	eqs = ieqs;
 	ip = eqs->GetrIP();
 	port = ntohs(eqs->GetrPort());
@@ -844,6 +844,10 @@ bool Client::HandlePacket(EQApplicationPacket *app) {
 	DumpPacket(app);
 #endif
 
+	//if (opcode != OP_UpdatePositionMsg) {
+	//	LogWrite(PACKET__DEBUG, 0, "opcode %s received", app->GetOpcodeName());
+	//}
+
 		switch(opcode){
 		case OP_LoginByNumRequestMsg:{
 			LogWrite(OPCODE__DEBUG, 0, "Opcode", "Opcode 0x%X (%i): OP_LoginByNumRequestMsg", opcode, opcode);
@@ -2287,10 +2291,10 @@ void Client::HandleExamineInfoRequest(EQApplicationPacket* app){
 			DumpPacket(app);
 		}
 	}
-	else if(type == 2){
+	else if (type == 2) {
 		request = configReader.getStruct("WS_ExamineInfoItemLinkRequest", GetVersion());
-		if(!request) {
-					return;
+		if (!request) {
+			return;
 		}
 
 		request->LoadPacketData(app->pBuffer, app->size);
@@ -2302,13 +2306,13 @@ void Client::HandleExamineInfoRequest(EQApplicationPacket* app){
 		//int16 unknown5 = request->getType_sint16_ByName("unknown5");
 		//printf("Type: (%i) Unknown_0: (%u) Unknown_1: (%u) Unknown2: (%i) Unique ID: (%u) Unknown5: (%i) Item ID: (%u)\n",type,unknown_0,unknown_1,unknown2,unique_id,unknown5,id);
 		Item* item = master_item_list.GetItem(id);
-		if(item){
+		if (item) {
 			//only display popup for non merchant links
-			EQ2Packet* app = item->serialize(GetVersion(), (request->getType_int32_ByName("unique_id") != 0xFFFFFFFF), GetPlayer(), true, 0, 0, true);
+			EQ2Packet* app = item->serialize(GetVersion(), (request->getType_int8_ByName("show_popup") != 0), GetPlayer(), true, 0, 0, true);
 			//DumpPacket(app);
 			QueuePacket(app);
 		}
-		else{
+		else {
 			LogWrite(WORLD__ERROR, 0, "World", "HandleExamineInfoRequest: Unknown Item ID = %u", id);
 			DumpPacket(app);
 		}
@@ -2489,6 +2493,8 @@ bool Client::Process(bool zone_process) {
 				skill = *itr;
 				SkillChanged(skill, skill->previous_val, skill->current_val);
 			}
+			EQ2Packet* app = GetPlayer()->skill_list.GetSkillPacket(GetVersion());
+			if (app) QueuePacket(app);
 			safe_delete(skills);
 		}
 	}
@@ -3373,10 +3379,7 @@ void Client::HandleVerbRequest(EQApplicationPacket* app){
 				if(player->IsIgnored(spawn->GetName()))
 					delete_commands.push_back(player->CreateEntityCommand("remove from ignore list", 10000, "ignore_remove", "", 0, 0));
 				else
-				{
 					delete_commands.push_back(player->CreateEntityCommand("add to ignore list", 10000, "ignore_add", "", 0, 0));
-					delete_commands.push_back(player->CreateEntityCommand("Trade", 10, "start_trade", "", 0, 0));
-				}
 				if(((Player*)spawn)->GetGroupMemberInfo()) {
 					if(player->IsGroupMember((Player*)spawn) && player->GetGroupMemberInfo()->leader) { //group leader
 						delete_commands.push_back(player->CreateEntityCommand("kick from group", 10000, "kickfromgroup", "", 0, 0));
@@ -3415,13 +3418,12 @@ void Client::HandleVerbRequest(EQApplicationPacket* app){
 }
 
 void Client::SkillChanged(Skill* skill, int16 previous_value, int16 new_value){
-	Message(CHANNEL_COLOR_SKILL, "You get %s at %s (%i/%i).", new_value > previous_value ? "better" : "worse", skill->name.data.c_str(), new_value, skill->max_val);
-	char tmp[200] = {0};
-	sprintf(tmp, "\\#6EFF6EYou get %s at \12\\#C8FFC8%s\\#6EFF6E! (%i/%i)", new_value > previous_value ? "better" : "worse", skill->name.data.c_str(), new_value, skill->max_val);
-	SendPopupMessage(6, tmp, new_value > previous_value ? "skill_up" : "skill_down", 2.75, 0xFF, 0xFF, 0xFF);
-	EQ2Packet* app = GetPlayer()->skill_list.GetSkillPacket(GetVersion());
-	if(app)
-		QueuePacket(app);
+	if (previous_value != new_value) {
+		Message(CHANNEL_COLOR_SKILL, "You get %s at %s (%i/%i).", new_value > previous_value ? "better" : "worse", skill->name.data.c_str(), new_value, skill->max_val);
+		char tmp[200] = { 0 };
+		sprintf(tmp, "\\#6EFF6EYou get %s at \12\\#C8FFC8%s\\#6EFF6E! (%i/%i)", new_value > previous_value ? "better" : "worse", skill->name.data.c_str(), new_value, skill->max_val);
+		SendPopupMessage(6, tmp, new_value > previous_value ? "skill_up" : "skill_down", 2.75, 0xFF, 0xFF, 0xFF);
+	}
 
 }
 
@@ -3501,7 +3503,6 @@ void Client::ChangeLevel(int16 old_level, int16 new_level){
 	if (!player->get_character_flag(CF_ENABLE_CHANGE_LASTNAME) && new_level >= rule_manager.GetGlobalRule(R_Player, MinLastNameLevel)->GetInt8())
 		player->set_character_flag(CF_ENABLE_CHANGE_LASTNAME);
 
-	player->GetSkills()->IncreaseAllSkillCaps(5 * (new_level - old_level));
 	SendNewSpells(player->GetAdventureClass());
 	SendNewSpells(classes.GetBaseClass(player->GetAdventureClass()));
 	SendNewSpells(classes.GetSecondaryBaseClass(player->GetAdventureClass()));
@@ -3520,18 +3521,19 @@ void Client::ChangeLevel(int16 old_level, int16 new_level){
 	GetPlayer()->CalculateBonuses();
 	GetPlayer()->SetHP(GetPlayer()->GetTotalHP());
 	GetPlayer()->SetPower(GetPlayer()->GetTotalPower());
-	GetPlayer()->GetInfoStruct()->agi_base = new_level*2+15;
-	GetPlayer()->GetInfoStruct()->intel_base = new_level*2+15;
-	GetPlayer()->GetInfoStruct()->wis_base = new_level*2+15;
-	GetPlayer()->GetInfoStruct()->str_base = new_level*2+15;
-	GetPlayer()->GetInfoStruct()->sta_base = new_level*2+15;
-	GetPlayer()->GetInfoStruct()->cold_base = (int16)(new_level*1.5+10);
-	GetPlayer()->GetInfoStruct()->heat_base = (int16)(new_level*1.5+10);
-	GetPlayer()->GetInfoStruct()->disease_base = (int16)(new_level*1.5+10);
-	GetPlayer()->GetInfoStruct()->mental_base = (int16)(new_level*1.5+10);
-	GetPlayer()->GetInfoStruct()->magic_base = (int16)(new_level*1.5+10);
-	GetPlayer()->GetInfoStruct()->divine_base = (int16)(new_level*1.5+10);
-	GetPlayer()->GetInfoStruct()->poison_base = (int16)(new_level*1.5+10);
+	InfoStruct* info = player->GetInfoStruct();
+	info->agi_base = new_level*2+15;
+	info->intel_base = new_level*2+15;
+	info->wis_base = new_level*2+15;
+	info->str_base = new_level*2+15;
+	info->sta_base = new_level*2+15;
+	info->cold_base = (int16)(new_level*1.5+10);
+	info->heat_base = (int16)(new_level*1.5+10);
+	info->disease_base = (int16)(new_level*1.5+10);
+	info->mental_base = (int16)(new_level*1.5+10);
+	info->magic_base = (int16)(new_level*1.5+10);
+	info->divine_base = (int16)(new_level*1.5+10);
+	info->poison_base = (int16)(new_level*1.5+10);
 	GetPlayer()->SetHPRegen((int)(new_level*.75)+(int)(new_level/10)+3);
 	GetPlayer()->SetPowerRegen(new_level+(int)(new_level/10)+4);
 	GetPlayer()->GetInfoStruct()->poison_base = (int16)(new_level*1.5+10);
@@ -3540,46 +3542,51 @@ void Client::ChangeLevel(int16 old_level, int16 new_level){
 
 	Message(CHANNEL_COLOR_EXP,"You are now level %i!", new_level);
 	LogWrite(WORLD__DEBUG, 0, "World", "Player: %s leveled from %u to %u", GetPlayer()->GetName(), old_level, new_level);
-	GetPlayer()->GetSkills()->SetSkillCapsByType(1, 5*new_level);
-	GetPlayer()->GetSkills()->SetSkillCapsByType(3, 5*new_level);
-	GetPlayer()->GetSkills()->SetSkillCapsByType(6, 5*new_level);
-	GetPlayer()->GetSkills()->SetSkillCapsByType(13, 5*new_level);
+	int16 new_skill_cap = 5 * new_level;
+	PlayerSkillList* player_skills = player->GetSkills();
+	player_skills->SetSkillCapsByType(SKILL_TYPE_COMBAT, new_skill_cap);
+	player_skills->SetSkillCapsByType(SKILL_TYPE_SPELLCASTING, new_skill_cap);
+	player_skills->SetSkillCapsByType(SKILL_TYPE_AVOIDANCE, new_skill_cap);
+	player_skills->SetSkillCapsByType(SKILL_TYPE_GENERAL, new_skill_cap);
+	if (new_level > player->GetTSLevel())
+		player_skills->SetSkillCapsByType(SKILL_TYPE_HARVESTING, new_skill_cap);
 
 	Guild* guild = GetPlayer()->GetGuild();
 	if (guild) {
-		int8 event_type = 0; 
+		int8 event_type = 0;
 		if (new_level < 10)
 			event_type = GUILD_EVENT_GAINS_ADV_LEVEL_1_10;
 		else if (new_level == 10)
 			event_type = GUILD_EVENT_GAINS_ADV_LEVEL_10;
-		else if (new_level < 20)
+		else if (new_level >= 11 && new_level < 20)
 			event_type = GUILD_EVENT_GAINS_ADV_LEVEL_11_20;
 		else if (new_level == 20)
 			event_type = GUILD_EVENT_GAINS_ADV_LEVEL_20;
-		else if (new_level < 30)
+		else if (new_level >= 21 && new_level < 30)
 			event_type = GUILD_EVENT_GAINS_ADV_LEVEL_21_30;
 		else if (new_level == 30)
 			event_type = GUILD_EVENT_GAINS_ADV_LEVEL_30;
-		else if (new_level < 40)
+		else if (new_level >= 31 && new_level < 40)
 			event_type = GUILD_EVENT_GAINS_ADV_LEVEL_31_40;
 		else if (new_level == 40)
 			event_type = GUILD_EVENT_GAINS_ADV_LEVEL_40;
-		else if (new_level < 50)
+		else if (new_level >= 41 && new_level < 50)
 			event_type = GUILD_EVENT_GAINS_ADV_LEVEL_41_50;
 		else if (new_level == 50)
 			event_type = GUILD_EVENT_GAINS_ADV_LEVEL_50;
-		else if (new_level < 60)
+		else if (new_level >= 51 && new_level < 60)
 			event_type = GUILD_EVENT_GAINS_ADV_LEVEL_51_60;
 		else if (new_level == 60)
 			event_type = GUILD_EVENT_GAINS_ADV_LEVEL_60;
-		else if (new_level < 70)
+		else if (new_level >= 61 && new_level < 70)
 			event_type = GUILD_EVENT_GAINS_ADV_LEVEL_61_70;
 		else if (new_level == 70)
 			event_type = GUILD_EVENT_GAINS_ADV_LEVEL_70;
-		else if (new_level < 80)
+		else if (new_level >= 71 && new_level < 80)
 			event_type = GUILD_EVENT_GAINS_ADV_LEVEL_71_80;
 		else if (new_level == 80)
 			event_type = GUILD_EVENT_GAINS_ADV_LEVEL_80;
+
 		guild->AddNewGuildEvent(event_type, "%s has gained an adventure level and is now a level %u %s.", Timer::GetUnixTimeStamp(), true, GetPlayer()->GetName(), new_level, classes.GetClassNameCase(GetPlayer()->GetAdventureClass()).c_str());
 		guild->SendMessageToGuild(event_type, "%s has gained an adventure level and is now a level %u %s.", GetPlayer()->GetName(), new_level, classes.GetClassNameCase(GetPlayer()->GetAdventureClass()).c_str());
 		guild->UpdateGuildMemberInfo(GetPlayer());
@@ -3625,7 +3632,6 @@ void Client::ChangeTSLevel(int16 old_level, int16 new_level){
 		}
 	}
 	// Only tradeskill skills should increace, and then only those related to your class
-	// player->GetSkills()->IncreaseAllSkillCaps(5 * (new_level - old_level));
 	PacketStruct* level_update = configReader.getStruct("WS_LevelChanged", GetVersion());
 	if(level_update){
 		level_update->setDataByName("old_level", old_level);
@@ -3653,10 +3659,104 @@ void Client::ChangeTSLevel(int16 old_level, int16 new_level){
 	GetPlayer()->SetCharSheetChanged(true);
 	Message(CHANNEL_COLOR_WHITE,"Your tradeskill level is now %i!", new_level);
 	LogWrite(WORLD__DEBUG, 0, "World", "Player: %s leveled from %u to %u", GetPlayer()->GetName(), old_level, new_level);
-	//GetPlayer()->GetSkills()->SetSkillCapsByType(1, 5*new_level);
-	//GetPlayer()->GetSkills()->SetSkillCapsByType(3, 5*new_level);
-	//GetPlayer()->GetSkills()->SetSkillCapsByType(6, 5*new_level);
-	//GetPlayer()->GetSkills()->SetSkillCapsByType(13, 5*new_level);
+	
+	PlayerSkillList* player_skills = player->GetSkills();
+	int16 specialize_skill_cap = new_level * 5;
+	int16 artisan_skill_cap = std::max<int16>(specialize_skill_cap, 49);
+	int16 specialize_10_skill_cap = std::max<int16>(specialize_skill_cap, 99);
+
+	int8 ts_class = player->GetTradeskillClass();
+	int8 base_ts_class = classes.GetSecondaryTSBaseClass(ts_class);
+	int32 skill_id_1, skill_id_2, skill_id_3;
+
+	switch (base_ts_class) {
+	case ARTISAN:
+		player_skills->SetSkillCapsByType(SKILL_TYPE_OUTFITTER, artisan_skill_cap);
+		player_skills->SetSkillCapsByType(SKILL_TYPE_SCHOLAR, artisan_skill_cap);
+		player_skills->SetSkillCapsByType(SKILL_TYPE_CRAFTSMAN, artisan_skill_cap);
+		break;
+	case OUTFITTER:
+		player_skills->SetSkillCapsByType(SKILL_TYPE_SCHOLAR, artisan_skill_cap);
+		player_skills->SetSkillCapsByType(SKILL_TYPE_CRAFTSMAN, artisan_skill_cap);
+
+		skill_id_1 = SKILL_ID_TAILORING;
+		skill_id_2 = SKILL_ID_METALSHAPING;
+		skill_id_3 = SKILL_ID_METALWORKING;
+
+		if (ts_class == TAILOR) {
+			player_skills->SetSkillCap(skill_id_1, specialize_skill_cap);
+			skill_id_1 = 0;
+		}
+		else if (ts_class == ARMORER) {
+			player_skills->SetSkillCap(skill_id_2, specialize_skill_cap);
+			skill_id_2 = 0;
+		}
+		else if (ts_class == WEAPONSMITH) {
+			player_skills->SetSkillCap(skill_id_3, specialize_skill_cap);
+			skill_id_3 = 0;
+		}
+
+		if (skill_id_1) player_skills->SetSkillCap(skill_id_1, specialize_10_skill_cap);
+		if (skill_id_2) player_skills->SetSkillCap(skill_id_2, specialize_10_skill_cap);
+		if (skill_id_3) player_skills->SetSkillCap(skill_id_3, specialize_10_skill_cap);
+		break;
+	case SCHOLAR:
+		player_skills->SetSkillCapsByType(SKILL_TYPE_OUTFITTER, artisan_skill_cap);
+		player_skills->SetSkillCapsByType(SKILL_TYPE_CRAFTSMAN, artisan_skill_cap);
+
+		skill_id_1 = SKILL_ID_SCRIBING;
+		skill_id_2 = SKILL_ID_CHEMISTRY;
+		skill_id_3 = SKILL_ID_ARTIFICING;
+
+		if (ts_class == SAGE) {
+			player_skills->SetSkillCap(skill_id_1, specialize_skill_cap);
+			skill_id_1 = 0;
+		}
+		else if (ts_class == ALCHEMIST) {
+			player_skills->SetSkillCap(skill_id_2, specialize_skill_cap);
+			skill_id_2 = 0;
+		}
+		else if (ts_class == JEWELER) {
+			player_skills->SetSkillCap(skill_id_3, specialize_skill_cap);
+			skill_id_3 = 0;
+		}
+
+		if (skill_id_1) player_skills->SetSkillCap(skill_id_1, specialize_10_skill_cap);
+		if (skill_id_2) player_skills->SetSkillCap(skill_id_2, specialize_10_skill_cap);
+		if (skill_id_3) player_skills->SetSkillCap(skill_id_3, specialize_10_skill_cap);
+		break;
+	case CRAFTSMAN:
+		player_skills->SetSkillCapsByType(SKILL_TYPE_OUTFITTER, artisan_skill_cap);
+		player_skills->SetSkillCapsByType(SKILL_TYPE_SCHOLAR, artisan_skill_cap);
+
+		skill_id_1 = SKILL_ID_ARTISTRY;
+		skill_id_2 = SKILL_ID_FLETCHING;
+		skill_id_3 = SKILL_ID_SCULPTING;
+
+		if (ts_class == PROVISIONER) {
+			player_skills->SetSkillCap(skill_id_1, specialize_skill_cap);
+			skill_id_1 = 0;
+		}
+		else if (ts_class == WOODWORKER) {
+			player_skills->SetSkillCap(skill_id_2, specialize_skill_cap);
+			skill_id_2 = 0;
+		}
+		else if (ts_class == CARPENTER) {
+			player_skills->SetSkillCap(skill_id_3, specialize_skill_cap);
+			skill_id_3 = 0;
+		}
+
+		if (skill_id_1) player_skills->SetSkillCap(skill_id_1, specialize_10_skill_cap);
+		if (skill_id_2) player_skills->SetSkillCap(skill_id_2, specialize_10_skill_cap);
+		if (skill_id_3) player_skills->SetSkillCap(skill_id_3, specialize_10_skill_cap);
+		break;
+	default:
+		break;
+	}
+
+	if (new_level > player->GetAdventureClass())
+		player_skills->SetSkillCapsByType(SKILL_TYPE_HARVESTING, specialize_skill_cap);
+
 	Guild* guild = GetPlayer()->GetGuild();
 	if (guild) {
 		int8 event_type = 0; 
@@ -3664,31 +3764,31 @@ void Client::ChangeTSLevel(int16 old_level, int16 new_level){
 			event_type = GUILD_EVENT_GAINS_TS_LEVEL_1_10;
 		else if (new_level == 10)
 			event_type = GUILD_EVENT_GAINS_TS_LEVEL_10;
-		else if (new_level < 20)
+		else if (new_level >= 11 && new_level < 20)
 			event_type = GUILD_EVENT_GAINS_TS_LEVEL_11_20;
 		else if (new_level == 20)
 			event_type = GUILD_EVENT_GAINS_TS_LEVEL_20;
-		else if (new_level < 30)
+		else if (new_level >= 21 && new_level < 30)
 			event_type = GUILD_EVENT_GAINS_TS_LEVEL_21_30;
 		else if (new_level == 30)
 			event_type = GUILD_EVENT_GAINS_TS_LEVEL_30;
-		else if (new_level < 40)
+		else if (new_level >= 31 && new_level < 40)
 			event_type = GUILD_EVENT_GAINS_TS_LEVEL_31_40;
 		else if (new_level == 40)
 			event_type = GUILD_EVENT_GAINS_TS_LEVEL_40;
-		else if (new_level < 50)
+		else if (new_level >= 41 && new_level < 50)
 			event_type = GUILD_EVENT_GAINS_TS_LEVEL_41_50;
 		else if (new_level == 50)
 			event_type = GUILD_EVENT_GAINS_TS_LEVEL_50;
-		else if (new_level < 60)
+		else if (new_level >= 51 && new_level < 60)
 			event_type = GUILD_EVENT_GAINS_TS_LEVEL_51_60;
 		else if (new_level == 60)
 			event_type = GUILD_EVENT_GAINS_TS_LEVEL_60;
-		else if (new_level < 70)
+		else if (new_level >= 61 && new_level < 70)
 			event_type = GUILD_EVENT_GAINS_TS_LEVEL_61_70;
 		else if (new_level == 70)
 			event_type = GUILD_EVENT_GAINS_TS_LEVEL_70;
-		else if (new_level < 80)
+		else if (new_level >= 71 && new_level < 80)
 			event_type = GUILD_EVENT_GAINS_TS_LEVEL_71_80;
 		else if (new_level == 80)
 			event_type = GUILD_EVENT_GAINS_TS_LEVEL_80;
@@ -5759,7 +5859,7 @@ void Client::SendSellMerchantList(bool sell){
 						packet->setArrayDataByName("status2", item->sell_status, i); //this one is the main status
 					}
 					packet->setArrayDataByName("item_id", item->details.item_id, i);
-					packet->setArrayDataByName("unique_item_id", (item->details.unique_id, i));
+					packet->setArrayDataByName("unique_item_id", item->details.unique_id, i);
 					packet->setArrayDataByName("stack_size", item->details.count, i);
 					packet->setArrayDataByName("icon", item->details.icon, i);
 					if(item->generic_info.adventure_default_level > 0)
@@ -7887,4 +7987,16 @@ bool Client::EntityCommandPrecheck(Spawn* spawn, const char* command){
 		}
 	}
 	return should_use_spawn;
+}
+
+bool Client::IsCurrentTransmuteID(int32 req_id) {
+	return req_id == transmuteID;
+}
+
+void Client::SetTransmuteID(int32 trans_id) {
+	transmuteID = trans_id;
+}
+
+int32 Client::GetTransmuteID() {
+	return transmuteID;
 }

+ 5 - 0
EQ2/source/WorldServer/client.h

@@ -385,6 +385,10 @@ public:
 
 	void EndAutoMount();
 	bool GetOnAutoMount() { return on_auto_mount; }
+	
+	bool IsCurrentTransmuteID(int32 trans_id);
+	void SetTransmuteID(int32 trans_id);
+	int32 GetTransmuteID();
 
 private:
 	void    SavePlayerImages();
@@ -463,6 +467,7 @@ private:
 	PendingResurrection current_rez;
 	string* pending_last_name;
 	IncomingPaperdollImage incoming_paperdoll;
+	int32 transmuteID;
 
 	bool m_recipeListSent;
 	bool initial_spawns_sent;

+ 4 - 0
EQ2/source/WorldServer/net.cpp

@@ -54,6 +54,7 @@ using namespace std;
 #include "Commands/ConsoleCommands.h"
 #include "Traits/Traits.h"
 #include "IRC/IRC.h"
+#include "Transmute.h"
 
 #ifdef WIN32
 	#include <process.h>
@@ -330,6 +331,9 @@ int main(int argc, char** argv) {
 	LogWrite(WORLD__INFO, 0, "World", "Loading Race Types Data...");
 	database.LoadRaceTypes();
 
+	LogWrite(WORLD__INFO, 0, "World", "Loading Transmuting Data...");
+	database.LoadTransmuting();
+
 	if (threadedLoad) {
 		LogWrite(WORLD__INFO, 0, "World", "Waiting for load threads to finish.");
 		while (!world.items_loaded || !world.spells_loaded /*|| !world.achievments_loaded*/)

+ 5 - 1
EQ2/source/WorldServer/zoneserver.cpp

@@ -2015,7 +2015,6 @@ void ZoneServer::ProcessSpawnLocation(int32 location_id, bool respawn)
 					CalculateSpawnGroup(spawn_location_list[location_id]);
 
 				LogWrite(SPAWN__TRACE, 0, "Spawn", "Exit %s", __FUNCTION__);
-
 				// need to unlock the list before we exit the function
 				MSpawnLocationList.releasereadlock(__FUNCTION__, __LINE__);
 				return;
@@ -4804,6 +4803,11 @@ EQ2Packet* ZoneServer::GetZoneInfoPacket(Client* client){
 	packet->setArrayLengthByName("num_client_setup", variables->size());
 	for(int i=variables->size()-1;i>=0;i--)
 		packet->setArrayDataByName("client_cmds", variables->at(i)->GetNameValuePair().c_str(), i);
+
+	// For AoM clients so item link work
+	if (client->GetVersion() >= 60114)
+		packet->setArrayDataByName("client_cmds", "chat_linkbrackets_item 1", variables->size());
+
 	safe_delete(variables);
 	//packet->setDataByName("unknown8", ); story?
 	// AA Tabs for 1193+ clients

+ 7 - 16
EQ2/source/common/EQPacket.cpp

@@ -30,6 +30,7 @@
 #include "packet_dump.h"
 #include <map>
 #include "Log.h"
+#include <time.h>
 
 using namespace std;
 extern map<int16,OpcodeManager*>EQOpcodeManager;
@@ -134,29 +135,19 @@ EQPacket::~EQPacket()
 	pBuffer=NULL;
 }
 
-void EQPacket::DumpRawHeader(uint16 seq, FILE *to) const
+
+void EQPacket::DumpRawHeader(uint16 seq, FILE* to) const
 {
-	if (timestamp.tv_sec) {
+	/*if (timestamp.tv_sec) {
 		char temp[20];
 		tm t;
 		const time_t sec = timestamp.tv_sec;
 		localtime_s(&t, &sec);
 		strftime(temp, 20, "%F %T", &t);
 		fprintf(to, "%s.%06lu ", temp, timestamp.tv_usec);
-	}
-	if (src_ip) {
-		string sIP, dIP;;
-		sIP = long2ip(src_ip);
-		dIP = long2ip(dst_ip);
-		fprintf(to, "[%s:%d->%s:%d]\n", sIP.c_str(), src_port, dIP.c_str(), dst_port);
-	}
-	if (seq != 0xffff)
-		fprintf(to, "[Seq=%u] ", seq);
-	string name;
-	int16 OpcodeVersion = GetOpcodeVersion(version);
-	if (EQOpcodeManager.count(OpcodeVersion) > 0)
-		name = EQOpcodeManager[OpcodeVersion]->EQToName(opcode);
-	fprintf(to, "[OpCode 0x%04x (%s) Size=%u]\n", opcode, name.c_str(), size);
+	}*/
+
+	DumpRawHeaderNoTime(seq, to);
 }
 
 const char* EQPacket::GetOpcodeName(){

+ 6 - 2
EQ2/source/common/MiscFunctions.cpp

@@ -40,7 +40,6 @@
 using namespace std;
 
 #ifndef PATCHER
-#include "../WorldServer/World.h"
 extern map<int16, int16> EQOpcodeVersions;
 #endif
 
@@ -387,7 +386,12 @@ int64 hextoi64(char* num) {
 
 float MakeRandomFloat(float low, float high)
 {
-	static bool seeded=0;
+#ifdef _WIN32	
+	thread_local bool seeded = false;
+#else
+	static bool seeded = false;
+#endif
+
 	float diff = high - low;
   
 	if(!diff) return low;

+ 2 - 1
EQ2/source/common/emu_oplist.h

@@ -500,4 +500,5 @@ N(OP_PaperdollImage),
 N(OP_ReadyForTakeOffMsg),
 N(OP_EarlyLandingRequestMsg),
 N(OP_SubmitCharCust),
-N(OP_DietyAbilityWindow),
+N(OP_DietyAbilityWindow),
+N(OP_EqTargetItemCmd),

+ 1 - 1
EQ2/source/common/version.h

@@ -21,7 +21,7 @@
 #ifndef VERSION_H
 #define VERSION_H
 
-#define CURRENT_DATABASE_MINORVERSION 41
+#define CURRENT_DATABASE_MINORVERSION 42
 #define CURRENT_DATABASE_MAJORVERSION 730
 #if defined(LOGIN)
 	#define EQ2EMU_MODULE	"EQ2EMu LoginServer"

+ 30 - 0
EQ2/structs/ItemStructs.xml

@@ -1185,6 +1185,28 @@
 <Data ElementName="name" Type="char" Size="64" />
 <Data ElementName="unknown6" Type="int8" Size="17" />
 </Struct>
+<Struct Name="Substruct_Item" ClientVersion="67650" >
+<Data ElementName="unique_id" Type="int32" Size="1" />
+<Data ElementName="bag_id" Type="int32" Size="1" />
+<Data ElementName="inv_slot_id" Type="int32" Size="1" />
+<Data ElementName="menu_type" Type="int32" Size="1" />
+<Data ElementName="unknown3" Type="int32" Size="1" />
+<Data ElementName="index" Type="int16" Size="1" />
+<Data ElementName="icon" Type="int16" Size="1" />
+<Data ElementName="slot_id" Type="int8" Size="1" />
+<Data ElementName="count" Type="int16" Size="1" />
+<Data ElementName="unknown4b" Type="int8" Size="1" />
+<Data ElementName="unknown4c" Type="int8" Size="1" />
+<Data ElementName="item_level" Type="int8" Size="1" />
+<Data ElementName="tier" Type="int8" Size="1" />
+<Data ElementName="num_slots" Type="int8" Size="1" />
+<Data ElementName="empty_slots" Type="int8" Size="1" />
+<Data ElementName="unknown5_2" Type="int8" Size="1" />
+<Data ElementName="item_id" Type="sint32" Size="1" />
+<Data ElementName="broker_id" Type="int64" Size="1" />
+<Data ElementName="name" Type="char" Size="64" />
+<Data ElementName="unknown6" Type="int8" Size="16" />
+</Struct>
 <Struct Name="Substruct_ItemFooter" ClientVersion="1" >
 <Data ElementName="num_effects" Type="int8" IfVariableNotSet="header_info_header_unknown_0_0,header_unknown_0" />
 <Data ElementName="effect_array" Type="Array" ArraySizeVariable="num_effects">
@@ -4011,6 +4033,14 @@
 </Data>
 <Data ElementName="equip_flag" Type="int8" Size="1" />
 </Struct>
+<Struct Name="WS_UpdateInventory" ClientVersion="67650" OpcodeName="OP_UpdateInventoryMsg" >
+<Data ElementName="item_count" Type="int16" />
+<Data ElementName="packed_size" Type="int32" />
+<Data ElementName="item_array" Type="Array" ArraySizeVariable="item_count">
+  <Data ElementName="items" Substruct="Substruct_Item" Size="1" />
+</Data>
+<Data ElementName="equip_flag" Type="int8" Size="1" />
+</Struct>
 <Struct Name="WS_ItemGeneric" ClientVersion="1" OpcodeName="OP_ClientCmdMsg" OpcodeType="OP_EqExamineInfoCmd">
 <Data ElementName="header" Substruct="Substruct_ItemDescription" Size="1" />
 <Data ElementName="footer" Substruct="Substruct_ItemFooter" Size="1" />

+ 2 - 0
EQ2/win/VC10Projects/EQ2World.vcxproj

@@ -497,6 +497,7 @@
     <ClCompile Include="..\..\source\WorldServer\Tradeskills\TradeskillsDB.cpp" />
     <ClCompile Include="..\..\source\WorldServer\Tradeskills\TradeskillsPackets.cpp" />
     <ClCompile Include="..\..\source\WorldServer\Traits\Traits.cpp" />
+    <ClCompile Include="..\..\source\WorldServer\Transmute.cpp" />
     <ClCompile Include="..\..\source\WorldServer\Widget.cpp" />
     <ClCompile Include="..\..\source\WorldServer\World.cpp" />
     <ClCompile Include="..\..\source\WorldServer\WorldDatabase.cpp" />
@@ -615,6 +616,7 @@
     <ClInclude Include="..\..\source\WorldServer\Titles.h" />
     <ClInclude Include="..\..\source\WorldServer\Trade.h" />
     <ClInclude Include="..\..\source\WorldServer\Traits\Traits.h" />
+    <ClInclude Include="..\..\source\WorldServer\Transmute.h" />
     <ClInclude Include="..\..\source\WorldServer\Variables.h" />
     <ClInclude Include="..\..\source\WorldServer\VisualStates.h" />
     <ClInclude Include="..\..\source\WorldServer\Widget.h" />

+ 940 - 0
EQ2/win/VC10Projects/EQ2World.vcxproj.filters

@@ -0,0 +1,940 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <ItemGroup>
+    <Filter Include="Source Files">
+      <UniqueIdentifier>{2a766c1a-b509-4fb8-adf7-5f3fa6e561fd}</UniqueIdentifier>
+      <Extensions>cpp;c;cxx;rc;def;r;odl;idl;hpj;bat</Extensions>
+    </Filter>
+    <Filter Include="Source Files\Tradeskills">
+      <UniqueIdentifier>{4b6b175f-8b3c-47fe-b88f-b02e8cc77dd6}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="Source Files\Commands">
+      <UniqueIdentifier>{f943b35c-f0dc-4c57-ae71-b75ad1c50c80}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="Source Files\Guilds">
+      <UniqueIdentifier>{272ad8c4-ce45-421d-aea2-018885a653a7}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="Header Files">
+      <UniqueIdentifier>{a2455786-c1af-4d5a-8b82-ab6944408d56}</UniqueIdentifier>
+      <Extensions>h;hpp;hxx;hm;inl</Extensions>
+    </Filter>
+    <Filter Include="Header Files\Commands">
+      <UniqueIdentifier>{036714f2-2c02-4794-8413-280d479f59a6}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="Header Files\Tradeskills">
+      <UniqueIdentifier>{a71a1ae1-870d-4861-bcbb-3bdb9554a408}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="Common Source Files">
+      <UniqueIdentifier>{00750afa-2aae-41f3-8523-d1f7acadbf8d}</UniqueIdentifier>
+      <Extensions>*.cpp</Extensions>
+    </Filter>
+    <Filter Include="Common Header Files">
+      <UniqueIdentifier>{f5338a37-e11c-4f63-a52f-835551cc2b8d}</UniqueIdentifier>
+      <Extensions>*.h</Extensions>
+    </Filter>
+    <Filter Include="Header Files\Collections">
+      <UniqueIdentifier>{2efcfe15-fe58-431c-a567-d8716784c9b4}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="Source Files\Collections">
+      <UniqueIdentifier>{255642e4-036a-4f3a-ac34-c371d89a19d2}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="Header Files\Recipes">
+      <UniqueIdentifier>{0c6782e8-5551-4ffd-957c-ab8f95a7def0}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="Source Files\Recipes">
+      <UniqueIdentifier>{02c901f8-7d74-4213-946c-3df4782bfcc3}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="Header Files\Rules">
+      <UniqueIdentifier>{514d3822-9c0d-48dc-bfad-2a433aba13f2}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="Source Files\Rules">
+      <UniqueIdentifier>{43c640be-ded7-4115-99f0-bb0a03740546}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="Header Files\Guilds">
+      <UniqueIdentifier>{1c53f02e-00f8-4fe4-9737-df9e38062b25}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="Header Files\Items">
+      <UniqueIdentifier>{942a4035-6c09-4a19-a5e6-251810220b49}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="Source Files\Items">
+      <UniqueIdentifier>{2906af95-7223-437c-b24a-7dde0bb0009e}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="Source Files\IRC">
+      <UniqueIdentifier>{380d91b2-642b-4771-880d-af11e41b534f}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="Header Files\IRC">
+      <UniqueIdentifier>{a3fe9b33-f540-4d5b-b1db-7bd7cb249e9b}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="Header Files\Traits">
+      <UniqueIdentifier>{8c26a024-3626-4d1a-b7ca-c0a812362e62}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="Source Files\Traits">
+      <UniqueIdentifier>{51e9b1f6-043e-4c84-9a04-5855211978e0}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="Source Files\Acheivements">
+      <UniqueIdentifier>{5b5793af-5c85-440c-896e-58b3fd8b7334}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="Header Files\Achievements">
+      <UniqueIdentifier>{c99e6828-a2b6-42b5-af99-e80899001446}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="Source Files\Chat">
+      <UniqueIdentifier>{dc6e9750-8b6f-42e6-896f-1c659cfa052e}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="Header Files\Chat">
+      <UniqueIdentifier>{4bc8d1da-6979-40d4-bdc2-37c44499de49}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="Header Files\AltAdvancement">
+      <UniqueIdentifier>{fb988684-58e6-4c21-bb04-3856f4b3f45c}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="Source Files\AltAdvancement">
+      <UniqueIdentifier>{be36d929-d107-4e06-aa58-f76b3c3c20af}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="Source Files\Housing">
+      <UniqueIdentifier>{5ffc936d-d1f9-4219-af84-f5ba0375c6cd}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="Header Files\RaceTypes">
+      <UniqueIdentifier>{cb0ea567-92f2-43da-8d7c-db27cdb4f09d}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="Source Files\RaceTypes">
+      <UniqueIdentifier>{387b255d-dcd9-41c2-b568-36762f1b096e}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="Source Files\HeroicOp">
+      <UniqueIdentifier>{3fdda05a-53d3-441c-a153-07ef811d676b}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="Header Files\HeroicOp">
+      <UniqueIdentifier>{e346a00a-fea8-41e2-8376-102aed344a46}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="Source Files\Zone">
+      <UniqueIdentifier>{336a3c4a-ec95-42b7-b05b-a5298f093102}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="Header Files\Zone">
+      <UniqueIdentifier>{eb29a311-6097-49be-8ef4-07479bda60b3}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="Source Files\LUA">
+      <UniqueIdentifier>{18bd779d-df1a-451e-978e-1aa865471b08}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="Header Files\LUA">
+      <UniqueIdentifier>{0ace3e54-1c82-4073-8411-a6b26127b2f8}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="Header Files\Patch">
+      <UniqueIdentifier>{2a4e5daa-ea00-4675-8c2d-1c35472e7568}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="Source Files\Patch">
+      <UniqueIdentifier>{426cef00-2d5d-41c3-93fb-24fffb144d89}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="Source Files\Bots">
+      <UniqueIdentifier>{df28eb71-7bf3-40a2-870e-66ca3e241815}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="Header Files\Bots">
+      <UniqueIdentifier>{7ba9d403-3833-4deb-8586-f00c9dda0ee8}</UniqueIdentifier>
+    </Filter>
+  </ItemGroup>
+  <ItemGroup>
+    <ClCompile Include="..\..\source\common\Condition.cpp">
+      <Filter>Common Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\source\common\ConfigReader.cpp">
+      <Filter>Common Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\source\common\CRC16.cpp">
+      <Filter>Common Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\source\common\Crypto.cpp">
+      <Filter>Common Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\source\common\database.cpp">
+      <Filter>Common Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\source\common\dbcore.cpp">
+      <Filter>Common Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\source\common\debug.cpp">
+      <Filter>Common Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\source\common\emu_opcodes.cpp">
+      <Filter>Common Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\source\common\EQEMuError.cpp">
+      <Filter>Common Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\source\common\EQPacket.cpp">
+      <Filter>Common Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\source\common\EQStream.cpp">
+      <Filter>Common Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\source\common\EQStreamFactory.cpp">
+      <Filter>Common Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\source\common\Log.cpp">
+      <Filter>Common Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\source\common\md5.cpp">
+      <Filter>Common Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\source\common\misc.cpp">
+      <Filter>Common Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\source\common\MiscFunctions.cpp">
+      <Filter>Common Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\source\common\Mutex.cpp">
+      <Filter>Common Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\source\common\opcodemgr.cpp">
+      <Filter>Common Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\source\common\packet_dump.cpp">
+      <Filter>Common Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\source\common\packet_functions.cpp">
+      <Filter>Common Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\source\common\PacketStruct.cpp">
+      <Filter>Common Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\source\common\RC4.cpp">
+      <Filter>Common Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\source\common\TCPConnection.cpp">
+      <Filter>Common Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\source\common\timer.cpp">
+      <Filter>Common Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\source\common\xmlParser.cpp">
+      <Filter>Common Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\source\WorldServer\classes.cpp">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\source\WorldServer\client.cpp">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\source\WorldServer\ClientPacketFunctions.cpp">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\source\WorldServer\Combat.cpp">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\source\WorldServer\Entity.cpp">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\source\WorldServer\Factions.cpp">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\source\WorldServer\GroundSpawn.cpp">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\source\WorldServer\LoginServer.cpp">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\source\WorldServer\LuaFunctions.cpp">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\source\WorldServer\LuaInterface.cpp">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\source\WorldServer\net.cpp">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\source\WorldServer\NPC.cpp">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\source\WorldServer\NPC_AI.cpp">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\source\WorldServer\Object.cpp">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\source\WorldServer\Player.cpp">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\source\WorldServer\Quests.cpp">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\source\WorldServer\races.cpp">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\source\WorldServer\Sign.cpp">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\source\WorldServer\Skills.cpp">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\source\WorldServer\Spawn.cpp">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\source\WorldServer\SpellProcess.cpp">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\source\WorldServer\Spells.cpp">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\source\WorldServer\Widget.cpp">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\source\WorldServer\World.cpp">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\source\WorldServer\WorldDatabase.cpp">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\source\WorldServer\zoneserver.cpp">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\source\WorldServer\Collections\Collections.cpp">
+      <Filter>Source Files\Collections</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\source\WorldServer\Commands\Commands.cpp">
+      <Filter>Source Files\Commands</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\source\WorldServer\Tradeskills\Tradeskills.cpp">
+      <Filter>Source Files\Tradeskills</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\source\WorldServer\Commands\ConsoleCommands.cpp">
+      <Filter>Source Files\Commands</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\source\WorldServer\Recipes\Recipe.cpp">
+      <Filter>Source Files\Recipes</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\source\WorldServer\Recipes\RecipeDB.cpp">
+      <Filter>Source Files\Recipes</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\source\WorldServer\Rules\Rules.cpp">
+      <Filter>Source Files\Rules</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\source\WorldServer\Rules\RulesDB.cpp">
+      <Filter>Source Files\Rules</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\source\WorldServer\Titles.cpp">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\source\WorldServer\Tradeskills\TradeskillsDB.cpp">
+      <Filter>Source Files\Tradeskills</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\source\WorldServer\Collections\CollectionsDB.cpp">
+      <Filter>Source Files\Collections</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\source\WorldServer\Commands\CommandsDB.cpp">
+      <Filter>Source Files\Commands</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\source\WorldServer\Guilds\Guild.cpp">
+      <Filter>Source Files\Guilds</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\source\WorldServer\Guilds\GuildDB.cpp">
+      <Filter>Source Files\Guilds</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\source\WorldServer\Languages.cpp">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\source\WorldServer\IRC\IRC.cpp">
+      <Filter>Source Files\IRC</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\source\WorldServer\IRC\IRCChannel.cpp">
+      <Filter>Source Files\IRC</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\source\WorldServer\IRC\IRCMessage.cpp">
+      <Filter>Source Files\IRC</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\source\WorldServer\IRC\IRCServer.cpp">
+      <Filter>Source Files\IRC</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\source\WorldServer\Achievements\Achievements.cpp">
+      <Filter>Source Files\Acheivements</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\source\WorldServer\Achievements\AchievementsDB.cpp">
+      <Filter>Source Files\Acheivements</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\source\WorldServer\Traits\Traits.cpp">
+      <Filter>Source Files\Traits</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\source\common\DatabaseResult.cpp">
+      <Filter>Common Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\source\common\DatabaseNew.cpp">
+      <Filter>Common Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\source\WorldServer\Chat\Chat.cpp">
+      <Filter>Source Files\Chat</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\source\WorldServer\Chat\ChatDB.cpp">
+      <Filter>Source Files\Chat</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\source\WorldServer\Chat\ChatChannel.cpp">
+      <Filter>Source Files\Chat</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\source\WorldServer\Items\ItemsDB.cpp">
+      <Filter>Source Files\Items</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\source\WorldServer\Items\Items.cpp">
+      <Filter>Source Files\Items</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\source\WorldServer\Items\Loot.cpp">
+      <Filter>Source Files\Items</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\source\WorldServer\Items\LootDB.cpp">
+      <Filter>Source Files\Items</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\source\WorldServer\AltAdvancement\AltAdvancement.cpp">
+      <Filter>Source Files\AltAdvancement</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\source\WorldServer\Tradeskills\TradeskillsPackets.cpp">
+      <Filter>Source Files\Tradeskills</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\source\WorldServer\AltAdvancement\AltAdvancementDB.cpp">
+      <Filter>Source Files\AltAdvancement</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\source\WorldServer\Housing\HousingDB.cpp">
+      <Filter>Source Files\Housing</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\source\WorldServer\Housing\HousingPackets.cpp">
+      <Filter>Source Files\Housing</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\source\WorldServer\RaceTypes\RaceTypes.cpp">
+      <Filter>Source Files\RaceTypes</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\source\WorldServer\HeroicOp\HeroicOp.cpp">
+      <Filter>Source Files\HeroicOp</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\source\WorldServer\HeroicOp\HeroicOpDB.cpp">
+      <Filter>Source Files\HeroicOp</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\source\WorldServer\HeroicOp\HeroicOpPackets.cpp">
+      <Filter>Source Files\HeroicOp</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\source\WorldServer\RaceTypes\RaceTypesDB.cpp">
+      <Filter>Source Files\RaceTypes</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\source\WorldServer\PlayerGroups.cpp">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\source\WorldServer\Zone\SPGrid.cpp">
+      <Filter>Source Files\Zone</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\source\WorldServer\Patch\patch.cpp">
+      <Filter>Source Files\Patch</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\source\WorldServer\Patch\tcp.cpp">
+      <Filter>Source Files\Patch</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\source\WorldServer\Patch\tcp-client.cpp">
+      <Filter>Source Files\Patch</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\source\WorldServer\Patch\buffer.cpp">
+      <Filter>Source Files\Patch</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\source\LUA\lapi.c">
+      <Filter>Source Files\LUA</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\source\LUA\lauxlib.c">
+      <Filter>Source Files\LUA</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\source\LUA\lbaselib.c">
+      <Filter>Source Files\LUA</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\source\LUA\lbitlib.c">
+      <Filter>Source Files\LUA</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\source\LUA\lcode.c">
+      <Filter>Source Files\LUA</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\source\LUA\lcorolib.c">
+      <Filter>Source Files\LUA</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\source\LUA\lctype.c">
+      <Filter>Source Files\LUA</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\source\LUA\ldblib.c">
+      <Filter>Source Files\LUA</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\source\LUA\ldebug.c">
+      <Filter>Source Files\LUA</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\source\LUA\ldo.c">
+      <Filter>Source Files\LUA</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\source\LUA\ldump.c">
+      <Filter>Source Files\LUA</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\source\LUA\lfunc.c">
+      <Filter>Source Files\LUA</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\source\LUA\lgc.c">
+      <Filter>Source Files\LUA</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\source\LUA\linit.c">
+      <Filter>Source Files\LUA</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\source\LUA\liolib.c">
+      <Filter>Source Files\LUA</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\source\LUA\llex.c">
+      <Filter>Source Files\LUA</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\source\LUA\lmathlib.c">
+      <Filter>Source Files\LUA</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\source\LUA\lmem.c">
+      <Filter>Source Files\LUA</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\source\LUA\loadlib.c">
+      <Filter>Source Files\LUA</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\source\LUA\lobject.c">
+      <Filter>Source Files\LUA</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\source\LUA\lopcodes.c">
+      <Filter>Source Files\LUA</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\source\LUA\loslib.c">
+      <Filter>Source Files\LUA</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\source\LUA\lparser.c">
+      <Filter>Source Files\LUA</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\source\LUA\lstate.c">
+      <Filter>Source Files\LUA</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\source\LUA\lstring.c">
+      <Filter>Source Files\LUA</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\source\LUA\lstrlib.c">
+      <Filter>Source Files\LUA</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\source\LUA\ltable.c">
+      <Filter>Source Files\LUA</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\source\LUA\ltablib.c">
+      <Filter>Source Files\LUA</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\source\LUA\ltm.c">
+      <Filter>Source Files\LUA</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\source\LUA\lundump.c">
+      <Filter>Source Files\LUA</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\source\LUA\lutf8lib.c">
+      <Filter>Source Files\LUA</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\source\LUA\lvm.c">
+      <Filter>Source Files\LUA</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\source\LUA\lzio.c">
+      <Filter>Source Files\LUA</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\source\WorldServer\Bots\Bot.cpp">
+      <Filter>Source Files\Bots</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\source\WorldServer\Bots\BotBrain.cpp">
+      <Filter>Source Files\Bots</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\source\WorldServer\Bots\BotDB.cpp">
+      <Filter>Source Files\Bots</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\source\WorldServer\Bots\BotCommands.cpp">
+      <Filter>Source Files\Bots</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\source\WorldServer\Trade.cpp">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\source\WorldServer\Transmute.cpp">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+  </ItemGroup>
+  <ItemGroup>
+    <ClInclude Include="..\..\source\common\Common_Defines.h">
+      <Filter>Common Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\source\common\ConfigReader.h">
+      <Filter>Common Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\source\common\CRC16.h">
+      <Filter>Common Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\source\common\Crypto.h">
+      <Filter>Common Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\source\common\database.h">
+      <Filter>Common Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\source\common\DataBuffer.h">
+      <Filter>Common Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\source\common\dbcore.h">
+      <Filter>Common Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\source\common\debug.h">
+      <Filter>Common Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\source\common\emu_opcodes.h">
+      <Filter>Common Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\source\common\emu_oplist.h">
+      <Filter>Common Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\source\common\EQ2_Common_Structs.h">
+      <Filter>Common Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\source\common\EQEMuError.h">
+      <Filter>Common Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\source\common\EQPacket.h">
+      <Filter>Common Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\source\common\EQStream.h">
+      <Filter>Common Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\source\common\EQStreamFactory.h">
+      <Filter>Common Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\source\common\GlobalHeaders.h">
+      <Filter>Common Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\source\common\linked_list.h">
+      <Filter>Common Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\source\common\Log.h">
+      <Filter>Common Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\source\common\LogTypes.h">
+      <Filter>Common Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\source\common\md5.h">
+      <Filter>Common Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\source\common\misc.h">
+      <Filter>Common Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\source\common\MiscFunctions.h">
+      <Filter>Common Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\source\common\Mutex.h">
+      <Filter>Common Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\source\common\opcodemgr.h">
+      <Filter>Common Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\source\common\packet_dump.h">
+      <Filter>Common Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\source\common\packet_functions.h">
+      <Filter>Common Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\source\common\PacketStruct.h">
+      <Filter>Common Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\source\common\queue.h">
+      <Filter>Common Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\source\common\RC4.h">
+      <Filter>Common Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\source\common\Seperator.h">
+      <Filter>Common Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\source\common\servertalk.h">
+      <Filter>Common Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\source\common\TCPConnection.h">
+      <Filter>Common Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\source\common\timer.h">
+      <Filter>Common Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\source\common\types.h">
+      <Filter>Common Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\source\common\version.h">
+      <Filter>Common Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\source\common\xmlParser.h">
+      <Filter>Common Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\source\WorldServer\classes.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\source\WorldServer\client.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\source\WorldServer\ClientPacketFunctions.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\source\WorldServer\Combat.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\source\WorldServer\Entity.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\source\WorldServer\Factions.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\source\WorldServer\GroundSpawn.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\source\WorldServer\LoginServer.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\source\WorldServer\LuaFunctions.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\source\WorldServer\LuaInterface.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\source\WorldServer\MutexHelper.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\source\WorldServer\MutexList.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\source\WorldServer\MutexMap.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\source\WorldServer\MutexVector.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\source\WorldServer\net.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\source\WorldServer\NPC.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\source\WorldServer\NPC_AI.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\source\WorldServer\Object.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\source\WorldServer\Player.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\source\WorldServer\Quests.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\source\WorldServer\races.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\source\WorldServer\Sign.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\source\WorldServer\Skills.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\source\WorldServer\Spawn.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\source\WorldServer\SpawnLists.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\source\WorldServer\SpellProcess.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\source\WorldServer\Spells.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\source\WorldServer\Variables.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\source\WorldServer\VisualStates.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\source\WorldServer\Widget.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\source\WorldServer\World.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\source\WorldServer\WorldDatabase.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\source\WorldServer\WorldTCPConnection.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\source\WorldServer\zoneserver.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\source\WorldServer\Collections\Collections.h">
+      <Filter>Header Files\Collections</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\source\WorldServer\Commands\Commands.h">
+      <Filter>Header Files\Commands</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\source\WorldServer\Commands\ConsoleCommands.h">
+      <Filter>Header Files\Commands</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\source\WorldServer\Tradeskills\Tradeskills.h">
+      <Filter>Header Files\Tradeskills</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\source\WorldServer\Recipes\Recipe.h">
+      <Filter>Header Files\Recipes</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\source\WorldServer\Rules\Rules.h">
+      <Filter>Header Files\Rules</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\source\WorldServer\Titles.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\source\WorldServer\Guilds\Guild.h">
+      <Filter>Header Files\Guilds</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\source\WorldServer\Languages.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\source\WorldServer\IRC\IRC.h">
+      <Filter>Header Files\IRC</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\source\WorldServer\IRC\IRCChannel.h">
+      <Filter>Header Files\IRC</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\source\WorldServer\IRC\IRCMessage.h">
+      <Filter>Header Files\IRC</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\source\WorldServer\IRC\IRCReplyCodes.h">
+      <Filter>Header Files\IRC</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\source\WorldServer\IRC\IRCServer.h">
+      <Filter>Header Files\IRC</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\source\WorldServer\Achievements\Achievements.h">
+      <Filter>Header Files\Achievements</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\source\WorldServer\Traits\Traits.h">
+      <Filter>Header Files\Traits</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\source\common\DatabaseResult.h">
+      <Filter>Common Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\source\common\DatabaseNew.h">
+      <Filter>Common Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\source\WorldServer\Chat\Chat.h">
+      <Filter>Header Files\Chat</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\source\WorldServer\Chat\ChatChannel.h">
+      <Filter>Header Files\Chat</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\source\WorldServer\Items\Items.h">
+      <Filter>Header Files\Items</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\source\WorldServer\Items\Loot.h">
+      <Filter>Header Files\Items</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\source\WorldServer\AltAdvancement\AltAdvancement.h">
+      <Filter>Header Files\AltAdvancement</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\source\WorldServer\Appearances.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\source\WorldServer\RaceTypes\RaceTypes.h">
+      <Filter>Header Files\RaceTypes</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\source\WorldServer\HeroicOp\HeroicOp.h">
+      <Filter>Header Files\HeroicOp</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\source\WorldServer\PlayerGroups.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\source\WorldServer\Zone\SPGrid.h">
+      <Filter>Header Files\Zone</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\source\WorldServer\Patch\patch.h">
+      <Filter>Header Files\Patch</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\source\WorldServer\Patch\tcp.h">
+      <Filter>Header Files\Patch</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\source\WorldServer\Patch\tcp-client.h">
+      <Filter>Header Files\Patch</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\source\WorldServer\Patch\buffer.h">
+      <Filter>Header Files\Patch</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\source\LUA\lapi.h">
+      <Filter>Header Files\LUA</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\source\LUA\lauxlib.h">
+      <Filter>Header Files\LUA</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\source\LUA\lcode.h">
+      <Filter>Header Files\LUA</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\source\LUA\lctype.h">
+      <Filter>Header Files\LUA</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\source\LUA\ldebug.h">
+      <Filter>Header Files\LUA</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\source\LUA\ldo.h">
+      <Filter>Header Files\LUA</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\source\LUA\lfunc.h">
+      <Filter>Header Files\LUA</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\source\LUA\lgc.h">
+      <Filter>Header Files\LUA</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\source\LUA\llex.h">
+      <Filter>Header Files\LUA</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\source\LUA\llimits.h">
+      <Filter>Header Files\LUA</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\source\LUA\lmem.h">
+      <Filter>Header Files\LUA</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\source\LUA\lobject.h">
+      <Filter>Header Files\LUA</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\source\LUA\lopcodes.h">
+      <Filter>Header Files\LUA</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\source\LUA\lparser.h">
+      <Filter>Header Files\LUA</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\source\LUA\lprefix.h">
+      <Filter>Header Files\LUA</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\source\LUA\lstate.h">
+      <Filter>Header Files\LUA</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\source\LUA\lstring.h">
+      <Filter>Header Files\LUA</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\source\LUA\ltable.h">
+      <Filter>Header Files\LUA</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\source\LUA\ltm.h">
+      <Filter>Header Files\LUA</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\source\LUA\lua.h">
+      <Filter>Header Files\LUA</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\source\LUA\luaconf.h">
+      <Filter>Header Files\LUA</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\source\LUA\lualib.h">
+      <Filter>Header Files\LUA</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\source\LUA\lundump.h">
+      <Filter>Header Files\LUA</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\source\LUA\lvm.h">
+      <Filter>Header Files\LUA</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\source\LUA\lzio.h">
+      <Filter>Header Files\LUA</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\source\WorldServer\Bots\Bot.h">
+      <Filter>Header Files\Bots</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\source\WorldServer\Bots\BotBrain.h">
+      <Filter>Header Files\Bots</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\source\WorldServer\Trade.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\source\WorldServer\Transmute.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+  </ItemGroup>
+</Project>

+ 3 - 0
EQ2/win/VC10Projects/EQ2World.vcxproj.user

@@ -0,0 +1,3 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+</Project>

+ 30 - 0
server/ItemStructs.xml

@@ -1185,6 +1185,28 @@
 <Data ElementName="name" Type="char" Size="64" />
 <Data ElementName="unknown6" Type="int8" Size="17" />
 </Struct>
+<Struct Name="Substruct_Item" ClientVersion="67650" >
+<Data ElementName="unique_id" Type="int32" Size="1" />
+<Data ElementName="bag_id" Type="int32" Size="1" />
+<Data ElementName="inv_slot_id" Type="int32" Size="1" />
+<Data ElementName="menu_type" Type="int32" Size="1" />
+<Data ElementName="unknown3" Type="int32" Size="1" />
+<Data ElementName="index" Type="int16" Size="1" />
+<Data ElementName="icon" Type="int16" Size="1" />
+<Data ElementName="slot_id" Type="int8" Size="1" />
+<Data ElementName="count" Type="int16" Size="1" />
+<Data ElementName="unknown4b" Type="int8" Size="1" />
+<Data ElementName="unknown4c" Type="int8" Size="1" />
+<Data ElementName="item_level" Type="int8" Size="1" />
+<Data ElementName="tier" Type="int8" Size="1" />
+<Data ElementName="num_slots" Type="int8" Size="1" />
+<Data ElementName="empty_slots" Type="int8" Size="1" />
+<Data ElementName="unknown5_2" Type="int8" Size="1" />
+<Data ElementName="item_id" Type="sint32" Size="1" />
+<Data ElementName="broker_id" Type="int64" Size="1" />
+<Data ElementName="name" Type="char" Size="64" />
+<Data ElementName="unknown6" Type="int8" Size="16" />
+</Struct>
 <Struct Name="Substruct_ItemFooter" ClientVersion="1" >
 <Data ElementName="num_effects" Type="int8" IfVariableNotSet="header_info_header_unknown_0_0,header_unknown_0" />
 <Data ElementName="effect_array" Type="Array" ArraySizeVariable="num_effects">
@@ -4011,6 +4033,14 @@
 </Data>
 <Data ElementName="equip_flag" Type="int8" Size="1" />
 </Struct>
+<Struct Name="WS_UpdateInventory" ClientVersion="67650" OpcodeName="OP_UpdateInventoryMsg" >
+<Data ElementName="item_count" Type="int16" />
+<Data ElementName="packed_size" Type="int32" />
+<Data ElementName="item_array" Type="Array" ArraySizeVariable="item_count">
+  <Data ElementName="items" Substruct="Substruct_Item" Size="1" />
+</Data>
+<Data ElementName="equip_flag" Type="int8" Size="1" />
+</Struct>
 <Struct Name="WS_ItemGeneric" ClientVersion="1" OpcodeName="OP_ClientCmdMsg" OpcodeType="OP_EqExamineInfoCmd">
 <Data ElementName="header" Substruct="Substruct_ItemDescription" Size="1" />
 <Data ElementName="footer" Substruct="Substruct_ItemFooter" Size="1" />

Some files were not shown because too many files changed in this diff