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

Merge branch 'master' of https://github.com/SapphireServer/Sapphire into actions-war

This commit is contained in:
Lucy 2023-03-12 20:04:12 +01:00
commit fb65f728a7
68 changed files with 1684 additions and 1605 deletions

View file

@ -1,7 +1,7 @@
{
"7": {
"name": "Attack",
"potency": 0,
"potency": 110,
"comboPotency": 0,
"flankPotency": 0,
"frontPotency": 0,
@ -16,7 +16,7 @@
},
"8": {
"name": "Shot",
"potency": 0,
"potency": 100,
"comboPotency": 0,
"flankPotency": 0,
"frontPotency": 0,

View file

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

View file

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

View file

@ -30,13 +30,11 @@ public:
status->setModifier( Common::ParamModifier::DamageDealtPercent, 0 );
auto dmg = action.calcDamage( Potency );
action.getEffectbuilder()->damage( pSource, pTarget, dmg.first, dmg.second );
action.getEffectbuilder()->heal( pTarget, pSource, dmg.first, Common::ActionHitSeverityType::NormalHeal,
Common::ActionEffectResultFlag::EffectOnSource );
action.getActionResultBuilder()->damage( pSource, pTarget, dmg.first, dmg.second );
action.getActionResultBuilder()->heal( pTarget, pSource, dmg.first, Common::ActionHitSeverityType::NormalHeal,
Common::ActionResultFlag::EffectOnSource );
action.applyStatusEffectSelf( InnerBeast );
pPlayer->addStatusEffectByIdIfNotExist( InnerBeast, 15000, *pSource,
{ StatusModifier{ Common::ParamModifier::DamageTakenPercent, -20 } } );
action.applyStatusEffectSelf( InnerBeast, 15000, false, { StatusModifier{ Common::ParamModifier::DamageTakenPercent, -20 } } );
if( !pPlayer->hasStatusEffect( Unchained ) )
{

View file

@ -25,8 +25,7 @@ public:
if( auto status = pPlayer->getStatusEffectById( Defiance ); status )
status->setModifier( Common::ParamModifier::DamageDealtPercent, 0 );
action.applyStatusEffectSelf( Unchained );
pPlayer->addStatusEffectByIdIfNotExist( Unchained, 20000, *pPlayer->getAsChara() );
action.applyStatusEffectSelf( Unchained, 20000, false );
}
};

View file

@ -1,7 +1,7 @@
{
"7": {
"name": "Attack",
"potency": 0,
"potency": 110,
"comboPotency": 0,
"flankPotency": 0,
"frontPotency": 0,
@ -16,7 +16,7 @@
},
"8": {
"name": "Shot",
"potency": 0,
"potency": 100,
"comboPotency": 0,
"flankPotency": 0,
"frontPotency": 0,

View file

@ -0,0 +1,52 @@
#include <cstdint>
#include <ForwardsZone.h>
#include "GambitTargetCondition.h"
#include "GambitRule.h"
using namespace Sapphire;
using namespace Sapphire::World;
AI::GambitRule::GambitRule( const GambitTargetConditionPtr targetCondition, Action::ActionPtr action, uint32_t coolDown ) :
m_targetCondition( targetCondition ),
m_pAction( std::move( action ) ),
m_lastExecutionMs( 0 ),
m_coolDownMs( coolDown ),
m_isEnabled( true )
{
}
void AI::GambitRule::toggleEnabled()
{
m_isEnabled = !m_isEnabled;
}
bool AI::GambitRule::isEnabled() const
{
return m_isEnabled;
}
uint64_t AI::GambitRule::getLastExecutionMs() const
{
return m_lastExecutionMs;
}
void AI::GambitRule::setLastExecutionMs( uint64_t lastExecution )
{
m_lastExecutionMs = lastExecution;
}
uint32_t AI::GambitRule::getCoolDown() const
{
return m_coolDownMs;
}
AI::GambitTargetConditionPtr AI::GambitRule::getGambitTargetCondition()
{
return m_targetCondition;
}
Action::ActionPtr AI::GambitRule::getActionPtr()
{
return m_pAction;
}

33
src/world/AI/GambitRule.h Normal file
View file

@ -0,0 +1,33 @@
#include <cstdint>
#include <ForwardsZone.h>
#include "GambitTargetCondition.h"
#pragma once
namespace Sapphire::World::AI
{
class GambitRule
{
public:
GambitRule( GambitTargetConditionPtr targetCondition, Action::ActionPtr action, uint32_t coolDown );
~GambitRule() = default;
bool isEnabled() const;
void toggleEnabled();
uint64_t getLastExecutionMs() const;
void setLastExecutionMs( uint64_t lastExecution );
uint32_t getCoolDown() const;
GambitTargetConditionPtr getGambitTargetCondition();
Action::ActionPtr getActionPtr();
private:
GambitTargetConditionPtr m_targetCondition;
Action::ActionPtr m_pAction;
uint32_t m_coolDownMs;
uint64_t m_lastExecutionMs;
bool m_isEnabled;
};
}

View file

@ -0,0 +1,66 @@
#include <cstdint>
#include <ForwardsZone.h>
#include <Actor/BNpc.h>
#pragma once
namespace Sapphire::World::AI
{
enum GambitTargetType : uint8_t
{
Self,
Player,
PlayerAndAlly,
Ally,
BNpc
};
class GambitTargetCondition
{
public:
GambitTargetCondition( GambitTargetType targetType ) : m_targetType( targetType ) {};
virtual ~GambitTargetCondition() = default;
virtual bool isConditionMet( Sapphire::Entity::BNpc& src ) { return false; };
Sapphire::Entity::CharaPtr getTarget() const { return m_pTarget; };
protected:
GambitTargetType m_targetType;
Sapphire::Entity::CharaPtr m_pTarget;
};
class TopHateTargetCondition : public GambitTargetCondition
{
public:
TopHateTargetCondition() : GambitTargetCondition( PlayerAndAlly ) {};
bool isConditionMet( Sapphire::Entity::BNpc& src ) override
{
auto foundChara = src.hateListGetHighest();
if( foundChara )
{
m_pTarget = foundChara;
return true;
}
return false;
};
};
class HPSelfPctLessThan : public GambitTargetCondition
{
public:
HPSelfPctLessThan( uint8_t pct ) : GambitTargetCondition( Self ), m_HpPct( pct ) {};
virtual bool isConditionMet( Sapphire::Entity::BNpc& src )
{
if( src.getHpPercent() < m_HpPct )
{
m_pTarget = src.getAsBNpc();
return true;
}
return false;
};
private:
uint8_t m_HpPct;
};
}

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"
@ -23,7 +24,7 @@
#include "Network/PacketWrappers/ActorControlPacket.h"
#include "Network/PacketWrappers/ActorControlSelfPacket.h"
#include "Network/PacketWrappers/ActorControlTargetPacket.h"
#include "Network/Util/PlayerUtil.h"
#include "Network/Util/PacketUtil.h"
#include <Logging/Logger.h>
@ -67,6 +68,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 )
@ -80,8 +86,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->getNextActionResultId();
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 );
@ -108,9 +117,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;
@ -244,34 +253,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 ) )
@ -284,7 +293,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 );
@ -318,20 +327,20 @@ 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 );
player->setRecastGroup( m_cooldownGroup, static_cast< float >( m_castTimeMs ) / 1000.f );
server().queueForPlayer( player->getCharacterId(), actionStartPkt );
if( player )
{
player->setRecastGroup( m_cooldownGroup, static_cast< float >( m_castTimeMs ) / 1000.f );
server().queueForPlayer( player->getCharacterId(), actionStartPkt );
}
onStart();
@ -365,7 +374,6 @@ void Action::Action::onStart()
void Action::Action::interrupt()
{
assert( m_pSource );
// things that aren't players don't care about cooldowns and state flags
if( m_pSource->isPlayer() )
{
@ -405,25 +413,20 @@ void Action::Action::onInterrupt()
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( hasCastTime() && m_pSource->isPlayer() )
{
if( auto pPlayer = m_pSource->getAsPlayer(); pPlayer )
{
pPlayer->setLastActionTick( 0 );
pPlayer->removeCondition( PlayerCondition::Casting );
}
auto pPlayer = m_pSource->getAsPlayer();
pPlayer->setLastActionTick( 0 );
pPlayer->removeCondition( PlayerCondition::Casting );
}
if( isCorrectCombo() )
@ -433,13 +436,9 @@ void Action::Action::execute()
}
if( !hasClientsideTarget() )
{
handleAction();
}
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.)
@ -447,13 +446,9 @@ 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 );
}
}
}
@ -469,13 +464,13 @@ std::pair< uint32_t, Common::ActionHitSeverityType > Action::Action::calcDamage(
auto role = player->getRole();
if( role == Common::Role::RangedMagical || role == Common::Role::Healer )
{
wepDmg = item->getMagicalDmg();
}
else
{
wepDmg = item->getPhysicalDmg();
}
// is auto attack
if( getId() == 7 || getId() == 8 )
return Math::CalcStats::calcAutoAttackDamage( *m_pSource->getAsPlayer() );
}
return Math::CalcStats::calcActionDamage( *m_pSource, potency, wepDmg );
@ -492,27 +487,34 @@ std::pair< uint32_t, Common::ActionHitSeverityType > Action::Action::calcHealing
auto role = player->getRole();
if( role == Common::Role::RangedMagical || role == Common::Role::Healer )
{
wepDmg = item->getMagicalDmg();
}
else
{
wepDmg = item->getPhysicalDmg();
}
}
return Math::CalcStats::calcActionHealing( *m_pSource, potency, wepDmg );
}
void Action::Action::applyStatusEffectSelf( uint16_t statusId, uint8_t param )
void Action::Action::applyStatusEffectSelf( StatusEntry& statusEntry, bool shouldOverride, uint8_t param )
{
if( m_hitActors.size() > 0 )
getEffectbuilder()->applyStatusEffect( m_hitActors[ 0 ], statusId, param, true );
getActionResultBuilder()->applyStatusEffect( m_hitActors[ 0 ], statusEntry.id, statusEntry.duration, param,
statusEntry.modifiers, statusEntry.flag, shouldOverride, true );
else
getEffectbuilder()->applyStatusEffect( m_pSource, statusId, param );
getActionResultBuilder()->applyStatusEffect( m_pSource, statusEntry.id, statusEntry.duration, param,
statusEntry.modifiers, statusEntry.flag, shouldOverride );
}
void Action::Action::handleAction()
void Action::Action::applyStatusEffectSelf( uint16_t statusId, int32_t duration, bool shouldOverride,
std::vector< StatusModifier > modifiers, uint8_t param )
{
if( m_hitActors.size() > 0 )
getActionResultBuilder()->applyStatusEffect( m_hitActors[ 0 ], statusId, duration, param, modifiers, shouldOverride, true );
else
getActionResultBuilder()->applyStatusEffect( m_pSource, statusId, duration, param, modifiers, shouldOverride );
}
void Action::Action::buildActionResults()
{
snapshotAffectedActors( m_hitActors );
@ -523,22 +525,19 @@ void Action::Action::handleAction()
if( !hasScript && !hasLutEntry )
{
if( auto player = m_pSource->getAsPlayer() )
{
Manager::PlayerMgr::sendUrgent( *player, "missing lut entry for action#{}", getId() );
}
return;
}
if( !hasScript )
m_enableGenericHandler = true;
Network::Util::Player::sendHudParam( *m_pSource->getAsPlayer() );
Network::Util::Packet::sendHudParam( *m_pSource );
if( !m_enableGenericHandler || !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;
}
@ -559,14 +558,14 @@ void Action::Action::handleAction()
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;
}
@ -575,35 +574,33 @@ void Action::Action::handleAction()
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;
}
}
@ -619,7 +616,7 @@ void Action::Action::handleAction()
if( m_lutEntry.statuses.caster.size() > 0 || m_lutEntry.statuses.target.size() > 0 )
handleStatusEffects();
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
@ -636,8 +633,7 @@ void Action::Action::handleStatusEffects()
{
for( auto& status : m_lutEntry.statuses.caster )
{
applyStatusEffectSelf( status.id );
m_pSource->addStatusEffectByIdIfNotExist( status.id, status.duration, *m_pSource, status );
applyStatusEffectSelf( status, true );
}
}
@ -648,8 +644,7 @@ void Action::Action::handleStatusEffects()
{
for( auto& status : m_lutEntry.statuses.target )
{
getEffectbuilder()->applyStatusEffect( actor, status.id, 0 );
actor->addStatusEffectByIdIfNotExist( status.id, status.duration, *m_pSource, status );
getActionResultBuilder()->applyStatusEffect( actor, status.id, status.duration, 0, status.modifiers, status.flag, true );
}
if( actor->getStatusEffectMap().size() > 0 )
@ -748,9 +743,7 @@ bool Action::Action::isCorrectCombo() const
auto lastActionId = m_pSource->getLastComboActionId();
if( lastActionId == 0 )
{
return false;
}
return m_actionData->data().ComboParent == lastActionId;
}
@ -934,10 +927,7 @@ std::vector< Entity::CharaPtr >& Action::Action::getHitCharas()
Entity::CharaPtr Action::Action::getHitChara()
{
if( !m_hitActors.empty() )
{
return m_hitActors.at( 0 );
}
return nullptr;
}
@ -948,9 +938,9 @@ bool Action::Action::hasValidLutEntry() const
m_lutEntry.statuses.caster.size() > 0 || m_lutEntry.statuses.target.size() > 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 );
@ -105,11 +107,14 @@ namespace Sapphire::World::Action
*/
bool snapshotAffectedActors( std::vector< Entity::CharaPtr >& actors );
EffectBuilderPtr getEffectbuilder();
ActionResultBuilderPtr getActionResultBuilder();
void applyStatusEffectSelf( uint16_t statusId, uint8_t param = 0 );
void applyStatusEffectSelf( StatusEntry& statusEntry, bool shouldOverride, uint8_t param = 0 );
void handleAction();
void applyStatusEffectSelf( uint16_t statusId, int32_t duration, bool shouldOverride,
std::vector< StatusModifier > modifiers = {}, uint8_t param = 0 );
void buildActionResults();
void handleStatusEffects();
@ -180,6 +185,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{};
@ -218,7 +224,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

@ -0,0 +1,165 @@
#include "ActionResult.h"
#include <Util/Util.h>
#include <Service.h>
#include <Manager/PlayerMgr.h>
#include "Actor/Chara.h"
#include "Actor/Player.h"
#include "StatusEffect/StatusEffect.h"
using namespace Sapphire;
using namespace Sapphire::World::Action;
ActionResult::ActionResult( Entity::CharaPtr target, uint64_t runAfter ) :
m_target( std::move( target ) ),
m_delayMs( runAfter )
{
m_result.Arg0 = 0;
m_result.Arg1 = 0;
m_result.Arg2 = 0;
m_result.Value = 0;
m_result.Flag = static_cast< uint8_t >( Common::ActionResultFlag::None );
m_result.Type = Common::ActionEffectType::CALC_RESULT_TYPE_NONE;
}
Entity::CharaPtr ActionResult::getTarget() const
{
return m_target;
}
uint64_t ActionResult::getDelay()
{
return m_delayMs;
}
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 );
m_result.Flag = static_cast< uint8_t >( flag );
m_result.Type = Common::ActionEffectType::CALC_RESULT_TYPE_DAMAGE_HP;
}
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 );
m_result.Flag = static_cast< uint8_t >( flag );
m_result.Type = Common::ActionEffectType::CALC_RESULT_TYPE_RECOVER_HP;
}
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 ActionResult::startCombo( uint16_t actionId )
{
m_result.Value = static_cast< int16_t >( actionId );
m_result.Flag = static_cast< uint8_t >( Common::ActionResultFlag::EffectOnSource );
m_result.Type = Common::ActionEffectType::CALC_RESULT_TYPE_COMBO;
}
void ActionResult::comboSucceed()
{
// no EffectOnSource flag on this
m_result.Type = Common::ActionEffectType::CALC_RESULT_TYPE_COMBO_HIT;
}
void ActionResult::applyStatusEffect( uint32_t id, int32_t duration, Entity::Chara& source, uint8_t param, bool shouldOverride, bool forSelf )
{
m_result.Value = static_cast< int16_t >( id );
m_result.Arg2 = param;
if( forSelf )
m_result.Flag = static_cast< uint8_t >( Common::ActionResultFlag::EffectOnSource );
m_result.Type = forSelf ? Common::ActionEffectType::CALC_RESULT_TYPE_SET_STATUS_ME : Common::ActionEffectType::CALC_RESULT_TYPE_SET_STATUS;
m_bOverrideStatus = shouldOverride;
m_pStatus = Sapphire::StatusEffect::make_StatusEffect( id, source.getAsChara(), m_target, duration, 3000 );
m_pStatus->setParam( param );
}
void ActionResult::applyStatusEffect( uint32_t id, int32_t duration, Entity::Chara& source, uint8_t param,
std::vector< StatusModifier > modifiers, uint32_t flag, bool shouldOverride, bool forSelf )
{
m_result.Value = static_cast< int16_t >( id );
m_result.Arg2 = param;
if( forSelf )
m_result.Flag = static_cast< uint8_t >( Common::ActionResultFlag::EffectOnSource );
m_result.Type = forSelf ? Common::ActionEffectType::CALC_RESULT_TYPE_SET_STATUS_ME : Common::ActionEffectType::CALC_RESULT_TYPE_SET_STATUS;
m_bOverrideStatus = shouldOverride;
m_pStatus = Sapphire::StatusEffect::make_StatusEffect( id, source.getAsChara(), m_target, duration, modifiers, flag, 3000 );
m_pStatus->setParam( param );
}
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& ActionResult::getCalcResultParam() const
{
return m_result;
}
const Sapphire::StatusEffect::StatusEffectPtr ActionResult::getStatusEffect() const
{
return m_pStatus;
}
void ActionResult::execute()
{
if( !m_target )
return;
switch( m_result.Type )
{
case Common::ActionEffectType::CALC_RESULT_TYPE_DAMAGE_HP:
{
m_target->takeDamage( m_result.Value );
break;
}
case Common::ActionEffectType::CALC_RESULT_TYPE_RECOVER_HP:
{
m_target->heal( m_result.Value );
break;
}
case Common::ActionEffectType::CALC_RESULT_TYPE_RECOVER_MP:
{
m_target->restoreMP( m_result.Value );
break;
}
case Common::ActionEffectType::CALC_RESULT_TYPE_SET_STATUS:
case Common::ActionEffectType::CALC_RESULT_TYPE_SET_STATUS_ME:
{
if( !m_bOverrideStatus )
m_target->addStatusEffectByIdIfNotExist( m_pStatus->getId(), m_pStatus->getDuration(), *m_pStatus->getSrcActor(),
m_pStatus->getStatusModifiers(), m_pStatus->getFlag(), m_pStatus->getParam() );
else
m_target->addStatusEffectById( m_pStatus->getId(), m_pStatus->getDuration(), *m_pStatus->getSrcActor(),
m_pStatus->getStatusModifiers(), m_pStatus->getFlag(), m_pStatus->getParam() );
break;
}
case Common::ActionEffectType::CALC_RESULT_TYPE_MOUNT:
{
auto pPlayer = m_target->getAsPlayer();
pPlayer->setMount( m_result.Value );
break;
}
default:
break;
}
}

View file

@ -0,0 +1,50 @@
#pragma once
#include <ForwardsZone.h>
#include <Common.h>
#include "ActionLut.h"
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 ActionResult
{
public:
explicit ActionResult( Entity::CharaPtr target, uint64_t delayMs );
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( uint32_t id, int32_t duration, Entity::Chara& source, uint8_t param, bool shouldOverride, bool forSelf );
void applyStatusEffect( uint32_t id, int32_t duration, Entity::Chara& source, uint8_t param,
std::vector< World::Action::StatusModifier > modifiers, uint32_t flag, bool shouldOverride, bool forSelf );
void mount( uint16_t mountId );
Entity::CharaPtr getTarget() const;
uint64_t getDelay();
const Common::CalcResultParam& getCalcResultParam() const;
const Sapphire::StatusEffect::StatusEffectPtr getStatusEffect() const;
void execute();
private:
uint64_t m_delayMs;
Entity::CharaPtr m_target;
Common::CalcResultParam m_result;
bool m_bOverrideStatus { false };
Sapphire::StatusEffect::StatusEffectPtr m_pStatus;
};
using ActionResultList = std::vector< ActionResultPtr >;
}

View file

@ -0,0 +1,188 @@
#include "ActionResultBuilder.h"
#include "ActionResult.h"
#include <Actor/Player.h>
#include <Network/PacketWrappers/EffectPacket.h>
#include <Network/PacketWrappers/EffectPacket1.h>
#include <Territory/Territory.h>
#include <Util/Util.h>
#include <Util/UtilMath.h>
#include <Logging/Logger.h>
#include <Manager/TerritoryMgr.h>
#include <Manager/MgrUtil.h>
#include <Service.h>
#include <Manager/TaskMgr.h>
#include <Task/ActionIntegrityTask.h>
using namespace Sapphire;
using namespace Sapphire::World::Action;
using namespace Sapphire::World::Manager;
using namespace Sapphire::Network::Packets;
using namespace Sapphire::Network::Packets::WorldPackets::Server;
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 )
{
}
void ActionResultBuilder::addResultToActor( Entity::CharaPtr& chara, ActionResultPtr result )
{
auto it = m_actorResultsMap.find( chara );
if( it == m_actorResultsMap.end() )
{
m_actorResultsMap[ chara ].push_back( std::move( result ) );
return;
}
it->second.push_back( std::move( result ) );
}
void ActionResultBuilder::heal( Entity::CharaPtr& effectTarget, Entity::CharaPtr& healingTarget, uint32_t amount, Common::ActionHitSeverityType severity, Common::ActionResultFlag flag )
{
ActionResultPtr nextResult = make_ActionResult( healingTarget, 0 );
nextResult->heal( amount, severity, flag );
addResultToActor( effectTarget, nextResult );
}
void ActionResultBuilder::restoreMP( Entity::CharaPtr& target, Entity::CharaPtr& restoringTarget, uint32_t amount, Common::ActionResultFlag flag )
{
ActionResultPtr nextResult = make_ActionResult( restoringTarget, 0 ); // restore mp source actor
nextResult->restoreMP( amount, flag );
addResultToActor( target, nextResult );
}
void ActionResultBuilder::damage( Entity::CharaPtr& effectTarget, Entity::CharaPtr& damagingTarget, uint32_t amount, Common::ActionHitSeverityType severity, Common::ActionResultFlag flag )
{
ActionResultPtr nextResult = make_ActionResult( damagingTarget, 0 );
nextResult->damage( amount, severity, flag );
addResultToActor( damagingTarget, nextResult );
}
void ActionResultBuilder::startCombo( Entity::CharaPtr& target, uint16_t actionId )
{
ActionResultPtr nextResult = make_ActionResult( target, 0 );
nextResult->startCombo( actionId );
addResultToActor( target, nextResult );
}
void ActionResultBuilder::comboSucceed( Entity::CharaPtr& target )
{
ActionResultPtr nextResult = make_ActionResult( target, 0 );
nextResult->comboSucceed();
addResultToActor( target, nextResult );
}
void ActionResultBuilder::applyStatusEffect( Entity::CharaPtr& target, uint16_t statusId, uint32_t duration, uint8_t param, bool shouldOverride, bool forSelf )
{
ActionResultPtr nextResult = make_ActionResult( target, 0 );
nextResult->applyStatusEffect( statusId, duration, *m_sourceChara, param, shouldOverride, forSelf );
addResultToActor( target, nextResult );
}
void ActionResultBuilder::applyStatusEffect( Entity::CharaPtr& target, uint16_t statusId, uint32_t duration, uint8_t param,
std::vector< World::Action::StatusModifier > modifiers, uint32_t flag,
bool shouldOverride, bool forSelf )
{
ActionResultPtr nextResult = make_ActionResult( target, 0 );
nextResult->applyStatusEffect( statusId, duration, *m_sourceChara, param, modifiers, flag, shouldOverride, forSelf );
addResultToActor( target, nextResult );
}
void ActionResultBuilder::mount( Entity::CharaPtr& target, uint16_t mountId )
{
ActionResultPtr nextResult = make_ActionResult( target, 0 );
nextResult->mount( mountId );
addResultToActor( target, nextResult );
}
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 = createActionResultPacket( targetList );
server().queueForPlayers( m_sourceChara->getInRangePlayerIds( true ), packet );
}
while( !m_actorResultsMap.empty() );
}
std::shared_ptr< FFXIVPacketBase > ActionResultBuilder::createActionResultPacket( const std::vector< Entity::CharaPtr >& targetList )
{
auto targetCount = 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() );
if( targetCount > 1 ) // use AoeEffect packets
{
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 );
uint8_t targetIndex = 0;
for( auto it = m_actorResultsMap.begin(); it != m_actorResultsMap.end(); ++it )
{
// get all effect results for an actor
auto actorResultList = it->second;
if( it->first )
taskMgr.queueTask( World::makeActionIntegrityTask( m_resultId, it->first, actorResultList, 300 ) );
for( auto& result : actorResultList )
{
auto effect = result->getCalcResultParam();
if( result->getTarget() == m_sourceChara )
actionResult->addSourceEffect( effect );
else
actionResult->addTargetEffect( effect, result->getTarget()->getId() );
}
targetIndex++;
if( targetIndex == 15 )
break;
}
return actionResult;
}
else // use Effect for single target
{
uint32_t mainTargetId = targetList.empty() ? m_sourceChara->getId() : targetList[ 0 ]->getId();
auto actionResult = std::make_shared< EffectPacket1 >( m_sourceChara->getId(), mainTargetId, m_actionId );
actionResult->setRotation( Common::Util::floatToUInt16Rot( m_sourceChara->getRot() ) );
actionResult->setRequestId( m_requestId );
actionResult->setResultId( m_resultId );
for( auto it = m_actorResultsMap.begin(); it != m_actorResultsMap.end(); ++it )
{
// get all effect results for an actor
auto actorResultList = it->second;
if( it->first )
taskMgr.queueTask( World::makeActionIntegrityTask( m_resultId, it->first, actorResultList, 300 ) );
for( auto& result : actorResultList )
{
auto effect = result->getCalcResultParam();
if( result->getTarget() == m_sourceChara )
actionResult->addSourceEffect( effect );
else
actionResult->addTargetEffect( effect );
}
}
m_actorResultsMap.clear();
return actionResult;
}
}

View file

@ -0,0 +1,52 @@
#pragma once
#include <ForwardsZone.h>
#include <Common.h>
#include "ActionLut.h"
namespace Sapphire::World::Action
{
class ActionResultBuilder
{
public:
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::ActionResultFlag flag = Common::ActionResultFlag::None );
void restoreMP( Entity::CharaPtr& effectTarget, Entity::CharaPtr& restoringTarget, uint32_t amount,
Common::ActionResultFlag flag = Common::ActionResultFlag::None );
void damage( Entity::CharaPtr& effectTarget, Entity::CharaPtr& damagingTarget, uint32_t amount,
Common::ActionHitSeverityType severity = Common::ActionHitSeverityType::NormalDamage,
Common::ActionResultFlag flag = Common::ActionResultFlag::None );
void startCombo( Entity::CharaPtr& target, uint16_t actionId );
void comboSucceed( Entity::CharaPtr& target );
void applyStatusEffect( Entity::CharaPtr& target, uint16_t statusId, uint32_t duration, uint8_t param, bool shouldOverride = false, bool forSelf = false );
void applyStatusEffect( Entity::CharaPtr& target, uint16_t statusId, uint32_t duration, uint8_t param,
std::vector< World::Action::StatusModifier > modifiers, uint32_t flag = 0, bool shouldOverride = false, bool forSelf = false );
void mount( Entity::CharaPtr& target, uint16_t mountId );
void sendActionResults( const std::vector< Entity::CharaPtr >& targetList );
private:
void addResultToActor( Entity::CharaPtr& chara, ActionResultPtr result );
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< Entity::CharaPtr, std::vector< ActionResultPtr > > m_actorResultsMap;
};
}

View file

@ -1,236 +0,0 @@
#include "EffectBuilder.h"
#include "EffectResult.h"
#include <Actor/Player.h>
#include <Network/PacketWrappers/EffectPacket.h>
#include <Network/PacketWrappers/EffectPacket1.h>
#include <Territory/Territory.h>
#include <Util/Util.h>
#include <Util/UtilMath.h>
#include <Logging/Logger.h>
#include <Manager/TerritoryMgr.h>
#include <Manager/MgrUtil.h>
#include <Service.h>
#include <Manager/TaskMgr.h>
#include <Task/ActionIntegrityTask.h>
using namespace Sapphire;
using namespace Sapphire::World::Action;
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 ) :
m_sourceChara( std::move( source ) ),
m_actionId( actionId ),
m_requestId( requestId )
{
}
uint64_t EffectBuilder::getResultDelayMs()
{
// todo: actually figure this retarded shit out
return Common::Util::getTimeMs() + 850;
}
void EffectBuilder::addResultToActor( Entity::CharaPtr& chara, EffectResultPtr result )
{
auto it = m_actorEffectsMap.find( chara->getId() );
if( it == m_actorEffectsMap.end() )
{
// create a new one
auto resultList = std::vector< EffectResultPtr >();
resultList.push_back( std::move( result ) );
m_actorEffectsMap[ chara->getId() ] = resultList;
return;
}
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 )
{
EffectResultPtr nextResult = make_EffectResult( 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 )
{
EffectResultPtr nextResult = make_EffectResult( 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 )
{
EffectResultPtr nextResult = make_EffectResult( damagingTarget, getResultDelayMs() );
nextResult->damage( amount, severity, flag );
addResultToActor( damagingTarget, nextResult );
}
void EffectBuilder::startCombo( Entity::CharaPtr& target, uint16_t actionId )
{
EffectResultPtr nextResult = make_EffectResult( target, 0 );
nextResult->startCombo( actionId );
addResultToActor( target, nextResult );
}
void EffectBuilder::comboSucceed( Entity::CharaPtr& target )
{
EffectResultPtr nextResult = make_EffectResult( target, 0 );
nextResult->comboSucceed();
addResultToActor( target, nextResult );
}
void EffectBuilder::applyStatusEffect( Entity::CharaPtr& target, uint16_t statusId, uint8_t param, bool forSelf )
{
EffectResultPtr nextResult = make_EffectResult( target, 0 );
nextResult->applyStatusEffect( statusId, param, forSelf );
addResultToActor( target, nextResult );
}
void EffectBuilder::mount( Entity::CharaPtr& target, uint16_t mountId )
{
EffectResultPtr nextResult = make_EffectResult( target, getResultDelayMs() );
nextResult->mount( mountId );
addResultToActor( target, nextResult );
}
void EffectBuilder::buildAndSendPackets( 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 );
server().queueForPlayers( m_sourceChara->getInRangePlayerIds( true ), packet );
}
while( !m_actorEffectsMap.empty() );
}
std::shared_ptr< FFXIVPacketBase > EffectBuilder::buildNextEffectPacket( const std::vector< Entity::CharaPtr >& targetList )
{
auto remainingTargetCount = targetList.size();
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 );
effectPacket->setRotation( Common::Util::floatToUInt16Rot( m_sourceChara->getRot() ) );
effectPacket->setRequestId( m_requestId );
effectPacket->setResultId( resultId );
effectPacket->setTargetActor( targetList[ 0 ]->getId() );
uint8_t targetIndex = 0;
for( auto it = m_actorEffectsMap.begin(); it != m_actorEffectsMap.end(); )
{
// get all effect results for an actor
auto actorResultList = it->second;
for( auto i = 0; i < actorResultList.size(); ++i )
{
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 ) );
}
zone->addEffectResult( std::move( result ) );
}
actorResultList.clear();
it = m_actorEffectsMap.erase( it );
targetIndex++;
if( targetIndex == 15 )
break;
}
return effectPacket;
}
else if( remainingTargetCount == 1 ) // use Effect for single target
{
Logger::debug( " - id: {}", targetList[0]->getId() );
Logger::debug( "------------------------------------------" );
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 );
for( auto it = m_actorEffectsMap.begin(); it != m_actorEffectsMap.end(); )
{
// get all effect results for an actor
auto actorResultList = it->second;
for( auto i = 0; i < actorResultList.size(); ++i )
{
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 ) );
}
zone->addEffectResult( std::move( result ) );
}
actorResultList.clear();
it = m_actorEffectsMap.erase( it );
}
m_actorEffectsMap.clear();
return effectPacket;
}
else // nothing is hit, this only happens when using aoe and AoeEffect8 is used on retail
{
auto effectPacket = makeZonePacket< FFXIVIpcActionResult1 >( m_sourceChara->getId() );
effectPacket->data().ActionKey = m_actionId;
effectPacket->data().Action = static_cast< uint16_t >( m_actionId );
effectPacket->data().Target = m_sourceChara->getId();
effectPacket->data().MainTarget = static_cast< uint64_t >( m_sourceChara->getId() );
effectPacket->data().DirTarget = Common::Util::floatToUInt16Rot( m_sourceChara->getRot() );
effectPacket->data().Flag = Common::ActionEffectDisplayType::HideActionName;
effectPacket->data().RequestId = m_requestId;
effectPacket->data().ResultId = resultId;
m_actorEffectsMap.clear();
return effectPacket;
}
}

View file

@ -1,49 +0,0 @@
#pragma once
#include <ForwardsZone.h>
#include <Common.h>
namespace Sapphire::World::Action
{
class EffectBuilder
{
public:
EffectBuilder( Entity::CharaPtr source, uint32_t actionId, 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 );
void restoreMP( Entity::CharaPtr& effectTarget, Entity::CharaPtr& restoringTarget, uint32_t amount,
Common::ActionEffectResultFlag flag = Common::ActionEffectResultFlag::None );
void damage( Entity::CharaPtr& effectTarget, Entity::CharaPtr& damagingTarget, uint32_t amount,
Common::ActionHitSeverityType severity = Common::ActionHitSeverityType::NormalDamage,
Common::ActionEffectResultFlag flag = Common::ActionEffectResultFlag::None );
void startCombo( Entity::CharaPtr& target, uint16_t actionId );
void comboSucceed( Entity::CharaPtr& target );
void applyStatusEffect( Entity::CharaPtr& target, uint16_t statusId, uint8_t param, bool forSelf = false );
void mount( Entity::CharaPtr& target, uint16_t mountId );
void buildAndSendPackets( const std::vector< Entity::CharaPtr >& targetList );
private:
void addResultToActor( Entity::CharaPtr& chara, EffectResultPtr result );
uint64_t getResultDelayMs();
Network::Packets::FFXIVPacketBasePtr buildNextEffectPacket( const std::vector< Entity::CharaPtr >& targetList );
private:
uint32_t m_actionId;
uint16_t m_requestId;
Entity::CharaPtr m_sourceChara;
std::unordered_map< uint32_t, std::vector< EffectResultPtr > > m_actorEffectsMap;
};
}

View file

@ -1,126 +0,0 @@
#include "EffectResult.h"
#include <Util/Util.h>
#include <Service.h>
#include <Manager/PlayerMgr.h>
#include "Actor/Chara.h"
#include "Actor/Player.h"
using namespace Sapphire;
using namespace Sapphire::World::Action;
EffectResult::EffectResult( Entity::CharaPtr target, uint64_t runAfter ) :
m_target( std::move( target ) ),
m_delayMs( runAfter )
{
m_result.Arg0 = 0;
m_result.Arg1 = 0;
m_result.Arg2 = 0;
m_result.Value = 0;
m_result.Flag = static_cast< uint8_t >( Common::ActionEffectResultFlag::None );
m_result.Type = Common::ActionEffectType::CALC_RESULT_TYPE_NONE;
}
Entity::CharaPtr EffectResult::getTarget() const
{
return m_target;
}
uint64_t EffectResult::getDelay()
{
return m_delayMs;
}
void EffectResult::damage( uint32_t amount, Common::ActionHitSeverityType severity, Common::ActionEffectResultFlag flag )
{
m_result.Arg0 = static_cast< uint8_t >( severity );
m_result.Value = static_cast< int16_t >( amount );
m_result.Flag = static_cast< uint8_t >( flag );
m_result.Type = Common::ActionEffectType::CALC_RESULT_TYPE_DAMAGE_HP;
}
void EffectResult::heal( uint32_t amount, Common::ActionHitSeverityType severity, Common::ActionEffectResultFlag flag )
{
m_result.Arg1 = static_cast< uint8_t >( severity );
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_HP;
}
void EffectResult::restoreMP( uint32_t amount, Common::ActionEffectResultFlag 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 )
{
m_result.Value = static_cast< int16_t >( actionId );
m_result.Flag = static_cast< uint8_t >( Common::ActionEffectResultFlag::EffectOnSource );
m_result.Type = Common::ActionEffectType::CALC_RESULT_TYPE_COMBO;
}
void EffectResult::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, bool forSelf )
{
m_result.Value = static_cast< int16_t >( statusId );
m_result.Arg2 = param;
if( forSelf )
m_result.Flag = static_cast< uint8_t >( Common::ActionEffectResultFlag::EffectOnSource );
m_result.Type = forSelf ? Common::ActionEffectType::CALC_RESULT_TYPE_SET_STATUS_ME : Common::ActionEffectType::CALC_RESULT_TYPE_SET_STATUS;
}
void EffectResult::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
{
return m_result;
}
void EffectResult::execute()
{
switch( m_result.Type )
{
case Common::ActionEffectType::CALC_RESULT_TYPE_DAMAGE_HP:
{
m_target->takeDamage( m_result.Value );
break;
}
case Common::ActionEffectType::CALC_RESULT_TYPE_RECOVER_HP:
{
m_target->heal( m_result.Value );
break;
}
case Common::ActionEffectType::CALC_RESULT_TYPE_RECOVER_MP:
{
m_target->restoreMP( m_result.Value );
break;
}
case Common::ActionEffectType::CALC_RESULT_TYPE_MOUNT:
{
auto pPlayer = m_target->getAsPlayer();
pPlayer->setMount( m_result.Value );
break;
}
default:
break;
}
}

View file

@ -1,41 +0,0 @@
#pragma once
#include <ForwardsZone.h>
#include <Common.h>
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
{
public:
explicit EffectResult( 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 startCombo( uint16_t actionId );
void comboSucceed();
void applyStatusEffect( uint16_t statusId, uint8_t param, bool forSelf );
void mount( uint16_t mountId );
Entity::CharaPtr getTarget() const;
uint64_t getDelay();
const Common::CalcResultParam& getCalcResultParam() const;
void execute();
private:
uint64_t m_delayMs;
Entity::CharaPtr m_target;
Common::CalcResultParam m_result;
};
}

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

@ -60,7 +60,6 @@ void Warrior::handleWrath( Entity::Player& player, Action& action )
if( !player.hasStatusEffect( Infuriated ) )
{
action.applyStatusEffectSelf( effectToApply );
player.addStatusEffectByIdIfNotExist( effectToApply, 30000, *asChara, { StatusModifier{ Common::ParamModifier::ParryPercent, parry } } );
action.applyStatusEffectSelf( effectToApply, 30000, false, { StatusModifier{ Common::ParamModifier::ParryPercent, parry } } );
}
}

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

@ -18,7 +18,7 @@
#include "Network/PacketWrappers/ActorControlTargetPacket.h"
#include "Network/PacketWrappers/NpcSpawnPacket.h"
#include "Network/PacketWrappers/MoveActorPacket.h"
#include "Network/Util/PlayerUtil.h"
#include "Network/Util/PacketUtil.h"
#include "Navi/NaviProvider.h"
@ -36,6 +36,7 @@
#include <Manager/PlayerMgr.h>
#include <Manager/TaskMgr.h>
#include <Manager/MgrUtil.h>
#include <Manager/ActionMgr.h>
#include <Script/ScriptMgr.h>
#include <Task/RemoveBNpcTask.h>
#include <Task/FadeBNpcTask.h>
@ -43,19 +44,24 @@
#include <Task/ActionIntegrityTask.h>
#include <Service.h>
#include <Action/Action.h>
#include <AI/GambitRule.h>
#include <AI/GambitTargetCondition.h>
using namespace Sapphire;
using namespace Sapphire::World;
using namespace Sapphire::Common;
using namespace Sapphire::Entity;
using namespace Sapphire::Network::Packets;
using namespace Sapphire::Network::Packets::WorldPackets::Server;
using namespace Sapphire::Network::ActorControl;
using namespace Sapphire::World::Manager;
Sapphire::Entity::BNpc::BNpc() :
Npc( ObjKind::BattleNpc )
BNpc::BNpc() : Npc( ObjKind::BattleNpc )
{
}
Sapphire::Entity::BNpc::BNpc( uint32_t id, std::shared_ptr< Common::BNPCInstanceObject > pInfo, const Territory& zone ) :
Npc( ObjKind::BattleNpc )
BNpc::BNpc( uint32_t id, std::shared_ptr< Common::BNPCInstanceObject > pInfo, const Territory& zone ) : Npc( ObjKind::BattleNpc )
{
m_id = id;
m_pInfo = pInfo;
@ -167,7 +173,7 @@ Sapphire::Entity::BNpc::BNpc( uint32_t id, std::shared_ptr< Common::BNPCInstance
}
Sapphire::Entity::BNpc::BNpc( uint32_t id, std::shared_ptr< Common::BNPCInstanceObject > pInfo, const Territory& zone, uint32_t hp, Common::BNpcType type ) :
BNpc::BNpc( uint32_t id, std::shared_ptr< Common::BNPCInstanceObject > pInfo, const Territory& zone, uint32_t hp, Common::BNpcType type ) :
Npc( ObjKind::BattleNpc )
{
m_id = id;
@ -269,81 +275,78 @@ Sapphire::Entity::BNpc::BNpc( uint32_t id, std::shared_ptr< Common::BNPCInstance
calculateStats();
}
Sapphire::Entity::BNpc::~BNpc() = default;
BNpc::~BNpc() = default;
uint8_t Sapphire::Entity::BNpc::getAggressionMode() const
uint8_t BNpc::getAggressionMode() const
{
return m_aggressionMode;
}
float Sapphire::Entity::BNpc::getNaviTargetReachedDistance() const
float BNpc::getNaviTargetReachedDistance() const
{
return m_naviTargetReachedDistance;
}
uint8_t Sapphire::Entity::BNpc::getEnemyType() const
uint8_t BNpc::getEnemyType() const
{
return m_enemyType;
}
uint64_t Sapphire::Entity::BNpc::getWeaponMain() const
uint64_t BNpc::getWeaponMain() const
{
return m_weaponMain;
}
uint64_t Sapphire::Entity::BNpc::getWeaponSub() const
uint64_t BNpc::getWeaponSub() const
{
return m_weaponSub;
}
uint16_t Sapphire::Entity::BNpc::getModelChara() const
uint16_t BNpc::getModelChara() const
{
return m_modelChara;
}
uint8_t Sapphire::Entity::BNpc::getLevel() const
uint8_t BNpc::getLevel() const
{
return m_level;
}
uint32_t Sapphire::Entity::BNpc::getBNpcBaseId() const
uint32_t BNpc::getBNpcBaseId() const
{
return m_bNpcBaseId;
}
uint32_t Sapphire::Entity::BNpc::getBNpcNameId() const
uint32_t BNpc::getBNpcNameId() const
{
return m_bNpcNameId;
}
void Sapphire::Entity::BNpc::spawn( PlayerPtr pTarget )
void BNpc::spawn( PlayerPtr pTarget )
{
m_lastRoamTargetReached = Util::getTimeSeconds();
m_lastRoamTargetReached = Common::Util::getTimeSeconds();
auto& server = Common::Service< World::WorldServer >::ref();
server.queueForPlayer( pTarget->getCharacterId(), std::make_shared< NpcSpawnPacket >( *this, *pTarget ) );
}
void Sapphire::Entity::BNpc::despawn( PlayerPtr pTarget )
void BNpc::despawn( PlayerPtr pTarget )
{
pTarget->freePlayerSpawnId( getId() );
auto& server = Common::Service< World::WorldServer >::ref();
server.queueForPlayer( pTarget->getCharacterId(), makeActorControlSelf( m_id, WarpStart, 0x04, getId(), 0x01 ) );
Network::Util::Packet::sendActorControlSelf( *pTarget, getId(), WarpStart, 4, getId(), 1 );
}
Sapphire::Entity::BNpcState Sapphire::Entity::BNpc::getState() const
BNpcState BNpc::getState() const
{
return m_state;
}
void Sapphire::Entity::BNpc::setState( BNpcState state )
void BNpc::setState( BNpcState state )
{
m_state = state;
}
bool Sapphire::Entity::BNpc::moveTo( const FFXIVARR_POSITION3& pos )
bool BNpc::moveTo( const FFXIVARR_POSITION3& pos )
{
auto& teriMgr = Common::Service< World::Manager::TerritoryMgr >::ref();
auto pZone = teriMgr.getTerritoryByGuId( getTerritoryId() );
@ -357,7 +360,7 @@ bool Sapphire::Entity::BNpc::moveTo( const FFXIVARR_POSITION3& pos )
}
auto pos1 = pNaviProvider->getMovePos( *this );
auto distance = Util::distance( pos1, pos );
auto distance = Common::Util::distance( pos1, pos );
if( distance < getNaviTargetReachedDistance() )
{
@ -380,7 +383,7 @@ bool Sapphire::Entity::BNpc::moveTo( const FFXIVARR_POSITION3& pos )
return false;
}
bool Sapphire::Entity::BNpc::moveTo( const Entity::Chara& targetChara )
bool BNpc::moveTo( const Chara& targetChara )
{
auto& teriMgr = Common::Service< World::Manager::TerritoryMgr >::ref();
@ -395,7 +398,7 @@ bool Sapphire::Entity::BNpc::moveTo( const Entity::Chara& targetChara )
}
auto pos1 = pNaviProvider->getMovePos( *this );
auto distance = Util::distance( pos1, targetChara.getPos() );
auto distance = Common::Util::distance( pos1, targetChara.getPos() );
if( distance <= ( getNaviTargetReachedDistance() + targetChara.getRadius() ) )
{
@ -418,7 +421,7 @@ bool Sapphire::Entity::BNpc::moveTo( const Entity::Chara& targetChara )
return false;
}
void Sapphire::Entity::BNpc::sendPositionUpdate()
void BNpc::sendPositionUpdate()
{
uint8_t animationType = 2;
@ -429,7 +432,7 @@ void Sapphire::Entity::BNpc::sendPositionUpdate()
server().queueForPlayers( getInRangePlayerIds(), movePacket );
}
void Sapphire::Entity::BNpc::hateListClear()
void BNpc::hateListClear()
{
for( auto& listEntry : m_hateList )
{
@ -439,7 +442,7 @@ void Sapphire::Entity::BNpc::hateListClear()
m_hateList.clear();
}
uint32_t Sapphire::Entity::BNpc::hateListGetValue( const Sapphire::Entity::CharaPtr& pChara )
uint32_t BNpc::hateListGetValue( const Sapphire::Entity::CharaPtr& pChara )
{
for( const auto& listEntry : m_hateList )
{
@ -452,7 +455,7 @@ uint32_t Sapphire::Entity::BNpc::hateListGetValue( const Sapphire::Entity::Chara
return 0;
}
uint32_t Sapphire::Entity::BNpc::hateListGetHighestValue()
uint32_t BNpc::hateListGetHighestValue()
{
auto it = m_hateList.begin();
uint32_t maxHate = 0;
@ -473,7 +476,7 @@ uint32_t Sapphire::Entity::BNpc::hateListGetHighestValue()
}
Sapphire::Entity::CharaPtr Sapphire::Entity::BNpc::hateListGetHighest()
CharaPtr BNpc::hateListGetHighest()
{
auto it = m_hateList.begin();
uint32_t maxHate = 0;
@ -493,7 +496,7 @@ Sapphire::Entity::CharaPtr Sapphire::Entity::BNpc::hateListGetHighest()
return nullptr;
}
void Sapphire::Entity::BNpc::hateListAdd( const Sapphire::Entity::CharaPtr& pChara, int32_t hateAmount )
void BNpc::hateListAdd( const CharaPtr& pChara, int32_t hateAmount )
{
auto hateEntry = std::make_shared< HateListEntry >();
hateEntry->m_hateAmount = static_cast< uint32_t >( hateAmount );
@ -507,14 +510,14 @@ void Sapphire::Entity::BNpc::hateListAdd( const Sapphire::Entity::CharaPtr& pCha
}
}
void Sapphire::Entity::BNpc::hateListAddDelayed( const Sapphire::Entity::CharaPtr& pChara, int32_t hateAmount )
void BNpc::hateListAddDelayed( const CharaPtr& pChara, int32_t hateAmount )
{
auto& taskMgr = Common::Service< World::Manager::TaskMgr >::ref();
auto delayedEmnityTask = std::make_shared< Sapphire::World::DelayedEmnityTask >( 5000, getAsBNpc(), pChara, hateAmount );
auto delayedEmnityTask = std::make_shared< World::DelayedEmnityTask >( 5000, getAsBNpc(), pChara, hateAmount );
taskMgr.queueTask( delayedEmnityTask );
}
void Sapphire::Entity::BNpc::hateListUpdate( const Sapphire::Entity::CharaPtr& pChara, int32_t hateAmount )
void BNpc::hateListUpdate( const CharaPtr& pChara, int32_t hateAmount )
{
bool hasEntry = false;
@ -542,12 +545,12 @@ void Sapphire::Entity::BNpc::hateListUpdate( const Sapphire::Entity::CharaPtr& p
if( pChara->isPlayer() )
{
auto pPlayer = pChara->getAsPlayer();
Network::Util::Player::sendHateList( *pPlayer );
Network::Util::Packet::sendHateList( *pPlayer );
}
}
}
void Sapphire::Entity::BNpc::hateListRemove( const Sapphire::Entity::CharaPtr& pChara )
void BNpc::hateListRemove( const CharaPtr& pChara )
{
for( const auto& listEntry : m_hateList )
{
@ -565,33 +568,33 @@ void Sapphire::Entity::BNpc::hateListRemove( const Sapphire::Entity::CharaPtr& p
}
}
uint32_t Sapphire::Entity::BNpc::getTriggerOwnerId() const
uint32_t BNpc::getTriggerOwnerId() const
{
return m_triggerOwnerId;
}
void Sapphire::Entity::BNpc::setTriggerOwnerId( uint32_t triggerOwnerId )
void BNpc::setTriggerOwnerId( uint32_t triggerOwnerId )
{
m_triggerOwnerId = triggerOwnerId;
}
bool Sapphire::Entity::BNpc::hateListHasActor( const Sapphire::Entity::CharaPtr& pChara )
bool BNpc::hateListHasActor( const Sapphire::Entity::CharaPtr& pChara )
{
return std::any_of( m_hateList.begin(), m_hateList.end(),
[ pChara ]( const auto& entry ) { return entry->m_pChara == pChara; } );
}
void Sapphire::Entity::BNpc::aggro( const Sapphire::Entity::CharaPtr& pChara )
void BNpc::aggro( const Sapphire::Entity::CharaPtr& pChara )
{
auto& pRNGMgr = Common::Service< World::Manager::RNGMgr >::ref();
auto variation = static_cast< uint32_t >( pRNGMgr.getRandGenerator< float >( 500, 1000 ).next() );
m_lastAttack = Util::getTimeMs() + variation;
m_lastAttack = Common::Util::getTimeMs() + variation;
setStance( Stance::Active );
m_state = BNpcState::Combat;
server().queueForPlayers( getInRangePlayerIds(), makeActorControl( getId(), ActorControlType::SetBattle, 1, 0, 0 ) );
Network::Util::Packet::sendActorControl( getInRangePlayerIds(), getId(), SetBattle, 1 );
changeTarget( pChara->getId() );
@ -603,7 +606,7 @@ void Sapphire::Entity::BNpc::aggro( const Sapphire::Entity::CharaPtr& pChara )
}
void Sapphire::Entity::BNpc::deaggro( const Sapphire::Entity::CharaPtr& pChara )
void BNpc::deaggro( const CharaPtr& pChara )
{
if( !hateListHasActor( pChara ) )
hateListRemove( pChara );
@ -611,8 +614,8 @@ void Sapphire::Entity::BNpc::deaggro( const Sapphire::Entity::CharaPtr& pChara )
if( pChara->isPlayer() )
{
PlayerPtr tmpPlayer = pChara->getAsPlayer();
server().queueForPlayers( getInRangePlayerIds(), makeActorControl( getId(), ActorControlType::ToggleWeapon, 0, 1, 1 ) );
server().queueForPlayers( getInRangePlayerIds(), makeActorControl( getId(), ActorControlType::SetBattle, 0, 0, 0 ) );
Network::Util::Packet::sendActorControl( getInRangePlayerIds(), getId(), ToggleWeapon, 0, 1, 1 );
Network::Util::Packet::sendActorControl( getInRangePlayerIds(), getId(), SetBattle );
tmpPlayer->onMobDeaggro( *this );
if( getTriggerOwnerId() == pChara->getId() )
@ -624,7 +627,7 @@ void Sapphire::Entity::BNpc::deaggro( const Sapphire::Entity::CharaPtr& pChara )
}
}
void Sapphire::Entity::BNpc::onTick()
void BNpc::onTick()
{
Chara::onTick();
if( m_state == BNpcState::Retreat )
@ -633,7 +636,7 @@ void Sapphire::Entity::BNpc::onTick()
}
}
void Sapphire::Entity::BNpc::update( uint64_t tickCount )
void BNpc::update( uint64_t tickCount )
{
auto& teriMgr = Common::Service< World::Manager::TerritoryMgr >::ref();
auto pZone = teriMgr.getTerritoryByGuId( getTerritoryId() );
@ -646,6 +649,9 @@ void Sapphire::Entity::BNpc::update( uint64_t tickCount )
if( !pNaviProvider )
return;
if( !checkAction() )
processGambits( tickCount );
switch( m_state )
{
case BNpcState::Dead:
@ -665,7 +671,7 @@ void Sapphire::Entity::BNpc::update( uint64_t tickCount )
// retail doesn't seem to roam straight after retreating
// todo: perhaps requires more investigation?
m_lastRoamTargetReached = Util::getTimeSeconds();
m_lastRoamTargetReached = Common::Util::getTimeSeconds();
// resetHp
setHp( getMaxHp() );
@ -684,7 +690,7 @@ void Sapphire::Entity::BNpc::update( uint64_t tickCount )
if( moveTo( m_roamPos ) )
{
m_lastRoamTargetReached = Util::getTimeSeconds();
m_lastRoamTargetReached = Common::Util::getTimeSeconds();
m_state = BNpcState::Idle;
}
@ -701,12 +707,12 @@ void Sapphire::Entity::BNpc::update( uint64_t tickCount )
if( pNaviProvider->syncPosToChara( *this ) )
sendPositionUpdate();
if( !hasFlag( Immobile ) && ( Util::getTimeSeconds() - m_lastRoamTargetReached > roamTick ) )
if( !hasFlag( Immobile ) && ( Common::Util::getTimeSeconds() - m_lastRoamTargetReached > roamTick ) )
{
if( !pNaviProvider )
{
m_lastRoamTargetReached = Util::getTimeSeconds();
m_lastRoamTargetReached = Common::Util::getTimeSeconds();
break;
}
if( m_pInfo->WanderingRange != 0 && getEnemyType() != 0 )
@ -732,7 +738,7 @@ void Sapphire::Entity::BNpc::update( uint64_t tickCount )
pNaviProvider->updateAgentParameters( *this );
auto distanceOrig = Util::distance( getPos().x, getPos().y, getPos().z, m_spawnPos.x, m_spawnPos.y, m_spawnPos.z );
auto distanceOrig = Common::Util::distance( getPos(), m_spawnPos );
if( pHatedActor && !pHatedActor->isAlive() )
{
@ -742,8 +748,7 @@ void Sapphire::Entity::BNpc::update( uint64_t tickCount )
if( pHatedActor )
{
auto distance = Util::distance( getPos().x, getPos().y, getPos().z,
pHatedActor->getPos().x, pHatedActor->getPos().y, pHatedActor->getPos().z );
auto distance = Common::Util::distance( getPos(), pHatedActor->getPos() );
if( !hasFlag( NoDeaggro ) && ( ( distanceOrig > maxDistanceToOrigin ) || distance > 30.0f ) )
{
@ -794,7 +799,7 @@ void Sapphire::Entity::BNpc::update( uint64_t tickCount )
Chara::update( tickCount );
}
void Sapphire::Entity::BNpc::restHp()
void BNpc::restHp()
{
if( m_hp < getMaxHp() )
{
@ -806,10 +811,10 @@ void Sapphire::Entity::BNpc::restHp()
m_hp = getMaxHp();
}
sendHudParam();
Network::Util::Packet::sendHudParam( *this );
}
void Sapphire::Entity::BNpc::onActionHostile( Sapphire::Entity::CharaPtr pSource )
void BNpc::onActionHostile( CharaPtr pSource )
{
if( !hateListGetHighest() )
aggro( pSource );
@ -820,7 +825,7 @@ void Sapphire::Entity::BNpc::onActionHostile( Sapphire::Entity::CharaPtr pSource
setOwner( pSource );
}
void Sapphire::Entity::BNpc::onDeath()
void BNpc::onDeath()
{
auto& playerMgr = Common::Service< World::Manager::PlayerMgr >::ref();
auto& taskMgr = Common::Service< World::Manager::TaskMgr >::ref();
@ -828,7 +833,7 @@ void Sapphire::Entity::BNpc::onDeath()
setTargetId( INVALID_GAME_OBJECT_ID64 );
m_currentStance = Stance::Passive;
m_state = BNpcState::Dead;
m_timeOfDeath = Util::getTimeSeconds();
m_timeOfDeath = Common::Util::getTimeSeconds();
setOwner( nullptr );
taskMgr.queueTask( World::makeFadeBNpcTask( 10000, getAsBNpc() ) );
@ -851,17 +856,17 @@ void Sapphire::Entity::BNpc::onDeath()
hateListClear();
}
uint32_t Sapphire::Entity::BNpc::getTimeOfDeath() const
uint32_t BNpc::getTimeOfDeath() const
{
return m_timeOfDeath;
}
void Sapphire::Entity::BNpc::setTimeOfDeath( uint32_t timeOfDeath )
void BNpc::setTimeOfDeath( uint32_t timeOfDeath )
{
m_timeOfDeath = timeOfDeath;
}
void Sapphire::Entity::BNpc::checkAggro()
void BNpc::checkAggro()
{
// passive mobs should ignore players unless aggro'd
if( m_aggressionMode == 1 )
@ -885,7 +890,7 @@ void Sapphire::Entity::BNpc::checkAggro()
range = std::max< float >( 0.f, range - std::pow( 1.53f, static_cast< float >( levelDiff ) * 0.6f ) );
}
auto distance = Util::distance( getPos(), pClosestChara->getPos() );
auto distance = Common::Util::distance( getPos(), pClosestChara->getPos() );
if( distance < range )
{
@ -916,7 +921,7 @@ void Sapphire::Entity::BNpc::checkAggro()
range = std::max< float >( 0.f, range - std::pow( 1.53f, static_cast< float >( levelDiff ) * 0.6f ) );
}
auto distance = Util::distance( getPos(), pClosestChara->getPos() );
auto distance = Common::Util::distance( getPos(), pClosestChara->getPos() );
if( distance < range )
{
@ -925,7 +930,7 @@ void Sapphire::Entity::BNpc::checkAggro()
}
}
void Sapphire::Entity::BNpc::setOwner( const Sapphire::Entity::CharaPtr& m_pChara )
void BNpc::setOwner( const CharaPtr& m_pChara )
{
m_pOwner = m_pChara;
auto targetId = static_cast< uint32_t >( INVALID_GAME_OBJECT_ID );
@ -937,40 +942,39 @@ void Sapphire::Entity::BNpc::setOwner( const Sapphire::Entity::CharaPtr& m_pChar
setOwnerPacket->data().Id = targetId;
server().queueForPlayers( getInRangePlayerIds(), setOwnerPacket );
if( m_pChara != nullptr && m_pChara->isPlayer() )
{
auto letter = makeActorControl( getId(), ActorControlType::SetHateLetter, 1, getId(), 0 );
server().queueForPlayer( m_pChara->getAsPlayer()->getCharacterId(), letter );
}
if( m_pChara && m_pChara->isPlayer() )
Network::Util::Packet::sendActorControl( *m_pChara->getAsPlayer(), getId(), SetHateLetter, 1, getId(), 0 );
}
void Sapphire::Entity::BNpc::setLevelId( uint32_t levelId )
void BNpc::setLevelId( uint32_t levelId )
{
m_levelId = levelId;
}
uint32_t Sapphire::Entity::BNpc::getLevelId() const
uint32_t BNpc::getLevelId() const
{
return m_levelId;
}
bool Sapphire::Entity::BNpc::hasFlag( uint32_t flag ) const
bool BNpc::hasFlag( uint32_t flag ) const
{
return m_flags & flag;
}
void Sapphire::Entity::BNpc::setFlag( uint32_t flag )
void BNpc::setFlag( uint32_t flag )
{
m_flags |= flag;
}
void Sapphire::Entity::BNpc::autoAttack( CharaPtr pTarget )
void BNpc::autoAttack( CharaPtr pTarget )
{
auto& teriMgr = Common::Service< World::Manager::TerritoryMgr >::ref();
auto pZone = teriMgr.getTerritoryByGuId( getTerritoryId() );
auto& actionMgr = Common::Service< World::Manager::ActionMgr >::ref();
auto& exdData = Common::Service< Data::ExdData >::ref();
uint64_t tick = Util::getTimeMs();
uint64_t tick = Common::Util::getTimeMs();
// todo: this needs to use the auto attack delay for the equipped weapon
if( ( tick - m_lastAttack ) > 2500 )
@ -978,30 +982,11 @@ void Sapphire::Entity::BNpc::autoAttack( CharaPtr pTarget )
pTarget->onActionHostile( getAsChara() );
m_lastAttack = tick;
srand( static_cast< uint32_t >( tick ) );
auto damage = Math::CalcStats::calcAutoAttackDamage( *this );
//damage.first = 1;
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 = 3;
effectEntry.Arg1 = 7;
auto resultId = pZone->getNextEffectResultId();
effectPacket->setResultId( resultId );
effectPacket->addTargetEffect( effectEntry );
server().queueForPlayers( getInRangePlayerIds(), effectPacket );
pTarget->takeDamage( static_cast< uint16_t >( damage.first ) );
auto& taskMgr = Common::Service< World::Manager::TaskMgr >::ref();
taskMgr.queueTask( Sapphire::World::makeActionIntegrityTask( resultId, pTarget, 500 ) );
actionMgr.handleTargetedAction( *this, 7, exdData.getRow< Excel::Action >( 7 ), pTarget->getId(), 0 );
}
}
void Sapphire::Entity::BNpc::calculateStats()
void BNpc::calculateStats()
{
auto level = getLevel();
auto job = static_cast< uint8_t >( getClass() );
@ -1044,28 +1029,61 @@ void Sapphire::Entity::BNpc::calculateStats()
}
uint32_t Sapphire::Entity::BNpc::getRank() const
uint32_t BNpc::getRank() const
{
return m_rank;
}
uint32_t Sapphire::Entity::BNpc::getBoundInstanceId() const
uint32_t BNpc::getBoundInstanceId() const
{
return m_boundInstanceId;
}
BNpcType Sapphire::Entity::BNpc::getBNpcType() const
BNpcType BNpc::getBNpcType() const
{
return m_bnpcType;
}
uint32_t Sapphire::Entity::BNpc::getLayoutId() const
uint32_t BNpc::getLayoutId() const
{
return m_layoutId;
}
void Sapphire::Entity::BNpc::init()
void BNpc::init()
{
m_maxHp = Sapphire::Math::CalcStats::calculateMaxHp( *getAsChara() );
auto& exdData = Common::Service< Data::ExdData >::ref();
m_maxHp = Math::CalcStats::calculateMaxHp( *getAsChara() );
m_hp = m_maxHp;
//setup a test gambit
auto testGambitRule = std::make_shared< AI::GambitRule >( std::make_shared< AI::TopHateTargetCondition >(),
Action::make_Action( getAsChara(), 88, 0, exdData.getRow< Excel::Action >( 88 ) ), 5000 );
auto testGambitRule1 = std::make_shared< AI::GambitRule >( std::make_shared< AI::HPSelfPctLessThan >( 50 ),
Action::make_Action( getAsChara(), 120, 0, exdData.getRow< Excel::Action >( 120 ) ), 5000 );
m_gambits.push_back( testGambitRule );
m_gambits.push_back( testGambitRule1 );
}
void BNpc::processGambits( uint64_t tickCount )
{
auto& exdData = Common::Service< Data::ExdData >::ref();
auto& actionMgr = Common::Service< World::Manager::ActionMgr >::ref();
for( auto& gambitRule : m_gambits )
{
if( !gambitRule->isEnabled() )
continue;
if( ( tickCount - gambitRule->getLastExecutionMs() ) > gambitRule->getCoolDown() )
{
if( !gambitRule->getGambitTargetCondition()->isConditionMet( *this ) )
continue;
gambitRule->setLastExecutionMs( tickCount );
actionMgr.handleTargetedAction( *this, gambitRule->getActionPtr()->getId(), exdData.getRow< Excel::Action >( gambitRule->getActionPtr()->getId() ),
gambitRule->getGambitTargetCondition()->getTarget()->getId(), 0 );
}
}
}

View file

@ -3,6 +3,7 @@
#include <Common.h>
#include "Forwards.h"
#include "ForwardsZone.h"
#include "Chara.h"
#include "Npc.h"
#include <set>
@ -148,6 +149,8 @@ namespace Sapphire::Entity
uint32_t getLayoutId() const;
void processGambits( uint64_t tickCount );
private:
uint32_t m_bNpcBaseId;
uint32_t m_bNpcNameId;
@ -189,6 +192,7 @@ namespace Sapphire::Entity
Common::FFXIVARR_POSITION3 m_naviTarget;
CharaPtr m_pOwner;
std::vector< World::AI::GambitRulePtr > m_gambits;
};

View file

@ -12,11 +12,10 @@
#include "Network/GameConnection.h"
#include "Network/PacketWrappers/ActorControlPacket.h"
#include "Network/PacketWrappers/ActorControlTargetPacket.h"
#include "Network/PacketWrappers/RestingPacket.h"
#include "Network/PacketWrappers/EffectPacket1.h"
#include "Network/PacketWrappers/HudParamPacket.h"
#include "Network/Util/PacketUtil.h"
#include "StatusEffect/StatusEffect.h"
#include "Action/Action.h"
#include "WorldServer.h"
#include "Session.h"
@ -28,13 +27,16 @@
#include "Manager/PlayerMgr.h"
#include "Common.h"
using namespace Sapphire;
using namespace Sapphire::Common;
using namespace Sapphire::Entity;
using namespace Sapphire::World;
using namespace Sapphire::World::Manager;
using namespace Sapphire::Network::Packets;
using namespace Sapphire::Network::Packets::WorldPackets::Server;
using namespace Sapphire::Network::ActorControl;
Sapphire::Entity::Chara::Chara( ObjKind type ) :
Chara::Chara( ObjKind type ) :
GameObject( type ),
m_pose( 0 ),
m_targetId( INVALID_GAME_OBJECT_ID64 ),
@ -44,7 +46,7 @@ Sapphire::Entity::Chara::Chara( ObjKind type ) :
m_lastTickTime = 0;
m_lastUpdate = 0;
m_lastAttack = Util::getTimeMs();
m_lastAttack = Common::Util::getTimeMs();
m_bonusStats.fill( 0 );
@ -55,76 +57,75 @@ Sapphire::Entity::Chara::Chara( ObjKind type ) :
}
}
Sapphire::Entity::Chara::~Chara()
= default;
Chara::~Chara() = default;
/*! \return the actors name */
std::string Sapphire::Entity::Chara::getName() const
std::string Chara::getName() const
{
return { m_name };
}
/*! \return current stance of the actors */
Sapphire::Common::Stance Sapphire::Entity::Chara::getStance() const
Stance Chara::getStance() const
{
return m_currentStance;
}
/*! \return actor stats */
const Sapphire::Entity::Chara::ActorStatsArray& Sapphire::Entity::Chara::getStats() const
const Chara::ActorStatsArray& Chara::getStats() const
{
return m_baseStats;
}
/*! \return current HP */
uint32_t Sapphire::Entity::Chara::getHp() const
uint32_t Chara::getHp() const
{
return m_hp;
}
uint32_t Sapphire::Entity::Chara::getHpPercent() const
uint32_t Chara::getHpPercent() const
{
return ( m_hp * 100 ) / m_maxHp;
}
/*! \return current MP */
uint32_t Sapphire::Entity::Chara::getMp() const
uint32_t Chara::getMp() const
{
return m_mp;
}
/*! \return current TP */
uint16_t Sapphire::Entity::Chara::getTp() const
uint16_t Chara::getTp() const
{
return m_tp;
}
/*! \return current GP */
uint16_t Sapphire::Entity::Chara::getGp() const
uint16_t Chara::getGp() const
{
return m_gp;
}
/*! \return current invincibility type */
InvincibilityType Sapphire::Entity::Chara::getInvincibilityType() const
InvincibilityType Chara::getInvincibilityType() const
{
return m_invincibilityType;
}
/*! \return current class or job */
Sapphire::Common::ClassJob Sapphire::Entity::Chara::getClass() const
ClassJob Chara::getClass() const
{
return m_class;
}
/*! \param ClassJob to set */
void Sapphire::Entity::Chara::setClass( Common::ClassJob classJob )
void Chara::setClass( ClassJob classJob )
{
m_class = classJob;
}
Sapphire::Common::Role Sapphire::Entity::Chara::getRole() const
Role Chara::getRole() const
{
switch( getClass() )
{
@ -181,67 +182,67 @@ Sapphire::Common::Role Sapphire::Entity::Chara::getRole() const
}
/*! \param Id of the target to set */
void Sapphire::Entity::Chara::setTargetId( uint64_t targetId )
void Chara::setTargetId( uint64_t targetId )
{
m_targetId = targetId;
}
/*! \return Id of the current target */
uint64_t Sapphire::Entity::Chara::getTargetId() const
uint64_t Chara::getTargetId() const
{
return m_targetId;
}
/*! \return True if the actor is alive */
bool Sapphire::Entity::Chara::isAlive() const
bool Chara::isAlive() const
{
return ( m_hp > 0 );
}
/*! \return max hp for the actor */
uint32_t Sapphire::Entity::Chara::getMaxHp() const
uint32_t Chara::getMaxHp() const
{
return m_maxHp;
}
/*! \return max mp for the actor */
uint32_t Sapphire::Entity::Chara::getMaxMp() const
uint32_t Chara::getMaxMp() const
{
return m_maxMp;
}
/*! \return reset hp to current max hp */
void Sapphire::Entity::Chara::resetHp()
void Chara::resetHp()
{
m_hp = getMaxHp();
}
/*! \return reset mp to current max mp */
void Sapphire::Entity::Chara::resetMp()
void Chara::resetMp()
{
m_mp = getMaxMp();
}
/*! \param hp amount to set ( caps to maxHp ) */
void Sapphire::Entity::Chara::setHp( uint32_t hp )
void Chara::setHp( uint32_t hp )
{
m_hp = hp < getMaxHp() ? hp : getMaxHp();
}
/*! \param mp amount to set ( caps to maxMp ) */
void Sapphire::Entity::Chara::setMp( uint32_t mp )
void Chara::setMp( uint32_t mp )
{
m_mp = mp < getMaxMp() ? mp : getMaxMp();
}
/*! \param gp amount to set*/
void Sapphire::Entity::Chara::setGp( uint32_t gp )
void Chara::setGp( uint32_t gp )
{
m_gp = static_cast< uint16_t >( gp );
}
/*! \param tp amount to set*/
void Sapphire::Entity::Chara::setTp( uint32_t tp )
void Chara::setTp( uint32_t tp )
{
m_tp = static_cast< uint16_t >( tp );
}
@ -253,13 +254,13 @@ void Sapphire::Entity::Chara::setInvincibilityType( Common::InvincibilityType ty
}
/*! \return current status of the actor */
Sapphire::Common::ActorStatus Sapphire::Entity::Chara::getStatus() const
ActorStatus Chara::getStatus() const
{
return m_status;
}
/*! \param status to set */
void Sapphire::Entity::Chara::setStatus( ActorStatus status )
void Chara::setStatus( ActorStatus status )
{
m_status = status;
}
@ -268,7 +269,7 @@ void Sapphire::Entity::Chara::setStatus( ActorStatus status )
Performs necessary steps to mark an actor dead.
Sets hp/mp/tp, sets status, plays animation and fires onDeath event
*/
void Sapphire::Entity::Chara::die()
void Chara::die()
{
m_status = ActorStatus::Dead;
m_hp = 0;
@ -280,13 +281,18 @@ void Sapphire::Entity::Chara::die()
// if the actor is a player, the update needs to be send to himself too
bool selfNeedsUpdate = isPlayer();
Network::Util::Packet::sendActorControl( getInRangePlayerIds( selfNeedsUpdate ), getId(), SetStatus, static_cast< uint8_t >( ActorStatus::Dead ) );
Network::Util::Packet::sendActorControl( getInRangePlayerIds( selfNeedsUpdate ), getId(), DeathAnimation );
}
FFXIVPacketBasePtr packet = makeActorControl( m_id, SetStatus, static_cast< uint8_t >( ActorStatus::Dead ) );
server().queueForPlayers( getInRangePlayerIds( selfNeedsUpdate ), packet );
FFXIVPacketBasePtr packet1 = makeActorControl( m_id, DeathAnimation, 0, 0, 0, 0 );
server().queueForPlayers( getInRangePlayerIds( selfNeedsUpdate ), packet1 );
uint64_t Chara::getLastAttack() const
{
return m_lastAttack;
}
void Chara::setLastAttack( uint64_t tickCount )
{
m_lastAttack = tickCount;
}
/*!
@ -295,10 +301,10 @@ position
\param Position to look towards
*/
bool Sapphire::Entity::Chara::face( const Common::FFXIVARR_POSITION3& p )
bool Chara::face( const FFXIVARR_POSITION3& p )
{
float oldRot = getRot();
float rot = Util::calcAngFrom( getPos().x, getPos().z, p.x, p.z );
float rot = Common::Util::calcAngFrom( getPos().x, getPos().z, p.x, p.z );
float newRot = PI - rot + ( PI / 2 );
setRot( newRot );
@ -312,12 +318,10 @@ Set and propagate the actor stance to in range players
\param stance to set
*/
void Sapphire::Entity::Chara::setStance( Stance stance )
void Chara::setStance( Stance stance )
{
m_currentStance = stance;
FFXIVPacketBasePtr packet = makeActorControl( m_id, ToggleWeapon, stance, 1 );
server().queueForPlayers( getInRangePlayerIds(), packet );
Network::Util::Packet::sendActorControl( getInRangePlayerIds(), getId(), ToggleWeapon, stance, 1 );
}
/*!
@ -326,7 +330,7 @@ and if fully performed, clean up again.
\return true if a queued action has been updated
*/
bool Sapphire::Entity::Chara::checkAction()
bool Chara::checkAction()
{
if( m_pCurrentAction == nullptr )
@ -339,7 +343,7 @@ bool Sapphire::Entity::Chara::checkAction()
}
void Sapphire::Entity::Chara::update( uint64_t tickCount )
void Chara::update( uint64_t tickCount )
{
updateStatusEffects();
@ -358,17 +362,16 @@ Change the current target and propagate to in range players
\param target actor id
*/
void Sapphire::Entity::Chara::changeTarget( uint64_t targetId )
void Chara::changeTarget( uint64_t targetId )
{
setTargetId( targetId );
FFXIVPacketBasePtr packet = makeActorControlTarget( m_id, SetTarget, 0, 0, 0, 0, targetId );
server().queueForPlayers( getInRangePlayerIds(), packet );
Network::Util::Packet::sendActorControlTarget( getInRangePlayerIds(), getId(), ToggleWeapon, SetTarget, 0, 0, 0, 0, targetId );
}
/*!
Dummy function \return 0
*/
uint8_t Sapphire::Entity::Chara::getLevel() const
uint8_t Chara::getLevel() const
{
return 0;
}
@ -382,7 +385,7 @@ magical dmg and take status effects into account
\param amount of damage to be taken
*/
void Sapphire::Entity::Chara::takeDamage( uint32_t damage )
void Chara::takeDamage( uint32_t damage )
{
if( damage >= m_hp )
{
@ -413,7 +416,7 @@ in range
\param amount of hp to be healed
*/
void Sapphire::Entity::Chara::heal( uint32_t amount )
void Chara::heal( uint32_t amount )
{
if( ( m_hp + amount ) > getMaxHp() )
{
@ -423,7 +426,7 @@ void Sapphire::Entity::Chara::heal( uint32_t amount )
m_hp += amount;
}
void Sapphire::Entity::Chara::restoreMP( uint32_t amount )
void Chara::restoreMP( uint32_t amount )
{
if( ( m_mp + amount ) > getMaxMp() )
{
@ -433,27 +436,14 @@ void Sapphire::Entity::Chara::restoreMP( uint32_t amount )
m_mp += amount;
}
/*!
Send an HpMpTp update to players in range ( and potentially to self )
TODO: poor naming, should be changed. Status is not HP. Also should be virtual
so players can have their own version and we can abolish the param.
\param true if the update should also be sent to the actor ( player ) himself
*/
void Sapphire::Entity::Chara::sendHudParam()
{
FFXIVPacketBasePtr packet = makeHudParam( *this );
server().queueForPlayers( getInRangePlayerIds( isPlayer() ), packet );
}
/*! \return ActionPtr of the currently registered action, or nullptr */
Sapphire::World::Action::ActionPtr Sapphire::Entity::Chara::getCurrentAction() const
Action::ActionPtr Chara::getCurrentAction() const
{
return m_pCurrentAction;
}
/*! \param ActionPtr of the action to be registered */
void Sapphire::Entity::Chara::setCurrentAction( Sapphire::World::Action::ActionPtr pAction )
void Chara::setCurrentAction( Action::ActionPtr pAction )
{
m_pCurrentAction = std::move( pAction );
}
@ -467,9 +457,9 @@ Will have to be extended for ranged attacks.
\param GameObjectPtr the autoAttack is performed on
*/
void Sapphire::Entity::Chara::autoAttack( CharaPtr pTarget )
void Chara::autoAttack( CharaPtr pTarget )
{
uint64_t tick = Util::getTimeMs();
uint64_t tick = Common::Util::getTimeMs();
// todo: this needs to use the auto attack delay for the equipped weapon
if( ( tick - m_lastAttack ) > 2500 )
@ -481,7 +471,7 @@ void Sapphire::Entity::Chara::autoAttack( CharaPtr pTarget )
auto damage = static_cast< uint16_t >( 10 + rand() % 12 );
auto effectPacket = std::make_shared< EffectPacket1 >( getId(), pTarget->getId(), 7 );
effectPacket->setRotation( Util::floatToUInt16Rot( getRot() ) );
effectPacket->setRotation( Common::Util::floatToUInt16Rot( getRot() ) );
Common::CalcResultParam effectEntry{};
effectEntry.Value = static_cast< int16_t >( damage );
@ -497,9 +487,9 @@ void Sapphire::Entity::Chara::autoAttack( CharaPtr pTarget )
}
/*! \param StatusEffectPtr to be applied to the actor */
void Sapphire::Entity::Chara::addStatusEffect( StatusEffect::StatusEffectPtr pEffect )
void Chara::addStatusEffect( StatusEffect::StatusEffectPtr pEffect )
{
auto& teriMgr = Common::Service< World::Manager::TerritoryMgr >::ref();
auto& teriMgr = Common::Service< Manager::TerritoryMgr >::ref();
auto pZone = teriMgr.getTerritoryByGuId( getTerritoryId() );
int8_t nextSlot = getStatusEffectFreeSlot();
@ -507,51 +497,29 @@ void Sapphire::Entity::Chara::addStatusEffect( StatusEffect::StatusEffectPtr pEf
if( nextSlot == -1 )
return;
pEffect->setSlot( nextSlot );
m_statusEffectMap[ nextSlot ] = pEffect;
pEffect->applyStatus();
auto statusEffectAdd = makeZonePacket< FFXIVIpcActionIntegrity >( getId() );
statusEffectAdd->data().ResultId = pZone->getNextEffectResultId();
statusEffectAdd->data().Target = pEffect->getTargetActorId();
statusEffectAdd->data().Hp = getHp();
statusEffectAdd->data().Mp = static_cast< uint16_t >( getMp() );
statusEffectAdd->data().Tp = static_cast< uint16_t >( getTp() );
statusEffectAdd->data().HpMax = getMaxHp();
statusEffectAdd->data().MpMax = static_cast< uint16_t >( getMaxMp() );
statusEffectAdd->data().ClassJob = static_cast< uint8_t >( getClass() );
statusEffectAdd->data().StatusCount = 1;
statusEffectAdd->data().unknown_E0 = 0xE0;
// set all status sources to u32 invalid game obj
// todo: chara status effect map should be filled instead, since hudparam also uses invalid gameobj
for( int i = 0; i < 4; ++i )
{
statusEffectAdd->data().Status[ i ].Source = INVALID_GAME_OBJECT_ID;
}
auto& status = statusEffectAdd->data().Status[ 0 ];
status.Source = pEffect->getSrcActorId();
status.Time = static_cast< float >( pEffect->getDuration() ) / 1000;
status.Id = static_cast< uint16_t >( pEffect->getId() );
status.Slot = static_cast< uint8_t >( nextSlot );
status.SystemParam = static_cast< int16_t >( pEffect->getParam() );
server().queueForPlayers( getInRangePlayerIds( isPlayer() ), statusEffectAdd );
}
/*! \param StatusEffectPtr to be applied to the actor */
void Sapphire::Entity::Chara::addStatusEffectById( uint32_t id, int32_t duration, Entity::Chara& source, uint16_t param )
void Chara::addStatusEffectById( uint32_t id, int32_t duration, Entity::Chara& source, uint16_t param )
{
auto effect = StatusEffect::make_StatusEffect( id, source.getAsChara(), getAsChara(), duration, 3000 );
effect->setParam( param );
addStatusEffect( effect );
}
void Chara::addStatusEffectById( uint32_t id, int32_t duration, Entity::Chara& source,
std::vector< World::Action::StatusModifier > modifiers, uint32_t flag, uint16_t param )
{
auto effect = StatusEffect::make_StatusEffect( id, source.getAsChara(), getAsChara(), duration, modifiers, flag, 3000 );
effect->setParam( param );
addStatusEffect( effect );
}
/*! \param StatusEffectPtr to be applied to the actor */
void Sapphire::Entity::Chara::addStatusEffectByIdIfNotExist( uint32_t id, int32_t duration, Entity::Chara& source,
uint16_t param )
void Chara::addStatusEffectByIdIfNotExist( uint32_t id, int32_t duration, Entity::Chara& source, uint16_t param )
{
if( hasStatusEffect( id ) )
return;
@ -562,28 +530,17 @@ void Sapphire::Entity::Chara::addStatusEffectByIdIfNotExist( uint32_t id, int32_
}
void Sapphire::Entity::Chara::addStatusEffectByIdIfNotExist( uint32_t id, int32_t duration, Entity::Chara& source,
std::vector< World::Action::StatusModifier > modifiers, uint16_t param )
std::vector< World::Action::StatusModifier > modifiers, uint32_t flag, uint16_t param )
{
if( hasStatusEffect( id ) )
return;
auto effect = StatusEffect::make_StatusEffect( id, source.getAsChara(), getAsChara(), duration, modifiers, 3000 );
auto effect = StatusEffect::make_StatusEffect( id, source.getAsChara(), getAsChara(), duration, modifiers, flag, 3000 );
effect->setParam( param );
addStatusEffect( effect );
}
void Sapphire::Entity::Chara::addStatusEffectByIdIfNotExist( uint32_t id, int32_t duration, Entity::Chara& source,
World::Action::StatusEntry& statusEntry, uint16_t param )
{
if( hasStatusEffect( id ) )
return;
auto effect = StatusEffect::make_StatusEffect( id, source.getAsChara(), getAsChara(), duration, statusEntry, 3000 );
effect->setParam( param );
addStatusEffect( effect );
}
int8_t Sapphire::Entity::Chara::getStatusEffectFreeSlot()
int8_t Chara::getStatusEffectFreeSlot()
{
int8_t freeEffectSlot = -1;
@ -596,12 +553,12 @@ int8_t Sapphire::Entity::Chara::getStatusEffectFreeSlot()
return freeEffectSlot;
}
void Sapphire::Entity::Chara::statusEffectFreeSlot( uint8_t slotId )
void Chara::statusEffectFreeSlot( uint8_t slotId )
{
m_statusEffectFreeSlotQueue.push( slotId );
}
void Sapphire::Entity::Chara::replaceSingleStatusEffectById( uint32_t id )
void Chara::replaceSingleStatusEffectById( uint32_t id )
{
for( const auto& effectIt : m_statusEffectMap )
{
@ -613,7 +570,7 @@ void Sapphire::Entity::Chara::replaceSingleStatusEffectById( uint32_t id )
}
}
void Sapphire::Entity::Chara::removeSingleStatusEffectById( uint32_t id )
void Chara::removeSingleStatusEffectById( uint32_t id )
{
for( const auto& effectIt : m_statusEffectMap )
{
@ -625,7 +582,7 @@ void Sapphire::Entity::Chara::removeSingleStatusEffectById( uint32_t id )
}
}
void Sapphire::Entity::Chara::removeStatusEffectByFlag( Common::StatusEffectFlag flag )
void Chara::removeStatusEffectByFlag( Common::StatusEffectFlag flag )
{
for( auto effectIt = m_statusEffectMap.begin(); effectIt != m_statusEffectMap.end(); )
{
@ -636,7 +593,7 @@ void Sapphire::Entity::Chara::removeStatusEffectByFlag( Common::StatusEffectFlag
}
}
std::map< uint8_t, Sapphire::StatusEffect::StatusEffectPtr >::iterator Sapphire::Entity::Chara::removeStatusEffect( uint8_t effectSlotId, bool sendOrder )
std::map< uint8_t, Sapphire::StatusEffect::StatusEffectPtr >::iterator Chara::removeStatusEffect( uint8_t effectSlotId, bool sendOrder )
{
auto pEffectIt = m_statusEffectMap.find( effectSlotId );
if( pEffectIt == m_statusEffectMap.end() )
@ -648,24 +605,19 @@ std::map< uint8_t, Sapphire::StatusEffect::StatusEffectPtr >::iterator Sapphire:
pEffect->removeStatus();
if( sendOrder )
server().queueForPlayers( getInRangePlayerIds( isPlayer() ), makeActorControl( getId(), StatusEffectLose, pEffect->getId() ) );
Network::Util::Packet::sendActorControl( getInRangePlayerIds( isPlayer() ), getId(), StatusEffectLose, pEffect->getId() );
auto it = m_statusEffectMap.erase( pEffectIt );
if( isPlayer() )
server().queueForPlayers( getInRangePlayerIds( isPlayer() ), makeHudParam( *getAsPlayer() ) );
else if( isBattleNpc() )
server().queueForPlayers( getInRangePlayerIds( isPlayer() ), makeHudParam( *getAsBNpc() ) );
Network::Util::Packet::sendHudParam( *this );
return it;
}
std::map< uint8_t, Sapphire::StatusEffect::StatusEffectPtr > Sapphire::Entity::Chara::getStatusEffectMap() const
std::map< uint8_t, StatusEffect::StatusEffectPtr > Chara::getStatusEffectMap() const
{
return m_statusEffectMap;
}
Sapphire::StatusEffect::StatusEffectPtr Sapphire::Entity::Chara::getStatusEffectById( uint32_t id ) const
Sapphire::StatusEffect::StatusEffectPtr Chara::getStatusEffectById( uint32_t id ) const
{
for( const auto& effectIt : m_statusEffectMap )
{
@ -676,29 +628,29 @@ Sapphire::StatusEffect::StatusEffectPtr Sapphire::Entity::Chara::getStatusEffect
return nullptr;
}
const uint8_t* Sapphire::Entity::Chara::getLookArray() const
const uint8_t* Chara::getLookArray() const
{
return m_customize;
}
const uint32_t* Sapphire::Entity::Chara::getModelArray() const
const uint32_t* Chara::getModelArray() const
{
return m_modelEquip;
}
uint8_t Sapphire::Entity::Chara::getPose() const
uint8_t Chara::getPose() const
{
return m_pose;
}
void Sapphire::Entity::Chara::setPose( uint8_t pose )
void Chara::setPose( uint8_t pose )
{
m_pose = pose;
}
void Sapphire::Entity::Chara::sendStatusEffectUpdate()
void Chara::sendStatusEffectUpdate()
{
uint64_t currentTimeMs = Util::getTimeMs();
uint64_t currentTimeMs = Common::Util::getTimeMs();
auto statusEffectList = makeZonePacket< FFXIVIpcStatus >( getId() );
uint8_t slot = 0;
@ -715,9 +667,9 @@ void Sapphire::Entity::Chara::sendStatusEffectUpdate()
server().queueForPlayers( getInRangePlayerIds( isPlayer() ), statusEffectList );
}
void Sapphire::Entity::Chara::updateStatusEffects()
void Chara::updateStatusEffects()
{
uint64_t currentTimeMs = Util::getTimeMs();
uint64_t currentTimeMs = Common::Util::getTimeMs();
for( auto effectIt = m_statusEffectMap.begin(); effectIt != m_statusEffectMap.end(); )
{
@ -742,7 +694,7 @@ void Sapphire::Entity::Chara::updateStatusEffects()
}
}
bool Sapphire::Entity::Chara::hasStatusEffect( uint32_t id )
bool Chara::hasStatusEffect( uint32_t id )
{
for( const auto& [ key, val ] : m_statusEffectMap )
{
@ -753,23 +705,23 @@ bool Sapphire::Entity::Chara::hasStatusEffect( uint32_t id )
return false;
}
int64_t Sapphire::Entity::Chara::getLastUpdateTime() const
int64_t Chara::getLastUpdateTime() const
{
return m_lastUpdate;
}
void Sapphire::Entity::Chara::setLastComboActionId( uint32_t actionId )
void Chara::setLastComboActionId( uint32_t actionId )
{
m_lastComboActionId = actionId;
m_lastComboActionTime = Util::getTimeMs();
m_lastComboActionTime = Common::Util::getTimeMs();
}
uint32_t Sapphire::Entity::Chara::getLastComboActionId() const
uint32_t Chara::getLastComboActionId() const
{
// initially check for the time passed first, if it's more than the threshold just return 0 for the combo
// we can hide the implementation detail this way and it just works:tm: for anything that uses it
if( std::difftime( static_cast< time_t >( Util::getTimeMs() ),
if( std::difftime( static_cast< time_t >( Common::Util::getTimeMs() ),
static_cast< time_t >( m_lastComboActionTime ) ) > Common::MAX_COMBO_LENGTH )
{
return 0;
@ -778,43 +730,42 @@ uint32_t Sapphire::Entity::Chara::getLastComboActionId() const
return m_lastComboActionId;
}
uint32_t Sapphire::Entity::Chara::getDirectorId() const
uint32_t Chara::getDirectorId() const
{
return m_directorId;
}
void Sapphire::Entity::Chara::setDirectorId( uint32_t directorId )
void Chara::setDirectorId( uint32_t directorId )
{
m_directorId = directorId;
}
uint32_t Sapphire::Entity::Chara::getAgentId() const
uint32_t Chara::getAgentId() const
{
return m_agentId;
}
void Sapphire::Entity::Chara::setAgentId( uint32_t agentId )
void Chara::setAgentId( uint32_t agentId )
{
m_agentId = agentId;
}
float Sapphire::Entity::Chara::getRadius() const
float Chara::getRadius() const
{
return m_radius;
}
Sapphire::Common::BaseParam Sapphire::Entity::Chara::getPrimaryStat() const
Common::BaseParam Chara::getPrimaryStat() const
{
auto& exdData = Common::Service< Data::ExdData >::ref();
auto classJob = exdData.getRow< Excel::ClassJob >( static_cast< uint16_t >( getClass() ) );
assert( classJob );
return static_cast< Sapphire::Common::BaseParam >( classJob->data().Role );
return static_cast< Common::BaseParam >( classJob->data().Role );
}
uint32_t Sapphire::Entity::Chara::getStatValue( Sapphire::Common::BaseParam baseParam ) const
uint32_t Chara::getStatValue( Common::BaseParam baseParam ) const
{
auto index = static_cast< uint32_t >( baseParam );
assert( index < m_baseStats.size() );
@ -822,7 +773,7 @@ uint32_t Sapphire::Entity::Chara::getStatValue( Sapphire::Common::BaseParam base
return m_baseStats[ index ] + m_bonusStats[ index ];
}
float Sapphire::Entity::Chara::getStatValueFloat( Common::BaseParam baseParam ) const
float Chara::getStatValueFloat( Common::BaseParam baseParam ) const
{
auto index = static_cast< uint32_t >( baseParam );
assert( index < m_baseStats.size() );
@ -830,7 +781,7 @@ float Sapphire::Entity::Chara::getStatValueFloat( Common::BaseParam baseParam )
return static_cast< float >( m_baseStats[ index ] + m_bonusStats[ index ] );
}
uint32_t Sapphire::Entity::Chara::getBonusStat( Sapphire::Common::BaseParam baseParam ) const
uint32_t Chara::getBonusStat( Common::BaseParam baseParam ) const
{
auto index = static_cast< uint32_t >( baseParam );
assert( index < m_bonusStats.size() );
@ -838,7 +789,7 @@ uint32_t Sapphire::Entity::Chara::getBonusStat( Sapphire::Common::BaseParam base
return m_bonusStats[ index ];
}
void Sapphire::Entity::Chara::setStatValue( Common::BaseParam baseParam, uint32_t value )
void Chara::setStatValue( Common::BaseParam baseParam, uint32_t value )
{
auto index = static_cast< uint32_t >( baseParam );
assert( index < m_baseStats.size() );
@ -846,7 +797,7 @@ void Sapphire::Entity::Chara::setStatValue( Common::BaseParam baseParam, uint32_
m_baseStats[ index ] = value;
}
float Sapphire::Entity::Chara::getModifier( Common::ParamModifier paramModifier ) const
float Chara::getModifier( Common::ParamModifier paramModifier ) const
{
auto result = paramModifier >= Common::ParamModifier::StrengthPercent ? 1.0f : 0;
@ -867,7 +818,7 @@ float Sapphire::Entity::Chara::getModifier( Common::ParamModifier paramModifier
return result;
}
void Sapphire::Entity::Chara::onTick()
void Chara::onTick()
{
uint32_t thisTickDmg = 0;
uint32_t thisTickHeal = 0;
@ -896,24 +847,18 @@ void Sapphire::Entity::Chara::onTick()
if( thisTickDmg != 0 )
{
takeDamage( thisTickDmg );
server().queueForPlayers( getInRangePlayerIds( isPlayer() ), makeActorControl( getId(), HPFloatingText, 0,
static_cast< uint8_t >( ActionEffectType::CALC_RESULT_TYPE_DAMAGE_HP ),
thisTickDmg ) );
if( isPlayer() )
server().queueForPlayers( getInRangePlayerIds( isPlayer() ), makeHudParam( *getAsPlayer() ) );
else if( isBattleNpc() )
server().queueForPlayers( getInRangePlayerIds( isPlayer() ), makeHudParam( *getAsBNpc() ) );
Network::Util::Packet::sendActorControl( getInRangePlayerIds( isPlayer() ), getId(), HPFloatingText, 0,
ActionEffectType::CALC_RESULT_TYPE_DAMAGE_HP, thisTickDmg );
Network::Util::Packet::sendHudParam( *this );
}
if( thisTickHeal != 0 )
{
heal( thisTickHeal );
server().queueForPlayers( getInRangePlayerIds( isPlayer() ), makeActorControl( getId(), HPFloatingText, 0,
static_cast< uint8_t >( ActionEffectType::CALC_RESULT_TYPE_RECOVER_HP ),
thisTickHeal ) );
if( isPlayer() )
server().queueForPlayers( getInRangePlayerIds( isPlayer() ), makeHudParam( *getAsPlayer() ) );
else if( isBattleNpc() )
server().queueForPlayers( getInRangePlayerIds( isPlayer() ), makeHudParam( *getAsBNpc() ) );
Network::Util::Packet::sendActorControl( getInRangePlayerIds( isPlayer() ), getId(), HPFloatingText, 0,
ActionEffectType::CALC_RESULT_TYPE_RECOVER_HP, thisTickHeal );
Network::Util::Packet::sendHudParam( *this );
}
}

View file

@ -141,12 +141,12 @@ namespace Sapphire::Entity
// add a status effect by id
void addStatusEffectById( uint32_t id, int32_t duration, Entity::Chara& source, uint16_t param = 0 );
void addStatusEffectById( uint32_t id, int32_t duration, Entity::Chara& source,
std::vector< World::Action::StatusModifier > modifiers, uint32_t flag, uint16_t param = 0 );
// add a status effect by id if it doesn't exist
void addStatusEffectByIdIfNotExist( uint32_t id, int32_t duration, Entity::Chara& source, uint16_t param = 0 );
void addStatusEffectByIdIfNotExist( uint32_t id, int32_t duration, Entity::Chara& source, std::vector< World::Action::StatusModifier > modifiers,
uint16_t param = 0 );
void addStatusEffectByIdIfNotExist( uint32_t id, int32_t duration, Entity::Chara& source, World::Action::StatusEntry& statusEntry,
uint16_t param = 0 );
void addStatusEffectByIdIfNotExist( uint32_t id, int32_t duration, Entity::Chara& source,
std::vector< World::Action::StatusModifier > modifiers, uint32_t flag, uint16_t param = 0 );
// remove a status effect by id
void removeSingleStatusEffectFromId( uint32_t id );
@ -216,6 +216,10 @@ namespace Sapphire::Entity
void die();
uint64_t getLastAttack() const;
void setLastAttack( uint64_t tickCount );
Common::ActorStatus getStatus() const;
void setStatus( Common::ActorStatus status );
@ -236,8 +240,6 @@ namespace Sapphire::Entity
virtual uint8_t getLevel() const;
virtual void sendHudParam();
virtual void takeDamage( uint32_t damage );
virtual void heal( uint32_t amount );

View file

@ -3,12 +3,10 @@
#include "Territory/InstanceContent.h"
#include "Actor/Player.h"
#include "Network/PacketWrappers/ActorControlPacket.h"
#include "Network/PacketWrappers/ActorControlTargetPacket.h"
#include <Logging/Logger.h>
#include <Network/PacketDef/Zone/ServerZoneDef.h>
#include <Network/CommonActorControl.h>
#include <Network/Util/PacketUtil.h>
#include <Util/UtilMath.h>
#include <Service.h>
@ -16,20 +14,19 @@
#include <utility>
#include "WorldServer.h"
#include "Session.h"
#include "Network/GameConnection.h"
#include "Manager/MgrUtil.h"
using namespace Sapphire;
using namespace Sapphire::Common;
using namespace Sapphire::Entity;
using namespace Sapphire::World::Manager;
using namespace Sapphire::Network::Packets;
using namespace Sapphire::Network::Packets::WorldPackets::Server;
using namespace Sapphire::Network::ActorControl;
Sapphire::Entity::EventObject::EventObject( uint32_t actorId, uint32_t objectId, uint32_t gimmickId, uint32_t instanceId,
uint8_t initialState, Common::FFXIVARR_POSITION3 pos,
float rotation, const std::string& givenName, uint8_t permissionInv ) :
Sapphire::Entity::GameObject( ObjKind::EventObj ),
EventObject::EventObject( uint32_t actorId, uint32_t objectId, uint32_t gimmickId, uint32_t instanceId, uint8_t initialState,
FFXIVARR_POSITION3 pos, float rotation, const std::string& givenName, uint8_t permissionInv ) :
GameObject( ObjKind::EventObj ),
m_gimmickId( gimmickId ),
m_instanceId( instanceId ),
m_state( initialState ),
@ -37,7 +34,7 @@ Sapphire::Entity::EventObject::EventObject( uint32_t actorId, uint32_t objectId,
m_name( givenName ),
m_housingLink( 0 ),
m_permissionInvisibility( permissionInv ),
m_ownerId( Common::INVALID_GAME_OBJECT_ID )
m_ownerId( INVALID_GAME_OBJECT_ID )
{
m_id = actorId;
m_pos.x = pos.x;
@ -46,78 +43,77 @@ Sapphire::Entity::EventObject::EventObject( uint32_t actorId, uint32_t objectId,
m_rot = rotation;
}
uint32_t Sapphire::Entity::EventObject::getGimmickId() const
uint32_t EventObject::getGimmickId() const
{
return m_gimmickId;
}
uint32_t Sapphire::Entity::EventObject::getObjectId() const
uint32_t EventObject::getObjectId() const
{
return m_objectId;
}
float Sapphire::Entity::EventObject::getScale() const
float EventObject::getScale() const
{
return m_scale;
}
void Sapphire::Entity::EventObject::setScale( float scale )
void EventObject::setScale( float scale )
{
m_scale = scale;
}
Sapphire::Entity::EventObject::OnTalkEventHandler Sapphire::Entity::EventObject::getOnTalkHandler() const
EventObject::OnTalkEventHandler EventObject::getOnTalkHandler() const
{
return m_onTalkEventHandler;
}
void Sapphire::Entity::EventObject::setOnTalkHandler( Sapphire::Entity::EventObject::OnTalkEventHandler handler )
void EventObject::setOnTalkHandler( EventObject::OnTalkEventHandler handler )
{
m_onTalkEventHandler = std::move( handler );
}
void Sapphire::Entity::EventObject::setGimmickId( uint32_t gimmickId )
void EventObject::setGimmickId( uint32_t gimmickId )
{
m_gimmickId = gimmickId;
}
uint8_t Sapphire::Entity::EventObject::getState() const
uint8_t EventObject::getState() const
{
return m_state;
}
void Sapphire::Entity::EventObject::setState( uint8_t state )
void EventObject::setState( uint8_t state )
{
m_state = state;
}
void Sapphire::Entity::EventObject::setAnimationFlag( uint32_t flag, uint32_t animationFlag )
void EventObject::setAnimationFlag( uint32_t flag, uint32_t animationFlag )
{
for( const auto& player : m_inRangePlayers )
server().queueForPlayer( player->getCharacterId(), makeActorControl( getId(), EObjAnimation, flag, animationFlag ) );
Network::Util::Packet::sendActorControl( getInRangePlayerIds(), getId(), EObjAnimation, flag, animationFlag );
}
void Sapphire::Entity::EventObject::setHousingLink( uint32_t housingLink )
void EventObject::setHousingLink( uint32_t housingLink )
{
m_housingLink = housingLink;
}
uint32_t Sapphire::Entity::EventObject::getHousingLink() const
uint32_t EventObject::getHousingLink() const
{
return m_housingLink;
}
void Sapphire::Entity::EventObject::setParentInstance( Sapphire::TerritoryPtr instance )
void EventObject::setParentInstance( Sapphire::TerritoryPtr instance )
{
m_parentInstance = std::move( instance );
}
Sapphire::TerritoryPtr Sapphire::Entity::EventObject::getParentInstance() const
TerritoryPtr EventObject::getParentInstance() const
{
return m_parentInstance;
}
void Sapphire::Entity::EventObject::spawn( Sapphire::Entity::PlayerPtr pTarget )
void EventObject::spawn( PlayerPtr pTarget )
{
auto spawnIndex = pTarget->getNextObjSpawnIndexForActorId( getId() );
if( !pTarget->isObjSpawnIndexValid( spawnIndex ) )
@ -149,34 +145,31 @@ void Sapphire::Entity::EventObject::spawn( Sapphire::Entity::PlayerPtr pTarget )
}
void Sapphire::Entity::EventObject::despawn( Sapphire::Entity::PlayerPtr pTarget )
void EventObject::despawn( PlayerPtr pTarget )
{
Logger::debug( "despawn eobj#{0}", getId() );
pTarget->freeObjSpawnIndexForActorId( getId() );
}
const std::string& Sapphire::Entity::EventObject::getName() const
const std::string& EventObject::getName() const
{
return m_name;
}
uint32_t Sapphire::Entity::EventObject::getInstanceId() const
uint32_t EventObject::getInstanceId() const
{
return m_instanceId;
}
uint8_t Sapphire::Entity::EventObject::getPermissionInvisibility() const
uint8_t EventObject::getPermissionInvisibility() const
{
return m_permissionInvisibility;
}
void Sapphire::Entity::EventObject::setPermissionInvisibility( uint8_t permissionInvisibility )
void EventObject::setPermissionInvisibility( uint8_t permissionInvisibility )
{
m_permissionInvisibility = permissionInvisibility;
auto& server = Common::Service< World::WorldServer >::ref();
auto inRangePlayerIds = getInRangePlayerIds();
server.queueForPlayers( inRangePlayerIds, makeActorControl( getId(), DirectorEObjMod, permissionInvisibility ) );
Network::Util::Packet::sendActorControl( getInRangePlayerIds(), getId(), DirectorEObjMod, permissionInvisibility );
}
uint32_t Sapphire::Entity::EventObject::getOwnerId() const

View file

@ -23,41 +23,42 @@
#include "StatusEffect/StatusEffect.h"
using namespace Sapphire::Common;
using namespace Sapphire::Entity;
using namespace Sapphire::Network::Packets;
//using namespace Sapphire::Network::Packets::Server;
Sapphire::Entity::GameObject::GameObject( ObjKind type ) :
GameObject::GameObject( ObjKind type ) :
m_objKind( type )
{
}
uint32_t Sapphire::Entity::GameObject::getId() const
uint32_t GameObject::getId() const
{
return m_id;
}
void Sapphire::Entity::GameObject::setId( uint32_t id )
void GameObject::setId( uint32_t id )
{
m_id = id;
}
Sapphire::Common::ObjKind Sapphire::Entity::GameObject::getObjKind() const
ObjKind GameObject::getObjKind() const
{
return m_objKind;
}
Sapphire::Common::FFXIVARR_POSITION3& Sapphire::Entity::GameObject::getPos()
FFXIVARR_POSITION3& GameObject::getPos()
{
return m_pos;
}
const Sapphire::Common::FFXIVARR_POSITION3& Sapphire::Entity::GameObject::getPos() const
const FFXIVARR_POSITION3& GameObject::getPos() const
{
return m_pos;
}
void Sapphire::Entity::GameObject::setPos( float x, float y, float z, bool broadcastUpdate )
void GameObject::setPos( float x, float y, float z, bool broadcastUpdate )
{
m_pos.x = x;
m_pos.y = y;
@ -72,7 +73,7 @@ void Sapphire::Entity::GameObject::setPos( float x, float y, float z, bool broad
}
void Sapphire::Entity::GameObject::setPos( const Sapphire::Common::FFXIVARR_POSITION3& pos, bool broadcastUpdate )
void GameObject::setPos( const FFXIVARR_POSITION3& pos, bool broadcastUpdate )
{
m_pos = pos;
@ -84,92 +85,92 @@ void Sapphire::Entity::GameObject::setPos( const Sapphire::Common::FFXIVARR_POSI
}
}
float Sapphire::Entity::GameObject::getRot() const
float GameObject::getRot() const
{
return m_rot;
}
void Sapphire::Entity::GameObject::setRot( float rot )
void GameObject::setRot( float rot )
{
m_rot = rot;
}
bool Sapphire::Entity::GameObject::isChara() const
bool GameObject::isChara() const
{
return isPlayer() || isBattleNpc() || isEventNpc() || isRetainer() || isCompanion();
}
bool Sapphire::Entity::GameObject::isPlayer() const
bool GameObject::isPlayer() const
{
return m_objKind == ObjKind::Player;
}
bool Sapphire::Entity::GameObject::isEventNpc() const
bool GameObject::isEventNpc() const
{
return m_objKind == ObjKind::EventNpc;
}
bool Sapphire::Entity::GameObject::isBattleNpc() const
bool GameObject::isBattleNpc() const
{
return m_objKind == ObjKind::BattleNpc;
}
bool Sapphire::Entity::GameObject::isRetainer() const
bool GameObject::isRetainer() const
{
return m_objKind == ObjKind::Retainer;
}
bool Sapphire::Entity::GameObject::isCompanion() const
bool GameObject::isCompanion() const
{
return m_objKind == ObjKind::Companion;
}
bool Sapphire::Entity::GameObject::isEventObj() const
bool GameObject::isEventObj() const
{
return m_objKind == ObjKind::EventObj;
}
bool Sapphire::Entity::GameObject::isHousingEventObj() const
bool GameObject::isHousingEventObj() const
{
return m_objKind == ObjKind::Housing;
}
bool Sapphire::Entity::GameObject::isAetheryte() const
bool GameObject::isAetheryte() const
{
return m_objKind == ObjKind::Aetheryte;
}
/*! \return pointer to this instance as GameObjectPtr */
Sapphire::Entity::CharaPtr Sapphire::Entity::GameObject::getAsChara()
CharaPtr GameObject::getAsChara()
{
if( !isChara() )
return nullptr;
return std::dynamic_pointer_cast< Entity::Chara, Entity::GameObject >( shared_from_this() );
return std::dynamic_pointer_cast< Chara, GameObject >( shared_from_this() );
}
/*! \return pointer to this instance as PlayerPtr */
Sapphire::Entity::PlayerPtr Sapphire::Entity::GameObject::getAsPlayer()
PlayerPtr GameObject::getAsPlayer()
{
if( !isPlayer() )
return nullptr;
return std::dynamic_pointer_cast< Entity::Player, Entity::GameObject >( shared_from_this() );
return std::dynamic_pointer_cast< Player, GameObject >( shared_from_this() );
}
/*! \return pointer to this instance as EventObjPtr */
Sapphire::Entity::EventObjectPtr Sapphire::Entity::GameObject::getAsEventObj()
EventObjectPtr GameObject::getAsEventObj()
{
if( !isEventObj() )
return nullptr;
return std::dynamic_pointer_cast< Entity::EventObject, Entity::GameObject >( shared_from_this() );
return std::dynamic_pointer_cast< EventObject, GameObject >( shared_from_this() );
}
/*! \return pointer to this instance as BNpcPtr */
Sapphire::Entity::BNpcPtr Sapphire::Entity::GameObject::getAsBNpc()
BNpcPtr GameObject::getAsBNpc()
{
if( !isBattleNpc() )
return nullptr;
return std::dynamic_pointer_cast< Entity::BNpc, Entity::GameObject >( shared_from_this() );
return std::dynamic_pointer_cast< BNpc, GameObject >( shared_from_this() );
}
/*!
@ -178,7 +179,7 @@ but also to the global actor map
\param GameObjectPtr to add
*/
void Sapphire::Entity::GameObject::addInRangeActor( GameObjectPtr pActor )
void GameObject::addInRangeActor( GameObjectPtr pActor )
{
// if this is null, something went wrong
@ -211,7 +212,7 @@ but also to the global actor map
\param GameObjectPtr to remove
*/
void Sapphire::Entity::GameObject::removeInRangeActor( GameObject& actor )
void GameObject::removeInRangeActor( GameObject& actor )
{
// call virtual event
onRemoveInRangeActor( actor );
@ -232,12 +233,12 @@ void Sapphire::Entity::GameObject::removeInRangeActor( GameObject& actor )
}
/*! \return true if there is at least one actor in the in range set */
bool Sapphire::Entity::GameObject::hasInRangeActor() const
bool GameObject::hasInRangeActor() const
{
return ( !m_inRangeActor.empty() );
}
void Sapphire::Entity::GameObject::removeFromInRange()
void GameObject::removeFromInRange()
{
if( !hasInRangeActor() )
return;
@ -255,14 +256,14 @@ check if a given actor is in the actors in range set
\param GameObjectPtr to be checked for
\return true if the actor was found
*/
bool Sapphire::Entity::GameObject::isInRangeSet( GameObjectPtr pActor ) const
bool GameObject::isInRangeSet( GameObjectPtr pActor ) const
{
return !( m_inRangeActor.find( pActor ) == m_inRangeActor.end() );
}
/*! \return GameObjectPtr of the closest actor in range, if none, nullptr */
Sapphire::Entity::CharaPtr Sapphire::Entity::GameObject::getClosestChara()
CharaPtr GameObject::getClosestChara()
{
if( m_inRangeActor.empty() )
// no actors in range, don't bother
@ -275,8 +276,7 @@ Sapphire::Entity::CharaPtr Sapphire::Entity::GameObject::getClosestChara()
for( const auto& pCurAct : m_inRangeActor )
{
float distance = Util::distance( getPos().x, getPos().y, getPos().z,
pCurAct->getPos().x, pCurAct->getPos().y, pCurAct->getPos().z );
float distance = Util::distance( getPos().x, getPos().y, getPos().z, pCurAct->getPos().x, pCurAct->getPos().y, pCurAct->getPos().z );
if( distance < minDistance )
{
@ -289,7 +289,7 @@ Sapphire::Entity::CharaPtr Sapphire::Entity::GameObject::getClosestChara()
}
/*! Clear the whole in range set, this does no cleanup */
void Sapphire::Entity::GameObject::clearInRangeSet()
void GameObject::clearInRangeSet()
{
m_inRangeActor.clear();
m_inRangePlayers.clear();
@ -297,7 +297,7 @@ void Sapphire::Entity::GameObject::clearInRangeSet()
}
/*! \return list of actors currently in range */
std::set< Sapphire::Entity::GameObjectPtr > Sapphire::Entity::GameObject::getInRangeActors( bool includeSelf )
std::set< GameObjectPtr > GameObject::getInRangeActors( bool includeSelf )
{
auto tempInRange = m_inRangeActor;
@ -307,7 +307,7 @@ std::set< Sapphire::Entity::GameObjectPtr > Sapphire::Entity::GameObject::getInR
return tempInRange;
}
std::set< uint64_t > Sapphire::Entity::GameObject::getInRangePlayerIds( bool includeSelf )
std::set< uint64_t > GameObject::getInRangePlayerIds( bool includeSelf )
{
std::set< uint64_t > playerIds;
for( auto& player : m_inRangePlayers )
@ -319,22 +319,22 @@ std::set< uint64_t > Sapphire::Entity::GameObject::getInRangePlayerIds( bool inc
return playerIds;
}
uint32_t Sapphire::Entity::GameObject::getTerritoryTypeId() const
uint32_t GameObject::getTerritoryTypeId() const
{
return m_territoryTypeId;
}
void Sapphire::Entity::GameObject::setTerritoryTypeId( uint32_t territoryTypeId )
void GameObject::setTerritoryTypeId( uint32_t territoryTypeId )
{
m_territoryTypeId = territoryTypeId;
}
uint32_t Sapphire::Entity::GameObject::getTerritoryId() const
uint32_t GameObject::getTerritoryId() const
{
return m_territoryId;
}
void Sapphire::Entity::GameObject::setTerritoryId( uint32_t territoryId )
void GameObject::setTerritoryId( uint32_t territoryId )
{
m_territoryId = territoryId;
}
@ -344,7 +344,7 @@ Get the current cellId of a region the actor is in
\return CellId
*/
Sapphire::Common::CellId Sapphire::Entity::GameObject::getCellId() const
CellId GameObject::getCellId() const
{
return m_cellId;
}
@ -354,7 +354,7 @@ Set the current cellId the actor is in
\param CellId for the cell to be set
*/
void Sapphire::Entity::GameObject::setCellId( Common::CellId cellId )
void GameObject::setCellId( CellId cellId )
{
m_cellId = cellId;
}

View file

@ -1,20 +1,14 @@
#include <Network/PacketContainer.h>
#include "Action/Action.h"
#include "Territory/Territory.h"
#include "Player.h"
#include "Npc.h"
#include "Common.h"
using namespace Sapphire::Entity;
using namespace Sapphire::Common;
using namespace Sapphire::Network::Packets;
using namespace Sapphire::Network::Packets::WorldPackets::Server;
Sapphire::Entity::Npc::Npc( ObjKind type ) : Chara( type )
{
}
Sapphire::Entity::Npc::~Npc()
Npc::Npc( ObjKind type ) : Chara( type )
{
}
Npc::~Npc()
{
}

View file

@ -35,7 +35,7 @@
#include "Network/PacketWrappers/EffectPacket1.h"
#include "Network/PacketWrappers/InitZonePacket.h"
#include "Network/Util/PlayerUtil.h"
#include "Network/Util/PacketUtil.h"
#include "Action/Action.h"
@ -264,7 +264,7 @@ void Player::addOnlineStatus( OnlineStatus status )
setOnlineStatusMask( newFlags );
Network::Util::Player::sendOnlineStatus( *this );
Network::Util::Packet::sendOnlineStatus( *this );
}
void Player::addOnlineStatus( const std::vector< Common::OnlineStatus >& status )
@ -278,7 +278,7 @@ void Player::addOnlineStatus( const std::vector< Common::OnlineStatus >& status
setOnlineStatusMask( newFlags );
Network::Util::Player::sendOnlineStatus( *this );
Network::Util::Packet::sendOnlineStatus( *this );
}
void Player::removeOnlineStatus( OnlineStatus status )
@ -292,7 +292,7 @@ void Player::removeOnlineStatus( OnlineStatus status )
setOnlineStatusMask( newFlags );
setOnlineStatusCustomMask( newFlagsCustom );
Network::Util::Player::sendOnlineStatus( *this );
Network::Util::Packet::sendOnlineStatus( *this );
}
void Player::removeOnlineStatus( const std::vector< Common::OnlineStatus >& status )
@ -309,7 +309,7 @@ void Player::removeOnlineStatus( const std::vector< Common::OnlineStatus >& stat
setOnlineStatusMask( newFlags );
setOnlineStatusCustomMask( newFlagsCustom );
Network::Util::Player::sendOnlineStatus( *this );
Network::Util::Packet::sendOnlineStatus( *this );
}
void Player::calculateStats()
@ -457,7 +457,7 @@ void Player::registerAetheryte( uint8_t aetheryteId )
Util::valueToFlagByteIndexValue( aetheryteId, value, index );
m_aetheryte[ index ] |= value;
Network::Util::Player::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::Player::sendActorControlSelf( *this, SetRewardFlag, unlock, 1 );
Network::Util::Packet::sendActorControlSelf( *this, getId(), SetRewardFlag, unlock, 1 );
}
void Player::setBorrowAction( uint8_t slot, uint32_t action )
@ -587,7 +587,7 @@ void Player::learnSong( uint8_t songId, uint32_t itemId )
m_orchestrion[ index ] |= value;
Network::Util::Player::sendActorControlSelf( *this, ToggleOrchestrionUnlock, songId, 1, itemId );
Network::Util::Packet::sendActorControlSelf( *this, getId(), ToggleOrchestrionUnlock, songId, 1, itemId );
}
bool Player::hasReward( Common::UnlockEntry unlockId ) const
@ -624,7 +624,7 @@ void Player::gainExp( uint32_t amount )
{
setExp( 0 );
if( currentExp != 0 )
Network::Util::Player::sendActorControlSelf( *this, UpdateUiExp, currentClass, 0 );
Network::Util::Packet::sendActorControlSelf( *this, getId(), UpdateUiExp, currentClass, 0 );
return;
}
@ -648,8 +648,8 @@ void Player::gainExp( uint32_t amount )
else
setExp( currentExp + amount );
Network::Util::Player::sendActorControlSelf( *this, GainExpMsg, currentClass, amount );
Network::Util::Player::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()
@ -658,7 +658,7 @@ void Player::levelUp()
m_mp = getMaxMp();
setLevel( getLevel() + 1 );
Network::Util::Player::sendActorControl( getInRangePlayerIds( true ), *this, LevelUpEffect, static_cast< uint8_t >( getClass() ), getLevel(), getLevel() - 1 );
Network::Util::Packet::sendActorControl( getInRangePlayerIds( true ), getId(), LevelUpEffect, static_cast< uint8_t >( getClass() ), getLevel(), getLevel() - 1 );
auto& achvMgr = Common::Service< World::Manager::AchievementMgr >::ref();
achvMgr.progressAchievementByType< Common::Achievement::Type::Classjob >( *this, static_cast< uint32_t >( getClass() ) );
@ -733,10 +733,10 @@ void Player::setClassJob( Common::ClassJob classJob )
m_tp = 0;
Network::Util::Player::sendChangeClass( *this );
Network::Util::Player::sendStatusUpdate( *this );
Network::Util::Player::sendActorControl( getInRangePlayerIds( true ), *this, ClassJobChange, 4 );
Network::Util::Player::sendHudParam( *this );
Network::Util::Packet::sendChangeClass( *this );
Network::Util::Packet::sendStatusUpdate( *this );
Network::Util::Packet::sendActorControl( getInRangePlayerIds( true ), getId(), ClassJobChange, 4 );
Network::Util::Packet::sendHudParam( *this );
Service< World::Manager::MapMgr >::ref().updateQuests( *this );
}
@ -747,9 +747,9 @@ void Player::setLevel( uint8_t level )
m_classArray[ classJobIndex ] = level;
calculateStats();
Network::Util::Player::sendBaseParams( *this );
Network::Util::Player::sendHudParam( *this );
Network::Util::Player::sendStatusUpdate( *this );
Network::Util::Packet::sendBaseParams( *this );
Network::Util::Packet::sendHudParam( *this );
Network::Util::Packet::sendStatusUpdate( *this );
}
void Player::setLevelForClass( uint8_t level, Common::ClassJob classjob )
@ -762,7 +762,7 @@ void Player::setLevelForClass( uint8_t level, Common::ClassJob classjob )
m_classArray[ classJobIndex ] = level;
Network::Util::Player::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 ) );
@ -835,7 +835,7 @@ void Player::despawn( Entity::PlayerPtr pTarget )
Logger::debug( "Despawning {0} for {1}", getName(), pTarget->getName() );
pPlayer->freePlayerSpawnId( getId() );
Network::Util::Player::sendActorControlSelf( *this, WarpStart, 4, getId(), 1 );
Network::Util::Packet::sendActorControlSelf( *this, getId(), WarpStart, 4, getId(), 1 );
}
GameObjectPtr Player::lookupTargetById( uint64_t targetId )
@ -865,13 +865,13 @@ void Player::setGrandCompany( uint8_t gc )
m_gc = gc;
if( m_gcRank[ gc ] == 0 )
m_gcRank[ gc ] = 1;
Network::Util::Player::sendGrandCompany( *this );
Network::Util::Packet::sendGrandCompany( *this );
}
void Player::setGrandCompanyRankAt( uint8_t index, uint8_t rank )
{
m_gcRank[ index ] = rank;
Network::Util::Player::sendGrandCompany( *this );
Network::Util::Packet::sendGrandCompany( *this );
}
const Player::Condition& Player::getConditions() const
@ -899,7 +899,7 @@ void Player::setCondition( Common::PlayerCondition flag )
Util::valueToFlagByteIndexValue( iFlag, value, index );
m_condition[ index ] |= value;
Network::Util::Player::sendCondition( *this );
Network::Util::Packet::sendCondition( *this );
}
void Player::setConditions( const std::vector< Common::PlayerCondition >& flags )
@ -914,7 +914,7 @@ void Player::setConditions( const std::vector< Common::PlayerCondition >& flags
m_condition[ index ] |= value;
}
Network::Util::Player::sendCondition( *this );
Network::Util::Packet::sendCondition( *this );
}
void Player::removeCondition( Common::PlayerCondition flag )
@ -929,7 +929,7 @@ void Player::removeCondition( Common::PlayerCondition flag )
Util::valueToFlagByteIndexValue( iFlag, value, index );
m_condition[ index ] ^= value;
Network::Util::Player::sendCondition( *this );
Network::Util::Packet::sendCondition( *this );
}
void Player::update( uint64_t tickCount )
@ -940,16 +940,6 @@ void Player::update( uint64_t tickCount )
Chara::update( tickCount );
}
uint64_t Player::getLastAttack() const
{
return m_lastAttack;
}
void Player::setLastAttack( uint64_t tickCount )
{
m_lastAttack = tickCount;
}
void Player::freePlayerSpawnId( uint32_t actorId )
{
auto spawnId = m_actorSpawnIndexAllocator.freeUsedSpawnIndex( actorId );
@ -958,7 +948,7 @@ void Player::freePlayerSpawnId( uint32_t actorId )
if( spawnId == m_actorSpawnIndexAllocator.getAllocFailId() )
return;
Network::Util::Player::sendDeletePlayer( *this, actorId, spawnId );
Network::Util::Packet::sendDeletePlayer( *this, actorId, spawnId );
}
Player::AetheryteList& Player::getAetheryteArray()
@ -970,7 +960,7 @@ Player::AetheryteList& Player::getAetheryteArray()
void Player::setHomepoint( uint8_t aetheryteId )
{
m_homePoint = aetheryteId;
Network::Util::Player::sendActorControlSelf( *this, SetHomepoint, aetheryteId );
Network::Util::Packet::sendActorControlSelf( *this, getId(), SetHomepoint, aetheryteId );
}
/*! get homepoint */
@ -1019,7 +1009,7 @@ void Player::unlockMount( uint32_t mountId )
m_mountGuide[ mount->data().MountOrder / 8 ] |= ( 1 << ( mount->data().MountOrder % 8 ) );
Network::Util::Player::sendActorControlSelf( *this, SetMountBitmask, mount->data().MountOrder, 1 );
Network::Util::Packet::sendActorControlSelf( *this, getId(), SetMountBitmask, mount->data().MountOrder, 1 );
}
void Player::unlockCompanion( uint32_t companionId )
@ -1036,7 +1026,7 @@ void Player::unlockCompanion( uint32_t companionId )
m_minionGuide[ index ] |= value;
Network::Util::Player::sendActorControlSelf( *this, LearnCompanion, companionId, 1 );
Network::Util::Packet::sendActorControlSelf( *this, getId(), LearnCompanion, companionId, 1 );
}
Player::MinionList& Player::getMinionGuideBitmask()
@ -1126,7 +1116,7 @@ void Player::hateListAdd( const BNpc& bnpc )
uint8_t hateId = m_freeHateSlotQueue.front();
m_freeHateSlotQueue.pop();
m_actorIdTohateSlotMap[ bnpc.getId() ] = hateId;
Network::Util::Player::sendHateList( *this );
Network::Util::Packet::sendHateList( *this );
}
}
@ -1141,7 +1131,7 @@ void Player::hateListRemove( const BNpc& bnpc )
uint8_t hateSlot = it->second;
m_freeHateSlotQueue.push( hateSlot );
m_actorIdTohateSlotMap.erase( it );
Network::Util::Player::sendHateList( *this );
Network::Util::Packet::sendHateList( *this );
return;
}
}
@ -1161,14 +1151,14 @@ const std::map< uint32_t, uint8_t >& Player::getActorIdToHateSlotMap()
void Player::onMobAggro( const BNpc& bnpc )
{
hateListAdd( bnpc );
Network::Util::Player::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::Player::sendActorControl( *this, SetBattle, 0 );
Network::Util::Packet::sendActorControl( *this, getId(), SetBattle, 0 );
}
bool Player::isLogin() const
@ -1210,7 +1200,7 @@ void Player::setTitle( uint16_t titleId )
return;
m_activeTitle = titleId;
Network::Util::Player::sendActorControl( getInRangePlayerIds( true ), *this, SetTitle, titleId );
Network::Util::Packet::sendActorControl( getInRangePlayerIds( true ), getId(), SetTitle, titleId );
}
const Player::AchievementData& Player::getAchievementData() const
@ -1226,7 +1216,7 @@ void Player::setAchievementData( const Player::AchievementData& achievementData
void Player::setMaxGearSets( uint8_t amount )
{
m_equippedMannequin = amount;
Network::Util::Player::sendActorControlSelf( *this, SetMaxGearSets, m_equippedMannequin );
Network::Util::Packet::sendActorControlSelf( *this, getId(), SetMaxGearSets, m_equippedMannequin );
}
void Player::addGearSet()
@ -1251,7 +1241,7 @@ uint8_t Player::getMaxGearSets() const
void Player::setConfigFlags( uint16_t state )
{
m_configFlags = static_cast< uint8_t >( state );
Network::Util::Player::sendConfigFlags( *this );
Network::Util::Packet::sendConfigFlags( *this );
}
uint8_t Player::getConfigFlags() const
@ -1262,7 +1252,7 @@ uint8_t Player::getConfigFlags() const
void Player::setMount( uint32_t mountId )
{
m_mount = mountId;
Network::Util::Player::sendMount( *this );
Network::Util::Packet::sendMount( *this );
}
void Player::setCompanion( uint8_t id )
@ -1275,7 +1265,7 @@ void Player::setCompanion( uint8_t id )
m_companionId = id;
Network::Util::Player::sendActorControl( getInRangePlayerIds( true ), *this, ToggleCompanion, id );
Network::Util::Packet::sendActorControl( getInRangePlayerIds( true ), getId(), ToggleCompanion, id );
}
uint8_t Player::getCurrentCompanion() const
@ -1312,9 +1302,9 @@ void Player::autoAttack( CharaPtr pTarget )
auto& RNGMgr = Common::Service< World::Manager::RNGMgr >::ref();
auto variation = static_cast< uint32_t >( RNGMgr.getRandGenerator< float >( 0, 3 ).next() );
//actionMgr.handleTargetedPlayerAction( *this, 7, exdData.getRow< Excel::Action >( 7 ), pTarget->getId(), 0 );
actionMgr.handleTargetedAction( *this, 7, exdData.getRow< Excel::Action >( 7 ), pTarget->getId(), 0 );
auto damage = Math::CalcStats::calcAutoAttackDamage( *this );
/* auto damage = Math::CalcStats::calcAutoAttackDamage( *this );
auto effectPacket = std::make_shared< EffectPacket1 >( getId(), pTarget->getId(), 7 );
@ -1328,7 +1318,7 @@ void Player::autoAttack( CharaPtr pTarget )
if( getClass() == ClassJob::Machinist || getClass() == ClassJob::Bard || getClass() == ClassJob::Archer )
effectPacket->setActionId( 8 );
auto resultId = pZone->getNextEffectResultId();
auto resultId = pZone->getNextActionResultId();
effectPacket->setResultId( resultId );
effectPacket->setRotation( Util::floatToUInt16Rot( getRot() ) );
effectPacket->addTargetEffect( entry );
@ -1337,8 +1327,8 @@ void Player::autoAttack( CharaPtr pTarget )
pTarget->takeDamage( static_cast< uint32_t >( damage.first ) );
auto& taskMgr = Common::Service< TaskMgr >::ref();
taskMgr.queueTask( Sapphire::World::makeActionIntegrityTask( resultId, pTarget, 500 ) );
auto& taskMgr = Common::Service< TaskMgr >::ref();*/
//taskMgr.queueTask( Sapphire::World::makeActionIntegrityTask( resultId, pTarget, 500 ) );
}
@ -1435,7 +1425,7 @@ void Player::teleportQuery( uint16_t aetheryteId )
cost = std::min< uint16_t >( 999, cost );
bool insufficientGil = getCurrency( Common::CurrencyType::Gil ) < cost;
Network::Util::Player::sendActorControlSelf( *this, OnExecuteTelepo, insufficientGil ? 2 : 0, aetheryteId );
Network::Util::Packet::sendActorControlSelf( *this, getId(), OnExecuteTelepo, insufficientGil ? 2 : 0, aetheryteId );
if( !insufficientGil )
{
@ -1510,7 +1500,7 @@ void Player::dyeItemFromDyeingInfo()
insertInventoryItem( static_cast< Sapphire::Common::InventoryType >( itemToDyeContainer ), static_cast< uint16_t >( itemToDyeSlot ), itemToDye );
writeItem( itemToDye );
Network::Util::Player::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 )
@ -1532,7 +1522,7 @@ void Player::glamourItemFromGlamouringInfo()
uint32_t glamourBagSlot = m_glamouringInfo.glamourBagSlot;
bool shouldGlamour = m_glamouringInfo.shouldGlamour;
Network::Util::Player::sendCondition( *this );
Network::Util::Packet::sendCondition( *this );
auto itemToGlamour = getItemAt( itemToGlamourContainer, itemToGlamourSlot );
auto glamourToUse = getItemAt( glamourBagContainer, glamourBagSlot );
@ -1564,9 +1554,9 @@ void Player::glamourItemFromGlamouringInfo()
writeItem( itemToGlamour );
if( shouldGlamour )
Network::Util::Player::sendActorControlSelf( *this, GlamourCastMsg, itemToGlamour->getId(), glamourToUse->getId(), invalidateGearSet );
Network::Util::Packet::sendActorControlSelf( *this, getId(), GlamourCastMsg, itemToGlamour->getId(), glamourToUse->getId(), invalidateGearSet );
else
Network::Util::Player::sendActorControlSelf( *this, GlamourRemoveMsg, itemToGlamour->getId(), invalidateGearSet );
Network::Util::Packet::sendActorControlSelf( *this, getId(), GlamourRemoveMsg, itemToGlamour->getId(), invalidateGearSet );
}
void Player::resetObjSpawnIndex()
@ -1582,7 +1572,7 @@ void Player::freeObjSpawnIndexForActorId( uint32_t actorId )
if( spawnId == m_objSpawnIndexAllocator.getAllocFailId() )
return;
Network::Util::Player::sendDeleteObject( *this, spawnId );
Network::Util::Packet::sendDeleteObject( *this, spawnId );
}
bool Player::isObjSpawnIndexValid( uint8_t index )
@ -1651,7 +1641,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::Player::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;
}
@ -1660,7 +1650,7 @@ void Player::updateHuntingLog( uint16_t id )
}
if( logChanged && sectionComplete && sectionChanged )
{
Network::Util::Player::sendActorControlSelf( *this, HuntingLogSectionFinish, monsterNoteId, i, 0 );
Network::Util::Packet::sendActorControlSelf( *this, getId(), HuntingLogSectionFinish, monsterNoteId, i, 0 );
gainExp( note->data().RewardExp );
}
if( !sectionComplete )
@ -1670,18 +1660,18 @@ void Player::updateHuntingLog( uint16_t id )
}
if( logChanged && allSectionsComplete )
{
Network::Util::Player::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::Player::sendActorControlSelf( *this, HuntingLogRankUnlock, currentClassId, logEntry.rank + 1, 0 );
Network::Util::Packet::sendActorControlSelf( *this, getId(), HuntingLogRankUnlock, currentClassId, logEntry.rank + 1, 0 );
}
}
if( logChanged )
Network::Util::Player::sendHuntingLog( *this );
Network::Util::Packet::sendHuntingLog( *this );
}
void Player::setActiveLand( uint8_t land, uint8_t ward )
@ -1744,7 +1734,7 @@ void Player::resetRecastGroups()
m_recast[ i ] = 0.0f;
m_recastMax[ i ] = 0.0f;
}
Network::Util::Player::sendRecastGroups( *this );
Network::Util::Packet::sendRecastGroups( *this );
}
bool Player::checkAction()
@ -1843,7 +1833,7 @@ void Player::setFalling( bool state, const Common::FFXIVARR_POSITION3& pos, bool
// no mercy on hated players
takeDamage( damage );
}
Network::Util::Player::sendActorControl( getInRangePlayerIds( true ), *this, SetFallDamage, damage );
Network::Util::Packet::sendActorControl( getInRangePlayerIds( true ), getId(), SetFallDamage, damage );
}
}
}

View file

@ -84,12 +84,6 @@ namespace Sapphire::Entity
/*! Event called on every session iteration */
void update( uint64_t tickCount ) override;
/*! get last attack tick for player */
uint64_t getLastAttack() const;
/*! set last attack tick for player */
void setLastAttack( uint64_t tickCount );
// Quest
//////////////////////////////////////////////////////////////////////////////////////////////////////
/*! load data for currently active quests */

View file

@ -6,29 +6,30 @@
#include "Actor/Player.h"
#include "Territory/Territory.h"
#include "WorldServer.h"
#include "Action/EventAction.h"
#include "Manager/PlayerMgr.h"
#include "Service.h"
#include <Network/PacketWrappers/RestingPacket.h>
#include <Network/Util/PacketUtil.h>
using namespace Sapphire;
using namespace Sapphire::Common;
using namespace Sapphire::Entity;
using namespace Sapphire::Network::Packets;
using namespace Sapphire::Network::Packets::WorldPackets::Server;
using namespace Sapphire::World::Manager;
void Sapphire::Entity::Player::addEvent( Event::EventHandlerPtr pEvent )
void Player::addEvent( Event::EventHandlerPtr pEvent )
{
m_eventHandlerMap[ pEvent->getId() ] = pEvent;
}
std::map< uint32_t, Sapphire::Event::EventHandlerPtr >& Sapphire::Entity::Player::getEventListRef()
std::map< uint32_t, Event::EventHandlerPtr >& Player::getEventListRef()
{
return m_eventHandlerMap;
}
Sapphire::Event::EventHandlerPtr Sapphire::Entity::Player::getEvent( uint32_t eventId ) const
Event::EventHandlerPtr Player::getEvent( uint32_t eventId ) const
{
auto it = m_eventHandlerMap.find( eventId );
if( it != m_eventHandlerMap.end() )
@ -37,12 +38,12 @@ Sapphire::Event::EventHandlerPtr Sapphire::Entity::Player::getEvent( uint32_t ev
return nullptr;
}
size_t Sapphire::Entity::Player::getEventCount()
size_t Player::getEventCount()
{
return m_eventHandlerMap.size();
}
void Sapphire::Entity::Player::removeEvent( uint32_t eventId )
void Player::removeEvent( uint32_t eventId )
{
auto it = m_eventHandlerMap.find( eventId );
if( it != m_eventHandlerMap.end() )
@ -53,13 +54,13 @@ void Sapphire::Entity::Player::removeEvent( uint32_t eventId )
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void Sapphire::Entity::Player::onDeath()
void Player::onDeath()
{
Service< World::Manager::PlayerMgr >::ref().onDeath( *this );
}
// TODO: slightly ugly here and way too static. Needs too be done properly
void Sapphire::Entity::Player::onTick()
void Player::onTick()
{
Chara::onTick();
// add 3 seconds to total play time
@ -71,10 +72,10 @@ void Sapphire::Entity::Player::onTick()
bool sendUpdate = performResting();
if( sendUpdate )
server().queueForPlayers( getInRangePlayerIds( true ), std::make_shared< RestingPacket >( *this ) );
Network::Util::Packet::sendRestingUpdate( *this );
}
bool Sapphire::Entity::Player::performResting()
bool Player::performResting()
{
bool sendUpdate = false;
auto addHp = static_cast< uint32_t >( static_cast< float >( getMaxHp() ) * 0.1f + 1 );

View file

@ -18,7 +18,7 @@
#include "Network/PacketWrappers/ActorControlSelfPacket.h"
#include "Network/PacketWrappers/UpdateInventorySlotPacket.h"
#include <Network/PacketDef/Zone/ServerZoneDef.h>
#include <Network/Util/PlayerUtil.h>
#include <Network/Util/PacketUtil.h>
#include "Manager/InventoryMgr.h"
#include "Manager/ItemMgr.h"
@ -27,6 +27,9 @@
#include <Service.h>
using namespace Sapphire;
using namespace Sapphire::Entity;
using namespace Sapphire::World;
using namespace Sapphire::Common;
using namespace Sapphire::World::Manager;
using namespace Sapphire::Network::Packets;
@ -34,7 +37,7 @@ using namespace Sapphire::Network::Packets::WorldPackets::Server;
using namespace Sapphire::Network::ActorControl;
void Sapphire::Entity::Player::initInventory()
void Player::initInventory()
{
const uint8_t inventorySize = 25;
auto setupContainer = [ this ]( InventoryType type, uint8_t maxSize, const std::string& tableName,
@ -103,9 +106,9 @@ void Sapphire::Entity::Player::initInventory()
calculateItemLevel();
}
void Sapphire::Entity::Player::equipWeapon( const Item& item )
void Player::equipWeapon( const Item& item )
{
auto& exdData = Common::Service< Sapphire::Data::ExdData >::ref();
auto& exdData = Common::Service< Data::ExdData >::ref();
auto itemInfo = exdData.getRow< Excel::Item >( item.getId() );
auto itemClassJob = itemInfo->data().Class;
@ -119,9 +122,9 @@ void Sapphire::Entity::Player::equipWeapon( const Item& item )
}
}
void Sapphire::Entity::Player::equipSoulCrystal( const Item& item )
void Player::equipSoulCrystal( const Item& item )
{
auto& exdData = Common::Service< Sapphire::Data::ExdData >::ref();
auto& exdData = Common::Service< Data::ExdData >::ref();
auto itemInfo = exdData.getRow< Excel::Item >( item.getId() );
auto itemClassJob = itemInfo->data().Class;
@ -131,7 +134,7 @@ void Sapphire::Entity::Player::equipSoulCrystal( const Item& item )
setClassJob( newClassJob );
}
void Sapphire::Entity::Player::updateModels( GearSetSlot equipSlotId, const Sapphire::Item& item )
void Player::updateModels( GearSetSlot equipSlotId, const Sapphire::Item& item )
{
uint64_t model = item.getModelId1();
uint64_t model2 = item.getModelId2();
@ -169,7 +172,7 @@ void Sapphire::Entity::Player::updateModels( GearSetSlot equipSlotId, const Sapp
}
}
Sapphire::Common::GearModelSlot Sapphire::Entity::Player::equipSlotToModelSlot( Common::GearSetSlot slot )
Common::GearModelSlot Player::equipSlotToModelSlot( Common::GearSetSlot slot )
{
switch( slot )
{
@ -203,7 +206,7 @@ Sapphire::Common::GearModelSlot Sapphire::Entity::Player::equipSlotToModelSlot(
}
// equip an item
void Sapphire::Entity::Player::equipItem( Common::GearSetSlot equipSlotId, Item& item, bool sendUpdate )
void Player::equipItem( Common::GearSetSlot equipSlotId, Item& item, bool sendUpdate )
{
switch( equipSlotId )
{
@ -225,15 +228,15 @@ void Sapphire::Entity::Player::equipItem( Common::GearSetSlot equipSlotId, Item&
calculateItemLevel();
if( sendUpdate )
{
Network::Util::Player::sendEquip( *this );
Network::Util::Player::sendActorControl( *this, SetItemLevel, getItemLevel() );
Network::Util::Player::sendBaseParams( *this );
Network::Util::Player::sendHudParam( *this );
Network::Util::Packet::sendEquip( *this );
Network::Util::Packet::sendActorControl( *this, getId(), SetItemLevel, getItemLevel() );
Network::Util::Packet::sendBaseParams( *this );
Network::Util::Packet::sendHudParam( *this );
}
}
void Sapphire::Entity::Player::unequipItem( Common::GearSetSlot equipSlotId, Item& item, bool sendUpdate )
void Player::unequipItem( Common::GearSetSlot equipSlotId, Item& item, bool sendUpdate )
{
auto modelSlot = equipSlotToModelSlot( equipSlotId );
if( modelSlot != GearModelSlot::ModelInvalid )
@ -247,14 +250,14 @@ void Sapphire::Entity::Player::unequipItem( Common::GearSetSlot equipSlotId, Ite
if( sendUpdate )
{
Network::Util::Player::sendEquip( *this );
Network::Util::Player::sendActorControl( *this, SetItemLevel, getItemLevel() );
Network::Util::Player::sendBaseParams( *this );
Network::Util::Player::sendHudParam( *this );
Network::Util::Packet::sendEquip( *this );
Network::Util::Packet::sendActorControl( *this, getId(), SetItemLevel, getItemLevel() );
Network::Util::Packet::sendBaseParams( *this );
Network::Util::Packet::sendHudParam( *this );
}
}
void Sapphire::Entity::Player::unequipSoulCrystal()
void Player::unequipSoulCrystal()
{
auto& exdData = Common::Service< Sapphire::Data::ExdData >::ref();
@ -263,7 +266,7 @@ void Sapphire::Entity::Player::unequipSoulCrystal()
setClassJob( parentClass );
}
uint32_t Sapphire::Entity::Player::currencyTypeToItem( Common::CurrencyType type ) const
uint32_t Player::currencyTypeToItem( Common::CurrencyType type ) const
{
switch( type )
{
@ -301,7 +304,7 @@ uint32_t Sapphire::Entity::Player::currencyTypeToItem( Common::CurrencyType type
}
// TODO: these next functions are so similar that they could likely be simplified
void Sapphire::Entity::Player::addCurrency( CurrencyType type, uint32_t amount )
void Player::addCurrency( CurrencyType type, uint32_t amount )
{
auto slot = static_cast< uint8_t >( static_cast< uint8_t >( type ) - 1 );
auto currItem = m_storageMap[ Currency ]->getItem( slot );
@ -339,7 +342,7 @@ void Sapphire::Entity::Player::addCurrency( CurrencyType type, uint32_t amount )
server().queueForPlayer( getCharacterId(), invTransFinPacket );
}
void Sapphire::Entity::Player::removeCurrency( Common::CurrencyType type, uint32_t amount )
void Player::removeCurrency( Common::CurrencyType type, uint32_t amount )
{
auto currItem = m_storageMap[ Currency ]->getItem( static_cast< uint8_t >( type ) - 1 );
@ -373,7 +376,7 @@ void Sapphire::Entity::Player::removeCurrency( Common::CurrencyType type, uint32
}
void Sapphire::Entity::Player::addCrystal( Common::CrystalType type, uint32_t amount )
void Player::addCrystal( Common::CrystalType type, uint32_t amount )
{
auto currItem = m_storageMap[ Crystal ]->getItem( static_cast< uint8_t >( type ) - 1 );
@ -412,7 +415,7 @@ void Sapphire::Entity::Player::addCrystal( Common::CrystalType type, uint32_t am
server().queueForPlayer( getCharacterId(), makeActorControlSelf( getId(), ItemObtainIcon, static_cast< uint8_t >( type ) + 1, amount ) );
}
void Sapphire::Entity::Player::removeCrystal( Common::CrystalType type, uint32_t amount )
void Player::removeCrystal( Common::CrystalType type, uint32_t amount )
{
auto currItem = m_storageMap[ Crystal ]->getItem( static_cast< uint8_t >( type ) - 1 );
@ -446,9 +449,9 @@ void Sapphire::Entity::Player::removeCrystal( Common::CrystalType type, uint32_t
server().queueForPlayer( getCharacterId(), invTransFinPacket );
}
void Sapphire::Entity::Player::sendInventory()
void Player::sendInventory()
{
auto& invMgr = Common::Service< World::Manager::InventoryMgr >::ref();
auto& invMgr = Common::Service< Manager::InventoryMgr >::ref();
for( auto& it : m_storageMap )
{
@ -456,14 +459,14 @@ void Sapphire::Entity::Player::sendInventory()
}
}
void Sapphire::Entity::Player::sendGearInventory()
void Player::sendGearInventory()
{
auto& invMgr = Common::Service< World::Manager::InventoryMgr >::ref();
auto& invMgr = Common::Service< Manager::InventoryMgr >::ref();
invMgr.sendInventoryContainer( *this, m_storageMap[ GearSet0 ] );
}
Sapphire::Entity::Player::InvSlotPairVec Sapphire::Entity::Player::getSlotsOfItemsInInventory( uint32_t catalogId )
Player::InvSlotPairVec Player::getSlotsOfItemsInInventory( uint32_t catalogId )
{
InvSlotPairVec outVec;
for( auto i : { Bag0, Bag1, Bag2, Bag3 } )
@ -478,7 +481,7 @@ Sapphire::Entity::Player::InvSlotPairVec Sapphire::Entity::Player::getSlotsOfIte
return outVec;
}
Sapphire::Entity::Player::InvSlotPair Sapphire::Entity::Player::getFreeBagSlot()
Player::InvSlotPair Player::getFreeBagSlot()
{
for( auto i : { Bag0, Bag1, Bag2, Bag3 } )
{
@ -491,7 +494,7 @@ Sapphire::Entity::Player::InvSlotPair Sapphire::Entity::Player::getFreeBagSlot()
return std::make_pair( 0, -1 );
}
Sapphire::Entity::Player::InvSlotPair Sapphire::Entity::Player::getFreeContainerSlot( uint32_t containerId )
Player::InvSlotPair Player::getFreeContainerSlot( uint32_t containerId )
{
auto freeSlot = static_cast< int8_t >( m_storageMap[ containerId ]->getFreeSlot() );
@ -502,13 +505,13 @@ Sapphire::Entity::Player::InvSlotPair Sapphire::Entity::Player::getFreeContainer
return std::make_pair( 0, -1 );
}
Sapphire::ItemPtr Sapphire::Entity::Player::getItemAt( uint16_t containerId, uint16_t slotId )
ItemPtr Player::getItemAt( uint16_t containerId, uint16_t slotId )
{
return m_storageMap[ containerId ]->getItem( slotId );
}
uint32_t Sapphire::Entity::Player::getCurrency( CurrencyType type )
uint32_t Player::getCurrency( CurrencyType type )
{
auto currItem = m_storageMap[ Currency ]->getItem( static_cast< uint8_t >( type ) - 1 );
@ -520,7 +523,7 @@ uint32_t Sapphire::Entity::Player::getCurrency( CurrencyType type )
}
uint32_t Sapphire::Entity::Player::getCrystal( CrystalType type )
uint32_t Player::getCrystal( CrystalType type )
{
auto currItem = m_storageMap[ Crystal ]->getItem( static_cast< uint8_t >( type ) - 1 );
@ -532,7 +535,7 @@ uint32_t Sapphire::Entity::Player::getCrystal( CrystalType type )
}
void Sapphire::Entity::Player::writeInventory( InventoryType type )
void Player::writeInventory( InventoryType type )
{
auto& db = Common::Service< Db::DbWorkerPool< Db::ZoneDbConnection > >::ref();
@ -561,7 +564,7 @@ void Sapphire::Entity::Player::writeInventory( InventoryType type )
db.execute( query );
}
void Sapphire::Entity::Player::writeItem( Sapphire::ItemPtr pItem ) const
void Player::writeItem( ItemPtr pItem ) const
{
auto& db = Common::Service< Db::DbWorkerPool< Db::ZoneDbConnection > >::ref();
auto stmt = db.getPreparedStatement( Db::CHARA_ITEMGLOBAL_UP );
@ -577,7 +580,7 @@ void Sapphire::Entity::Player::writeItem( Sapphire::ItemPtr pItem ) const
db.directExecute( stmt );
}
void Sapphire::Entity::Player::writeCurrencyItem( CurrencyType type )
void Player::writeCurrencyItem( CurrencyType type )
{
auto& db = Common::Service< Db::DbWorkerPool< Db::ZoneDbConnection > >::ref();
@ -590,7 +593,7 @@ void Sapphire::Entity::Player::writeCurrencyItem( CurrencyType type )
db.execute( query );
}
void Sapphire::Entity::Player::deleteItemDb( Sapphire::ItemPtr item ) const
void Player::deleteItemDb( ItemPtr item ) const
{
auto& db = Common::Service< Db::DbWorkerPool< Db::ZoneDbConnection > >::ref();
auto stmt = db.getPreparedStatement( Db::CHARA_ITEMGLOBAL_DELETE );
@ -601,14 +604,14 @@ void Sapphire::Entity::Player::deleteItemDb( Sapphire::ItemPtr item ) const
}
bool Sapphire::Entity::Player::isObtainable( uint32_t catalogId, uint8_t quantity )
bool Player::isObtainable( uint32_t catalogId, uint8_t quantity )
{
return true;
}
Sapphire::ItemPtr Sapphire::Entity::Player::addItem( uint32_t catalogId, uint32_t quantity, bool isHq, bool silent, bool canMerge )
ItemPtr Player::addItem( uint32_t catalogId, uint32_t quantity, bool isHq, bool silent, bool canMerge )
{
auto& exdData = Common::Service< Data::ExdData >::ref();
auto itemInfo = exdData.getRow< Excel::Item >( catalogId );
@ -741,7 +744,7 @@ Sapphire::ItemPtr Sapphire::Entity::Player::addItem( uint32_t catalogId, uint32_
return item;
}
bool Sapphire::Entity::Player::removeItem( uint32_t catalogId, uint32_t quantity, bool isHq )
bool Player::removeItem( uint32_t catalogId, uint32_t quantity, bool isHq )
{
std::vector< uint16_t > bags = { Bag0, Bag1, Bag2, Bag3 };
@ -790,7 +793,7 @@ bool Sapphire::Entity::Player::removeItem( uint32_t catalogId, uint32_t quantity
}
void
Sapphire::Entity::Player::moveItem( uint16_t fromInventoryId, uint16_t fromSlotId, uint16_t toInventoryId, uint16_t toSlot )
Player::moveItem( uint16_t fromInventoryId, uint16_t fromSlotId, uint16_t toInventoryId, uint16_t toSlot )
{
auto tmpItem = m_storageMap[ fromInventoryId ]->getItem( fromSlotId );
@ -819,9 +822,9 @@ Sapphire::Entity::Player::moveItem( uint16_t fromInventoryId, uint16_t fromSlotI
sendStatusEffectUpdate(); // send if any equip is changed
}
bool Sapphire::Entity::Player::updateContainer( uint16_t storageId, uint16_t slotId, ItemPtr pItem )
bool Player::updateContainer( uint16_t storageId, uint16_t slotId, ItemPtr pItem )
{
auto containerType = World::Manager::ItemMgr::getContainerType( storageId );
auto containerType = Manager::ItemMgr::getContainerType( storageId );
auto pOldItem = getItemAt( storageId, slotId );
m_storageMap[ storageId ]->setItem( slotId, pItem );
@ -857,8 +860,7 @@ bool Sapphire::Entity::Player::updateContainer( uint16_t storageId, uint16_t slo
return true;
}
void Sapphire::Entity::Player::splitItem( uint16_t fromInventoryId, uint16_t fromSlotId,
uint16_t toInventoryId, uint16_t toSlot, uint16_t itemCount )
void Player::splitItem( uint16_t fromInventoryId, uint16_t fromSlotId, uint16_t toInventoryId, uint16_t toSlot, uint16_t itemCount )
{
if( itemCount == 0 )
return;
@ -890,8 +892,7 @@ void Sapphire::Entity::Player::splitItem( uint16_t fromInventoryId, uint16_t fro
writeItem( fromItem );
}
void Sapphire::Entity::Player::mergeItem( uint16_t fromInventoryId, uint16_t fromSlotId,
uint16_t toInventoryId, uint16_t toSlot )
void Player::mergeItem( uint16_t fromInventoryId, uint16_t fromSlotId, uint16_t toInventoryId, uint16_t toSlot )
{
auto fromItem = m_storageMap[ fromInventoryId ]->getItem( fromSlotId );
auto toItem = m_storageMap[ toInventoryId ]->getItem( toSlot );
@ -925,8 +926,7 @@ void Sapphire::Entity::Player::mergeItem( uint16_t fromInventoryId, uint16_t fro
updateContainer( toInventoryId, toSlot, toItem );
}
void Sapphire::Entity::Player::swapItem( uint16_t fromInventoryId, uint16_t fromSlotId,
uint16_t toInventoryId, uint16_t toSlot )
void Player::swapItem( uint16_t fromInventoryId, uint16_t fromSlotId, uint16_t toInventoryId, uint16_t toSlot )
{
auto fromItem = m_storageMap[ fromInventoryId ]->getItem( fromSlotId );
auto toItem = m_storageMap[ toInventoryId ]->getItem( toSlot );
@ -959,7 +959,7 @@ void Sapphire::Entity::Player::swapItem( uint16_t fromInventoryId, uint16_t from
sendStatusEffectUpdate(); // send if any equip is changed
}
void Sapphire::Entity::Player::discardItem( uint16_t fromInventoryId, uint16_t fromSlotId )
void Player::discardItem( uint16_t fromInventoryId, uint16_t fromSlotId )
{
// i am not entirely sure how this should be generated or if it even is important for us...
uint32_t sequence = getNextInventorySequence();
@ -988,7 +988,7 @@ void Sapphire::Entity::Player::discardItem( uint16_t fromInventoryId, uint16_t f
server().queueForPlayer( getCharacterId(), invTransFinPacket );
}
uint16_t Sapphire::Entity::Player::calculateItemLevel()
uint16_t Player::calculateItemLevel()
{
uint32_t iLvlResult = 0;
@ -1020,7 +1020,7 @@ uint16_t Sapphire::Entity::Player::calculateItemLevel()
return ilvl;
}
void Sapphire::Entity::Player::calculateBonusStats()
void Player::calculateBonusStats()
{
m_bonusStats.fill( 0 );
@ -1052,12 +1052,12 @@ void Sapphire::Entity::Player::calculateBonusStats()
}
Sapphire::ItemPtr Sapphire::Entity::Player::getEquippedWeapon()
ItemPtr Player::getEquippedWeapon()
{
return m_storageMap[ GearSet0 ]->getItem( GearSetSlot::MainHand );
}
uint16_t Sapphire::Entity::Player::getFreeSlotsInBags()
uint16_t Player::getFreeSlotsInBags()
{
uint16_t slots = 0;
for( uint8_t container : { Bag0, Bag1, Bag2, Bag3 } )
@ -1068,7 +1068,7 @@ uint16_t Sapphire::Entity::Player::getFreeSlotsInBags()
return slots;
}
bool Sapphire::Entity::Player::collectHandInItems( std::vector< uint32_t > itemIds )
bool Player::collectHandInItems( std::vector< uint32_t > itemIds )
{
// todo: figure out how the game gets the required stack count
const auto& container = m_storageMap[ HandIn ];
@ -1102,12 +1102,12 @@ bool Sapphire::Entity::Player::collectHandInItems( std::vector< uint32_t > itemI
return true;
}
uint32_t Sapphire::Entity::Player::getNextInventorySequence()
uint32_t Player::getNextInventorySequence()
{
return m_inventorySequence++;
}
Sapphire::ItemPtr Sapphire::Entity::Player::dropInventoryItem( Sapphire::Common::InventoryType storageId, uint8_t slotId )
ItemPtr Player::dropInventoryItem( Sapphire::Common::InventoryType storageId, uint8_t slotId )
{
auto& container = m_storageMap[ storageId ];
@ -1141,24 +1141,24 @@ Sapphire::ItemPtr Sapphire::Entity::Player::dropInventoryItem( Sapphire::Common:
return item;
}
void Sapphire::Entity::Player::addSoldItem( uint32_t itemId, uint8_t stackSize )
void Player::addSoldItem( uint32_t itemId, uint8_t stackSize )
{
if( m_soldItems.size() > 10 )
m_soldItems.pop_back();
m_soldItems.emplace_front( itemId, stackSize );
}
std::deque< std::pair< uint32_t, uint8_t > > *Sapphire::Entity::Player::getSoldItems()
std::deque< std::pair< uint32_t, uint8_t > >* Player::getSoldItems()
{
return &m_soldItems;
}
void Sapphire::Entity::Player::clearSoldItems()
void Player::clearSoldItems()
{
m_soldItems.clear();
}
bool Sapphire::Entity::Player::getFreeInventoryContainerSlot( Inventory::InventoryContainerPair& containerPair ) const
bool Player::getFreeInventoryContainerSlot( Inventory::InventoryContainerPair& containerPair ) const
{
for( auto bagId : { Bag0, Bag1, Bag2, Bag3 } )
{
@ -1182,8 +1182,7 @@ bool Sapphire::Entity::Player::getFreeInventoryContainerSlot( Inventory::Invento
return false;
}
void Sapphire::Entity::Player::insertInventoryItem( Sapphire::Common::InventoryType type, uint16_t slot,
const Sapphire::ItemPtr item )
void Player::insertInventoryItem( Common::InventoryType type, uint16_t slot, const ItemPtr item )
{
updateContainer( type, slot, item );
@ -1199,8 +1198,7 @@ void Sapphire::Entity::Player::insertInventoryItem( Sapphire::Common::InventoryT
server().queueForPlayer( getCharacterId(), invTransFinPacket );
}
bool Sapphire::Entity::Player::findFirstItemWithId( uint32_t catalogId,
Inventory::InventoryContainerPair& location, std::initializer_list< InventoryType > bags )
bool Player::findFirstItemWithId( uint32_t catalogId, Inventory::InventoryContainerPair& location, std::initializer_list< InventoryType > bags )
{
for( auto bagId : bags )
{

View file

@ -7,16 +7,18 @@
#include "Player.h"
using namespace Sapphire;
using namespace Sapphire::Common;
using namespace Sapphire::Entity;
using namespace Sapphire::World;
using namespace Sapphire::Network::Packets;
using namespace Sapphire::Network::Packets::WorldPackets::Server;
void Sapphire::Entity::Player::finishQuest( uint16_t questId, uint32_t optionalChoice )
void Player::finishQuest( uint16_t questId, uint32_t optionalChoice )
{
removeQuest( questId );
auto& questMgr = Common::Service< World::Manager::QuestMgr >::ref();
auto& questMgr = Common::Service< Manager::QuestMgr >::ref();
updateQuestsCompleted( questId );
@ -24,14 +26,14 @@ void Sapphire::Entity::Player::finishQuest( uint16_t questId, uint32_t optionalC
questMgr.onCompleteQuest( *this, questId, optionalChoice );
}
void Sapphire::Entity::Player::unfinishQuest( uint16_t questId )
void Player::unfinishQuest( uint16_t questId )
{
removeQuestsCompleted( questId );
auto& questMgr = Common::Service< World::Manager::QuestMgr >::ref();
auto& questMgr = Common::Service< Manager::QuestMgr >::ref();
questMgr.sendQuestsInfo( *this );
}
void Sapphire::Entity::Player::removeQuest( uint16_t questId )
void Player::removeQuest( uint16_t questId )
{
int8_t idx = getQuestIndex( questId );
@ -41,8 +43,8 @@ void Sapphire::Entity::Player::removeQuest( uint16_t questId )
return;
}
auto& questMgr = Common::Service< World::Manager::QuestMgr >::ref();
auto& mapMgr = Common::Service< World::Manager::MapMgr >::ref();
auto& questMgr = Common::Service< Manager::QuestMgr >::ref();
auto& mapMgr = Common::Service< Manager::MapMgr >::ref();
m_quests[ idx ] = World::Quest();
removeQuestTracking( idx );
@ -53,7 +55,7 @@ void Sapphire::Entity::Player::removeQuest( uint16_t questId )
}
void Sapphire::Entity::Player::removeQuestTracking( int8_t idx )
void Player::removeQuestTracking( int8_t idx )
{
for( int32_t ii = 0; ii < 5; ii++ )
{
@ -62,12 +64,12 @@ void Sapphire::Entity::Player::removeQuestTracking( int8_t idx )
}
}
bool Sapphire::Entity::Player::hasQuest( uint32_t questId )
bool Player::hasQuest( uint32_t questId )
{
return ( getQuestIndex( static_cast< uint16_t >( questId ) ) > -1 );
}
int8_t Sapphire::Entity::Player::getQuestIndex( uint16_t questId )
int8_t Player::getQuestIndex( uint16_t questId )
{
for( size_t pos = 0; pos < 30; ++pos )
{
@ -77,7 +79,7 @@ int8_t Sapphire::Entity::Player::getQuestIndex( uint16_t questId )
return -1;
}
void Sapphire::Entity::Player::updateQuest( const World::Quest& quest )
void Player::updateQuest( const World::Quest& quest )
{
auto& questMgr = Common::Service< World::Manager::QuestMgr >::ref();
auto& mapMgr = Common::Service< World::Manager::MapMgr >::ref();
@ -93,7 +95,7 @@ void Sapphire::Entity::Player::updateQuest( const World::Quest& quest )
addQuest( quest );
}
bool Sapphire::Entity::Player::addQuest( const World::Quest& quest )
bool Player::addQuest( const World::Quest& quest )
{
int8_t idx = getFreeQuestSlot();
@ -103,8 +105,8 @@ bool Sapphire::Entity::Player::addQuest( const World::Quest& quest )
return false;
}
auto& questMgr = Common::Service< World::Manager::QuestMgr >::ref();
auto& mapMgr = Common::Service< World::Manager::MapMgr >::ref();
auto& questMgr = Common::Service< Manager::QuestMgr >::ref();
auto& mapMgr = Common::Service< Manager::MapMgr >::ref();
m_quests[ idx ] = quest;
@ -117,7 +119,7 @@ bool Sapphire::Entity::Player::addQuest( const World::Quest& quest )
return true;
}
std::optional< Sapphire::World::Quest > Sapphire::Entity::Player::getQuest( uint32_t questId )
std::optional< World::Quest > Player::getQuest( uint32_t questId )
{
if( !hasQuest( questId ) )
return std::nullopt;
@ -128,7 +130,7 @@ std::optional< Sapphire::World::Quest > Sapphire::Entity::Player::getQuest( uint
return { quest };
}
int8_t Sapphire::Entity::Player::getFreeQuestSlot()
int8_t Player::getFreeQuestSlot()
{
int8_t result = -1;
for( int8_t idx = 0; idx < 30; idx++ )
@ -141,7 +143,7 @@ int8_t Sapphire::Entity::Player::getFreeQuestSlot()
return result;
}
void Sapphire::Entity::Player::addQuestTracking( uint8_t idx )
void Player::addQuestTracking( uint8_t idx )
{
for( int32_t ii = 0; ii < 5; ii++ )
{
@ -153,7 +155,7 @@ void Sapphire::Entity::Player::addQuestTracking( uint8_t idx )
}
}
void Sapphire::Entity::Player::updateQuestsCompleted( uint32_t questId )
void Player::updateQuestsCompleted( uint32_t questId )
{
uint8_t index = questId / 8;
uint8_t bitIndex = ( questId ) % 8;
@ -163,7 +165,7 @@ void Sapphire::Entity::Player::updateQuestsCompleted( uint32_t questId )
m_questCompleteFlags[ index ] |= value;
}
bool Sapphire::Entity::Player::isQuestCompleted( uint32_t questId )
bool Player::isQuestCompleted( uint32_t questId )
{
uint8_t index = questId / 8;
uint8_t bitIndex = ( questId ) % 8;
@ -173,7 +175,7 @@ bool Sapphire::Entity::Player::isQuestCompleted( uint32_t questId )
return m_questCompleteFlags[ index ] & value;
}
void Sapphire::Entity::Player::removeQuestsCompleted( uint32_t questId )
void Player::removeQuestsCompleted( uint32_t questId )
{
uint8_t index = questId / 8;
uint8_t bitIndex = ( questId ) % 8;
@ -182,27 +184,27 @@ void Sapphire::Entity::Player::removeQuestsCompleted( uint32_t questId )
m_questCompleteFlags[ index ] ^= value;
Common::Service< World::Manager::MapMgr >::ref().updateQuests( *this );
Common::Service< Manager::MapMgr >::ref().updateQuests( *this );
}
Sapphire::World::Quest& Sapphire::Entity::Player::getQuestByIndex( uint16_t index )
World::Quest& Player::getQuestByIndex( uint16_t index )
{
return m_quests[ index ];
}
std::array< Sapphire::World::Quest, 30 >& Sapphire::Entity::Player::getQuestArrayRef()
std::array< World::Quest, 30 >& Player::getQuestArrayRef()
{
return m_quests;
}
int16_t Sapphire::Entity::Player::getQuestTracking( uint8_t index ) const
int16_t Player::getQuestTracking( uint8_t index ) const
{
if( index < 0 || index >= 5 )
return -1;
return m_questTracking[ index ];
}
Sapphire::Entity::Player::QuestComplete& Sapphire::Entity::Player::getQuestCompleteFlags()
Player::QuestComplete& Player::getQuestCompleteFlags()
{
return m_questCompleteFlags;
}

View file

@ -16,12 +16,14 @@
#include "WorldServer.h"
using namespace Sapphire;
using namespace Sapphire::Entity;
using namespace Sapphire::Common;
using namespace Sapphire::Network::Packets;
using namespace Sapphire::Network::Packets::WorldPackets::Server;
using namespace Sapphire::World::Manager;
bool Sapphire::Entity::Player::loadFromDb( uint64_t characterId )
bool Player::loadFromDb( uint64_t characterId )
{
m_characterId = characterId;
@ -181,7 +183,7 @@ bool Sapphire::Entity::Player::loadFromDb( uint64_t characterId )
return true;
}
bool Sapphire::Entity::Player::loadActiveQuests()
bool Player::loadActiveQuests()
{
auto& db = Common::Service< Db::DbWorkerPool< Db::ZoneDbConnection > >::ref();
auto stmt = db.getPreparedStatement( Db::ZoneDbStatements::CHARA_SEL_QUEST );
@ -194,7 +196,6 @@ bool Sapphire::Entity::Player::loadActiveQuests()
while( res->next() )
{
auto slotId = res->getUInt8( 2 );
auto quest = World::Quest( res->getUInt16( 3 ), res->getUInt8( 4 ), res->getUInt8( 5 ) );
@ -205,14 +206,13 @@ bool Sapphire::Entity::Player::loadActiveQuests()
quest.setUI8E( res->getUInt8( 10 ) );
quest.setUI8F( res->getUInt8( 11 ) );
m_quests[ slotId ] = quest;
}
return true;
}
bool Sapphire::Entity::Player::loadAchievements()
bool Player::loadAchievements()
{
auto& db = Common::Service< Db::DbWorkerPool< Db::ZoneDbConnection > >::ref();
auto stmt = db.getPreparedStatement( Db::ZoneDbStatements::CHARA_ACHIEV_SEL );
@ -255,7 +255,7 @@ bool Sapphire::Entity::Player::loadAchievements()
return true;
}
bool Sapphire::Entity::Player::loadClassData()
bool Player::loadClassData()
{
auto& db = Common::Service< Db::DbWorkerPool< Db::ZoneDbConnection > >::ref();
// ClassIdx, Exp, Lvl, BorrowAction
@ -278,7 +278,7 @@ bool Sapphire::Entity::Player::loadClassData()
return true;
}
bool Sapphire::Entity::Player::loadSearchInfo()
bool Player::loadSearchInfo()
{
auto& db = Common::Service< Db::DbWorkerPool< Db::ZoneDbConnection > >::ref();
auto stmt = db.getPreparedStatement( Db::ZoneDbStatements::CHARA_SEL_SEARCHINFO );
@ -303,7 +303,7 @@ bool Sapphire::Entity::Player::loadSearchInfo()
}
bool Sapphire::Entity::Player::loadHuntingLog()
bool Player::loadHuntingLog()
{
auto& db = Common::Service< Db::DbWorkerPool< Db::ZoneDbConnection > >::ref();
auto stmt = db.getPreparedStatement( Db::ZoneDbStatements::CHARA_MONSTERNOTE_SEL );
@ -326,7 +326,7 @@ bool Sapphire::Entity::Player::loadHuntingLog()
return true;
}
void Sapphire::Entity::Player::updateSql()
void Player::updateSql()
{
////// Update player data
updateDbChara();
@ -356,7 +356,7 @@ void Sapphire::Entity::Player::updateSql()
syncLastDBWrite();
}
void Sapphire::Entity::Player::updateDbChara() const
void Player::updateDbChara() const
{
auto& db = Service< Db::DbWorkerPool< Db::ZoneDbConnection > >::ref();
/*"Hp 1, Mp 2, Tp 3, Gp 4, Mode 5, Mount 6, InvincibleGM 7, Voice 8, "
@ -484,7 +484,7 @@ void Sapphire::Entity::Player::updateDbChara() const
db.execute( stmt );
}
void Sapphire::Entity::Player::updateDbClass() const
void Player::updateDbClass() const
{
auto& db = Common::Service< Db::DbWorkerPool< Db::ZoneDbConnection > >::ref();
auto& exdData = Common::Service< Data::ExdData >::ref();
@ -505,7 +505,7 @@ void Sapphire::Entity::Player::updateDbClass() const
db.execute( stmtS );
}
void Sapphire::Entity::Player::updateDbMonsterNote()
void Player::updateDbMonsterNote()
{
auto& db = Common::Service< Db::DbWorkerPool< Db::ZoneDbConnection > >::ref();
// Category_0-11
@ -523,7 +523,7 @@ void Sapphire::Entity::Player::updateDbMonsterNote()
db.execute( stmt );
}
void Sapphire::Entity::Player::updateDbFriendList()
void Player::updateDbFriendList()
{
auto& db = Common::Service< Db::DbWorkerPool< Db::ZoneDbConnection > >::ref();
@ -541,7 +541,7 @@ void Sapphire::Entity::Player::updateDbFriendList()
}
void Sapphire::Entity::Player::updateDbBlacklist()
void Player::updateDbBlacklist()
{
auto& db = Common::Service< Db::DbWorkerPool< Db::ZoneDbConnection > >::ref();
@ -555,7 +555,7 @@ void Sapphire::Entity::Player::updateDbBlacklist()
db.execute( stmt );
}
void Sapphire::Entity::Player::updateDbAchievement()
void Player::updateDbAchievement()
{
auto& db = Common::Service< Db::DbWorkerPool< Db::ZoneDbConnection > >::ref();
@ -585,7 +585,7 @@ void Sapphire::Entity::Player::updateDbAchievement()
}
void Sapphire::Entity::Player::insertDbClass( const uint8_t classJobIndex, uint8_t level ) const
void Player::insertDbClass( const uint8_t classJobIndex, uint8_t level ) const
{
auto& db = Common::Service< Db::DbWorkerPool< Db::ZoneDbConnection > >::ref();
auto stmtClass = db.getPreparedStatement( Db::CHARA_CLASS_INS );
@ -600,7 +600,7 @@ void Sapphire::Entity::Player::insertDbClass( const uint8_t classJobIndex, uint8
db.directExecute( stmtClass );
}
void Sapphire::Entity::Player::updateDbSearchInfo() const
void Player::updateDbSearchInfo() const
{
auto& db = Common::Service< Db::DbWorkerPool< Db::ZoneDbConnection > >::ref();
auto stmtS = db.getPreparedStatement( Db::CHARA_SEARCHINFO_UP_SELECTCLASS );
@ -619,7 +619,7 @@ void Sapphire::Entity::Player::updateDbSearchInfo() const
db.execute( stmtS2 );
}
void Sapphire::Entity::Player::updateDbAllQuests() const
void Player::updateDbAllQuests() const
{
auto& db = Common::Service< Db::DbWorkerPool< Db::ZoneDbConnection > >::ref();
for( int32_t i = 0; i < 30; i++ )
@ -645,7 +645,7 @@ void Sapphire::Entity::Player::updateDbAllQuests() const
}
}
void Sapphire::Entity::Player::deleteDbQuest( uint16_t questId ) const
void Player::deleteDbQuest( uint16_t questId ) const
{
auto& db = Common::Service< Db::DbWorkerPool< Db::ZoneDbConnection > >::ref();
auto stmt = db.getPreparedStatement( Db::CHARA_QUEST_DEL );
@ -654,7 +654,7 @@ void Sapphire::Entity::Player::deleteDbQuest( uint16_t questId ) const
db.execute( stmt );
}
void Sapphire::Entity::Player::insertDbQuest( uint16_t questId, uint8_t index, uint8_t seq ) const
void Player::insertDbQuest( uint16_t questId, uint8_t index, uint8_t seq ) const
{
auto& db = Common::Service< Db::DbWorkerPool< Db::ZoneDbConnection > >::ref();
auto stmt = db.getPreparedStatement( Db::CHARA_QUEST_INS );
@ -673,7 +673,7 @@ void Sapphire::Entity::Player::insertDbQuest( uint16_t questId, uint8_t index, u
db.execute( stmt );
}
void Sapphire::Entity::Player::insertDbQuest( const World::Quest& quest, uint8_t index ) const
void Player::insertDbQuest( const World::Quest& quest, uint8_t index ) const
{
auto& db = Common::Service< Db::DbWorkerPool< Db::ZoneDbConnection > >::ref();
auto stmt = db.getPreparedStatement( Db::CHARA_QUEST_INS );
@ -692,7 +692,7 @@ void Sapphire::Entity::Player::insertDbQuest( const World::Quest& quest, uint8_t
db.execute( stmt );
}
Sapphire::ItemPtr Sapphire::Entity::Player::createItem( uint32_t catalogId, uint32_t quantity )
ItemPtr Player::createItem( uint32_t catalogId, uint32_t quantity )
{
auto& exdData = Common::Service< Data::ExdData >::ref();
auto& db = Common::Service< Db::DbWorkerPool< Db::ZoneDbConnection > >::ref();
@ -719,7 +719,7 @@ Sapphire::ItemPtr Sapphire::Entity::Player::createItem( uint32_t catalogId, uint
return pItem;
}
bool Sapphire::Entity::Player::loadInventory()
bool Player::loadInventory()
{
auto& itemMgr = Common::Service< World::Manager::ItemMgr >::ref();
auto& db = Common::Service< Db::DbWorkerPool< Db::ZoneDbConnection > >::ref();
@ -818,7 +818,7 @@ bool Sapphire::Entity::Player::loadInventory()
return true;
}
bool Sapphire::Entity::Player::loadFriendList()
bool Player::loadFriendList()
{
auto& db = Common::Service< Db::DbWorkerPool< Db::ZoneDbConnection > >::ref();
auto stmt = db.getPreparedStatement( Db::ZoneDbStatements::CHARA_FRIENDLIST_SEL );
@ -843,7 +843,7 @@ bool Sapphire::Entity::Player::loadFriendList()
return true;
}
bool Sapphire::Entity::Player::loadBlacklist()
bool Player::loadBlacklist()
{
auto& db = Common::Service< Db::DbWorkerPool< Db::ZoneDbConnection > >::ref();
auto stmt = db.getPreparedStatement( Db::ZoneDbStatements::CHARA_BLACKLIST_SEL );
@ -865,7 +865,7 @@ bool Sapphire::Entity::Player::loadBlacklist()
}
bool Sapphire::Entity::Player::syncLastDBWrite()
bool Player::syncLastDBWrite()
{
auto& db = Common::Service< Db::DbWorkerPool< Db::ZoneDbConnection > >::ref();
auto res = db.query( "SELECT UNIX_TIMESTAMP(UPDATE_DATE) FROM charainfo WHERE characterid = " + std::to_string( m_characterId ) );

View file

@ -8,6 +8,7 @@ file( GLOB SERVER_SOURCE_FILES RELATIVE ${CMAKE_CURRENT_SOURCE_DIR}
Actor/*.cpp
Action/*.cpp
Action/Job/*.cpp
AI/*.cpp
ContentFinder/*.cpp
DebugCommand/*.cpp
Event/*.cpp

View file

@ -18,13 +18,15 @@
#include <WorldServer.h>
using namespace Sapphire;
using namespace Sapphire::World;
using namespace Sapphire::Common;
using namespace Sapphire::Network::Packets;
using namespace Sapphire::Network::Packets::WorldPackets;
using namespace Sapphire::Network::Packets::WorldPackets::Server;
using namespace Sapphire::World::Manager;
void Sapphire::World::ContentFinder::update()
void World::ContentFinder::update()
{
auto& exdData = Service< Data::ExdData >::ref();
auto& server = Service< WorldServer >::ref();
@ -114,19 +116,19 @@ void Sapphire::World::ContentFinder::update()
}
void Sapphire::World::ContentFinder::registerContentsRequest( Sapphire::Entity::Player &player, const std::vector< uint32_t >& contentIds )
void World::ContentFinder::registerContentsRequest( Entity::Player &player, const std::vector< uint32_t >& contentIds )
{
queueForContent( player, contentIds );
completeRegistration( player );
}
void Sapphire::World::ContentFinder::registerContentRequest( Sapphire::Entity::Player &player, uint32_t contentId, uint8_t flags )
void World::ContentFinder::registerContentRequest( Entity::Player &player, uint32_t contentId, uint8_t flags )
{
queueForContent( player, { contentId } );
completeRegistration( player, flags );
}
void Sapphire::World::ContentFinder::registerRandomContentRequest( Sapphire::Entity::Player &player, uint32_t randomContentTypeId )
void World::ContentFinder::registerRandomContentRequest( Entity::Player &player, uint32_t randomContentTypeId )
{
auto& exdData = Service< Data::ExdData >::ref();
auto contentListIds = exdData.getIdList< Excel::ContentFinderCondition >();
@ -146,9 +148,8 @@ void Sapphire::World::ContentFinder::registerRandomContentRequest( Sapphire::Ent
completeRegistration( player );
}
void Sapphire::World::ContentFinder::completeRegistration( const Sapphire::Entity::Player &player, uint8_t flags )
void World::ContentFinder::completeRegistration( const Entity::Player &player, uint8_t flags )
{
auto& server = Service< WorldServer >::ref();
auto queuedContent = m_queuedContent[ m_queuedPlayer[ player.getId() ]->getActiveRegisterId() ];
@ -182,7 +183,7 @@ void Sapphire::World::ContentFinder::completeRegistration( const Sapphire::Entit
}
}
void Sapphire::World::ContentFinder::queueForContent( Sapphire::Entity::Player &player, const std::vector< uint32_t >& contentIds )
void World::ContentFinder::queueForContent( Entity::Player &player, const std::vector< uint32_t >& contentIds )
{
for( auto contentId : contentIds )
{
@ -215,7 +216,7 @@ void Sapphire::World::ContentFinder::queueForContent( Sapphire::Entity::Player &
}
}
void Sapphire::World::QueuedContent::queuePlayer( const std::shared_ptr< QueuedPlayer >& pQPlayer )
void World::QueuedContent::queuePlayer( const std::shared_ptr< QueuedPlayer >& pQPlayer )
{
m_players.push_back( pQPlayer );
m_partyMemberCount++;
@ -241,7 +242,7 @@ void Sapphire::World::QueuedContent::queuePlayer( const std::shared_ptr< QueuedP
}
}
bool Sapphire::World::QueuedContent::withdrawPlayer( const std::shared_ptr< QueuedPlayer >& pQPlayer )
bool World::QueuedContent::withdrawPlayer( const std::shared_ptr< QueuedPlayer >& pQPlayer )
{
auto preSize = m_players.size();
auto it = m_players.begin();
@ -282,12 +283,12 @@ bool Sapphire::World::QueuedContent::withdrawPlayer( const std::shared_ptr< Queu
return true;
}
uint32_t Sapphire::World::ContentFinder::getNextRegisterId()
uint32_t World::ContentFinder::getNextRegisterId()
{
return ++m_nextRegisterId;
}
Sapphire::World::ContentFinder::QueuedContentPtrList Sapphire::World::ContentFinder::getMatchingContentList( Sapphire::Entity::Player &player, uint32_t contentFinderId )
World::ContentFinder::QueuedContentPtrList World::ContentFinder::getMatchingContentList( Entity::Player &player, uint32_t contentFinderId )
{
QueuedContentPtrList outVec;
for( auto& it : m_queuedContent )
@ -361,7 +362,7 @@ Sapphire::World::ContentFinder::QueuedContentPtrList Sapphire::World::ContentFin
return outVec;
}
void Sapphire::World::ContentFinder::accept( Entity::Player& player )
void World::ContentFinder::accept( Entity::Player& player )
{
auto& server = Service< WorldServer >::ref();
auto& exdData = Service< Data::ExdData >::ref();
@ -408,7 +409,7 @@ void Sapphire::World::ContentFinder::accept( Entity::Player& player )
queuedContent->setState( Accepted );
}
void Sapphire::World::ContentFinder::withdraw( Entity::Player& player )
void World::ContentFinder::withdraw( Entity::Player& player )
{
auto& server = Service< WorldServer >::ref();
auto& exdData = Service< Data::ExdData >::ref();
@ -471,7 +472,7 @@ void Sapphire::World::ContentFinder::withdraw( Entity::Player& player )
}
std::shared_ptr< Sapphire::World::QueuedContent > Sapphire::World::ContentFinder::findContentByRegisterId( uint32_t registerId )
std::shared_ptr< World::QueuedContent > World::ContentFinder::findContentByRegisterId( uint32_t registerId )
{
auto it = m_queuedContent.find( registerId );
if( it != m_queuedContent.end() )
@ -479,7 +480,7 @@ std::shared_ptr< Sapphire::World::QueuedContent > Sapphire::World::ContentFinder
return nullptr;
}
bool Sapphire::World::ContentFinder::removeContentByRegisterId( uint32_t registerId )
bool World::ContentFinder::removeContentByRegisterId( uint32_t registerId )
{
auto it = m_queuedContent.find( registerId );
if( it == m_queuedContent.end() )
@ -490,21 +491,21 @@ bool Sapphire::World::ContentFinder::removeContentByRegisterId( uint32_t registe
//////////////////////////////////////////////////////////////////////
uint32_t Sapphire::World::QueuedContent::getInstanceId() const
uint32_t World::QueuedContent::getInstanceId() const
{
return m_contentFinderId;
}
uint32_t Sapphire::World::QueuedContent::getRegisterId() const
uint32_t World::QueuedContent::getRegisterId() const
{
return m_registerId;
}
Sapphire::World::QueuedContent::QueuedContent( uint32_t registerId, uint32_t contentId ) :
m_registerId( registerId ),
m_contentFinderId( contentId ),
m_state( QueuedContentState::MatchingInProgress ),
m_contentPopTime( 0 )
World::QueuedContent::QueuedContent( uint32_t registerId, uint32_t contentId ) :
m_registerId( registerId ),
m_contentFinderId( contentId ),
m_state( QueuedContentState::MatchingInProgress ),
m_contentPopTime( 0 )
{
// auto& exdData = Common::Service< Data::ExdData >::ref();
// auto content = exdData.getRow< Excel::InstanceContent >( contentId );
@ -512,7 +513,7 @@ Sapphire::World::QueuedContent::QueuedContent( uint32_t registerId, uint32_t con
}
uint8_t Sapphire::World::QueuedContent::getRoleCount( Sapphire::Common::Role role ) const
uint8_t World::QueuedContent::getRoleCount( Common::Role role ) const
{
switch( role )
{
@ -533,12 +534,12 @@ uint8_t Sapphire::World::QueuedContent::getRoleCount( Sapphire::Common::Role rol
return 0;
}
Sapphire::World::QueuedContentState Sapphire::World::QueuedContent::getState() const
World::QueuedContentState World::QueuedContent::getState() const
{
return m_state;
}
void Sapphire::World::QueuedContent::setState( Sapphire::World::QueuedContentState state )
void World::QueuedContent::setState( World::QueuedContentState state )
{
m_state = state;
}
@ -546,7 +547,7 @@ void Sapphire::World::QueuedContent::setState( Sapphire::World::QueuedContentSta
//////////////////////////////////////////////////////////////////////
Sapphire::World::QueuedPlayer::QueuedPlayer( const Entity::Player &player, uint8_t registerId )
World::QueuedPlayer::QueuedPlayer( const Entity::Player &player, uint8_t registerId )
{
m_characterId = player.getCharacterId();
m_classJob = static_cast< uint32_t >( player.getClass() );
@ -556,27 +557,27 @@ Sapphire::World::QueuedPlayer::QueuedPlayer( const Entity::Player &player, uint8
m_entityId = player.getId();
}
Sapphire::Common::Role Sapphire::World::QueuedPlayer::getRole() const
Common::Role World::QueuedPlayer::getRole() const
{
return m_role;
}
void Sapphire::World::QueuedPlayer::setActiveRegisterId( uint8_t registerId )
void World::QueuedPlayer::setActiveRegisterId( uint8_t registerId )
{
m_activeRegisterId = registerId;
}
uint8_t Sapphire::World::QueuedPlayer::getActiveRegisterId() const
uint8_t World::QueuedPlayer::getActiveRegisterId() const
{
return m_activeRegisterId;
}
uint64_t Sapphire::World::QueuedPlayer::getCharacterId() const
uint64_t World::QueuedPlayer::getCharacterId() const
{
return m_characterId;
}
uint32_t Sapphire::World::QueuedPlayer::getEntityId() const
uint32_t World::QueuedPlayer::getEntityId() const
{
return m_entityId;
}

View file

@ -5,17 +5,19 @@
#include <Network/PacketWrappers/EventLogMessagePacket.h>
#include <Network/PacketDef/Zone/ServerZoneDef.h>
#include <Network/CommonActorControl.h>
#include "Network/PacketWrappers/ActorControlPacket.h"
#include "Network/PacketWrappers/ActorControlSelfPacket.h"
#include "Network/GameConnection.h"
#include "Network/Util/PacketUtil.h"
#include "Actor/Player.h"
#include "Network/PacketWrappers/ActorControlPacket.h"
#include "Network/PacketWrappers/ActorControlSelfPacket.h"
#include <Logging/Logger.h>
#include <Service.h>
#include "WorldServer.h"
#include "Session.h"
#include "Network/GameConnection.h"
using namespace Sapphire::Common;
using namespace Sapphire::Network::Packets;
@ -83,8 +85,7 @@ void Sapphire::Event::Director::sendEventLogMessage( Sapphire::Entity::Player& p
void Sapphire::Event::Director::sendDirectorClear( Sapphire::Entity::Player& player ) const
{
auto& server = Common::Service< World::WorldServer >::ref();
server.queueForPlayer( player.getCharacterId(), makeActorControlSelf( player.getId(), DirectorClear, m_directorId ) );
Network::Util::Packet::sendActorControlSelf( player, player.getId(), DirectorClear, m_directorId );
}
void Sapphire::Event::Director::sendDirectorVars( Sapphire::Entity::Player& player ) const
@ -102,8 +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 );
auto& server = Common::Service< World::WorldServer >::ref();
server.queueForPlayer( player.getCharacterId(), makeActorControlSelf( player.getId(), 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

@ -2,8 +2,9 @@
#include <utility>
Sapphire::Event::EventHandler::EventHandler( uint64_t actorId, uint32_t eventId,
EventType eventType, uint32_t eventParam ) :
using namespace Sapphire;
Event::EventHandler::EventHandler( uint64_t actorId, uint32_t eventId, EventType eventType, uint32_t eventParam ) :
m_actorId( actorId ),
m_eventId( eventId ),
m_eventType( eventType ),
@ -15,107 +16,107 @@ Sapphire::Event::EventHandler::EventHandler( uint64_t actorId, uint32_t eventId,
m_returnCallback = nullptr;
}
uint64_t Sapphire::Event::EventHandler::getActorId() const
uint64_t Event::EventHandler::getActorId() const
{
return m_actorId;
}
uint32_t Sapphire::Event::EventHandler::getId() const
uint32_t Event::EventHandler::getId() const
{
return m_eventId;
}
uint8_t Sapphire::Event::EventHandler::getEventType() const
uint8_t Event::EventHandler::getEventType() const
{
return m_eventType;
}
uint16_t Sapphire::Event::EventHandler::getType() const
uint16_t Event::EventHandler::getType() const
{
return m_type;
}
uint16_t Sapphire::Event::EventHandler::getEntryId() const
uint16_t Event::EventHandler::getEntryId() const
{
return m_entryId;
}
uint32_t Sapphire::Event::EventHandler::getEventParam() const
uint32_t Event::EventHandler::getEventParam() const
{
return m_eventParam;
}
Sapphire::Event::EventHandler::SceneReturnCallback Sapphire::Event::EventHandler::getEventReturnCallback() const
Event::EventHandler::SceneReturnCallback Event::EventHandler::getEventReturnCallback() const
{
return m_returnCallback;
}
void Sapphire::Event::EventHandler::setEventReturnCallback( SceneReturnCallback callback )
void Event::EventHandler::setEventReturnCallback( SceneReturnCallback callback )
{
m_returnCallback = std::move( callback );
}
Sapphire::Event::EventHandler::QuestSceneReturnCallback Sapphire::Event::EventHandler::getQuestEventReturnCallback() const
Event::EventHandler::QuestSceneReturnCallback Event::EventHandler::getQuestEventReturnCallback() const
{
return m_questReturnCallback;
}
void Sapphire::Event::EventHandler::setQuestEventReturnCallback( QuestSceneReturnCallback callback )
void Event::EventHandler::setQuestEventReturnCallback( QuestSceneReturnCallback callback )
{
m_questReturnCallback = std::move( callback );
}
Sapphire::Event::EventHandler::SceneChainCallback Sapphire::Event::EventHandler::getSceneChainCallback() const
Event::EventHandler::SceneChainCallback Event::EventHandler::getSceneChainCallback() const
{
return m_chainCallback;
}
void Sapphire::Event::EventHandler::setSceneChainCallback( Sapphire::Event::EventHandler::SceneChainCallback callback )
void Event::EventHandler::setSceneChainCallback( Event::EventHandler::SceneChainCallback callback )
{
m_chainCallback = std::move( callback );
}
Sapphire::Event::EventHandler::QuestSceneChainCallback Sapphire::Event::EventHandler::getQuestSceneChainCallback() const
Event::EventHandler::QuestSceneChainCallback Event::EventHandler::getQuestSceneChainCallback() const
{
return m_questChainCallback;
}
void Sapphire::Event::EventHandler::setQuestSceneChainCallback( Sapphire::Event::EventHandler::QuestSceneChainCallback callback )
void Event::EventHandler::setQuestSceneChainCallback( Event::EventHandler::QuestSceneChainCallback callback )
{
m_questChainCallback = std::move( callback );
}
Sapphire::Event::EventHandler::EventFinishCallback Sapphire::Event::EventHandler::getEventFinishCallback() const
Event::EventHandler::EventFinishCallback Event::EventHandler::getEventFinishCallback() const
{
return m_finishCallback;
}
void Sapphire::Event::EventHandler::setEventFinishCallback( EventFinishCallback callback )
void Event::EventHandler::setEventFinishCallback( EventFinishCallback callback )
{
m_finishCallback = std::move( callback );
}
bool Sapphire::Event::EventHandler::hasPlayedScene() const
bool Event::EventHandler::hasPlayedScene() const
{
return m_playedScene;
}
void Sapphire::Event::EventHandler::setPlayedScene( bool playedScene )
void Event::EventHandler::setPlayedScene( bool playedScene )
{
m_playedScene = playedScene;
}
bool Sapphire::Event::EventHandler::hasNestedEvent() const
bool Event::EventHandler::hasNestedEvent() const
{
return m_pNestedEvent != nullptr;
}
void Sapphire::Event::EventHandler::removeNestedEvent()
void Event::EventHandler::removeNestedEvent()
{
m_pNestedEvent.reset();
}
Sapphire::Event::ScenePlayParam *Sapphire::Event::EventHandler::getScenePlayParams()
Event::ScenePlayParam* Event::EventHandler::getScenePlayParams()
{
return &m_scenePlayParams;
}

View file

@ -47,6 +47,12 @@ namespace World::Territory::Housing
TYPE_FORWARD( HousingInteriorTerritory );
}
namespace World::AI
{
TYPE_FORWARD( GambitTargetCondition );
TYPE_FORWARD( GambitRule );
}
namespace Inventory
{
using InventoryContainerPair = std::pair< Common::InventoryType, uint8_t >;
@ -88,8 +94,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

@ -2,7 +2,9 @@
#include <utility>
Sapphire::FreeCompany::FreeCompany( uint64_t id, std::string name, std::string tag, uint64_t masterId, uint64_t chatChannelId ) :
using namespace Sapphire;
FreeCompany::FreeCompany( uint64_t id, std::string name, std::string tag, uint64_t masterId, uint64_t chatChannelId ) :
m_id( id ),
m_name( std::move( name ) ),
m_tag( std::move( tag ) ),
@ -12,211 +14,211 @@ Sapphire::FreeCompany::FreeCompany( uint64_t id, std::string name, std::string t
}
uint64_t Sapphire::FreeCompany::getId() const
uint64_t FreeCompany::getId() const
{
return m_id;
}
const std::string& Sapphire::FreeCompany::getName() const
const std::string& FreeCompany::getName() const
{
return m_name;
}
void Sapphire::FreeCompany::setName( std::string name )
void FreeCompany::setName( std::string name )
{
m_name = std::move( name );
}
const std::string& Sapphire::FreeCompany::getTag() const
const std::string& FreeCompany::getTag() const
{
return m_tag;
}
void Sapphire::FreeCompany::setTag( std::string tag )
void FreeCompany::setTag( std::string tag )
{
m_tag = std::move( tag );
}
uint64_t Sapphire::FreeCompany::getMasterId() const
uint64_t FreeCompany::getMasterId() const
{
return m_masterCharacterId;
}
void Sapphire::FreeCompany::setMasterId( uint64_t masterId )
void FreeCompany::setMasterId( uint64_t masterId )
{
m_masterCharacterId = masterId;
}
uint64_t Sapphire::FreeCompany::getCredit() const
uint64_t FreeCompany::getCredit() const
{
return m_credit;
}
void Sapphire::FreeCompany::setCredit( uint64_t credit )
void FreeCompany::setCredit( uint64_t credit )
{
m_credit = credit;
}
uint64_t Sapphire::FreeCompany::getCreditAccumulated() const
uint64_t FreeCompany::getCreditAccumulated() const
{
return m_creditAccumulated;
}
void Sapphire::FreeCompany::setCreditAccumulated( uint64_t credit )
void FreeCompany::setCreditAccumulated( uint64_t credit )
{
m_creditAccumulated = credit;
}
uint8_t Sapphire::FreeCompany::getRank() const
uint8_t FreeCompany::getRank() const
{
return m_rank;
}
void Sapphire::FreeCompany::setRank( uint8_t rank )
void FreeCompany::setRank( uint8_t rank )
{
m_rank = rank;
}
uint64_t Sapphire::FreeCompany::getPoints() const
uint64_t FreeCompany::getPoints() const
{
return m_points;
}
void Sapphire::FreeCompany::setPoints( uint64_t points )
void FreeCompany::setPoints( uint64_t points )
{
m_points = points;
}
uint64_t Sapphire::FreeCompany::getCrest() const
uint64_t FreeCompany::getCrest() const
{
return m_crest;
}
void Sapphire::FreeCompany::setCrest( uint64_t crest )
void FreeCompany::setCrest( uint64_t crest )
{
m_crest = crest;
}
uint32_t Sapphire::FreeCompany::getCreateDate() const
uint32_t FreeCompany::getCreateDate() const
{
return m_createDate;
}
void Sapphire::FreeCompany::setCreateDate( uint32_t createDate )
void FreeCompany::setCreateDate( uint32_t createDate )
{
m_createDate = createDate;
}
uint8_t Sapphire::FreeCompany::getGrandCompany() const
uint8_t FreeCompany::getGrandCompany() const
{
return m_gc;
}
void Sapphire::FreeCompany::setGrandCompany( uint8_t gcIndex )
void FreeCompany::setGrandCompany( uint8_t gcIndex )
{
if( gcIndex > 2 )
return;
m_gc = gcIndex;
}
uint64_t Sapphire::FreeCompany::getGcReputation( uint8_t gcIndex ) const
uint64_t FreeCompany::getGcReputation( uint8_t gcIndex ) const
{
if( gcIndex > 2 )
return 0;
return m_gcReputation[ gcIndex ];
}
void Sapphire::FreeCompany::setGcReputation( uint8_t gcIndex, uint64_t reputation )
void FreeCompany::setGcReputation( uint8_t gcIndex, uint64_t reputation )
{
if( gcIndex > 2 )
return;
m_gcReputation[ gcIndex ] = reputation;
}
Sapphire::Common::FreeCompanyStatus Sapphire::FreeCompany::getFcStatus() const
Common::FreeCompanyStatus FreeCompany::getFcStatus() const
{
return m_status;
}
void Sapphire::FreeCompany::setFcStatus( Sapphire::Common::FreeCompanyStatus status )
void FreeCompany::setFcStatus( Common::FreeCompanyStatus status )
{
m_status = status;
}
const std::string& Sapphire::FreeCompany::getFcBoard() const
const std::string& FreeCompany::getFcBoard() const
{
return m_fcBoard;
}
void Sapphire::FreeCompany::setFcBoard( const std::string& board )
void FreeCompany::setFcBoard( const std::string& board )
{
m_fcBoard = board;
}
const std::string& Sapphire::FreeCompany::getFcMotto() const
const std::string& FreeCompany::getFcMotto() const
{
return m_fcMotto;
}
void Sapphire::FreeCompany::setFcMotto( const std::string& motto )
void FreeCompany::setFcMotto( const std::string& motto )
{
m_fcMotto = motto;
}
uint32_t Sapphire::FreeCompany::getFcVersion() const
uint32_t FreeCompany::getFcVersion() const
{
return m_fcVersion;
}
void Sapphire::FreeCompany::setFcVersion( uint32_t version )
void FreeCompany::setFcVersion( uint32_t version )
{
m_fcVersion = version;
}
const std::array< uint64_t, 3 >& Sapphire::FreeCompany::getActiveActionIdArr() const
const std::array< uint64_t, 3 >& FreeCompany::getActiveActionIdArr() const
{
return m_activeActionId;
}
const std::array< uint64_t, 3 >& Sapphire::FreeCompany::getActiveActionTimeLeftArr() const
const std::array< uint64_t, 3 >& FreeCompany::getActiveActionTimeLeftArr() const
{
return m_activeActionTimeLeft;
}
const std::array< uint64_t, 15 >& Sapphire::FreeCompany::getActionStockArr() const
const std::array< uint64_t, 15 >& FreeCompany::getActionStockArr() const
{
return m_actionStock;
}
uint64_t Sapphire::FreeCompany::getChatChannel() const
uint64_t FreeCompany::getChatChannel() const
{
return m_chatChannelId;
}
const std::set< uint64_t >& Sapphire::FreeCompany::getMemberIdList() const
const std::set< uint64_t >& FreeCompany::getMemberIdList() const
{
return m_memberIds;
}
std::set< uint64_t >& Sapphire::FreeCompany::getMemberIdList()
std::set< uint64_t >& FreeCompany::getMemberIdList()
{
return m_memberIds;
}
void Sapphire::FreeCompany::addMember( uint64_t memberId, uint8_t hierarchyId, uint32_t lastLogout )
void FreeCompany::addMember( uint64_t memberId, uint8_t hierarchyId, uint32_t lastLogout )
{
FcMember member{ memberId, hierarchyId, lastLogout };
m_memberDetails[ memberId ] = member;
m_memberIds.insert( memberId );
}
void Sapphire::FreeCompany::removeMember( uint64_t memberId )
void FreeCompany::removeMember( uint64_t memberId )
{
m_memberDetails.erase( memberId );
m_memberIds.erase( memberId );
}
void Sapphire::FreeCompany::setChatChannel( uint64_t chatChannelId )
void FreeCompany::setChatChannel( uint64_t chatChannelId )
{
m_chatChannelId = chatChannelId;
}

View file

@ -2,7 +2,7 @@
#include <Util/Util.h>
#include "AchievementMgr.h"
#include <Network/Util/PlayerUtil.h>
#include <Network/Util/PacketUtil.h>
#include <Network/CommonActorControl.h>
using namespace Sapphire;
@ -69,9 +69,9 @@ void AchievementMgr::unlockAchievement( Entity::Player& player, uint32_t achieve
// fire packets
player.setAchievementData( achvData );
Network::Util::Player::sendAchievementList( player );
Network::Util::Player::sendActorControl( player, AchievementComplete, achievementId );
Network::Util::Player::sendActorControl( player, AchievementObtainMsg, achievementId );
Network::Util::Packet::sendAchievementList( player );
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

@ -59,19 +59,18 @@ void ActionMgr::handleItemManipulationAction( Entity::Player& player, uint32_t a
action->start();
}
void ActionMgr::handleTargetedPlayerAction( Entity::Player& player, uint32_t actionId,
Excel::ExcelStructPtr< Excel::Action > actionData, uint64_t targetId, uint16_t requestId )
void ActionMgr::handleTargetedAction( Entity::Chara& src, uint32_t actionId,
Excel::ExcelStructPtr< Excel::Action > actionData, uint64_t targetId, uint16_t requestId )
{
auto action = Action::make_Action( player.getAsPlayer(), actionId, requestId, actionData );
auto action = Action::make_Action( src.getAsChara(), actionId, requestId, actionData );
action->setTargetId( targetId );
action->setPos( player.getPos() );
action->setPos( src.getPos() );
if( !action->init() )
return;
bootstrapAction( player, action, actionData );
bootstrapAction( src, action, actionData );
}
void ActionMgr::handleItemAction( Sapphire::Entity::Player& player, uint32_t itemId,
@ -118,7 +117,7 @@ void ActionMgr::handleMountAction( Entity::Player& player, uint16_t mountId,
bootstrapAction( player, action, actionData );
}
void ActionMgr::bootstrapAction( Entity::Player& player, Action::ActionPtr currentAction,
void ActionMgr::bootstrapAction( Entity::Chara& src, Action::ActionPtr currentAction,
Excel::ExcelStructPtr< Excel::Action > actionData )
{
/*
@ -131,22 +130,25 @@ void ActionMgr::bootstrapAction( Entity::Player& player, Action::ActionPtr curre
}
*/
if( player.getCurrentAction() )
if( src.getCurrentAction() )
{
PlayerMgr::sendDebug( player, "Skill queued: {0}", currentAction->getId() );
player.setQueuedAction( currentAction );
if( src.isPlayer() )
{
auto& player = *src.getAsPlayer();
PlayerMgr::sendDebug( player, "Skill queued: {0}", currentAction->getId() );
player.setQueuedAction( currentAction );
}
}
else
{
// 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 );
}
src.setCurrentAction( currentAction );
// todo: what do in cases of swiftcast/etc? script callback?
currentAction->start();
player.setLastAttack( Common::Util::getTimeMs() );
src.setLastAttack( Common::Util::getTimeMs() );
}
}

View file

@ -24,8 +24,8 @@ namespace Sapphire::World::Manager
void handleItemManipulationAction( Entity::Player& player, uint32_t actionId, Excel::ExcelStructPtr< Excel::Action > actionData, uint16_t sequence );
void handleTargetedPlayerAction( Entity::Player& player, uint32_t actionId,
std::shared_ptr< Excel::ExcelStruct< Excel::Action > > actionData, uint64_t targetId, uint16_t requestId );
void handleTargetedAction( Entity::Chara& chara, uint32_t actionId,
std::shared_ptr< Excel::ExcelStruct< Excel::Action > > actionData, uint64_t targetId, uint16_t requestId );
void handlePlacedPlayerAction( Entity::Player& player, uint32_t actionId,
std::shared_ptr< Excel::ExcelStruct< Excel::Action > > actionData, Common::FFXIVARR_POSITION3 pos, uint16_t sequence );
@ -40,7 +40,7 @@ namespace Sapphire::World::Manager
bool actionHasCastTime( uint32_t actionId );
private:
void bootstrapAction( Entity::Player& player, Action::ActionPtr currentAction, std::shared_ptr< Excel::ExcelStruct< Excel::Action > > actionData );
void bootstrapAction( Entity::Chara& src, Action::ActionPtr currentAction, std::shared_ptr< Excel::ExcelStruct< Excel::Action > > actionData );
// item action handlers
void handleItemActionVFX( Entity::Player& player, uint32_t itemId, uint16_t vfxId );

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 );
@ -539,7 +538,7 @@ void DebugCommandMgr::add( char* data, Entity::Player& player, std::shared_ptr<
entry.Arg0 = static_cast< uint8_t >( Common::ActionHitSeverityType::NormalDamage );
effectPacket->addTargetEffect( entry, static_cast< uint64_t >( player.getId() ) );
effectPacket->setResultId( pCurrentZone->getNextEffectResultId() );
effectPacket->setResultId( pCurrentZone->getNextActionResultId() );
server().queueForPlayer( player.getCharacterId(), effectPacket );
}

View file

@ -8,6 +8,7 @@
#include <Network/PacketWrappers/ActorControlSelfPacket.h>
#include <Network/CommonActorControl.h>
#include <Network/GameConnection.h>
#include <Network/Util/PacketUtil.h>
#include <unordered_map>
#include <cstring>
@ -288,7 +289,6 @@ uint32_t HousingMgr::toLandSetId( int16_t territoryTypeId, int16_t wardId ) cons
return ( static_cast< uint32_t >( territoryTypeId ) << 16 ) | wardId;
}
LandPtr HousingMgr::getLandByOwnerId( uint64_t id )
{
@ -404,7 +404,7 @@ LandPurchaseResult HousingMgr::purchaseLand( Entity::Player& player, HousingZone
pLand->setStatus( Common::HouseStatus::Sold );
pLand->setLandType( Common::LandType::Private );
player.setLandFlags( Common::LandFlagsSlot::Private, 0x00, pLand->getLandIdent() );
player.setLandFlags( Common::LandFlagsSlot::Private, 0, pLand->getLandIdent() );
sendLandFlagsSlot( player, Common::LandFlagsSlot::Private );
@ -432,10 +432,9 @@ bool HousingMgr::relinquishLand( Entity::Player& player, HousingZone& zone, uint
// can't relinquish when you are not the owner
// TODO: actually use permissions here for FC houses
if( !hasPermission( player, *pLand, 0 ) )
if( !pLand || !hasPermission( player, *pLand, 0 ) )
{
auto msgPkt = makeActorControlSelf( player.getId(), ActorControl::LogMsg, 3304, 0 );
server.queueForPlayer( player.getCharacterId(), msgPkt );
Network::Util::Packet::sendActorControlSelf( player, player.getId(), ActorControl::LogMsg, 3304 );
return false;
}
@ -443,8 +442,7 @@ bool HousingMgr::relinquishLand( Entity::Player& player, HousingZone& zone, uint
// TODO: additionally check for yard items
if( pLand->getHouse() )
{
auto msgPkt = makeActorControlSelf( player.getId(), ActorControl::LogMsg, 3315, 0 );
server.queueForPlayer( player.getCharacterId(), msgPkt );
Network::Util::Packet::sendActorControlSelf( player, player.getId(), ActorControl::LogMsg, 3315 );
return false;
}
@ -456,15 +454,12 @@ bool HousingMgr::relinquishLand( Entity::Player& player, HousingZone& zone, uint
Common::LandIdent ident { 0xFF, 0xFF, 0xFF, 0xFF };
player.setLandFlags( Common::LandFlagsSlot::Private, 0x00, ident );
player.setLandFlags( Common::LandFlagsSlot::Private, 0, ident );
sendLandFlagsSlot( player, Common::LandFlagsSlot::Private );
auto screenMsgPkt2 = makeActorControlSelf( player.getId(), ActorControl::LogMsg, 3351, 0x1AA,
pLand->getLandIdent().wardNum + 1, plot + 1 );
server.queueForPlayer( player.getCharacterId(), screenMsgPkt2 );
Network::Util::Packet::sendActorControlSelf( player, player.getId(), ActorControl::LogMsg, 3351, 0x1AA, pLand->getLandIdent().wardNum + 1, plot + 1 );
zone.sendLandUpdate( plot );
return true;
}
@ -680,10 +675,7 @@ void HousingMgr::buildPresetEstate( Entity::Player& player, HousingZone& zone, u
auto& server = Common::Service< World::WorldServer >::ref();
auto pLand = zone.getLand( plotNum );
if( !pLand )
return;
if( !hasPermission( player, *pLand, 0 ) )
if( !pLand || !hasPermission( player, *pLand, 0 ) )
return;
// create house
@ -708,9 +700,7 @@ void HousingMgr::buildPresetEstate( Entity::Player& player, HousingZone& zone, u
pLand->setLandType( Common::LandType::Private );
zone.sendLandUpdate( plotNum );
auto pSuccessBuildingPacket = makeActorControl( player.getId(), ActorControl::BuildPresetResponse, plotNum );
server.queueForPlayer( player.getCharacterId(), pSuccessBuildingPacket );
Network::Util::Packet::sendActorControl( player, player.getId(), ActorControl::BuildPresetResponse, plotNum );
pLand->updateLandDb();
@ -790,10 +780,7 @@ void HousingMgr::updateEstateGreeting( Entity::Player& player, const Common::Lan
return;
auto land = hZone->getLand( static_cast< uint8_t >( ident.landId ) );
if( !land )
return;
if( !hasPermission( player, *land, 0 ) )
if( !land || !hasPermission( player, *land, 0 ) )
return;
auto house = land->getHouse();
@ -819,10 +806,7 @@ void HousingMgr::requestEstateEditGuestAccess( Entity::Player& player, const Com
return;
auto land = hZone->getLand( ident.landId );
if( !land )
return;
if( !hasPermission( player, *land, 0 ) )
if( !land || !hasPermission( player, *land, 0 ) )
return;
auto packet = makeZonePacket< FFXIVIpcHousingWelcome >( player.getId() );
@ -886,10 +870,7 @@ void HousingMgr::sendEstateInventory( Entity::Player& player, uint16_t inventory
targetLand = zone->getLand( plotNum );
}
if( !targetLand )
return;
if( !hasPermission( player, *targetLand, 0 ) )
if( !targetLand || !hasPermission( player, *targetLand, 0 ) )
return;
auto& containers = getEstateInventory( targetLand->getLandIdent() );
@ -1024,10 +1005,7 @@ void HousingMgr::reqPlaceHousingItem( Entity::Player& player, uint16_t landId, u
else
return;
if( !land )
return;
if( !hasPermission( player, *land, 0 ) )
if( !land || !hasPermission( player, *land, 0 ) )
return;
// todo: check item position and make sure it's not outside the plot
@ -1065,7 +1043,7 @@ void HousingMgr::reqPlaceHousingItem( Entity::Player& player, uint16_t landId, u
status = placeInteriorItem( player, item );
if( status )
server.queueForPlayer( player.getCharacterId(), makeActorControlSelf( player.getId(), 0x3f3 ) );
Network::Util::Packet::sendActorControlSelf( player, player.getId(), 0x3f3 );
else
PlayerMgr::sendUrgent( player, "An internal error occurred when placing the item." );
}
@ -1281,10 +1259,7 @@ void HousingMgr::reqMoveHousingItem( Entity::Player& player, Common::LandIdent i
auto hZone = std::dynamic_pointer_cast< HousingZone >( pTeri );
auto land = hZone->getLand( static_cast< uint8_t >( ident.landId ) );
if( !land )
return;
if( !hasPermission( player, *land, 0 ) )
if( !land || !hasPermission( player, *land, 0 ) )
return;
auto pZone = teriMgr.getTerritoryByGuId( player.getTerritoryId() );
@ -1343,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 );
server.queueForPlayer( player.getCharacterId(), makeActorControlSelf( player.getId(), ActorControl::HousingItemMoveConfirm, param1, slotIdx ) );
Network::Util::Packet::sendActorControlSelf( player, player.getId(), ActorControl::HousingItemMoveConfirm, param1, slotIdx );
return true;
}
@ -1353,8 +1328,7 @@ bool HousingMgr::moveExternalItem( Entity::Player& player, Common::LandIdent ide
auto& server = Common::Service< World::WorldServer >::ref();
auto land = terri.getLand( static_cast< uint8_t >( ident.landId ) );
if( !hasPermission( player, *land, 0 ) )
if( !land || !hasPermission( player, *land, 0 ) )
return false;
auto& containers = getEstateInventory( ident );
@ -1377,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 );
server.queueForPlayer( player.getCharacterId(), makeActorControlSelf( player.getId(), ActorControl::HousingItemMoveConfirm, param1, slot ) );
Network::Util::Packet::sendActorControlSelf( player, player.getId(), ActorControl::HousingItemMoveConfirm, param1, slot );
return true;
}
@ -1396,11 +1370,7 @@ void HousingMgr::reqRemoveHousingItem( Entity::Player& player, uint16_t plot, ui
auto hZone = std::dynamic_pointer_cast< HousingZone >( pTeri );
auto land = hZone->getLand( static_cast< uint8_t >( ident.landId ) );
if( !land )
return;
if( !hasPermission( player, *land, 0 ) )
if( !land || !hasPermission( player, *land, 0 ) )
return;
removeInternalItem( player, *terri, containerId, slot, sendToStoreroom );
@ -1408,10 +1378,7 @@ void HousingMgr::reqRemoveHousingItem( Entity::Player& player, uint16_t plot, ui
else if( auto terri = std::dynamic_pointer_cast< HousingZone >( pZone ) )
{
auto land = terri->getLand( static_cast< uint8_t >( plot ) );
if( !land )
return;
if( !hasPermission( player, *land, 0 ) )
if( !land || !hasPermission( player, *land, 0 ) )
return;
auto containerType = static_cast< Common::InventoryType >( containerId );
@ -1614,9 +1581,7 @@ void HousingMgr::reqEstateExteriorRemodel( Entity::Player& player, uint16_t plot
invMgr.sendInventoryContainer( player, it->second );
auto pkt = makeActorControlSelf( player.getId(), Network::ActorControl::ShowEstateExternalAppearanceUI, plot );
server.queueForPlayer( player.getCharacterId(), pkt );
Network::Util::Packet::sendActorControlSelf( player, player.getId(), ActorControl::ShowEstateExternalAppearanceUI, plot );
}
void HousingMgr::reqEstateInteriorRemodel( Entity::Player& player )
@ -1653,8 +1618,7 @@ void HousingMgr::reqEstateInteriorRemodel( Entity::Player& player )
invMgr.sendInventoryContainer( player, it->second );
auto pkt = makeActorControlSelf( player.getId(), Network::ActorControl::ShowEstateInternalAppearanceUI );
server.queueForPlayer( player.getCharacterId(), pkt );
Network::Util::Packet::sendActorControlSelf( player, player.getId(), ActorControl::ShowEstateInternalAppearanceUI );
}
bool HousingMgr::hasPermission( Entity::Player& player, Sapphire::Land& land, uint32_t permission )
@ -1697,8 +1661,7 @@ void HousingMgr::removeHouse( Entity::Player& player, uint16_t plot )
// TODO: actually use permissions here for FC houses
if( !hasPermission( player, *pLand, 0 ) )
{
auto msgPkt = makeActorControlSelf( player.getId(), ActorControl::LogMsg, 3305, 0 );
server.queueForPlayer( player.getCharacterId(), msgPkt );
Network::Util::Packet::sendActorControlSelf( player, player.getId(), ActorControl::LogMsg, 3305 );
return;
}

View file

@ -200,7 +200,7 @@ void PartyMgr::onMemberDisconnect( Entity::Player& disconnectingPlayer )
{
// TODO: 2nd argument here makes it automatically send passing leadership message
server.queueForPlayer( member->getCharacterId(), { makePcPartyUpdate( disconnectingPlayer, UpdateStatus::OFFLINE_MEMBER, party->PartyCount ),
makeZonePacket< FFXIVIpcUpdateParty >( member->getId() ) } );
makeZonePacket< FFXIVIpcUpdateParty >( member->getId() ) } );
}
sendPartyUpdate( *party );

View file

@ -7,8 +7,6 @@
#include <Territory/Land.h>
#include <Manager/TerritoryMgr.h>
#include <Manager/AchievementMgr.h>
#include <Manager/PartyMgr.h>
#include <Manager/HousingMgr.h>
#include <Manager/QuestMgr.h>
@ -18,18 +16,8 @@
#include <Database/ZoneDbConnection.h>
#include <Database/DbWorkerPool.h>
#include <Network/GameConnection.h>
#include <Network/CommonActorControl.h>
#include <Network/PacketDef/Zone/ServerZoneDef.h>
#include <Network/PacketWrappers/ActorControlPacket.h>
#include <Network/PacketWrappers/ActorControlSelfPacket.h>
#include <Network/PacketWrappers/ActorControlTargetPacket.h>
#include <Network/PacketWrappers/InitZonePacket.h>
#include <Network/PacketWrappers/PlayerSetupPacket.h>
#include <Network/PacketWrappers/ServerNoticePacket.h>
#include <Network/PacketWrappers/ChatPacket.h>
#include <Network/PacketWrappers/HudParamPacket.h>
#include <Network/Util/PlayerUtil.h>
#include <Network/Util/PacketUtil.h>
#include <Actor/Player.h>
#include <Actor/BNpc.h>
@ -218,9 +206,7 @@ void PlayerMgr::onMobKill( Entity::Player& player, Entity::BNpc& bnpc )
scriptMgr.onBNpcKill( player, bnpc );
if( player.hasReward( Common::UnlockEntry::HuntingLog ) )
{
player.updateHuntingLog( bnpc.getBNpcNameId() );
}
}
void PlayerMgr::sendLoginMessage( Entity::Player& player )
@ -262,48 +248,48 @@ void PlayerMgr::onMoveZone( Sapphire::Entity::Player& player )
}
auto& teri = *pZone;
Network::Util::Player::sendLogin( player );
Network::Util::Packet::sendLogin( player );
player.sendInventory();
if( player.isLogin() )
{
Network::Util::Player::sendActorControlSelf( player, SetConfigFlags, player.getConfigFlags(), 1 );
Network::Util::Player::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 )
//setStateFlag( PlayerStateFlag::BetweenAreas );
//setStateFlag( PlayerStateFlag::BetweenAreas1 );
Network::Util::Player::sendHuntingLog( player );
Network::Util::Packet::sendHuntingLog( player );
if( player.isLogin() )
Network::Util::Player::sendPlayerSetup( player );
Network::Util::Packet::sendPlayerSetup( player );
Network::Util::Player::sendRecastGroups( player );
Network::Util::Player::sendBaseParams( player );
Network::Util::Player::sendActorControl( player, SetItemLevel, player.getItemLevel() );
Network::Util::Packet::sendRecastGroups( player );
Network::Util::Packet::sendBaseParams( player );
Network::Util::Packet::sendActorControl( player, player.getId(), SetItemLevel, player.getItemLevel() );
if( player.isLogin() )
{
Network::Util::Player::sendChangeClass( player );
Network::Util::Player::sendActorControl( player, 0x112, 0x24 ); // unknown
Network::Util::Player::sendContentAttainFlags( player );
Network::Util::Packet::sendChangeClass( player );
Network::Util::Packet::sendActorControl( player, player.getId(), 0x112, 0x24 ); // unknown
Network::Util::Packet::sendContentAttainFlags( player );
player.clearSoldItems();
}
housingMgr.sendLandFlags( player );
Network::Util::Player::sendInitZone( player );
Network::Util::Packet::sendInitZone( player );
if( player.isLogin() )
{
Network::Util::Player::sendDailyQuests( player );
Network::Util::Player::sendQuestRepeatFlags( player );
Network::Util::Packet::sendDailyQuests( player );
Network::Util::Packet::sendQuestRepeatFlags( player );
auto &questMgr = Common::Service< World::Manager::QuestMgr >::ref();
questMgr.sendQuestsInfo( player );
Network::Util::Player::sendGrandCompany( player );
Network::Util::Packet::sendGrandCompany( player );
}
teri.onPlayerZoneIn( player );
@ -321,35 +307,38 @@ void PlayerMgr::onUpdate( Entity::Player& player, uint64_t tickCount )
if( !player.isAlive() )
return;
auto mainWeap = player.getItemAt( Common::GearSet0, Common::GearSetSlot::MainHand );
if( mainWeap && !player.checkAction() && ( player.getTargetId() && player.getStance() == Common::Stance::Active && player.isAutoattackOn() ) )
checkAutoAttack( player, tickCount );
}
void PlayerMgr::checkAutoAttack( Entity::Player& player, uint64_t tickCount ) const
{
auto mainWeap = player.getItemAt( Common::GearSet0, Common::MainHand );
if( !mainWeap || !player.isAutoattackOn() || player.checkAction() || !player.getTargetId() || player.getStance() != Common::Active )
return;
for( const auto& actor : player.getInRangeActors() )
{
// @TODO i dislike this, iterating over all in range actors when you already know the id of the actor you need...
for( const auto& actor : player.getInRangeActors() )
if( actor->getId() != player.getTargetId() || !actor->getAsChara()->isAlive() )
continue;
auto chara = actor->getAsChara();
// default autoattack range
float range = 3.f + chara->getRadius() + player.getRadius() * 0.5f;
// default autoattack range for ranged classes
auto classJob = player.getClass();
if( classJob == Common::ClassJob::Machinist || classJob == Common::ClassJob::Bard || classJob == Common::ClassJob::Archer )
range = 25.f + chara->getRadius() + player.getRadius() * 0.5f;
if( ( Common::Util::distance( player.getPos(), actor->getPos() ) <= range ) &&
( ( tickCount - player.getLastAttack() ) > mainWeap->getDelay() ) )
{
if( actor->getId() != player.getTargetId() || !actor->getAsChara()->isAlive() )
continue;
auto chara = actor->getAsChara();
// default autoattack range
float range = 3.f + chara->getRadius() + player.getRadius() * 0.5f;
// default autoattack range for ranged classes
auto classJob = player.getClass();
if( classJob == Common::ClassJob::Machinist || classJob == Common::ClassJob::Bard || classJob == Common::ClassJob::Archer )
range = 25.f + chara->getRadius() + player.getRadius() * 0.5f;
if( Common::Util::distance( player.getPos(), actor->getPos() ) <= range )
{
if( ( tickCount - player.getLastAttack() ) > mainWeap->getDelay() )
{
player.setLastAttack( tickCount );
player.autoAttack( actor->getAsChara() );
}
}
player.setLastAttack( tickCount );
player.autoAttack( actor->getAsChara() );
}
}
}
@ -357,22 +346,21 @@ void PlayerMgr::onUpdate( Entity::Player& player, uint64_t tickCount )
void PlayerMgr::sendServerNotice( Entity::Player& player, const std::string& message ) //Purple Text
{
server().queueForPlayer( player.getCharacterId(), std::make_shared< ServerNoticePacket >( player.getId(), message ) );
Network::Util::Packet::sendServerNotice( player, message );
}
void PlayerMgr::sendUrgent( Entity::Player& player, const std::string& message ) //Red Text
{
server().queueForPlayer( player.getCharacterId(), std::make_shared< ChatPacket >( player, Common::ChatType::ServerUrgent, message ) );
Network::Util::Packet::sendChat( player, Common::ChatType::ServerUrgent, message );
}
void PlayerMgr::sendDebug( Entity::Player& player, const std::string& message ) //Grey Text
{
server().queueForPlayer( player.getCharacterId(), std::make_shared< ChatPacket >( player, Common::ChatType::SystemMessage, message ) );
Network::Util::Packet::sendChat( player, Common::ChatType::SystemMessage, 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 )
{
server().queueForPlayer( player.getCharacterId(), makeActorControlTarget( player.getId(), ActorControlType::LogMsg, messageId,
param2, param3, param4, param5, param6 ) );
Network::Util::Packet::sendActorControlTarget( player, player.getId(), LogMsg, messageId, param2, param3, param4, param5, param6 );
}

View file

@ -65,6 +65,8 @@ namespace Sapphire::World::Manager
std::map< uint32_t, Entity::PlayerPtr > m_playerMapById;
std::map< uint64_t, Entity::PlayerPtr > m_playerMapByCharacterId;
std::map< std::string, Entity::PlayerPtr > m_playerMapByName;
void checkAutoAttack( Entity::Player& player, uint64_t tickCount ) const;
};

View file

@ -9,27 +9,32 @@ using namespace Sapphire::World;
void TaskMgr::update( uint64_t tickCount )
{
for( auto it = m_taskList.begin(); it != m_taskList.end(); )
std::vector< TaskPtr > tmpTaskList;
for( const auto& pTask : m_taskList )
{
auto pTask = *it;
// is the task ready for execution?
if( ( tickCount - pTask->getQueueTimeMs() ) >= pTask->getDelayTimeMs() )
{
Logger::info( "[TaskMgr] " + pTask->toString() );
pTask->execute();
it = m_taskList.erase( it );
}
else
++it;
tmpTaskList.push_back( pTask );
}
m_taskList = tmpTaskList;
m_lastTick = tickCount;
while( !m_deferredTasks.empty() )
{
auto pTask = m_deferredTasks.front();
m_deferredTasks.pop();
m_taskList.push_back( pTask );
}
}
void TaskMgr::queueTask( const TaskPtr& pTask )
{
pTask->onQueue();
m_taskList.push_back( pTask );
m_deferredTasks.push( pTask );
}

View file

@ -2,6 +2,7 @@
#include <cstdint>
#include <string>
#include <queue>
#include <ForwardsZone.h>
#include <Util/Util.h>
@ -45,6 +46,7 @@ namespace Sapphire::World::Manager
private:
uint64_t m_lastTick{};
std::vector< TaskPtr > m_taskList;
std::queue< TaskPtr > m_deferredTasks;
};

View file

@ -14,6 +14,7 @@
#include <Network/CommonActorControl.h>
#include <Network/PacketWrappers/ActorControlSelfPacket.h>
#include <Network/PacketWrappers/ActorControlPacket.h>
#include <Network/Util/PacketUtil.h>
#include <Manager/PlayerMgr.h>
#include <Manager/MapMgr.h>
@ -90,10 +91,8 @@ void WarpMgr::requestWarp( Entity::Player& player, Common::WarpType warpType, Co
{
m_entityIdToWarpInfoMap[ player.getId() ] = { 0, warpType, targetPos, targetRot };
server().queueForPlayers( player.getInRangePlayerIds( true ),
makeActorControlSelf( player.getId(), WarpStart, warpType, warpType, 0, player.getTerritoryTypeId(), 1 ) );
server().queueForPlayers( player.getInRangePlayerIds(),
makeActorControl( player.getId(), ActorDespawnEffect, warpType, player.getTerritoryTypeId() ) );
Network::Util::Packet::sendActorControlSelf( player.getInRangePlayerIds( true ), player.getId(), WarpStart, warpType, warpType, 0, player.getTerritoryTypeId(), 1 );
Network::Util::Packet::sendActorControl( player.getInRangePlayerIds(), player.getId(), ActorDespawnEffect, warpType, player.getTerritoryTypeId() );
auto& taskMgr = Common::Service< TaskMgr >::ref();
taskMgr.queueTask( makeWarpTask( player, warpType, targetPos, targetRot, 1000 ) );
@ -127,14 +126,11 @@ void WarpMgr::finishWarp( Entity::Player& player )
auto warpFinishAnim = warpType - 1;
auto zoneInPacket = makeActorControlSelf( player.getId(), Appear, warpFinishAnim, raiseAnim, 0, 0 );
auto setStatusPacket = makeActorControl( player.getId(), SetStatus, static_cast< uint8_t >( Common::ActorStatus::Idle ) );
if( !player.getGmInvis() )
server().queueForPlayers( player.getInRangePlayerIds(), zoneInPacket );
Network::Util::Packet::sendActorControlSelf( player.getInRangePlayerIds(), player.getId(), Appear, warpFinishAnim, raiseAnim );
server().queueForPlayer( player.getCharacterId(), zoneInPacket );
server().queueForPlayers( player.getInRangePlayerIds( true ), setStatusPacket );
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

@ -52,7 +52,7 @@ void Sapphire::Network::GameConnection::actionRequest( const Packets::FFXIVARR_P
if( category == Common::ActionCategory::ItemManipulation )
actionMgr.handleItemManipulationAction( player, actionId, action, requestId );
else
actionMgr.handleTargetedPlayerAction( player, actionId, action, targetId, requestId );
actionMgr.handleTargetedAction( player, actionId, action, targetId, requestId );
break;
}

View file

@ -17,7 +17,7 @@
#include "Network/PacketWrappers/ActorControlPacket.h"
#include "Network/PacketWrappers/ActorControlTargetPacket.h"
#include "Network/PacketWrappers/MoveActorPacket.h"
#include "Network/Util/PlayerUtil.h"
#include "Network/Util/PacketUtil.h"
#include "Action/Action.h"
@ -388,15 +388,9 @@ void examineHandler( Sapphire::Entity::Player& player, uint32_t targetId )
return;
if( pPlayer->isActingAsGm() || pPlayer->getTerritoryTypeId() != player.getTerritoryTypeId() )
{
server().queueForPlayer( player.getCharacterId(), makeActorControl( player.getId(), ActorControlType::ExamineError ) );
}
Network::Util::Packet::sendActorControl( player, player.getId(), ExamineError );
else
{
server().queueForPlayer( player.getCharacterId(), std::make_shared< InspectPacket >( player, pPlayer ) );
}
}
void Sapphire::Network::GameConnection::commandHandler( const Packets::FFXIVARR_PACKET_RAW& inPacket, Entity::Player& player )
@ -424,7 +418,7 @@ void Sapphire::Network::GameConnection::commandHandler( const Packets::FFXIVARR_
player.setStance( Stance::Passive );
player.setAutoattack( false );
}
server().queueForPlayers( player.getInRangePlayerIds(), makeActorControl( player.getId(), 0, data.Arg0, 1 ) );
Network::Util::Packet::sendActorControl( player.getInRangePlayerIds(), player.getId(), ToggleWeapon, data.Arg0, 1 );
break;
}
case PacketCommand::AUTO_ATTACK: // Toggle auto-attack
@ -437,7 +431,7 @@ void Sapphire::Network::GameConnection::commandHandler( const Packets::FFXIVARR_
else
player.setAutoattack( false );
server().queueForPlayers( player.getInRangePlayerIds(), makeActorControl( player.getId(), 1, data.Arg0, 1 ) );
Network::Util::Packet::sendActorControl( player.getInRangePlayerIds(), player.getId(), AutoAttack, data.Arg0, 1 );
break;
}
@ -494,7 +488,7 @@ void Sapphire::Network::GameConnection::commandHandler( const Packets::FFXIVARR_
}
case PacketCommand::TITLE_LIST: // Get title list
{
Network::Util::Player::sendTitleList( player );
Network::Util::Packet::sendTitleList( player );
break;
}
case PacketCommand::BORROW_ACTION:
@ -509,7 +503,7 @@ void Sapphire::Network::GameConnection::commandHandler( const Packets::FFXIVARR_
}
case PacketCommand::SET_CUTSCENE:
{
server().queueForPlayer( player.getCharacterId(), makeActorControl( player.getId(), ActorControlType::SetCutsceneFlag, data.Arg0, 1 ) );
Network::Util::Packet::sendActorControl( player, player.getId(), SetCutsceneFlag, data.Arg0, 1 );
break;
}
case PacketCommand::EMOTE: // emote
@ -524,8 +518,7 @@ void Sapphire::Network::GameConnection::commandHandler( const Packets::FFXIVARR_
if( !emoteData )
return;
server().queueForPlayers( player.getInRangePlayerIds(),
makeActorControlTarget( player.getId(), ActorControlType::Emote, emoteId, 0, isSilent ? 1 : 0, 0, targetId ) );
Network::Util::Packet::sendActorControlTarget( player.getInRangePlayerIds(), player.getId(), Emote, emoteId, 0, isSilent ? 1 : 0, 0, targetId );
bool isPersistent = emoteData->data().Mode != 0;
@ -536,9 +529,8 @@ void Sapphire::Network::GameConnection::commandHandler( const Packets::FFXIVARR_
player.setPersistentEmote( emoteData->data().Mode );
player.setStatus( ActorStatus::EmoteMode );
server().queueForPlayers( player.getInRangePlayerIds( true ), makeActorControl( player.getId(), ActorControlType::SetStatus,
static_cast< uint8_t >( ActorStatus::EmoteMode ),
emoteData->data().IsEndEmoteMode ? 1 : 0 ) );
Network::Util::Packet::sendActorControl( player.getInRangePlayerIds( true ), player.getId(), SetStatus, static_cast< uint8_t >( ActorStatus::EmoteMode ),
emoteData->data().IsEndEmoteMode ? 1 : 0 );
}
if( emoteData->data().IsAvailableWhenDrawn )
@ -550,7 +542,7 @@ void Sapphire::Network::GameConnection::commandHandler( const Packets::FFXIVARR_
}
case PacketCommand::EMOTE_CANCEL: // emote
{
server().queueForPlayers( player.getInRangePlayerIds(), makeActorControl( player.getId(), ActorControlType::EmoteInterrupt ) );
Network::Util::Packet::sendActorControl( player.getInRangePlayerIds(), player.getId(), EmoteModeInterrupt );
break;
}
case PacketCommand::EMOTE_MODE_CANCEL:
@ -561,8 +553,9 @@ void Sapphire::Network::GameConnection::commandHandler( const Packets::FFXIVARR_
player.setStatus( ActorStatus::Idle );
server().queueForPlayers( player.getInRangePlayerIds(), std::make_shared< MoveActorPacket >( player, player.getRot(), 2, 0, 0, 0x5A / 4 ) );
server().queueForPlayers( player.getInRangePlayerIds(), makeActorControl( player.getId(), ActorControlType::EmoteModeInterrupt ) );
server().queueForPlayers( player.getInRangePlayerIds(), makeActorControl( player.getId(), SetStatus, static_cast< uint8_t >( ActorStatus::Idle ) ) );
Network::Util::Packet::sendActorControl( player.getInRangePlayerIds(), player.getId(), EmoteModeInterrupt );
Network::Util::Packet::sendActorControl( player.getInRangePlayerIds(), player.getId(), SetStatus, static_cast< uint8_t >( ActorStatus::Idle ) );
}
break;
}
@ -570,7 +563,7 @@ void Sapphire::Network::GameConnection::commandHandler( const Packets::FFXIVARR_
case PacketCommand::POSE_EMOTE_WORK: // reapply pose
{
player.setPose( static_cast< uint8_t >( data.Arg1 ) );
server().queueForPlayers( player.getInRangePlayerIds( true ), makeActorControl( player.getId(), SetPose, data.Arg0, data.Arg1 ) );
Network::Util::Packet::sendActorControl( player.getInRangePlayerIds( true ), player.getId(), SetPose, data.Arg0, data.Arg1 );
break;
}
case PacketCommand::POSE_EMOTE_CANCEL: // cancel pose
@ -609,12 +602,12 @@ 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::Player::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:
{
Network::Util::Player::sendAchievementList( player );
Network::Util::Packet::sendAchievementList( player );
break;
}
case PacketCommand::TELEPO_INQUIRY: // Teleport
@ -675,7 +668,7 @@ void Sapphire::Network::GameConnection::commandHandler( const Packets::FFXIVARR_
player.setActiveLand( static_cast< uint8_t >( data.Arg0 ), hZone->getWardNum() );
server().queueForPlayer( player.getCharacterId(), makeActorControl( player.getId(), ShowBuildPresetUI, data.Arg0 ) );
Network::Util::Packet::sendActorControl( player, player.getId(), ShowBuildPresetUI, data.Arg0 );
break;
}
case PacketCommand::HOUSING_AUCTION_INFO:
@ -753,8 +746,7 @@ void Sapphire::Network::GameConnection::commandHandler( const Packets::FFXIVARR_
uint8_t ward = ( data.Arg1 >> 16 ) & 0xFF;
uint8_t plot = ( data.Arg1 & 0xFF );
server().queueForPlayer( player.getCharacterId(), makeActorControl( player.getId(), ShowHousingItemUI, 0, plot ) );
Network::Util::Packet::sendActorControl( player, player.getId(), ShowHousingItemUI, 0, plot );
//TODO: show item housing container
break;

View file

@ -29,6 +29,7 @@
#include "Network/PacketWrappers/ActorControlSelfPacket.h"
#include "Network/PacketWrappers/ActorControlTargetPacket.h"
#include "Network/PacketWrappers/UpdateInventorySlotPacket.h"
#include "Network/Util/PacketUtil.h"
#include "Manager/DebugCommandMgr.h"
#include "Manager/MarketMgr.h"
@ -83,8 +84,7 @@ void Sapphire::Network::GameConnection::setProfileHandler( const Packets::FFXIVA
strcpy( searchInfoPacket->data().SearchComment, player.getSearchMessage() );
queueOutPacket( searchInfoPacket );
server().queueForPlayers( player.getInRangePlayerIds( true ), makeActorControl( player.getId(), SetStatusIcon,
static_cast< uint8_t >( player.getOnlineStatus() ) ) );
Network::Util::Packet::sendActorControl( player.getInRangePlayerIds( true ), player.getId(), SetStatusIcon, static_cast< uint8_t >( player.getOnlineStatus() ) );
}
void Sapphire::Network::GameConnection::getProfileHandler( const Packets::FFXIVARR_PACKET_RAW& inPacket, Entity::Player& player )
@ -103,17 +103,15 @@ void Sapphire::Network::GameConnection::getSearchCommentHandler( const Packets::
Logger::debug( "getSearchCommentHandler: {0}", targetId );
if( pPlayer )
{
if( pPlayer->isActingAsGm() || pPlayer->getTerritoryTypeId() != player.getTerritoryTypeId() )
return;
if( !pPlayer || pPlayer->isActingAsGm() || pPlayer->getTerritoryTypeId() != player.getTerritoryTypeId() )
return;
// retail sends the requester's id as both (isForSelf)
auto searchInfoPacket = makeZonePacket< FFXIVIpcGetSearchCommentResult >( player.getId() );
searchInfoPacket->data().TargetEntityID = targetId;
strcpy( searchInfoPacket->data().SearchComment, pPlayer->getSearchMessage() );
server().queueForPlayer( player.getCharacterId(), searchInfoPacket );
// retail sends the requester's id as both (isForSelf)
auto searchInfoPacket = makeZonePacket< FFXIVIpcGetSearchCommentResult >( player.getId() );
searchInfoPacket->data().TargetEntityID = targetId;
strcpy( searchInfoPacket->data().SearchComment, pPlayer->getSearchMessage() );
server().queueForPlayer( player.getCharacterId(), searchInfoPacket );
}
}
void Sapphire::Network::GameConnection::reqExamineFcInfo( const Packets::FFXIVARR_PACKET_RAW& inPacket, Entity::Player& player )
@ -236,7 +234,7 @@ void Sapphire::Network::GameConnection::moveHandler( const Packets::FFXIVARR_PAC
unknownRotation = 0x7F;
}
uint64_t currentTime = Util::getTimeMs();
uint64_t currentTime = Common::Util::getTimeMs();
player.m_lastMoveTime = currentTime;
player.m_lastMoveflag = animationType;
@ -313,14 +311,14 @@ void Sapphire::Network::GameConnection::newDiscoveryHandler( const Packets::FFXI
PlayerMgr::sendDebug( player, "Discovery ref pos id#{0}", layoutId );
if( pRefInfo )
{
auto discoveryPacket = makeZonePacket< FFXIVIpcDiscoveryReply >( player.getId() );
discoveryPacket->data().mapId = tInfo->data().Map;
discoveryPacket->data().mapPartId = pRefInfo->data.discoveryIndex;
server().queueForPlayer( player.getCharacterId(), discoveryPacket );
player.discover( tInfo->data().Map, pRefInfo->data.discoveryIndex );
}
if( !pRefInfo )
return;
auto discoveryPacket = makeZonePacket< FFXIVIpcDiscoveryReply >( player.getId() );
discoveryPacket->data().mapId = tInfo->data().Map;
discoveryPacket->data().mapPartId = pRefInfo->data.discoveryIndex;
server().queueForPlayer( player.getCharacterId(), discoveryPacket );
player.discover( tInfo->data().Map, pRefInfo->data.discoveryIndex );
}
@ -363,9 +361,7 @@ void Sapphire::Network::GameConnection::setLanguageHandler( const Packets::FFXIV
// if this is a login event
if( player.isLogin() )
{
playerMgr().sendLoginMessage( player );
}
// spawn the player for himself
player.spawn( player.getAsPlayer() );
@ -619,9 +615,7 @@ void Sapphire::Network::GameConnection::gearSetEquip( const Packets::FFXIVARR_PA
player.sendGearInventory();
if( packet.data().contextId < 0xFE )
{
server().queueForPlayer( player.getCharacterId(), makeActorControlSelf( player.getId(), Network::ActorControl::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

@ -1,4 +1,4 @@
#include "PlayerUtil.h"
#include "PacketUtil.h"
#include <Exd/ExdData.h>
@ -18,23 +18,25 @@
#include <Network/PacketWrappers/RestingPacket.h>
#include <Network/PacketWrappers/PlayerSetupPacket.h>
#include <Network/PacketWrappers/InitZonePacket.h>
#include <Network/PacketWrappers/ServerNoticePacket.h>
#include <Network/PacketWrappers/ChatPacket.h>
using namespace Sapphire;
using namespace Sapphire::World::Manager;
using namespace Sapphire::Network;
using namespace Sapphire::Network::Util::Player;
using namespace Sapphire::Network::Util::Packet;
using namespace Sapphire::Network::Packets;
using namespace Sapphire::Network::Packets::WorldPackets::Server;
using namespace Sapphire::Network::ActorControl;
void Util::Player::sendConfigFlags( Entity::Player& player )
void Util::Packet::sendConfigFlags( Entity::Player& player )
{
auto paramPacket = makeZonePacket< FFXIVIpcConfig >( player.getId() );
paramPacket->data().flag = player.getConfigFlags();
server().queueForPlayers( player.getInRangePlayerIds( true ), paramPacket );
}
void Util::Player::sendOnlineStatus( Entity::Player& player )
void Util::Packet::sendOnlineStatus( Entity::Player& player )
{
auto statusPacket = makeZonePacket< FFXIVIpcSetOnlineStatus >( player.getId() );
statusPacket->data().onlineStatusFlags = player.getFullOnlineStatusMask();
@ -44,7 +46,7 @@ void Util::Player::sendOnlineStatus( Entity::Player& player )
makeActorControl( player.getId(), SetStatusIcon, static_cast< uint8_t >( player.getOnlineStatus() ) ) );
}
void Util::Player::sendBaseParams( Entity::Player& player )
void Util::Packet::sendBaseParams( Entity::Player& player )
{
std::array< uint32_t, 50 > statParams{};
std::fill( std::begin( statParams ), std::end( statParams ), 0 );
@ -67,13 +69,17 @@ void Util::Player::sendBaseParams( Entity::Player& player )
server().queueForPlayer( player.getCharacterId(), statPacket );
}
void Util::Player::sendHudParam( Entity::Player& player )
void Util::Packet::sendHudParam( Entity::Chara& source )
{
auto hudParamPacket = makeHudParam( player );
server().queueForPlayer( player.getCharacterId(), hudParamPacket );
if( source.isPlayer() )
server().queueForPlayers( source.getInRangePlayerIds( true ), makeHudParam( *source.getAsPlayer() ) );
else if( source.isBattleNpc() )
server().queueForPlayers( source.getInRangePlayerIds( false ), makeHudParam( *source.getAsBNpc() ) );
else
server().queueForPlayers( source.getInRangePlayerIds( false ), makeHudParam( source ) );
}
void Util::Player::sendStatusUpdate( Entity::Player& player )
void Util::Packet::sendStatusUpdate( Entity::Player& player )
{
auto playerStatusUpdate = makeZonePacket< FFXIVIpcPlayerStatusUpdate >( player.getId() );
playerStatusUpdate->data().ClassJob = static_cast< uint8_t >( player.getClass() );
@ -85,7 +91,7 @@ void Util::Player::sendStatusUpdate( Entity::Player& player )
server().queueForPlayer( player.getCharacterId(), playerStatusUpdate );
}
void Util::Player::sendHuntingLog( Entity::Player& player )
void Util::Packet::sendHuntingLog( Entity::Player& player )
{
auto& exdData = Common::Service< Data::ExdData >::ref();
for( auto entryCount = 0; entryCount < Common::ARRSIZE_MONSTERNOTE; ++entryCount )
@ -128,37 +134,49 @@ void Util::Player::sendHuntingLog( Entity::Player& player )
}
}
void Util::Player::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::Player::sendActorControlSelf( const std::set< uint64_t >& characterIds, Entity::Player& player, uint16_t category, uint32_t param1,
void Util::Packet::sendActorControlSelf( const std::set< uint64_t >& characterIds, uint32_t srcId, uint16_t category, uint32_t param1,
uint32_t param2, uint32_t param3, uint32_t param4, uint32_t param5 )
{
server().queueForPlayers( characterIds, makeActorControlSelf( player.getId(), category, param1, param2, param3, param4, param5 ) );
server().queueForPlayers( characterIds, makeActorControlSelf( srcId, category, param1, param2, param3, param4, param5 ) );
}
void Util::Player::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::Player::sendActorControl( const std::set< uint64_t >& characterIds, Entity::Player& player, uint16_t category, uint32_t param1,
void Util::Packet::sendActorControl( const std::set< uint64_t >& characterIds, uint32_t srcId, uint16_t category, uint32_t param1,
uint32_t param2, uint32_t param3, uint32_t param4 )
{
server().queueForPlayers( characterIds, makeActorControl( player.getId(), category, param1, param2, param3, param4 ) );
server().queueForPlayers( characterIds, makeActorControl( srcId, category, param1, param2, param3, param4 ) );
}
void Util::Player::sendTitleList( Entity::Player& player )
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( 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,
uint32_t param2, uint32_t param3, uint32_t param4, uint32_t param5, uint32_t param6 )
{
server().queueForPlayers( characterIds, makeActorControlTarget( srcId, category, param1, param2, param3, param4, param5, param6 ) );
}
void Util::Packet::sendTitleList( Entity::Player& player )
{
auto titleListPacket = makeZonePacket< FFXIVIpcTitleList >( player.getId() );
memcpy( titleListPacket->data().TitleFlagsArray, player.getTitleList().data(), sizeof( titleListPacket->data().TitleFlagsArray ) );
server().queueForPlayer( player.getCharacterId(), titleListPacket );
}
void Util::Player::sendGrandCompany( Entity::Player& player )
void Util::Packet::sendGrandCompany( Entity::Player& player )
{
auto gcAffPacket = makeZonePacket< FFXIVIpcGrandCompany >( player.getId() );
gcAffPacket->data().ActiveCompanyId = player.getGc();
@ -168,7 +186,7 @@ void Util::Player::sendGrandCompany( Entity::Player& player )
server().queueForPlayer( player.getCharacterId(), gcAffPacket );
}
void Util::Player::sendDeletePlayer( Entity::Player& player, uint32_t actorId, uint8_t spawnIndex )
void Util::Packet::sendDeletePlayer( Entity::Player& player, uint32_t actorId, uint8_t spawnIndex )
{
auto freeActorSpawnPacket = makeZonePacket< FFXIVIpcActorFreeSpawn >( player.getId() );
freeActorSpawnPacket->data().actorId = actorId;
@ -176,14 +194,14 @@ void Util::Player::sendDeletePlayer( Entity::Player& player, uint32_t actorId, u
server().queueForPlayer( player.getCharacterId(), freeActorSpawnPacket );
}
void Util::Player::sendDeleteObject( Entity::Player& player, uint8_t spawnIndex )
void Util::Packet::sendDeleteObject( Entity::Player& player, uint8_t spawnIndex )
{
auto freeObjectSpawnPacket = makeZonePacket< FFXIVIpcDeleteObject >( player.getId() );
freeObjectSpawnPacket->data().Index = spawnIndex;
server().queueForPlayer( player.getCharacterId(), freeObjectSpawnPacket );
}
void Util::Player::sendHateList( Entity::Player& player )
void Util::Packet::sendHateList( Entity::Player& player )
{
auto& teriMgr = Common::Service< World::Manager::TerritoryMgr >::ref();
@ -211,7 +229,7 @@ void Util::Player::sendHateList( Entity::Player& player )
if( hateValue == 0 )
continue;
auto hatePercent = ( hateValue / static_cast< float >( pBNpc->hateListGetHighestValue() ) ) * 100.f;
auto hatePercent = ( static_cast< float >( hateValue ) / static_cast< float >( pBNpc->hateListGetHighestValue() ) ) * 100.f;
hateListPacket->data().List[ i ].Id = player.getId();
hateListPacket->data().List[ i ].Value = hateValue;
@ -223,36 +241,36 @@ void Util::Player::sendHateList( Entity::Player& player )
server().queueForPlayer( player.getCharacterId(), { hateListPacket, hateRankPacket } );
}
void Util::Player::sendMount( Entity::Player& player )
void Util::Packet::sendMount( Entity::Player& player )
{
auto mountId = player.getCurrentMount();
auto inRangePlayerIds = player.getInRangePlayerIds( true );
if( mountId != 0 )
{
Network::Util::Player::sendActorControl( inRangePlayerIds, player, SetStatus, static_cast< uint8_t >( Common::ActorStatus::Mounted ) );
Network::Util::Player::sendActorControlSelf( inRangePlayerIds, player, 0x39e, 12 );
Network::Util::Packet::sendActorControl( inRangePlayerIds, player.getId(), SetStatus, static_cast< uint8_t >( Common::ActorStatus::Mounted ) );
Network::Util::Packet::sendActorControlSelf( inRangePlayerIds, player.getId(), 0x39e, 12 );
}
else
{
Network::Util::Player::sendActorControl( inRangePlayerIds, player, SetStatus, static_cast< uint8_t >( Common::ActorStatus::Idle ) );
Network::Util::Player::sendActorControlSelf( inRangePlayerIds, player, Dismount, 1 );
Network::Util::Packet::sendActorControl( inRangePlayerIds, player.getId(), SetStatus, static_cast< uint8_t >( Common::ActorStatus::Idle ) );
Network::Util::Packet::sendActorControlSelf( inRangePlayerIds, player.getId(), Dismount, 1 );
}
auto mountPacket = makeZonePacket< FFXIVIpcMount >( player.getId() );
mountPacket->data().id = mountId;
server().queueForPlayers( inRangePlayerIds, mountPacket );
}
void Util::Player::sendEquip( Entity::Player& player )
void Util::Packet::sendEquip( Entity::Player& player )
{
server().queueForPlayers( player.getInRangePlayerIds( true ), std::make_shared< ModelEquipPacket >( player ) );
}
void Util::Player::sendCondition( Entity::Player& player )
void Util::Packet::sendCondition( Entity::Player& player )
{
server().queueForPlayer( player.getCharacterId(), std::make_shared< ConditionPacket >( player ) );
}
void Util::Player::sendRecastGroups( Entity::Player& player )
void Util::Packet::sendRecastGroups( Entity::Player& player )
{
const auto& recastGroups = player.getRecastGroups();
const auto& recastGroupsMax = player.getRecastGroupsMax();
@ -262,7 +280,7 @@ void Util::Player::sendRecastGroups( Entity::Player& player )
server().queueForPlayer( player.getCharacterId(), recastGroupPaket );
}
void Util::Player::sendAchievementList( Entity::Player& player )
void Util::Packet::sendAchievementList( Entity::Player& player )
{
auto achvData = player.getAchievementData();
auto achvPacket = makeZonePacket< FFXIVIpcAchievement >( player.getId() );
@ -271,24 +289,24 @@ void Util::Player::sendAchievementList( Entity::Player& player )
server().queueForPlayer( player.getCharacterId(), achvPacket );
}
void Util::Player::sendRestingUpdate( Entity::Player& player )
void Util::Packet::sendRestingUpdate( Entity::Player& player )
{
server().queueForPlayers( player.getInRangePlayerIds( true ), std::make_shared< RestingPacket >( player ) );
}
void Util::Player::sendLogin( Entity::Player& player )
void Util::Packet::sendLogin( Entity::Player& player )
{
auto initPacket = makeZonePacket< FFXIVIpcLogin >( player.getId() );
initPacket->data().playerActorId = player.getId();
server().queueForPlayer( player.getCharacterId(), initPacket );
}
void Util::Player::sendPlayerSetup( Entity::Player& player )
void Util::Packet::sendPlayerSetup( Entity::Player& player )
{
server().queueForPlayer( player.getCharacterId(), makePlayerSetup( player ) );
}
void Util::Player::sendChangeClass( Entity::Player& player )
void Util::Packet::sendChangeClass( Entity::Player& player )
{
auto classInfo = makeZonePacket< FFXIVIpcChangeClass >( player.getId() );
auto& borrowAction = player.getBorrowAction();
@ -300,7 +318,7 @@ void Util::Player::sendChangeClass( Entity::Player& player )
server().queueForPlayer( player.getCharacterId(), classInfo );
}
void Util::Player::sendContentAttainFlags( Entity::Player& player )
void Util::Packet::sendContentAttainFlags( Entity::Player& player )
{
// todo - fill with actual data from player
auto contentFinderList = makeZonePacket< FFXIVIpcContentAttainFlags >( player.getId() );
@ -308,7 +326,7 @@ void Util::Player::sendContentAttainFlags( Entity::Player& player )
server().queueForPlayer( player.getCharacterId(), contentFinderList );
}
void Util::Player::sendInitZone( Entity::Player& player )
void Util::Packet::sendInitZone( Entity::Player& player )
{
auto& teriMgr = Common::Service< World::Manager::TerritoryMgr >::ref();
auto pZone = teriMgr.getTerritoryByGuId( player.getTerritoryId() );
@ -321,12 +339,22 @@ void Util::Player::sendInitZone( Entity::Player& player )
server().queueForPlayer( player.getCharacterId(), makeInitZone( player, teri ) );
}
void Util::Player::sendDailyQuests( Entity::Player& player )
void Util::Packet::sendDailyQuests( Entity::Player& player )
{
server().queueForPlayer( player.getCharacterId(), makeZonePacket< FFXIVIpcDailyQuests >( player.getId() ) );
}
void Util::Player::sendQuestRepeatFlags( Entity::Player& player )
void Util::Packet::sendQuestRepeatFlags( Entity::Player& player )
{
server().queueForPlayer( player.getCharacterId(), makeZonePacket< FFXIVIpcQuestRepeatFlags >( player.getId() ) );
}
void Util::Packet::sendServerNotice( Entity::Player& player, const std::string& message )
{
server().queueForPlayer( player.getCharacterId(), std::make_shared< ServerNoticePacket >( player.getId(), message ) );
}
void Util::Packet::sendChat( Entity::Player& player, Common::ChatType chatType, const std::string& message )
{
server().queueForPlayer( player.getCharacterId(), std::make_shared< ChatPacket >( player, chatType, message ) );
}

View file

@ -5,12 +5,12 @@
#include <Actor/Player.h>
#include "Forwards.h"
namespace Sapphire::Network::Util::Player
namespace Sapphire::Network::Util::Packet
{
void sendConfigFlags( Entity::Player& player );
void sendOnlineStatus( Entity::Player& player );
void sendBaseParams( Entity::Player& player );
void sendHudParam( Entity::Player& player );
void sendHudParam( Entity::Chara& player );
void sendStatusUpdate( Entity::Player& player );
void sendHuntingLog( Entity::Player& player );
@ -48,15 +48,24 @@ namespace Sapphire::Network::Util::Player
void sendDailyQuests( Entity::Player& player );
void sendQuestRepeatFlags( Entity::Player& player );
void sendActorControlSelf( Entity::Player& player, uint16_t category, uint32_t param1 = 0, uint32_t param2 = 0, uint32_t param3 = 0,
void sendServerNotice( Entity::Player& player, const std::string& message );
void sendChat( Entity::Player& player, Common::ChatType chatType, const std::string& message );
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, Entity::Player& player, uint16_t category, uint32_t param1 = 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, Entity::Player& player, uint16_t category, uint32_t param1 = 0, uint32_t param2 = 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, 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,
uint32_t param2 = 0, uint32_t param3 = 0, uint32_t param4 = 0, uint32_t param5 = 0, uint32_t param6 = 0 );
}

View file

@ -204,27 +204,35 @@ void Sapphire::World::Session::sendReplayInfo()
PlayerMgr::sendDebug( *getPlayer(), message );
}
void Sapphire::World::Session::processOutQueue()
{
if( !m_pZoneConnection )
return;
m_pZoneConnection->processOutQueue();
}
void Sapphire::World::Session::update()
{
if( m_isReplaying )
processReplay();
if( m_pZoneConnection )
if( !m_pZoneConnection )
return;
m_pZoneConnection->processInQueue();
// SESSION LOGIC
m_pPlayer->update( Common::Util::getTimeMs() );
if( Common::Util::getTimeSeconds() - static_cast< uint32_t >( getLastSqlTime() ) > 10 )
{
m_pZoneConnection->processInQueue();
// SESSION LOGIC
m_pPlayer->update( Common::Util::getTimeMs() );
if( Common::Util::getTimeSeconds() - static_cast< uint32_t >( getLastSqlTime() ) > 10 )
{
updateLastSqlTime();
m_pPlayer->updateSql();
}
m_pZoneConnection->processOutQueue();
updateLastSqlTime();
m_pPlayer->updateSql();
}
m_pZoneConnection->processOutQueue();
if( m_pChatConnection )
{
m_pChatConnection->processInQueue();

View file

@ -47,6 +47,8 @@ namespace Sapphire::World
void update();
void processOutQueue();
bool isValid() const;
Entity::PlayerPtr getPlayer() const;

View file

@ -22,18 +22,12 @@ using namespace Sapphire::Network::Packets;
//using namespace Sapphire::Network::Packets::WorldPackets::Server;
Sapphire::StatusEffect::StatusEffect::StatusEffect( uint32_t id, Entity::CharaPtr sourceActor, Entity::CharaPtr targetActor,
uint32_t duration, std::vector< World::Action::StatusModifier >& modifiers, uint32_t tickRate ) :
uint32_t duration,std::vector< World::Action::StatusModifier >& modifiers,
uint32_t flag, uint32_t tickRate ) :
StatusEffect( id, sourceActor, targetActor, duration, tickRate )
{
m_statusModifiers = std::move( modifiers );
}
Sapphire::StatusEffect::StatusEffect::StatusEffect( uint32_t id, Entity::CharaPtr sourceActor, Entity::CharaPtr targetActor,
uint32_t duration, World::Action::StatusEntry& statusEntry, uint32_t tickRate ) :
StatusEffect( id, sourceActor, targetActor, duration, tickRate )
{
m_statusModifiers = statusEntry.modifiers;
m_flag |= statusEntry.flag;
m_flag = flag;
}
Sapphire::StatusEffect::StatusEffect::StatusEffect( uint32_t id, Entity::CharaPtr sourceActor, Entity::CharaPtr targetActor,
@ -100,6 +94,11 @@ uint32_t Sapphire::StatusEffect::StatusEffect::getSrcActorId() const
return m_sourceActor->getId();
}
Sapphire::Entity::CharaPtr Sapphire::StatusEffect::StatusEffect::getSrcActor() const
{
return m_sourceActor;
}
uint32_t Sapphire::StatusEffect::StatusEffect::getTargetActorId() const
{
return m_targetActor->getId();
@ -153,24 +152,6 @@ void Sapphire::StatusEffect::StatusEffect::applyStatus()
m_targetActor->calculateStats();
// this is only right when an action is being used by the player
// else you probably need to use an actorcontrol
//GamePacketNew< FFXIVIpcEffect > effectPacket( m_sourceActor->getId() );
//effectPacket.data().targetId = m_sourceActor->getId();
//effectPacket.data().actionAnimationId = 3;
//effectPacket.data().unknown_3 = 1;
//effectPacket.data().actionTextId = 3;
//effectPacket.data().unknown_5 = 1;
//effectPacket.data().unknown_6 = 321;
//effectPacket.data().rotation = ( uint16_t ) ( 0x8000 * ( ( m_sourceActor->getPos().getR() + 3.1415926 ) ) / 3.1415926 );
//effectPacket.data().effectTargetId = m_sourceActor->getId();
//effectPacket.data().effects[4].unknown_1 = 17;
//effectPacket.data().effects[4].bonusPercent = 30;
//effectPacket.data().effects[4].param1 = m_id;
//effectPacket.data().effects[4].unknown_5 = 0x80;
//m_sourceActor->sendToInRangeSet( effectPacket, true );
scriptMgr.onStatusReceive( m_targetActor, m_id );
}
@ -215,6 +196,11 @@ uint32_t Sapphire::StatusEffect::StatusEffect::getFlag() const
return m_flag;
}
std::vector< World::Action::StatusModifier > Sapphire::StatusEffect::StatusEffect::getStatusModifiers() const
{
return m_statusModifiers;
}
void Sapphire::StatusEffect::StatusEffect::setFlag( uint32_t flag )
{
m_flag = flag;
@ -234,3 +220,13 @@ const std::string& Sapphire::StatusEffect::StatusEffect::getName() const
{
return m_name;
}
uint8_t Sapphire::StatusEffect::StatusEffect::getSlot() const
{
return m_slot;
}
void Sapphire::StatusEffect::StatusEffect::setSlot( uint8_t slot )
{
m_slot = slot;
}

View file

@ -12,10 +12,7 @@ class StatusEffect
{
public:
StatusEffect( uint32_t id, Entity::CharaPtr sourceActor, Entity::CharaPtr targetActor,
uint32_t duration, std::vector< World::Action::StatusModifier >& modifiers, uint32_t tickRate );
StatusEffect( uint32_t id, Entity::CharaPtr sourceActor, Entity::CharaPtr targetActor,
uint32_t duration, World::Action::StatusEntry& statusEntry, uint32_t tickRate );
uint32_t duration, std::vector< World::Action::StatusModifier >& modifiers, uint32_t flag, uint32_t tickRate );
StatusEffect( uint32_t id, Entity::CharaPtr sourceActor, Entity::CharaPtr targetActor,
uint32_t duration, uint32_t tickRate );
@ -41,6 +38,7 @@ public:
uint32_t getTickRate() const;
uint32_t getSrcActorId() const;
Entity::CharaPtr getSrcActor() const;
uint32_t getTargetActorId() const;
@ -52,6 +50,8 @@ public:
uint32_t getFlag() const;
std::vector< World::Action::StatusModifier > getStatusModifiers() const;
void setLastTick( uint64_t lastTick );
void setParam( uint16_t param );
@ -64,6 +64,9 @@ public:
const std::string& getName() const;
uint8_t getSlot() const;
void setSlot( uint8_t slot );
private:
uint32_t m_id;
Entity::CharaPtr m_sourceActor;
@ -78,6 +81,8 @@ private:
std::pair< Common::ParamModifier, uint32_t > m_currTickEffect;
std::vector< World::Action::StatusModifier > m_statusModifiers;
std::unordered_map< Common::ParamModifier, int32_t > m_modifiers;
uint8_t m_slot;
};
}

View file

@ -6,6 +6,7 @@
#include <WorldServer.h>
#include <Service.h>
#include <Network/PacketWrappers/WarpPacket.h>
#include <StatusEffect/StatusEffect.h>
#include <utility>
@ -14,10 +15,11 @@ using namespace Sapphire::World::Manager;
using namespace Sapphire::Network::Packets;
using namespace Sapphire::Network::Packets::WorldPackets::Server;
ActionIntegrityTask::ActionIntegrityTask( uint32_t resultId, Entity::CharaPtr pTarget, uint64_t delayTime ) : Task( delayTime )
ActionIntegrityTask::ActionIntegrityTask( uint32_t resultId, Entity::CharaPtr pTarget, Action::ActionResultList& results, uint64_t delayTime ) : Task( delayTime )
{
m_resultId = resultId;
m_pTarget = std::move( pTarget );
m_results = results;
}
void ActionIntegrityTask::onQueue()
@ -27,6 +29,9 @@ void ActionIntegrityTask::onQueue()
void ActionIntegrityTask::execute()
{
if( !m_pTarget )
return;
auto& server = Common::Service< WorldServer >::ref();
auto inRangePlayers = m_pTarget->getInRangePlayerIds( true );
@ -37,6 +42,28 @@ void ActionIntegrityTask::execute()
auto integrityPacket = makeZonePacket< FFXIVIpcActionIntegrity >( 0 );
auto& data = integrityPacket->data();
integrityPacket->setSourceActor( m_pTarget->getId() );
for( int i = 0; i < 4; ++i )
data.Status[ i ].Source = Common::INVALID_GAME_OBJECT_ID;
int statusIdx = 0;
for( auto& actionResult : m_results )
{
if( actionResult->getCalcResultParam().Type == Common::CALC_RESULT_TYPE_SET_STATUS )
{
auto& status = data.Status[ statusIdx++ ];
auto pEffect = actionResult->getStatusEffect();
status.Source = pEffect->getSrcActorId();
status.Time = static_cast< float >( pEffect->getDuration() ) / 1000;
status.Id = static_cast< uint16_t >( pEffect->getId() );
status.Slot = static_cast< uint8_t >( pEffect->getSlot() );
status.SystemParam = static_cast< int16_t >( pEffect->getParam() );
}
if( actionResult && actionResult->getTarget() )
actionResult->execute();
}
data.Hp = m_pTarget->getHp();
data.HpMax = m_pTarget->getMaxHp();
data.Mp = m_pTarget->getMp();
@ -44,6 +71,9 @@ void ActionIntegrityTask::execute()
data.Tp = m_pTarget->getTp();
data.ResultId = m_resultId;
data.Target = m_pTarget->getId();
data.StatusCount = statusIdx;
data.ClassJob = static_cast< uint8_t >( m_pTarget->getClass() );
data.unknown_E0 = 0xE0;
server.queueForPlayers( inRangePlayers, integrityPacket );
@ -51,7 +81,7 @@ void ActionIntegrityTask::execute()
std::string ActionIntegrityTask::toString()
{
return fmt::format( "ActionIntegrityTask: ResultId#{}, TargetId#{}, ElapsedTimeMs: {}", m_resultId, m_pTarget->getId(), getDelayTimeMs() );
return fmt::format( "ActionIntegrityTask: ResultId#{}, TargetId#{}, ElapsedTimeMs: {}", m_resultId, m_pTarget ? m_pTarget->getId() : 0, getDelayTimeMs() );
}

View file

@ -4,6 +4,7 @@
#include <string>
#include <ForwardsZone.h>
#include "Task.h"
#include <Action/ActionResult.h>
namespace Sapphire::World
{
@ -11,7 +12,7 @@ namespace Sapphire::World
class ActionIntegrityTask : public Task
{
public:
ActionIntegrityTask( uint32_t resultId, Entity::CharaPtr pTarget, uint64_t delayTime );
ActionIntegrityTask( uint32_t resultId, Entity::CharaPtr pTarget, Action::ActionResultList& results, uint64_t delayTime );
void onQueue() override;
void execute() override;
@ -20,6 +21,7 @@ public:
private:
uint32_t m_resultId;
Entity::CharaPtr m_pTarget;
Action::ActionResultList m_results;
};
template< typename... Args >

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,8 +466,6 @@ bool Territory::update( uint64_t tickCount )
updateSessions( tickCount, changedWeather );
onUpdate( tickCount );
processEffectResults( tickCount );
if( !m_playerMap.empty() )
m_lastActivityTime = tickCount;
@ -824,7 +822,7 @@ void Territory::updateSpawnPoints()
}
}
uint32_t Territory::getNextEffectResultId()
uint32_t Territory::getNextActionResultId()
{
return m_effectCounter++;
}
@ -875,30 +873,6 @@ std::shared_ptr< World::Navi::NaviProvider > Territory::getNaviProvider()
return m_pNaviProvider;
}
void Territory::addEffectResult( World::Action::EffectResultPtr result )
{
m_effectResults.emplace_back( std::move( result ) );
}
void Territory::processEffectResults( 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(); )
{
auto effect = *it;
if( tickCount < effect->getDelay() )
{
++it;
continue;
}
effect->execute();
it = m_effectResults.erase( it );
}
}
bool Territory::loadBNpcs()
{
auto& db = Common::Service< Db::DbWorkerPool< Db::ZoneDbConnection > >::ref();

View file

@ -72,8 +72,6 @@ namespace Sapphire
uint32_t m_effectCounter{};
std::shared_ptr< World::Navi::NaviProvider > m_pNaviProvider;
std::vector< World::Action::EffectResultPtr > m_effectResults;
Common::TerritoryIdent m_ident;
float m_inRangeDistance;
@ -194,13 +192,9 @@ namespace Sapphire
void updateSpawnPoints();
uint32_t getNextEffectResultId();
uint32_t getNextActionResultId();
std::shared_ptr< World::Navi::NaviProvider > getNaviProvider();
void addEffectResult( World::Action::EffectResultPtr result );
void processEffectResults( uint64_t tickCount );
};
}

View file

@ -386,20 +386,21 @@ void WorldServer::mainLoop()
{
auto tickCount = Common::Util::getTimeMs();
auto currTime = Common::Util::getTimeSeconds();
taskMgr.update( tickCount );
updateSessions( currTime );
if( tickCount - m_lastServerTick < 300 )
{
std::this_thread::sleep_for( std::chrono::milliseconds( 50 ) );
std::this_thread::sleep_for( std::chrono::milliseconds( 10 ) );
continue;
}
m_lastServerTick = tickCount;
auto currTime = Common::Util::getTimeSeconds();
taskMgr.update( tickCount );
terriMgr.updateTerritoryInstances( tickCount );
scriptMgr.update();
contentFinder.update();
updateSessions( currTime );
DbKeepAlive( currTime );
}