mirror of
https://github.com/SapphireServer/Sapphire.git
synced 2025-04-28 15:17:46 +00:00
wip: encounter timepoint separate update from execute
- todo: implement conditions and timepoint parsing for remaining types - todo: test lmao
This commit is contained in:
parent
daf906d2ae
commit
f96c633c6c
2 changed files with 112 additions and 31 deletions
|
@ -4,6 +4,8 @@
|
|||
#include <Actor/BNpc.h>
|
||||
#include <Actor/Chara.h>
|
||||
|
||||
#include <Util/UtilMath.h>
|
||||
|
||||
namespace Sapphire
|
||||
{
|
||||
bool EncounterTimeline::ConditionHp::isConditionMet( EncounterFightPtr pFight, uint64_t time )
|
||||
|
@ -83,8 +85,9 @@ namespace Sapphire
|
|||
return false;
|
||||
}
|
||||
|
||||
void EncounterTimeline::Timepoint::execute( EncounterFightPtr pFight, uint64_t time )
|
||||
void EncounterTimeline::Timepoint::update( EncounterFightPtr pFight, uint64_t time )
|
||||
{
|
||||
m_lastTick = time;
|
||||
switch( m_type )
|
||||
{
|
||||
case TimepointDataType::Idle:
|
||||
|
@ -111,12 +114,25 @@ namespace Sapphire
|
|||
auto pMoveToData = std::dynamic_pointer_cast< TimepointDataMoveTo, TimepointData >( getData() );
|
||||
auto pBNpc = pFight->getBNpc( pMoveToData->m_actorId );
|
||||
|
||||
// todo: path
|
||||
if( pBNpc )
|
||||
{
|
||||
pBNpc->setPos( pMoveToData->m_x, pMoveToData->m_y, pMoveToData->m_z );
|
||||
auto currPos = pBNpc->getPos();
|
||||
Common::FFXIVARR_POSITION3 targetPos = { pMoveToData->m_x, pMoveToData->m_y, pMoveToData->m_z };
|
||||
|
||||
auto distance = Common::Util::distance( currPos, targetPos );
|
||||
if( distance > 0.5f )
|
||||
{
|
||||
if( pMoveToData->m_moveType == MoveType::WalkPath )
|
||||
pBNpc->moveTo( targetPos );
|
||||
else
|
||||
pBNpc->setPos( pMoveToData->m_x, pMoveToData->m_y, pMoveToData->m_z );
|
||||
}
|
||||
else
|
||||
{
|
||||
// if we are at the pos, stop waiting
|
||||
m_finished = true;
|
||||
}
|
||||
pBNpc->setRot( pMoveToData->m_rot );
|
||||
pBNpc->sendPositionUpdate();
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
@ -160,6 +176,75 @@ namespace Sapphire
|
|||
}
|
||||
break;
|
||||
}
|
||||
m_finished = m_finished || m_executeTime + m_duration <= time;
|
||||
}
|
||||
|
||||
/*
|
||||
class RngCondition : TimepointCondition
|
||||
{
|
||||
EncounterTimepointConditionId m_type;
|
||||
std::vector< uint32_t > m_params
|
||||
|
||||
RngCondition( EncounterTimepointConditionId conditionId std::vector< uint32_t params ) : m_type( conditionId ), m_params( params ){}
|
||||
bool isConditionMet( uint32_t shit )
|
||||
{
|
||||
switch( m_type )
|
||||
{
|
||||
case EncounterTimepointConditionId::RngMinMax:
|
||||
return RNGMgr::generate( params[0], params[1] ) == params[2];
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
enum class ActionCallbackType : uint32_t
|
||||
{
|
||||
OnActionInit,
|
||||
OnActionStart,
|
||||
OnActionInterrupt,
|
||||
OnActionExecute
|
||||
};
|
||||
|
||||
using CallbackFunc = std::function< void < CharaPtr, Action > >;
|
||||
|
||||
std::unordered_map< ActionCallbackType, CallbackFunc > m_actionCallbacks;
|
||||
void Chara::registerActionCallback( ActionCallbackType type, CallbackFunc callback )
|
||||
{
|
||||
m_actionCallbacks[ type ].push_back( callback );
|
||||
}
|
||||
|
||||
// call this when changing EncounterPack
|
||||
void Chara::clearActionCallbacks()
|
||||
{
|
||||
for( auto& callback : m_actionCallbacks )
|
||||
callback.second.clear()
|
||||
}
|
||||
|
||||
void Chara::onActionInterrupt()
|
||||
{
|
||||
auto action = getCurrentAction();
|
||||
for( auto& callback : m_actionCallbacks[ ActionCallbackType::OnActionInterrupt ] )
|
||||
callback( this, action );
|
||||
}
|
||||
|
||||
void EncounterTimeline::Timepoint::execute( EncounterFightPtr pFight, uint64_t time )
|
||||
{
|
||||
switch( m_type )
|
||||
{
|
||||
case TimepointDataType::CastAction:
|
||||
{
|
||||
auto pActionData = std::dynamic_pointer_cast< TimepointDataAction, TimepointData >( getData() );
|
||||
|
||||
// todo: filter the correct target
|
||||
// todo: tie to mechanic script?
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
void EncounterTimeline::Timepoint::execute( EncounterFightPtr pFight, uint64_t time )
|
||||
{
|
||||
m_executeTime = time;
|
||||
update( pFight, time );
|
||||
}
|
||||
|
||||
//
|
||||
|
@ -333,24 +418,6 @@ namespace Sapphire
|
|||
TimelinePack pack;
|
||||
if( cache.find( encounterId ) != cache.end() && !reload )
|
||||
return cache.at( encounterId );
|
||||
/*
|
||||
class RngCondition : TimepointCondition
|
||||
{
|
||||
EncounterTimepointConditionId m_type;
|
||||
std::vector< uint32_t > m_params
|
||||
|
||||
RngCondition( EncounterTimepointConditionId conditionId std::vector< uint32_t params ) : m_type( conditionId ), m_params( params ){}
|
||||
bool isConditionMet( uint32_t shit )
|
||||
{
|
||||
switch( m_type )
|
||||
{
|
||||
case EncounterTimepointConditionId::RngMinMax:
|
||||
return RNGMgr::generate( params[0], params[1] ) == params[2];
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
std::string encounter_name( fmt::format( std::string( "data/EncounterTimelines/EncounterTimeline%u.json" ), encounterId ) );
|
||||
|
||||
|
@ -385,7 +452,7 @@ namespace Sapphire
|
|||
auto actorV = actorJ.value();
|
||||
std::string actorName = actorV.at( "name" );
|
||||
|
||||
TimelineActor& actor = actorNameMap[actorName];
|
||||
TimelineActor& actor = actorNameMap[ actorName ];
|
||||
// todo: are phases linked by actor, or global in the json
|
||||
for( const auto& phaseJ : json.at( "phases" ).items() )
|
||||
{
|
||||
|
@ -420,7 +487,7 @@ namespace Sapphire
|
|||
for( const auto& pcJ : json.at( "phaseConditions" ).items() )
|
||||
{
|
||||
auto pcV = pcJ.value();
|
||||
auto conditionName = pcV.at( "condition" ).get< std::string>();
|
||||
auto conditionName = pcV.at( "condition" ).get< std::string >();
|
||||
auto description = pcV.at( "description" ).get< std::string >();
|
||||
auto loop = pcV.at( "loop" ).get< bool >();
|
||||
auto phaseRef = pcV.at( "targetPhase" ).get< std::string >();
|
||||
|
|
|
@ -260,9 +260,11 @@ namespace Sapphire
|
|||
TimepointDataType m_type;
|
||||
uint64_t m_duration{ 0 };
|
||||
uint64_t m_executeTime{ 0 };
|
||||
uint64_t m_lastTick{ 0 };
|
||||
TimepointOverrideFlags m_overrideFlags;
|
||||
TimepointDataPtr m_pData;
|
||||
std::string m_description;
|
||||
bool m_finished{ false };
|
||||
|
||||
// todo: repeatable?
|
||||
|
||||
|
@ -273,15 +275,24 @@ namespace Sapphire
|
|||
|
||||
bool canExecute( uint64_t elapsed )
|
||||
{
|
||||
return m_executeTime == 0 && m_duration <= elapsed;
|
||||
return m_executeTime == 0; // & &m_duration <= elapsed;
|
||||
}
|
||||
|
||||
bool finished( uint64_t time )
|
||||
{
|
||||
return m_executeTime + m_duration <= time;
|
||||
return m_executeTime + m_duration <= time || m_finished;
|
||||
}
|
||||
|
||||
void reset()
|
||||
{
|
||||
m_executeTime = 0;
|
||||
m_lastTick = 0;
|
||||
m_finished = false;
|
||||
}
|
||||
|
||||
void from_json( const nlohmann::json& json, const std::unordered_map< std::string, TimelineActor >& actors, uint32_t selfLayoutId );
|
||||
// todo: separate execute/update into onStart and onTick?
|
||||
void update( EncounterFightPtr pFight, uint64_t time );
|
||||
void execute( EncounterFightPtr pFight, uint64_t time );
|
||||
};
|
||||
|
||||
|
@ -320,13 +331,16 @@ namespace Sapphire
|
|||
m_lastTimepointTime = time;
|
||||
m_executed.push( timepoint );
|
||||
}
|
||||
else if( !timepoint.finished( timepointElapsed ) )
|
||||
{
|
||||
timepoint.update( pFight, time );
|
||||
}
|
||||
|
||||
// fire off all timepoints
|
||||
if( timepoint.finished( timepointElapsed ) )
|
||||
{
|
||||
// todo: this is stupid, temp workaround for allowing phases to loop
|
||||
timepoint.m_executeTime = 0;
|
||||
timepoint.reset();
|
||||
m_lastTimepointIndex = i;
|
||||
// make sure this timepoint isnt run again unless phase loops
|
||||
++i;
|
||||
continue;
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue