mirror of
https://github.com/SapphireServer/Sapphire.git
synced 2025-05-06 10:47:45 +00:00
Added the framework for a fsm for future use on bnpcs.
This commit is contained in:
parent
fe9a2ef974
commit
e72fe535f6
7 changed files with 189 additions and 41 deletions
38
src/world/AI/Fsm.cpp
Normal file
38
src/world/AI/Fsm.cpp
Normal file
|
@ -0,0 +1,38 @@
|
|||
#include <cstdint>
|
||||
#include <ForwardsZone.h>
|
||||
#include <Actor/BNpc.h>
|
||||
#include "Fsm.h"
|
||||
#include "FsmState.h"
|
||||
|
||||
#pragma once
|
||||
|
||||
using namespace Sapphire;
|
||||
using namespace Sapphire::World;
|
||||
|
||||
AI::FsmStatePtr AI::Fsm::addState( FsmStatePtr state )
|
||||
{
|
||||
m_states.push_back( state );
|
||||
return state;
|
||||
}
|
||||
|
||||
void AI::Fsm::setCurrentState( FsmStatePtr state )
|
||||
{
|
||||
m_pCurrentState = state;
|
||||
}
|
||||
|
||||
void AI::Fsm::update( Entity::BNpc& bnpc, float deltaTime )
|
||||
{
|
||||
if( !m_pCurrentState )
|
||||
return;
|
||||
|
||||
FsmTransitionPtr transition = m_pCurrentState->getTriggeredTransition( bnpc );
|
||||
|
||||
if( transition )
|
||||
{
|
||||
m_pCurrentState->onExit( bnpc );
|
||||
m_pCurrentState = transition->getTargetState();
|
||||
m_pCurrentState->onEnter( bnpc );
|
||||
}
|
||||
|
||||
m_pCurrentState->onUpdate( bnpc, deltaTime );
|
||||
}
|
23
src/world/AI/Fsm.h
Normal file
23
src/world/AI/Fsm.h
Normal file
|
@ -0,0 +1,23 @@
|
|||
#include <cstdint>
|
||||
#include <ForwardsZone.h>
|
||||
#include <Actor/BNpc.h>
|
||||
|
||||
#pragma once
|
||||
|
||||
namespace Sapphire::World::AI
|
||||
{
|
||||
class Fsm
|
||||
{
|
||||
public:
|
||||
Fsm() = default;
|
||||
~Fsm() = default;
|
||||
|
||||
FsmStatePtr addState( FsmStatePtr state );
|
||||
void setCurrentState( FsmStatePtr state );
|
||||
virtual void update( Entity::BNpc& bnpc, float deltaTime );
|
||||
|
||||
protected:
|
||||
std::vector< FsmStatePtr > m_states;
|
||||
FsmStatePtr m_pCurrentState;
|
||||
};
|
||||
}
|
23
src/world/AI/FsmCondition.h
Normal file
23
src/world/AI/FsmCondition.h
Normal file
|
@ -0,0 +1,23 @@
|
|||
#include <cstdint>
|
||||
#include <ForwardsZone.h>
|
||||
#include <Actor/BNpc.h>
|
||||
|
||||
#pragma once
|
||||
|
||||
namespace Sapphire::World::AI
|
||||
{
|
||||
class FsmCondition
|
||||
{
|
||||
public:
|
||||
FsmCondition() = default;
|
||||
virtual ~FsmCondition() = default;
|
||||
|
||||
virtual bool isConditionMet( Sapphire::Entity::BNpc& src ) const = 0;
|
||||
virtual bool update( Sapphire::Entity::BNpc& src, float time )
|
||||
{
|
||||
if( isConditionMet( src ) )
|
||||
return true;
|
||||
return false;
|
||||
};
|
||||
};
|
||||
}
|
37
src/world/AI/FsmState.h
Normal file
37
src/world/AI/FsmState.h
Normal file
|
@ -0,0 +1,37 @@
|
|||
#include <cstdint>
|
||||
#include <ForwardsZone.h>
|
||||
#include <Actor/BNpc.h>
|
||||
#include "FsmTransition.h"
|
||||
|
||||
#pragma once
|
||||
|
||||
namespace Sapphire::World::AI
|
||||
{
|
||||
class FsmState
|
||||
{
|
||||
public:
|
||||
virtual ~FsmState() = default;
|
||||
|
||||
virtual void onUpdate( Entity::BNpc& bnpc, float deltaTime ) = 0;
|
||||
virtual void onEnter( Entity::BNpc& bnpc ) { }
|
||||
virtual void onExit( Entity::BNpc& bnpc ) { }
|
||||
|
||||
void addTransition( FsmTransitionPtr transition )
|
||||
{
|
||||
m_transitions.push_back( transition );
|
||||
}
|
||||
|
||||
FsmTransitionPtr getTriggeredTransition( Entity::BNpc& bnpc )
|
||||
{
|
||||
for( auto transition : m_transitions )
|
||||
{
|
||||
if( transition->hasTriggered( bnpc ) )
|
||||
return transition;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
private:
|
||||
std::vector< FsmTransitionPtr > m_transitions;
|
||||
};
|
||||
}
|
22
src/world/AI/FsmTransition.h
Normal file
22
src/world/AI/FsmTransition.h
Normal file
|
@ -0,0 +1,22 @@
|
|||
#include <cstdint>
|
||||
#include <ForwardsZone.h>
|
||||
#include <Actor/BNpc.h>
|
||||
#include "FsmCondition.h"
|
||||
|
||||
#pragma once
|
||||
|
||||
namespace Sapphire::World::AI
|
||||
{
|
||||
class FsmTransition
|
||||
{
|
||||
public:
|
||||
FsmTransition( FsmStatePtr targetState, FsmConditionPtr condition ) : m_pTargetState( targetState ), m_pCondition( condition ) { }
|
||||
virtual ~FsmTransition() = default;
|
||||
|
||||
FsmStatePtr getTargetState() { return m_pTargetState; }
|
||||
bool hasTriggered( Entity::BNpc& bnpc ) { return m_pCondition->isConditionMet( bnpc ); }
|
||||
private:
|
||||
FsmStatePtr m_pTargetState;
|
||||
FsmConditionPtr m_pCondition;
|
||||
};
|
||||
}
|
|
@ -649,6 +649,8 @@ void BNpc::update( uint64_t tickCount )
|
|||
if( !pNaviProvider )
|
||||
return;
|
||||
|
||||
Chara::update( tickCount );
|
||||
|
||||
if( !checkAction() )
|
||||
processGambits( tickCount );
|
||||
|
||||
|
@ -740,14 +742,22 @@ void BNpc::update( uint64_t tickCount )
|
|||
|
||||
auto distanceOrig = Common::Util::distance( getPos(), m_spawnPos );
|
||||
|
||||
if( pHatedActor && !pHatedActor->isAlive() )
|
||||
if( !pHatedActor->isAlive() || getTerritoryId() != pHatedActor->getTerritoryId() )
|
||||
{
|
||||
hateListRemove( pHatedActor );
|
||||
pHatedActor = hateListGetHighest();
|
||||
}
|
||||
|
||||
if( pHatedActor )
|
||||
if( !pHatedActor )
|
||||
{
|
||||
changeTarget( INVALID_GAME_OBJECT_ID64 );
|
||||
setStance( Stance::Passive );
|
||||
//setOwner( nullptr );
|
||||
m_state = BNpcState::Retreat;
|
||||
pNaviProvider->updateAgentParameters( *this );
|
||||
break;
|
||||
}
|
||||
|
||||
auto distance = Common::Util::distance( getPos(), pHatedActor->getPos() );
|
||||
|
||||
if( !hasFlag( NoDeaggro ) && ( ( distanceOrig > maxDistanceToOrigin ) || distance > 30.0f ) )
|
||||
|
@ -782,21 +792,11 @@ void BNpc::update( uint64_t tickCount )
|
|||
// in combat range. ATTACK!
|
||||
autoAttack( pHatedActor );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
changeTarget( INVALID_GAME_OBJECT_ID64 );
|
||||
setStance( Stance::Passive );
|
||||
//setOwner( nullptr );
|
||||
m_state = BNpcState::Retreat;
|
||||
pNaviProvider->updateAgentParameters( *this );
|
||||
}
|
||||
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
Chara::update( tickCount );
|
||||
}
|
||||
|
||||
void BNpc::restHp()
|
||||
|
|
|
@ -54,6 +54,11 @@ namespace World::AI
|
|||
TYPE_FORWARD( HPSelfPctLessThanTargetCondition );
|
||||
|
||||
TYPE_FORWARD( GambitRule );
|
||||
|
||||
TYPE_FORWARD( FsmCondition );
|
||||
TYPE_FORWARD( FsmState );
|
||||
TYPE_FORWARD( FsmTransition );
|
||||
TYPE_FORWARD( Fsm );
|
||||
}
|
||||
|
||||
namespace Inventory
|
||||
|
|
Loading…
Add table
Reference in a new issue