aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/server/game/Entities/Player/Player.cpp74
-rw-r--r--src/server/game/Entities/Player/Player.h3
-rw-r--r--src/server/game/Handlers/MiscHandler.cpp7
-rw-r--r--src/server/game/Quests/QuestDef.h15
-rw-r--r--src/server/game/Server/Packets/QuestPackets.cpp9
-rw-r--r--src/server/game/Server/Packets/QuestPackets.h14
-rw-r--r--src/server/game/Server/Protocol/Opcodes.cpp2
7 files changed, 89 insertions, 35 deletions
diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp
index 1b03615ca1b..0954cebe91d 100644
--- a/src/server/game/Entities/Player/Player.cpp
+++ b/src/server/game/Entities/Player/Player.cpp
@@ -16215,7 +16215,7 @@ void Player::AdjustQuestReqItemCount(Quest const* quest)
uint32 reqItemCount = obj.Amount;
uint32 curItemCount = GetItemCount(obj.ObjectID, true);
- SetQuestObjectiveData(quest, obj.StorageIndex, std::min(curItemCount, reqItemCount));
+ SetQuestObjectiveData(obj, std::min(curItemCount, reqItemCount));
}
}
}
@@ -16370,7 +16370,7 @@ void Player::ItemAddedQuestCheck(uint32 entry, uint32 count)
if (curItemCount < reqItemCount)
{
uint32 newItemCount = std::min<uint32>(curItemCount + count, reqItemCount);
- SetQuestObjectiveData(qInfo, obj.StorageIndex, newItemCount);
+ SetQuestObjectiveData(obj, newItemCount);
//SendQuestUpdateAddItem(qInfo, j, additemcount);
// FIXME: verify if there's any packet sent updating item
@@ -16419,7 +16419,7 @@ void Player::ItemRemovedQuestCheck(uint32 entry, uint32 count)
if (newItemCount < reqItemCount)
{
- SetQuestObjectiveData(qInfo, obj.StorageIndex, newItemCount);
+ SetQuestObjectiveData(obj, newItemCount);
IncompleteQuest(questid);
}
return;
@@ -16485,7 +16485,7 @@ void Player::KilledMonsterCredit(uint32 entry, ObjectGuid guid /*= ObjectGuid::E
uint16 curKillCount = GetQuestObjectiveData(qInfo, obj.StorageIndex);
if (curKillCount < reqKillCount)
{
- SetQuestObjectiveData(qInfo, obj.StorageIndex, curKillCount + addKillCount);
+ SetQuestObjectiveData(obj, curKillCount + addKillCount);
SendQuestUpdateAddCredit(qInfo, guid, obj, curKillCount + addKillCount);
}
@@ -16531,7 +16531,7 @@ void Player::KilledPlayerCredit()
uint32 curKillCount = GetQuestObjectiveData(qInfo, obj.StorageIndex);
if (curKillCount < uint32(obj.Amount))
{
- SetQuestObjectiveData(qInfo, obj.StorageIndex, curKillCount + addKillCount);
+ SetQuestObjectiveData(obj, curKillCount + addKillCount);
SendQuestUpdateAddPlayer(qInfo, curKillCount + addKillCount);
}
@@ -16579,7 +16579,7 @@ void Player::KillCreditGO(uint32 entry, ObjectGuid guid)
uint32 curCastCount = GetQuestObjectiveData(qInfo, obj.StorageIndex);
if (curCastCount < reqCastCount)
{
- SetQuestObjectiveData(qInfo, obj.StorageIndex, curCastCount + addCastCount);
+ SetQuestObjectiveData(obj, curCastCount + addCastCount);
SendQuestUpdateAddCredit(qInfo, guid, obj, curCastCount + addCastCount);
}
@@ -16626,7 +16626,7 @@ void Player::TalkedToCreature(uint32 entry, ObjectGuid guid)
uint32 curTalkCount = GetQuestObjectiveData(qInfo, obj.StorageIndex);
if (curTalkCount < reqTalkCount)
{
- SetQuestObjectiveData(qInfo, obj.StorageIndex, curTalkCount + addTalkCount);
+ SetQuestObjectiveData(obj, curTalkCount + addTalkCount);
SendQuestUpdateAddCredit(qInfo, guid, obj, curTalkCount + addTalkCount);
}
@@ -16744,15 +16744,12 @@ void Player::CurrencyChanged(uint32 currencyId, int32 change)
if (uint32(obj.ObjectID) != currencyId)
continue;
- if (obj.Type != QUEST_OBJECTIVE_HAVE_CURRENCY)
- continue;
-
QuestStatusData& q_status = m_QuestStatus[questid];
if (obj.Type == QUEST_OBJECTIVE_CURRENCY || obj.Type == QUEST_OBJECTIVE_HAVE_CURRENCY)
{
int64 value = GetCurrency(currencyId);
if (obj.Type == QUEST_OBJECTIVE_HAVE_CURRENCY)
- SetQuestObjectiveData(qInfo, obj.StorageIndex, int32(std::min<int64>(value, obj.Amount)));
+ SetQuestObjectiveData(obj, int32(std::min<int64>(value, obj.Amount)));
if (q_status.Status == QUEST_STATUS_INCOMPLETE)
{
@@ -16771,7 +16768,7 @@ void Player::CurrencyChanged(uint32 currencyId, int32 change)
else if (obj.Type == QUEST_OBJECTIVE_OBTAIN_CURRENCY && change > 0) // currency losses are not accounted for in this objective type
{
int64 currentProgress = GetQuestObjectiveData(qInfo, obj.StorageIndex);
- SetQuestObjectiveData(qInfo, obj.StorageIndex, int32(std::max(std::min<int64>(currentProgress + change, obj.Amount), SI64LIT(0))));
+ SetQuestObjectiveData(obj, int32(std::max(std::min<int64>(currentProgress + change, obj.Amount), SI64LIT(0))));
if (CanCompleteQuest(questid))
CompleteQuest(questid);
}
@@ -16919,44 +16916,51 @@ bool Player::IsQuestObjectiveComplete(QuestObjective const& objective) const
return true;
}
-void Player::SetQuestObjectiveData(Quest const* quest, int8 storageIndex, int32 data)
+void Player::SetQuestObjectiveData(QuestObjective const& objective, int32 data)
{
- if (storageIndex < 0)
+ if (objective.StorageIndex < 0)
TC_LOG_ERROR("entities.player.quest", "Player::SetQuestObjectiveData: called for quest %u with invalid StorageIndex %d (objective data is not tracked)",
- quest->GetQuestId(), storageIndex);
+ objective.QuestID, objective.StorageIndex);
- auto itr = m_QuestStatus.find(quest->GetQuestId());
+ auto itr = m_QuestStatus.find(objective.QuestID);
if (itr == m_QuestStatus.end())
{
TC_LOG_ERROR("entities.player.quest", "Player::SetQuestObjectiveData: player '%s' (%s) doesn't have quest status data (QuestID: %u)",
- GetName().c_str(), GetGUID().ToString().c_str(), quest->GetQuestId());
+ GetName().c_str(), GetGUID().ToString().c_str(), objective.QuestID);
return;
}
QuestStatusData& status = itr->second;
- if (uint8(storageIndex) >= status.ObjectiveData.size())
+ if (uint8(objective.StorageIndex) >= status.ObjectiveData.size())
{
TC_LOG_ERROR("entities.player.quest", "Player::SetQuestObjectiveData: player '%s' (%s) quest %u out of range StorageIndex %u",
- GetName().c_str(), GetGUID().ToString().c_str(), quest->GetQuestId(), storageIndex);
+ GetName().c_str(), GetGUID().ToString().c_str(), objective.QuestID, objective.StorageIndex);
return;
}
// No change
- if (status.ObjectiveData[storageIndex] == data)
+ if (status.ObjectiveData[objective.StorageIndex] == data)
return;
// Set data
- status.ObjectiveData[storageIndex] = data;
+ status.ObjectiveData[objective.StorageIndex] = data;
// Add to save
- m_QuestStatusSave[quest->GetQuestId()] = QUEST_DEFAULT_SAVE_TYPE;
+ m_QuestStatusSave[objective.QuestID] = QUEST_DEFAULT_SAVE_TYPE;
// Update quest fields
- uint16 log_slot = FindQuestSlot(quest->GetQuestId());
+ uint16 log_slot = FindQuestSlot(objective.QuestID);
if (log_slot < MAX_QUEST_LOG_SIZE)
- SetQuestSlotCounter(log_slot, storageIndex, status.ObjectiveData[storageIndex]);
+ {
+ if (!objective.IsStoringFlag())
+ SetQuestSlotCounter(log_slot, objective.StorageIndex, status.ObjectiveData[objective.StorageIndex]);
+ else if (data)
+ SetQuestSlotState(log_slot, 256 << objective.StorageIndex);
+ else
+ RemoveQuestSlotState(log_slot, 256 << objective.StorageIndex);
+ }
}
void Player::SendQuestComplete(Quest const* quest) const
@@ -17080,6 +17084,15 @@ void Player::SendQuestUpdateAddCredit(Quest const* quest, ObjectGuid guid, Quest
GetSession()->SendPacket(packet.Write());
}
+void Player::SendQuestUpdateAddCreditSimple(QuestObjective const& obj) const
+{
+ WorldPackets::Quest::QuestUpdateAddCreditSimple packet;
+ packet.QuestID = obj.QuestID;
+ packet.ObjectID = obj.ObjectID;
+ packet.ObjectiveType = obj.Type;
+ SendDirectMessage(packet.Write());
+}
+
void Player::SendQuestUpdateAddPlayer(Quest const* quest, uint16 newCount) const
{
WorldPackets::Quest::QuestUpdateAddPvPCredit questUpdateAddPvpCredit;
@@ -18956,19 +18969,22 @@ void Player::_LoadQuestStatusObjectives(PreparedQueryResult result)
Field* fields = result->Fetch();
uint32 questID = fields[0].GetUInt32();
-
+ Quest const* quest = sObjectMgr->GetQuestTemplate(questID);
uint16 slot = FindQuestSlot(questID);
auto itr = m_QuestStatus.find(questID);
- if (itr != m_QuestStatus.end() && slot < MAX_QUEST_LOG_SIZE)
+ if (itr != m_QuestStatus.end() && slot < MAX_QUEST_LOG_SIZE && quest)
{
QuestStatusData& questStatusData = itr->second;
uint8 objectiveIndex = fields[1].GetUInt8();
-
- if (objectiveIndex < questStatusData.ObjectiveData.size())
+ auto objectiveItr = std::find_if(quest->Objectives.begin(), quest->Objectives.end(), [=](QuestObjective const& objective) { return uint8(objective.StorageIndex) == objectiveIndex; });
+ if (objectiveIndex < questStatusData.ObjectiveData.size() && objectiveItr != quest->Objectives.end())
{
int32 data = fields[2].GetInt32();
questStatusData.ObjectiveData[objectiveIndex] = data;
- SetQuestSlotCounter(slot, objectiveIndex, data);
+ if (!objectiveItr->IsStoringFlag())
+ SetQuestSlotCounter(slot, objectiveIndex, data);
+ else if (data)
+ SetQuestSlotState(slot, 256 << objectiveIndex);
}
else
TC_LOG_ERROR("entities.player", "Player::_LoadQuestStatusObjectives: Player '%s' (%s) has quest %d out of range objective index %u.", GetName().c_str(), GetGUID().ToString().c_str(), questID, objectiveIndex);
diff --git a/src/server/game/Entities/Player/Player.h b/src/server/game/Entities/Player/Player.h
index 140d46758ef..f1006c14e0f 100644
--- a/src/server/game/Entities/Player/Player.h
+++ b/src/server/game/Entities/Player/Player.h
@@ -1431,7 +1431,7 @@ class TC_GAME_API Player : public Unit, public GridObject<Player>
int32 GetQuestObjectiveData(Quest const* quest, int8 storageIndex) const;
bool IsQuestObjectiveComplete(QuestObjective const& objective) const;
- void SetQuestObjectiveData(Quest const* quest, int8 storageIndex, int32 data);
+ void SetQuestObjectiveData(QuestObjective const& objective, int32 data);
bool IsQuestObjectiveProgressComplete(Quest const* quest) const;
void SendQuestComplete(Quest const* quest) const;
void SendQuestReward(Quest const* quest, uint32 XP) const;
@@ -1441,6 +1441,7 @@ class TC_GAME_API Player : public Unit, public GridObject<Player>
void SendQuestConfirmAccept(Quest const* quest, Player* receiver) const;
void SendPushToPartyResponse(Player* player, QuestPushReason reason) const;
void SendQuestUpdateAddCredit(Quest const* quest, ObjectGuid guid, QuestObjective const& obj, uint16 count) const;
+ void SendQuestUpdateAddCreditSimple(QuestObjective const& obj) const;
void SendQuestUpdateAddPlayer(Quest const* quest, uint16 newCount) const;
void SendQuestGiverStatusMultiple();
diff --git a/src/server/game/Handlers/MiscHandler.cpp b/src/server/game/Handlers/MiscHandler.cpp
index b70dce9a901..24369347dba 100644
--- a/src/server/game/Handlers/MiscHandler.cpp
+++ b/src/server/game/Handlers/MiscHandler.cpp
@@ -511,11 +511,12 @@ void WorldSession::HandleAreaTriggerOpcode(WorldPackets::AreaTrigger::AreaTrigge
Quest const* qInfo = sObjectMgr->GetQuestTemplate(questId);
if (qInfo && player->GetQuestStatus(questId) == QUEST_STATUS_INCOMPLETE)
{
- for (uint8 j = 0; j < qInfo->Objectives.size(); ++j)
+ for (QuestObjective const& obj : qInfo->Objectives)
{
- if (qInfo->Objectives[j].Type == QUEST_OBJECTIVE_AREATRIGGER)
+ if (obj.Type == QUEST_OBJECTIVE_AREATRIGGER && !player->IsQuestObjectiveComplete(obj))
{
- player->SetQuestObjectiveData(qInfo, j, int32(true));
+ player->SetQuestObjectiveData(obj, 1);
+ player->SendQuestUpdateAddCreditSimple(obj);
break;
}
}
diff --git a/src/server/game/Quests/QuestDef.h b/src/server/game/Quests/QuestDef.h
index 9ce57084b6a..237ba1147d6 100644
--- a/src/server/game/Quests/QuestDef.h
+++ b/src/server/game/Quests/QuestDef.h
@@ -289,6 +289,21 @@ struct QuestObjective
float ProgressBarWeight = 0.0f;
std::string Description;
std::vector<int32> VisualEffects;
+
+ bool IsStoringFlag() const
+ {
+ switch (Type)
+ {
+ case QUEST_OBJECTIVE_AREATRIGGER:
+ case QUEST_OBJECTIVE_WINPETBATTLEAGAINSTNPC:
+ case QUEST_OBJECTIVE_DEFEATBATTLEPET:
+ case QUEST_OBJECTIVE_CRITERIA_TREE:
+ return true;
+ default:
+ break;
+ }
+ return false;
+ }
};
typedef std::vector<QuestObjective> QuestObjectives;
diff --git a/src/server/game/Server/Packets/QuestPackets.cpp b/src/server/game/Server/Packets/QuestPackets.cpp
index 69b87c3fc0a..5ccb0e9b745 100644
--- a/src/server/game/Server/Packets/QuestPackets.cpp
+++ b/src/server/game/Server/Packets/QuestPackets.cpp
@@ -201,6 +201,15 @@ WorldPacket const* WorldPackets::Quest::QuestUpdateAddCredit::Write()
return &_worldPacket;
};
+WorldPacket const* WorldPackets::Quest::QuestUpdateAddCreditSimple::Write()
+{
+ _worldPacket << int32(QuestID);
+ _worldPacket << int32(ObjectID);
+ _worldPacket << uint8(ObjectiveType);
+
+ return &_worldPacket;
+}
+
WorldPacket const* WorldPackets::Quest::QuestUpdateAddPvPCredit::Write()
{
_worldPacket << int32(QuestID);
diff --git a/src/server/game/Server/Packets/QuestPackets.h b/src/server/game/Server/Packets/QuestPackets.h
index 12d94ac4527..241771961a7 100644
--- a/src/server/game/Server/Packets/QuestPackets.h
+++ b/src/server/game/Server/Packets/QuestPackets.h
@@ -187,7 +187,7 @@ namespace WorldPackets
class QuestUpdateAddCredit final : public ServerPacket
{
public:
- QuestUpdateAddCredit() : ServerPacket(SMSG_QUEST_UPDATE_ADD_CREDIT, 16+4+4+2+2+1) { }
+ QuestUpdateAddCredit() : ServerPacket(SMSG_QUEST_UPDATE_ADD_CREDIT, 16 + 4 + 4 + 2 + 2 + 1) { }
WorldPacket const* Write() override;
@@ -199,6 +199,18 @@ namespace WorldPackets
uint8 ObjectiveType = 0;
};
+ class QuestUpdateAddCreditSimple final : public ServerPacket
+ {
+ public:
+ QuestUpdateAddCreditSimple() : ServerPacket(SMSG_QUEST_UPDATE_ADD_CREDIT_SIMPLE, 4 + 4 + 1) { }
+
+ WorldPacket const* Write() override;
+
+ int32 QuestID = 0;
+ int32 ObjectID = 0;
+ uint8 ObjectiveType = 0;
+ };
+
class QuestUpdateAddPvPCredit final : public ServerPacket
{
public:
diff --git a/src/server/game/Server/Protocol/Opcodes.cpp b/src/server/game/Server/Protocol/Opcodes.cpp
index 35c77b92e2c..b33cff4fd6a 100644
--- a/src/server/game/Server/Protocol/Opcodes.cpp
+++ b/src/server/game/Server/Protocol/Opcodes.cpp
@@ -1594,7 +1594,7 @@ void OpcodeTable::Initialize()
DEFINE_SERVER_OPCODE_HANDLER(SMSG_QUEST_PUSH_RESULT, STATUS_NEVER, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_QUEST_SPAWN_TRACKING_UPDATE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_QUEST_UPDATE_ADD_CREDIT, STATUS_NEVER, CONNECTION_TYPE_INSTANCE);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_QUEST_UPDATE_ADD_CREDIT_SIMPLE, STATUS_UNHANDLED, CONNECTION_TYPE_INSTANCE);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_QUEST_UPDATE_ADD_CREDIT_SIMPLE, STATUS_NEVER, CONNECTION_TYPE_INSTANCE);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_QUEST_UPDATE_ADD_PVP_CREDIT, STATUS_NEVER, CONNECTION_TYPE_INSTANCE);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_QUEST_UPDATE_COMPLETE, STATUS_NEVER, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_QUEST_UPDATE_COMPLETE_BY_SPELL, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);