2018-08-29 21:40:59 +02:00
# include <Util/Util.h>
# include <Util/UtilMath.h>
# include <Network/PacketContainer.h>
# include <Exd/ExdDataGenerated.h>
# include <utility>
# include <Network/CommonActorControl.h>
2018-09-20 23:31:38 +02:00
# include <Network/PacketWrappers/EffectPacket.h>
2019-01-17 23:54:47 +01:00
# include <Network/PacketDef/Zone/ClientZoneDef.h>
2019-01-23 22:37:55 +01:00
# include <Logging/Logger.h>
2018-08-29 21:40:59 +02:00
# include "Forwards.h"
# include "Action/Action.h"
2018-12-01 00:27:16 +11:00
# include "Territory/Zone.h"
2018-08-29 21:40:59 +02:00
# include "Network/GameConnection.h"
# include "Network/PacketWrappers/ActorControlPacket142.h"
# include "Network/PacketWrappers/ActorControlPacket143.h"
# include "Network/PacketWrappers/ActorControlPacket144.h"
# include "Network/PacketWrappers/UpdateHpMpTpPacket.h"
2018-09-13 22:14:31 +02:00
# include "Network/PacketWrappers/NpcSpawnPacket.h"
2019-01-17 23:54:47 +01:00
# include "Network/PacketWrappers/MoveActorPacket.h"
2018-08-29 21:40:59 +02:00
# include "StatusEffect/StatusEffect.h"
# include "Action/ActionCollision.h"
2018-11-20 21:32:13 +01:00
# include "ServerMgr.h"
2018-08-29 21:40:59 +02:00
# include "Session.h"
# include "Math/CalcBattle.h"
# include "Chara.h"
# include "Player.h"
2018-08-29 22:03:10 +02:00
# include "BNpc.h"
2018-09-10 23:57:14 +02:00
# include "BNpcTemplate.h"
2018-12-01 00:27:16 +11:00
# include "Manager/TerritoryMgr.h"
2018-08-29 21:40:59 +02:00
# include "Common.h"
2019-01-23 19:23:49 +01:00
# include "Framework.h"
2019-01-21 15:15:28 +01:00
# include <Logging/Logger.h>
2019-01-23 19:23:49 +01:00
# include <Manager/NaviMgr.h>
2018-08-29 21:40:59 +02:00
2018-11-29 16:55:48 +01:00
using namespace Sapphire : : Common ;
using namespace Sapphire : : Network : : Packets ;
using namespace Sapphire : : Network : : Packets : : Server ;
using namespace Sapphire : : Network : : ActorControl ;
2018-08-29 21:40:59 +02:00
2018-12-29 00:53:52 +01:00
Sapphire : : Entity : : BNpc : : BNpc ( FrameworkPtr pFw ) :
Npc ( ObjKind : : BattleNpc , pFw )
2018-08-29 21:40:59 +02:00
{
}
2019-01-13 00:51:31 +01:00
Sapphire : : Entity : : BNpc : : BNpc ( uint32_t id , BNpcTemplatePtr pTemplate , float posX , float posY , float posZ , float rot ,
2019-01-17 23:54:47 +01:00
uint8_t level , uint32_t maxHp , ZonePtr pZone , FrameworkPtr pFw ) :
2018-12-29 00:53:52 +01:00
Npc ( ObjKind : : BattleNpc , pFw )
2018-09-10 23:57:14 +02:00
{
2019-01-13 00:51:31 +01:00
m_id = id ;
2018-09-10 23:57:14 +02:00
m_modelChara = pTemplate - > getModelChara ( ) ;
m_displayFlags = pTemplate - > getDisplayFlags ( ) ;
m_pose = pTemplate - > getPose ( ) ;
m_aggressionMode = pTemplate - > getAggressionMode ( ) ;
m_weaponMain = pTemplate - > getWeaponMain ( ) ;
m_weaponSub = pTemplate - > getWeaponSub ( ) ;
m_bNpcNameId = pTemplate - > getBNpcNameId ( ) ;
m_bNpcBaseId = pTemplate - > getBNpcBaseId ( ) ;
2018-09-13 22:14:31 +02:00
m_enemyType = pTemplate - > getEnemyType ( ) ;
m_pos . x = posX ;
m_pos . y = posY ;
m_pos . z = posZ ;
2019-01-13 00:51:31 +01:00
m_rot = rot ;
2018-09-13 22:14:31 +02:00
m_level = level ;
2019-01-20 00:20:35 +01:00
m_invincibilityType = InvincibilityNone ;
2018-09-13 22:14:31 +02:00
2019-01-17 23:54:47 +01:00
m_pCurrentZone = pZone ;
m_spawnPos = m_pos ;
2019-01-23 22:37:55 +01:00
m_timeOfDeath = 0 ;
2019-01-08 17:08:48 +01:00
m_maxHp = maxHp ;
2018-09-13 22:14:31 +02:00
m_maxMp = 200 ;
2019-01-08 17:08:48 +01:00
m_hp = maxHp ;
2018-09-13 22:14:31 +02:00
m_mp = 200 ;
2019-01-17 23:54:47 +01:00
m_state = BNpcState : : Idle ;
2019-01-20 23:49:43 +01:00
m_status = ActorStatus : : Idle ;
2019-01-17 23:54:47 +01:00
2019-01-08 17:08:48 +01:00
m_baseStats . max_hp = maxHp ;
2018-09-13 22:14:31 +02:00
m_baseStats . max_mp = 200 ;
2018-09-10 23:57:14 +02:00
memcpy ( m_customize , pTemplate - > getCustomize ( ) , sizeof ( m_customize ) ) ;
memcpy ( m_modelEquip , pTemplate - > getModelEquip ( ) , sizeof ( m_modelEquip ) ) ;
}
2018-11-29 16:55:48 +01:00
Sapphire : : Entity : : BNpc : : ~ BNpc ( )
2018-08-29 21:40:59 +02:00
{
}
2018-09-09 23:56:22 +02:00
2018-11-29 16:55:48 +01:00
uint8_t Sapphire : : Entity : : BNpc : : getAggressionMode ( ) const
2018-09-13 22:14:31 +02:00
{
return m_aggressionMode ;
}
2018-11-29 16:55:48 +01:00
uint8_t Sapphire : : Entity : : BNpc : : getEnemyType ( ) const
2018-09-13 22:14:31 +02:00
{
return m_enemyType ;
}
2018-11-29 16:55:48 +01:00
uint64_t Sapphire : : Entity : : BNpc : : getWeaponMain ( ) const
2018-09-09 23:56:22 +02:00
{
2018-09-13 22:14:31 +02:00
return m_weaponMain ;
}
2018-09-09 23:56:22 +02:00
2018-11-29 16:55:48 +01:00
uint64_t Sapphire : : Entity : : BNpc : : getWeaponSub ( ) const
2018-09-13 22:14:31 +02:00
{
return m_weaponSub ;
}
2018-11-29 16:55:48 +01:00
uint16_t Sapphire : : Entity : : BNpc : : getModelChara ( ) const
2018-09-13 22:14:31 +02:00
{
return m_modelChara ;
}
2018-11-29 16:55:48 +01:00
uint8_t Sapphire : : Entity : : BNpc : : getLevel ( ) const
2018-09-13 22:14:31 +02:00
{
return m_level ;
}
2018-11-29 16:55:48 +01:00
uint32_t Sapphire : : Entity : : BNpc : : getBNpcBaseId ( ) const
2018-09-13 22:14:31 +02:00
{
return m_bNpcBaseId ;
}
2018-11-29 16:55:48 +01:00
uint32_t Sapphire : : Entity : : BNpc : : getBNpcNameId ( ) const
2018-09-13 22:14:31 +02:00
{
return m_bNpcNameId ;
}
2018-11-29 16:55:48 +01:00
void Sapphire : : Entity : : BNpc : : spawn ( PlayerPtr pTarget )
2018-09-13 22:14:31 +02:00
{
2019-01-20 23:49:43 +01:00
pTarget - > queuePacket ( std : : make_shared < NpcSpawnPacket > ( * this , * pTarget ) ) ;
2018-09-26 03:32:43 -04:00
}
2019-01-17 23:54:47 +01:00
2019-01-19 17:50:33 +11:00
void Sapphire : : Entity : : BNpc : : despawn ( PlayerPtr pTarget )
{
pTarget - > freePlayerSpawnId ( getId ( ) ) ;
2019-01-23 22:37:55 +01:00
pTarget - > queuePacket ( makeActorControl143 ( m_id , DespawnZoneScreenMsg , 0x04 , getId ( ) , 0x01 ) ) ;
2019-01-19 17:50:33 +11:00
}
2019-01-17 23:54:47 +01:00
Sapphire : : Entity : : BNpcState Sapphire : : Entity : : BNpc : : getState ( ) const
{
return m_state ;
}
void Sapphire : : Entity : : BNpc : : setState ( BNpcState state )
{
m_state = state ;
}
2019-01-23 17:07:40 +01:00
void Sapphire : : Entity : : BNpc : : step ( )
{
if ( m_naviLastPath . empty ( ) )
// No path to track
return ;
if ( Util : : distance ( getPos ( ) . x , getPos ( ) . y , getPos ( ) . z , m_naviTarget . x , m_naviTarget . y , m_naviTarget . z ) < = 4 )
{
// Reached target
m_naviLastPath . clear ( ) ;
return ;
}
2019-01-23 21:36:26 +01:00
auto stepPos = m_naviLastPath [ m_naviPathStep ] ;
2019-01-23 17:07:40 +01:00
2019-01-23 17:42:09 +01:00
if ( Util : : distance ( getPos ( ) . x , getPos ( ) . y , getPos ( ) . z , stepPos . x , stepPos . y , stepPos . z ) < = 4 & & m_naviPathStep < m_naviLastPath . size ( ) - 1 )
2019-01-23 17:07:40 +01:00
{
// Reached step in path
m_naviPathStep + + ;
2019-01-23 21:36:26 +01:00
stepPos = m_naviLastPath [ m_naviPathStep ] ;
2019-01-23 17:07:40 +01:00
}
2019-01-23 17:42:09 +01:00
// This is probably not a good way to do it but works fine for now
2019-01-23 17:07:40 +01:00
float rot = Util : : calcAngFrom ( getPos ( ) . x , getPos ( ) . z , stepPos . x , stepPos . z ) ;
float newRot = PI - rot + ( PI / 2 ) ;
face ( stepPos ) ;
float angle = Util : : calcAngFrom ( getPos ( ) . x , getPos ( ) . z , stepPos . x , stepPos . z ) + PI ;
auto x = ( cosf ( angle ) * 1.1f ) ;
2019-01-23 17:42:09 +01:00
auto y = ( getPos ( ) . y + stepPos . y ) * 0.5f ; // Get speed from somewhere else?
2019-01-23 17:07:40 +01:00
auto z = ( sinf ( angle ) * 1.1f ) ;
Common : : FFXIVARR_POSITION3 newPos { getPos ( ) . x + x , y , getPos ( ) . z + z } ;
setPos ( newPos ) ;
setRot ( newRot ) ;
sendPositionUpdate ( ) ;
}
2019-01-17 23:54:47 +01:00
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 )
2019-01-23 17:07:40 +01:00
// Reached destination
2019-01-17 23:54:47 +01:00
return true ;
2019-01-23 17:07:40 +01:00
if ( m_naviTarget . x = = pos . x & & m_naviTarget . y = = pos . y & & m_naviTarget . z = = pos . z )
// Targets are the same
return false ;
2019-01-23 17:42:09 +01:00
// Check if we have to recalculate
if ( Util : : getTimeMs ( ) - m_naviLastUpdate > 500 )
2019-01-21 15:15:28 +01:00
{
2019-01-23 19:23:49 +01:00
auto pNaviMgr = m_pFw - > get < World : : Manager : : NaviMgr > ( ) ;
auto pNaviProvider = pNaviMgr - > getNaviProvider ( m_pCurrentZone - > getInternalName ( ) ) ;
2019-01-23 21:26:48 +01:00
if ( ! pNaviProvider )
2019-01-23 19:23:49 +01:00
{
Logger : : error ( " No NaviProvider for zone#{0} - {1} " , m_pCurrentZone - > getGuId ( ) , m_pCurrentZone - > getInternalName ( ) ) ;
return false ;
}
auto path = pNaviProvider - > findFollowPath ( m_pos , pos ) ;
2019-01-21 15:15:28 +01:00
2019-01-23 17:42:09 +01:00
if ( ! path . empty ( ) )
{
m_naviLastPath = path ;
m_naviTarget = pos ;
m_naviPathStep = 0 ;
m_naviLastUpdate = Util : : getTimeMs ( ) ;
}
else
{
2019-01-23 23:50:31 +01:00
Logger : : debug ( " No path found from x{0} y{1} z{2} to x{3} y{4} z{5} in {6} " , getPos ( ) . x , getPos ( ) . y , getPos ( ) . z , pos . x , pos . y , pos . z , m_pCurrentZone - > getInternalName ( ) ) ;
2019-01-23 17:42:09 +01:00
}
}
2019-01-21 02:42:47 +01:00
/*
2019-01-23 21:10:53 +01:00
float rot = Util : : calcAngFrom ( getPos ( ) . x , getPos ( ) . z , pos . x , pos . z ) ;
2019-01-17 23:54:47 +01:00
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 ( ) ;
2019-01-21 02:42:47 +01:00
*/
2019-01-17 23:54:47 +01:00
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 )
{
2019-01-19 01:15:17 +01:00
if ( isInRangeSet ( listEntry - > m_pChara ) )
deaggro ( listEntry - > m_pChara ) ;
2019-01-17 23:54:47 +01:00
}
m_hateList . clear ( ) ;
}
2019-01-19 01:15:17 +01:00
Sapphire : : Entity : : CharaPtr Sapphire : : Entity : : BNpc : : hateListGetHighest ( )
2019-01-17 23:54:47 +01:00
{
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 )
2019-01-19 01:15:17 +01:00
return entry - > m_pChara ;
2019-01-17 23:54:47 +01:00
return nullptr ;
}
2019-01-19 01:15:17 +01:00
void Sapphire : : Entity : : BNpc : : hateListAdd ( Sapphire : : Entity : : CharaPtr pChara , int32_t hateAmount )
2019-01-17 23:54:47 +01:00
{
auto hateEntry = std : : make_shared < HateListEntry > ( ) ;
hateEntry - > m_hateAmount = hateAmount ;
2019-01-19 01:15:17 +01:00
hateEntry - > m_pChara = pChara ;
2019-01-17 23:54:47 +01:00
m_hateList . insert ( hateEntry ) ;
}
2019-01-19 01:15:17 +01:00
void Sapphire : : Entity : : BNpc : : hateListUpdate ( Sapphire : : Entity : : CharaPtr pChara , int32_t hateAmount )
2019-01-17 23:54:47 +01:00
{
for ( auto listEntry : m_hateList )
{
2019-01-19 01:15:17 +01:00
if ( listEntry - > m_pChara = = pChara )
2019-01-17 23:54:47 +01:00
{
listEntry - > m_hateAmount + = hateAmount ;
return ;
}
}
auto hateEntry = std : : make_shared < HateListEntry > ( ) ;
hateEntry - > m_hateAmount = hateAmount ;
2019-01-19 01:15:17 +01:00
hateEntry - > m_pChara = pChara ;
2019-01-17 23:54:47 +01:00
m_hateList . insert ( hateEntry ) ;
}
2019-01-19 01:15:17 +01:00
void Sapphire : : Entity : : BNpc : : hateListRemove ( Sapphire : : Entity : : CharaPtr pChara )
2019-01-17 23:54:47 +01:00
{
for ( auto listEntry : m_hateList )
{
2019-01-19 01:15:17 +01:00
if ( listEntry - > m_pChara = = pChara )
2019-01-17 23:54:47 +01:00
{
m_hateList . erase ( listEntry ) ;
2019-01-19 01:15:17 +01:00
if ( pChara - > isPlayer ( ) )
2019-01-17 23:54:47 +01:00
{
2019-01-19 01:15:17 +01:00
PlayerPtr tmpPlayer = pChara - > getAsPlayer ( ) ;
2019-01-19 22:56:07 +01:00
tmpPlayer - > onMobDeaggro ( getAsBNpc ( ) ) ;
2019-01-17 23:54:47 +01:00
}
return ;
}
}
}
2019-01-19 01:15:17 +01:00
bool Sapphire : : Entity : : BNpc : : hateListHasActor ( Sapphire : : Entity : : CharaPtr pChara )
2019-01-17 23:54:47 +01:00
{
for ( auto listEntry : m_hateList )
{
2019-01-19 01:15:17 +01:00
if ( listEntry - > m_pChara = = pChara )
2019-01-17 23:54:47 +01:00
return true ;
}
return false ;
}
2019-01-19 01:15:17 +01:00
void Sapphire : : Entity : : BNpc : : aggro ( Sapphire : : Entity : : CharaPtr pChara )
2019-01-17 23:54:47 +01:00
{
m_lastAttack = Util : : getTimeMs ( ) ;
2019-01-19 01:15:17 +01:00
hateListUpdate ( pChara , 1 ) ;
2019-01-17 23:54:47 +01:00
2019-01-19 01:15:17 +01:00
changeTarget ( pChara - > getId ( ) ) ;
2019-01-17 23:54:47 +01:00
setStance ( Stance : : Active ) ;
m_state = BNpcState : : Combat ;
2019-01-19 01:15:17 +01:00
if ( pChara - > isPlayer ( ) )
2019-01-17 23:54:47 +01:00
{
2019-01-19 01:15:17 +01:00
PlayerPtr tmpPlayer = pChara - > getAsPlayer ( ) ;
2019-01-23 22:37:55 +01:00
tmpPlayer - > queuePacket ( makeActorControl142 ( getId ( ) , ActorControlType : : ToggleWeapon , 1 , 1 , 1 ) ) ;
2019-01-19 22:56:07 +01:00
tmpPlayer - > onMobAggro ( getAsBNpc ( ) ) ;
2019-01-17 23:54:47 +01:00
}
}
2019-01-19 01:15:17 +01:00
void Sapphire : : Entity : : BNpc : : deaggro ( Sapphire : : Entity : : CharaPtr pChara )
2019-01-17 23:54:47 +01:00
{
2019-01-19 01:15:17 +01:00
if ( ! hateListHasActor ( pChara ) )
hateListRemove ( pChara ) ;
2019-01-17 23:54:47 +01:00
2019-01-19 01:15:17 +01:00
if ( pChara - > isPlayer ( ) )
2019-01-17 23:54:47 +01:00
{
2019-01-19 01:15:17 +01:00
PlayerPtr tmpPlayer = pChara - > getAsPlayer ( ) ;
2019-01-23 22:37:55 +01:00
tmpPlayer - > queuePacket ( makeActorControl142 ( getId ( ) , ActorControlType : : ToggleWeapon , 0 , 1 , 1 ) ) ;
2019-01-19 22:56:07 +01:00
tmpPlayer - > onMobDeaggro ( getAsBNpc ( ) ) ;
2019-01-17 23:54:47 +01:00
}
}
void Sapphire : : Entity : : BNpc : : update ( int64_t currTime )
{
2019-01-19 01:15:17 +01:00
const uint8_t minActorDistance = 4 ;
const uint8_t aggroRange = 8 ;
2019-01-23 21:10:53 +01:00
const uint8_t maxDistanceToOrigin = 40 ;
2019-01-19 01:15:17 +01:00
2019-01-17 23:54:47 +01:00
switch ( m_state )
{
2019-01-23 22:37:55 +01:00
case BNpcState : : Dead :
case BNpcState : : JustDied :
2019-01-21 02:42:47 +01:00
return ;
2019-01-17 23:54:47 +01:00
case BNpcState : : Retreat :
{
if ( moveTo ( m_spawnPos ) )
m_state = BNpcState : : Idle ;
}
break ;
case BNpcState : : Idle :
{
2019-01-19 17:50:33 +11:00
// passive mobs should ignore players unless aggro'd
if ( m_aggressionMode = = 1 )
return ;
2019-01-19 01:15:17 +01:00
CharaPtr pClosestChara = getClosestChara ( ) ;
2019-01-17 23:54:47 +01:00
2019-01-19 01:15:17 +01:00
if ( pClosestChara & & pClosestChara - > isAlive ( ) )
2019-01-17 23:54:47 +01:00
{
auto distance = Util : : distance ( getPos ( ) . x , getPos ( ) . y , getPos ( ) . z ,
2019-01-19 01:15:17 +01:00
pClosestChara - > getPos ( ) . x ,
pClosestChara - > getPos ( ) . y ,
pClosestChara - > getPos ( ) . z ) ;
2019-01-17 23:54:47 +01:00
2019-01-19 01:15:17 +01:00
if ( distance < aggroRange & & pClosestChara - > isPlayer ( ) )
aggro ( pClosestChara ) ;
2019-01-17 23:54:47 +01:00
}
}
case BNpcState : : Combat :
{
2019-01-19 01:15:17 +01:00
auto pHatedActor = hateListGetHighest ( ) ;
if ( ! pHatedActor )
2019-01-17 23:54:47 +01:00
return ;
auto distanceOrig = Util : : distance ( getPos ( ) . x , getPos ( ) . y , getPos ( ) . z ,
m_spawnPos . x ,
m_spawnPos . y ,
m_spawnPos . z ) ;
2019-01-19 01:15:17 +01:00
if ( pHatedActor & & ! pHatedActor - > isAlive ( ) )
2019-01-17 23:54:47 +01:00
{
2019-01-19 01:15:17 +01:00
hateListRemove ( pHatedActor ) ;
pHatedActor = hateListGetHighest ( ) ;
2019-01-21 02:42:47 +01:00
}
2019-01-19 01:15:17 +01:00
if ( pHatedActor )
2019-01-17 23:54:47 +01:00
{
auto distance = Util : : distance ( getPos ( ) . x , getPos ( ) . y , getPos ( ) . z ,
2019-01-19 01:15:17 +01:00
pHatedActor - > getPos ( ) . x ,
pHatedActor - > getPos ( ) . y ,
pHatedActor - > getPos ( ) . z ) ;
2019-01-17 23:54:47 +01:00
2019-01-19 01:15:17 +01:00
if ( distanceOrig > maxDistanceToOrigin )
2019-01-17 23:54:47 +01:00
{
hateListClear ( ) ;
changeTarget ( INVALID_GAME_OBJECT_ID ) ;
setStance ( Stance : : Passive ) ;
//setOwner( nullptr );
m_state = BNpcState : : Retreat ;
break ;
}
2019-01-19 01:15:17 +01:00
if ( distance > minActorDistance )
moveTo ( pHatedActor - > getPos ( ) ) ;
2019-01-17 23:54:47 +01:00
else
{
2019-01-19 01:15:17 +01:00
if ( face ( pHatedActor - > getPos ( ) ) )
2019-01-17 23:54:47 +01:00
sendPositionUpdate ( ) ;
// in combat range. ATTACK!
2019-01-19 01:15:17 +01:00
autoAttack ( pHatedActor ) ;
2019-01-17 23:54:47 +01:00
}
}
2019-01-21 02:42:47 +01:00
else
{
2019-01-17 23:54:47 +01:00
changeTarget ( INVALID_GAME_OBJECT_ID ) ;
setStance ( Stance : : Passive ) ;
//setOwner( nullptr );
m_state = BNpcState : : Retreat ;
}
}
}
2019-01-23 17:07:40 +01:00
step ( ) ;
2019-01-17 23:54:47 +01:00
}
2019-01-20 13:36:34 +01:00
void Sapphire : : Entity : : BNpc : : onActionHostile ( Sapphire : : Entity : : CharaPtr pSource )
{
if ( ! hateListGetHighest ( ) )
aggro ( pSource ) ;
//if( !getClaimer() )
// setOwner( pSource->getAsPlayer() );
}
void Sapphire : : Entity : : BNpc : : onDeath ( )
{
setTargetId ( INVALID_GAME_OBJECT_ID ) ;
m_currentStance = Stance : : Passive ;
m_state = BNpcState : : Dead ;
2019-01-23 22:37:55 +01:00
m_timeOfDeath = Util : : getTimeSeconds ( ) ;
2019-01-20 13:36:34 +01:00
hateListClear ( ) ;
}
2019-01-23 22:37:55 +01:00
uint32_t Sapphire : : Entity : : BNpc : : getTimeOfDeath ( ) const
{
return m_timeOfDeath ;
}
void Sapphire : : Entity : : BNpc : : setTimeOfDeath ( uint32_t timeOfDeath )
{
m_timeOfDeath = timeOfDeath ;
}