mirror of
https://github.com/SapphireServer/Sapphire.git
synced 2025-05-25 19:17:45 +00:00
Implementation of ItemAction 1322 (obtaining mounts), gear sets are set persistently and are added when unlocking classes, setLevelForClass() now properly sets the level in the database for new entries.
This commit is contained in:
parent
d3f0c04a13
commit
97e72fa61c
18 changed files with 627 additions and 19 deletions
|
@ -679,6 +679,7 @@ namespace Sapphire::Common
|
||||||
{
|
{
|
||||||
ItemActionVFX = 852,
|
ItemActionVFX = 852,
|
||||||
ItemActionVFX2 = 944,
|
ItemActionVFX2 = 944,
|
||||||
|
ItemActionMount = 1322,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum ActionEffectDisplayType : uint8_t
|
enum ActionEffectDisplayType : uint8_t
|
||||||
|
|
|
@ -31,6 +31,8 @@ namespace Sapphire::Network::ActorControl
|
||||||
DefeatMsg = 0x06,
|
DefeatMsg = 0x06,
|
||||||
GainExpMsg = 0x07,
|
GainExpMsg = 0x07,
|
||||||
|
|
||||||
|
ClassJobUpdate = 0x9,
|
||||||
|
|
||||||
LevelUpEffect = 0x0A,
|
LevelUpEffect = 0x0A,
|
||||||
|
|
||||||
ExpChainMsg = 0x0C,
|
ExpChainMsg = 0x0C,
|
||||||
|
@ -263,19 +265,21 @@ namespace Sapphire::Network::ActorControl
|
||||||
HuntingLogSectionFinish = 0x21F,
|
HuntingLogSectionFinish = 0x21F,
|
||||||
HuntingLogRankFinish = 0x220,
|
HuntingLogRankFinish = 0x220,
|
||||||
|
|
||||||
SetMaxGearSets = 0x230,
|
|
||||||
|
|
||||||
SetCharaGearParamUI = 0x260,
|
SetCharaGearParamUI = 0x260,
|
||||||
ToggleWireframeRendering = 0x261,
|
ToggleWireframeRendering = 0x261,
|
||||||
|
|
||||||
ExamineError = 0x2BF,
|
ExamineError = 0x2BF,
|
||||||
|
|
||||||
|
SetMaxGearSets = 0x320,
|
||||||
|
|
||||||
GearSetEquipMsg = 0x321,
|
GearSetEquipMsg = 0x321,
|
||||||
|
|
||||||
SetBait = 0x325, // param1: bait ID
|
SetBait = 0x325, // param1: bait ID
|
||||||
|
|
||||||
SetFestival = 0x386, // param1: festival.exd index
|
SetFestival = 0x386, // param1: festival.exd index
|
||||||
|
|
||||||
|
SetMountBitmask = 0x387, // param1: mount ID, param2: unlock/lock (1/0)
|
||||||
|
|
||||||
ToggleOrchestrionUnlock = 0x396,
|
ToggleOrchestrionUnlock = 0x396,
|
||||||
|
|
||||||
EventBattleDialog = 0x39D,
|
EventBattleDialog = 0x39D,
|
||||||
|
|
|
@ -471,6 +471,14 @@ struct FFXIVIpcCFCommenceHandler :
|
||||||
uint8_t dummy[7];
|
uint8_t dummy[7];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct FFXIVInventoryEquipRecommendedItemsHandler :
|
||||||
|
FFXIVIpcBasePacket< InventoryEquipRecommendedItems >
|
||||||
|
{
|
||||||
|
uint32_t contextId;
|
||||||
|
uint16_t storageId[14];
|
||||||
|
int16_t containerIndex[14];
|
||||||
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif //_CORE_NETWORK_PACKETS_ZONE_CLIENT_IPC_H
|
#endif //_CORE_NETWORK_PACKETS_ZONE_CLIENT_IPC_H
|
||||||
|
|
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,13 @@ void ItemAction::execute()
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case Common::ItemActionType::ItemActionMount:
|
||||||
|
{
|
||||||
|
handleMountItem();
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -55,6 +62,13 @@ 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::handleVFXItem()
|
void ItemAction::handleVFXItem()
|
||||||
{
|
{
|
||||||
Common::EffectEntry effect{};
|
Common::EffectEntry effect{};
|
||||||
|
|
|
@ -27,6 +27,8 @@ namespace Sapphire::World::Action
|
||||||
private:
|
private:
|
||||||
void handleVFXItem();
|
void handleVFXItem();
|
||||||
|
|
||||||
|
void handleMountItem();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Sapphire::Data::ItemActionPtr m_itemAction;
|
Sapphire::Data::ItemActionPtr m_itemAction;
|
||||||
|
|
||||||
|
|
|
@ -858,6 +858,13 @@ void Sapphire::Entity::Player::setExp( uint32_t amount )
|
||||||
m_expArray[ classJobIndex ] = 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
|
bool Sapphire::Entity::Player::isInCombat() const
|
||||||
{
|
{
|
||||||
return m_bInCombat;
|
return m_bInCombat;
|
||||||
|
@ -909,9 +916,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;
|
uint8_t classJobIndex = exdData.get< Sapphire::Data::ClassJob >( static_cast< uint8_t >( classjob ) )->expArrayIndex;
|
||||||
|
|
||||||
if( m_classArray[ classJobIndex ] == 0 )
|
if( m_classArray[ classJobIndex ] == 0 )
|
||||||
insertDbClass( classJobIndex );
|
insertDbClass( classJobIndex, level );
|
||||||
|
|
||||||
m_classArray[ classJobIndex ] = level;
|
m_classArray[ classJobIndex ] = level;
|
||||||
|
|
||||||
|
queuePacket( makeActorControlSelf( getId(), Network::ActorControl::ClassJobUpdate, static_cast< uint8_t >( classjob ), level ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
void Sapphire::Entity::Player::sendModel()
|
void Sapphire::Entity::Player::sendModel()
|
||||||
|
@ -1287,6 +1296,19 @@ const uint8_t* Sapphire::Entity::Player::getMountGuideBitmask() const
|
||||||
return m_mountGuide;
|
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
|
const bool Sapphire::Entity::Player::hasMount( uint32_t mountId ) const
|
||||||
{
|
{
|
||||||
auto& exdData = Common::Service< Data::ExdDataGenerated >::ref();
|
auto& exdData = Common::Service< Data::ExdDataGenerated >::ref();
|
||||||
|
@ -1563,6 +1585,13 @@ void Sapphire::Entity::Player::setTitle( uint16_t titleId )
|
||||||
sendToInRangeSet( makeActorControl( getId(), SetTitle, titleId ), true );
|
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 )
|
void Sapphire::Entity::Player::setEquipDisplayFlags( uint8_t state )
|
||||||
{
|
{
|
||||||
m_equipDisplayFlags = state;
|
m_equipDisplayFlags = state;
|
||||||
|
@ -1571,6 +1600,11 @@ void Sapphire::Entity::Player::setEquipDisplayFlags( uint8_t state )
|
||||||
sendToInRangeSet( paramPacket, true );
|
sendToInRangeSet( paramPacket, true );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint8_t Sapphire::Entity::Player::getEquippedMannequin() const
|
||||||
|
{
|
||||||
|
return m_equippedMannequin;
|
||||||
|
}
|
||||||
|
|
||||||
uint8_t Sapphire::Entity::Player::getEquipDisplayFlags() const
|
uint8_t Sapphire::Entity::Player::getEquipDisplayFlags() const
|
||||||
{
|
{
|
||||||
return m_equipDisplayFlags;
|
return m_equipDisplayFlags;
|
||||||
|
@ -1779,6 +1813,7 @@ void Sapphire::Entity::Player::sendZonePackets()
|
||||||
if( isLogin() )
|
if( isLogin() )
|
||||||
{
|
{
|
||||||
queuePacket( makeActorControlSelf( getId(), SetCharaGearParamUI, m_equipDisplayFlags, 1 ) );
|
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 )
|
// set flags, will be reset automatically by zoning ( only on client side though )
|
||||||
|
|
|
@ -404,6 +404,9 @@ namespace Sapphire::Entity
|
||||||
/*! sets the exp of the currently active class / job */
|
/*! sets the exp of the currently active class / job */
|
||||||
void setExp( uint32_t amount );
|
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 */
|
/*! adds exp to the currently active class / job */
|
||||||
void gainExp( uint32_t amount );
|
void gainExp( uint32_t amount );
|
||||||
|
|
||||||
|
@ -573,6 +576,12 @@ namespace Sapphire::Entity
|
||||||
/*! change gear param state */
|
/*! change gear param state */
|
||||||
void setEquipDisplayFlags( uint8_t 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 */
|
/*! get gear param state */
|
||||||
uint8_t getEquipDisplayFlags() const;
|
uint8_t getEquipDisplayFlags() const;
|
||||||
|
|
||||||
|
@ -657,6 +666,8 @@ namespace Sapphire::Entity
|
||||||
/*! return a const pointer to the mount guide bitmask array */
|
/*! return a const pointer to the mount guide bitmask array */
|
||||||
const uint8_t* getMountGuideBitmask() const;
|
const uint8_t* getMountGuideBitmask() const;
|
||||||
|
|
||||||
|
void unlockMount( uint32_t mountId );
|
||||||
|
|
||||||
const bool hasMount( uint32_t mountId ) const;
|
const bool hasMount( uint32_t mountId ) const;
|
||||||
|
|
||||||
bool checkAction() override;
|
bool checkAction() override;
|
||||||
|
@ -744,6 +755,9 @@ namespace Sapphire::Entity
|
||||||
/*! send the entire inventory sequence */
|
/*! send the entire inventory sequence */
|
||||||
void sendInventory();
|
void sendInventory();
|
||||||
|
|
||||||
|
/* send only the gear inventory */
|
||||||
|
void sendGearInventory();
|
||||||
|
|
||||||
/*! send active quest list */
|
/*! send active quest list */
|
||||||
void sendQuestInfo();
|
void sendQuestInfo();
|
||||||
|
|
||||||
|
@ -896,7 +910,7 @@ namespace Sapphire::Entity
|
||||||
|
|
||||||
void updateDbClass() const;
|
void updateDbClass() const;
|
||||||
|
|
||||||
void insertDbClass( const uint8_t classJobIndex ) const;
|
void insertDbClass( const uint8_t classJobIndex, const uint8_t classJobLevel = 1 ) const;
|
||||||
|
|
||||||
void setMarkedForRemoval();
|
void setMarkedForRemoval();
|
||||||
|
|
||||||
|
@ -935,7 +949,7 @@ namespace Sapphire::Entity
|
||||||
ItemPtr addItem( uint32_t catalogId, uint32_t quantity = 1, bool isHq = false, bool silent = false, bool canMerge = true, bool sendLootMessage = false );
|
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 );
|
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 );
|
||||||
|
|
||||||
|
@ -950,6 +964,8 @@ namespace Sapphire::Entity
|
||||||
|
|
||||||
bool updateContainer( uint16_t storageId, uint8_t slotId, ItemPtr pItem );
|
bool updateContainer( uint16_t storageId, uint8_t slotId, ItemPtr pItem );
|
||||||
|
|
||||||
|
bool updateGearContainer( uint8_t slotId, ItemPtr pItem );
|
||||||
|
|
||||||
/*! calculate and return player ilvl based off equipped gear */
|
/*! calculate and return player ilvl based off equipped gear */
|
||||||
uint16_t calculateEquippedGearItemLevel();
|
uint16_t calculateEquippedGearItemLevel();
|
||||||
|
|
||||||
|
@ -1054,6 +1070,8 @@ namespace Sapphire::Entity
|
||||||
|
|
||||||
uint8_t m_voice;
|
uint8_t m_voice;
|
||||||
|
|
||||||
|
uint8_t m_equippedMannequin;
|
||||||
|
|
||||||
uint64_t m_modelMainWeapon;
|
uint64_t m_modelMainWeapon;
|
||||||
uint64_t m_modelSubWeapon;
|
uint64_t m_modelSubWeapon;
|
||||||
uint64_t m_modelSystemWeapon;
|
uint64_t m_modelSystemWeapon;
|
||||||
|
|
|
@ -436,6 +436,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 )
|
Sapphire::Entity::Player::InvSlotPairVec Sapphire::Entity::Player::getSlotsOfItemsInInventory( uint32_t catalogId )
|
||||||
{
|
{
|
||||||
InvSlotPairVec outVec;
|
InvSlotPairVec outVec;
|
||||||
|
@ -710,7 +718,7 @@ Sapphire::ItemPtr Sapphire::Entity::Player::addItem( uint32_t catalogId, uint32_
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
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 );
|
auto tmpItem = m_storageMap[ fromInventoryId ]->getItem( fromSlotId );
|
||||||
|
@ -729,16 +737,25 @@ Sapphire::Entity::Player::moveItem( uint16_t fromInventoryId, uint8_t fromSlotId
|
||||||
writeInventory( static_cast< InventoryType >( fromInventoryId ) );
|
writeInventory( static_cast< InventoryType >( fromInventoryId ) );
|
||||||
|
|
||||||
if( static_cast< InventoryType >( toInventoryId ) == GearSet0 )
|
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 )
|
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 ||
|
if( static_cast< InventoryType >( toInventoryId ) == GearSet0 ||
|
||||||
static_cast< InventoryType >( fromInventoryId ) == GearSet0 )
|
static_cast< InventoryType >( fromInventoryId ) == GearSet0 )
|
||||||
sendStatusEffectUpdate(); // send if any equip is changed
|
sendStatusEffectUpdate(); // send if any equip is changed
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Sapphire::Entity::Player::updateGearContainer( uint8_t slotId, ItemPtr pItem )
|
||||||
|
{
|
||||||
|
m_storageMap[ GearSet0 ]->setItem( slotId, pItem );
|
||||||
|
|
||||||
|
writeInventory( GearSet0 );
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
bool Sapphire::Entity::Player::updateContainer( uint16_t storageId, uint8_t slotId, ItemPtr pItem )
|
bool Sapphire::Entity::Player::updateContainer( uint16_t storageId, uint8_t slotId, ItemPtr pItem )
|
||||||
{
|
{
|
||||||
auto containerType = World::Manager::ItemMgr::getContainerType( storageId );
|
auto containerType = World::Manager::ItemMgr::getContainerType( storageId );
|
||||||
|
|
|
@ -159,6 +159,8 @@ bool Sapphire::Entity::Player::load( uint32_t charId, World::SessionPtr pSession
|
||||||
|
|
||||||
m_gmRank = res->getUInt8( "GMRank" );
|
m_gmRank = res->getUInt8( "GMRank" );
|
||||||
|
|
||||||
|
m_equippedMannequin = res->getUInt8( "EquippedMannequin" );
|
||||||
|
|
||||||
m_equipDisplayFlags = res->getUInt8( "EquipDisplayFlags" );
|
m_equipDisplayFlags = res->getUInt8( "EquipDisplayFlags" );
|
||||||
|
|
||||||
m_pose = res->getUInt8( "Pose" );
|
m_pose = res->getUInt8( "Pose" );
|
||||||
|
@ -452,7 +454,7 @@ void Sapphire::Entity::Player::updateSql()
|
||||||
memcpy( orchestrionVec.data(), m_orchestrion, sizeof( m_orchestrion ) );
|
memcpy( orchestrionVec.data(), m_orchestrion, sizeof( m_orchestrion ) );
|
||||||
stmt->setBinary( 42, mountsVec );
|
stmt->setBinary( 42, mountsVec );
|
||||||
|
|
||||||
stmt->setInt( 44, 0 ); // EquippedMannequin
|
stmt->setInt( 44, m_equippedMannequin ); // EquippedMannequin
|
||||||
|
|
||||||
stmt->setInt( 45, 0 ); // DisplayFlags
|
stmt->setInt( 45, 0 ); // DisplayFlags
|
||||||
std::vector< uint8_t > questCompleteVec( sizeof( m_questCompleteFlags ) );
|
std::vector< uint8_t > questCompleteVec( sizeof( m_questCompleteFlags ) );
|
||||||
|
@ -538,14 +540,14 @@ void Sapphire::Entity::Player::updateDbMonsterNote()
|
||||||
db.execute( stmt );
|
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& db = Common::Service< Db::DbWorkerPool< Db::ZoneDbConnection > >::ref();
|
||||||
auto stmtClass = db.getPreparedStatement( Db::CHARA_CLASS_INS );
|
auto stmtClass = db.getPreparedStatement( Db::CHARA_CLASS_INS );
|
||||||
stmtClass->setInt( 1, getId() );
|
stmtClass->setInt( 1, getId() );
|
||||||
stmtClass->setInt( 2, classJobIndex );
|
stmtClass->setInt( 2, classJobIndex );
|
||||||
stmtClass->setInt( 3, 0 );
|
stmtClass->setInt( 3, 0 );
|
||||||
stmtClass->setInt( 4, 1 );
|
stmtClass->setInt( 4, classJobLevel );
|
||||||
db.directExecute( stmtClass );
|
db.directExecute( stmtClass );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -32,6 +32,7 @@ Sapphire::Item::Item( uint64_t uId, uint32_t catalogId, bool isHq ) :
|
||||||
m_block = itemInfo->block;
|
m_block = itemInfo->block;
|
||||||
m_defense = itemInfo->defensePhys;
|
m_defense = itemInfo->defensePhys;
|
||||||
m_defenseMag = itemInfo->defenseMag;
|
m_defenseMag = itemInfo->defenseMag;
|
||||||
|
m_equipSlotCategory = itemInfo->equipSlotCategory;
|
||||||
|
|
||||||
for( int i = 0; i < 6; ++i )
|
for( int i = 0; i < 6; ++i )
|
||||||
{
|
{
|
||||||
|
@ -181,6 +182,11 @@ uint32_t Sapphire::Item::getAdditionalData() const
|
||||||
return m_additionalData;
|
return m_additionalData;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint8_t Sapphire::Item::getEquipSlotCategory() const
|
||||||
|
{
|
||||||
|
return m_equipSlotCategory;
|
||||||
|
}
|
||||||
|
|
||||||
uint16_t Sapphire::Item::getSpiritbond() const
|
uint16_t Sapphire::Item::getSpiritbond() const
|
||||||
{
|
{
|
||||||
return m_spiritBond;
|
return m_spiritBond;
|
||||||
|
|
|
@ -76,6 +76,8 @@ namespace Sapphire
|
||||||
|
|
||||||
uint32_t getAdditionalData() const;
|
uint32_t getAdditionalData() const;
|
||||||
|
|
||||||
|
uint8_t getEquipSlotCategory() const;
|
||||||
|
|
||||||
void setSpiritbond( uint16_t spiritbond );
|
void setSpiritbond( uint16_t spiritbond );
|
||||||
uint16_t getSpiritbond() const;
|
uint16_t getSpiritbond() const;
|
||||||
|
|
||||||
|
@ -117,6 +119,7 @@ namespace Sapphire
|
||||||
uint32_t m_defenseMag;
|
uint32_t m_defenseMag;
|
||||||
|
|
||||||
uint32_t m_additionalData;
|
uint32_t m_additionalData;
|
||||||
|
uint8_t m_equipSlotCategory;
|
||||||
|
|
||||||
BaseParamStruct m_baseParam[6];
|
BaseParamStruct m_baseParam[6];
|
||||||
|
|
||||||
|
|
|
@ -138,6 +138,8 @@ Sapphire::Network::GameConnection::GameConnection( Sapphire::Network::HivePtr pH
|
||||||
setZoneHandler( ClientZoneIpcType::WorldInteractionHandler, "WorldInteractionHandler", &GameConnection::worldInteractionhandler );
|
setZoneHandler( ClientZoneIpcType::WorldInteractionHandler, "WorldInteractionHandler", &GameConnection::worldInteractionhandler );
|
||||||
setZoneHandler( ClientZoneIpcType::Dive, "Dive", &GameConnection::diveHandler );
|
setZoneHandler( ClientZoneIpcType::Dive, "Dive", &GameConnection::diveHandler );
|
||||||
|
|
||||||
|
setZoneHandler( ClientZoneIpcType::InventoryEquipRecommendedItems, "InventoryEquipRecommendedItemsHandler", &GameConnection::inventoryEquipRecommendedItemsHandler );
|
||||||
|
|
||||||
setChatHandler( ClientChatIpcType::TellReq, "TellReq", &GameConnection::tellHandler );
|
setChatHandler( ClientChatIpcType::TellReq, "TellReq", &GameConnection::tellHandler );
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -196,6 +196,8 @@ namespace Sapphire::Network
|
||||||
DECLARE_HANDLER( diveHandler );
|
DECLARE_HANDLER( diveHandler );
|
||||||
|
|
||||||
DECLARE_HANDLER( eventYieldHandler );
|
DECLARE_HANDLER( eventYieldHandler );
|
||||||
|
|
||||||
|
DECLARE_HANDLER( inventoryEquipRecommendedItemsHandler );
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -38,6 +38,7 @@
|
||||||
#include "Network/PacketWrappers/EventStartPacket.h"
|
#include "Network/PacketWrappers/EventStartPacket.h"
|
||||||
#include "Network/PacketWrappers/EventFinishPacket.h"
|
#include "Network/PacketWrappers/EventFinishPacket.h"
|
||||||
#include "Network/PacketWrappers/PlayerStateFlagsPacket.h"
|
#include "Network/PacketWrappers/PlayerStateFlagsPacket.h"
|
||||||
|
#include "Network/PacketWrappers/UpdateInventorySlotPacket.h"
|
||||||
|
|
||||||
#include "Manager/DebugCommandMgr.h"
|
#include "Manager/DebugCommandMgr.h"
|
||||||
#include "Manager/EventMgr.h"
|
#include "Manager/EventMgr.h"
|
||||||
|
@ -47,6 +48,7 @@
|
||||||
#include "Manager/RNGMgr.h"
|
#include "Manager/RNGMgr.h"
|
||||||
|
|
||||||
#include "Action/Action.h"
|
#include "Action/Action.h"
|
||||||
|
#include "Inventory/Item.h"
|
||||||
|
|
||||||
#include "Session.h"
|
#include "Session.h"
|
||||||
#include "ServerMgr.h"
|
#include "ServerMgr.h"
|
||||||
|
@ -929,3 +931,121 @@ void Sapphire::Network::GameConnection::diveHandler( const Packets::FFXIVARR_PAC
|
||||||
setPos->data().unknown1 = 0;
|
setPos->data().unknown1 = 0;
|
||||||
player.queuePacket( setPos ); // need delay, same as above.
|
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 );
|
||||||
|
const auto sequence = player.getNextInventorySequence();
|
||||||
|
|
||||||
|
// Loop over all swapped pieces
|
||||||
|
for (int slot = 0; slot < 14; slot++ )
|
||||||
|
{
|
||||||
|
const auto fromSlot = packet.data().containerIndex[ slot ];
|
||||||
|
const auto fromContainer = packet.data().storageId[ slot ];
|
||||||
|
|
||||||
|
player.sendDebug( "Container: {} ", fromContainer );
|
||||||
|
player.sendDebug( "Slot: {} ", fromSlot );
|
||||||
|
|
||||||
|
const auto fromItem = fromSlot == -1 ? nullptr : player.getItemAt( fromContainer, fromSlot );
|
||||||
|
const auto equippedItem = player.getItemAt( Common::GearSet0, slot );
|
||||||
|
|
||||||
|
if ( fromItem )
|
||||||
|
{
|
||||||
|
auto slotUpdate = std::make_shared< UpdateInventorySlotPacket >( player.getId(), fromSlot, fromContainer, *fromItem, slot );
|
||||||
|
player.queuePacket( slotUpdate );
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( equippedItem )
|
||||||
|
{
|
||||||
|
auto slotUpdate2 = std::make_shared< UpdateInventorySlotPacket >( player.getId(), slot, Common::GearSet0, *equippedItem, slot + 1 );
|
||||||
|
player.queuePacket( slotUpdate2 );
|
||||||
|
|
||||||
|
//player.updateModels( static_cast< Common::GearSetSlot >( slot ), equippedItem, true );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Loop over all the changed items
|
||||||
|
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 )
|
||||||
|
{
|
||||||
|
auto invTransPacket = makeZonePacket< Server::FFXIVIpcInventoryTransaction >( player.getId() );
|
||||||
|
invTransPacket->data().sequence = sequence;
|
||||||
|
invTransPacket->data().ownerId = player.getId();
|
||||||
|
invTransPacket->data().storageId = Common::GearSet0;
|
||||||
|
invTransPacket->data().catalogId = fromItem->getId();
|
||||||
|
invTransPacket->data().stackSize = fromItem->getStackSize();
|
||||||
|
invTransPacket->data().slotId = slot;
|
||||||
|
invTransPacket->data().type = Common::InventoryOperation::Swap;
|
||||||
|
player.queuePacket( invTransPacket );
|
||||||
|
|
||||||
|
player.swapItem( fromContainer, fromSlot, Common::GearSet0, slot );
|
||||||
|
|
||||||
|
//player.updateGearContainer( slot, fromItem );
|
||||||
|
//player.updateContainer( fromContainer, fromSlot, equippedItem );
|
||||||
|
}
|
||||||
|
else if ( fromItem && !equippedItem )
|
||||||
|
{
|
||||||
|
auto invTransPacket = makeZonePacket< Server::FFXIVIpcInventoryTransaction >( player.getId() );
|
||||||
|
invTransPacket->data().sequence = sequence;
|
||||||
|
invTransPacket->data().ownerId = player.getId();
|
||||||
|
invTransPacket->data().storageId = Common::GearSet0;
|
||||||
|
invTransPacket->data().catalogId = fromItem->getId();
|
||||||
|
invTransPacket->data().stackSize = fromItem->getStackSize();
|
||||||
|
invTransPacket->data().slotId = slot;
|
||||||
|
invTransPacket->data().type = Common::InventoryOperation::Move;
|
||||||
|
player.queuePacket( invTransPacket );
|
||||||
|
|
||||||
|
player.moveItem( fromContainer, fromSlot, Common::GearSet0, slot, false );
|
||||||
|
}
|
||||||
|
else if ( !fromItem && equippedItem )
|
||||||
|
{
|
||||||
|
player.equipItem( static_cast< Common::GearSetSlot >( slot ), equippedItem, false );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Transaction finished
|
||||||
|
auto ackPacket = makeZonePacket< Server::FFXIVIpcInventoryTransactionFinish >( player.getId() );
|
||||||
|
ackPacket->data().sequenceId = sequence;
|
||||||
|
ackPacket->data().sequenceId1 = sequence;
|
||||||
|
ackPacket->data().padding = 3298534884017;
|
||||||
|
|
||||||
|
// Send the gear inventory
|
||||||
|
player.sendGearInventory();
|
||||||
|
|
||||||
|
// Send the player stats
|
||||||
|
player.sendStats();
|
||||||
|
|
||||||
|
// Send the player model
|
||||||
|
player.sendModel();
|
||||||
|
|
||||||
|
// Send status effect update
|
||||||
|
auto effectListPacket = makeZonePacket< Server::FFXIVIpcStatusEffectList >( player.getId() );
|
||||||
|
effectListPacket->data().classId = static_cast< uint8_t > ( player.getClass() );
|
||||||
|
effectListPacket->data().level1 = player.getLevel();
|
||||||
|
effectListPacket->data().level = player.getLevel();
|
||||||
|
effectListPacket->data().current_hp = player.getMaxHp();
|
||||||
|
effectListPacket->data().current_mp = player.getMaxMp();
|
||||||
|
effectListPacket->data().max_hp = player.getMaxHp();
|
||||||
|
effectListPacket->data().max_mp = player.getMaxMp();
|
||||||
|
player.sendToInRangeSet( effectListPacket, true );
|
||||||
|
|
||||||
|
// Send class info
|
||||||
|
auto classInfoPacket = makeZonePacket< FFXIVIpcUpdateClassInfo >( player.getId() );
|
||||||
|
classInfoPacket->data().classId = static_cast< uint8_t > ( player.getClass() );
|
||||||
|
classInfoPacket->data().level1 = player.getLevel();
|
||||||
|
classInfoPacket->data().level = player.getLevel();
|
||||||
|
classInfoPacket->data().nextLevelIndex = player.getLevel();
|
||||||
|
classInfoPacket->data().currentExp = player.getExp();
|
||||||
|
player.queuePacket( classInfoPacket );
|
||||||
|
}
|
|
@ -15,22 +15,22 @@ namespace Sapphire::Network::Packets::Server
|
||||||
class UpdateInventorySlotPacket : public ZoneChannelPacket< FFXIVIpcUpdateInventorySlot >
|
class UpdateInventorySlotPacket : public ZoneChannelPacket< FFXIVIpcUpdateInventorySlot >
|
||||||
{
|
{
|
||||||
public:
|
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 )
|
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 )
|
ZoneChannelPacket< FFXIVIpcUpdateInventorySlot >( playerId, playerId )
|
||||||
{
|
{
|
||||||
initialize( slot, storageId );
|
initialize( slot, storageId, sequence );
|
||||||
};
|
};
|
||||||
|
|
||||||
private:
|
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.containerId = storageId;
|
||||||
m_data.slot = slot;
|
m_data.slot = slot;
|
||||||
m_data.quantity = item.getStackSize();
|
m_data.quantity = item.getStackSize();
|
||||||
|
@ -54,9 +54,9 @@ namespace Sapphire::Network::Packets::Server
|
||||||
//uint8_t buffer5;
|
//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.containerId = storageId;
|
||||||
m_data.slot = slot;
|
m_data.slot = slot;
|
||||||
m_data.quantity = 0;
|
m_data.quantity = 0;
|
||||||
|
|
Loading…
Add table
Reference in a new issue