mirror of
https://github.com/SapphireServer/Sapphire.git
synced 2025-04-27 14:57:44 +00:00
remove WorldInteractionHandler as it turns out it's just another ClientTrigger.
handler merged and values used by WorldInteractionHandler fit perfectly in ClientTriggerType(name picked up from 3.x). also update the packet and rename params to be more consistent
This commit is contained in:
parent
24fb38c40e
commit
06d6f4db30
8 changed files with 189 additions and 248 deletions
|
@ -382,11 +382,11 @@ namespace Sapphire::Network::ActorControl
|
||||||
TitleList = 0x12F,
|
TitleList = 0x12F,
|
||||||
|
|
||||||
UpdatedSeenHowTos = 0x132,
|
UpdatedSeenHowTos = 0x132,
|
||||||
CutscenePlayed = 0x134, // param1 = cutscene id
|
CutscenePlayed = 0x134, // p1 = cutscene id
|
||||||
AllotAttribute = 0x135,
|
AllotAttribute = 0x135,
|
||||||
|
|
||||||
//ClearFieldMarkers = 0x13A,
|
//ClearFieldMarkers = 0x13A,
|
||||||
CameraMode = 0x13A, // param11 (only read lowest byte), 1 = enable, 0 = disable
|
CameraMode = 0x13A, // p1 (only read lowest byte), 1 = enable, 0 = disable
|
||||||
CharaNameReq = 0x13D, // requests character name by content id
|
CharaNameReq = 0x13D, // requests character name by content id
|
||||||
HuntingLogDetails = 0x194,
|
HuntingLogDetails = 0x194,
|
||||||
|
|
||||||
|
@ -397,10 +397,12 @@ namespace Sapphire::Network::ActorControl
|
||||||
RequestChocoboInventory = 0x1C4,
|
RequestChocoboInventory = 0x1C4,
|
||||||
|
|
||||||
EmoteReq = 0x1F4,
|
EmoteReq = 0x1F4,
|
||||||
|
EmoteWithWarp = 0x1F5,
|
||||||
EmoteCancel = 0x1F6,
|
EmoteCancel = 0x1F6,
|
||||||
PersistentEmoteCancel = 0x1F7,
|
PersistentEmoteCancel = 0x1F7,
|
||||||
|
EmoteCancelWithWarp = 0x1F8,
|
||||||
/*!
|
/*!
|
||||||
* param2 = pose ID
|
* p2 = pose ID
|
||||||
* 0 = idle pose 0 (just standing)
|
* 0 = idle pose 0 (just standing)
|
||||||
* 1 = idle pose 1
|
* 1 = idle pose 1
|
||||||
* 2-4 = idle poses 2-4
|
* 2-4 = idle poses 2-4
|
||||||
|
@ -430,9 +432,9 @@ namespace Sapphire::Network::ActorControl
|
||||||
AchievementCritReq = 0x3E8,
|
AchievementCritReq = 0x3E8,
|
||||||
AchievementList = 0x3E9,
|
AchievementList = 0x3E9,
|
||||||
|
|
||||||
SetEstateLightingLevel = 0x40B, // param1 = light level 0 - 5 maps to UI val 5-0
|
SetEstateLightingLevel = 0x40B, // p1 = light level 0 - 5 maps to UI val 5-0
|
||||||
RequestHousingBuildPreset = 0x44C,
|
RequestHousingBuildPreset = 0x44C,
|
||||||
RequestEstateExteriorRemodel = 0x044D, // param11 = land id
|
RequestEstateExteriorRemodel = 0x044D, // p1 = land id
|
||||||
RequestEstateInteriorRemodel = 0x44E,
|
RequestEstateInteriorRemodel = 0x44E,
|
||||||
RequestEstateHallRemoval = 0x44F,
|
RequestEstateHallRemoval = 0x44F,
|
||||||
RequestBuildPreset = 0x450, // no idea what this is, it gets sent with BuildPresetHandler and has the plot id in param1
|
RequestBuildPreset = 0x450, // no idea what this is, it gets sent with BuildPresetHandler and has the plot id in param1
|
||||||
|
|
|
@ -392,6 +392,7 @@ enum ClientZoneIpcType :
|
||||||
|
|
||||||
ZoneLineHandler = 0x326, // updated 6.58 hotfix 2
|
ZoneLineHandler = 0x326, // updated 6.58 hotfix 2
|
||||||
ClientTrigger = 0x035C, // updated 6.58 hotfix 2
|
ClientTrigger = 0x035C, // updated 6.58 hotfix 2
|
||||||
|
ClientTriggerEnvironment = 0x0295, // updated 6.58 hotfix 2
|
||||||
DiscoveryHandler = 0x0129, // updated 6.58 hotfix 2
|
DiscoveryHandler = 0x0129, // updated 6.58 hotfix 2
|
||||||
|
|
||||||
SkillHandler = 0x07C, // updated 6.58 hotfix 2
|
SkillHandler = 0x07C, // updated 6.58 hotfix 2
|
||||||
|
@ -436,8 +437,6 @@ enum ClientZoneIpcType :
|
||||||
UpdatePositionInstance = 0x0227, // updated 6.58 hotfix 2
|
UpdatePositionInstance = 0x0227, // updated 6.58 hotfix 2
|
||||||
|
|
||||||
PerformNoteHandler = 0x0243, // updated 5.58h
|
PerformNoteHandler = 0x0243, // updated 5.58h
|
||||||
|
|
||||||
WorldInteractionHandler = 0x0295, // updated 6.58 hotfix 2
|
|
||||||
Dive = 0x018C, // updated 6.30h
|
Dive = 0x018C, // updated 6.30h
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -37,12 +37,11 @@ struct FFXIVIpcClientTrigger :
|
||||||
{
|
{
|
||||||
/* 0000 */ uint16_t commandId;
|
/* 0000 */ uint16_t commandId;
|
||||||
/* 0002 */ uint8_t unk_2[2];
|
/* 0002 */ uint8_t unk_2[2];
|
||||||
/* 0004 */ uint32_t param11;
|
/* 0004 */ uint32_t param1;
|
||||||
/* 0008 */ uint32_t param12;
|
/* 0008 */ uint32_t param2;
|
||||||
/* 000C */ uint32_t param2;
|
/* 000C */ uint32_t param3;
|
||||||
/* 0010 */ uint32_t param4; // todo: really?
|
/* 0010 */ uint32_t param4;
|
||||||
/* 0014 */ uint32_t param5;
|
/* 0014 */ Common::FFXIVARR_POSITION3 position;
|
||||||
/* 0018 */ uint64_t param3;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct FFXIVIpcUpdatePosition :
|
struct FFXIVIpcUpdatePosition :
|
||||||
|
@ -351,17 +350,6 @@ struct FFXIVIpcFreeCompanyUpdateShortMessageHandler :
|
||||||
uint16_t unknown2;
|
uint16_t unknown2;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct FFXIVIpcWorldInteractionHandler :
|
|
||||||
FFXIVIpcBasePacket< WorldInteractionHandler >
|
|
||||||
{
|
|
||||||
uint32_t action;
|
|
||||||
uint32_t param1;
|
|
||||||
uint32_t param2;
|
|
||||||
uint32_t param3;
|
|
||||||
uint32_t param4;
|
|
||||||
Common::FFXIVARR_POSITION3 position;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct FFXIVIpcSocialInviteHandler :
|
struct FFXIVIpcSocialInviteHandler :
|
||||||
FFXIVIpcBasePacket< SocialInviteHandler >
|
FFXIVIpcBasePacket< SocialInviteHandler >
|
||||||
{
|
{
|
||||||
|
|
|
@ -2020,10 +2020,10 @@ void Sapphire::Entity::Player::finishZoning()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Sapphire::Entity::Player::emote( uint32_t emoteId, uint64_t targetId, bool isSilent )
|
void Sapphire::Entity::Player::emote( uint32_t emoteId, uint64_t targetId, bool isSilent, uint32_t rotation )
|
||||||
{
|
{
|
||||||
sendToInRangeSet( makeActorControlTarget( getId(), ActorControlType::Emote,
|
sendToInRangeSet( makeActorControlTarget( getId(), ActorControlType::Emote,
|
||||||
emoteId, 0, isSilent ? 1 : 0, 0, targetId ) );
|
emoteId, 0, isSilent ? 1 : 0, rotation, targetId ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
void Sapphire::Entity::Player::emoteInterrupt()
|
void Sapphire::Entity::Player::emoteInterrupt()
|
||||||
|
|
|
@ -791,7 +791,7 @@ namespace Sapphire::Entity
|
||||||
/*! return true if the player is marked for zoning */
|
/*! return true if the player is marked for zoning */
|
||||||
bool isMarkedForZoning() const;
|
bool isMarkedForZoning() const;
|
||||||
|
|
||||||
void emote( uint32_t emoteId, uint64_t targetId, bool isSilent );
|
void emote( uint32_t emoteId, uint64_t targetId, bool isSilent, uint32_t rotation = 0 );
|
||||||
|
|
||||||
void emoteInterrupt();
|
void emoteInterrupt();
|
||||||
|
|
||||||
|
|
|
@ -70,7 +70,7 @@ Sapphire::Network::GameConnection::GameConnection( Sapphire::Network::HivePtr pH
|
||||||
setZoneHandler( ClientZoneIpcType::ReqExamineFcInfo, "ReqExamineFcInfo", &GameConnection::reqExamineFcInfo );
|
setZoneHandler( ClientZoneIpcType::ReqExamineFcInfo, "ReqExamineFcInfo", &GameConnection::reqExamineFcInfo );
|
||||||
setZoneHandler( ClientZoneIpcType::ZoneLineHandler, "ZoneLineHandler", &GameConnection::zoneLineHandler );
|
setZoneHandler( ClientZoneIpcType::ZoneLineHandler, "ZoneLineHandler", &GameConnection::zoneLineHandler );
|
||||||
setZoneHandler( ClientZoneIpcType::ClientTrigger, "ClientTrigger", &GameConnection::clientTriggerHandler );
|
setZoneHandler( ClientZoneIpcType::ClientTrigger, "ClientTrigger", &GameConnection::clientTriggerHandler );
|
||||||
|
setZoneHandler( ClientZoneIpcType::ClientTriggerEnvironment, "ClientTriggerEnvironment", &GameConnection::clientTriggerHandler );
|
||||||
setZoneHandler( ClientZoneIpcType::DiscoveryHandler, "DiscoveryHandler", &GameConnection::discoveryHandler );
|
setZoneHandler( ClientZoneIpcType::DiscoveryHandler, "DiscoveryHandler", &GameConnection::discoveryHandler );
|
||||||
|
|
||||||
setZoneHandler( ClientZoneIpcType::SkillHandler, "ActionHandler", &GameConnection::actionHandler );
|
setZoneHandler( ClientZoneIpcType::SkillHandler, "ActionHandler", &GameConnection::actionHandler );
|
||||||
|
@ -137,7 +137,6 @@ Sapphire::Network::GameConnection::GameConnection( Sapphire::Network::HivePtr pH
|
||||||
setZoneHandler( ClientZoneIpcType::MarketBoardRequestItemListings, "MarketBoardRequestItemListings",
|
setZoneHandler( ClientZoneIpcType::MarketBoardRequestItemListings, "MarketBoardRequestItemListings",
|
||||||
&GameConnection::marketBoardRequestItemListings );
|
&GameConnection::marketBoardRequestItemListings );
|
||||||
|
|
||||||
setZoneHandler( ClientZoneIpcType::WorldInteractionHandler, "WorldInteractionHandler", &GameConnection::worldInteractionhandler );
|
|
||||||
setZoneHandler( ClientZoneIpcType::Dive, "Dive", &GameConnection::diveHandler );
|
setZoneHandler( ClientZoneIpcType::Dive, "Dive", &GameConnection::diveHandler );
|
||||||
|
|
||||||
setZoneHandler( ClientZoneIpcType::InventoryEquipRecommendedItems, "InventoryEquipRecommendedItemsHandler", &GameConnection::inventoryEquipRecommendedItemsHandler );
|
setZoneHandler( ClientZoneIpcType::InventoryEquipRecommendedItems, "InventoryEquipRecommendedItemsHandler", &GameConnection::inventoryEquipRecommendedItemsHandler );
|
||||||
|
|
|
@ -8,8 +8,12 @@
|
||||||
#include <Network/PacketDef/Zone/ClientZoneDef.h>
|
#include <Network/PacketDef/Zone/ClientZoneDef.h>
|
||||||
#include <Util/Util.h>
|
#include <Util/Util.h>
|
||||||
|
|
||||||
|
#include <datReader/DatCategories/bg/LgbTypes.h>
|
||||||
|
#include <datReader/DatCategories/bg/lgb.h>
|
||||||
|
|
||||||
#include "Territory/Territory.h"
|
#include "Territory/Territory.h"
|
||||||
#include "Territory/ZonePosition.h"
|
#include "Territory/ZonePosition.h"
|
||||||
|
#include <Territory/InstanceObjectCache.h>
|
||||||
#include "Manager/HousingMgr.h"
|
#include "Manager/HousingMgr.h"
|
||||||
|
|
||||||
#include "Network/GameConnection.h"
|
#include "Network/GameConnection.h"
|
||||||
|
@ -70,16 +74,15 @@ void Sapphire::Network::GameConnection::clientTriggerHandler( const Packets::FFX
|
||||||
const auto packet = ZoneChannelPacket< Client::FFXIVIpcClientTrigger >( inPacket );
|
const auto packet = ZoneChannelPacket< Client::FFXIVIpcClientTrigger >( inPacket );
|
||||||
|
|
||||||
const auto commandId = packet.data().commandId;
|
const auto commandId = packet.data().commandId;
|
||||||
const auto param1 = *reinterpret_cast< const uint64_t* >( &packet.data().param11 );
|
const auto p1u64 = *reinterpret_cast< const uint64_t* >( &packet.data().param1 );
|
||||||
const auto param11 = packet.data().param11;
|
const auto p1 = packet.data().param1;
|
||||||
const auto param12 = packet.data().param12;
|
const auto p2 = packet.data().param2;
|
||||||
const auto param2 = packet.data().param2;
|
const auto p3 = packet.data().param3;
|
||||||
const auto param3 = packet.data().param3;
|
const auto p4 = packet.data().param4;
|
||||||
const auto param4 = packet.data().param4;
|
const auto pos = packet.data().position;
|
||||||
const auto param5 = packet.data().param5;
|
|
||||||
|
|
||||||
Logger::debug( "[{0}] Incoming action: {1:X} ( p1:{2:X} p2:{3:X} p3:{4:X} )",
|
Logger::debug( "[{0}] Type: {1:X} (p1u64:{2:X} p1:{3} p2:{4} p3:{5} p4:{6} x:{7} y:{8} z:{9}",
|
||||||
m_pSession->getId(), commandId, param1, param2, param3 );
|
m_pSession->getId(), commandId, p1u64, p1, p2, p3, p4, pos.x, pos.y, pos.z );
|
||||||
|
|
||||||
//Logger::Log(LoggingSeverity::debug, "[" + std::to_string(m_pSession->getId()) + "] " + pInPacket->toString());
|
//Logger::Log(LoggingSeverity::debug, "[" + std::to_string(m_pSession->getId()) + "] " + pInPacket->toString());
|
||||||
|
|
||||||
|
@ -87,7 +90,7 @@ void Sapphire::Network::GameConnection::clientTriggerHandler( const Packets::FFX
|
||||||
{
|
{
|
||||||
case ClientTriggerType::ToggleSheathe: // Toggle sheathe
|
case ClientTriggerType::ToggleSheathe: // Toggle sheathe
|
||||||
{
|
{
|
||||||
if( param11 == 1 )
|
if( p1 == 1 )
|
||||||
player.setStance( Common::Stance::Active );
|
player.setStance( Common::Stance::Active );
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -95,13 +98,13 @@ void Sapphire::Network::GameConnection::clientTriggerHandler( const Packets::FFX
|
||||||
player.setAutoattack( false );
|
player.setAutoattack( false );
|
||||||
}
|
}
|
||||||
|
|
||||||
player.sendToInRangeSet( makeActorControl( player.getId(), 0, param11, 1 ) );
|
player.sendToInRangeSet( makeActorControl( player.getId(), 0, p1, 1 ) );
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case ClientTriggerType::ToggleAutoAttack: // Toggle auto-attack
|
case ClientTriggerType::ToggleAutoAttack: // Toggle auto-attack
|
||||||
{
|
{
|
||||||
if( param11 == 1 )
|
if( p1 == 1 )
|
||||||
{
|
{
|
||||||
player.setAutoattack( true );
|
player.setAutoattack( true );
|
||||||
player.setStance( Common::Stance::Active );
|
player.setStance( Common::Stance::Active );
|
||||||
|
@ -110,15 +113,15 @@ void Sapphire::Network::GameConnection::clientTriggerHandler( const Packets::FFX
|
||||||
player.setAutoattack( false );
|
player.setAutoattack( false );
|
||||||
|
|
||||||
// the client seems to ignore source actor of this packet and always set auto-attack on itself. causing everyone on screen take their weapons out
|
// the client seems to ignore source actor of this packet and always set auto-attack on itself. causing everyone on screen take their weapons out
|
||||||
player.queuePacket( makeActorControl( player.getId(), 1, param11, 1 ) );
|
player.queuePacket( makeActorControl( player.getId(), 1, p1, 1 ) );
|
||||||
//player.sendToInRangeSet( makeActorControl( player.getId(), 1, param11, 1 ) );
|
//player.sendToInRangeSet( makeActorControl( player.getId(), 1, p1, 1 ) );
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case ClientTriggerType::ChangeTarget: // Change target
|
case ClientTriggerType::ChangeTarget: // Change target
|
||||||
{
|
{
|
||||||
|
|
||||||
uint64_t targetId = param1;
|
uint64_t targetId = p1u64;
|
||||||
player.changeTarget( targetId );
|
player.changeTarget( targetId );
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -129,7 +132,7 @@ void Sapphire::Network::GameConnection::clientTriggerHandler( const Packets::FFX
|
||||||
}
|
}
|
||||||
case ClientTriggerType::SpawnCompanionReq:
|
case ClientTriggerType::SpawnCompanionReq:
|
||||||
{
|
{
|
||||||
player.spawnCompanion( static_cast< uint16_t >( param1 ) );
|
player.spawnCompanion( static_cast< uint16_t >( p1 ) );
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case ClientTriggerType::DespawnCompanionReq:
|
case ClientTriggerType::DespawnCompanionReq:
|
||||||
|
@ -140,7 +143,7 @@ void Sapphire::Network::GameConnection::clientTriggerHandler( const Packets::FFX
|
||||||
case ClientTriggerType::RemoveStatusEffect: // Remove status (clicking it off)
|
case ClientTriggerType::RemoveStatusEffect: // 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
|
||||||
player.removeSingleStatusEffectById( static_cast< uint32_t >( param1 ) );
|
player.removeSingleStatusEffectById( static_cast< uint32_t >( p1 ) );
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case ClientTriggerType::CastCancel: // Cancel cast
|
case ClientTriggerType::CastCancel: // Cancel cast
|
||||||
|
@ -151,7 +154,7 @@ void Sapphire::Network::GameConnection::clientTriggerHandler( const Packets::FFX
|
||||||
}
|
}
|
||||||
case ClientTriggerType::Examine:
|
case ClientTriggerType::Examine:
|
||||||
{
|
{
|
||||||
uint32_t targetId = param11;
|
uint32_t targetId = p1u64;
|
||||||
examineHandler( player, targetId );
|
examineHandler( player, targetId );
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -161,7 +164,7 @@ void Sapphire::Network::GameConnection::clientTriggerHandler( const Packets::FFX
|
||||||
}
|
}
|
||||||
case ClientTriggerType::SetTitleReq: // Set player title
|
case ClientTriggerType::SetTitleReq: // Set player title
|
||||||
{
|
{
|
||||||
player.setTitle( static_cast< uint16_t >( param1 ) );
|
player.setTitle( static_cast< uint16_t >( p1 ) );
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case ClientTriggerType::TitleList: // Get title list
|
case ClientTriggerType::TitleList: // Get title list
|
||||||
|
@ -171,13 +174,13 @@ void Sapphire::Network::GameConnection::clientTriggerHandler( const Packets::FFX
|
||||||
}
|
}
|
||||||
case ClientTriggerType::UpdatedSeenHowTos: // Update howtos seen
|
case ClientTriggerType::UpdatedSeenHowTos: // Update howtos seen
|
||||||
{
|
{
|
||||||
uint32_t howToId = param11;
|
uint32_t howToId = p1;
|
||||||
player.updateHowtosSeen( howToId );
|
player.updateHowtosSeen( howToId );
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case ClientTriggerType::CharaNameReq:
|
case ClientTriggerType::CharaNameReq:
|
||||||
{
|
{
|
||||||
uint64_t targetContentId = param1;
|
uint64_t targetContentId = p1u64;
|
||||||
// todo: look up player by content id
|
// todo: look up player by content id
|
||||||
/*
|
/*
|
||||||
auto packet = makeZonePacket< FFXIVIpcCharaNameReq >( player.getId() );
|
auto packet = makeZonePacket< FFXIVIpcCharaNameReq >( player.getId() );
|
||||||
|
@ -192,10 +195,11 @@ void Sapphire::Network::GameConnection::clientTriggerHandler( const Packets::FFX
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case ClientTriggerType::EmoteReq: // emote
|
case ClientTriggerType::EmoteReq: // emote
|
||||||
|
case ClientTriggerType::EmoteWithWarp:
|
||||||
{
|
{
|
||||||
uint64_t targetId = player.getTargetId();
|
uint64_t targetId = player.getTargetId();
|
||||||
uint32_t emoteId = param11;
|
uint32_t emoteId = p1;
|
||||||
bool isSilent = param2 == 1;
|
bool isSilent = p3 == 1;
|
||||||
|
|
||||||
auto& exdData = Common::Service< Data::ExdDataGenerated >::ref();
|
auto& exdData = Common::Service< Data::ExdDataGenerated >::ref();
|
||||||
auto emoteData = exdData.get< Data::Emote >( emoteId );
|
auto emoteData = exdData.get< Data::Emote >( emoteId );
|
||||||
|
@ -203,7 +207,23 @@ void Sapphire::Network::GameConnection::clientTriggerHandler( const Packets::FFX
|
||||||
if( !emoteData )
|
if( !emoteData )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
player.emote( emoteId, targetId, isSilent );
|
if( commandId == ClientTriggerType::EmoteWithWarp )
|
||||||
|
{
|
||||||
|
player.setPos( packet.data().position );
|
||||||
|
player.setRot( Util::floatFromUInt16Rot( p4 ) );
|
||||||
|
if( player.hasInRangeActor() )
|
||||||
|
{
|
||||||
|
auto setpos = makeZonePacket< FFXIVIpcActorSetPos >( player.getId() );
|
||||||
|
setpos->data().r16 = p4;
|
||||||
|
setpos->data().waitForLoad = 18;
|
||||||
|
setpos->data().x = packet.data().position.x;
|
||||||
|
setpos->data().y = packet.data().position.y;
|
||||||
|
setpos->data().z = packet.data().position.z;
|
||||||
|
player.sendToInRangeSet( setpos, false );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
player.emote( emoteId, targetId, isSilent, commandId == ClientTriggerType::EmoteWithWarp ? p4 : 0 );
|
||||||
|
|
||||||
bool isPersistent = emoteData->emoteMode != 0;
|
bool isPersistent = emoteData->emoteMode != 0;
|
||||||
|
|
||||||
|
@ -213,10 +233,6 @@ void Sapphire::Network::GameConnection::clientTriggerHandler( const Packets::FFX
|
||||||
player.setAutoattack( false );
|
player.setAutoattack( false );
|
||||||
player.setPersistentEmote( emoteData->emoteMode );
|
player.setPersistentEmote( emoteData->emoteMode );
|
||||||
player.setStatus( Common::ActorStatus::EmoteMode );
|
player.setStatus( Common::ActorStatus::EmoteMode );
|
||||||
|
|
||||||
player.sendToInRangeSet( makeActorControl( player.getId(), ActorControlType::SetStatus,
|
|
||||||
static_cast< uint8_t >( Common::ActorStatus::EmoteMode ),
|
|
||||||
emoteData->hasCancelEmote ? 1 : 0 ), true );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if( emoteData->drawsWeapon )
|
if( emoteData->drawsWeapon )
|
||||||
|
@ -226,38 +242,52 @@ void Sapphire::Network::GameConnection::clientTriggerHandler( const Packets::FFX
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case ClientTriggerType::EmoteCancel: // emote
|
case ClientTriggerType::EmoteCancel: // emote cancel
|
||||||
{
|
|
||||||
player.emoteInterrupt();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case ClientTriggerType::PersistentEmoteCancel: // cancel persistent emote
|
case ClientTriggerType::PersistentEmoteCancel: // cancel persistent emote
|
||||||
|
case ClientTriggerType::EmoteCancelWithWarp:
|
||||||
|
{
|
||||||
|
if( commandId == ClientTriggerType::EmoteCancelWithWarp )
|
||||||
|
{
|
||||||
|
player.setPos( packet.data().position );
|
||||||
|
if( player.hasInRangeActor() )
|
||||||
|
{
|
||||||
|
auto setpos = makeZonePacket< FFXIVIpcActorSetPos >( player.getId() );
|
||||||
|
setpos->data().r16 = p2;
|
||||||
|
setpos->data().waitForLoad = 18;
|
||||||
|
setpos->data().x = packet.data().position.x;
|
||||||
|
setpos->data().y = packet.data().position.y;
|
||||||
|
setpos->data().z = packet.data().position.z;
|
||||||
|
player.sendToInRangeSet( setpos, false );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
player.emoteInterrupt();
|
||||||
|
if( player.getPersistentEmote() )
|
||||||
{
|
{
|
||||||
player.setPersistentEmote( 0 );
|
player.setPersistentEmote( 0 );
|
||||||
player.emoteInterrupt();
|
|
||||||
player.setStatus( Common::ActorStatus::Idle );
|
player.setStatus( Common::ActorStatus::Idle );
|
||||||
auto pSetStatusPacket = makeActorControl( player.getId(), SetStatus, static_cast< uint8_t >( Common::ActorStatus::Idle ) );
|
auto pSetStatusPacket = makeActorControl( player.getId(), SetStatus, static_cast< uint8_t >( Common::ActorStatus::Idle ) );
|
||||||
player.sendToInRangeSet( pSetStatusPacket );
|
player.sendToInRangeSet( pSetStatusPacket );
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case ClientTriggerType::PoseChange: // change pose
|
case ClientTriggerType::PoseChange: // change pose
|
||||||
case ClientTriggerType::PoseReapply: // reapply pose
|
case ClientTriggerType::PoseReapply: // reapply pose
|
||||||
{
|
{
|
||||||
player.setPose( static_cast< uint8_t >( param12 ) );
|
player.setPose( static_cast< uint8_t >( p2 ) );
|
||||||
auto pSetStatusPacket = makeActorControl( player.getId(), SetPose, param11, param12 );
|
auto pSetStatusPacket = makeActorControl( player.getId(), SetPose, p1, p2 );
|
||||||
player.sendToInRangeSet( pSetStatusPacket, true );
|
player.sendToInRangeSet( pSetStatusPacket, true );
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case ClientTriggerType::PoseCancel: // cancel pose
|
case ClientTriggerType::PoseCancel: // cancel pose
|
||||||
{
|
{
|
||||||
player.setPose( static_cast< uint8_t >( param12 ) );
|
player.setPose( static_cast< uint8_t >( p2 ) );
|
||||||
auto pSetStatusPacket = makeActorControl( player.getId(), SetPose, param11, param12 );
|
auto pSetStatusPacket = makeActorControl( player.getId(), SetPose, p1, p2 );
|
||||||
player.sendToInRangeSet( pSetStatusPacket, false );
|
player.sendToInRangeSet( pSetStatusPacket, false );
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case ClientTriggerType::Return: // return dead / accept raise
|
case ClientTriggerType::Return: // return dead / accept raise
|
||||||
{
|
{
|
||||||
switch( static_cast < ResurrectType >( param1 ) )
|
switch( static_cast < ResurrectType >( p1 ) )
|
||||||
{
|
{
|
||||||
case ResurrectType::RaiseSpell:
|
case ResurrectType::RaiseSpell:
|
||||||
// todo: handle raise case (set position to raiser, apply weakness status, set hp/mp/tp as well as packet)
|
// todo: handle raise case (set position to raiser, apply weakness status, set hp/mp/tp as well as packet)
|
||||||
|
@ -280,16 +310,16 @@ void Sapphire::Network::GameConnection::clientTriggerHandler( const Packets::FFX
|
||||||
case ClientTriggerType::Teleport: // Teleport
|
case ClientTriggerType::Teleport: // Teleport
|
||||||
{
|
{
|
||||||
|
|
||||||
player.teleportQuery( static_cast< uint16_t >( param11 ) );
|
player.teleportQuery( static_cast< uint16_t >( p1 ) );
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case ClientTriggerType::DyeItem: // Dye item
|
case ClientTriggerType::DyeItem: // Dye item
|
||||||
{
|
{
|
||||||
// param11 = item to dye container
|
// p1 = item to dye container
|
||||||
// param12 = item to dye slot
|
// p2 = item to dye slot
|
||||||
// param2 = dye bag container
|
// p3 = dye bag container
|
||||||
// param4 = dye bag slot
|
// p4 = dye bag slot
|
||||||
player.setDyeingInfo( param11, param12, param2, param4 );
|
player.setDyeingInfo( p1, p2, p3, p4 );
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case ClientTriggerType::DirectorInitFinish: // Director init finish
|
case ClientTriggerType::DirectorInitFinish: // Director init finish
|
||||||
|
@ -315,7 +345,7 @@ void Sapphire::Network::GameConnection::clientTriggerHandler( const Packets::FFX
|
||||||
}
|
}
|
||||||
case ClientTriggerType::AbandonQuest:
|
case ClientTriggerType::AbandonQuest:
|
||||||
{
|
{
|
||||||
player.removeQuest( static_cast< uint16_t >( param1 ) );
|
player.removeQuest( static_cast< uint16_t >( p1 ) );
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case ClientTriggerType::RequestHousingBuildPreset:
|
case ClientTriggerType::RequestHousingBuildPreset:
|
||||||
|
@ -325,9 +355,9 @@ void Sapphire::Network::GameConnection::clientTriggerHandler( const Packets::FFX
|
||||||
if (!hZone)
|
if (!hZone)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
player.setActiveLand( static_cast< uint8_t >( param11 ), hZone->getWardNum() );
|
player.setActiveLand( static_cast< uint8_t >( p1 ), hZone->getWardNum() );
|
||||||
|
|
||||||
auto pShowBuildPresetUIPacket = makeActorControl( player.getId(), ShowBuildPresetUI, param11 );
|
auto pShowBuildPresetUIPacket = makeActorControl( player.getId(), ShowBuildPresetUI, p1 );
|
||||||
player.queuePacket( pShowBuildPresetUIPacket );
|
player.queuePacket( pShowBuildPresetUIPacket );
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
@ -336,7 +366,7 @@ void Sapphire::Network::GameConnection::clientTriggerHandler( const Packets::FFX
|
||||||
{
|
{
|
||||||
auto& housingMgr = Common::Service< HousingMgr >::ref();
|
auto& housingMgr = Common::Service< HousingMgr >::ref();
|
||||||
|
|
||||||
auto ident = housingMgr.clientTriggerParamsToLandIdent( param11, param12 );
|
auto ident = housingMgr.clientTriggerParamsToLandIdent( p1, p2 );
|
||||||
housingMgr.sendLandSignFree( player, ident );
|
housingMgr.sendLandSignFree( player, ident );
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
@ -345,7 +375,7 @@ void Sapphire::Network::GameConnection::clientTriggerHandler( const Packets::FFX
|
||||||
{
|
{
|
||||||
auto& housingMgr = Common::Service< HousingMgr >::ref();
|
auto& housingMgr = Common::Service< HousingMgr >::ref();
|
||||||
|
|
||||||
auto ident = housingMgr.clientTriggerParamsToLandIdent( param11, param12, false );
|
auto ident = housingMgr.clientTriggerParamsToLandIdent( p1, p2, false );
|
||||||
housingMgr.sendLandSignOwned( player, ident );
|
housingMgr.sendLandSignOwned( player, ident );
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
@ -354,7 +384,7 @@ void Sapphire::Network::GameConnection::clientTriggerHandler( const Packets::FFX
|
||||||
{
|
{
|
||||||
auto& housingMgr = Common::Service< HousingMgr >::ref();
|
auto& housingMgr = Common::Service< HousingMgr >::ref();
|
||||||
|
|
||||||
housingMgr.sendWardLandInfo( player, static_cast< uint8_t >( param12 ), static_cast< uint8_t >( param11 ) );
|
housingMgr.sendWardLandInfo( player, static_cast< uint8_t >( p2 ), static_cast< uint8_t >( p1 ) );
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -362,7 +392,7 @@ void Sapphire::Network::GameConnection::clientTriggerHandler( const Packets::FFX
|
||||||
{
|
{
|
||||||
auto& housingMgr = Common::Service< HousingMgr >::ref();
|
auto& housingMgr = Common::Service< HousingMgr >::ref();
|
||||||
|
|
||||||
auto plot = static_cast< uint8_t >( param12 & 0xFF );
|
auto plot = static_cast< uint8_t >( p2 & 0xFF );
|
||||||
housingMgr.relinquishLand( player, plot );
|
housingMgr.relinquishLand( player, plot );
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
@ -371,7 +401,7 @@ void Sapphire::Network::GameConnection::clientTriggerHandler( const Packets::FFX
|
||||||
{
|
{
|
||||||
auto& housingMgr = Common::Service< HousingMgr >::ref();
|
auto& housingMgr = Common::Service< HousingMgr >::ref();
|
||||||
|
|
||||||
auto ident = housingMgr.clientTriggerParamsToLandIdent( param11, param12 );
|
auto ident = housingMgr.clientTriggerParamsToLandIdent( p1, p2 );
|
||||||
housingMgr.requestEstateRename( player, ident );
|
housingMgr.requestEstateRename( player, ident );
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
@ -380,7 +410,7 @@ void Sapphire::Network::GameConnection::clientTriggerHandler( const Packets::FFX
|
||||||
{
|
{
|
||||||
auto& housingMgr = Common::Service< HousingMgr >::ref();
|
auto& housingMgr = Common::Service< HousingMgr >::ref();
|
||||||
|
|
||||||
auto ident = housingMgr.clientTriggerParamsToLandIdent( param11, param12 );
|
auto ident = housingMgr.clientTriggerParamsToLandIdent( p1, p2 );
|
||||||
housingMgr.requestEstateEditGreeting( player, ident );
|
housingMgr.requestEstateEditGreeting( player, ident );
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
@ -389,7 +419,7 @@ void Sapphire::Network::GameConnection::clientTriggerHandler( const Packets::FFX
|
||||||
{
|
{
|
||||||
auto& housingMgr = Common::Service< HousingMgr >::ref();
|
auto& housingMgr = Common::Service< HousingMgr >::ref();
|
||||||
|
|
||||||
auto ident = housingMgr.clientTriggerParamsToLandIdent( param11, param12 );
|
auto ident = housingMgr.clientTriggerParamsToLandIdent( p1, p2 );
|
||||||
housingMgr.requestEstateEditGuestAccess( player, ident );
|
housingMgr.requestEstateEditGuestAccess( player, ident );
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
@ -397,13 +427,13 @@ void Sapphire::Network::GameConnection::clientTriggerHandler( const Packets::FFX
|
||||||
case ClientTriggerType::RequestHousingItemUI:
|
case ClientTriggerType::RequestHousingItemUI:
|
||||||
{
|
{
|
||||||
// close ui
|
// close ui
|
||||||
if( param11 == 1 )
|
if( p1 == 1 )
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// param12 is 0 when inside a house
|
// p2 is 0 when inside a house
|
||||||
|
|
||||||
uint8_t ward = ( param12 >> 16 ) & 0xFF;
|
uint8_t ward = ( p2 >> 16 ) & 0xFF;
|
||||||
uint8_t plot = ( param12 & 0xFF );
|
uint8_t plot = ( p2 & 0xFF );
|
||||||
auto pShowHousingItemUIPacket = makeActorControl( player.getId(), ShowHousingItemUI, 0, plot );
|
auto pShowHousingItemUIPacket = makeActorControl( player.getId(), ShowHousingItemUI, 0, plot );
|
||||||
|
|
||||||
player.queuePacket( pShowHousingItemUIPacket );
|
player.queuePacket( pShowHousingItemUIPacket );
|
||||||
|
@ -416,19 +446,19 @@ void Sapphire::Network::GameConnection::clientTriggerHandler( const Packets::FFX
|
||||||
{
|
{
|
||||||
auto& housingMgr = Common::Service< HousingMgr >::ref();
|
auto& housingMgr = Common::Service< HousingMgr >::ref();
|
||||||
|
|
||||||
auto ident = housingMgr.clientTriggerParamsToLandIdent( param11, param12 );
|
auto ident = housingMgr.clientTriggerParamsToLandIdent( p1, p2 );
|
||||||
housingMgr.sendEstateGreeting( player, ident );
|
housingMgr.sendEstateGreeting( player, ident );
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case ClientTriggerType::RequestLandInventory:
|
case ClientTriggerType::RequestLandInventory:
|
||||||
{
|
{
|
||||||
uint8_t plot = ( param12 & 0xFF );
|
uint8_t plot = ( p2 & 0xFF );
|
||||||
|
|
||||||
auto& housingMgr = Common::Service< HousingMgr >::ref();
|
auto& housingMgr = Common::Service< HousingMgr >::ref();
|
||||||
|
|
||||||
uint16_t inventoryType = Common::InventoryType::HousingExteriorPlacedItems;
|
uint16_t inventoryType = Common::InventoryType::HousingExteriorPlacedItems;
|
||||||
if( param2 == 1 )
|
if( p3 == 1 )
|
||||||
inventoryType = Common::InventoryType::HousingExteriorStoreroom;
|
inventoryType = Common::InventoryType::HousingExteriorStoreroom;
|
||||||
|
|
||||||
housingMgr.sendEstateInventory( player, inventoryType, plot );
|
housingMgr.sendEstateInventory( player, inventoryType, plot );
|
||||||
|
@ -439,10 +469,10 @@ void Sapphire::Network::GameConnection::clientTriggerHandler( const Packets::FFX
|
||||||
{
|
{
|
||||||
auto& housingMgr = Common::Service< HousingMgr >::ref();
|
auto& housingMgr = Common::Service< HousingMgr >::ref();
|
||||||
|
|
||||||
// param1 = 1 - storeroom
|
// p1 = 1 - storeroom
|
||||||
// param1 = 0 - placed items
|
// p1 = 0 - placed items
|
||||||
|
|
||||||
if( param1 == 1 )
|
if( p1 == 1 )
|
||||||
housingMgr.sendInternalEstateInventoryBatch( player, true );
|
housingMgr.sendInternalEstateInventoryBatch( player, true );
|
||||||
else
|
else
|
||||||
housingMgr.sendInternalEstateInventoryBatch( player );
|
housingMgr.sendInternalEstateInventoryBatch( player );
|
||||||
|
@ -453,11 +483,11 @@ void Sapphire::Network::GameConnection::clientTriggerHandler( const Packets::FFX
|
||||||
{
|
{
|
||||||
auto& housingMgr = Common::Service< HousingMgr >::ref();
|
auto& housingMgr = Common::Service< HousingMgr >::ref();
|
||||||
|
|
||||||
auto slot = param4 & 0xFF;
|
auto slot = p4 & 0xFF;
|
||||||
auto sendToStoreroom = ( param4 >> 16 ) != 0;
|
auto sendToStoreroom = ( p4 >> 16 ) != 0;
|
||||||
|
|
||||||
//player, plot, containerId, slot, sendToStoreroom
|
//player, plot, containerId, slot, sendToStoreroom
|
||||||
housingMgr.reqRemoveHousingItem( player, static_cast< uint16_t >( param12 ), static_cast< uint16_t >( param2 ), static_cast< uint8_t >( slot ), sendToStoreroom );
|
housingMgr.reqRemoveHousingItem( player, static_cast< uint16_t >( p2 ), static_cast< uint16_t >( p3 ), static_cast< uint8_t >( slot ), sendToStoreroom );
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -465,7 +495,7 @@ void Sapphire::Network::GameConnection::clientTriggerHandler( const Packets::FFX
|
||||||
{
|
{
|
||||||
auto& housingMgr = Common::Service< HousingMgr >::ref();
|
auto& housingMgr = Common::Service< HousingMgr >::ref();
|
||||||
|
|
||||||
housingMgr.reqEstateExteriorRemodel( player, static_cast< uint16_t >( param11 ) );
|
housingMgr.reqEstateExteriorRemodel( player, static_cast< uint16_t >( p1 ) );
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -481,16 +511,16 @@ void Sapphire::Network::GameConnection::clientTriggerHandler( const Packets::FFX
|
||||||
{
|
{
|
||||||
auto& housingMgr = Common::Service< HousingMgr >::ref();
|
auto& housingMgr = Common::Service< HousingMgr >::ref();
|
||||||
|
|
||||||
housingMgr.removeHouse( player, static_cast< uint16_t >( param11 ) );
|
housingMgr.removeHouse( player, static_cast< uint16_t >( p1 ) );
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case ClientTriggerType::UpdateEstateGuestAccess:
|
case ClientTriggerType::UpdateEstateGuestAccess:
|
||||||
{
|
{
|
||||||
auto canTeleport = ( param2 & 0xFF ) == 1;
|
auto canTeleport = ( p3 & 0xFF ) == 1;
|
||||||
auto unk1 = ( param2 >> 8 & 0xFF ) == 1; // todo: related to fc? or unused?
|
auto unk1 = ( p3 >> 8 & 0xFF ) == 1; // todo: related to fc? or unused?
|
||||||
auto privateEstateAccess = ( param2 >> 16 & 0xFF ) == 1;
|
auto privateEstateAccess = ( p3 >> 16 & 0xFF ) == 1;
|
||||||
auto unk = ( param2 >> 24 & 0xFF ) == 1; // todo: related to fc? or unused?
|
auto unk = ( p3 >> 24 & 0xFF ) == 1; // todo: related to fc? or unused?
|
||||||
|
|
||||||
player.sendDebug( "can teleport: {0}, unk: {1}, privateEstateAccess: {2}, unk: {3}",
|
player.sendDebug( "can teleport: {0}, unk: {1}, privateEstateAccess: {2}, unk: {3}",
|
||||||
canTeleport, unk1, privateEstateAccess, unk );
|
canTeleport, unk1, privateEstateAccess, unk );
|
||||||
|
@ -498,36 +528,34 @@ void Sapphire::Network::GameConnection::clientTriggerHandler( const Packets::FFX
|
||||||
}
|
}
|
||||||
case ClientTriggerType::RequestEventBattle:
|
case ClientTriggerType::RequestEventBattle:
|
||||||
{
|
{
|
||||||
auto packet = makeActorControlSelf( player.getId(), ActorControl::EventBattleDialog, 0, param12, param2 );
|
auto packet = makeActorControlSelf( player.getId(), ActorControl::EventBattleDialog, 0, p2, p3 );
|
||||||
player.queuePacket( packet );
|
player.queuePacket( packet );
|
||||||
|
|
||||||
player.sendDebug( "event battle p1: {0}, p11: {1}, p12: {2}, p2: {3}, p3: {4}, p4: {5}, p5: {6}", param1, param11, param12, param2, param3, param4, param5 );
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case ClientTriggerType::CutscenePlayed:
|
case ClientTriggerType::CutscenePlayed:
|
||||||
{
|
{
|
||||||
player.sendDebug( "cutscene: {}", param1 );
|
player.sendDebug( "cutscene: {}", p1 );
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case ClientTriggerType::OpenPerformInstrumentUI:
|
case ClientTriggerType::OpenPerformInstrumentUI:
|
||||||
{
|
{
|
||||||
//param11 = instrument, 0 = end
|
//p1 = instrument, 0 = end
|
||||||
player.sendDebug( "perform: {}", param11 );
|
player.sendDebug( "perform: {}", p1 );
|
||||||
if( param11 == 0 )
|
if( p1 == 0 )
|
||||||
{
|
{
|
||||||
player.sendToInRangeSet( makeActorControl( player.getId(), ActorControl::SetStatus, 1, 0, 0, 0 ), true );
|
player.sendToInRangeSet( makeActorControl( player.getId(), ActorControl::SetStatus, 1, 0, 0, 0 ), true );
|
||||||
player.unsetStateFlag( PlayerStateFlag::Performing );
|
player.unsetStateFlag( PlayerStateFlag::Performing );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
player.sendToInRangeSet( makeActorControl( player.getId(), ActorControl::SetStatus, 16, param11, 0, 0 ), true );
|
player.sendToInRangeSet( makeActorControl( player.getId(), ActorControl::SetStatus, 16, p1, 0, 0 ), true );
|
||||||
player.setStateFlag( PlayerStateFlag::Performing );
|
player.setStateFlag( PlayerStateFlag::Performing );
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case ClientTriggerType::CameraMode:
|
case ClientTriggerType::CameraMode:
|
||||||
{
|
{
|
||||||
if( ( param11 & 0xFF ) == 1 )
|
if( ( p1 & 0xFF ) == 1 )
|
||||||
{
|
{
|
||||||
player.setOnlineStatusMask( player.getOnlineStatusMask() | 0x0000000000040000 );
|
player.setOnlineStatusMask( player.getOnlineStatusMask() | 0x0000000000040000 );
|
||||||
}
|
}
|
||||||
|
@ -537,6 +565,64 @@ void Sapphire::Network::GameConnection::clientTriggerHandler( const Packets::FFX
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case 0x25E: // coming out from water (no 3.x name)
|
||||||
|
case 0xD1: // underwater town portal (3.x NEWBIE_TELEPO_INQUIRY)
|
||||||
|
{
|
||||||
|
auto p = makeZonePacket< FFXIVIpcPrepareZoning >( player.getId() );
|
||||||
|
p->data().targetZone = player.getCurrentTerritory()->getTerritoryTypeId();
|
||||||
|
p->data().param4 = commandId == 0xD1 ? 14 : 227;
|
||||||
|
p->data().hideChar = commandId == 0xD1 ? 2 : 1;
|
||||||
|
p->data().fadeOut = commandId == 0xD1 ? 24 : 25;
|
||||||
|
p->data().fadeOutTime = 1;
|
||||||
|
p->data().unknown = commandId == 0xD1 ? 4 : 6;
|
||||||
|
auto x = pos.x;
|
||||||
|
auto y = pos.y;
|
||||||
|
auto z = pos.z;
|
||||||
|
auto rot = player.getRot();
|
||||||
|
if( commandId == 0xD1 )
|
||||||
|
{
|
||||||
|
auto& instanceObjectCache = Common::Service< InstanceObjectCache >::ref();
|
||||||
|
auto exit = instanceObjectCache.getExitRange( p->data().targetZone, p1 );
|
||||||
|
if( exit )
|
||||||
|
{
|
||||||
|
player.sendDebug( "exitRange {0} found!", p1 );
|
||||||
|
auto destZone = exit->data.destTerritoryType;
|
||||||
|
if( destZone == 0 )
|
||||||
|
destZone = p->data().targetZone;
|
||||||
|
else
|
||||||
|
p->data().targetZone = destZone;
|
||||||
|
auto pop = instanceObjectCache.getPopRange( destZone, exit->data.destInstanceObjectId );
|
||||||
|
if( pop )
|
||||||
|
{
|
||||||
|
player.sendDebug( "popRange {0} found!", exit->data.destInstanceObjectId );
|
||||||
|
x = pop->header.transform.translation.x;
|
||||||
|
y = pop->header.transform.translation.y;
|
||||||
|
z = pop->header.transform.translation.z;
|
||||||
|
//rot = pop->header.transform.rotation.y; all x/y/z not correct, maybe we don't need it since we have to be facing the portal anyway?
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
player.sendUrgent( "popRange {0} not found in {1}!", exit->data.destInstanceObjectId, destZone );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
player.sendUrgent( "exitRange {0} not found in {1}!", p1, p->data().targetZone );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
player.queuePacket( p );
|
||||||
|
player.setPos( x, y, z, true );
|
||||||
|
player.setRot( rot );
|
||||||
|
auto setPos = makeZonePacket< FFXIVIpcActorSetPos >( player.getId() );
|
||||||
|
setPos->data().r16 = Common::Util::floatToUInt16Rot( player.getRot() );
|
||||||
|
setPos->data().x = x;
|
||||||
|
setPos->data().y = y;
|
||||||
|
setPos->data().z = z;
|
||||||
|
setPos->data().waitForLoad = commandId == 0xD1 ? 24 : 25;
|
||||||
|
setPos->data().unknown1 = 0;
|
||||||
|
player.queuePacket( setPos ); // this packet needs a delay of 0.8 second to wait for the client finishing its water animation otherwise it looks odd.
|
||||||
|
break;
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
{
|
{
|
||||||
Logger::debug( "[{0}] Unhandled action: {1:04X}", m_pSession->getId(), commandId );
|
Logger::debug( "[{0}] Unhandled action: {1:04X}", m_pSession->getId(), commandId );
|
||||||
|
|
|
@ -805,139 +805,6 @@ void Sapphire::Network::GameConnection::marketBoardRequestItemListings( const Pa
|
||||||
marketMgr.requestItemListings( player, packet.data().itemCatalogId );
|
marketMgr.requestItemListings( player, packet.data().itemCatalogId );
|
||||||
}
|
}
|
||||||
|
|
||||||
void Sapphire::Network::GameConnection::worldInteractionhandler( const Packets::FFXIVARR_PACKET_RAW& inPacket,
|
|
||||||
Entity::Player& player )
|
|
||||||
{
|
|
||||||
const auto packet = ZoneChannelPacket< Client::FFXIVIpcWorldInteractionHandler >( inPacket );
|
|
||||||
auto action = packet.data().action;
|
|
||||||
player.sendDebug( "WorldInteraction {}", action );
|
|
||||||
switch( action )
|
|
||||||
{
|
|
||||||
case 0x1F5: // emote
|
|
||||||
{
|
|
||||||
auto emote = packet.data().param1;
|
|
||||||
if( emote == 0x32 || emote == 0x33 ) // "/sit"
|
|
||||||
{
|
|
||||||
auto param4 = packet.data().param4;
|
|
||||||
auto& exdData = Common::Service< Data::ExdDataGenerated >::ref();
|
|
||||||
auto emoteData = exdData.get< Data::Emote >( emote );
|
|
||||||
|
|
||||||
if( !emoteData )
|
|
||||||
break;
|
|
||||||
|
|
||||||
player.setPos( packet.data().position );
|
|
||||||
player.setRot( Util::floatFromUInt16Rot( param4 ) );
|
|
||||||
if( emote == 0x32 && player.hasInRangeActor() )
|
|
||||||
{
|
|
||||||
auto setpos = makeZonePacket< FFXIVIpcActorSetPos >( player.getId() );
|
|
||||||
setpos->data().r16 = param4;
|
|
||||||
setpos->data().waitForLoad = 18;
|
|
||||||
setpos->data().x = packet.data().position.x;
|
|
||||||
setpos->data().y = packet.data().position.y;
|
|
||||||
setpos->data().z = packet.data().position.z;
|
|
||||||
player.sendToInRangeSet( setpos, false );
|
|
||||||
}
|
|
||||||
player.sendToInRangeSet( makeActorControlTarget( player.getId(), ActorControl::ActorControlType::Emote, emote, 0, 0, param4, 0xE0000000 ), true );
|
|
||||||
|
|
||||||
if( emote == 0x32 && emoteData->emoteMode != 0 )
|
|
||||||
{
|
|
||||||
player.setStance( Common::Stance::Passive );
|
|
||||||
player.setAutoattack( false );
|
|
||||||
player.setPersistentEmote( emoteData->emoteMode );
|
|
||||||
player.setStatus( Common::ActorStatus::EmoteMode );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case 0x1F8:
|
|
||||||
{
|
|
||||||
if( player.getPersistentEmote() > 0 )
|
|
||||||
{
|
|
||||||
auto param2 = packet.data().param2;
|
|
||||||
|
|
||||||
player.setPos( packet.data().position );
|
|
||||||
if( player.hasInRangeActor() )
|
|
||||||
{
|
|
||||||
auto setpos = makeZonePacket< FFXIVIpcActorSetPos >( player.getId() );
|
|
||||||
setpos->data().r16 = param2;
|
|
||||||
setpos->data().waitForLoad = 18;
|
|
||||||
setpos->data().x = packet.data().position.x;
|
|
||||||
setpos->data().y = packet.data().position.y;
|
|
||||||
setpos->data().z = packet.data().position.z;
|
|
||||||
player.sendToInRangeSet( setpos, false );
|
|
||||||
}
|
|
||||||
|
|
||||||
player.setPersistentEmote( 0 );
|
|
||||||
player.emoteInterrupt();
|
|
||||||
player.setStatus( Common::ActorStatus::Idle );
|
|
||||||
auto pSetStatusPacket = makeActorControl( player.getId(), SetStatus, static_cast< uint8_t >( Common::ActorStatus::Idle ) );
|
|
||||||
player.sendToInRangeSet( pSetStatusPacket );
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case 0x25E: // coming out from water
|
|
||||||
case 0xD1: // underwater town portal
|
|
||||||
{
|
|
||||||
auto p = makeZonePacket< FFXIVIpcPrepareZoning >( player.getId() );
|
|
||||||
p->data().targetZone = player.getCurrentTerritory()->getTerritoryTypeId();
|
|
||||||
p->data().param4 = action == 0xD1 ? 14 : 227;
|
|
||||||
p->data().hideChar = action == 0xD1 ? 2 : 1;
|
|
||||||
p->data().fadeOut = action == 0xD1 ? 24 : 25;
|
|
||||||
p->data().fadeOutTime = 1;
|
|
||||||
p->data().unknown = action == 0xD1 ? 4 : 6;
|
|
||||||
auto x = packet.data().position.x;
|
|
||||||
auto y = packet.data().position.y;
|
|
||||||
auto z = packet.data().position.z;
|
|
||||||
auto rot = player.getRot();
|
|
||||||
if( action == 0xD1 )
|
|
||||||
{
|
|
||||||
auto exitRange = packet.data().param1;
|
|
||||||
|
|
||||||
auto& instanceObjectCache = Common::Service< InstanceObjectCache >::ref();
|
|
||||||
auto exit = instanceObjectCache.getExitRange( p->data().targetZone, exitRange );
|
|
||||||
if( exit )
|
|
||||||
{
|
|
||||||
player.sendDebug( "exitRange {0} found!", exitRange );
|
|
||||||
auto destZone = exit->data.destTerritoryType;
|
|
||||||
if( destZone == 0 )
|
|
||||||
destZone = p->data().targetZone;
|
|
||||||
else
|
|
||||||
p->data().targetZone = destZone;
|
|
||||||
auto pop = instanceObjectCache.getPopRange( destZone, exit->data.destInstanceObjectId );
|
|
||||||
if( pop )
|
|
||||||
{
|
|
||||||
player.sendDebug( "popRange {0} found!", exit->data.destInstanceObjectId );
|
|
||||||
x = pop->header.transform.translation.x;
|
|
||||||
y = pop->header.transform.translation.y;
|
|
||||||
z = pop->header.transform.translation.z;
|
|
||||||
//rot = pop->header.transform.rotation.y; all x/y/z not correct, maybe we don't need it since we have to be facing the portal anyway?
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
player.sendUrgent( "popRange {0} not found in {1}!", exit->data.destInstanceObjectId, destZone );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
player.sendUrgent( "exitRange {0} not found in {1}!", exitRange, p->data().targetZone );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
player.queuePacket( p );
|
|
||||||
player.setPos( x, y, z, true );
|
|
||||||
player.setRot( rot );
|
|
||||||
auto setPos = makeZonePacket< FFXIVIpcActorSetPos >( player.getId() );
|
|
||||||
setPos->data().r16 = Common::Util::floatToUInt16Rot( player.getRot() );
|
|
||||||
setPos->data().x = x;
|
|
||||||
setPos->data().y = y;
|
|
||||||
setPos->data().z = z;
|
|
||||||
setPos->data().waitForLoad = action == 0xD1 ? 24 : 25;
|
|
||||||
setPos->data().unknown1 = 0;
|
|
||||||
player.queuePacket( setPos ); // this packet needs a delay of 0.8 second to wait for the client finishing its water animation otherwise it looks odd.
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Sapphire::Network::GameConnection::diveHandler( const Packets::FFXIVARR_PACKET_RAW& inPacket, Entity::Player& player )
|
void Sapphire::Network::GameConnection::diveHandler( const Packets::FFXIVARR_PACKET_RAW& inPacket, Entity::Player& player )
|
||||||
{
|
{
|
||||||
const auto packetIn = ZoneChannelPacket< Client::FFXIVIpcDive >( inPacket );
|
const auto packetIn = ZoneChannelPacket< Client::FFXIVIpcDive >( inPacket );
|
||||||
|
|
Loading…
Add table
Reference in a new issue