From 249194630cc5b5e4c11c272612245adc84b351c9 Mon Sep 17 00:00:00 2001 From: collett Date: Thu, 20 Jul 2023 15:30:55 +0900 Subject: [PATCH] fix mob movement, hopefully. --- src/world/Actor/BNpc.cpp | 59 +++++++++++---------------------- src/world/Actor/BNpc.h | 3 +- src/world/Actor/Player.cpp | 4 +-- src/world/Navi/NaviProvider.cpp | 14 ++++---- 4 files changed, 31 insertions(+), 49 deletions(-) diff --git a/src/world/Actor/BNpc.cpp b/src/world/Actor/BNpc.cpp index ba981e6f..cfb7ec7a 100644 --- a/src/world/Actor/BNpc.cpp +++ b/src/world/Actor/BNpc.cpp @@ -83,6 +83,7 @@ Sapphire::Entity::BNpc::BNpc( uint32_t id, BNpcTemplatePtr pTemplate, float posX m_pCurrentTerritory = std::move( pZone ); m_spawnPos = m_pos; + m_isMoving = false; m_timeOfDeath = 0; m_targetId = Common::INVALID_GAME_OBJECT_ID64; @@ -116,9 +117,7 @@ Sapphire::Entity::BNpc::BNpc( uint32_t id, BNpcTemplatePtr pTemplate, float posX m_radius *= modelSkeleton->radius; } - // todo: is this actually good? - //m_naviTargetReachedDistance = m_scale * 2.f; - m_naviTargetReachedDistance = 4.f; + m_naviTargetReachedDistance = m_radius; calculateStats(); auto& scriptMgr = Common::Service< Sapphire::Scripting::ScriptMgr >::ref(); @@ -194,7 +193,7 @@ void Sapphire::Entity::BNpc::setState( BNpcState state ) m_state = state; } -bool Sapphire::Entity::BNpc::moveTo( const FFXIVARR_POSITION3& pos ) +bool Sapphire::Entity::BNpc::moveTo( const FFXIVARR_POSITION3& pos, float radius ) { auto pNaviProvider = m_pCurrentTerritory->getNaviProvider(); @@ -208,14 +207,15 @@ bool Sapphire::Entity::BNpc::moveTo( const FFXIVARR_POSITION3& pos ) } auto pos1 = pNaviProvider->getMovePos( *this ); - - if( Util::distance( pos1, pos ) < getRadius() + 3.f ) + + if( Util::distance( pos1, pos ) < getNaviTargetReachedDistance() + radius ) { // Reached destination face( pos ); setPos( pos1 ); sendPositionUpdate(); pNaviProvider->updateAgentPosition( *this ); + m_isMoving = false; return true; } @@ -223,59 +223,38 @@ bool Sapphire::Entity::BNpc::moveTo( const FFXIVARR_POSITION3& pos ) face( pos ); setPos( pos1 ); sendPositionUpdate(); + m_isMoving = true; return false; } bool Sapphire::Entity::BNpc::moveTo( const Entity::Chara& targetChara ) { - - auto pNaviProvider = m_pCurrentTerritory->getNaviProvider(); - - if( !pNaviProvider ) - { - Logger::error( "No NaviProvider for zone#{0} - {1}", - m_pCurrentTerritory->getGuId(), - m_pCurrentTerritory->getInternalName() ); - return false; - } - - auto pos1 = pNaviProvider->getMovePos( *this ); - - if( Util::distance( pos1, targetChara.getPos() ) <= ( getRadius() + targetChara.getRadius() ) + 3.f ) - { - // Reached destination - face( targetChara.getPos() ); - setPos( pos1 ); - sendPositionUpdate(); - pNaviProvider->updateAgentPosition( *this ); - return true; - } - - m_pCurrentTerritory->updateActorPosition( *this ); - face( targetChara.getPos() ); - setPos( pos1 ); - sendPositionUpdate(); - return false; + return moveTo( targetChara.getPos(), targetChara.getRadius() ); } void Sapphire::Entity::BNpc::stopMoving() { auto pNaviProvider = m_pCurrentTerritory->getNaviProvider(); - if( !pNaviProvider ) + if( !pNaviProvider || !m_isMoving ) return; sendPositionUpdate(); pNaviProvider->updateAgentPosition( *this ); + m_isMoving = false; } void Sapphire::Entity::BNpc::sendPositionUpdate() { uint8_t unk1 = 0x3a; uint8_t animationType = 2; + uint16_t moveSpeed = MoveSpeed::Walk; if( m_state == BNpcState::Combat || m_state == BNpcState::Retreat ) + { animationType = 0; + moveSpeed = MoveSpeed::Run; + } - auto movePacket = std::make_shared< MoveActorPacket >( *getAsChara(), unk1, animationType, 0, 0x5A ); + auto movePacket = std::make_shared< MoveActorPacket >( *getAsChara(), unk1, animationType, 0, moveSpeed ); sendToInRangeSet( movePacket ); } @@ -496,6 +475,7 @@ void Sapphire::Entity::BNpc::doDefaultBNpcUpdate( uint64_t tickCount ) m_roamPos = pNaviProvider->findRandomPositionInCircle( m_spawnPos, 5 ); m_state = BNpcState::Roaming; + pNaviProvider->updateAgentParameters( *this ); } checkAggro(); @@ -527,9 +507,6 @@ void Sapphire::Entity::BNpc::doDefaultBNpcUpdate( uint64_t tickCount ) return; } - if( pNaviProvider->syncPosToChara( *this ) ) - sendPositionUpdate(); - auto distance = Util::distance( getPos().x, getPos().y, getPos().z, pHatedActor->getPos().x, pHatedActor->getPos().y, pHatedActor->getPos().z ); @@ -543,7 +520,7 @@ void Sapphire::Entity::BNpc::doDefaultBNpcUpdate( uint64_t tickCount ) break; } - if( distance > ( getRadius() + pHatedActor->getRadius() ) ) + if( distance > ( getNaviTargetReachedDistance() + pHatedActor->getRadius() ) ) { if( hasFlag( Immobile ) ) break; @@ -556,6 +533,8 @@ void Sapphire::Entity::BNpc::doDefaultBNpcUpdate( uint64_t tickCount ) if( distance < ( getRadius() + pHatedActor->getRadius() + 3.f ) ) { + stopMoving(); + if( !hasFlag( TurningDisabled ) && face( pHatedActor->getPos() ) ) sendPositionUpdate(); diff --git a/src/world/Actor/BNpc.h b/src/world/Actor/BNpc.h index 7e693a1c..20c2e5b4 100644 --- a/src/world/Actor/BNpc.h +++ b/src/world/Actor/BNpc.h @@ -75,7 +75,7 @@ namespace Sapphire::Entity float getNaviTargetReachedDistance() const; // return true if it reached the position - bool moveTo( const Common::FFXIVARR_POSITION3& pos ); + bool moveTo( const Common::FFXIVARR_POSITION3& pos, float radius = 0 ); bool moveTo( const Entity::Chara& targetChara ); @@ -149,6 +149,7 @@ namespace Sapphire::Entity Common::FFXIVARR_POSITION3 m_spawnPos; Common::FFXIVARR_POSITION3 m_roamPos; + bool m_isMoving; BNpcState m_state; std::set< std::shared_ptr< HateListEntry > > m_hateList; diff --git a/src/world/Actor/Player.cpp b/src/world/Actor/Player.cpp index 030c5c06..7aa9ff58 100644 --- a/src/world/Actor/Player.cpp +++ b/src/world/Actor/Player.cpp @@ -1244,13 +1244,13 @@ void Sapphire::Entity::Player::update( uint64_t tickCount ) auto chara = actor->getAsChara(); // default autoattack range - float range = 3.f + chara->getRadius(); + float range = 3.f + chara->getRadius() + getRadius() * 0.5f; // default autoattack range for ranged classes if( getClass() == ClassJob::Machinist || getClass() == ClassJob::Bard || getClass() == ClassJob::Archer ) - range = 25; + range = 25.f + chara->getRadius() + getRadius() * 0.5f; if( Util::distance( getPos().x, getPos().y, getPos().z, diff --git a/src/world/Navi/NaviProvider.cpp b/src/world/Navi/NaviProvider.cpp index e118734b..84922b01 100644 --- a/src/world/Navi/NaviProvider.cpp +++ b/src/world/Navi/NaviProvider.cpp @@ -24,9 +24,9 @@ Sapphire::World::Navi::NaviProvider::NaviProvider( const std::string& internalNa m_internalName( internalName ) { // Set defaults - m_polyFindRange[ 0 ] = 10; + m_polyFindRange[ 0 ] = 20; m_polyFindRange[ 1 ] = 20; - m_polyFindRange[ 2 ] = 10; + m_polyFindRange[ 2 ] = 20; } bool Sapphire::World::Navi::NaviProvider::init() @@ -355,7 +355,7 @@ std::vector< Sapphire::Common::FFXIVARR_POSITION3 > // iterPos[ 0 ], iterPos[ 1 ], iterPos[ 2 ], // targetPos[ 0 ], targetPos[ 1 ], targetPos[ 2 ] ); - const float STEP_SIZE = 1.2f; + const float STEP_SIZE = 0.5f; const float SLOP = 0.15f; int32_t numSmoothPath = 0; @@ -573,7 +573,8 @@ int32_t Sapphire::World::Navi::NaviProvider::addAgent( Entity::Chara& chara ) std::memset( ¶ms, 0, sizeof( params ) ); params.height = 3.f; params.maxAcceleration = 25.f; - params.maxSpeed = std::pow( 2, chara.getRadius() * 0.35f ) + 1.f; + //params.maxSpeed = std::pow( 2, chara.getRadius() * 0.35f ) + 1.f; + params.maxSpeed = ( std::pow( 2.f, 1.f * 0.35f ) + 1.f ) * 0.5f; params.radius = ( chara.getRadius() ) * 0.75f; params.collisionQueryRange = params.radius * 12.0f; params.pathOptimizationRange = params.radius * 20.0f; @@ -589,9 +590,10 @@ void Sapphire::World::Navi::NaviProvider::updateAgentParameters( Entity::BNpc& b std::memset( ¶ms, 0, sizeof( params ) ); params.height = 3.f; params.maxAcceleration = 25.f; - params.maxSpeed = std::pow( 2, bnpc.getRadius() * 0.35f ) + 1.f; + //params.maxSpeed = std::pow( 2, bnpc.getRadius() * 0.35f ) + 1.f; + params.maxSpeed = ( std::pow( 2.f, 1.f * 0.35f ) + 1.f ) * 0.5f; if( bnpc.getState() == Entity::BNpcState::Combat || bnpc.getState() == Entity::BNpcState::Retreat ) - params.maxSpeed *= 2; + params.maxSpeed *= 2.5f; params.radius = ( bnpc.getRadius() ) * 0.75f; params.collisionQueryRange = params.radius * 12.0f; params.pathOptimizationRange = params.radius * 20.0f;