From 8f0c517514fc8b3906d11f424f716ace947b8335 Mon Sep 17 00:00:00 2001 From: Lucy <44952533+Skyliegirl33@users.noreply.github.com> Date: Mon, 23 Jan 2023 21:39:12 +0100 Subject: [PATCH] [wip] Implement minions --- src/common/Common.h | 1 + src/world/Action/ItemAction.cpp | 16 ++++++++++++ src/world/Action/ItemAction.h | 2 ++ src/world/Actor/Player.cpp | 25 ++++++++++++++++++- src/world/Actor/Player.h | 8 +++++- src/world/Actor/PlayerSql.cpp | 7 ++++-- src/world/Manager/PlayerMgr.cpp | 5 ++++ src/world/Manager/PlayerMgr.h | 2 ++ .../Network/Handlers/PacketCommandHandler.cpp | 5 ++++ .../PacketWrappers/PlayerSetupPacket.h | 2 ++ 10 files changed, 69 insertions(+), 4 deletions(-) diff --git a/src/common/Common.h b/src/common/Common.h index fa9e9e2d..86d639e3 100644 --- a/src/common/Common.h +++ b/src/common/Common.h @@ -922,6 +922,7 @@ namespace Sapphire::Common { KeyItemAction = 1, ItemActionVFX = 852, + ItemActionCompanion = 853, ItemActionVFX2 = 944, ItemActionMount = 1322, }; diff --git a/src/world/Action/ItemAction.cpp b/src/world/Action/ItemAction.cpp index f2d51d86..1e8e5678 100644 --- a/src/world/Action/ItemAction.cpp +++ b/src/world/Action/ItemAction.cpp @@ -58,6 +58,13 @@ void ItemAction::execute() break; } + + case Common::ItemActionType::ItemActionCompanion: + { + handleCompanionItem(); + + break; + } } } @@ -81,6 +88,15 @@ void ItemAction::handleVFXItem() m_pSource->sendToInRangeSet( effectPacket, true ); } +void ItemAction::handleCompanionItem() +{ + auto player = getSourceChara()->getAsPlayer(); + + Logger::debug( "Companion arg: {0}", m_itemAction->data().Calcu0Arg[ 0 ] ); + + player->unlockCompanion( m_itemAction->data().Calcu0Arg[ 0 ] ); +} + void ItemAction::handleMountItem() { auto player = getSourceChara()->getAsPlayer(); diff --git a/src/world/Action/ItemAction.h b/src/world/Action/ItemAction.h index b7add735..d1078bd9 100644 --- a/src/world/Action/ItemAction.h +++ b/src/world/Action/ItemAction.h @@ -27,6 +27,8 @@ namespace Sapphire::World::Action private: void handleVFXItem(); + void handleCompanionItem(); + void handleMountItem(); private: diff --git a/src/world/Actor/Player.cpp b/src/world/Actor/Player.cpp index fc9b52d6..c7880f65 100644 --- a/src/world/Actor/Player.cpp +++ b/src/world/Actor/Player.cpp @@ -1125,6 +1125,28 @@ void Player::unlockMount( uint32_t mountId ) queuePacket( makeActorControlSelf( getId(), Network::ActorControl::SetMountBitmask, mount->data().MountOrder, 1 ) ); } +void Player::unlockCompanion( uint32_t companionId ) +{ + auto& exdData = Common::Service< Data::ExdData >::ref(); + auto companion = exdData.getRow< Excel::Companion >( companionId ); + + //if( companion->data(). == -1 ) + // return; + + uint16_t index; + uint8_t value; + Util::valueToFlagByteIndexValue( companionId, value, index ); + + m_minionGuide[ index ] |= value; + + queuePacket( makeActorControlSelf( getId(), Network::ActorControl::LearnCompanion, companionId, 1 ) ); +} + +Player::MinionList& Player::getMinionGuideBitmask() +{ + return m_minionGuide; +} + Player::MountList& Player::getMountGuideBitmask() { return m_mountGuide; @@ -1364,7 +1386,8 @@ void Player::setCompanion( uint8_t id ) return; m_companionId = id; - sendToInRangeSet( makeActorControl( getId(), ActorControlType::ToggleCompanion, id ), true ); + + Service< World::Manager::PlayerMgr >::ref().onCompanionUpdate( *this, m_companionId ); } uint8_t Player::getCurrentCompanion() const diff --git a/src/world/Actor/Player.h b/src/world/Actor/Player.h index a393fb0d..8118431e 100644 --- a/src/world/Actor/Player.h +++ b/src/world/Actor/Player.h @@ -459,6 +459,12 @@ namespace Sapphire::Entity /*! unlock a mount */ void unlockMount( uint32_t mountId ); + /*! unlock a companion */ + void unlockCompanion( uint32_t companionId ); + + /*! return a const pointer to the minion guide bitmask array */ + MinionList& getMinionGuideBitmask(); + /*! return a const pointer to the setMount guide bitmask array */ MountList& getMountGuideBitmask(); @@ -873,7 +879,7 @@ namespace Sapphire::Entity uint16_t m_activeTitle{}; TitleList m_titleList{}; HowToList m_howTo{}; - MinionList m_minions{}; + MinionList m_minionGuide{}; MountList m_mountGuide{}; QuestComplete m_questCompleteFlags{}; Discovery m_discovery{}; diff --git a/src/world/Actor/PlayerSql.cpp b/src/world/Actor/PlayerSql.cpp index 07695d46..77ec4e01 100644 --- a/src/world/Actor/PlayerSql.cpp +++ b/src/world/Actor/PlayerSql.cpp @@ -129,6 +129,9 @@ bool Sapphire::Entity::Player::loadFromDb( uint64_t characterId ) auto titleList = res->getBlobVector( "TitleList" ); memcpy( reinterpret_cast< char* >( m_titleList.data() ), titleList.data(), titleList.size() ); + auto minionGuide = res->getBlobVector( "Minions" ); + memcpy( reinterpret_cast< char* >( m_minionGuide.data() ), minionGuide.data(), minionGuide.size() ); + auto mountGuide = res->getBlobVector( "Mounts" ); memcpy( reinterpret_cast< char* >( m_mountGuide.data() ), mountGuide.data(), mountGuide.size() ); @@ -384,8 +387,8 @@ void Sapphire::Entity::Player::updateDbChara() const memcpy( howToVec.data(), m_howTo.data(), m_howTo.size() ); stmt->setBinary( 40, howToVec ); - std::vector< uint8_t > minionsVec( sizeof( m_minions ) ); - memcpy( minionsVec.data(), m_minions.data(), m_minions.size() ); + std::vector< uint8_t > minionsVec( sizeof( m_minionGuide ) ); + memcpy( minionsVec.data(), m_minionGuide.data(), m_minionGuide.size() ); stmt->setBinary( 41, minionsVec ); std::vector< uint8_t > mountsVec( sizeof( m_mountGuide ) ); diff --git a/src/world/Manager/PlayerMgr.cpp b/src/world/Manager/PlayerMgr.cpp index 16439b7b..c43e1f85 100644 --- a/src/world/Manager/PlayerMgr.cpp +++ b/src/world/Manager/PlayerMgr.cpp @@ -223,6 +223,11 @@ void PlayerMgr::onGcUpdate( Entity::Player& player ) server.queueForPlayer( player.getCharacterId(), gcAffPacket ); } +void PlayerMgr::onCompanionUpdate( Entity::Player& player, uint8_t companionId ) +{ + player.sendToInRangeSet( makeActorControl( player.getId(), ActorControlType::ToggleCompanion, companionId ), true ); +} + void PlayerMgr::onMountUpdate( Entity::Player& player, uint32_t mountId ) { if( mountId != 0 ) diff --git a/src/world/Manager/PlayerMgr.h b/src/world/Manager/PlayerMgr.h index 91c73406..15e686a9 100644 --- a/src/world/Manager/PlayerMgr.h +++ b/src/world/Manager/PlayerMgr.h @@ -44,6 +44,8 @@ class PlayerMgr void onGcUpdate( Sapphire::Entity::Player& player ); + void onCompanionUpdate( Entity::Player& player, uint8_t companionId ); + void onMountUpdate( Sapphire::Entity::Player& player, uint32_t mountId ); void onMobKill( Sapphire::Entity::Player& player, Sapphire::Entity::BNpc& bnpc ); diff --git a/src/world/Network/Handlers/PacketCommandHandler.cpp b/src/world/Network/Handlers/PacketCommandHandler.cpp index 632b0db4..265ab496 100644 --- a/src/world/Network/Handlers/PacketCommandHandler.cpp +++ b/src/world/Network/Handlers/PacketCommandHandler.cpp @@ -465,6 +465,11 @@ void Sapphire::Network::GameConnection::commandHandler( const Packets::FFXIVARR_ player.setCompanion( static_cast< uint8_t >( param1 ) ); break; } + case PacketCommand::COMPANION_CANCEL: + { + player.setCompanion( 0 ); + break; + } case PacketCommand::REQUEST_STATUS_RESET: // Remove status (clicking it off) { // todo: check if status can be removed by client from exd diff --git a/src/world/Network/PacketWrappers/PlayerSetupPacket.h b/src/world/Network/PacketWrappers/PlayerSetupPacket.h index da562f69..d9b2a61f 100644 --- a/src/world/Network/PacketWrappers/PlayerSetupPacket.h +++ b/src/world/Network/PacketWrappers/PlayerSetupPacket.h @@ -58,6 +58,8 @@ namespace Sapphire::Network::Packets::WorldPackets::Server // memcpy( m_data.orchestrionMask, player.getOrchestrionBitmask(), sizeof( m_data.orchestrionMask ) ); + memcpy( m_data.Companion, player.getMinionGuideBitmask().data(), sizeof( m_data.Companion ) ); + memcpy( m_data.MountList, player.getMountGuideBitmask().data(), sizeof( m_data.MountList ) ); memcpy( m_data.Reward, player.getUnlockBitmask().data(), sizeof( m_data.Reward ) );