1
Fork 0
mirror of https://github.com/SapphireServer/Sapphire.git synced 2025-04-30 16:17:46 +00:00

cleaned up movement code a bit, roamings mobs can aggro now

This commit is contained in:
Mordred 2019-01-27 01:12:31 +01:00
parent a155420786
commit 956b115e58
5 changed files with 63 additions and 45 deletions

View file

@ -174,14 +174,19 @@ void Sapphire::Entity::BNpc::step()
// 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 ) * .5f );
float speed = 1.7f;
if( m_state == BNpcState::Roaming )
speed *= 0.5f;
auto x = ( cosf( angle ) * speed );
auto y = stepPos.y;
auto z = ( sinf( angle ) * .5f );
auto z = ( sinf( angle ) * speed );
face( stepPos );
setPos( { getPos().x + x, y, getPos().z + z } );
sendPositionUpdate();
}
bool Sapphire::Entity::BNpc::moveTo( const FFXIVARR_POSITION3& pos )
@ -201,7 +206,9 @@ bool Sapphire::Entity::BNpc::moveTo( const FFXIVARR_POSITION3& pos )
if( !pNaviProvider )
{
Logger::error( "No NaviProvider for zone#{0} - {1}", m_pCurrentZone->getGuId(), m_pCurrentZone->getInternalName() );
Logger::error( "No NaviProvider for zone#{0} - {1}",
m_pCurrentZone->getGuId(),
m_pCurrentZone->getInternalName() );
return false;
}
@ -223,7 +230,6 @@ bool Sapphire::Entity::BNpc::moveTo( const FFXIVARR_POSITION3& pos )
step();
return false;
}
@ -232,10 +238,9 @@ void Sapphire::Entity::BNpc::sendPositionUpdate()
uint8_t unk1 = 0x3a;
uint8_t animationType = 2;
if( m_state == BNpcState::Combat )
if( m_state == BNpcState::Combat || m_state == BNpcState::Retreat )
animationType = 0;
auto movePacket = std::make_shared< MoveActorPacket >( *getAsChara(), unk1, animationType, 0, 0x5A );
sendToInRangeSet( movePacket );
}
@ -362,6 +367,7 @@ void Sapphire::Entity::BNpc::update( int64_t currTime )
const uint8_t maxDistanceToOrigin = 40;
const uint32_t roamTick = 20;
switch( m_state )
{
case BNpcState::Dead:
@ -372,25 +378,10 @@ void Sapphire::Entity::BNpc::update( int64_t currTime )
{
setInvincibilityType( InvincibilityType::InvincibilityIgnoreDamage );
// slowly restore hp every tick
if( std::difftime( currTime, m_lastTickTime ) > 3000 )
{
m_lastTickTime = currTime;
if( m_hp < getMaxHp() )
{
auto addHp = static_cast< uint32_t >( getMaxHp() * 0.1f + 1 );
if( m_hp + addHp < getMaxHp() )
m_hp += addHp;
else
m_hp = getMaxHp();
}
sendStatusUpdate();
}
regainHp( currTime );
// slowly restore hp every tick
if( moveTo( m_spawnPos ) )
{
setInvincibilityType( InvincibilityType::InvincibilityNone );
@ -399,6 +390,7 @@ void Sapphire::Entity::BNpc::update( int64_t currTime )
// todo: perhaps requires more investigation?
m_lastRoamTargetReached = Util::getTimeSeconds();
// resetHp
setHp( getMaxHp() );
m_state = BNpcState::Idle;
@ -414,7 +406,7 @@ void Sapphire::Entity::BNpc::update( int64_t currTime )
m_state = BNpcState::Idle;
}
// checkaggro
checkAggro( aggroRange );
}
break;
@ -435,22 +427,7 @@ void Sapphire::Entity::BNpc::update( int64_t currTime )
m_state = BNpcState::Roaming;
}
// passive mobs should ignore players unless aggro'd
if( m_aggressionMode == 1 )
return;
CharaPtr pClosestChara = getClosestChara();
if( pClosestChara && pClosestChara->isAlive() )
{
auto distance = Util::distance( getPos().x, getPos().y, getPos().z,
pClosestChara->getPos().x,
pClosestChara->getPos().y,
pClosestChara->getPos().z );
if( distance < aggroRange && pClosestChara->isPlayer() )
aggro( pClosestChara );
}
checkAggro( aggroRange );
}
case BNpcState::Combat:
@ -508,6 +485,23 @@ void Sapphire::Entity::BNpc::update( int64_t currTime )
}
}
void Sapphire::Entity::BNpc::regainHp( int64_t currTime )
{
this->m_lastTickTime = currTime;
if( this->m_hp < this->getMaxHp() )
{
auto addHp = static_cast< uint32_t >( this->getMaxHp() * 0.1f + 1 );
if( this->m_hp + addHp < this->getMaxHp() )
this->m_hp += addHp;
else
this->m_hp = this->getMaxHp();
}
this->sendStatusUpdate();
}
void Sapphire::Entity::BNpc::onActionHostile( Sapphire::Entity::CharaPtr pSource )
{
if( !hateListGetHighest() )
@ -535,3 +529,23 @@ void Sapphire::Entity::BNpc::setTimeOfDeath( uint32_t timeOfDeath )
{
m_timeOfDeath = timeOfDeath;
}
void Sapphire::Entity::BNpc::checkAggro( uint32_t range )
{
// passive mobs should ignore players unless aggro'd
if( m_aggressionMode == 1 )
return;
CharaPtr pClosestChara = getClosestChara();
if( pClosestChara && pClosestChara->isAlive() )
{
auto distance = Util::distance( getPos().x, getPos().y, getPos().z,
pClosestChara->getPos().x,
pClosestChara->getPos().y,
pClosestChara->getPos().z );
if( distance < range && pClosestChara->isPlayer() )
aggro( pClosestChara );
}
}

View file

@ -90,6 +90,10 @@ namespace Sapphire::Entity
uint32_t getTimeOfDeath() const;
void setTimeOfDeath( uint32_t timeOfDeath );
void regainHp( int64_t currTime );
void checkAggro( uint32_t range );
private:
uint32_t m_bNpcBaseId;
uint32_t m_bNpcNameId;

View file

@ -255,7 +255,7 @@ Sapphire::Common::FFXIVARR_POSITION3
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);
&randomRef, randomPt );
if( dtStatusFailed( status ) )
{

View file

@ -45,7 +45,7 @@ public:
bool hasPlayers() const
{
return ( ( m_playerCount > 0 ) ? true : false );
return m_playerCount > 0;
}
size_t getActorCount() const

View file

@ -407,9 +407,9 @@ void Sapphire::Zone::updateBNpcs( int64_t tickCount )
}
}
for( uint32_t x = 0; x < _sizeX; x++ )
for( uint32_t y = 0; y < _sizeY; ++y )
{
for( uint32_t y = 0; y < _sizeY; ++y )
for( uint32_t x = 0; x < _sizeX; ++x )
{
auto cell = getCellPtr( x, y );
if( !cell )