1
Fork 0
mirror of https://github.com/SapphireServer/Sapphire.git synced 2025-04-28 15:17:46 +00:00
sapphire/src/world/Manager/ActionMgr.cpp

156 lines
4.7 KiB
C++
Raw Normal View History

#include "ActionMgr.h"
#include "PlayerMgr.h"
2023-01-27 05:23:13 +01:00
#include "Action/ActionLutData.h"
#include "Action/Action.h"
#include "Action/ItemAction.h"
#include "Action/EventItemAction.h"
2020-01-23 22:36:01 +09:00
#include "Action/MountAction.h"
#include "Script/ScriptMgr.h"
#include "Actor/Player.h"
#include <Service.h>
#include <Exd/ExdData.h>
2019-02-09 21:48:42 +11:00
#include <Network/PacketWrappers/EffectPacket.h>
using namespace Sapphire;
using namespace Sapphire::World::Manager;
2023-01-27 05:23:13 +01:00
bool ActionMgr::cacheActionLut()
{
return Action::ActionLutData::cacheActions();
}
void ActionMgr::handlePlacedPlayerAction( Entity::Player& player, uint32_t actionId,
2022-01-27 21:24:54 +01:00
Excel::ExcelStructPtr< Excel::Action > actionData, Common::FFXIVARR_POSITION3 pos,
uint16_t sequence )
{
PlayerMgr::sendDebug( player, "got aoe act: {0}", actionData->getString( actionData->data().Text.Name ) );
2020-03-01 01:00:57 +11:00
auto action = Action::make_Action( player.getAsPlayer(), actionId, sequence, actionData );
2020-01-05 17:09:27 +09:00
action->setPos( pos );
if( !action->init() )
return;
if( !actionData->data().EffectRange )
{
// not an action that has an aoe, cancel it
action->interrupt();
return;
}
bootstrapAction( player, action, actionData );
}
void ActionMgr::handleTargetedPlayerAction( Entity::Player& player, uint32_t actionId,
2022-01-27 21:24:54 +01:00
Excel::ExcelStructPtr< Excel::Action > actionData, uint64_t targetId, uint16_t sequence )
{
2020-03-01 01:00:57 +11:00
auto action = Action::make_Action( player.getAsPlayer(), actionId, sequence, actionData );
action->setTargetId( targetId );
2020-01-05 17:09:27 +09:00
action->setPos( player.getPos() );
if( !action->init() )
return;
// cancel any aoe actions casted with this packet
if( actionData->data().EffectRange )
{
action->interrupt();
return;
}
bootstrapAction( player, action, actionData );
}
void ActionMgr::handleItemAction( Sapphire::Entity::Player& player, uint32_t itemId,
2022-01-27 21:24:54 +01:00
Excel::ExcelStructPtr< Excel::ItemAction > itemActionData,
uint16_t itemSourceSlot, uint16_t itemSourceContainer )
2019-02-09 19:26:31 +11:00
{
PlayerMgr::sendDebug( player, "got item act: {0}, slot: {1}, container: {2}", itemId, itemSourceSlot, itemSourceContainer );
auto action = Action::make_ItemAction( player.getAsChara(), itemId, itemActionData,
2020-03-01 01:00:57 +11:00
itemSourceSlot, itemSourceContainer );
2019-02-09 21:48:42 +11:00
// todo: item actions don't have cast times? if so we can just start it and we're good
action->start();
2019-02-09 19:26:31 +11:00
}
void ActionMgr::handleEventItemAction( Sapphire::Entity::Player& player, uint32_t itemId,
2022-01-27 21:24:54 +01:00
Excel::ExcelStructPtr< Excel::EventItem > itemActionData,
uint32_t sequence, uint64_t targetId )
{
auto action = Action::make_EventItemAction( player.getAsChara(), itemId, itemActionData, sequence, targetId );
action->init();
if( itemActionData->data().CastTime )
{
player.setCurrentAction( action );
}
action->start();
}
void ActionMgr::handleMountAction( Entity::Player& player, uint16_t mountId,
2022-01-27 21:24:54 +01:00
Excel::ExcelStructPtr< Excel::Action > actionData, uint64_t targetId,
uint16_t sequence )
2020-01-23 22:36:01 +09:00
{
PlayerMgr::sendDebug( player, "setMount: {0}", mountId );
2020-01-23 22:36:01 +09:00
2020-03-01 01:00:57 +11:00
auto action = Action::make_MountAction( player.getAsPlayer(), mountId, sequence, actionData );
2020-01-23 22:36:01 +09:00
action->setTargetId( targetId );
if( !action->init() )
return;
bootstrapAction( player, action, actionData );
2020-01-23 22:36:01 +09:00
}
void ActionMgr::bootstrapAction( Entity::Player& player, Action::ActionPtr currentAction,
2022-01-27 21:24:54 +01:00
Excel::ExcelStructPtr< Excel::Action > actionData )
{
/*
//TODO: need to be fixed
2019-06-02 02:30:54 +10:00
if( !currentAction->preCheck() )
{
// forcefully interrupt the action and reset the cooldown
currentAction->interrupt();
return;
}
*/
2020-01-05 17:09:27 +09:00
if( player.getCurrentAction() )
{
PlayerMgr::sendDebug( player, "Skill queued: {0}", currentAction->getId() );
2020-01-05 17:09:27 +09:00
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 );
}
// todo: what do in cases of swiftcast/etc? script callback?
currentAction->start();
2022-01-02 22:32:17 +01:00
player.setLastAttack( Common::Util::getTimeMs() );
}
}
bool ActionMgr::actionHasCastTime( uint32_t actionId ) //TODO: Add logic for special cases
{
auto& exdData = Common::Service< Data::ExdData >::ref();
2022-01-27 21:24:54 +01:00
auto actionInfoPtr = exdData.getRow< Excel::Action >( actionId );
if( actionInfoPtr->data().ComboContinue )
return false;
return actionInfoPtr->data().CastTime != 0;
2023-01-27 05:23:13 +01:00
}