Implementing and Fixing All Racing Achievements (#366)

* Grammatical changes in comments

* Grammatical fixes in comments

Small grammatical fixes found in comments throughout the code.

* Added descriptions to functions

Added descriptions to functions that didn't have them to keep the code well documented

* Created RacingTaskParam.h

Created RacingTaskParam so eliminate magic numbers in the original implementation of completing racing missions.

* Updated magic numbers in Mission.cpp

Updated magic numbers in Mission.cpp to a meaningful name.

* Implemented racing smashable task progression

Previously, races did not progress tasks for smashing Entities.  Now all achievements tracking smashables track them correctly.  This has been implemented in the three Entities that can be smashed in a race (imagination boxes, track specific smashables, Forbidden Valley dragon eggs).

* Updated race imagination task progression

Race imagination now no longer uses a magic number when passed to missionComponent.  Instead we use a number defined in an enum located in RacingTaskParam.h

* Updated Race task checks

Racing tasks for completing races without smashing now no longer auto complete the whole chain of missions.  Tasks that track placing on tracks and races overall now properly complete.  Tasks that count how many missions in a zone are completed now function.  Tasks that track race completions in multiple areas now function.

* Updated RacingControlComponent.cpp

Fixed any tasks that required 3 players to now require 3 or more players in a race to progress.  This restriction is ignored if the world config opted in for solo racing to allow progression in solo worlds.  Updated magic numbers sent into missionComponent->Progress to an enum created in this PR.  Fixed some indentation.

* Fixed a grammatical error in variable name

Fixed a grammatical error in the enum for task params
This commit is contained in:
David Markowitz 2022-02-05 03:28:17 -08:00 committed by GitHub
parent dc2bd76aba
commit c6f220ee31
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
15 changed files with 109 additions and 67 deletions

View File

@ -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);

View File

@ -45,7 +45,7 @@ std::vector<LOT> EntityManager::m_GhostingExcludedLOTs = {
9524,
12408,
// AG - Fotrace
// AG - Footrace
4967
};

View File

@ -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<MissionComponent>();
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<MissionComponent>();
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<CharacterComponent>();
auto *characterComponent = playerEntity->GetComponent<CharacterComponent>();
if (characterComponent != nullptr) {
characterComponent->TrackRaceCompleted(m_Finished ==
1);
characterComponent->TrackRaceCompleted(m_Finished == 1);
}
// TODO: Figure out how to update the GUI leaderboard.

View File

@ -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<LWOOBJID> 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;

View File

@ -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<CDMissionEmailTable>("MissionEmail");
const auto missionId = GetMissionId();

View File

@ -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
{

View File

@ -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
*/

View File

@ -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

View File

@ -0,0 +1,20 @@
#pragma once
#include <cstdint>
enum class RacingTaskParam : int32_t {
RACING_TASK_PARAM_FINISH_WITH_PLACEMENT = 1, //<! A task param for finishing with a specific placement.
RACING_TASK_PARAM_LAP_TIME = 2, //<! A task param for finishing with a specific lap time.
RACING_TASK_PARAM_TOTAL_TRACK_TIME = 3, //<! A task param for finishing with a specific track time.
RACING_TASK_PARAM_COMPLETE_ANY_RACING_TASK = 4, //<! A task param for completing a racing task.
RACING_TASK_PARAM_COMPLETE_TRACK_TASKS = 5, //<! A task param for completing a task for a specific track.
RACING_TASK_PARAM_MODULAR_BUILDING = 6, //<! A task param for modular building with racing builds.
RACING_TASK_PARAM_SAFE_DRIVER = 10, //<! A task param for completing a race without smashing.
RACING_TASK_PARAM_SMASHABLES = 11, //<! A task param for smashing entities during a race.
RACING_TASK_PARAM_COLLECT_IMAGINATION = 12, //<! A task param for collecting imagination during a race.
RACING_TASK_PARAM_COMPETED_IN_RACE = 13, //<! A task param for competing in a race.
RACING_TASK_PARAM_WIN_RACE_IN_WORLD = 14, //<! A task param for winning a race in a specific world.
RACING_TASK_PARAM_FIRST_PLACE_MULTIPLE_TRACKS = 15, //<! A task param for finishing in first place on multiple tracks.
RACING_TASK_PARAM_LAST_PLACE_FINISH = 16, //<! A task param for finishing in last place.
RACING_TASK_PARAM_SMASH_DRAGON_EGGS = 17 //<! A task param for smashing dragon eggs during a race.
};

View File

@ -1,8 +1,9 @@
#include "FvRaceSmashEggImagineServer.h"
#include "DestroyableComponent.h"
#include "CharacterComponent.h"
#include "DestroyableComponent.h"
#include "EntityManager.h"
#include "FvRaceSmashEggImagineServer.h"
#include "PossessableComponent.h"
#include "RacingTaskParam.h"
void FvRaceSmashEggImagineServer::OnDie(Entity *self, Entity *killer) {
if (killer != nullptr) {
@ -12,18 +13,21 @@ void FvRaceSmashEggImagineServer::OnDie(Entity *self, Entity *killer) {
EntityManager::Instance()->SerializeEntity(killer);
}
// Crate is killed by the car
// get possessor to progress statistics and tasks.
auto* possessableComponent = killer->GetComponent<PossessableComponent>();
if (possessableComponent != nullptr) {
auto* possessor = EntityManager::Instance()->GetEntity(possessableComponent->GetPossessor());
if (possessor != nullptr) {
auto* missionComponent = possessor->GetComponent<MissionComponent>();
auto* characterComponent = possessor->GetComponent<CharacterComponent>();
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);
}
}

View File

@ -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<bool>(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<PossessableComponent>();
if (possessableComponent != nullptr) {
auto* possessor = EntityManager::Instance()->GetEntity(possessableComponent->GetPossessor());
if (possessor != nullptr) {
auto* missionComponent = possessor->GetComponent<MissionComponent>();
auto* characterComponent = possessor->GetComponent<CharacterComponent>();
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);
}

View File

@ -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;
};

View File

@ -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<MissionComponent>();
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);
}
}

View File

@ -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<MissionComponent>();
auto* characterComponent = possessor->GetComponent<CharacterComponent>();
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);
}
}
}

View File

@ -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;
};