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

135 lines
4 KiB
C++
Raw Normal View History

#include "ActionMgr.h"
#include "Action/Action.h"
#include "Script/ScriptMgr.h"
#include "Actor/Player.h"
#include <Exd/ExdDataGenerated.h>
2019-02-09 18:02:11 +11:00
#include "Framework.h"
2019-02-09 21:48:42 +11:00
#include <Network/PacketWrappers/EffectPacket.h>
using namespace Sapphire;
World::Manager::ActionMgr::ActionMgr( Sapphire::FrameworkPtr pFw ) :
BaseManager( pFw )
{
}
2019-02-09 19:26:31 +11:00
void World::Manager::ActionMgr::handleAoEPlayerAction( Entity::Player& player, uint32_t actionId,
Data::ActionPtr actionData, Common::FFXIVARR_POSITION3 pos )
{
player.sendDebug( "got aoe act: {0}", actionData->name );
2019-02-09 18:02:11 +11:00
auto action = Action::make_Action( player.getAsPlayer(), actionId, actionData, framework() );
action->setPos( pos );
bootstrapAction( player, action, *actionData );
}
2019-02-09 19:26:31 +11:00
void World::Manager::ActionMgr::handleTargetedPlayerAction( Entity::Player& player, uint32_t actionId,
Data::ActionPtr actionData, uint64_t targetId )
{
player.sendDebug( "got act: {0}", actionData->name );
auto action = Action::make_Action( player.getAsPlayer(), actionId, actionData, framework() );
bootstrapAction( player, action, *actionData );
}
2019-02-09 21:48:42 +11:00
void World::Manager::ActionMgr::handleItemAction( Sapphire::Entity::Player& player, uint32_t itemId, Data::ItemActionPtr itemActionData )
2019-02-09 19:26:31 +11:00
{
2019-02-09 21:48:42 +11:00
player.sendDebug( "got item act: {0}", itemId );
switch( itemActionData->type )
{
default:
return;
case Common::ItemActionType::ItemActionVFX:
{
handleItemActionVFX( player, itemId, itemActionData->data[ 0 ] );
break;
}
}
2019-02-09 19:26:31 +11:00
}
void World::Manager::ActionMgr::bootstrapAction( Entity::Player& player,
Action::ActionPtr currentAction,
Data::Action& actionData )
{
if( !canPlayerUseAction( player, *currentAction, actionData ) )
return;
// instantly cast and finish actions that have no cast time
// not worth adding it to the player
// todo: what do in cases of swiftcast/etc? script callback?
if( !currentAction->isCastedAction() )
{
currentAction->start();
currentAction->onFinish();
return;
}
// otherwise, set the action on the player and start it
player.setCurrentAction( currentAction );
currentAction->start();
}
bool World::Manager::ActionMgr::canPlayerUseAction( Entity::Player& player,
Action::Action& currentAction,
Data::Action& actionData )
{
// lol
if( !player.isAlive() )
return false;
// npc actions/non player actions
if( actionData.classJob == -1 )
return false;
2019-02-09 18:02:11 +11:00
if( player.getLevel() < actionData.classJobLevel )
return false;
if( player.getClass() != static_cast< Common::ClassJob >( actionData.classJob ) )
{
// check if not a base class action
auto exdData = framework()->get< Data::ExdDataGenerated >();
assert( exdData );
auto classJob = exdData->get< Data::ClassJob >( static_cast< uint8_t >( player.getClass() ) );
if( !classJob )
return false;
if( classJob->classJobParent != actionData.classJob )
return false;
}
// todo: min tp
// todo: min mp
// todo: script callback for action conditionals?
return true;
2019-02-09 21:48:42 +11:00
}
void World::Manager::ActionMgr::handleItemActionVFX( Sapphire::Entity::Player& player, uint32_t itemId, uint16_t vfxId )
{
// todo: check we have item & remove item from inventory
Common::EffectEntry effect{};
effect.effectType = Common::ActionEffectType::VFX;
effect.value = vfxId;
auto effectPacket = std::make_shared< Network::Packets::Server::EffectPacket >( player.getId(), player.getId(), itemId );
effectPacket->setTargetActor( player.getId() );
effectPacket->setAnimationId( Common::ItemActionType::ItemActionVFX );
effectPacket->setDisplayType( Common::ActionEffectDisplayType::ShowItemName );
effectPacket->addEffect( effect );
player.sendToInRangeSet( effectPacket, true );
}