From 9b2ebd5d3ee35ab2213d96182137e72aeaaa7de7 Mon Sep 17 00:00:00 2001 From: Kooper Date: Sat, 19 Jul 2025 18:47:02 +0200 Subject: [PATCH 1/6] Fixed deaggro function to now remove entities from aggro list (without crashing the server) --- src/world/AI/Fsm/StateCombat.cpp | 5 +++++ src/world/Actor/BNpc.cpp | 32 +++++++++++++++++++------------- 2 files changed, 24 insertions(+), 13 deletions(-) diff --git a/src/world/AI/Fsm/StateCombat.cpp b/src/world/AI/Fsm/StateCombat.cpp index 5bcefd58..4fd020a0 100644 --- a/src/world/AI/Fsm/StateCombat.cpp +++ b/src/world/AI/Fsm/StateCombat.cpp @@ -48,6 +48,11 @@ void AI::Fsm::StateCombat::onUpdate( Entity::BNpc& bnpc, uint64_t tickCount ) bnpc.moveTo( *pHatedActor ); } + if (bnpc.hasFlag(Entity::Immobile) && distance > 30.0f ) + { + bnpc.deaggro( pHatedActor ); + } + if( pNaviProvider->syncPosToChara( bnpc ) ) bnpc.sendPositionUpdate(); diff --git a/src/world/Actor/BNpc.cpp b/src/world/Actor/BNpc.cpp index ca796d7f..481c52b5 100644 --- a/src/world/Actor/BNpc.cpp +++ b/src/world/Actor/BNpc.cpp @@ -447,7 +447,10 @@ void BNpc::hateListClear() for( auto& listEntry : m_hateList ) { if( isInRangeSet( listEntry->m_pChara ) ) - deaggro( listEntry->m_pChara ); + { + if( listEntry->m_pChara->isPlayer() ) + notifyPlayerDeaggro( listEntry->m_pChara ) + } } m_hateList.clear(); } @@ -623,22 +626,25 @@ void BNpc::aggro( const Sapphire::Entity::CharaPtr& pChara ) void BNpc::deaggro( const CharaPtr& pChara ) { - if( !hateListHasActor( pChara ) ) + if( hateListHasActor( pChara ) ) hateListRemove( pChara ); if( pChara->isPlayer() ) - { - PlayerPtr tmpPlayer = pChara->getAsPlayer(); - Network::Util::Packet::sendActorControl( getInRangePlayerIds(), getId(), ToggleWeapon, 0, 1, 1 ); - Network::Util::Packet::sendActorControl( getInRangePlayerIds(), getId(), SetBattle ); - tmpPlayer->onMobDeaggro( *this ); + notifyPlayerDeaggro(pChara) +} - if( getTriggerOwnerId() == pChara->getId() ) - { - auto& scriptMgr = Common::Service< Scripting::ScriptMgr >::ref(); - auto bnpc = *getAsBNpc(); - scriptMgr.onTriggerOwnerDeaggro( *tmpPlayer, bnpc ); - } +void BNpc::notifyPlayerDeaggro(const CharaPtr& pChara) +{ + PlayerPtr tmpPlayer = pChara->getAsPlayer(); + Network::Util::Packet::sendActorControl( getInRangePlayerIds(), getId(), ToggleWeapon, 0, 1, 1 ); + Network::Util::Packet::sendActorControl( getInRangePlayerIds(), getId(), SetBattle ); + tmpPlayer->onMobDeaggro( *this ); + + if( getTriggerOwnerId() == pChara->getId() ) + { + auto& scriptMgr = Common::Service< Scripting::ScriptMgr >::ref(); + auto bnpc = *getAsBNpc(); + scriptMgr.onTriggerOwnerDeaggro( *tmpPlayer, bnpc ); } } From cfa81f0df51a283c8590abeddcd7958c5b36cf21 Mon Sep 17 00:00:00 2001 From: Kooper Date: Sat, 19 Jul 2025 19:44:27 +0200 Subject: [PATCH 2/6] Code compiles now... --- src/world/Actor/BNpc.cpp | 4 ++-- src/world/Actor/BNpc.h | 1 + 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/world/Actor/BNpc.cpp b/src/world/Actor/BNpc.cpp index 481c52b5..26313ac3 100644 --- a/src/world/Actor/BNpc.cpp +++ b/src/world/Actor/BNpc.cpp @@ -449,7 +449,7 @@ void BNpc::hateListClear() if( isInRangeSet( listEntry->m_pChara ) ) { if( listEntry->m_pChara->isPlayer() ) - notifyPlayerDeaggro( listEntry->m_pChara ) + BNpc::notifyPlayerDeaggro( listEntry->m_pChara ); } } m_hateList.clear(); @@ -630,7 +630,7 @@ void BNpc::deaggro( const CharaPtr& pChara ) hateListRemove( pChara ); if( pChara->isPlayer() ) - notifyPlayerDeaggro(pChara) + notifyPlayerDeaggro( pChara ); } void BNpc::notifyPlayerDeaggro(const CharaPtr& pChara) diff --git a/src/world/Actor/BNpc.h b/src/world/Actor/BNpc.h index 7076ae6e..f07062fc 100644 --- a/src/world/Actor/BNpc.h +++ b/src/world/Actor/BNpc.h @@ -115,6 +115,7 @@ namespace Sapphire::Entity void aggro( const CharaPtr& pChara ); void deaggro( const CharaPtr& pChara ); + void notifyPlayerDeaggro( const CharaPtr& pChara ); void update( uint64_t tickCount ) override; void onTick() override; From b8efc8f8dcd5209331e5e4389d462cae4f2773e9 Mon Sep 17 00:00:00 2001 From: Kooper Date: Sat, 19 Jul 2025 20:57:08 +0200 Subject: [PATCH 3/6] Deaggro when outranging gets higher priority --- src/world/AI/Fsm/StateCombat.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/world/AI/Fsm/StateCombat.cpp b/src/world/AI/Fsm/StateCombat.cpp index 4fd020a0..9990007c 100644 --- a/src/world/AI/Fsm/StateCombat.cpp +++ b/src/world/AI/Fsm/StateCombat.cpp @@ -35,6 +35,11 @@ void AI::Fsm::StateCombat::onUpdate( Entity::BNpc& bnpc, uint64_t tickCount ) auto distance = Common::Util::distance( bnpc.getPos(), pHatedActor->getPos() ); + if( bnpc.hasFlag( Entity::Immobile ) && distance > 30.0f ) + { + bnpc.deaggro( pHatedActor ); + } + if( !bnpc.hasFlag( Entity::NoDeaggro ) ) { @@ -48,11 +53,6 @@ void AI::Fsm::StateCombat::onUpdate( Entity::BNpc& bnpc, uint64_t tickCount ) bnpc.moveTo( *pHatedActor ); } - if (bnpc.hasFlag(Entity::Immobile) && distance > 30.0f ) - { - bnpc.deaggro( pHatedActor ); - } - if( pNaviProvider->syncPosToChara( bnpc ) ) bnpc.sendPositionUpdate(); From 12bda0e38e4432c95f4dec2c44a66e02fdef4aa3 Mon Sep 17 00:00:00 2001 From: Kooper Date: Sat, 19 Jul 2025 22:10:47 +0200 Subject: [PATCH 4/6] small refactor --- src/world/Actor/BNpc.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/world/Actor/BNpc.cpp b/src/world/Actor/BNpc.cpp index 26313ac3..8e2bd54d 100644 --- a/src/world/Actor/BNpc.cpp +++ b/src/world/Actor/BNpc.cpp @@ -449,7 +449,7 @@ void BNpc::hateListClear() if( isInRangeSet( listEntry->m_pChara ) ) { if( listEntry->m_pChara->isPlayer() ) - BNpc::notifyPlayerDeaggro( listEntry->m_pChara ); + notifyPlayerDeaggro( listEntry->m_pChara ); } } m_hateList.clear(); From ccbf6bea61eaf0982ca90f2bc4d27960bb4206d2 Mon Sep 17 00:00:00 2001 From: Kooper Date: Mon, 21 Jul 2025 19:58:30 +0200 Subject: [PATCH 5/6] Immobile BNpcs don't deaggro anymore when having the "NoDeaggro" flag --- src/world/AI/Fsm/StateCombat.cpp | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/src/world/AI/Fsm/StateCombat.cpp b/src/world/AI/Fsm/StateCombat.cpp index 9990007c..78e1463f 100644 --- a/src/world/AI/Fsm/StateCombat.cpp +++ b/src/world/AI/Fsm/StateCombat.cpp @@ -35,14 +35,13 @@ void AI::Fsm::StateCombat::onUpdate( Entity::BNpc& bnpc, uint64_t tickCount ) auto distance = Common::Util::distance( bnpc.getPos(), pHatedActor->getPos() ); - if( bnpc.hasFlag( Entity::Immobile ) && distance > 30.0f ) - { - bnpc.deaggro( pHatedActor ); - } - + // All possibilities to automatically lose aggro go here if( !bnpc.hasFlag( Entity::NoDeaggro ) ) { - + if( bnpc.hasFlag( Entity::Immobile ) && distance > 30.0f ) + { + bnpc.deaggro( pHatedActor ); + } } if( !bnpc.hasFlag( Entity::Immobile ) && distance > ( bnpc.getNaviTargetReachedDistance() + pHatedActor->getRadius() ) ) From a181b4ac4a7518c69302b86735dab9343c7078d0 Mon Sep 17 00:00:00 2001 From: Kooper Date: Mon, 21 Jul 2025 20:33:20 +0200 Subject: [PATCH 6/6] Deaggro range changed to 40y after testing --- src/world/AI/Fsm/StateCombat.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/world/AI/Fsm/StateCombat.cpp b/src/world/AI/Fsm/StateCombat.cpp index 78e1463f..211f645c 100644 --- a/src/world/AI/Fsm/StateCombat.cpp +++ b/src/world/AI/Fsm/StateCombat.cpp @@ -38,7 +38,7 @@ void AI::Fsm::StateCombat::onUpdate( Entity::BNpc& bnpc, uint64_t tickCount ) // All possibilities to automatically lose aggro go here if( !bnpc.hasFlag( Entity::NoDeaggro ) ) { - if( bnpc.hasFlag( Entity::Immobile ) && distance > 30.0f ) + if( bnpc.hasFlag( Entity::Immobile ) && distance > 40.0f ) { bnpc.deaggro( pHatedActor ); }