diff --git a/src/world/Actor/BNpc.cpp b/src/world/Actor/BNpc.cpp index 5b1e06ba0..3431a499a 100644 --- a/src/world/Actor/BNpc.cpp +++ b/src/world/Actor/BNpc.cpp @@ -831,29 +831,62 @@ bool BNpc::hasFlag( uint32_t flag ) const { return m_flags & flag; } +void BNpc::resetFlags( uint32_t flags ) +{ + uint32_t oldFlags = m_flags; + m_flags = 0; + m_flags |= flags; + + auto& teriMgr = Common::Service< World::Manager::TerritoryMgr >::ref(); + auto pZone = teriMgr.getTerritoryByGuId( getTerritoryId() ); + + + if( pZone && getAgentId() != -1 && ( oldFlags & Entity::Immobile ) != Entity::Immobile && + ( m_flags & Entity::Immobile ) == Entity::Immobile ) + { + Logger::debug( "{} {} Pathing deactivated", m_id, getAgentId() ); + auto pNaviProvider = pZone->getNaviProvider(); + pNaviProvider->removeAgent( *this ); + setPathingActive( false ); + } + else if( pZone && ( oldFlags & Entity::Immobile ) == Entity::Immobile && + ( m_flags & Entity::Immobile ) != Entity::Immobile ) + { + Logger::debug( "{} Pathing activated", m_id ); + auto pNaviProvider = pZone->getNaviProvider(); + if( getAgentId() != -1 ) + pNaviProvider->removeAgent( *this ); + auto agentId = pNaviProvider->addAgent( *this ); + setAgentId( agentId ); + setPathingActive( true ); + } +} void BNpc::setFlag( uint32_t flag ) { uint32_t oldFlags = m_flags; + m_flags = 0; m_flags |= flag; auto& teriMgr = Common::Service< World::Manager::TerritoryMgr >::ref(); auto pZone = teriMgr.getTerritoryByGuId( getTerritoryId() ); - if( pZone && ( oldFlags & Entity::Immobile ) != Entity::Immobile && + if( pZone && getAgentId() != -1 && ( oldFlags & Entity::Immobile ) != Entity::Immobile && ( m_flags & Entity::Immobile ) == Entity::Immobile ) { + Logger::debug( "{} {} Pathing deactivated", m_id, getAgentId() ); auto pNaviProvider = pZone->getNaviProvider(); pNaviProvider->removeAgent( *this ); - setAgentId( 0 ); setPathingActive( false ); } else if( pZone && ( oldFlags & Entity::Immobile ) == Entity::Immobile && ( m_flags & Entity::Immobile ) != Entity::Immobile ) { + Logger::debug( "{} Pathing activated", m_id ); auto pNaviProvider = pZone->getNaviProvider(); - pNaviProvider->removeAgent( *this ); + if( getAgentId() != -1 ) + pNaviProvider->removeAgent( *this ); auto agentId = pNaviProvider->addAgent( *this ); setAgentId( agentId ); setPathingActive( true ); diff --git a/src/world/Actor/BNpc.h b/src/world/Actor/BNpc.h index 0460231eb..b76d26e58 100644 --- a/src/world/Actor/BNpc.h +++ b/src/world/Actor/BNpc.h @@ -146,6 +146,9 @@ namespace Sapphire::Entity bool hasFlag( uint32_t flag ) const; void setFlag( uint32_t flags ); + + // resets all flags to the given flags + void resetFlags( uint32_t flags ); void removeFlag( uint32_t flag ); void clearFlags(); diff --git a/src/world/Actor/Chara.cpp b/src/world/Actor/Chara.cpp index e4f65a026..30eae64b3 100644 --- a/src/world/Actor/Chara.cpp +++ b/src/world/Actor/Chara.cpp @@ -756,12 +756,12 @@ void Chara::setDirectorId( uint32_t directorId ) m_directorId = directorId; } -uint32_t Chara::getAgentId() const +int32_t Chara::getAgentId() const { return m_agentId; } -void Chara::setAgentId( uint32_t agentId ) +void Chara::setAgentId( int32_t agentId ) { m_agentId = agentId; } diff --git a/src/world/Actor/Chara.h b/src/world/Actor/Chara.h index 1fdfae631..4b11d2ec5 100644 --- a/src/world/Actor/Chara.h +++ b/src/world/Actor/Chara.h @@ -99,7 +99,7 @@ namespace Sapphire::Entity std::map< uint8_t, StatusEffect::StatusEffectPtr > m_statusEffectMap; /*! Detour Crowd AgentId */ - uint32_t m_agentId{0}; + int32_t m_agentId{-1}; /*! Detour Crowd actor scale */ float m_radius; @@ -279,8 +279,8 @@ namespace Sapphire::Entity uint32_t getDirectorId() const; void setDirectorId( uint32_t directorId ); - uint32_t getAgentId() const; - void setAgentId( uint32_t agentId ); + int32_t getAgentId() const; + void setAgentId( int32_t agentId ); float getRadius() const; diff --git a/src/world/Actor/Npc.h b/src/world/Actor/Npc.h index 5b4a56d70..c45f8faf7 100644 --- a/src/world/Actor/Npc.h +++ b/src/world/Actor/Npc.h @@ -27,7 +27,7 @@ namespace Sapphire::Entity void setPathingActive( bool pathing ); private: - bool m_bPathingActive{true}; + bool m_bPathingActive{false}; }; diff --git a/src/world/Encounter/Timepoint.cpp b/src/world/Encounter/Timepoint.cpp index 7ae02fedc..dbeebfab7 100644 --- a/src/world/Encounter/Timepoint.cpp +++ b/src/world/Encounter/Timepoint.cpp @@ -662,8 +662,7 @@ namespace Sapphire::Encounter if( pBNpc ) { - pBNpc->clearFlags(); - pBNpc->setFlag( pSpawnData->m_flags ); + pBNpc->resetFlags( pSpawnData->m_flags ); pBNpc->init(); pTeri->pushActor( pBNpc ); @@ -677,8 +676,7 @@ namespace Sapphire::Encounter if( pBNpc ) { - pBNpc->clearFlags(); - pBNpc->setFlag( pBNpcFlagData->m_flags ); + pBNpc->resetFlags( pBNpcFlagData->m_flags ); // todo: resend some bnpc packet/actrl? } } diff --git a/src/world/Navi/NaviProvider.cpp b/src/world/Navi/NaviProvider.cpp index 0a4ae78c4..51f703ee8 100644 --- a/src/world/Navi/NaviProvider.cpp +++ b/src/world/Navi/NaviProvider.cpp @@ -586,6 +586,8 @@ int32_t Sapphire::World::Navi::NaviProvider::addAgent( Entity::Chara& chara ) void Sapphire::World::Navi::NaviProvider::updateAgentParameters( Entity::BNpc& bnpc ) { + if( bnpc.getAgentId() == -1 ) + return; dtCrowdAgentParams params{}; std::memset( ¶ms, 0, sizeof( params ) ); params.height = 3.f; diff --git a/src/world/Territory/Territory.cpp b/src/world/Territory/Territory.cpp index 0d8b587dc..b8cb22334 100644 --- a/src/world/Territory/Territory.cpp +++ b/src/world/Territory/Territory.cpp @@ -259,10 +259,11 @@ void Territory::pushActor( const Entity::GameObjectPtr& pActor ) { auto pBNpc = pActor->getAsBNpc(); - if( m_pNaviProvider && pBNpc->pathingActive() ) + if( m_pNaviProvider && !pBNpc->hasFlag( Entity::Immobile ) ) { agentId = m_pNaviProvider->addAgent( *pBNpc ); pBNpc->setAgentId( agentId ); + pBNpc->setPathingActive( true ); } m_bNpcMap[ pBNpc->getId() ] = pBNpc;