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

View File

@ -193,6 +193,13 @@ private:
* 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;
/**
* 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

View File

@ -26,6 +26,8 @@ Mission::Mission(MissionComponent* missionComponent, const uint32_t missionId) {
m_Timestamp = 0;
m_UniqueMissionID = dZoneManager::Instance()->GetUniqueMissionIdStartingValue();
m_Reward = 0;
m_State = MissionState::MISSION_STATE_UNKNOWN;
@ -283,6 +285,7 @@ void Mission::Accept() {
void Mission::Complete(const bool yieldRewards) {
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();
}

View File

@ -220,6 +220,18 @@ public:
* @return true if the mission exists, false otherwise
*/
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:
/**
* 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
*/
std::vector<MissionTask*> m_Tasks;
/**
* The unique ID what order this mission was accepted in.
*/
uint32_t m_UniqueMissionID;
};
#endif

View File

@ -240,3 +240,12 @@ std::vector<Spawner*> dZoneManager::GetSpawnersInGroup(std::string group) {
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);
Entity* GetZoneControlObject() { return m_ZoneControlObject; }
bool GetPlayerLoseCoinOnDeath() { return m_PlayerLoseCoinsOnDeath; }
uint32_t GetUniqueMissionIdStartingValue();
private:
/**
@ -55,6 +56,11 @@ private:
*/
int32_t m_CurrencyConversionRate = 0;
/**
* The starting unique mission ID.
*/
uint32_t m_UniqueMissionIdStart = 0;
static dZoneManager* m_Address; //Singleton
Zone* m_pZone;
LWOZONEID m_ZoneID;