From b247f69a96c61f4857976d09659b38120e1b99e4 Mon Sep 17 00:00:00 2001 From: NotAdam Date: Fri, 8 Feb 2019 22:09:48 +1100 Subject: [PATCH] move the old actioncast code into base action class --- src/world/Action/Action.cpp | 118 +++++++++++++++++++++++++++++++----- src/world/Action/Action.h | 41 +++++-------- 2 files changed, 119 insertions(+), 40 deletions(-) diff --git a/src/world/Action/Action.cpp b/src/world/Action/Action.cpp index d6ae040a..e320cbfe 100644 --- a/src/world/Action/Action.cpp +++ b/src/world/Action/Action.cpp @@ -1,15 +1,44 @@ #include "Action.h" +#include #include +#include "Framework.h" +#include "Script/ScriptMgr.h" + +#include "Actor/Player.h" + +#include +#include "Network/PacketWrappers/ActorControlPacket142.h" +#include "Network/PacketWrappers/ActorControlPacket143.h" +#include "Network/PacketWrappers/ActorControlPacket144.h" + +using namespace Sapphire::Common; +using namespace Sapphire::Network; +using namespace Sapphire::Network::Packets; +using namespace Sapphire::Network::Packets::Server; +using namespace Sapphire::Network::ActorControl; -Sapphire::Action::Action::Action() +Sapphire::Action::Action::Action() = default; +Sapphire::Action::Action::~Action() = default; + +Sapphire::Action::Action::Action( Entity::CharaPtr caster, Entity::CharaPtr target, + uint16_t actionId, FrameworkPtr fw ) : + + m_pSource( std::move( caster ) ), + m_pTarget( std::move( target ) ), + m_pFw( std::move( fw ) ), + m_id( actionId ), + m_startTime( 0 ) { -} + auto exdData = m_pFw->get< Data::ExdDataGenerated >(); + assert( exdData ); -Sapphire::Action::Action::~Action() -{ + auto actionData = exdData->get< Data::Action >( actionId ); + // todo: clients can crash the server here, ideally we do this check outside of the action anyway + assert( actionData ); + m_castTime = actionData->cast100ms * 100; } uint16_t Sapphire::Action::Action::getId() const @@ -17,11 +46,6 @@ uint16_t Sapphire::Action::Action::getId() const return m_id; } -Sapphire::Common::HandleActionType Sapphire::Action::Action::getHandleActionType() const -{ - return m_handleActionType; -} - Sapphire::Entity::CharaPtr Sapphire::Action::Action::getTargetChara() const { return m_pTarget; @@ -37,14 +61,11 @@ void Sapphire::Action::Action::setInterrupted() m_bInterrupt = true; } -uint64_t Sapphire::Action::Action::getStartTime() const +void Sapphire::Action::Action::start() { - return m_startTime; -} + m_startTime = Util::getTimeMs(); -void Sapphire::Action::Action::setStartTime( uint64_t startTime ) -{ - m_startTime = startTime; + onStart(); } uint32_t Sapphire::Action::Action::getCastTime() const @@ -57,6 +78,11 @@ void Sapphire::Action::Action::setCastTime( uint32_t castTime ) m_castTime = castTime; } +bool Sapphire::Action::Action::isCastedAction() const +{ + return m_castTime > 0; +} + Sapphire::Entity::CharaPtr Sapphire::Action::Action::getActionSource() const { return m_pSource; @@ -83,3 +109,65 @@ bool Sapphire::Action::Action::update() } return false; } + +void Sapphire::Action::Action::onStart() +{ + assert( m_pSource ); + + if( isCastedAction() ) + { + m_pSource->getAsPlayer()->sendDebug( "onStart()" ); + m_startTime = Util::getTimeMs(); + + auto castPacket = makeZonePacket< FFXIVIpcActorCast >( getId() ); + + castPacket->data().action_id = m_id; + castPacket->data().skillType = Common::SkillType::Normal; + castPacket->data().unknown_1 = m_id; + // This is used for the cast bar above the target bar of the caster. + castPacket->data().cast_time = static_cast< float >( m_castTime / 1000.f ); + castPacket->data().target_id = m_pTarget->getId(); + + m_pSource->sendToInRangeSet( castPacket, true ); + m_pSource->getAsPlayer()->setStateFlag( PlayerStateFlag::Casting ); + } +} + +void Sapphire::Action::Action::onInterrupt() +{ + assert( m_pSource ); + + if( isCastedAction() ) + { + //m_pSource->getAsPlayer()->unsetStateFlag( PlayerStateFlag::Occupied1 ); + m_pSource->getAsPlayer()->unsetStateFlag( PlayerStateFlag::Casting ); + + auto control = makeActorControl142( m_pSource->getId(), ActorControlType::CastInterrupt, 0x219, 1, m_id, 0 ); + + // Note: When cast interrupt from taking too much damage, set the last value to 1. This enables the cast interrupt effect. Example: + // auto control = ActorControlPacket142( m_pSource->getId(), ActorControlType::CastInterrupt, 0x219, 1, m_id, 0 ); + + m_pSource->sendToInRangeSet( control, true ); + } +} + +void Sapphire::Action::Action::onFinish() +{ + assert( m_pSource ); + + auto pScriptMgr = m_pFw->get< Scripting::ScriptMgr >(); + + auto pPlayer = m_pSource->getAsPlayer(); + pPlayer->sendDebug( "onFinish()" ); + + if( isCastedAction() ) + { + pPlayer->unsetStateFlag( PlayerStateFlag::Casting ); + + /*auto control = ActorControlPacket143( m_pTarget->getId(), ActorControlType::Unk7, + 0x219, m_id, m_id, m_id, m_id ); + m_pSource->sendToInRangeSet( control, true );*/ + + pScriptMgr->onCastFinish( *pPlayer, m_pTarget, m_id ); + } +} diff --git a/src/world/Action/Action.h b/src/world/Action/Action.h index ef4af91b..9c2134e9 100644 --- a/src/world/Action/Action.h +++ b/src/world/Action/Action.h @@ -12,47 +12,38 @@ namespace Sapphire::Action public: Action(); + Action( Entity::CharaPtr caster, Entity::CharaPtr target, uint16_t actionId, FrameworkPtr fw ); virtual ~Action(); uint16_t getId() const; - Common::HandleActionType getHandleActionType() const; - Entity::CharaPtr getTargetChara() const; - - bool isInterrupted() const; - - void setInterrupted(); - - uint64_t getStartTime() const; - - void setStartTime( uint64_t startTime ); - - uint32_t getCastTime() const; - - void setCastTime( uint32_t castTime ); - Entity::CharaPtr getActionSource() const; - virtual void onStart() - { - }; + bool isInterrupted() const; + void setInterrupted(); - virtual void onFinish() - { - }; + uint32_t getCastTime() const; + void setCastTime( uint32_t castTime ); - virtual void onInterrupt() - { - }; + /*! + * @brief Tests whether the action is instantly usable or has a cast assoc'd with it + * @return true if action has a cast time + */ + bool isCastedAction() const; + + void start(); + + virtual void onStart(); + virtual void onFinish(); + virtual void onInterrupt(); // update action, if returns true, action is done and has to be removed from the actor virtual bool update(); protected: uint16_t m_id; - Common::HandleActionType m_handleActionType; uint64_t m_startTime; uint32_t m_castTime;