diff --git a/dGame/dMission/Mission.cpp b/dGame/dMission/Mission.cpp index 085fc38b5..a30c785fc 100644 --- a/dGame/dMission/Mission.cpp +++ b/dGame/dMission/Mission.cpp @@ -24,9 +24,18 @@ #include "eMissionTaskType.h" #include "eMissionLockState.h" #include "eReplicaComponentType.h" - #include "CDMissionEmailTable.h" +Mission::Mission() { + m_MissionComponent = nullptr; + m_Completions = 0; + m_Timestamp = 0; + m_Reward = 0; + m_UniqueMissionID = 0; + m_State = eMissionState::UNKNOWN; + info = nullptr; +} + Mission::Mission(MissionComponent* missionComponent, const uint32_t missionId) { m_MissionComponent = missionComponent; @@ -205,7 +214,7 @@ bool Mission::IsValidMission(const uint32_t missionId, CDMissions& info) { } Entity* Mission::GetAssociate() const { - return m_MissionComponent->GetParent(); + return m_MissionComponent != nullptr? m_MissionComponent->GetParent() : nullptr; } User* Mission::GetUser() const { diff --git a/dGame/dMission/Mission.h b/dGame/dMission/Mission.h index f7c17003c..4919176aa 100644 --- a/dGame/dMission/Mission.h +++ b/dGame/dMission/Mission.h @@ -24,6 +24,7 @@ class MissionComponent; class Mission final { public: + Mission(); Mission(MissionComponent* missionComponent, uint32_t missionId); ~Mission(); diff --git a/dGame/dMission/MissionPrerequisites.cpp b/dGame/dMission/MissionPrerequisites.cpp index ec4522b9d..08e628b14 100644 --- a/dGame/dMission/MissionPrerequisites.cpp +++ b/dGame/dMission/MissionPrerequisites.cpp @@ -105,9 +105,7 @@ bool PrerequisiteExpression::Execute(const std::unordered_mapsub != 0) { // Special case for one Wisp Lee repeatable mission. - a = mission->GetClientInfo().id == 1883 ? - mission->GetMissionState() == static_cast(this->sub) : - mission->GetMissionState() >= static_cast(this->sub); + a = mission->GetMissionState() == static_cast(this->sub); } else if (mission->IsComplete()) { a = true; } diff --git a/dGame/dMission/MissionPrerequisites.h b/dGame/dMission/MissionPrerequisites.h index 13b8e903a..0821c364c 100644 --- a/dGame/dMission/MissionPrerequisites.h +++ b/dGame/dMission/MissionPrerequisites.h @@ -10,6 +10,7 @@ */ class PrerequisiteExpression final { +public: bool m_or; uint32_t a; uint32_t sub; diff --git a/tests/dGameTests/CMakeLists.txt b/tests/dGameTests/CMakeLists.txt index b1fdaa070..8f446e650 100644 --- a/tests/dGameTests/CMakeLists.txt +++ b/tests/dGameTests/CMakeLists.txt @@ -1,5 +1,6 @@ set(DGAMETEST_SOURCES "GameDependencies.cpp" + "MissionPrerequisiteTest.cpp" ) add_subdirectory(dComponentsTests) diff --git a/tests/dGameTests/MissionPrerequisiteTest.cpp b/tests/dGameTests/MissionPrerequisiteTest.cpp new file mode 100644 index 000000000..ec14ec10a --- /dev/null +++ b/tests/dGameTests/MissionPrerequisiteTest.cpp @@ -0,0 +1,213 @@ +#include "GameDependencies.h" +#include + +#include "MissionPrerequisites.h" +#include "eMissionState.h" + +class MissionPrerequisiteTest : public GameDependenciesTest { +protected: + std::unordered_map missionMap; + void SetUp() override { + SetUpDependencies(); + } + + void TearDown() override { + TearDownDependencies(); + for (auto mission : missionMap) { + if (mission.second) delete mission.second; + } + } +}; + +/** + * Test that the structure of a single prerequisite mission is created correctly. + */ +TEST_F(MissionPrerequisiteTest, OneMissionPrerequisiteInitializeTest) { + auto* preReq = new PrerequisiteExpression("1964"); + ASSERT_EQ(preReq->a, 1964); + missionMap[1964] = new Mission(); + missionMap[1] = new Mission(); + ASSERT_FALSE(preReq->Execute(missionMap)); + missionMap[1964]->SetMissionState(eMissionState::COMPLETE); + ASSERT_TRUE(preReq->Execute(missionMap)); + delete preReq; +}; + +/** + * Test that the structure of a multi mission prerequisite is created correctly. + */ +TEST_F(MissionPrerequisiteTest, MultiMissionPrerequisiteInitializeTest) { + auto* preReq = new PrerequisiteExpression("1806,1868"); + missionMap[1806] = new Mission(); + missionMap[1868] = new Mission(); + ASSERT_EQ(preReq->a, 1806); + ASSERT_FALSE(preReq->m_or); + ASSERT_EQ(preReq->b->a, 1868); + ASSERT_FALSE(preReq->Execute(missionMap)); + missionMap[1806]->SetMissionState(eMissionState::COMPLETE); + ASSERT_FALSE(preReq->Execute(missionMap)); + missionMap[1806]->SetMissionState(eMissionState::ACTIVE); + missionMap[1868]->SetMissionState(eMissionState::COMPLETE); + ASSERT_FALSE(preReq->Execute(missionMap)); + missionMap[1806]->SetMissionState(eMissionState::COMPLETE); + missionMap[1868]->SetMissionState(eMissionState::COMPLETE); + ASSERT_TRUE(preReq->Execute(missionMap)); + delete preReq; +}; + +/** + * Test that the structure of an or prerequisite for missions is created properly + */ +TEST_F(MissionPrerequisiteTest, OrMissionPrerequisiteInitializeTest) { + auto* preReq = new PrerequisiteExpression("2061|891"); + missionMap[2061] = new Mission(); + missionMap[891] = new Mission(); + ASSERT_TRUE(preReq->m_or); + ASSERT_EQ(preReq->a, 2061); + ASSERT_EQ(preReq->b->a, 891); + ASSERT_FALSE(preReq->Execute(missionMap)); + missionMap[2061]->SetMissionState(eMissionState::COMPLETE); + ASSERT_TRUE(preReq->Execute(missionMap)); + missionMap[2061]->SetMissionState(eMissionState::ACTIVE); + missionMap[891]->SetMissionState(eMissionState::COMPLETE); + ASSERT_TRUE(preReq->Execute(missionMap)); + missionMap[2061]->SetMissionState(eMissionState::COMPLETE); + missionMap[891]->SetMissionState(eMissionState::COMPLETE); + ASSERT_TRUE(preReq->Execute(missionMap)); + delete preReq; +}; + +/** + * Test that the structure of an or prerequisite for multiple missions is created properly + */ +TEST_F(MissionPrerequisiteTest, MultiOrMissionPrerequisiteInitializeTest) { + auto* preReq = new PrerequisiteExpression("815|812|813|814"); + missionMap[815] = new Mission(); + missionMap[812] = new Mission(); + missionMap[813] = new Mission(); + missionMap[814] = new Mission(); + ASSERT_TRUE(preReq->m_or); + ASSERT_EQ(preReq->a, 815); + ASSERT_EQ(preReq->b->a, 812); + ASSERT_TRUE(preReq->b->m_or); + ASSERT_EQ(preReq->b->b->a, 813); + ASSERT_TRUE(preReq->b->b->m_or); + ASSERT_EQ(preReq->b->b->b->a, 814); + ASSERT_FALSE(preReq->b->b->b->m_or); + ASSERT_EQ(preReq->b->b->b->b, nullptr); + ASSERT_FALSE(preReq->Execute(missionMap)); + missionMap[815]->SetMissionState(eMissionState::COMPLETE); + missionMap[812]->SetMissionState(eMissionState::ACTIVE); + missionMap[813]->SetMissionState(eMissionState::ACTIVE); + missionMap[814]->SetMissionState(eMissionState::ACTIVE); + ASSERT_TRUE(preReq->Execute(missionMap)); + missionMap[815]->SetMissionState(eMissionState::ACTIVE); + missionMap[812]->SetMissionState(eMissionState::COMPLETE); + missionMap[813]->SetMissionState(eMissionState::ACTIVE); + missionMap[814]->SetMissionState(eMissionState::ACTIVE); + ASSERT_TRUE(preReq->Execute(missionMap)); + missionMap[815]->SetMissionState(eMissionState::ACTIVE); + missionMap[812]->SetMissionState(eMissionState::ACTIVE); + missionMap[813]->SetMissionState(eMissionState::COMPLETE); + missionMap[814]->SetMissionState(eMissionState::ACTIVE); + ASSERT_TRUE(preReq->Execute(missionMap)); + missionMap[815]->SetMissionState(eMissionState::ACTIVE); + missionMap[812]->SetMissionState(eMissionState::ACTIVE); + missionMap[813]->SetMissionState(eMissionState::ACTIVE); + missionMap[814]->SetMissionState(eMissionState::COMPLETE); + ASSERT_TRUE(preReq->Execute(missionMap)); + missionMap[815]->SetMissionState(eMissionState::ACTIVE); + missionMap[812]->SetMissionState(eMissionState::COMPLETE); + missionMap[813]->SetMissionState(eMissionState::ACTIVE); + missionMap[814]->SetMissionState(eMissionState::COMPLETE); + ASSERT_TRUE(preReq->Execute(missionMap)); + missionMap[815]->SetMissionState(eMissionState::COMPLETE); + missionMap[812]->SetMissionState(eMissionState::ACTIVE); + missionMap[813]->SetMissionState(eMissionState::COMPLETE); + missionMap[814]->SetMissionState(eMissionState::ACTIVE); + ASSERT_TRUE(preReq->Execute(missionMap)); + delete preReq; +}; + +/** + * Test that the structure of a mission with an expected state is created properly + */ +TEST_F(MissionPrerequisiteTest, MissionStatePrerequisiteInitializeTest) { + auto* preReq = new PrerequisiteExpression("236:2"); + missionMap[236] = new Mission(); + ASSERT_EQ(preReq->a, 236); + ASSERT_EQ(preReq->sub, 2); + ASSERT_FALSE(preReq->Execute(missionMap)); + missionMap[236]->SetMissionState(eMissionState::COMPLETE); + ASSERT_FALSE(preReq->Execute(missionMap)); + missionMap[236]->SetMissionState(eMissionState::ACTIVE); + ASSERT_TRUE(preReq->Execute(missionMap)); + delete preReq; +}; + +/** + * Test that the structure of an or prerequisite for missions is created properly + */ +TEST_F(MissionPrerequisiteTest, AndMissionPrerequisiteInitializeTest) { + auto* preReq = new PrerequisiteExpression("(2061|1000)&(8091|1500)"); + missionMap[2061] = new Mission(); + missionMap[1000] = new Mission(); + missionMap[8091] = new Mission(); + missionMap[1500] = new Mission(); + ASSERT_EQ(preReq->a, 0); + ASSERT_FALSE(preReq->m_or); + + ASSERT_EQ(preReq->b->a, 2061); + ASSERT_TRUE(preReq->b->m_or); + + ASSERT_EQ(preReq->b->b->a, 1000); + ASSERT_FALSE(preReq->b->b->m_or); + + ASSERT_EQ(preReq->b->b->b->a, 0); + ASSERT_FALSE(preReq->b->b->b->m_or); + + ASSERT_EQ(preReq->b->b->b->b->a, 8091); + ASSERT_TRUE(preReq->b->b->b->b->m_or); + + ASSERT_EQ(preReq->b->b->b->b->b->a, 1500); + ASSERT_FALSE(preReq->b->b->b->b->b->m_or); + + ASSERT_EQ(preReq->b->b->b->b->b->b, nullptr); + EXPECT_FALSE(preReq->Execute(missionMap)); + missionMap[2061]->SetMissionState(eMissionState::COMPLETE); + missionMap[1000]->SetMissionState(eMissionState::ACTIVE); + missionMap[8091]->SetMissionState(eMissionState::ACTIVE); + missionMap[1500]->SetMissionState(eMissionState::ACTIVE); + EXPECT_FALSE(preReq->Execute(missionMap)); + missionMap[2061]->SetMissionState(eMissionState::ACTIVE); + missionMap[1000]->SetMissionState(eMissionState::COMPLETE); + missionMap[8091]->SetMissionState(eMissionState::ACTIVE); + missionMap[1500]->SetMissionState(eMissionState::ACTIVE); + EXPECT_FALSE(preReq->Execute(missionMap)); + missionMap[2061]->SetMissionState(eMissionState::ACTIVE); + missionMap[1000]->SetMissionState(eMissionState::ACTIVE); + missionMap[8091]->SetMissionState(eMissionState::COMPLETE); + missionMap[1500]->SetMissionState(eMissionState::ACTIVE); + EXPECT_FALSE(preReq->Execute(missionMap)); + missionMap[2061]->SetMissionState(eMissionState::ACTIVE); + missionMap[1000]->SetMissionState(eMissionState::ACTIVE); + missionMap[8091]->SetMissionState(eMissionState::ACTIVE); + missionMap[1500]->SetMissionState(eMissionState::COMPLETE); + EXPECT_FALSE(preReq->Execute(missionMap)); + missionMap[2061]->SetMissionState(eMissionState::COMPLETE); + missionMap[1000]->SetMissionState(eMissionState::ACTIVE); + missionMap[8091]->SetMissionState(eMissionState::COMPLETE); + missionMap[1500]->SetMissionState(eMissionState::ACTIVE); + EXPECT_TRUE(preReq->Execute(missionMap)); + missionMap[2061]->SetMissionState(eMissionState::ACTIVE); + missionMap[1000]->SetMissionState(eMissionState::COMPLETE); + missionMap[8091]->SetMissionState(eMissionState::ACTIVE); + missionMap[1500]->SetMissionState(eMissionState::COMPLETE); + EXPECT_TRUE(preReq->Execute(missionMap)); + missionMap[2061]->SetMissionState(eMissionState::COMPLETE); + missionMap[1000]->SetMissionState(eMissionState::COMPLETE); + missionMap[8091]->SetMissionState(eMissionState::COMPLETE); + missionMap[1500]->SetMissionState(eMissionState::COMPLETE); + EXPECT_TRUE(preReq->Execute(missionMap)); + delete preReq; +};