2023-03-09 21:54:30 +01:00
|
|
|
#include "ActionResultBuilder.h"
|
|
|
|
#include "ActionResult.h"
|
2019-07-25 22:46:10 +10:00
|
|
|
|
2019-07-26 20:28:01 +10:00
|
|
|
#include <Actor/Player.h>
|
2019-07-25 22:46:10 +10:00
|
|
|
|
|
|
|
#include <Network/PacketWrappers/EffectPacket.h>
|
2022-01-06 20:25:50 +01:00
|
|
|
#include <Network/PacketWrappers/EffectPacket1.h>
|
2019-07-25 22:46:10 +10:00
|
|
|
|
|
|
|
#include <Territory/Territory.h>
|
|
|
|
|
|
|
|
#include <Util/Util.h>
|
|
|
|
#include <Util/UtilMath.h>
|
|
|
|
|
|
|
|
#include <Logging/Logger.h>
|
2022-01-10 23:50:44 +01:00
|
|
|
#include <Manager/TerritoryMgr.h>
|
2023-02-17 22:46:02 +01:00
|
|
|
#include <Manager/MgrUtil.h>
|
2022-01-10 23:50:44 +01:00
|
|
|
#include <Service.h>
|
2019-07-25 22:46:10 +10:00
|
|
|
|
2023-02-16 08:24:39 +01:00
|
|
|
#include <Manager/TaskMgr.h>
|
|
|
|
#include <Task/ActionIntegrityTask.h>
|
|
|
|
|
2019-07-25 22:46:10 +10:00
|
|
|
using namespace Sapphire;
|
|
|
|
using namespace Sapphire::World::Action;
|
2023-02-17 22:46:02 +01:00
|
|
|
using namespace Sapphire::World::Manager;
|
2019-07-25 22:46:10 +10:00
|
|
|
using namespace Sapphire::Network::Packets;
|
2021-11-27 00:53:57 +01:00
|
|
|
using namespace Sapphire::Network::Packets::WorldPackets::Server;
|
2019-07-25 22:46:10 +10:00
|
|
|
|
2023-03-09 21:54:30 +01:00
|
|
|
ActionResultBuilder::ActionResultBuilder( Entity::CharaPtr source, uint32_t actionId, uint32_t resultId, uint16_t requestId ) :
|
2019-07-25 22:46:10 +10:00
|
|
|
m_sourceChara( std::move( source ) ),
|
2019-07-26 20:28:01 +10:00
|
|
|
m_actionId( actionId ),
|
2023-03-09 21:54:30 +01:00
|
|
|
m_resultId( resultId ),
|
2023-02-28 10:31:59 +01:00
|
|
|
m_requestId( requestId )
|
2019-07-25 22:46:10 +10:00
|
|
|
{
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2023-03-09 21:54:30 +01:00
|
|
|
void ActionResultBuilder::addResultToActor( Entity::CharaPtr& chara, ActionResultPtr result )
|
2019-07-25 22:46:10 +10:00
|
|
|
{
|
2023-03-10 17:32:52 +01:00
|
|
|
auto it = m_actorResultsMap.find( chara );
|
2023-03-09 21:54:30 +01:00
|
|
|
if( it == m_actorResultsMap.end() )
|
2019-07-25 22:46:10 +10:00
|
|
|
{
|
2023-03-10 17:32:52 +01:00
|
|
|
m_actorResultsMap[ chara ].push_back( std::move( result ) );
|
2020-01-06 17:52:45 +09:00
|
|
|
return;
|
2019-07-25 22:46:10 +10:00
|
|
|
}
|
|
|
|
|
2022-01-10 19:31:21 -03:00
|
|
|
it->second.push_back( std::move( result ) );
|
2019-07-25 22:46:10 +10:00
|
|
|
}
|
|
|
|
|
2023-03-09 21:54:30 +01:00
|
|
|
void ActionResultBuilder::heal( Entity::CharaPtr& effectTarget, Entity::CharaPtr& healingTarget, uint32_t amount, Common::ActionHitSeverityType severity, Common::ActionResultFlag flag )
|
2019-07-25 22:46:10 +10:00
|
|
|
{
|
2023-03-10 17:32:52 +01:00
|
|
|
ActionResultPtr nextResult = make_ActionResult( healingTarget, 0 );
|
2020-01-05 20:49:50 +09:00
|
|
|
nextResult->heal( amount, severity, flag );
|
2022-01-10 19:31:21 -03:00
|
|
|
addResultToActor( effectTarget, nextResult );
|
2020-01-05 17:09:27 +09:00
|
|
|
}
|
|
|
|
|
2023-03-09 21:54:30 +01:00
|
|
|
void ActionResultBuilder::restoreMP( Entity::CharaPtr& target, Entity::CharaPtr& restoringTarget, uint32_t amount, Common::ActionResultFlag flag )
|
2020-01-05 17:09:27 +09:00
|
|
|
{
|
2023-03-10 17:32:52 +01:00
|
|
|
ActionResultPtr nextResult = make_ActionResult( restoringTarget, 0 ); // restore mp source actor
|
2020-01-05 20:49:50 +09:00
|
|
|
nextResult->restoreMP( amount, flag );
|
2022-01-10 19:31:21 -03:00
|
|
|
addResultToActor( target, nextResult );
|
2020-01-05 17:09:27 +09:00
|
|
|
}
|
|
|
|
|
2023-03-09 21:54:30 +01:00
|
|
|
void ActionResultBuilder::damage( Entity::CharaPtr& effectTarget, Entity::CharaPtr& damagingTarget, uint32_t amount, Common::ActionHitSeverityType severity, Common::ActionResultFlag flag )
|
2020-01-05 17:09:27 +09:00
|
|
|
{
|
2023-03-10 17:32:52 +01:00
|
|
|
ActionResultPtr nextResult = make_ActionResult( damagingTarget, 0 );
|
2020-01-05 20:49:50 +09:00
|
|
|
nextResult->damage( amount, severity, flag );
|
2022-01-10 19:31:21 -03:00
|
|
|
addResultToActor( damagingTarget, nextResult );
|
2020-01-05 17:09:27 +09:00
|
|
|
}
|
|
|
|
|
2023-03-09 21:54:30 +01:00
|
|
|
void ActionResultBuilder::startCombo( Entity::CharaPtr& target, uint16_t actionId )
|
2020-01-05 17:09:27 +09:00
|
|
|
{
|
2023-03-09 21:54:30 +01:00
|
|
|
ActionResultPtr nextResult = make_ActionResult( target, 0 );
|
2020-01-05 17:09:27 +09:00
|
|
|
nextResult->startCombo( actionId );
|
2022-01-10 19:31:21 -03:00
|
|
|
addResultToActor( target, nextResult );
|
2020-01-05 17:09:27 +09:00
|
|
|
}
|
|
|
|
|
2023-03-09 21:54:30 +01:00
|
|
|
void ActionResultBuilder::comboSucceed( Entity::CharaPtr& target )
|
2020-01-05 17:09:27 +09:00
|
|
|
{
|
2023-03-09 21:54:30 +01:00
|
|
|
ActionResultPtr nextResult = make_ActionResult( target, 0 );
|
2020-01-05 20:49:50 +09:00
|
|
|
nextResult->comboSucceed();
|
2022-01-10 19:31:21 -03:00
|
|
|
addResultToActor( target, nextResult );
|
2019-07-25 22:46:10 +10:00
|
|
|
}
|
|
|
|
|
2023-03-10 22:34:12 +01:00
|
|
|
void ActionResultBuilder::applyStatusEffect( Entity::CharaPtr& target, uint16_t statusId, uint32_t duration, uint8_t param, bool shouldOverride )
|
2020-01-06 19:25:01 +09:00
|
|
|
{
|
2023-03-09 21:54:30 +01:00
|
|
|
ActionResultPtr nextResult = make_ActionResult( target, 0 );
|
2023-03-10 22:34:12 +01:00
|
|
|
nextResult->applyStatusEffect( statusId, duration, *m_sourceChara, param, shouldOverride );
|
2022-01-10 19:31:21 -03:00
|
|
|
addResultToActor( target, nextResult );
|
2020-01-06 19:25:01 +09:00
|
|
|
}
|
|
|
|
|
2023-03-09 21:54:30 +01:00
|
|
|
void ActionResultBuilder::mount( Entity::CharaPtr& target, uint16_t mountId )
|
2020-01-23 22:36:01 +09:00
|
|
|
{
|
2023-03-10 17:32:52 +01:00
|
|
|
ActionResultPtr nextResult = make_ActionResult( target, 0 );
|
2020-01-23 22:36:01 +09:00
|
|
|
nextResult->mount( mountId );
|
2022-01-10 19:31:21 -03:00
|
|
|
addResultToActor( target, nextResult );
|
2020-01-23 22:36:01 +09:00
|
|
|
}
|
|
|
|
|
2023-03-09 21:54:30 +01:00
|
|
|
void ActionResultBuilder::sendActionResults( const std::vector< Entity::CharaPtr >& targetList )
|
2019-07-25 22:46:10 +10:00
|
|
|
{
|
2019-07-25 23:21:42 +10:00
|
|
|
Logger::debug( "EffectBuilder result: " );
|
2022-01-10 19:31:21 -03:00
|
|
|
Logger::debug( "Targets afflicted: {}", targetList.size() );
|
2020-01-05 17:09:27 +09:00
|
|
|
|
2020-01-06 04:29:45 +09:00
|
|
|
do // we want to send at least one packet even nothing is hit so other players can see
|
2020-01-05 17:09:27 +09:00
|
|
|
{
|
2023-03-09 21:54:30 +01:00
|
|
|
auto packet = createActionResultPacket( targetList );
|
2023-02-17 22:46:02 +01:00
|
|
|
server().queueForPlayers( m_sourceChara->getInRangePlayerIds( true ), packet );
|
2020-01-05 17:09:27 +09:00
|
|
|
}
|
2023-03-09 21:54:30 +01:00
|
|
|
while( !m_actorResultsMap.empty() );
|
2020-01-05 17:09:27 +09:00
|
|
|
}
|
|
|
|
|
2023-03-09 21:54:30 +01:00
|
|
|
std::shared_ptr< FFXIVPacketBase > ActionResultBuilder::createActionResultPacket( const std::vector< Entity::CharaPtr >& targetList )
|
2020-01-05 17:09:27 +09:00
|
|
|
{
|
2023-03-10 17:32:52 +01:00
|
|
|
auto targetCount = targetList.size();
|
2023-03-09 21:54:30 +01:00
|
|
|
auto& taskMgr = Common::Service< World::Manager::TaskMgr >::ref();
|
2022-01-10 23:50:44 +01:00
|
|
|
auto& teriMgr = Common::Service< Sapphire::World::Manager::TerritoryMgr >::ref();
|
2022-01-14 23:13:47 +01:00
|
|
|
auto zone = teriMgr.getTerritoryByGuId( m_sourceChara->getTerritoryId() );
|
2022-01-10 23:50:44 +01:00
|
|
|
|
2023-03-10 22:59:53 +01:00
|
|
|
if( targetCount > 1 ) // use AoeEffect packets
|
2020-01-05 17:09:27 +09:00
|
|
|
{
|
2023-03-10 17:32:52 +01:00
|
|
|
auto actionResult = std::make_shared< EffectPacket >( m_sourceChara->getId(), targetList[ 0 ]->getId(), m_actionId );
|
|
|
|
actionResult->setRotation( Common::Util::floatToUInt16Rot( m_sourceChara->getRot() ) );
|
|
|
|
actionResult->setRequestId( m_requestId );
|
|
|
|
actionResult->setResultId( m_resultId );
|
2020-01-05 17:09:27 +09:00
|
|
|
|
|
|
|
uint8_t targetIndex = 0;
|
2023-03-10 17:32:52 +01:00
|
|
|
for( auto it = m_actorResultsMap.begin(); it != m_actorResultsMap.end(); ++it )
|
2020-01-05 17:09:27 +09:00
|
|
|
{
|
2022-01-10 19:31:21 -03:00
|
|
|
// get all effect results for an actor
|
|
|
|
auto actorResultList = it->second;
|
2020-01-05 17:09:27 +09:00
|
|
|
|
2023-03-10 17:32:52 +01:00
|
|
|
if( it->first )
|
|
|
|
taskMgr.queueTask( World::makeActionIntegrityTask( m_resultId, it->first, actorResultList, 300 ) );
|
|
|
|
|
2023-03-09 21:54:30 +01:00
|
|
|
for( auto& result : actorResultList )
|
2020-01-05 17:09:27 +09:00
|
|
|
{
|
2023-02-28 10:31:59 +01:00
|
|
|
auto effect = result->getCalcResultParam();
|
2022-01-10 19:31:21 -03:00
|
|
|
if( result->getTarget() == m_sourceChara )
|
2023-03-10 17:32:52 +01:00
|
|
|
actionResult->addSourceEffect( effect );
|
2022-01-10 19:31:21 -03:00
|
|
|
else
|
2023-03-10 17:32:52 +01:00
|
|
|
actionResult->addTargetEffect( effect, result->getTarget()->getId() );
|
2020-01-05 17:09:27 +09:00
|
|
|
}
|
|
|
|
targetIndex++;
|
|
|
|
|
2021-11-27 00:53:57 +01:00
|
|
|
if( targetIndex == 15 )
|
2020-01-05 17:09:27 +09:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2023-03-10 17:32:52 +01:00
|
|
|
return actionResult;
|
2020-01-05 17:09:27 +09:00
|
|
|
}
|
2023-03-10 17:32:52 +01:00
|
|
|
else // use Effect for single target
|
2019-07-25 22:46:10 +10:00
|
|
|
{
|
2023-03-10 22:59:53 +01:00
|
|
|
uint32_t mainTargetId = targetList.empty() ? m_sourceChara->getId() : targetList[ 0 ]->getId();
|
|
|
|
auto actionResult = std::make_shared< EffectPacket1 >( m_sourceChara->getId(), mainTargetId, m_actionId );
|
2023-03-10 17:32:52 +01:00
|
|
|
actionResult->setRotation( Common::Util::floatToUInt16Rot( m_sourceChara->getRot() ) );
|
|
|
|
actionResult->setRequestId( m_requestId );
|
|
|
|
actionResult->setResultId( m_resultId );
|
2022-01-10 23:50:44 +01:00
|
|
|
|
2023-03-10 17:32:52 +01:00
|
|
|
for( auto it = m_actorResultsMap.begin(); it != m_actorResultsMap.end(); ++it )
|
2020-01-05 17:09:27 +09:00
|
|
|
{
|
2022-01-10 19:31:21 -03:00
|
|
|
// get all effect results for an actor
|
|
|
|
auto actorResultList = it->second;
|
2019-07-25 22:46:10 +10:00
|
|
|
|
2023-03-10 17:32:52 +01:00
|
|
|
if( it->first )
|
|
|
|
taskMgr.queueTask( World::makeActionIntegrityTask( m_resultId, it->first, actorResultList, 300 ) );
|
|
|
|
|
2023-03-09 21:54:30 +01:00
|
|
|
for( auto& result : actorResultList )
|
2022-01-10 19:31:21 -03:00
|
|
|
{
|
2023-02-28 10:31:59 +01:00
|
|
|
auto effect = result->getCalcResultParam();
|
2022-01-10 19:31:21 -03:00
|
|
|
if( result->getTarget() == m_sourceChara )
|
2023-03-10 17:32:52 +01:00
|
|
|
actionResult->addSourceEffect( effect );
|
2022-01-10 19:31:21 -03:00
|
|
|
else
|
2023-03-10 17:32:52 +01:00
|
|
|
actionResult->addTargetEffect( effect );
|
2022-01-10 19:31:21 -03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-03-09 21:54:30 +01:00
|
|
|
m_actorResultsMap.clear();
|
2023-03-10 17:32:52 +01:00
|
|
|
return actionResult;
|
2019-07-27 13:59:35 +10:00
|
|
|
}
|
2019-07-25 22:46:10 +10:00
|
|
|
}
|