[9507] Implement SPELL_EFFECT_RESTORE_ITEM_CHARGES

Also it application in special case of item 5513 and similar.
This commit is contained in:
VladimirMangos 2010-03-03 05:58:36 +03:00
parent d775eea9a4
commit 4c4629e861
11 changed files with 105 additions and 3 deletions

View file

@ -179,6 +179,15 @@ bool Bag::IsEmpty() const
return true;
}
Item* Bag::GetItemByEntry( uint32 item ) const
{
for(uint32 i = 0; i < GetBagSize(); ++i)
if (m_bagslot[i] && m_bagslot[i]->GetEntry() == item)
return m_bagslot[i];
return NULL;
}
uint32 Bag::GetItemCount( uint32 item, Item* eItem ) const
{
Item *pItem;

View file

@ -42,6 +42,7 @@ class Bag : public Item
void RemoveItem( uint8 slot, bool update );
Item* GetItemByPos( uint8 slot ) const;
Item* GetItemByEntry( uint32 item ) const;
uint32 GetItemCount( uint32 item, Item* eItem = NULL ) const;
uint32 GetItemCountWithLimitCategory(uint32 limitCategory) const;

View file

@ -1055,3 +1055,28 @@ bool ItemRequiredTarget::IsFitToRequirements( Unit* pUnitTarget ) const
return false;
}
}
bool Item::HasMaxCharges() const
{
ItemPrototype const* itemProto = GetProto();
for(int i = 0; i < MAX_ITEM_PROTO_SPELLS; ++i)
if (GetSpellCharges(i) != itemProto->Spells[i].SpellCharges)
return false;
return true;
}
void Item::RestoreCharges()
{
ItemPrototype const* itemProto = GetProto();
for(int i = 0; i < MAX_ITEM_PROTO_SPELLS; ++i)
{
if (GetSpellCharges(i) != itemProto->Spells[i].SpellCharges)
{
SetSpellCharges(i, itemProto->Spells[i].SpellCharges);
SetState(ITEM_CHANGED);
}
}
}

View file

@ -299,6 +299,8 @@ class MANGOS_DLL_SPEC Item : public Object
// spell charges (signed but stored as unsigned)
int32 GetSpellCharges(uint8 index/*0..5*/ = 0) const { return GetInt32Value(ITEM_FIELD_SPELL_CHARGES + index); }
void SetSpellCharges(uint8 index/*0..5*/, int32 value) { SetInt32Value(ITEM_FIELD_SPELL_CHARGES + index,value); }
bool HasMaxCharges() const;
void RestoreCharges();
Loot loot;
bool m_lootGenerated;

View file

@ -8622,6 +8622,26 @@ uint32 Player::GetItemCountWithLimitCategory( uint32 limitCategory ) const
return count;
}
Item* Player::GetItemByEntry( uint32 item ) const
{
for(int i = EQUIPMENT_SLOT_START; i < INVENTORY_SLOT_ITEM_END; ++i)
if (Item *pItem = GetItemByPos(INVENTORY_SLOT_BAG_0, i))
if (pItem->GetEntry() == item)
return pItem;
for(int i = KEYRING_SLOT_START; i < CURRENCYTOKEN_SLOT_END; ++i)
if (Item *pItem = GetItemByPos(INVENTORY_SLOT_BAG_0, i))
if (pItem->GetEntry() == item)
return pItem;
for(int i = INVENTORY_SLOT_BAG_START; i < INVENTORY_SLOT_BAG_END; ++i)
if (Bag* pBag = (Bag*)GetItemByPos( INVENTORY_SLOT_BAG_0, i))
if (Item* itemPtr = pBag->GetItemByEntry(item))
return itemPtr;
return NULL;
}
Item* Player::GetItemByGuid( uint64 guid ) const
{
for(int i = EQUIPMENT_SLOT_START; i < INVENTORY_SLOT_ITEM_END; ++i)

View file

@ -1150,6 +1150,7 @@ class MANGOS_DLL_SPEC Player : public Unit
uint32 GetItemCount( uint32 item, bool inBankAlso = false, Item* skipItem = NULL ) const;
uint32 GetItemCountWithLimitCategory(uint32 limitCategory) const;
Item* GetItemByGuid( uint64 guid ) const;
Item* GetItemByEntry(uint32 item) const; // only for special cases
Item* GetItemByPos( uint16 pos ) const;
Item* GetItemByPos( uint8 bag, uint8 slot ) const;
Item* GetWeaponForAttack(WeaponAttackType attackType) const { return GetWeaponForAttack(attackType,false,false); }

View file

@ -594,7 +594,7 @@ enum SpellEffects
SPELL_EFFECT_THREAT = 63,
SPELL_EFFECT_TRIGGER_SPELL = 64,
SPELL_EFFECT_APPLY_AREA_AURA_RAID = 65,
SPELL_EFFECT_CREATE_MANA_GEM = 66,
SPELL_EFFECT_RESTORE_ITEM_CHARGES = 66,
SPELL_EFFECT_HEAL_MAX_HEALTH = 67,
SPELL_EFFECT_INTERRUPT_CAST = 68,
SPELL_EFFECT_DISTRACT = 69,

View file

@ -5614,6 +5614,19 @@ SpellCastResult Spell::CheckItems()
{
if (!m_IsTriggeredSpell && m_spellInfo->EffectItemType[i])
{
// Conjure Mana Gem
if (i == EFFECT_INDEX_0 && m_spellInfo->Effect[EFFECT_INDEX_1] == SPELL_EFFECT_DUMMY)
{
if (Item* item = p_caster->GetItemByEntry(m_spellInfo->EffectItemType[i]))
{
if (item->HasMaxCharges())
return SPELL_FAILED_ITEM_AT_MAX_CHARGES;
// will recharge in next effect
continue;
}
}
ItemPosCountVec dest;
uint8 msg = p_caster->CanStoreNewItem(NULL_BAG, NULL_SLOT, dest, m_spellInfo->EffectItemType[i], 1 );
if (msg != EQUIP_ERR_OK )
@ -5624,6 +5637,14 @@ SpellCastResult Spell::CheckItems()
}
break;
}
case SPELL_EFFECT_RESTORE_ITEM_CHARGES:
{
if (Item* item = p_caster->GetItemByEntry(m_spellInfo->EffectItemType[i]))
if (item->HasMaxCharges())
return SPELL_FAILED_ITEM_AT_MAX_CHARGES;
break;
}
case SPELL_EFFECT_ENCHANT_ITEM:
case SPELL_EFFECT_ENCHANT_ITEM_PRISMATIC:
{

View file

@ -266,6 +266,7 @@ class Spell
void EffectTriggerSpell(SpellEffectIndex eff_idx);
void EffectTriggerMissileSpell(SpellEffectIndex eff_idx);
void EffectThreat(SpellEffectIndex eff_idx);
void EffectRestoreItemCharges(SpellEffectIndex eff_idx);
void EffectHealMaxHealth(SpellEffectIndex eff_idx);
void EffectInterruptCast(SpellEffectIndex eff_idx);
void EffectSummonObjectWild(SpellEffectIndex eff_idx);

View file

@ -123,7 +123,7 @@ pEffect SpellEffects[TOTAL_SPELL_EFFECTS]=
&Spell::EffectThreat, // 63 SPELL_EFFECT_THREAT
&Spell::EffectTriggerSpell, // 64 SPELL_EFFECT_TRIGGER_SPELL
&Spell::EffectApplyAreaAura, // 65 SPELL_EFFECT_APPLY_AREA_AURA_RAID
&Spell::EffectUnused, // 66 SPELL_EFFECT_CREATE_MANA_GEM (possibly recharge it, misc - is item ID)
&Spell::EffectRestoreItemCharges, // 66 SPELL_EFFECT_RESTORE_ITEM_CHARGES itemtype - is affected item ID
&Spell::EffectHealMaxHealth, // 67 SPELL_EFFECT_HEAL_MAX_HEALTH
&Spell::EffectInterruptCast, // 68 SPELL_EFFECT_INTERRUPT_CAST
&Spell::EffectDistract, // 69 SPELL_EFFECT_DISTRACT
@ -1652,6 +1652,13 @@ void Spell::EffectDummy(SpellEffectIndex eff_idx)
return;
}
}
// Conjure Mana Gem
if (eff_idx == EFFECT_INDEX_1 && m_spellInfo->Effect[EFFECT_INDEX_0] == SPELL_EFFECT_CREATE_ITEM)
{
unitTarget->CastSpell( unitTarget, m_spellInfo->CalculateSimpleValue(eff_idx), true, m_CastItem);
return;
}
break;
}
case SPELLFAMILY_WARRIOR:
@ -3191,6 +3198,10 @@ void Spell::DoCreateItem(SpellEffectIndex eff_idx, uint32 itemtype)
num_to_add -= no_space;
else
{
// ignore mana gem case (next effect will recharge existed example)
if (eff_idx == EFFECT_INDEX_0 && m_spellInfo->Effect[EFFECT_INDEX_1] == SPELL_EFFECT_DUMMY )
return;
// if not created by another reason from full inventory or unique items amount limitation
player->SendEquipError( msg, NULL, NULL, newitemid );
return;
@ -7436,3 +7447,14 @@ void Spell::EffectBind(SpellEffectIndex eff_idx)
data << uint32(area_id);
player->SendMessageToSet( &data, true );
}
void Spell::EffectRestoreItemCharges( SpellEffectIndex eff_idx )
{
if (m_caster->GetTypeId() != TYPEID_PLAYER)
return;
Player* player = (Player*)unitTarget;
if (Item* item = player->GetItemByEntry(m_spellInfo->EffectItemType[eff_idx]))
item->RestoreCharges();
}

View file

@ -1,4 +1,4 @@
#ifndef __REVISION_NR_H__
#define __REVISION_NR_H__
#define REVISION_NR "9506"
#define REVISION_NR "9507"
#endif // __REVISION_NR_H__