2019-02-03 19:38:04 +11:00
# include "ActionMgr.h"
2021-11-27 00:53:57 +01:00
# include "PlayerMgr.h"
2019-02-03 19:38:04 +11:00
2023-01-27 05:23:13 +01:00
# include "Action/ActionLutData.h"
2019-02-09 14:45:22 +11:00
# include "Action/Action.h"
2019-06-02 20:45:18 +10:00
# include "Action/ItemAction.h"
2021-12-17 15:48:56 +01:00
# include "Action/EventItemAction.h"
2020-01-23 22:36:01 +09:00
# include "Action/MountAction.h"
2023-02-10 04:27:21 +01:00
# include "Action/ItemManipulationAction.h"
2019-02-09 14:45:22 +11:00
# include "Script/ScriptMgr.h"
# include "Actor/Player.h"
2021-11-27 00:53:57 +01:00
# include <Service.h>
# include <Exd/ExdData.h>
2019-02-09 14:45:22 +11:00
2019-02-09 21:48:42 +11:00
# include <Network/PacketWrappers/EffectPacket.h>
2019-02-03 19:38:04 +11:00
using namespace Sapphire ;
2022-01-27 21:08:43 +01:00
using namespace Sapphire : : World : : Manager ;
2019-02-03 19:38:04 +11:00
2023-01-27 05:23:13 +01:00
bool ActionMgr : : cacheActionLut ( )
{
return Action : : ActionLutData : : cacheActions ( ) ;
}
2023-03-12 20:46:27 +01:00
void ActionMgr : : handlePlacedAction ( Entity : : Chara & chara , uint32_t actionId , Common : : FFXIVARR_POSITION3 pos , uint16_t requestId )
2019-02-03 19:57:04 +11:00
{
2023-03-12 20:46:27 +01:00
auto action = Action : : make_Action ( chara . getAsChara ( ) , actionId , requestId ) ;
2019-03-07 21:58:12 +11:00
2020-01-05 17:09:27 +09:00
action - > setPos ( pos ) ;
2019-03-07 21:58:12 +11:00
if ( ! action - > init ( ) )
return ;
2019-02-09 18:32:10 +11:00
2023-03-12 20:46:27 +01:00
auto actionData = action - > getActionData ( ) ;
if ( chara . isPlayer ( ) )
PlayerMgr : : sendDebug ( * chara . getAsPlayer ( ) , " got aoe act: {0} " , actionData - > getString ( actionData - > data ( ) . Text . Name ) ) ;
2021-11-27 00:53:57 +01:00
if ( ! actionData - > data ( ) . EffectRange )
2019-02-11 19:10:42 +11:00
{
// not an action that has an aoe, cancel it
2019-03-07 20:33:14 +11:00
action - > interrupt ( ) ;
2019-02-11 19:10:42 +11:00
return ;
}
2023-03-12 20:46:27 +01:00
bootstrapAction ( chara , action , actionData ) ;
2019-02-03 19:57:04 +11:00
}
2023-03-12 20:46:27 +01:00
void ActionMgr : : handleItemManipulationAction ( Entity : : Player & player , uint32_t actionId , uint16_t sequence )
2023-02-10 04:27:21 +01:00
{
2023-03-12 20:46:27 +01:00
auto action = Action : : make_ItemManipulationAction ( player . getAsPlayer ( ) , actionId , sequence , nullptr , 2500 ) ; // todo: maybe the delay can be retrieved from data
2023-02-10 04:27:21 +01:00
player . setCurrentAction ( action ) ;
if ( ! action - > init ( ) )
return ;
action - > start ( ) ;
}
2023-03-12 20:46:27 +01:00
void ActionMgr : : handleTargetedAction ( Entity : : Chara & src , uint32_t actionId , uint64_t targetId , uint16_t requestId )
2019-02-03 19:57:04 +11:00
{
2023-03-12 20:46:27 +01:00
auto action = Action : : make_Action ( src . getAsChara ( ) , actionId , requestId ) ;
2019-02-09 15:39:05 +11:00
2019-04-07 16:04:36 +10:00
action - > setTargetId ( targetId ) ;
2023-03-11 20:52:52 +01:00
action - > setPos ( src . getPos ( ) ) ;
2020-01-05 17:09:27 +09:00
2019-03-07 21:58:12 +11:00
if ( ! action - > init ( ) )
return ;
2023-03-12 20:46:27 +01:00
auto actionData = action - > getActionData ( ) ;
2023-03-11 20:52:52 +01:00
bootstrapAction ( src , action , actionData ) ;
2019-02-09 15:39:05 +11:00
}
2022-01-27 21:08:43 +01:00
void ActionMgr : : handleItemAction ( Sapphire : : Entity : : Player & player , uint32_t itemId ,
2022-01-27 21:24:54 +01:00
Excel : : ExcelStructPtr < Excel : : ItemAction > itemActionData ,
2022-01-27 21:08:43 +01:00
uint16_t itemSourceSlot , uint16_t itemSourceContainer )
2019-02-09 19:26:31 +11:00
{
2021-11-27 00:53:57 +01:00
PlayerMgr : : sendDebug ( player , " got item act: {0}, slot: {1}, container: {2} " , itemId , itemSourceSlot , itemSourceContainer ) ;
2019-02-10 19:50:28 +11:00
2019-06-02 20:45:18 +10:00
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
2019-06-02 20:45:18 +10: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
}
2022-01-27 21:08:43 +01:00
void ActionMgr : : handleEventItemAction ( Sapphire : : Entity : : Player & player , uint32_t itemId ,
2022-01-27 21:24:54 +01:00
Excel : : ExcelStructPtr < Excel : : EventItem > itemActionData ,
2022-01-27 21:08:43 +01:00
uint32_t sequence , uint64_t targetId )
2021-12-17 15:48:56 +01:00
{
auto action = Action : : make_EventItemAction ( player . getAsChara ( ) , itemId , itemActionData , sequence , targetId ) ;
action - > init ( ) ;
if ( itemActionData - > data ( ) . CastTime )
{
player . setCurrentAction ( action ) ;
}
action - > start ( ) ;
}
2022-01-27 21:08:43 +01:00
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 ,
2022-01-27 21:08:43 +01:00
uint16_t sequence )
2020-01-23 22:36:01 +09:00
{
2021-11-27 00:53:57 +01: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 ;
2021-11-27 00:53:57 +01:00
bootstrapAction ( player , action , actionData ) ;
2020-01-23 22:36:01 +09:00
}
2023-03-11 20:52:52 +01:00
void ActionMgr : : bootstrapAction ( Entity : : Chara & src , Action : : ActionPtr currentAction ,
2022-01-27 21:24:54 +01:00
Excel : : ExcelStructPtr < Excel : : Action > actionData )
2019-02-09 15:39:05 +11:00
{
2021-11-27 00:53:57 +01:00
/*
//TODO: need to be fixed
2019-06-02 02:30:54 +10:00
if ( ! currentAction - > preCheck ( ) )
2019-02-11 00:40:00 +11:00
{
// forcefully interrupt the action and reset the cooldown
2019-03-07 20:33:14 +11:00
currentAction - > interrupt ( ) ;
2019-02-09 15:39:05 +11:00
return ;
2019-02-11 00:40:00 +11:00
}
2021-11-27 00:53:57 +01:00
*/
2019-02-09 15:39:05 +11:00
2023-03-11 20:52:52 +01:00
if ( src . getCurrentAction ( ) )
2019-02-09 15:39:05 +11:00
{
2023-03-11 20:52:52 +01:00
if ( src . isPlayer ( ) )
{
auto & player = * src . getAsPlayer ( ) ;
PlayerMgr : : sendDebug ( player , " Skill queued: {0} " , currentAction - > getId ( ) ) ;
player . setQueuedAction ( currentAction ) ;
}
2020-01-05 17:09:27 +09:00
}
else
{
// if we have a cast time we want to associate the action with the player so update is called
if ( currentAction - > hasCastTime ( ) )
2023-03-11 20:52:52 +01:00
src . setCurrentAction ( currentAction ) ;
2020-01-05 17:09:27 +09:00
// todo: what do in cases of swiftcast/etc? script callback?
currentAction - > start ( ) ;
2023-03-11 20:52:52 +01:00
src . setLastAttack ( Common : : Util : : getTimeMs ( ) ) ;
2019-02-09 15:39:05 +11:00
}
2021-11-27 00:53:57 +01:00
}
2022-01-27 21:08:43 +01:00
bool ActionMgr : : actionHasCastTime ( uint32_t actionId ) //TODO: Add logic for special cases
2021-11-27 00:53:57 +01:00
{
auto & exdData = Common : : Service < Data : : ExdData > : : ref ( ) ;
2022-01-27 21:24:54 +01:00
auto actionInfoPtr = exdData . getRow < Excel : : Action > ( actionId ) ;
2021-11-27 00:53:57 +01:00
if ( actionInfoPtr - > data ( ) . ComboContinue )
return false ;
return actionInfoPtr - > data ( ) . CastTime ! = 0 ;
2023-01-27 05:23:13 +01:00
}