1
Fork 0
mirror of https://github.com/SapphireServer/Sapphire.git synced 2025-04-28 15:17:46 +00:00

wip: add encounter combat state parsing

This commit is contained in:
Tahir 2024-05-09 17:27:51 +01:00
parent 959df68b63
commit daf906d2ae
2 changed files with 57 additions and 18 deletions

View file

@ -1,14 +1,14 @@
#include "EncounterFight.h" #include "EncounterFight.h"
#include "EncounterTimeline.h" #include "EncounterTimeline.h"
#include "../Actor/BNpc.h" #include <Actor/BNpc.h>
#include "../Actor/Chara.h" #include <Actor/Chara.h>
namespace Sapphire namespace Sapphire
{ {
bool EncounterTimeline::ConditionHp::isConditionMet( EncounterFightPtr pFight, uint64_t time ) bool EncounterTimeline::ConditionHp::isConditionMet( EncounterFightPtr pFight, uint64_t time )
{ {
auto pBNpc = pFight->getBNpc( actorId ); auto pBNpc = pFight->getBNpc( layoutId );
if( !pBNpc ) if( !pBNpc )
return false; return false;
@ -53,6 +53,36 @@ namespace Sapphire
return false; return false;
} }
bool EncounterTimeline::ConditionCombatState::isConditionMet( EncounterFightPtr pFight, uint64_t time)
{
auto pBattleNpc = pFight->getBNpc( this->layoutId );
switch( combatState )
{
case CombatStateType::Idle:
return pBattleNpc->getState() == Entity::BNpcState::Idle;
break;
case CombatStateType::Combat:
return pBattleNpc->getState() == Entity::BNpcState::Combat;
break;
case CombatStateType::Retreat:
return pBattleNpc->getState() == Entity::BNpcState::Retreat;
break;
case CombatStateType::Roaming:
return pBattleNpc->getState() == Entity::BNpcState::Roaming;
break;
case CombatStateType::JustDied:
return pBattleNpc->getState() == Entity::BNpcState::JustDied;
break;
case CombatStateType::Dead:
return pBattleNpc->getState() == Entity::BNpcState::Dead;
break;
default:
break;
}
return false;
}
void EncounterTimeline::Timepoint::execute( EncounterFightPtr pFight, uint64_t time ) void EncounterTimeline::Timepoint::execute( EncounterFightPtr pFight, uint64_t time )
{ {
switch( m_type ) switch( m_type )
@ -146,7 +176,7 @@ namespace Sapphire
// resolve the actor whose hp we are checking // resolve the actor whose hp we are checking
if( auto it = actors.find( actorRef ); it != actors.end() ) if( auto it = actors.find( actorRef ); it != actors.end() )
this->actorId = it->second.m_layoutId; this->layoutId = it->second.m_layoutId;
else else
throw std::runtime_error( fmt::format( std::string( "EncounterTimeline::ConditionHp::from_json unable to find actor by name: %s" ), actorRef ) ); throw std::runtime_error( fmt::format( std::string( "EncounterTimeline::ConditionHp::from_json unable to find actor by name: %s" ), actorRef ) );
@ -195,6 +225,7 @@ namespace Sapphire
break; break;
} }
} }
void EncounterTimeline::ConditionCombatState::from_json( nlohmann::json& json, Phase phase, ConditionId conditionId, void EncounterTimeline::ConditionCombatState::from_json( nlohmann::json& json, Phase phase, ConditionId conditionId,
const std::unordered_map< std::string, TimelineActor >& actors ) const std::unordered_map< std::string, TimelineActor >& actors )
{ {
@ -205,13 +236,14 @@ namespace Sapphire
// resolve the actor whose name we are checking // resolve the actor whose name we are checking
if( auto it = actors.find( actorRef ); it != actors.end() ) if( auto it = actors.find( actorRef ); it != actors.end() )
this->actorId = it->second.m_layoutId; this->layoutId = it->second.m_layoutId;
else else
throw std::runtime_error( fmt::format( std::string( "EncounterTimeline::ConditionCombatState::from_json unable to find actor by name: %s" ), actorRef ) ); throw std::runtime_error( fmt::format( std::string( "EncounterTimeline::ConditionCombatState::from_json unable to find actor by name: %s" ), actorRef ) );
this->type = paramData.at( "combatState" ).get< CombatStateType >(); this->combatState = paramData.at( "combatState" ).get< CombatStateType >();
} }
void EncounterTimeline::Timepoint::from_json( const nlohmann::json& json, const std::unordered_map< std::string, TimelineActor>& actors )
void EncounterTimeline::Timepoint::from_json( const nlohmann::json& json, const std::unordered_map< std::string, TimelineActor>& actors, uint32_t selfLayoutId )
{ {
const static std::unordered_map< std::string, TimepointDataType > timepointTypeMap = const static std::unordered_map< std::string, TimepointDataType > timepointTypeMap =
{ {
@ -275,7 +307,7 @@ namespace Sapphire
auto z = posJ.at( "z" ).get< float >(); auto z = posJ.at( "z" ).get< float >();
auto rot = dataJ.at( "rot" ).get< float >(); auto rot = dataJ.at( "rot" ).get< float >();
auto pathReq = dataJ.at( "pathRequested" ).get< bool >() ? MoveType::WalkPath : MoveType::Teleport; auto pathReq = dataJ.at( "pathRequested" ).get< bool >() ? MoveType::WalkPath : MoveType::Teleport;
auto actorId = dataJ.at( "actorId" ).get< uint32_t >(); auto actorId = selfLayoutId;
m_pData = std::make_shared< TimepointDataMoveTo >( actorId, pathReq, x, y, z, rot ); m_pData = std::make_shared< TimepointDataMoveTo >( actorId, pathReq, x, y, z, rot );
} }
@ -284,6 +316,7 @@ namespace Sapphire
break; break;
} }
} }
EncounterTimeline::TimelinePack EncounterTimeline::buildEncounterTimeline( uint32_t encounterId, bool reload ) EncounterTimeline::TimelinePack EncounterTimeline::buildEncounterTimeline( uint32_t encounterId, bool reload )
{ {
static std::map< uint32_t, TimelinePack > cache = {}; static std::map< uint32_t, TimelinePack > cache = {};
@ -350,10 +383,9 @@ namespace Sapphire
std::map< std::string, Phase > phaseNameMap; std::map< std::string, Phase > phaseNameMap;
auto actorV = actorJ.value(); auto actorV = actorJ.value();
uint32_t layoutId = actorV.at( "layoutId" );
std::string actorName = actorV.at( "name" ); std::string actorName = actorV.at( "name" );
TimelineActor actor; TimelineActor& actor = actorNameMap[actorName];
// todo: are phases linked by actor, or global in the json // todo: are phases linked by actor, or global in the json
for( const auto& phaseJ : json.at( "phases" ).items() ) for( const auto& phaseJ : json.at( "phases" ).items() )
{ {
@ -367,7 +399,7 @@ namespace Sapphire
{ {
auto timepointV = timepointJ.value(); auto timepointV = timepointJ.value();
Timepoint timepoint; Timepoint timepoint;
timepoint.from_json( timepointV, actorNameMap ); timepoint.from_json( timepointV, actorNameMap, actor.m_layoutId );
phase.m_timepoints.push_back( timepoint ); phase.m_timepoints.push_back( timepoint );
} }
@ -433,6 +465,12 @@ namespace Sapphire
pDirectorCondition->from_json( pcV, phase, conditionId ); pDirectorCondition->from_json( pcV, phase, conditionId );
} }
break; break;
case ConditionId::CombatState:
{
auto pCombatStateCondition = std::make_shared< ConditionCombatState >();
pCombatStateCondition->from_json( pcV, phase, conditionId, actorNameMap );
}
break;
default: default:
break; break;
} }

View file

@ -32,7 +32,8 @@ namespace Sapphire
DirectorFlagsEquals, DirectorFlagsEquals,
DirectorFlagsGreaterThan, DirectorFlagsGreaterThan,
PhaseTimeElapsed, PhaseTimeElapsed,
EncounterTimeElapsed EncounterTimeElapsed,
CombatState
}; };
enum class DirectorOpId enum class DirectorOpId
@ -280,7 +281,7 @@ namespace Sapphire
return m_executeTime + m_duration <= time; return m_executeTime + m_duration <= time;
} }
void from_json( const nlohmann::json& json, const std::unordered_map< std::string, TimelineActor >& actors ); void from_json( const nlohmann::json& json, const std::unordered_map< std::string, TimelineActor >& actors, uint32_t selfLayoutId );
void execute( EncounterFightPtr pFight, uint64_t time ); void execute( EncounterFightPtr pFight, uint64_t time );
}; };
@ -409,8 +410,8 @@ namespace Sapphire
class TimelineActor class TimelineActor
{ {
public: public:
uint32_t m_layoutId; uint32_t m_layoutId{ 0 };
uint32_t m_hp; uint32_t m_hp{ 0 };
std::string m_name; std::string m_name;
std::vector< PhaseConditionPtr > m_phaseConditions; std::vector< PhaseConditionPtr > m_phaseConditions;
@ -465,7 +466,7 @@ namespace Sapphire
class ConditionHp : PhaseCondition class ConditionHp : PhaseCondition
{ {
public: public:
uint32_t actorId; uint32_t layoutId;
union union
{ {
uint8_t val; uint8_t val;
@ -502,8 +503,8 @@ namespace Sapphire
class ConditionCombatState : PhaseCondition class ConditionCombatState : PhaseCondition
{ {
public: public:
uint32_t actorId; uint32_t layoutId;
CombatStateType type; CombatStateType combatState;
void from_json( nlohmann::json& json, Phase phase, ConditionId conditionId, const std::unordered_map< std::string, TimelineActor >& actors ); void from_json( nlohmann::json& json, Phase phase, ConditionId conditionId, const std::unordered_map< std::string, TimelineActor >& actors );
bool isConditionMet( EncounterFightPtr pFight, uint64_t time ) override; bool isConditionMet( EncounterFightPtr pFight, uint64_t time ) override;