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

encounter timeline fix json parsing

This commit is contained in:
Tahir 2024-06-22 06:12:41 +01:00
parent 29c990311b
commit 7b2ea407e9
8 changed files with 85 additions and 59 deletions

View file

@ -94,7 +94,7 @@ namespace Sapphire::Encounter
TimelinePack EncounterTimeline::getEncounterPack( const std::string& name, bool reload )
{
static std::map< std::string, TimelinePack > cache = {};
static std::unordered_map< std::string, TimelinePack > cache = {};
const static std::unordered_map< std::string, ConditionType > conditionMap =
{
{ "hpPctLessThan", ConditionType::HpPctLessThan },
@ -119,7 +119,7 @@ namespace Sapphire::Encounter
if( cache.find( name ) != cache.end() && !reload )
return cache.at( name );
std::string encounter_name( fmt::format( std::string( "data/EncounterTimelines/%s.json" ), name ) );
std::string encounter_name( fmt::format( std::string( "data/EncounterTimelines/{}.json" ), name ) );
std::fstream f( encounter_name );
@ -164,14 +164,17 @@ namespace Sapphire::Encounter
TimelineActor& actor = actorNameMap[ actorName ];
// todo: are phases linked by actor, or global in the json
for( const auto& phaseJ : json.at( "phases" ).items() )
for( const auto& phaseJ : actorV.at( "phases" ).items() )
{
auto& phaseV = phaseJ.value();
const auto id = phaseV.at( "id" ).get< uint32_t >();
const auto& phaseName = phaseV.at( "name" ).get< std::string >();
const auto& timepointsJ = phaseV.at( "timepoints" );
const auto& description = phaseV.at( "description" ).get< std::string >();
Phase phase;
phase.m_name = phaseName;
phase.m_description = description;
for( const auto& timepointJ : timepointsJ.items() )
{
auto timepointV = timepointJ.value();
@ -182,15 +185,11 @@ namespace Sapphire::Encounter
}
if( phaseNameMap.find( phaseName ) != phaseNameMap.end() )
throw std::runtime_error( fmt::format( std::string( "EncounterTimeline::buildEncounterTimeline - duplicate phase by name: %s" ), phaseName ) );
throw std::runtime_error( fmt::format( std::string( "EncounterTimeline::getEncounterPack - duplicate phase by name: {}" ), phaseName ) );
phaseNameMap.emplace( std::make_pair( phaseName, phase ) );
}
actorNamePhaseMap[ actorName ] = phaseNameMap;
if( actorNameMap.find( actorName ) != actorNameMap.end() )
throw std::runtime_error( fmt::format( std::string( "EncounterTimeline::buildEncounterTimeline - duplicate actor by name: %s" ), actorName ) );
actorNameMap.emplace( std::make_pair( actorName, actor ) );
}
// build the condition list
@ -207,7 +206,7 @@ namespace Sapphire::Encounter
if( auto it = conditionMap.find( conditionName ); it != conditionMap.end() )
condition = it->second;
else
throw std::runtime_error( fmt::format( std::string( "EncounterTimeline::buildEncounterTimeline - no condition id found by name: %s" ), conditionName ) );
throw std::runtime_error( fmt::format( std::string( "EncounterTimeline::getEncounterPack - no condition id found by name: {}" ), conditionName ) );
// make sure the actor we're referencing exists
if( auto actorIt = actorNameMap.find( actorRef ); actorIt != actorNameMap.end() )
@ -222,14 +221,14 @@ namespace Sapphire::Encounter
Phase& phase = phaseIt->second;
// build the condition
PhaseConditionPtr pCondition;
PhaseConditionPtr pCondition = nullptr;
switch( condition )
{
case ConditionType::HpPctLessThan:
case ConditionType::HpPctBetween:
{
auto pHpCondition = std::make_shared< ConditionHp >();
pHpCondition->from_json( pcV, phase, condition, actorNameMap );
pCondition = std::make_shared< ConditionHp >();
pCondition->from_json( pcV, phase, condition, actorNameMap );
}
break;
case ConditionType::DirectorVarEquals:
@ -239,20 +238,20 @@ namespace Sapphire::Encounter
case ConditionType::DirectorSeqEquals:
case ConditionType::DirectorSeqGreaterThan:
{
auto pDirectorCondition = std::make_shared< ConditionDirectorVar >();
pDirectorCondition->from_json( pcV, phase, condition );
pCondition = std::make_shared< ConditionDirectorVar >();
pCondition->from_json( pcV, phase, condition, actorNameMap );
}
break;
case ConditionType::EncounterTimeElapsed:
{
auto pEncounterCondition = std::make_shared< ConditionEncounterTimeElapsed >();
pEncounterCondition->from_json( pcV, phase, condition );
pCondition = std::make_shared< ConditionEncounterTimeElapsed >();
pCondition->from_json( pcV, phase, condition, actorNameMap );
}
break;
case ConditionType::CombatState:
{
auto pCombatStateCondition = std::make_shared< ConditionCombatState >();
pCombatStateCondition->from_json( pcV, phase, condition, actorNameMap );
pCondition = std::make_shared< ConditionCombatState >();
pCondition->from_json( pcV, phase, condition, actorNameMap );
}
break;
default:
@ -263,7 +262,7 @@ namespace Sapphire::Encounter
}
else
{
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::getEncounterPack - no state found by name: {}" ), phaseRef ) );
}
}
@ -329,6 +328,14 @@ namespace Sapphire::Encounter
return nullptr;
}
void TimelinePack::reset( TerritoryPtr pTeri )
{
for( auto& actor : m_actors )
{
actor.resetAllSubActors( pTeri );
}
}
void TimelinePack::setStartTime( uint64_t time )
{
m_startTime = time;

View file

@ -17,6 +17,8 @@
#include <Common.h>
#include <Forwards.h>
#include "TimelineActor.h"
#include "Selector.h"
#include "Forwards.h"
@ -66,6 +68,8 @@ namespace Sapphire::Encounter
Entity::BNpcPtr getBNpcByActorRef( const std::string& name, TerritoryPtr pTeri, const std::string& subActorName = {} );
void reset( TerritoryPtr pTeri );
void setStartTime( uint64_t time );
uint64_t getStartTime() const;
@ -77,6 +81,6 @@ namespace Sapphire::Encounter
{
public:
TimelinePack getEncounterPack( const std::string& name, bool reload = false );
static TimelinePack getEncounterPack( const std::string& name, bool reload = false );
};
}// namespace Sapphire

View file

@ -101,7 +101,7 @@ namespace Sapphire::Encounter
void ConditionHp::from_json( nlohmann::json& json, Phase& phase, ConditionType condition,
const std::unordered_map< std::string, TimelineActor >& actors )
{
PhaseCondition::from_json( json, phase, condition );
PhaseCondition::from_json( json, phase, condition, actors );
auto& paramData = json.at( "paramData" );
auto actorRef = paramData.at( "sourceActor" ).get< std::string >();
@ -126,9 +126,10 @@ namespace Sapphire::Encounter
}
}
void ConditionDirectorVar::from_json( nlohmann::json& json, Phase& phase, ConditionType condition )
void ConditionDirectorVar::from_json( nlohmann::json& json, Phase& phase, ConditionType condition,
const std::unordered_map< std::string, TimelineActor >& actors )
{
PhaseCondition::from_json( json, phase, condition );
PhaseCondition::from_json( json, phase, condition, actors );
auto& paramData = json.at( "paramData" );
@ -161,7 +162,7 @@ namespace Sapphire::Encounter
void ConditionCombatState::from_json( nlohmann::json& json, Phase& phase, ConditionType condition,
const std::unordered_map< std::string, TimelineActor >& actors )
{
PhaseCondition::from_json( json, phase, condition );
PhaseCondition::from_json( json, phase, condition, actors );
auto& paramData = json.at( "paramData" );
auto actorRef = paramData.at( "sourceActor" ).get< std::string >();
@ -175,9 +176,10 @@ namespace Sapphire::Encounter
this->combatState = paramData.at( "combatState" ).get< CombatStateType >();
}
void ConditionEncounterTimeElapsed::from_json( nlohmann::json& json, Phase& phase, ConditionType condition )
void ConditionEncounterTimeElapsed::from_json( nlohmann::json& json, Phase& phase, ConditionType condition,
const std::unordered_map< std::string, TimelineActor >& actors )
{
PhaseCondition::from_json( json, phase, condition );
PhaseCondition::from_json( json, phase, condition, actors );
auto& paramData = json.at( "paramData" );
auto duration = paramData.at( "duration" ).get< uint64_t >();
@ -188,7 +190,7 @@ namespace Sapphire::Encounter
void ConditionBNpcFlags::from_json( nlohmann::json& json, Phase& phase, ConditionType condition,
const std::unordered_map< std::string, TimelineActor >& actors )
{
PhaseCondition::from_json( json, phase, condition );
PhaseCondition::from_json( json, phase, condition, actors );
auto& paramData = json.at( "paramData" );
auto actorRef = paramData.at( "sourceActor" ).get< std::string >();

View file

@ -41,6 +41,7 @@ namespace Sapphire::Encounter
// todo: getters/setters
std::string m_name;
std::vector< Timepoint > m_timepoints;
std::string m_description;
void execute( ConditionState& state, TimelineActor& self, TimelinePack& pack, TerritoryPtr pTeri, uint64_t time ) const;
@ -65,7 +66,7 @@ namespace Sapphire::Encounter
PhaseCondition() {}
~PhaseCondition() {}
virtual void from_json( nlohmann::json& json, Phase& phase, ConditionType condition )
virtual void from_json( nlohmann::json& json, Phase& phase, ConditionType condition, const std::unordered_map< std::string, TimelineActor >& actors )
{
this->m_conditionType = condition;
this->m_loop = json.at( "loop" ).get< bool >();
@ -145,7 +146,7 @@ namespace Sapphire::Encounter
//
// Conditions
//
class ConditionHp : PhaseCondition
class ConditionHp : public PhaseCondition
{
public:
uint32_t layoutId;
@ -158,13 +159,12 @@ namespace Sapphire::Encounter
};
} hp;
void from_json( nlohmann::json& json, Phase& phase, ConditionType condition,
const std::unordered_map< std::string, TimelineActor >& actors );
void from_json( nlohmann::json& json, Phase& phase, ConditionType condition, const std::unordered_map< std::string, TimelineActor >& actors ) override;
bool isConditionMet( ConditionState& state, TimelinePack& pack, TerritoryPtr pTeri, uint64_t time ) const override;
};
class ConditionDirectorVar : PhaseCondition
class ConditionDirectorVar : public PhaseCondition
{
public:
union
@ -178,36 +178,36 @@ namespace Sapphire::Encounter
uint8_t flags;
} param;
void from_json( nlohmann::json& json, Phase& phase, ConditionType condition );
void from_json( nlohmann::json& json, Phase& phase, ConditionType condition, const std::unordered_map< std::string, TimelineActor >& actors ) override;
bool isConditionMet( ConditionState& state, TimelinePack& pack, TerritoryPtr pTeri, uint64_t time ) const override;
};
class ConditionEncounterTimeElapsed : PhaseCondition
class ConditionEncounterTimeElapsed : public PhaseCondition
{
public:
uint64_t duration;
void from_json( nlohmann::json& json, Phase& phase, ConditionType condition );
void from_json( nlohmann::json& json, Phase& phase, ConditionType condition, const std::unordered_map< std::string, TimelineActor >& actors ) override;
bool isConditionMet( ConditionState& state, TimelinePack& pack, TerritoryPtr pTeri, uint64_t time ) const override;
};
class ConditionCombatState : PhaseCondition
class ConditionCombatState : public PhaseCondition
{
public:
uint32_t layoutId;
CombatStateType combatState;
void from_json( nlohmann::json& json, Phase& phase, ConditionType condition, const std::unordered_map< std::string, TimelineActor >& actors );
void from_json( nlohmann::json& json, Phase& phase, ConditionType condition, const std::unordered_map< std::string, TimelineActor >& actors ) override;
bool isConditionMet( ConditionState& state, TimelinePack& pack, TerritoryPtr pTeri, uint64_t time ) const override;
};
class ConditionBNpcFlags : PhaseCondition
class ConditionBNpcFlags : public PhaseCondition
{
public:
uint32_t layoutId;
uint32_t flags;
void from_json( nlohmann::json& json, Phase& phase, ConditionType condition, const std::unordered_map< std::string, TimelineActor >& actors );
void from_json( nlohmann::json& json, Phase& phase, ConditionType condition, const std::unordered_map< std::string, TimelineActor >& actors ) override;
bool isConditionMet( ConditionState& state, TimelinePack& pack, TerritoryPtr pTeri, uint64_t time ) const override;
};

View file

@ -3,6 +3,7 @@
#include "EncounterTimeline.h"
#include <Actor/BNpc.h>
#include <Action/Action.h>
namespace Sapphire::Encounter
{
@ -117,6 +118,11 @@ namespace Sapphire::Encounter
if( auto pPlayer = pActor->getAsPlayer() )
subActor.second->despawn( pPlayer );
}
// todo: need to reset the ai on interrupt
auto pAction = subActor.second->getCurrentAction();
if( pAction )
pAction->interrupt();
pTeri->removeActor( subActor.second );
subActor.second = nullptr;
}

View file

@ -1,3 +1,5 @@
#pragma once
#include <cstdint>
#include "PhaseCondition.h"

View file

@ -107,7 +107,7 @@ namespace Sapphire::Encounter
if( auto it = timepointTypeMap.find( typeStr ); it != timepointTypeMap.end() )
tpType = it->second;
else
throw std::runtime_error( fmt::format( "Timepoint::from_json unable to find timepoint by type: %s", typeStr ) );
throw std::runtime_error( fmt::format( "Timepoint::from_json unable to find timepoint by type: {}", typeStr ) );
m_duration = json.at( "duration" ).get< uint64_t >();
//m_overrideFlags = json.at( "overrideFlags" ).get< TimepointOverrideFlags >();
@ -163,10 +163,10 @@ namespace Sapphire::Encounter
auto pBattleTalkData = std::make_shared< TimepointDataBattleTalk >( params );
pBattleTalkData->m_battleTalkId = dataJ.at( "battleTalkId" ).get< uint32_t >();
pBattleTalkData->m_handlerId = dataJ.at( "handlerId" ).get< uint32_t >();
pBattleTalkData->m_handlerRef = dataJ.at( "handlerActorName" ).get< std::string >();
pBattleTalkData->m_kind = dataJ.at( "kind" ).get< uint32_t >();
pBattleTalkData->m_nameId = dataJ.at( "nameId" ).get< uint32_t >();
pBattleTalkData->m_talkerId = dataJ.at( "talkerId" ).get< uint32_t >();
pBattleTalkData->m_talkerRef = dataJ.at( "talkerActorName" ).get< std::string >();
m_pData = pBattleTalkData;
}
@ -248,12 +248,12 @@ namespace Sapphire::Encounter
case TimepointDataType::SpawnBNpc:
{
auto& dataJ = json.at( "data" );
auto hateSrcJ = dataJ.at( "hateSrc" );
// auto hateSrcJ = dataJ.at( "hateSrc" );
auto actorRef = dataJ.at( "spawnActor" ).get< std::string >();
auto flags = dataJ.at( "flags" ).get< uint32_t >();
// todo: batallion
// auto battalion = dataJ.at( "batallion" ).get< uint32_t >();
auto bnpcType = bnpcTypeMap.at( dataJ.at( "type" ).get< std::string >() );
auto bnpcType = Common::BNpcType::Enemy;//bnpcTypeMap.at( dataJ.at( "type" ).get< std::string >() );
// todo: hateSrc
@ -261,7 +261,7 @@ namespace Sapphire::Encounter
if( auto it = actors.find( actorRef ); it != actors.end() )
layoutId = it->second.m_layoutId;
else
throw std::runtime_error( fmt::format( std::string( "Timepoint::from_json: SpawnBNpc invalid actor ref: %s" ), actorRef ) );
throw std::runtime_error( fmt::format( std::string( "Timepoint::from_json: SpawnBNpc invalid actor ref: {}" ), actorRef ) );
m_pData = std::make_shared< TimepointDataSpawnBNpc >( layoutId, flags, bnpcType );
}
@ -269,16 +269,16 @@ namespace Sapphire::Encounter
case TimepointDataType::SetBNpcFlags:
{
auto& dataJ = json.at( "data" );
auto actorRef = dataJ.at( "spawnActor" ).get< std::string >();
auto actorRef = dataJ.at( "targetActor" ).get< std::string >();
auto flags = dataJ.at( "flags" ).get< uint32_t >();
// todo: hateSrc
uint32_t layoutId = 0xE0000000;
if( auto it = actors.find( actorRef ); it != actors.end() )
layoutId = it->second.m_layoutId;
else
throw std::runtime_error( fmt::format( std::string( "Timepoint::from_json: SetBNpcFlags invalid actor ref: %s" ), actorRef ) );
uint32_t layoutId = selfLayoutId;
//if( auto it = actors.find( actorRef ); it != actors.end() )
// layoutId = it->second.m_layoutId;
//else
// throw std::runtime_error( fmt::format( std::string( "Timepoint::from_json: SetBNpcFlags invalid actor ref: {}" ), actorRef ) );
m_pData = std::make_shared< TimepointDataBNpcFlags >( layoutId, flags );
// todo: SetBNpcFlags
@ -308,7 +308,7 @@ namespace Sapphire::Encounter
auto& dataJ = json.at( "data" );
auto selectorName = dataJ.at( "selectorName" ).get< std::string >();
auto actorRef = dataJ.at( "sourceActor" ).get< std::string >();
auto excludeSelector = std::string(); // dataJ.at( "excludeSelector" ).get< std::string >();
auto excludeSelector = std::string(); // dataJ.at( "excludeSelectorName" ).get< std::string >();
// todo: use exclude selector when added to ui
m_pData = std::make_shared< TimepointDataSnapshot >( selectorName, actorRef, excludeSelector );
@ -440,14 +440,19 @@ namespace Sapphire::Encounter
auto pBtData = std::dynamic_pointer_cast< TimepointDataBattleTalk, TimepointData >( m_pData );
auto params = pBtData->m_params;
auto pHandler = pack.getBNpcByActorRef( pBtData->m_handlerRef , pTeri );
auto pTalker = pack.getBNpcByActorRef( pBtData->m_talkerRef, pTeri );
auto handlerId = pHandler ? pHandler->getId() : 0xE0000000;
auto talkerId = pTalker ? pTalker->getId() : 0xE0000000;
auto& playerMgr = Common::Service< Sapphire::World::Manager::PlayerMgr >::ref();
for( auto& player : pTeri->getPlayers() )
{
auto& pPlayer = player.second;
if( pPlayer )
playerMgr.sendBattleTalk( *pPlayer.get(), pBtData->m_battleTalkId, pBtData->m_handlerId,
pBtData->m_kind, pBtData->m_nameId, pBtData->m_talkerId,
playerMgr.sendBattleTalk( *pPlayer.get(), pBtData->m_battleTalkId, handlerId,
pBtData->m_kind, pBtData->m_nameId, talkerId,
params[ 0 ], params[ 1 ], params[ 2 ], params[ 3 ],
params[ 4 ], params[ 5 ], params[ 6 ], params[ 7 ] );
}

View file

@ -143,10 +143,10 @@ namespace Sapphire::Encounter
struct TimepointDataBattleTalk : public TimepointData {
uint32_t m_battleTalkId;
uint32_t m_handlerId;
std::string m_handlerRef;
uint32_t m_kind;
uint32_t m_nameId;
uint32_t m_talkerId;
std::string m_talkerRef;
uint32_t m_params[ 8 ]{ 0 };