2024-04-29 16:51:28 +01:00
|
|
|
#include <fstream>
|
|
|
|
#include <memory>
|
|
|
|
#include <map>
|
|
|
|
#include <optional>
|
|
|
|
#include <stack>
|
|
|
|
#include <stdexcept>
|
|
|
|
#include <string>
|
|
|
|
#include <vector>
|
2024-05-06 01:45:42 +01:00
|
|
|
#include <queue>
|
2024-04-29 16:51:28 +01:00
|
|
|
|
2024-05-09 16:17:46 +01:00
|
|
|
#include <Common.h>
|
|
|
|
#include <Forwards.h>
|
2024-04-29 16:51:28 +01:00
|
|
|
#include <nlohmann/json.hpp>
|
|
|
|
|
|
|
|
namespace Sapphire
|
|
|
|
{
|
2024-05-05 16:15:05 +01:00
|
|
|
class EncounterTimeline
|
2024-04-29 16:51:28 +01:00
|
|
|
{
|
|
|
|
public:
|
2024-05-09 16:17:46 +01:00
|
|
|
// forwards
|
|
|
|
class TimelineActor;
|
2024-05-10 22:46:33 +01:00
|
|
|
class TimelinePack;
|
|
|
|
|
2024-05-23 18:40:37 +01:00
|
|
|
//
|
|
|
|
// State tracking objects (per actor)
|
|
|
|
//
|
|
|
|
// todo: move ConditionState/TimepointState to Chara::GambitState?
|
|
|
|
|
2024-05-10 22:46:33 +01:00
|
|
|
struct TimepointState
|
|
|
|
{
|
|
|
|
uint64_t m_startTime{ 0 };
|
|
|
|
uint64_t m_lastTick{ 0 };
|
|
|
|
bool m_finished{ false };
|
|
|
|
};
|
|
|
|
|
|
|
|
struct ConditionState
|
|
|
|
{
|
|
|
|
uint64_t m_startTime{ 0 };
|
|
|
|
bool m_loop{ false };
|
|
|
|
bool m_completed{ false };
|
2024-05-23 18:40:37 +01:00
|
|
|
bool m_enabled{ false };
|
2024-05-10 22:46:33 +01:00
|
|
|
|
|
|
|
struct
|
|
|
|
{
|
|
|
|
uint64_t m_startTime{ 0 };
|
|
|
|
uint64_t m_lastTimepointTime{ 0 };
|
|
|
|
uint32_t m_lastTimepointIndex{ 0 };
|
|
|
|
|
|
|
|
std::vector< TimepointState > m_timepointStates;
|
|
|
|
} m_phaseInfo;
|
|
|
|
};
|
2024-05-09 16:17:46 +01:00
|
|
|
|
2024-05-23 18:40:37 +01:00
|
|
|
//
|
|
|
|
// Enums
|
|
|
|
//
|
2024-04-29 16:51:28 +01:00
|
|
|
// EncounterFight::OnTick() { switch EncounterTimepointConditionId }
|
2024-05-06 01:45:42 +01:00
|
|
|
enum class ConditionId : uint32_t
|
2024-04-29 16:51:28 +01:00
|
|
|
{
|
|
|
|
HpPctLessThan,
|
|
|
|
HpPctBetween,
|
2024-05-10 17:42:39 +01:00
|
|
|
|
2024-04-29 16:51:28 +01:00
|
|
|
DirectorVarEquals,
|
2024-05-06 01:45:42 +01:00
|
|
|
DirectorVarGreaterThan,
|
2024-05-06 20:13:53 +01:00
|
|
|
DirectorSeqEquals,
|
|
|
|
DirectorSeqGreaterThan,
|
|
|
|
DirectorFlagsEquals,
|
|
|
|
DirectorFlagsGreaterThan,
|
2024-05-10 17:42:39 +01:00
|
|
|
|
2024-05-09 17:27:51 +01:00
|
|
|
EncounterTimeElapsed,
|
2024-05-10 17:42:39 +01:00
|
|
|
CombatState,
|
|
|
|
BNpcHasFlags
|
2024-05-06 01:45:42 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
enum class DirectorOpId
|
|
|
|
{
|
2024-05-23 18:40:37 +01:00
|
|
|
Set, // idx = val
|
|
|
|
Add, // idx += val
|
|
|
|
Sub, // idx -= val
|
|
|
|
Mul, // idx *= val
|
|
|
|
Div, // idx /= val
|
|
|
|
Mod, // idx %= val
|
|
|
|
Sll, // idx << val
|
|
|
|
Srl, // idx >> val
|
|
|
|
Or, // idx |= val
|
|
|
|
Xor, // idx ^= val
|
|
|
|
Nor, // idx ~= val
|
|
|
|
And // idx &= val
|
2024-04-29 16:51:28 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
// TODO: what should this do?
|
2024-05-06 01:45:42 +01:00
|
|
|
enum class TimepointOverrideFlags : uint32_t
|
2024-04-29 16:51:28 +01:00
|
|
|
{
|
|
|
|
None,
|
|
|
|
Invulnerable
|
|
|
|
};
|
|
|
|
|
2024-05-06 01:45:42 +01:00
|
|
|
enum class TimepointDataType : uint32_t
|
2024-04-29 16:51:28 +01:00
|
|
|
{
|
|
|
|
Idle,
|
|
|
|
CastAction,
|
|
|
|
MoveTo,
|
2024-05-10 22:46:33 +01:00
|
|
|
|
2024-04-29 16:51:28 +01:00
|
|
|
LogMessage,
|
|
|
|
BattleTalk,
|
2024-05-10 22:46:33 +01:00
|
|
|
|
2024-05-23 18:40:37 +01:00
|
|
|
DirectorVar,
|
|
|
|
DirectorVarLR,
|
|
|
|
DirectorSeq,
|
|
|
|
DirectorFlags,
|
2024-05-10 22:46:33 +01:00
|
|
|
|
2024-04-29 16:51:28 +01:00
|
|
|
AddStatusEffect,
|
2024-05-10 17:42:39 +01:00
|
|
|
RemoveStatusEffect,
|
2024-05-10 22:46:33 +01:00
|
|
|
|
2024-05-23 18:40:37 +01:00
|
|
|
SpawnBNpc,
|
2024-05-10 17:42:39 +01:00
|
|
|
SetBNpcFlags,
|
|
|
|
SetEObjState,
|
2024-05-23 18:40:37 +01:00
|
|
|
SetBgm,
|
|
|
|
|
|
|
|
SetCondition
|
2024-04-29 16:51:28 +01:00
|
|
|
};
|
|
|
|
|
2024-05-06 01:45:42 +01:00
|
|
|
enum class TimepointCallbackType : uint32_t
|
2024-04-29 16:51:28 +01:00
|
|
|
{
|
|
|
|
OnActionInit,
|
|
|
|
OnActionStart,
|
|
|
|
OnActionInterrupt,
|
|
|
|
OnActionExecute
|
|
|
|
};
|
|
|
|
|
2024-05-27 01:45:37 +01:00
|
|
|
enum class TargetSelectFilterFlags : uint32_t
|
2024-04-29 16:51:28 +01:00
|
|
|
{
|
2024-05-27 01:45:37 +01:00
|
|
|
Self = 0x00000000,
|
2024-04-29 16:51:28 +01:00
|
|
|
|
2024-05-27 01:45:37 +01:00
|
|
|
Player = 0x00000001,
|
|
|
|
|
|
|
|
EnemyBattalion = 0x00000002,
|
|
|
|
OwnBattalion = 0x00000004,
|
|
|
|
|
|
|
|
Tank = 0x00000010,
|
|
|
|
Healer = 0x00000020,
|
|
|
|
Dps = 0x00000040,
|
|
|
|
Melee = 0x00000080,
|
|
|
|
Ranged = 0x00000100,
|
|
|
|
Closest = 0x00000200,
|
|
|
|
Furthest = 0x00000400,
|
|
|
|
|
|
|
|
Aggro1 = 0x10000000,
|
|
|
|
Aggro2 = 0x20000000,
|
2024-04-29 16:51:28 +01:00
|
|
|
};
|
|
|
|
|
2024-05-09 16:17:46 +01:00
|
|
|
enum class MoveType : uint32_t
|
2024-04-29 16:51:28 +01:00
|
|
|
{
|
|
|
|
WalkPath,
|
|
|
|
Teleport
|
|
|
|
};
|
|
|
|
|
2024-05-09 16:17:46 +01:00
|
|
|
enum class TimelineActorType : uint32_t
|
|
|
|
{
|
|
|
|
LayerSetObject,
|
|
|
|
BattleNpc
|
|
|
|
};
|
|
|
|
|
|
|
|
enum class CombatStateType
|
|
|
|
{
|
|
|
|
Idle,
|
|
|
|
Combat,
|
|
|
|
Retreat,
|
|
|
|
Roaming,
|
|
|
|
JustDied,
|
|
|
|
Dead
|
|
|
|
};
|
|
|
|
|
|
|
|
enum class TimelinePackType : uint32_t
|
|
|
|
{
|
|
|
|
Solo,
|
|
|
|
EncounterFight
|
|
|
|
};
|
|
|
|
|
2024-04-29 16:51:28 +01:00
|
|
|
struct TargetSelectFilter
|
|
|
|
{
|
2024-05-27 01:45:37 +01:00
|
|
|
TargetSelectFilterFlags m_flags;
|
2024-04-29 16:51:28 +01:00
|
|
|
};
|
|
|
|
|
2024-05-23 18:40:37 +01:00
|
|
|
//
|
|
|
|
// Timepoint.m_pData objects
|
|
|
|
//
|
2024-05-27 01:45:37 +01:00
|
|
|
using TimepointCallbackFunc = std::function< void( TerritoryPtr, uint64_t ) >;
|
2024-05-06 01:45:42 +01:00
|
|
|
// Timepoint Data Objects
|
|
|
|
struct TimepointCallbackData :
|
|
|
|
public std::enable_shared_from_this< TimepointCallbackData >
|
2024-04-29 16:51:28 +01:00
|
|
|
{
|
2024-05-06 01:45:42 +01:00
|
|
|
TimepointCallbackType m_type;
|
|
|
|
std::vector < TimepointCallbackFunc > m_callbacks;
|
2024-04-29 16:51:28 +01:00
|
|
|
};
|
2024-05-06 01:45:42 +01:00
|
|
|
using TimebackCallbackDataPtr = std::shared_ptr< TimepointCallbackData >;
|
|
|
|
using TimepointCallbacks = std::map< TimepointCallbackType, TimebackCallbackDataPtr >;
|
2024-04-29 16:51:28 +01:00
|
|
|
|
|
|
|
|
2024-05-06 01:45:42 +01:00
|
|
|
struct TimepointData :
|
|
|
|
public std::enable_shared_from_this< TimepointData >
|
2024-04-29 16:51:28 +01:00
|
|
|
{
|
2024-05-06 20:13:53 +01:00
|
|
|
TimepointData( TimepointDataType type ) : m_type( type ) {}
|
|
|
|
virtual ~TimepointData(){};
|
|
|
|
TimepointDataType m_type{ 0 };
|
2024-04-29 16:51:28 +01:00
|
|
|
};
|
2024-05-06 01:45:42 +01:00
|
|
|
using TimepointDataPtr = std::shared_ptr< TimepointData >;
|
2024-04-29 16:51:28 +01:00
|
|
|
|
2024-05-06 01:45:42 +01:00
|
|
|
struct TimepointDataIdle : public TimepointData
|
|
|
|
{
|
2024-05-23 18:40:37 +01:00
|
|
|
uint32_t m_layoutId{ 0xE0000000 };
|
2024-05-06 01:45:42 +01:00
|
|
|
uint64_t m_durationMs;
|
2024-05-06 20:13:53 +01:00
|
|
|
|
2024-05-10 15:48:42 +01:00
|
|
|
TimepointDataIdle( uint32_t layoutId, uint64_t durationMs ) :
|
2024-05-06 20:13:53 +01:00
|
|
|
TimepointData( TimepointDataType::Idle ),
|
2024-05-10 15:48:42 +01:00
|
|
|
m_layoutId( layoutId ),
|
2024-05-06 20:13:53 +01:00
|
|
|
m_durationMs( durationMs )
|
|
|
|
{
|
|
|
|
}
|
2024-05-06 01:45:42 +01:00
|
|
|
};
|
2024-04-29 16:51:28 +01:00
|
|
|
|
2024-05-06 20:13:53 +01:00
|
|
|
struct TimepointDataAddStatusEffect : public TimepointData
|
2024-04-29 16:51:28 +01:00
|
|
|
{
|
|
|
|
uint32_t m_statusEffectId;
|
|
|
|
TargetSelectFilter m_targetFilter;
|
|
|
|
uint32_t m_durationMs;
|
2024-05-06 20:13:53 +01:00
|
|
|
|
|
|
|
TimepointDataAddStatusEffect( uint32_t statusId, TargetSelectFilter targFilter, uint32_t durationMs ) :
|
|
|
|
TimepointData( TimepointDataType::AddStatusEffect ),
|
|
|
|
m_statusEffectId( statusId ),
|
|
|
|
m_targetFilter( targFilter ),
|
|
|
|
m_durationMs( durationMs )
|
|
|
|
{
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
struct TimepointDataRemoveStatusEffect : public TimepointData
|
|
|
|
{
|
|
|
|
uint32_t m_statusEffectId;
|
|
|
|
TargetSelectFilter m_targetFilter;
|
|
|
|
|
|
|
|
TimepointDataRemoveStatusEffect( uint32_t statusId, TargetSelectFilter targFilter ) :
|
|
|
|
TimepointData( TimepointDataType::RemoveStatusEffect ),
|
|
|
|
m_statusEffectId( statusId ),
|
|
|
|
m_targetFilter( targFilter )
|
|
|
|
{
|
|
|
|
}
|
2024-04-29 16:51:28 +01:00
|
|
|
};
|
|
|
|
|
2024-05-06 01:45:42 +01:00
|
|
|
struct TimepointDataAction : public TimepointData
|
2024-04-29 16:51:28 +01:00
|
|
|
{
|
2024-05-23 18:40:37 +01:00
|
|
|
uint32_t m_layoutId{ 0xE0000000 };
|
2024-04-29 16:51:28 +01:00
|
|
|
uint32_t m_actionId;
|
2024-05-23 18:40:37 +01:00
|
|
|
//TimepointCallbacks m_callbacks;
|
2024-05-06 20:13:53 +01:00
|
|
|
|
2024-05-23 18:40:37 +01:00
|
|
|
TimepointDataAction( uint32_t layoutId, uint32_t actionId ) :
|
2024-05-06 20:13:53 +01:00
|
|
|
TimepointData( TimepointDataType::CastAction ),
|
2024-05-10 15:48:42 +01:00
|
|
|
m_layoutId( layoutId ),
|
2024-05-23 18:40:37 +01:00
|
|
|
m_actionId( actionId )
|
|
|
|
//m_callbacks( callbacks )
|
2024-05-06 20:13:53 +01:00
|
|
|
{
|
|
|
|
}
|
2024-05-06 01:45:42 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
struct TimepointDataMoveTo : public TimepointData
|
|
|
|
{
|
2024-05-23 18:40:37 +01:00
|
|
|
uint32_t m_layoutId{ 0xE0000000 };
|
2024-05-06 01:45:42 +01:00
|
|
|
MoveType m_moveType;
|
|
|
|
float m_x, m_y, m_z, m_rot;
|
2024-05-06 20:13:53 +01:00
|
|
|
|
2024-05-10 15:48:42 +01:00
|
|
|
TimepointDataMoveTo( uint32_t layoutId, MoveType moveType, float x, float y, float z, float rot ) :
|
2024-05-06 20:13:53 +01:00
|
|
|
TimepointData( TimepointDataType::MoveTo ),
|
2024-05-10 15:48:42 +01:00
|
|
|
m_layoutId( layoutId ),
|
2024-05-06 20:13:53 +01:00
|
|
|
m_moveType( moveType ),
|
|
|
|
m_x( x ), m_y( y ), m_z( z ), m_rot( rot )
|
|
|
|
{
|
|
|
|
}
|
2024-05-06 01:45:42 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
struct TimepointDataLogMessage : public TimepointData
|
|
|
|
{
|
2024-05-06 20:13:53 +01:00
|
|
|
uint32_t m_messageId;
|
2024-05-23 18:40:37 +01:00
|
|
|
uint32_t m_params[ 5 ]{ 0 };
|
2024-05-06 20:13:53 +01:00
|
|
|
|
2024-05-23 18:40:37 +01:00
|
|
|
TimepointDataLogMessage( uint32_t messageId, const std::vector< uint32_t >& params ) :
|
2024-05-06 20:13:53 +01:00
|
|
|
TimepointData( TimepointDataType::LogMessage ),
|
|
|
|
m_messageId( messageId )
|
|
|
|
{
|
2024-05-23 18:40:37 +01:00
|
|
|
for( auto i = 0; i < params.size() && i < 5; ++i )
|
|
|
|
m_params[i] = params[i];
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
struct TimepointDataBattleTalk : public TimepointData
|
|
|
|
{
|
|
|
|
uint32_t m_battleTalkId;
|
|
|
|
uint32_t m_handlerId;
|
|
|
|
uint32_t m_kind;
|
|
|
|
uint32_t m_nameId;
|
|
|
|
uint32_t m_talkerId;
|
|
|
|
|
|
|
|
uint32_t m_params[ 8 ]{ 0 };
|
|
|
|
|
|
|
|
TimepointDataBattleTalk( const std::vector< uint32_t >& params ) :
|
|
|
|
TimepointData( TimepointDataType::BattleTalk )
|
|
|
|
{
|
|
|
|
for( auto i = 0; i < params.size() && i < 8; ++i )
|
2024-05-06 20:13:53 +01:00
|
|
|
m_params[i] = params[i];
|
|
|
|
}
|
2024-04-29 16:51:28 +01:00
|
|
|
};
|
|
|
|
|
2024-05-06 01:45:42 +01:00
|
|
|
struct TimepointDataDirector : public TimepointData
|
2024-04-29 16:51:28 +01:00
|
|
|
{
|
2024-05-10 17:42:39 +01:00
|
|
|
DirectorOpId m_directorOp{ 0 };
|
2024-05-06 01:45:42 +01:00
|
|
|
union
|
|
|
|
{
|
|
|
|
struct
|
|
|
|
{
|
|
|
|
uint8_t index;
|
|
|
|
union
|
|
|
|
{
|
|
|
|
uint8_t val;
|
|
|
|
struct
|
|
|
|
{
|
|
|
|
uint8_t left, right;
|
|
|
|
};
|
|
|
|
} value;
|
|
|
|
};
|
|
|
|
uint8_t seq;
|
|
|
|
uint8_t flags;
|
2024-05-10 17:42:39 +01:00
|
|
|
} m_data{ 0 };
|
2024-05-06 20:13:53 +01:00
|
|
|
|
2024-05-23 18:40:37 +01:00
|
|
|
TimepointDataDirector( TimepointDataType type, DirectorOpId op ) :
|
|
|
|
TimepointData( type ),
|
|
|
|
m_directorOp( op )
|
|
|
|
{
|
|
|
|
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
struct TimepointDataSpawnBNpc : public TimepointData
|
|
|
|
{
|
|
|
|
uint32_t m_layoutId{ 0xE0000000 };
|
|
|
|
uint32_t m_flags{ 0 };
|
|
|
|
// todo: hate type, source
|
|
|
|
|
|
|
|
TimepointDataSpawnBNpc( uint32_t layoutId, uint32_t flags ) :
|
|
|
|
TimepointData( TimepointDataType::SpawnBNpc ),
|
|
|
|
m_layoutId( layoutId ),
|
|
|
|
m_flags( flags)
|
2024-05-10 17:42:39 +01:00
|
|
|
{
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
struct TimepointDataBNpcFlags : public TimepointData
|
|
|
|
{
|
2024-05-23 18:40:37 +01:00
|
|
|
uint32_t m_layoutId{ 0xE0000000 };
|
|
|
|
uint32_t m_flags{ 0 };
|
2024-05-10 17:42:39 +01:00
|
|
|
|
|
|
|
TimepointDataBNpcFlags( uint32_t layoutId, uint32_t flags ) :
|
|
|
|
TimepointData( TimepointDataType::SetBNpcFlags ),
|
|
|
|
m_layoutId( layoutId ),
|
|
|
|
m_flags( flags )
|
|
|
|
{
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
struct TimepointDataEObjState : public TimepointData
|
|
|
|
{
|
|
|
|
uint32_t m_eobjId{ 0xE0000000 };
|
|
|
|
uint32_t m_state{ 0 };
|
|
|
|
|
|
|
|
TimepointDataEObjState( uint32_t eobjId, uint32_t state ) :
|
|
|
|
TimepointData( TimepointDataType::SetEObjState ),
|
|
|
|
m_eobjId( eobjId ),
|
|
|
|
m_state( state )
|
|
|
|
{
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
struct TimepointDataBGM : public TimepointData
|
|
|
|
{
|
|
|
|
uint32_t m_bgmId{ 0 };
|
|
|
|
|
|
|
|
TimepointDataBGM( uint32_t bgmId ):
|
|
|
|
TimepointData( TimepointDataType::SetBgm ),
|
|
|
|
m_bgmId( bgmId )
|
|
|
|
{
|
|
|
|
}
|
2024-04-29 16:51:28 +01:00
|
|
|
};
|
|
|
|
|
2024-05-23 18:40:37 +01:00
|
|
|
struct TimepointDataCondition : public TimepointData
|
|
|
|
{
|
|
|
|
// todo: rng?
|
|
|
|
uint32_t m_index;
|
|
|
|
bool m_enabled;
|
|
|
|
|
|
|
|
TimepointDataCondition( uint32_t index, bool enabled ) :
|
|
|
|
TimepointData( TimepointDataType::SetCondition ),
|
|
|
|
m_index( index ),
|
|
|
|
m_enabled( enabled )
|
|
|
|
{
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2024-05-09 16:17:46 +01:00
|
|
|
// todo: refactor all this to allow solo actor to use
|
2024-05-06 01:45:42 +01:00
|
|
|
class Timepoint :
|
|
|
|
public std::enable_shared_from_this< Timepoint >
|
2024-04-29 16:51:28 +01:00
|
|
|
{
|
|
|
|
public:
|
2024-05-06 01:45:42 +01:00
|
|
|
TimepointDataType m_type;
|
2024-05-23 18:40:37 +01:00
|
|
|
uint64_t m_duration{ 0 }; // milliseconds
|
2024-05-06 01:45:42 +01:00
|
|
|
TimepointOverrideFlags m_overrideFlags;
|
|
|
|
TimepointDataPtr m_pData;
|
2024-04-29 16:51:28 +01:00
|
|
|
std::string m_description;
|
|
|
|
|
2024-05-06 01:45:42 +01:00
|
|
|
// todo: repeatable?
|
|
|
|
|
2024-05-06 20:13:53 +01:00
|
|
|
const TimepointDataPtr getData() const
|
|
|
|
{
|
|
|
|
return m_pData;
|
|
|
|
}
|
|
|
|
|
2024-05-23 18:40:37 +01:00
|
|
|
bool canExecute( const TimepointState& state, uint64_t elapsed ) const
|
2024-05-06 01:45:42 +01:00
|
|
|
{
|
2024-05-10 22:46:33 +01:00
|
|
|
return state.m_startTime == 0; // & &m_duration <= elapsed;
|
2024-05-06 01:45:42 +01:00
|
|
|
}
|
|
|
|
|
2024-05-23 18:40:37 +01:00
|
|
|
bool durationElapsed( uint64_t elapsed ) const
|
2024-05-06 01:45:42 +01:00
|
|
|
{
|
2024-05-23 18:40:37 +01:00
|
|
|
return m_duration < elapsed;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool finished( const TimepointState& state, uint64_t elapsed ) const
|
|
|
|
{
|
|
|
|
return durationElapsed( elapsed ) || state.m_finished;
|
2024-05-10 15:18:06 +01:00
|
|
|
}
|
|
|
|
|
2024-05-10 22:46:33 +01:00
|
|
|
void reset( TimepointState& state ) const
|
2024-05-10 15:18:06 +01:00
|
|
|
{
|
2024-05-10 22:46:33 +01:00
|
|
|
state.m_startTime = 0;
|
|
|
|
state.m_lastTick = 0;
|
|
|
|
state.m_finished = false;
|
2024-05-06 01:45:42 +01:00
|
|
|
}
|
|
|
|
|
2024-05-09 17:27:51 +01:00
|
|
|
void from_json( const nlohmann::json& json, const std::unordered_map< std::string, TimelineActor >& actors, uint32_t selfLayoutId );
|
2024-05-10 15:18:06 +01:00
|
|
|
// todo: separate execute/update into onStart and onTick?
|
2024-05-27 01:45:37 +01:00
|
|
|
void update( TimepointState& state, TimelineActor& self, TerritoryPtr pTeri, uint64_t time ) const;
|
|
|
|
void execute( TimepointState& state, TimelineActor& self, TerritoryPtr pTeri, uint64_t time ) const;
|
2024-04-29 16:51:28 +01:00
|
|
|
};
|
|
|
|
|
2024-05-06 01:45:42 +01:00
|
|
|
class Phase :
|
|
|
|
public std::enable_shared_from_this< Phase >
|
2024-04-29 16:51:28 +01:00
|
|
|
{
|
|
|
|
public:
|
2024-05-06 01:45:42 +01:00
|
|
|
|
2024-05-23 18:40:37 +01:00
|
|
|
// todo: allow callbacks to push timepoints
|
2024-05-06 01:45:42 +01:00
|
|
|
|
2024-04-29 16:51:28 +01:00
|
|
|
std::string m_name;
|
2024-05-09 16:17:46 +01:00
|
|
|
std::vector< Timepoint > m_timepoints;
|
2024-05-06 01:45:42 +01:00
|
|
|
|
|
|
|
// todo: i wrote this very sleep deprived, ensure it is actually sane
|
2024-05-27 01:45:37 +01:00
|
|
|
void execute( ConditionState& state, TimelineActor& self, TerritoryPtr pTeri, uint64_t time ) const
|
2024-04-29 16:51:28 +01:00
|
|
|
{
|
2024-05-10 22:46:33 +01:00
|
|
|
if( state.m_startTime == 0 )
|
|
|
|
state.m_startTime = time;
|
|
|
|
if( state.m_phaseInfo.m_startTime == 0 )
|
|
|
|
state.m_phaseInfo.m_startTime = time;
|
2024-05-11 00:07:09 +01:00
|
|
|
|
2024-05-10 22:46:33 +01:00
|
|
|
if( state.m_phaseInfo.m_lastTimepointTime == 0 )
|
2024-05-11 00:07:09 +01:00
|
|
|
{
|
2024-05-10 22:46:33 +01:00
|
|
|
state.m_phaseInfo.m_lastTimepointTime = time;
|
2024-05-11 00:07:09 +01:00
|
|
|
state.m_phaseInfo.m_timepointStates.clear();
|
|
|
|
state.m_phaseInfo.m_timepointStates.resize( m_timepoints.size() );
|
|
|
|
}
|
2024-05-10 22:46:33 +01:00
|
|
|
|
|
|
|
for( auto i = state.m_phaseInfo.m_lastTimepointIndex; i < m_timepoints.size(); )
|
2024-05-06 01:45:42 +01:00
|
|
|
{
|
2024-05-10 22:46:33 +01:00
|
|
|
uint64_t phaseElapsed = time - state.m_phaseInfo.m_startTime;
|
|
|
|
uint64_t timepointElapsed = time - state.m_phaseInfo.m_lastTimepointTime;
|
|
|
|
|
|
|
|
auto& tpState = state.m_phaseInfo.m_timepointStates[ i ];
|
2024-05-09 16:17:46 +01:00
|
|
|
auto& timepoint = m_timepoints[ i ];
|
2024-05-23 18:40:37 +01:00
|
|
|
|
2024-05-10 22:46:33 +01:00
|
|
|
if( timepoint.canExecute( tpState, timepointElapsed ) )
|
2024-05-06 01:45:42 +01:00
|
|
|
{
|
2024-05-27 01:45:37 +01:00
|
|
|
timepoint.execute( tpState, self, pTeri, time );
|
2024-05-10 22:46:33 +01:00
|
|
|
state.m_phaseInfo.m_lastTimepointTime = time;
|
2024-05-06 01:45:42 +01:00
|
|
|
}
|
2024-05-10 22:46:33 +01:00
|
|
|
else if( !timepoint.finished( tpState, timepointElapsed ) )
|
2024-05-10 15:18:06 +01:00
|
|
|
{
|
2024-05-27 01:45:37 +01:00
|
|
|
timepoint.update( tpState, self, pTeri, time );
|
2024-05-10 15:18:06 +01:00
|
|
|
}
|
2024-05-09 16:17:46 +01:00
|
|
|
|
2024-05-23 18:40:37 +01:00
|
|
|
if( timepoint.durationElapsed( timepointElapsed ) && timepoint.finished( tpState, timepointElapsed ) )
|
2024-05-06 01:45:42 +01:00
|
|
|
{
|
2024-05-10 22:46:33 +01:00
|
|
|
timepoint.reset( tpState );
|
2024-05-10 15:18:06 +01:00
|
|
|
// make sure this timepoint isnt run again unless phase loops
|
2024-05-09 16:17:46 +01:00
|
|
|
++i;
|
2024-05-10 22:46:33 +01:00
|
|
|
state.m_phaseInfo.m_lastTimepointIndex = i;
|
|
|
|
|
|
|
|
if( i == m_timepoints.size() )
|
|
|
|
{
|
|
|
|
state.m_phaseInfo.m_lastTimepointIndex++;
|
|
|
|
}
|
2024-05-09 16:17:46 +01:00
|
|
|
continue;
|
2024-05-06 01:45:42 +01:00
|
|
|
}
|
2024-05-09 16:17:46 +01:00
|
|
|
break;
|
2024-05-06 01:45:42 +01:00
|
|
|
}
|
2024-04-29 16:51:28 +01:00
|
|
|
}
|
2024-05-06 20:13:53 +01:00
|
|
|
|
2024-05-10 22:46:33 +01:00
|
|
|
void reset( ConditionState& state ) const
|
|
|
|
{
|
|
|
|
state.m_phaseInfo.m_startTime = 0;
|
|
|
|
state.m_phaseInfo.m_lastTimepointIndex = 0;
|
|
|
|
state.m_phaseInfo.m_lastTimepointTime = 0;
|
|
|
|
|
|
|
|
state.m_phaseInfo.m_timepointStates.clear();
|
2024-05-11 00:07:09 +01:00
|
|
|
state.m_phaseInfo.m_timepointStates.resize( m_timepoints.size() );
|
2024-05-10 22:46:33 +01:00
|
|
|
}
|
|
|
|
|
2024-05-23 18:40:37 +01:00
|
|
|
bool completed( const ConditionState& state ) const
|
2024-05-06 20:13:53 +01:00
|
|
|
{
|
2024-05-10 22:46:33 +01:00
|
|
|
return state.m_phaseInfo.m_lastTimepointIndex > m_timepoints.size();
|
2024-05-06 20:13:53 +01:00
|
|
|
}
|
2024-04-29 16:51:28 +01:00
|
|
|
};
|
2024-05-06 01:45:42 +01:00
|
|
|
using PhasePtr = std::shared_ptr< Phase >;
|
2024-04-29 16:51:28 +01:00
|
|
|
|
2024-05-09 16:17:46 +01:00
|
|
|
class PhaseCondition :
|
|
|
|
public std::enable_shared_from_this< PhaseCondition >
|
2024-04-29 16:51:28 +01:00
|
|
|
{
|
2024-05-10 22:46:33 +01:00
|
|
|
protected:
|
2024-05-06 01:45:42 +01:00
|
|
|
ConditionId m_conditionId{ 0 };
|
2024-05-06 20:13:53 +01:00
|
|
|
Phase m_phase;
|
2024-05-09 16:17:46 +01:00
|
|
|
std::string m_description;
|
2024-05-10 22:46:33 +01:00
|
|
|
uint32_t m_cooldown{ 0 };
|
|
|
|
bool m_loop{ false };
|
2024-05-23 18:40:37 +01:00
|
|
|
bool m_enabled{ true };
|
|
|
|
|
2024-05-10 22:46:33 +01:00
|
|
|
public:
|
2024-05-09 16:17:46 +01:00
|
|
|
PhaseCondition() {}
|
|
|
|
~PhaseCondition() {}
|
2024-04-29 16:51:28 +01:00
|
|
|
|
2024-05-10 17:42:39 +01:00
|
|
|
virtual void from_json( nlohmann::json& json, Phase& phase, ConditionId conditionId )
|
2024-04-29 16:51:28 +01:00
|
|
|
{
|
|
|
|
this->m_conditionId = conditionId;
|
|
|
|
this->m_loop = json.at( "loop" ).get< bool >();
|
2024-05-09 16:17:46 +01:00
|
|
|
//this->m_cooldown = json.at( "cooldown" ).get< uint32_t >();
|
2024-05-06 20:13:53 +01:00
|
|
|
this->m_phase = phase;
|
2024-05-10 22:46:33 +01:00
|
|
|
this->m_description = json.at( "description" ).get< std::string >();
|
2024-05-23 18:40:37 +01:00
|
|
|
this->m_enabled = json.at( "enabled" ).get< bool >();
|
2024-04-29 16:51:28 +01:00
|
|
|
}
|
|
|
|
|
2024-05-27 01:45:37 +01:00
|
|
|
void execute( ConditionState& state, TimelineActor& self, TerritoryPtr pTeri, TimelinePack& pack, uint64_t time ) const
|
2024-04-29 16:51:28 +01:00
|
|
|
{
|
2024-05-10 22:46:33 +01:00
|
|
|
state.m_startTime = time;
|
2024-05-27 01:45:37 +01:00
|
|
|
m_phase.execute( state, self, pTeri, time );
|
2024-04-29 16:51:28 +01:00
|
|
|
};
|
|
|
|
|
2024-05-27 01:45:37 +01:00
|
|
|
void update( ConditionState& state, TimelineActor& self, TerritoryPtr pTeri, TimelinePack& pack, uint64_t time ) const
|
2024-05-09 16:17:46 +01:00
|
|
|
{
|
2024-05-27 01:45:37 +01:00
|
|
|
m_phase.execute( state, self, pTeri, time );
|
2024-05-23 18:40:37 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
void setEnabled( ConditionState& state, bool enabled )
|
|
|
|
{
|
|
|
|
state.m_enabled = enabled;
|
2024-05-09 16:17:46 +01:00
|
|
|
}
|
|
|
|
|
2024-05-10 22:46:33 +01:00
|
|
|
void reset( ConditionState& state ) const
|
2024-05-09 16:17:46 +01:00
|
|
|
{
|
2024-05-10 22:46:33 +01:00
|
|
|
state.m_startTime = 0;
|
2024-05-23 18:40:37 +01:00
|
|
|
state.m_enabled = isDefaultEnabled();
|
2024-05-10 22:46:33 +01:00
|
|
|
m_phase.reset( state );
|
2024-05-09 16:17:46 +01:00
|
|
|
}
|
|
|
|
|
2024-05-23 18:40:37 +01:00
|
|
|
bool inProgress( const ConditionState& state ) const
|
2024-05-09 16:17:46 +01:00
|
|
|
{
|
2024-05-10 22:46:33 +01:00
|
|
|
return state.m_startTime != 0;
|
2024-05-09 16:17:46 +01:00
|
|
|
}
|
|
|
|
|
2024-05-23 18:40:37 +01:00
|
|
|
// todo: better naming
|
|
|
|
bool isStateEnabled( const ConditionState& state ) const
|
|
|
|
{
|
|
|
|
return state.m_enabled;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool isDefaultEnabled() const
|
|
|
|
{
|
|
|
|
return m_enabled;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool completed( const ConditionState& state ) const
|
2024-05-06 20:13:53 +01:00
|
|
|
{
|
2024-05-10 22:46:33 +01:00
|
|
|
return m_phase.completed( state );
|
2024-05-06 20:13:53 +01:00
|
|
|
}
|
|
|
|
|
2024-05-10 22:46:33 +01:00
|
|
|
bool isLoopable() const
|
2024-05-09 16:17:46 +01:00
|
|
|
{
|
|
|
|
return m_loop;
|
|
|
|
}
|
|
|
|
|
2024-05-10 22:46:33 +01:00
|
|
|
bool loopReady( ConditionState& state, uint64_t time ) const
|
2024-05-06 20:13:53 +01:00
|
|
|
{
|
2024-05-10 22:46:33 +01:00
|
|
|
return m_phase.completed( state ) && m_loop && ( state.m_startTime + m_cooldown <= time );
|
2024-05-06 20:13:53 +01:00
|
|
|
}
|
|
|
|
|
2024-05-27 01:45:37 +01:00
|
|
|
virtual bool isConditionMet( ConditionState& state, TerritoryPtr pTeri, TimelinePack& pack, uint64_t time ) const
|
2024-04-29 16:51:28 +01:00
|
|
|
{
|
|
|
|
return false;
|
|
|
|
};
|
|
|
|
|
|
|
|
};
|
2024-05-09 16:17:46 +01:00
|
|
|
using PhaseConditionPtr = std::shared_ptr< PhaseCondition >;
|
2024-04-29 16:51:28 +01:00
|
|
|
|
2024-05-09 16:17:46 +01:00
|
|
|
class TimelineActor
|
|
|
|
{
|
2024-05-10 22:46:33 +01:00
|
|
|
protected:
|
|
|
|
std::vector< PhaseConditionPtr > m_phaseConditions;
|
|
|
|
std::queue< PhaseConditionPtr > m_phaseHistory;
|
|
|
|
std::vector< ConditionState > m_conditionStates;
|
2024-05-27 01:45:37 +01:00
|
|
|
// PARENTNAME_SUBACTOR_1, ..., PARENTNAME_SUBACTOR_69
|
|
|
|
std::map< std::string, Entity::BNpcPtr > m_subActors;
|
2024-05-09 16:17:46 +01:00
|
|
|
public:
|
2024-05-09 17:27:51 +01:00
|
|
|
uint32_t m_layoutId{ 0 };
|
|
|
|
uint32_t m_hp{ 0 };
|
2024-05-09 16:17:46 +01:00
|
|
|
std::string m_name;
|
|
|
|
|
2024-05-10 23:39:06 +01:00
|
|
|
TimelineActor() { }
|
|
|
|
TimelineActor( const TimelineActor& rhs ) :
|
|
|
|
m_layoutId( rhs.m_layoutId ),
|
|
|
|
m_hp( rhs.m_hp ),
|
|
|
|
m_name( rhs.m_name ),
|
|
|
|
m_phaseConditions( rhs.m_phaseConditions ),
|
|
|
|
m_conditionStates( rhs.m_conditionStates )
|
|
|
|
{
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2024-05-10 22:46:33 +01:00
|
|
|
void addPhaseCondition( PhaseConditionPtr pCondition )
|
|
|
|
{
|
|
|
|
m_phaseConditions.push_back( pCondition );
|
|
|
|
m_conditionStates.push_back( {} );
|
2024-05-23 18:40:37 +01:00
|
|
|
m_conditionStates[ m_conditionStates.size() - 1 ].m_enabled = pCondition->isDefaultEnabled();
|
2024-05-10 22:46:33 +01:00
|
|
|
}
|
2024-05-09 16:17:46 +01:00
|
|
|
|
2024-05-27 01:45:37 +01:00
|
|
|
// todo: make this sane
|
|
|
|
void update( TerritoryPtr pTeri, TimelinePack& pack, uint64_t time )
|
2024-05-09 16:17:46 +01:00
|
|
|
{
|
|
|
|
// todo: handle interrupts
|
2024-05-10 22:46:33 +01:00
|
|
|
for( auto i = 0; i < m_phaseConditions.size(); ++i )
|
2024-05-09 16:17:46 +01:00
|
|
|
{
|
2024-05-10 22:46:33 +01:00
|
|
|
const auto& pCondition = m_phaseConditions[ i ];
|
|
|
|
auto& state = m_conditionStates[ i ];
|
|
|
|
|
2024-05-23 18:40:37 +01:00
|
|
|
// ignore if not enabled, unless overriden to enable
|
2024-05-27 01:45:37 +01:00
|
|
|
if( !pCondition->isStateEnabled( state ) )
|
2024-05-23 18:40:37 +01:00
|
|
|
continue;
|
|
|
|
|
2024-05-10 22:46:33 +01:00
|
|
|
if( pCondition->completed( state ) )
|
2024-05-09 16:17:46 +01:00
|
|
|
{
|
|
|
|
if( pCondition->isLoopable() )
|
|
|
|
{
|
2024-05-10 22:46:33 +01:00
|
|
|
if( pCondition->loopReady( state, time ) )
|
|
|
|
pCondition->reset( state );
|
2024-05-09 16:17:46 +01:00
|
|
|
}
|
|
|
|
}
|
2024-05-10 22:46:33 +01:00
|
|
|
else if( pCondition->inProgress( state ) )
|
2024-05-09 16:17:46 +01:00
|
|
|
{
|
2024-05-27 01:45:37 +01:00
|
|
|
pCondition->update( state, *this, pTeri, pack, time );
|
2024-05-09 16:17:46 +01:00
|
|
|
}
|
2024-05-27 01:45:37 +01:00
|
|
|
else if( pCondition->isConditionMet( state, pTeri, pack, time ) )
|
2024-05-09 16:17:46 +01:00
|
|
|
{
|
2024-05-27 01:45:37 +01:00
|
|
|
pCondition->execute( state, *this, pTeri, pack, time );
|
2024-05-09 16:17:46 +01:00
|
|
|
m_phaseHistory.push( pCondition );
|
2024-05-23 18:40:37 +01:00
|
|
|
|
|
|
|
if( pack.getStartTime() == 0 )
|
|
|
|
pack.setStartTime( state.m_startTime );
|
2024-05-09 16:17:46 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2024-05-23 18:40:37 +01:00
|
|
|
|
|
|
|
void resetConditionState( uint32_t conditionIdx )
|
|
|
|
{
|
|
|
|
assert( conditionIdx < m_phaseConditions.size() );
|
|
|
|
|
|
|
|
const auto& pCondition = m_phaseConditions[ conditionIdx ];
|
|
|
|
auto& state = m_conditionStates[ conditionIdx ];
|
|
|
|
|
|
|
|
pCondition->reset( state );
|
|
|
|
}
|
|
|
|
|
|
|
|
void setConditionStateEnabled( uint32_t conditionIdx, bool enabled )
|
|
|
|
{
|
|
|
|
assert( conditionIdx < m_conditionStates.size() );
|
|
|
|
|
|
|
|
auto& state = m_conditionStates[ conditionIdx ];
|
|
|
|
state.m_enabled = enabled;
|
|
|
|
}
|
2024-05-27 01:45:37 +01:00
|
|
|
|
|
|
|
void resetAllConditionStates()
|
|
|
|
{
|
|
|
|
for( auto i = 0; i < m_phaseConditions.size(); ++i )
|
|
|
|
{
|
|
|
|
const auto& pCondition = m_phaseConditions[ i ];
|
|
|
|
auto& state = m_conditionStates[ i ];
|
|
|
|
|
|
|
|
pCondition->reset( state );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
Entity::BNpcPtr spawnSubActor( TerritoryPtr pTeri, const std::string& name );
|
|
|
|
Entity::BNpcPtr getSubActor( const std::string& name );
|
|
|
|
void resetSubActors( TerritoryPtr pTeri );
|
2024-05-09 16:17:46 +01:00
|
|
|
};
|
|
|
|
|
2024-05-10 22:46:33 +01:00
|
|
|
// todo: actually handle solo stuff properly (or tie to zone director/content director at least)
|
2024-05-09 16:17:46 +01:00
|
|
|
class TimelinePack
|
|
|
|
{
|
2024-05-27 01:45:37 +01:00
|
|
|
TimelinePackType m_type{TimelinePackType::EncounterFight};
|
2024-05-09 16:17:46 +01:00
|
|
|
std::vector< TimelineActor > m_actors;
|
|
|
|
std::string m_name;
|
|
|
|
|
2024-05-10 22:46:33 +01:00
|
|
|
uint64_t m_startTime{ 0 };
|
2024-05-09 16:17:46 +01:00
|
|
|
public:
|
|
|
|
TimelinePack() { }
|
2024-05-10 23:39:06 +01:00
|
|
|
TimelinePack( const TimelinePack& rhs ) :
|
|
|
|
m_type( rhs.m_type ),
|
|
|
|
m_name( rhs.m_name ),
|
|
|
|
m_actors( rhs.m_actors ),
|
|
|
|
m_startTime( 0 )
|
|
|
|
{
|
|
|
|
|
|
|
|
}
|
2024-05-09 16:17:46 +01:00
|
|
|
TimelinePack( TimelinePackType type ) : m_type( type ) {}
|
2024-05-10 22:46:33 +01:00
|
|
|
|
2024-05-10 23:39:06 +01:00
|
|
|
void setName( const std::string& name )
|
|
|
|
{
|
|
|
|
m_name = name;
|
|
|
|
}
|
|
|
|
|
2024-05-11 00:07:09 +01:00
|
|
|
void addTimelineActor( const TimelineActor& actor )
|
2024-05-10 23:39:06 +01:00
|
|
|
{
|
2024-05-27 01:45:37 +01:00
|
|
|
m_actors.emplace_back( actor );
|
2024-05-10 23:39:06 +01:00
|
|
|
}
|
|
|
|
|
2024-05-10 22:46:33 +01:00
|
|
|
void setStartTime( uint64_t time )
|
|
|
|
{
|
|
|
|
m_startTime = time;
|
|
|
|
}
|
|
|
|
|
|
|
|
uint64_t getStartTime() const
|
|
|
|
{
|
|
|
|
return m_startTime;
|
|
|
|
}
|
|
|
|
|
2024-05-27 01:45:37 +01:00
|
|
|
void update( TerritoryPtr pTeri, uint64_t time )
|
2024-05-09 16:17:46 +01:00
|
|
|
{
|
|
|
|
for( auto& actor : m_actors )
|
2024-05-27 01:45:37 +01:00
|
|
|
actor.update( pTeri, *this, time );
|
2024-05-09 16:17:46 +01:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
//
|
|
|
|
// Conditions
|
|
|
|
//
|
|
|
|
class ConditionHp : PhaseCondition
|
2024-04-29 16:51:28 +01:00
|
|
|
{
|
|
|
|
public:
|
2024-05-09 17:27:51 +01:00
|
|
|
uint32_t layoutId;
|
2024-04-29 16:51:28 +01:00
|
|
|
union
|
|
|
|
{
|
|
|
|
uint8_t val;
|
|
|
|
struct
|
|
|
|
{
|
2024-05-09 16:17:46 +01:00
|
|
|
uint8_t min, max;
|
2024-04-29 16:51:28 +01:00
|
|
|
};
|
|
|
|
} hp;
|
|
|
|
|
2024-05-10 17:42:39 +01:00
|
|
|
void from_json( nlohmann::json& json, Phase& phase, ConditionId conditionId,
|
2024-05-09 16:17:46 +01:00
|
|
|
const std::unordered_map< std::string, TimelineActor >& actors );
|
|
|
|
|
2024-05-27 01:45:37 +01:00
|
|
|
bool isConditionMet( ConditionState& state, TerritoryPtr pTeri, TimelinePack& pack, uint64_t time ) const override;
|
2024-04-29 16:51:28 +01:00
|
|
|
};
|
|
|
|
|
2024-05-09 16:17:46 +01:00
|
|
|
class ConditionDirectorVar : PhaseCondition
|
2024-04-29 16:51:28 +01:00
|
|
|
{
|
|
|
|
public:
|
2024-05-06 20:13:53 +01:00
|
|
|
union
|
|
|
|
{
|
|
|
|
struct
|
|
|
|
{
|
2024-05-10 17:42:39 +01:00
|
|
|
uint32_t index;
|
2024-05-06 20:13:53 +01:00
|
|
|
uint32_t value;
|
|
|
|
};
|
|
|
|
uint8_t seq;
|
2024-05-10 17:42:39 +01:00
|
|
|
uint8_t flags;
|
2024-05-06 20:13:53 +01:00
|
|
|
} param;
|
2024-05-09 16:17:46 +01:00
|
|
|
|
2024-05-10 17:42:39 +01:00
|
|
|
void from_json( nlohmann::json& json, Phase& phase, ConditionId conditionId );
|
2024-05-27 01:45:37 +01:00
|
|
|
bool isConditionMet( ConditionState& state, TerritoryPtr pTeri, TimelinePack& pack, uint64_t time ) const override;
|
2024-05-10 17:42:39 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
class ConditionEncounterTimeElapsed : PhaseCondition
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
uint64_t duration;
|
|
|
|
|
|
|
|
void from_json( nlohmann::json& json, Phase& phase, ConditionId conditionId );
|
2024-05-27 01:45:37 +01:00
|
|
|
bool isConditionMet( ConditionState& state, TerritoryPtr pTeri, TimelinePack& pack, uint64_t time ) const override;
|
2024-04-29 16:51:28 +01:00
|
|
|
};
|
|
|
|
|
2024-05-09 16:17:46 +01:00
|
|
|
class ConditionCombatState : PhaseCondition
|
|
|
|
{
|
|
|
|
public:
|
2024-05-09 17:27:51 +01:00
|
|
|
uint32_t layoutId;
|
|
|
|
CombatStateType combatState;
|
2024-05-09 16:17:46 +01:00
|
|
|
|
2024-05-10 17:42:39 +01:00
|
|
|
void from_json( nlohmann::json& json, Phase& phase, ConditionId conditionId, const std::unordered_map< std::string, TimelineActor >& actors );
|
2024-05-27 01:45:37 +01:00
|
|
|
bool isConditionMet( ConditionState& state, TerritoryPtr pTeri, TimelinePack& pack, uint64_t time ) const override;
|
2024-05-10 17:42:39 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
class ConditionBNpcFlags : PhaseCondition
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
uint32_t layoutId;
|
|
|
|
uint32_t flags;
|
|
|
|
|
|
|
|
void from_json( nlohmann::json& json, Phase& phase, ConditionId conditionId, const std::unordered_map< std::string, TimelineActor >& actors );
|
2024-05-27 01:45:37 +01:00
|
|
|
bool isConditionMet( ConditionState& state, TerritoryPtr pTeri, TimelinePack& pack, uint64_t time ) const override;
|
2024-05-09 16:17:46 +01:00
|
|
|
};
|
2024-04-29 16:51:28 +01:00
|
|
|
|
|
|
|
public:
|
|
|
|
|
2024-05-27 01:45:37 +01:00
|
|
|
TimelinePack getEncounterPack( const std::string& name, bool reload = false );
|
2024-04-29 16:51:28 +01:00
|
|
|
};
|
|
|
|
}// namespace Sapphire
|