mirror of
https://github.com/SapphireServer/Sapphire.git
synced 2025-04-27 22:57:45 +00:00
commit
c315e61c9b
5 changed files with 157 additions and 52 deletions
|
@ -395,6 +395,7 @@ namespace Sapphire::Network::Packets
|
|||
PerformNoteHandler = 0x029B, // updated 4.3
|
||||
|
||||
WorldInteractionHandler = 0x00A9, // updated 5.35 hotfix
|
||||
Dive = 0x02CC, // updated 5.35 hotfix
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
@ -417,6 +417,15 @@ struct FFXIVIpcDisbandPartyHandler :
|
|||
};
|
||||
|
||||
|
||||
struct FFXIVIpcDive :
|
||||
FFXIVIpcBasePacket< Dive >
|
||||
{
|
||||
float unknown;
|
||||
Common::FFXIVARR_POSITION3 posTarget;
|
||||
Common::FFXIVARR_POSITION3 posOriginal;
|
||||
uint32_t padding;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif //_CORE_NETWORK_PACKETS_ZONE_CLIENT_IPC_H
|
||||
|
|
|
@ -132,6 +132,7 @@ Sapphire::Network::GameConnection::GameConnection( Sapphire::Network::HivePtr pH
|
|||
&GameConnection::marketBoardRequestItemListings );
|
||||
|
||||
setZoneHandler( ClientZoneIpcType::WorldInteractionHandler, "WorldInteractionHandler", &GameConnection::worldInteractionhandler );
|
||||
setZoneHandler( ClientZoneIpcType::Dive, "Dive", &GameConnection::diveHandler );
|
||||
|
||||
setChatHandler( ClientChatIpcType::TellReq, "TellReq", &GameConnection::tellHandler );
|
||||
|
||||
|
|
|
@ -189,6 +189,7 @@ namespace Sapphire::Network
|
|||
|
||||
DECLARE_HANDLER( worldInteractionhandler );
|
||||
|
||||
DECLARE_HANDLER( diveHandler );
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -731,65 +731,158 @@ void Sapphire::Network::GameConnection::worldInteractionhandler( const Packets::
|
|||
const auto packet = ZoneChannelPacket< Client::FFXIVIpcWorldInteractionHandler >( inPacket );
|
||||
auto action = packet.data().action;
|
||||
player.sendDebug( "WorldInteraction {}", action );
|
||||
if( action == 0x1F5 )
|
||||
switch( action )
|
||||
{
|
||||
auto emote = packet.data().param1;
|
||||
if( emote == 0x32 || emote == 0x33 ) // "/sit"
|
||||
case 0x1F5: // emote
|
||||
{
|
||||
auto param4 = packet.data().param4;
|
||||
auto& exdData = Common::Service< Data::ExdDataGenerated >::ref();
|
||||
auto emoteData = exdData.get< Data::Emote >( emote );
|
||||
|
||||
if( !emoteData )
|
||||
return;
|
||||
|
||||
player.setPos( packet.data().position );
|
||||
if( emote == 0x32 && player.hasInRangeActor() )
|
||||
auto emote = packet.data().param1;
|
||||
if( emote == 0x32 || emote == 0x33 ) // "/sit"
|
||||
{
|
||||
auto setpos = makeZonePacket< FFXIVIpcActorSetPos >( player.getId() );
|
||||
setpos->data().r16 = param4;
|
||||
setpos->data().waitForLoad = 18;
|
||||
setpos->data().unknown1 = 1;
|
||||
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 );
|
||||
auto param4 = packet.data().param4;
|
||||
auto& exdData = Common::Service< Data::ExdDataGenerated >::ref();
|
||||
auto emoteData = exdData.get< Data::Emote >( emote );
|
||||
|
||||
if( emote == 0x32 && emoteData->emoteMode != 0 )
|
||||
{
|
||||
player.setStance( Common::Stance::Passive );
|
||||
player.setAutoattack( false );
|
||||
player.setPersistentEmote( emoteData->emoteMode );
|
||||
player.setStatus( Common::ActorStatus::EmoteMode );
|
||||
if( !emoteData )
|
||||
break;
|
||||
|
||||
player.setPos( packet.data().position );
|
||||
if( emote == 0x32 && player.hasInRangeActor() )
|
||||
{
|
||||
auto setpos = makeZonePacket< FFXIVIpcActorSetPos >( player.getId() );
|
||||
setpos->data().r16 = param4;
|
||||
setpos->data().waitForLoad = 18;
|
||||
setpos->data().unknown1 = 1;
|
||||
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().unknown1 = 2;
|
||||
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;
|
||||
}
|
||||
}
|
||||
else if( action == 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().unknown1 = 2;
|
||||
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 );
|
||||
}
|
||||
void Sapphire::Network::GameConnection::diveHandler( const Packets::FFXIVARR_PACKET_RAW& inPacket, Entity::Player& player )
|
||||
{
|
||||
const auto packetIn = ZoneChannelPacket< Client::FFXIVIpcDive >( inPacket );
|
||||
auto p = makeZonePacket< FFXIVIpcPrepareZoning >( player.getId() );
|
||||
p->data().targetZone = player.getCurrentTerritory()->getTerritoryTypeId();
|
||||
p->data().param4 = 218;
|
||||
p->data().hideChar = 1;
|
||||
p->data().fadeOut = 25;
|
||||
p->data().fadeOutTime = 1;
|
||||
p->data().unknown = 6;
|
||||
player.queuePacket( p );
|
||||
|
||||
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 );
|
||||
}
|
||||
}
|
||||
player.setStance( Common::Stance::Passive );
|
||||
|
||||
auto x = packetIn.data().posTarget.x;
|
||||
auto y = packetIn.data().posTarget.y;
|
||||
auto z = packetIn.data().posTarget.z;
|
||||
player.setPos( x, y, z, true );
|
||||
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 = 25;
|
||||
setPos->data().unknown1 = 0;
|
||||
player.queuePacket( setPos ); // need delay, same as above.
|
||||
}
|
Loading…
Add table
Reference in a new issue