From daf906d2aedaa6e3fd454674d3fa2d0604e4dc01 Mon Sep 17 00:00:00 2001 From: Tahir Date: Thu, 9 May 2024 17:27:51 +0100 Subject: [PATCH] wip: add encounter combat state parsing --- src/world/Encounter/EncounterTimeline.cpp | 60 ++++++++++++++++++----- src/world/Encounter/EncounterTimeline.h | 15 +++--- 2 files changed, 57 insertions(+), 18 deletions(-) diff --git a/src/world/Encounter/EncounterTimeline.cpp b/src/world/Encounter/EncounterTimeline.cpp index 23419926..8843906b 100644 --- a/src/world/Encounter/EncounterTimeline.cpp +++ b/src/world/Encounter/EncounterTimeline.cpp @@ -1,14 +1,14 @@ #include "EncounterFight.h" #include "EncounterTimeline.h" -#include "../Actor/BNpc.h" -#include "../Actor/Chara.h" +#include +#include namespace Sapphire { bool EncounterTimeline::ConditionHp::isConditionMet( EncounterFightPtr pFight, uint64_t time ) { - auto pBNpc = pFight->getBNpc( actorId ); + auto pBNpc = pFight->getBNpc( layoutId ); if( !pBNpc ) return false; @@ -53,6 +53,36 @@ namespace Sapphire 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 ) { switch( m_type ) @@ -146,7 +176,7 @@ namespace Sapphire // resolve the actor whose hp we are checking if( auto it = actors.find( actorRef ); it != actors.end() ) - this->actorId = it->second.m_layoutId; + this->layoutId = it->second.m_layoutId; else 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; } } + void EncounterTimeline::ConditionCombatState::from_json( nlohmann::json& json, Phase phase, ConditionId conditionId, const std::unordered_map< std::string, TimelineActor >& actors ) { @@ -205,13 +236,14 @@ namespace Sapphire // resolve the actor whose name we are checking if( auto it = actors.find( actorRef ); it != actors.end() ) - this->actorId = it->second.m_layoutId; + this->layoutId = it->second.m_layoutId; else 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 = { @@ -275,7 +307,7 @@ namespace Sapphire auto z = posJ.at( "z" ).get< float >(); auto rot = dataJ.at( "rot" ).get< float >(); 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 ); } @@ -284,6 +316,7 @@ namespace Sapphire break; } } + EncounterTimeline::TimelinePack EncounterTimeline::buildEncounterTimeline( uint32_t encounterId, bool reload ) { static std::map< uint32_t, TimelinePack > cache = {}; @@ -350,10 +383,9 @@ namespace Sapphire std::map< std::string, Phase > phaseNameMap; auto actorV = actorJ.value(); - uint32_t layoutId = actorV.at( "layoutId" ); std::string actorName = actorV.at( "name" ); - TimelineActor actor; + TimelineActor& actor = actorNameMap[actorName]; // todo: are phases linked by actor, or global in the json for( const auto& phaseJ : json.at( "phases" ).items() ) { @@ -367,7 +399,7 @@ namespace Sapphire { auto timepointV = timepointJ.value(); Timepoint timepoint; - timepoint.from_json( timepointV, actorNameMap ); + timepoint.from_json( timepointV, actorNameMap, actor.m_layoutId ); phase.m_timepoints.push_back( timepoint ); } @@ -433,6 +465,12 @@ namespace Sapphire pDirectorCondition->from_json( pcV, phase, conditionId ); } break; + case ConditionId::CombatState: + { + auto pCombatStateCondition = std::make_shared< ConditionCombatState >(); + pCombatStateCondition->from_json( pcV, phase, conditionId, actorNameMap ); + } + break; default: break; } diff --git a/src/world/Encounter/EncounterTimeline.h b/src/world/Encounter/EncounterTimeline.h index 1021a71b..6830e8af 100644 --- a/src/world/Encounter/EncounterTimeline.h +++ b/src/world/Encounter/EncounterTimeline.h @@ -32,7 +32,8 @@ namespace Sapphire DirectorFlagsEquals, DirectorFlagsGreaterThan, PhaseTimeElapsed, - EncounterTimeElapsed + EncounterTimeElapsed, + CombatState }; enum class DirectorOpId @@ -280,7 +281,7 @@ namespace Sapphire 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 ); }; @@ -409,8 +410,8 @@ namespace Sapphire class TimelineActor { public: - uint32_t m_layoutId; - uint32_t m_hp; + uint32_t m_layoutId{ 0 }; + uint32_t m_hp{ 0 }; std::string m_name; std::vector< PhaseConditionPtr > m_phaseConditions; @@ -465,7 +466,7 @@ namespace Sapphire class ConditionHp : PhaseCondition { public: - uint32_t actorId; + uint32_t layoutId; union { uint8_t val; @@ -502,8 +503,8 @@ namespace Sapphire class ConditionCombatState : PhaseCondition { public: - uint32_t actorId; - CombatStateType type; + uint32_t layoutId; + CombatStateType combatState; 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;