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

Implement ItemManipulationAction

Used for actions with a delay time but no cast
This commit is contained in:
Lucy 2023-02-10 04:27:21 +01:00
parent dac6c63414
commit f56a0a38e8
6 changed files with 120 additions and 1 deletions

View file

@ -0,0 +1,70 @@
#include "ItemManipulationAction.h"
#include <Exd/ExdData.h>
#include "Script/ScriptMgr.h"
#include "Actor/Player.h"
#include "Actor/BNpc.h"
#include <Logging/Logger.h>
#include <Service.h>
#include "WorldServer.h"
using namespace Sapphire;
using namespace Sapphire::World::Action;
using namespace Sapphire::Network::Packets::WorldPackets::Server;
ItemManipulationAction::ItemManipulationAction( Entity::CharaPtr source, uint32_t actionId, uint16_t sequence,
std::shared_ptr< Excel::ExcelStruct< Excel::Action > > actionData, uint32_t delayTime ) :
m_delayTimeMs( delayTime )
{
m_id = actionId;
m_pSource = std::move( source );
m_actionData = std::move( actionData );
m_sequence = sequence;
}
void ItemManipulationAction::start()
{
assert( m_pSource );
m_startTime = Common::Util::getTimeMs();
onStart();
execute();
}
void ItemManipulationAction::execute()
{
assert( m_pSource );
m_effectBuilder->buildAndSendPackets( m_hitActors );
}
void ItemManipulationAction::onFinish()
{
auto& scriptMgr = Common::Service< Scripting::ScriptMgr >::ref();
// send execute event to action script
scriptMgr.onExecute( *this );
}
bool ItemManipulationAction::update()
{
// action has not been started yet
if( m_startTime == 0 )
return false;
uint64_t tickCount = Common::Util::getTimeMs();
uint32_t delayTime = m_delayTimeMs;
if( std::difftime( static_cast< time_t >( tickCount ), static_cast< time_t >( m_startTime ) ) > delayTime )
{
onFinish();
return true;
}
return false;
}

View file

@ -0,0 +1,26 @@
#pragma once
#include "Action.h"
#include <Exd/Structs.h>
namespace Sapphire::World::Action
{
class ItemManipulationAction : public Action
{
public:
ItemManipulationAction( Entity::CharaPtr source, uint32_t actionId, uint16_t sequence,
std::shared_ptr< Excel::ExcelStruct< Excel::Action > > actionData, uint32_t delayTime );
virtual ~ItemManipulationAction() = default;
void start() override;
void execute() override;
bool update() override;
private:
void onFinish();
uint32_t m_delayTimeMs{};
};
}

View file

@ -87,6 +87,7 @@ TYPE_FORWARD( EventAction );
TYPE_FORWARD( ItemAction );
TYPE_FORWARD( EventItemAction );
TYPE_FORWARD( MountAction );
TYPE_FORWARD( ItemManipulationAction );
TYPE_FORWARD( EffectBuilder );
TYPE_FORWARD( EffectResult );

View file

@ -6,6 +6,7 @@
#include "Action/ItemAction.h"
#include "Action/EventItemAction.h"
#include "Action/MountAction.h"
#include "Action/ItemManipulationAction.h"
#include "Script/ScriptMgr.h"
#include "Actor/Player.h"
@ -45,6 +46,19 @@ void ActionMgr::handlePlacedPlayerAction( Entity::Player& player, uint32_t actio
bootstrapAction( player, action, actionData );
}
void ActionMgr::handleItemManipulationAction( Entity::Player& player, uint32_t actionId,
Excel::ExcelStructPtr< Excel::Action > actionData, uint16_t sequence )
{
auto action = Action::make_ItemManipulationAction( player.getAsPlayer(), actionId, sequence, actionData, 2500 ); // todo: maybe the delay can be retrieved from data
player.setCurrentAction( action );
if( !action->init() )
return;
action->start();
}
void ActionMgr::handleTargetedPlayerAction( Entity::Player& player, uint32_t actionId,
Excel::ExcelStructPtr< Excel::Action > actionData, uint64_t targetId, uint16_t sequence )
{

View file

@ -22,6 +22,9 @@ namespace Sapphire::World::Manager
bool cacheActionLut();
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 sequence );
void handlePlacedPlayerAction( Entity::Player& player, uint32_t actionId,

View file

@ -47,7 +47,12 @@ void Sapphire::Network::GameConnection::actionRequest( const Packets::FFXIVARR_P
if( !action )
return;
actionMgr.handleTargetedPlayerAction( player, actionId, action, targetId, sequence );
auto category = static_cast< Common::ActionCategory >( action->data().Category );
if( category == Common::ActionCategory::ItemManipulation )
actionMgr.handleItemManipulationAction( player, actionId, action, sequence );
else
actionMgr.handleTargetedPlayerAction( player, actionId, action, targetId, sequence );
break;
}