diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/server/game/Entities/Player/Player.cpp | 74 | ||||
-rw-r--r-- | src/server/game/Entities/Player/Player.h | 3 | ||||
-rw-r--r-- | src/server/game/Handlers/MiscHandler.cpp | 7 | ||||
-rw-r--r-- | src/server/game/Quests/QuestDef.h | 15 | ||||
-rw-r--r-- | src/server/game/Server/Packets/QuestPackets.cpp | 9 | ||||
-rw-r--r-- | src/server/game/Server/Packets/QuestPackets.h | 14 | ||||
-rw-r--r-- | src/server/game/Server/Protocol/Opcodes.cpp | 2 |
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); |