Files
TrinityCore/src/server/game/Handlers/AzeriteHandler.cpp
Matan Shukry a8fa2a03be Core/Items: Calculating item level + organized iterating over items (#26276)
* Unified iterating player items into a single function

Co-authored-by: Shauren <shauren.trinity@gmail.com>
2021-04-21 10:02:42 +02:00

236 lines
10 KiB
C++

/*
* This file is part of the TrinityCore Project. See AUTHORS file for Copyright information
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "WorldSession.h"
#include "AzeriteEmpoweredItem.h"
#include "AzeriteItem.h"
#include "AzeritePackets.h"
#include "DB2Stores.h"
#include "Player.h"
#include "SpellHistory.h"
void WorldSession::HandleAzeriteEssenceUnlockMilestone(WorldPackets::Azerite::AzeriteEssenceUnlockMilestone& azeriteEssenceUnlockMilestone)
{
if (!AzeriteItem::FindHeartForge(_player))
return;
Item* item = _player->GetItemByEntry(ITEM_ID_HEART_OF_AZEROTH, ItemSearchLocation::Everywhere);
if (!item)
return;
AzeriteItem* azeriteItem = item->ToAzeriteItem();
if (!azeriteItem || !azeriteItem->CanUseEssences())
return;
AzeriteItemMilestonePowerEntry const* milestonePower = sAzeriteItemMilestonePowerStore.LookupEntry(azeriteEssenceUnlockMilestone.AzeriteItemMilestonePowerID);
if (!milestonePower || milestonePower->RequiredLevel > int32(azeriteItem->GetLevel()))
return;
// check that all previous milestones are unlocked
for (AzeriteItemMilestonePowerEntry const* previousMilestone : sDB2Manager.GetAzeriteItemMilestonePowers())
{
if (previousMilestone == milestonePower)
break;
if (!azeriteItem->HasUnlockedEssenceMilestone(previousMilestone->ID))
return;
}
azeriteItem->AddUnlockedEssenceMilestone(milestonePower->ID);
_player->ApplyAzeriteItemMilestonePower(azeriteItem, milestonePower, true);
azeriteItem->SetState(ITEM_CHANGED, _player);
}
void WorldSession::HandleAzeriteEssenceActivateEssence(WorldPackets::Azerite::AzeriteEssenceActivateEssence& azeriteEssenceActivateEssence)
{
WorldPackets::Azerite::ActivateEssenceFailed activateEssenceResult;
activateEssenceResult.AzeriteEssenceID = azeriteEssenceActivateEssence.AzeriteEssenceID;
Item* item = _player->GetItemByEntry(ITEM_ID_HEART_OF_AZEROTH, ItemSearchLocation::Equipment);
if (!item)
{
activateEssenceResult.Reason = AzeriteEssenceActivateResult::NotEquipped;
activateEssenceResult.Slot = azeriteEssenceActivateEssence.Slot;
SendPacket(activateEssenceResult.Write());
return;
}
AzeriteItem* azeriteItem = item->ToAzeriteItem();
if (!azeriteItem || !azeriteItem->CanUseEssences())
{
activateEssenceResult.Reason = AzeriteEssenceActivateResult::ConditionFailed;
SendPacket(activateEssenceResult.Write());
return;
}
if (azeriteEssenceActivateEssence.Slot >= MAX_AZERITE_ESSENCE_SLOT || !azeriteItem->HasUnlockedEssenceSlot(azeriteEssenceActivateEssence.Slot))
{
activateEssenceResult.Reason = AzeriteEssenceActivateResult::SlotLocked;
SendPacket(activateEssenceResult.Write());
return;
}
UF::SelectedAzeriteEssences const* selectedEssences = azeriteItem->GetSelectedAzeriteEssences();
// essence is already in that slot, nothing to do
if (selectedEssences && selectedEssences->AzeriteEssenceID[azeriteEssenceActivateEssence.Slot] == uint32(azeriteEssenceActivateEssence.AzeriteEssenceID))
return;
uint32 rank = azeriteItem->GetEssenceRank(azeriteEssenceActivateEssence.AzeriteEssenceID);
if (!rank)
{
activateEssenceResult.Reason = AzeriteEssenceActivateResult::EssenceNotUnlocked;
activateEssenceResult.Arg = azeriteEssenceActivateEssence.AzeriteEssenceID;
SendPacket(activateEssenceResult.Write());
return;
}
if (_player->IsInCombat())
{
activateEssenceResult.Reason = AzeriteEssenceActivateResult::AffectingCombat;
activateEssenceResult.Slot = azeriteEssenceActivateEssence.Slot;
SendPacket(activateEssenceResult.Write());
return;
}
if (_player->isDead())
{
activateEssenceResult.Reason = AzeriteEssenceActivateResult::CantDoThatRightNow;
activateEssenceResult.Slot = azeriteEssenceActivateEssence.Slot;
SendPacket(activateEssenceResult.Write());
return;
}
if (!_player->HasPlayerFlag(PLAYER_FLAGS_RESTING) && !_player->HasUnitFlag2(UNIT_FLAG2_ALLOW_CHANGING_TALENTS))
{
activateEssenceResult.Reason = AzeriteEssenceActivateResult::NotInRestArea;
activateEssenceResult.Slot = azeriteEssenceActivateEssence.Slot;
SendPacket(activateEssenceResult.Write());
return;
}
if (selectedEssences)
{
// need to remove selected essence from another slot if selected
int32 removeEssenceFromSlot = -1;
for (int32 slot = 0; slot < MAX_AZERITE_ESSENCE_SLOT; ++slot)
if (azeriteEssenceActivateEssence.Slot != uint8(slot) && selectedEssences->AzeriteEssenceID[slot] == uint32(azeriteEssenceActivateEssence.AzeriteEssenceID))
removeEssenceFromSlot = slot;
// check cooldown of major essence slot
if (selectedEssences->AzeriteEssenceID[0] && (azeriteEssenceActivateEssence.Slot == 0 || removeEssenceFromSlot == 0))
{
for (uint32 essenceRank = 1; essenceRank <= rank; ++essenceRank)
{
AzeriteEssencePowerEntry const* azeriteEssencePower = ASSERT_NOTNULL(sDB2Manager.GetAzeriteEssencePower(selectedEssences->AzeriteEssenceID[0], essenceRank));
if (_player->GetSpellHistory()->HasCooldown(azeriteEssencePower->MajorPowerDescription))
{
activateEssenceResult.Reason = AzeriteEssenceActivateResult::CantRemoveEssence;
activateEssenceResult.Arg = azeriteEssencePower->MajorPowerDescription;
activateEssenceResult.Slot = azeriteEssenceActivateEssence.Slot;
SendPacket(activateEssenceResult.Write());
return;
}
}
}
if (removeEssenceFromSlot != -1)
{
_player->ApplyAzeriteEssence(azeriteItem, selectedEssences->AzeriteEssenceID[removeEssenceFromSlot], MAX_AZERITE_ESSENCE_RANK,
AzeriteItemMilestoneType(sDB2Manager.GetAzeriteItemMilestonePower(removeEssenceFromSlot)->Type) == AzeriteItemMilestoneType::MajorEssence, false);
azeriteItem->SetSelectedAzeriteEssence(removeEssenceFromSlot, 0);
}
if (selectedEssences->AzeriteEssenceID[azeriteEssenceActivateEssence.Slot])
{
_player->ApplyAzeriteEssence(azeriteItem, selectedEssences->AzeriteEssenceID[azeriteEssenceActivateEssence.Slot], MAX_AZERITE_ESSENCE_RANK,
AzeriteItemMilestoneType(sDB2Manager.GetAzeriteItemMilestonePower(azeriteEssenceActivateEssence.Slot)->Type) == AzeriteItemMilestoneType::MajorEssence, false);
}
}
else
azeriteItem->CreateSelectedAzeriteEssences(_player->GetPrimarySpecialization());
azeriteItem->SetSelectedAzeriteEssence(azeriteEssenceActivateEssence.Slot, azeriteEssenceActivateEssence.AzeriteEssenceID);
_player->ApplyAzeriteEssence(azeriteItem, azeriteEssenceActivateEssence.AzeriteEssenceID, rank,
AzeriteItemMilestoneType(sDB2Manager.GetAzeriteItemMilestonePower(azeriteEssenceActivateEssence.Slot)->Type) == AzeriteItemMilestoneType::MajorEssence, true);
azeriteItem->SetState(ITEM_CHANGED, _player);
}
void WorldSession::HandleAzeriteEmpoweredItemViewed(WorldPackets::Azerite::AzeriteEmpoweredItemViewed& azeriteEmpoweredItemViewed)
{
Item* item = _player->GetItemByGuid(azeriteEmpoweredItemViewed.ItemGUID);
if (!item || !item->IsAzeriteEmpoweredItem())
return;
item->AddItemFlag(ITEM_FIELD_FLAG_AZERITE_EMPOWERED_ITEM_VIEWED);
item->SetState(ITEM_CHANGED, _player);
}
void WorldSession::HandleAzeriteEmpoweredItemSelectPower(WorldPackets::Azerite::AzeriteEmpoweredItemSelectPower& azeriteEmpoweredItemSelectPower)
{
Item* item = _player->GetItemByPos(azeriteEmpoweredItemSelectPower.ContainerSlot, azeriteEmpoweredItemSelectPower.Slot);
if (!item)
return;
AzeritePowerEntry const* azeritePower = sAzeritePowerStore.LookupEntry(azeriteEmpoweredItemSelectPower.AzeritePowerID);
if (!azeritePower)
return;
AzeriteEmpoweredItem* azeriteEmpoweredItem = item->ToAzeriteEmpoweredItem();
if (!azeriteEmpoweredItem)
return;
// Validate tier
int32 actualTier = azeriteEmpoweredItem->GetTierForAzeritePower(Classes(_player->getClass()), azeriteEmpoweredItemSelectPower.AzeritePowerID);
if (azeriteEmpoweredItemSelectPower.Tier > MAX_AZERITE_EMPOWERED_TIER || azeriteEmpoweredItemSelectPower.Tier != actualTier)
return;
uint32 azeriteLevel = 0;
Item const* heartOfAzeroth = _player->GetItemByEntry(ITEM_ID_HEART_OF_AZEROTH, ItemSearchLocation::Everywhere);
if (!heartOfAzeroth)
return;
if (AzeriteItem const* azeriteItem = heartOfAzeroth->ToAzeriteItem())
azeriteLevel = azeriteItem->GetEffectiveLevel();
// Check required heart of azeroth level
if (azeriteLevel < azeriteEmpoweredItem->GetRequiredAzeriteLevelForTier(uint32(actualTier)))
return;
// tiers are ordered backwards, you first select the highest one
for (int32 i = actualTier + 1; i < azeriteEmpoweredItem->GetMaxAzeritePowerTier(); ++i)
if (!azeriteEmpoweredItem->GetSelectedAzeritePower(i))
return;
bool activateAzeritePower = azeriteEmpoweredItem->IsEquipped() && heartOfAzeroth->IsEquipped();
if (azeritePower->ItemBonusListID && activateAzeritePower)
_player->_ApplyItemMods(azeriteEmpoweredItem, azeriteEmpoweredItem->GetSlot(), false);
azeriteEmpoweredItem->SetSelectedAzeritePower(actualTier, azeriteEmpoweredItemSelectPower.AzeritePowerID);
if (activateAzeritePower)
{
// apply all item mods when azerite power grants a bonus, item level changes and that affects stats and auras that scale with item level
if (azeritePower->ItemBonusListID)
_player->_ApplyItemMods(azeriteEmpoweredItem, azeriteEmpoweredItem->GetSlot(), true);
else
_player->ApplyAzeritePower(azeriteEmpoweredItem, azeritePower, true);
}
azeriteEmpoweredItem->SetState(ITEM_CHANGED, _player);
}