diff options
Diffstat (limited to 'src')
-rwxr-xr-x | src/server/game/DataStores/DBCStores.cpp | 6 | ||||
-rwxr-xr-x | src/server/game/DataStores/DBCStores.h | 6 | ||||
-rwxr-xr-x | src/server/game/DataStores/DBCStructure.h | 49 | ||||
-rwxr-xr-x | src/server/game/DataStores/DBCfmt.h | 10 | ||||
-rwxr-xr-x | src/server/game/Entities/Item/Item.cpp | 167 | ||||
-rwxr-xr-x | src/server/game/Entities/Item/Item.h | 5 | ||||
-rwxr-xr-x | src/server/game/Entities/Item/ItemPrototype.h | 9 | ||||
-rwxr-xr-x | src/server/game/Handlers/ItemHandler.cpp | 8 |
8 files changed, 250 insertions, 10 deletions
diff --git a/src/server/game/DataStores/DBCStores.cpp b/src/server/game/DataStores/DBCStores.cpp index f7f38021daf..fb2e0806d99 100755 --- a/src/server/game/DataStores/DBCStores.cpp +++ b/src/server/game/DataStores/DBCStores.cpp @@ -110,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); 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..3c2900f60e9 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[]="dixxfs"; 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..59c23ec5176 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); // it only has two rows, it's unclear which is the one used + 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 64b74539727..2d5ebaa555f 100755 --- a/src/server/game/Entities/Item/Item.h +++ b/src/server/game/Entities/Item/Item.h @@ -323,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); @@ -350,6 +350,7 @@ 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 { @@ -358,6 +359,8 @@ class Item : public Object return GetEntry(); } + uint32 GetSellPrice(bool& success) const; + private: std::string m_text; uint8 m_slot; 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/Handlers/ItemHandler.cpp b/src/server/game/Handlers/ItemHandler.cpp index b36ca5853cf..18859e766d1 100755 --- a/src/server/game/Handlers/ItemHandler.cpp +++ b/src/server/game/Handlers/ItemHandler.cpp @@ -1534,6 +1534,7 @@ void WorldSession::HandleTransmogrifyItems(WorldPacket& recvData) return; } + int32 cost = 0; for (uint8 i = 0; i < count; ++i) { // slot of the transmogrified item @@ -1615,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; |