mirror of
https://github.com/SapphireServer/Sapphire.git
synced 2025-04-25 14:07:46 +00:00
Gearset handler, mount item action, some GLA starting quests.
This is #732 with 25eaa62fa0
merged, cleaned up and slightly modified to avoid client desync.
This commit is contained in:
parent
14860047b6
commit
ea27ff3a55
19 changed files with 630 additions and 28 deletions
|
@ -734,6 +734,8 @@ namespace Sapphire::Common
|
|||
{
|
||||
ItemActionVFX = 852,
|
||||
ItemActionVFX2 = 944,
|
||||
ItemActionMount = 1322,
|
||||
ItemActionOrchestrion = 5845,
|
||||
};
|
||||
|
||||
enum ActionEffectDisplayType : uint8_t
|
||||
|
|
|
@ -31,6 +31,8 @@ namespace Sapphire::Network::ActorControl
|
|||
DefeatMsg = 0x06,
|
||||
GainExpMsg = 0x07,
|
||||
|
||||
ClassJobUpdate = 0x9,
|
||||
|
||||
LevelUpEffect = 0x0A,
|
||||
|
||||
ExpChainMsg = 0x0C,
|
||||
|
@ -263,19 +265,21 @@ namespace Sapphire::Network::ActorControl
|
|||
HuntingLogSectionFinish = 0x21F,
|
||||
HuntingLogRankFinish = 0x220,
|
||||
|
||||
SetMaxGearSets = 0x230,
|
||||
|
||||
SetCharaGearParamUI = 0x260,
|
||||
ToggleWireframeRendering = 0x261,
|
||||
|
||||
ExamineError = 0x2BF,
|
||||
|
||||
SetMaxGearSets = 0x320,
|
||||
|
||||
GearSetEquipMsg = 0x321,
|
||||
|
||||
SetBait = 0x325, // param1: bait ID
|
||||
|
||||
SetFestival = 0x386, // param1: festival.exd index
|
||||
|
||||
SetMountBitmask = 0x387, // param1: mount ID, param2: unlock/lock (1/0)
|
||||
|
||||
ToggleOrchestrionUnlock = 0x396,
|
||||
|
||||
EventBattleDialog = 0x39D,
|
||||
|
|
|
@ -471,6 +471,14 @@ struct FFXIVIpcCFCommenceHandler :
|
|||
uint8_t padding[7];
|
||||
};
|
||||
|
||||
struct FFXIVInventoryEquipRecommendedItemsHandler :
|
||||
FFXIVIpcBasePacket< InventoryEquipRecommendedItems >
|
||||
{
|
||||
uint32_t contextId;
|
||||
uint16_t storageId[14];
|
||||
int16_t containerIndex[14];
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif //_CORE_NETWORK_PACKETS_ZONE_CLIENT_IPC_H
|
||||
|
|
|
@ -1344,7 +1344,10 @@ namespace Sapphire::Network::Packets::Server
|
|||
uint32_t catalogId;
|
||||
uint32_t someActorId;
|
||||
int32_t targetStorageId;
|
||||
uint32_t padding3[3];
|
||||
uint16_t targetSlotId;
|
||||
uint16_t padding3;
|
||||
uint32_t targetStackSize;
|
||||
uint32_t targetCatalogId;
|
||||
};
|
||||
|
||||
|
||||
|
|
65
src/scripts/quest/classquest/GLA/ClsGla001.cpp
Normal file
65
src/scripts/quest/classquest/GLA/ClsGla001.cpp
Normal file
|
@ -0,0 +1,65 @@
|
|||
// This is an automatically generated C++ script template
|
||||
// Content needs to be added by hand to make it function
|
||||
// In order for this script to be loaded, move it to the correct folder in <root>/scripts/
|
||||
|
||||
#include <Actor/Player.h>
|
||||
#include "Manager/EventMgr.h"
|
||||
#include <ScriptObject.h>
|
||||
#include <Service.h>
|
||||
|
||||
// Quest Script: ClsGla001_00177
|
||||
// Quest Name: So You Want to Be a Gladiator
|
||||
// Quest ID: 65713
|
||||
// Start NPC: 1002277
|
||||
// End NPC: 1002277
|
||||
|
||||
using namespace Sapphire;
|
||||
|
||||
class ClsGla001 : public Sapphire::ScriptAPI::EventScript
|
||||
{
|
||||
private:
|
||||
// Basic quest information
|
||||
// Quest vars / flags used
|
||||
|
||||
// Steps in this quest ( 0 is before accepting,
|
||||
// 1 is first, 255 means ready for turning it in
|
||||
enum Sequence : uint8_t
|
||||
{
|
||||
};
|
||||
|
||||
// Entities found in the script data of the quest
|
||||
|
||||
public:
|
||||
ClsGla001() : Sapphire::ScriptAPI::EventScript( 65713 ){};
|
||||
~ClsGla001() = default;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// Event Handlers
|
||||
void onTalk( uint32_t eventId, Entity::Player& player, uint64_t actorId ) override
|
||||
{
|
||||
Scene00000( player );
|
||||
}
|
||||
|
||||
|
||||
private:
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// Available Scenes in this quest, not necessarly all are used
|
||||
void Scene00000( Entity::Player& player )
|
||||
{
|
||||
auto callback = [ & ]( Entity::Player& player, const Event::SceneResult& result )
|
||||
{
|
||||
if( result.param1 > 0 && result.param2 == 1 )
|
||||
{
|
||||
if( player.giveQuestRewards( getId(), result.param3 ) )
|
||||
{
|
||||
player.finishQuest( getId() );
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
player.playScene( getId(), 0, HIDE_UI, callback );
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
EXPOSE_SCRIPT( ClsGla001 );
|
118
src/scripts/quest/classquest/GLA/ClsGla011.cpp
Normal file
118
src/scripts/quest/classquest/GLA/ClsGla011.cpp
Normal file
|
@ -0,0 +1,118 @@
|
|||
// FFXIVTheMovie.ParserV3.3
|
||||
// fake IsAnnounce table
|
||||
#include <Actor/Player.h>
|
||||
#include <ScriptObject.h>
|
||||
#include <Service.h>
|
||||
#include "Manager/TerritoryMgr.h"
|
||||
#include "Manager/EventMgr.h"
|
||||
|
||||
using namespace Sapphire;
|
||||
|
||||
class ClsGla011 : public Sapphire::ScriptAPI::EventScript
|
||||
{
|
||||
public:
|
||||
ClsGla011() : Sapphire::ScriptAPI::EventScript( 65821 ){};
|
||||
~ClsGla011() = default;
|
||||
|
||||
//SEQ_0, 1 entries
|
||||
//SEQ_255, 1 entries
|
||||
|
||||
//ACTOR0 = 1002277
|
||||
//ACTOR1 = 1001739
|
||||
static constexpr auto CLASSJOB = 1;
|
||||
//GEARSETUNLOCK = 1905
|
||||
//LOGMESSAGEMONSTERNOTEPAGEUNLOCK = 1010
|
||||
//UNLOCKIMAGECLASSGLA = 36
|
||||
|
||||
private:
|
||||
void onProgress( Entity::Player& player, uint64_t param1, uint32_t param2, uint32_t type, uint32_t param3 )
|
||||
{
|
||||
switch( player.getQuestSeq( getId() ) )
|
||||
{
|
||||
case 0:
|
||||
{
|
||||
Scene00000( player ); // Scene00000: Normal(Talk, QuestOffer, QuestAccept, TargetCanMove), id=LULUTSU
|
||||
break;
|
||||
}
|
||||
case 255:
|
||||
{
|
||||
Scene00001( player ); // Scene00001: Normal(Talk, YesNo, Message, FadeIn, QuestReward, QuestComplete, TargetCanMove, CanCancel), id=MYLLA
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
player.sendUrgent( "Sequence {} not defined.", player.getQuestSeq( getId() ) );
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public:
|
||||
void onTalk( uint32_t eventId, Entity::Player& player, uint64_t actorId ) override
|
||||
{
|
||||
auto& eventMgr = Common::Service< World::Manager::EventMgr >::ref();
|
||||
auto actor = eventMgr.mapEventActorToRealActor( static_cast< uint32_t >( actorId ) );
|
||||
onProgress( player, actorId, actor, 0, 0 );
|
||||
}
|
||||
|
||||
void onEmote( uint64_t actorId, uint32_t eventId, uint32_t emoteId, Entity::Player& player ) override
|
||||
{
|
||||
auto& eventMgr = Common::Service< World::Manager::EventMgr >::ref();
|
||||
auto actor = eventMgr.mapEventActorToRealActor( static_cast< uint32_t >( actorId ) );
|
||||
onProgress( player, actorId, actor, 1, emoteId );
|
||||
}
|
||||
|
||||
void onBNpcKill( uint32_t npcId, Entity::Player& player ) override
|
||||
{
|
||||
onProgress( player, npcId, 0, 2, 0 );
|
||||
}
|
||||
|
||||
void onWithinRange( Entity::Player& player, uint32_t eventId, uint32_t param1, float x, float y, float z ) override
|
||||
{
|
||||
onProgress( player, param1, param1, 3, 0 );
|
||||
}
|
||||
|
||||
void onEnterTerritory( Sapphire::Entity::Player& player, uint32_t eventId, uint16_t param1, uint16_t param2 ) override
|
||||
{
|
||||
onProgress( player, param1, param2, 4, 0 );
|
||||
}
|
||||
|
||||
private:
|
||||
void checkProgressSeq0( Entity::Player& player )
|
||||
{
|
||||
player.updateQuest( getId(), 255 );
|
||||
}
|
||||
|
||||
void Scene00000( Entity::Player& player )
|
||||
{
|
||||
player.sendDebug( "ClsGla011:65821 calling Scene00000: Normal(Talk, QuestOffer, QuestAccept, TargetCanMove), id=LULUTSU" );
|
||||
auto callback = [ & ]( Entity::Player& player, const Event::SceneResult& result )
|
||||
{
|
||||
if( result.param1 > 0 && result.param2 == 1 )
|
||||
{
|
||||
checkProgressSeq0( player );
|
||||
}
|
||||
};
|
||||
player.playScene( getId(), 0, HIDE_UI, callback );
|
||||
}
|
||||
|
||||
void Scene00001( Entity::Player& player )
|
||||
{
|
||||
player.sendDebug( "ClsGla011:65821 calling Scene00001: Normal(Talk, YesNo, Message, FadeIn, QuestReward, QuestComplete, TargetCanMove, CanCancel), id=MYLLA" );
|
||||
auto callback = [ & ]( Entity::Player& player, const Event::SceneResult& result )
|
||||
{
|
||||
if( result.param1 > 0 && result.param2 == 1 )
|
||||
{
|
||||
if( player.giveQuestRewards( getId(), result.param3 ) )
|
||||
{
|
||||
player.finishQuest( getId() );
|
||||
player.setEquippedMannequin( player.getEquippedMannequin() + 1 );
|
||||
player.setLevelForClass( 1, static_cast< Common::ClassJob > ( CLASSJOB ) );
|
||||
}
|
||||
}
|
||||
};
|
||||
player.playScene( getId(), 1, FADE_OUT | CONDITION_CUTSCENE | HIDE_UI, callback );
|
||||
}
|
||||
};
|
||||
|
||||
EXPOSE_SCRIPT( ClsGla011 );
|
191
src/scripts/quest/classquest/GLA/ClsGla020.cpp
Normal file
191
src/scripts/quest/classquest/GLA/ClsGla020.cpp
Normal file
|
@ -0,0 +1,191 @@
|
|||
// FFXIVTheMovie.ParserV3.3
|
||||
#include <Actor/Player.h>
|
||||
#include <ScriptObject.h>
|
||||
#include <Service.h>
|
||||
#include "Manager/TerritoryMgr.h"
|
||||
#include "Manager/EventMgr.h"
|
||||
|
||||
using namespace Sapphire;
|
||||
|
||||
class ClsGla020 : public Sapphire::ScriptAPI::EventScript
|
||||
{
|
||||
public:
|
||||
ClsGla020() : Sapphire::ScriptAPI::EventScript( 65789 ){};
|
||||
~ClsGla020() = default;
|
||||
|
||||
//SEQ_0, 1 entries
|
||||
//SEQ_1, 1 entries
|
||||
//SEQ_2, 3 entries
|
||||
//SEQ_255, 1 entries
|
||||
|
||||
//ACTOR0 = 1002277
|
||||
//ACTOR1 = 1001739
|
||||
//ENEMY0 = 351
|
||||
//ENEMY1 = 385
|
||||
//ENEMY2 = 205
|
||||
//LOGMESSAGEMONSTERNOTEPAGEUNLOCK = 1010
|
||||
//UNLOCKIMAGEMONSTERNOTE = 32
|
||||
|
||||
private:
|
||||
void onProgress( Entity::Player& player, uint64_t param1, uint32_t param2, uint32_t type, uint32_t param3 )
|
||||
{
|
||||
switch( player.getQuestSeq( getId() ) )
|
||||
{
|
||||
case 0:
|
||||
{
|
||||
Scene00000( player ); // Scene00000: Normal(Talk, YesNo, QuestOffer, QuestAccept, TargetCanMove), id=LULUTSU
|
||||
break;
|
||||
}
|
||||
case 1:
|
||||
{
|
||||
Scene00001( player ); // Scene00001: Normal(Talk, YesNo, FadeIn, TargetCanMove, CanCancel), id=MYLLA
|
||||
break;
|
||||
}
|
||||
case 2:
|
||||
{
|
||||
if( param1 == 351 || param2 == 351 ) // ENEMY0 = unknown
|
||||
{
|
||||
if( player.getQuestUI8AL( getId() ) != 3 )
|
||||
{
|
||||
player.setQuestUI8AL( getId(), player.getQuestUI8AL( getId() ) + 1 );
|
||||
checkProgressSeq2( player );
|
||||
}
|
||||
break;
|
||||
}
|
||||
if( param1 == 385 || param2 == 385 ) // ENEMY1 = unknown
|
||||
{
|
||||
if( player.getQuestUI8BH( getId() ) != 3 )
|
||||
{
|
||||
player.setQuestUI8BH( getId(), player.getQuestUI8BH( getId() ) + 1 );
|
||||
checkProgressSeq2( player );
|
||||
}
|
||||
break;
|
||||
}
|
||||
if( param1 == 205 || param2 == 205 ) // ENEMY2 = unknown
|
||||
{
|
||||
if( player.getQuestUI8BL( getId() ) != 3 )
|
||||
{
|
||||
Scene00002( player ); // Scene00002: Normal(None), id=unknown
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 255:
|
||||
{
|
||||
Scene00005( player ); // Scene00005: Normal(Talk, Message, QuestReward, QuestComplete, TargetCanMove, SystemTalk), id=MYLLA
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
player.sendUrgent( "Sequence {} not defined.", player.getQuestSeq( getId() ) );
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public:
|
||||
void onTalk( uint32_t eventId, Entity::Player& player, uint64_t actorId ) override
|
||||
{
|
||||
auto& eventMgr = Common::Service< World::Manager::EventMgr >::ref();
|
||||
auto actor = eventMgr.mapEventActorToRealActor( static_cast< uint32_t >( actorId ) );
|
||||
onProgress( player, actorId, actor, 0, 0 );
|
||||
}
|
||||
|
||||
void onEmote( uint64_t actorId, uint32_t eventId, uint32_t emoteId, Entity::Player& player ) override
|
||||
{
|
||||
auto& eventMgr = Common::Service< World::Manager::EventMgr >::ref();
|
||||
auto actor = eventMgr.mapEventActorToRealActor( static_cast< uint32_t >( actorId ) );
|
||||
onProgress( player, actorId, actor, 1, emoteId );
|
||||
}
|
||||
|
||||
void onBNpcKill( uint32_t npcId, Entity::Player& player ) override
|
||||
{
|
||||
onProgress( player, npcId, 0, 2, 0 );
|
||||
}
|
||||
|
||||
void onWithinRange( Entity::Player& player, uint32_t eventId, uint32_t param1, float x, float y, float z ) override
|
||||
{
|
||||
onProgress( player, param1, param1, 3, 0 );
|
||||
}
|
||||
|
||||
void onEnterTerritory( Sapphire::Entity::Player& player, uint32_t eventId, uint16_t param1, uint16_t param2 ) override
|
||||
{
|
||||
onProgress( player, param1, param2, 4, 0 );
|
||||
}
|
||||
|
||||
private:
|
||||
void checkProgressSeq0( Entity::Player& player )
|
||||
{
|
||||
player.updateQuest( getId(), 1 );
|
||||
}
|
||||
void checkProgressSeq1( Entity::Player& player )
|
||||
{
|
||||
player.updateQuest( getId(), 2 );
|
||||
}
|
||||
void checkProgressSeq2( Entity::Player& player )
|
||||
{
|
||||
if( player.getQuestUI8AL( getId() ) == 3 )
|
||||
if( player.getQuestUI8BH( getId() ) == 3 )
|
||||
if( player.getQuestUI8BL( getId() ) == 3 )
|
||||
{
|
||||
player.setQuestUI8AL( getId(), 0 );
|
||||
player.setQuestUI8BH( getId(), 0 );
|
||||
player.setQuestUI8BL( getId(), 0 );
|
||||
player.updateQuest( getId(), 255 );
|
||||
}
|
||||
}
|
||||
|
||||
void Scene00000( Entity::Player& player )
|
||||
{
|
||||
player.sendDebug( "ClsGla020:65789 calling Scene00000: Normal(Talk, YesNo, QuestOffer, QuestAccept, TargetCanMove), id=LULUTSU" );
|
||||
auto callback = [ & ]( Entity::Player& player, const Event::SceneResult& result )
|
||||
{
|
||||
if( result.param1 > 0 && result.param2 == 1 )
|
||||
{
|
||||
checkProgressSeq0( player );
|
||||
}
|
||||
};
|
||||
player.playScene( getId(), 0, HIDE_UI, callback );
|
||||
}
|
||||
|
||||
void Scene00001( Entity::Player& player )
|
||||
{
|
||||
player.sendDebug( "ClsGla020:65789 calling Scene00001: Normal(Talk, YesNo, FadeIn, TargetCanMove, CanCancel), id=MYLLA" );
|
||||
auto callback = [ & ]( Entity::Player& player, const Event::SceneResult& result )
|
||||
{
|
||||
if( result.param1 == 512 || ( result.param1 > 0 && result.param2 == 1 ) )
|
||||
{
|
||||
checkProgressSeq1( player );
|
||||
}
|
||||
};
|
||||
player.playScene( getId(), 1, FADE_OUT | CONDITION_CUTSCENE | HIDE_UI, callback );
|
||||
}
|
||||
|
||||
|
||||
|
||||
void Scene00002( Entity::Player& player )
|
||||
{
|
||||
player.sendDebug( "ClsGla020:65789 calling Scene00002: Normal(None), id=unknown" );
|
||||
player.setQuestUI8BL( getId(), player.getQuestUI8BL( getId() ) + 1 );
|
||||
checkProgressSeq2( player );
|
||||
}
|
||||
|
||||
void Scene00005( Entity::Player& player )
|
||||
{
|
||||
player.sendDebug( "ClsGla020:65789 calling Scene00005: Normal(Talk, Message, QuestReward, QuestComplete, TargetCanMove, SystemTalk), id=MYLLA" );
|
||||
auto callback = [ & ]( Entity::Player& player, const Event::SceneResult& result )
|
||||
{
|
||||
if( result.param1 > 0 && result.param2 == 1 )
|
||||
{
|
||||
if( player.giveQuestRewards( getId(), result.param3 ) )
|
||||
{
|
||||
player.finishQuest( getId() );
|
||||
}
|
||||
}
|
||||
};
|
||||
player.playScene( getId(), 5, HIDE_UI, callback );
|
||||
}
|
||||
};
|
||||
|
||||
EXPOSE_SCRIPT( ClsGla020 );
|
|
@ -47,6 +47,20 @@ void ItemAction::execute()
|
|||
|
||||
break;
|
||||
}
|
||||
|
||||
case Common::ItemActionType::ItemActionMount:
|
||||
{
|
||||
handleMountItem();
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case Common::ItemActionType::ItemActionOrchestrion:
|
||||
{
|
||||
handleOrchestrionItem();
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -55,6 +69,21 @@ void ItemAction::interrupt()
|
|||
|
||||
}
|
||||
|
||||
void ItemAction::handleMountItem()
|
||||
{
|
||||
auto player = getSourceChara()->getAsPlayer();
|
||||
player->unlockMount( m_itemAction->data[ 0 ] );
|
||||
player->dropInventoryItem ( static_cast< Common::InventoryType >( m_itemSourceContainer ), m_itemSourceSlot, false );
|
||||
}
|
||||
|
||||
void ItemAction::handleOrchestrionItem()
|
||||
{
|
||||
auto player = getSourceChara()->getAsPlayer();
|
||||
//player->learnSong( m_itemAction->data[ 0 ], m_itemAction->data[ 1 ] );
|
||||
//player->dropInventoryItem ( static_cast< Common::InventoryType >( m_itemSourceContainer ), m_itemSourceSlot, false );
|
||||
player->sendUrgent( "orchestrion is not aligned correctly, handleOrchestrionItem() disabled until PlayerSetup fully fixed." );
|
||||
}
|
||||
|
||||
void ItemAction::handleVFXItem()
|
||||
{
|
||||
Common::EffectEntry effect{};
|
||||
|
|
|
@ -27,6 +27,10 @@ namespace Sapphire::World::Action
|
|||
private:
|
||||
void handleVFXItem();
|
||||
|
||||
void handleMountItem();
|
||||
|
||||
void handleOrchestrionItem();
|
||||
|
||||
private:
|
||||
Sapphire::Data::ItemActionPtr m_itemAction;
|
||||
|
||||
|
|
|
@ -859,6 +859,13 @@ void Sapphire::Entity::Player::setExp( uint32_t amount )
|
|||
m_expArray[ classJobIndex ] = amount;
|
||||
}
|
||||
|
||||
void Sapphire::Entity::Player::setExp( uint8_t classId, uint32_t amount )
|
||||
{
|
||||
auto exdData = Common::Service< Data::ExdDataGenerated >::ref();
|
||||
uint8_t classJobIndex = exdData.get< Sapphire::Data::ClassJob >( static_cast< uint8_t >( classId ) )->expArrayIndex;
|
||||
m_expArray[ classJobIndex ] = amount;
|
||||
}
|
||||
|
||||
bool Sapphire::Entity::Player::isInCombat() const
|
||||
{
|
||||
return m_bInCombat;
|
||||
|
@ -910,9 +917,11 @@ void Sapphire::Entity::Player::setLevelForClass( uint8_t level, Common::ClassJob
|
|||
uint8_t classJobIndex = exdData.get< Sapphire::Data::ClassJob >( static_cast< uint8_t >( classjob ) )->expArrayIndex;
|
||||
|
||||
if( m_classArray[ classJobIndex ] == 0 )
|
||||
insertDbClass( classJobIndex );
|
||||
insertDbClass( classJobIndex, level );
|
||||
|
||||
m_classArray[ classJobIndex ] = level;
|
||||
|
||||
queuePacket( makeActorControlSelf( getId(), Network::ActorControl::ClassJobUpdate, static_cast< uint8_t >( classjob ), level ) );
|
||||
}
|
||||
|
||||
void Sapphire::Entity::Player::sendModel()
|
||||
|
@ -1288,6 +1297,19 @@ const uint8_t* Sapphire::Entity::Player::getMountGuideBitmask() const
|
|||
return m_mountGuide;
|
||||
}
|
||||
|
||||
void Sapphire::Entity::Player::unlockMount( uint32_t mountId )
|
||||
{
|
||||
auto& exdData = Common::Service< Data::ExdDataGenerated >::ref();
|
||||
auto mount = exdData.get< Data::Mount >( mountId );
|
||||
|
||||
if ( mount->order == -1 || mount->modelChara == 0 )
|
||||
return;
|
||||
|
||||
m_mountGuide[ mount->order / 8 ] |= ( 1 << ( mount->order % 8 ) );
|
||||
|
||||
queuePacket( makeActorControlSelf( getId(), Network::ActorControl::SetMountBitmask, mount->order, 1 ) );
|
||||
}
|
||||
|
||||
const bool Sapphire::Entity::Player::hasMount( uint32_t mountId ) const
|
||||
{
|
||||
auto& exdData = Common::Service< Data::ExdDataGenerated >::ref();
|
||||
|
@ -1564,6 +1586,13 @@ void Sapphire::Entity::Player::setTitle( uint16_t titleId )
|
|||
sendToInRangeSet( makeActorControl( getId(), SetTitle, titleId ), true );
|
||||
}
|
||||
|
||||
void Sapphire::Entity::Player::setEquippedMannequin( uint8_t amount )
|
||||
{
|
||||
m_equippedMannequin = amount;
|
||||
|
||||
queuePacket( makeActorControlSelf( getId(), SetMaxGearSets, m_equippedMannequin ) );
|
||||
}
|
||||
|
||||
void Sapphire::Entity::Player::setEquipDisplayFlags( uint8_t state )
|
||||
{
|
||||
m_equipDisplayFlags = state;
|
||||
|
@ -1572,6 +1601,11 @@ void Sapphire::Entity::Player::setEquipDisplayFlags( uint8_t state )
|
|||
sendToInRangeSet( paramPacket, true );
|
||||
}
|
||||
|
||||
uint8_t Sapphire::Entity::Player::getEquippedMannequin() const
|
||||
{
|
||||
return m_equippedMannequin;
|
||||
}
|
||||
|
||||
uint8_t Sapphire::Entity::Player::getEquipDisplayFlags() const
|
||||
{
|
||||
return m_equipDisplayFlags;
|
||||
|
@ -1780,6 +1814,7 @@ void Sapphire::Entity::Player::sendZonePackets()
|
|||
if( isLogin() )
|
||||
{
|
||||
queuePacket( makeActorControlSelf( getId(), SetCharaGearParamUI, m_equipDisplayFlags, 1 ) );
|
||||
queuePacket( makeActorControlSelf( getId(), SetMaxGearSets, m_equippedMannequin ) );
|
||||
}
|
||||
|
||||
// set flags, will be reset automatically by zoning ( only on client side though )
|
||||
|
|
|
@ -348,6 +348,9 @@ namespace Sapphire::Entity
|
|||
/*! send player ilvl */
|
||||
void sendItemLevel();
|
||||
|
||||
/*! calculate player ilvl */
|
||||
void calculateItemLevel();
|
||||
|
||||
/*! get the current main hand model */
|
||||
uint64_t getModelMainWeapon() const;
|
||||
|
||||
|
@ -404,6 +407,9 @@ namespace Sapphire::Entity
|
|||
/*! sets the exp of the currently active class / job */
|
||||
void setExp( uint32_t amount );
|
||||
|
||||
/*! sets the exp of the specified class / job */
|
||||
void setExp( uint8_t classId, uint32_t amount );
|
||||
|
||||
/*! adds exp to the currently active class / job */
|
||||
void gainExp( uint32_t amount );
|
||||
|
||||
|
@ -573,6 +579,12 @@ namespace Sapphire::Entity
|
|||
/*! change gear param state */
|
||||
void setEquipDisplayFlags( uint8_t state );
|
||||
|
||||
/*! set number of gear sets */
|
||||
void setEquippedMannequin( uint8_t amount );
|
||||
|
||||
/*! get number of gear sets */
|
||||
uint8_t getEquippedMannequin() const;
|
||||
|
||||
/*! get gear param state */
|
||||
uint8_t getEquipDisplayFlags() const;
|
||||
|
||||
|
@ -657,6 +669,8 @@ namespace Sapphire::Entity
|
|||
/*! return a const pointer to the mount guide bitmask array */
|
||||
const uint8_t* getMountGuideBitmask() const;
|
||||
|
||||
void unlockMount( uint32_t mountId );
|
||||
|
||||
const bool hasMount( uint32_t mountId ) const;
|
||||
|
||||
bool checkAction() override;
|
||||
|
@ -744,6 +758,9 @@ namespace Sapphire::Entity
|
|||
/*! send the entire inventory sequence */
|
||||
void sendInventory();
|
||||
|
||||
/* send only the gear inventory */
|
||||
void sendGearInventory();
|
||||
|
||||
/*! send active quest list */
|
||||
void sendQuestInfo();
|
||||
|
||||
|
@ -896,7 +913,7 @@ namespace Sapphire::Entity
|
|||
|
||||
void updateDbClass() const;
|
||||
|
||||
void insertDbClass( const uint8_t classJobIndex ) const;
|
||||
void insertDbClass( const uint8_t classJobIndex, const uint8_t classJobLevel = 1 ) const;
|
||||
|
||||
void setMarkedForRemoval();
|
||||
|
||||
|
@ -932,12 +949,14 @@ namespace Sapphire::Entity
|
|||
|
||||
InvSlotPair getFreeBagSlot();
|
||||
|
||||
InvSlotPair getFreeContainerSlot( uint32_t containerId );
|
||||
|
||||
ItemPtr addItem( uint32_t catalogId, uint32_t quantity = 1, bool isHq = false, bool silent = false, bool canMerge = true, bool sendLootMessage = false );
|
||||
ItemPtr addItem( ItemPtr itemToAdd, bool silent = false, bool canMerge = true, bool sendLootMessage = false );
|
||||
|
||||
void moveItem( uint16_t fromInventoryId, uint8_t fromSlotId, uint16_t toInventoryId, uint8_t toSlot );
|
||||
void moveItem( uint16_t fromInventoryId, uint8_t fromSlotId, uint16_t toInventoryId, uint8_t toSlot, bool sendUpdate = true );
|
||||
|
||||
void swapItem( uint16_t fromInventoryId, uint8_t fromSlotId, uint16_t toInventoryId, uint8_t toSlot );
|
||||
void swapItem( uint16_t fromInventoryId, uint8_t fromSlotId, uint16_t toInventoryId, uint8_t toSlot, bool sendUpdate = true );
|
||||
|
||||
void discardItem( uint16_t fromInventoryId, uint8_t fromSlotId );
|
||||
|
||||
|
@ -1054,6 +1073,8 @@ namespace Sapphire::Entity
|
|||
|
||||
uint8_t m_voice;
|
||||
|
||||
uint8_t m_equippedMannequin;
|
||||
|
||||
uint64_t m_modelMainWeapon;
|
||||
uint64_t m_modelSubWeapon;
|
||||
uint64_t m_modelSystemWeapon;
|
||||
|
|
|
@ -110,6 +110,11 @@ void Sapphire::Entity::Player::sendItemLevel()
|
|||
queuePacket( makeActorControl( getId(), SetItemLevel, getItemLevel(), 0 ) );
|
||||
}
|
||||
|
||||
void Sapphire::Entity::Player::calculateItemLevel()
|
||||
{
|
||||
m_itemLevel = calculateEquippedGearItemLevel();
|
||||
}
|
||||
|
||||
void Sapphire::Entity::Player::equipWeapon( ItemPtr pItem, bool updateClass )
|
||||
{
|
||||
auto& exdData = Common::Service< Sapphire::Data::ExdDataGenerated >::ref();
|
||||
|
@ -436,6 +441,14 @@ void Sapphire::Entity::Player::sendInventory()
|
|||
}
|
||||
}
|
||||
|
||||
void Sapphire::Entity::Player::sendGearInventory()
|
||||
{
|
||||
auto& invMgr = Common::Service< World::Manager::InventoryMgr >::ref();
|
||||
|
||||
invMgr.sendInventoryContainer( *this, m_storageMap[ GearSet0 ] );
|
||||
}
|
||||
|
||||
|
||||
Sapphire::Entity::Player::InvSlotPairVec Sapphire::Entity::Player::getSlotsOfItemsInInventory( uint32_t catalogId )
|
||||
{
|
||||
InvSlotPairVec outVec;
|
||||
|
@ -451,6 +464,17 @@ Sapphire::Entity::Player::InvSlotPairVec Sapphire::Entity::Player::getSlotsOfIte
|
|||
return outVec;
|
||||
}
|
||||
|
||||
Sapphire::Entity::Player::InvSlotPair Sapphire::Entity::Player::getFreeContainerSlot( uint32_t containerId )
|
||||
{
|
||||
auto freeSlot = static_cast < int8_t >( m_storageMap[ containerId ]->getFreeSlot() );
|
||||
|
||||
if( freeSlot != -1 )
|
||||
return std::make_pair( containerId, freeSlot );
|
||||
|
||||
// no room in inventory
|
||||
return std::make_pair( 0, -1 );
|
||||
}
|
||||
|
||||
Sapphire::Entity::Player::InvSlotPair Sapphire::Entity::Player::getFreeBagSlot()
|
||||
{
|
||||
for( auto i : { Bag0, Bag1, Bag2, Bag3 } )
|
||||
|
@ -717,7 +741,7 @@ Sapphire::ItemPtr Sapphire::Entity::Player::addItem( uint32_t catalogId, uint32_
|
|||
}
|
||||
|
||||
void
|
||||
Sapphire::Entity::Player::moveItem( uint16_t fromInventoryId, uint8_t fromSlotId, uint16_t toInventoryId, uint8_t toSlot )
|
||||
Sapphire::Entity::Player::moveItem( uint16_t fromInventoryId, uint8_t fromSlotId, uint16_t toInventoryId, uint8_t toSlot, bool sendUpdate )
|
||||
{
|
||||
|
||||
auto tmpItem = m_storageMap[ fromInventoryId ]->getItem( fromSlotId );
|
||||
|
@ -736,13 +760,13 @@ Sapphire::Entity::Player::moveItem( uint16_t fromInventoryId, uint8_t fromSlotId
|
|||
writeInventory( static_cast< InventoryType >( fromInventoryId ) );
|
||||
|
||||
if( static_cast< InventoryType >( toInventoryId ) == GearSet0 )
|
||||
equipItem( static_cast< GearSetSlot >( toSlot ), tmpItem, true );
|
||||
equipItem( static_cast< GearSetSlot >( toSlot ), tmpItem, sendUpdate );
|
||||
|
||||
if( static_cast< InventoryType >( fromInventoryId ) == GearSet0 )
|
||||
unequipItem( static_cast< GearSetSlot >( fromSlotId ), tmpItem, true );
|
||||
unequipItem( static_cast< GearSetSlot >( fromSlotId ), tmpItem, sendUpdate );
|
||||
|
||||
if( static_cast< InventoryType >( toInventoryId ) == GearSet0 ||
|
||||
static_cast< InventoryType >( fromInventoryId ) == GearSet0 )
|
||||
if( ( static_cast< InventoryType >( toInventoryId ) == GearSet0 ||
|
||||
static_cast< InventoryType >( fromInventoryId ) == GearSet0 ) && sendUpdate )
|
||||
sendStatusEffectUpdate(); // send if any equip is changed
|
||||
}
|
||||
|
||||
|
@ -855,7 +879,7 @@ void Sapphire::Entity::Player::mergeItem( uint16_t fromInventoryId, uint8_t from
|
|||
}
|
||||
|
||||
void Sapphire::Entity::Player::swapItem( uint16_t fromInventoryId, uint8_t fromSlotId,
|
||||
uint16_t toInventoryId, uint8_t toSlot )
|
||||
uint16_t toInventoryId, uint8_t toSlot, bool sendUpdate )
|
||||
{
|
||||
auto fromItem = m_storageMap[ fromInventoryId ]->getItem( fromSlotId );
|
||||
auto toItem = m_storageMap[ toInventoryId ]->getItem( toSlot );
|
||||
|
@ -872,8 +896,7 @@ void Sapphire::Entity::Player::swapItem( uint16_t fromInventoryId, uint8_t fromS
|
|||
{
|
||||
updateContainer( fromInventoryId, fromSlotId, nullptr );
|
||||
auto& exdData = Common::Service< Data::ExdDataGenerated >::ref();
|
||||
auto itemInfo = exdData.get< Sapphire::Data::Item >( toItem->getId() );
|
||||
fromInventoryId = World::Manager::ItemMgr::getCharaEquipSlotCategoryToArmoryId( static_cast< Common::EquipSlotCategory >( itemInfo->equipSlotCategory ) );
|
||||
fromInventoryId = World::Manager::ItemMgr::getCharaEquipSlotCategoryToArmoryId( static_cast< Common::EquipSlotCategory >( toItem->getEquipSlotCategory() ) );
|
||||
fromSlotId = static_cast < uint8_t >( m_storageMap[ fromInventoryId ]->getFreeSlot() );
|
||||
}
|
||||
|
||||
|
@ -883,8 +906,8 @@ void Sapphire::Entity::Player::swapItem( uint16_t fromInventoryId, uint8_t fromS
|
|||
updateContainer( toInventoryId, toSlot, fromItem, fromInventoryId != toInventoryId );
|
||||
updateContainer( fromInventoryId, fromSlotId, toItem );
|
||||
|
||||
if( static_cast< InventoryType >( toInventoryId ) == GearSet0 ||
|
||||
static_cast< InventoryType >( fromInventoryId ) == GearSet0 )
|
||||
if( ( static_cast< InventoryType >( toInventoryId ) == GearSet0 ||
|
||||
static_cast< InventoryType >( fromInventoryId ) == GearSet0 ) && sendUpdate )
|
||||
sendStatusEffectUpdate(); // send if any equip is changed
|
||||
}
|
||||
|
||||
|
|
|
@ -159,6 +159,8 @@ bool Sapphire::Entity::Player::load( uint32_t charId, World::SessionPtr pSession
|
|||
|
||||
m_gmRank = res->getUInt8( "GMRank" );
|
||||
|
||||
m_equippedMannequin = res->getUInt8( "EquippedMannequin" );
|
||||
|
||||
m_equipDisplayFlags = res->getUInt8( "EquipDisplayFlags" );
|
||||
|
||||
m_pose = res->getUInt8( "Pose" );
|
||||
|
@ -452,7 +454,7 @@ void Sapphire::Entity::Player::updateSql()
|
|||
memcpy( orchestrionVec.data(), m_orchestrion, sizeof( m_orchestrion ) );
|
||||
stmt->setBinary( 42, mountsVec );
|
||||
|
||||
stmt->setInt( 44, 0 ); // EquippedMannequin
|
||||
stmt->setInt( 44, m_equippedMannequin ); // EquippedMannequin
|
||||
|
||||
stmt->setInt( 45, 0 ); // DisplayFlags
|
||||
std::vector< uint8_t > questCompleteVec( sizeof( m_questCompleteFlags ) );
|
||||
|
@ -538,14 +540,14 @@ void Sapphire::Entity::Player::updateDbMonsterNote()
|
|||
db.execute( stmt );
|
||||
}
|
||||
|
||||
void Sapphire::Entity::Player::insertDbClass( const uint8_t classJobIndex ) const
|
||||
void Sapphire::Entity::Player::insertDbClass( const uint8_t classJobIndex, const uint8_t classJobLevel ) const
|
||||
{
|
||||
auto& db = Common::Service< Db::DbWorkerPool< Db::ZoneDbConnection > >::ref();
|
||||
auto stmtClass = db.getPreparedStatement( Db::CHARA_CLASS_INS );
|
||||
stmtClass->setInt( 1, getId() );
|
||||
stmtClass->setInt( 2, classJobIndex );
|
||||
stmtClass->setInt( 3, 0 );
|
||||
stmtClass->setInt( 4, 1 );
|
||||
stmtClass->setInt( 4, classJobLevel );
|
||||
db.directExecute( stmtClass );
|
||||
}
|
||||
|
||||
|
|
|
@ -32,6 +32,7 @@ Sapphire::Item::Item( uint64_t uId, uint32_t catalogId, bool isHq ) :
|
|||
m_block = itemInfo->block;
|
||||
m_defense = itemInfo->defensePhys;
|
||||
m_defenseMag = itemInfo->defenseMag;
|
||||
m_equipSlotCategory = itemInfo->equipSlotCategory;
|
||||
|
||||
for( int i = 0; i < 6; ++i )
|
||||
{
|
||||
|
@ -181,6 +182,11 @@ uint32_t Sapphire::Item::getAdditionalData() const
|
|||
return m_additionalData;
|
||||
}
|
||||
|
||||
uint8_t Sapphire::Item::getEquipSlotCategory() const
|
||||
{
|
||||
return m_equipSlotCategory;
|
||||
}
|
||||
|
||||
uint16_t Sapphire::Item::getSpiritbond() const
|
||||
{
|
||||
return m_spiritBond;
|
||||
|
|
|
@ -76,6 +76,8 @@ namespace Sapphire
|
|||
|
||||
uint32_t getAdditionalData() const;
|
||||
|
||||
uint8_t getEquipSlotCategory() const;
|
||||
|
||||
void setSpiritbond( uint16_t spiritbond );
|
||||
uint16_t getSpiritbond() const;
|
||||
|
||||
|
@ -117,6 +119,7 @@ namespace Sapphire
|
|||
uint32_t m_defenseMag;
|
||||
|
||||
uint32_t m_additionalData;
|
||||
uint8_t m_equipSlotCategory;
|
||||
|
||||
BaseParamStruct m_baseParam[6];
|
||||
|
||||
|
|
|
@ -138,6 +138,8 @@ Sapphire::Network::GameConnection::GameConnection( Sapphire::Network::HivePtr pH
|
|||
setZoneHandler( ClientZoneIpcType::WorldInteractionHandler, "WorldInteractionHandler", &GameConnection::worldInteractionhandler );
|
||||
setZoneHandler( ClientZoneIpcType::Dive, "Dive", &GameConnection::diveHandler );
|
||||
|
||||
setZoneHandler( ClientZoneIpcType::InventoryEquipRecommendedItems, "InventoryEquipRecommendedItemsHandler", &GameConnection::inventoryEquipRecommendedItemsHandler );
|
||||
|
||||
setChatHandler( ClientChatIpcType::TellReq, "TellReq", &GameConnection::tellHandler );
|
||||
|
||||
}
|
||||
|
|
|
@ -196,6 +196,8 @@ namespace Sapphire::Network
|
|||
DECLARE_HANDLER( diveHandler );
|
||||
|
||||
DECLARE_HANDLER( eventYieldHandler );
|
||||
|
||||
DECLARE_HANDLER( inventoryEquipRecommendedItemsHandler );
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -38,6 +38,7 @@
|
|||
#include "Network/PacketWrappers/EventStartPacket.h"
|
||||
#include "Network/PacketWrappers/EventFinishPacket.h"
|
||||
#include "Network/PacketWrappers/PlayerStateFlagsPacket.h"
|
||||
#include "Network/PacketWrappers/UpdateInventorySlotPacket.h"
|
||||
|
||||
#include "Manager/DebugCommandMgr.h"
|
||||
#include "Manager/EventMgr.h"
|
||||
|
@ -45,8 +46,10 @@
|
|||
#include "Manager/TerritoryMgr.h"
|
||||
#include "Manager/HousingMgr.h"
|
||||
#include "Manager/RNGMgr.h"
|
||||
#include "Manager/ItemMgr.h"
|
||||
|
||||
#include "Action/Action.h"
|
||||
#include "Inventory/Item.h"
|
||||
|
||||
#include "Session.h"
|
||||
#include "ServerMgr.h"
|
||||
|
@ -928,4 +931,85 @@ void Sapphire::Network::GameConnection::diveHandler( const Packets::FFXIVARR_PAC
|
|||
setPos->data().waitForLoad = 25;
|
||||
setPos->data().unknown1 = 0;
|
||||
player.queuePacket( setPos ); // need delay, same as above.
|
||||
}
|
||||
|
||||
// Also used for gearsets
|
||||
void Sapphire::Network::GameConnection::inventoryEquipRecommendedItemsHandler( const Packets::FFXIVARR_PACKET_RAW& inPacket, Entity::Player& player )
|
||||
{
|
||||
const auto packet = ZoneChannelPacket< Client::FFXIVInventoryEquipRecommendedItemsHandler >( inPacket );
|
||||
|
||||
// Loop over all slots
|
||||
for (int slot = 0; slot < 14; slot++ )
|
||||
{
|
||||
const auto fromSlot = packet.data().containerIndex[ slot ];
|
||||
const auto fromContainer = packet.data().storageId[ slot ];
|
||||
|
||||
if ( fromContainer == Common::GearSet0 )
|
||||
continue;
|
||||
|
||||
const auto fromItem = fromSlot == -1 ? nullptr : player.getItemAt( fromContainer, fromSlot );
|
||||
const auto equippedItem = player.getItemAt( Common::GearSet0, slot );
|
||||
|
||||
if ( fromItem && equippedItem )
|
||||
{
|
||||
player.swapItem( fromContainer, fromSlot, Common::GearSet0, slot, slot == 0 || slot == 13 );
|
||||
player.queuePacket( std::make_shared< UpdateInventorySlotPacket >( player.getId(), fromSlot, fromContainer, *equippedItem, 0 ) );
|
||||
player.queuePacket( std::make_shared< UpdateInventorySlotPacket >( player.getId(), slot, Common::GearSet0, *fromItem, 0 ) );
|
||||
}
|
||||
else if ( fromItem && !equippedItem )
|
||||
{
|
||||
player.moveItem( fromContainer, fromSlot, Common::GearSet0, slot, slot == 0 || slot == 13 );
|
||||
player.queuePacket( std::make_shared< UpdateInventorySlotPacket >( player.getId(), fromSlot, fromContainer, 0 ) );
|
||||
player.queuePacket( std::make_shared< UpdateInventorySlotPacket >( player.getId(), slot, Common::GearSet0, *fromItem, 0 ) );
|
||||
}
|
||||
else if ( !fromItem && equippedItem )
|
||||
{
|
||||
auto containerId = World::Manager::ItemMgr::getCharaEquipSlotCategoryToArmoryId( static_cast< Common::EquipSlotCategory >( equippedItem->getEquipSlotCategory() ) );
|
||||
auto freeContainerSlot = player.getFreeContainerSlot( containerId );
|
||||
if( freeContainerSlot.second > 0 )
|
||||
player.moveItem( Common::GearSet0, slot, freeContainerSlot.first, freeContainerSlot.second, slot == 0 || slot == 13 );
|
||||
else
|
||||
{
|
||||
for( int i = Common::Bag0; i <= Common::Bag3; i++ )
|
||||
{
|
||||
freeContainerSlot = player.getFreeContainerSlot( i );
|
||||
if( freeContainerSlot.second > 0 )
|
||||
break;
|
||||
}
|
||||
if( freeContainerSlot.second > 0 )
|
||||
player.moveItem( Common::GearSet0, slot, freeContainerSlot.first, freeContainerSlot.second, slot == 0 || slot == 13 );
|
||||
else
|
||||
{
|
||||
player.sendUrgent( "No free inventory space to swap out item at container:{}, slot{}", Common::GearSet0, slot );
|
||||
continue;
|
||||
}
|
||||
}
|
||||
player.queuePacket( std::make_shared< UpdateInventorySlotPacket >( player.getId(), freeContainerSlot.second, freeContainerSlot.first, *equippedItem, 0 ) );
|
||||
player.queuePacket( std::make_shared< UpdateInventorySlotPacket >( player.getId(), slot, Common::GearSet0, 0 ) );
|
||||
}
|
||||
}
|
||||
|
||||
// Send the gear inventory
|
||||
player.sendGearInventory();
|
||||
|
||||
// Send the player stats
|
||||
player.sendStats();
|
||||
|
||||
// Send the player model
|
||||
player.sendModel();
|
||||
|
||||
// Send the item level
|
||||
player.calculateItemLevel();
|
||||
player.sendItemLevel();
|
||||
|
||||
// Send status effect update
|
||||
player.sendStatusEffectUpdate();
|
||||
|
||||
if( packet.data().contextId < 0xFE ) // >= 0xFE are not geaesets
|
||||
{
|
||||
auto actorControl2 = makeZonePacket< FFXIVIpcActorControlSelf >( player.getId(), player.getId() );
|
||||
actorControl2->data().category = static_cast< uint16_t >( Network::ActorControl::GearSetEquipMsg );
|
||||
actorControl2->data().param1 = packet.data().contextId;
|
||||
player.queuePacket( actorControl2 );
|
||||
}
|
||||
}
|
|
@ -15,22 +15,22 @@ namespace Sapphire::Network::Packets::Server
|
|||
class UpdateInventorySlotPacket : public ZoneChannelPacket< FFXIVIpcUpdateInventorySlot >
|
||||
{
|
||||
public:
|
||||
UpdateInventorySlotPacket( uint32_t playerId, uint8_t slot, uint16_t storageId, const Item& item ) :
|
||||
UpdateInventorySlotPacket( uint32_t playerId, uint8_t slot, uint16_t storageId, const Item& item, uint32_t sequence = 0 ) :
|
||||
ZoneChannelPacket< FFXIVIpcUpdateInventorySlot >( playerId, playerId )
|
||||
{
|
||||
initialize( slot, storageId, item );
|
||||
initialize( slot, storageId, item, sequence );
|
||||
};
|
||||
|
||||
UpdateInventorySlotPacket( uint32_t playerId, uint8_t slot, uint16_t storageId ) :
|
||||
UpdateInventorySlotPacket( uint32_t playerId, uint8_t slot, uint16_t storageId, uint32_t sequence = 0 ) :
|
||||
ZoneChannelPacket< FFXIVIpcUpdateInventorySlot >( playerId, playerId )
|
||||
{
|
||||
initialize( slot, storageId );
|
||||
initialize( slot, storageId, sequence );
|
||||
};
|
||||
|
||||
private:
|
||||
void initialize( uint8_t slot, uint16_t storageId, const Item& item )
|
||||
void initialize( uint8_t slot, uint16_t storageId, const Item& item, uint32_t sequence )
|
||||
{
|
||||
m_data.sequence = 0;
|
||||
m_data.sequence = sequence;
|
||||
m_data.containerId = storageId;
|
||||
m_data.slot = slot;
|
||||
m_data.quantity = item.getStackSize();
|
||||
|
@ -54,9 +54,9 @@ namespace Sapphire::Network::Packets::Server
|
|||
//uint8_t buffer5;
|
||||
};
|
||||
|
||||
void initialize( uint8_t slot, uint16_t storageId )
|
||||
void initialize( uint8_t slot, uint16_t storageId, uint32_t sequence )
|
||||
{
|
||||
m_data.sequence = 0;
|
||||
m_data.sequence = sequence;
|
||||
m_data.containerId = storageId;
|
||||
m_data.slot = slot;
|
||||
m_data.quantity = 0;
|
||||
|
|
Loading…
Add table
Reference in a new issue