1
Fork 0
mirror of https://github.com/SapphireServer/Sapphire.git synced 2025-05-01 00:27:44 +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 // 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; 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 y = stepPos.y;
auto z = ( sinf( angle ) * .5f ); auto z = ( sinf( angle ) * speed );
face( stepPos ); face( stepPos );
setPos( { getPos().x + x, y, getPos().z + z } ); setPos( { getPos().x + x, y, getPos().z + z } );
sendPositionUpdate(); sendPositionUpdate();
} }
bool Sapphire::Entity::BNpc::moveTo( const FFXIVARR_POSITION3& pos ) bool Sapphire::Entity::BNpc::moveTo( const FFXIVARR_POSITION3& pos )
@ -201,7 +206,9 @@ bool Sapphire::Entity::BNpc::moveTo( const FFXIVARR_POSITION3& pos )
if( !pNaviProvider ) 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; return false;
} }
@ -223,7 +230,6 @@ bool Sapphire::Entity::BNpc::moveTo( const FFXIVARR_POSITION3& pos )
step(); step();
return false; return false;
} }
@ -232,10 +238,9 @@ void Sapphire::Entity::BNpc::sendPositionUpdate()
uint8_t unk1 = 0x3a; uint8_t unk1 = 0x3a;
uint8_t animationType = 2; uint8_t animationType = 2;
if( m_state == BNpcState::Combat ) if( m_state == BNpcState::Combat || m_state == BNpcState::Retreat )
animationType = 0; animationType = 0;
auto movePacket = std::make_shared< MoveActorPacket >( *getAsChara(), unk1, animationType, 0, 0x5A ); auto movePacket = std::make_shared< MoveActorPacket >( *getAsChara(), unk1, animationType, 0, 0x5A );
sendToInRangeSet( movePacket ); sendToInRangeSet( movePacket );
} }
@ -362,6 +367,7 @@ void Sapphire::Entity::BNpc::update( int64_t currTime )
const uint8_t maxDistanceToOrigin = 40; const uint8_t maxDistanceToOrigin = 40;
const uint32_t roamTick = 20; const uint32_t roamTick = 20;
switch( m_state ) switch( m_state )
{ {
case BNpcState::Dead: case BNpcState::Dead:
@ -372,25 +378,10 @@ void Sapphire::Entity::BNpc::update( int64_t currTime )
{ {
setInvincibilityType( InvincibilityType::InvincibilityIgnoreDamage ); setInvincibilityType( InvincibilityType::InvincibilityIgnoreDamage );
// slowly restore hp every tick
if( std::difftime( currTime, m_lastTickTime ) > 3000 ) if( std::difftime( currTime, m_lastTickTime ) > 3000 )
{ regainHp( currTime );
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();
}
// slowly restore hp every tick
if( moveTo( m_spawnPos ) ) if( moveTo( m_spawnPos ) )
{ {
setInvincibilityType( InvincibilityType::InvincibilityNone ); setInvincibilityType( InvincibilityType::InvincibilityNone );
@ -399,6 +390,7 @@ void Sapphire::Entity::BNpc::update( int64_t currTime )
// todo: perhaps requires more investigation? // todo: perhaps requires more investigation?
m_lastRoamTargetReached = Util::getTimeSeconds(); m_lastRoamTargetReached = Util::getTimeSeconds();
// resetHp
setHp( getMaxHp() ); setHp( getMaxHp() );
m_state = BNpcState::Idle; m_state = BNpcState::Idle;
@ -414,7 +406,7 @@ void Sapphire::Entity::BNpc::update( int64_t currTime )
m_state = BNpcState::Idle; m_state = BNpcState::Idle;
} }
// checkaggro checkAggro( aggroRange );
} }
break; break;
@ -435,22 +427,7 @@ void Sapphire::Entity::BNpc::update( int64_t currTime )
m_state = BNpcState::Roaming; m_state = BNpcState::Roaming;
} }
// passive mobs should ignore players unless aggro'd checkAggro( aggroRange );
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 );
}
} }
case BNpcState::Combat: 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 ) void Sapphire::Entity::BNpc::onActionHostile( Sapphire::Entity::CharaPtr pSource )
{ {
if( !hateListGetHighest() ) if( !hateListGetHighest() )
@ -535,3 +529,23 @@ void Sapphire::Entity::BNpc::setTimeOfDeath( uint32_t timeOfDeath )
{ {
m_timeOfDeath = 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; uint32_t getTimeOfDeath() const;
void setTimeOfDeath( uint32_t timeOfDeath ); void setTimeOfDeath( uint32_t timeOfDeath );
void regainHp( int64_t currTime );
void checkAggro( uint32_t range );
private: private:
uint32_t m_bNpcBaseId; uint32_t m_bNpcBaseId;
uint32_t m_bNpcNameId; uint32_t m_bNpcNameId;

View file

@ -255,7 +255,7 @@ Sapphire::Common::FFXIVARR_POSITION3
auto pRNGMgr = m_pFw->get< World::Manager::RNGMgr >(); auto pRNGMgr = m_pFw->get< World::Manager::RNGMgr >();
auto rng = pRNGMgr->getRandGenerator< float >( 0.f, 1.f ); auto rng = pRNGMgr->getRandGenerator< float >( 0.f, 1.f );
status = m_naviMeshQuery->findRandomPointAroundCircle( startRef, spos, maxRadius, &filter, frand, status = m_naviMeshQuery->findRandomPointAroundCircle( startRef, spos, maxRadius, &filter, frand,
&randomRef, randomPt); &randomRef, randomPt );
if( dtStatusFailed( status ) ) if( dtStatusFailed( status ) )
{ {

View file

@ -45,7 +45,7 @@ public:
bool hasPlayers() const bool hasPlayers() const
{ {
return ( ( m_playerCount > 0 ) ? true : false ); return m_playerCount > 0;
} }
size_t getActorCount() const 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 ); auto cell = getCellPtr( x, y );
if( !cell ) if( !cell )