mirror of
https://github.com/SapphireServer/Sapphire.git
synced 2025-04-27 06:47:45 +00:00
Initial roaming tests, still very rough and ugly
This commit is contained in:
parent
93e24a28b1
commit
7e935df56f
6 changed files with 99 additions and 42 deletions
|
@ -19,7 +19,6 @@ add_custom_target( copy_runtime_files ALL
|
|||
# Dependencies and compiler settings #
|
||||
######################################
|
||||
include( "cmake/paths.cmake" )
|
||||
#include( "cmake/mysql.cmake" )
|
||||
include( "cmake/compiler.cmake" )
|
||||
include( "cmake/cotire.cmake" )
|
||||
|
||||
|
|
|
@ -12,3 +12,4 @@ endif()
|
|||
|
||||
# Create log folder
|
||||
file( MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/bin/log )
|
||||
file( MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/bin/navi )
|
||||
|
|
|
@ -161,32 +161,25 @@ void Sapphire::Entity::BNpc::step()
|
|||
// No path to track
|
||||
return;
|
||||
|
||||
if( Util::distance( getPos().x, getPos().y, getPos().z, m_naviTarget.x, m_naviTarget.y, m_naviTarget.z ) <= 4 )
|
||||
{
|
||||
// Reached target
|
||||
m_naviLastPath.clear();
|
||||
return;
|
||||
}
|
||||
|
||||
auto stepPos = m_naviLastPath[ m_naviPathStep ];
|
||||
|
||||
if( Util::distance( getPos().x, getPos().y, getPos().z, stepPos.x, stepPos.y, stepPos.z ) <= 4 && m_naviPathStep < m_naviLastPath.size() - 1 )
|
||||
if( Util::distance( getPos().x, getPos().y, getPos().z, stepPos.x, stepPos.y, stepPos.z ) <= 4 &&
|
||||
m_naviPathStep < m_naviLastPath.size() - 1 )
|
||||
{
|
||||
// Reached step in path
|
||||
m_naviPathStep++;
|
||||
|
||||
stepPos = m_naviLastPath[ m_naviPathStep ];
|
||||
}
|
||||
|
||||
// This is probably not a good way to do it but works fine for now
|
||||
float angle = Util::calcAngFrom( getPos().x, getPos().z, stepPos.x, stepPos.z ) + PI;
|
||||
|
||||
auto x = ( cosf( angle ) * 1.1f );
|
||||
auto x = ( cosf( angle ) * 1.7f );
|
||||
auto y = stepPos.y;
|
||||
auto z = ( sinf( angle ) * 1.1f );
|
||||
auto z = ( sinf( angle ) * 1.7f );
|
||||
|
||||
setPos( { getPos().x + x, y, getPos().z + z } );
|
||||
face( stepPos );
|
||||
setPos( { getPos().x + x, y, getPos().z + z } );
|
||||
|
||||
sendPositionUpdate();
|
||||
}
|
||||
|
@ -194,12 +187,11 @@ void Sapphire::Entity::BNpc::step()
|
|||
bool Sapphire::Entity::BNpc::moveTo( const FFXIVARR_POSITION3& pos )
|
||||
{
|
||||
if( Util::distance( getPos().x, getPos().y, getPos().z, pos.x, pos.y, pos.z ) <= 4 )
|
||||
{
|
||||
// Reached destination
|
||||
m_naviLastPath.clear();
|
||||
return true;
|
||||
|
||||
if( m_naviTarget.x == pos.x && m_naviTarget.y == pos.y && m_naviTarget.z == pos.z )
|
||||
// Targets are the same
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check if we have to recalculate
|
||||
if( Util::getTimeMs() - m_naviLastUpdate > 500 )
|
||||
|
@ -224,29 +216,13 @@ bool Sapphire::Entity::BNpc::moveTo( const FFXIVARR_POSITION3& pos )
|
|||
}
|
||||
else
|
||||
{
|
||||
Logger::debug( "No path found from x{0} y{1} z{2} to x{3} y{4} z{5} in {6}", getPos().x, getPos().y, getPos().z, pos.x, pos.y, pos.z, m_pCurrentZone->getInternalName() );
|
||||
Logger::debug( "No path found from x{0} y{1} z{2} to x{3} y{4} z{5} in {6}",
|
||||
getPos().x, getPos().y, getPos().z, pos.x, pos.y, pos.z, m_pCurrentZone->getInternalName() );
|
||||
}
|
||||
}
|
||||
/*
|
||||
float rot = Util::calcAngFrom( getPos().x, getPos().z, pos.x, pos.z );
|
||||
float newRot = PI - rot + ( PI / 2 );
|
||||
|
||||
face( pos );
|
||||
float angle = Util::calcAngFrom( getPos().x, getPos().z, pos.x, pos.z ) + PI;
|
||||
|
||||
auto x = ( cosf( angle ) * 1.1f );
|
||||
auto y = ( getPos().y + pos.y ) * 0.5f; // fake value while there is no collision
|
||||
auto z = ( sinf( angle ) * 1.1f );
|
||||
|
||||
Common::FFXIVARR_POSITION3 newPos{ getPos().x + x, y, getPos().z + z };
|
||||
setPos( newPos );
|
||||
|
||||
Common::FFXIVARR_POSITION3 tmpPos{ getPos().x + x, y, getPos().z + z };
|
||||
setPos( tmpPos );
|
||||
setRot( newRot );
|
||||
|
||||
sendPositionUpdate();
|
||||
*/
|
||||
step();
|
||||
|
||||
return false;
|
||||
}
|
||||
|
@ -377,6 +353,7 @@ void Sapphire::Entity::BNpc::update( int64_t currTime )
|
|||
const uint8_t minActorDistance = 4;
|
||||
const uint8_t aggroRange = 8;
|
||||
const uint8_t maxDistanceToOrigin = 40;
|
||||
const uint32_t roamTick = 20;
|
||||
|
||||
switch( m_state )
|
||||
{
|
||||
|
@ -391,8 +368,28 @@ void Sapphire::Entity::BNpc::update( int64_t currTime )
|
|||
}
|
||||
break;
|
||||
|
||||
case BNpcState::Roaming:
|
||||
{
|
||||
if( moveTo( m_roamPos ) )
|
||||
{
|
||||
m_lastRoamTargetReached = Util::getTimeSeconds();
|
||||
m_state = BNpcState::Idle;
|
||||
}
|
||||
|
||||
// checkaggro
|
||||
}
|
||||
break;
|
||||
|
||||
case BNpcState::Idle:
|
||||
{
|
||||
if( Util::getTimeSeconds() - m_lastRoamTargetReached > roamTick )
|
||||
{
|
||||
auto pNaviMgr = m_pFw->get< World::Manager::NaviMgr >();
|
||||
auto pNaviProvider = pNaviMgr->getNaviProvider( m_pCurrentZone->getBgPath() );
|
||||
m_roamPos = pNaviProvider->findRandomPositionInCircle( m_spawnPos, 5 );
|
||||
m_state = BNpcState::Roaming;
|
||||
}
|
||||
|
||||
// passive mobs should ignore players unless aggro'd
|
||||
if( m_aggressionMode == 1 )
|
||||
return;
|
||||
|
@ -465,7 +462,6 @@ void Sapphire::Entity::BNpc::update( int64_t currTime )
|
|||
}
|
||||
}
|
||||
|
||||
step();
|
||||
}
|
||||
|
||||
void Sapphire::Entity::BNpc::onActionHostile( Sapphire::Entity::CharaPtr pSource )
|
||||
|
|
|
@ -24,6 +24,7 @@ namespace Sapphire::Entity
|
|||
Idle,
|
||||
Combat,
|
||||
Retreat,
|
||||
Roaming,
|
||||
JustDied,
|
||||
Dead,
|
||||
};
|
||||
|
@ -103,8 +104,10 @@ namespace Sapphire::Entity
|
|||
uint8_t m_level;
|
||||
|
||||
uint32_t m_timeOfDeath;
|
||||
uint32_t m_lastRoamTargetReached;
|
||||
|
||||
Common::FFXIVARR_POSITION3 m_spawnPos;
|
||||
Common::FFXIVARR_POSITION3 m_roamPos;
|
||||
|
||||
BNpcState m_state;
|
||||
std::set< std::shared_ptr< HateListEntry > > m_hateList;
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
#include <Logging/Logger.h>
|
||||
#include <ServerMgr.h>
|
||||
|
||||
#include <Manager/RNGMgr.h>
|
||||
|
||||
#include "NaviProvider.h"
|
||||
|
||||
|
@ -210,6 +211,60 @@ bool Sapphire::World::Navi::NaviProvider::getSteerTarget( dtNavMeshQuery* navQue
|
|||
return true;
|
||||
}
|
||||
|
||||
static float frand()
|
||||
{
|
||||
return ( float ) rand() / (float)RAND_MAX;
|
||||
}
|
||||
|
||||
|
||||
Sapphire::Common::FFXIVARR_POSITION3
|
||||
Sapphire::World::Navi::NaviProvider::findRandomPositionInCircle( const Sapphire::Common::FFXIVARR_POSITION3& startPos,
|
||||
float maxRadius )
|
||||
{
|
||||
dtStatus status;
|
||||
|
||||
float spos[ 3 ] = { startPos.x, startPos.y, startPos.z };
|
||||
|
||||
float polyPickExt[ 3 ];
|
||||
polyPickExt[ 0 ] = 30;
|
||||
polyPickExt[ 1 ] = 60;
|
||||
polyPickExt[ 2 ] = 30;
|
||||
|
||||
float randomPt[ 3 ];
|
||||
float snearest[ 3 ];
|
||||
|
||||
dtQueryFilter filter;
|
||||
filter.setIncludeFlags( 0xffff );
|
||||
filter.setExcludeFlags( 0 );
|
||||
|
||||
dtPolyRef startRef;
|
||||
dtPolyRef randomRef;
|
||||
|
||||
status = m_naviMeshQuery->findNearestPoly( spos, polyPickExt, &filter, &startRef, snearest );
|
||||
|
||||
if( dtStatusFailed( status ) )
|
||||
{
|
||||
return {};
|
||||
}
|
||||
|
||||
if( !m_naviMesh->isValidPolyRef( startRef ) )
|
||||
{
|
||||
return {};
|
||||
}
|
||||
|
||||
auto pRNGMgr = m_pFw->get< World::Manager::RNGMgr >();
|
||||
auto rng = pRNGMgr->getRandGenerator< float >( 0.f, 1.f );
|
||||
status = m_naviMeshQuery->findRandomPointAroundCircle( startRef, spos, maxRadius, &filter, frand,
|
||||
&randomRef, randomPt);
|
||||
|
||||
if( dtStatusFailed( status ) )
|
||||
{
|
||||
return {};
|
||||
}
|
||||
|
||||
return { randomPt[ 0 ], randomPt[ 1 ], randomPt[ 2 ] };
|
||||
}
|
||||
|
||||
std::vector< Sapphire::Common::FFXIVARR_POSITION3 >
|
||||
Sapphire::World::Navi::NaviProvider::findFollowPath( const Common::FFXIVARR_POSITION3& startPos,
|
||||
const Common::FFXIVARR_POSITION3& endPos )
|
||||
|
@ -251,9 +306,9 @@ std::vector< Sapphire::Common::FFXIVARR_POSITION3 >
|
|||
m_naviMeshQuery->closestPointOnPoly( startRef, spos, iterPos, 0 );
|
||||
m_naviMeshQuery->closestPointOnPoly( polys[ npolys - 1 ], epos, targetPos, 0 );
|
||||
|
||||
Logger::debug( "IterPos: {0} {1} {2}; TargetPos: {3} {4} {5}",
|
||||
iterPos[ 0 ], iterPos[ 1 ], iterPos[ 2 ],
|
||||
targetPos[ 0 ], targetPos[ 1 ], targetPos[ 2 ] );
|
||||
//Logger::debug( "IterPos: {0} {1} {2}; TargetPos: {3} {4} {5}",
|
||||
// iterPos[ 0 ], iterPos[ 1 ], iterPos[ 2 ],
|
||||
// targetPos[ 0 ], targetPos[ 1 ], targetPos[ 2 ] );
|
||||
|
||||
const float STEP_SIZE = 1.2f;
|
||||
const float SLOP = 0.15f;
|
||||
|
@ -370,7 +425,7 @@ std::vector< Sapphire::Common::FFXIVARR_POSITION3 >
|
|||
|
||||
for( int32_t i = 0; i < numSmoothPath; i += 3 )
|
||||
{
|
||||
resultCoords.push_back( Common::FFXIVARR_POSITION3{ smoothPath[ i ], smoothPath[ i + 1 ], smoothPath[ i + 2 ] } );
|
||||
resultCoords.emplace_back( Common::FFXIVARR_POSITION3{ smoothPath[ i ], smoothPath[ i + 1 ], smoothPath[ i + 2 ] } );
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -40,7 +40,10 @@ namespace Sapphire::World::Navi
|
|||
void toDetourPos( const Common::FFXIVARR_POSITION3& position, float* out );
|
||||
Common::FFXIVARR_POSITION3 toGamePos( float* pos );
|
||||
|
||||
std::vector< Common::FFXIVARR_POSITION3 > findFollowPath( const Common::FFXIVARR_POSITION3& startPos, const Common::FFXIVARR_POSITION3& endPos );
|
||||
std::vector< Common::FFXIVARR_POSITION3 > findFollowPath( const Common::FFXIVARR_POSITION3& startPos,
|
||||
const Common::FFXIVARR_POSITION3& endPos );
|
||||
Common::FFXIVARR_POSITION3 findRandomPositionInCircle( const Sapphire::Common::FFXIVARR_POSITION3& startPos,
|
||||
float maxRadius );
|
||||
|
||||
bool hasNaviMesh() const;
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue