diff --git a/src/game/Bag.cpp b/src/game/Bag.cpp index d263ad929..9786e0530 100644 --- a/src/game/Bag.cpp +++ b/src/game/Bag.cpp @@ -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; diff --git a/src/game/Bag.h b/src/game/Bag.h index 53ec788bf..4306d628c 100644 --- a/src/game/Bag.h +++ b/src/game/Bag.h @@ -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; diff --git a/src/game/Item.cpp b/src/game/Item.cpp index 10eef36eb..2f5deaa0a 100644 --- a/src/game/Item.cpp +++ b/src/game/Item.cpp @@ -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); + } + } +} diff --git a/src/game/Item.h b/src/game/Item.h index 409f8cee9..fcf64188f 100644 --- a/src/game/Item.h +++ b/src/game/Item.h @@ -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; diff --git a/src/game/Player.cpp b/src/game/Player.cpp index 5403725c3..fc8e2dd87 100644 --- a/src/game/Player.cpp +++ b/src/game/Player.cpp @@ -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) diff --git a/src/game/Player.h b/src/game/Player.h index abebe7384..23e1a8bcf 100644 --- a/src/game/Player.h +++ b/src/game/Player.h @@ -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); } diff --git a/src/game/SharedDefines.h b/src/game/SharedDefines.h index 5ebdedbbf..900441562 100644 --- a/src/game/SharedDefines.h +++ b/src/game/SharedDefines.h @@ -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, diff --git a/src/game/Spell.cpp b/src/game/Spell.cpp index ba9ef854a..95f5dd427 100644 --- a/src/game/Spell.cpp +++ b/src/game/Spell.cpp @@ -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: { diff --git a/src/game/Spell.h b/src/game/Spell.h index 7612ff084..301ab53c5 100644 --- a/src/game/Spell.h +++ b/src/game/Spell.h @@ -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); diff --git a/src/game/SpellEffects.cpp b/src/game/SpellEffects.cpp index d2ede363e..fe136bdea 100644 --- a/src/game/SpellEffects.cpp +++ b/src/game/SpellEffects.cpp @@ -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(); +} \ No newline at end of file diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index bbc4d019d..9246e42a7 100644 --- a/src/shared/revision_nr.h +++ b/src/shared/revision_nr.h @@ -1,4 +1,4 @@ #ifndef __REVISION_NR_H__ #define __REVISION_NR_H__ - #define REVISION_NR "9506" + #define REVISION_NR "9507" #endif // __REVISION_NR_H__