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

Make sure to reinit DB -> Various small fixes and refactors

This commit is contained in:
Mordred 2019-01-17 23:54:47 +01:00
parent dd0610bdcc
commit 77c4403a2c
7 changed files with 318 additions and 25 deletions

View file

@ -251,13 +251,13 @@ bool Sapphire::Entity::Actor::isInRangeSet( ActorPtr pActor ) const
/*! \return ActorPtr of the closest actor in range, if none, nullptr */ /*! \return ActorPtr of the closest actor in range, if none, nullptr */
Sapphire::Entity::ActorPtr Sapphire::Entity::Actor::getClosestActor() Sapphire::Entity::CharaPtr Sapphire::Entity::Actor::getClosestChara()
{ {
if( m_inRangeActor.empty() ) if( m_inRangeActor.empty() )
// no actors in range, don't bother // no actors in range, don't bother
return nullptr; return nullptr;
ActorPtr tmpActor = nullptr; CharaPtr tmpActor = nullptr;
// arbitrary high number // arbitrary high number
float minDistance = 10000; float minDistance = 10000;
@ -270,7 +270,7 @@ Sapphire::Entity::ActorPtr Sapphire::Entity::Actor::getClosestActor()
if( distance < minDistance ) if( distance < minDistance )
{ {
minDistance = distance; minDistance = distance;
tmpActor = pCurAct; tmpActor = pCurAct->getAsChara();
} }
} }

View file

@ -91,7 +91,7 @@ namespace Sapphire::Entity
// check if another actor is in the actors in range set // check if another actor is in the actors in range set
bool isInRangeSet( ActorPtr pActor ) const; bool isInRangeSet( ActorPtr pActor ) const;
ActorPtr getClosestActor(); CharaPtr getClosestChara();
void sendToInRangeSet( Network::Packets::FFXIVPacketBasePtr pPacket, bool bToSelf = false ); void sendToInRangeSet( Network::Packets::FFXIVPacketBasePtr pPacket, bool bToSelf = false );

View file

@ -5,6 +5,7 @@
#include <utility> #include <utility>
#include <Network/CommonActorControl.h> #include <Network/CommonActorControl.h>
#include <Network/PacketWrappers/EffectPacket.h> #include <Network/PacketWrappers/EffectPacket.h>
#include <Network/PacketDef/Zone/ClientZoneDef.h>
#include "Forwards.h" #include "Forwards.h"
#include "Action/Action.h" #include "Action/Action.h"
@ -17,6 +18,7 @@
#include "Network/PacketWrappers/ActorControlPacket144.h" #include "Network/PacketWrappers/ActorControlPacket144.h"
#include "Network/PacketWrappers/UpdateHpMpTpPacket.h" #include "Network/PacketWrappers/UpdateHpMpTpPacket.h"
#include "Network/PacketWrappers/NpcSpawnPacket.h" #include "Network/PacketWrappers/NpcSpawnPacket.h"
#include "Network/PacketWrappers/MoveActorPacket.h"
#include "StatusEffect/StatusEffect.h" #include "StatusEffect/StatusEffect.h"
#include "Action/ActionCollision.h" #include "Action/ActionCollision.h"
@ -41,7 +43,7 @@ Sapphire::Entity::BNpc::BNpc( FrameworkPtr pFw ) :
} }
Sapphire::Entity::BNpc::BNpc( uint32_t id, BNpcTemplatePtr pTemplate, float posX, float posY, float posZ, float rot, Sapphire::Entity::BNpc::BNpc( uint32_t id, BNpcTemplatePtr pTemplate, float posX, float posY, float posZ, float rot,
uint8_t level, uint32_t maxHp, FrameworkPtr pFw ) : uint8_t level, uint32_t maxHp, ZonePtr pZone, FrameworkPtr pFw ) :
Npc( ObjKind::BattleNpc, pFw ) Npc( ObjKind::BattleNpc, pFw )
{ {
m_id = id; m_id = id;
@ -60,11 +62,17 @@ Sapphire::Entity::BNpc::BNpc( uint32_t id, BNpcTemplatePtr pTemplate, float posX
m_rot = rot; m_rot = rot;
m_level = level; m_level = level;
m_pCurrentZone = pZone;
m_spawnPos = m_pos;
m_maxHp = maxHp; m_maxHp = maxHp;
m_maxMp = 200; m_maxMp = 200;
m_hp = maxHp; m_hp = maxHp;
m_mp = 200; m_mp = 200;
m_state = BNpcState::Idle;
m_baseStats.max_hp = maxHp; m_baseStats.max_hp = maxHp;
m_baseStats.max_mp = 200; m_baseStats.max_mp = 200;
@ -121,3 +129,251 @@ void Sapphire::Entity::BNpc::spawn( PlayerPtr pTarget )
{ {
pTarget->queuePacket( std::make_shared< NpcSpawnPacket >( *getAsBNpc(), *pTarget ) ); pTarget->queuePacket( std::make_shared< NpcSpawnPacket >( *getAsBNpc(), *pTarget ) );
} }
Sapphire::Entity::BNpcState Sapphire::Entity::BNpc::getState() const
{
return m_state;
}
void Sapphire::Entity::BNpc::setState( BNpcState state )
{
m_state = state;
}
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
return true;
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();
return false;
}
void Sapphire::Entity::BNpc::sendPositionUpdate()
{
auto movePacket = std::make_shared< MoveActorPacket >( *getAsChara(), 0x3A, 0, 0, 0x5A );
sendToInRangeSet( movePacket );
}
void Sapphire::Entity::BNpc::hateListClear()
{
auto it = m_hateList.begin();
for( auto listEntry : m_hateList )
{
//if( isInRangeSet( listEntry->m_pActor ) )
//deaggro( listEntry->m_pActor );
}
m_hateList.clear();
}
Sapphire::Entity::ActorPtr Sapphire::Entity::BNpc::hateListGetHighest()
{
auto it = m_hateList.begin();
uint32_t maxHate = 0;
std::shared_ptr< HateListEntry > entry;
for( ; it != m_hateList.end(); ++it )
{
if( ( *it )->m_hateAmount > maxHate )
{
maxHate = ( *it )->m_hateAmount;
entry = *it;
}
}
if( entry && maxHate != 0 )
return entry->m_pActor;
return nullptr;
}
void Sapphire::Entity::BNpc::hateListAdd( Sapphire::Entity::ActorPtr pActor, int32_t hateAmount )
{
auto hateEntry = std::make_shared< HateListEntry >();
hateEntry->m_hateAmount = hateAmount;
hateEntry->m_pActor = pActor;
m_hateList.insert( hateEntry );
}
void Sapphire::Entity::BNpc::hateListUpdate( Sapphire::Entity::ActorPtr pActor, int32_t hateAmount )
{
for( auto listEntry : m_hateList )
{
if( listEntry->m_pActor == pActor )
{
listEntry->m_hateAmount += hateAmount;
return;
}
}
auto hateEntry = std::make_shared< HateListEntry >();
hateEntry->m_hateAmount = hateAmount;
hateEntry->m_pActor = pActor;
m_hateList.insert( hateEntry );
}
void Sapphire::Entity::BNpc::hateListRemove( Sapphire::Entity::ActorPtr pActor )
{
for( auto listEntry : m_hateList )
{
if( listEntry->m_pActor == pActor )
{
m_hateList.erase( listEntry );
if( pActor->isPlayer() )
{
PlayerPtr tmpPlayer = pActor->getAsPlayer();
//tmpPlayer->onMobDeaggro( getAsBattleNpc() );
}
return;
}
}
}
bool Sapphire::Entity::BNpc::hateListHasActor( Sapphire::Entity::ActorPtr pActor )
{
for( auto listEntry : m_hateList )
{
if( listEntry->m_pActor == pActor )
return true;
}
return false;
}
void Sapphire::Entity::BNpc::aggro( Sapphire::Entity::ActorPtr pActor )
{
m_lastAttack = Util::getTimeMs();
hateListUpdate( pActor, 1 );
changeTarget( pActor->getId() );
setStance( Stance::Active );
m_state = BNpcState::Combat;
if( pActor->isPlayer() )
{
PlayerPtr tmpPlayer = pActor->getAsPlayer();
tmpPlayer->queuePacket( makeActorControl142( getId(), ActorControlType::ToggleWeapon, 0, 1, 1 ) );
//tmpPlayer->onMobAggro( getAsBattleNpc() );
}
}
void Sapphire::Entity::BNpc::deaggro( Sapphire::Entity::ActorPtr pActor )
{
if( !hateListHasActor( pActor ) )
hateListRemove( pActor );
if( pActor->isPlayer() )
{
PlayerPtr tmpPlayer = pActor->getAsPlayer();
//tmpPlayer->onMobDeaggro( getAsBattleNpc() );
}
}
void Sapphire::Entity::BNpc::update( int64_t currTime )
{
switch( m_state )
{
case BNpcState::Retreat:
{
if( moveTo( m_spawnPos ) )
m_state = BNpcState::Idle;
}
break;
case BNpcState::Idle:
{
CharaPtr pClosestActor = getClosestChara();
if( ( pClosestActor != nullptr ) && pClosestActor->isAlive() )
{
auto distance = Util::distance( getPos().x, getPos().y, getPos().z,
pClosestActor->getPos().x,
pClosestActor->getPos().y,
pClosestActor->getPos().z );
if( distance < 8 && pClosestActor->isPlayer() )
aggro( pClosestActor );
//if( distance < 8 && getbehavior() == 2 )
// aggro( pClosestActor );
}
}
case BNpcState::Combat:
{
auto pActor = hateListGetHighest();
if( !pActor )
return;
auto pClosestActor = pActor->getAsChara();
auto distanceOrig = Util::distance( getPos().x, getPos().y, getPos().z,
m_spawnPos.x,
m_spawnPos.y,
m_spawnPos.z );
if( pClosestActor && !pClosestActor->isAlive() )
{
hateListRemove( pClosestActor );
pActor = hateListGetHighest();
if( pActor )
pClosestActor = pActor->getAsChara();
else
pClosestActor.reset();
}
if( pClosestActor != nullptr )
{
auto distance = Util::distance( getPos().x, getPos().y, getPos().z,
pClosestActor->getPos().x,
pClosestActor->getPos().y,
pClosestActor->getPos().z );
if( distanceOrig > 30 )
{
hateListClear();
changeTarget( INVALID_GAME_OBJECT_ID );
setStance( Stance::Passive );
//setOwner( nullptr );
m_state = BNpcState::Retreat;
break;
}
if( distance > 4 )
moveTo( pClosestActor->getPos() );
else
{
if( face( pClosestActor->getPos() ) )
sendPositionUpdate();
// in combat range. ATTACK!
autoAttack( pClosestActor );
}
}
else
{
changeTarget( INVALID_GAME_OBJECT_ID );
setStance( Stance::Passive );
//setOwner( nullptr );
m_state = BNpcState::Retreat;
}
}
}
}

View file

@ -13,6 +13,21 @@
namespace Sapphire::Entity namespace Sapphire::Entity
{ {
typedef struct
{
uint32_t m_hateAmount;
ActorPtr m_pActor;
} HateListEntry;
enum class BNpcState
{
Idle,
Combat,
Retreat,
JustDied,
Dead,
};
/*! /*!
\class BNpc \class BNpc
\brief Base class for all BNpcs \brief Base class for all BNpcs
@ -24,7 +39,7 @@ namespace Sapphire::Entity
public: public:
BNpc( FrameworkPtr pFw ); BNpc( FrameworkPtr pFw );
BNpc( uint32_t id, BNpcTemplatePtr pTemplate, float posX, float posY, float posZ, float rot, BNpc( uint32_t id, BNpcTemplatePtr pTemplate, float posX, float posY, float posZ, float rot,
uint8_t level, uint32_t maxHp, FrameworkPtr pFw ); uint8_t level, uint32_t maxHp, ZonePtr pZone,FrameworkPtr pFw );
virtual ~BNpc() override; virtual ~BNpc() override;
@ -43,6 +58,26 @@ namespace Sapphire::Entity
uint8_t getAggressionMode() const; uint8_t getAggressionMode() const;
// return true if it reached the position
bool moveTo( const Common::FFXIVARR_POSITION3& pos );
void sendPositionUpdate();
BNpcState getState() const;
void setState( BNpcState state );
void hateListClear();
ActorPtr hateListGetHighest();
void hateListAdd( ActorPtr pActor, int32_t hateAmount );
void hateListUpdate( ActorPtr pActor, int32_t hateAmount );
void hateListRemove( ActorPtr pActor );
bool hateListHasActor( ActorPtr pActor );
void aggro( ActorPtr pActor );
void deaggro( ActorPtr pActor );
void update( int64_t currTime ) override;
private: private:
uint32_t m_bNpcBaseId; uint32_t m_bNpcBaseId;
uint32_t m_bNpcNameId; uint32_t m_bNpcNameId;
@ -56,6 +91,11 @@ namespace Sapphire::Entity
uint32_t m_displayFlags; uint32_t m_displayFlags;
uint8_t m_level; uint8_t m_level;
Common::FFXIVARR_POSITION3 m_spawnPos;
BNpcState m_state;
std::set< std::shared_ptr< HateListEntry > > m_hateList;
}; };
} }

View file

@ -439,7 +439,7 @@ void Sapphire::World::Manager::DebugCommandMgr::add( char* data, Entity::Player&
player.getPos().y, player.getPos().y,
player.getPos().z, player.getPos().z,
player.getRot(), player.getRot(),
1, 1000, framework() ); 1, 1000, playerZone, framework() );

View file

@ -376,8 +376,7 @@ bool Sapphire::Zone::checkWeather()
return false; return false;
} }
/* void Sapphire::Zone::updateBNpcs( int64_t tickCount )
void Sapphire::Zone::updateBnpcs( int64_t tickCount )
{ {
if( ( tickCount - m_lastMobUpdate ) > 250 ) if( ( tickCount - m_lastMobUpdate ) > 250 )
{ {
@ -385,7 +384,7 @@ void Sapphire::Zone::updateBnpcs( int64_t tickCount )
m_lastMobUpdate = tickCount; m_lastMobUpdate = tickCount;
uint32_t currTime = static_cast< uint32_t >( time( nullptr ) ); uint32_t currTime = static_cast< uint32_t >( time( nullptr ) );
for( auto it3 = m_BattleNpcDeadMap.begin(); it3 != m_BattleNpcDeadMap.end(); ++it3 ) /*for( auto it3 = m_BattleNpcDeadMap.begin(); it3 != m_BattleNpcDeadMap.end(); ++it3 )
{ {
Entity::BattleNpcPtr pBNpc = *it3; Entity::BattleNpcPtr pBNpc = *it3;
@ -402,29 +401,29 @@ void Sapphire::Zone::updateBnpcs( int64_t tickCount )
break; break;
} }
} }*/
for( auto entry : m_BattleNpcMap ) for( auto entry : m_bNpcMap )
{ {
Entity::BattleNpcPtr pBNpc = entry.second; Entity::BNpcPtr pBNpc = entry.second;
if( !pBNpc ) if( !pBNpc )
continue; continue;
if( !pBNpc->isAlive() && currTime - pBNpc->getTimeOfDeath() > ( 10 ) ) //if( !pBNpc->isAlive() && currTime - pBNpc->getTimeOfDeath() > ( 10 ) )
{ //{
removeActor( pBNpc ); // removeActor( pBNpc );
m_BattleNpcDeadMap.insert( pBNpc ); // m_BattleNpcDeadMap.insert( pBNpc );
break; // break;
} //}
pBNpc->update( tickCount ); pBNpc->update( tickCount );
} }
} }
} }
*/
bool Sapphire::Zone::update( uint32_t currTime ) bool Sapphire::Zone::update( uint32_t currTime )
{ {
@ -434,7 +433,7 @@ bool Sapphire::Zone::update( uint32_t currTime )
bool changedWeather = checkWeather(); bool changedWeather = checkWeather();
updateSessions( changedWeather ); updateSessions( changedWeather );
//updateBnpcs( tickCount ); updateBNpcs( tickCount );
onUpdate( currTime ); onUpdate( currTime );
updateSpawnPoints(); updateSpawnPoints();
@ -832,8 +831,6 @@ void Sapphire::Zone::updateSpawnPoints()
continue; continue;
} }
uint32_t random = rand() % 20;
auto pBNpc = std::make_shared< Entity::BNpc >( getNextActorId(), auto pBNpc = std::make_shared< Entity::BNpc >( getNextActorId(),
bNpcTemplate, bNpcTemplate,
point->getPosX(), point->getPosX(),
@ -841,7 +838,7 @@ void Sapphire::Zone::updateSpawnPoints()
point->getPosZ(), point->getPosZ(),
dist( mt ), dist( mt ),
group.getLevel(), group.getLevel(),
group.getMaxHp(), m_pFw ); group.getMaxHp(), shared_from_this(), m_pFw );
point->setLinkedBNpc( pBNpc ); point->setLinkedBNpc( pBNpc );
pushActor( pBNpc ); pushActor( pBNpc );

View file

@ -142,7 +142,7 @@ namespace Sapphire
bool loadSpawnGroups(); bool loadSpawnGroups();
bool checkWeather(); bool checkWeather();
//void updateBnpcs( int64_t tickCount ); void updateBNpcs( int64_t tickCount );
bool update( uint32_t currTime ); bool update( uint32_t currTime );