[12736] Implemented reforge, also added missing part for HandleObjectUpdateFailedOpcode

This commit is contained in:
sanctum32 2013-11-18 19:04:50 +02:00 committed by Antz
parent 22e906cea5
commit 3490f642cf
17 changed files with 464 additions and 14 deletions

View file

@ -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");

View file

@ -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;

View file

@ -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

View file

@ -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";

View file

@ -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;
}

View file

@ -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;

View file

@ -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);
}

View file

@ -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

View file

@ -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");
}

View file

@ -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 );
};

View file

@ -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

View file

@ -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)

View file

@ -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);

View file

@ -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);

View file

@ -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

View file

@ -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[]);

View file

@ -1,4 +1,4 @@
#ifndef __REVISION_NR_H__
#define __REVISION_NR_H__
#define REVISION_NR "12735"
#define REVISION_NR "12736"
#endif // __REVISION_NR_H__