2023-03-20 10:29:56 +01:00
|
|
|
#include "StateCombat.h"
|
|
|
|
#include "Actor/BNpc.h"
|
|
|
|
#include "Logging/Logger.h"
|
|
|
|
#include <Service.h>
|
|
|
|
|
|
|
|
#include <Manager/TerritoryMgr.h>
|
|
|
|
#include <Territory/Territory.h>
|
|
|
|
#include <Navi/NaviProvider.h>
|
|
|
|
|
|
|
|
using namespace Sapphire::World;
|
|
|
|
|
|
|
|
void AI::Fsm::StateCombat::onUpdate( Entity::BNpc& bnpc, uint64_t tickCount )
|
|
|
|
{
|
|
|
|
|
|
|
|
auto& teriMgr = Common::Service< World::Manager::TerritoryMgr >::ref();
|
|
|
|
auto pZone = teriMgr.getTerritoryByGuId( bnpc.getTerritoryId() );
|
|
|
|
auto pNaviProvider = pZone->getNaviProvider();
|
|
|
|
|
2025-01-04 23:15:50 +01:00
|
|
|
bool hasQueuedAction = bnpc.checkAction();
|
|
|
|
|
2023-03-20 10:29:56 +01:00
|
|
|
auto pHatedActor = bnpc.hateListGetHighest();
|
|
|
|
if( !pHatedActor )
|
|
|
|
return;
|
|
|
|
|
|
|
|
pNaviProvider->updateAgentParameters( bnpc );
|
|
|
|
|
|
|
|
auto distanceOrig = Common::Util::distance( bnpc.getPos(), bnpc.getSpawnPos() );
|
|
|
|
|
|
|
|
if( !pHatedActor->isAlive() || bnpc.getTerritoryId() != pHatedActor->getTerritoryId() )
|
|
|
|
{
|
|
|
|
bnpc.hateListRemove( pHatedActor );
|
|
|
|
pHatedActor = bnpc.hateListGetHighest();
|
|
|
|
}
|
|
|
|
|
|
|
|
if( !pHatedActor )
|
|
|
|
return;
|
|
|
|
|
|
|
|
auto distance = Common::Util::distance( bnpc.getPos(), pHatedActor->getPos() );
|
|
|
|
|
|
|
|
if( !bnpc.hasFlag( Entity::NoDeaggro ) )
|
|
|
|
{
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2025-01-07 22:54:53 +01:00
|
|
|
if( !hasQueuedAction && !bnpc.hasFlag( Entity::Immobile ) && distance > ( bnpc.getNaviTargetReachedDistance() + pHatedActor->getRadius() ) )
|
2023-03-20 10:29:56 +01:00
|
|
|
{
|
2025-01-07 22:54:53 +01:00
|
|
|
|
2023-03-20 10:29:56 +01:00
|
|
|
if( pNaviProvider )
|
|
|
|
pNaviProvider->setMoveTarget( bnpc, pHatedActor->getPos() );
|
|
|
|
|
|
|
|
bnpc.moveTo( *pHatedActor );
|
|
|
|
}
|
|
|
|
|
2024-06-25 17:41:14 +01:00
|
|
|
pNaviProvider->syncPosToChara( bnpc );
|
2023-03-20 10:29:56 +01:00
|
|
|
|
2024-06-26 20:44:36 +01:00
|
|
|
if( distance < ( bnpc.getNaviTargetReachedDistance() + pHatedActor->getRadius() ) )
|
2023-03-20 10:29:56 +01:00
|
|
|
{
|
2024-06-26 20:44:36 +01:00
|
|
|
// todo: dont turn if facing
|
2024-06-25 17:41:14 +01:00
|
|
|
if( !bnpc.hasFlag( Entity::TurningDisabled ) )
|
|
|
|
bnpc.face( pHatedActor->getPos() );
|
2023-03-20 10:29:56 +01:00
|
|
|
|
2025-01-04 23:15:50 +01:00
|
|
|
if( !hasQueuedAction )
|
2023-03-20 10:29:56 +01:00
|
|
|
bnpc.processGambits( tickCount );
|
|
|
|
|
|
|
|
// in combat range. ATTACK!
|
2024-06-25 17:41:14 +01:00
|
|
|
if( !bnpc.hasFlag( Entity::BNpcFlag::AutoAttackDisabled ) )
|
|
|
|
bnpc.autoAttack( pHatedActor );
|
2023-03-20 10:29:56 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
void AI::Fsm::StateCombat::onEnter( Entity::BNpc& bnpc )
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
void AI::Fsm::StateCombat::onExit( Entity::BNpc& bnpc )
|
|
|
|
{
|
|
|
|
bnpc.hateListClear();
|
|
|
|
bnpc.changeTarget( Common::INVALID_GAME_OBJECT_ID64 );
|
|
|
|
bnpc.setStance( Common::Stance::Passive );
|
|
|
|
bnpc.setOwner( nullptr );
|
|
|
|
}
|
|
|
|
|