1
Fork 0
mirror of https://github.com/SapphireServer/Sapphire.git synced 2025-05-01 00:27:44 +00:00

Changed position checks to recude moveactor spam, also fixed actions not fireing on idle actors

This commit is contained in:
Mordred 2025-01-04 23:15:50 +01:00
parent f19d3167ca
commit 135b056f52
6 changed files with 43 additions and 21 deletions

View file

@ -16,6 +16,8 @@ void AI::Fsm::StateCombat::onUpdate( Entity::BNpc& bnpc, uint64_t tickCount )
auto pZone = teriMgr.getTerritoryByGuId( bnpc.getTerritoryId() ); auto pZone = teriMgr.getTerritoryByGuId( bnpc.getTerritoryId() );
auto pNaviProvider = pZone->getNaviProvider(); auto pNaviProvider = pZone->getNaviProvider();
bool hasQueuedAction = bnpc.checkAction();
auto pHatedActor = bnpc.hateListGetHighest(); auto pHatedActor = bnpc.hateListGetHighest();
if( !pHatedActor ) if( !pHatedActor )
return; return;
@ -56,7 +58,7 @@ void AI::Fsm::StateCombat::onUpdate( Entity::BNpc& bnpc, uint64_t tickCount )
if( !bnpc.hasFlag( Entity::TurningDisabled ) ) if( !bnpc.hasFlag( Entity::TurningDisabled ) )
bnpc.face( pHatedActor->getPos() ); bnpc.face( pHatedActor->getPos() );
if( !bnpc.checkAction() ) if( !hasQueuedAction )
bnpc.processGambits( tickCount ); bnpc.processGambits( tickCount );
// in combat range. ATTACK! // in combat range. ATTACK!

View file

@ -6,7 +6,7 @@ using namespace Sapphire::World;
void AI::Fsm::StateIdle::onUpdate( Entity::BNpc& bnpc, uint64_t tickCount ) void AI::Fsm::StateIdle::onUpdate( Entity::BNpc& bnpc, uint64_t tickCount )
{ {
bool hasQueuedAction = bnpc.checkAction();
} }
void AI::Fsm::StateIdle::onEnter( Entity::BNpc& bnpc ) void AI::Fsm::StateIdle::onEnter( Entity::BNpc& bnpc )

View file

@ -15,6 +15,12 @@ void AI::Fsm::StateRoam::onUpdate( Entity::BNpc& bnpc, uint64_t tickCount )
auto pZone = teriMgr.getTerritoryByGuId( bnpc.getTerritoryId() ); auto pZone = teriMgr.getTerritoryByGuId( bnpc.getTerritoryId() );
auto pNaviProvider = pZone->getNaviProvider(); auto pNaviProvider = pZone->getNaviProvider();
if( bnpc.hasFlag( Entity::NoRoam ) )
{
bnpc.setRoamTargetReached( true );
return;
}
if( pNaviProvider ) if( pNaviProvider )
pNaviProvider->setMoveTarget( bnpc, bnpc.getRoamTargetPos() ); pNaviProvider->setMoveTarget( bnpc, bnpc.getRoamTargetPos() );

View file

@ -115,7 +115,7 @@ BNpc::BNpc( uint32_t id, std::shared_ptr< Common::BNPCInstanceObject > pInfo, co
m_enemyType = bNpcBaseData->data().Battalion; m_enemyType = bNpcBaseData->data().Battalion;
if( pInfo->WanderingRange == 0 || pInfo->BoundInstanceID != 0 || m_enemyType == 0 ) if( pInfo->WanderingRange == 0 || pInfo->BoundInstanceID != 0 || m_enemyType == 0 )
setFlag( Immobile ); setFlag( NoRoam | Immobile );
m_class = ClassJob::Gladiator; m_class = ClassJob::Gladiator;
@ -215,7 +215,7 @@ BNpc::BNpc( uint32_t id, std::shared_ptr< Common::BNPCInstanceObject > pInfo, co
m_territoryId = zone.getGuId(); m_territoryId = zone.getGuId();
if( pInfo->WanderingRange == 0 || pInfo->BoundInstanceID != 0 ) if( pInfo->WanderingRange == 0 || pInfo->BoundInstanceID != 0 )
setFlag( Immobile ); setFlag( Immobile | NoRoam );
auto& exdData = Common::Service< Data::ExdData >::ref(); auto& exdData = Common::Service< Data::ExdData >::ref();
@ -434,8 +434,12 @@ void BNpc::sendPositionUpdate()
if( m_state == BNpcState::Combat || m_state == BNpcState::Retreat ) if( m_state == BNpcState::Combat || m_state == BNpcState::Retreat )
animationType = 0; animationType = 0;
auto movePacket = std::make_shared< MoveActorPacket >( *getAsChara(), 0x3A, animationType, 0, 0x5A / 4 ); if( m_lastPos.x != m_pos.x || m_lastPos.y != m_pos.y || m_lastPos.z != m_lastPos.z )
server().queueForPlayers( getInRangePlayerIds(), movePacket ); {
auto movePacket = std::make_shared< MoveActorPacket >( *getAsChara(), 0x3A, animationType, 0, 0x5A / 4 );
server().queueForPlayers( getInRangePlayerIds(), movePacket );
}
m_lastPos = m_pos;
} }
const std::set< std::shared_ptr< HateListEntry > >& BNpc::getHateList() const const std::set< std::shared_ptr< HateListEntry > >& BNpc::getHateList() const
@ -656,8 +660,9 @@ void BNpc::update( uint64_t tickCount )
{ {
Chara::update( tickCount ); Chara::update( tickCount );
if( m_dirtyFlag & DirtyFlag::Position ) // removed check for now, replaced by position check to last position
sendPositionUpdate(); //if( m_dirtyFlag & DirtyFlag::Position )
sendPositionUpdate();
m_fsm->update( *this, tickCount ); m_fsm->update( *this, tickCount );
} }
@ -950,12 +955,17 @@ void BNpc::init()
gambitPack->addTimeLine( AI::make_TopHateTargetCondition(), Action::make_Action( getAsChara(), 82, 0 ), 14 ); gambitPack->addTimeLine( AI::make_TopHateTargetCondition(), Action::make_Action( getAsChara(), 82, 0 ), 14 );
m_pGambitPack = gambitPack; m_pGambitPack = gambitPack;
*/ */
initFsm();
}
void BNpc::initFsm()
{
using namespace AI::Fsm; using namespace AI::Fsm;
m_fsm = make_StateMachine(); m_fsm = make_StateMachine();
auto stateIdle = make_StateIdle(); auto stateIdle = make_StateIdle();
auto stateCombat = make_StateCombat(); auto stateCombat = make_StateCombat();
auto stateDead = make_StateDead(); auto stateDead = make_StateDead();
if( !hasFlag( Immobile ) ) if( !hasFlag( Immobile ) && !hasFlag( NoRoam ) )
{ {
auto stateRoam = make_StateRoam(); auto stateRoam = make_StateRoam();
stateIdle->addTransition( stateRoam, make_RoamNextTimeReachedCondition() ); stateIdle->addTransition( stateRoam, make_RoamNextTimeReachedCondition() );

View file

@ -32,14 +32,15 @@ namespace Sapphire::Entity
enum BNpcFlag enum BNpcFlag
{ {
Immobile = 0x01, Immobile = 0x001,
TurningDisabled = 0x02, TurningDisabled = 0x002,
Invincible = 0x04, Invincible = 0x004,
StayAlive = 0x08, StayAlive = 0x008,
NoDeaggro = 0x10, NoDeaggro = 0x010,
Untargetable = 0x20, Untargetable = 0x020,
AutoAttackDisabled = 0x40, AutoAttackDisabled = 0x040,
Invisible = 0x80, Invisible = 0x080,
NoRoam = 0x100,
Intermission = 0x77 // for transition phases to ensure boss only moves/acts when scripted Intermission = 0x77 // for transition phases to ensure boss only moves/acts when scripted
}; };
@ -170,6 +171,7 @@ namespace Sapphire::Entity
const Common::FFXIVARR_POSITION3& getRoamTargetPos() const; const Common::FFXIVARR_POSITION3& getRoamTargetPos() const;
const Common::FFXIVARR_POSITION3& getSpawnPos() const; const Common::FFXIVARR_POSITION3& getSpawnPos() const;
void initFsm();
private: private:
uint32_t m_bNpcBaseId; uint32_t m_bNpcBaseId;
@ -203,6 +205,7 @@ namespace Sapphire::Entity
Common::FFXIVARR_POSITION3 m_spawnPos; Common::FFXIVARR_POSITION3 m_spawnPos;
Common::FFXIVARR_POSITION3 m_roamPos; Common::FFXIVARR_POSITION3 m_roamPos;
Common::FFXIVARR_POSITION3 m_lastPos;
BNpcState m_state; BNpcState m_state;
std::set< std::shared_ptr< HateListEntry > > m_hateList; std::set< std::shared_ptr< HateListEntry > > m_hateList;
@ -217,6 +220,7 @@ namespace Sapphire::Entity
std::shared_ptr< World::AI::Fsm::StateMachine > m_fsm; std::shared_ptr< World::AI::Fsm::StateMachine > m_fsm;
}; };
} }

View file

@ -421,10 +421,10 @@ namespace Sapphire::Encounter
// todo: this really shouldnt exist, but need to figure out why actions interrupt // todo: this really shouldnt exist, but need to figure out why actions interrupt
else if( pAction->getId() == pActionData->m_actionId ) else if( pAction->getId() == pActionData->m_actionId )
{ {
pAction->setInterrupted( Common::ActionInterruptType::RegularInterrupt ); // pAction->setInterrupted( Common::ActionInterruptType::RegularInterrupt );
pAction->interrupt(); // pAction->interrupt();
pBNpc->setCurrentAction( nullptr ); // pBNpc->setCurrentAction( nullptr );
return false; // return false;
} }
else else
{ {