diff --git a/CMakeLists.txt b/CMakeLists.txt index c46151f3..cb4fcae7 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -41,7 +41,7 @@ find_package( MySQL ) add_subdirectory( "deps/zlib" ) add_subdirectory( "deps/MySQL" ) add_subdirectory( "deps/datReader" ) -#add_subdirectory( "deps/datReaderPs3" ) +add_subdirectory( "deps/datReaderPs3" ) add_subdirectory( "deps/mysqlConnector" ) add_subdirectory( "deps/recastnavigation" ) diff --git a/src/tools/CMakeLists.txt b/src/tools/CMakeLists.txt index f65c3f5e..f52bbe89 100644 --- a/src/tools/CMakeLists.txt +++ b/src/tools/CMakeLists.txt @@ -24,7 +24,7 @@ add_subdirectory( "discovery_parser" ) #add_subdirectory( "mob_parse" ) add_subdirectory( "pcb_reader" ) add_subdirectory( "nav_export" ) -#add_subdirectory( "BattleNpcParserPs3" ) +add_subdirectory( "BattleNpcParserPs3" ) #add_subdirectory( "event_object_parser" ) #add_subdirectory( "action_parse" ) #add_subdirectory( "questbattle_bruteforce" ) \ No newline at end of file diff --git a/src/world/Action/Action.cpp b/src/world/Action/Action.cpp index 7ade7aa1..bc2f7f9c 100644 --- a/src/world/Action/Action.cpp +++ b/src/world/Action/Action.cpp @@ -55,7 +55,8 @@ Action::Action::Action( Entity::CharaPtr caster, uint32_t actionId, uint16_t seq m_targetId( 0 ), m_startTime( 0 ), m_interruptType( Common::ActionInterruptType::None ), - m_sequence( sequence ) + m_sequence( sequence ), + m_actionKind( Common::SkillType::Normal ) { } @@ -288,7 +289,7 @@ void Action::Action::start() data.Action = static_cast< uint16_t >( m_id ); data.ActionKey = m_id; - data.ActionKind = Common::SkillType::Normal; + data.ActionKind = m_actionKind; data.CastTime = m_castTimeMs / 1000.f; data.Target = static_cast< uint32_t >( m_targetId ); @@ -313,7 +314,17 @@ void Action::Action::start() server.queueForPlayer( player->getCharacterId(), actionStartPkt ); + onStart(); + + // instantly finish cast if there's no cast time + if( !hasCastTime() ) + execute(); +} + +void Action::Action::onStart() +{ auto& scriptMgr = Common::Service< Scripting::ScriptMgr >::ref(); + auto player = m_pSource->getAsPlayer(); // check the lut too and see if we have something usable, otherwise cancel the cast if( !scriptMgr.onStart( *this ) && !ActionLut::validEntryExists( static_cast< uint16_t >( getId() ) ) ) @@ -330,9 +341,6 @@ void Action::Action::start() return; } - // instantly finish cast if there's no cast time - if( !hasCastTime() ) - execute(); } void Action::Action::interrupt() @@ -366,6 +374,12 @@ void Action::Action::interrupt() m_pSource->sendToInRangeSet( control, true ); } + onInterrupt(); + +} + +void Action::Action::onInterrupt() +{ auto& scriptMgr = Common::Service< Scripting::ScriptMgr >::ref(); scriptMgr.onInterrupt( *this ); } @@ -843,4 +857,14 @@ bool Action::Action::hasValidLutEntry() const Action::EffectBuilderPtr Action::Action::getEffectbuilder() { return m_effectBuilder; -} \ No newline at end of file +} + +uint8_t Action::Action::getActionKind() const +{ + return m_actionKind; +} + +void Action::Action::setActionKind( uint8_t actionKind ) +{ + m_actionKind = actionKind; +} diff --git a/src/world/Action/Action.h b/src/world/Action/Action.h index e93e493f..b9967d8e 100644 --- a/src/world/Action/Action.h +++ b/src/world/Action/Action.h @@ -46,6 +46,9 @@ namespace Sapphire::World::Action bool isComboAction() const; + uint8_t getActionKind() const; + void setActionKind( uint8_t actionKind ); + /*! * @brief Checks if a chara has enough resources available to cast the action (tp/mp/etc) * @return true if they have the required resources @@ -135,6 +138,9 @@ namespace Sapphire::World::Action */ virtual bool update(); + virtual void onInterrupt(); + virtual void onStart(); + protected: bool primaryCostCheck( bool subtractCosts ); @@ -147,6 +153,7 @@ namespace Sapphire::World::Action bool hasValidLutEntry() const; uint32_t m_id; + uint8_t m_actionKind; uint16_t m_sequence; diff --git a/src/world/Action/EventItemAction.cpp b/src/world/Action/EventItemAction.cpp index 276d5bda..a236b7cc 100644 --- a/src/world/Action/EventItemAction.cpp +++ b/src/world/Action/EventItemAction.cpp @@ -1,4 +1,4 @@ -#include "ItemAction.h" +#include "EventItemAction.h" #include #include @@ -7,69 +7,59 @@ #include #include "Manager/PlayerMgr.h" +#include +#include +#include +#include "Network/PacketWrappers/ActorControlPacket.h" +#include "Network/PacketWrappers/ActorControlSelfPacket.h" +#include "Network/PacketWrappers/ActorControlTargetPacket.h" +#include +#include + using namespace Sapphire; +using namespace Sapphire::Common; using namespace Sapphire::World::Action; +using namespace Sapphire::Network::Packets; +using namespace Sapphire::Network::Packets::WorldPackets; using namespace Sapphire::Network::Packets::WorldPackets::Server; +using namespace Sapphire::Network::ActorControl; -ItemAction::ItemAction( Sapphire::Entity::CharaPtr source, uint32_t itemId, - std::shared_ptr< Component::Excel::ExcelStruct< Component::Excel::ItemAction > > itemActionData, uint16_t itemSourceSlot, - uint16_t itemSourceContainer ) : - m_itemAction( std::move( itemActionData ) ), - m_itemSourceSlot( itemSourceSlot ), - m_itemSourceContainer( itemSourceContainer ) +EventItemAction::EventItemAction( Sapphire::Entity::CharaPtr source, uint32_t eventItemId, + std::shared_ptr< Component::Excel::ExcelStruct< Component::Excel::EventItem > > eventItemActionData, + uint32_t sequence, uint64_t targetId ) : + m_eventItemAction( std::move( eventItemActionData ) ) { - m_id = itemId; + m_id = eventItemId; + m_eventItem = eventItemId; m_pSource = std::move( source ); + m_sequence = sequence; + m_targetId = targetId; + m_interruptType = Common::ActionInterruptType::None; + m_actionKind = Common::SkillType::EventItem; } -void ItemAction::start() +bool EventItemAction::init() { - if( !m_pSource->isPlayer() ) - return; + auto& exdData = Common::Service< Data::ExdData >::ref(); + auto actionInfoPtr = exdData.getRow< Component::Excel::Action >( m_eventItemAction->data().Action ); - // todo: check inv slot for item - - // todo: can we just do this? - execute(); + m_castTimeMs = static_cast< uint32_t >( m_eventItemAction->data().CastTime * 1000 ); + m_recastTimeMs = static_cast< uint32_t >( actionInfoPtr->data().RecastTime * 100 ); + m_cooldownGroup = actionInfoPtr->data().RecastGroup; + m_id = m_eventItemAction->data().Action; + return true; } -void ItemAction::execute() +void EventItemAction::execute() { - switch( m_itemAction->data().Action ) - { - default: - { - Manager::PlayerMgr::sendDebug( *getSourceChara()->getAsPlayer(), "ItemAction type {0} not supported.", m_itemAction->data().Action ); - break; - } - - case Common::ItemActionType::ItemActionVFX: - case Common::ItemActionType::ItemActionVFX2: - { - handleVFXItem(); - - break; - } - } + Manager::PlayerMgr::sendDebug( *getSourceChara()->getAsPlayer(), "EventItemAction type {0} execute called.", m_eventItemAction->data().Action ); } -void ItemAction::interrupt() +void EventItemAction::onStart() { - } -void ItemAction::handleVFXItem() +void EventItemAction::onInterrupt() { - Common::CalcResultParam effect{}; - effect.Type = Common::ActionEffectType::CALC_RESULT_TYPE_CHECK_BARRIER; - effect.Value = m_itemAction->data().Calcu0Arg[ 0 ]; - - auto effectPacket = std::make_shared< EffectPacket >( getSourceChara()->getId(), getSourceChara()->getId(), getId() ); - effectPacket->setTargetActor( getSourceChara()->getId() ); - effectPacket->setAnimationId( Common::ItemActionType::ItemActionVFX ); - effectPacket->setDisplayType( Common::ActionEffectDisplayType::ShowItemName ); - effectPacket->addEffect( effect, static_cast< uint64_t >( getSourceChara()->getId() ) ); - - m_pSource->sendToInRangeSet( effectPacket, true ); -} \ No newline at end of file +} diff --git a/src/world/Action/EventItemAction.h b/src/world/Action/EventItemAction.h index a3b60faa..0cc1b457 100644 --- a/src/world/Action/EventItemAction.h +++ b/src/world/Action/EventItemAction.h @@ -11,26 +11,26 @@ namespace Sapphire::Data namespace Sapphire::World::Action { - class ItemAction : public Action + class EventItemAction : public Action { public: - ItemAction( Entity::CharaPtr source, uint32_t itemId, std::shared_ptr< Component::Excel::ExcelStruct< Component::Excel::ItemAction > > itemActionData, - uint16_t itemSourceSlot, uint16_t itemSourceContainer ); - virtual ~ItemAction() = default; + EventItemAction( Entity::CharaPtr source, uint32_t eventItemId, std::shared_ptr< Component::Excel::ExcelStruct< Component::Excel::EventItem > > itemActionData, + uint32_t sequence, uint64_t targetId ); - void start() override; + virtual ~EventItemAction() = default; + + bool init(); void execute() override; - void interrupt() override; + void onInterrupt() override; + + void onStart() override; + private: - void handleVFXItem(); - - private: - std::shared_ptr< Component::Excel::ExcelStruct< Component::Excel::ItemAction > > m_itemAction; - - uint16_t m_itemSourceSlot; - uint16_t m_itemSourceContainer; + std::shared_ptr< Component::Excel::ExcelStruct< Component::Excel::EventItem > > m_eventItemAction; + uint32_t m_eventItem; + uint32_t m_sequence; }; } \ No newline at end of file diff --git a/src/world/Action/MountAction.cpp b/src/world/Action/MountAction.cpp index 8682fe79..069425d9 100644 --- a/src/world/Action/MountAction.cpp +++ b/src/world/Action/MountAction.cpp @@ -25,6 +25,7 @@ MountAction::MountAction( Sapphire::Entity::CharaPtr source, uint16_t mountId, u Action::Action( source, 4, sequence, actionData ), m_mountId( mountId ) { + m_actionKind = Common::SkillType::MountSkill; } bool MountAction::preCheck() @@ -45,7 +46,7 @@ void MountAction::start() auto& data = castPacket->data(); data.Action = static_cast< uint16_t >( m_id ); - data.ActionKind = Common::SkillType::MountSkill; + data.ActionKind = m_actionKind; data.CastTime = m_castTimeMs / 1000.f; data.Target = static_cast< uint32_t >( m_targetId ); data.BallistaEntityId = 0xE0000000; diff --git a/src/world/ForwardsZone.h b/src/world/ForwardsZone.h index 3a97d2f9..311b3265 100644 --- a/src/world/ForwardsZone.h +++ b/src/world/ForwardsZone.h @@ -84,6 +84,7 @@ namespace World::Action TYPE_FORWARD( Action ); TYPE_FORWARD( EventAction ); TYPE_FORWARD( ItemAction ); +TYPE_FORWARD( EventItemAction ); TYPE_FORWARD( MountAction ); TYPE_FORWARD( EffectBuilder ); TYPE_FORWARD( EffectResult ); diff --git a/src/world/Manager/ActionMgr.cpp b/src/world/Manager/ActionMgr.cpp index bc56b039..6ece6cf4 100644 --- a/src/world/Manager/ActionMgr.cpp +++ b/src/world/Manager/ActionMgr.cpp @@ -3,6 +3,7 @@ #include "Action/Action.h" #include "Action/ItemAction.h" +#include "Action/EventItemAction.h" #include "Action/MountAction.h" #include "Script/ScriptMgr.h" #include "Actor/Player.h" @@ -73,6 +74,21 @@ void World::Manager::ActionMgr::handleItemAction( Sapphire::Entity::Player& play action->start(); } +void World::Manager::ActionMgr::handleEventItemAction( Sapphire::Entity::Player& player, uint32_t itemId, + std::shared_ptr< Component::Excel::ExcelStruct< Component::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 World::Manager::ActionMgr::handleMountAction( Entity::Player& player, uint16_t mountId, std::shared_ptr< Component::Excel::ExcelStruct< Component::Excel::Action > > actionData, uint64_t targetId, uint16_t sequence ) diff --git a/src/world/Manager/ActionMgr.h b/src/world/Manager/ActionMgr.h index fcf96cfa..5a440023 100644 --- a/src/world/Manager/ActionMgr.h +++ b/src/world/Manager/ActionMgr.h @@ -29,6 +29,9 @@ namespace Sapphire::World::Manager std::shared_ptr< Component::Excel::ExcelStruct< Component::Excel::ItemAction > > itemActionData, uint16_t itemSourceSlot, uint16_t itemSourceContainer ); + void handleEventItemAction( Entity::Player& player, uint32_t itemId, + std::shared_ptr< Component::Excel::ExcelStruct< Component::Excel::EventItem > > itemActionData, uint32_t sequence, uint64_t targetId ); + void handleMountAction( Entity::Player& player, uint16_t mountId, std::shared_ptr< Component::Excel::ExcelStruct< Component::Excel::Action > > actionData, uint64_t targetId, uint16_t sequence ); diff --git a/src/world/Network/Handlers/ActionHandler.cpp b/src/world/Network/Handlers/ActionHandler.cpp index 5cf4c3e9..4b0ad7b0 100644 --- a/src/world/Network/Handlers/ActionHandler.cpp +++ b/src/world/Network/Handlers/ActionHandler.cpp @@ -10,6 +10,7 @@ #include "Manager/ActionMgr.h" #include "Manager/PlayerMgr.h" +#include "Manager/EventMgr.h" using namespace Sapphire::Common; using namespace Sapphire::World::Manager; @@ -32,6 +33,7 @@ void Sapphire::Network::GameConnection::actionRequest( const Packets::FFXIVARR_P auto& exdData = Common::Service< Data::ExdData >::ref(); auto& actionMgr = Common::Service< World::Manager::ActionMgr >::ref(); + auto& eventMgr = Common::Service< World::Manager::EventMgr >::ref(); switch( type ) { @@ -69,6 +71,16 @@ void Sapphire::Network::GameConnection::actionRequest( const Packets::FFXIVARR_P break; } + case Common::SkillType::EventItem: + { + auto action = exdData.getRow< Component::Excel::EventItem >( actionId ); + assert( action ); + + actionMgr.handleEventItemAction( player, actionId, action, sequence, targetId ); + + break; + } + case Common::SkillType::MountSkill: { auto action = exdData.getRow< Component::Excel::Action >( 4 );