From 2973b27e26a835e5b5c5cbc42cf9c3fa767bb949 Mon Sep 17 00:00:00 2001 From: Mordred Date: Wed, 23 Jan 2019 22:37:55 +0100 Subject: [PATCH] Despawn and respawn dead bnpcs --- src/world/Actor/BNpc.cpp | 27 +++++++-- src/world/Actor/BNpc.h | 5 ++ .../Network/PacketWrappers/NpcSpawnPacket.h | 3 + src/world/Territory/Zone.cpp | 59 +++++++------------ 4 files changed, 50 insertions(+), 44 deletions(-) diff --git a/src/world/Actor/BNpc.cpp b/src/world/Actor/BNpc.cpp index 2fb811a3..dffaf929 100644 --- a/src/world/Actor/BNpc.cpp +++ b/src/world/Actor/BNpc.cpp @@ -6,6 +6,7 @@ #include #include #include +#include #include "Forwards.h" #include "Action/Action.h" @@ -67,6 +68,8 @@ Sapphire::Entity::BNpc::BNpc( uint32_t id, BNpcTemplatePtr pTemplate, float posX m_spawnPos = m_pos; + m_timeOfDeath = 0; + m_maxHp = maxHp; m_maxMp = 200; m_hp = maxHp; @@ -135,6 +138,7 @@ void Sapphire::Entity::BNpc::spawn( PlayerPtr pTarget ) void Sapphire::Entity::BNpc::despawn( PlayerPtr pTarget ) { pTarget->freePlayerSpawnId( getId() ); + pTarget->queuePacket( makeActorControl143( m_id, DespawnZoneScreenMsg, 0x04, getId(), 0x01 ) ); } Sapphire::Entity::BNpcState Sapphire::Entity::BNpc::getState() const @@ -278,7 +282,7 @@ void Sapphire::Entity::BNpc::aggro( Sapphire::Entity::CharaPtr pChara ) if( pChara->isPlayer() ) { PlayerPtr tmpPlayer = pChara->getAsPlayer(); - tmpPlayer->queuePacket( makeActorControl142( getId(), ActorControlType::ToggleWeapon, 0, 1, 1 ) ); + tmpPlayer->queuePacket( makeActorControl142( getId(), ActorControlType::ToggleWeapon, 1, 1, 1 ) ); tmpPlayer->onMobAggro( getAsBNpc() ); } } @@ -291,6 +295,7 @@ void Sapphire::Entity::BNpc::deaggro( Sapphire::Entity::CharaPtr pChara ) if( pChara->isPlayer() ) { PlayerPtr tmpPlayer = pChara->getAsPlayer(); + tmpPlayer->queuePacket( makeActorControl142( getId(), ActorControlType::ToggleWeapon, 0, 1, 1 ) ); tmpPlayer->onMobDeaggro( getAsBNpc() ); } } @@ -301,11 +306,12 @@ void Sapphire::Entity::BNpc::update( int64_t currTime ) const uint8_t aggroRange = 8; const uint8_t maxDistanceToOrigin = 30; - if( m_status == ActorStatus::Dead ) - return; - switch( m_state ) { + case BNpcState::Dead: + case BNpcState::JustDied: + return; + case BNpcState::Retreat: { if( moveTo( m_spawnPos ) ) @@ -330,8 +336,6 @@ void Sapphire::Entity::BNpc::update( int64_t currTime ) if( distance < aggroRange && pClosestChara->isPlayer() ) aggro( pClosestChara ); - //if( distance < aggroRange && getbehavior() == 2 ) - // aggro( pClosestActor ); } } @@ -404,5 +408,16 @@ void Sapphire::Entity::BNpc::onDeath() setTargetId( INVALID_GAME_OBJECT_ID ); m_currentStance = Stance::Passive; m_state = BNpcState::Dead; + m_timeOfDeath = Util::getTimeSeconds(); hateListClear(); } + +uint32_t Sapphire::Entity::BNpc::getTimeOfDeath() const +{ + return m_timeOfDeath; +} + +void Sapphire::Entity::BNpc::setTimeOfDeath( uint32_t timeOfDeath ) +{ + m_timeOfDeath = timeOfDeath; +} diff --git a/src/world/Actor/BNpc.h b/src/world/Actor/BNpc.h index db0fb1f9..aed22678 100644 --- a/src/world/Actor/BNpc.h +++ b/src/world/Actor/BNpc.h @@ -83,6 +83,9 @@ namespace Sapphire::Entity void onDeath() override; + uint32_t getTimeOfDeath() const; + void setTimeOfDeath( uint32_t timeOfDeath); + private: uint32_t m_bNpcBaseId; uint32_t m_bNpcNameId; @@ -96,6 +99,8 @@ namespace Sapphire::Entity uint32_t m_displayFlags; uint8_t m_level; + uint32_t m_timeOfDeath; + Common::FFXIVARR_POSITION3 m_spawnPos; BNpcState m_state; diff --git a/src/world/Network/PacketWrappers/NpcSpawnPacket.h b/src/world/Network/PacketWrappers/NpcSpawnPacket.h index caa0d072..77d50e7e 100644 --- a/src/world/Network/PacketWrappers/NpcSpawnPacket.h +++ b/src/world/Network/PacketWrappers/NpcSpawnPacket.h @@ -4,6 +4,7 @@ #include #include #include +#include #include "Actor/Player.h" #include "Actor/BNpc.h" #include "Forwards.h" @@ -57,6 +58,8 @@ namespace Sapphire::Network::Packets::Server m_data.classJob = 0; + m_data.targetId = Common::INVALID_GAME_OBJECT_ID; + //m_data.u23 = 0x04; //m_data.u24 = 256; m_data.state = static_cast< uint8_t >( bnpc.getStatus() ); diff --git a/src/world/Territory/Zone.cpp b/src/world/Territory/Zone.cpp index 21817559..04be405e 100644 --- a/src/world/Territory/Zone.cpp +++ b/src/world/Territory/Zone.cpp @@ -381,49 +381,27 @@ bool Sapphire::Zone::checkWeather() void Sapphire::Zone::updateBNpcs( int64_t tickCount ) { - if( ( tickCount - m_lastMobUpdate ) > 250 ) - { - m_lastMobUpdate = tickCount; - uint32_t currTime = Sapphire::Util::getTimeSeconds(); + if( ( tickCount - m_lastMobUpdate ) <= 250 ) + return; - /*for( auto it3 = m_BattleNpcDeadMap.begin(); it3 != m_BattleNpcDeadMap.end(); ++it3 ) - { + m_lastMobUpdate = tickCount; + uint32_t currTime = Sapphire::Util::getTimeSeconds(); - Entity::BattleNpcPtr pBNpc = *it3; + for( auto entry : m_bNpcMap ) + { + Entity::BNpcPtr pBNpc = entry.second; - if( ( currTime - pBNpc->getTimeOfDeath() ) > 60 ) - { + if( !pBNpc ) + continue; - pBNpc->resetHp(); - pBNpc->resetMp(); - pBNpc->resetPos(); - pushActor( pBNpc ); + if( !pBNpc->isAlive() && currTime - pBNpc->getTimeOfDeath() > 10 ) + { + removeActor( pBNpc ); + break; + } - m_BattleNpcDeadMap.erase( it3 ); - - break; - } - }*/ - - - for( auto entry : m_bNpcMap ) - { - Entity::BNpcPtr pBNpc = entry.second; - - if( !pBNpc ) - continue; - - //if( !pBNpc->isAlive() && currTime - pBNpc->getTimeOfDeath() > ( 10 ) ) - //{ - // removeActor( pBNpc ); - // m_BattleNpcDeadMap.insert( pBNpc ); - // break; - //} - - pBNpc->update( tickCount ); - - } - } + pBNpc->update( tickCount ); + } } @@ -844,6 +822,11 @@ void Sapphire::Zone::updateSpawnPoints() pushActor( pBNpc ); } + else if( point->getLinkedBNpc() && !point->getLinkedBNpc()->isAlive() ) + { + point->setTimeOfDeath( Util::getTimeSeconds() ); + point->setLinkedBNpc( nullptr ); + } } }