1
Fork 0
mirror of https://github.com/SapphireServer/Sapphire.git synced 2025-05-06 02:37:47 +00:00

[wip] Implement minions

This commit is contained in:
Lucy 2023-01-23 21:39:12 +01:00
parent 0a5a556186
commit 8f0c517514
10 changed files with 69 additions and 4 deletions

View file

@ -922,6 +922,7 @@ namespace Sapphire::Common
{ {
KeyItemAction = 1, KeyItemAction = 1,
ItemActionVFX = 852, ItemActionVFX = 852,
ItemActionCompanion = 853,
ItemActionVFX2 = 944, ItemActionVFX2 = 944,
ItemActionMount = 1322, ItemActionMount = 1322,
}; };

View file

@ -58,6 +58,13 @@ void ItemAction::execute()
break; break;
} }
case Common::ItemActionType::ItemActionCompanion:
{
handleCompanionItem();
break;
}
} }
} }
@ -81,6 +88,15 @@ void ItemAction::handleVFXItem()
m_pSource->sendToInRangeSet( effectPacket, true ); 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() void ItemAction::handleMountItem()
{ {
auto player = getSourceChara()->getAsPlayer(); auto player = getSourceChara()->getAsPlayer();

View file

@ -27,6 +27,8 @@ namespace Sapphire::World::Action
private: private:
void handleVFXItem(); void handleVFXItem();
void handleCompanionItem();
void handleMountItem(); void handleMountItem();
private: private:

View file

@ -1125,6 +1125,28 @@ void Player::unlockMount( uint32_t mountId )
queuePacket( makeActorControlSelf( getId(), Network::ActorControl::SetMountBitmask, mount->data().MountOrder, 1 ) ); 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() Player::MountList& Player::getMountGuideBitmask()
{ {
return m_mountGuide; return m_mountGuide;
@ -1364,7 +1386,8 @@ void Player::setCompanion( uint8_t id )
return; return;
m_companionId = id; m_companionId = id;
sendToInRangeSet( makeActorControl( getId(), ActorControlType::ToggleCompanion, id ), true );
Service< World::Manager::PlayerMgr >::ref().onCompanionUpdate( *this, m_companionId );
} }
uint8_t Player::getCurrentCompanion() const uint8_t Player::getCurrentCompanion() const

View file

@ -459,6 +459,12 @@ namespace Sapphire::Entity
/*! unlock a mount */ /*! unlock a mount */
void unlockMount( uint32_t mountId ); 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 */ /*! return a const pointer to the setMount guide bitmask array */
MountList& getMountGuideBitmask(); MountList& getMountGuideBitmask();
@ -873,7 +879,7 @@ namespace Sapphire::Entity
uint16_t m_activeTitle{}; uint16_t m_activeTitle{};
TitleList m_titleList{}; TitleList m_titleList{};
HowToList m_howTo{}; HowToList m_howTo{};
MinionList m_minions{}; MinionList m_minionGuide{};
MountList m_mountGuide{}; MountList m_mountGuide{};
QuestComplete m_questCompleteFlags{}; QuestComplete m_questCompleteFlags{};
Discovery m_discovery{}; Discovery m_discovery{};

View file

@ -129,6 +129,9 @@ bool Sapphire::Entity::Player::loadFromDb( uint64_t characterId )
auto titleList = res->getBlobVector( "TitleList" ); auto titleList = res->getBlobVector( "TitleList" );
memcpy( reinterpret_cast< char* >( m_titleList.data() ), titleList.data(), titleList.size() ); 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" ); auto mountGuide = res->getBlobVector( "Mounts" );
memcpy( reinterpret_cast< char* >( m_mountGuide.data() ), mountGuide.data(), mountGuide.size() ); 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() ); memcpy( howToVec.data(), m_howTo.data(), m_howTo.size() );
stmt->setBinary( 40, howToVec ); stmt->setBinary( 40, howToVec );
std::vector< uint8_t > minionsVec( sizeof( m_minions ) ); std::vector< uint8_t > minionsVec( sizeof( m_minionGuide ) );
memcpy( minionsVec.data(), m_minions.data(), m_minions.size() ); memcpy( minionsVec.data(), m_minionGuide.data(), m_minionGuide.size() );
stmt->setBinary( 41, minionsVec ); stmt->setBinary( 41, minionsVec );
std::vector< uint8_t > mountsVec( sizeof( m_mountGuide ) ); std::vector< uint8_t > mountsVec( sizeof( m_mountGuide ) );

View file

@ -223,6 +223,11 @@ void PlayerMgr::onGcUpdate( Entity::Player& player )
server.queueForPlayer( player.getCharacterId(), gcAffPacket ); 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 ) void PlayerMgr::onMountUpdate( Entity::Player& player, uint32_t mountId )
{ {
if( mountId != 0 ) if( mountId != 0 )

View file

@ -44,6 +44,8 @@ class PlayerMgr
void onGcUpdate( Sapphire::Entity::Player& player ); void onGcUpdate( Sapphire::Entity::Player& player );
void onCompanionUpdate( Entity::Player& player, uint8_t companionId );
void onMountUpdate( Sapphire::Entity::Player& player, uint32_t mountId ); void onMountUpdate( Sapphire::Entity::Player& player, uint32_t mountId );
void onMobKill( Sapphire::Entity::Player& player, Sapphire::Entity::BNpc& bnpc ); void onMobKill( Sapphire::Entity::Player& player, Sapphire::Entity::BNpc& bnpc );

View file

@ -465,6 +465,11 @@ void Sapphire::Network::GameConnection::commandHandler( const Packets::FFXIVARR_
player.setCompanion( static_cast< uint8_t >( param1 ) ); player.setCompanion( static_cast< uint8_t >( param1 ) );
break; break;
} }
case PacketCommand::COMPANION_CANCEL:
{
player.setCompanion( 0 );
break;
}
case PacketCommand::REQUEST_STATUS_RESET: // Remove status (clicking it off) case PacketCommand::REQUEST_STATUS_RESET: // Remove status (clicking it off)
{ {
// todo: check if status can be removed by client from exd // todo: check if status can be removed by client from exd

View file

@ -58,6 +58,8 @@ namespace Sapphire::Network::Packets::WorldPackets::Server
// memcpy( m_data.orchestrionMask, player.getOrchestrionBitmask(), sizeof( m_data.orchestrionMask ) ); // 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.MountList, player.getMountGuideBitmask().data(), sizeof( m_data.MountList ) );
memcpy( m_data.Reward, player.getUnlockBitmask().data(), sizeof( m_data.Reward ) ); memcpy( m_data.Reward, player.getUnlockBitmask().data(), sizeof( m_data.Reward ) );