1
Fork 0
mirror of https://github.com/SapphireServer/Sapphire.git synced 2025-04-27 14:57:44 +00:00

Refactoring of action logic, ongoing.

Fixing source of actorcontrols being always player for single target packets.
This commit is contained in:
Mordred 2023-03-09 21:54:30 +01:00
parent 859f2329bb
commit 0def7896ec
29 changed files with 209 additions and 238 deletions

View file

@ -1018,7 +1018,7 @@ namespace Sapphire::Common
CritDirectHitDamage = 3
};
enum class ActionEffectResultFlag : uint8_t
enum class ActionResultFlag : uint8_t
{
None = 0,
Absorbed = 0x04,

View file

@ -18,7 +18,7 @@ public:
uint32_t duration = ( sourceChara->getAsPlayer()->getTp() / 50 ) * 1000;
action.getEffectbuilder()->applyStatusEffect( sourceChara, 50, 30 );
action.getActionResultBuilder()->applyStatusEffect( sourceChara, 50, 30 );
sourceChara->getAsPlayer()->addStatusEffectByIdIfNotExist( 50, duration, *sourceChara, 30 );
sourceChara->getAsPlayer()->setTp( 0 );

View file

@ -16,6 +16,7 @@
#include "Manager/PlayerMgr.h"
#include "Manager/MgrUtil.h"
#include "Manager/TerritoryMgr.h"
#include "Session.h"
#include "Network/GameConnection.h"
@ -65,6 +66,11 @@ uint32_t Action::Action::getId() const
return m_id;
}
uint32_t Action::Action::getResultId() const
{
return m_resultId;
}
bool Action::Action::init()
{
if( !m_actionData )
@ -78,8 +84,11 @@ bool Action::Action::init()
m_actionData = actionData;
}
auto teriMgr = Common::Service< Manager::TerritoryMgr >::ref();
auto zone = teriMgr.getTerritoryByGuId( m_pSource->getTerritoryId() );
m_resultId = zone->getNextEffectResultId();
m_effectBuilder = make_EffectBuilder( m_pSource, getId(), m_requestId );
m_actionResultBuilder = make_ActionResultBuilder( m_pSource, getId(), m_resultId, m_requestId );
m_castTimeMs = static_cast< uint32_t >( m_actionData->data().CastTime * 100 );
m_recastTimeMs = static_cast< uint32_t >( m_actionData->data().RecastTime * 100 );
@ -105,9 +114,9 @@ bool Action::Action::init()
{
case Common::ClassJob::Bard:
case Common::ClassJob::Archer:
case Common::ClassJob::Machinist:
m_range = 25;
break;
// anything that isnt ranged
default:
m_range = 3;
break;
@ -241,34 +250,34 @@ bool Action::Action::update()
// todo: check if the target is still in range
}
uint64_t tickCount = Common::Util::getTimeMs();
uint32_t castTime = m_castTimeMs;
auto tickCount = static_cast< time_t >( Common::Util::getTimeMs() );
auto startTime = static_cast< time_t >( m_startTime );
uint64_t castTime = m_castTimeMs;
if( auto player = m_pSource->getAsPlayer() )
{
uint64_t lastActionTick = player->getLastActionTick();
auto lastActionTick = static_cast< time_t >( player->getLastActionTick() );
uint32_t lastTickMs = 0;
if( lastActionTick > 0 )
{
lastTickMs = static_cast< uint32_t >( std::difftime( static_cast< time_t >( tickCount ), static_cast< time_t >( lastActionTick ) ) );
lastTickMs = static_cast< uint32_t >( std::difftime( tickCount, lastActionTick ) );
if( lastTickMs > 100 ) //max 100ms
lastTickMs = 100;
}
player->setLastActionTick( tickCount );
uint32_t delayMs = 100 - lastTickMs;
uint64_t delayMs = 100 - lastTickMs;
castTime = ( m_castTimeMs + delayMs );
m_castTimeRestMs = static_cast< uint64_t >( m_castTimeMs ) -
static_cast< uint64_t >( std::difftime( static_cast< time_t >( tickCount ), static_cast< time_t >( m_startTime ) ) );
m_castTimeRestMs = static_cast< uint64_t >( m_castTimeMs ) - static_cast< uint64_t >( std::difftime( tickCount, startTime ) );
}
if( !hasCastTime() || std::difftime( static_cast< time_t >( tickCount ), static_cast< time_t >( m_startTime ) ) > castTime )
if( !hasCastTime() || std::difftime( tickCount, startTime ) > castTime )
{
execute();
return true;
}
if( m_pTarget == nullptr && m_targetId != 0 )
if( !m_pTarget && m_targetId != 0 )
{
// try to search for the target actor
for( const auto& actor : m_pSource->getInRangeActors( true ) )
@ -281,7 +290,7 @@ bool Action::Action::update()
}
}
if( m_pTarget != nullptr && !m_pTarget->isAlive() )
if( m_pTarget && !m_pTarget->isAlive() )
{
// interrupt the cast if target died
setInterrupted( Common::ActionInterruptType::RegularInterrupt );
@ -315,13 +324,11 @@ void Action::Action::start()
data.TargetPos[ 2 ] = Common::Util::floatToUInt16( m_pSource->getPos().z );
data.Dir = m_pSource->getRot();
server().queueForPlayers( m_pSource->getInRangePlayerIds( true ), castPacket );
server().queueForPlayers( m_pSource->getInRangePlayerIds( m_pSource->isPlayer() ), castPacket );
if( player )
{
player->setCondition( PlayerCondition::Casting );
}
}
// todo: m_recastTimeMs needs to be adjusted for player sks/sps
auto actionStartPkt = makeActorControlSelf( m_pSource->getId(), ActorControlType::ActionStart, m_cooldownGroup, getId(), m_recastTimeMs / 10 );
@ -404,24 +411,20 @@ void Action::Action::execute()
assert( m_pSource );
// subtract costs first, if somehow the caster stops meeting those requirements cancel the cast
if( !consumeResources() )
{
interrupt();
return;
}
auto& scriptMgr = Common::Service< Scripting::ScriptMgr >::ref();
if( hasCastTime() )
{
if( auto pPlayer = m_pSource->getAsPlayer(); pPlayer )
if( hasCastTime() && m_pSource->isPlayer() )
{
auto pPlayer = m_pSource->getAsPlayer();
pPlayer->setLastActionTick( 0 );
pPlayer->removeCondition( PlayerCondition::Casting );
}
}
if( isCorrectCombo() )
{
@ -430,13 +433,9 @@ void Action::Action::execute()
}
if( !hasClientsideTarget() )
{
buildEffects();
}
buildActionResults();
else if( auto player = m_pSource->getAsPlayer() )
{
scriptMgr.onEObjHit( *player, m_targetId, getId() );
}
// set currently casted action as the combo action if it interrupts a combo
// ignore it otherwise (ogcds, etc.)
@ -444,15 +443,11 @@ void Action::Action::execute()
{
// potential combo starter or correct combo from last action, must hit something to progress combo
if( !m_hitActors.empty() && ( !isComboAction() || isCorrectCombo() ) )
{
m_pSource->setLastComboActionId( getId() );
}
else // clear last combo action if the combo breaks
{
m_pSource->setLastComboActionId( 0 );
}
}
}
std::pair< uint32_t, Common::ActionHitSeverityType > Action::Action::calcDamage( uint32_t potency )
{
@ -501,7 +496,7 @@ std::pair< uint32_t, Common::ActionHitSeverityType > Action::Action::calcHealing
return Math::CalcStats::calcActionHealing( *m_pSource, potency, wepDmg );
}
void Action::Action::buildEffects()
void Action::Action::buildActionResults()
{
snapshotAffectedActors( m_hitActors );
@ -511,10 +506,7 @@ void Action::Action::buildEffects()
if( !scriptMgr.onExecute( *this ) && !hasLutEntry )
{
if( auto player = m_pSource->getAsPlayer() )
{
Manager::PlayerMgr::sendUrgent( *player, "missing lut entry for action#{}", getId() );
}
return;
}
@ -523,7 +515,7 @@ void Action::Action::buildEffects()
if( !hasLutEntry || m_hitActors.empty() )
{
// send any effect packet added by script or an empty one just to play animation for other players
m_effectBuilder->buildAndSendPackets( m_hitActors );
m_actionResultBuilder->sendActionResults( {} );
return;
}
@ -544,14 +536,14 @@ void Action::Action::buildEffects()
if( m_lutEntry.potency > 0 )
{
auto dmg = calcDamage( isCorrectCombo() ? m_lutEntry.comboPotency : m_lutEntry.potency );
m_effectBuilder->damage( m_pSource, actor, dmg.first, dmg.second );
m_actionResultBuilder->damage( m_pSource, actor, dmg.first, dmg.second );
if( dmg.first > 0 )
actor->onActionHostile( m_pSource );
if( isCorrectCombo() && shouldApplyComboSucceedEffect )
{
m_effectBuilder->comboSucceed( m_pSource );
m_actionResultBuilder->comboSucceed( m_pSource );
shouldApplyComboSucceedEffect = false;
}
@ -560,40 +552,40 @@ void Action::Action::buildEffects()
if( m_lutEntry.curePotency > 0 ) // actions with self heal
{
auto heal = calcHealing( m_lutEntry.curePotency );
m_effectBuilder->heal( actor, m_pSource, heal.first, heal.second, Common::ActionEffectResultFlag::EffectOnSource );
m_actionResultBuilder->heal( actor, m_pSource, heal.first, heal.second, Common::ActionResultFlag::EffectOnSource );
}
if( m_lutEntry.restoreMPPercentage > 0 && shouldRestoreMP )
{
m_effectBuilder->restoreMP( actor, m_pSource, m_pSource->getMaxMp() * m_lutEntry.restoreMPPercentage / 100, Common::ActionEffectResultFlag::EffectOnSource );
m_actionResultBuilder->restoreMP( actor, m_pSource, m_pSource->getMaxMp() * m_lutEntry.restoreMPPercentage / 100, Common::ActionResultFlag::EffectOnSource );
shouldRestoreMP = false;
}
if( !m_lutEntry.nextCombo.empty() ) // if we have a combo action followup
{
m_effectBuilder->startCombo( m_pSource, getId() ); // this is on all targets hit
m_actionResultBuilder->startCombo( m_pSource, getId() ); // this is on all targets hit
}
}
}
else if( m_lutEntry.curePotency > 0 )
{
auto heal = calcHealing( m_lutEntry.curePotency );
m_effectBuilder->heal( actor, actor, heal.first, heal.second );
m_actionResultBuilder->heal( actor, actor, heal.first, heal.second );
if( m_lutEntry.restoreMPPercentage > 0 && shouldRestoreMP )
{
m_effectBuilder->restoreMP( actor, m_pSource, m_pSource->getMaxMp() * m_lutEntry.restoreMPPercentage / 100, Common::ActionEffectResultFlag::EffectOnSource );
m_actionResultBuilder->restoreMP( actor, m_pSource, m_pSource->getMaxMp() * m_lutEntry.restoreMPPercentage / 100, Common::ActionResultFlag::EffectOnSource );
shouldRestoreMP = false;
}
}
else if( m_lutEntry.restoreMPPercentage > 0 && shouldRestoreMP )
{
m_effectBuilder->restoreMP( actor, m_pSource, m_pSource->getMaxMp() * m_lutEntry.restoreMPPercentage / 100, Common::ActionEffectResultFlag::EffectOnSource );
m_actionResultBuilder->restoreMP( actor, m_pSource, m_pSource->getMaxMp() * m_lutEntry.restoreMPPercentage / 100, Common::ActionResultFlag::EffectOnSource );
shouldRestoreMP = false;
}
}
m_effectBuilder->buildAndSendPackets( m_hitActors );
m_actionResultBuilder->sendActionResults( m_hitActors );
// TODO: disabled, reset kills our queued actions
// at this point we're done with it and no longer need it
@ -678,9 +670,7 @@ bool Action::Action::isCorrectCombo() const
auto lastActionId = m_pSource->getLastComboActionId();
if( lastActionId == 0 )
{
return false;
}
return m_actionData->data().ComboParent == lastActionId;
}
@ -854,10 +844,7 @@ std::vector< Entity::CharaPtr >& Action::Action::getHitCharas()
Entity::CharaPtr Action::Action::getHitChara()
{
if( !m_hitActors.empty() )
{
return m_hitActors.at( 0 );
}
return nullptr;
}
@ -867,9 +854,9 @@ bool Action::Action::hasValidLutEntry() const
m_lutEntry.rearPotency != 0 || m_lutEntry.curePotency != 0 || m_lutEntry.restoreMPPercentage != 0;
}
Action::EffectBuilderPtr Action::Action::getEffectbuilder()
Action::ActionResultBuilderPtr Action::Action::getActionResultBuilder()
{
return m_effectBuilder;
return m_actionResultBuilder;
}
uint8_t Action::Action::getActionKind() const

View file

@ -4,7 +4,7 @@
#include "ActionLut.h"
#include "Util/ActorFilter.h"
#include "ForwardsZone.h"
#include "EffectBuilder.h"
#include "ActionResultBuilder.h"
#include "Exd/Structs.h"
namespace Sapphire::World::Action
@ -23,6 +23,8 @@ namespace Sapphire::World::Action
uint32_t getId() const;
uint32_t getResultId() const;
bool init();
void setPos( const Common::FFXIVARR_POSITION3& pos );
@ -103,9 +105,9 @@ namespace Sapphire::World::Action
*/
bool snapshotAffectedActors( std::vector< Entity::CharaPtr >& actors );
EffectBuilderPtr getEffectbuilder();
ActionResultBuilderPtr getActionResultBuilder();
void buildEffects();
void buildActionResults();
/*!
* @brief Adds an actor filter to this action.
@ -172,6 +174,7 @@ namespace Sapphire::World::Action
uint8_t m_actionKind{};
uint16_t m_requestId{};
uint32_t m_resultId{};
Common::ActionPrimaryCostType m_primaryCostType;
uint16_t m_primaryCost{};
@ -208,7 +211,7 @@ namespace Sapphire::World::Action
Common::FFXIVARR_POSITION3 m_pos{};
EffectBuilderPtr m_effectBuilder;
ActionResultBuilderPtr m_actionResultBuilder;
std::vector< World::Util::ActorFilterPtr > m_actorFilters;
std::vector< Entity::CharaPtr > m_hitActors;

View file

@ -1,4 +1,4 @@
#include "EffectResult.h"
#include "ActionResult.h"
#include <Util/Util.h>
@ -12,7 +12,7 @@ using namespace Sapphire;
using namespace Sapphire::World::Action;
EffectResult::EffectResult( Entity::CharaPtr target, uint64_t runAfter ) :
ActionResult::ActionResult( Entity::CharaPtr target, uint64_t runAfter ) :
m_target( std::move( target ) ),
m_delayMs( runAfter )
{
@ -20,21 +20,21 @@ EffectResult::EffectResult( Entity::CharaPtr target, uint64_t runAfter ) :
m_result.Arg1 = 0;
m_result.Arg2 = 0;
m_result.Value = 0;
m_result.Flag = static_cast< uint8_t >( Common::ActionEffectResultFlag::None );
m_result.Flag = static_cast< uint8_t >( Common::ActionResultFlag::None );
m_result.Type = Common::ActionEffectType::CALC_RESULT_TYPE_NONE;
}
Entity::CharaPtr EffectResult::getTarget() const
Entity::CharaPtr ActionResult::getTarget() const
{
return m_target;
}
uint64_t EffectResult::getDelay()
uint64_t ActionResult::getDelay()
{
return m_delayMs;
}
void EffectResult::damage( uint32_t amount, Common::ActionHitSeverityType severity, Common::ActionEffectResultFlag flag )
void ActionResult::damage( uint32_t amount, Common::ActionHitSeverityType severity, Common::ActionResultFlag flag )
{
m_result.Arg0 = static_cast< uint8_t >( severity );
m_result.Value = static_cast< int16_t >( amount );
@ -42,7 +42,7 @@ void EffectResult::damage( uint32_t amount, Common::ActionHitSeverityType severi
m_result.Type = Common::ActionEffectType::CALC_RESULT_TYPE_DAMAGE_HP;
}
void EffectResult::heal( uint32_t amount, Common::ActionHitSeverityType severity, Common::ActionEffectResultFlag flag )
void ActionResult::heal( uint32_t amount, Common::ActionHitSeverityType severity, Common::ActionResultFlag flag )
{
m_result.Arg1 = static_cast< uint8_t >( severity );
m_result.Value = static_cast< int16_t >( amount );
@ -50,46 +50,46 @@ void EffectResult::heal( uint32_t amount, Common::ActionHitSeverityType severity
m_result.Type = Common::ActionEffectType::CALC_RESULT_TYPE_RECOVER_HP;
}
void EffectResult::restoreMP( uint32_t amount, Common::ActionEffectResultFlag flag )
void ActionResult::restoreMP( uint32_t amount, Common::ActionResultFlag flag )
{
m_result.Value = static_cast< int16_t >( amount );
m_result.Flag = static_cast< uint8_t >( flag );
m_result.Type = Common::ActionEffectType::CALC_RESULT_TYPE_RECOVER_MP;
}
void EffectResult::startCombo( uint16_t actionId )
void ActionResult::startCombo( uint16_t actionId )
{
m_result.Value = static_cast< int16_t >( actionId );
m_result.Flag = static_cast< uint8_t >( Common::ActionEffectResultFlag::EffectOnSource );
m_result.Flag = static_cast< uint8_t >( Common::ActionResultFlag::EffectOnSource );
m_result.Type = Common::ActionEffectType::CALC_RESULT_TYPE_COMBO;
}
void EffectResult::comboSucceed()
void ActionResult::comboSucceed()
{
// no EffectOnSource flag on this
m_result.Type = Common::ActionEffectType::CALC_RESULT_TYPE_COMBO_HIT;
}
void EffectResult::applyStatusEffect( uint16_t statusId, uint8_t param )
void ActionResult::applyStatusEffect( uint16_t statusId, uint8_t param )
{
m_result.Value = static_cast< int16_t >( statusId );
m_result.Arg2 = param;
m_result.Type = Common::ActionEffectType::CALC_RESULT_TYPE_SET_STATUS;
}
void EffectResult::mount( uint16_t mountId )
void ActionResult::mount( uint16_t mountId )
{
m_result.Value = static_cast< int16_t >( mountId );
m_result.Arg0 = 1;
m_result.Type = Common::ActionEffectType::CALC_RESULT_TYPE_MOUNT;
}
const Common::CalcResultParam& EffectResult::getCalcResultParam() const
const Common::CalcResultParam& ActionResult::getCalcResultParam() const
{
return m_result;
}
void EffectResult::execute()
void ActionResult::execute()
{
switch( m_result.Type )
{

View file

@ -9,14 +9,14 @@ namespace Sapphire::World::Action
* @brief A container for the computed result of an effect on a single actor. Used to apply damage/healing dealt
* at a later point in time.
*/
class EffectResult
class ActionResult
{
public:
explicit EffectResult( Entity::CharaPtr target, uint64_t delayMs );
explicit ActionResult( Entity::CharaPtr target, uint64_t delayMs );
void damage( uint32_t amount, Common::ActionHitSeverityType severity, Common::ActionEffectResultFlag flag = Common::ActionEffectResultFlag::None );
void heal( uint32_t amount, Common::ActionHitSeverityType severity, Common::ActionEffectResultFlag flag = Common::ActionEffectResultFlag::None );
void restoreMP( uint32_t amount, Common::ActionEffectResultFlag flag = Common::ActionEffectResultFlag::None );
void damage( uint32_t amount, Common::ActionHitSeverityType severity, Common::ActionResultFlag flag = Common::ActionResultFlag::None );
void heal( uint32_t amount, Common::ActionHitSeverityType severity, Common::ActionResultFlag flag = Common::ActionResultFlag::None );
void restoreMP( uint32_t amount, Common::ActionResultFlag flag = Common::ActionResultFlag::None );
void startCombo( uint16_t actionId );
void comboSucceed();
void applyStatusEffect( uint16_t statusId, uint8_t param );

View file

@ -1,5 +1,5 @@
#include "EffectBuilder.h"
#include "EffectResult.h"
#include "ActionResultBuilder.h"
#include "ActionResult.h"
#include <Actor/Player.h>
@ -25,32 +25,33 @@ using namespace Sapphire::World::Manager;
using namespace Sapphire::Network::Packets;
using namespace Sapphire::Network::Packets::WorldPackets::Server;
EffectBuilder::EffectBuilder( Entity::CharaPtr source, uint32_t actionId, uint16_t requestId ) :
ActionResultBuilder::ActionResultBuilder( Entity::CharaPtr source, uint32_t actionId, uint32_t resultId, uint16_t requestId ) :
m_sourceChara( std::move( source ) ),
m_actionId( actionId ),
m_resultId( resultId ),
m_requestId( requestId )
{
}
uint64_t EffectBuilder::getResultDelayMs()
uint64_t ActionResultBuilder::getResultDelayMs()
{
// todo: actually figure this retarded shit out
return Common::Util::getTimeMs() + 850;
}
void EffectBuilder::addResultToActor( Entity::CharaPtr& chara, EffectResultPtr result )
void ActionResultBuilder::addResultToActor( Entity::CharaPtr& chara, ActionResultPtr result )
{
auto it = m_actorEffectsMap.find( chara->getId() );
if( it == m_actorEffectsMap.end() )
auto it = m_actorResultsMap.find( chara->getId() );
if( it == m_actorResultsMap.end() )
{
// create a new one
auto resultList = std::vector< EffectResultPtr >();
auto resultList = std::vector< ActionResultPtr >();
resultList.push_back( std::move( result ) );
m_actorEffectsMap[ chara->getId() ] = resultList;
m_actorResultsMap[ chara->getId() ] = resultList;
return;
}
@ -58,112 +59,107 @@ void EffectBuilder::addResultToActor( Entity::CharaPtr& chara, EffectResultPtr r
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 )
void ActionResultBuilder::heal( Entity::CharaPtr& effectTarget, Entity::CharaPtr& healingTarget, uint32_t amount, Common::ActionHitSeverityType severity, Common::ActionResultFlag flag )
{
EffectResultPtr nextResult = make_EffectResult( healingTarget, getResultDelayMs() );
ActionResultPtr nextResult = make_ActionResult( healingTarget, getResultDelayMs() );
nextResult->heal( amount, severity, flag );
addResultToActor( effectTarget, nextResult );
}
void EffectBuilder::restoreMP( Entity::CharaPtr& target, Entity::CharaPtr& restoringTarget, uint32_t amount, Common::ActionEffectResultFlag flag )
void ActionResultBuilder::restoreMP( Entity::CharaPtr& target, Entity::CharaPtr& restoringTarget, uint32_t amount, Common::ActionResultFlag flag )
{
EffectResultPtr nextResult = make_EffectResult( restoringTarget, getResultDelayMs() ); // restore mp source actor
ActionResultPtr nextResult = make_ActionResult( restoringTarget, getResultDelayMs() ); // restore mp source actor
nextResult->restoreMP( amount, flag );
addResultToActor( target, nextResult );
}
void EffectBuilder::damage( Entity::CharaPtr& effectTarget, Entity::CharaPtr& damagingTarget, uint32_t amount, Common::ActionHitSeverityType severity, Common::ActionEffectResultFlag flag )
void ActionResultBuilder::damage( Entity::CharaPtr& effectTarget, Entity::CharaPtr& damagingTarget, uint32_t amount, Common::ActionHitSeverityType severity, Common::ActionResultFlag flag )
{
EffectResultPtr nextResult = make_EffectResult( damagingTarget, getResultDelayMs() );
ActionResultPtr nextResult = make_ActionResult( damagingTarget, getResultDelayMs() );
nextResult->damage( amount, severity, flag );
addResultToActor( damagingTarget, nextResult );
}
void EffectBuilder::startCombo( Entity::CharaPtr& target, uint16_t actionId )
void ActionResultBuilder::startCombo( Entity::CharaPtr& target, uint16_t actionId )
{
EffectResultPtr nextResult = make_EffectResult( target, 0 );
ActionResultPtr nextResult = make_ActionResult( target, 0 );
nextResult->startCombo( actionId );
addResultToActor( target, nextResult );
}
void EffectBuilder::comboSucceed( Entity::CharaPtr& target )
void ActionResultBuilder::comboSucceed( Entity::CharaPtr& target )
{
EffectResultPtr nextResult = make_EffectResult( target, 0 );
ActionResultPtr nextResult = make_ActionResult( target, 0 );
nextResult->comboSucceed();
addResultToActor( target, nextResult );
}
void EffectBuilder::applyStatusEffect( Entity::CharaPtr& target, uint16_t statusId, uint8_t param )
void ActionResultBuilder::applyStatusEffect( Entity::CharaPtr& target, uint16_t statusId, uint8_t param )
{
EffectResultPtr nextResult = make_EffectResult( target, 0 );
ActionResultPtr nextResult = make_ActionResult( target, 0 );
nextResult->applyStatusEffect( statusId, param );
addResultToActor( target, nextResult );
}
void EffectBuilder::mount( Entity::CharaPtr& target, uint16_t mountId )
void ActionResultBuilder::mount( Entity::CharaPtr& target, uint16_t mountId )
{
EffectResultPtr nextResult = make_EffectResult( target, getResultDelayMs() );
ActionResultPtr nextResult = make_ActionResult( target, getResultDelayMs() );
nextResult->mount( mountId );
addResultToActor( target, nextResult );
}
void EffectBuilder::buildAndSendPackets( const std::vector< Entity::CharaPtr >& targetList )
void ActionResultBuilder::sendActionResults( const std::vector< Entity::CharaPtr >& targetList )
{
Logger::debug( "EffectBuilder result: " );
Logger::debug( "Targets afflicted: {}", targetList.size() );
do // we want to send at least one packet even nothing is hit so other players can see
{
auto packet = buildNextEffectPacket( targetList );
auto packet = createActionResultPacket( targetList );
server().queueForPlayers( m_sourceChara->getInRangePlayerIds( true ), packet );
}
while( !m_actorEffectsMap.empty() );
while( !m_actorResultsMap.empty() );
}
std::shared_ptr< FFXIVPacketBase > EffectBuilder::buildNextEffectPacket( const std::vector< Entity::CharaPtr >& targetList )
std::shared_ptr< FFXIVPacketBase > ActionResultBuilder::createActionResultPacket( const std::vector< Entity::CharaPtr >& targetList )
{
auto remainingTargetCount = targetList.size();
auto& taskMgr = Common::Service< World::Manager::TaskMgr >::ref();
auto& teriMgr = Common::Service< Sapphire::World::Manager::TerritoryMgr >::ref();
auto zone = teriMgr.getTerritoryByGuId( m_sourceChara->getTerritoryId() );
auto resultId = zone->getNextEffectResultId();
if( remainingTargetCount > 1 ) // use AoeEffect packets
{
auto effectPacket = std::make_shared< EffectPacket >( m_sourceChara->getId(), m_actionId );
auto effectPacket = std::make_shared< EffectPacket >( m_sourceChara->getId(), targetList[ 0 ]->getId(), m_actionId );
effectPacket->setRotation( Common::Util::floatToUInt16Rot( m_sourceChara->getRot() ) );
effectPacket->setRequestId( m_requestId );
effectPacket->setResultId( resultId );
effectPacket->setTargetActor( targetList[ 0 ]->getId() );
effectPacket->setResultId( m_resultId );
uint8_t targetIndex = 0;
for( auto it = m_actorEffectsMap.begin(); it != m_actorEffectsMap.end(); )
for( auto it = m_actorResultsMap.begin(); it != m_actorResultsMap.end(); )
{
// get all effect results for an actor
auto actorResultList = it->second;
for( auto i = 0; i < actorResultList.size(); ++i )
for( auto& result : actorResultList )
{
auto result = actorResultList.data()[ i ];
auto effect = result->getCalcResultParam();
// if effect result is a source/caster effect
if( result->getTarget() == m_sourceChara )
{
effectPacket->addSourceEffect( effect );
}
else
{
effectPacket->addTargetEffect( effect, result->getTarget()->getId() );
auto& taskMgr = Common::Service< World::Manager::TaskMgr >::ref();
taskMgr.queueTask( Sapphire::World::makeActionIntegrityTask( resultId, result->getTarget(), 1000 ) );
taskMgr.queueTask( Sapphire::World::makeActionIntegrityTask( m_resultId, result->getTarget(), 1000 ) );
}
zone->addEffectResult( std::move( result ) );
zone->addActionResult( std::move( result ) );
}
actorResultList.clear();
it = m_actorEffectsMap.erase( it );
it = m_actorResultsMap.erase( it );
targetIndex++;
if( targetIndex == 15 )
@ -181,38 +177,34 @@ std::shared_ptr< FFXIVPacketBase > EffectBuilder::buildNextEffectPacket( const s
auto effectPacket = std::make_shared< EffectPacket1 >( m_sourceChara->getId(), targetList[ 0 ]->getId(), m_actionId );
effectPacket->setRotation( Common::Util::floatToUInt16Rot( m_sourceChara->getRot() ) );
effectPacket->setRequestId( m_requestId );
effectPacket->setResultId( resultId );
effectPacket->setResultId( m_resultId );
for( auto it = m_actorEffectsMap.begin(); it != m_actorEffectsMap.end(); )
for( auto it = m_actorResultsMap.begin(); it != m_actorResultsMap.end(); )
{
// get all effect results for an actor
auto actorResultList = it->second;
for( auto i = 0; i < actorResultList.size(); ++i )
for( auto& result : actorResultList )
{
auto result = actorResultList.data()[ i ];
auto effect = result->getCalcResultParam();
// if effect result is a source/caster effect
if( result->getTarget() == m_sourceChara )
{
effectPacket->addSourceEffect( effect );
}
else
{
effectPacket->addTargetEffect( effect );
auto& taskMgr = Common::Service< World::Manager::TaskMgr >::ref();
taskMgr.queueTask( Sapphire::World::makeActionIntegrityTask( resultId, result->getTarget(), 1000 ) );
taskMgr.queueTask( Sapphire::World::makeActionIntegrityTask( m_resultId, result->getTarget(), 1000 ) );
}
zone->addEffectResult( std::move( result ) );
zone->addActionResult( std::move( result ) );
}
actorResultList.clear();
it = m_actorEffectsMap.erase( it );
it = m_actorResultsMap.erase( it );
}
m_actorEffectsMap.clear();
m_actorResultsMap.clear();
return effectPacket;
}
@ -227,9 +219,9 @@ std::shared_ptr< FFXIVPacketBase > EffectBuilder::buildNextEffectPacket( const s
effectPacket->data().DirTarget = Common::Util::floatToUInt16Rot( m_sourceChara->getRot() );
effectPacket->data().Flag = Common::ActionEffectDisplayType::HideActionName;
effectPacket->data().RequestId = m_requestId;
effectPacket->data().ResultId = resultId;
effectPacket->data().ResultId = m_resultId;
m_actorEffectsMap.clear();
m_actorResultsMap.clear();
return effectPacket;
}

View file

@ -5,21 +5,21 @@
namespace Sapphire::World::Action
{
class EffectBuilder
class ActionResultBuilder
{
public:
EffectBuilder( Entity::CharaPtr source, uint32_t actionId, uint16_t requestId );
ActionResultBuilder( Entity::CharaPtr source, uint32_t actionId, uint32_t resultId, uint16_t requestId );
void heal( Entity::CharaPtr& effectTarget, Entity::CharaPtr& healingTarget, uint32_t amount,
Common::ActionHitSeverityType severity = Common::ActionHitSeverityType::NormalHeal,
Common::ActionEffectResultFlag flag = Common::ActionEffectResultFlag::None );
Common::ActionResultFlag flag = Common::ActionResultFlag::None );
void restoreMP( Entity::CharaPtr& effectTarget, Entity::CharaPtr& restoringTarget, uint32_t amount,
Common::ActionEffectResultFlag flag = Common::ActionEffectResultFlag::None );
Common::ActionResultFlag flag = Common::ActionResultFlag::None );
void damage( Entity::CharaPtr& effectTarget, Entity::CharaPtr& damagingTarget, uint32_t amount,
Common::ActionHitSeverityType severity = Common::ActionHitSeverityType::NormalDamage,
Common::ActionEffectResultFlag flag = Common::ActionEffectResultFlag::None );
Common::ActionResultFlag flag = Common::ActionResultFlag::None );
void startCombo( Entity::CharaPtr& target, uint16_t actionId );
@ -29,21 +29,22 @@ namespace Sapphire::World::Action
void mount( Entity::CharaPtr& target, uint16_t mountId );
void buildAndSendPackets( const std::vector< Entity::CharaPtr >& targetList );
void sendActionResults( const std::vector< Entity::CharaPtr >& targetList );
private:
void addResultToActor( Entity::CharaPtr& chara, EffectResultPtr result );
void addResultToActor( Entity::CharaPtr& chara, ActionResultPtr result );
uint64_t getResultDelayMs();
Network::Packets::FFXIVPacketBasePtr buildNextEffectPacket( const std::vector< Entity::CharaPtr >& targetList );
Network::Packets::FFXIVPacketBasePtr createActionResultPacket( const std::vector< Entity::CharaPtr >& targetList );
private:
uint32_t m_actionId;
uint16_t m_requestId;
uint32_t m_resultId;
Entity::CharaPtr m_sourceChara;
std::unordered_map< uint32_t, std::vector< EffectResultPtr > > m_actorEffectsMap;
std::unordered_map< uint32_t, std::vector< ActionResultPtr > > m_actorResultsMap;
};
}

View file

@ -81,9 +81,8 @@ void ItemAction::handleVFXItem()
effect.Type = Common::ActionEffectType::CALC_RESULT_TYPE_CHECK_BARRIER;
effect.Value = m_itemAction->data().Calcu0Arg[ 0 ];
auto effectPacket = std::make_shared< EffectPacket >( getSourceChara()->getId(), getId() );
effectPacket->setTargetActor( getSourceChara()->getId() );
effectPacket->setAnimationId( Common::ItemActionType::ItemActionVFX );
auto effectPacket = std::make_shared< EffectPacket >( getSourceChara()->getId(), getSourceChara()->getId(), getId() );
effectPacket->setActionId( Common::ItemActionType::ItemActionVFX );
effectPacket->setDisplayType( Common::ActionEffectDisplayType::ShowItemName );
effectPacket->addTargetEffect( effect, static_cast< uint64_t >( getSourceChara()->getId() ) );
server().queueForPlayers( m_pSource->getInRangePlayerIds( true ), effectPacket );

View file

@ -40,7 +40,7 @@ void ItemManipulationAction::execute()
{
assert( m_pSource );
m_effectBuilder->buildAndSendPackets( m_hitActors );
m_actionResultBuilder->sendActionResults( m_hitActors );
}
void ItemManipulationAction::onFinish()

View file

@ -69,6 +69,6 @@ void MountAction::execute()
assert( m_pSource );
m_pSource->getAsPlayer()->removeCondition( Common::PlayerCondition::Casting );
m_effectBuilder->mount( m_pSource, m_mountId );
m_effectBuilder->buildAndSendPackets( { m_pSource } );
m_actionResultBuilder->mount( m_pSource, m_mountId );
m_actionResultBuilder->sendActionResults( { m_pSource } );
}

View file

@ -327,7 +327,7 @@ void BNpc::spawn( PlayerPtr pTarget )
void BNpc::despawn( PlayerPtr pTarget )
{
pTarget->freePlayerSpawnId( getId() );
Network::Util::Packet::sendActorControl( *pTarget, WarpStart, 4, getId(), 1 );
Network::Util::Packet::sendActorControlSelf( *pTarget, getId(), WarpStart, 4, getId(), 1 );
}
BNpcState BNpc::getState() const
@ -935,7 +935,7 @@ void BNpc::setOwner( const CharaPtr& m_pChara )
server().queueForPlayers( getInRangePlayerIds(), setOwnerPacket );
if( m_pChara && m_pChara->isPlayer() )
Network::Util::Packet::sendActorControl( *m_pChara->getAsPlayer(), SetHateLetter, 1, getId(), 0 );
Network::Util::Packet::sendActorControl( *m_pChara->getAsPlayer(), getId(), SetHateLetter, 1, getId(), 0 );
}

View file

@ -457,7 +457,7 @@ void Player::registerAetheryte( uint8_t aetheryteId )
Util::valueToFlagByteIndexValue( aetheryteId, value, index );
m_aetheryte[ index ] |= value;
Network::Util::Packet::sendActorControlSelf( *this, LearnTeleport, aetheryteId, 1 );
Network::Util::Packet::sendActorControlSelf( *this, getId(), LearnTeleport, aetheryteId, 1 );
}
bool Player::isAetheryteRegistered( uint8_t aetheryteId ) const
@ -560,7 +560,7 @@ void Player::setRewardFlag( Common::UnlockEntry unlockId )
m_unlocks[ index ] |= value;
Network::Util::Packet::sendActorControlSelf( *this, SetRewardFlag, unlock, 1 );
Network::Util::Packet::sendActorControlSelf( *this, getId(), SetRewardFlag, unlock, 1 );
}
void Player::learnSong( uint8_t songId, uint32_t itemId )
@ -571,7 +571,7 @@ void Player::learnSong( uint8_t songId, uint32_t itemId )
m_orchestrion[ index ] |= value;
Network::Util::Packet::sendActorControlSelf( *this, ToggleOrchestrionUnlock, songId, 1, itemId );
Network::Util::Packet::sendActorControlSelf( *this, getId(), ToggleOrchestrionUnlock, songId, 1, itemId );
}
bool Player::hasReward( Common::UnlockEntry unlockId ) const
@ -608,7 +608,7 @@ void Player::gainExp( uint32_t amount )
{
setExp( 0 );
if( currentExp != 0 )
Network::Util::Packet::sendActorControlSelf( *this, UpdateUiExp, currentClass, 0 );
Network::Util::Packet::sendActorControlSelf( *this, getId(), UpdateUiExp, currentClass, 0 );
return;
}
@ -632,8 +632,8 @@ void Player::gainExp( uint32_t amount )
else
setExp( currentExp + amount );
Network::Util::Packet::sendActorControlSelf( *this, GainExpMsg, currentClass, amount );
Network::Util::Packet::sendActorControlSelf( *this, UpdateUiExp, currentClass, getExp() );
Network::Util::Packet::sendActorControlSelf( *this, getId(), GainExpMsg, currentClass, amount );
Network::Util::Packet::sendActorControlSelf( *this, getId(), UpdateUiExp, currentClass, getExp() );
}
void Player::levelUp()
@ -745,7 +745,7 @@ void Player::setLevelForClass( uint8_t level, Common::ClassJob classjob )
m_classArray[ classJobIndex ] = level;
Network::Util::Packet::sendActorControlSelf( *this, ClassJobUpdate, static_cast< uint8_t >( classjob ), getLevelForClass( classjob ) );
Network::Util::Packet::sendActorControlSelf( *this, getId(), ClassJobUpdate, static_cast< uint8_t >( classjob ), getLevelForClass( classjob ) );
auto& achvMgr = Common::Service< World::Manager::AchievementMgr >::ref();
achvMgr.progressAchievementByType< Common::Achievement::Type::Classjob >( *this, static_cast< uint32_t >( classjob ) );
@ -818,7 +818,7 @@ void Player::despawn( Entity::PlayerPtr pTarget )
Logger::debug( "Despawning {0} for {1}", getName(), pTarget->getName() );
pPlayer->freePlayerSpawnId( getId() );
Network::Util::Packet::sendActorControlSelf( *this, WarpStart, 4, getId(), 1 );
Network::Util::Packet::sendActorControlSelf( *this, getId(), WarpStart, 4, getId(), 1 );
}
GameObjectPtr Player::lookupTargetById( uint64_t targetId )
@ -953,7 +953,7 @@ Player::AetheryteList& Player::getAetheryteArray()
void Player::setHomepoint( uint8_t aetheryteId )
{
m_homePoint = aetheryteId;
Network::Util::Packet::sendActorControlSelf( *this, SetHomepoint, aetheryteId );
Network::Util::Packet::sendActorControlSelf( *this, getId(), SetHomepoint, aetheryteId );
}
/*! get homepoint */
@ -1002,7 +1002,7 @@ void Player::unlockMount( uint32_t mountId )
m_mountGuide[ mount->data().MountOrder / 8 ] |= ( 1 << ( mount->data().MountOrder % 8 ) );
Network::Util::Packet::sendActorControlSelf( *this, SetMountBitmask, mount->data().MountOrder, 1 );
Network::Util::Packet::sendActorControlSelf( *this, getId(), SetMountBitmask, mount->data().MountOrder, 1 );
}
void Player::unlockCompanion( uint32_t companionId )
@ -1019,7 +1019,7 @@ void Player::unlockCompanion( uint32_t companionId )
m_minionGuide[ index ] |= value;
Network::Util::Packet::sendActorControlSelf( *this, LearnCompanion, companionId, 1 );
Network::Util::Packet::sendActorControlSelf( *this, getId(), LearnCompanion, companionId, 1 );
}
Player::MinionList& Player::getMinionGuideBitmask()
@ -1144,14 +1144,14 @@ const std::map< uint32_t, uint8_t >& Player::getActorIdToHateSlotMap()
void Player::onMobAggro( const BNpc& bnpc )
{
hateListAdd( bnpc );
Network::Util::Packet::sendActorControl( *this, SetBattle, 1 );
Network::Util::Packet::sendActorControl( *this, getId(), SetBattle, 1 );
}
void Player::onMobDeaggro( const BNpc& bnpc )
{
hateListRemove( bnpc );
if( m_actorIdTohateSlotMap.empty() )
Network::Util::Packet::sendActorControl( *this, SetBattle, 0 );
Network::Util::Packet::sendActorControl( *this, getId(), SetBattle, 0 );
}
bool Player::isLogin() const
@ -1209,7 +1209,7 @@ void Player::setAchievementData( const Player::AchievementData& achievementData
void Player::setMaxGearSets( uint8_t amount )
{
m_equippedMannequin = amount;
Network::Util::Packet::sendActorControlSelf( *this, SetMaxGearSets, m_equippedMannequin );
Network::Util::Packet::sendActorControlSelf( *this, getId(), SetMaxGearSets, m_equippedMannequin );
}
void Player::addGearSet()
@ -1418,7 +1418,7 @@ void Player::teleportQuery( uint16_t aetheryteId )
cost = std::min< uint16_t >( 999, cost );
bool insufficientGil = getCurrency( Common::CurrencyType::Gil ) < cost;
Network::Util::Packet::sendActorControlSelf( *this, OnExecuteTelepo, insufficientGil ? 2 : 0, aetheryteId );
Network::Util::Packet::sendActorControlSelf( *this, getId(), OnExecuteTelepo, insufficientGil ? 2 : 0, aetheryteId );
if( !insufficientGil )
{
@ -1493,7 +1493,7 @@ void Player::dyeItemFromDyeingInfo()
insertInventoryItem( static_cast< Sapphire::Common::InventoryType >( itemToDyeContainer ), static_cast< uint16_t >( itemToDyeSlot ), itemToDye );
writeItem( itemToDye );
Network::Util::Packet::sendActorControlSelf( *this, DyeMsg, itemToDye->getId(), shouldDye, invalidateGearSet );
Network::Util::Packet::sendActorControlSelf( *this, getId(), DyeMsg, itemToDye->getId(), shouldDye, invalidateGearSet );
}
void Player::setGlamouringInfo( uint32_t itemToGlamourContainer, uint32_t itemToGlamourSlot, uint32_t glamourBagContainer, uint32_t glamourBagSlot, bool shouldGlamour )
@ -1547,9 +1547,9 @@ void Player::glamourItemFromGlamouringInfo()
writeItem( itemToGlamour );
if( shouldGlamour )
Network::Util::Packet::sendActorControlSelf( *this, GlamourCastMsg, itemToGlamour->getId(), glamourToUse->getId(), invalidateGearSet );
Network::Util::Packet::sendActorControlSelf( *this, getId(), GlamourCastMsg, itemToGlamour->getId(), glamourToUse->getId(), invalidateGearSet );
else
Network::Util::Packet::sendActorControlSelf( *this, GlamourRemoveMsg, itemToGlamour->getId(), invalidateGearSet );
Network::Util::Packet::sendActorControlSelf( *this, getId(), GlamourRemoveMsg, itemToGlamour->getId(), invalidateGearSet );
}
void Player::resetObjSpawnIndex()
@ -1634,7 +1634,7 @@ void Player::updateHuntingLog( uint16_t id )
if( note1->data().Monster == id && logEntry.entries[ i - 1 ][ x ] < note->data().NeededKills[ x ] )
{
logEntry.entries[ i - 1 ][ x ]++;
Network::Util::Packet::sendActorControlSelf( *this, HuntingLogEntryUpdate, monsterNoteId, x, logEntry.entries[ i - 1 ][ x ] );
Network::Util::Packet::sendActorControlSelf( *this, getId(), HuntingLogEntryUpdate, monsterNoteId, x, logEntry.entries[ i - 1 ][ x ] );
logChanged = true;
sectionChanged = true;
}
@ -1643,7 +1643,7 @@ void Player::updateHuntingLog( uint16_t id )
}
if( logChanged && sectionComplete && sectionChanged )
{
Network::Util::Packet::sendActorControlSelf( *this, HuntingLogSectionFinish, monsterNoteId, i, 0 );
Network::Util::Packet::sendActorControlSelf( *this, getId(), HuntingLogSectionFinish, monsterNoteId, i, 0 );
gainExp( note->data().RewardExp );
}
if( !sectionComplete )
@ -1653,13 +1653,13 @@ void Player::updateHuntingLog( uint16_t id )
}
if( logChanged && allSectionsComplete )
{
Network::Util::Packet::sendActorControlSelf( *this, HuntingLogRankFinish, 4 );
Network::Util::Packet::sendActorControlSelf( *this, getId(), HuntingLogRankFinish, 4 );
gainExp( rankRewards[ logEntry.rank ] );
if( logEntry.rank < 4 )
{
logEntry.rank++;
memset( logEntry.entries, 0, 40 );
Network::Util::Packet::sendActorControlSelf( *this, HuntingLogRankUnlock, currentClassId, logEntry.rank + 1, 0 );
Network::Util::Packet::sendActorControlSelf( *this, getId(), HuntingLogRankUnlock, currentClassId, logEntry.rank + 1, 0 );
}
}

View file

@ -229,7 +229,7 @@ void Player::equipItem( Common::GearSetSlot equipSlotId, Item& item, bool sendUp
if( sendUpdate )
{
Network::Util::Packet::sendEquip( *this );
Network::Util::Packet::sendActorControl( *this, SetItemLevel, getItemLevel() );
Network::Util::Packet::sendActorControl( *this, getId(), SetItemLevel, getItemLevel() );
Network::Util::Packet::sendBaseParams( *this );
Network::Util::Packet::sendHudParam( *this );
}
@ -251,7 +251,7 @@ void Player::unequipItem( Common::GearSetSlot equipSlotId, Item& item, bool send
if( sendUpdate )
{
Network::Util::Packet::sendEquip( *this );
Network::Util::Packet::sendActorControl( *this, SetItemLevel, getItemLevel() );
Network::Util::Packet::sendActorControl( *this, getId(), SetItemLevel, getItemLevel() );
Network::Util::Packet::sendBaseParams( *this );
Network::Util::Packet::sendHudParam( *this );
}

View file

@ -85,7 +85,7 @@ void Sapphire::Event::Director::sendEventLogMessage( Sapphire::Entity::Player& p
void Sapphire::Event::Director::sendDirectorClear( Sapphire::Entity::Player& player ) const
{
Network::Util::Packet::sendActorControlSelf( player, DirectorClear, m_directorId );
Network::Util::Packet::sendActorControlSelf( player, player.getId(), DirectorClear, m_directorId );
}
void Sapphire::Event::Director::sendDirectorVars( Sapphire::Entity::Player& player ) const
@ -103,7 +103,7 @@ void Sapphire::Event::Director::sendDirectorVars( Sapphire::Entity::Player& play
void Sapphire::Event::Director::sendDirectorInit( Sapphire::Entity::Player& player ) const
{
Logger::debug( "[{}] directorInit: directorId#{}, contextId#{}", player.getId(), m_directorId, m_contextId );
Network::Util::Packet::sendActorControlSelf( player, DirectorInit, m_directorId, m_contextId );
Network::Util::Packet::sendActorControlSelf( player, player.getId(), DirectorInit, m_directorId, m_contextId );
}
Sapphire::Event::Director::DirectorType Sapphire::Event::Director::getType() const

View file

@ -88,8 +88,8 @@ TYPE_FORWARD( ItemAction );
TYPE_FORWARD( EventItemAction );
TYPE_FORWARD( MountAction );
TYPE_FORWARD( ItemManipulationAction );
TYPE_FORWARD( EffectBuilder );
TYPE_FORWARD( EffectResult );
TYPE_FORWARD( ActionResultBuilder );
TYPE_FORWARD( ActionResult );
using ActionCallback = std::function< void( Entity::Player&, uint32_t, uint64_t ) >;
}

View file

@ -70,8 +70,8 @@ void AchievementMgr::unlockAchievement( Entity::Player& player, uint32_t achieve
// fire packets
player.setAchievementData( achvData );
Network::Util::Packet::sendAchievementList( player );
Network::Util::Packet::sendActorControl( player, AchievementComplete, achievementId );
Network::Util::Packet::sendActorControl( player, AchievementObtainMsg, achievementId );
Network::Util::Packet::sendActorControl( player, player.getId(), AchievementComplete, achievementId );
Network::Util::Packet::sendActorControl( player, player.getId(), AchievementObtainMsg, achievementId );
// check and add title to player
auto achvTitleId = achvExd->data().Title;

View file

@ -65,7 +65,6 @@ void ActionMgr::handleTargetedPlayerAction( Entity::Player& player, uint32_t act
auto action = Action::make_Action( player.getAsPlayer(), actionId, requestId, actionData );
action->setTargetId( targetId );
action->setPos( player.getPos() );
if( !action->init() )
@ -147,9 +146,7 @@ void ActionMgr::bootstrapAction( Entity::Player& player, Action::ActionPtr curre
{
// if we have a cast time we want to associate the action with the player so update is called
if( currentAction->hasCastTime() )
{
player.setCurrentAction( currentAction );
}
// todo: what do in cases of swiftcast/etc? script callback?
currentAction->start();

View file

@ -529,9 +529,8 @@ void DebugCommandMgr::add( char* data, Entity::Player& player, std::shared_ptr<
uint16_t param1;
sscanf( params.c_str(), "%hu", &param1 );
auto effectPacket = std::make_shared< EffectPacket >( player.getId(), param1 );
auto effectPacket = std::make_shared< EffectPacket >( player.getId(), static_cast< uint32_t >( player.getTargetId() ), param1 );
effectPacket->setRotation( Common::Util::floatToUInt16Rot( player.getRot() ) );
effectPacket->setTargetActor( static_cast< uint32_t >( player.getTargetId() ) );
Common::CalcResultParam entry{};
entry.Value = static_cast< int16_t >( param1 );

View file

@ -434,7 +434,7 @@ bool HousingMgr::relinquishLand( Entity::Player& player, HousingZone& zone, uint
// TODO: actually use permissions here for FC houses
if( !pLand || !hasPermission( player, *pLand, 0 ) )
{
Network::Util::Packet::sendActorControlSelf( player, ActorControl::LogMsg, 3304 );
Network::Util::Packet::sendActorControlSelf( player, player.getId(), ActorControl::LogMsg, 3304 );
return false;
}
@ -442,7 +442,7 @@ bool HousingMgr::relinquishLand( Entity::Player& player, HousingZone& zone, uint
// TODO: additionally check for yard items
if( pLand->getHouse() )
{
Network::Util::Packet::sendActorControlSelf( player, ActorControl::LogMsg, 3315 );
Network::Util::Packet::sendActorControlSelf( player, player.getId(), ActorControl::LogMsg, 3315 );
return false;
}
@ -458,7 +458,7 @@ bool HousingMgr::relinquishLand( Entity::Player& player, HousingZone& zone, uint
sendLandFlagsSlot( player, Common::LandFlagsSlot::Private );
Network::Util::Packet::sendActorControlSelf( player, ActorControl::LogMsg, 3351, 0x1AA, pLand->getLandIdent().wardNum + 1, plot + 1 );
Network::Util::Packet::sendActorControlSelf( player, player.getId(), ActorControl::LogMsg, 3351, 0x1AA, pLand->getLandIdent().wardNum + 1, plot + 1 );
zone.sendLandUpdate( plot );
return true;
}
@ -700,7 +700,7 @@ void HousingMgr::buildPresetEstate( Entity::Player& player, HousingZone& zone, u
pLand->setLandType( Common::LandType::Private );
zone.sendLandUpdate( plotNum );
Network::Util::Packet::sendActorControl( player, ActorControl::BuildPresetResponse, plotNum );
Network::Util::Packet::sendActorControl( player, player.getId(), ActorControl::BuildPresetResponse, plotNum );
pLand->updateLandDb();
@ -1043,7 +1043,7 @@ void HousingMgr::reqPlaceHousingItem( Entity::Player& player, uint16_t landId, u
status = placeInteriorItem( player, item );
if( status )
Network::Util::Packet::sendActorControlSelf( player, 0x3f3 );
Network::Util::Packet::sendActorControlSelf( player, player.getId(), 0x3f3 );
else
PlayerMgr::sendUrgent( player, "An internal error occurred when placing the item." );
}
@ -1318,7 +1318,7 @@ bool HousingMgr::moveInternalItem( Entity::Player& player, Common::LandIdent ide
// send confirmation to player
uint32_t param1 = static_cast< uint32_t >( ( ident.landId << 16 ) | containerId );
Network::Util::Packet::sendActorControlSelf( player, ActorControl::HousingItemMoveConfirm, param1, slotIdx );
Network::Util::Packet::sendActorControlSelf( player, player.getId(), ActorControl::HousingItemMoveConfirm, param1, slotIdx );
return true;
}
@ -1351,7 +1351,7 @@ bool HousingMgr::moveExternalItem( Entity::Player& player, Common::LandIdent ide
terri.updateYardObjectPos( player, slot, static_cast< uint16_t >( ident.landId ), *item );
uint32_t param1 = static_cast< uint32_t >( ( ident.landId << 16 ) | Common::InventoryType::HousingExteriorPlacedItems );
Network::Util::Packet::sendActorControlSelf( player, ActorControl::HousingItemMoveConfirm, param1, slot );
Network::Util::Packet::sendActorControlSelf( player, player.getId(), ActorControl::HousingItemMoveConfirm, param1, slot );
return true;
}
@ -1581,7 +1581,7 @@ void HousingMgr::reqEstateExteriorRemodel( Entity::Player& player, uint16_t plot
invMgr.sendInventoryContainer( player, it->second );
Network::Util::Packet::sendActorControlSelf( player, ActorControl::ShowEstateExternalAppearanceUI, plot );
Network::Util::Packet::sendActorControlSelf( player, player.getId(), ActorControl::ShowEstateExternalAppearanceUI, plot );
}
void HousingMgr::reqEstateInteriorRemodel( Entity::Player& player )
@ -1618,7 +1618,7 @@ void HousingMgr::reqEstateInteriorRemodel( Entity::Player& player )
invMgr.sendInventoryContainer( player, it->second );
Network::Util::Packet::sendActorControlSelf( player, ActorControl::ShowEstateInternalAppearanceUI );
Network::Util::Packet::sendActorControlSelf( player, player.getId(), ActorControl::ShowEstateInternalAppearanceUI );
}
bool HousingMgr::hasPermission( Entity::Player& player, Sapphire::Land& land, uint32_t permission )
@ -1661,7 +1661,7 @@ void HousingMgr::removeHouse( Entity::Player& player, uint16_t plot )
// TODO: actually use permissions here for FC houses
if( !hasPermission( player, *pLand, 0 ) )
{
Network::Util::Packet::sendActorControlSelf( player, ActorControl::LogMsg, 3305 );
Network::Util::Packet::sendActorControlSelf( player, player.getId(), ActorControl::LogMsg, 3305 );
return;
}

View file

@ -254,8 +254,8 @@ void PlayerMgr::onMoveZone( Sapphire::Entity::Player& player )
if( player.isLogin() )
{
Network::Util::Packet::sendActorControlSelf( player, SetConfigFlags, player.getConfigFlags(), 1 );
Network::Util::Packet::sendActorControlSelf( player, SetMaxGearSets, player.getMaxGearSets() );
Network::Util::Packet::sendActorControlSelf( player, player.getId(), SetConfigFlags, player.getConfigFlags(), 1 );
Network::Util::Packet::sendActorControlSelf( player, player.getId(), SetMaxGearSets, player.getMaxGearSets() );
}
// set flags, will be reset automatically by zoning ( only on client side though )
@ -269,11 +269,11 @@ void PlayerMgr::onMoveZone( Sapphire::Entity::Player& player )
Network::Util::Packet::sendRecastGroups( player );
Network::Util::Packet::sendBaseParams( player );
Network::Util::Packet::sendActorControl( player, SetItemLevel, player.getItemLevel() );
Network::Util::Packet::sendActorControl( player, player.getId(), SetItemLevel, player.getItemLevel() );
if( player.isLogin() )
{
Network::Util::Packet::sendChangeClass( player );
Network::Util::Packet::sendActorControl( player, 0x112, 0x24 ); // unknown
Network::Util::Packet::sendActorControl( player, player.getId(), 0x112, 0x24 ); // unknown
Network::Util::Packet::sendContentAttainFlags( player );
player.clearSoldItems();
}
@ -362,5 +362,5 @@ void PlayerMgr::sendDebug( Entity::Player& player, const std::string& message )
void PlayerMgr::sendLogMessage( Entity::Player& player, uint32_t messageId, uint32_t param2, uint32_t param3,
uint32_t param4, uint32_t param5, uint32_t param6 )
{
Network::Util::Packet::sendActorControlTarget( player, LogMsg, messageId, param2, param3, param4, param5, param6 );
Network::Util::Packet::sendActorControlTarget( player, player.getId(), LogMsg, messageId, param2, param3, param4, param5, param6 );
}

View file

@ -129,7 +129,7 @@ void WarpMgr::finishWarp( Entity::Player& player )
if( !player.getGmInvis() )
Network::Util::Packet::sendActorControlSelf( player.getInRangePlayerIds(), player.getId(), Appear, warpFinishAnim, raiseAnim );
Network::Util::Packet::sendActorControlSelf( player, Appear, warpFinishAnim, raiseAnim );
Network::Util::Packet::sendActorControlSelf( player, player.getId(), Appear, warpFinishAnim, raiseAnim );
Network::Util::Packet::sendActorControl( player.getInRangePlayerIds( true ), player.getId(), SetStatus, static_cast< uint8_t >( Common::ActorStatus::Idle ) );
player.removeCondition( PlayerCondition::BetweenAreas );

View file

@ -388,7 +388,7 @@ void examineHandler( Sapphire::Entity::Player& player, uint32_t targetId )
return;
if( pPlayer->isActingAsGm() || pPlayer->getTerritoryTypeId() != player.getTerritoryTypeId() )
Network::Util::Packet::sendActorControl( player, ExamineError );
Network::Util::Packet::sendActorControl( player, player.getId(), ExamineError );
else
server().queueForPlayer( player.getCharacterId(), std::make_shared< InspectPacket >( player, pPlayer ) );
}
@ -498,7 +498,7 @@ void Sapphire::Network::GameConnection::commandHandler( const Packets::FFXIVARR_
}
case PacketCommand::SET_CUTSCENE:
{
Network::Util::Packet::sendActorControl( player, SetCutsceneFlag, data.Arg0, 1 );
Network::Util::Packet::sendActorControl( player, player.getId(), SetCutsceneFlag, data.Arg0, 1 );
break;
}
case PacketCommand::EMOTE: // emote
@ -597,7 +597,7 @@ void Sapphire::Network::GameConnection::commandHandler( const Packets::FFXIVARR_
auto achievementId = data.Arg0;
auto& achvMgr = Common::Service< AchievementMgr >::ref();
auto achvProgress = achvMgr.getAchievementDataById( player, achievementId );
Network::Util::Packet::sendActorControl( player, AchievementSetRate, achievementId, achvProgress.first, achvProgress.second );
Network::Util::Packet::sendActorControl( player, player.getId(), AchievementSetRate, achievementId, achvProgress.first, achvProgress.second );
break;
}
case PacketCommand::ACHIEVEMENT_REQUEST:
@ -663,7 +663,7 @@ void Sapphire::Network::GameConnection::commandHandler( const Packets::FFXIVARR_
player.setActiveLand( static_cast< uint8_t >( data.Arg0 ), hZone->getWardNum() );
Network::Util::Packet::sendActorControl( player, ShowBuildPresetUI, data.Arg0 );
Network::Util::Packet::sendActorControl( player, player.getId(), ShowBuildPresetUI, data.Arg0 );
break;
}
case PacketCommand::HOUSING_AUCTION_INFO:
@ -741,7 +741,7 @@ void Sapphire::Network::GameConnection::commandHandler( const Packets::FFXIVARR_
uint8_t ward = ( data.Arg1 >> 16 ) & 0xFF;
uint8_t plot = ( data.Arg1 & 0xFF );
Network::Util::Packet::sendActorControl( player, ShowHousingItemUI, 0, plot );
Network::Util::Packet::sendActorControl( player, player.getId(), ShowHousingItemUI, 0, plot );
//TODO: show item housing container
break;

View file

@ -615,7 +615,7 @@ void Sapphire::Network::GameConnection::gearSetEquip( const Packets::FFXIVARR_PA
player.sendGearInventory();
if( packet.data().contextId < 0xFE )
Network::Util::Packet::sendActorControlSelf( player, GearSetEquipMsg, packet.data().contextId );
Network::Util::Packet::sendActorControlSelf( player, player.getId(), GearSetEquipMsg, packet.data().contextId );
auto invTransFinPacket = makeZonePacket< FFXIVIpcItemOperationBatch >( player.getId() );
invTransFinPacket->data().contextId = contextId;

View file

@ -13,15 +13,15 @@ namespace Sapphire::Network::Packets::WorldPackets::Server
class EffectPacket : public ZoneChannelPacket< FFXIVIpcActionResult >
{
public:
EffectPacket( uint64_t sourceId, uint32_t actionId ) :
ZoneChannelPacket< FFXIVIpcActionResult >( static_cast< uint32_t >( sourceId ) )
EffectPacket( uint64_t sourceId, uint32_t mainTarget, uint32_t actionId ) :
ZoneChannelPacket< FFXIVIpcActionResult >( static_cast< uint32_t >( sourceId ), mainTarget )
{
m_data.Flag = 0;
m_data.ActionKey = actionId;
m_data.Action = static_cast< uint16_t >( actionId );
m_data.ActionKind = 1;
m_data.MainTarget = Common::INVALID_GAME_OBJECT_ID;
m_data.MainTarget = static_cast< uint64_t >( mainTarget );
m_data.BallistaEntityId = Common::INVALID_GAME_OBJECT_ID;
m_data.LockTime = 0.6f;
@ -58,9 +58,9 @@ namespace Sapphire::Network::Packets::WorldPackets::Server
std::memcpy( &m_data.CalcResult[ m_data.TargetCount - 1 ].CalcResultCt[ m_sourceEffectCount++ ], &effect, sizeof( Common::CalcResultParam ) );
}
void setAnimationId( uint16_t animationId )
void setActionId( uint16_t actionId )
{
m_data.Action = animationId;
m_data.Action = actionId;
}
void setDisplayType( Common::ActionEffectDisplayType displayType )
@ -78,13 +78,6 @@ namespace Sapphire::Network::Packets::WorldPackets::Server
m_data.DirTarget = rotation;
}
void setTargetActor( const uint32_t targetId )
{
m_data.MainTarget = static_cast< uint64_t >( targetId );
FFXIVPacketBase::setTargetActor( targetId );
}
void setRequestId( uint16_t requestId )
{
m_data.RequestId = static_cast< uint32_t >( requestId );

View file

@ -130,10 +130,10 @@ void Util::Packet::sendHuntingLog( Entity::Player& player )
}
}
void Util::Packet::sendActorControlSelf( Entity::Player& player, uint16_t category, uint32_t param1, uint32_t param2, uint32_t param3,
void Util::Packet::sendActorControlSelf( Entity::Player& player, uint32_t srcId, uint16_t category, uint32_t param1, uint32_t param2, uint32_t param3,
uint32_t param4, uint32_t param5 )
{
server().queueForPlayer( player.getCharacterId(), makeActorControlSelf( player.getId(), category, param1, param2, param3, param4, param5 ) );
server().queueForPlayer( player.getCharacterId(), makeActorControlSelf( srcId, category, param1, param2, param3, param4, param5 ) );
}
void Util::Packet::sendActorControlSelf( const std::set< uint64_t >& characterIds, uint32_t srcId, uint16_t category, uint32_t param1,
@ -142,9 +142,9 @@ void Util::Packet::sendActorControlSelf( const std::set< uint64_t >& characterId
server().queueForPlayers( characterIds, makeActorControlSelf( srcId, category, param1, param2, param3, param4, param5 ) );
}
void Util::Packet::sendActorControl( Entity::Player& player, uint16_t category, uint32_t param1, uint32_t param2, uint32_t param3, uint32_t param4 )
void Util::Packet::sendActorControl( Entity::Player& player, uint32_t srcId, uint16_t category, uint32_t param1, uint32_t param2, uint32_t param3, uint32_t param4 )
{
server().queueForPlayer( player.getCharacterId(), makeActorControl( player.getId(), category, param1, param2, param3, param4 ) );
server().queueForPlayer( player.getCharacterId(), makeActorControl( srcId, category, param1, param2, param3, param4 ) );
}
void Util::Packet::sendActorControl( const std::set< uint64_t >& characterIds, uint32_t srcId, uint16_t category, uint32_t param1,
@ -153,10 +153,10 @@ void Util::Packet::sendActorControl( const std::set< uint64_t >& characterIds, u
server().queueForPlayers( characterIds, makeActorControl( srcId, category, param1, param2, param3, param4 ) );
}
void Util::Packet::sendActorControlTarget( Entity::Player& player, uint16_t category, uint32_t param1, uint32_t param2, uint32_t param3,
void Util::Packet::sendActorControlTarget( Entity::Player& player, uint32_t srcId, uint16_t category, uint32_t param1, uint32_t param2, uint32_t param3,
uint32_t param4, uint32_t param5, uint32_t param6 )
{
server().queueForPlayer( player.getCharacterId(), makeActorControlTarget( player.getId(), category, param1, param2, param3, param4, param5, param6 ) );
server().queueForPlayer( player.getCharacterId(), makeActorControlTarget( srcId, category, param1, param2, param3, param4, param5, param6 ) );
}
void Util::Packet::sendActorControlTarget( const std::set< uint64_t >& characterIds, uint32_t srcId, uint16_t category, uint32_t param1,

View file

@ -52,18 +52,18 @@ namespace Sapphire::Network::Util::Packet
void sendChat( Entity::Player& player, Common::ChatType chatType, const std::string& message );
void sendActorControlSelf( Entity::Player& player, uint16_t category, uint32_t param1 = 0, uint32_t param2 = 0, uint32_t param3 = 0,
void sendActorControlSelf( Entity::Player& player, uint32_t srcId, uint16_t category, uint32_t param1 = 0, uint32_t param2 = 0, uint32_t param3 = 0,
uint32_t param4 = 0, uint32_t param5 = 0 );
void sendActorControlSelf( const std::set< uint64_t >& characterIds, uint32_t srcId, uint16_t category, uint32_t param1 = 0,
uint32_t param2 = 0, uint32_t param3 = 0, uint32_t param4 = 0, uint32_t param5 = 0 );
void sendActorControl( Entity::Player& player, uint16_t category, uint32_t param1 = 0, uint32_t param2 = 0, uint32_t param3 = 0, uint32_t param4 = 0 );
void sendActorControl( Entity::Player& player, uint32_t srcId, uint16_t category, uint32_t param1 = 0, uint32_t param2 = 0, uint32_t param3 = 0, uint32_t param4 = 0 );
void sendActorControl( const std::set< uint64_t >& characterIds, uint32_t srcId, uint16_t category, uint32_t param1 = 0, uint32_t param2 = 0,
uint32_t param3 = 0, uint32_t param4 = 0 );
void sendActorControlTarget( Entity::Player& player, uint16_t category, uint32_t param1 = 0, uint32_t param2 = 0, uint32_t param3 = 0,
void sendActorControlTarget( Entity::Player& player, uint32_t srcId, uint16_t category, uint32_t param1 = 0, uint32_t param2 = 0, uint32_t param3 = 0,
uint32_t param4 = 0, uint32_t param5 = 0, uint32_t param6 = 0 );
void sendActorControlTarget( const std::set< uint64_t >& characterIds, uint32_t srcId, uint16_t category, uint32_t param1 = 0,

View file

@ -29,7 +29,7 @@
#include "Actor/Player.h"
#include "Actor/EventObject.h"
#include "Action/EffectResult.h"
#include "Action/ActionResult.h"
#include "Network/GameConnection.h"
@ -466,7 +466,7 @@ bool Territory::update( uint64_t tickCount )
updateSessions( tickCount, changedWeather );
onUpdate( tickCount );
processEffectResults( tickCount );
processActionResults( tickCount );
if( !m_playerMap.empty() )
m_lastActivityTime = tickCount;
@ -875,15 +875,15 @@ std::shared_ptr< World::Navi::NaviProvider > Territory::getNaviProvider()
return m_pNaviProvider;
}
void Territory::addEffectResult( World::Action::EffectResultPtr result )
void Territory::addActionResult( World::Action::ActionResultPtr result )
{
m_effectResults.emplace_back( std::move( result ) );
m_actionResults.emplace_back( std::move( result ) );
}
void Territory::processEffectResults( uint64_t tickCount )
void Territory::processActionResults( uint64_t tickCount )
{
// todo: move this to generic territory/instance delay wrapper cause it might be useful scheduling other things
for( auto it = m_effectResults.begin(); it != m_effectResults.end(); )
for( auto it = m_actionResults.begin(); it != m_actionResults.end(); )
{
auto effect = *it;
@ -895,7 +895,7 @@ void Territory::processEffectResults( uint64_t tickCount )
effect->execute();
it = m_effectResults.erase( it );
it = m_actionResults.erase( it );
}
}

View file

@ -72,7 +72,7 @@ namespace Sapphire
uint32_t m_effectCounter{};
std::shared_ptr< World::Navi::NaviProvider > m_pNaviProvider;
std::vector< World::Action::EffectResultPtr > m_effectResults;
std::vector< World::Action::ActionResultPtr > m_actionResults;
Common::TerritoryIdent m_ident;
@ -198,9 +198,9 @@ namespace Sapphire
std::shared_ptr< World::Navi::NaviProvider > getNaviProvider();
void addEffectResult( World::Action::EffectResultPtr result );
void addActionResult( World::Action::ActionResultPtr result );
void processEffectResults( uint64_t tickCount );
void processActionResults( uint64_t tickCount );
};
}