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