From 5dd893a0c728572f8adf3a963e432fc6b08e28ea Mon Sep 17 00:00:00 2001 From: Rushi <44952533+Skyliegirl33@users.noreply.github.com> Date: Sat, 22 Jun 2024 07:31:50 +0200 Subject: [PATCH 1/2] Fix StatusEffect flags --- src/world/StatusEffect/StatusEffect.cpp | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/src/world/StatusEffect/StatusEffect.cpp b/src/world/StatusEffect/StatusEffect.cpp index 85f5497d8..0bb160a0f 100644 --- a/src/world/StatusEffect/StatusEffect.cpp +++ b/src/world/StatusEffect/StatusEffect.cpp @@ -57,13 +57,20 @@ Sapphire::StatusEffect::StatusEffect::StatusEffect( uint32_t id, Entity::CharaPt Util::eraseAll( m_name, ')' ); m_flag |= entry->data().Category; - m_flag |= static_cast< uint32_t >( entry->data().Forever ) << static_cast< uint32_t >( Common::StatusEffectFlag::Permanent ); - m_flag |= static_cast< uint32_t >( entry->data().CanOff ) << static_cast< uint32_t >( Common::StatusEffectFlag::CanStatusOff ); - m_flag |= static_cast< uint32_t >( entry->data().NotAction ) << static_cast< uint32_t >( Common::StatusEffectFlag::LockActions ); - m_flag |= static_cast< uint32_t >( entry->data().NotControl ) << static_cast< uint32_t >( Common::StatusEffectFlag::LockControl ); - m_flag |= static_cast< uint32_t >( entry->data().NotMove ) << static_cast< uint32_t >( Common::StatusEffectFlag::LockMovement ); - m_flag |= static_cast< uint32_t >( entry->data().NotLookAt ) << static_cast< uint32_t >( Common::StatusEffectFlag::IsGaze ); - m_flag |= static_cast< uint32_t >( entry->data().FcAction ) << static_cast< uint32_t >( Common::StatusEffectFlag::FcBuff ); + if( entry->data().Forever ) + m_flag |= static_cast< uint32_t >( Common::StatusEffectFlag::Permanent ); + if( entry->data().CanOff ) + m_flag |= static_cast< uint32_t >( Common::StatusEffectFlag::CanStatusOff ); + if( entry->data().NotAction ) + m_flag |= static_cast< uint32_t >( Common::StatusEffectFlag::LockActions ); + if( entry->data().NotControl ) + m_flag |= static_cast< uint32_t >( Common::StatusEffectFlag::LockControl ); + if( entry->data().NotMove ) + m_flag |= static_cast< uint32_t >( Common::StatusEffectFlag::LockMovement ); + if( entry->data().NotLookAt ) + m_flag |= static_cast< uint32_t >( Common::StatusEffectFlag::IsGaze ); + if( entry->data().FcAction ) + m_flag |= static_cast< uint32_t >( Common::StatusEffectFlag::FcBuff ); } From 0acff69b46f8e096aef3dd13bab65f72d6b5a428 Mon Sep 17 00:00:00 2001 From: Rushi <44952533+Skyliegirl33@users.noreply.github.com> Date: Wed, 26 Jun 2024 20:48:20 +0200 Subject: [PATCH 2/2] Add isFacingTarget and helper functions --- src/common/Util/UtilMath.cpp | 20 ++++++++++++++ src/common/Util/UtilMath.h | 8 ++++++ src/common/Vector3.cpp | 11 +++++++- src/common/Vector3.h | 2 ++ src/world/Actor/Chara.cpp | 20 ++++++++++++++ src/world/Actor/Chara.h | 4 +++ src/world/Manager/DebugCommandMgr.cpp | 40 +++++++++++++++++++++++++++ src/world/Manager/DebugCommandMgr.h | 2 ++ 8 files changed, 106 insertions(+), 1 deletion(-) diff --git a/src/common/Util/UtilMath.cpp b/src/common/Util/UtilMath.cpp index 6a162d64f..4d7410b53 100644 --- a/src/common/Util/UtilMath.cpp +++ b/src/common/Util/UtilMath.cpp @@ -143,3 +143,23 @@ float Util::trunc( float value, uint8_t digitsToRemain ) return std::floor( value * factor ) / factor; } + +float Util::length( const FFXIVARR_POSITION3& vec ) { + return std::sqrt( vec.x * vec.x + vec.y * vec.y + vec.z * vec.z ); +} + +FFXIVARR_POSITION3 Util::normalize( const FFXIVARR_POSITION3& vec ) { + float len = length( vec ); + if( len == 0 ) return FFXIVARR_POSITION3(); + return FFXIVARR_POSITION3{ vec.x / len, vec.y / len, vec.z / len }; +} + +float Util::dot( const FFXIVARR_POSITION3& vec1, const FFXIVARR_POSITION3& vec2 ) +{ + return vec1.x * vec2.x + vec1.y * vec2.y + vec1.z * vec2.z; +} + +FFXIVARR_POSITION3 Util::projectY( const FFXIVARR_POSITION3& vec ) +{ + return FFXIVARR_POSITION3{ vec.x, 0, vec.z }; +} \ No newline at end of file diff --git a/src/common/Util/UtilMath.h b/src/common/Util/UtilMath.h index 1f6ddd504..6ec655c65 100644 --- a/src/common/Util/UtilMath.h +++ b/src/common/Util/UtilMath.h @@ -44,6 +44,14 @@ namespace Sapphire::Common::Util FFXIVARR_POSITION3 transform( const FFXIVARR_POSITION3& vector, const Matrix33& matrix ); float eulerToDirection( const FFXIVARR_POSITION3& euler ); + + float length( const FFXIVARR_POSITION3& vec ); + + FFXIVARR_POSITION3 normalize( const FFXIVARR_POSITION3& vec ); + + float dot( const FFXIVARR_POSITION3& vec1, const FFXIVARR_POSITION3& vec2 ); + + FFXIVARR_POSITION3 projectY( const FFXIVARR_POSITION3& vec ); } #endif diff --git a/src/common/Vector3.cpp b/src/common/Vector3.cpp index a98c4fdeb..7f2bb3940 100644 --- a/src/common/Vector3.cpp +++ b/src/common/Vector3.cpp @@ -7,8 +7,17 @@ inline bool FFXIVARR_POSITION3::operator == ( const FFXIVARR_POSITION3& target ) return x == target.x && y == target.y && z == target.z; } +FFXIVARR_POSITION3 FFXIVARR_POSITION3::operator - ( const FFXIVARR_POSITION3& target ) const +{ + return FFXIVARR_POSITION3{ x - target.x, y - target.y, z - target.z }; +} inline bool Vector3::operator == ( const Vector3& target ) const { return x == target.x && y == target.y && z == target.z && reserve == target.reserve; -} \ No newline at end of file +} + +Vector3 Vector3::operator - ( const Vector3& target ) const +{ + return Vector3{ x - target.x, y - target.y, z - target.z }; +} diff --git a/src/common/Vector3.h b/src/common/Vector3.h index 1658aa76c..3ca47061b 100644 --- a/src/common/Vector3.h +++ b/src/common/Vector3.h @@ -8,6 +8,7 @@ namespace Sapphire::Common float y; float z; inline bool operator == ( const FFXIVARR_POSITION3& target ) const; + FFXIVARR_POSITION3 operator - ( const FFXIVARR_POSITION3& target ) const; }; struct Vector3 @@ -17,6 +18,7 @@ namespace Sapphire::Common float z; float reserve; inline bool operator == ( const Vector3& target ) const; + Vector3 operator - ( const Vector3& target ) const; }; struct Matrix33 diff --git a/src/world/Actor/Chara.cpp b/src/world/Actor/Chara.cpp index 2d6abf28d..9593b0450 100644 --- a/src/world/Actor/Chara.cpp +++ b/src/world/Actor/Chara.cpp @@ -813,6 +813,26 @@ float Chara::getModifier( Common::ParamModifier paramModifier ) const return result; } +// Compute forward direction based on rotation angle (assuming rotation around Z axis) +FFXIVARR_POSITION3 Chara::getForwardVector() const { + return Common::Util::normalize( FFXIVARR_POSITION3{ std::sin( getRot() ), 0, std::cos( getRot() ) } ); +} + +// Function to check if actor is facing target +bool Chara::isFacingTarget( const Chara& other, float threshold ) +{ + auto toActor = Common::Util::normalize( Common::Util::projectY( other.getPos() - getPos() ) ); + + auto forward = getForwardVector(); + + float dot = Common::Util::dot( forward, toActor ); + + // The threshold is used to determine how closely the actors need to be facing each other + // 1.0 means they need to be perfectly facing each other + // Lower values allow for some deviation + return dot >= threshold; +} + void Chara::onTick() { uint32_t thisTickDmg = 0; diff --git a/src/world/Actor/Chara.h b/src/world/Actor/Chara.h index 8ee157de0..212ea1de0 100644 --- a/src/world/Actor/Chara.h +++ b/src/world/Actor/Chara.h @@ -249,6 +249,10 @@ namespace Sapphire::Entity virtual void update( uint64_t tickCount ); + Common::FFXIVARR_POSITION3 getForwardVector() const; + + bool isFacingTarget( const Chara& other, float threshold = 0.95f ); + World::Action::ActionPtr getCurrentAction() const; void setCurrentAction( World::Action::ActionPtr pAction ); diff --git a/src/world/Manager/DebugCommandMgr.cpp b/src/world/Manager/DebugCommandMgr.cpp index 2442c679a..aaf583be8 100644 --- a/src/world/Manager/DebugCommandMgr.cpp +++ b/src/world/Manager/DebugCommandMgr.cpp @@ -80,6 +80,7 @@ DebugCommandMgr::DebugCommandMgr() registerCommand( "cf", &DebugCommandMgr::contentFinder, "Content-Finder", 1 ); registerCommand( "ew", &DebugCommandMgr::easyWarp, "Easy warping", 1 ); registerCommand( "reload", &DebugCommandMgr::hotReload, "Reloads a resource", 1 ); + registerCommand( "facing", &DebugCommandMgr::facing, "Checks if you are facing an actor", 1 ); } // clear all loaded commands @@ -1481,4 +1482,43 @@ void DebugCommandMgr::hotReload( char* data, Sapphire::Entity::Player& player, s { PlayerMgr::sendDebug( player, "Unknown sub command." ); } +} + +void DebugCommandMgr::facing( char* data, Sapphire::Entity::Player& player, std::shared_ptr< DebugCommand > command ) +{ + std::string subCommand; + std::string params = ""; + + // check if the command has parameters + std::string tmpCommand = std::string( data + command->getName().length() + 1 ); + + std::size_t pos = tmpCommand.find_first_of( ' ' ); + + if( pos != std::string::npos ) + // command has parameters, grab the first part + subCommand = tmpCommand.substr( 0, pos ); + else + // no subcommand given + subCommand = tmpCommand; + + if( command->getName().length() + 1 + pos + 1 < strlen( data ) ) + params = std::string( data + command->getName().length() + 1 + pos + 1 ); + + Logger::debug( "[{0}] subCommand: {1} params: {2}", player.getId(), subCommand, params ); + + float threshold = 0.95f; + sscanf( params.c_str(), "%f", &threshold ); + + if( player.getTargetId() != 0 ) + { + auto target = player.lookupTargetById( player.getTargetId() ); + + if( !target ) + return; + + if( auto bnpc = target->getAsBNpc() ) + { + PlayerMgr::sendDebug( player, "Player facing target {0}: {1}", bnpc->getLayoutId(), player.isFacingTarget( *bnpc->getAsChara(), threshold ) ); + } + } } \ No newline at end of file diff --git a/src/world/Manager/DebugCommandMgr.h b/src/world/Manager/DebugCommandMgr.h index 084b99b69..57552896d 100644 --- a/src/world/Manager/DebugCommandMgr.h +++ b/src/world/Manager/DebugCommandMgr.h @@ -65,6 +65,8 @@ namespace Sapphire::World::Manager void hotReload( char* data, Sapphire::Entity::Player& player, std::shared_ptr< DebugCommand > command ); + void facing( char* data, Sapphire::Entity::Player& player, std::shared_ptr< DebugCommand > command ); + }; } \ No newline at end of file