diff --git a/src/world/Actor/BNpc.cpp b/src/world/Actor/BNpc.cpp index a9e8be94..5ec37921 100644 --- a/src/world/Actor/BNpc.cpp +++ b/src/world/Actor/BNpc.cpp @@ -241,7 +241,7 @@ bool Sapphire::Entity::BNpc::moveTo( const FFXIVARR_POSITION3& pos ) auto pos1 = pNaviProvider->getMovePos( *this ); - if( Util::distance( pos1, pos ) < 1.1f ) + if( Util::distance( pos1, pos ) < ( getScale() / 2 ) ) { // Reached destination face( pos1 ); @@ -259,6 +259,41 @@ bool Sapphire::Entity::BNpc::moveTo( const FFXIVARR_POSITION3& pos ) return false; } +bool Sapphire::Entity::BNpc::moveTo( const Entity::Chara& targetChara ) +{ + + auto pNaviMgr = m_pFw->get< World::Manager::NaviMgr >(); + auto pNaviProvider = m_pCurrentZone->getNaviProvider(); + + if( !pNaviProvider ) + { + Logger::error( "No NaviProvider for zone#{0} - {1}", + m_pCurrentZone->getGuId(), + m_pCurrentZone->getInternalName() ); + return false; + } + + auto pos1 = pNaviProvider->getMovePos( *this ); + + if( Util::distance( pos1, targetChara.getPos() ) <= ( ( getScale() / 2 + targetChara.getScale() / 2 ) ) ) + { + // Reached destination + face( pos1 ); + setPos( pos1 ); + sendPositionUpdate(); + //pNaviProvider->resetMoveTarget( *this ); + pNaviProvider->updateAgentPosition( *this ); + return true; + } + + m_pCurrentZone->updateActorPosition( *this ); + face( pos1 ); + setPos( pos1 ); + sendPositionUpdate(); + return false; +} + + void Sapphire::Entity::BNpc::sendPositionUpdate() { uint8_t unk1 = 0x3a; @@ -411,6 +446,8 @@ void Sapphire::Entity::BNpc::update( uint64_t tickCount ) const uint8_t maxDistanceToOrigin = 40; const uint32_t roamTick = 20; + auto pNaviMgr = m_pFw->get< World::Manager::NaviMgr >(); + auto pNaviProvider = m_pCurrentZone->getNaviProvider(); switch( m_state ) { @@ -422,11 +459,8 @@ void Sapphire::Entity::BNpc::update( uint64_t tickCount ) { setInvincibilityType( InvincibilityType::InvincibilityIgnoreDamage ); - auto pNaviMgr = m_pFw->get< World::Manager::NaviMgr >(); - auto pNaviProvider = m_pCurrentZone->getNaviProvider(); if( pNaviProvider ) { - //if( !pNaviProvider->hasTargetState( *this ) ) pNaviProvider->setMoveTarget( *this, m_spawnPos ); } @@ -449,13 +483,10 @@ void Sapphire::Entity::BNpc::update( uint64_t tickCount ) case BNpcState::Roaming: { - auto pNaviMgr = m_pFw->get< World::Manager::NaviMgr >(); - auto pNaviProvider = m_pCurrentZone->getNaviProvider(); if( pNaviProvider ) { - //if( !pNaviProvider->hasTargetState( *this ) ) - pNaviProvider->setMoveTarget( *this, m_roamPos ); + pNaviProvider->setMoveTarget( *this, m_roamPos ); } if( moveTo( m_roamPos ) ) @@ -474,9 +505,6 @@ void Sapphire::Entity::BNpc::update( uint64_t tickCount ) if( pHatedActor ) aggro( pHatedActor ); - auto pNaviMgr = m_pFw->get< World::Manager::NaviMgr >(); - auto pNaviProvider = m_pCurrentZone->getNaviProvider(); - if( pNaviProvider->syncPosToChara( *this ) ) sendPositionUpdate(); @@ -513,6 +541,9 @@ void Sapphire::Entity::BNpc::update( uint64_t tickCount ) pHatedActor = hateListGetHighest(); } + if( pNaviProvider->syncPosToChara( *this ) ) + sendPositionUpdate(); + if( pHatedActor ) { auto distance = Util::distance( getPos().x, getPos().y, getPos().z, @@ -530,18 +561,16 @@ void Sapphire::Entity::BNpc::update( uint64_t tickCount ) break; } - if( !hasFlag( Immobile ) && ( distance > minActorDistance ) ) + if( distance > ( getScale() / 2 + pHatedActor->getScale() / 2 ) ) { - auto pNaviMgr = m_pFw->get< World::Manager::NaviMgr >(); - auto pNaviProvider = m_pCurrentZone->getNaviProvider(); + if( hasFlag( Immobile ) ) + break; + if( pNaviProvider ) { - //if( !pNaviProvider->hasTargetState( *this ) ) pNaviProvider->setMoveTarget( *this, pHatedActor->getPos() ); } - //auto pTeriMgr = m_pFw->get< World::Manager::TerritoryMgr >(); - //if ( ( currTime - m_lastAttack ) > 600 && pTeriMgr->isDefaultTerritory( getCurrentZone()->getTerritoryTypeId() ) ) - moveTo( pHatedActor->getPos() ); + moveTo( *pHatedActor ); } else { @@ -666,7 +695,7 @@ void Sapphire::Entity::BNpc::setOwner( Sapphire::Entity::CharaPtr m_pChara ) { auto setOwnerPacket = makeZonePacket< FFXIVIpcActorOwner >( getId() ); setOwnerPacket->data().type = 0x01; - setOwnerPacket->data().actorId = 0; + setOwnerPacket->data().actorId = INVALID_GAME_OBJECT_ID; sendToInRangeSet( setOwnerPacket ); } } diff --git a/src/world/Actor/BNpc.h b/src/world/Actor/BNpc.h index 8ed859b9..cb8156bc 100644 --- a/src/world/Actor/BNpc.h +++ b/src/world/Actor/BNpc.h @@ -77,6 +77,8 @@ namespace Sapphire::Entity // return true if it reached the position bool moveTo( const Common::FFXIVARR_POSITION3& pos ); + bool moveTo( const Entity::Chara& targetChara ); + // processes movement void step(); diff --git a/src/world/Navi/NaviProvider.cpp b/src/world/Navi/NaviProvider.cpp index 2db4bdcb..3feff0ed 100644 --- a/src/world/Navi/NaviProvider.cpp +++ b/src/world/Navi/NaviProvider.cpp @@ -571,11 +571,11 @@ int32_t Sapphire::World::Navi::NaviProvider::addAgent( Entity::Chara& chara ) dtCrowdAgentParams params; std::memset( ¶ms, 0, sizeof( params ) ); params.height = 7.f; - params.maxAcceleration = 26.f; + params.maxAcceleration = 126.f; params.maxSpeed = 13.5f; params.radius = chara.getScale() / 2; - params.collisionQueryRange = params.radius * 12.0f; - params.pathOptimizationRange = params.radius * 30.0f; + params.collisionQueryRange = params.radius * 20.0f; + params.pathOptimizationRange = params.radius * 10.0f; params.updateFlags = 0; //params.updateFlags |= DT_CROWD_OBSTACLE_AVOIDANCE; float position[] = { chara.getPos().x, chara.getPos().y, chara.getPos().z };