diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/game/Item.cpp | 7 | ||||
-rw-r--r-- | src/game/Item.h | 2 | ||||
-rw-r--r-- | src/game/ItemPrototype.h | 3 | ||||
-rw-r--r-- | src/game/Spell.cpp | 28 | ||||
-rw-r--r-- | src/game/SpellEffects.cpp | 68 | ||||
-rw-r--r-- | src/game/SpellMgr.cpp | 12 | ||||
-rw-r--r-- | src/game/SpellMgr.h | 2 |
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 |