1
Fork 0
mirror of https://github.com/SapphireServer/Sapphire.git synced 2025-05-25 11:07:45 +00:00

wedding ceremony up to the first scene

This commit is contained in:
collett 2021-08-15 08:49:13 +09:00
parent d2226b459b
commit 53edec08c1
6 changed files with 199 additions and 13 deletions

View file

@ -274,6 +274,8 @@ namespace Sapphire::Network::Packets
LandSetMap = 0x02F6, // updated 5.58 LandSetMap = 0x02F6, // updated 5.58
CeremonySetActorAppearance = 0x00EB, // updated 5.58
////////////////////////////////////////////////// //////////////////////////////////////////////////
DuelChallenge = 0x0277, // 4.2; this is responsible for opening the ui DuelChallenge = 0x0277, // 4.2; this is responsible for opening the ui

View file

@ -2266,6 +2266,29 @@ namespace Sapphire::Network::Packets::Server
uint32_t param[4]; uint32_t param[4];
uint64_t unknown; uint64_t unknown;
}; };
struct FFXIVCeremonySetActorAppearance : FFXIVIpcBasePacket< CeremonySetActorAppearance >
{
uint8_t u1;
uint8_t u2;
uint16_t padding1;
uint32_t u3;
struct
{
uint64_t mainWeaponModel;
uint64_t secWeaponModel;
uint64_t craftToolModel;
uint32_t c_u6;
uint32_t c_u7;
uint32_t charId;
uint16_t u4;
uint16_t guardianDeity;
uint32_t u5;
uint32_t models[10];
uint8_t look[26];
uint16_t padding3;
} actors[2];
};
} }
#endif /*_CORE_NETWORK_PACKETS_SERVER_IPC_H*/ #endif /*_CORE_NETWORK_PACKETS_SERVER_IPC_H*/

View file

@ -7,6 +7,7 @@
#include <Util/UtilMath.h> #include <Util/UtilMath.h>
#include "Network/CommonActorControl.h" #include "Network/CommonActorControl.h"
#include "Network/PacketWrappers/ActorControlSelfPacket.h" #include "Network/PacketWrappers/ActorControlSelfPacket.h"
#include "Network/PacketDef/Zone/ServerZoneDef.h"
using namespace Sapphire; using namespace Sapphire;
using namespace Sapphire::Network::ActorControl; using namespace Sapphire::Network::ActorControl;
@ -26,9 +27,108 @@ public:
player.exitInstance(); player.exitInstance();
}; };
instance.registerEObj( "unknown_0", 2005027, 0, 0, { 0.0f, 251.103f, -60.39313f }, 1.0f, Common::Util::floatFromUInt16Rot( 28453 ) ); auto mainBookHandler = [ & ]( Entity::Player& player, Entity::EventObjectPtr eobj, TerritoryPtr terri, uint32_t eventId, uint64_t actorId )
{
if( instance.getSequence() == 1 )
{
auto v1 = instance.getCustomVar( 1 );
if( v1 == 0 )
{
player.sendUrgent( "The host of this ceremony is not determined yet, become the host as the first one to join the instance with quest 67114 at seq 12." );
return;
}
if( v1 != player.getId() )
{
player.sendUrgent( "You are not the host of this ceremony." );
return;
}
auto v2 = instance.getCustomVar( 2 );
if( v2 > 0 )
{
auto p1 = instance.getPlayer( v1 );
auto p2 = instance.getPlayer( v2 );
if( p1 && p2 )
{
//skip seq 2, 3 for now
instance.setDirectorSequence( 4 );
p1->eventFinish( eventId, 1 );
FFXIVCeremonySetActorAppearance packetData = {};
packetData.u1 = 1;
packetData.u2 = 1;
if( !( p1->getEquipDisplayFlags() & Sapphire::Common::EquipDisplayFlags::HideWeapon ) )
{
packetData.actors[0].mainWeaponModel = p1->getModelMainWeapon();
packetData.actors[0].secWeaponModel = p1->getModelSubWeapon();
}
packetData.actors[0].charId = p1->getId();
packetData.actors[0].guardianDeity = p1->getGuardianDeity();
packetData.actors[0].models[ Common::GearModelSlot::ModelHead ] = p1->getModelForSlot( Common::GearModelSlot::ModelHead );
packetData.actors[0].models[ Common::GearModelSlot::ModelBody ] = p1->getModelForSlot( Common::GearModelSlot::ModelBody );
packetData.actors[0].models[ Common::GearModelSlot::ModelHands ] = p1->getModelForSlot( Common::GearModelSlot::ModelHands );
packetData.actors[0].models[ Common::GearModelSlot::ModelLegs ] = p1->getModelForSlot( Common::GearModelSlot::ModelLegs );
packetData.actors[0].models[ Common::GearModelSlot::ModelFeet ] = p1->getModelForSlot( Common::GearModelSlot::ModelFeet );
packetData.actors[0].models[ Common::GearModelSlot::ModelNeck ] = p1->getModelForSlot( Common::GearModelSlot::ModelNeck );
packetData.actors[0].models[ Common::GearModelSlot::ModelEar ] = p1->getModelForSlot( Common::GearModelSlot::ModelEar );
packetData.actors[0].models[ Common::GearModelSlot::ModelRing1 ] = p1->getModelForSlot( Common::GearModelSlot::ModelRing1 );
packetData.actors[0].models[ Common::GearModelSlot::ModelRing2 ] = p1->getModelForSlot( Common::GearModelSlot::ModelRing2 );
packetData.actors[0].models[ Common::GearModelSlot::ModelWrist ] = p1->getModelForSlot( Common::GearModelSlot::ModelWrist );
memcpy( packetData.actors[0].look, p1->getLookArray(), sizeof( packetData.actors[0].look ) );
if( !( p2->getEquipDisplayFlags() & Sapphire::Common::EquipDisplayFlags::HideWeapon ) )
{
packetData.actors[1].mainWeaponModel = p2->getModelMainWeapon();
packetData.actors[1].secWeaponModel = p2->getModelSubWeapon();
}
packetData.actors[1].charId = p2->getId();
packetData.actors[1].guardianDeity = p2->getGuardianDeity();
packetData.actors[1].models[ Common::GearModelSlot::ModelHead ] = p2->getModelForSlot( Common::GearModelSlot::ModelHead );
packetData.actors[1].models[ Common::GearModelSlot::ModelBody ] = p2->getModelForSlot( Common::GearModelSlot::ModelBody );
packetData.actors[1].models[ Common::GearModelSlot::ModelHands ] = p2->getModelForSlot( Common::GearModelSlot::ModelHands );
packetData.actors[1].models[ Common::GearModelSlot::ModelLegs ] = p2->getModelForSlot( Common::GearModelSlot::ModelLegs );
packetData.actors[1].models[ Common::GearModelSlot::ModelFeet ] = p2->getModelForSlot( Common::GearModelSlot::ModelFeet );
packetData.actors[1].models[ Common::GearModelSlot::ModelNeck ] = p2->getModelForSlot( Common::GearModelSlot::ModelNeck );
packetData.actors[1].models[ Common::GearModelSlot::ModelEar ] = p2->getModelForSlot( Common::GearModelSlot::ModelEar );
packetData.actors[1].models[ Common::GearModelSlot::ModelRing1 ] = p2->getModelForSlot( Common::GearModelSlot::ModelRing1 );
packetData.actors[1].models[ Common::GearModelSlot::ModelRing2 ] = p2->getModelForSlot( Common::GearModelSlot::ModelRing2 );
packetData.actors[1].models[ Common::GearModelSlot::ModelWrist ] = p2->getModelForSlot( Common::GearModelSlot::ModelWrist );
memcpy( packetData.actors[1].look, p2->getLookArray(), sizeof( packetData.actors[1].look ) );
instance.foreachPlayer( [ &instance, &packetData ]( auto p )
{
auto packet = makeZonePacket< FFXIVCeremonySetActorAppearance >( p->getId() );
memcpy( &packet->data(), &packetData, sizeof( packetData ) );
p->queuePacket( packet );
p->eventStart( p->getId(), instance.getDirectorId(), Event::EventHandler::EnterTerritory, 1, p->getZoneId() );
p->directorPlayScene( instance.getDirectorId(), 3, 9219, 0, 1, 50000 );
});
}
else
{
player.sendUrgent( "Two main characters must be in the instance to begin the ceremony." );
}
}
else
{
player.sendUrgent( "Need another character with quest 67114 at seq 12 to begin the ceremony." );
}
}
else if( instance.getSequence() == 4 )
{
player.sendUrgent( "WIP..." );
}
};
auto subBookHandler = [ & ]( Entity::Player& player, Entity::EventObjectPtr eobj, TerritoryPtr terri, uint32_t eventId, uint64_t actorId )
{
auto v2 = instance.getCustomVar( 2 );
if( v2 == player.getId() )
{
player.sendUrgent( "Wait for your partner to start the ceremony." );
}
};
instance.registerEObj( "unknown_0", 2005027, 0, 0, { 0.0f, 251.103f, -60.39313f }, 1.0f, Common::Util::floatFromUInt16Rot( 28453 ) )->setOnTalkHandler( subBookHandler );
instance.registerEObj( "unknown_1", 2004902, 0, 1, { -0.1025963f, 2.902821f, -125.97f }, 1.0f, Common::Util::floatFromUInt16Rot( 32767 ) ); instance.registerEObj( "unknown_1", 2004902, 0, 1, { -0.1025963f, 2.902821f, -125.97f }, 1.0f, Common::Util::floatFromUInt16Rot( 32767 ) );
instance.registerEObj( "unknown_2", 2004786, 0, 0, { 0.0f, 501.103f, -60.39313f }, 1.0f, Common::Util::floatFromUInt16Rot( 28453 ) ); instance.registerEObj( "unknown_2", 2004786, 0, 0, { 0.0f, 501.103f, -60.39313f }, 1.0f, Common::Util::floatFromUInt16Rot( 28453 ) )->setOnTalkHandler( mainBookHandler );
instance.registerEObj( "unknown_3", 2004783, 0, 0, { 0.0f, 0.5f, 19.0f }, 1.0f, Common::Util::floatFromUInt16Rot( 32767 ) )->setOnTalkHandler( exitHandler ); instance.registerEObj( "unknown_3", 2004783, 0, 0, { 0.0f, 0.5f, 19.0f }, 1.0f, Common::Util::floatFromUInt16Rot( 32767 ) )->setOnTalkHandler( exitHandler );
instance.registerEObj( "unknown_4", 2004783, 0, 0, { 0.0f, 250.5515f, -48.19313f }, 1.0f, Common::Util::floatFromUInt16Rot( 32767 ) )->setOnTalkHandler( exitHandler ); instance.registerEObj( "unknown_4", 2004783, 0, 0, { 0.0f, 250.5515f, -48.19313f }, 1.0f, Common::Util::floatFromUInt16Rot( 32767 ) )->setOnTalkHandler( exitHandler );
instance.registerEObj( "unknown_5", 2004783, 0, 0, { -0.01531982f, 500.5456f, -48.20331 }, 0.9917603f, Common::Util::floatFromUInt16Rot( 32767 ) )->setOnTalkHandler( exitHandler ); instance.registerEObj( "unknown_5", 2004783, 0, 0, { -0.01531982f, 500.5456f, -48.20331 }, 0.9917603f, Common::Util::floatFromUInt16Rot( 32767 ) )->setOnTalkHandler( exitHandler );
@ -45,7 +145,7 @@ public:
{ {
if( instance.getCustomVar( 1 ) == 0 || instance.getCustomVar( 1 ) == player.getId() ) if( instance.getCustomVar( 1 ) == 0 || instance.getCustomVar( 1 ) == player.getId() )
{ {
if( player.hasQuest( 67114 ) ) if( player.hasQuest( 67114 ) && player.getQuestSeq( 67114 ) == 12 )
{ {
instance.setCustomVar( 1, player.getId() ); instance.setCustomVar( 1, player.getId() );
instance.setDirectorUI8AL( player.getQuestUI8AH( 67114 ) ); instance.setDirectorUI8AL( player.getQuestUI8AH( 67114 ) );
@ -60,6 +160,23 @@ public:
instance.setDirectorUI8JL( 1 ); instance.setDirectorUI8JL( 1 );
} }
} }
else if( instance.getCustomVar( 2 ) == 0 || instance.getCustomVar( 2 ) == player.getId() )
{
if( player.hasQuest( 67114 ) && player.getQuestSeq( 67114 ) == 12 )
{
instance.setCustomVar( 2, player.getId() );
auto p1 = instance.getPlayer( instance.getCustomVar( 1 ) );
if( p1 )
{
auto p = makeZonePacket< FFXIVDirectorUnk4 >( getId() );
p->data().param[0] = instance.getDirectorId();
p->data().param[1] = 4365;
p->data().param[2] = 0;
p->data().param[3] = 0;
p1->queuePacket( p );
}
}
}
} }
void onLeaveTerritory( PublicContent& instance, Entity::Player& player ) override void onLeaveTerritory( PublicContent& instance, Entity::Player& player ) override
@ -70,14 +187,20 @@ public:
{ {
auto callback = [ & ]( Entity::Player& player, const Event::SceneResult& result ) auto callback = [ & ]( Entity::Player& player, const Event::SceneResult& result )
{ {
auto p = makeZonePacket< FFXIVDirectorUnk4 >( getId() );
p->data().param[0] = instance.getDirectorId();
p->data().param[1] = 4365;
p->data().param[2] = 0;
p->data().param[3] = 0;
player.queuePacket( p );
}; };
player.queuePacket( makeActorControlSelf( getId(), DirectorUpdate, instance.getDirectorId(), 0x80000003, 1200 ) ); // timer if( instance.getCustomVar( 1 ) == player.getId() )
{
player.setPosAndSendActorMove( 0, 500, -50, -3.14f );
}
else if( instance.getCustomVar( 2 ) == player.getId() )
{
player.setPosAndSendActorMove( 0, 250, -50, -3.14f );
}
else
{
player.setPosAndSendActorMove( 0, 750, -50, -3.14f );
}
//player.queuePacket( makeActorControlSelf( getId(), DirectorUpdate, instance.getDirectorId(), 0x80000003, 1200 ) ); // timer
player.playScene( instance.getDirectorId(), 1, HIDE_HOTBAR, 0, 2, 4, callback ); player.playScene( instance.getDirectorId(), 1, HIDE_HOTBAR, 0, 2, 4, callback );
} }

View file

@ -11,6 +11,8 @@
#include "Manager/EventMgr.h" #include "Manager/EventMgr.h"
#include "Network/CommonActorControl.h" #include "Network/CommonActorControl.h"
#include "Network/PacketWrappers/ActorControlSelfPacket.h" #include "Network/PacketWrappers/ActorControlSelfPacket.h"
#include "Territory/Territory.h"
#include "Territory/PublicContent.h"
using namespace Sapphire; using namespace Sapphire;
using namespace Sapphire::Network::ActorControl; using namespace Sapphire::Network::ActorControl;
@ -1375,15 +1377,32 @@ private:
{ {
player.prepareZoning( 392, true, 1, 0, 0, 1, 8 ); player.prepareZoning( 392, true, 1, 0, 0, 1, 8 );
player.eventFinish( getId(), 1 ); player.eventFinish( getId(), 1 );
auto& terriMgr = Common::Service< World::Manager::TerritoryMgr >::ref();
if( currentInstance )
{
if( currentInstance->getPopCount() == 0 )
{
auto terriId = currentInstance->getGuId();
if( terriMgr.removeTerritoryInstance( terriId ) )
player.sendDebug( "Removed old instance with id#{0}", terriId );
else
player.sendDebug( "Failed to remove old instance with id#{0}", terriId );
currentInstance = nullptr;
}
else
{
player.sendDebug( "Wedding in progress, joining..." );
}
}
if( !currentInstance ) if( !currentInstance )
{ {
auto& terriMgr = Common::Service< World::Manager::TerritoryMgr >::ref(); player.sendDebug( "Creating new wedding instance..." );
currentInstance = terriMgr.createPublicContent( 1, 392 ); currentInstance = terriMgr.createPublicContent( 1, 392 );
} }
Common::FFXIVARR_POSITION3 pos; Common::FFXIVARR_POSITION3 pos;
pos.x = 0; pos.x = 0;
pos.y = 500; pos.y = 0;
pos.z = -50; pos.z = 0;
player.setInstance( currentInstance, pos, -3.14f ); player.setInstance( currentInstance, pos, -3.14f );
} }
}; };

View file

@ -1055,3 +1055,18 @@ void Sapphire::Territory::processEffectResults( uint64_t tickCount )
it = m_effectResults.erase( it ); it = m_effectResults.erase( it );
} }
} }
Sapphire::Entity::PlayerPtr Sapphire::Territory::getPlayer( uint32_t charId )
{
return m_playerMap[ charId ];
}
void Sapphire::Territory::foreachPlayer( std::function< void( Sapphire::Entity::PlayerPtr player ) > callback )
{
if( !callback )
return;
for( auto entry : m_playerMap )
{
callback( entry.second );
}
}

View file

@ -183,6 +183,10 @@ namespace Sapphire
void addEffectResult( World::Action::EffectResultPtr result ); void addEffectResult( World::Action::EffectResultPtr result );
void processEffectResults( uint64_t tickCount ); void processEffectResults( uint64_t tickCount );
Entity::PlayerPtr getPlayer( uint32_t charId );
void foreachPlayer( std::function< void( Entity::PlayerPtr player ) > callback );
}; };
} }