aboutsummaryrefslogtreecommitdiff
path: root/src/server/game/Entities
diff options
context:
space:
mode:
authorShauren <shauren.trinity@gmail.com>2016-11-08 00:04:19 +0100
committerShauren <shauren.trinity@gmail.com>2016-11-08 00:04:19 +0100
commitfcbb4397ea5c803b5b46bda770606ae7a79e565f (patch)
tree07bbcd1f1f45c27503617301e7bc36c68b185f43 /src/server/game/Entities
parent0abb9873ec3798b6476400c8d283a6410d9418fe (diff)
Core/Quests: Implemented handling all QuestPackageItem types
Closes #18209
Diffstat (limited to 'src/server/game/Entities')
-rw-r--r--src/server/game/Entities/Item/ItemTemplate.cpp14
-rw-r--r--src/server/game/Entities/Item/ItemTemplate.h4
-rw-r--r--src/server/game/Entities/Player/Player.cpp98
-rw-r--r--src/server/game/Entities/Player/Player.h1
4 files changed, 94 insertions, 23 deletions
diff --git a/src/server/game/Entities/Item/ItemTemplate.cpp b/src/server/game/Entities/Item/ItemTemplate.cpp
index 77848112014..d76985b269d 100644
--- a/src/server/game/Entities/Item/ItemTemplate.cpp
+++ b/src/server/game/Entities/Item/ItemTemplate.cpp
@@ -212,9 +212,11 @@ void ItemTemplate::GetDamage(uint32 itemLevel, float& minDamage, float& maxDamag
maxDamage = floor(float(avgDamage * (GetStatScalingFactor() * 0.5f + 1.0f) + 0.5f));
}
-bool ItemTemplate::IsUsableBySpecialization(Player const* player) const
+bool ItemTemplate::IsUsableByLootSpecialization(Player const* player) const
{
- uint32 spec = player->GetUInt32Value(PLAYER_FIELD_CURRENT_SPEC_ID);
+ uint32 spec = player->GetUInt32Value(PLAYER_FIELD_LOOT_SPEC_ID);
+ if (!spec)
+ spec = player->GetUInt32Value(PLAYER_FIELD_CURRENT_SPEC_ID);
if (!spec)
spec = player->GetDefaultSpecId();
@@ -222,7 +224,13 @@ bool ItemTemplate::IsUsableBySpecialization(Player const* player) const
if (!chrSpecialization)
return false;
- return Specializations[player->getLevel() > 40].test(CalculateItemSpecBit(chrSpecialization));
+ std::size_t levelIndex = 0;
+ if (player->getLevel() >= 110)
+ levelIndex = 2;
+ else if (player->getLevel() > 40)
+ levelIndex = 1;
+
+ return Specializations[levelIndex].test(CalculateItemSpecBit(chrSpecialization));
}
std::size_t ItemTemplate::CalculateItemSpecBit(ChrSpecializationEntry const* spec)
diff --git a/src/server/game/Entities/Item/ItemTemplate.h b/src/server/game/Entities/Item/ItemTemplate.h
index fb08248e4d3..5b997200758 100644
--- a/src/server/game/Entities/Item/ItemTemplate.h
+++ b/src/server/game/Entities/Item/ItemTemplate.h
@@ -776,7 +776,7 @@ struct TC_GAME_API ItemTemplate
uint32 MaxMoneyLoot;
uint32 FlagsCu;
float SpellPPMRate;
- std::bitset<MAX_CLASSES * MAX_SPECIALIZATIONS> Specializations[2]; // one set for 1-40 level range and another for 41-100
+ std::bitset<MAX_CLASSES * MAX_SPECIALIZATIONS> Specializations[3]; // one set for 1-40 level range and another for 41-109 and one for 110
uint32 ItemSpecClassMask;
// helpers
@@ -807,7 +807,7 @@ struct TC_GAME_API ItemTemplate
char const* GetDefaultLocaleName() const;
uint32 GetArmor(uint32 itemLevel) const;
void GetDamage(uint32 itemLevel, float& minDamage, float& maxDamage) const;
- bool IsUsableBySpecialization(Player const* player) const;
+ bool IsUsableByLootSpecialization(Player const* player) const;
static std::size_t CalculateItemSpecBit(ChrSpecializationEntry const* spec);
};
diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp
index aacc602d3d6..a8d57558db5 100644
--- a/src/server/game/Entities/Player/Player.cpp
+++ b/src/server/game/Entities/Player/Player.cpp
@@ -14699,6 +14699,7 @@ bool Player::CanRewardQuest(Quest const* quest, uint32 reward, bool msg)
// QuestPackageItem.db2
if (quest->GetQuestPackageID())
{
+ bool hasFilteredQuestPackageReward = false;
if (std::vector<QuestPackageItemEntry const*> const* questPackageItems = sDB2Manager.GetQuestPackageItems(quest->GetQuestPackageID()))
{
for (QuestPackageItemEntry const* questPackageItem : *questPackageItems)
@@ -14706,16 +14707,33 @@ bool Player::CanRewardQuest(Quest const* quest, uint32 reward, bool msg)
if (questPackageItem->ItemID != reward)
continue;
- if (ItemTemplate const* rewardProto = sObjectMgr->GetItemTemplate(questPackageItem->ItemID))
+ if (CanSelectQuestPackageItem(questPackageItem))
{
- if (rewardProto->IsUsableBySpecialization(this))
+ hasFilteredQuestPackageReward = true;
+ InventoryResult res = CanStoreNewItem(NULL_BAG, NULL_SLOT, dest, questPackageItem->ItemID, questPackageItem->ItemCount);
+ if (res != EQUIP_ERR_OK)
{
- InventoryResult res = CanStoreNewItem(NULL_BAG, NULL_SLOT, dest, questPackageItem->ItemID, questPackageItem->ItemCount);
- if (res != EQUIP_ERR_OK)
- {
- SendEquipError(res, nullptr, nullptr, questPackageItem->ItemID);
- return false;
- }
+ SendEquipError(res, nullptr, nullptr, questPackageItem->ItemID);
+ return false;
+ }
+ }
+ }
+ }
+
+ if (!hasFilteredQuestPackageReward)
+ {
+ if (std::vector<QuestPackageItemEntry const*> const* questPackageItems = sDB2Manager.GetQuestPackageItemsFallback(quest->GetQuestPackageID()))
+ {
+ for (QuestPackageItemEntry const* questPackageItem : *questPackageItems)
+ {
+ if (questPackageItem->ItemID != reward)
+ continue;
+
+ InventoryResult res = CanStoreNewItem(NULL_BAG, NULL_SLOT, dest, questPackageItem->ItemID, questPackageItem->ItemCount);
+ if (res != EQUIP_ERR_OK)
+ {
+ SendEquipError(res, nullptr, nullptr, questPackageItem->ItemID);
+ return false;
}
}
}
@@ -14865,6 +14883,31 @@ uint32 Player::GetQuestXPReward(Quest const* quest)
return XP;
}
+bool Player::CanSelectQuestPackageItem(QuestPackageItemEntry const* questPackageItem) const
+{
+ ItemTemplate const* rewardProto = sObjectMgr->GetItemTemplate(questPackageItem->ItemID);
+ if (!rewardProto)
+ return false;
+
+ if ((rewardProto->GetFlags2() & ITEM_FLAG2_FACTION_ALLIANCE && GetTeam() != ALLIANCE) ||
+ (rewardProto->GetFlags2() & ITEM_FLAG2_FACTION_HORDE && GetTeam() != HORDE))
+ return false;
+
+ switch (questPackageItem->FilterType)
+ {
+ case QUEST_PACKAGE_FILTER_LOOT_SPECIALIZATION:
+ return rewardProto->IsUsableByLootSpecialization(this);
+ case QUEST_PACKAGE_FILTER_CLASS:
+ return (rewardProto->ItemSpecClassMask & getClassMask()) != 0;
+ case QUEST_PACKAGE_FILTER_EVERYONE:
+ return true;
+ default:
+ break;
+ }
+
+ return false;
+}
+
void Player::RewardQuest(Quest const* quest, uint32 reward, Object* questGiver, bool announce)
{
//this THING should be here to protect code from quest, which cast on player far teleport as a reward
@@ -14901,7 +14944,8 @@ void Player::RewardQuest(Quest const* quest, uint32 reward, Object* questGiver,
RemoveTimedQuest(quest_id);
- if (quest->GetRewChoiceItemsCount() > 0)
+ ItemTemplate const* rewardProto = sObjectMgr->GetItemTemplate(reward);
+ if (rewardProto && quest->GetRewChoiceItemsCount())
{
for (uint32 i = 0; i < quest->GetRewChoiceItemsCount(); ++i)
{
@@ -14918,8 +14962,9 @@ void Player::RewardQuest(Quest const* quest, uint32 reward, Object* questGiver,
}
// QuestPackageItem.db2
- if (quest->GetQuestPackageID())
+ if (rewardProto && quest->GetQuestPackageID())
{
+ bool hasFilteredQuestPackageReward = false;
if (std::vector<QuestPackageItemEntry const*> const* questPackageItems = sDB2Manager.GetQuestPackageItems(quest->GetQuestPackageID()))
{
for (QuestPackageItemEntry const* questPackageItem : *questPackageItems)
@@ -14927,16 +14972,33 @@ void Player::RewardQuest(Quest const* quest, uint32 reward, Object* questGiver,
if (questPackageItem->ItemID != reward)
continue;
- if (ItemTemplate const* rewardProto = sObjectMgr->GetItemTemplate(questPackageItem->ItemID))
+ if (CanSelectQuestPackageItem(questPackageItem))
{
- if (rewardProto->IsUsableBySpecialization(this))
+ hasFilteredQuestPackageReward = true;
+ ItemPosCountVec dest;
+ if (CanStoreNewItem(NULL_BAG, NULL_SLOT, dest, questPackageItem->ItemID, questPackageItem->ItemCount) == EQUIP_ERR_OK)
{
- ItemPosCountVec dest;
- if (CanStoreNewItem(NULL_BAG, NULL_SLOT, dest, questPackageItem->ItemID, questPackageItem->ItemCount) == EQUIP_ERR_OK)
- {
- Item* item = StoreNewItem(dest, questPackageItem->ItemID, true, Item::GenerateItemRandomPropertyId(questPackageItem->ItemID));
- SendNewItem(item, questPackageItem->ItemCount, true, false);
- }
+ Item* item = StoreNewItem(dest, questPackageItem->ItemID, true, Item::GenerateItemRandomPropertyId(questPackageItem->ItemID));
+ SendNewItem(item, questPackageItem->ItemCount, true, false);
+ }
+ }
+ }
+ }
+
+ if (!hasFilteredQuestPackageReward)
+ {
+ if (std::vector<QuestPackageItemEntry const*> const* questPackageItems = sDB2Manager.GetQuestPackageItemsFallback(quest->GetQuestPackageID()))
+ {
+ for (QuestPackageItemEntry const* questPackageItem : *questPackageItems)
+ {
+ if (questPackageItem->ItemID != reward)
+ continue;
+
+ ItemPosCountVec dest;
+ if (CanStoreNewItem(NULL_BAG, NULL_SLOT, dest, questPackageItem->ItemID, questPackageItem->ItemCount) == EQUIP_ERR_OK)
+ {
+ Item* item = StoreNewItem(dest, questPackageItem->ItemID, true, Item::GenerateItemRandomPropertyId(questPackageItem->ItemID));
+ SendNewItem(item, questPackageItem->ItemCount, true, false);
}
}
}
diff --git a/src/server/game/Entities/Player/Player.h b/src/server/game/Entities/Player/Player.h
index 97fe7df32c1..d39c9d3e314 100644
--- a/src/server/game/Entities/Player/Player.h
+++ b/src/server/game/Entities/Player/Player.h
@@ -1529,6 +1529,7 @@ class TC_GAME_API Player : public Unit, public GridObject<Player>
void IncompleteQuest(uint32 quest_id);
uint32 GetQuestMoneyReward(Quest const* quest) const;
uint32 GetQuestXPReward(Quest const* quest);
+ bool CanSelectQuestPackageItem(QuestPackageItemEntry const* questPackageItem) const;
void RewardQuest(Quest const* quest, uint32 reward, Object* questGiver, bool announce = true);
void FailQuest(uint32 quest_id);
bool SatisfyQuestSkill(Quest const* qInfo, bool msg) const;