aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sql/updates/characters/2012_08_01_00_characters_item_instance_434.sql11
-rw-r--r--src/server/game/DataStores/DB2Structure.h1
-rwxr-xr-xsrc/server/game/DataStores/DBCStores.cpp13
-rwxr-xr-xsrc/server/game/DataStores/DBCStores.h6
-rwxr-xr-xsrc/server/game/DataStores/DBCStructure.h49
-rwxr-xr-xsrc/server/game/DataStores/DBCfmt.h10
-rwxr-xr-xsrc/server/game/Entities/Item/Item.cpp167
-rwxr-xr-xsrc/server/game/Entities/Item/Item.h29
-rwxr-xr-xsrc/server/game/Entities/Item/ItemPrototype.h9
-rwxr-xr-xsrc/server/game/Entities/Player/Player.cpp4
-rwxr-xr-xsrc/server/game/Globals/ObjectMgr.cpp16
-rw-r--r--src/server/game/Handlers/CharacterHandler.cpp27
-rwxr-xr-xsrc/server/game/Handlers/GroupHandler.cpp78
-rwxr-xr-xsrc/server/game/Handlers/ItemHandler.cpp24
-rw-r--r--src/server/game/Handlers/VoidStorageHandler.cpp1
-rw-r--r--src/server/game/Movement/Spline/MovementPacketBuilder.cpp1
-rwxr-xr-xsrc/server/game/Quests/QuestDef.cpp1
-rwxr-xr-xsrc/server/game/Quests/QuestDef.h1
-rw-r--r--src/server/game/Server/Protocol/Opcodes.cpp11
-rwxr-xr-xsrc/server/game/Server/Protocol/Opcodes.h1
-rwxr-xr-xsrc/server/game/Server/WorldSession.h1
21 files changed, 369 insertions, 92 deletions
diff --git a/sql/updates/characters/2012_08_01_00_characters_item_instance_434.sql b/sql/updates/characters/2012_08_01_00_characters_item_instance_434.sql
new file mode 100644
index 00000000000..b87b781e293
--- /dev/null
+++ b/sql/updates/characters/2012_08_01_00_characters_item_instance_434.sql
@@ -0,0 +1,11 @@
+UPDATE `item_instance` SET `enchantments` = REPLACE(`enchantments`,' ',' ');
+UPDATE `item_instance` SET `enchantments` = CONCAT(TRIM(`enchantments`),' ');
+
+UPDATE `item_instance` SET `enchantments` = CONCAT(
+ SUBSTRING_INDEX(`enchantments`, ' ', 7*3),
+ ' 0 0 0 0 0 0 0 0 0 ',
+ SUBSTRING_INDEX(`enchantments`, ' ', -(12-7)*3 - 1))
+WHERE (LENGTH(`enchantments`) - LENGTH(REPLACE(`enchantments`, ' ', ''))) = 12*3;
+
+UPDATE `item_instance` SET `enchantments` = REPLACE(`enchantments`,' ',' ');
+UPDATE `item_instance` SET `enchantments` = CONCAT(TRIM(`enchantments`),' ');
diff --git a/src/server/game/DataStores/DB2Structure.h b/src/server/game/DataStores/DB2Structure.h
index a7b4fe4c07f..386e8546236 100644
--- a/src/server/game/DataStores/DB2Structure.h
+++ b/src/server/game/DataStores/DB2Structure.h
@@ -25,6 +25,7 @@
#include "Util.h"
#include "Vehicle.h"
#include "SharedDefines.h"
+#include "ItemPrototype.h"
#include <map>
#include <set>
diff --git a/src/server/game/DataStores/DBCStores.cpp b/src/server/game/DataStores/DBCStores.cpp
index 80f62d9cedb..a9de83d3f80 100755
--- a/src/server/game/DataStores/DBCStores.cpp
+++ b/src/server/game/DataStores/DBCStores.cpp
@@ -21,6 +21,7 @@
#include "SharedDefines.h"
#include "SpellMgr.h"
#include "DBCfmt.h"
+#include "ItemPrototype.h"
#include <map>
@@ -109,9 +110,15 @@ DBCStorage <GtRegenMPPerSptEntry> sGtRegenMPPerSptStore(GtRegenMPPerSptf
DBCStorage <HolidaysEntry> sHolidaysStore(Holidaysfmt);
+DBCStorage <ImportPriceArmorEntry> sImportPriceArmorStore(ImportPriceArmorfmt);
+DBCStorage <ImportPriceQualityEntry> sImportPriceQualityStore(ImportPriceQualityfmt);
+DBCStorage <ImportPriceShieldEntry> sImportPriceShieldStore(ImportPriceShieldfmt);
+DBCStorage <ImportPriceWeaponEntry> sImportPriceWeaponStore(ImportPriceWeaponfmt);
+DBCStorage <ItemPriceBaseEntry> sItemPriceBaseStore(ItemPriceBasefmt);
DBCStorage <ItemArmorQualityEntry> sItemArmorQualityStore(ItemArmorQualityfmt);
DBCStorage <ItemArmorShieldEntry> sItemArmorShieldStore(ItemArmorShieldfmt);
DBCStorage <ItemArmorTotalEntry> sItemArmorTotalStore(ItemArmorTotalfmt);
+DBCStorage <ItemClassEntry> sItemClassStore(ItemClassfmt);
DBCStorage <ItemBagFamilyEntry> sItemBagFamilyStore(ItemBagFamilyfmt);
DBCStorage <ItemDamageEntry> sItemDamageAmmoStore(ItemDamagefmt);
DBCStorage <ItemDamageEntry> sItemDamageOneHandStore(ItemDamagefmt);
@@ -390,7 +397,13 @@ void LoadDBCStores(const std::string& dataPath)
LoadDBC(availableDbcLocales, bad_dbc_files, sGtRegenMPPerSptStore, dbcPath, "gtRegenMPPerSpt.dbc");//14545
LoadDBC(availableDbcLocales, bad_dbc_files, sHolidaysStore, dbcPath, "Holidays.dbc");//14545
+ LoadDBC(availableDbcLocales, bad_dbc_files, sImportPriceArmorStore, dbcPath, "ImportPriceArmor.dbc"); // 15595
+ LoadDBC(availableDbcLocales, bad_dbc_files, sImportPriceQualityStore, dbcPath, "ImportPriceQuality.dbc"); // 15595
+ LoadDBC(availableDbcLocales, bad_dbc_files, sImportPriceShieldStore, dbcPath, "ImportPriceShield.dbc"); // 15595
+ LoadDBC(availableDbcLocales, bad_dbc_files, sImportPriceWeaponStore, dbcPath, "ImportPriceWeapon.dbc"); // 15595
+ LoadDBC(availableDbcLocales, bad_dbc_files, sItemPriceBaseStore, dbcPath, "ItemPriceBase.dbc"); // 15595
LoadDBC(availableDbcLocales, bad_dbc_files, sItemBagFamilyStore, dbcPath, "ItemBagFamily.dbc");//14545
+ LoadDBC(availableDbcLocales, bad_dbc_files, sItemClassStore, dbcPath, "ItemClass.dbc"); // 15595
//LoadDBC(dbcCount, availableDbcLocales, bad_dbc_files, sItemDisplayInfoStore, dbcPath, "ItemDisplayInfo.dbc"); -- not used currently
LoadDBC(availableDbcLocales, bad_dbc_files, sItemLimitCategoryStore, dbcPath, "ItemLimitCategory.dbc");//14545
LoadDBC(availableDbcLocales, bad_dbc_files, sItemRandomPropertiesStore, dbcPath, "ItemRandomProperties.dbc");//14545
diff --git a/src/server/game/DataStores/DBCStores.h b/src/server/game/DataStores/DBCStores.h
index d94b60c1384..252d8c53d92 100755
--- a/src/server/game/DataStores/DBCStores.h
+++ b/src/server/game/DataStores/DBCStores.h
@@ -121,9 +121,15 @@ extern DBCStorage <GtRegenHPPerSptEntry> sGtRegenHPPerSptStore;
extern DBCStorage <gtOCTHpPerStaminaEntry> sGtOCTHpPerStaminaStore;
extern DBCStorage <GtRegenMPPerSptEntry> sGtRegenMPPerSptStore;
extern DBCStorage <HolidaysEntry> sHolidaysStore;
+extern DBCStorage <ImportPriceArmorEntry> sImportPriceArmorStore;
+extern DBCStorage <ImportPriceQualityEntry> sImportPriceQualityStore;
+extern DBCStorage <ImportPriceShieldEntry> sImportPriceShieldStore;
+extern DBCStorage <ImportPriceWeaponEntry> sImportPriceWeaponStore;
+extern DBCStorage <ItemPriceBaseEntry> sItemPriceBaseStore;
extern DBCStorage <ItemArmorQualityEntry> sItemArmorQualityStore;
extern DBCStorage <ItemArmorShieldEntry> sItemArmorShieldStore;
extern DBCStorage <ItemArmorTotalEntry> sItemArmorTotalStore;
+extern DBCStorage <ItemClassEntry> sItemClassStore;
extern DBCStorage <ItemBagFamilyEntry> sItemBagFamilyStore;
extern DBCStorage <ItemDamageEntry> sItemDamageAmmoStore;
extern DBCStorage <ItemDamageEntry> sItemDamageOneHandStore;
diff --git a/src/server/game/DataStores/DBCStructure.h b/src/server/game/DataStores/DBCStructure.h
index cde1aa51e0d..1a9c7b16398 100755
--- a/src/server/game/DataStores/DBCStructure.h
+++ b/src/server/game/DataStores/DBCStructure.h
@@ -1153,6 +1153,45 @@ struct HolidaysEntry
//uint32 flags; // 54 m_flags (0 = Darkmoon Faire, Fishing Contest and Wotlk Launch, rest is 1)
};
+// ImportPriceArmor.dbc
+struct ImportPriceArmorEntry
+{
+ uint32 InventoryType; // 1 Id/InventoryType
+ float ClothFactor; // 2 Price factor cloth
+ float LeatherFactor; // 3 Price factor leather
+ float MailFactor; // 4 Price factor mail
+ float PlateFactor; // 5 Price factor plate
+};
+
+// ImportPriceQuality.dbc
+struct ImportPriceQualityEntry
+{
+ uint32 QualityId; // 1 Quality Id (+1?)
+ float Factor; // 2 Price factor
+};
+
+// ImportPriceShield.dbc
+struct ImportPriceShieldEntry
+{
+ uint32 Id; // 1 Unk id (only 1 and 2)
+ float Factor; // 2 Price factor
+};
+
+// ImportPriceWeapon.dbc
+struct ImportPriceWeaponEntry
+{
+ uint32 Id; // 1 Unk id (mainhand - 0, offhand - 1, weapon - 2, 2hweapon - 3, ranged/rangedright/relic - 4)
+ float Factor; // 2 Price factor
+};
+
+// ItemPriceBase.dbc
+struct ItemPriceBaseEntry
+{
+ uint32 ItemLevel; // 2 Item level (1 - 1000)
+ float ArmorFactor; // 3 Price factor for armor
+ float WeaponFactor; // 4 Price factor for weapons
+};
+
// common struct for:
// ItemDamageAmmo.dbc
// ItemDamageOneHand.dbc
@@ -1190,6 +1229,16 @@ struct ItemArmorTotalEntry
float Value[4]; // 2-5 multiplier for armor types (cloth...plate)
};
+// ItemClass.dbc
+struct ItemClassEntry
+{
+ uint32 Class; // 1 item class id
+ //uint32 Unk; // 2 unk
+ //uint32 IsWeapon; // 3 1 for weapon, 0 for everything else
+ float PriceFactor; // 4 used to calculate certain prices
+ //char* Name; // class name
+};
+
struct ItemBagFamilyEntry
{
uint32 ID; // 0
diff --git a/src/server/game/DataStores/DBCfmt.h b/src/server/game/DataStores/DBCfmt.h
index 780a33685d6..03521512c99 100755
--- a/src/server/game/DataStores/DBCfmt.h
+++ b/src/server/game/DataStores/DBCfmt.h
@@ -19,6 +19,9 @@
#ifndef TRINITY_DBCSFRM_H
#define TRINITY_DBCSFRM_H
+// x - skip<uint32>, X - skip<uint8>, s - char*, f - float, i - uint32, b - uint8, d - index (not included)
+// n - index (included), l - bool, p - field present in sql dbc, a - field absent in sql dbc
+
const char Achievementfmt[]="niixsxiixixxii";
//const std::string CustomAchievementfmt="pppaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaapapaaaaaaaaaaaaaaaaaapp";
//const std::string CustomAchievementIndex = "ID";
@@ -74,12 +77,17 @@ const char GtOCTRegenHPfmt[]="f";
//const char GtOCTRegenMPfmt[]="f";
const char GtRegenHPPerSptfmt[]="f";
const char GtRegenMPPerSptfmt[]="xf";
-
const char Holidaysfmt[]="niiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiixxsiix";
+const char ImportPriceArmorfmt[]="nffff";
+const char ImportPriceQualityfmt[]="nf";
+const char ImportPriceShieldfmt[]="nf";
+const char ImportPriceWeaponfmt[]="nf";
+const char ItemPriceBasefmt[]="diff";
const char ItemBagFamilyfmt[]="nx";
const char ItemArmorQualityfmt[]="nfffffffi";
const char ItemArmorShieldfmt[]="nifffffff";
const char ItemArmorTotalfmt[]="niffff";
+const char ItemClassfmt[]="dixxfx";
const char ItemDamagefmt[]="nfffffffi";
const char ItemDisenchantLootfmt[]="niiiiii";
//const char ItemDisplayTemplateEntryfmt[]="nxxxxxxxxxxixxxxxxxxxxx";
diff --git a/src/server/game/Entities/Item/Item.cpp b/src/server/game/Entities/Item/Item.cpp
index 130aac50935..9c5d03f5440 100755
--- a/src/server/game/Entities/Item/Item.cpp
+++ b/src/server/game/Entities/Item/Item.cpp
@@ -1275,7 +1275,7 @@ bool Item::CanTransmogrifyItemWithItem(Item const* transmogrified, Item const* t
proto1->InventoryType == INVTYPE_QUIVER)
return false;
- if (proto1->SubClass != proto2->SubClass && (proto1->Class != ITEM_CLASS_WEAPON || !transmogrified->IsRangedWeapon() || !transmogrifier->IsRangedWeapon()))
+ if (proto1->SubClass != proto2->SubClass && (proto1->Class != ITEM_CLASS_WEAPON || !proto2->IsRangedWeapon() || !proto1->IsRangedWeapon()))
return false;
if (proto1->InventoryType != proto2->InventoryType &&
@@ -1290,20 +1290,171 @@ bool Item::HasStats() const
if (GetItemRandomPropertyId() != 0)
return true;
+ ItemTemplate const* proto = GetTemplate();
for (uint8 i = 0; i < MAX_ITEM_PROTO_STATS; ++i)
- if (GetTemplate()->ItemStat[i].ItemStatValue != 0)
+ if (proto->ItemStat[i].ItemStatValue != 0)
return true;
return false;
}
-bool Item::IsRangedWeapon() const
+// used by mail items, transmog cost, stationeryinfo and others
+uint32 Item::GetSellPrice(bool& normalSellPrice) const
{
ItemTemplate const* proto = GetTemplate();
- if (proto && proto->Class == ITEM_CLASS_WEAPON)
- return proto->SubClass == ITEM_SUBCLASS_WEAPON_BOW ||
- proto->SubClass == ITEM_SUBCLASS_WEAPON_GUN ||
- proto->SubClass == ITEM_SUBCLASS_WEAPON_CROSSBOW;
+ normalSellPrice = true;
- return false;
+ if (proto->Flags2 & ITEM_FLAGS_EXTRA_HAS_NORMAL_PRICE)
+ {
+ return proto->BuyPrice;
+ }
+ else
+ {
+ ImportPriceQualityEntry const* qualityPrice = sImportPriceQualityStore.LookupEntry(proto->Quality + 1);
+ ItemPriceBaseEntry const* basePrice = sItemPriceBaseStore.LookupEntry(proto->ItemLevel);
+
+ if (!qualityPrice || !basePrice)
+ return 0;
+
+ float qualityFactor = qualityPrice->Factor;
+ float baseFactor = 0.0f;
+
+ uint32 inventoryType = proto->InventoryType;
+
+ if (inventoryType == INVTYPE_WEAPON ||
+ inventoryType == INVTYPE_2HWEAPON ||
+ inventoryType == INVTYPE_WEAPONMAINHAND ||
+ inventoryType == INVTYPE_WEAPONOFFHAND ||
+ inventoryType == INVTYPE_RANGED ||
+ inventoryType == INVTYPE_THROWN ||
+ inventoryType == INVTYPE_RANGEDRIGHT)
+ baseFactor = basePrice->WeaponFactor;
+ else
+ baseFactor = basePrice->ArmorFactor;
+
+ if (inventoryType == INVTYPE_ROBE)
+ inventoryType = INVTYPE_CHEST;
+
+ float typeFactor = 0.0f;
+ uint8 wepType = -1;
+
+ switch (inventoryType)
+ {
+ case INVTYPE_HEAD:
+ case INVTYPE_SHOULDERS:
+ case INVTYPE_CHEST:
+ case INVTYPE_WAIST:
+ case INVTYPE_LEGS:
+ case INVTYPE_FEET:
+ case INVTYPE_WRISTS:
+ case INVTYPE_HANDS:
+ case INVTYPE_CLOAK:
+ {
+ ImportPriceArmorEntry const* armorPrice = sImportPriceArmorStore.LookupEntry(inventoryType);
+ if (!armorPrice)
+ return 0;
+
+ switch (proto->SubClass)
+ {
+ case ITEM_SUBCLASS_ARMOR_MISCELLANEOUS:
+ case ITEM_SUBCLASS_ARMOR_CLOTH:
+ {
+ typeFactor = armorPrice->ClothFactor;
+ break;
+ }
+ case ITEM_SUBCLASS_ARMOR_LEATHER:
+ {
+ typeFactor = armorPrice->ClothFactor;
+ break;
+ }
+ case ITEM_SUBCLASS_ARMOR_MAIL:
+ {
+ typeFactor = armorPrice->ClothFactor;
+ break;
+ }
+ case ITEM_SUBCLASS_ARMOR_PLATE:
+ {
+ typeFactor = armorPrice->ClothFactor;
+ break;
+ }
+ default:
+ {
+ return 0;
+ }
+ }
+
+ break;
+ }
+ case INVTYPE_SHIELD:
+ {
+ ImportPriceShieldEntry const* shieldPrice = sImportPriceShieldStore.LookupEntry(1); // it only has two rows, it's unclear which is the one used
+ if (!shieldPrice)
+ return 0;
+
+ typeFactor = shieldPrice->Factor;
+ break;
+ }
+ case INVTYPE_WEAPONMAINHAND:
+ wepType = 0; // unk enum, fall back
+ case INVTYPE_WEAPONOFFHAND:
+ wepType = 1; // unk enum, fall back
+ case INVTYPE_WEAPON:
+ wepType = 2; // unk enum, fall back
+ case INVTYPE_2HWEAPON:
+ wepType = 3; // unk enum, fall back
+ case INVTYPE_RANGED:
+ case INVTYPE_RANGEDRIGHT:
+ case INVTYPE_RELIC:
+ {
+ wepType = 4; // unk enum
+
+ ImportPriceWeaponEntry const* weaponPrice = sImportPriceWeaponStore.LookupEntry(wepType + 1);
+ if (!weaponPrice)
+ return 0;
+
+ typeFactor = weaponPrice->Factor;
+ break;
+ }
+ default:
+ return proto->BuyPrice;
+ }
+
+ normalSellPrice = false;
+ return (uint32)(qualityFactor * proto->Unk430_2 * proto->Unk430_1 * typeFactor * baseFactor);
+ }
+}
+
+uint32 Item::GetTransmogrifyCost() const
+{
+ ItemTemplate const* proto = GetTemplate();
+ uint32 cost = 0;
+
+ if (proto->Flags2 & ITEM_FLAGS_EXTRA_HAS_NORMAL_PRICE)
+ cost = proto->SellPrice;
+ else
+ {
+ bool normalPrice;
+ cost = GetSellPrice(normalPrice);
+
+ if (!normalPrice)
+ {
+ if (proto->BuyCount <= 1)
+ {
+ ItemClassEntry const* classEntry = sItemClassStore.LookupEntry(proto->Class);
+ if (classEntry)
+ cost *= classEntry->PriceFactor;
+ else
+ cost = 0;
+ }
+ else
+ cost /= 4 * proto->BuyCount;
+ }
+ else
+ cost = proto->SellPrice;
+ }
+
+ if (cost < 10000)
+ cost = 10000;
+
+ return cost;
}
diff --git a/src/server/game/Entities/Item/Item.h b/src/server/game/Entities/Item/Item.h
index 2f9d10bb9d5..2d5ebaa555f 100755
--- a/src/server/game/Entities/Item/Item.h
+++ b/src/server/game/Entities/Item/Item.h
@@ -164,14 +164,15 @@ enum EnchantmentSlot
PRISMATIC_ENCHANTMENT_SLOT = 6, // added at apply special permanent enchantment
//TODO: 7,
//TODO: 8,
- MAX_INSPECTED_ENCHANTMENT_SLOT = 9,
-
- PROP_ENCHANTMENT_SLOT_0 = 7, // used with RandomSuffix
- PROP_ENCHANTMENT_SLOT_1 = 8, // used with RandomSuffix
- PROP_ENCHANTMENT_SLOT_2 = 9, // used with RandomSuffix and RandomProperty
- PROP_ENCHANTMENT_SLOT_3 = 10, // used with RandomProperty
- PROP_ENCHANTMENT_SLOT_4 = 11, // used with RandomProperty
- MAX_ENCHANTMENT_SLOT = 12
+ TRANSMOGRIFY_ENCHANTMENT_SLOT = 9,
+ MAX_INSPECTED_ENCHANTMENT_SLOT = 10,
+
+ PROP_ENCHANTMENT_SLOT_0 = 10, // used with RandomSuffix
+ PROP_ENCHANTMENT_SLOT_1 = 11, // used with RandomSuffix
+ PROP_ENCHANTMENT_SLOT_2 = 12, // used with RandomSuffix and RandomProperty
+ PROP_ENCHANTMENT_SLOT_3 = 13, // used with RandomProperty
+ PROP_ENCHANTMENT_SLOT_4 = 14, // used with RandomProperty
+ MAX_ENCHANTMENT_SLOT = 15
};
#define MAX_VISIBLE_ITEM_OFFSET 2 // 2 fields per visible item (entry+enchantment)
@@ -322,7 +323,7 @@ class Item : public Object
bool IsWeaponVellum() const { return GetTemplate()->IsWeaponVellum(); }
bool IsArmorVellum() const { return GetTemplate()->IsArmorVellum(); }
bool IsConjuredConsumable() const { return GetTemplate()->IsConjuredConsumable(); }
- bool IsRangedWeapon() const;
+ bool IsRangedWeapon() const { return GetTemplate()->IsRangedWeapon(); }
// Item Refund system
void SetNotRefundable(Player* owner, bool changestate = true, SQLTransaction* trans = NULL);
@@ -349,6 +350,16 @@ class Item : public Object
bool CanBeTransmogrified() const;
bool CanTransmogrify() const;
static bool CanTransmogrifyItemWithItem(Item const* transmogrified, Item const* transmogrifier);
+ uint32 GetTransmogrifyCost() const;
+
+ uint32 GetVisibleEntry() const
+ {
+ if (uint32 transmogrification = GetEnchantmentId(TRANSMOGRIFY_ENCHANTMENT_SLOT))
+ return transmogrification;
+ return GetEntry();
+ }
+
+ uint32 GetSellPrice(bool& success) const;
private:
std::string m_text;
diff --git a/src/server/game/Entities/Item/ItemPrototype.h b/src/server/game/Entities/Item/ItemPrototype.h
index 7bfe43e0691..cfc65292507 100755
--- a/src/server/game/Entities/Item/ItemPrototype.h
+++ b/src/server/game/Entities/Item/ItemPrototype.h
@@ -196,6 +196,7 @@ enum ItemFlagsExtra
ITEM_FLAGS_EXTRA_EXT_COST_REQUIRES_GOLD = 0x00000004, // when item uses extended cost, gold is also required
ITEM_FLAGS_EXTRA_NEED_ROLL_DISABLED = 0x00000100,
ITEM_FLAGS_EXTRA_CASTER_WEAPON = 0x00000200,
+ ITEM_FLAGS_EXTRA_HAS_NORMAL_PRICE = 0x00004000,
ITEM_FLAGS_EXTRA_BNET_ACCOUNT_BOUND = 0x00020000,
ITEM_FLAGS_EXTRA_CANNOT_BE_TRANSMOG = 0x00200000,
ITEM_FLAGS_EXTRA_CANNOT_TRANSMOG = 0x00400000,
@@ -740,6 +741,14 @@ struct ItemTemplate
bool IsWeaponVellum() const { return Class == ITEM_CLASS_TRADE_GOODS && SubClass == ITEM_SUBCLASS_WEAPON_ENCHANTMENT; }
bool IsArmorVellum() const { return Class == ITEM_CLASS_TRADE_GOODS && SubClass == ITEM_SUBCLASS_ITEM_ENCHANTMENT; }
bool IsConjuredConsumable() const { return Class == ITEM_CLASS_CONSUMABLE && (Flags & ITEM_PROTO_FLAG_CONJURED); }
+
+ bool IsRangedWeapon() const
+ {
+ return Class == ITEM_CLASS_WEAPON ||
+ SubClass == ITEM_SUBCLASS_WEAPON_BOW ||
+ SubClass == ITEM_SUBCLASS_WEAPON_GUN ||
+ SubClass == ITEM_SUBCLASS_WEAPON_CROSSBOW;
+ }
};
// Benchmarked: Faster than std::map (insert/find)
diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp
index f3375fb115e..f729fe1502f 100755
--- a/src/server/game/Entities/Player/Player.cpp
+++ b/src/server/game/Entities/Player/Player.cpp
@@ -12357,7 +12357,7 @@ void Player::SetVisibleItemSlot(uint8 slot, Item* pItem)
{
if (pItem)
{
- SetUInt32Value(PLAYER_VISIBLE_ITEM_1_ENTRYID + (slot * 2), pItem->GetEntry());
+ SetUInt32Value(PLAYER_VISIBLE_ITEM_1_ENTRYID + (slot * 2), pItem->GetVisibleEntry());
SetUInt16Value(PLAYER_VISIBLE_ITEM_1_ENCHANTMENT + (slot * 2), 0, pItem->GetEnchantmentId(PERM_ENCHANTMENT_SLOT));
SetUInt16Value(PLAYER_VISIBLE_ITEM_1_ENCHANTMENT + (slot * 2), 1, pItem->GetEnchantmentId(TEMP_ENCHANTMENT_SLOT));
}
@@ -25717,7 +25717,7 @@ uint8 Player::AddVoidStorageItem(const VoidStorageItem& item)
GetSession()->SendVoidStorageTransferResult(VOID_TRANSFER_ERROR_FULL);
return -1;
}
-
+
_voidStorageItems[slot] = new VoidStorageItem(item.ItemId, item.ItemEntry,
item.CreatorGuid, item.ItemRandomPropertyId, item.ItemSuffixFactor);
return slot;
diff --git a/src/server/game/Globals/ObjectMgr.cpp b/src/server/game/Globals/ObjectMgr.cpp
index 258e5d3ec25..1c56c64c985 100755
--- a/src/server/game/Globals/ObjectMgr.cpp
+++ b/src/server/game/Globals/ObjectMgr.cpp
@@ -2448,25 +2448,25 @@ void ObjectMgr::LoadItemTemplates()
itemTemplate.ContainerSlots = uint32(fields[28].GetUInt8());
for (uint32 i = 0; i < MAX_ITEM_PROTO_STATS; ++i)
{
- itemTemplate.ItemStat[i].ItemStatType = uint32(fields[28 + i * 4 + 0].GetUInt8());
- itemTemplate.ItemStat[i].ItemStatValue = int32(fields[28 + i * 4 + 1].GetInt16());
- itemTemplate.ItemStat[i].ItemStatUnk1 = fields[28 + i * 4 + 2].GetInt32();
- itemTemplate.ItemStat[i].ItemStatUnk2 = fields[28 + i * 4 + 3].GetInt32();
+ itemTemplate.ItemStat[i].ItemStatType = uint32(fields[29 + i * 4 + 0].GetUInt8());
+ itemTemplate.ItemStat[i].ItemStatValue = int32(fields[29 + i * 4 + 1].GetInt16());
+ itemTemplate.ItemStat[i].ItemStatUnk1 = fields[29 + i * 4 + 2].GetInt32();
+ itemTemplate.ItemStat[i].ItemStatUnk2 = fields[29 + i * 4 + 3].GetInt32();
}
itemTemplate.ScalingStatDistribution = uint32(fields[69].GetUInt16());
// cache item damage
FillItemDamageFields(&itemTemplate.DamageMin, &itemTemplate.DamageMax, &itemTemplate.DPS, itemTemplate.ItemLevel,
- itemTemplate.Class, itemTemplate.SubClass, itemTemplate.Quality, fields[71].GetUInt32(),
+ itemTemplate.Class, itemTemplate.SubClass, itemTemplate.Quality, fields[71].GetUInt16(),
fields[131].GetFloat(), itemTemplate.InventoryType, itemTemplate.Flags2);
- itemTemplate.DamageType = fields[70].GetUInt32();
+ itemTemplate.DamageType = fields[70].GetUInt8();
itemTemplate.Armor = FillItemArmor(itemTemplate.ItemLevel, itemTemplate.Class,
itemTemplate.SubClass, itemTemplate.Quality,
itemTemplate.InventoryType);
- itemTemplate.Delay = fields[71].GetUInt32();
+ itemTemplate.Delay = fields[71].GetUInt16();
itemTemplate.RangedModRange = fields[72].GetFloat();
for (uint32 i = 0; i < MAX_ITEM_PROTO_SPELLS; ++i)
{
@@ -8906,7 +8906,7 @@ void ObjectMgr::LoadHotfixData()
HotfixInfo info;
info.Entry = fields[0].GetUInt32();
info.Type = fields[1].GetUInt32();
- info.Timestamp = fields[2].GetUInt32();
+ info.Timestamp = fields[2].GetUInt64();
_hotfixData.push_back(info);
++count;
diff --git a/src/server/game/Handlers/CharacterHandler.cpp b/src/server/game/Handlers/CharacterHandler.cpp
index d75d25b00e2..996e0e97ea6 100644
--- a/src/server/game/Handlers/CharacterHandler.cpp
+++ b/src/server/game/Handlers/CharacterHandler.cpp
@@ -850,26 +850,27 @@ void WorldSession::HandlePlayerLogin(LoginQueryHolder* holder)
LoadAccountData(holder->GetPreparedResult(PLAYER_LOGIN_QUERY_LOADACCOUNTDATA), PER_CHARACTER_CACHE_MASK);
SendAccountDataTimes(PER_CHARACTER_CACHE_MASK);
+ bool featureBit4 = true;
data.Initialize(SMSG_FEATURE_SYSTEM_STATUS, 7); // checked in 4.2.2
data << uint8(2); // unknown value
+ data << uint32(1);
+ data << uint32(1);
+ data << uint32(2);
data << uint32(0);
- data << uint32(0);
- data << uint32(0);
- data << uint32(0);
- data.WriteBit(0);
- data.WriteBit(0);
- data.WriteBit(0);
+ data.WriteBit(1);
+ data.WriteBit(1);
data.WriteBit(0);
+ data.WriteBit(featureBit4);
data.WriteBit(0);
data.WriteBit(0);
data.FlushBits();
- //if (featureBit4)
- //{
- // data << uint32(0);
- // data << uint32(0);
- // data << uint32(0);
- // data << uint32(0);
- //}
+ if (featureBit4)
+ {
+ data << uint32(1);
+ data << uint32(0);
+ data << uint32(10);
+ data << uint32(60);
+ }
//if (featureBit5)
//{
diff --git a/src/server/game/Handlers/GroupHandler.cpp b/src/server/game/Handlers/GroupHandler.cpp
index 60b698d79b8..8ffb41ddc87 100755
--- a/src/server/game/Handlers/GroupHandler.cpp
+++ b/src/server/game/Handlers/GroupHandler.cpp
@@ -59,86 +59,90 @@ void WorldSession::SendPartyResult(PartyOperation operation, const std::string&
SendPacket(&data);
}
-void WorldSession::HandleGroupInviteOpcode(WorldPacket & recv_data)
+void WorldSession::HandleGroupInviteOpcode(WorldPacket & recvData)
{
sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Received CMSG_GROUP_INVITE");
- //BytesGuid guid;
- //guid.guid = 0;
+ ObjectGuid crossRealmGuid; // unused
- //recv_data.ReadByteMask(guid.bytes[6]);
- //recv_data.ReadByteMask(guid.bytes[5]);
- //recv_data.ReadByteMask(guid.bytes[0]);
- //recv_data.ReadByteMask(guid.bytes[3]);
- //recv_data.ReadByteMask(guid.bytes[4]);
- //recv_data.ReadByteMask(guid.bytes[7]);
- //recv_data.ReadByteMask(guid.bytes[1]);
- //recv_data.ReadByteMask(guid.bytes[2]);
+ recvData.read_skip<uint32>(); // Non-zero in cross realm invites
+ recvData.read_skip<uint32>(); // Always 0
- recv_data.read_skip<uint32>();
- recv_data.read_skip<uint32>();
+ crossRealmGuid[2] = recvData.ReadBit();
+ crossRealmGuid[7] = recvData.ReadBit();
- std::string membername;
- recv_data >> membername;
- recv_data.read_skip<uint32>();
+ uint8 realmLen = recvData.ReadBits(9);
+
+ crossRealmGuid[3] = recvData.ReadBit();
- //recv_data.ReadByteSeq(guid.bytes[0]);
- //recv_data.ReadByteSeq(guid.bytes[7]);
- //recv_data.ReadByteSeq(guid.bytes[4]);
- //recv_data.ReadByteSeq(guid.bytes[1]);
- //recv_data.ReadByteSeq(guid.bytes[2]);
- //recv_data.ReadByteSeq(guid.bytes[6]);
- //recv_data.ReadByteSeq(guid.bytes[5]);
- std::string string0;
- recv_data >> string0;
- //recv_data.ReadByteSeq(guid.bytes[3]);
+ uint8 nameLen = recvData.ReadBits(10);
+
+ crossRealmGuid[5] = recvData.ReadBit();
+ crossRealmGuid[4] = recvData.ReadBit();
+ crossRealmGuid[6] = recvData.ReadBit();
+ crossRealmGuid[0] = recvData.ReadBit();
+ crossRealmGuid[1] = recvData.ReadBit();
+
+ recvData.ReadByteSeq(crossRealmGuid[4]);
+ recvData.ReadByteSeq(crossRealmGuid[7]);
+ recvData.ReadByteSeq(crossRealmGuid[6]);
+
+ std::string memberName, realmName;
+ memberName = recvData.ReadString(nameLen);
+ realmName = recvData.ReadString(realmLen); // unused
+
+ recvData.ReadByteSeq(crossRealmGuid[1]);
+ recvData.ReadByteSeq(crossRealmGuid[0]);
+ recvData.ReadByteSeq(crossRealmGuid[5]);
+ recvData.ReadByteSeq(crossRealmGuid[3]);
+ recvData.ReadByteSeq(crossRealmGuid[2]);
// attempt add selected player
// cheating
- if (!normalizePlayerName(membername))
+ if (!normalizePlayerName(memberName))
{
- SendPartyResult(PARTY_OP_INVITE, membername, ERR_BAD_PLAYER_NAME_S);
+ SendPartyResult(PARTY_OP_INVITE, memberName, ERR_BAD_PLAYER_NAME_S);
return;
}
- Player* player = sObjectAccessor->FindPlayerByName(membername.c_str());
+ Player* player = sObjectAccessor->FindPlayerByName(memberName.c_str());
// no player
if (!player)
{
- SendPartyResult(PARTY_OP_INVITE, membername, ERR_BAD_PLAYER_NAME_S);
+ SendPartyResult(PARTY_OP_INVITE, memberName, ERR_BAD_PLAYER_NAME_S);
return;
}
// restrict invite to GMs
if (!sWorld->getBoolConfig(CONFIG_ALLOW_GM_GROUP) && !GetPlayer()->isGameMaster() && player->isGameMaster())
{
- SendPartyResult(PARTY_OP_INVITE, membername, ERR_BAD_PLAYER_NAME_S);
+ SendPartyResult(PARTY_OP_INVITE, memberName, ERR_BAD_PLAYER_NAME_S);
return;
}
// can't group with
if (!GetPlayer()->isGameMaster() && !sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_GROUP) && GetPlayer()->GetTeam() != player->GetTeam())
{
- SendPartyResult(PARTY_OP_INVITE, membername, ERR_PLAYER_WRONG_FACTION);
+ SendPartyResult(PARTY_OP_INVITE, memberName, ERR_PLAYER_WRONG_FACTION);
return;
}
if (GetPlayer()->GetInstanceId() != 0 && player->GetInstanceId() != 0 && GetPlayer()->GetInstanceId() != player->GetInstanceId() && GetPlayer()->GetMapId() == player->GetMapId())
{
- SendPartyResult(PARTY_OP_INVITE, membername, ERR_TARGET_NOT_IN_INSTANCE_S);
+ SendPartyResult(PARTY_OP_INVITE, memberName, ERR_TARGET_NOT_IN_INSTANCE_S);
return;
}
// just ignore us
if (player->GetInstanceId() != 0 && player->GetDungeonDifficulty() != GetPlayer()->GetDungeonDifficulty())
{
- SendPartyResult(PARTY_OP_INVITE, membername, ERR_IGNORING_YOU_S);
+ SendPartyResult(PARTY_OP_INVITE, memberName, ERR_IGNORING_YOU_S);
return;
}
if (player->GetSocial()->HasIgnore(GetPlayer()->GetGUIDLow()))
{
- SendPartyResult(PARTY_OP_INVITE, membername, ERR_IGNORING_YOU_S);
+ SendPartyResult(PARTY_OP_INVITE, memberName, ERR_IGNORING_YOU_S);
return;
}
@@ -152,7 +156,7 @@ void WorldSession::HandleGroupInviteOpcode(WorldPacket & recv_data)
// player already in another group or invited
if (group2 || player->GetGroupInvite())
{
- SendPartyResult(PARTY_OP_INVITE, membername, ERR_ALREADY_IN_GROUP_S);
+ SendPartyResult(PARTY_OP_INVITE, memberName, ERR_ALREADY_IN_GROUP_S);
if (group2)
{
@@ -221,7 +225,7 @@ void WorldSession::HandleGroupInviteOpcode(WorldPacket & recv_data)
data << uint32(0); // unk
player->GetSession()->SendPacket(&data);
- SendPartyResult(PARTY_OP_INVITE, membername, ERR_PARTY_RESULT_OK);
+ SendPartyResult(PARTY_OP_INVITE, memberName, ERR_PARTY_RESULT_OK);
}
void WorldSession::HandleGroupAcceptOpcode(WorldPacket& recv_data)
diff --git a/src/server/game/Handlers/ItemHandler.cpp b/src/server/game/Handlers/ItemHandler.cpp
index 0b21363a783..18859e766d1 100755
--- a/src/server/game/Handlers/ItemHandler.cpp
+++ b/src/server/game/Handlers/ItemHandler.cpp
@@ -746,7 +746,7 @@ void WorldSession::SendListInventory(uint64 vendorGuid)
VendorItemData const* vendorItems = vendor->GetVendorItems();
uint8 rawItemCount = vendorItems ? vendorItems->GetItemCount() : 0;
- //if (rawItemCount > 300),
+ //if (rawItemCount > 300),
// rawItemCount = 300; // client cap but uint8 max value is 255
ByteBuffer itemsData(32 * rawItemCount);
@@ -783,7 +783,7 @@ void WorldSession::SendListInventory(uint64 vendorGuid)
if (leftInStock == 0)
continue;
}
-
+
int32 price = vendorItem->IsGoldRequired(itemTemplate) ? uint32(floor(itemTemplate->BuyPrice * discountMod)) : 0;
uint32 leftInStock = !vendorItem->maxcount ? 0xFFFFFFFF : vendor->GetVendorItemCurrentCount(vendorItem);
@@ -1464,7 +1464,6 @@ void WorldSession::HandleTransmogrifyItems(WorldPacket& recvData)
Player* player = GetPlayer();
// Read data
-
uint32 count = recvData.ReadBits(22);
if (count < EQUIPMENT_SLOT_START || count >= EQUIPMENT_SLOT_END)
@@ -1477,7 +1476,7 @@ void WorldSession::HandleTransmogrifyItems(WorldPacket& recvData)
ObjectGuid* itemGuids = new ObjectGuid[count];
uint32* newEntries = new uint32[count];
uint32* slots = new uint32[count];
-
+
for (uint8 i = 0; i < count; ++i)
{
itemGuids[i][0] = recvData.ReadBit();
@@ -1535,6 +1534,7 @@ void WorldSession::HandleTransmogrifyItems(WorldPacket& recvData)
return;
}
+ int32 cost = 0;
for (uint8 i = 0; i < count; ++i)
{
// slot of the transmogrified item
@@ -1592,8 +1592,8 @@ void WorldSession::HandleTransmogrifyItems(WorldPacket& recvData)
if (!newEntries[i]) // reset look
{
- player->SetUInt32Value(PLAYER_VISIBLE_ITEM_1_ENTRYID + (slots[i] * 2), itemTransmogrified->GetEntry());
- itemTransmogrified->SetUInt32Value(ITEM_FIELD_ENCHANTMENT_10_1, 0);
+ itemTransmogrified->ClearEnchantment(TRANSMOGRIFY_ENCHANTMENT_SLOT);
+ player->SetVisibleItemSlot(slots[i], itemTransmogrified);
}
else
{
@@ -1604,9 +1604,8 @@ void WorldSession::HandleTransmogrifyItems(WorldPacket& recvData)
}
// All okay, proceed
-
- player->SetUInt32Value(PLAYER_VISIBLE_ITEM_1_ENTRYID + (slots[i] * 2), newEntries[i]);
- itemTransmogrified->SetUInt32Value(ITEM_FIELD_ENCHANTMENT_10_1, newEntries[i]);
+ itemTransmogrified->SetEnchantment(TRANSMOGRIFY_ENCHANTMENT_SLOT, newEntries[i], 0, 0);
+ player->SetVisibleItemSlot(slots[i], itemTransmogrified);
itemTransmogrified->UpdatePlayedTime(player);
@@ -1617,7 +1616,14 @@ void WorldSession::HandleTransmogrifyItems(WorldPacket& recvData)
itemTransmogrifier->SetOwnerGUID(player->GetGUID());
itemTransmogrifier->SetNotRefundable(player);
itemTransmogrifier->ClearSoulboundTradeable(player);
+
+ cost += itemTransmogrified->GetTransmogrifyCost();
}
+
+ // trusting the client, if it got here it has to have enough money
+ // ... unless client was modified
+ if (cost) // 0 cost if reverting look
+ player->ModifyMoney(-cost);
}
delete[] itemGuids;
diff --git a/src/server/game/Handlers/VoidStorageHandler.cpp b/src/server/game/Handlers/VoidStorageHandler.cpp
index 3938def0cc7..5e3ecc89e21 100644
--- a/src/server/game/Handlers/VoidStorageHandler.cpp
+++ b/src/server/game/Handlers/VoidStorageHandler.cpp
@@ -20,6 +20,7 @@
#include "WorldSession.h"
#include "World.h"
#include "ObjectAccessor.h"
+#include "ObjectMgr.h"
#include "Log.h"
#include "Opcodes.h"
#include "Player.h"
diff --git a/src/server/game/Movement/Spline/MovementPacketBuilder.cpp b/src/server/game/Movement/Spline/MovementPacketBuilder.cpp
index 69f087a6b2a..6a3c2ba8eea 100644
--- a/src/server/game/Movement/Spline/MovementPacketBuilder.cpp
+++ b/src/server/game/Movement/Spline/MovementPacketBuilder.cpp
@@ -19,6 +19,7 @@
#include "MovementPacketBuilder.h"
#include "MoveSpline.h"
#include "WorldPacket.h"
+#include "Object.h"
namespace Movement
{
diff --git a/src/server/game/Quests/QuestDef.cpp b/src/server/game/Quests/QuestDef.cpp
index ff351f90f74..32dc58e582b 100755
--- a/src/server/game/Quests/QuestDef.cpp
+++ b/src/server/game/Quests/QuestDef.cpp
@@ -19,6 +19,7 @@
#include "QuestDef.h"
#include "Player.h"
#include "World.h"
+#include "ObjectMgr.h"
Quest::Quest(Field* questRecord)
{
diff --git a/src/server/game/Quests/QuestDef.h b/src/server/game/Quests/QuestDef.h
index 1c8afd2a90b..b72956ce313 100755
--- a/src/server/game/Quests/QuestDef.h
+++ b/src/server/game/Quests/QuestDef.h
@@ -22,6 +22,7 @@
#include "Define.h"
#include "DatabaseEnv.h"
#include "SharedDefines.h"
+#include "WorldPacket.h"
#include <string>
#include <vector>
diff --git a/src/server/game/Server/Protocol/Opcodes.cpp b/src/server/game/Server/Protocol/Opcodes.cpp
index 166a9ad5601..47ca9d86e31 100644
--- a/src/server/game/Server/Protocol/Opcodes.cpp
+++ b/src/server/game/Server/Protocol/Opcodes.cpp
@@ -21,6 +21,7 @@
*/
#include "Opcodes.h"
+#include "WorldSession.h"
OpcodeHandler* opcodeTable[NUM_OPCODE_HANDLERS] = { };
@@ -313,7 +314,7 @@ void InitOpcodes()
//DEFINE_OPCODE_HANDLER(CMSG_GROUP_CHANGE_SUB_GROUP, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleGroupChangeSubGroupOpcode );
//DEFINE_OPCODE_HANDLER(CMSG_GROUP_DECLINE, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleGroupDeclineOpcode );
//DEFINE_OPCODE_HANDLER(CMSG_GROUP_DISBAND, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleGroupDisbandOpcode );
- //DEFINE_OPCODE_HANDLER(CMSG_GROUP_INVITE, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleGroupInviteOpcode );
+ DEFINE_OPCODE_HANDLER(CMSG_GROUP_INVITE, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleGroupInviteOpcode );
//DEFINE_OPCODE_HANDLER(CMSG_GROUP_RAID_CONVERT, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleGroupRaidConvertOpcode );
//DEFINE_OPCODE_HANDLER(CMSG_GROUP_SET_LEADER, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleGroupSetLeaderOpcode );
//DEFINE_OPCODE_HANDLER(CMSG_GROUP_SWAP_SUB_GROUP, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleGroupSwapSubGroupOpcode );
@@ -683,8 +684,8 @@ void InitOpcodes()
DEFINE_OPCODE_HANDLER(CMSG_VOID_SWAP_ITEM, STATUS_LOGGEDIN, PROCESS_INPLACE, &WorldSession::HandleVoidSwapItem );
//DEFINE_OPCODE_HANDLER(CMSG_WARDEN_DATA, STATUS_AUTHED, PROCESS_THREADUNSAFE, &WorldSession::HandleWardenDataOpcode );
//DEFINE_OPCODE_HANDLER(CMSG_WEATHER_SPEED_CHEAT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
- //DEFINE_OPCODE_HANDLER(CMSG_WHO, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleWhoOpcode );
- //DEFINE_OPCODE_HANDLER(CMSG_WHOIS, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleWhoisOpcode );
+ DEFINE_OPCODE_HANDLER(CMSG_WHO, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleWhoOpcode );
+ DEFINE_OPCODE_HANDLER(CMSG_WHOIS, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleWhoisOpcode );
DEFINE_OPCODE_HANDLER(CMSG_WORLD_STATE_UI_TIMER_UPDATE, STATUS_LOGGEDIN, PROCESS_INPLACE, &WorldSession::HandleWorldStateUITimerUpdate );
//DEFINE_OPCODE_HANDLER(CMSG_WORLD_TELEPORT, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleWorldTeleportOpcode );
//DEFINE_OPCODE_HANDLER(CMSG_WRAP_ITEM, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleWrapItemOpcode );
@@ -1392,8 +1393,8 @@ void InitOpcodes()
DEFINE_OPCODE_HANDLER(SMSG_VOID_STORAGE_FAILED, STATUS_LOGGEDIN, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
//DEFINE_OPCODE_HANDLER(SMSG_WARDEN_DATA, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
DEFINE_OPCODE_HANDLER(SMSG_WEATHER, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
- //DEFINE_OPCODE_HANDLER(SMSG_WHO, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
- //DEFINE_OPCODE_HANDLER(SMSG_WHOIS, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_WHO, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_WHOIS, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
DEFINE_OPCODE_HANDLER(SMSG_WORLD_STATE_UI_TIMER_UPDATE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
//DEFINE_OPCODE_HANDLER(SMSG_ZONE_MAP, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
//DEFINE_OPCODE_HANDLER(SMSG_ZONE_UNDER_ATTACK, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
diff --git a/src/server/game/Server/Protocol/Opcodes.h b/src/server/game/Server/Protocol/Opcodes.h
index b1790d096b8..6ee5ade502a 100755
--- a/src/server/game/Server/Protocol/Opcodes.h
+++ b/src/server/game/Server/Protocol/Opcodes.h
@@ -1438,6 +1438,7 @@ enum PacketProcessing
};
class WorldPacket;
+class WorldSession;
typedef void(WorldSession::*pOpcodeHandler)(WorldPacket& recvPacket);
diff --git a/src/server/game/Server/WorldSession.h b/src/server/game/Server/WorldSession.h
index 38351e8340b..fb9c90e94b8 100755
--- a/src/server/game/Server/WorldSession.h
+++ b/src/server/game/Server/WorldSession.h
@@ -30,6 +30,7 @@
#include "World.h"
#include "WorldPacket.h"
#include "Cryptography/BigNumber.h"
+#include "Opcodes.h"
class CalendarEvent;
class CalendarInvite;