mirror of
https://github.com/SapphireServer/Sapphire.git
synced 2025-05-05 02:07:46 +00:00
EncounterFight and state refactor;
This commit is contained in:
parent
9d49139a0c
commit
6bd8dee22d
3 changed files with 164 additions and 153 deletions
|
@ -7,6 +7,8 @@
|
||||||
|
|
||||||
namespace Sapphire
|
namespace Sapphire
|
||||||
{
|
{
|
||||||
|
using EncounterCallback = std::function< void( EncounterFightPtr, EncounterState ) >;
|
||||||
|
|
||||||
class EncounterState
|
class EncounterState
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -19,6 +21,11 @@ namespace Sapphire
|
||||||
StateStackPtr m_stateStack;
|
StateStackPtr m_stateStack;
|
||||||
std::shared_ptr< EncounterFight > m_pEncounter;
|
std::shared_ptr< EncounterFight > m_pEncounter;
|
||||||
uint64_t m_startTime{ 0 };
|
uint64_t m_startTime{ 0 };
|
||||||
|
uint64_t m_currTime{ 0 };
|
||||||
|
|
||||||
|
EncounterCallback m_onInitCb;
|
||||||
|
EncounterCallback m_onUpdateCb;
|
||||||
|
EncounterCallback m_onFinishCb;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
EncounterState( std::shared_ptr< EncounterFight > pEncounter ) :
|
EncounterState( std::shared_ptr< EncounterFight > pEncounter ) :
|
||||||
|
@ -26,13 +33,51 @@ namespace Sapphire
|
||||||
{
|
{
|
||||||
};
|
};
|
||||||
|
|
||||||
virtual ~EncounterState() = default;
|
bool shouldFinish() const { return m_bShouldFinish; };
|
||||||
bool shouldFinish() { return m_bShouldFinish; };
|
|
||||||
|
|
||||||
virtual void init() = 0;
|
void setFinishFlag() { m_bShouldFinish = true; };
|
||||||
virtual void update( uint64_t deltaTime ) = 0;
|
|
||||||
|
|
||||||
virtual void finish() = 0;
|
uint64_t getStartTime() const { return m_startTime; };
|
||||||
|
uint64_t getCurrTime() const { return m_currTime; };
|
||||||
|
uint64_t getElapsedTime() const { return m_currTime - m_startTime; };
|
||||||
|
|
||||||
|
void init()
|
||||||
|
{
|
||||||
|
if( m_onInitCb )
|
||||||
|
m_onInitCb( m_pEncounter, *this );
|
||||||
|
}
|
||||||
|
|
||||||
|
void update( uint64_t currTime )
|
||||||
|
{
|
||||||
|
if( m_startTime == 0 )
|
||||||
|
m_startTime = currTime;
|
||||||
|
|
||||||
|
m_currTime = currTime;
|
||||||
|
|
||||||
|
if( m_onUpdateCb )
|
||||||
|
m_onUpdateCb( m_pEncounter, *this );
|
||||||
|
}
|
||||||
|
|
||||||
|
void finish()
|
||||||
|
{
|
||||||
|
if( m_onFinishCb )
|
||||||
|
m_onFinishCb( m_pEncounter, *this );
|
||||||
|
}
|
||||||
|
|
||||||
|
void setOnInitCallback( EncounterCallback cb )
|
||||||
|
{
|
||||||
|
m_onInitCb = cb;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setOnUpdateCallback( EncounterCallback cb )
|
||||||
|
{
|
||||||
|
m_onUpdateCb = cb;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setOnFinishCallback( EncounterCallback cb )
|
||||||
|
{
|
||||||
|
m_onFinishCb = cb;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
enum class EncounterFightStatus
|
enum class EncounterFightStatus
|
||||||
|
@ -50,19 +95,44 @@ namespace Sapphire
|
||||||
m_pInstance( pInstance )
|
m_pInstance( pInstance )
|
||||||
{
|
{
|
||||||
};
|
};
|
||||||
|
|
||||||
virtual ~EncounterFight() = default;
|
virtual ~EncounterFight() = default;
|
||||||
|
|
||||||
virtual void init() = 0;
|
virtual void init() = 0;
|
||||||
virtual void start() = 0;
|
virtual void start() = 0;
|
||||||
virtual void update( uint64_t deltaTime ) = 0;
|
virtual void update( uint64_t currTime ) = 0;
|
||||||
virtual void reset() = 0;
|
virtual void reset() = 0;
|
||||||
|
|
||||||
virtual void addState( EncounterState::EncounterStatePtr pState, bool initState = true ) = 0;
|
void addState( EncounterState::EncounterStatePtr pState, bool initState = true )
|
||||||
virtual void addBNpc( Entity::BNpcPtr pBNpc ) = 0;
|
{
|
||||||
virtual void removeBNpc( uint32_t layoutId ) = 0;
|
m_stateStack->push( pState );
|
||||||
virtual Entity::BNpcPtr getBNpc( uint32_t layoutId ) = 0;
|
if( initState )
|
||||||
|
pState->init();
|
||||||
|
}
|
||||||
|
|
||||||
virtual EncounterFightStatus getEncounterFightStatus() const = 0;
|
EncounterFightStatus getEncounterFightStatus() const
|
||||||
|
{
|
||||||
|
return m_status;
|
||||||
|
}
|
||||||
|
|
||||||
|
void addBNpc( Entity::BNpcPtr pBNpc )
|
||||||
|
{
|
||||||
|
m_bnpcs[ pBNpc->getLayoutId() ] = pBNpc;
|
||||||
|
}
|
||||||
|
|
||||||
|
Entity::BNpcPtr getBNpc( uint32_t layoutId ) const
|
||||||
|
{
|
||||||
|
auto bnpc = m_bnpcs.find( layoutId );
|
||||||
|
if( bnpc != std::end( m_bnpcs ) )
|
||||||
|
return bnpc->second;
|
||||||
|
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
void removeBNpc( uint32_t layoutId )
|
||||||
|
{
|
||||||
|
m_bnpcs.erase( layoutId );
|
||||||
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
uint64_t m_startTime{ 0 };
|
uint64_t m_startTime{ 0 };
|
||||||
|
|
|
@ -2,98 +2,13 @@
|
||||||
|
|
||||||
namespace Sapphire
|
namespace Sapphire
|
||||||
{
|
{
|
||||||
class IfritNormalData
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
static constexpr int IFRIT = 4126276;
|
|
||||||
static constexpr int HELLFIRE = 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
class IfritStateTwo : public EncounterState
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
IfritStateTwo( EncounterFightPtr pEncounter ) : EncounterState( pEncounter )
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void init() override
|
|
||||||
{
|
|
||||||
Logger::info( "stage 2 init" );
|
|
||||||
}
|
|
||||||
|
|
||||||
void update( uint64_t deltaTime ) override
|
|
||||||
{
|
|
||||||
if( m_startTime == 0 )
|
|
||||||
m_startTime = deltaTime;
|
|
||||||
|
|
||||||
auto timeElapsedMs = deltaTime - m_startTime;
|
|
||||||
|
|
||||||
auto pIfrit = m_pEncounter->getBNpc( IfritNormalData::IFRIT );
|
|
||||||
|
|
||||||
pIfrit->setRot( pIfrit->getRot() - .2f );
|
|
||||||
pIfrit->sendPositionUpdate();
|
|
||||||
|
|
||||||
if( timeElapsedMs > 5000 )
|
|
||||||
{
|
|
||||||
m_bShouldFinish = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void finish() override
|
|
||||||
{
|
|
||||||
Logger::info( "stage 2 done, going back to stage 1" );
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
class IfritStateOne : public EncounterState
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
IfritStateOne( EncounterFightPtr pEncounter ) : EncounterState( pEncounter )
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void init() override
|
|
||||||
{
|
|
||||||
Logger::info( "stage 1 init" );
|
|
||||||
}
|
|
||||||
|
|
||||||
void update( uint64_t deltaTime ) override
|
|
||||||
{
|
|
||||||
if( m_startTime == 0 )
|
|
||||||
m_startTime = deltaTime;
|
|
||||||
|
|
||||||
auto timeElapsedMs = deltaTime - m_startTime;
|
|
||||||
|
|
||||||
auto pIfrit = m_pEncounter->getBNpc( IfritNormalData::IFRIT );
|
|
||||||
|
|
||||||
pIfrit->setRot( pIfrit->getRot() + .2f );
|
|
||||||
pIfrit->sendPositionUpdate();
|
|
||||||
|
|
||||||
if( timeElapsedMs > 10000 )
|
|
||||||
{
|
|
||||||
m_bShouldFinish = true;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if( timeElapsedMs > 5000 )
|
|
||||||
{
|
|
||||||
auto ifritTwoState = std::make_shared< IfritStateTwo >( m_pEncounter );
|
|
||||||
m_pEncounter->addState( ifritTwoState );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void finish() override
|
|
||||||
{
|
|
||||||
Logger::info( "stage 1 finish - enrage" );
|
|
||||||
|
|
||||||
auto pIfrit = m_pEncounter->getBNpc( IfritNormalData::IFRIT );
|
|
||||||
pIfrit->hateListGetHighest()->die();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
class IfritEncounterFight : public EncounterFight
|
class IfritEncounterFight : public EncounterFight
|
||||||
{
|
{
|
||||||
|
private:
|
||||||
|
static constexpr int NPC_IFRIT = 4126276;
|
||||||
|
static constexpr int VAL_IFRIT_HP = 13884;
|
||||||
|
static constexpr int ACT_HELLFIRE = 0;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
IfritEncounterFight( InstanceContentPtr pInstance ) : EncounterFight( pInstance )
|
IfritEncounterFight( InstanceContentPtr pInstance ) : EncounterFight( pInstance )
|
||||||
{
|
{
|
||||||
|
@ -108,35 +23,97 @@ namespace Sapphire
|
||||||
m_stateStack = std::make_shared< EncounterState::StateStack >();
|
m_stateStack = std::make_shared< EncounterState::StateStack >();
|
||||||
|
|
||||||
// todo: i don't like this
|
// todo: i don't like this
|
||||||
auto boss = m_pInstance->createBNpcFromLayoutId( IfritNormalData::IFRIT, 13884, Common::BNpcType::Enemy );
|
auto boss = m_pInstance->createBNpcFromLayoutId( NPC_IFRIT, VAL_IFRIT_HP, Common::BNpcType::Enemy );
|
||||||
addBNpc( boss );
|
addBNpc( boss );
|
||||||
|
|
||||||
//instance.sendForward();
|
|
||||||
/*
|
|
||||||
auto ifritStateTwo = std::make_shared< IfritStateTwo >( m_stateStack );
|
|
||||||
m_stateStack->push( ifritStateTwo );*/
|
|
||||||
}
|
|
||||||
|
|
||||||
void addState( EncounterState::EncounterStatePtr pState, bool initState = true ) override
|
|
||||||
{
|
|
||||||
m_stateStack->push( pState );
|
|
||||||
if( initState )
|
|
||||||
pState->init();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void start() override
|
void start() override
|
||||||
{
|
{
|
||||||
auto ifritInitState = std::make_shared< IfritStateOne >( shared_from_this() );
|
auto ifritInitState = makeIfritPhaseOneState();
|
||||||
|
|
||||||
addState( ifritInitState );
|
addState( ifritInitState );
|
||||||
|
|
||||||
m_status = EncounterFightStatus::ACTIVE;
|
m_status = EncounterFightStatus::ACTIVE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void reset() override
|
||||||
|
{
|
||||||
|
if( auto boss = m_pInstance->getActiveBNpcByLayoutId( NPC_IFRIT ); boss )
|
||||||
|
{
|
||||||
|
removeBNpc( NPC_IFRIT );
|
||||||
|
m_pInstance->removeActor( boss );
|
||||||
|
}
|
||||||
|
|
||||||
|
init();
|
||||||
|
}
|
||||||
|
|
||||||
|
EncounterStatePtr makeIfritPhaseOneState()
|
||||||
|
{
|
||||||
|
auto ifritInitState = std::make_shared< EncounterState >( shared_from_this() );
|
||||||
|
ifritInitState->setOnUpdateCallback( [ & ]( EncounterFightPtr pEncounter, EncounterState state )
|
||||||
|
{
|
||||||
|
auto timeElapsedMs = state.getElapsedTime();
|
||||||
|
|
||||||
|
auto pIfrit = pEncounter->getBNpc( NPC_IFRIT );
|
||||||
|
|
||||||
|
pIfrit->setRot( pIfrit->getRot() + .2f );
|
||||||
|
pIfrit->sendPositionUpdate();
|
||||||
|
|
||||||
|
// todo: use gambits+timelines for this
|
||||||
|
if( timeElapsedMs > 10000 )
|
||||||
|
{
|
||||||
|
state.setFinishFlag();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// todo: use gambits+timelines for this
|
||||||
|
if( timeElapsedMs > 5000 )
|
||||||
|
{
|
||||||
|
auto ifritTwoState = makeIfritPhaseTwoState();
|
||||||
|
pEncounter->addState( ifritTwoState );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
ifritInitState->setOnFinishCallback( [ & ]( EncounterFightPtr pEncounter, EncounterState state )
|
||||||
|
{
|
||||||
|
Logger::info( "stage 1 finish - enrage" );
|
||||||
|
|
||||||
|
auto pIfrit = pEncounter->getBNpc( NPC_IFRIT );
|
||||||
|
pIfrit->hateListGetHighest()->die();
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
return ifritInitState;
|
||||||
|
}
|
||||||
|
|
||||||
|
EncounterStatePtr makeIfritPhaseTwoState()
|
||||||
|
{
|
||||||
|
auto ifritTwoState = std::make_shared< EncounterState >( shared_from_this() );
|
||||||
|
ifritTwoState->setOnUpdateCallback( [ & ]( EncounterFightPtr pEncounter, EncounterState state ) {
|
||||||
|
auto timeElapsedMs = state.getElapsedTime();
|
||||||
|
|
||||||
|
auto pIfrit = pEncounter->getBNpc( NPC_IFRIT );
|
||||||
|
|
||||||
|
pIfrit->setRot( pIfrit->getRot() - .2f );
|
||||||
|
pIfrit->sendPositionUpdate();
|
||||||
|
|
||||||
|
// todo: use gambits+timelines for this
|
||||||
|
if( timeElapsedMs > 5000 )
|
||||||
|
{
|
||||||
|
state.setFinishFlag();
|
||||||
|
}
|
||||||
|
} );
|
||||||
|
|
||||||
|
return ifritTwoState;
|
||||||
|
}
|
||||||
|
|
||||||
void update( uint64_t deltaTime ) override
|
void update( uint64_t deltaTime ) override
|
||||||
{
|
{
|
||||||
// todo: better way to start fights here..
|
// todo: better way to start fights here..
|
||||||
|
// this probably doesn't need to be overriden either
|
||||||
|
|
||||||
auto ifrit = getBNpc( IfritNormalData::IFRIT );
|
auto ifrit = getBNpc( NPC_IFRIT );
|
||||||
|
|
||||||
if( ifrit; ifrit->hateListGetHighestValue() != 0 && m_status == EncounterFightStatus::IDLE )
|
if( ifrit; ifrit->hateListGetHighestValue() != 0 && m_status == EncounterFightStatus::IDLE )
|
||||||
{
|
{
|
||||||
|
@ -161,42 +138,5 @@ namespace Sapphire
|
||||||
m_stateStack->top()->update( deltaTime );
|
m_stateStack->top()->update( deltaTime );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void reset() override
|
|
||||||
{
|
|
||||||
auto boss = m_pInstance->getActiveBNpcByLayoutId( IfritNormalData::IFRIT );
|
|
||||||
if( boss )
|
|
||||||
{
|
|
||||||
removeBNpc( IfritNormalData::IFRIT );
|
|
||||||
m_pInstance->removeActor( boss );
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
init();
|
|
||||||
}
|
|
||||||
|
|
||||||
EncounterFightStatus getEncounterFightStatus() const override
|
|
||||||
{
|
|
||||||
return m_status;
|
|
||||||
}
|
|
||||||
|
|
||||||
void addBNpc( Entity::BNpcPtr pBNpc ) override
|
|
||||||
{
|
|
||||||
m_bnpcs[ pBNpc->getLayoutId() ] = pBNpc;
|
|
||||||
}
|
|
||||||
|
|
||||||
Entity::BNpcPtr getBNpc( uint32_t layoutId ) override
|
|
||||||
{
|
|
||||||
auto bnpc = m_bnpcs.find( layoutId );
|
|
||||||
if( bnpc != std::end( m_bnpcs ) )
|
|
||||||
return bnpc->second;
|
|
||||||
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
void removeBNpc( uint32_t layoutId ) override
|
|
||||||
{
|
|
||||||
m_bnpcs.erase( layoutId );
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,6 +30,7 @@ TYPE_FORWARD( Land );
|
||||||
TYPE_FORWARD( Linkshell );
|
TYPE_FORWARD( Linkshell );
|
||||||
TYPE_FORWARD( FreeCompany );
|
TYPE_FORWARD( FreeCompany );
|
||||||
TYPE_FORWARD( EncounterFight );
|
TYPE_FORWARD( EncounterFight );
|
||||||
|
TYPE_FORWARD( EncounterState );
|
||||||
|
|
||||||
namespace World
|
namespace World
|
||||||
{
|
{
|
||||||
|
|
Loading…
Add table
Reference in a new issue