1
Fork 0
mirror of https://github.com/SapphireServer/Sapphire.git synced 2025-05-03 09:17:47 +00:00

more encounter timeline work

This commit is contained in:
Tahir 2024-05-06 01:45:42 +01:00
parent 41ac3b88a6
commit 6c5df82306
3 changed files with 287 additions and 158 deletions

View file

@ -134,6 +134,11 @@ namespace Sapphire
m_bnpcs.erase( layoutId ); m_bnpcs.erase( layoutId );
} }
InstanceContentPtr getInstance()
{
return m_pInstance;
}
protected: protected:
uint64_t m_startTime{ 0 }; uint64_t m_startTime{ 0 };
EncounterState::StateStackPtr m_stateStack; EncounterState::StateStackPtr m_stateStack;

View file

@ -6,21 +6,21 @@
namespace Sapphire namespace Sapphire
{ {
void EncounterTimeline::EncounterConditionHp::from_json( nlohmann::json& json, EncounterPhasePtr pPhase, EncounterConditionId conditionId ) void EncounterTimeline::ConditionHp::from_json( nlohmann::json& json, PhasePtr pPhase, ConditionId conditionId )
{ {
EncounterTimepointCondition::from_json( json, pPhase, conditionId ); TimepointCondition::from_json( json, pPhase, conditionId );
auto params = json.at( "params" ).get< std::vector< uint32_t > >(); auto params = json.at( "params" ).get< std::vector< uint32_t > >();
this->actorId = params[ 0 ]; this->actorId = params[ 0 ];
if( conditionId == EncounterConditionId::HpPctLessThan ) if( conditionId == ConditionId::HpPctLessThan )
this->hp.val = params[ 1 ]; this->hp.val = params[ 1 ];
else else
this->hp.min = params[ 1 ], this->hp.max = params[ 2 ]; this->hp.min = params[ 1 ], this->hp.max = params[ 2 ];
} }
bool EncounterTimeline::EncounterConditionHp::canExecute( EncounterFightPtr pFight, uint64_t time ) bool EncounterTimeline::ConditionHp::canExecute( EncounterFightPtr pFight, uint64_t time )
{ {
auto pBNpc = pFight->getBNpc( actorId ); auto pBNpc = pFight->getBNpc( actorId );
if( !pBNpc ) if( !pBNpc )
@ -30,9 +30,9 @@ namespace Sapphire
switch( m_conditionId ) switch( m_conditionId )
{ {
case EncounterConditionId::HpPctLessThan: case ConditionId::HpPctLessThan:
return pBNpc->getHpPercent() < hp.val; return pBNpc->getHpPercent() < hp.val;
case EncounterConditionId::HpPctBetween: case ConditionId::HpPctBetween:
{ {
auto hpPct = pBNpc->getHpPercent(); auto hpPct = pBNpc->getHpPercent();
return hpPct >= hp.min && hpPct <= hp.max; return hpPct >= hp.min && hpPct <= hp.max;
@ -41,9 +41,9 @@ namespace Sapphire
return false; return false;
}; };
void EncounterTimeline::EncounterConditionDirectorVar::from_json( nlohmann::json& json, EncounterPhasePtr pPhase, EncounterConditionId conditionId ) void EncounterTimeline::ConditionDirectorVar::from_json( nlohmann::json& json, PhasePtr pPhase, ConditionId conditionId )
{ {
EncounterTimepointCondition::from_json( json, pPhase, conditionId ); TimepointCondition::from_json( json, pPhase, conditionId );
auto params = json.at( "params" ).get< std::vector< uint32_t > >(); auto params = json.at( "params" ).get< std::vector< uint32_t > >();
@ -51,110 +51,142 @@ namespace Sapphire
this->value = params[ 1 ]; this->value = params[ 1 ];
} }
bool EncounterTimeline::EncounterConditionDirectorVar::canExecute( EncounterFightPtr pFight, uint64_t time ) bool EncounterTimeline::ConditionDirectorVar::canExecute( EncounterFightPtr pFight, uint64_t time )
{ {
auto pInstance = pFight->getInstance();
// todo: use something other than InstanceContentPtr
if( !pInstance )
return false;
switch( m_conditionId ) switch( m_conditionId )
{ {
case EncounterConditionId::DirectorVarEquals: case ConditionId::DirectorVarEquals:
return false; // pFight->getDirectorVar( directorVar ) == value; return pInstance->getDirectorVar( directorVar ) == value;
case EncounterConditionId::DirectorVarGreaterThan: case ConditionId::DirectorVarGreaterThan:
return false; // pFight->getDirectorVar( directorVar ) > value; return pInstance->getDirectorVar( directorVar ) > value;
} }
return false; return false;
} }
void EncounterTimeline::Timepoint::execute( EncounterFightPtr pFight, uint64_t time )
{
switch( m_type )
{
case TimepointDataType::Idle:
{
auto pIdleData = std::dynamic_pointer_cast< TimepointDataIdle, TimepointData >( m_pData );
auto pBNpc = pFight->getBNpc( pIdleData->m_actorId );
if( pBNpc )
{
// todo: idle
}
}
break;
case TimepointDataType::CastAction:
{
auto pActionData = std::dynamic_pointer_cast< TimepointDataAction, TimepointData >( m_pData );
// todo: filter the correct target
// todo: tie to mechanic script?
}
break;
case TimepointDataType::MoveTo:
{
auto pMoveToData = std::dynamic_pointer_cast< TimepointDataMoveTo, TimepointData >( m_pData );
auto pBNpc = pFight->getBNpc( pMoveToData->m_actorId );
// todo: path
if( pBNpc )
{
pBNpc->setPos( pMoveToData->m_x, pMoveToData->m_y, pMoveToData->m_z );
pBNpc->setRot( pMoveToData->m_rot );
pBNpc->sendPositionUpdate();
}
}
break;
case TimepointDataType::BattleTalk:
{
// auto pBattleTalkData = std::dynamic_pointer_cast< TimepointDataBattleTalk, TimepointData >();
}
break;
case TimepointDataType::SetDirectorSeq:
case TimepointDataType::SetDirectorVar:
case TimepointDataType::SetDirectorFlag:
{
auto pDirectorData = std::dynamic_pointer_cast< TimepointDataDirector, TimepointData >( m_pData );
auto pInstance = pFight->getInstance();
// todo: this should never not be set?
// todo: probably should use ContentDirector
if( pInstance )
{
switch( pDirectorData->m_directorOp )
{
case DirectorOpId::SetDirectorVar:
pInstance->setDirectorVar( pDirectorData->m_data.index, pDirectorData->m_data.value.val );
break;
case DirectorOpId::SetDirectorVarLR:
pInstance->setDirectorVar( pDirectorData->m_data.index, pDirectorData->m_data.value.left, pDirectorData->m_data.value.right );
break;
case DirectorOpId::SetDirectorFlag:
pInstance->setDirectorFlags( pDirectorData->m_data.flags );
break;
case DirectorOpId::SetDirectorSeq:
pInstance->setDirectorSequence( pDirectorData->m_data.seq );
break;
case DirectorOpId::ClearDirectorFlag:
break;
default:
// probably throw an error here
break;
}
}
}
break;
}
}
EncounterTimeline::EncounterTimelineInfo EncounterTimeline::buildEncounterTimeline( uint32_t encounterId, bool reload ) EncounterTimeline::EncounterTimelineInfo EncounterTimeline::buildEncounterTimeline( uint32_t encounterId, bool reload )
{ {
static std::map< uint32_t, EncounterTimelineInfo > cache = {}; static std::map< uint32_t, EncounterTimelineInfo > cache = {};
const static std::map< std::string, EncounterTimepointDataType > timepointTypeMap = const static std::map< std::string, TimepointDataType > timepointTypeMap =
{ {
{ "idle", EncounterTimepointDataType::Idle }, { "idle", TimepointDataType::Idle },
{ "castAction", EncounterTimepointDataType::CastAction }, { "castAction", TimepointDataType::CastAction },
{ "moveTo", EncounterTimepointDataType::MoveTo }, { "moveTo", TimepointDataType::MoveTo },
{ "logMessage", EncounterTimepointDataType::LogMessage }, { "logMessage", TimepointDataType::LogMessage },
{ "setDirectorVar", EncounterTimepointDataType::SetDirectorVar }, { "setDirectorVar", TimepointDataType::SetDirectorVar },
{ "addStatusEffect", EncounterTimepointDataType::AddStatusEffect }, { "setDirectorSeq", TimepointDataType::SetDirectorSeq },
{ "removeStatusEffect", EncounterTimepointDataType::RemoveStatusEffect } { "setDirectorFlags", TimepointDataType::SetDirectorFlag },
{ "addStatusEffect", TimepointDataType::AddStatusEffect },
{ "removeStatusEffect", TimepointDataType::RemoveStatusEffect }
}; };
const static std::map< std::string, EncounterTimepointCallbackType > callbackTypeMap = const static std::map< std::string, TimepointCallbackType > callbackTypeMap =
{ {
{ "onActionInit", EncounterTimepointCallbackType::OnActionInit }, { "onActionInit", TimepointCallbackType::OnActionInit },
{ "onActionStart", EncounterTimepointCallbackType::OnActionStart }, { "onActionStart", TimepointCallbackType::OnActionStart },
{ "onActionInterrupt", EncounterTimepointCallbackType::OnActionInterrupt }, { "onActionInterrupt", TimepointCallbackType::OnActionInterrupt },
{ "onActionExecute", EncounterTimepointCallbackType::OnActionExecute }, { "onActionExecute", TimepointCallbackType::OnActionExecute },
}; };
const static std::map< std::string, EncounterConditionId > conditionIdMap = const static std::map< std::string, ConditionId > conditionIdMap =
{ {
{ "hpPctLessThan", EncounterConditionId::HpPctLessThan }, { "hpPctLessThan", ConditionId::HpPctLessThan },
{ "hpPctBetween", EncounterConditionId::HpPctBetween }, { "hpPctBetween", ConditionId::HpPctBetween },
{ "directorVarEquals", EncounterConditionId::DirectorVarEquals }, { "directorVarEquals", ConditionId::DirectorVarEquals },
{ "directorVarGreaterThan", EncounterConditionId::DirectorVarGreaterThan }, { "directorVarGreaterThan", ConditionId::DirectorVarGreaterThan },
{ "encounterTimeElapsed", ConditionId::EncounterTimeElapsed },
{ "phaseTimeElapsed", ConditionId::PhaseTimeElapsed }
}; };
EncounterTimelineInfo info; EncounterTimelineInfo info;
if( cache.find( encounterId ) != cache.end() && !reload ) if( cache.find( encounterId ) != cache.end() && !reload )
return cache.at( encounterId ); return cache.at( encounterId );
/* /*
array of states e.g. class RngCondition : TimepointCondition
[
pushStates:
[
{
condition: "HpPctBetween", params:[ 20, 25 ], state: "phase1", loop: true
},
{
condition: "RNGMinMax", params:[ 0, 10, 5 ], state: "phase1", loop: true
}
],
states:
[
{
name: "idle",
type: "idle",
duration: 5000,
overrideFlags: ["INVULNERABLE"],
data: {}
}
{
name: "phase1",
type: "action",
data: {
actionId: 150,
onFinish: {
type: "addStatusEffect",
data: {
selectFilter: "self",
statusEffectId: 70,
duration: 30000
}
}
}
}
]
]
/*
*
class HpPercentCondition : EncounterTimepointCondition
{
EncounterTimepointConditionId m_type;
std::vector< uint32_t > m_params
HpPercentCondition( EncounterTimepointConditionId conditionId std::vector< uint32_t params ) : m_type( conditionId ), m_params( params ){}
bool isConditionMet( uint32_t bossHpPct )
{
switch( m_type )
{
case EncounterTimepointConditionId::HpLessThanPct:
return bossHpPct < m_params[0];
case EncounterTimepointConditionId::HpBetweenPct:
return bossHpPct >= m_params[0] && bossHpPct <= m_params[1];
}
return false;
}
}
class RngCondition : EncounterTimepointCondition
{ {
EncounterTimepointConditionId m_type; EncounterTimepointConditionId m_type;
std::vector< uint32_t > m_params std::vector< uint32_t > m_params
@ -196,7 +228,7 @@ namespace Sapphire
auto json = nlohmann::json::parse( f ); auto json = nlohmann::json::parse( f );
std::map< std::string, EncounterPhasePtr > phaseNameMap; std::map< std::string, PhasePtr > phaseNameMap;
for( const auto& phaseJ : json.at( "phases" ).items() ) for( const auto& phaseJ : json.at( "phases" ).items() )
@ -206,7 +238,7 @@ namespace Sapphire
const auto& phaseName = phaseV.at( "name" ).get< std::string >(); const auto& phaseName = phaseV.at( "name" ).get< std::string >();
const auto& timepoints = phaseV.at( "timepoints" ); const auto& timepoints = phaseV.at( "timepoints" );
EncounterPhasePtr pPhase = std::make_shared< EncounterPhase >(); PhasePtr pPhase = std::make_shared< Phase >();
for( const auto& timepoint : timepoints.items() ) for( const auto& timepoint : timepoints.items() )
{ {
@ -228,8 +260,8 @@ namespace Sapphire
auto loop = pcV.at( "loop" ).get< bool >(); auto loop = pcV.at( "loop" ).get< bool >();
auto phaseRef = pcV.at( "phase" ).get< std::string >(); auto phaseRef = pcV.at( "phase" ).get< std::string >();
EncounterPhasePtr pPhase; PhasePtr pPhase;
EncounterConditionId conditionId; ConditionId conditionId;
// make sure condition exists // make sure condition exists
if( auto it = conditionIdMap.find( conditionName ); it != conditionIdMap.end() ) if( auto it = conditionIdMap.find( conditionName ); it != conditionIdMap.end() )
@ -244,20 +276,20 @@ namespace Sapphire
throw std::runtime_error( fmt::format( std::string( "EncounterTimeline::buildEncounterTimeline - no state found by name: %s" ), phaseRef ) ); throw std::runtime_error( fmt::format( std::string( "EncounterTimeline::buildEncounterTimeline - no state found by name: %s" ), phaseRef ) );
// build the condition // build the condition
EncounterTimepointConditionPtr pCondition; TimepointConditionPtr pCondition;
switch( conditionId ) switch( conditionId )
{ {
case EncounterConditionId::HpPctLessThan: case ConditionId::HpPctLessThan:
case EncounterConditionId::HpPctBetween: case ConditionId::HpPctBetween:
{ {
auto pHpCondition = std::make_shared< EncounterConditionHp >(); auto pHpCondition = std::make_shared< ConditionHp >();
pHpCondition->from_json( pcV, pPhase, conditionId ); pHpCondition->from_json( pcV, pPhase, conditionId );
} }
break; break;
case EncounterConditionId::DirectorVarEquals: case ConditionId::DirectorVarEquals:
case EncounterConditionId::DirectorVarGreaterThan: case ConditionId::DirectorVarGreaterThan:
{ {
auto pDirectorCondition = std::make_shared< EncounterConditionDirectorVar >(); auto pDirectorCondition = std::make_shared< ConditionDirectorVar >();
pDirectorCondition->from_json( pcV, pPhase, conditionId ); pDirectorCondition->from_json( pcV, pPhase, conditionId );
} }
break; break;

View file

@ -6,6 +6,7 @@
#include <stdexcept> #include <stdexcept>
#include <string> #include <string>
#include <vector> #include <vector>
#include <queue>
#include <nlohmann/json.hpp> #include <nlohmann/json.hpp>
@ -15,22 +16,33 @@ namespace Sapphire
{ {
public: public:
// EncounterFight::OnTick() { switch EncounterTimepointConditionId } // EncounterFight::OnTick() { switch EncounterTimepointConditionId }
enum class EncounterConditionId : uint32_t enum class ConditionId : uint32_t
{ {
HpPctLessThan, HpPctLessThan,
HpPctBetween, HpPctBetween,
DirectorVarEquals, DirectorVarEquals,
DirectorVarGreaterThan DirectorVarGreaterThan,
PhaseTimeElapsed,
EncounterTimeElapsed
};
enum class DirectorOpId
{
SetDirectorVar,
SetDirectorVarLR,
SetDirectorSeq,
SetDirectorFlag,
ClearDirectorFlag
}; };
// TODO: what should this do? // TODO: what should this do?
enum class EncounterTimepointOverrideFlags enum class TimepointOverrideFlags : uint32_t
{ {
None, None,
Invulnerable Invulnerable
}; };
enum class EncounterTimepointDataType : uint32_t enum class TimepointDataType : uint32_t
{ {
Idle, Idle,
CastAction, CastAction,
@ -38,11 +50,13 @@ namespace Sapphire
LogMessage, LogMessage,
BattleTalk, BattleTalk,
SetDirectorVar, SetDirectorVar,
SetDirectorSeq,
SetDirectorFlag,
AddStatusEffect, AddStatusEffect,
RemoveStatusEffect RemoveStatusEffect
}; };
enum class EncounterTimepointCallbackType : uint32_t enum class TimepointCallbackType : uint32_t
{ {
OnActionInit, OnActionInit,
OnActionStart, OnActionStart,
@ -50,7 +64,7 @@ namespace Sapphire
OnActionExecute OnActionExecute
}; };
enum class TargetSelectFilterIds enum class TargetSelectFilterIds : uint32_t
{ {
Self, Self,
Tank, Tank,
@ -76,97 +90,175 @@ namespace Sapphire
}; };
// Generated Structures using TimepointCallbackFunc = std::function< void( EncounterFightPtr, uint64_t ) >;
// Timepoint Data Objects
// Generated Callback Structure struct TimepointCallbackData :
struct EncounterTimepointCallbackData : public std::enable_shared_from_this< TimepointCallbackData >
public std::enable_shared_from_this< EncounterTimepointCallbackData >
{ {
EncounterTimepointCallbackType m_type; TimepointCallbackType m_type;
std::vector < TimepointCallbackFunc > m_callbacks;
}; };
using EncounterTimepointCallbackDataPtr = std::shared_ptr< EncounterTimepointCallbackData >; using TimebackCallbackDataPtr = std::shared_ptr< TimepointCallbackData >;
using EncounterTimepointCallbacks = std::map< EncounterTimepointCallbackType, EncounterTimepointCallbackDataPtr >; using TimepointCallbacks = std::map< TimepointCallbackType, TimebackCallbackDataPtr >;
// Generated State Objects struct TimepointData :
struct EncounterTimepointData : public std::enable_shared_from_this< TimepointData >
public std::enable_shared_from_this< EncounterTimepointData >
{ {
EncounterTimepointDataType m_type; TimepointData( TimepointDataType) {}
virtual ~TimepointData() = 0;
TimepointDataType m_type;
}; };
using EncounterTimepointDataPtr = std::shared_ptr< EncounterTimepointData >; using TimepointDataPtr = std::shared_ptr< TimepointData >;
struct TimepointDataIdle : public TimepointData
{
uint32_t m_actorId;
uint64_t m_durationMs;
};
// Generated State Data Objects struct TimepointDataStatusEffect : public TimepointData
struct EncounterTimepointDataStatusEffect : EncounterTimepointData
{ {
uint32_t m_statusEffectId; uint32_t m_statusEffectId;
TargetSelectFilter m_targetFilter; TargetSelectFilter m_targetFilter;
uint32_t m_durationMs; uint32_t m_durationMs;
}; };
struct EncounterTimepointDataAction : EncounterTimepointData struct TimepointDataAction : public TimepointData
{ {
uint32_t m_actorId;
uint32_t m_actionId; uint32_t m_actionId;
EncounterTimepointCallbacks m_callbacks; TimepointCallbacks m_callbacks;
}; };
struct EncounterTimepointDataMoveTo : EncounterTimepointData struct TimepointDataMoveTo : public TimepointData
{ {
float x, y, z, rot; uint32_t m_actorId;
MoveType m_moveType;
float m_x, m_y, m_z, m_rot;
}; };
struct EncounterTimepoint :
public std::enable_shared_from_this< EncounterTimepoint > struct TimepointDataLogMessage : public TimepointData
{
uint32_t m_logMessageType;
uint32_t m_logMessageId;
std::string m_message;
};
struct TimepointDataDirector : public TimepointData
{
DirectorOpId m_directorOp;
union
{
struct
{
uint8_t index;
union
{
uint8_t val;
struct
{
uint8_t left, right;
};
} value;
};
uint8_t seq;
uint8_t flags;
} m_data;
};
class Timepoint :
public std::enable_shared_from_this< Timepoint >
{ {
public: public:
EncounterTimepointDataType m_type; TimepointDataType m_type;
uint32_t m_duration; uint64_t m_duration{ 0 };
EncounterTimepointOverrideFlags m_overrideFlags; uint64_t m_executeTime{ 0 };
EncounterTimepointDataPtr m_pData; TimepointOverrideFlags m_overrideFlags;
TimepointDataPtr m_pData;
std::string m_description; std::string m_description;
// switch( m_type ) // todo: repeatable?
virtual void execute( EncounterFightPtr pFight, uint64_t time );
};
using EncounterTimepointPtr = std::shared_ptr< EncounterTimepoint >;
class EncounterPhase : bool canExecute()
public std::enable_shared_from_this< EncounterPhase > {
return m_executeTime == 0;
}
bool finished( uint64_t time )
{
return m_executeTime + m_duration <= time;
}
void execute( EncounterFightPtr pFight, uint64_t time );
};
using TimepointPtr = std::shared_ptr< Timepoint >;
class Phase :
public std::enable_shared_from_this< Phase >
{ {
public: public:
// todo: respect looping phases, allow callbacks to push timepoints
std::string m_name; std::string m_name;
std::map< std::string, EncounterTimepointPtr > m_timepoints; std::queue< TimepointPtr > m_timepoints;
uint64_t m_startTime{ 0 }; uint64_t m_startTime{ 0 };
uint64_t m_currTime{ 0 }; uint64_t m_lastTimepoint{ 0 };
std::queue< TimepointPtr > m_executed;
// todo: i wrote this very sleep deprived, ensure it is actually sane
void execute( EncounterFightPtr pFight, uint64_t time ) void execute( EncounterFightPtr pFight, uint64_t time )
{ {
uint64_t durationMs = time - m_currTime;
for( const auto& timepoint : m_timepoints )
timepoint.second->execute( pFight, time );
if( m_startTime == 0 ) if( m_startTime == 0 )
m_startTime = time; m_startTime = time;
if( m_lastTimepoint == 0 )
m_lastTimepoint = time;
m_currTime = time; // todo: this is stupid
while( m_timepoints.size() > 0 )
{
uint64_t phaseElapsed = time - m_startTime;
uint64_t timepointElapsed = time - m_lastTimepoint;
auto& pTimepoint = m_timepoints.front();
if( pTimepoint->canExecute() )
{
pTimepoint->execute( pFight, time );
m_lastTimepoint = time;
m_executed.push( pTimepoint );
}
else if( pTimepoint->finished( timepointElapsed ) )
{
// todo: this is stupid, temp workaround for allowing phases to loop
pTimepoint->m_executeTime = 0;
m_timepoints.pop();
}
else
{
break;
}
}
} }
}; };
using EncounterPhasePtr = std::shared_ptr< EncounterPhase >; using PhasePtr = std::shared_ptr< Phase >;
class EncounterTimepointCondition : class TimepointCondition :
public std::enable_shared_from_this< EncounterTimepointCondition > public std::enable_shared_from_this< TimepointCondition >
{ {
public: public:
EncounterConditionId m_conditionId{ 0 }; ConditionId m_conditionId{ 0 };
EncounterPhasePtr m_pPhase{ nullptr }; PhasePtr m_pPhase{ nullptr };
bool m_loop{ false }; bool m_loop{ false };
uint64_t m_startTime{ 0 }; uint64_t m_startTime{ 0 };
uint32_t m_cooldown{ 0 }; uint32_t m_cooldown{ 0 };
EncounterTimepointCondition() {} TimepointCondition() {}
~EncounterTimepointCondition() {} ~TimepointCondition() {}
virtual void from_json( nlohmann::json& json, EncounterPhasePtr pPhase, EncounterConditionId conditionId ) virtual void from_json( nlohmann::json& json, PhasePtr pPhase, ConditionId conditionId )
{ {
this->m_conditionId = conditionId; this->m_conditionId = conditionId;
this->m_loop = json.at( "loop" ).get< bool >(); this->m_loop = json.at( "loop" ).get< bool >();
@ -186,9 +278,9 @@ namespace Sapphire
}; };
}; };
using EncounterTimepointConditionPtr = std::shared_ptr< EncounterTimepointCondition >; using TimepointConditionPtr = std::shared_ptr< TimepointCondition >;
class EncounterConditionHp : EncounterTimepointCondition class ConditionHp : TimepointCondition
{ {
public: public:
uint32_t actorId; uint32_t actorId;
@ -201,21 +293,21 @@ namespace Sapphire
}; };
} hp; } hp;
void from_json( nlohmann::json& json, EncounterPhasePtr pPhase, EncounterConditionId conditionId ); void from_json( nlohmann::json& json, PhasePtr pPhase, ConditionId conditionId );
bool canExecute( EncounterFightPtr pFight, uint64_t time ) override; bool canExecute( EncounterFightPtr pFight, uint64_t time ) override;
}; };
class EncounterConditionDirectorVar : EncounterTimepointCondition class ConditionDirectorVar : TimepointCondition
{ {
public: public:
uint32_t directorVar; uint32_t directorVar;
uint32_t value; uint32_t value;
void from_json( nlohmann::json& json, EncounterPhasePtr pPhase, EncounterConditionId conditionId ); void from_json( nlohmann::json& json, PhasePtr pPhase, ConditionId conditionId );
bool canExecute( EncounterFightPtr pFight, uint64_t time ) override; bool canExecute( EncounterFightPtr pFight, uint64_t time ) override;
}; };
using EncounterTimelineInfo = std::stack< EncounterTimepointConditionPtr >; using EncounterTimelineInfo = std::queue< TimepointConditionPtr >;
public: public: