aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xsrc/server/game/DataStores/DBCStructure.h4
-rwxr-xr-xsrc/server/game/Entities/Item/Item.cpp65
-rwxr-xr-xsrc/server/game/Entities/Item/Item.h2
-rwxr-xr-xsrc/server/game/Entities/Player/Player.cpp274
-rwxr-xr-xsrc/server/game/Entities/Player/Player.h1
-rwxr-xr-xsrc/server/game/Handlers/ItemHandler.cpp18
-rw-r--r--src/server/scripts/Spells/spell_rogue.cpp3
7 files changed, 355 insertions, 12 deletions
diff --git a/src/server/game/DataStores/DBCStructure.h b/src/server/game/DataStores/DBCStructure.h
index 6cb013bec50..5e841a2f78b 100755
--- a/src/server/game/DataStores/DBCStructure.h
+++ b/src/server/game/DataStores/DBCStructure.h
@@ -1204,10 +1204,10 @@ struct ItemPriceBaseEntry
struct ItemReforgeEntry
{
uint32 Id;
- uint32 FinalStat;
- float FinalMultiplier;
uint32 SourceStat;
float SourceMultiplier;
+ uint32 FinalStat;
+ float FinalMultiplier;
};
// common struct for:
diff --git a/src/server/game/Entities/Item/Item.cpp b/src/server/game/Entities/Item/Item.cpp
index f0cd629b5e3..3dae2aa581c 100755
--- a/src/server/game/Entities/Item/Item.cpp
+++ b/src/server/game/Entities/Item/Item.cpp
@@ -644,8 +644,8 @@ void Item::SetItemRandomProperties(int32 randomPropId)
SetInt32Value(ITEM_FIELD_RANDOM_PROPERTIES_ID, item_rand->ID);
SetState(ITEM_CHANGED, GetOwner());
}
- 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_1 + 3; ++i)
+ SetEnchantment(EnchantmentSlot(i), item_rand->enchant_id[i - PROP_ENCHANTMENT_SLOT_1], 0, 0);
}
}
else
@@ -661,7 +661,7 @@ void Item::SetItemRandomProperties(int32 randomPropId)
SetState(ITEM_CHANGED, GetOwner());
}
- 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);
}
}
@@ -781,10 +781,15 @@ bool Item::HasEnchantRequiredSkill(const Player* player) const
{
// Check all enchants for required skill
for (uint32 enchant_slot = PERM_ENCHANTMENT_SLOT; enchant_slot < MAX_ENCHANTMENT_SLOT; ++enchant_slot)
+ {
+ if (enchant_slot > PRISMATIC_ENCHANTMENT_SLOT || enchant_slot < PROP_ENCHANTMENT_SLOT_0) // not holding enchantment id
+ continue;
+
if (uint32 enchant_id = GetEnchantmentId(EnchantmentSlot(enchant_slot)))
if (SpellItemEnchantmentEntry const* enchantEntry = sSpellItemEnchantmentStore.LookupEntry(enchant_id))
if (enchantEntry->requiredSkill && player->GetSkillValue(enchantEntry->requiredSkill) < enchantEntry->requiredSkillValue)
return false;
+ }
return true;
}
@@ -795,10 +800,15 @@ uint32 Item::GetEnchantRequiredLevel() const
// Check all enchants for required level
for (uint32 enchant_slot = PERM_ENCHANTMENT_SLOT; enchant_slot < MAX_ENCHANTMENT_SLOT; ++enchant_slot)
+ {
+ if (enchant_slot > PRISMATIC_ENCHANTMENT_SLOT || enchant_slot < PROP_ENCHANTMENT_SLOT_0) // not holding enchantment id
+ continue;
+
if (uint32 enchant_id = GetEnchantmentId(EnchantmentSlot(enchant_slot)))
if (SpellItemEnchantmentEntry const* enchantEntry = sSpellItemEnchantmentStore.LookupEntry(enchant_id))
if (enchantEntry->requiredLevel > level)
level = enchantEntry->requiredLevel;
+ }
return level;
}
@@ -807,10 +817,16 @@ bool Item::IsBoundByEnchant() const
{
// Check all enchants for soulbound
for (uint32 enchant_slot = PERM_ENCHANTMENT_SLOT; enchant_slot < MAX_ENCHANTMENT_SLOT; ++enchant_slot)
+ {
+ if (enchant_slot > PRISMATIC_ENCHANTMENT_SLOT || enchant_slot < PROP_ENCHANTMENT_SLOT_0) // not holding enchantment id
+ continue;
+
if (uint32 enchant_id = GetEnchantmentId(EnchantmentSlot(enchant_slot)))
if (SpellItemEnchantmentEntry const* enchantEntry = sSpellItemEnchantmentStore.LookupEntry(enchant_id))
if (enchantEntry->slot & ENCHANTMENT_CAN_SOULBOUND)
return true;
+ }
+
return false;
}
@@ -1458,3 +1474,46 @@ uint32 Item::GetSpecialPrice(uint32 minimumPrice) const
return cost;
}
+
+int32 Item::GetReforgableStat(ItemModType statType) const
+{
+ ItemTemplate const* proto = GetTemplate();
+ 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 < MAX_ITEM_ENCHANTMENT_EFFECTS; ++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 < MAX_ITEM_ENCHANTMENT_EFFECTS; ++f)
+ if (enchant->type[f] == ITEM_ENCHANTMENT_TYPE_STAT && enchant->spellid[f] == statType)
+ for (int k = 0; k < MAX_ITEM_ENCHANTMENT_EFFECTS; ++k)
+ if (randomProp->enchant_id[k] == enchant->ID)
+ return int32(enchant->amount[k]);
+ }
+
+ return 0;
+}
diff --git a/src/server/game/Entities/Item/Item.h b/src/server/game/Entities/Item/Item.h
index e8bf234c591..5b86d55f170 100755
--- a/src/server/game/Entities/Item/Item.h
+++ b/src/server/game/Entities/Item/Item.h
@@ -361,6 +361,8 @@ class Item : public Object
uint32 GetSellPrice(bool& success) const;
+ int32 GetReforgableStat(ItemModType statType) const;
+
private:
std::string m_text;
uint8 m_slot;
diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp
index 3f40b0b5346..412e136d8d2 100755
--- a/src/server/game/Entities/Player/Player.cpp
+++ b/src/server/game/Entities/Player/Player.cpp
@@ -8423,6 +8423,9 @@ void Player::CastItemCombatSpell(Unit* target, WeaponAttackType attType, uint32
// item combat enchantments
for (uint8 e_slot = 0; e_slot < MAX_ENCHANTMENT_SLOT; ++e_slot)
{
+ if (e_slot > PRISMATIC_ENCHANTMENT_SLOT || e_slot < PROP_ENCHANTMENT_SLOT_0) // not holding enchantment id
+ continue;
+
uint32 enchant_id = item->GetEnchantmentId(EnchantmentSlot(e_slot));
SpellItemEnchantmentEntry const* pEnchant = sSpellItemEnchantmentStore.LookupEntry(enchant_id);
if (!pEnchant)
@@ -8545,6 +8548,9 @@ void Player::CastItemUseSpell(Item* item, SpellCastTargets const& targets, uint8
// Item enchantments spells casted at use
for (uint8 e_slot = 0; e_slot < MAX_ENCHANTMENT_SLOT; ++e_slot)
{
+ if (e_slot > PRISMATIC_ENCHANTMENT_SLOT || e_slot < PROP_ENCHANTMENT_SLOT_0) // not holding enchantment id
+ continue;
+
uint32 enchant_id = item->GetEnchantmentId(EnchantmentSlot(e_slot));
SpellItemEnchantmentEntry const* pEnchant = sSpellItemEnchantmentStore.LookupEntry(enchant_id);
if (!pEnchant)
@@ -13240,6 +13246,9 @@ void Player::AddEnchantmentDurations(Item* item)
{
for (int x = 0; x < MAX_ENCHANTMENT_SLOT; ++x)
{
+ if (x > PRISMATIC_ENCHANTMENT_SLOT || x < PROP_ENCHANTMENT_SLOT_0) // not holding enchantment id
+ continue;
+
if (!item->GetEnchantmentId(EnchantmentSlot(x)))
continue;
@@ -13334,10 +13343,257 @@ void Player::AddEnchantmentDuration(Item* item, EnchantmentSlot slot, uint32 dur
}
}
+void Player::ApplyReforgeEnchantment(Item* item, bool apply)
+{
+ if (!item)
+ return;
+
+ ItemReforgeEntry const* reforge = sItemReforgeStore.LookupEntry(item->GetEnchantmentId(REFORGE_ENCHANTMENT_SLOT));
+ if (!reforge)
+ return;
+
+ ItemTemplate const* proto = item->GetTemplate();
+
+ float removeValue = item->GetReforgableStat(ItemModType(reforge->SourceStat)) * reforge->SourceMultiplier;
+ float addValue = removeValue * reforge->FinalMultiplier;
+
+ switch (reforge->SourceStat)
+ {
+ case ITEM_MOD_MANA:
+ HandleStatModifier(UNIT_MOD_MANA, BASE_VALUE, -removeValue, apply);
+ break;
+ 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_CRIT_TAKEN_MELEE, -int32(removeValue), apply);
+ ApplyRatingMod(CR_CRIT_TAKEN_RANGED, -int32(removeValue), apply);
+ ApplyRatingMod(CR_CRIT_TAKEN_SPELL, -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:
+ HandleBaseModValue(SHIELD_BLOCK_VALUE, FLAT_MOD, -removeValue, apply);
+ break;
+ }
+
+ switch (reforge->FinalStat)
+ {
+ case ITEM_MOD_MANA:
+ HandleStatModifier(UNIT_MOD_MANA, BASE_VALUE, addValue, apply);
+ break;
+ 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_CRIT_TAKEN_MELEE, int32(addValue), apply);
+ ApplyRatingMod(CR_CRIT_TAKEN_RANGED, int32(addValue), apply);
+ ApplyRatingMod(CR_CRIT_TAKEN_SPELL, 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:
+ HandleBaseModValue(SHIELD_BLOCK_VALUE, FLAT_MOD, addValue, apply);
+ break;
+ }
+}
+
void Player::ApplyEnchantment(Item* item, bool apply)
{
for (uint32 slot = 0; slot < MAX_ENCHANTMENT_SLOT; ++slot)
+ {
+ // Apply reforge as last enchant
+ if (slot == REFORGE_ENCHANTMENT_SLOT)
+ continue;
+
ApplyEnchantment(item, EnchantmentSlot(slot), apply);
+ }
+
+ ApplyEnchantment(item, REFORGE_ENCHANTMENT_SLOT, apply);
}
void Player::ApplyEnchantment(Item* item, EnchantmentSlot slot, bool apply, bool apply_dur, bool ignore_condition)
@@ -13348,6 +13604,15 @@ void Player::ApplyEnchantment(Item* item, EnchantmentSlot slot, bool apply, bool
if (slot >= MAX_ENCHANTMENT_SLOT)
return;
+ if (slot == TRANSMOGRIFY_ENCHANTMENT_SLOT)
+ return;
+
+ if (slot == REFORGE_ENCHANTMENT_SLOT)
+ {
+ ApplyReforgeEnchantment(item, apply);
+ return;
+ }
+
uint32 enchant_id = item->GetEnchantmentId(slot);
if (!enchant_id)
return;
@@ -13411,13 +13676,13 @@ void Player::ApplyEnchantment(Item* item, EnchantmentSlot slot, bool apply, bool
{
int32 basepoints = 0;
// Random Property Exist - try found basepoints for spell (basepoints depends from item suffix factor)
- if (item->GetItemRandomPropertyId())
+ if (item->GetItemRandomPropertyId() < 0)
{
ItemRandomSuffixEntry const* item_rand = sItemRandomSuffixStore.LookupEntry(abs(item->GetItemRandomPropertyId()));
if (item_rand)
{
// Search enchant_amount
- for (int k = 0; k < MAX_ITEM_ENCHANTMENT_EFFECTS; ++k)
+ for (int k = 0; k < 5; ++k)
{
if (item_rand->enchant_id[k] == enchant_id)
{
@@ -13463,7 +13728,7 @@ void Player::ApplyEnchantment(Item* item, EnchantmentSlot slot, bool apply, bool
ItemRandomSuffixEntry const* item_rand_suffix = sItemRandomSuffixStore.LookupEntry(abs(item->GetItemRandomPropertyId()));
if (item_rand_suffix)
{
- for (int k = 0; k < MAX_ITEM_ENCHANTMENT_EFFECTS; ++k)
+ for (int k = 0; k < 5; ++k)
{
if (item_rand_suffix->enchant_id[k] == enchant_id)
{
@@ -13720,6 +13985,9 @@ void Player::UpdateSkillEnchantments(uint16 skill_id, uint16 curr_value, uint16
{
for (uint8 slot = 0; slot < MAX_ENCHANTMENT_SLOT; ++slot)
{
+ if (slot > PRISMATIC_ENCHANTMENT_SLOT || slot < PROP_ENCHANTMENT_SLOT_0) // not holding enchantment id
+ continue;
+
uint32 ench_id = m_items[i]->GetEnchantmentId(EnchantmentSlot(slot));
if (!ench_id)
continue;
diff --git a/src/server/game/Entities/Player/Player.h b/src/server/game/Entities/Player/Player.h
index e8dde100473..e192c88b2c2 100755
--- a/src/server/game/Entities/Player/Player.h
+++ b/src/server/game/Entities/Player/Player.h
@@ -1393,6 +1393,7 @@ class Player : public Unit, public GridObject<Player>
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 UpdateSkillEnchantments(uint16 skill_id, uint16 curr_value, uint16 new_value);
void SendEnchantmentDurations();
void BuildEnchantmentsInfoData(WorldPacket* data);
diff --git a/src/server/game/Handlers/ItemHandler.cpp b/src/server/game/Handlers/ItemHandler.cpp
index 31720266ff0..6a8cc5b1c5f 100755
--- a/src/server/game/Handlers/ItemHandler.cpp
+++ b/src/server/game/Handlers/ItemHandler.cpp
@@ -688,7 +688,7 @@ void WorldSession::HandleBuyItemOpcode(WorldPacket& recvData)
uint32 item, slot, count;
uint8 itemType; // 1 = item, 2 = currency (not implemented)
uint8 bagSlot;
-
+
recvData >> vendorguid >> itemType >> item >> slot >> count >> bagGuid >> bagSlot;
// client expects count starting at 1, and we send vendorslot+1 to client already
@@ -1216,7 +1216,7 @@ void WorldSession::HandleSocketOpcode(WorldPacket& recvData)
// tried to put meta gem in normal socket
if (itemProto->Socket[i].Color != SOCKET_COLOR_META && GemProps[i]->color == SOCKET_COLOR_META)
return;
-
+
// tried to put normal gem in cogwheel socket
if (itemProto->Socket[i].Color == SOCKET_COLOR_COGWHEEL && GemProps[i]->color != SOCKET_COLOR_COGWHEEL)
return;
@@ -1667,18 +1667,27 @@ void WorldSession::HandleReforgeItemOpcode(WorldPacket& recvData)
if (!reforgeEntry)
{
// Reset the item
+ if (item->IsEquipped())
+ player->ApplyReforgeEnchantment(item, false);
item->ClearEnchantment(REFORGE_ENCHANTMENT_SLOT);
SendReforgeResult(true);
return;
}
- if (!sItemReforgeStore.LookupEntry(reforgeEntry))
+ ItemReforgeEntry const* stats = sItemReforgeStore.LookupEntry(reforgeEntry);
+ if (!stats)
{
sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: HandleReforgeItemOpcode - Player (Guid: %u Name: %s) tried to reforge an item with invalid reforge entry (%u).", player->GetGUIDLow(), player->GetName(), 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->HasEnoughMoney(uint64(item->GetSpecialPrice()))) // cheating
{
SendReforgeResult(false);
@@ -1691,5 +1700,6 @@ void WorldSession::HandleReforgeItemOpcode(WorldPacket& recvData)
SendReforgeResult(true);
- // ToDo: Apply and remove the destination/source stats to the player
+ if (item->IsEquipped())
+ player->ApplyReforgeEnchantment(item, true);
}
diff --git a/src/server/scripts/Spells/spell_rogue.cpp b/src/server/scripts/Spells/spell_rogue.cpp
index 3a4132f62fe..0fc30420d35 100644
--- a/src/server/scripts/Spells/spell_rogue.cpp
+++ b/src/server/scripts/Spells/spell_rogue.cpp
@@ -338,6 +338,9 @@ class spell_rog_deadly_poison : public SpellScriptLoader
// item combat enchantments
for (uint8 slot = 0; slot < MAX_ENCHANTMENT_SLOT; ++slot)
{
+ if (slot > PRISMATIC_ENCHANTMENT_SLOT || slot < PROP_ENCHANTMENT_SLOT_0) // not holding enchantment id
+ continue;
+
SpellItemEnchantmentEntry const* enchant = sSpellItemEnchantmentStore.LookupEntry(item->GetEnchantmentId(EnchantmentSlot(slot)));
if (!enchant)
continue;