1
Fork 0
mirror of https://github.com/SapphireServer/Sapphire.git synced 2025-04-26 22:37:45 +00:00

Initial roaming tests, still very rough and ugly

This commit is contained in:
Mordred 2019-01-26 00:06:24 +01:00
parent 93e24a28b1
commit 7e935df56f
6 changed files with 99 additions and 42 deletions

View file

@ -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" )

View file

@ -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 )

View file

@ -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 )

View file

@ -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;

View file

@ -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 ] } );
}
}

View file

@ -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;