*Implement enchanting vellums.
--HG-- branch : trunk
This commit is contained in:
@@ -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
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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); }
|
||||
};
|
||||
|
||||
|
||||
+26
-2
@@ -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();
|
||||
|
||||
+46
-26
@@ -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);
|
||||
|
||||
uint32 enchant_id = m_spellInfo->EffectMiscValue[effect_idx];
|
||||
if (!enchant_id)
|
||||
return;
|
||||
|
||||
SpellItemEnchantmentEntry const *pEnchant = sSpellItemEnchantmentStore.LookupEntry(enchant_id);
|
||||
if(!pEnchant)
|
||||
return;
|
||||
|
||||
// item can be in trade slot and have owner diff. from caster
|
||||
Player* item_owner = itemTarget->GetOwner();
|
||||
if(!item_owner)
|
||||
return;
|
||||
|
||||
if(item_owner!=p_caster && p_caster->GetSession()->GetSecurity() > SEC_PLAYER && sWorld.getConfig(CONFIG_GM_LOG_TRADE) )
|
||||
// Handle vellums
|
||||
if (itemTarget->IsWeaponVellum() || itemTarget->IsArmorVellum())
|
||||
{
|
||||
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;
|
||||
|
||||
// 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);
|
||||
|
||||
// remove old enchanting before applying new if equipped
|
||||
item_owner->ApplyEnchantment(itemTarget,PERM_ENCHANTMENT_SLOT,false);
|
||||
uint32 enchant_id = m_spellInfo->EffectMiscValue[effect_idx];
|
||||
if (!enchant_id)
|
||||
return;
|
||||
|
||||
itemTarget->SetEnchantment(PERM_ENCHANTMENT_SLOT, enchant_id, 0, 0);
|
||||
SpellItemEnchantmentEntry const *pEnchant = sSpellItemEnchantmentStore.LookupEntry(enchant_id);
|
||||
if(!pEnchant)
|
||||
return;
|
||||
|
||||
// add new enchanting if equipped
|
||||
item_owner->ApplyEnchantment(itemTarget,PERM_ENCHANTMENT_SLOT,true);
|
||||
// item can be in trade slot and have owner diff. from caster
|
||||
Player* item_owner = itemTarget->GetOwner();
|
||||
if(!item_owner)
|
||||
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());
|
||||
}
|
||||
|
||||
// remove old enchanting before applying new if equipped
|
||||
item_owner->ApplyEnchantment(itemTarget,PERM_ENCHANTMENT_SLOT,false);
|
||||
|
||||
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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user