From 4e11690a4568eeb21e950c9f9bf62f9c9347d98c Mon Sep 17 00:00:00 2001 From: collett Date: Mon, 6 Jan 2020 04:29:45 +0900 Subject: [PATCH 1/2] Fix skill animation for other players. --- src/world/Action/Action.cpp | 20 +++++++++----------- src/world/Action/EffectBuilder.cpp | 25 ++++++++++++++++++++----- 2 files changed, 29 insertions(+), 16 deletions(-) diff --git a/src/world/Action/Action.cpp b/src/world/Action/Action.cpp index 6c13d8cb..4e456c5d 100644 --- a/src/world/Action/Action.cpp +++ b/src/world/Action/Action.cpp @@ -751,20 +751,18 @@ bool Action::Action::preFilterActor( Sapphire::Entity::Actor& actor ) const // todo: are there any server side eobjs that players can hit? if( kind != ObjKind::BattleNpc && kind != ObjKind::Player ) return false; - - if( m_lutEntry.potency > 0 && chara->getId() == m_pSource->getId() ) - { - // damage action shouldn't hit self + + if( !m_canTargetSelf && chara->getId() == m_pSource->getId() ) return false; - } - - if( ( m_lutEntry.potency > 0 || m_lutEntry.curePotency > 0 ) && !chara->isAlive() ) - { - // can't deal damage or heal a dead entity + + if( ( m_lutEntry.potency > 0 || m_lutEntry.curePotency > 0 ) && !chara->isAlive() ) // !m_canTargetDead not working for aoe return false; - } - // todo: handle things such based on canTargetX + if( m_lutEntry.potency > 0 && m_pSource->getObjKind() == chara->getObjKind() ) // !m_canTargetFriendly not working for aoe + return false; + + if( ( m_lutEntry.potency == 0 && m_lutEntry.curePotency > 0 ) && m_pSource->getObjKind() != chara->getObjKind() ) // !m_canTargetHostile not working for aoe + return false; return true; } diff --git a/src/world/Action/EffectBuilder.cpp b/src/world/Action/EffectBuilder.cpp index 761af0e3..a27ec2e6 100644 --- a/src/world/Action/EffectBuilder.cpp +++ b/src/world/Action/EffectBuilder.cpp @@ -105,11 +105,12 @@ void EffectBuilder::buildAndSendPackets() auto globalSequence = m_sourceChara->getCurrentTerritory()->getNextEffectSequence(); - while( !m_resolvedEffects.empty() ) + do // we want to send at least one packet even nothing is hit so other players can see { auto packet = buildNextEffectPacket( globalSequence ); m_sourceChara->sendToInRangeSet( packet, true ); } + while( !m_resolvedEffects.empty() ); } std::shared_ptr< FFXIVPacketBase > EffectBuilder::buildNextEffectPacket( uint32_t globalSequence ) @@ -118,9 +119,7 @@ std::shared_ptr< FFXIVPacketBase > EffectBuilder::buildNextEffectPacket( uint32_ if( remainingTargetCount > 1 ) // use AoeEffect packets { - int packetSize = remainingTargetCount <= 8 ? 8 : - ( remainingTargetCount <= 16 ? 16 : - ( remainingTargetCount <= 24 ? 24 : 32 ) ); + int packetSize = remainingTargetCount <= 8 ? 8 : ( remainingTargetCount <= 16 ? 16 : ( remainingTargetCount <= 24 ? 24 : 32 ) ); using EffectHeader = Server::FFXIVIpcAoeEffect< 8 >; // dummy type to access header part of the packet @@ -215,7 +214,7 @@ std::shared_ptr< FFXIVPacketBase > EffectBuilder::buildNextEffectPacket( uint32_ return effectPacket; } - else + else if ( remainingTargetCount == 1 ) // use Effect for single target { auto resultList = m_resolvedEffects.begin()->second; assert( !resultList->empty() ); @@ -239,6 +238,22 @@ std::shared_ptr< FFXIVPacketBase > EffectBuilder::buildNextEffectPacket( uint32_ m_resolvedEffects.clear(); + return effectPacket; + } + else // nothing is hit, this only happens when using aoe and AoeEffect8 is used on retail + { + auto effectPacket = makeZonePacket< Server::FFXIVIpcAoeEffect8 >( m_sourceChara->getId() ); + + effectPacket->data().actionId = m_actionId; + effectPacket->data().actionAnimationId = static_cast< uint16_t >( m_actionId ); + effectPacket->data().animationTargetId = m_sourceChara->getId(); + effectPacket->data().someTargetId = 0xE0000000; + effectPacket->data().rotation = Common::Util::floatToUInt16Rot( m_sourceChara->getRot() ); + effectPacket->data().effectDisplayType = Common::ActionEffectDisplayType::HideActionName; + effectPacket->data().effectCount = 0; + effectPacket->data().sourceSequence = m_sequence; + effectPacket->data().globalSequence = globalSequence; + return effectPacket; } } \ No newline at end of file From 05480df1d923755a4472ff0ca988b50b177dc5b8 Mon Sep 17 00:00:00 2001 From: collett Date: Mon, 6 Jan 2020 17:52:45 +0900 Subject: [PATCH 2/2] no need to return the list --- src/world/Action/EffectBuilder.cpp | 35 ++++++++++-------------------- src/world/Action/EffectBuilder.h | 2 +- 2 files changed, 12 insertions(+), 25 deletions(-) diff --git a/src/world/Action/EffectBuilder.cpp b/src/world/Action/EffectBuilder.cpp index a27ec2e6..23765c27 100644 --- a/src/world/Action/EffectBuilder.cpp +++ b/src/world/Action/EffectBuilder.cpp @@ -31,70 +31,57 @@ uint64_t EffectBuilder::getResultDelayMs() return Common::Util::getTimeMs() + 850; } -std::shared_ptr< std::vector< EffectResultPtr > > EffectBuilder::getResultList( Entity::CharaPtr& chara ) +void EffectBuilder::moveToResultList( Entity::CharaPtr& chara, EffectResultPtr result ) { auto it = m_resolvedEffects.find( chara->getId() ); if( it == m_resolvedEffects.end() ) { - // create a new one and return it + // create a new one auto resultList = std::make_shared< std::vector< EffectResultPtr > >(); m_resolvedEffects[ chara->getId() ] = resultList; - return resultList; + resultList->push_back( std::move( result ) ); + + return; } - return it->second; + it->second->push_back( std::move( result ) ); } void EffectBuilder::heal( Entity::CharaPtr& effectTarget, Entity::CharaPtr& healingTarget, uint32_t amount, Common::ActionHitSeverityType severity, Common::ActionEffectResultFlag flag ) { - auto resultList = getResultList( effectTarget ); - assert( resultList ); - EffectResultPtr nextResult = make_EffectResult( healingTarget, getResultDelayMs() ); nextResult->heal( amount, severity, flag ); - resultList->push_back( std::move( nextResult ) ); + moveToResultList( effectTarget, nextResult ); } void EffectBuilder::restoreMP( Entity::CharaPtr& target, Entity::CharaPtr& restoringTarget, uint32_t amount, Common::ActionEffectResultFlag flag ) { - auto resultList = getResultList( target ); - assert( resultList ); - EffectResultPtr nextResult = make_EffectResult( restoringTarget, getResultDelayMs() ); // restore mp source actor nextResult->restoreMP( amount, flag ); - resultList->push_back( std::move( nextResult ) ); + moveToResultList( target, nextResult ); } void EffectBuilder::damage( Entity::CharaPtr& effectTarget, Entity::CharaPtr& damagingTarget, uint32_t amount, Common::ActionHitSeverityType severity, Common::ActionEffectResultFlag flag ) { - auto resultList = getResultList( effectTarget ); - assert( resultList ); - EffectResultPtr nextResult = make_EffectResult( damagingTarget, getResultDelayMs() ); nextResult->damage( amount, severity, flag ); - resultList->push_back( std::move( nextResult ) ); + moveToResultList( effectTarget, nextResult ); } void EffectBuilder::startCombo( Entity::CharaPtr& target, uint16_t actionId ) { - auto resultList = getResultList( target ); - assert( resultList ); - EffectResultPtr nextResult = make_EffectResult( target, 0 ); nextResult->startCombo( actionId ); - resultList->push_back( std::move( nextResult ) ); + moveToResultList( target, nextResult ); } void EffectBuilder::comboSucceed( Entity::CharaPtr& target ) { - auto resultList = getResultList( target ); - assert( resultList ); - EffectResultPtr nextResult = make_EffectResult( target, 0 ); nextResult->comboSucceed(); - resultList->push_back( std::move( nextResult ) ); + moveToResultList( target, nextResult ); } void EffectBuilder::buildAndSendPackets() diff --git a/src/world/Action/EffectBuilder.h b/src/world/Action/EffectBuilder.h index b2a76221..dda471e2 100644 --- a/src/world/Action/EffectBuilder.h +++ b/src/world/Action/EffectBuilder.h @@ -30,7 +30,7 @@ namespace Sapphire::World::Action private: - std::shared_ptr< std::vector< EffectResultPtr > > getResultList( Entity::CharaPtr& chara ); + void moveToResultList( Entity::CharaPtr& chara, EffectResultPtr result ); uint64_t getResultDelayMs();