diff --git a/src/common/Network/CommonActorControl.h b/src/common/Network/CommonActorControl.h index d144e83c..4d69a966 100644 --- a/src/common/Network/CommonActorControl.h +++ b/src/common/Network/CommonActorControl.h @@ -395,6 +395,8 @@ namespace Sapphire::Network::ActorControl RequestEventBattle = 0x232C, + Trigger612 = 0x264, + QuestJournalUpdateQuestVisibility = 0x2BE, QuestJournalClosed = 0x2BF, diff --git a/src/common/Network/PacketDef/Ipcs.h b/src/common/Network/PacketDef/Ipcs.h index 8bbd0a01..d1856b20 100644 --- a/src/common/Network/PacketDef/Ipcs.h +++ b/src/common/Network/PacketDef/Ipcs.h @@ -376,6 +376,7 @@ namespace Sapphire::Network::Packets PerformNoteHandler = 0x029B, // updated 4.3 + MapInteractionHandler = 0x0285, // updated 5.25 }; //////////////////////////////////////////////////////////////////////////////// diff --git a/src/common/Network/PacketDef/Zone/ClientZoneDef.h b/src/common/Network/PacketDef/Zone/ClientZoneDef.h index bf698237..6944cf39 100644 --- a/src/common/Network/PacketDef/Zone/ClientZoneDef.h +++ b/src/common/Network/PacketDef/Zone/ClientZoneDef.h @@ -344,6 +344,16 @@ struct FFXIVIpcFreeCompanyUpdateShortMessageHandler : uint16_t unknown2; }; +struct FFXIVIpcMapInteractionHandler : + FFXIVIpcBasePacket< MapInteractionHandler > +{ + uint32_t action; + uint32_t unknown2; + uint64_t unknown3; + uint32_t unknown4; + Common::FFXIVARR_POSITION3 position; +}; + } #endif //_CORE_NETWORK_PACKETS_ZONE_CLIENT_IPC_H diff --git a/src/world/Actor/Chara.cpp b/src/world/Actor/Chara.cpp index d4785135..2d9e8ce9 100644 --- a/src/world/Actor/Chara.cpp +++ b/src/world/Actor/Chara.cpp @@ -535,20 +535,30 @@ void Sapphire::Entity::Chara::addStatusEffect( StatusEffect::StatusEffectPtr pEf sendStatusEffectUpdate(); // although client buff displays correctly without this but retail sends it so we do it as well } -void Sapphire::Entity::Chara::addStatusEffectById( uint32_t id, int32_t duration, Entity::Chara& source, uint16_t param ) +void Sapphire::Entity::Chara::addStatusEffectById( uint32_t id, int32_t duration, Entity::Chara& source, uint16_t param, bool sendActorControl ) { auto effect = StatusEffect::make_StatusEffect( id, source.getAsChara(), getAsChara(), duration, 3000 ); effect->setParam( param ); + if( sendActorControl ) + { + auto p = makeActorControl( getId(), Network::ActorControl::StatusEffectGain, id, 0, 0, 0 ); + sendToInRangeSet( p, true ); + } addStatusEffect( effect ); } -void Sapphire::Entity::Chara::addStatusEffectByIdIfNotExist( uint32_t id, int32_t duration, Entity::Chara& source, uint16_t param ) +void Sapphire::Entity::Chara::addStatusEffectByIdIfNotExist( uint32_t id, int32_t duration, Entity::Chara& source, uint16_t param, bool sendActorControl ) { if( getStatusEffectById( id ).second ) return; auto effect = StatusEffect::make_StatusEffect( id, source.getAsChara(), getAsChara(), duration, 3000 ); effect->setParam( param ); + if( sendActorControl ) + { + auto p = makeActorControl( getId(), Network::ActorControl::StatusEffectGain, id, 0, 0, 0 ); + sendToInRangeSet( p, true ); + } addStatusEffect( effect ); } diff --git a/src/world/Actor/Chara.h b/src/world/Actor/Chara.h index 698343e4..6f228627 100644 --- a/src/world/Actor/Chara.h +++ b/src/world/Actor/Chara.h @@ -174,10 +174,10 @@ namespace Sapphire::Entity const uint32_t* getModelArray() const; // add a status effect by id - void addStatusEffectById( uint32_t id, int32_t duration, Entity::Chara& source, uint16_t param = 0 ); + void addStatusEffectById( uint32_t id, int32_t duration, Entity::Chara& source, uint16_t param = 0, bool sendActorControl = false ); // add a status effect by id if it doesn't exist - void addStatusEffectByIdIfNotExist( uint32_t id, int32_t duration, Entity::Chara& source, uint16_t param = 0 ); + void addStatusEffectByIdIfNotExist( uint32_t id, int32_t duration, Entity::Chara& source, uint16_t param = 0, bool sendActorControl = false ); /// End Status Effect Functions diff --git a/src/world/Network/GameConnection.cpp b/src/world/Network/GameConnection.cpp index 7fda9109..d74635dc 100644 --- a/src/world/Network/GameConnection.cpp +++ b/src/world/Network/GameConnection.cpp @@ -130,6 +130,8 @@ Sapphire::Network::GameConnection::GameConnection( Sapphire::Network::HivePtr pH setZoneHandler( ClientZoneIpcType::MarketBoardRequestItemListings, "MarketBoardRequestItemListings", &GameConnection::marketBoardRequestItemListings ); + setZoneHandler( ClientZoneIpcType::MapInteractionHandler, "MapInteractionHandler", &GameConnection::eventHandlerMapInteraction ); + setChatHandler( ClientChatIpcType::TellReq, "TellReq", &GameConnection::tellHandler ); } diff --git a/src/world/Network/GameConnection.h b/src/world/Network/GameConnection.h index 94fa4f02..e175bca5 100644 --- a/src/world/Network/GameConnection.h +++ b/src/world/Network/GameConnection.h @@ -143,6 +143,8 @@ namespace Sapphire::Network DECLARE_HANDLER( eventHandlerShop ); + DECLARE_HANDLER( eventHandlerMapInteraction ); + DECLARE_HANDLER( eventHandlerLinkshell ); DECLARE_HANDLER( logoutHandler ); diff --git a/src/world/Network/Handlers/ClientTriggerHandler.cpp b/src/world/Network/Handlers/ClientTriggerHandler.cpp index 5f1bb6ae..8219830f 100644 --- a/src/world/Network/Handlers/ClientTriggerHandler.cpp +++ b/src/world/Network/Handlers/ClientTriggerHandler.cpp @@ -489,7 +489,11 @@ void Sapphire::Network::GameConnection::clientTriggerHandler( const Packets::FFX player.sendDebug( "event battle level sync: {0}, ilevel sync?: {1}", param12, param2 ); break; } - + case ClientTriggerType::Trigger612: + { + player.sendStateFlags(); + break; + } default: { Logger::debug( "[{0}] Unhandled action: {1:04X}", m_pSession->getId(), commandId ); diff --git a/src/world/Network/Handlers/EventHandlers.cpp b/src/world/Network/Handlers/EventHandlers.cpp index 33fe1641..9dc97dbb 100644 --- a/src/world/Network/Handlers/EventHandlers.cpp +++ b/src/world/Network/Handlers/EventHandlers.cpp @@ -8,6 +8,9 @@ #include #include "Network/GameConnection.h" +#include +#include "Network/PacketWrappers/ActorControlPacket.h" +#include "Network/PacketWrappers/ActorControlSelfPacket.h" #include "Network/PacketWrappers/ServerNoticePacket.h" #include "Network/PacketWrappers/EventStartPacket.h" #include "Network/PacketWrappers/EventFinishPacket.h" @@ -273,5 +276,57 @@ void Sapphire::Network::GameConnection::eventHandlerShop( const Packets::FFXIVAR scriptMgr.onTalk( player, player.getId(), eventId ); } +void Sapphire::Network::GameConnection::eventHandlerMapInteraction( const Packets::FFXIVARR_PACKET_RAW& inPacket, + Entity::Player& player ) +{ + const auto packet = ZoneChannelPacket< Client::FFXIVIpcMapInteractionHandler >( inPacket ); + if( packet.data().action == 0xD4 && player.getRace() == 3 ) // enter dwarf house lalafell only of course + { + // looks like shit but IT WORKS. + auto x = packet.data().position.x; + auto z = packet.data().position.z; + if( x < -448 && x > -453 ) + { + // west + if( x > -451 ) + { + // enter + auto p = makeActorControl( player.getId(), 242, 1174189454, 817758208, 67, 0 ); + queueOutPacket( p ); + player.addStatusEffectById( 1945, 0, player, 0, true ); + } + else + { + // exit + auto p = makeActorControl( player.getId(), 242, 1182315916, 827392000, 68, 0 ); + queueOutPacket( p ); + player.removeSingleStatusEffectById( 1945 ); + } + } + else if ( x > 637 && x < 641 ) + { + // east + if( z > -188 ) + { + // enter + auto p = makeActorControl( player.getId(), 242, 3521816124, 1737687040, 69, 0 ); + queueOutPacket( p ); + player.addStatusEffectById( 1945, 0, player, 0, true ); + } + else + { + // exit + auto p = makeActorControl( player.getId(), 242, 3517228601, 1749483520, 70, 0 ); + queueOutPacket( p ); + player.removeSingleStatusEffectById( 1945 ); + } + } + else + { + player.sendDebug( "Unknown dwarf house." ); + } + } +} +