From 8bb5f9737dae43dbfe9f512ffbf29b0e05607eb8 Mon Sep 17 00:00:00 2001 From: NotAdam Date: Thu, 31 Jan 2019 22:49:04 +1100 Subject: [PATCH] add naive bnpc pushing behaviour --- src/world/Actor/BNpc.cpp | 60 +++++++++++++++++++++++++++++++++++++--- src/world/Actor/BNpc.h | 8 ++++++ 2 files changed, 64 insertions(+), 4 deletions(-) diff --git a/src/world/Actor/BNpc.cpp b/src/world/Actor/BNpc.cpp index 752a211e..0e192525 100644 --- a/src/world/Actor/BNpc.cpp +++ b/src/world/Actor/BNpc.cpp @@ -91,17 +91,36 @@ Sapphire::Entity::BNpc::BNpc( uint32_t id, BNpcTemplatePtr pTemplate, float posX memcpy( m_modelEquip, pTemplate->getModelEquip(), sizeof( m_modelEquip ) ); m_lastTickTime = 0; + + auto exdData = m_pFw->get< Data::ExdDataGenerated >(); + assert( exdData ); + + auto bNpcBaseData = exdData->get< Data::BNpcBase >( m_bNpcBaseId ); + assert( bNpcBaseData ); + + m_scale = bNpcBaseData->scale; + + // todo: is this actually good? + m_naviTargetReachedDistance = m_scale * 2.f; } -Sapphire::Entity::BNpc::~BNpc() -{ -} +Sapphire::Entity::BNpc::~BNpc() = default; uint8_t Sapphire::Entity::BNpc::getAggressionMode() const { return m_aggressionMode; } +float Sapphire::Entity::BNpc::getNaviTargetReachedDistance() const +{ + return m_naviTargetReachedDistance; +} + +float Sapphire::Entity::BNpc::getScale() const +{ + return m_scale; +} + uint8_t Sapphire::Entity::BNpc::getEnemyType() const { return m_enemyType; @@ -203,7 +222,11 @@ void Sapphire::Entity::BNpc::step() bool Sapphire::Entity::BNpc::moveTo( const FFXIVARR_POSITION3& pos ) { - if( Util::distance( getPos(), pos ) <= 4 ) + // do this first, this will update local actor position and the position of other actors + // and then this npc will then path from the position after pushing/being pushed + pushNearbyBNpcs(); + + if( Util::distance( getPos(), pos ) <= m_naviTargetReachedDistance ) { // Reached destination m_naviLastPath.clear(); @@ -606,4 +629,33 @@ void Sapphire::Entity::BNpc::checkAggro() aggro( pClosestChara ); } } +} + +void Sapphire::Entity::BNpc::pushNearbyBNpcs() +{ + for( auto& bNpc : m_inRangeBNpc ) + { + auto pos = bNpc->getPos(); + auto distance = Util::distance( m_pos, bNpc->getPos() ); + + // too far away, ignore it + if( distance > getNaviTargetReachedDistance() ) + continue; + + auto angle = Util::calcAngFrom( m_pos.x, m_pos.y, pos.x, pos.y ) + PI; + + auto x = ( cosf( angle ) ); + auto z = ( sinf( angle ) ); + + // todo: not sure what's good here + auto factor = bNpc->getScale(); + + bNpc->setPos( pos.x + ( x * factor ), + pos.y, + pos.z + ( z * factor ) ); + +// setPos( m_pos.x + ( xBase * -pushDistance ), +// m_pos.y, +// m_pos.z + ( zBase * -pushDistance ) ); + } } \ No newline at end of file diff --git a/src/world/Actor/BNpc.h b/src/world/Actor/BNpc.h index d873699f..429203ec 100644 --- a/src/world/Actor/BNpc.h +++ b/src/world/Actor/BNpc.h @@ -60,6 +60,9 @@ namespace Sapphire::Entity uint8_t getAggressionMode() const; + float getScale() const; + float getNaviTargetReachedDistance() const; + // return true if it reached the position bool moveTo( const Common::FFXIVARR_POSITION3& pos ); @@ -95,6 +98,8 @@ namespace Sapphire::Entity void checkAggro(); + void pushNearbyBNpcs(); + private: uint32_t m_bNpcBaseId; uint32_t m_bNpcNameId; @@ -108,6 +113,9 @@ namespace Sapphire::Entity uint32_t m_displayFlags; uint8_t m_level; + float m_scale; + float m_naviTargetReachedDistance; + uint32_t m_timeOfDeath; uint32_t m_lastRoamTargetReached;