diff --git a/src/common/Network/CommonActorControl.h b/src/common/Network/CommonActorControl.h index ee3b19f2..fbf12af1 100644 --- a/src/common/Network/CommonActorControl.h +++ b/src/common/Network/CommonActorControl.h @@ -186,6 +186,7 @@ namespace Sapphire::Network::ActorControl RelicInfuseMsg = 0x179, + /*! * Sent as result of an aetherial reduction. * param1 = Reduced item ID + 500 000 (idk what this 500 000 is but it's always here no matter what) @@ -206,6 +207,7 @@ namespace Sapphire::Network::ActorControl SetTitle = 0x1F4, + SetHateLetter = 0x1F7, SetStatusIcon = 0x1F8, LimitBreakGauge = 0x1F9, // Max level, amount, build type (chop sound), lb type(0=pve lb 1=pvp lb) SetHomepoint = 0x1FB, diff --git a/src/common/Network/PacketDef/Zone/ServerZoneDef.h b/src/common/Network/PacketDef/Zone/ServerZoneDef.h index 0796bd7a..00664937 100644 --- a/src/common/Network/PacketDef/Zone/ServerZoneDef.h +++ b/src/common/Network/PacketDef/Zone/ServerZoneDef.h @@ -645,7 +645,7 @@ namespace Sapphire::Network::Packets::WorldPackets::Server uint16_t DirTarget; uint64_t Target; uint32_t BallistaEntityId; - Common::CalcResult CalcResult[1]; + Common::CalcResult CalcResult; }; struct MountStruct diff --git a/src/world/Action/EffectBuilder.cpp b/src/world/Action/EffectBuilder.cpp index e5ab8633..9b1f1c65 100644 --- a/src/world/Action/EffectBuilder.cpp +++ b/src/world/Action/EffectBuilder.cpp @@ -4,6 +4,7 @@ #include #include +#include #include @@ -171,7 +172,7 @@ std::shared_ptr< FFXIVPacketBase > EffectBuilder::buildNextEffectPacket( uint32_ auto seq = m_sourceChara->getCurrentTerritory()->getNextEffectSequence(); - auto effectPacket = std::make_shared< EffectPacket >( m_sourceChara->getId(), firstResult->getTarget()->getId(), m_actionId ); + auto effectPacket = std::make_shared< EffectPacket1 >( m_sourceChara->getId(), firstResult->getTarget()->getId(), m_actionId ); effectPacket->setRotation( Common::Util::floatToUInt16Rot( m_sourceChara->getRot() ) ); effectPacket->setSequence( seq, m_sequence ); diff --git a/src/world/Actor/BNpc.cpp b/src/world/Actor/BNpc.cpp index e9f648cf..08eb7ade 100644 --- a/src/world/Actor/BNpc.cpp +++ b/src/world/Actor/BNpc.cpp @@ -5,6 +5,7 @@ #include #include #include +#include #include #include @@ -361,8 +362,9 @@ bool Sapphire::Entity::BNpc::moveTo( const FFXIVARR_POSITION3& pos ) } auto pos1 = pNaviProvider->getMovePos( *this ); + auto distance = Util::distance( pos1, pos ); - if( Util::distance( pos1, pos ) < getNaviTargetReachedDistance() ) + if( distance < getNaviTargetReachedDistance() ) { // Reached destination face( pos ); @@ -374,6 +376,10 @@ bool Sapphire::Entity::BNpc::moveTo( const FFXIVARR_POSITION3& pos ) m_pCurrentTerritory->updateActorPosition( *this ); face( pos ); + if( distance > 2.0f ) + face( { ( pos.x - pos1.x ) + pos.x, 1.0f, ( pos.z - pos1.z ) + pos.z } ); + else + face( pos ); setPos( pos1 ); sendPositionUpdate(); return false; @@ -391,8 +397,9 @@ bool Sapphire::Entity::BNpc::moveTo( const Entity::Chara& targetChara ) } auto pos1 = pNaviProvider->getMovePos( *this ); + auto distance = Util::distance( pos1, targetChara.getPos() ); - if( Util::distance( pos1, targetChara.getPos() ) <= ( getNaviTargetReachedDistance() + targetChara.getRadius() ) ) + if( distance <= ( getNaviTargetReachedDistance() + targetChara.getRadius() ) ) { // Reached destination face( targetChara.getPos() ); @@ -404,7 +411,10 @@ bool Sapphire::Entity::BNpc::moveTo( const Entity::Chara& targetChara ) } m_pCurrentTerritory->updateActorPosition( *this ); - face( { ( pos1.x - getPos().x ) + pos1.x, 1, (pos1.z - getPos().z ) + pos1.z } ); + if( distance > 2.0f ) + face( { ( pos1.x - getPos().x ) + pos1.x, 1.0f, ( pos1.z - getPos().z ) + pos1.z } ); + else + face( targetChara.getPos() ); setPos( pos1 ); sendPositionUpdate(); return false; @@ -520,13 +530,13 @@ void Sapphire::Entity::BNpc::aggro( Sapphire::Entity::CharaPtr pChara ) m_lastAttack = Util::getTimeMs() + variation; hateListUpdate( pChara, 1 ); - changeTarget( pChara->getId() ); setStance( Stance::Active ); m_state = BNpcState::Combat; - sendToInRangeSet( makeActorControl( getId(), ActorControlType::ToggleWeapon, 1, 1, 0 ) ); sendToInRangeSet( makeActorControl( getId(), ActorControlType::SetBattle, 1, 0, 0 ) ); + changeTarget( pChara->getId() ); + if( pChara->isPlayer() ) { PlayerPtr tmpPlayer = pChara->getAsPlayer(); @@ -854,6 +864,14 @@ void Sapphire::Entity::BNpc::setOwner( Sapphire::Entity::CharaPtr m_pChara ) setOwnerPacket->data().Id = static_cast< uint32_t >( INVALID_GAME_OBJECT_ID ); sendToInRangeSet( setOwnerPacket ); } + + if( m_pChara != nullptr && m_pChara->isPlayer() ) + { + auto letter = makeActorControl( getId(), ActorControlType::SetHateLetter, 1, getId(), 0 ); + auto& server = Common::Service< World::WorldServer >::ref(); + server.queueForPlayer( m_pChara->getAsPlayer()->getCharacterId(), letter ); + } + } void Sapphire::Entity::BNpc::setLevelId( uint32_t levelId ) @@ -891,13 +909,16 @@ void Sapphire::Entity::BNpc::autoAttack( CharaPtr pTarget ) auto damage = Math::CalcStats::calcAutoAttackDamage( *this ); //damage.first = 1; - auto effectPacket = std::make_shared< EffectPacket >( getId(), pTarget->getId(), 7 ); + auto effectPacket = std::make_shared< EffectPacket1 >( getId(), pTarget->getId(), 7 ); effectPacket->setRotation( Util::floatToUInt16Rot( getRot() ) ); Common::CalcResultParam effectEntry{}; effectEntry.Value = static_cast< int16_t >( damage.first ); effectEntry.Type = ActionEffectType::CALC_RESULT_TYPE_DAMAGE_HP; - effectEntry.Arg0 = static_cast< uint8_t >( damage.second ); + effectEntry.Flag = 128; + effectEntry.Arg0 = 3; + effectEntry.Arg1 = 7; //effectEntry.Arg2 = 0x71; + effectPacket->setSequence( getCurrentTerritory()->getNextEffectSequence() ); effectPacket->addEffect( effectEntry, static_cast< uint64_t >( pTarget->getId() ) ); sendToInRangeSet( effectPacket ); diff --git a/src/world/Actor/Chara.cpp b/src/world/Actor/Chara.cpp index b4f517d7..df772a58 100644 --- a/src/world/Actor/Chara.cpp +++ b/src/world/Actor/Chara.cpp @@ -324,7 +324,7 @@ void Sapphire::Entity::Chara::setStance( Stance stance ) { m_currentStance = stance; - FFXIVPacketBasePtr packet = makeActorControl( m_id, ToggleWeapon, stance, 0 ); + FFXIVPacketBasePtr packet = makeActorControl( m_id, ToggleWeapon, stance, 1 ); sendToInRangeSet( packet ); } diff --git a/src/world/Actor/Player.cpp b/src/world/Actor/Player.cpp index ca4f90fa..d8bb570e 100644 --- a/src/world/Actor/Player.cpp +++ b/src/world/Actor/Player.cpp @@ -35,6 +35,7 @@ #include "Network/PacketWrappers/PlayerSpawnPacket.h" #include "Network/PacketWrappers/EffectPacket.h" +#include "Network/PacketWrappers/EffectPacket1.h" #include "Network/PacketWrappers/InitZonePacket.h" #include "Network/PacketWrappers/WarpPacket.h" @@ -1500,25 +1501,29 @@ void Sapphire::Entity::Player::autoAttack( CharaPtr pTarget ) auto damage = Math::CalcStats::calcAutoAttackDamage( *this ); - auto effectPacket = std::make_shared< EffectPacket >( getId(), pTarget->getId(), 8 ); + auto effectPacket = std::make_shared< EffectPacket1 >( getId(), pTarget->getId(), 7 ); Common::CalcResultParam entry{}; entry.Value = static_cast< int16_t >( damage.first ); entry.Type = Common::ActionEffectType::CALC_RESULT_TYPE_DAMAGE_HP; - entry.Arg0 = static_cast< uint8_t >( damage.second ); + entry.Arg0 = 2; + entry.Arg1 = 7; + entry.Flag = 128; if( getClass() == ClassJob::Machinist || getClass() == ClassJob::Bard || getClass() == ClassJob::Archer ) { - effectPacket->setAnimationId( 8 ); + // effectPacket->setAnimationId( 8 ); //entry.Arg2 = 0x72; } else { - effectPacket->setAnimationId( 7 ); + //effectPacket->setAnimationId( 7 ); //entry.Arg2 = 0x73; } + effectPacket->setSequence( getCurrentTerritory()->getNextEffectSequence() ); + effectPacket->setRotation( Util::floatToUInt16Rot( getRot() ) ); effectPacket->addEffect( entry, static_cast< uint64_t >( pTarget->getId() ) ); @@ -2175,10 +2180,10 @@ void Sapphire::Entity::Player::setFalling( bool state, const Common::FFXIVARR_PO if( fallHeight >= 10.f ) { // calculate how much damage to deal out (max. 20y : 100%) - float deltaMax = std::min( fallHeight, 20.f ); + float deltaMax = std::min( fallHeight, 30.f ); // get hp percentage starting from 0.1, increasing to 100% at max height - float hpPer = std::min( 0.1f + ( deltaMax - 10.f ) / 10.f, 1.f ); + float hpPer = std::min( 0.1f + ( deltaMax - 10.f ) / 20.f, 1.f ); uint32_t damage = getMaxHp() * hpPer; diff --git a/src/world/Manager/PlayerMgr.cpp b/src/world/Manager/PlayerMgr.cpp index 00502e9f..e1c83661 100644 --- a/src/world/Manager/PlayerMgr.cpp +++ b/src/world/Manager/PlayerMgr.cpp @@ -279,11 +279,11 @@ void PlayerMgr::onHateListChanged( Sapphire::Entity::Player& player ) for( int32_t i = 0; it != actorIdToHateSlotMap.end(); ++it, i++ ) { // TODO: get actual hate values for these - hateListPacket->data().List[ i ].Id = it->first; - hateListPacket->data().List[ i ].Value = 100; + hateListPacket->data().List[ i ].Id = player.getId(); + hateListPacket->data().List[ i ].Value = 6; hateRankPacket->data().List[ i ].Id = it->first; - hateRankPacket->data().List[ i ].Rate = 1; + hateRankPacket->data().List[ i ].Rate = 100; } server.queueForPlayer( player.getCharacterId(), { hateListPacket, hateRankPacket } ); diff --git a/src/world/Network/PacketWrappers/EffectPacket1.h b/src/world/Network/PacketWrappers/EffectPacket1.h new file mode 100644 index 00000000..dc0ffec1 --- /dev/null +++ b/src/world/Network/PacketWrappers/EffectPacket1.h @@ -0,0 +1,74 @@ +#pragma once + +#include +#include +#include "Forwards.h" +#include +#include +#include + +namespace Sapphire::Network::Packets::WorldPackets::Server +{ + + class EffectPacket1 : public ZoneChannelPacket< FFXIVIpcActionResult1 > + { + public: + EffectPacket1( uint64_t sourceId, uint32_t targetId, uint32_t actionId ) : + ZoneChannelPacket< FFXIVIpcActionResult1 >( static_cast< uint32_t >( sourceId ), targetId ) + { + m_data.Flag = 0; + m_data.ActionKey = actionId; + m_data.Action = static_cast< uint16_t >( actionId ); + m_data.ActionKind = 1; + + m_data.LockTime = 0.6f; + m_data.MainTarget = static_cast< uint64_t >( targetId ); + m_data.Target = targetId; + + //m_data.ActionArg = Common::ActionEffectDisplayType::ShowActionName; + m_data.BallistaEntityId = Common::INVALID_GAME_OBJECT_ID; + + std::memset( &m_data.CalcResult, 0, sizeof( Common::CalcResult ) ); + } + + void addEffect( const Common::CalcResultParam& effect, uint64_t targetId = Common::INVALID_GAME_OBJECT_ID64 ) + { + std::memcpy( &m_data.CalcResult.CalcResultTg, &effect, sizeof( Common::CalcResultParam ) ); + } + + void setAnimationId( uint16_t animationId ) + { + m_data.Action = animationId; + } + + void setDisplayType( Common::ActionEffectDisplayType displayType ) + { + m_data.ActionArg = displayType; + } + + void setEffectFlags( uint32_t effectFlags ) + { + m_data.Flag = effectFlags; + } + + void setRotation( uint16_t rotation ) + { + m_data.DirTarget = rotation; + } + + void setTargetActor( const uint32_t targetId ) + { + m_data.MainTarget = static_cast< uint64_t >( targetId ); + + FFXIVPacketBase::setTargetActor( targetId ); + } + + void setSequence( uint32_t sequence, uint16_t sourceSequence = 0 ) + { + m_data.RequestId = static_cast< uint32_t >( sourceSequence ); + m_data.ResultId = static_cast< uint32_t>( sequence ); + } + }; + +} +