*Implement enchanting vellums.

--HG--
branch : trunk
This commit is contained in:
QAston
2009-05-01 15:40:49 +02:00
parent db977d7005
commit 0f5a9cb46f
7 changed files with 98 additions and 28 deletions
+7
View File
@@ -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
+2
View File
@@ -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;
+3
View File
@@ -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
View File
@@ -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
View File
@@ -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)
+12
View File
@@ -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
+2
View File
@@ -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