1
Fork 0
mirror of https://github.com/SapphireServer/Sapphire.git synced 2025-04-25 05:57:45 +00:00

heal npcs when retreating, set hp to max when retreat finishes, cleanup

This commit is contained in:
NotAdam 2019-01-26 13:40:02 +11:00
parent 7cef77e2eb
commit edd050ece9
7 changed files with 54 additions and 15 deletions

View file

@ -615,6 +615,7 @@ namespace Sapphire::Common
InvincibilityNone, InvincibilityNone,
InvincibilityRefill, InvincibilityRefill,
InvincibilityStayAlive, InvincibilityStayAlive,
InvincibilityIgnoreDamage,
}; };
enum PlayerStateFlag : uint8_t enum PlayerStateFlag : uint8_t

View file

@ -370,8 +370,39 @@ void Sapphire::Entity::BNpc::update( int64_t currTime )
case BNpcState::Retreat: case BNpcState::Retreat:
{ {
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();
}
if( moveTo( m_spawnPos ) ) if( moveTo( m_spawnPos ) )
{
setInvincibilityType( InvincibilityType::InvincibilityNone );
// retail doesn't seem to roam straight after retreating
// todo: perhaps requires more investigation?
m_lastRoamTargetReached = Util::getTimeSeconds();
setHp( getMaxHp() );
m_state = BNpcState::Idle; m_state = BNpcState::Idle;
}
} }
break; break;
@ -475,7 +506,6 @@ void Sapphire::Entity::BNpc::update( int64_t currTime )
} }
} }
} }
} }
void Sapphire::Entity::BNpc::onActionHostile( Sapphire::Entity::CharaPtr pSource ) void Sapphire::Entity::BNpc::onActionHostile( Sapphire::Entity::CharaPtr pSource )

View file

@ -151,35 +151,35 @@ uint32_t Sapphire::Entity::Chara::getMaxMp() const
void Sapphire::Entity::Chara::resetHp() void Sapphire::Entity::Chara::resetHp()
{ {
m_hp = getMaxHp(); m_hp = getMaxHp();
sendStatusUpdate( true ); sendStatusUpdate();
} }
/*! \return reset mp to current max mp */ /*! \return reset mp to current max mp */
void Sapphire::Entity::Chara::resetMp() void Sapphire::Entity::Chara::resetMp()
{ {
m_mp = getMaxMp(); m_mp = getMaxMp();
sendStatusUpdate( true ); sendStatusUpdate();
} }
/*! \param hp amount to set ( caps to maxHp ) */ /*! \param hp amount to set ( caps to maxHp ) */
void Sapphire::Entity::Chara::setHp( uint32_t hp ) void Sapphire::Entity::Chara::setHp( uint32_t hp )
{ {
m_hp = hp < getMaxHp() ? hp : getMaxHp(); m_hp = hp < getMaxHp() ? hp : getMaxHp();
sendStatusUpdate( true ); sendStatusUpdate();
} }
/*! \param mp amount to set ( caps to maxMp ) */ /*! \param mp amount to set ( caps to maxMp ) */
void Sapphire::Entity::Chara::setMp( uint32_t mp ) void Sapphire::Entity::Chara::setMp( uint32_t mp )
{ {
m_mp = mp < getMaxMp() ? mp : getMaxMp(); m_mp = mp < getMaxMp() ? mp : getMaxMp();
sendStatusUpdate( true ); sendStatusUpdate();
} }
/*! \param gp amount to set*/ /*! \param gp amount to set*/
void Sapphire::Entity::Chara::setGp( uint32_t gp ) void Sapphire::Entity::Chara::setGp( uint32_t gp )
{ {
m_gp = gp; m_gp = gp;
sendStatusUpdate( true ); sendStatusUpdate();
} }
/*! \param type invincibility type to set */ /*! \param type invincibility type to set */
@ -325,12 +325,14 @@ void Sapphire::Entity::Chara::takeDamage( uint32_t damage )
case InvincibilityStayAlive: case InvincibilityStayAlive:
setHp( 0 ); setHp( 0 );
break; break;
case InvincibilityIgnoreDamage:
break;
} }
} }
else else
m_hp -= damage; m_hp -= damage;
sendStatusUpdate( false ); sendStatusUpdate();
} }
/*! /*!
@ -349,7 +351,7 @@ void Sapphire::Entity::Chara::heal( uint32_t amount )
else else
m_hp += amount; m_hp += amount;
sendStatusUpdate( false ); sendStatusUpdate();
} }
/*! /*!
@ -359,7 +361,7 @@ so players can have their own version and we can abolish the param.
\param true if the update should also be sent to the actor ( player ) himself \param true if the update should also be sent to the actor ( player ) himself
*/ */
void Sapphire::Entity::Chara::sendStatusUpdate( bool toSelf ) void Sapphire::Entity::Chara::sendStatusUpdate()
{ {
FFXIVPacketBasePtr packet = std::make_shared< UpdateHpMpTpPacket >( *this ); FFXIVPacketBasePtr packet = std::make_shared< UpdateHpMpTpPacket >( *this );
sendToInRangeSet( packet ); sendToInRangeSet( packet );
@ -391,6 +393,7 @@ void Sapphire::Entity::Chara::autoAttack( CharaPtr pTarget )
uint64_t tick = Util::getTimeMs(); uint64_t tick = Util::getTimeMs();
// todo: this needs to use the auto attack delay for the equipped weapon
if( ( tick - m_lastAttack ) > 2500 ) if( ( tick - m_lastAttack ) > 2500 )
{ {
pTarget->onActionHostile( getAsChara() ); pTarget->onActionHostile( getAsChara() );

View file

@ -229,7 +229,7 @@ namespace Sapphire::Entity
virtual uint8_t getLevel() const; virtual uint8_t getLevel() const;
virtual void sendStatusUpdate( bool toSelf = true ); virtual void sendStatusUpdate();
virtual void takeDamage( uint32_t damage ); virtual void takeDamage( uint32_t damage );

View file

@ -739,7 +739,7 @@ void Sapphire::Entity::Player::gainLevel()
} }
void Sapphire::Entity::Player::sendStatusUpdate( bool toSelf ) void Sapphire::Entity::Player::sendStatusUpdate()
{ {
sendToInRangeSet( std::make_shared< UpdateHpMpTpPacket >( *this ), true ); sendToInRangeSet( std::make_shared< UpdateHpMpTpPacket >( *this ), true );
} }
@ -810,7 +810,7 @@ void Sapphire::Entity::Player::setClassJob( Common::ClassJob classJob )
sendToInRangeSet( makeActorControl142( getId(), ClassJobChange, 0x04 ), true ); sendToInRangeSet( makeActorControl142( getId(), ClassJobChange, 0x04 ), true );
sendStatusUpdate( true ); sendStatusUpdate();
} }
void Sapphire::Entity::Player::setLevel( uint8_t level ) void Sapphire::Entity::Player::setLevel( uint8_t level )

View file

@ -707,7 +707,7 @@ namespace Sapphire::Entity
void sendStateFlags(); void sendStateFlags();
/*! send status update */ /*! send status update */
void sendStatusUpdate( bool toSelf = true ) override; void sendStatusUpdate() override;
/*! send the entire inventory sequence */ /*! send the entire inventory sequence */
void sendInventory(); void sendInventory();

View file

@ -275,8 +275,13 @@ void Sapphire::Network::GameConnection::gm1Handler( FrameworkPtr pFw,
} }
case GmCommand::Hp: case GmCommand::Hp:
{ {
targetPlayer->setHp( param1 ); auto chara = targetActor->getAsChara();
player.sendNotice( "Hp for {0} was set to {1}", targetPlayer->getName(), param1 ); if( chara )
{
chara->setHp( param1 );
player.sendNotice( "Hp for {0} was set to {1}", chara->getName(), param1 );
}
break; break;
} }
case GmCommand::Mp: case GmCommand::Mp: