Fix missions re-ordering on reload (#686)

* Fix missions re-ordering on reload

Check for success rather than failure

* Add a comment

* Get base value from database

* Update Mission.h
This commit is contained in:
David Markowitz 2022-07-30 20:56:21 -07:00 committed by GitHub
parent f80a26a944
commit d64fa1680d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 59 additions and 4 deletions

View File

@ -24,6 +24,7 @@ std::unordered_map<size_t, std::vector<uint32_t>> MissionComponent::m_Achievemen
//! Initializer //! Initializer
MissionComponent::MissionComponent(Entity* parent) : Component(parent) { MissionComponent::MissionComponent(Entity* parent) : Component(parent) {
m_LastUsedMissionOrderUID = dZoneManager::Instance()->GetUniqueMissionIdStartingValue();
} }
//! Destructor //! Destructor
@ -83,6 +84,7 @@ void MissionComponent::AcceptMission(const uint32_t missionId, const bool skipCh
if (mission != nullptr) { if (mission != nullptr) {
if (mission->GetClientInfo().repeatable) { if (mission->GetClientInfo().repeatable) {
mission->Accept(); mission->Accept();
if (mission->IsMission()) mission->SetUniqueMissionOrderID(++m_LastUsedMissionOrderUID);
} }
return; return;
@ -90,6 +92,8 @@ void MissionComponent::AcceptMission(const uint32_t missionId, const bool skipCh
mission = new Mission(this, missionId); mission = new Mission(this, missionId);
if (mission->IsMission()) mission->SetUniqueMissionOrderID(++m_LastUsedMissionOrderUID);
mission->Accept(); mission->Accept();
this->m_Missions.insert_or_assign(missionId, mission); this->m_Missions.insert_or_assign(missionId, mission);
@ -299,6 +303,8 @@ bool MissionComponent::LookForAchievements(MissionTaskType type, int32_t value,
m_Missions.insert_or_assign(missionID, instance); m_Missions.insert_or_assign(missionID, instance);
if (instance->IsMission()) instance->SetUniqueMissionOrderID(++m_LastUsedMissionOrderUID);
instance->Accept(); instance->Accept();
any = true; any = true;
@ -368,6 +374,8 @@ bool MissionComponent::LookForAchievements(MissionTaskType type, int32_t value,
m_Missions.insert_or_assign(mission.id, instance); m_Missions.insert_or_assign(mission.id, instance);
if (instance->IsMission()) instance->SetUniqueMissionOrderID(++m_LastUsedMissionOrderUID);
instance->Accept(); instance->Accept();
any = true; any = true;
@ -523,6 +531,7 @@ void MissionComponent::LoadFromXml(tinyxml2::XMLDocument* doc) {
auto* currentM = cur->FirstChildElement(); auto* currentM = cur->FirstChildElement();
uint32_t missionOrder{};
while (currentM) { while (currentM) {
int missionId; int missionId;
@ -532,6 +541,11 @@ void MissionComponent::LoadFromXml(tinyxml2::XMLDocument* doc) {
mission->LoadFromXml(currentM); mission->LoadFromXml(currentM);
if (currentM->QueryAttribute("o", &missionOrder) == tinyxml2::XML_SUCCESS && mission->IsMission()) {
mission->SetUniqueMissionOrderID(missionOrder);
if (missionOrder > m_LastUsedMissionOrderUID) m_LastUsedMissionOrderUID = missionOrder;
}
currentM = currentM->NextSiblingElement(); currentM = currentM->NextSiblingElement();
m_Missions.insert_or_assign(missionId, mission); m_Missions.insert_or_assign(missionId, mission);
@ -565,17 +579,16 @@ void MissionComponent::UpdateXml(tinyxml2::XMLDocument* doc) {
if (mission) { if (mission) {
const auto complete = mission->IsComplete(); const auto complete = mission->IsComplete();
if (complete) { auto* m = doc->NewElement("m");
auto* m = doc->NewElement("m");
if (complete) {
mission->UpdateXml(m); mission->UpdateXml(m);
done->LinkEndChild(m); done->LinkEndChild(m);
continue; continue;
} }
if (mission->IsMission()) m->SetAttribute("o", mission->GetUniqueMissionOrderID());
auto* m = doc->NewElement("m");
mission->UpdateXml(m); mission->UpdateXml(m);

View File

@ -193,6 +193,13 @@ private:
* combination of tasks and values, so that they can be easily re-queried later * combination of tasks and values, so that they can be easily re-queried later
*/ */
static std::unordered_map<size_t, std::vector<uint32_t>> m_AchievementCache; static std::unordered_map<size_t, std::vector<uint32_t>> m_AchievementCache;
/**
* Order of missions in the UI. This value is incremented by 1
* for each mission the Entity that owns this component accepts.
* In live this value started at 745.
*/
uint32_t m_LastUsedMissionOrderUID = 746U;
}; };
#endif // MISSIONCOMPONENT_H #endif // MISSIONCOMPONENT_H

View File

@ -26,6 +26,8 @@ Mission::Mission(MissionComponent* missionComponent, const uint32_t missionId) {
m_Timestamp = 0; m_Timestamp = 0;
m_UniqueMissionID = dZoneManager::Instance()->GetUniqueMissionIdStartingValue();
m_Reward = 0; m_Reward = 0;
m_State = MissionState::MISSION_STATE_UNKNOWN; m_State = MissionState::MISSION_STATE_UNKNOWN;
@ -283,6 +285,7 @@ void Mission::Accept() {
void Mission::Complete(const bool yieldRewards) { void Mission::Complete(const bool yieldRewards) {
if (m_State != MissionState::MISSION_STATE_ACTIVE && m_State != MissionState::MISSION_STATE_COMPLETE_ACTIVE) { if (m_State != MissionState::MISSION_STATE_ACTIVE && m_State != MissionState::MISSION_STATE_COMPLETE_ACTIVE) {
// If we are accepting a mission here there is no point to giving it a unique ID since we just complete it immediately.
Accept(); Accept();
} }

View File

@ -220,6 +220,18 @@ public:
* @return true if the mission exists, false otherwise * @return true if the mission exists, false otherwise
*/ */
static bool IsValidMission(uint32_t missionId, CDMissions& info); static bool IsValidMission(uint32_t missionId, CDMissions& info);
/**
* @brief Returns the unique mission order ID
*
* @return The unique order ID
*/
uint32_t GetUniqueMissionOrderID() { return m_UniqueMissionID; };
/**
* Sets the unique mission order ID of this mission
*/
void SetUniqueMissionOrderID(uint32_t value) { m_UniqueMissionID = value; };
private: private:
/** /**
* Progresses all the newly accepted tasks for this mission after it has been accepted to reflect the state of the * Progresses all the newly accepted tasks for this mission after it has been accepted to reflect the state of the
@ -261,6 +273,11 @@ private:
* All the tasks that can be progressed for this mission * All the tasks that can be progressed for this mission
*/ */
std::vector<MissionTask*> m_Tasks; std::vector<MissionTask*> m_Tasks;
/**
* The unique ID what order this mission was accepted in.
*/
uint32_t m_UniqueMissionID;
}; };
#endif #endif

View File

@ -240,3 +240,12 @@ std::vector<Spawner*> dZoneManager::GetSpawnersInGroup(std::string group) {
return spawnersInGroup; return spawnersInGroup;
} }
uint32_t dZoneManager::GetUniqueMissionIdStartingValue() {
if (m_UniqueMissionIdStart == 0) {
auto tableData = CDClientDatabase::ExecuteQuery("SELECT COUNT(*) FROM Missions WHERE isMission = 0 GROUP BY isMission;");
m_UniqueMissionIdStart = tableData.getIntField(0, -1);
tableData.finalize();
}
return m_UniqueMissionIdStart;
}

View File

@ -43,6 +43,7 @@ public:
void Update(float deltaTime); void Update(float deltaTime);
Entity* GetZoneControlObject() { return m_ZoneControlObject; } Entity* GetZoneControlObject() { return m_ZoneControlObject; }
bool GetPlayerLoseCoinOnDeath() { return m_PlayerLoseCoinsOnDeath; } bool GetPlayerLoseCoinOnDeath() { return m_PlayerLoseCoinsOnDeath; }
uint32_t GetUniqueMissionIdStartingValue();
private: private:
/** /**
@ -55,6 +56,11 @@ private:
*/ */
int32_t m_CurrencyConversionRate = 0; int32_t m_CurrencyConversionRate = 0;
/**
* The starting unique mission ID.
*/
uint32_t m_UniqueMissionIdStart = 0;
static dZoneManager* m_Address; //Singleton static dZoneManager* m_Address; //Singleton
Zone* m_pZone; Zone* m_pZone;
LWOZONEID m_ZoneID; LWOZONEID m_ZoneID;