1
Fork 0
mirror of https://github.com/SapphireServer/Sapphire.git synced 2025-04-25 22:17: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 */
Sapphire::Entity::ActorPtr Sapphire::Entity::Actor::getClosestActor()
Sapphire::Entity::CharaPtr Sapphire::Entity::Actor::getClosestChara()
{
if( m_inRangeActor.empty() )
// no actors in range, don't bother
return nullptr;
ActorPtr tmpActor = nullptr;
CharaPtr tmpActor = nullptr;
// arbitrary high number
float minDistance = 10000;
@ -270,7 +270,7 @@ Sapphire::Entity::ActorPtr Sapphire::Entity::Actor::getClosestActor()
if( distance < minDistance )
{
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
bool isInRangeSet( ActorPtr pActor ) const;
ActorPtr getClosestActor();
CharaPtr getClosestChara();
void sendToInRangeSet( Network::Packets::FFXIVPacketBasePtr pPacket, bool bToSelf = false );

View file

@ -5,6 +5,7 @@
#include <utility>
#include <Network/CommonActorControl.h>
#include <Network/PacketWrappers/EffectPacket.h>
#include <Network/PacketDef/Zone/ClientZoneDef.h>
#include "Forwards.h"
#include "Action/Action.h"
@ -17,6 +18,7 @@
#include "Network/PacketWrappers/ActorControlPacket144.h"
#include "Network/PacketWrappers/UpdateHpMpTpPacket.h"
#include "Network/PacketWrappers/NpcSpawnPacket.h"
#include "Network/PacketWrappers/MoveActorPacket.h"
#include "StatusEffect/StatusEffect.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,
uint8_t level, uint32_t maxHp, FrameworkPtr pFw ) :
uint8_t level, uint32_t maxHp, ZonePtr pZone, FrameworkPtr pFw ) :
Npc( ObjKind::BattleNpc, pFw )
{
m_id = id;
@ -60,11 +62,17 @@ Sapphire::Entity::BNpc::BNpc( uint32_t id, BNpcTemplatePtr pTemplate, float posX
m_rot = rot;
m_level = level;
m_pCurrentZone = pZone;
m_spawnPos = m_pos;
m_maxHp = maxHp;
m_maxMp = 200;
m_hp = maxHp;
m_mp = 200;
m_state = BNpcState::Idle;
m_baseStats.max_hp = maxHp;
m_baseStats.max_mp = 200;
@ -121,3 +129,251 @@ void Sapphire::Entity::BNpc::spawn( PlayerPtr 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
{
typedef struct
{
uint32_t m_hateAmount;
ActorPtr m_pActor;
} HateListEntry;
enum class BNpcState
{
Idle,
Combat,
Retreat,
JustDied,
Dead,
};
/*!
\class BNpc
\brief Base class for all BNpcs
@ -24,7 +39,7 @@ namespace Sapphire::Entity
public:
BNpc( FrameworkPtr pFw );
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;
@ -43,6 +58,26 @@ namespace Sapphire::Entity
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:
uint32_t m_bNpcBaseId;
uint32_t m_bNpcNameId;
@ -56,6 +91,11 @@ namespace Sapphire::Entity
uint32_t m_displayFlags;
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().z,
player.getRot(),
1, 1000, framework() );
1, 1000, playerZone, framework() );

View file

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

View file

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