mirror of
https://github.com/DarkflameUniverse/DarkflameServer.git
synced 2026-11-14 15:57:13 +00:00
LWOMissionOfferComponent builds a player's missions for a giver (0x00c605f0, one entry 0x00bebf30) in priority order: 0 a mission to turn in here, 5 one in progress, 10 a new one, 15 a repeat. A ready mission is only listed where MissionNPCComponent.acceptsMission is set, a new one only where offersMission is set and its cooldown has run out, a mission in progress by every giver that has it. A random mission (0x00c5ffd0) lists one of its pool that the giver has: one to turn in first, then one in progress, else a random one. Missions are kept by mission ID; equal priorities keep that order. DLU sent an OfferMission for every mission that qualified, including one ready to turn in at a giver that does not accept it. In the live captures every use got one mission's OfferMission pair. A use now offers the head of the list, and a pick from the multi interaction menu the picked one. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
127 lines
4.0 KiB
C++
127 lines
4.0 KiB
C++
/*
|
|
* Darkflame Universe
|
|
* Copyright 2019
|
|
*/
|
|
|
|
#ifndef MISSIONOFFERCOMPONENT_H
|
|
#define MISSIONOFFERCOMPONENT_H
|
|
|
|
#include "dCommonVars.h"
|
|
#include "Component.h"
|
|
#include <optional>
|
|
#include <string>
|
|
#include <vector>
|
|
#include <stdint.h>
|
|
#include "eReplicaComponentType.h"
|
|
|
|
class Entity;
|
|
class MissionComponent;
|
|
|
|
// One mission of a mission giver for a player, as the client lists them (LWOMissionOfferComponent 0x00c605f0): the
|
|
// lowest priority comes first. 0 a mission to turn in here, 5 one in progress, 10 a new one, 15 a repeat, 20 a
|
|
// completed one.
|
|
struct MissionOfferEntry {
|
|
uint8_t priority{};
|
|
uint32_t missionID{};
|
|
int32_t state{};
|
|
bool isTurnIn{};
|
|
|
|
bool operator==(const MissionOfferEntry&) const = default;
|
|
};
|
|
|
|
/**
|
|
* Light wrapper around missions that may be offered by an entity
|
|
*/
|
|
struct OfferedMission {
|
|
OfferedMission(uint32_t missionId, bool offersMission, bool acceptsMission);
|
|
|
|
/**
|
|
* Returns the ID of the mission
|
|
* @return the ID of the mission
|
|
*/
|
|
uint32_t GetMissionId() const;
|
|
|
|
/**
|
|
* Returns if this mission is offered by the entity
|
|
* @return true if this mission is offered by the entity, false otherwise
|
|
*/
|
|
bool GetOffersMission() const;
|
|
|
|
/**
|
|
* Returns if this mission may be accepted by the entity (currently unused)
|
|
* @return true if this mission may be accepted by the entity, false otherwise
|
|
*/
|
|
bool GetAcceptsMission() const;
|
|
|
|
private:
|
|
|
|
/**
|
|
* The ID of the mission
|
|
*/
|
|
uint32_t missionId;
|
|
|
|
/**
|
|
* Determines if the mission is offered by the entity
|
|
*/
|
|
bool offersMission;
|
|
|
|
/**
|
|
* Determines if the mission can be accepted by the entity
|
|
*/
|
|
bool acceptsMission;
|
|
};
|
|
|
|
/**
|
|
* Allows entities to offer missions to other entities, depending on their mission inventory progression.
|
|
*/
|
|
class MissionOfferComponent final : public Component {
|
|
public:
|
|
static constexpr eReplicaComponentType ComponentType = eReplicaComponentType::MISSION_OFFER;
|
|
|
|
MissionOfferComponent(Entity* parent, const int32_t componentID);
|
|
|
|
void LoadDataFromTemplate() override;
|
|
|
|
/**
|
|
* Handles a RequestUse triggered by some entity, determines which missions to show based on what they may
|
|
* hand in now and what they may start based on their mission history.
|
|
* @param originator the entity that triggered the event
|
|
*/
|
|
bool OnRequestUse(GameMessages::RequestUseEvent& event);
|
|
|
|
/**
|
|
* Offers all the missions an entity can accept to said entity
|
|
* @param entity the entity to offer missions to
|
|
* @param specifiedMissionId optional mission ID if you wish to offer a specific mission
|
|
*/
|
|
void OfferMissions(Entity* entity, uint32_t specifiedMissionId = 0);
|
|
|
|
// RequestLinkedMission after a mission window: offers the next mission of this giver, if there is a new one
|
|
void OfferLinkedMission(Entity* entity, uint32_t missionID);
|
|
|
|
// The client's entry for one mission (0x00bebf30), from its state bit mask (MissionComponent::GetClientMissionState)
|
|
static std::optional<MissionOfferEntry> GetOfferEntry(uint32_t missionID, int32_t state, bool cooldownRunning, bool offers, bool accepts, bool alsoCompleted);
|
|
|
|
// Inserts after the entries of the same priority, as the client's multimap does
|
|
static void InsertByPriority(std::vector<MissionOfferEntry>& entries, const MissionOfferEntry& entry);
|
|
|
|
// The missions of this giver for a player, in the client's order (0x00c605f0)
|
|
std::vector<MissionOfferEntry> GetMissionsForPlayer(const MissionComponent& missionComponent, bool alsoCompleted) const;
|
|
|
|
// The mission a RequestLinkedMission offers: the head of the list without the mission the window was for, when new
|
|
static std::optional<uint32_t> GetLinkedMission(std::vector<MissionOfferEntry> entries, uint32_t missionID);
|
|
|
|
static std::vector<uint32_t> ParseRandomPool(const std::string& randomPool);
|
|
|
|
private:
|
|
const OfferedMission* GetOfferedMission(uint32_t missionID) const;
|
|
static std::optional<MissionOfferEntry> GetEntryFor(const MissionComponent& missionComponent, const OfferedMission& offered, bool alsoCompleted);
|
|
|
|
/**
|
|
* The missions this entity has to offer
|
|
*/
|
|
std::vector<OfferedMission> offeredMissions;
|
|
};
|
|
|
|
#endif // MISSIONOFFERCOMPONENT_H
|