mirror of
https://github.com/Jous99/F4MP.git
synced 2026-01-13 21:50:53 +01:00
140 lines
3.8 KiB
C
140 lines
3.8 KiB
C
#pragma once
|
|
|
|
#include <Games/Primitives.h>
|
|
#include <Misc/BSString.h>
|
|
#include <Components/TESFullName.h>
|
|
#include <Forms/BGSStoryManagerTree.h>
|
|
|
|
struct BGSScene : TESForm
|
|
{
|
|
GameArray<void*> phases;
|
|
GameArray<uint32_t> actorIds;
|
|
};
|
|
|
|
struct TESQuest : BGSStoryManagerTreeForm
|
|
{
|
|
enum class State : uint8_t
|
|
{
|
|
WaitingPromotion,
|
|
Running,
|
|
Stopped,
|
|
WaitingForStage
|
|
};
|
|
|
|
enum Flags : uint16_t
|
|
{
|
|
StopStart = USHRT_MAX,
|
|
None = 0,
|
|
Enabled = 1 << 0,
|
|
Completed = 1 << 1,
|
|
AddIdleToHello = 1 << 2,
|
|
AllowRepeatStages = 1 << 3,
|
|
StartsEnabled = 1 << 4,
|
|
DisplayedInHUD = 1 << 5,
|
|
Failed = 1 << 6,
|
|
StageWait = 1 << 7,
|
|
RunOnce = 1 << 8,
|
|
ExcludeFromExport = 1 << 9,
|
|
WarnOnAliasFillFailure = 1 << 10,
|
|
Active = 1 << 11,
|
|
RepeatsConditions = 1 << 12,
|
|
KeepInstance = 1 << 13,
|
|
WantDormant = 1 << 14,
|
|
HasDialogueData = 1 << 15
|
|
};
|
|
|
|
enum class Type : uint8_t
|
|
{
|
|
None = 0,
|
|
MainQuest = 1,
|
|
MagesGuild = 2,
|
|
ThievesGuild = 3,
|
|
DarkBrotherhood = 4,
|
|
CompanionsQuest = 5,
|
|
Miscellaneous = 6,
|
|
Daedric = 7,
|
|
SideQuest = 8,
|
|
CivilWar = 9,
|
|
DLC01_Vampire = 10,
|
|
DLC02_Dragonborn = 11
|
|
};
|
|
|
|
struct Objective
|
|
{
|
|
BSFixedString nameRef; // 0x0000
|
|
TESQuest* parent; // 0x0008
|
|
char pad10[12]; // 0x0010
|
|
uint16_t stageId;
|
|
uint8_t pad30;
|
|
uint8_t state;
|
|
};
|
|
|
|
static_assert(offsetof(Objective, state) == 31);
|
|
|
|
struct Stage
|
|
{
|
|
uint16_t stageIndex;
|
|
uint8_t flags;
|
|
|
|
inline bool IsDone() { return flags & 1; }
|
|
};
|
|
|
|
TESFullName fullName;
|
|
GameArray<void*> instanceData;
|
|
uint32_t currentInstanceID;
|
|
GameArray<void*> aliases; // 0x0058
|
|
char pad70[0xD8 - 0x70];
|
|
float questDelay; // 0x00D8
|
|
uint16_t flags; // 0x00DC default init: 256
|
|
uint8_t priority; // 0x00DE
|
|
Type type; // 0x00DF
|
|
int32_t scopedStatus; // 0x00E0 default init: -1, if not -1 outside of story manager scope
|
|
uint32_t padE4;
|
|
GameList<Stage> stages;
|
|
/*
|
|
GameList<Stage>* pExecutedStages; // 0x00E8
|
|
GameList<Stage>* pWaitingStages; // 0x00F0
|
|
*/
|
|
GameList<Objective> objectives; // 0x00F8
|
|
char pad108[0x100]; // 0x0108
|
|
GameArray<BGSScene*> scenes; // 0x0208
|
|
char pad210[8]; // 0x0210
|
|
uint16_t currentStage; // 0x0228
|
|
bool alreadyRun; // 0x022A
|
|
char pad22B[2];
|
|
BSString idName; // < this is the proper quest ID
|
|
void* pStartEventData;
|
|
uint64_t unkFlags;
|
|
char pad250[24];
|
|
|
|
TESObjectREFR* GetAliasedRef(uint32_t aiAliasID) noexcept;
|
|
|
|
bool IsStageDone(uint16_t stageIndex);
|
|
void SetCompleted(bool force);
|
|
|
|
void CompleteAllObjectives(); // completes all objectives + stages
|
|
void SetActive(bool toggle); // < is the quest selected in journal and followed?
|
|
|
|
inline void Disable() { flags &= ~Flags::Enabled; };
|
|
|
|
inline bool IsEnabled() const { return flags & Flags::Enabled; }
|
|
inline bool IsActive() const { return flags & Flags::Active; }
|
|
inline bool IsStopped() const { return (flags & (Flags::Enabled | Flags::StageWait)) == 0; } // & 0x81
|
|
|
|
bool Kill();
|
|
State getState();
|
|
|
|
bool EnsureQuestStarted(bool& succeded, bool force);
|
|
|
|
bool SetStage(uint16_t stage);
|
|
void ScriptSetStage(uint16_t stage);
|
|
void SetStopped();
|
|
};
|
|
|
|
static_assert(sizeof(TESQuest) == 0x268);
|
|
static_assert(offsetof(TESQuest, fullName) == 0x28);
|
|
static_assert(offsetof(TESQuest, flags) == 0xDC);
|
|
static_assert(offsetof(TESQuest, stages) == 0xE8);
|
|
static_assert(offsetof(TESQuest, objectives) == 0xF8);
|
|
static_assert(offsetof(TESQuest, currentStage) == 0x228);
|
|
static_assert(offsetof(TESQuest, unkFlags) == 0x248);
|