aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/game/Item.cpp7
-rw-r--r--src/game/Item.h2
-rw-r--r--src/game/ItemPrototype.h3
-rw-r--r--src/game/Spell.cpp28
-rw-r--r--src/game/SpellEffects.cpp68
-rw-r--r--src/game/SpellMgr.cpp12
-rw-r--r--src/game/SpellMgr.h2
7 files changed, 96 insertions, 26 deletions
diff --git a/src/game/Item.cpp b/src/game/Item.cpp
index c44bca06246..02a9b37d994 100644
--- a/src/game/Item.cpp
+++ b/src/game/Item.cpp
@@ -24,6 +24,7 @@
#include "WorldPacket.h"
#include "Database/DatabaseEnv.h"
#include "ItemEnchantmentMgr.h"
+#include "SpellMgr.h"
void AddItemsSetItem(Player*player,Item *item)
{
@@ -744,6 +745,12 @@ bool Item::IsFitToSpellRequirements(SpellEntry const* spellInfo) const
if (spellInfo->EquippedItemClass != -1) // -1 == any item class
{
+ // Special case - accept vellum for armor/weapon requirements
+ if( (spellInfo->EquippedItemClass==ITEM_CLASS_ARMOR && proto->IsArmorVellum())
+ ||( spellInfo->EquippedItemClass==ITEM_CLASS_WEAPON && proto->IsWeaponVellum()))
+ if (spellmgr.IsSkillTypeSpell(spellInfo->Id, SKILL_ENCHANTING)) // only for enchanting spells
+ return true;
+
if(spellInfo->EquippedItemClass != int32(proto->Class))
return false; // wrong item class
diff --git a/src/game/Item.h b/src/game/Item.h
index 824375cea8d..9237c6715f2 100644
--- a/src/game/Item.h
+++ b/src/game/Item.h
@@ -290,6 +290,8 @@ class TRINITY_DLL_SPEC Item : public Object
bool hasQuest(uint32 quest_id) const { return GetProto()->StartQuest == quest_id; }
bool hasInvolvedQuest(uint32 /*quest_id*/) const { return false; }
bool IsPotion() const { return GetProto()->IsPotion(); }
+ bool IsWeaponVellum() const { return GetProto()->IsWeaponVellum(); }
+ bool IsArmorVellum() const { return GetProto()->IsArmorVellum(); }
bool IsConjuredConsumable() const { return GetProto()->IsConjuredConsumable(); }
private:
uint8 m_slot;
diff --git a/src/game/ItemPrototype.h b/src/game/ItemPrototype.h
index 3967b37622b..a4210521bc7 100644
--- a/src/game/ItemPrototype.h
+++ b/src/game/ItemPrototype.h
@@ -117,6 +117,7 @@ enum ITEM_FLAGS
ITEM_FLAGS_THROWABLE = 0x00400000, // not used in game for check trow possibility, only for item in game tooltip
ITEM_FLAGS_SPECIALUSE = 0x00800000, // last used flag in 2.3.0
ITEM_FLAGS_BOA = 0x08000000, // bind on account
+ ITEM_FLAGS_NO_REAGENT_CAST = 0x10000000, // used by enchanting scrolls made with vellum
ITEM_FLAGS_MILLABLE = 0x20000000
};
@@ -661,6 +662,8 @@ struct ItemPrototype
}
bool IsPotion() const { return Class==ITEM_CLASS_CONSUMABLE && SubClass==ITEM_SUBCLASS_POTION; }
+ 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_ARMOR_ENCHANTMENT; }
bool IsConjuredConsumable() const { return Class == ITEM_CLASS_CONSUMABLE && (Flags & ITEM_FLAGS_CONJURED); }
};
diff --git a/src/game/Spell.cpp b/src/game/Spell.cpp
index 9590322617f..d0e6b0f8ede 100644
--- a/src/game/Spell.cpp
+++ b/src/game/Spell.cpp
@@ -590,8 +590,11 @@ void Spell::FillTargetMap()
if(Guardian* pet = m_caster->GetGuardianPet())
tmpUnitMap.push_back(pet);
break;
- /*case SPELL_EFFECT_ENCHANT_ITEM:
- case SPELL_EFFECT_ENCHANT_ITEM_TEMPORARY:
+ case SPELL_EFFECT_ENCHANT_ITEM:
+ // add caster as unit target-needed by vellums to define who gets item
+ AddUnitTarget(m_caster, i);
+ break;
+ /*case SPELL_EFFECT_ENCHANT_ITEM_TEMPORARY:
case SPELL_EFFECT_ENCHANT_ITEM_PRISMATIC:
case SPELL_EFFECT_DISENCHANT:
case SPELL_EFFECT_PROSPECTING:
@@ -3505,6 +3508,10 @@ void Spell::TakeReagents()
if(m_IsTriggeredSpell) // reagents used in triggered spell removed by original spell or don't must be removed.
return;
+ if (m_CastItem)
+ if (m_CastItem->GetProto()->Flags & ITEM_FLAGS_NO_REAGENT_CAST)
+ return;
+
if (m_caster->GetTypeId() != TYPEID_PLAYER)
return;
@@ -5004,6 +5011,23 @@ SpellCastResult Spell::CheckItems()
break;
}
case SPELL_EFFECT_ENCHANT_ITEM:
+ if(m_spellInfo->EffectItemType[i] && m_targets.getItemTarget()
+ && (m_targets.getItemTarget()->IsWeaponVellum() || m_targets.getItemTarget()->IsArmorVellum()))
+ {
+ // cannot enchant vellum for other player
+ if (m_targets.getItemTarget()->GetOwner()!=m_caster)
+ return SPELL_FAILED_NOT_TRADEABLE;
+ // do not allow to enchant vellum from scroll made by vellum-prevent exploit
+ if (m_CastItem && m_CastItem->GetProto()->Flags & ITEM_FLAGS_NO_REAGENT_CAST)
+ return SPELL_FAILED_TOTEM_CATEGORY;
+ ItemPosCountVec dest;
+ uint8 msg = p_caster->CanStoreNewItem(NULL_BAG, NULL_SLOT, dest, m_spellInfo->EffectItemType[i], 1 );
+ if (msg != EQUIP_ERR_OK )
+ {
+ p_caster->SendEquipError( msg, NULL, NULL );
+ return SPELL_FAILED_DONT_REPORT;
+ }
+ }
case SPELL_EFFECT_ENCHANT_ITEM_PRISMATIC:
{
Item* targetItem = m_targets.getItemTarget();
diff --git a/src/game/SpellEffects.cpp b/src/game/SpellEffects.cpp
index a1ae00b17c8..b1510f9039f 100644
--- a/src/game/SpellEffects.cpp
+++ b/src/game/SpellEffects.cpp
@@ -3685,37 +3685,57 @@ void Spell::EffectEnchantItemPerm(uint32 effect_idx)
Player* p_caster = (Player*)m_caster;
- // not grow at item use at item case
- p_caster->UpdateCraftSkill(m_spellInfo->Id);
+ // Handle vellums
+ if (itemTarget->IsWeaponVellum() || itemTarget->IsArmorVellum())
+ {
+ // item can be in trade slot and have owner diff. from caster
+ Player* item_owner = itemTarget->GetOwner();
+ if(!item_owner)
+ return;
- uint32 enchant_id = m_spellInfo->EffectMiscValue[effect_idx];
- if (!enchant_id)
- return;
+ // destroy one vellum from stack
+ uint32 count=1;
+ item_owner->DestroyItemCount(itemTarget,count,true);
+ unitTarget=item_owner;
+ // and add a scroll
+ DoCreateItem(effect_idx,m_spellInfo->EffectItemType[effect_idx]);
+ itemTarget=NULL;
+ m_targets.setItemTarget(NULL);
+ }
+ else
+ {
+ // not grow at item use at item case
+ p_caster->UpdateCraftSkill(m_spellInfo->Id);
- SpellItemEnchantmentEntry const *pEnchant = sSpellItemEnchantmentStore.LookupEntry(enchant_id);
- if(!pEnchant)
- return;
+ uint32 enchant_id = m_spellInfo->EffectMiscValue[effect_idx];
+ if (!enchant_id)
+ return;
- // item can be in trade slot and have owner diff. from caster
- Player* item_owner = itemTarget->GetOwner();
- if(!item_owner)
- return;
+ SpellItemEnchantmentEntry const *pEnchant = sSpellItemEnchantmentStore.LookupEntry(enchant_id);
+ if(!pEnchant)
+ return;
- if(item_owner!=p_caster && p_caster->GetSession()->GetSecurity() > SEC_PLAYER && sWorld.getConfig(CONFIG_GM_LOG_TRADE) )
- {
- sLog.outCommand(p_caster->GetSession()->GetAccountId(),"GM %s (Account: %u) enchanting(perm): %s (Entry: %d) for player: %s (Account: %u)",
- p_caster->GetName(),p_caster->GetSession()->GetAccountId(),
- itemTarget->GetProto()->Name1,itemTarget->GetEntry(),
- item_owner->GetName(),item_owner->GetSession()->GetAccountId());
- }
+ // item can be in trade slot and have owner diff. from caster
+ Player* item_owner = itemTarget->GetOwner();
+ if(!item_owner)
+ return;
- // remove old enchanting before applying new if equipped
- item_owner->ApplyEnchantment(itemTarget,PERM_ENCHANTMENT_SLOT,false);
+ if(item_owner!=p_caster && p_caster->GetSession()->GetSecurity() > SEC_PLAYER && sWorld.getConfig(CONFIG_GM_LOG_TRADE) )
+ {
+ sLog.outCommand(p_caster->GetSession()->GetAccountId(),"GM %s (Account: %u) enchanting(perm): %s (Entry: %d) for player: %s (Account: %u)",
+ p_caster->GetName(),p_caster->GetSession()->GetAccountId(),
+ itemTarget->GetProto()->Name1,itemTarget->GetEntry(),
+ item_owner->GetName(),item_owner->GetSession()->GetAccountId());
+ }
- itemTarget->SetEnchantment(PERM_ENCHANTMENT_SLOT, enchant_id, 0, 0);
+ // remove old enchanting before applying new if equipped
+ item_owner->ApplyEnchantment(itemTarget,PERM_ENCHANTMENT_SLOT,false);
- // add new enchanting if equipped
- item_owner->ApplyEnchantment(itemTarget,PERM_ENCHANTMENT_SLOT,true);
+ itemTarget->SetEnchantment(PERM_ENCHANTMENT_SLOT, enchant_id, 0, 0);
+
+ // add new enchanting if equipped
+ item_owner->ApplyEnchantment(itemTarget,PERM_ENCHANTMENT_SLOT,true);
+ }
}
void Spell::EffectEnchantItemPrismatic(uint32 effect_idx)
diff --git a/src/game/SpellMgr.cpp b/src/game/SpellMgr.cpp
index e4bee68d3a3..a22441614af 100644
--- a/src/game/SpellMgr.cpp
+++ b/src/game/SpellMgr.cpp
@@ -1521,6 +1521,18 @@ bool SpellMgr::IsSkillBonusSpell(uint32 spellId) const
return false;
}
+bool SpellMgr::IsSkillTypeSpell(uint32 spellId, SkillType type) const
+{
+ SkillLineAbilityMap::const_iterator lower = GetBeginSkillLineAbilityMap(spellId);
+ SkillLineAbilityMap::const_iterator upper = GetEndSkillLineAbilityMap(spellId);
+ for (;lower!=upper;++lower)
+ {
+ if (lower->second->skillId==type)
+ return true;
+ }
+ return false;
+}
+
SpellEntry const* SpellMgr::SelectAuraRankForPlayerLevel(SpellEntry const* spellInfo, uint32 playerLevel) const
{
// ignore passive spells
diff --git a/src/game/SpellMgr.h b/src/game/SpellMgr.h
index 934326fe6d1..5f5fe37ec02 100644
--- a/src/game/SpellMgr.h
+++ b/src/game/SpellMgr.h
@@ -280,6 +280,7 @@ inline bool IsDispel(SpellEntry const *spellInfo)
return true;
return false;
}
+
inline bool IsDispelSpell(SpellEntry const *spellInfo)
{
//spellsteal is also dispel
@@ -880,6 +881,7 @@ class SpellMgr
bool IsPrimaryProfessionFirstRankSpell(uint32 spellId) const;
bool IsSkillBonusSpell(uint32 spellId) const;
+ bool IsSkillTypeSpell(uint32 spellId, SkillType type) const;
// Spell script targets