DarkflameServer/dGame/dComponents/MissionComponent.h

210 lines
8.5 KiB
C
Raw Normal View History

/*
* Darkflame Universe
* Copyright 2019
*/
#ifndef MISSIONCOMPONENT_H
#define MISSIONCOMPONENT_H
#include <unordered_map>
#include <vector>
#include "dCommonVars.h"
#include "RakNetTypes.h"
#include "Entity.h"
#include "Mission.h"
#include "tinyxml2.h"
#include "CDClientManager.h"
#include "CDMissionsTable.h"
#include "Component.h"
#include "eReplicaComponentType.h"
class AchievementCacheKey;
/**
* The mission inventory of an entity. Tracks mission state for each mission that can be accepted and allows for
* progression of each of the mission task types (see eMissionTaskType).
*/
class MissionComponent : public Component
{
public:
feat: Add isolated and simplified path to add components (#1204) * Components: Make ComponentType inline Prevents the next commits ODR violation * Components: Add new components * Entity: Add headers inline script component ComponentType * Components: Flip constructor argument order Entity comes first always * Entity: Add generic AddComponent Allows for much easier adding of components and is error proof by not allowing the user to add more than 1 of a specific component type to an Entity. * Entity: Migrate all component constructors Move all to the new variadic templates AddComponent function to reduce clutter and ways the component map is modified. The new function makes no assumptions. Component is assumed to not exist and is checked for with operator[]. This will construct a null component which will then be newed if the component didnt exist, or it will just get the current component if it does already exist. No new component will be allocated or constructed if the component already exists and the already existing pointer is returned instead. * Entity: Add placement new For the case where the component may already exist, use a placement new to construct the component again, it would be constructed again, but would not need to go through the allocator. * Entity: Add comments on likely new code * Tests: Fix tests * Update Entity.cpp * Update SGCannon.cpp * Entity: call destructor when re-constructing * Update Entity.cpp Update Entity.cpp --------- Co-authored-by: Aaron Kimbrell <aronwk.aaron@gmail.com>
2023-10-23 01:08:49 +00:00
inline static const eReplicaComponentType ComponentType = eReplicaComponentType::MISSION;
explicit MissionComponent(Entity* parent);
2022-07-28 13:39:57 +00:00
~MissionComponent() override;
void Serialize(RakNet::BitStream* outBitStream, bool bIsInitialUpdate, unsigned int& flags);
void LoadFromXml(tinyxml2::XMLDocument* doc) override;
void UpdateXml(tinyxml2::XMLDocument* doc) override;
/**
* Returns all the missions for this entity, mapped by mission ID
* @return the missions for this entity, mapped by mission ID
*/
const std::unordered_map<uint32_t, Mission*>& GetMissions() const;
/**
* Returns the mission for the given mission ID, if it exists
* @param missionId the id of the mission to get
* @return the mission for the given mission ID
*/
Mission* GetMission(uint32_t missionId) const;
/**
* Returns the current state of the entities progression for the mission of the specified ID
* @param missionId the ID of the mission to get the mission state for
* @return the mission state of the mission specified by the ID
*/
eMissionState GetMissionState(uint32_t missionId) const;
2022-07-28 13:39:57 +00:00
/**
* Checks if the entity has all the requirements for accepting the mission specified by the ID.
* @param missionId the mission ID to check for if the character may accept it
* @return whether this entity can accept the mission represented by the given mission ID
*/
bool CanAccept(uint32_t missionId) const;
/**
* Accepts the mission specified by the ID, if the entity may accept it. Also stores it in the mission inventory.
* @param missionId the ID of the mission to accept
* @param skipChecks skips the checks for the mission prerequisites
*/
void AcceptMission(uint32_t missionId, bool skipChecks = false);
/**
* Completes the mission specified by the given ID, if the entity has fulfilled all progress requirements.
* @param missionId the ID of the mission to complete
* @param skipChecks skips the checks for having completed all of the mission tasks
* @param yieldRewards whether to yield mission rewards, currently unused
*/
void CompleteMission(uint32_t missionId, bool skipChecks = false, bool yieldRewards = true);
/**
* Removes the mission from the entities' mission chain. Not used for normal gameplay but useful for debugging.
* @param missionId the ID of the mission to remove
*/
void RemoveMission(uint32_t missionId);
/**
* Attempts to progress mission tasks for a given type using parameters to progress. Note that this function is
* very abstract and different mission tasks require different combinations of parameters. This also progresses
* achievements, which are basically just missions with the isMission flag set to false.
* @param type the type of the mission task to try and progress with
* @param value the value to progress with, could be a LOT for item collection for example
* @param associate an associated entity for the progression, might be an activity host for example
* @param targets optionally multiple target values that could exist for the mission that we wish to progress
* @param count the number to progress by, for example the number of items
* @param ignoreAchievements do not progress achievements
*/
void Progress(eMissionTaskType type, int32_t value, LWOOBJID associate = 0, const std::string& targets = "", int32_t count = 1, bool ignoreAchievements = false);
2022-07-28 13:39:57 +00:00
/**
* Forces progression for a mission and task, ignoring checks
* @param missionId the mission ID to try and progress
* @param taskId the task ID of the task belonging to the mission trying to progress
* @param value the value to progress with
* @param acceptMission accept the mission if it was not already accepted
*/
void ForceProgress(uint32_t missionId, uint32_t taskId, int32_t value, bool acceptMission = true);
/**
* Forces progress for all tasks of a certain type that belong to the same mission
* @param missionId the mission to progress
* @param taskType the task tyoe to progress
* @param value the value to progress with
* @param acceptMission accept the mission if it wasn't already
*/
void ForceProgressTaskType(uint32_t missionId, uint32_t taskType, int32_t value, bool acceptMission = true);
/**
* Force progresses by checking the value and progressing by 1
* @param missionId the mission to progress
* @param taskType the task to progress for
* @param value the value to check the mission values before progressing
* @param acceptMission accept the mission if it wasn't already
*/
void ForceProgressValue(uint32_t missionId, uint32_t taskType, int32_t value, bool acceptMission = true);
/**
* Returns client database mission information for a mission
* @param missionId the ID of the mission to get the info for
* @param result the result to store the information in
* @return true if the information was succesfully retrieved, false otherwise
*/
bool GetMissionInfo(uint32_t missionId, CDMissions& result);
/**
* Checks if there's any achievements we might be able to accept for the given parameters
* @param type the task type for tasks in the achievement that we wish to progress
* @param value the value to progress by
* @param progress if we can accept the mission, this will apply the progression
* @param associate optional associate related to mission progression
* @param targets optional multiple targets related to mission progression
* @param count the number of values to progress by (differs by task type)
* @return true if a achievement was accepted, false otherwise
*/
const std::vector<uint32_t> LookForAchievements(eMissionTaskType type, int32_t value, bool progress = true, LWOOBJID associate = LWOOBJID_EMPTY, const std::string& targets = "", int32_t count = 1);
2022-07-28 13:39:57 +00:00
/**
* Checks if there's a mission active that requires the collection of the specified LOT
* @param lot the LOT to check for
* @return if there's a mission active that requires the collection of the specified LOT
*/
bool RequiresItem(LOT lot);
/**
* Collects a collectable for the entity, unrendering it for the entity
* @param collectibleID the ID of the collectable to add
*/
void AddCollectible(int32_t collectibleID);
/**
* Checks if the entity already has a collectible of the specified ID
* @param collectibleID the ID of the collectible to check
* @return if the entity already has a collectible of the specified ID
*/
bool HasCollectible(int32_t collectibleID);
/**
* Checks if the entity has a certain mission in its inventory
* @param missionId the ID of the mission to check
* @return if the entity has a certain mission in its inventory
*/
bool HasMission(uint32_t missionId);
void ResetMission(const int32_t missionId);
private:
2022-07-28 13:39:57 +00:00
/**
* All the missions owned by this entity, mapped by mission ID
*/
std::unordered_map<uint32_t, Mission*> m_Missions;
/**
* All the collectibles currently collected by the entity
*/
std::vector<int32_t> m_Collectibles;
/**
* For the given parameters, finds the mission IDs of the achievements that may be unlcoked
* @param type the mission task type to try and progress
* @param value the value to try and progress with
* @param targets optional targets to progress with
* @return list of mission IDs (achievements) that can be progressed for the given parameters
*/
static const std::vector<uint32_t>& QueryAchievements(eMissionTaskType type, int32_t value, const std::string targets);
2022-07-28 13:39:57 +00:00
/**
* As achievements can be hard to query, we here store a list of all the mission IDs that can be unlocked for a
* combination of tasks and values, so that they can be easily re-queried later
*/
static std::unordered_map<AchievementCacheKey, 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