mirror of
https://github.com/mangosfour/server.git
synced 2025-12-12 01:37:00 +00:00
[12736] Implemented reforge, also added missing part for HandleObjectUpdateFailedOpcode
This commit is contained in:
parent
22e906cea5
commit
3490f642cf
17 changed files with 464 additions and 14 deletions
|
|
@ -131,9 +131,11 @@ DBCStorage <ItemDamageEntry> sItemDamageTwoHandStore(ItemDamagefmt)
|
|||
DBCStorage <ItemDamageEntry> sItemDamageTwoHandCasterStore(ItemDamagefmt);
|
||||
DBCStorage <ItemDamageEntry> sItemDamageWandStore(ItemDamagefmt);
|
||||
//DBCStorage <ItemDisplayInfoEntry> sItemDisplayInfoStore(ItemDisplayTemplateEntryfmt); -- not used currently
|
||||
DBCStorage <ItemLimitCategoryEntry> sItemLimitCategoryStore(ItemLimitCategoryEntryfmt);
|
||||
DBCStorage <ItemRandomPropertiesEntry> sItemRandomPropertiesStore(ItemRandomPropertiesfmt);
|
||||
DBCStorage <ItemRandomSuffixEntry> sItemRandomSuffixStore(ItemRandomSuffixfmt);
|
||||
DBCStorage <ItemLimitCategoryEntry> sItemLimitCategoryStore(ItemLimitCategoryEntryfmt);
|
||||
DBCStorage <ItemRandomPropertiesEntry> sItemRandomPropertiesStore(ItemRandomPropertiesfmt);
|
||||
DBCStorage <ItemRandomSuffixEntry> sItemRandomSuffixStore(ItemRandomSuffixfmt);
|
||||
DBCStorage <ItemReforgeEntry> sItemReforgeStore(ItemReforgefmt);
|
||||
|
||||
DBCStorage <ItemSetEntry> sItemSetStore(ItemSetEntryfmt);
|
||||
DBCStorage <LiquidTypeEntry> sLiquidTypeStore(LiquidTypefmt);
|
||||
DBCStorage <LockEntry> sLockStore(LockEntryfmt);
|
||||
|
|
@ -417,7 +419,7 @@ void LoadDBCStores(const std::string& dataPath)
|
|||
exit(1);
|
||||
}
|
||||
|
||||
const uint32 DBCFilesCount = 124;
|
||||
const uint32 DBCFilesCount = 129;
|
||||
|
||||
BarGoLink bar(DBCFilesCount);
|
||||
|
||||
|
|
@ -536,6 +538,7 @@ void LoadDBCStores(const std::string& dataPath)
|
|||
LoadDBC(availableDbcLocales,bar,bad_dbc_files,sItemArmorShieldStore, dbcPath,"ItemArmorShield.dbc");
|
||||
LoadDBC(availableDbcLocales,bar,bad_dbc_files,sItemArmorTotalStore, dbcPath,"ItemArmorTotal.dbc");
|
||||
LoadDBC(availableDbcLocales, bar, bad_dbc_files, sItemBagFamilyStore, dbcPath, "ItemBagFamily.dbc");
|
||||
LoadDBC(availableDbcLocales,bar,bad_dbc_files,sItemReforgeStore, dbcPath, "ItemReforge.dbc");
|
||||
LoadDBC(availableDbcLocales, bar, bad_dbc_files, sItemClassStore, dbcPath, "ItemClass.dbc");
|
||||
LoadDBC(availableDbcLocales,bar,bad_dbc_files,sItemDamageAmmoStore, dbcPath,"ItemDamageAmmo.dbc");
|
||||
LoadDBC(availableDbcLocales,bar,bad_dbc_files,sItemDamageOneHandStore, dbcPath,"ItemDamageOneHand.dbc");
|
||||
|
|
|
|||
|
|
@ -171,6 +171,7 @@ extern DBCStorage <ItemDamageEntry> sItemDamageWandStore;
|
|||
extern DBCStorage <ItemLimitCategoryEntry> sItemLimitCategoryStore;
|
||||
extern DBCStorage <ItemRandomPropertiesEntry> sItemRandomPropertiesStore;
|
||||
extern DBCStorage <ItemRandomSuffixEntry> sItemRandomSuffixStore;
|
||||
extern DBCStorage <ItemReforgeEntry> sItemReforgeStore;
|
||||
extern DBCStorage <ItemSetEntry> sItemSetStore;
|
||||
extern DBCStorage <LiquidTypeEntry> sLiquidTypeStore;
|
||||
extern DBCStorage <LockEntry> sLockStore;
|
||||
|
|
|
|||
|
|
@ -1162,7 +1162,7 @@ struct ItemClassEntry
|
|||
uint32 Class; // 1
|
||||
//uint32 unk2; // 2 looks like second class
|
||||
//uint32 unk3; // 3 1 for weapons
|
||||
//float Multiplier // 4
|
||||
float PriceFactor; // 4
|
||||
DBCString name; // 5 m_name_lang
|
||||
};
|
||||
|
||||
|
|
@ -1223,6 +1223,15 @@ struct ItemRandomSuffixEntry
|
|||
uint32 prefix[5]; // 8-12 m_allocationPct
|
||||
};
|
||||
|
||||
struct ItemReforgeEntry
|
||||
{
|
||||
uint32 Id; // 0
|
||||
uint32 SourceStat; // 1
|
||||
float SourceMultiplier; // 2
|
||||
uint32 FinalStat; // 3
|
||||
float FinalMultiplier; // 4
|
||||
};
|
||||
|
||||
struct ItemSetEntry
|
||||
{
|
||||
//uint32 id // 0 m_ID
|
||||
|
|
|
|||
|
|
@ -71,7 +71,7 @@ const char GtSpellScalingfmt[]="df";
|
|||
const char GtOCTBaseHPByClassfmt[]="df";
|
||||
const char GtOCTBaseMPByClassfmt[]="df";
|
||||
const char Holidaysfmt[] = "nxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
|
||||
const char ItemClassfmt[]="nixxxs";
|
||||
const char ItemClassfmt[]="nixxfs";
|
||||
const char ItemArmorQualityfmt[]="nfffffffi";
|
||||
const char ItemArmorShieldfmt[]="nifffffff";
|
||||
const char ItemArmorTotalfmt[]="niffff";
|
||||
|
|
@ -82,6 +82,7 @@ const char ItemDamagefmt[]="nfffffffi";
|
|||
const char ItemLimitCategoryEntryfmt[]="nxii";
|
||||
const char ItemRandomPropertiesfmt[]="nxiiiiis";
|
||||
const char ItemRandomSuffixfmt[]="nsxiiiiiiiiii";
|
||||
const char ItemReforgefmt[]="nifif";
|
||||
const char ItemSetEntryfmt[]="dsxxxxxxxxxxxxxxxxxiiiiiiiiiiiiiiiiii";
|
||||
const char LiquidTypefmt[] = "nxxixixxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
|
||||
const char LockEntryfmt[] = "niiiiiiiiiiiiiiiiiiiiiiiixxxxxxxx";
|
||||
|
|
|
|||
|
|
@ -812,8 +812,8 @@ void Item::SetItemRandomProperties(int32 randomPropId)
|
|||
SetInt32Value(ITEM_FIELD_RANDOM_PROPERTIES_ID, item_rand->ID);
|
||||
SetState(ITEM_CHANGED);
|
||||
}
|
||||
for (uint32 i = PROP_ENCHANTMENT_SLOT_2; i < PROP_ENCHANTMENT_SLOT_2 + 3; ++i)
|
||||
SetEnchantment(EnchantmentSlot(i), item_rand->enchant_id[i - PROP_ENCHANTMENT_SLOT_2], 0, 0);
|
||||
for (uint32 i = PROP_ENCHANTMENT_SLOT_1; i < PROP_ENCHANTMENT_SLOT_4; ++i)
|
||||
SetEnchantment(EnchantmentSlot(i), item_rand->enchant_id[i - PROP_ENCHANTMENT_SLOT_1], 0, 0);
|
||||
}
|
||||
}
|
||||
else
|
||||
|
|
@ -829,7 +829,7 @@ void Item::SetItemRandomProperties(int32 randomPropId)
|
|||
SetState(ITEM_CHANGED);
|
||||
}
|
||||
|
||||
for (uint32 i = PROP_ENCHANTMENT_SLOT_0; i < PROP_ENCHANTMENT_SLOT_0 + 3; ++i)
|
||||
for (uint32 i = PROP_ENCHANTMENT_SLOT_0; i < PROP_ENCHANTMENT_SLOT_4; ++i)
|
||||
SetEnchantment(EnchantmentSlot(i), item_rand->enchant_id[i - PROP_ENCHANTMENT_SLOT_0], 0, 0);
|
||||
}
|
||||
}
|
||||
|
|
@ -1394,3 +1394,102 @@ void Item::SetLootState(ItemLootUpdateState state)
|
|||
if (m_lootState != ITEM_LOOT_NONE && m_lootState != ITEM_LOOT_UNCHANGED && m_lootState != ITEM_LOOT_TEMPORARY)
|
||||
SetState(ITEM_CHANGED);
|
||||
}
|
||||
|
||||
uint32 Item::GetSpecialPrice(ItemPrototype const* proto, uint32 minimumPrice /*= 10000*/)
|
||||
{
|
||||
uint32 cost = 0;
|
||||
|
||||
if (proto->Flags2 & ITEM_FLAG2_HAS_NORMAL_PRICE)
|
||||
cost = proto->SellPrice;
|
||||
else
|
||||
{
|
||||
bool normalPrice = true;
|
||||
//cost = Item::GetSellPrice(proto, normalPrice);
|
||||
cost = proto->SellPrice;
|
||||
|
||||
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 < minimumPrice)
|
||||
cost = minimumPrice;
|
||||
|
||||
return cost;
|
||||
}
|
||||
|
||||
int32 Item::GetReforgableStat(ItemModType statType) const
|
||||
{
|
||||
ItemPrototype const* proto = GetProto();
|
||||
for (uint32 i = 0; i < MAX_ITEM_PROTO_STATS; ++i)
|
||||
if (proto->ItemStat[i].ItemStatType == statType)
|
||||
return proto->ItemStat[i].ItemStatValue;
|
||||
|
||||
int32 randomPropId = GetItemRandomPropertyId();
|
||||
if (!randomPropId)
|
||||
return 0;
|
||||
|
||||
if (randomPropId < 0)
|
||||
{
|
||||
ItemRandomSuffixEntry const* randomSuffix = sItemRandomSuffixStore.LookupEntry(-randomPropId);
|
||||
if (!randomSuffix)
|
||||
return 0;
|
||||
|
||||
for (uint32 e = PROP_ENCHANTMENT_SLOT_0; e <= PROP_ENCHANTMENT_SLOT_4; ++e)
|
||||
{
|
||||
if (SpellItemEnchantmentEntry const* enchant = sSpellItemEnchantmentStore.LookupEntry(GetEnchantmentId(EnchantmentSlot(e))))
|
||||
{
|
||||
for (uint32 f = 0; f < 3; ++f)
|
||||
{
|
||||
if (enchant->type[f] == ITEM_ENCHANTMENT_TYPE_STAT && enchant->spellid[f] == statType)
|
||||
{
|
||||
for (int k = 0; k < 5; ++k)
|
||||
{
|
||||
if (randomSuffix->enchant_id[k] == enchant->ID)
|
||||
return int32((randomSuffix->prefix[k] * GetItemSuffixFactor()) / 10000);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ItemRandomPropertiesEntry const* randomProp = sItemRandomPropertiesStore.LookupEntry(randomPropId);
|
||||
if (!randomProp)
|
||||
return 0;
|
||||
|
||||
for (uint32 e = PROP_ENCHANTMENT_SLOT_0; e <= PROP_ENCHANTMENT_SLOT_4; ++e)
|
||||
{
|
||||
if (SpellItemEnchantmentEntry const* enchant = sSpellItemEnchantmentStore.LookupEntry(GetEnchantmentId(EnchantmentSlot(e))))
|
||||
{
|
||||
for (uint32 f = 0; f < 3; ++f)
|
||||
{
|
||||
if (enchant->type[f] == ITEM_ENCHANTMENT_TYPE_STAT && enchant->spellid[f] == statType)
|
||||
{
|
||||
for (int k = 0; k < 3; ++k)
|
||||
{
|
||||
if (randomProp->enchant_id[k] == enchant->ID)
|
||||
return int32(enchant->amount[k]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -388,6 +388,11 @@ class MANGOS_DLL_SPEC Item : public Object
|
|||
void AddToClientUpdateList() override;
|
||||
void RemoveFromClientUpdateList() override;
|
||||
void BuildUpdateData(UpdateDataMapType& update_players) override;
|
||||
|
||||
// Reforge
|
||||
static uint32 GetSpecialPrice(ItemPrototype const* proto, uint32 minimumPrice = 10000);
|
||||
uint32 GetSpecialPrice(uint32 minimumPrice = 10000) const { return Item::GetSpecialPrice(GetProto(), minimumPrice); }
|
||||
int32 GetReforgableStat(ItemModType statType) const;
|
||||
private:
|
||||
std::string m_text;
|
||||
uint8 m_slot;
|
||||
|
|
|
|||
|
|
@ -1481,4 +1481,77 @@ void WorldSession::SendItemSparseDb2Reply(uint32 entry)
|
|||
data.append(buff);
|
||||
|
||||
SendPacket(&data);
|
||||
}
|
||||
}
|
||||
|
||||
void WorldSession::SendReforgeResult(bool success)
|
||||
{
|
||||
WorldPacket data(SMSG_REFORGE_RESULT, 1);
|
||||
data.WriteBit(success);
|
||||
SendPacket(&data);
|
||||
}
|
||||
|
||||
void WorldSession::HandleReforgeItemOpcode(WorldPacket& recvData)
|
||||
{
|
||||
uint32 slot, reforgeEntry;
|
||||
ObjectGuid guid;
|
||||
uint32 bag;
|
||||
Player* player = GetPlayer();
|
||||
|
||||
recvData >> reforgeEntry >> slot >> bag;
|
||||
recvData.ReadGuidMask<2, 6, 3, 4, 1, 0, 7, 5>(guid);
|
||||
recvData.ReadGuidBytes<2, 3, 6, 4, 1, 0, 7, 5>(guid);
|
||||
|
||||
if (!player->GetNPCIfCanInteractWith(guid, UNIT_NPC_FLAG_REFORGER))
|
||||
{
|
||||
sLog.outDebug("WORLD: HandleReforgeItemOpcode - Unit (GUID: %s) not found or player can't interact with it.", guid.GetString().c_str());
|
||||
SendReforgeResult(false);
|
||||
return;
|
||||
}
|
||||
|
||||
Item* item = player->GetItemByPos(bag, slot);
|
||||
if (!item)
|
||||
{
|
||||
sLog.outDebug("WORLD: HandleReforgeItemOpcode - Player (Guid: %s) tried to reforge an invalid/non-existant item.", player->GetGuidStr().c_str());
|
||||
SendReforgeResult(false);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!reforgeEntry)
|
||||
{
|
||||
// Reset the item
|
||||
if (item->IsEquipped())
|
||||
player->ApplyReforgeEnchantment(item, false);
|
||||
|
||||
item->ClearEnchantment(REFORGE_ENCHANTMENT_SLOT);
|
||||
SendReforgeResult(true);
|
||||
return;
|
||||
}
|
||||
|
||||
ItemReforgeEntry const* stats = sItemReforgeStore.LookupEntry(reforgeEntry);
|
||||
if (!stats)
|
||||
{
|
||||
sLog.outDebug("WORLD: HandleReforgeItemOpcode - Player (Guid: %s) tried to reforge an item with invalid reforge entry (%u).", player->GetGuidStr().c_str(), reforgeEntry);
|
||||
SendReforgeResult(false);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!item->GetReforgableStat(ItemModType(stats->SourceStat)) || item->GetReforgableStat(ItemModType(stats->FinalStat))) // Cheating, you cant reforge to a stat that the item already has, nor reforge from a stat that the item does not have
|
||||
{
|
||||
SendReforgeResult(false);
|
||||
return;
|
||||
}
|
||||
|
||||
if (player->GetMoney() < uint64(item->GetSpecialPrice())) // cheating
|
||||
{
|
||||
SendReforgeResult(false);
|
||||
return;
|
||||
}
|
||||
|
||||
player->ModifyMoney(-int64(item->GetSpecialPrice()));
|
||||
item->SetEnchantment(REFORGE_ENCHANTMENT_SLOT, reforgeEntry, 0, 0);
|
||||
SendReforgeResult(true);
|
||||
|
||||
if (item->IsEquipped())
|
||||
player->ApplyReforgeEnchantment(item, true);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -158,6 +158,7 @@ enum ItemPrototypeFlags2
|
|||
ITEM_FLAG2_UNK8 = 0x00000080,
|
||||
ITEM_FLAG2_NEED_ROLL_DISABLED = 0x00000100, // need roll during looting is not allowed for this item
|
||||
ITEM_FLAG2_CASTER_WEAPON = 0x00000200, // uses caster specific dbc file for DPS calculations
|
||||
ITEM_FLAG2_HAS_NORMAL_PRICE = 0x00004000,
|
||||
};
|
||||
|
||||
enum BagFamilyMask
|
||||
|
|
|
|||
|
|
@ -1604,5 +1604,12 @@ void WorldSession::HandleObjectUpdateFailedOpcode(WorldPacket& recv_data)
|
|||
recv_data.ReadGuidBytes<6, 7, 2, 3, 1, 4, 0, 5>(guid);
|
||||
|
||||
DEBUG_LOG("WORLD: Received CMSG_OBJECT_UPDATE_FAILED from %s (%u) guid: %s", GetPlayerName(), GetAccountId(), guid.GetString().c_str());
|
||||
if (_player->IsInWorld())
|
||||
{
|
||||
if (WorldObject* obj = _player->GetMap()->GetWorldObject(guid))
|
||||
obj->SendCreateUpdateToPlayer(_player);
|
||||
}
|
||||
else
|
||||
sLog.outError("WorldSession::HandleObjectUpdateFailedOpcode: received from player not in map");
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1408,5 +1408,7 @@ void InitializeOpcodes()
|
|||
OPCODE(SMSG_PVP_OPTIONS_ENABLED, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
|
||||
OPCODE(CMSG_REQUEST_HOTFIX, STATUS_AUTHED, PROCESS_INPLACE, &WorldSession::HandleRequestHotfix );
|
||||
OPCODE(SMSG_DB_REPLY, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
|
||||
OPCODE(CMSG_OBJECT_UPDATE_FAILED, STATUS_LOGGEDIN, PROCESS_INPLACE, &WorldSession::HandleObjectUpdateFailedOpcode );
|
||||
//OPCODE(CMSG_OBJECT_UPDATE_FAILED, STATUS_LOGGEDIN, PROCESS_INPLACE, &WorldSession::HandleObjectUpdateFailedOpcode );
|
||||
OPCODE(CMSG_REFORGE_ITEM, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleReforgeItemOpcode );
|
||||
OPCODE(SMSG_REFORGE_RESULT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1426,7 +1426,9 @@ enum Opcodes
|
|||
SMSG_PVP_OPTIONS_ENABLED = 0x50A1, // 4.3.4 15595
|
||||
CMSG_REQUEST_HOTFIX = 0x2401, // 4.3.4 15595
|
||||
SMSG_DB_REPLY = 0x38A4, // 4.3.4 15595
|
||||
CMSG_OBJECT_UPDATE_FAILED = 0x3808, // 4.3.4 15595
|
||||
CMSG_OBJECT_UPDATE_FAILED = 0x3808, // 4.3.4 15595
|
||||
CMSG_REFORGE_ITEM = 0x331A, // 4.3.4 15595
|
||||
SMSG_REFORGE_RESULT = 0x58A4, // 4.3.4 15595
|
||||
};
|
||||
|
||||
#define MAX_OPCODE_TABLE_SIZE 0xFFFF
|
||||
|
|
|
|||
|
|
@ -12450,6 +12450,12 @@ void Player::ApplyEnchantment(Item* item, EnchantmentSlot slot, bool apply, bool
|
|||
if (slot >= MAX_ENCHANTMENT_SLOT)
|
||||
return;
|
||||
|
||||
if (slot == REFORGE_ENCHANTMENT_SLOT)
|
||||
{
|
||||
ApplyReforgeEnchantment(item, apply);
|
||||
return;
|
||||
}
|
||||
|
||||
uint32 enchant_id = item->GetEnchantmentId(slot);
|
||||
if (!enchant_id)
|
||||
return;
|
||||
|
|
@ -12741,6 +12747,240 @@ void Player::ApplyEnchantment(Item* item, EnchantmentSlot slot, bool apply, bool
|
|||
}
|
||||
}
|
||||
|
||||
void Player::ApplyReforgeEnchantment(Item* item, bool apply)
|
||||
{
|
||||
|
||||
if (!item)
|
||||
return;
|
||||
|
||||
ItemReforgeEntry const* reforge = sItemReforgeStore.LookupEntry(item->GetEnchantmentId(REFORGE_ENCHANTMENT_SLOT));
|
||||
if (!reforge)
|
||||
return;
|
||||
|
||||
float removeValue = item->GetReforgableStat(ItemModType(reforge->SourceStat)) * reforge->SourceMultiplier;
|
||||
|
||||
float addValue = removeValue * reforge->FinalMultiplier;
|
||||
|
||||
switch (reforge->SourceStat)
|
||||
{
|
||||
case ITEM_MOD_HEALTH:
|
||||
HandleStatModifier(UNIT_MOD_HEALTH, BASE_VALUE, -removeValue, apply);
|
||||
break;
|
||||
case ITEM_MOD_AGILITY:
|
||||
HandleStatModifier(UNIT_MOD_STAT_AGILITY, TOTAL_VALUE, -removeValue, apply);
|
||||
ApplyStatBuffMod(STAT_AGILITY, -removeValue, apply);
|
||||
break;
|
||||
case ITEM_MOD_STRENGTH:
|
||||
HandleStatModifier(UNIT_MOD_STAT_STRENGTH, TOTAL_VALUE, -removeValue, apply);
|
||||
ApplyStatBuffMod(STAT_STRENGTH, -removeValue, apply);
|
||||
break;
|
||||
case ITEM_MOD_INTELLECT:
|
||||
HandleStatModifier(UNIT_MOD_STAT_INTELLECT, TOTAL_VALUE, -removeValue, apply);
|
||||
ApplyStatBuffMod(STAT_INTELLECT, -removeValue, apply);
|
||||
break;
|
||||
case ITEM_MOD_SPIRIT:
|
||||
HandleStatModifier(UNIT_MOD_STAT_SPIRIT, TOTAL_VALUE, -removeValue, apply);
|
||||
ApplyStatBuffMod(STAT_SPIRIT, -removeValue, apply);
|
||||
break;
|
||||
case ITEM_MOD_STAMINA:
|
||||
HandleStatModifier(UNIT_MOD_STAT_STAMINA, TOTAL_VALUE, -removeValue, apply);
|
||||
ApplyStatBuffMod(STAT_STAMINA, -removeValue, apply);
|
||||
break;
|
||||
case ITEM_MOD_DEFENSE_SKILL_RATING:
|
||||
ApplyRatingMod(CR_DEFENSE_SKILL, -int32(removeValue), apply);
|
||||
break;
|
||||
case ITEM_MOD_DODGE_RATING:
|
||||
ApplyRatingMod(CR_DODGE, -int32(removeValue), apply);
|
||||
break;
|
||||
case ITEM_MOD_PARRY_RATING:
|
||||
ApplyRatingMod(CR_PARRY, -int32(removeValue), apply);
|
||||
break;
|
||||
case ITEM_MOD_BLOCK_RATING:
|
||||
ApplyRatingMod(CR_BLOCK, -int32(removeValue), apply);
|
||||
break;
|
||||
case ITEM_MOD_HIT_MELEE_RATING:
|
||||
ApplyRatingMod(CR_HIT_MELEE, -int32(removeValue), apply);
|
||||
break;
|
||||
case ITEM_MOD_HIT_RANGED_RATING:
|
||||
ApplyRatingMod(CR_HIT_RANGED, -int32(removeValue), apply);
|
||||
break;
|
||||
case ITEM_MOD_HIT_SPELL_RATING:
|
||||
ApplyRatingMod(CR_HIT_SPELL, -int32(removeValue), apply);
|
||||
break;
|
||||
case ITEM_MOD_CRIT_MELEE_RATING:
|
||||
ApplyRatingMod(CR_CRIT_MELEE, -int32(removeValue), apply);
|
||||
break;
|
||||
case ITEM_MOD_CRIT_RANGED_RATING:
|
||||
ApplyRatingMod(CR_CRIT_RANGED, -int32(removeValue), apply);
|
||||
break;
|
||||
case ITEM_MOD_CRIT_SPELL_RATING:
|
||||
ApplyRatingMod(CR_CRIT_SPELL, -int32(removeValue), apply);
|
||||
break;
|
||||
case ITEM_MOD_HASTE_SPELL_RATING:
|
||||
ApplyRatingMod(CR_HASTE_SPELL, -int32(removeValue), apply);
|
||||
break;
|
||||
case ITEM_MOD_HIT_RATING:
|
||||
ApplyRatingMod(CR_HIT_MELEE, -int32(removeValue), apply);
|
||||
ApplyRatingMod(CR_HIT_RANGED, -int32(removeValue), apply);
|
||||
ApplyRatingMod(CR_HIT_SPELL, -int32(removeValue), apply);
|
||||
break;
|
||||
case ITEM_MOD_CRIT_RATING:
|
||||
ApplyRatingMod(CR_CRIT_MELEE, -int32(removeValue), apply);
|
||||
ApplyRatingMod(CR_CRIT_RANGED, -int32(removeValue), apply);
|
||||
ApplyRatingMod(CR_CRIT_SPELL, -int32(removeValue), apply);
|
||||
break;
|
||||
case ITEM_MOD_RESILIENCE_RATING:
|
||||
ApplyRatingMod(CR_RESILIENCE_DAMAGE_TAKEN, -int32(removeValue), apply);
|
||||
break;
|
||||
case ITEM_MOD_HASTE_RATING:
|
||||
ApplyRatingMod(CR_HASTE_MELEE, -int32(removeValue), apply);
|
||||
ApplyRatingMod(CR_HASTE_RANGED, -int32(removeValue), apply);
|
||||
ApplyRatingMod(CR_HASTE_SPELL, -int32(removeValue), apply);
|
||||
break;
|
||||
case ITEM_MOD_EXPERTISE_RATING:
|
||||
ApplyRatingMod(CR_EXPERTISE, -int32(removeValue), apply);
|
||||
break;
|
||||
case ITEM_MOD_ATTACK_POWER:
|
||||
HandleStatModifier(UNIT_MOD_ATTACK_POWER, TOTAL_VALUE, -removeValue, apply);
|
||||
HandleStatModifier(UNIT_MOD_ATTACK_POWER_RANGED, TOTAL_VALUE, -removeValue, apply);
|
||||
break;
|
||||
case ITEM_MOD_RANGED_ATTACK_POWER:
|
||||
HandleStatModifier(UNIT_MOD_ATTACK_POWER_RANGED, TOTAL_VALUE, -removeValue, apply);
|
||||
break;
|
||||
case ITEM_MOD_MANA_REGENERATION:
|
||||
ApplyManaRegenBonus(-int32(removeValue), apply);
|
||||
break;
|
||||
case ITEM_MOD_ARMOR_PENETRATION_RATING:
|
||||
ApplyRatingMod(CR_ARMOR_PENETRATION, -int32(removeValue), apply);
|
||||
break;
|
||||
case ITEM_MOD_SPELL_POWER:
|
||||
ApplySpellPowerBonus(-int32(removeValue), apply);
|
||||
break;
|
||||
case ITEM_MOD_HEALTH_REGEN:
|
||||
ApplyHealthRegenBonus(-int32(removeValue), apply);
|
||||
break;
|
||||
case ITEM_MOD_SPELL_PENETRATION:
|
||||
ApplyModInt32Value(PLAYER_FIELD_MOD_TARGET_RESISTANCE, -int32(removeValue), apply);
|
||||
m_spellPenetrationItemMod += apply ? -int32(removeValue) : int32(removeValue);
|
||||
break;
|
||||
case ITEM_MOD_BLOCK_VALUE:
|
||||
break;
|
||||
case ITEM_MOD_MASTERY_RATING:
|
||||
ApplyRatingMod(CR_MASTERY, -int32(removeValue), apply);
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
switch (reforge->FinalStat)
|
||||
{
|
||||
case ITEM_MOD_HEALTH:
|
||||
HandleStatModifier(UNIT_MOD_HEALTH, BASE_VALUE, addValue, apply);
|
||||
break;
|
||||
case ITEM_MOD_AGILITY:
|
||||
HandleStatModifier(UNIT_MOD_STAT_AGILITY, TOTAL_VALUE, addValue, apply);
|
||||
ApplyStatBuffMod(STAT_AGILITY, addValue, apply);
|
||||
break;
|
||||
case ITEM_MOD_STRENGTH:
|
||||
HandleStatModifier(UNIT_MOD_STAT_STRENGTH, TOTAL_VALUE, addValue, apply);
|
||||
ApplyStatBuffMod(STAT_STRENGTH, addValue, apply);
|
||||
break;
|
||||
case ITEM_MOD_INTELLECT:
|
||||
HandleStatModifier(UNIT_MOD_STAT_INTELLECT, TOTAL_VALUE, addValue, apply);
|
||||
ApplyStatBuffMod(STAT_INTELLECT, addValue, apply);
|
||||
break;
|
||||
case ITEM_MOD_SPIRIT:
|
||||
HandleStatModifier(UNIT_MOD_STAT_SPIRIT, TOTAL_VALUE, addValue, apply);
|
||||
ApplyStatBuffMod(STAT_SPIRIT, addValue, apply);
|
||||
break;
|
||||
case ITEM_MOD_STAMINA:
|
||||
HandleStatModifier(UNIT_MOD_STAT_STAMINA, TOTAL_VALUE, addValue, apply);
|
||||
ApplyStatBuffMod(STAT_STAMINA, addValue, apply);
|
||||
break;
|
||||
case ITEM_MOD_DEFENSE_SKILL_RATING:
|
||||
ApplyRatingMod(CR_DEFENSE_SKILL, int32(addValue), apply);
|
||||
break;
|
||||
case ITEM_MOD_DODGE_RATING:
|
||||
ApplyRatingMod(CR_DODGE, int32(addValue), apply);
|
||||
break;
|
||||
case ITEM_MOD_PARRY_RATING:
|
||||
ApplyRatingMod(CR_PARRY, int32(addValue), apply);
|
||||
break;
|
||||
case ITEM_MOD_BLOCK_RATING:
|
||||
ApplyRatingMod(CR_BLOCK, int32(addValue), apply);
|
||||
break;
|
||||
case ITEM_MOD_HIT_MELEE_RATING:
|
||||
ApplyRatingMod(CR_HIT_MELEE, int32(addValue), apply);
|
||||
break;
|
||||
case ITEM_MOD_HIT_RANGED_RATING:
|
||||
ApplyRatingMod(CR_HIT_RANGED, int32(addValue), apply);
|
||||
break;
|
||||
case ITEM_MOD_HIT_SPELL_RATING:
|
||||
ApplyRatingMod(CR_HIT_SPELL, int32(addValue), apply);
|
||||
break;
|
||||
case ITEM_MOD_CRIT_MELEE_RATING:
|
||||
ApplyRatingMod(CR_CRIT_MELEE, int32(addValue), apply);
|
||||
break;
|
||||
case ITEM_MOD_CRIT_RANGED_RATING:
|
||||
ApplyRatingMod(CR_CRIT_RANGED, int32(addValue), apply);
|
||||
break;
|
||||
case ITEM_MOD_CRIT_SPELL_RATING:
|
||||
ApplyRatingMod(CR_CRIT_SPELL, int32(addValue), apply);
|
||||
break;
|
||||
case ITEM_MOD_HASTE_SPELL_RATING:
|
||||
ApplyRatingMod(CR_HASTE_SPELL, int32(addValue), apply);
|
||||
break;
|
||||
case ITEM_MOD_HIT_RATING:
|
||||
ApplyRatingMod(CR_HIT_MELEE, int32(addValue), apply);
|
||||
ApplyRatingMod(CR_HIT_RANGED, int32(addValue), apply);
|
||||
ApplyRatingMod(CR_HIT_SPELL, int32(addValue), apply);
|
||||
break;
|
||||
case ITEM_MOD_CRIT_RATING:
|
||||
ApplyRatingMod(CR_CRIT_MELEE, int32(addValue), apply);
|
||||
ApplyRatingMod(CR_CRIT_RANGED, int32(addValue), apply);
|
||||
ApplyRatingMod(CR_CRIT_SPELL, int32(addValue), apply);
|
||||
break;
|
||||
case ITEM_MOD_RESILIENCE_RATING:
|
||||
ApplyRatingMod(CR_RESILIENCE_DAMAGE_TAKEN, int32(addValue), apply);
|
||||
break;
|
||||
case ITEM_MOD_HASTE_RATING:
|
||||
ApplyRatingMod(CR_HASTE_MELEE, int32(addValue), apply);
|
||||
ApplyRatingMod(CR_HASTE_RANGED, int32(addValue), apply);
|
||||
ApplyRatingMod(CR_HASTE_SPELL, int32(addValue), apply);
|
||||
break;
|
||||
case ITEM_MOD_EXPERTISE_RATING:
|
||||
ApplyRatingMod(CR_EXPERTISE, int32(addValue), apply);
|
||||
break;
|
||||
case ITEM_MOD_ATTACK_POWER:
|
||||
HandleStatModifier(UNIT_MOD_ATTACK_POWER, TOTAL_VALUE, addValue, apply);
|
||||
HandleStatModifier(UNIT_MOD_ATTACK_POWER_RANGED, TOTAL_VALUE, addValue, apply);
|
||||
break;
|
||||
case ITEM_MOD_RANGED_ATTACK_POWER:
|
||||
HandleStatModifier(UNIT_MOD_ATTACK_POWER_RANGED, TOTAL_VALUE, addValue, apply);
|
||||
break;
|
||||
case ITEM_MOD_MANA_REGENERATION:
|
||||
ApplyManaRegenBonus(int32(addValue), apply);
|
||||
break;
|
||||
case ITEM_MOD_ARMOR_PENETRATION_RATING:
|
||||
ApplyRatingMod(CR_ARMOR_PENETRATION, int32(addValue), apply);
|
||||
break;
|
||||
case ITEM_MOD_SPELL_POWER:
|
||||
ApplySpellPowerBonus(int32(addValue), apply);
|
||||
break;
|
||||
case ITEM_MOD_HEALTH_REGEN:
|
||||
ApplyHealthRegenBonus(int32(addValue), apply);
|
||||
break;
|
||||
case ITEM_MOD_SPELL_PENETRATION:
|
||||
ApplyModInt32Value(PLAYER_FIELD_MOD_TARGET_RESISTANCE, int32(addValue), apply);
|
||||
m_spellPenetrationItemMod += apply ? int32(addValue) : -int32(addValue);
|
||||
break;
|
||||
case ITEM_MOD_BLOCK_VALUE:
|
||||
break;
|
||||
case ITEM_MOD_MASTERY_RATING:
|
||||
ApplyRatingMod(CR_MASTERY, int32(addValue), apply);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void Player::SendEnchantmentDurations()
|
||||
{
|
||||
for (EnchantDurationList::const_iterator itr = m_enchantDuration.begin(); itr != m_enchantDuration.end(); ++itr)
|
||||
|
|
|
|||
|
|
@ -1290,6 +1290,7 @@ class MANGOS_DLL_SPEC Player : public Unit
|
|||
void AddEnchantmentDuration(Item* item, EnchantmentSlot slot, uint32 duration);
|
||||
void ApplyEnchantment(Item* item, EnchantmentSlot slot, bool apply, bool apply_dur = true, bool ignore_condition = false);
|
||||
void ApplyEnchantment(Item* item, bool apply);
|
||||
void ApplyReforgeEnchantment(Item* item, bool apply);
|
||||
void SendEnchantmentDurations();
|
||||
void BuildEnchantmentsInfoData(WorldPacket* data);
|
||||
void AddItemDurations(Item* item);
|
||||
|
|
|
|||
|
|
@ -145,7 +145,7 @@ void WorldSession::SendUpdateTrade(bool trader_state /*= true*/)
|
|||
data << uint32(item->GetEnchantmentId(EnchantmentSlot(enchant_slot)));
|
||||
data << uint32(item->GetUInt32Value(ITEM_FIELD_MAXDURABILITY));
|
||||
data.WriteGuidBytes<6, 2, 7, 4>(creatorGuid);
|
||||
data << uint32(0); // reforge Id
|
||||
data << uint32(item->GetEnchantmentId(REFORGE_ENCHANTMENT_SLOT)); // reforge Id
|
||||
data << uint32(item->GetUInt32Value(ITEM_FIELD_DURABILITY));
|
||||
data << uint32(item->GetItemRandomPropertyId());
|
||||
data.WriteGuidBytes<3>(creatorGuid);
|
||||
|
|
|
|||
|
|
@ -653,6 +653,7 @@ enum NPCFlags
|
|||
UNIT_NPC_FLAG_GUILD_BANKER = 0x00800000, // cause client to send 997 opcode
|
||||
UNIT_NPC_FLAG_SPELLCLICK = 0x01000000, // cause client to send 1015 opcode (spell click), dynamic, set at loading and don't must be set in DB
|
||||
UNIT_NPC_FLAG_PLAYER_VEHICLE = 0x02000000, // players with mounts that have vehicle data should have it set
|
||||
UNIT_NPC_FLAG_REFORGER = 0x08000000, // reforging
|
||||
};
|
||||
|
||||
// used in most movement packets (send and received), 30 bits in client
|
||||
|
|
|
|||
|
|
@ -888,6 +888,11 @@ class MANGOS_DLL_SPEC WorldSession
|
|||
void HandleQueryQuestsCompletedOpcode(WorldPacket& recv_data);
|
||||
void HandleQuestPOIQueryOpcode(WorldPacket& recv_data);
|
||||
void HandleSetCurrencyFlagsOpcode(WorldPacket& recv_data);
|
||||
|
||||
// Reforge
|
||||
void HandleReforgeItemOpcode(WorldPacket& recvData);
|
||||
void SendReforgeResult(bool success);
|
||||
|
||||
private:
|
||||
// private trade methods
|
||||
void moveItems(Item* myItems[], Item* hisItems[]);
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
#ifndef __REVISION_NR_H__
|
||||
#define __REVISION_NR_H__
|
||||
#define REVISION_NR "12735"
|
||||
#define REVISION_NR "12736"
|
||||
#endif // __REVISION_NR_H__
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue