diff options
author | Shauren <shauren.trinity@gmail.com> | 2016-08-15 00:03:38 +0200 |
---|---|---|
committer | Shauren <shauren.trinity@gmail.com> | 2016-08-15 00:03:38 +0200 |
commit | fea0cb16f2e73ec21891ac14cdc10d9d8f518cfe (patch) | |
tree | 7e3a6ee9b3876ca5b3a7115a9d932ce8125c41e1 /src/server/game/Handlers/ArtifactHandler.cpp | |
parent | f8c5a2c723c734513eddc98a5c7f380c2f00e479 (diff) |
Core/Items: Implemented artifacts
Diffstat (limited to 'src/server/game/Handlers/ArtifactHandler.cpp')
-rw-r--r-- | src/server/game/Handlers/ArtifactHandler.cpp | 220 |
1 files changed, 220 insertions, 0 deletions
diff --git a/src/server/game/Handlers/ArtifactHandler.cpp b/src/server/game/Handlers/ArtifactHandler.cpp new file mode 100644 index 00000000000..87ee711cc7a --- /dev/null +++ b/src/server/game/Handlers/ArtifactHandler.cpp @@ -0,0 +1,220 @@ +/* + * Copyright (C) 2008-2016 TrinityCore <http://www.trinitycore.org/> + * + * 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 "ArtifactPackets.h" +#include "ConditionMgr.h" +#include "GameTables.h" +#include "Player.h" +#include "SpellAuraEffects.h" +#include "SpellInfo.h" +#include "SpellPackets.h" + +void WorldSession::HandleArtifactAddPower(WorldPackets::Artifact::ArtifactAddPower& artifactAddPower) +{ + if (!_player->GetGameObjectIfCanInteractWith(artifactAddPower.ForgeGUID, GAMEOBJECT_TYPE_ARTIFACT_FORGE)) + return; + + Item* artifact = _player->GetItemByGuid(artifactAddPower.ArtifactGUID); + if (!artifact) + return; + + int32 xpCost = 0; + if (GtArtifactLevelXPEntry const* cost = sArtifactLevelXPGameTable.GetRow(artifact->GetTotalPurchasedArtifactPowers() + 1)) + xpCost = int32(cost->XP); + + if (xpCost > artifact->GetInt32Value(ITEM_FIELD_ARTIFACT_XP)) + return; + + if (artifactAddPower.PowerChoices.empty()) + return; + + ItemDynamicFieldArtifactPowers const* artifactPower = artifact->GetArtifactPower(artifactAddPower.PowerChoices[0].ArtifactPowerID); + if (!artifactPower) + return; + + ArtifactPowerEntry const* artifactPowerEntry = sArtifactPowerStore.LookupEntry(artifactPower->ArtifactPowerId); + if (!artifactPowerEntry) + return; + + if (artifactAddPower.PowerChoices[0].Rank != artifactPower->PurchasedRank + 1 || + artifactAddPower.PowerChoices[0].Rank > artifactPowerEntry->MaxRank) + return; + + if (std::unordered_set<uint32> const* artifactPowerLinks = sDB2Manager.GetArtifactPowerLinks(artifactPower->ArtifactPowerId)) + { + bool hasAnyLink = false; + for (uint32 artifactPowerLinkId : *artifactPowerLinks) + { + ArtifactPowerEntry const* artifactPowerLink = sArtifactPowerStore.LookupEntry(artifactPowerLinkId); + if (!artifactPowerLink) + continue; + + ItemDynamicFieldArtifactPowers const* artifactPowerLinkLearned = artifact->GetArtifactPower(artifactPowerLinkId); + if (!artifactPowerLinkLearned) + continue; + + if (artifactPowerLinkLearned->PurchasedRank >= artifactPowerLink->MaxRank) + { + hasAnyLink = true; + break; + } + } + + if (!hasAnyLink) + return; + } + + ArtifactPowerRankEntry const* artifactPowerRank = sDB2Manager.GetArtifactPowerRank(artifactPower->ArtifactPowerId, artifactPower->CurrentRankWithBonus + 1 - 1); // need data for next rank, but -1 because of how db2 data is structured + if (!artifactPowerRank) + return; + + ItemDynamicFieldArtifactPowers newPower = *artifactPower; + ++newPower.PurchasedRank; + ++newPower.CurrentRankWithBonus; + artifact->SetArtifactPower(&newPower); + + if (artifact->IsEquipped()) + { + _player->ApplyArtifactPowerRank(artifact, artifactPowerRank, true); + + for (ItemDynamicFieldArtifactPowers const& power : artifact->GetArtifactPowers()) + { + ArtifactPowerEntry const* scaledArtifactPowerEntry = sArtifactPowerStore.AssertEntry(power.ArtifactPowerId); + if (!(scaledArtifactPowerEntry->Flags & ARTIFACT_POWER_FLAG_SCALES_WITH_NUM_POWERS)) + continue; + + ArtifactPowerRankEntry const* scaledArtifactPowerRank = sDB2Manager.GetArtifactPowerRank(scaledArtifactPowerEntry->ID, 0); + if (!scaledArtifactPowerRank) + continue; + + ItemDynamicFieldArtifactPowers newScaledPower = power; + ++newScaledPower.CurrentRankWithBonus; + artifact->SetArtifactPower(&newScaledPower); + + _player->ApplyArtifactPowerRank(artifact, scaledArtifactPowerRank, false); + _player->ApplyArtifactPowerRank(artifact, scaledArtifactPowerRank, true); + } + } + + artifact->ApplyModInt32Value(ITEM_FIELD_ARTIFACT_XP, xpCost, false); + artifact->SetState(ITEM_CHANGED, _player); +} + +void WorldSession::HandleArtifactSetAppearance(WorldPackets::Artifact::ArtifactSetAppearance& artifactSetAppearance) +{ + if (!_player->GetGameObjectIfCanInteractWith(artifactSetAppearance.ForgeGUID, GAMEOBJECT_TYPE_ARTIFACT_FORGE)) + return; + + ArtifactAppearanceEntry const* artifactAppearance = sArtifactAppearanceStore.LookupEntry(artifactSetAppearance.ArtifactAppearanceID); + if (!artifactAppearance) + return; + + Item* artifact = _player->GetItemByGuid(artifactSetAppearance.ArtifactGUID); + if (!artifact) + return; + + ArtifactAppearanceSetEntry const* artifactAppearanceSet = sArtifactAppearanceSetStore.LookupEntry(artifactAppearance->ArtifactAppearanceSetID); + if (!artifactAppearanceSet || artifactAppearanceSet->ArtifactID != artifact->GetTemplate()->GetArtifactID()) + return; + + if (PlayerConditionEntry const* playerCondition = sPlayerConditionStore.LookupEntry(artifactAppearance->PlayerConditionID)) + if (!sConditionMgr->IsPlayerMeetingCondition(_player, playerCondition)) + return; + + artifact->SetAppearanceModId(artifactAppearance->AppearanceModID); + artifact->SetModifier(ITEM_MODIFIER_ARTIFACT_APPEARANCE_ID, artifactAppearance->ID); + artifact->SetState(ITEM_CHANGED, _player); + Item* childItem = _player->GetChildItemByGuid(artifact->GetChildItem()); + if (childItem) + { + childItem->SetAppearanceModId(artifactAppearance->AppearanceModID); + childItem->SetState(ITEM_CHANGED, _player); + } + + if (artifact->IsEquipped()) + { + // change weapon appearance + _player->SetVisibleItemSlot(artifact->GetSlot(), artifact); + if (childItem) + _player->SetVisibleItemSlot(childItem->GetSlot(), childItem); + + // change druid form appearance + if (artifactAppearance->ShapeshiftDisplayID && artifactAppearance->ModifiesShapeshiftFormDisplay && _player->GetShapeshiftForm() == ShapeshiftForm(artifactAppearance->ModifiesShapeshiftFormDisplay)) + _player->RestoreDisplayId(); + } +} + +void WorldSession::HandleConfirmArtifactRespec(WorldPackets::Artifact::ConfirmArtifactRespec& confirmArtifactRespec) +{ + if (!_player->GetNPCIfCanInteractWith(confirmArtifactRespec.NpcGUID, UNIT_NPC_FLAG_ARTIFACT_POWER_RESPEC)) + return; + + Item* artifact = _player->GetItemByGuid(confirmArtifactRespec.ArtifactGUID); + if (!artifact) + return; + + uint32 xpCost = 0; + if (GtArtifactLevelXPEntry const* cost = sArtifactLevelXPGameTable.GetRow(artifact->GetTotalPurchasedArtifactPowers() + 1)) + xpCost = uint32(cost->XP); + + if (xpCost > artifact->GetUInt32Value(ITEM_FIELD_ARTIFACT_XP)) + return; + + uint32 newAmount = artifact->GetUInt32Value(ITEM_FIELD_ARTIFACT_XP) - xpCost; + for (uint32 i = 0; i <= artifact->GetTotalPurchasedArtifactPowers(); ++i) + if (GtArtifactLevelXPEntry const* cost = sArtifactLevelXPGameTable.GetRow(i)) + newAmount += uint32(cost->XP); + + for (ItemDynamicFieldArtifactPowers const& artifactPower : artifact->GetArtifactPowers()) + { + uint8 oldPurchasedRank = artifactPower.PurchasedRank; + if (!oldPurchasedRank) + continue; + + ItemDynamicFieldArtifactPowers newPower = artifactPower; + newPower.PurchasedRank -= oldPurchasedRank; + newPower.CurrentRankWithBonus -= oldPurchasedRank; + artifact->SetArtifactPower(&newPower); + + if (artifact->IsEquipped()) + { + ArtifactPowerRankEntry const* artifactPowerRank = sDB2Manager.GetArtifactPowerRank(artifactPower.ArtifactPowerId, 0); + _player->ApplyArtifactPowerRank(artifact, artifactPowerRank, false); + } + } + + for (ItemDynamicFieldArtifactPowers const& power : artifact->GetArtifactPowers()) + { + ArtifactPowerEntry const* scaledArtifactPowerEntry = sArtifactPowerStore.AssertEntry(power.ArtifactPowerId); + if (!(scaledArtifactPowerEntry->Flags & ARTIFACT_POWER_FLAG_SCALES_WITH_NUM_POWERS)) + continue; + + ArtifactPowerRankEntry const* scaledArtifactPowerRank = sDB2Manager.GetArtifactPowerRank(scaledArtifactPowerEntry->ID, 0); + if (!scaledArtifactPowerRank) + continue; + + ItemDynamicFieldArtifactPowers newScaledPower = power; + newScaledPower.CurrentRankWithBonus = 0; + artifact->SetArtifactPower(&newScaledPower); + + _player->ApplyArtifactPowerRank(artifact, scaledArtifactPowerRank, false); + } + + artifact->SetUInt32Value(ITEM_FIELD_ARTIFACT_XP, newAmount); + artifact->SetState(ITEM_CHANGED, _player); +} |