diff --git a/dGame/Entity.cpp b/dGame/Entity.cpp index dd6df1d4..6515b9b4 100644 --- a/dGame/Entity.cpp +++ b/dGame/Entity.cpp @@ -346,7 +346,7 @@ void Entity::Initialize() } /** - * Multiple components require te destructible component. + * Multiple components require the destructible component. */ int buffComponentID = compRegistryTable->GetByIDAndType(m_TemplateID, COMPONENT_TYPE_BUFF); diff --git a/dGame/EntityManager.cpp b/dGame/EntityManager.cpp index b9c8763b..8fb75fb2 100644 --- a/dGame/EntityManager.cpp +++ b/dGame/EntityManager.cpp @@ -45,7 +45,7 @@ std::vector EntityManager::m_GhostingExcludedLOTs = { 9524, 12408, - // AG - Fotrace + // AG - Footrace 4967 }; diff --git a/dGame/dComponents/RacingControlComponent.cpp b/dGame/dComponents/RacingControlComponent.cpp index bbd85672..27df339d 100644 --- a/dGame/dComponents/RacingControlComponent.cpp +++ b/dGame/dComponents/RacingControlComponent.cpp @@ -15,6 +15,7 @@ #include "Player.h" #include "PossessableComponent.h" #include "PossessorComponent.h" +#include "RacingTaskParam.h" #include "Spawner.h" #include "VehiclePhysicsComponent.h" #include "dServer.h" @@ -401,18 +402,18 @@ void RacingControlComponent::HandleMessageBoxResponse(Entity *player, auto *missionComponent = player->GetComponent(); - if (missionComponent != nullptr) { - missionComponent->Progress( - MissionTaskType::MISSION_TASK_TYPE_RACING, 0, 13); // Enter race - missionComponent->Progress( - MissionTaskType::MISSION_TASK_TYPE_RACING, data->finished, - 1); // Finish with rating, one track - missionComponent->Progress( - MissionTaskType::MISSION_TASK_TYPE_RACING, data->finished, - 15); // Finish with rating, multiple tracks - missionComponent->Progress( - MissionTaskType::MISSION_TASK_TYPE_RACING, data->smashedTimes, - 10); // Safe driver type missions + if (missionComponent == nullptr) return; + + missionComponent->Progress(MissionTaskType::MISSION_TASK_TYPE_RACING, 0, (LWOOBJID)RacingTaskParam::RACING_TASK_PARAM_COMPETED_IN_RACE); // Progress task for competing in a race + missionComponent->Progress(MissionTaskType::MISSION_TASK_TYPE_RACING, data->smashedTimes, (LWOOBJID)RacingTaskParam::RACING_TASK_PARAM_SAFE_DRIVER); // Finish a race without being smashed. + + // If solo racing is enabled OR if there are 3 players in the race, progress placement tasks. + if(m_SoloRacing || m_LoadedPlayers > 2) { + missionComponent->Progress(MissionTaskType::MISSION_TASK_TYPE_RACING, data->finished, (LWOOBJID)RacingTaskParam::RACING_TASK_PARAM_FINISH_WITH_PLACEMENT); // Finish in 1st place on a race + missionComponent->Progress(MissionTaskType::MISSION_TASK_TYPE_RACING, data->finished, (LWOOBJID)RacingTaskParam::RACING_TASK_PARAM_FIRST_PLACE_MULTIPLE_TRACKS); // Finish in 1st place on multiple tracks. + if(m_Finished != 1) return; + missionComponent->Progress(MissionTaskType::MISSION_TASK_TYPE_RACING, dZoneManager::Instance()->GetZone()->GetWorldID(), (LWOOBJID)RacingTaskParam::RACING_TASK_PARAM_WIN_RACE_IN_WORLD); // Finished first place in specific world. + } } else if (id == "ACT_RACE_EXIT_THE_RACE?" || id == "Exit") { auto *vehicle = EntityManager::Instance()->GetEntity(data->vehicleID); @@ -809,9 +810,7 @@ void RacingControlComponent::Update(float deltaTime) { // Reached the start point, lapped if (respawnIndex == 0) { - time_t lapTime = - std::time(nullptr) - - (player.lap == 1 ? m_StartTime : player.lapTime); + time_t lapTime = std::time(nullptr) - (player.lap == 1 ? m_StartTime : player.lapTime); // Cheating check if (lapTime < 40) { @@ -833,10 +832,9 @@ void RacingControlComponent::Update(float deltaTime) { playerEntity->GetComponent(); if (missionComponent != nullptr) { - // Lap time - missionComponent->Progress( - MissionTaskType::MISSION_TASK_TYPE_RACING, - (lapTime)*1000, 2); + + // Progress lap time tasks + missionComponent->Progress(MissionTaskType::MISSION_TASK_TYPE_RACING, (lapTime)*1000, (LWOOBJID)RacingTaskParam::RACING_TASK_PARAM_LAP_TIME); if (player.lap == 3) { m_Finished++; @@ -852,15 +850,11 @@ void RacingControlComponent::Update(float deltaTime) { raceTime, raceTime * 1000); // Entire race time - missionComponent->Progress( - MissionTaskType::MISSION_TASK_TYPE_RACING, - (raceTime)*1000, 3); + missionComponent->Progress(MissionTaskType::MISSION_TASK_TYPE_RACING, (raceTime)*1000, (LWOOBJID)RacingTaskParam::RACING_TASK_PARAM_TOTAL_TRACK_TIME); - auto *characterComponent = - playerEntity->GetComponent(); + auto *characterComponent = playerEntity->GetComponent(); if (characterComponent != nullptr) { - characterComponent->TrackRaceCompleted(m_Finished == - 1); + characterComponent->TrackRaceCompleted(m_Finished == 1); } // TODO: Figure out how to update the GUI leaderboard. diff --git a/dGame/dComponents/RacingControlComponent.h b/dGame/dComponents/RacingControlComponent.h index 0dbb9eaa..63d5b2e4 100644 --- a/dGame/dComponents/RacingControlComponent.h +++ b/dGame/dComponents/RacingControlComponent.h @@ -146,7 +146,7 @@ public: void HandleMessageBoxResponse(Entity* player, const std::string& id); /** - * Get the reacing data from a player's LWOOBJID. + * Get the racing data from a player's LWOOBJID. */ RacingPlayerInfo* GetPlayerData(LWOOBJID playerID); @@ -230,7 +230,7 @@ private: std::vector m_LobbyPlayers; /** - * The number of players that have fi nished the race + * The number of players that have finished the race */ uint32_t m_Finished; diff --git a/dGame/dMission/Mission.cpp b/dGame/dMission/Mission.cpp index 28f4b278..854782f9 100644 --- a/dGame/dMission/Mission.cpp +++ b/dGame/dMission/Mission.cpp @@ -11,6 +11,7 @@ #include "GameMessages.h" #include "Mail.h" #include "MissionComponent.h" +#include "RacingTaskParam.h" #include "dLocale.h" #include "dLogger.h" #include "dServer.h" @@ -314,6 +315,10 @@ void Mission::Complete(const bool yieldRewards) { missionComponent->Progress(MissionTaskType::MISSION_TASK_TYPE_MISSION_COMPLETE, info->id); + missionComponent->Progress(MissionTaskType::MISSION_TASK_TYPE_RACING, info->id, (LWOOBJID)RacingTaskParam::RACING_TASK_PARAM_COMPLETE_ANY_RACING_TASK); + + missionComponent->Progress(MissionTaskType::MISSION_TASK_TYPE_RACING, info->id, (LWOOBJID)RacingTaskParam::RACING_TASK_PARAM_COMPLETE_TRACK_TASKS); + auto* missionEmailTable = CDClientManager::Instance()->GetTable("MissionEmail"); const auto missionId = GetMissionId(); diff --git a/dGame/dMission/MissionTask.cpp b/dGame/dMission/MissionTask.cpp index 423966c4..d90f7682 100644 --- a/dGame/dMission/MissionTask.cpp +++ b/dGame/dMission/MissionTask.cpp @@ -425,28 +425,27 @@ void MissionTask::Progress(int32_t value, LWOOBJID associate, const std::string& { if (parameters.empty()) break; - if (!InAllTargets(dZoneManager::Instance()->GetZone()->GetWorldID())) break; + if (!InAllTargets(dZoneManager::Instance()->GetZone()->GetWorldID()) && !(parameters[0] == 4 || parameters[0] == 5) && !InAllTargets(value)) break; if (parameters[0] != associate) break; - if (associate == 1 || associate == 15) + if (associate == 1 || associate == 15 || associate == 2 || associate == 3) { if (value > info->targetValue) break; - AddProgress(1); - } - else if (associate == 2 || associate == 3) - { - if (info->targetValue < value) break; - AddProgress(info->targetValue); } else if (associate == 10) { - if (info->targetValue > value) - { - AddProgress(info->targetValue); - } + // If the player did not crash during the race, progress this task by count. + if (value != 0) break; + + AddProgress(count); + } + else if (associate == 4 || associate == 5 || associate == 14) + { + if (!InAllTargets(value)) break; + AddProgress(count); } else { diff --git a/dGame/dMission/MissionTask.h b/dGame/dMission/MissionTask.h index 6cdc4039..b77b9c59 100644 --- a/dGame/dMission/MissionTask.h +++ b/dGame/dMission/MissionTask.h @@ -19,7 +19,7 @@ public: * Attempts to progress this task using the provided parameters. Note that the behavior of this method is different * for each mission task type. * @param value the value to progress by - * @param associate optional object ID of an entity that was related to the porgression + * @param associate optional object ID of an entity that was related to the progression * @param targets optional multiple targets that need to be met to progress * @param count a number that indicates the times to progress */ diff --git a/dGame/dMission/MissionTaskType.h b/dGame/dMission/MissionTaskType.h index 8519e0d9..6643d161 100644 --- a/dGame/dMission/MissionTaskType.h +++ b/dGame/dMission/MissionTaskType.h @@ -5,7 +5,7 @@ enum class MissionTaskType : int { MISSION_TASK_TYPE_UNKNOWN = -1, //!< The task type is unknown MISSION_TASK_TYPE_SMASH = 0, //!< A task for smashing something MISSION_TASK_TYPE_SCRIPT = 1, //!< A task handled by a server LUA script - MISSION_TASK_TYPE_ACTIVITY = 2, //!< A task for completing a quickbuild + MISSION_TASK_TYPE_ACTIVITY = 2, //!< A task for completing a quickbuild MISSION_TASK_TYPE_ENVIRONMENT = 3, //!< A task for something in the environment MISSION_TASK_TYPE_MISSION_INTERACTION = 4, //!< A task for interacting with a mission MISSION_TASK_TYPE_EMOTE = 5, //!< A task for playing an emote diff --git a/dGame/dMission/RacingTaskParam.h b/dGame/dMission/RacingTaskParam.h new file mode 100644 index 00000000..e85d9f91 --- /dev/null +++ b/dGame/dMission/RacingTaskParam.h @@ -0,0 +1,20 @@ +#pragma once + +#include + +enum class RacingTaskParam : int32_t { + RACING_TASK_PARAM_FINISH_WITH_PLACEMENT = 1, //SerializeEntity(killer); } - // Crate is killed by the car + // get possessor to progress statistics and tasks. auto* possessableComponent = killer->GetComponent(); if (possessableComponent != nullptr) { auto* possessor = EntityManager::Instance()->GetEntity(possessableComponent->GetPossessor()); if (possessor != nullptr) { + auto* missionComponent = possessor->GetComponent(); auto* characterComponent = possessor->GetComponent(); if (characterComponent != nullptr) { characterComponent->UpdatePlayerStatistic(ImaginationPowerUpsCollected); characterComponent->UpdatePlayerStatistic(RacingSmashablesSmashed); } + if (missionComponent == nullptr) return; + missionComponent->Progress(MissionTaskType::MISSION_TASK_TYPE_RACING, self->GetLOT(), (LWOOBJID)RacingTaskParam::RACING_TASK_PARAM_SMASH_DRAGON_EGGS); } } diff --git a/dScripts/RaceImagineCrateServer.cpp b/dScripts/RaceImagineCrateServer.cpp index f233d408..166b3363 100644 --- a/dScripts/RaceImagineCrateServer.cpp +++ b/dScripts/RaceImagineCrateServer.cpp @@ -1,10 +1,11 @@ -#include "RaceImagineCrateServer.h" -#include "SkillComponent.h" -#include "GameMessages.h" -#include "EntityManager.h" -#include "DestroyableComponent.h" #include "CharacterComponent.h" +#include "DestroyableComponent.h" +#include "EntityManager.h" +#include "GameMessages.h" #include "PossessableComponent.h" +#include "RaceImagineCrateServer.h" +#include "RacingTaskParam.h" +#include "SkillComponent.h" void RaceImagineCrateServer::OnDie(Entity* self, Entity* killer) { @@ -13,8 +14,6 @@ void RaceImagineCrateServer::OnDie(Entity* self, Entity* killer) return; } - //GameMessages::SendPlayFXEffect(self, -1, u"pickup", "", LWOOBJID_EMPTY, 1, 1, true); - self->SetVar(u"bIsDead", true); if (killer == nullptr) @@ -38,21 +37,24 @@ void RaceImagineCrateServer::OnDie(Entity* self, Entity* killer) EntityManager::Instance()->SerializeEntity(killer); } - // Crate is killed by the car + // Find possessor of race car to progress missions and update stats. auto* possessableComponent = killer->GetComponent(); if (possessableComponent != nullptr) { auto* possessor = EntityManager::Instance()->GetEntity(possessableComponent->GetPossessor()); if (possessor != nullptr) { + auto* missionComponent = possessor->GetComponent(); auto* characterComponent = possessor->GetComponent(); + if (characterComponent != nullptr) { characterComponent->UpdatePlayerStatistic(RacingImaginationCratesSmashed); characterComponent->UpdatePlayerStatistic(RacingSmashablesSmashed); } + + // Progress racing smashable missions + if(missionComponent == nullptr) return; + missionComponent->Progress(MissionTaskType::MISSION_TASK_TYPE_RACING, 0, (LWOOBJID)RacingTaskParam::RACING_TASK_PARAM_SMASHABLES); } } - - - //skillComponent->CalculateBehavior(586, 9450, killer->GetObjectID(), true); } diff --git a/dScripts/RaceImagineCrateServer.h b/dScripts/RaceImagineCrateServer.h index 9e8ffa5a..42f36b30 100644 --- a/dScripts/RaceImagineCrateServer.h +++ b/dScripts/RaceImagineCrateServer.h @@ -4,5 +4,11 @@ class RaceImagineCrateServer : public CppScripts::Script { public: +/** + * @brief When a boost smashable has been smashed, this function is called + * + * @param self The Entity that called this function. + * @param killer The Entity that killed this Entity. + */ void OnDie(Entity* self, Entity* killer) override; }; diff --git a/dScripts/RaceImaginePowerup.cpp b/dScripts/RaceImaginePowerup.cpp index 91354acf..43e20e9d 100644 --- a/dScripts/RaceImaginePowerup.cpp +++ b/dScripts/RaceImaginePowerup.cpp @@ -1,9 +1,10 @@ -#include "RaceImaginePowerup.h" -#include "DestroyableComponent.h" -#include "PossessorComponent.h" -#include "EntityManager.h" #include "CharacterComponent.h" +#include "DestroyableComponent.h" +#include "EntityManager.h" #include "PossessableComponent.h" +#include "PossessorComponent.h" +#include "RaceImaginePowerup.h" +#include "RacingTaskParam.h" void RaceImaginePowerup::OnFireEventServerSide(Entity *self, Entity *sender, std::string args, int32_t param1, @@ -36,9 +37,7 @@ void RaceImaginePowerup::OnFireEventServerSide(Entity *self, Entity *sender, std auto* missionComponent = sender->GetComponent(); - if (missionComponent != nullptr) - { - missionComponent->Progress(MissionTaskType::MISSION_TASK_TYPE_RACING, self->GetLOT(), 12); - } + if (missionComponent == nullptr) return; + missionComponent->Progress(MissionTaskType::MISSION_TASK_TYPE_RACING, self->GetLOT(), (LWOOBJID)RacingTaskParam::RACING_TASK_PARAM_COLLECT_IMAGINATION); } } diff --git a/dScripts/RaceSmashServer.cpp b/dScripts/RaceSmashServer.cpp index 4fd09f19..059ac430 100644 --- a/dScripts/RaceSmashServer.cpp +++ b/dScripts/RaceSmashServer.cpp @@ -1,7 +1,8 @@ -#include "RaceSmashServer.h" #include "CharacterComponent.h" #include "EntityManager.h" #include "PossessableComponent.h" +#include "RaceSmashServer.h" +#include "RacingTaskParam.h" void RaceSmashServer::OnDie(Entity *self, Entity *killer) { // Crate is smashed by the car @@ -11,10 +12,16 @@ void RaceSmashServer::OnDie(Entity *self, Entity *killer) { auto* possessor = EntityManager::Instance()->GetEntity(possessableComponent->GetPossessor()); if (possessor != nullptr) { + auto* missionComponent = possessor->GetComponent(); auto* characterComponent = possessor->GetComponent(); + if (characterComponent != nullptr) { characterComponent->UpdatePlayerStatistic(RacingSmashablesSmashed); } + + // Progress racing smashable missions + if(missionComponent == nullptr) return; + missionComponent->Progress(MissionTaskType::MISSION_TASK_TYPE_RACING, 0, (LWOOBJID)RacingTaskParam::RACING_TASK_PARAM_SMASHABLES); } } } diff --git a/dScripts/RaceSmashServer.h b/dScripts/RaceSmashServer.h index 750bc00a..7fa1441d 100644 --- a/dScripts/RaceSmashServer.h +++ b/dScripts/RaceSmashServer.h @@ -2,5 +2,11 @@ #include "CppScripts.h" class RaceSmashServer : public CppScripts::Script { + /** + * @brief When a smashable has been destroyed, this function is called. + * + * @param self The Entity that called this function. + * @param killer The Entity that killed this Entity. + */ void OnDie(Entity *self, Entity *killer) override; };