From 76172595a4ea82334a68fa7ad1c02d10a5c84ae8 Mon Sep 17 00:00:00 2001 From: NotAdam Date: Sun, 3 Feb 2019 19:38:04 +1100 Subject: [PATCH 01/63] fix SkillHandler packet size and add AoESkillHandler packet --- src/common/Network/PacketDef/Ipcs.h | 1 + .../Network/PacketDef/Zone/ClientZoneDef.h | 14 ++++++++++++++ src/world/Manager/ActionMgr.cpp | 9 +++++++++ src/world/Manager/ActionMgr.h | 18 ++++++++++++++++++ src/world/ServerMgr.cpp | 4 ++++ 5 files changed, 46 insertions(+) create mode 100644 src/world/Manager/ActionMgr.cpp create mode 100644 src/world/Manager/ActionMgr.h diff --git a/src/common/Network/PacketDef/Ipcs.h b/src/common/Network/PacketDef/Ipcs.h index afded198..1af7218b 100644 --- a/src/common/Network/PacketDef/Ipcs.h +++ b/src/common/Network/PacketDef/Ipcs.h @@ -304,6 +304,7 @@ namespace Sapphire::Network::Packets SkillHandler = 0x013B, // updated 4.5 GMCommand1 = 0x013C, // updated 4.5 GMCommand2 = 0x013D, // updated 4.5 + AoESkillHandler = 0x13E, // updated 4.5 UpdatePositionHandler = 0x013F, // updated 4.5 UpdatePositionInstance = 0x0183, // updated 4.3 diff --git a/src/common/Network/PacketDef/Zone/ClientZoneDef.h b/src/common/Network/PacketDef/Zone/ClientZoneDef.h index 663feb3c..a80d962f 100644 --- a/src/common/Network/PacketDef/Zone/ClientZoneDef.h +++ b/src/common/Network/PacketDef/Zone/ClientZoneDef.h @@ -70,6 +70,20 @@ struct FFXIVIpcSkillHandler : /* 0008 */ uint32_t useCount; /* 000C */ char pad_000C[4]; /* 0010 */ uint64_t targetId; + /* 0018 */ uint64_t unknown; +}; + +struct FFXIVIpcAoESkillHandler : + FFXIVIpcBasePacket< AoESkillHandler > +{ + /* 0000 */ char pad_0000[1]; + /* 0001 */ uint8_t type; + /* 0002 */ char pad_0002[2]; + /* 0004 */ uint32_t actionId; + /* 0008 */ uint16_t useCount; + /* 000A */ char pad_000C[6]; + /* 0010 */ Common::FFXIVARR_POSITION3 pos; + /* 001C */ uint32_t unknown; // could almost be rotation + 16 bits more padding? }; struct FFXIVIpcZoneLineHandler : diff --git a/src/world/Manager/ActionMgr.cpp b/src/world/Manager/ActionMgr.cpp new file mode 100644 index 00000000..e83c934f --- /dev/null +++ b/src/world/Manager/ActionMgr.cpp @@ -0,0 +1,9 @@ +#include "ActionMgr.h" + +using namespace Sapphire; + +World::Manager::ActionMgr::ActionMgr( Sapphire::FrameworkPtr pFw ) : + BaseManager( pFw ) +{ + +} \ No newline at end of file diff --git a/src/world/Manager/ActionMgr.h b/src/world/Manager/ActionMgr.h new file mode 100644 index 00000000..dffad0f3 --- /dev/null +++ b/src/world/Manager/ActionMgr.h @@ -0,0 +1,18 @@ +#ifndef SAPPHIRE_ACTIONMGR_H +#define SAPPHIRE_ACTIONMGR_H + +#include "BaseManager.h" + +namespace Sapphire::World::Manager +{ + class ActionMgr : public Manager::BaseManager + { + public: + explicit ActionMgr( FrameworkPtr pFw ); + ~ActionMgr() = default; + +// void handlePlayerCast( Entity::Player& player) + }; +} + +#endif //SAPPHIRE_ACTIONMGR_H diff --git a/src/world/ServerMgr.cpp b/src/world/ServerMgr.cpp index 7bbc28ec..1387fc12 100644 --- a/src/world/ServerMgr.cpp +++ b/src/world/ServerMgr.cpp @@ -42,6 +42,7 @@ #include "Manager/MarketMgr.h" #include "Manager/RNGMgr.h" #include "Manager/NaviMgr.h" +#include "Manager/ActionMgr.h" using namespace Sapphire::World::Manager; @@ -170,6 +171,9 @@ void Sapphire::World::ServerMgr::run( int32_t argc, char* argv[] ) } framework()->set< Scripting::ScriptMgr >( pScript ); + auto pActionMgr = std::make_shared< Manager::ActionMgr >( framework() ); + framework()->set< Manager::ActionMgr >( pActionMgr ); + loadBNpcTemplates(); auto pNaviMgr = std::make_shared< Manager::NaviMgr >( framework() ); From 497cc1f028bf5c36547272c06759c619967929e4 Mon Sep 17 00:00:00 2001 From: NotAdam Date: Sun, 3 Feb 2019 19:57:04 +1100 Subject: [PATCH 02/63] skeleton action handling inside actionmgr, packet fixes --- .../Network/PacketDef/Zone/ClientZoneDef.h | 6 +- src/world/Manager/ActionMgr.cpp | 12 ++ src/world/Manager/ActionMgr.h | 4 +- src/world/Network/GameConnection.cpp | 1 + src/world/Network/GameConnection.h | 2 + src/world/Network/Handlers/ActionHandler.cpp | 111 ++++-------------- 6 files changed, 44 insertions(+), 92 deletions(-) diff --git a/src/common/Network/PacketDef/Zone/ClientZoneDef.h b/src/common/Network/PacketDef/Zone/ClientZoneDef.h index a80d962f..6794399a 100644 --- a/src/common/Network/PacketDef/Zone/ClientZoneDef.h +++ b/src/common/Network/PacketDef/Zone/ClientZoneDef.h @@ -67,8 +67,8 @@ struct FFXIVIpcSkillHandler : /* 0001 */ uint8_t type; /* 0002 */ char pad_0002[2]; /* 0004 */ uint32_t actionId; - /* 0008 */ uint32_t useCount; - /* 000C */ char pad_000C[4]; + /* 0008 */ uint16_t sequence; + /* 000A */ char pad_000C[6]; /* 0010 */ uint64_t targetId; /* 0018 */ uint64_t unknown; }; @@ -80,7 +80,7 @@ struct FFXIVIpcAoESkillHandler : /* 0001 */ uint8_t type; /* 0002 */ char pad_0002[2]; /* 0004 */ uint32_t actionId; - /* 0008 */ uint16_t useCount; + /* 0008 */ uint16_t sequence; /* 000A */ char pad_000C[6]; /* 0010 */ Common::FFXIVARR_POSITION3 pos; /* 001C */ uint32_t unknown; // could almost be rotation + 16 bits more padding? diff --git a/src/world/Manager/ActionMgr.cpp b/src/world/Manager/ActionMgr.cpp index e83c934f..58c1dfb3 100644 --- a/src/world/Manager/ActionMgr.cpp +++ b/src/world/Manager/ActionMgr.cpp @@ -6,4 +6,16 @@ World::Manager::ActionMgr::ActionMgr( Sapphire::FrameworkPtr pFw ) : BaseManager( pFw ) { +} + +void World::Manager::ActionMgr::handleAoEPlayerAction( Entity::Player& player, uint8_t type, + uint32_t actionId, Common::FFXIVARR_POSITION3 pos ) +{ + +} + +void World::Manager::ActionMgr::handleTargetedPlayerAction( Entity::Player& player, uint8_t type, + uint32_t actionId, uint64_t targetId ) +{ + } \ No newline at end of file diff --git a/src/world/Manager/ActionMgr.h b/src/world/Manager/ActionMgr.h index dffad0f3..1745de04 100644 --- a/src/world/Manager/ActionMgr.h +++ b/src/world/Manager/ActionMgr.h @@ -2,6 +2,7 @@ #define SAPPHIRE_ACTIONMGR_H #include "BaseManager.h" +#include "ForwardsZone.h" namespace Sapphire::World::Manager { @@ -11,7 +12,8 @@ namespace Sapphire::World::Manager explicit ActionMgr( FrameworkPtr pFw ); ~ActionMgr() = default; -// void handlePlayerCast( Entity::Player& player) + void handleTargetedPlayerAction( Entity::Player& player, uint8_t type, uint32_t actionId, uint64_t targetId ); + void handleAoEPlayerAction( Entity::Player& player, uint8_t type, uint32_t actionId, Common::FFXIVARR_POSITION3 pos ); }; } diff --git a/src/world/Network/GameConnection.cpp b/src/world/Network/GameConnection.cpp index 006ee48b..a3c6fa87 100644 --- a/src/world/Network/GameConnection.cpp +++ b/src/world/Network/GameConnection.cpp @@ -73,6 +73,7 @@ Sapphire::Network::GameConnection::GameConnection( Sapphire::Network::HivePtr pH setZoneHandler( ClientZoneIpcType::DiscoveryHandler, "DiscoveryHandler", &GameConnection::discoveryHandler ); setZoneHandler( ClientZoneIpcType::SkillHandler, "ActionHandler", &GameConnection::actionHandler ); + setZoneHandler( ClientZoneIpcType::AoESkillHandler, "AoESkillHandler", &GameConnection::aoeActionHandler ); setZoneHandler( ClientZoneIpcType::GMCommand1, "GMCommand1", &GameConnection::gm1Handler ); setZoneHandler( ClientZoneIpcType::GMCommand2, "GMCommand2", &GameConnection::gm2Handler ); diff --git a/src/world/Network/GameConnection.h b/src/world/Network/GameConnection.h index 72c800b2..56e3f77f 100644 --- a/src/world/Network/GameConnection.h +++ b/src/world/Network/GameConnection.h @@ -155,6 +155,8 @@ namespace Sapphire::Network DECLARE_HANDLER( cfDutyAccepted ); DECLARE_HANDLER( actionHandler ); + + DECLARE_HANDLER( aoeActionHandler ); DECLARE_HANDLER( gm1Handler ); diff --git a/src/world/Network/Handlers/ActionHandler.cpp b/src/world/Network/Handlers/ActionHandler.cpp index 3ee00e6f..ffc73dc2 100644 --- a/src/world/Network/Handlers/ActionHandler.cpp +++ b/src/world/Network/Handlers/ActionHandler.cpp @@ -18,6 +18,7 @@ #include "Network/PacketWrappers/PlayerStateFlagsPacket.h" #include "Manager/DebugCommandMgr.h" +#include "Manager/ActionMgr.h" #include "Action/Action.h" #include "Action/ActionCast.h" @@ -41,95 +42,29 @@ void Sapphire::Network::GameConnection::actionHandler( FrameworkPtr pFw, const auto type = packet.data().type; const auto action = packet.data().actionId; - const auto useCount = packet.data().useCount; + const auto sequence = packet.data().sequence; const auto targetId = packet.data().targetId; - player.sendDebug( "Skill type: {0}", type ); - - auto pExdData = pFw->get< Data::ExdDataGenerated >(); - auto pScriptMgr = pFw->get< Scripting::ScriptMgr >(); - - switch( type ) - { - case Common::SkillType::Normal: - - if( action < 1000000 ) // normal action - { - std::string actionIdStr = Util::intToHexString( action, 4 ); - player.sendDebug( "---------------------------------------" ); - player.sendDebug( "ActionHandler ( {0} | {1} | {2} )", - actionIdStr, pExdData->get< Sapphire::Data::Action >( action )->name, targetId ); - - player.queuePacket( makeActorControl142( player.getId(), ActorControlType::ActionStart, 0x01, action ) ); - - if( action == 5 ) - { - auto currentAction = player.getCurrentAction(); - - // we should always have an action here, if not there is a bug - assert( currentAction ); - currentAction->onStart(); - } - else - { - Sapphire::Entity::ActorPtr targetActor = player.getAsPlayer(); - - if( targetId != player.getId() ) - { - targetActor = player.lookupTargetById( targetId ); - } - - // Check if we actually have an actor - if( !targetActor ) - { - // todo: interrupt a cast. - player.sendDebug( "Invalid target." ); - return; - } - - if( !player.actionHasCastTime( action ) ) - { - pScriptMgr->onCastFinish( player, targetActor->getAsChara(), action ); - } - else - { - auto pActionCast = Action::make_ActionCast( player.getAsPlayer(), targetActor->getAsChara(), action, m_pFw ); - player.setCurrentAction( pActionCast ); - player.sendDebug( "setCurrentAction()" ); - player.getCurrentAction()->onStart(); - } - } - } - else if( action < 2000000 ) // craft action - { - - } - else if( action < 3000000 ) // item action - { - auto info = pExdData->get< Sapphire::Data::EventItem >( action ); - if( info ) - { - pScriptMgr->onEventItem( player, action, info->quest, info->castTime, targetId ); - } - } - else if( action > 3000000 ) // unknown - { - - } - - break; - - case Common::SkillType::MountSkill: - - player.sendDebug( "Request mount {0}", action ); - - auto pActionMount = Action::make_ActionMount( player.getAsPlayer(), action ); - player.setCurrentAction( pActionMount ); - player.sendDebug( "setCurrentAction()" ); - player.getCurrentAction()->onStart(); - - break; - - } + player.sendDebug( "Skill type: {0}, sequence: {1}, actionId: {2}, targetId: {3}", type, sequence, action, targetId ); + auto actionMgr = pFw->get< World::Manager::ActionMgr >(); + actionMgr->handleTargetedPlayerAction( player, type, action, targetId ); +} + +void Sapphire::Network::GameConnection::aoeActionHandler( FrameworkPtr pFw, + const Packets::FFXIVARR_PACKET_RAW& inPacket, + Entity::Player& player ) +{ + const auto packet = ZoneChannelPacket< Client::FFXIVIpcAoESkillHandler >( inPacket ); + + const auto type = packet.data().type; + const auto action = packet.data().actionId; + const auto sequence = packet.data().sequence; + const auto pos = packet.data().pos; + + auto actionMgr = pFw->get< World::Manager::ActionMgr >(); + actionMgr->handleAoEPlayerAction( player, type, action, pos ); + + player.sendDebug( "Skill type: {0}, sequence: {1}, actionId: {2}\nx:{3}, y:{4}, z:{5}", + type, sequence, action, pos.x, pos.y, pos.z ); } From 259c69c3cabbe771d38a485de009c74a69cb0765 Mon Sep 17 00:00:00 2001 From: NotAdam Date: Fri, 8 Feb 2019 21:18:01 +1100 Subject: [PATCH 03/63] remove most code related to the old action implementation --- src/world/Action/ActionCollision.cpp | 143 ------------------ src/world/Action/ActionCollision.h | 46 ------ src/world/Action/ActionMount.cpp | 107 ------------- src/world/Action/ActionMount.h | 31 ---- src/world/Action/ActionTeleport.cpp | 105 ------------- src/world/Action/ActionTeleport.h | 33 ---- src/world/Action/EventAction.cpp | 138 ----------------- src/world/Action/EventAction.h | 40 ----- src/world/Action/EventItemAction.cpp | 115 -------------- src/world/Action/EventItemAction.h | 38 ----- src/world/Actor/Actor.cpp | 3 - src/world/Actor/BNpc.cpp | 1 - src/world/Actor/Chara.cpp | 142 +---------------- src/world/Actor/Chara.h | 3 - src/world/Actor/Npc.cpp | 2 - src/world/Actor/Player.cpp | 61 ++++---- src/world/Actor/PlayerEvent.cpp | 57 ++++--- src/world/Network/Handlers/ActionHandler.cpp | 2 - .../Network/Handlers/ClientTriggerHandler.cpp | 1 - src/world/Network/Handlers/PacketHandlers.cpp | 1 - 20 files changed, 56 insertions(+), 1013 deletions(-) delete mode 100644 src/world/Action/ActionCollision.cpp delete mode 100644 src/world/Action/ActionCollision.h delete mode 100644 src/world/Action/ActionMount.cpp delete mode 100644 src/world/Action/ActionMount.h delete mode 100644 src/world/Action/ActionTeleport.cpp delete mode 100644 src/world/Action/ActionTeleport.h delete mode 100644 src/world/Action/EventAction.cpp delete mode 100644 src/world/Action/EventAction.h delete mode 100644 src/world/Action/EventItemAction.cpp delete mode 100644 src/world/Action/EventItemAction.h diff --git a/src/world/Action/ActionCollision.cpp b/src/world/Action/ActionCollision.cpp deleted file mode 100644 index 12b4e815..00000000 --- a/src/world/Action/ActionCollision.cpp +++ /dev/null @@ -1,143 +0,0 @@ -#include -#include - -#include - -#include "ActionCollision.h" -#include "Actor/Actor.h" -#include "Actor/Chara.h" -#include "Actor/Player.h" - -#include -#include - -using namespace Sapphire::Entity; -using namespace Sapphire::Common; - -// todo: add AoE actor limits (16, 32) - -bool ActionCollision::isActorApplicable( Actor& actor, TargetFilter targetFilter ) -{ - bool actorApplicable = false; - switch( targetFilter ) - { - case TargetFilter::All: - { - actorApplicable = true; - break; - } - case TargetFilter::Players: - { - actorApplicable = actor.isPlayer(); - break; - } - case TargetFilter::Allies: - { - // todo: implement ally NPCs - // actorApplicable = !chara.isBattleNpc(); - break; - } - case TargetFilter::Party: - { - // todo: implement party - actorApplicable = actor.isPlayer(); - break; - } - case TargetFilter::Enemies: - { - //actorApplicable = chara.isBattleNpc(); - break; - } - } - - return ( actorApplicable && actor.getAsChara()->isAlive() ); -} - -std::set< Sapphire::Entity::ActorPtr > ActionCollision::getActorsHitFromAction( FFXIVARR_POSITION3 aoePosition, - std::set< ActorPtr > actorsInRange, - std::shared_ptr< Sapphire::Data::Action > actionInfo, - TargetFilter targetFilter ) -{ - std::set< ActorPtr > actorsCollided; - - switch( static_cast< ActionCollisionType >( actionInfo->castType ) ) - { - case ActionCollisionType::None: - case ActionCollisionType::SingleTarget: - { - // This is actually needed. There is "splash damage" in actions marked as single target. - // Notice how we're using aoe_width. How collision works for SingleTarget is unknown as of now. - for( auto pActor : actorsInRange ) - { - // Make sure actor exists. If it doesn't we done goofed. - assert( pActor ); - - // Don't bother wasting on collision if actor doesn't apply for it - if( !isActorApplicable( *pActor, targetFilter ) ) - continue; - - // Test our collision from actor with the area generated by the action from the AoE data - if( radiusCollision( pActor->getPos(), aoePosition, actionInfo->effectRange ) ) - { - // Add it to the actors collided with the area - actorsCollided.insert( pActor ); - } - } - break; - } - case ActionCollisionType::Circle: - { - for( auto pActor : actorsInRange ) - { - assert( pActor ); - - if( !isActorApplicable( *pActor, targetFilter ) ) - continue; - - if( radiusCollision( pActor->getPos(), aoePosition, actionInfo->effectRange ) ) - actorsCollided.insert( pActor ); - } - break; - } - case ActionCollisionType::Box: - { - for( auto pActor : actorsInRange ) - { - assert( pActor ); - - if( !isActorApplicable( *pActor, targetFilter ) ) - continue; - - if( boxCollision( pActor->getPos(), aoePosition, actionInfo->xAxisModifier, actionInfo->effectRange ) ) - { - // todo: does this actually work? - - actorsCollided.insert( pActor ); - } - } - break; - } - default: - { - break; - } - } - - return actorsCollided; -} - -bool -ActionCollision::radiusCollision( FFXIVARR_POSITION3 actorPosition, FFXIVARR_POSITION3 aoePosition, uint16_t radius ) -{ - return Sapphire::Util::distance( actorPosition.x, actorPosition.y, actorPosition.z, - aoePosition.x, aoePosition.y, aoePosition.z ) <= radius; -} - -bool ActionCollision::boxCollision( FFXIVARR_POSITION3 actorPosition, FFXIVARR_POSITION3 aoePosition, uint16_t width, - uint16_t height ) -{ - return actorPosition.x < aoePosition.x + width && - actorPosition.x > aoePosition.x && - actorPosition.y < aoePosition.y + height && - actorPosition.y > aoePosition.y; -} diff --git a/src/world/Action/ActionCollision.h b/src/world/Action/ActionCollision.h deleted file mode 100644 index 9c9f5e18..00000000 --- a/src/world/Action/ActionCollision.h +++ /dev/null @@ -1,46 +0,0 @@ -#ifndef _ACTIONCOLLISION_H -#define _ACTIONCOLLISION_H - -#include -#include "ForwardsZone.h" - -namespace Sapphire::Data -{ - struct Action; -} - -namespace Sapphire::Entity -{ - - enum class TargetFilter - { - All, // All actors in the AoE are applicable for collision - Players, // Only players - Allies, // Only allies (players, ally NPCs) - Party, // Only party members - Enemies // Only enemies - }; - - class ActionCollision - { - public: - - static bool isActorApplicable( Actor& actor, TargetFilter targetFilter ); - - static std::set< ActorPtr > getActorsHitFromAction( Common::FFXIVARR_POSITION3 aoePosition, - std::set< ActorPtr > actorsInRange, - std::shared_ptr< Data::Action > actionInfo, - TargetFilter targetFilter ); - - private: - static bool radiusCollision( Common::FFXIVARR_POSITION3 actorPosition, Common::FFXIVARR_POSITION3 aoePosition, - uint16_t radius ); - - static bool boxCollision( Common::FFXIVARR_POSITION3 actorPosition, Common::FFXIVARR_POSITION3 aoePosition, - uint16_t width, uint16_t height ); - - }; - -} - -#endif diff --git a/src/world/Action/ActionMount.cpp b/src/world/Action/ActionMount.cpp deleted file mode 100644 index 917b54d8..00000000 --- a/src/world/Action/ActionMount.cpp +++ /dev/null @@ -1,107 +0,0 @@ -#include -#include -#include -#include -#include - -#include "Network/PacketWrappers/ActorControlPacket142.h" -#include "Network/PacketWrappers/ActorControlPacket143.h" -#include "Network/PacketWrappers/ActorControlPacket144.h" -#include "Network/PacketWrappers/EffectPacket.h" - -#include "Actor/Player.h" -#include "Script/ScriptMgr.h" - -#include "ActionMount.h" -#include "Framework.h" - -using namespace Sapphire::Common; -using namespace Sapphire::Network; -using namespace Sapphire::Network::Packets; -using namespace Sapphire::Network::Packets::Server; -using namespace Sapphire::Network::ActorControl; - -extern Sapphire::Framework g_framework; - -Sapphire::Action::ActionMount::ActionMount() -{ - m_handleActionType = HandleActionType::Event; -} - -Sapphire::Action::ActionMount::ActionMount( Entity::CharaPtr pActor, uint16_t mountId ) -{ - m_startTime = 0; - m_id = mountId; - m_handleActionType = HandleActionType::Spell; - m_castTime = 1000; - m_pSource = pActor; - m_bInterrupt = false; -} - -Sapphire::Action::ActionMount::~ActionMount() -{ - -} - -void Sapphire::Action::ActionMount::onStart() -{ - if( !m_pSource ) - return; - - m_pSource->getAsPlayer()->sendDebug( "ActionMount::onStart()" ); - m_startTime = Util::getTimeMs(); - - auto castPacket = makeZonePacket< FFXIVIpcActorCast >( getId() ); - castPacket->data().action_id = m_id; - castPacket->data().skillType = Common::SkillType::MountSkill; - castPacket->data().unknown_1 = m_id; - // This is used for the cast bar above the target bar of the caster. - castPacket->data().cast_time = static_cast< float >( m_castTime / 1000 ); - castPacket->data().target_id = m_pSource->getAsPlayer()->getId(); - - m_pSource->sendToInRangeSet( castPacket, true ); - m_pSource->getAsPlayer()->setStateFlag( PlayerStateFlag::Casting ); - -} - -void Sapphire::Action::ActionMount::onFinish() -{ - if( !m_pSource ) - return; - - auto pPlayer = m_pSource->getAsPlayer(); - pPlayer->sendDebug( "ActionMount::onFinish()" ); - - pPlayer->unsetStateFlag( PlayerStateFlag::Casting ); - - auto effectPacket = std::make_shared< Server::EffectPacket >( getId(), pPlayer->getId(), 4 ); - effectPacket->setRotation( Util::floatToUInt16Rot( pPlayer->getRot() ) ); - - Server::EffectEntry effectEntry{}; - effectEntry.effectType = ActionEffectType::Mount; - effectEntry.hitSeverity = ActionHitSeverityType::CritDamage; - effectEntry.value = m_id; - - effectPacket->addEffect( effectEntry ); - - pPlayer->sendToInRangeSet( effectPacket, true ); - - pPlayer->mount( m_id ); -} - -void Sapphire::Action::ActionMount::onInterrupt() -{ - if( !m_pSource ) - return; - - //m_pSource->getAsPlayer()->unsetStateFlag( PlayerStateFlag::Occupied1 ); - m_pSource->getAsPlayer()->unsetStateFlag( PlayerStateFlag::Casting ); - - auto control = makeActorControl142( m_pSource->getId(), ActorControlType::CastInterrupt, 0x219, 1, m_id, 0 ); - - // Note: When cast interrupt from taking too much damage, set the last value to 1. This enables the cast interrupt effect. Example: - // auto control = ActorControlPacket142( m_pSource->getId(), ActorControlType::CastInterrupt, 0x219, 1, m_id, 0 ); - - m_pSource->sendToInRangeSet( control, true ); - -} diff --git a/src/world/Action/ActionMount.h b/src/world/Action/ActionMount.h deleted file mode 100644 index 3fbcb96e..00000000 --- a/src/world/Action/ActionMount.h +++ /dev/null @@ -1,31 +0,0 @@ -#ifndef _ACTIONMOUNT_H_ -#define _ACTIONMOUNT_H_ - -#include "ForwardsZone.h" -#include "Action.h" - -namespace Sapphire::Action -{ - - class ActionMount : public Action - { - private: - - public: - ActionMount(); - - ~ActionMount(); - - ActionMount( Entity::CharaPtr pActor, uint16_t mountId ); - - void onStart() override; - - void onFinish() override; - - void onInterrupt() override; - - }; - -} - -#endif diff --git a/src/world/Action/ActionTeleport.cpp b/src/world/Action/ActionTeleport.cpp deleted file mode 100644 index 6023a1a7..00000000 --- a/src/world/Action/ActionTeleport.cpp +++ /dev/null @@ -1,105 +0,0 @@ -#include -#include -#include -#include -#include - -#include "Network/PacketWrappers/ActorControlPacket142.h" -#include "Network/PacketWrappers/ActorControlPacket143.h" -#include "Network/PacketWrappers/EffectPacket.h" - -#include "Actor/Player.h" - -#include "ActionTeleport.h" -#include "Framework.h" - -using namespace Sapphire::Common; -using namespace Sapphire::Network; -using namespace Sapphire::Network::Packets; -using namespace Sapphire::Network::Packets::Server; -using namespace Sapphire::Network::ActorControl; - -Sapphire::Action::ActionTeleport::ActionTeleport() -{ - m_handleActionType = HandleActionType::Event; -} - -Sapphire::Action::ActionTeleport::ActionTeleport( Entity::CharaPtr pActor, uint16_t targetZone, uint16_t cost, FrameworkPtr pFw ) -{ - auto pExdData = pFw->get< Data::ExdDataGenerated >(); - m_startTime = 0; - m_id = 5; - m_handleActionType = HandleActionType::Teleport; - m_castTime = pExdData->get< Sapphire::Data::Action >( 5 )->cast100ms * 100; // TODO: Add security checks. - m_pSource = pActor; - m_bInterrupt = false; - m_targetAetheryte = targetZone; - m_cost = cost; -} - -Sapphire::Action::ActionTeleport::~ActionTeleport() -{ - -} - -void Sapphire::Action::ActionTeleport::onStart() -{ - if( !m_pSource ) - return; - - m_startTime = Util::getTimeMs(); - - auto castPacket = makeZonePacket< FFXIVIpcActorCast >( getId() ); - castPacket->data().action_id = 5; - castPacket->data().unknown = 1; - castPacket->data().cast_time = 5.0f; - castPacket->data().target_id = m_pSource->getId(); - - m_pSource->sendToInRangeSet( castPacket, true ); - m_pSource->getAsPlayer()->setStateFlag( PlayerStateFlag::Casting ); - -} - -void Sapphire::Action::ActionTeleport::onFinish() -{ - if( !m_pSource ) - return; - - auto pPlayer = m_pSource->getAsPlayer(); - - // check we can finish teleporting - if( pPlayer->getCurrency( Common::CurrencyType::Gil ) < m_cost ) - { - onInterrupt(); - return; - } - - pPlayer->removeCurrency( Common::CurrencyType::Gil, m_cost ); - - pPlayer->unsetStateFlag( PlayerStateFlag::Casting ); - - // TODO: not sure if this ever gets sent - //auto control = makeActorControl142( m_pSource->getId(), Common::ActorControlType::TeleportDone ); - //m_pSource->sendToInRangeSet( control, false ); - - pPlayer->setZoningType( ZoneingType::Teleport ); - - auto effectPacket = std::make_shared< Server::EffectPacket >( getId(), pPlayer->getId(), 5 ); - effectPacket->setRotation( Util::floatToUInt16Rot( pPlayer->getRot() ) ); - - - pPlayer->sendToInRangeSet( effectPacket, true ); - pPlayer->teleport( m_targetAetheryte ); -} - -void Sapphire::Action::ActionTeleport::onInterrupt() -{ - if( !m_pSource ) - return; - - m_pSource->getAsPlayer()->unsetStateFlag( PlayerStateFlag::Casting ); - - auto control = makeActorControl142( m_pSource->getId(), ActorControlType::CastInterrupt, 0x219, 0x04, m_id, 0 ); - m_pSource->sendToInRangeSet( control, true ); - -} diff --git a/src/world/Action/ActionTeleport.h b/src/world/Action/ActionTeleport.h deleted file mode 100644 index 088fa8b0..00000000 --- a/src/world/Action/ActionTeleport.h +++ /dev/null @@ -1,33 +0,0 @@ -#ifndef _ACTIONTELEPORT_H_ -#define _ACTIONTELEPORT_H_ - -#include "ForwardsZone.h" -#include "Action.h" - -namespace Sapphire::Action -{ - - class ActionTeleport : public Action - { - private: - uint16_t m_targetAetheryte; - uint16_t m_cost; - - public: - ActionTeleport(); - - ~ActionTeleport(); - - ActionTeleport( Entity::CharaPtr pActor, uint16_t action, uint16_t cost, FrameworkPtr pFw ); - - void onStart() override; - - void onFinish() override; - - void onInterrupt() override; - - }; - -} - -#endif diff --git a/src/world/Action/EventAction.cpp b/src/world/Action/EventAction.cpp deleted file mode 100644 index 8e5c362d..00000000 --- a/src/world/Action/EventAction.cpp +++ /dev/null @@ -1,138 +0,0 @@ -#include -#include -#include -#include - -#include "Network/PacketWrappers/ActorControlPacket142.h" -#include "Network/PacketWrappers/ActorControlPacket143.h" - -#include "Actor/Player.h" - -#include "EventAction.h" -#include "Framework.h" - -using namespace Sapphire::Common; -using namespace Sapphire::Network; -using namespace Sapphire::Network::Packets; -using namespace Sapphire::Network::Packets::Server; -using namespace Sapphire::Network::ActorControl; - -Sapphire::Action::EventAction::EventAction() -{ - m_handleActionType = HandleActionType::Event; -} - -Sapphire::Action::EventAction::EventAction( Entity::CharaPtr pActor, uint32_t eventId, uint16_t action, - ActionCallback finishRef, ActionCallback interruptRef, uint64_t additional, - FrameworkPtr pFw ) -{ - m_additional = additional; - m_handleActionType = HandleActionType::Event; - m_eventId = eventId; - m_id = action; - m_pFw = pFw; - auto pExdData = pFw->get< Data::ExdDataGenerated >(); - m_castTime = pExdData->get< Sapphire::Data::EventAction >( action )->castTime * 1000; // TODO: Add security checks. - m_onActionFinishClb = finishRef; - m_onActionInterruptClb = interruptRef; - m_pSource = pActor; - m_bInterrupt = false; -} - -Sapphire::Action::EventAction::~EventAction() -{ - -} - -void Sapphire::Action::EventAction::onStart() -{ - if( !m_pSource ) - return; - - m_startTime = Util::getTimeMs(); - - auto control = makeActorControl142( m_pSource->getId(), ActorControlType::CastStart, 1, m_id, 0x4000004E ); - - if( m_pSource->isPlayer() ) - { - m_pSource->sendToInRangeSet( control, true ); - if( m_pSource->getAsPlayer()->hasStateFlag( PlayerStateFlag::InNpcEvent ) ) - m_pSource->getAsPlayer()->unsetStateFlag( PlayerStateFlag::InNpcEvent ); - } - else - m_pSource->sendToInRangeSet( control ); -} - -void Sapphire::Action::EventAction::onFinish() -{ - if( !m_pSource ) - return; - - try - { - auto pEvent = m_pSource->getAsPlayer()->getEvent( m_eventId ); - - pEvent->setPlayedScene( false ); - - if( m_onActionFinishClb ) - m_onActionFinishClb( *m_pSource->getAsPlayer(), m_eventId, m_additional ); - - auto control = makeActorControl142( m_pSource->getId(), ActorControlType::CastStart, 0, m_id ); - - if( !pEvent->hasPlayedScene() ) - m_pSource->getAsPlayer()->eventFinish( m_eventId, 1 ); - else - pEvent->setPlayedScene( false ); - - if( m_pSource->isPlayer() ) - { - //m_pSource->getAsPlayer()->unsetStateFlag( PlayerStateFlag::Occupied2 ); - m_pSource->sendToInRangeSet( control, true ); - } - else - m_pSource->sendToInRangeSet( control ); - } - catch( std::exception& e ) - { - Logger::error( e.what() ); - } - -} - -void Sapphire::Action::EventAction::onInterrupt() -{ - if( !m_pSource ) - return; - - try - { - - auto control = makeActorControl142( m_pSource->getId(), ActorControlType::CastInterrupt, 0x219, 0x04, m_id ); - - if( m_pSource->isPlayer() ) - { - auto control1 = makeActorControl143( m_pSource->getId(), ActorControlType::FreeEventPos, m_eventId ); - - //m_pSource->getAsPlayer()->unsetStateFlag( PlayerStateFlag::NoCombat ); - //m_pSource->getAsPlayer()->unsetStateFlag( PlayerStateFlag::Occupied1 ); - m_pSource->sendToInRangeSet( control ); - m_pSource->sendToInRangeSet( control1 ); - - m_pSource->getAsPlayer()->queuePacket( control1 ); - m_pSource->getAsPlayer()->queuePacket( control ); - m_pSource->getAsPlayer()->eventFinish( m_eventId, 1 ); - - } - else - m_pSource->sendToInRangeSet( control ); - - if( m_onActionInterruptClb ) - m_onActionInterruptClb( *m_pSource->getAsPlayer(), m_eventId, m_additional ); - - } - catch( std::exception& e ) - { - Logger::error( e.what() ); - } - -} diff --git a/src/world/Action/EventAction.h b/src/world/Action/EventAction.h deleted file mode 100644 index 68d981da..00000000 --- a/src/world/Action/EventAction.h +++ /dev/null @@ -1,40 +0,0 @@ -#ifndef _EVENTACTION_H_ -#define _EVENTACTION_H_ - -#include - -#include "ForwardsZone.h" -#include "Action.h" - -namespace Sapphire::Action -{ - - class EventAction : public Action - { - - public: - EventAction(); - - ~EventAction(); - - EventAction( Entity::CharaPtr pActor, uint32_t eventId, uint16_t action, - ActionCallback finishRef, ActionCallback interruptRef, uint64_t additional, FrameworkPtr pFw ); - - void onStart() override; - - void onFinish() override; - - void onInterrupt() override; - - private: - uint32_t m_eventId; - uint64_t m_additional; - - ActionCallback m_onActionFinishClb; - ActionCallback m_onActionInterruptClb; - - }; - -} - -#endif diff --git a/src/world/Action/EventItemAction.cpp b/src/world/Action/EventItemAction.cpp deleted file mode 100644 index 13316c44..00000000 --- a/src/world/Action/EventItemAction.cpp +++ /dev/null @@ -1,115 +0,0 @@ -#include - -#include -#include -#include -#include - -#include "Network/PacketWrappers/ActorControlPacket142.h" -#include "Network/PacketWrappers/ActorControlPacket143.h" -#include "Network/PacketWrappers/EffectPacket.h" - -#include "Actor/Player.h" - -#include "EventItemAction.h" -#include "Framework.h" - -using namespace Sapphire::Common; -using namespace Sapphire::Network; -using namespace Sapphire::Network::Packets; -using namespace Sapphire::Network::Packets::Server; -using namespace Sapphire::Network::ActorControl; - -Sapphire::Action::EventItemAction::EventItemAction() -{ - m_handleActionType = HandleActionType::Event; -} - -Sapphire::Action::EventItemAction::EventItemAction( Entity::CharaPtr pActor, uint32_t eventId, uint16_t action, - ActionCallback finishRef, ActionCallback interruptRef, - uint64_t additional ) -{ - m_additional = additional; - m_handleActionType = HandleActionType::Event; - m_eventId = eventId; - m_id = action; - // TODO: read the cast time from the action itself - m_castTime = 3000; - m_onActionFinishClb = finishRef; - m_onActionInterruptClb = interruptRef; - m_pSource = pActor; - m_bInterrupt = false; -} - -Sapphire::Action::EventItemAction::~EventItemAction() = default; - -void Sapphire::Action::EventItemAction::onStart() -{ - if( !m_pSource ) - return; - - m_startTime = Util::getTimeMs(); - - auto castPacket = makeZonePacket< FFXIVIpcActorCast >( m_pSource->getId() ); - castPacket->data().action_id = 1; - castPacket->data().unknown = 3; - castPacket->data().unknown_1 = m_id; - castPacket->data().cast_time = 3.0f; - castPacket->data().target_id = m_pSource->getId(); - - m_pSource->sendToInRangeSet( castPacket, true ); - m_pSource->getAsPlayer()->setStateFlag( PlayerStateFlag::Casting ); - -} - -void Sapphire::Action::EventItemAction::onFinish() -{ - if( !m_pSource ) - return; - - try - { - auto effectPacket = std::make_shared< Server::EffectPacket >( m_pSource->getId(), m_additional, m_id ); - effectPacket->setAnimationId( 1 ); - effectPacket->setRotation( Util::floatToUInt16Rot( m_pSource->getRot() ) ); - - m_pSource->getAsPlayer()->unsetStateFlag( Common::PlayerStateFlag::Casting ); - m_pSource->sendToInRangeSet( effectPacket, true ); - - if( m_onActionFinishClb ) - m_onActionFinishClb( *m_pSource->getAsPlayer(), m_eventId, m_additional ); - } - catch( std::exception& e ) - { - Logger::error( e.what() ); - } - -} - -void Sapphire::Action::EventItemAction::onInterrupt() -{ - if( !m_pSource ) - return; - - try - { - - auto control = makeActorControl142( m_pSource->getId(), ActorControlType::CastInterrupt, 0x219, 0x04, m_id ); - if( m_pSource->isPlayer() ) - { - m_pSource->getAsPlayer()->unsetStateFlag( PlayerStateFlag::Casting ); - m_pSource->sendToInRangeSet( control, true ); - } - else - m_pSource->sendToInRangeSet( control ); - - if( m_onActionInterruptClb ) - m_onActionInterruptClb( *m_pSource->getAsPlayer(), m_eventId, m_additional ); - - } - catch( std::exception& e ) - { - Logger::error( e.what() ); - } - -} diff --git a/src/world/Action/EventItemAction.h b/src/world/Action/EventItemAction.h deleted file mode 100644 index 323a41f2..00000000 --- a/src/world/Action/EventItemAction.h +++ /dev/null @@ -1,38 +0,0 @@ -#ifndef _EVENTITEMACTION_H_ -#define _EVENTITEMACTION_H_ - -#include "ForwardsZone.h" -#include "Action.h" - -namespace Sapphire::Action -{ - - class EventItemAction : public Action - { - - public: - EventItemAction(); - - ~EventItemAction(); - - EventItemAction( Entity::CharaPtr pActor, uint32_t eventId, uint16_t action, - ActionCallback finishRef, ActionCallback interruptRef, uint64_t additional ); - - void onStart() override; - - void onFinish() override; - - void onInterrupt() override; - - private: - uint32_t m_eventId; - uint64_t m_additional; - - ActionCallback m_onActionFinishClb; - ActionCallback m_onActionInterruptClb; - - }; - -} - -#endif diff --git a/src/world/Actor/Actor.cpp b/src/world/Actor/Actor.cpp index fa3d3124..7a314bd6 100644 --- a/src/world/Actor/Actor.cpp +++ b/src/world/Actor/Actor.cpp @@ -6,9 +6,6 @@ #include #include -#include "Action/Action.h" -#include "Action/ActionCollision.h" - #include "Territory/Zone.h" #include "Network/GameConnection.h" diff --git a/src/world/Actor/BNpc.cpp b/src/world/Actor/BNpc.cpp index 9cdc8a6e..a7c6d6cd 100644 --- a/src/world/Actor/BNpc.cpp +++ b/src/world/Actor/BNpc.cpp @@ -23,7 +23,6 @@ #include "Navi/NaviProvider.h" #include "StatusEffect/StatusEffect.h" -#include "Action/ActionCollision.h" #include "ServerMgr.h" #include "Session.h" #include "Math/CalcBattle.h" diff --git a/src/world/Actor/Chara.cpp b/src/world/Actor/Chara.cpp index 8002db79..76695bec 100644 --- a/src/world/Actor/Chara.cpp +++ b/src/world/Actor/Chara.cpp @@ -7,7 +7,6 @@ #include "Forwards.h" -#include "Action/Action.h" #include "Territory/Zone.h" @@ -19,7 +18,7 @@ #include "Network/PacketWrappers/EffectPacket.h" #include "StatusEffect/StatusEffect.h" -#include "Action/ActionCollision.h" +#include "Action/Action.h" #include "ServerMgr.h" #include "Session.h" #include "Math/CalcBattle.h" @@ -431,145 +430,6 @@ void Sapphire::Entity::Chara::autoAttack( CharaPtr pTarget ) } } -/*! -Skill Handler. - -\param GamePacketPtr to send -\param bool should be send to self? -*/ -void Sapphire::Entity::Chara::handleScriptSkill( uint32_t type, uint16_t actionId, uint64_t param1, - uint64_t param2, Entity::Chara& target ) -{ - auto pExdData = m_pFw->get< Data::ExdDataGenerated >(); - if( isPlayer() ) - { - getAsPlayer()->sendDebug( "{0}", target.getId() ); - getAsPlayer()->sendDebug( "Handle script skill type: {0}", type ); - } - - auto actionInfoPtr = pExdData->get< Sapphire::Data::Action >( actionId ); - - // Todo: Effect packet generator. 90% of this is basically setting params and it's basically unreadable. - // Prepare packet. This is seemingly common for all packets in the action handler. - - auto effectPacket = std::make_shared< Server::EffectPacket >( getId(), target.getId(), actionId ); - effectPacket->setRotation( Util::floatToUInt16Rot( getRot() ) ); - - // Todo: for each actor, calculate how much damage the calculated value should deal to them - 2-step damage calc. we only have 1-step - switch( type ) - { - - case ActionEffectType::Damage: - { - Server::EffectEntry effectEntry{}; - effectEntry.value = static_cast< uint16_t >( param1 ); - effectEntry.effectType = ActionEffectType::Damage; - effectEntry.hitSeverity = ActionHitSeverityType::NormalDamage; - - effectPacket->addEffect( effectEntry ); - - if( ( actionInfoPtr->castType == 1 && actionInfoPtr->effectRange != 0 ) || - ( actionInfoPtr->castType != 1 ) ) - { - // If action on this specific target is valid... - if( isPlayer() && !ActionCollision::isActorApplicable( target, TargetFilter::Enemies ) ) - break; - - sendToInRangeSet( effectPacket, true ); - - if( target.isAlive() ) - target.onActionHostile( getAsChara() ); - - target.takeDamage( static_cast< uint32_t >( param1 ) ); - - } - else - { - - auto actorsCollided = ActionCollision::getActorsHitFromAction( target.getPos(), getInRangeActors( true ), - actionInfoPtr, TargetFilter::Enemies ); - - for( const auto& pHitActor : actorsCollided ) - { - effectPacket->setTargetActor( pHitActor->getId() ); - - // todo: send to range of what? ourselves? when mob script hits this is going to be lacking - sendToInRangeSet( effectPacket, true ); - - - if( pHitActor->getAsChara()->isAlive() ) - pHitActor->getAsChara()->onActionHostile( getAsChara() ); - - pHitActor->getAsChara()->takeDamage( static_cast< uint32_t >( param1 ) ); - - // Debug - if( isPlayer() ) - { - if( pHitActor->isPlayer() ) - getAsPlayer()->sendDebug( "AoE hit actor#{0} ({1})", pHitActor->getId(), pHitActor->getAsChara()->getName() ); - else - getAsPlayer()->sendDebug( "AoE hit actor#{0}", pHitActor->getId() ); - } - } - } - - break; - } - - case ActionEffectType::Heal: - { - uint32_t calculatedHeal = Math::CalcBattle::calculateHealValue( getAsPlayer(), - static_cast< uint32_t >( param1 ), - m_pFw ); - - Server::EffectEntry effectEntry{}; - effectEntry.value = calculatedHeal; - effectEntry.effectType = ActionEffectType::Heal; - effectEntry.hitSeverity = ActionHitSeverityType::NormalHeal; - - effectPacket->addEffect( effectEntry ); - - if( ( actionInfoPtr->castType == 1 && actionInfoPtr->effectRange != 0 ) || actionInfoPtr->castType != 1 ) - { - if( isPlayer() && !ActionCollision::isActorApplicable( target, TargetFilter::Allies ) ) - break; - - sendToInRangeSet( effectPacket, true ); - target.heal( calculatedHeal ); - } - else - { - // todo: get proper packets: the following was just kind of thrown together from what we know. - // atm buggy (packets look "delayed" from client) - - auto actorsCollided = ActionCollision::getActorsHitFromAction( target.getPos(), getInRangeActors( true ), - actionInfoPtr, TargetFilter::Allies ); - - for( const auto& pHitActor : actorsCollided ) - { - effectPacket->setTargetActor( pHitActor->getId() ); - - sendToInRangeSet( effectPacket, true ); - pHitActor->getAsChara()->heal( calculatedHeal ); - - // Debug - if( isPlayer() ) - { - if( pHitActor->isPlayer() ) - getAsPlayer()->sendDebug( "AoE hit actor#{0} ({1})", pHitActor->getId(), pHitActor->getAsChara()->getName() ); - else - getAsPlayer()->sendDebug( "AoE hit actor#{0}", pHitActor->getId() ); - } - } - } - break; - } - - default: - break; - } -} - /*! \param StatusEffectPtr to be applied to the actor */ void Sapphire::Entity::Chara::addStatusEffect( StatusEffect::StatusEffectPtr pEffect ) { diff --git a/src/world/Actor/Chara.h b/src/world/Actor/Chara.h index fcf38ded..253ec9bc 100644 --- a/src/world/Actor/Chara.h +++ b/src/world/Actor/Chara.h @@ -212,9 +212,6 @@ namespace Sapphire::Entity void setStatus( Common::ActorStatus status ); - void - handleScriptSkill( uint32_t type, uint16_t actionId, uint64_t param1, uint64_t param2, Entity::Chara& target ); - virtual void autoAttack( CharaPtr pTarget ); virtual void onDeath() {}; diff --git a/src/world/Actor/Npc.cpp b/src/world/Actor/Npc.cpp index 38223d34..b0c86a90 100644 --- a/src/world/Actor/Npc.cpp +++ b/src/world/Actor/Npc.cpp @@ -18,8 +18,6 @@ #include "Network/PacketWrappers/UpdateHpMpTpPacket.h" #include "Network/PacketWrappers/EffectPacket.h" -#include "StatusEffect/StatusEffect.h" -#include "Action/ActionCollision.h" #include "ServerMgr.h" #include "Session.h" #include "Math/CalcBattle.h" diff --git a/src/world/Actor/Player.cpp b/src/world/Actor/Player.cpp index a7d66676..6d7d891a 100644 --- a/src/world/Actor/Player.cpp +++ b/src/world/Actor/Player.cpp @@ -34,11 +34,6 @@ #include "Script/ScriptMgr.h" -#include "Action/Action.h" -#include "Action/ActionTeleport.h" -#include "Action/EventAction.h" -#include "Action/EventItemAction.h" - #include "Math/CalcStats.h" #include "Math/CalcBattle.h" @@ -1835,34 +1830,34 @@ void Sapphire::Entity::Player::emoteInterrupt() void Sapphire::Entity::Player::teleportQuery( uint16_t aetheryteId, FrameworkPtr pFw ) { - auto pExdData = pFw->get< Data::ExdDataGenerated >(); - // TODO: only register this action if enough gil is in possession - auto targetAetheryte = pExdData->get< Sapphire::Data::Aetheryte >( aetheryteId ); - - if( targetAetheryte ) - { - auto fromAetheryte = pExdData->get< Sapphire::Data::Aetheryte >( - pExdData->get< Sapphire::Data::TerritoryType >( getZoneId() )->aetheryte ); - - // calculate cost - does not apply for favorite points or homepoints neither checks for aether tickets - auto cost = static_cast< uint16_t > ( - ( std::sqrt( std::pow( fromAetheryte->aetherstreamX - targetAetheryte->aetherstreamX, 2 ) + - std::pow( fromAetheryte->aetherstreamY - targetAetheryte->aetherstreamY, 2 ) ) / 2 ) + 100 ); - - // cap at 999 gil - cost = cost > uint16_t{ 999 } ? uint16_t{ 999 } : cost; - - bool insufficientGil = getCurrency( Common::CurrencyType::Gil ) < cost; - // TODO: figure out what param1 really does - queuePacket( makeActorControl143( getId(), TeleportStart, insufficientGil ? 2 : 0, aetheryteId ) ); - - if( !insufficientGil ) - { - Action::ActionPtr pActionTeleport; - pActionTeleport = Action::make_ActionTeleport( getAsPlayer(), aetheryteId, cost, pFw ); - setCurrentAction( pActionTeleport ); - } - } +// auto pExdData = pFw->get< Data::ExdDataGenerated >(); +// // TODO: only register this action if enough gil is in possession +// auto targetAetheryte = pExdData->get< Sapphire::Data::Aetheryte >( aetheryteId ); +// +// if( targetAetheryte ) +// { +// auto fromAetheryte = pExdData->get< Sapphire::Data::Aetheryte >( +// pExdData->get< Sapphire::Data::TerritoryType >( getZoneId() )->aetheryte ); +// +// // calculate cost - does not apply for favorite points or homepoints neither checks for aether tickets +// auto cost = static_cast< uint16_t > ( +// ( std::sqrt( std::pow( fromAetheryte->aetherstreamX - targetAetheryte->aetherstreamX, 2 ) + +// std::pow( fromAetheryte->aetherstreamY - targetAetheryte->aetherstreamY, 2 ) ) / 2 ) + 100 ); +// +// // cap at 999 gil +// cost = cost > uint16_t{ 999 } ? uint16_t{ 999 } : cost; +// +// bool insufficientGil = getCurrency( Common::CurrencyType::Gil ) < cost; +// // TODO: figure out what param1 really does +// queuePacket( makeActorControl143( getId(), TeleportStart, insufficientGil ? 2 : 0, aetheryteId ) ); +// +// if( !insufficientGil ) +// { +// Action::ActionPtr pActionTeleport; +// pActionTeleport = Action::make_ActionTeleport( getAsPlayer(), aetheryteId, cost, pFw ); +// setCurrentAction( pActionTeleport ); +// } +// } } uint8_t Sapphire::Entity::Player::getNextObjSpawnIndexForActorId( uint32_t actorId ) diff --git a/src/world/Actor/PlayerEvent.cpp b/src/world/Actor/PlayerEvent.cpp index 6b0865eb..ba504475 100644 --- a/src/world/Actor/PlayerEvent.cpp +++ b/src/world/Actor/PlayerEvent.cpp @@ -11,9 +11,6 @@ #include "Network/PacketWrappers/EventFinishPacket.h" #include "Network/PacketWrappers/DirectorPlayScenePacket.h" -#include "Action/EventAction.h" -#include "Action/EventItemAction.h" - #include "Territory/Zone.h" #include "ServerMgr.h" #include "Framework.h" @@ -283,27 +280,27 @@ void Sapphire::Entity::Player::eventActionStart( uint32_t eventId, ActionCallback interruptCallback, uint64_t additional ) { - auto pEventAction = Action::make_EventAction( getAsChara(), eventId, action, - finishCallback, interruptCallback, additional, m_pFw ); - - setCurrentAction( pEventAction ); - auto pEvent = getEvent( eventId ); - - if( !pEvent && getEventCount() ) - { - // We're trying to play a nested event, need to start it first. - eventStart( getId(), eventId, Event::EventHandler::Nest, 0, 0 ); - pEvent = getEvent( eventId ); - } - else if( !pEvent ) - { - Logger::error( "Could not find event #{0}, event has not been started!", eventId ); - return; - } - - if( pEvent ) - pEvent->setPlayedScene( true ); - pEventAction->onStart(); +// auto pEventAction = Action::make_EventAction( getAsChara(), eventId, action, +// finishCallback, interruptCallback, additional, m_pFw ); +// +// setCurrentAction( pEventAction ); +// auto pEvent = getEvent( eventId ); +// +// if( !pEvent && getEventCount() ) +// { +// // We're trying to play a nested event, need to start it first. +// eventStart( getId(), eventId, Event::EventHandler::Nest, 0, 0 ); +// pEvent = getEvent( eventId ); +// } +// else if( !pEvent ) +// { +// Logger::error( "Could not find event #{0}, event has not been started!", eventId ); +// return; +// } +// +// if( pEvent ) +// pEvent->setPlayedScene( true ); +// pEventAction->onStart(); } @@ -313,12 +310,12 @@ void Sapphire::Entity::Player::eventItemActionStart( uint32_t eventId, ActionCallback interruptCallback, uint64_t additional ) { - Action::ActionPtr pEventItemAction = Action::make_EventItemAction( getAsChara(), eventId, action, - finishCallback, interruptCallback, additional ); - - setCurrentAction( pEventItemAction ); - - pEventItemAction->onStart(); +// Action::ActionPtr pEventItemAction = Action::make_EventItemAction( getAsChara(), eventId, action, +// finishCallback, interruptCallback, additional ); +// +// setCurrentAction( pEventItemAction ); +// +// pEventItemAction->onStart(); } ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/src/world/Network/Handlers/ActionHandler.cpp b/src/world/Network/Handlers/ActionHandler.cpp index ffc73dc2..eb70eab8 100644 --- a/src/world/Network/Handlers/ActionHandler.cpp +++ b/src/world/Network/Handlers/ActionHandler.cpp @@ -22,8 +22,6 @@ #include "Action/Action.h" #include "Action/ActionCast.h" -#include "Action/ActionMount.h" - #include "Script/ScriptMgr.h" #include "Session.h" diff --git a/src/world/Network/Handlers/ClientTriggerHandler.cpp b/src/world/Network/Handlers/ClientTriggerHandler.cpp index 1b49e689..899c062b 100644 --- a/src/world/Network/Handlers/ClientTriggerHandler.cpp +++ b/src/world/Network/Handlers/ClientTriggerHandler.cpp @@ -26,7 +26,6 @@ #include "Manager/EventMgr.h" #include "Action/Action.h" -#include "Action/ActionTeleport.h" #include "Session.h" diff --git a/src/world/Network/Handlers/PacketHandlers.cpp b/src/world/Network/Handlers/PacketHandlers.cpp index 0560e69a..da9cb293 100644 --- a/src/world/Network/Handlers/PacketHandlers.cpp +++ b/src/world/Network/Handlers/PacketHandlers.cpp @@ -41,7 +41,6 @@ #include "Manager/RNGMgr.h" #include "Action/Action.h" -#include "Action/ActionTeleport.h" #include "Session.h" #include "ServerMgr.h" From 3db83cf716287164332f5704c33cd8d0d6356413 Mon Sep 17 00:00:00 2001 From: NotAdam Date: Fri, 8 Feb 2019 21:20:53 +1100 Subject: [PATCH 04/63] cleanup teleport query code --- src/world/Actor/Player.cpp | 32 ++----------------- src/world/Actor/Player.h | 4 ++- .../Network/Handlers/ClientTriggerHandler.cpp | 2 +- 3 files changed, 7 insertions(+), 31 deletions(-) diff --git a/src/world/Actor/Player.cpp b/src/world/Actor/Player.cpp index 6d7d891a..ea2ca233 100644 --- a/src/world/Actor/Player.cpp +++ b/src/world/Actor/Player.cpp @@ -1828,36 +1828,10 @@ void Sapphire::Entity::Player::emoteInterrupt() sendToInRangeSet( makeActorControl142( getId(), ActorControlType::EmoteInterrupt ) ); } -void Sapphire::Entity::Player::teleportQuery( uint16_t aetheryteId, FrameworkPtr pFw ) +void Sapphire::Entity::Player::teleportQuery( uint16_t aetheryteId ) { -// auto pExdData = pFw->get< Data::ExdDataGenerated >(); -// // TODO: only register this action if enough gil is in possession -// auto targetAetheryte = pExdData->get< Sapphire::Data::Aetheryte >( aetheryteId ); -// -// if( targetAetheryte ) -// { -// auto fromAetheryte = pExdData->get< Sapphire::Data::Aetheryte >( -// pExdData->get< Sapphire::Data::TerritoryType >( getZoneId() )->aetheryte ); -// -// // calculate cost - does not apply for favorite points or homepoints neither checks for aether tickets -// auto cost = static_cast< uint16_t > ( -// ( std::sqrt( std::pow( fromAetheryte->aetherstreamX - targetAetheryte->aetherstreamX, 2 ) + -// std::pow( fromAetheryte->aetherstreamY - targetAetheryte->aetherstreamY, 2 ) ) / 2 ) + 100 ); -// -// // cap at 999 gil -// cost = cost > uint16_t{ 999 } ? uint16_t{ 999 } : cost; -// -// bool insufficientGil = getCurrency( Common::CurrencyType::Gil ) < cost; -// // TODO: figure out what param1 really does -// queuePacket( makeActorControl143( getId(), TeleportStart, insufficientGil ? 2 : 0, aetheryteId ) ); -// -// if( !insufficientGil ) -// { -// Action::ActionPtr pActionTeleport; -// pActionTeleport = Action::make_ActionTeleport( getAsPlayer(), aetheryteId, cost, pFw ); -// setCurrentAction( pActionTeleport ); -// } -// } + m_teleportTargetAetheryte = aetheryteId; + sendDebug( "requested aetheryte destination: {0}", aetheryteId ); } uint8_t Sapphire::Entity::Player::getNextObjSpawnIndexForActorId( uint32_t actorId ) diff --git a/src/world/Actor/Player.h b/src/world/Actor/Player.h index 154b4fe2..9633b7a7 100644 --- a/src/world/Actor/Player.h +++ b/src/world/Actor/Player.h @@ -531,7 +531,7 @@ namespace Sapphire::Entity void teleport( uint16_t aetheryteId, uint8_t type = 1 ); /*! query teleport of a specified type */ - void teleportQuery( uint16_t aetheryteId, FrameworkPtr pFw ); + void teleportQuery( uint16_t aetheryteId ); /*! prepares zoning / fades out the screen */ void prepareZoning( uint16_t targetZone, bool fadeOut, uint8_t fadeOutTime = 0, uint16_t animation = 0 ); @@ -1086,6 +1086,8 @@ namespace Sapphire::Entity uint32_t m_mount; uint32_t m_emoteMode; + uint16_t m_teleportTargetAetheryte; + Util::SpawnIndexAllocator< uint8_t > m_objSpawnIndexAllocator; Util::SpawnIndexAllocator< uint8_t > m_actorSpawnIndexAllocator; }; diff --git a/src/world/Network/Handlers/ClientTriggerHandler.cpp b/src/world/Network/Handlers/ClientTriggerHandler.cpp index 899c062b..6aad2f8c 100644 --- a/src/world/Network/Handlers/ClientTriggerHandler.cpp +++ b/src/world/Network/Handlers/ClientTriggerHandler.cpp @@ -274,7 +274,7 @@ void Sapphire::Network::GameConnection::clientTriggerHandler( FrameworkPtr pFw, case ClientTriggerType::Teleport: // Teleport { - player.teleportQuery( param11, pFw ); + player.teleportQuery( param11 ); break; } case ClientTriggerType::DyeItem: // Dye item From 37e07784cdf7863d591bd68439b6e9e0a678c60f Mon Sep 17 00:00:00 2001 From: NotAdam Date: Fri, 8 Feb 2019 21:53:13 +1100 Subject: [PATCH 05/63] cleanup forward defs --- src/world/ForwardsZone.h | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/world/ForwardsZone.h b/src/world/ForwardsZone.h index 46140156..f5ea396f 100644 --- a/src/world/ForwardsZone.h +++ b/src/world/ForwardsZone.h @@ -84,11 +84,7 @@ TYPE_FORWARD( EventHandler ); namespace Action { TYPE_FORWARD( Action ); -TYPE_FORWARD( ActionTeleport ); TYPE_FORWARD( ActionCast ); -TYPE_FORWARD( ActionMount ); -TYPE_FORWARD( EventAction ); -TYPE_FORWARD( EventItemAction ); } namespace Network From 1085a3c154a808806fbd93c79bdba324d290fbfa Mon Sep 17 00:00:00 2001 From: NotAdam Date: Fri, 8 Feb 2019 22:07:49 +1100 Subject: [PATCH 06/63] remove old actioncast setup --- src/world/Action/ActionCast.cpp | 102 ------------------- src/world/Action/ActionCast.h | 31 ------ src/world/Network/Handlers/ActionHandler.cpp | 1 - 3 files changed, 134 deletions(-) delete mode 100644 src/world/Action/ActionCast.cpp delete mode 100644 src/world/Action/ActionCast.h diff --git a/src/world/Action/ActionCast.cpp b/src/world/Action/ActionCast.cpp deleted file mode 100644 index 56f0c79d..00000000 --- a/src/world/Action/ActionCast.cpp +++ /dev/null @@ -1,102 +0,0 @@ -#include -#include -#include -#include -#include -#include - -#include "Network/PacketWrappers/ActorControlPacket142.h" -#include "Network/PacketWrappers/ActorControlPacket143.h" -#include "Network/PacketWrappers/ActorControlPacket144.h" - -#include "Actor/Player.h" - -#include "Script/ScriptMgr.h" - -#include "ActionCast.h" -#include "Framework.h" - -using namespace Sapphire::Common; -using namespace Sapphire::Network; -using namespace Sapphire::Network::Packets; -using namespace Sapphire::Network::Packets::Server; -using namespace Sapphire::Network::ActorControl; - -Sapphire::Action::ActionCast::ActionCast() -{ - m_handleActionType = Common::HandleActionType::Event; -} - -Sapphire::Action::ActionCast::ActionCast( Entity::CharaPtr pActor, Entity::CharaPtr pTarget, - uint16_t actionId, FrameworkPtr pFw ) -{ - m_pFw = pFw; - auto pExdData = m_pFw->get< Data::ExdDataGenerated >(); - m_startTime = 0; - m_id = actionId; - m_handleActionType = HandleActionType::Spell; - m_castTime = pExdData->get< Sapphire::Data::Action >( actionId )->cast100ms * 100; // TODO: Add security checks. - m_pSource = pActor; - m_pTarget = pTarget; - m_bInterrupt = false; -} - -Sapphire::Action::ActionCast::~ActionCast() = default; - -void Sapphire::Action::ActionCast::onStart() -{ - if( !m_pSource ) - return; - - m_pSource->getAsPlayer()->sendDebug( "onStart()" ); - m_startTime = Util::getTimeMs(); - - auto castPacket = makeZonePacket< FFXIVIpcActorCast >( getId() ); - - castPacket->data().action_id = m_id; - castPacket->data().skillType = Common::SkillType::Normal; - castPacket->data().unknown_1 = m_id; - // This is used for the cast bar above the target bar of the caster. - castPacket->data().cast_time = static_cast< float >( m_castTime / 1000 ); - castPacket->data().target_id = m_pTarget->getId(); - - m_pSource->sendToInRangeSet( castPacket, true ); - m_pSource->getAsPlayer()->setStateFlag( PlayerStateFlag::Casting ); - -} - -void Sapphire::Action::ActionCast::onFinish() -{ - if( !m_pSource ) - return; - - auto pScriptMgr = m_pFw->get< Scripting::ScriptMgr >(); - - auto pPlayer = m_pSource->getAsPlayer(); - pPlayer->sendDebug( "onFinish()" ); - - pPlayer->unsetStateFlag( PlayerStateFlag::Casting ); - - /*auto control = ActorControlPacket143( m_pTarget->getId(), ActorControlType::Unk7, - 0x219, m_id, m_id, m_id, m_id ); - m_pSource->sendToInRangeSet( control, true );*/ - - pScriptMgr->onCastFinish( *pPlayer, m_pTarget, m_id ); -} - -void Sapphire::Action::ActionCast::onInterrupt() -{ - if( !m_pSource ) - return; - - //m_pSource->getAsPlayer()->unsetStateFlag( PlayerStateFlag::Occupied1 ); - m_pSource->getAsPlayer()->unsetStateFlag( PlayerStateFlag::Casting ); - - auto control = makeActorControl142( m_pSource->getId(), ActorControlType::CastInterrupt, 0x219, 1, m_id, 0 ); - - // Note: When cast interrupt from taking too much damage, set the last value to 1. This enables the cast interrupt effect. Example: - // auto control = ActorControlPacket142( m_pSource->getId(), ActorControlType::CastInterrupt, 0x219, 1, m_id, 0 ); - - m_pSource->sendToInRangeSet( control, true ); - -} diff --git a/src/world/Action/ActionCast.h b/src/world/Action/ActionCast.h deleted file mode 100644 index 3a3b01b0..00000000 --- a/src/world/Action/ActionCast.h +++ /dev/null @@ -1,31 +0,0 @@ -#ifndef _ACTIONCAST_H_ -#define _ACTIONCAST_H_ - -#include "ForwardsZone.h" -#include "Action.h" - -namespace Sapphire::Action -{ - - class ActionCast : public Action - { - private: - - public: - ActionCast(); - - ~ActionCast(); - - ActionCast( Entity::CharaPtr pActor, Entity::CharaPtr pTarget, uint16_t actionId, FrameworkPtr pFw ); - - void onStart() override; - - void onFinish() override; - - void onInterrupt() override; - - }; - -} - -#endif diff --git a/src/world/Network/Handlers/ActionHandler.cpp b/src/world/Network/Handlers/ActionHandler.cpp index eb70eab8..9d50a599 100644 --- a/src/world/Network/Handlers/ActionHandler.cpp +++ b/src/world/Network/Handlers/ActionHandler.cpp @@ -21,7 +21,6 @@ #include "Manager/ActionMgr.h" #include "Action/Action.h" -#include "Action/ActionCast.h" #include "Script/ScriptMgr.h" #include "Session.h" From b247f69a96c61f4857976d09659b38120e1b99e4 Mon Sep 17 00:00:00 2001 From: NotAdam Date: Fri, 8 Feb 2019 22:09:48 +1100 Subject: [PATCH 07/63] move the old actioncast code into base action class --- src/world/Action/Action.cpp | 118 +++++++++++++++++++++++++++++++----- src/world/Action/Action.h | 41 +++++-------- 2 files changed, 119 insertions(+), 40 deletions(-) diff --git a/src/world/Action/Action.cpp b/src/world/Action/Action.cpp index d6ae040a..e320cbfe 100644 --- a/src/world/Action/Action.cpp +++ b/src/world/Action/Action.cpp @@ -1,15 +1,44 @@ #include "Action.h" +#include #include +#include "Framework.h" +#include "Script/ScriptMgr.h" + +#include "Actor/Player.h" + +#include +#include "Network/PacketWrappers/ActorControlPacket142.h" +#include "Network/PacketWrappers/ActorControlPacket143.h" +#include "Network/PacketWrappers/ActorControlPacket144.h" + +using namespace Sapphire::Common; +using namespace Sapphire::Network; +using namespace Sapphire::Network::Packets; +using namespace Sapphire::Network::Packets::Server; +using namespace Sapphire::Network::ActorControl; -Sapphire::Action::Action::Action() +Sapphire::Action::Action::Action() = default; +Sapphire::Action::Action::~Action() = default; + +Sapphire::Action::Action::Action( Entity::CharaPtr caster, Entity::CharaPtr target, + uint16_t actionId, FrameworkPtr fw ) : + + m_pSource( std::move( caster ) ), + m_pTarget( std::move( target ) ), + m_pFw( std::move( fw ) ), + m_id( actionId ), + m_startTime( 0 ) { -} + auto exdData = m_pFw->get< Data::ExdDataGenerated >(); + assert( exdData ); -Sapphire::Action::Action::~Action() -{ + auto actionData = exdData->get< Data::Action >( actionId ); + // todo: clients can crash the server here, ideally we do this check outside of the action anyway + assert( actionData ); + m_castTime = actionData->cast100ms * 100; } uint16_t Sapphire::Action::Action::getId() const @@ -17,11 +46,6 @@ uint16_t Sapphire::Action::Action::getId() const return m_id; } -Sapphire::Common::HandleActionType Sapphire::Action::Action::getHandleActionType() const -{ - return m_handleActionType; -} - Sapphire::Entity::CharaPtr Sapphire::Action::Action::getTargetChara() const { return m_pTarget; @@ -37,14 +61,11 @@ void Sapphire::Action::Action::setInterrupted() m_bInterrupt = true; } -uint64_t Sapphire::Action::Action::getStartTime() const +void Sapphire::Action::Action::start() { - return m_startTime; -} + m_startTime = Util::getTimeMs(); -void Sapphire::Action::Action::setStartTime( uint64_t startTime ) -{ - m_startTime = startTime; + onStart(); } uint32_t Sapphire::Action::Action::getCastTime() const @@ -57,6 +78,11 @@ void Sapphire::Action::Action::setCastTime( uint32_t castTime ) m_castTime = castTime; } +bool Sapphire::Action::Action::isCastedAction() const +{ + return m_castTime > 0; +} + Sapphire::Entity::CharaPtr Sapphire::Action::Action::getActionSource() const { return m_pSource; @@ -83,3 +109,65 @@ bool Sapphire::Action::Action::update() } return false; } + +void Sapphire::Action::Action::onStart() +{ + assert( m_pSource ); + + if( isCastedAction() ) + { + m_pSource->getAsPlayer()->sendDebug( "onStart()" ); + m_startTime = Util::getTimeMs(); + + auto castPacket = makeZonePacket< FFXIVIpcActorCast >( getId() ); + + castPacket->data().action_id = m_id; + castPacket->data().skillType = Common::SkillType::Normal; + castPacket->data().unknown_1 = m_id; + // This is used for the cast bar above the target bar of the caster. + castPacket->data().cast_time = static_cast< float >( m_castTime / 1000.f ); + castPacket->data().target_id = m_pTarget->getId(); + + m_pSource->sendToInRangeSet( castPacket, true ); + m_pSource->getAsPlayer()->setStateFlag( PlayerStateFlag::Casting ); + } +} + +void Sapphire::Action::Action::onInterrupt() +{ + assert( m_pSource ); + + if( isCastedAction() ) + { + //m_pSource->getAsPlayer()->unsetStateFlag( PlayerStateFlag::Occupied1 ); + m_pSource->getAsPlayer()->unsetStateFlag( PlayerStateFlag::Casting ); + + auto control = makeActorControl142( m_pSource->getId(), ActorControlType::CastInterrupt, 0x219, 1, m_id, 0 ); + + // Note: When cast interrupt from taking too much damage, set the last value to 1. This enables the cast interrupt effect. Example: + // auto control = ActorControlPacket142( m_pSource->getId(), ActorControlType::CastInterrupt, 0x219, 1, m_id, 0 ); + + m_pSource->sendToInRangeSet( control, true ); + } +} + +void Sapphire::Action::Action::onFinish() +{ + assert( m_pSource ); + + auto pScriptMgr = m_pFw->get< Scripting::ScriptMgr >(); + + auto pPlayer = m_pSource->getAsPlayer(); + pPlayer->sendDebug( "onFinish()" ); + + if( isCastedAction() ) + { + pPlayer->unsetStateFlag( PlayerStateFlag::Casting ); + + /*auto control = ActorControlPacket143( m_pTarget->getId(), ActorControlType::Unk7, + 0x219, m_id, m_id, m_id, m_id ); + m_pSource->sendToInRangeSet( control, true );*/ + + pScriptMgr->onCastFinish( *pPlayer, m_pTarget, m_id ); + } +} diff --git a/src/world/Action/Action.h b/src/world/Action/Action.h index ef4af91b..9c2134e9 100644 --- a/src/world/Action/Action.h +++ b/src/world/Action/Action.h @@ -12,47 +12,38 @@ namespace Sapphire::Action public: Action(); + Action( Entity::CharaPtr caster, Entity::CharaPtr target, uint16_t actionId, FrameworkPtr fw ); virtual ~Action(); uint16_t getId() const; - Common::HandleActionType getHandleActionType() const; - Entity::CharaPtr getTargetChara() const; - - bool isInterrupted() const; - - void setInterrupted(); - - uint64_t getStartTime() const; - - void setStartTime( uint64_t startTime ); - - uint32_t getCastTime() const; - - void setCastTime( uint32_t castTime ); - Entity::CharaPtr getActionSource() const; - virtual void onStart() - { - }; + bool isInterrupted() const; + void setInterrupted(); - virtual void onFinish() - { - }; + uint32_t getCastTime() const; + void setCastTime( uint32_t castTime ); - virtual void onInterrupt() - { - }; + /*! + * @brief Tests whether the action is instantly usable or has a cast assoc'd with it + * @return true if action has a cast time + */ + bool isCastedAction() const; + + void start(); + + virtual void onStart(); + virtual void onFinish(); + virtual void onInterrupt(); // update action, if returns true, action is done and has to be removed from the actor virtual bool update(); protected: uint16_t m_id; - Common::HandleActionType m_handleActionType; uint64_t m_startTime; uint32_t m_castTime; From cc31adcbe3852983d41b3778e47a62cfbb95d911 Mon Sep 17 00:00:00 2001 From: NotAdam Date: Sat, 9 Feb 2019 14:44:43 +1100 Subject: [PATCH 08/63] fix dependency on packetcontainer when gameconnection handlers are split into another file --- src/world/Network/GameConnection.h | 1 + 1 file changed, 1 insertion(+) diff --git a/src/world/Network/GameConnection.h b/src/world/Network/GameConnection.h index 56e3f77f..46a17000 100644 --- a/src/world/Network/GameConnection.h +++ b/src/world/Network/GameConnection.h @@ -14,6 +14,7 @@ namespace Sapphire::Network::Packets { class GamePacket; + class PacketContainer; } namespace Sapphire::Network From 2c076520b9b06a09d87a4f04d352c5fb677c5ed9 Mon Sep 17 00:00:00 2001 From: NotAdam Date: Sat, 9 Feb 2019 14:45:22 +1100 Subject: [PATCH 09/63] ignore invalid actions and pass action data into manager --- src/world/Manager/ActionMgr.cpp | 15 ++++-- src/world/Manager/ActionMgr.h | 10 +++- src/world/Network/Handlers/ActionHandler.cpp | 53 ++++++++++---------- 3 files changed, 46 insertions(+), 32 deletions(-) diff --git a/src/world/Manager/ActionMgr.cpp b/src/world/Manager/ActionMgr.cpp index 58c1dfb3..cd066c59 100644 --- a/src/world/Manager/ActionMgr.cpp +++ b/src/world/Manager/ActionMgr.cpp @@ -1,5 +1,12 @@ #include "ActionMgr.h" +#include "Action/Action.h" +#include "Script/ScriptMgr.h" + +#include "Actor/Player.h" + +#include + using namespace Sapphire; World::Manager::ActionMgr::ActionMgr( Sapphire::FrameworkPtr pFw ) : @@ -9,13 +16,13 @@ World::Manager::ActionMgr::ActionMgr( Sapphire::FrameworkPtr pFw ) : } void World::Manager::ActionMgr::handleAoEPlayerAction( Entity::Player& player, uint8_t type, - uint32_t actionId, Common::FFXIVARR_POSITION3 pos ) + Data::ActionPtr action, Common::FFXIVARR_POSITION3 pos ) { - + player.sendDebug( "got aoe act: {0}", action->name ); } void World::Manager::ActionMgr::handleTargetedPlayerAction( Entity::Player& player, uint8_t type, - uint32_t actionId, uint64_t targetId ) + Data::ActionPtr action, uint64_t targetId ) { - + player.sendDebug( "got act: {0}", action->name ); } \ No newline at end of file diff --git a/src/world/Manager/ActionMgr.h b/src/world/Manager/ActionMgr.h index 1745de04..0e06ce31 100644 --- a/src/world/Manager/ActionMgr.h +++ b/src/world/Manager/ActionMgr.h @@ -4,6 +4,12 @@ #include "BaseManager.h" #include "ForwardsZone.h" +namespace Sapphire::Data +{ + class Action; + using ActionPtr = std::shared_ptr< Action >; +} + namespace Sapphire::World::Manager { class ActionMgr : public Manager::BaseManager @@ -12,8 +18,8 @@ namespace Sapphire::World::Manager explicit ActionMgr( FrameworkPtr pFw ); ~ActionMgr() = default; - void handleTargetedPlayerAction( Entity::Player& player, uint8_t type, uint32_t actionId, uint64_t targetId ); - void handleAoEPlayerAction( Entity::Player& player, uint8_t type, uint32_t actionId, Common::FFXIVARR_POSITION3 pos ); + void handleTargetedPlayerAction( Entity::Player& player, uint8_t type, Data::ActionPtr action, uint64_t targetId ); + void handleAoEPlayerAction( Entity::Player& player, uint8_t type, Data::ActionPtr action, Common::FFXIVARR_POSITION3 pos ); }; } diff --git a/src/world/Network/Handlers/ActionHandler.cpp b/src/world/Network/Handlers/ActionHandler.cpp index 9d50a599..5ca1a98c 100644 --- a/src/world/Network/Handlers/ActionHandler.cpp +++ b/src/world/Network/Handlers/ActionHandler.cpp @@ -1,35 +1,18 @@ #include -#include #include #include -#include -#include #include #include -#include + +#include #include "Network/GameConnection.h" -#include "Network/PacketWrappers/ServerNoticePacket.h" -#include "Network/PacketWrappers/ActorControlPacket142.h" -#include "Network/PacketWrappers/ActorControlPacket143.h" -#include "Network/PacketWrappers/ActorControlPacket144.h" -#include "Network/PacketWrappers/MoveActorPacket.h" - -#include "Network/PacketWrappers/PlayerStateFlagsPacket.h" - -#include "Manager/DebugCommandMgr.h" -#include "Manager/ActionMgr.h" - -#include "Action/Action.h" -#include "Script/ScriptMgr.h" - -#include "Session.h" #include "Framework.h" +#include "Manager/ActionMgr.h" + using namespace Sapphire::Common; using namespace Sapphire::Network::Packets; -using namespace Sapphire::Network::Packets::Server; -using namespace Sapphire::Network::ActorControl; void Sapphire::Network::GameConnection::actionHandler( FrameworkPtr pFw, const Packets::FFXIVARR_PACKET_RAW& inPacket, @@ -38,14 +21,23 @@ void Sapphire::Network::GameConnection::actionHandler( FrameworkPtr pFw, const auto packet = ZoneChannelPacket< Client::FFXIVIpcSkillHandler >( inPacket ); const auto type = packet.data().type; - const auto action = packet.data().actionId; + const auto actionId = packet.data().actionId; const auto sequence = packet.data().sequence; const auto targetId = packet.data().targetId; - player.sendDebug( "Skill type: {0}, sequence: {1}, actionId: {2}, targetId: {3}", type, sequence, action, targetId ); + auto exdData = m_pFw->get< Data::ExdDataGenerated >(); + assert( exdData ); + + auto action = exdData->get< Data::Action >( actionId ); + + // ignore invalid actions + if( !action ) + return; auto actionMgr = pFw->get< World::Manager::ActionMgr >(); actionMgr->handleTargetedPlayerAction( player, type, action, targetId ); + + player.sendDebug( "Skill type: {0}, sequence: {1}, actionId: {2}, targetId: {3}", type, sequence, actionId, targetId ); } void Sapphire::Network::GameConnection::aoeActionHandler( FrameworkPtr pFw, @@ -55,13 +47,22 @@ void Sapphire::Network::GameConnection::aoeActionHandler( FrameworkPtr pFw, const auto packet = ZoneChannelPacket< Client::FFXIVIpcAoESkillHandler >( inPacket ); const auto type = packet.data().type; - const auto action = packet.data().actionId; + const auto actionId = packet.data().actionId; const auto sequence = packet.data().sequence; const auto pos = packet.data().pos; + auto exdData = m_pFw->get< Data::ExdDataGenerated >(); + assert( exdData ); + + auto action = exdData->get< Data::Action >( actionId ); + + // ignore invalid actions + if( !action ) + return; + auto actionMgr = pFw->get< World::Manager::ActionMgr >(); actionMgr->handleAoEPlayerAction( player, type, action, pos ); - player.sendDebug( "Skill type: {0}, sequence: {1}, actionId: {2}\nx:{3}, y:{4}, z:{5}", - type, sequence, action, pos.x, pos.y, pos.z ); + player.sendDebug( "Skill type: {0}, sequence: {1}, actionId: {2}, x:{3}, y:{4}, z:{5}", + type, sequence, actionId, pos.x, pos.y, pos.z ); } From 6cd3ad594b177e8d25902c314c2e39dbcb03eb50 Mon Sep 17 00:00:00 2001 From: NotAdam Date: Sat, 9 Feb 2019 15:39:05 +1100 Subject: [PATCH 10/63] basic action sanity checking, partial casting support, some cleanup --- src/world/Action/Action.cpp | 40 +++++++------ src/world/Action/Action.h | 19 ++++++- src/world/Manager/ActionMgr.cpp | 59 ++++++++++++++++++-- src/world/Manager/ActionMgr.h | 12 +++- src/world/Network/Handlers/ActionHandler.cpp | 4 +- 5 files changed, 106 insertions(+), 28 deletions(-) diff --git a/src/world/Action/Action.cpp b/src/world/Action/Action.cpp index e320cbfe..65cf285e 100644 --- a/src/world/Action/Action.cpp +++ b/src/world/Action/Action.cpp @@ -22,30 +22,39 @@ using namespace Sapphire::Network::ActorControl; Sapphire::Action::Action::Action() = default; Sapphire::Action::Action::~Action() = default; -Sapphire::Action::Action::Action( Entity::CharaPtr caster, Entity::CharaPtr target, - uint16_t actionId, FrameworkPtr fw ) : - +Sapphire::Action::Action::Action( Entity::CharaPtr caster, uint32_t actionId, + Data::ActionPtr action, FrameworkPtr fw ) : m_pSource( std::move( caster ) ), - m_pTarget( std::move( target ) ), m_pFw( std::move( fw ) ), m_id( actionId ), m_startTime( 0 ) { - auto exdData = m_pFw->get< Data::ExdDataGenerated >(); - assert( exdData ); - - auto actionData = exdData->get< Data::Action >( actionId ); - // todo: clients can crash the server here, ideally we do this check outside of the action anyway - assert( actionData ); - - m_castTime = actionData->cast100ms * 100; + m_castTime = static_cast< uint32_t >( action->cast100ms ) * 100; } -uint16_t Sapphire::Action::Action::getId() const +uint32_t Sapphire::Action::Action::getId() const { return m_id; } +Sapphire::Common::ActionType Sapphire::Action::Action::getType() const +{ + return m_type; +} + +void Sapphire::Action::Action::setType( Sapphire::Common::ActionType type ) +{ + m_type = type; +} + +void Sapphire::Action::Action::setTargetChara( Sapphire::Entity::CharaPtr chara ) +{ + assert( chara ); + + m_pTarget = chara; + m_targetId = chara->getId(); +} + Sapphire::Entity::CharaPtr Sapphire::Action::Action::getTargetChara() const { return m_pTarget; @@ -102,7 +111,7 @@ bool Sapphire::Action::Action::update() uint64_t currTime = Util::getTimeMs(); - if( ( currTime - m_startTime ) > m_castTime ) + if( !isCastedAction() || ( currTime - m_startTime ) > m_castTime ) { onFinish(); return true; @@ -117,7 +126,6 @@ void Sapphire::Action::Action::onStart() if( isCastedAction() ) { m_pSource->getAsPlayer()->sendDebug( "onStart()" ); - m_startTime = Util::getTimeMs(); auto castPacket = makeZonePacket< FFXIVIpcActorCast >( getId() ); @@ -125,7 +133,7 @@ void Sapphire::Action::Action::onStart() castPacket->data().skillType = Common::SkillType::Normal; castPacket->data().unknown_1 = m_id; // This is used for the cast bar above the target bar of the caster. - castPacket->data().cast_time = static_cast< float >( m_castTime / 1000.f ); + castPacket->data().cast_time = m_castTime / 1000.f; castPacket->data().target_id = m_pTarget->getId(); m_pSource->sendToInRangeSet( castPacket, true ); diff --git a/src/world/Action/Action.h b/src/world/Action/Action.h index 9c2134e9..4448ab67 100644 --- a/src/world/Action/Action.h +++ b/src/world/Action/Action.h @@ -4,6 +4,12 @@ #include #include "ForwardsZone.h" +namespace Sapphire::Data +{ + struct Action; + using ActionPtr = std::shared_ptr< Action >; +} + namespace Sapphire::Action { @@ -12,12 +18,16 @@ namespace Sapphire::Action public: Action(); - Action( Entity::CharaPtr caster, Entity::CharaPtr target, uint16_t actionId, FrameworkPtr fw ); + Action( Entity::CharaPtr caster, uint32_t actionId, Data::ActionPtr action, FrameworkPtr fw ); virtual ~Action(); - uint16_t getId() const; + uint32_t getId() const; + Common::ActionType getType() const; + void setType( Common::ActionType type ); + + void setTargetChara( Entity::CharaPtr chara ); Entity::CharaPtr getTargetChara() const; Entity::CharaPtr getActionSource() const; @@ -43,13 +53,16 @@ namespace Sapphire::Action virtual bool update(); protected: - uint16_t m_id; + uint32_t m_id; + + Common::ActionType m_type; uint64_t m_startTime; uint32_t m_castTime; Entity::CharaPtr m_pSource; Entity::CharaPtr m_pTarget; + uint64_t m_targetId; bool m_bInterrupt; diff --git a/src/world/Manager/ActionMgr.cpp b/src/world/Manager/ActionMgr.cpp index cd066c59..45723cc9 100644 --- a/src/world/Manager/ActionMgr.cpp +++ b/src/world/Manager/ActionMgr.cpp @@ -16,13 +16,64 @@ World::Manager::ActionMgr::ActionMgr( Sapphire::FrameworkPtr pFw ) : } void World::Manager::ActionMgr::handleAoEPlayerAction( Entity::Player& player, uint8_t type, - Data::ActionPtr action, Common::FFXIVARR_POSITION3 pos ) + uint32_t actionId, Data::ActionPtr actionData, + Common::FFXIVARR_POSITION3 pos ) { - player.sendDebug( "got aoe act: {0}", action->name ); + player.sendDebug( "got aoe act: {0}", actionData->name ); } void World::Manager::ActionMgr::handleTargetedPlayerAction( Entity::Player& player, uint8_t type, - Data::ActionPtr action, uint64_t targetId ) + uint32_t actionId, Data::ActionPtr actionData, uint64_t targetId ) { - player.sendDebug( "got act: {0}", action->name ); + player.sendDebug( "got act: {0}", actionData->name ); + + auto action = Action::make_Action( player.getAsPlayer(), nullptr, actionId, actionData, framework() ); + action->setType( static_cast< Common::ActionType >( type ) ); + + bootstrapAction( player, action, *actionData ); +} + +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; + + // todo: check class/job reqs + + // todo: min tp + // todo: min mp + + // todo: script callback for action conditionals? + + return true; } \ No newline at end of file diff --git a/src/world/Manager/ActionMgr.h b/src/world/Manager/ActionMgr.h index 0e06ce31..c40f5e8a 100644 --- a/src/world/Manager/ActionMgr.h +++ b/src/world/Manager/ActionMgr.h @@ -6,7 +6,7 @@ namespace Sapphire::Data { - class Action; + struct Action; using ActionPtr = std::shared_ptr< Action >; } @@ -18,8 +18,14 @@ namespace Sapphire::World::Manager explicit ActionMgr( FrameworkPtr pFw ); ~ActionMgr() = default; - void handleTargetedPlayerAction( Entity::Player& player, uint8_t type, Data::ActionPtr action, uint64_t targetId ); - void handleAoEPlayerAction( Entity::Player& player, uint8_t type, Data::ActionPtr action, Common::FFXIVARR_POSITION3 pos ); + void handleTargetedPlayerAction( Entity::Player& player, uint8_t type, uint32_t actionId, + Data::ActionPtr actionData, uint64_t targetId ); + void handleAoEPlayerAction( Entity::Player& player, uint8_t type, uint32_t actionId, + Data::ActionPtr actionData, Common::FFXIVARR_POSITION3 pos ); + + private: + void bootstrapAction( Entity::Player& player, Action::ActionPtr currentAction, Data::Action& actionData ); + bool canPlayerUseAction( Entity::Player& player, Action::Action& currentAction, Data::Action& actionData ); }; } diff --git a/src/world/Network/Handlers/ActionHandler.cpp b/src/world/Network/Handlers/ActionHandler.cpp index 5ca1a98c..3283813c 100644 --- a/src/world/Network/Handlers/ActionHandler.cpp +++ b/src/world/Network/Handlers/ActionHandler.cpp @@ -35,7 +35,7 @@ void Sapphire::Network::GameConnection::actionHandler( FrameworkPtr pFw, return; auto actionMgr = pFw->get< World::Manager::ActionMgr >(); - actionMgr->handleTargetedPlayerAction( player, type, action, targetId ); + actionMgr->handleTargetedPlayerAction( player, type, actionId, action, targetId ); player.sendDebug( "Skill type: {0}, sequence: {1}, actionId: {2}, targetId: {3}", type, sequence, actionId, targetId ); } @@ -61,7 +61,7 @@ void Sapphire::Network::GameConnection::aoeActionHandler( FrameworkPtr pFw, return; auto actionMgr = pFw->get< World::Manager::ActionMgr >(); - actionMgr->handleAoEPlayerAction( player, type, action, pos ); + actionMgr->handleAoEPlayerAction( player, type, actionId, action, pos ); player.sendDebug( "Skill type: {0}, sequence: {1}, actionId: {2}, x:{3}, y:{4}, z:{5}", type, sequence, actionId, pos.x, pos.y, pos.z ); From e3c0ae740389e98811e325152ed1a619595b858f Mon Sep 17 00:00:00 2001 From: NotAdam Date: Sat, 9 Feb 2019 15:45:02 +1100 Subject: [PATCH 11/63] fix a crash where m_pTarget was invalid --- src/world/Action/Action.cpp | 4 ++-- src/world/Manager/ActionMgr.cpp | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/world/Action/Action.cpp b/src/world/Action/Action.cpp index 65cf285e..0838cd21 100644 --- a/src/world/Action/Action.cpp +++ b/src/world/Action/Action.cpp @@ -127,14 +127,14 @@ void Sapphire::Action::Action::onStart() { m_pSource->getAsPlayer()->sendDebug( "onStart()" ); - auto castPacket = makeZonePacket< FFXIVIpcActorCast >( getId() ); + auto castPacket = makeZonePacket< Server::FFXIVIpcActorCast >( getId() ); castPacket->data().action_id = m_id; castPacket->data().skillType = Common::SkillType::Normal; castPacket->data().unknown_1 = m_id; // This is used for the cast bar above the target bar of the caster. castPacket->data().cast_time = m_castTime / 1000.f; - castPacket->data().target_id = m_pTarget->getId(); + castPacket->data().target_id = m_targetId; m_pSource->sendToInRangeSet( castPacket, true ); m_pSource->getAsPlayer()->setStateFlag( PlayerStateFlag::Casting ); diff --git a/src/world/Manager/ActionMgr.cpp b/src/world/Manager/ActionMgr.cpp index 45723cc9..75c6dec0 100644 --- a/src/world/Manager/ActionMgr.cpp +++ b/src/world/Manager/ActionMgr.cpp @@ -27,7 +27,7 @@ void World::Manager::ActionMgr::handleTargetedPlayerAction( Entity::Player& play { player.sendDebug( "got act: {0}", actionData->name ); - auto action = Action::make_Action( player.getAsPlayer(), nullptr, actionId, actionData, framework() ); + auto action = Action::make_Action( player.getAsPlayer(), actionId, actionData, framework() ); action->setType( static_cast< Common::ActionType >( type ) ); bootstrapAction( player, action, *actionData ); From 6b41b8eb85acf461c5a4c6859d6765f3a33fc064 Mon Sep 17 00:00:00 2001 From: NotAdam Date: Sat, 9 Feb 2019 16:50:04 +1100 Subject: [PATCH 12/63] remove scriptloader files from git --- src/scripts/action/ScriptLoader.cpp | 17 - src/scripts/common/ScriptLoader.cpp | 47 --- src/scripts/instances/ScriptLoader.cpp | 549 ------------------------- src/scripts/opening/ScriptLoader.cpp | 19 - src/scripts/quest/ScriptLoader.cpp | 97 ----- 5 files changed, 729 deletions(-) delete mode 100644 src/scripts/action/ScriptLoader.cpp delete mode 100644 src/scripts/common/ScriptLoader.cpp delete mode 100644 src/scripts/instances/ScriptLoader.cpp delete mode 100644 src/scripts/opening/ScriptLoader.cpp delete mode 100644 src/scripts/quest/ScriptLoader.cpp diff --git a/src/scripts/action/ScriptLoader.cpp b/src/scripts/action/ScriptLoader.cpp deleted file mode 100644 index 53a1a372..00000000 --- a/src/scripts/action/ScriptLoader.cpp +++ /dev/null @@ -1,17 +0,0 @@ -#include