diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/server/game/Entities/Item/Item.cpp | 75 | ||||
-rw-r--r-- | src/server/game/Entities/Item/Item.h | 6 | ||||
-rw-r--r-- | src/server/game/Entities/Player/Player.cpp | 34 | ||||
-rw-r--r-- | src/server/game/Entities/Player/Player.h | 6 |
4 files changed, 59 insertions, 62 deletions
diff --git a/src/server/game/Entities/Item/Item.cpp b/src/server/game/Entities/Item/Item.cpp index 90bbb1c2278..5d6be5e8c2a 100644 --- a/src/server/game/Entities/Item/Item.cpp +++ b/src/server/game/Entities/Item/Item.cpp @@ -51,7 +51,7 @@ void AddItemsSetItem(Player* player, Item* item) for (size_t x = 0; x < player->ItemSetEff.size(); ++x) { - if (player->ItemSetEff[x] && player->ItemSetEff[x]->setid == setid) + if (player->ItemSetEff[x] && player->ItemSetEff[x]->ItemSetID == setid) { eff = player->ItemSetEff[x]; break; @@ -61,7 +61,8 @@ void AddItemsSetItem(Player* player, Item* item) if (!eff) { eff = new ItemSetEffect(); - eff->setid = setid; + eff->ItemSetID = setid; + eff->EquippedItemCount = 0; size_t x = 0; for (; x < player->ItemSetEff.size(); ++x) @@ -69,51 +70,39 @@ void AddItemsSetItem(Player* player, Item* item) break; if (x < player->ItemSetEff.size()) - player->ItemSetEff[x]=eff; + player->ItemSetEff[x] = eff; else player->ItemSetEff.push_back(eff); } - ++eff->item_count; + ++eff->EquippedItemCount; ItemSetSpells& spells = sItemSetSpellsStore[setid]; - for (uint32 x = 0; x < spells.size(); ++x) + for (ItemSetSpellEntry const* itemSetSpell : spells) { //not enough for spell - if (spells[x]->Threshold > eff->item_count) + if (itemSetSpell->Threshold > eff->EquippedItemCount) continue; - uint32 z = 0; - for (; z < MAX_ITEM_SET_SPELLS; ++z) - if (eff->spells[z] && eff->spells[z]->Id == spells[x]->SpellID) - break; - - if (z < MAX_ITEM_SET_SPELLS) + if (eff->SetBonuses.count(itemSetSpell)) continue; - //new spell - for (uint32 y = 0; y < MAX_ITEM_SET_SPELLS; ++y) + SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(itemSetSpell->SpellID); + if (!spellInfo) { - if (!eff->spells[y]) // free slot - { - SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spells[x]->SpellID); - if (!spellInfo) - { - TC_LOG_ERROR("entities.player.items", "WORLD: unknown spell id %u in items set %u effects", spells[x]->SpellID, setid); - break; - } - - // spell cast only if fit form requirement, in other case will cast at form change - player->ApplyEquipSpell(spellInfo, NULL, true); - eff->spells[y] = spellInfo; - break; - } + TC_LOG_ERROR("entities.player.items", "WORLD: unknown spell id %u in items set %u effects", itemSetSpell->SpellID, setid); + continue; } + + eff->SetBonuses.insert(itemSetSpell); + // spell cast only if fit form requirement, in other case will cast at form change + if (!itemSetSpell->ChrSpecID || itemSetSpell->ChrSpecID == player->GetUInt32Value(PLAYER_FIELD_CURRENT_SPEC_ID)) + player->ApplyEquipSpell(spellInfo, NULL, true); } } -void RemoveItemsSetItem(Player*player, ItemTemplate const* proto) +void RemoveItemsSetItem(Player* player, ItemTemplate const* proto) { uint32 setid = proto->GetItemSet(); @@ -129,7 +118,7 @@ void RemoveItemsSetItem(Player*player, ItemTemplate const* proto) size_t setindex = 0; for (; setindex < player->ItemSetEff.size(); setindex++) { - if (player->ItemSetEff[setindex] && player->ItemSetEff[setindex]->setid == setid) + if (player->ItemSetEff[setindex] && player->ItemSetEff[setindex]->ItemSetID == setid) { eff = player->ItemSetEff[setindex]; break; @@ -140,29 +129,23 @@ void RemoveItemsSetItem(Player*player, ItemTemplate const* proto) if (!eff) return; - --eff->item_count; - - ItemSetSpells& spells = sItemSetSpellsStore[setid]; + --eff->EquippedItemCount; - for (uint32 x = 0; x < spells.size(); x++) + ItemSetSpells const& spells = sItemSetSpellsStore[setid]; + for (ItemSetSpellEntry const* itemSetSpell : spells) { // enough for spell - if (spells[x]->Threshold <= eff->item_count) + if (itemSetSpell->Threshold <= eff->EquippedItemCount) continue; - for (uint32 z = 0; z < MAX_ITEM_SET_SPELLS; z++) - { - if (eff->spells[z] && eff->spells[z]->Id == spells[x]->SpellID) - { - // spell can be not active if not fit form requirement - player->ApplyEquipSpell(eff->spells[z], NULL, false); - eff->spells[z]=NULL; - break; - } - } + if (!eff->SetBonuses.count(itemSetSpell)) + continue; + + player->ApplyEquipSpell(sSpellMgr->AssertSpellInfo(itemSetSpell->SpellID), nullptr, false); + eff->SetBonuses.erase(itemSetSpell); } - if (!eff->item_count) //all items of a set were removed + if (!eff->EquippedItemCount) //all items of a set were removed { ASSERT(eff == player->ItemSetEff[setindex]); delete eff; diff --git a/src/server/game/Entities/Item/Item.h b/src/server/game/Entities/Item/Item.h index 545d402b699..ffd4872a2e8 100644 --- a/src/server/game/Entities/Item/Item.h +++ b/src/server/game/Entities/Item/Item.h @@ -31,9 +31,9 @@ class Unit; struct ItemSetEffect { - uint32 setid; - uint32 item_count; - SpellInfo const* spells[8]; + uint32 ItemSetID; + uint32 EquippedItemCount; + std::unordered_set<ItemSetSpellEntry const*> SetBonuses; }; enum InventoryResult diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp index 3365b1c79dd..f3426010071 100644 --- a/src/server/game/Entities/Player/Player.cpp +++ b/src/server/game/Entities/Player/Player.cpp @@ -7970,7 +7970,7 @@ void Player::_ApplyWeaponDependentAuraDamageMod(Item* item, WeaponAttackType att } } -void Player::ApplyItemEquipSpell(Item* item, bool apply, bool form_change) +void Player::ApplyItemEquipSpell(Item* item, bool apply, bool formChange /*= false*/) { if (!item) return; @@ -7992,11 +7992,11 @@ void Player::ApplyItemEquipSpell(Item* item, bool apply, bool form_change) if (!spellproto) continue; - ApplyEquipSpell(spellproto, item, apply, form_change); + ApplyEquipSpell(spellproto, item, apply, formChange); } } -void Player::ApplyEquipSpell(SpellInfo const* spellInfo, Item* item, bool apply, bool form_change) +void Player::ApplyEquipSpell(SpellInfo const* spellInfo, Item* item, bool apply, bool formChange /*= false*/) { if (apply) { @@ -8004,7 +8004,7 @@ void Player::ApplyEquipSpell(SpellInfo const* spellInfo, Item* item, bool apply, if (spellInfo->CheckShapeshift(GetShapeshiftForm()) != SPELL_CAST_OK) return; - if (form_change) // check aura active state from other form + if (formChange) // check aura active state from other form { AuraApplicationMapBounds range = GetAppliedAuras().equal_range(spellInfo->Id); for (AuraApplicationMap::const_iterator itr = range.first; itr != range.second; ++itr) @@ -8018,7 +8018,7 @@ void Player::ApplyEquipSpell(SpellInfo const* spellInfo, Item* item, bool apply, } else { - if (form_change) // check aura compatibility + if (formChange) // check aura compatibility { // Cannot be used in this stance/form if (spellInfo->CheckShapeshift(GetShapeshiftForm()) == SPELL_CAST_OK) @@ -8043,6 +8043,11 @@ void Player::UpdateEquipSpellsAtFormChange() } } + UpdateItemSetAuras(true); +} + +void Player::UpdateItemSetAuras(bool formChange /*= false*/) +{ // item set bonuses not dependent from item broken state for (size_t setindex = 0; setindex < ItemSetEff.size(); ++setindex) { @@ -8050,17 +8055,21 @@ void Player::UpdateEquipSpellsAtFormChange() if (!eff) continue; - for (uint32 y = 0; y < MAX_ITEM_SET_SPELLS; ++y) + for (ItemSetSpellEntry const* itemSetSpell : eff->SetBonuses) { - SpellInfo const* spellInfo = eff->spells[y]; - if (!spellInfo) - continue; + SpellInfo const* spellInfo = sSpellMgr->AssertSpellInfo(itemSetSpell->SpellID); - ApplyEquipSpell(spellInfo, NULL, false, true); // remove spells that not fit to form - ApplyEquipSpell(spellInfo, NULL, true, true); // add spells that fit form but not active + if (itemSetSpell->ChrSpecID && itemSetSpell->ChrSpecID != GetUInt32Value(PLAYER_FIELD_CURRENT_SPEC_ID)) + ApplyEquipSpell(spellInfo, nullptr, false, false); // item set aura is not for current spec + else + { + ApplyEquipSpell(spellInfo, nullptr, false, formChange); // remove spells that not fit to form - removal is skipped if shapeshift condition is satisfied + ApplyEquipSpell(spellInfo, nullptr, true, formChange); // add spells that fit form but not active + } } } } + void Player::CastItemCombatSpell(Unit* target, WeaponAttackType attType, uint32 procVictim, uint32 procEx) { if (!target || !target->IsAlive() || target == this) @@ -25043,6 +25052,7 @@ void Player::LearnTalentSpecialization(uint32 talentSpec) LearnSpecializationSpells(); SendTalentsInfoData(); + UpdateItemSetAuras(false); } void Player::ResetTalentSpecialization() @@ -25063,6 +25073,7 @@ void Player::ResetTalentSpecialization() RemoveSpecializationSpells(); SendTalentsInfoData(); + UpdateItemSetAuras(false); } void Player::UpdateFallInformationIfNeed(MovementInfo const& minfo, uint16 opcode) @@ -25619,6 +25630,7 @@ void Player::ActivateTalentGroup(uint8 spec) SetPower(POWER_MANA, 0); // Mana must be 0 even if it isn't the active power type. SetPower(pw, 0); + UpdateItemSetAuras(false); if (!sChrSpecializationStore.LookupEntry(GetSpecId(GetActiveTalentGroup()))) ResetTalents(true); diff --git a/src/server/game/Entities/Player/Player.h b/src/server/game/Entities/Player/Player.h index fa183c78cb3..d61b7845abf 100644 --- a/src/server/game/Entities/Player/Player.h +++ b/src/server/game/Entities/Player/Player.h @@ -2279,9 +2279,11 @@ class Player : public Unit, public GridObject<Player> void CorrectMetaGemEnchants(uint8 slot, bool apply); void InitDataForForm(bool reapplyMods = false); - void ApplyItemEquipSpell(Item* item, bool apply, bool form_change = false); - void ApplyEquipSpell(SpellInfo const* spellInfo, Item* item, bool apply, bool form_change = false); + void ApplyItemEquipSpell(Item* item, bool apply, bool formChange = false); + void ApplyEquipSpell(SpellInfo const* spellInfo, Item* item, bool apply, bool formChange = false); void UpdateEquipSpellsAtFormChange(); + void UpdateItemSetAuras(bool formChange = false); + void CastItemCombatSpell(Unit* target, WeaponAttackType attType, uint32 procVictim, uint32 procEx); void CastItemUseSpell(Item* item, SpellCastTargets const& targets, uint8 castCount, uint32 misc); void CastItemCombatSpell(Unit* target, WeaponAttackType attType, uint32 procVictim, uint32 procEx, Item* item, ItemTemplate const* proto); |