From d0e2de1abfeb78aca8ed8ae280c2135c03190af6 Mon Sep 17 00:00:00 2001 From: collett Date: Sun, 15 Aug 2021 20:39:37 +0900 Subject: [PATCH 1/2] play proper scene depending on wedding settings and add some popup message --- .../Network/PacketDef/Zone/ServerZoneDef.h | 6 +- .../common/warptaxi/WarpTaxi131137.cpp | 2 +- .../common/warptaxi/WarpTaxi131142.cpp | 2 +- .../common/warptaxi/WarpTaxi131143.cpp | 2 +- .../common/warptaxi/WarpTaxi131146.cpp | 2 +- .../common/warptaxi/WarpTaxi131147.cpp | 2 +- .../common/warptaxi/WarpTaxi131256.cpp | 2 +- .../common/warptaxi/WarpTaxi131306.cpp | 2 +- .../instances/wedding/SanctumOfTheTwelve.cpp | 241 +++++++++++++----- .../quest/subquest/gridania/SubCts999.cpp | 3 +- src/world/Actor/Player.cpp | 28 +- src/world/Actor/Player.h | 7 +- src/world/Actor/PlayerEvent.cpp | 3 +- src/world/Event/Director.cpp | 4 +- src/world/Event/Director.h | 6 +- src/world/Territory/PublicContent.cpp | 1 + 16 files changed, 228 insertions(+), 85 deletions(-) diff --git a/src/common/Network/PacketDef/Zone/ServerZoneDef.h b/src/common/Network/PacketDef/Zone/ServerZoneDef.h index 42df1579..9d09a47b 100644 --- a/src/common/Network/PacketDef/Zone/ServerZoneDef.h +++ b/src/common/Network/PacketDef/Zone/ServerZoneDef.h @@ -1449,8 +1449,8 @@ namespace Sapphire::Network::Packets::Server uint32_t param3; uint8_t paramSize; uint8_t padding1[3]; - uint32_t param5; uint32_t param[16]; + uint32_t padding2; }; template< int ArgCount > @@ -1849,7 +1849,7 @@ namespace Sapphire::Network::Packets::Server uint32_t bNPCName; uint32_t textId; uint32_t popupTimeMs; - uint32_t pad3[4]; + uint32_t param[6]; }; @@ -2270,7 +2270,7 @@ namespace Sapphire::Network::Packets::Server struct FFXIVCeremonySetActorAppearance : FFXIVIpcBasePacket< CeremonySetActorAppearance > { uint8_t u1; - uint8_t u2; + uint8_t questBL; uint16_t padding1; uint32_t u3; struct diff --git a/src/scripts/common/warptaxi/WarpTaxi131137.cpp b/src/scripts/common/warptaxi/WarpTaxi131137.cpp index 24045225..278efc6b 100644 --- a/src/scripts/common/warptaxi/WarpTaxi131137.cpp +++ b/src/scripts/common/warptaxi/WarpTaxi131137.cpp @@ -19,7 +19,7 @@ public: void onTalk( uint32_t eventId, Entity::Player& player, uint64_t actorId ) override { player.eventFinish( getId(), 1 ); - player.setPosAndSendActorMove( 24.7, 20.1, -679.2, 0.82 ); + player.setPosAndNotifyClient( 24.7, 20.1, -679.2, 0.82 ); } }; diff --git a/src/scripts/common/warptaxi/WarpTaxi131142.cpp b/src/scripts/common/warptaxi/WarpTaxi131142.cpp index ed3d904e..2eb9664f 100644 --- a/src/scripts/common/warptaxi/WarpTaxi131142.cpp +++ b/src/scripts/common/warptaxi/WarpTaxi131142.cpp @@ -19,7 +19,7 @@ public: void onTalk( uint32_t eventId, Entity::Player& player, uint64_t actorId ) override { player.eventFinish( getId(), 1 ); - player.setPosAndSendActorMove( 0, -2, -31, 3.1415 ); + player.setPosAndNotifyClient( 0, -2, -31, 3.1415 ); } }; diff --git a/src/scripts/common/warptaxi/WarpTaxi131143.cpp b/src/scripts/common/warptaxi/WarpTaxi131143.cpp index b21a46c5..4914f475 100644 --- a/src/scripts/common/warptaxi/WarpTaxi131143.cpp +++ b/src/scripts/common/warptaxi/WarpTaxi131143.cpp @@ -19,7 +19,7 @@ public: void onTalk( uint32_t eventId, Entity::Player& player, uint64_t actorId ) override { player.eventFinish( getId(), 1 ); - player.setPosAndSendActorMove( 0, -2, -23, 0 ); + player.setPosAndNotifyClient( 0, -2, -23, 0 ); } }; diff --git a/src/scripts/common/warptaxi/WarpTaxi131146.cpp b/src/scripts/common/warptaxi/WarpTaxi131146.cpp index 1d3d9294..b303f374 100644 --- a/src/scripts/common/warptaxi/WarpTaxi131146.cpp +++ b/src/scripts/common/warptaxi/WarpTaxi131146.cpp @@ -19,7 +19,7 @@ public: void onTalk( uint32_t eventId, Entity::Player& player, uint64_t actorId ) override { player.eventFinish( getId(), 1 ); - player.setPosAndSendActorMove( 565, -1.7, -253, -0.83 ); + player.setPosAndNotifyClient( 565, -1.7, -253, -0.83 ); } }; diff --git a/src/scripts/common/warptaxi/WarpTaxi131147.cpp b/src/scripts/common/warptaxi/WarpTaxi131147.cpp index 0d2f4251..8a6583c2 100644 --- a/src/scripts/common/warptaxi/WarpTaxi131147.cpp +++ b/src/scripts/common/warptaxi/WarpTaxi131147.cpp @@ -19,7 +19,7 @@ public: void onTalk( uint32_t eventId, Entity::Player& player, uint64_t actorId ) override { player.eventFinish( getId(), 1 ); - player.setPosAndSendActorMove( 574, -1.9, -264, 2.62 ); + player.setPosAndNotifyClient( 574, -1.9, -264, 2.62 ); } }; diff --git a/src/scripts/common/warptaxi/WarpTaxi131256.cpp b/src/scripts/common/warptaxi/WarpTaxi131256.cpp index d6d391f0..468b3efb 100644 --- a/src/scripts/common/warptaxi/WarpTaxi131256.cpp +++ b/src/scripts/common/warptaxi/WarpTaxi131256.cpp @@ -19,7 +19,7 @@ public: void onTalk( uint32_t eventId, Entity::Player& player, uint64_t actorId ) override { player.eventFinish( getId(), 1 ); - player.setPosAndSendActorMove( 676, 60, 465, 0 ); + player.setPosAndNotifyClient( 676, 60, 465, 0 ); } }; diff --git a/src/scripts/common/warptaxi/WarpTaxi131306.cpp b/src/scripts/common/warptaxi/WarpTaxi131306.cpp index 5ecdc5db..fef26f36 100644 --- a/src/scripts/common/warptaxi/WarpTaxi131306.cpp +++ b/src/scripts/common/warptaxi/WarpTaxi131306.cpp @@ -19,7 +19,7 @@ public: void onTalk( uint32_t eventId, Entity::Player& player, uint64_t actorId ) override { player.eventFinish( getId(), 1 ); - player.setPosAndSendActorMove( -466, 107.7, 107.7, -2 ); + player.setPosAndNotifyClient( -466, 107.7, 107.7, -2 ); } }; diff --git a/src/scripts/instances/wedding/SanctumOfTheTwelve.cpp b/src/scripts/instances/wedding/SanctumOfTheTwelve.cpp index e9fce321..0587ad59 100644 --- a/src/scripts/instances/wedding/SanctumOfTheTwelve.cpp +++ b/src/scripts/instances/wedding/SanctumOfTheTwelve.cpp @@ -19,6 +19,23 @@ class SanctumOfTheTwelve : public Sapphire::ScriptAPI::PublicContentScript public: SanctumOfTheTwelve() : Sapphire::ScriptAPI::PublicContentScript( 1 ) { } + /* + Custom var usage: + 0: current time + 1: main actor 1 id + 2: main actor 2 id + 3: seq 3 start time + 4: seq 3 internal sequence + 5: seq 3 remaining unfinished player count + 6: seq 4 internal sequence + 101: questBL + 102: questBH + 103: questCL + 104: questCH + 105: questDL + 106: questDH + */ + void onInit( PublicContent& instance ) override { auto exitHandler = [ & ]( Entity::Player& player, Entity::EventObjectPtr eobj, TerritoryPtr terri, uint32_t eventId, uint64_t actorId ) @@ -49,57 +66,23 @@ public: auto p2 = instance.getPlayer( v2 ); if( p1 && p2 ) { - //skip seq 2, 3 for now - instance.setSequence( 4 ); - p1->eventFinish( eventId, 1 ); - FFXIVCeremonySetActorAppearance packetData = {}; - packetData.u1 = 1; - packetData.u2 = 1; - if( !( p1->getEquipDisplayFlags() & Sapphire::Common::EquipDisplayFlags::HideWeapon ) ) + auto seq1Callback = [ & ]( Entity::Player& player, const Event::SceneResult& result ) { - 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 ); - }); + if( result.param1 != 512 || result.param2 != 0 ) + return; + instance.setCustomVar( 3, 0 ); + instance.setCustomVar( 4, 0 ); + //skip 2 for now + instance.setSequence( 3 ); + instance.foreachPlayer( [ &instance ]( auto p ) + { + p->queuePacket( makeActorControlSelf( p->getId(), DirectorUpdate, instance.getDirectorId(), 0x80000001, 1 ) ); + }); + }; + // event item workaround + player.eventFinish( eventId, 1 ); + player.eventStart( player.getId(), instance.getDirectorId(), Event::EventHandler::Item, 0, 2001464 ); + player.playScene( instance.getDirectorId(), 32, 134225921, 0, 1, 1077, seq1Callback ); } else { @@ -138,7 +121,145 @@ public: void onUpdate( PublicContent& instance, uint64_t tickCount ) override { + switch( instance.getSequence() ) + { + case 3: + { + if( instance.getCustomVar( 3 ) == 0 ) + instance.setCustomVar( 3, tickCount ); + auto dt = std::difftime( tickCount, instance.getCustomVar( 3 ) ) / 1000.f; + auto v4 = instance.getCustomVar( 4 ); + switch( v4 ) + { + case 0: + case 1: + case 2: + { + if( dt >= 1 + v4 * 6 ) + { + instance.setCustomVar( 4, v4 + 1 ); + FFXIVIpcDirectorPopUp packetData = {}; + packetData.directorId = instance.getDirectorId(); + packetData.flags = 3; + packetData.bNPCName = 1010505; + packetData.textId = v4 == 0 ? 1088 : ( v4 == 1 ? 1006 : 1007 ); + packetData.popupTimeMs = 6000; + packetData.param[ 0 ] = 1024; + packetData.param[ 1 ] = instance.getCustomVar( 1 ); + packetData.param[ 2 ] = instance.getCustomVar( 2 ); + instance.foreachPlayer( [ &instance, &packetData ]( auto p ) + { + auto packet = makeZonePacket< FFXIVIpcDirectorPopUp >( p->getId() ); + memcpy( &packet->data(), &packetData, sizeof( packetData ) ); + p->queuePacket( packet ); + }); + } + break; + } + case 3: + { + if( dt < 20 ) + return; + instance.setCustomVar( 4, 255 ); + auto p1 = instance.getPlayer( instance.getCustomVar( 1 ) ); + auto p2 = instance.getPlayer( instance.getCustomVar( 2 ) ); + if( !p1 || !p2 ) + { + instance.setSequence( 1 ); + instance.foreachPlayer( [ &instance ]( auto p ) + { + p->sendUrgent( "Failed to start the scene, missing main actors." ); + }); + return; + } + FFXIVCeremonySetActorAppearance packetData = {}; + auto qBL = instance.getCustomVar( 101 ); + packetData.questBL = qBL; + packetData.u1 = 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, qBL ]( 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::GameProgress, 1, 1 ); + std::vector< uint32_t > paramList; + paramList.push_back( qBL < 2 ? 664 : 665 ); + + auto seq3Callback = [ & ]( Entity::Player& player, const Event::SceneResult& result ) + { + //keep everyone in their room for now + /* + if( player.getId() == instance.getCustomVar( 1 ) ) + { + player.setPosAndNotifyClient( 1.454, 3.12581, -132.7992, -3.14 ); + } + else if( player.getId() == instance.getCustomVar( 2 ) ) + { + player.setPosAndNotifyClient( -1.454, 3.12581, -132.7992, -3.14 ); + } + else + { + player.setPosAndNotifyClient( 0, 2.64, -119, -3.14 ); + } + */ + auto v5 = instance.getCustomVar( 5 ); + v5--; + instance.setCustomVar( 5, v5 ); + if( v5 == 0 ) + { + player.sendDebug( "all players finished scene" ); + } + }; + + p->playScene16( instance.getDirectorId(), 3, 9219, 0, paramList, seq3Callback ); + }); + instance.setCustomVar( 5, instance.getPopCount() ); + instance.setCustomVar( 6, 0 ); + instance.setSequence( 4 ); + break; + } + } + } + break; + } + instance.setCustomVar( 0, tickCount ); } void onPlayerZoneIn( PublicContent& instance, Entity::Player& player ) override @@ -154,10 +275,12 @@ public: instance.setDirectorUI8DL( player.getGuardianDeity() ); instance.setDirectorUI8EL( player.getQuestUI8FH( 67114 ) ); instance.setDirectorUI8FL( player.getQuestUI8FL( 67114 ) ); - instance.setDirectorUI8GL( 1 ); - instance.setDirectorUI8HL( 1 ); - instance.setDirectorUI8IL( 1 ); - instance.setDirectorUI8JL( 1 ); + instance.setCustomVar( 101, player.getQuestUI8BL( 67114 ) ); + instance.setCustomVar( 102, player.getQuestUI8BH( 67114 ) ); + instance.setCustomVar( 103, player.getQuestUI8CL( 67114 ) ); + instance.setCustomVar( 104, player.getQuestUI8CH( 67114 ) ); + instance.setCustomVar( 105, player.getQuestUI8DL( 67114 ) ); + instance.setCustomVar( 106, player.getQuestUI8DH( 67114 ) ); } } else if( instance.getCustomVar( 2 ) == 0 || instance.getCustomVar( 2 ) == player.getId() ) @@ -188,17 +311,17 @@ public: auto callback = [ & ]( Entity::Player& player, const Event::SceneResult& result ) { }; - if( instance.getCustomVar( 1 ) == player.getId() ) + if( instance.getCustomVar( 1 ) == player.getId() && instance.getSequence() == 1 ) { - player.setPosAndSendActorMove( 0, 500, -50, -3.14f ); + player.setPosAndNotifyClient( 0, 500, -50, -3.14f ); } - else if( instance.getCustomVar( 2 ) == player.getId() ) + else if( instance.getCustomVar( 2 ) == player.getId() && instance.getSequence() == 1 ) { - player.setPosAndSendActorMove( 0, 250, -50, -3.14f ); + player.setPosAndNotifyClient( 0, 250, -50, -3.14f ); } else { - player.setPosAndSendActorMove( 0, 750, -50, -3.14f ); + player.setPosAndNotifyClient( 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 ); diff --git a/src/scripts/quest/subquest/gridania/SubCts999.cpp b/src/scripts/quest/subquest/gridania/SubCts999.cpp index 46d6a577..44585736 100644 --- a/src/scripts/quest/subquest/gridania/SubCts999.cpp +++ b/src/scripts/quest/subquest/gridania/SubCts999.cpp @@ -1407,8 +1407,9 @@ private: } }; std::vector< uint32_t > list; + list.push_back( 0 ); list.push_back( std::time( 0 ) ); - player.playScene16( getId(), 70, HIDE_HOTBAR, 0, 0, list, callback ); + player.playScene16( getId(), 70, HIDE_HOTBAR, 0, list, callback ); } void Scene00071( Entity::Player& player ) diff --git a/src/world/Actor/Player.cpp b/src/world/Actor/Player.cpp index 587cc6c8..e376ee9c 100644 --- a/src/world/Actor/Player.cpp +++ b/src/world/Actor/Player.cpp @@ -1925,6 +1925,8 @@ void Sapphire::Entity::Player::sendZonePackets() // if( getLastPing() == 0 ) // sendQuestInfo(); + sendPartyList(); + m_bMarkedForZoning = false; } @@ -2536,7 +2538,7 @@ uint8_t Sapphire::Entity::Player::getPartySize() return 0; } -void Sapphire::Entity::Player::sendPartyListToParty() +void Sapphire::Entity::Player::sendPartyListToParty( PlayerPtr filter ) { assert( isPartyLeader() ); FFXIVIpcPartyList partyList = {}; @@ -2571,9 +2573,25 @@ void Sapphire::Entity::Player::sendPartyListToParty() for( auto member : m_partyMemberList ) { - auto packet = makeZonePacket< FFXIVIpcPartyList >( member->getId() ); - memcpy( &packet->data().member[ 0 ], &partyList, sizeof( partyList ) ); - member->queuePacket( packet ); + if( !filter || member->getId() == filter->getId() ) + { + auto packet = makeZonePacket< FFXIVIpcPartyList >( member->getId() ); + memcpy( &packet->data().member[ 0 ], &partyList, sizeof( partyList ) ); + member->queuePacket( packet ); + } + } +} + +void Sapphire::Entity::Player::sendPartyList() +{ + if( !isInParty() ) + { + auto packet = makeZonePacket< FFXIVIpcPartyList >( getId() ); + queuePacket( packet ); + } + else + { + getPartyLeader()->sendPartyListToParty( getAsPlayer() ); } } @@ -2821,7 +2839,7 @@ bool Sapphire::Entity::Player::gaugeSamHasAnySen() return static_cast< uint8_t >( m_gauge.sam.sen ) > 0; } -void Sapphire::Entity::Player::setPosAndSendActorMove( float x, float y, float z, float rot ) +void Sapphire::Entity::Player::setPosAndNotifyClient( float x, float y, float z, float rot ) { setRot( rot ); setPos( x, y, z, true ); diff --git a/src/world/Actor/Player.h b/src/world/Actor/Player.h index 39c6ddc0..d8991cdd 100644 --- a/src/world/Actor/Player.h +++ b/src/world/Actor/Player.h @@ -111,7 +111,7 @@ namespace Sapphire::Entity void playSceneChain( uint32_t eventId, uint32_t scene, uint32_t flags, Event::EventHandler::SceneChainCallback sceneChainCallback ); - void playScene16( uint32_t eventId, uint32_t scene, uint32_t flags, uint32_t param3, uint32_t param5, std::vector< uint32_t > paramList, Event::EventHandler::SceneReturnCallback eventReturnCallback ); + void playScene16( uint32_t eventId, uint32_t scene, uint32_t flags, uint32_t param3, std::vector< uint32_t > paramList, Event::EventHandler::SceneReturnCallback eventReturnCallback ); /*! setup the event and return a ptr to it */ Event::EventHandlerPtr bootstrapSceneEvent( uint32_t eventId, uint32_t flags ); @@ -1033,7 +1033,8 @@ namespace Sapphire::Entity PlayerPtr m_partyInvitationSender; std::vector< PlayerPtr > m_partyMemberList; void clearPartyList(); - void sendPartyListToParty(); + void sendPartyListToParty( PlayerPtr filter = nullptr ); + void sendPartyList(); public: bool isPartyLeader(); bool isInParty(); @@ -1049,7 +1050,7 @@ namespace Sapphire::Entity void foreachPartyMember( std::function< void( PlayerPtr member ) > callback); ////////////////////////////////////////////////////////////////////////////////////////////////////// - void setPosAndSendActorMove( float x, float y, float z, float rot ); + void setPosAndNotifyClient( float x, float y, float z, float rot ); std::unordered_map< uint32_t, TerritoryPtr > m_privateInstanceMap; TerritoryPtr getOrCreatePrivateInstance( uint32_t zoneId ); bool enterPredefinedPrivateInstance( uint32_t zoneId ); diff --git a/src/world/Actor/PlayerEvent.cpp b/src/world/Actor/PlayerEvent.cpp index 33c4efe3..eb9659e0 100644 --- a/src/world/Actor/PlayerEvent.cpp +++ b/src/world/Actor/PlayerEvent.cpp @@ -323,7 +323,7 @@ void Sapphire::Entity::Player::eventFinish( uint32_t eventId, uint32_t freePlaye unsetStateFlag( PlayerStateFlag::InNpcEvent ); } -void Sapphire::Entity::Player::playScene16( uint32_t eventId, uint32_t scene, uint32_t flags, uint32_t param3, uint32_t param5, std::vector< uint32_t > paramList, Event::EventHandler::SceneReturnCallback eventReturnCallback ) +void Sapphire::Entity::Player::playScene16( uint32_t eventId, uint32_t scene, uint32_t flags, uint32_t param3, std::vector< uint32_t > paramList, Event::EventHandler::SceneReturnCallback eventReturnCallback ) { auto pEvent = bootstrapSceneEvent( eventId, flags ); if( !pEvent ) @@ -338,7 +338,6 @@ void Sapphire::Entity::Player::playScene16( uint32_t eventId, uint32_t scene, ui eventPlay16->data().scene = scene; eventPlay16->data().flags = flags; eventPlay16->data().param3 = param3; - eventPlay16->data().param5 = param5; eventPlay16->data().paramSize = paramList.size(); int i = 0; for( auto p : paramList ) diff --git a/src/world/Event/Director.cpp b/src/world/Event/Director.cpp index 48a313d4..c3eb06f0 100644 --- a/src/world/Event/Director.cpp +++ b/src/world/Event/Director.cpp @@ -198,12 +198,12 @@ void Sapphire::Event::Director::setDirectorSequence( uint8_t value ) m_sequence = value; } -void Sapphire::Event::Director::setCustomVar( uint32_t varId, uint32_t value ) +void Sapphire::Event::Director::setCustomVar( uint32_t varId, uint64_t value ) { m_customVarMap[ varId ] = value; } -uint32_t Sapphire::Event::Director::getCustomVar( uint32_t varId ) +uint64_t Sapphire::Event::Director::getCustomVar( uint32_t varId ) { auto it = m_customVarMap.find( varId ); if( it != m_customVarMap.end() ) diff --git a/src/world/Event/Director.h b/src/world/Event/Director.h index 123865ad..3bc9efaa 100644 --- a/src/world/Event/Director.h +++ b/src/world/Event/Director.h @@ -106,8 +106,8 @@ namespace Sapphire::Event void setDirectorBranch( uint8_t value ); - void setCustomVar( uint32_t varId, uint32_t value ); - uint32_t getCustomVar( uint32_t varId ); + void setCustomVar( uint32_t varId, uint64_t value ); + uint64_t getCustomVar( uint32_t varId ); private: /*! Id of the content of the director */ @@ -187,7 +187,7 @@ namespace Sapphire::Event uint32_t m_elapsedTime; - std::unordered_map< uint32_t, uint32_t > m_customVarMap; + std::unordered_map< uint32_t, uint64_t > m_customVarMap; }; diff --git a/src/world/Territory/PublicContent.cpp b/src/world/Territory/PublicContent.cpp index 0285f92f..a74f15dd 100644 --- a/src/world/Territory/PublicContent.cpp +++ b/src/world/Territory/PublicContent.cpp @@ -84,6 +84,7 @@ void Sapphire::PublicContent::onLeaveTerritory( Entity::Player& player ) void Sapphire::PublicContent::onUpdate( uint64_t tickCount ) { + updateBNpcs( tickCount ); auto& scriptMgr = Common::Service< Scripting::ScriptMgr >::ref(); scriptMgr.onPublicContentUpdate( getAsPublicContent(), tickCount ); } From 8416e5d5e2d22e2daebeaadccecbb10151c4aafc Mon Sep 17 00:00:00 2001 From: collett Date: Sun, 15 Aug 2021 21:41:00 +0900 Subject: [PATCH 2/2] new event yield handler --- src/common/Common.h | 12 ------- src/common/Network/PacketDef/Ipcs.h | 11 ++----- .../Network/PacketDef/Zone/ClientZoneDef.h | 18 +++++++++-- .../Network/PacketDef/Zone/ServerZoneDef.h | 2 +- .../quest/subquest/gridania/SubCts999.cpp | 24 +++++++------- src/world/Network/GameConnection.cpp | 3 +- src/world/Network/GameConnection.h | 2 +- src/world/Network/Handlers/EventHandlers.cpp | 31 ++++++++++++++----- src/world/Script/NativeScriptApi.cpp | 2 +- src/world/Script/NativeScriptApi.h | 2 +- src/world/Script/ScriptMgr.cpp | 6 ++-- src/world/Script/ScriptMgr.h | 2 +- 12 files changed, 62 insertions(+), 53 deletions(-) diff --git a/src/common/Common.h b/src/common/Common.h index fe8636fd..6bfdd5ab 100644 --- a/src/common/Common.h +++ b/src/common/Common.h @@ -1312,18 +1312,6 @@ namespace Sapphire::Common GetGil = 9, // p1: gil EmptyCoffer = 11, // seems like no param }; - - struct EventSaveData - { - uint32_t eventId; - uint16_t scene; - uint16_t unknown1; - uint32_t params[11]; - uint64_t unknown2; - uint8_t unknown3[4]; - uint64_t unknown4; - }; - } #endif diff --git a/src/common/Network/PacketDef/Ipcs.h b/src/common/Network/PacketDef/Ipcs.h index 541ad6d0..7bce247e 100644 --- a/src/common/Network/PacketDef/Ipcs.h +++ b/src/common/Network/PacketDef/Ipcs.h @@ -194,14 +194,7 @@ namespace Sapphire::Network::Packets EventPlay128 = 0x026E, // updated 5.58 EventPlay255 = 0x039E, // updated 5.58 - EventYield = 0x0123, // updated 5.58 - //EventYield4 = 0x0000, - //EventYield8 = 0x0000, - //EventYield16 = 0x0000, - //EventYield32 = 0x0000, - //EventYield64 = 0x0000, - //EventYield128 = 0x0000, - //EventYield255 = 0x0000, + EventContinue = 0x0123, // updated 5.58 EventStart = 0x01CC, // updated 5.58 EventFinish = 0x0180, // updated 5.58 @@ -401,7 +394,7 @@ namespace Sapphire::Network::Packets ReturnEventHandler = 0x0333, // updated 5.58 TradeReturnEventHandler = 0x0179, // updated 5.58 TradeReturnEventHandler2 = 0x02E1, // updated 5.58 - SaveDataEventHandler = 0x03D7, // updated 5.58 + EventYield16Handler = 0x03D7, // updated 5.58 LinkshellEventHandler = 0x016B, // updated 4.5 LinkshellEventHandler1 = 0x016C, // updated 4.5 diff --git a/src/common/Network/PacketDef/Zone/ClientZoneDef.h b/src/common/Network/PacketDef/Zone/ClientZoneDef.h index 772f6a1c..903abf90 100644 --- a/src/common/Network/PacketDef/Zone/ClientZoneDef.h +++ b/src/common/Network/PacketDef/Zone/ClientZoneDef.h @@ -446,10 +446,22 @@ struct FFXIVIpcHousingEditInterior : uint16_t slot[10]; }; -struct FFXIVIpcSaveDataEventHandler : - FFXIVIpcBasePacket< SaveDataEventHandler > +struct FFXIVIpcEventYieldHandler : + FFXIVIpcBasePacket< EventYieldHandler > { - Common::EventSaveData data; + uint32_t eventId; + uint16_t scene; + uint16_t padding; + uint64_t unknown; +}; + +struct FFXIVIpcEventYield16Handler : + FFXIVIpcBasePacket< EventYield16Handler > +{ + uint32_t eventId; + uint16_t scene; + uint16_t padding; + uint32_t params[16]; }; struct FFXIVIpcCFCommenceHandler : diff --git a/src/common/Network/PacketDef/Zone/ServerZoneDef.h b/src/common/Network/PacketDef/Zone/ServerZoneDef.h index 9d09a47b..c0899b1e 100644 --- a/src/common/Network/PacketDef/Zone/ServerZoneDef.h +++ b/src/common/Network/PacketDef/Zone/ServerZoneDef.h @@ -2253,7 +2253,7 @@ namespace Sapphire::Network::Packets::Server uint8_t padding[3]; }; - struct FFXIVIpcEventYield : FFXIVIpcBasePacket< EventYield > + struct FFXIVIpcEventContinue : FFXIVIpcBasePacket< EventContinue > { uint32_t eventId; uint16_t scene; diff --git a/src/scripts/quest/subquest/gridania/SubCts999.cpp b/src/scripts/quest/subquest/gridania/SubCts999.cpp index 44585736..84826b5f 100644 --- a/src/scripts/quest/subquest/gridania/SubCts999.cpp +++ b/src/scripts/quest/subquest/gridania/SubCts999.cpp @@ -508,22 +508,22 @@ public: onProgress( player, param1, param2, 4, 0 ); } - void onSaveData( Sapphire::Entity::Player& player, const Common::EventSaveData& data ) override + void onEventYield( Sapphire::Entity::Player& player, uint16_t scene, std::vector< uint32_t > param ) override { - if( data.scene == 69 ) + if( scene == 69 ) { - player.setQuestUI8AH( getId(), data.params[0] ); - player.setQuestUI8AL( getId(), data.params[1] ); - player.setQuestUI8BH( getId(), data.params[2] ); - player.setQuestUI8BL( getId(), data.params[3] ); - player.setQuestUI8CH( getId(), data.params[4] ); - player.setQuestUI8CL( getId(), data.params[5] ); - player.setQuestUI8DH( getId(), data.params[6] ); - player.setQuestUI8DL( getId(), data.params[7] ); + player.setQuestUI8AH( getId(), param[0] ); + player.setQuestUI8AL( getId(), param[1] ); + player.setQuestUI8BH( getId(), param[2] ); + player.setQuestUI8BL( getId(), param[3] ); + player.setQuestUI8CH( getId(), param[4] ); + player.setQuestUI8CL( getId(), param[5] ); + player.setQuestUI8DH( getId(), param[6] ); + player.setQuestUI8DL( getId(), param[7] ); // retail does not save these two values here, we borrow them since they are unused. - player.setQuestUI8FH( getId(), data.params[8] ); - player.setQuestUI8FL( getId(), data.params[9] ); + player.setQuestUI8FH( getId(), param[8] ); + player.setQuestUI8FL( getId(), param[9] ); player.sendDebug( "Ceremony settings saved." ); } } diff --git a/src/world/Network/GameConnection.cpp b/src/world/Network/GameConnection.cpp index 9f45b926..fc0c6028 100644 --- a/src/world/Network/GameConnection.cpp +++ b/src/world/Network/GameConnection.cpp @@ -106,7 +106,8 @@ Sapphire::Network::GameConnection::GameConnection( Sapphire::Network::HivePtr pH setZoneHandler( ClientZoneIpcType::TradeReturnEventHandler, "TradeReturnEventHandler", &GameConnection::eventHandlerReturn ); setZoneHandler( ClientZoneIpcType::TradeReturnEventHandler2, "TradeReturnEventHandler2", &GameConnection::eventHandlerReturn ); - setZoneHandler( ClientZoneIpcType::SaveDataEventHandler, "SaveDataEventHandler", &GameConnection::saveDataEventHandler ); + setZoneHandler( ClientZoneIpcType::EventYieldHandler, "EventYieldHandler", &GameConnection::eventYieldHandler ); + setZoneHandler( ClientZoneIpcType::EventYield16Handler, "EventYield16Handler", &GameConnection::eventYieldHandler ); setZoneHandler( ClientZoneIpcType::ShopEventHandler, "ShopEventHandler", &GameConnection::eventHandlerShop ); diff --git a/src/world/Network/GameConnection.h b/src/world/Network/GameConnection.h index 76013146..a01f0749 100644 --- a/src/world/Network/GameConnection.h +++ b/src/world/Network/GameConnection.h @@ -209,7 +209,7 @@ namespace Sapphire::Network DECLARE_HANDLER( disbandPartyHandler ); - DECLARE_HANDLER( saveDataEventHandler ); + DECLARE_HANDLER( eventYieldHandler ); }; } diff --git a/src/world/Network/Handlers/EventHandlers.cpp b/src/world/Network/Handlers/EventHandlers.cpp index 19c9b3d0..744e6575 100644 --- a/src/world/Network/Handlers/EventHandlers.cpp +++ b/src/world/Network/Handlers/EventHandlers.cpp @@ -303,24 +303,39 @@ void Sapphire::Network::GameConnection::eventHandlerShop( const Packets::FFXIVAR scriptMgr.onTalk( player, player.getId(), eventId ); } -void Sapphire::Network::GameConnection::saveDataEventHandler( const Packets::FFXIVARR_PACKET_RAW& inPacket, Entity::Player& player ) +void Sapphire::Network::GameConnection::eventYieldHandler( const Packets::FFXIVARR_PACKET_RAW& inPacket, Entity::Player& player ) { auto& scriptMgr = Common::Service< Scripting::ScriptMgr >::ref(); auto& eventMgr = Common::Service< World::Manager::EventMgr >::ref(); - const auto packet = ZoneChannelPacket< Client::FFXIVIpcSaveDataEventHandler >( inPacket ); + auto opcode = *reinterpret_cast< const uint16_t* >( &inPacket.data[ 2 ] ); + auto eventId = *reinterpret_cast< const uint32_t* >( &inPacket.data[ 0x10 + 0 ] ); + auto scene = *reinterpret_cast< const uint16_t* >( &inPacket.data[ 0x10 + 4 ] ); + auto pParam = reinterpret_cast< const uint32_t* >( &inPacket.data[ 0x10 + 8 ] ); + + std::vector< uint32_t > param; - const auto eventId = packet.data().data.eventId; + switch( opcode ) + { + case EventYield16Handler: + { + for( int i = 0; i < 16; i++ ) + { + param.push_back( pParam[ i ] ); + } + break; + } + } - std::string eventName = "onSaveData"; + std::string eventName = "onEventYield"; std::string objName = eventMgr.getEventName( eventId ); - player.sendDebug( "Calling: {0}.{1} - {2} scene: {3}", objName, eventName, eventId, packet.data().data.scene ); + player.sendDebug( "Calling: {0}.{1} - {2} scene: {3}", objName, eventName, eventId, scene ); - scriptMgr.onSaveData( player, packet.data().data ); + scriptMgr.onEventYield( player, eventId, scene, param ); - auto response = makeZonePacket< FFXIVIpcEventYield >( player.getId() ); + auto response = makeZonePacket< FFXIVIpcEventContinue >( player.getId() ); response->data().eventId = eventId; - response->data().scene = packet.data().data.scene; + response->data().scene = scene; player.queuePacket( response ); } diff --git a/src/world/Script/NativeScriptApi.cpp b/src/world/Script/NativeScriptApi.cpp index 4c04f36e..70e32151 100644 --- a/src/world/Script/NativeScriptApi.cpp +++ b/src/world/Script/NativeScriptApi.cpp @@ -150,7 +150,7 @@ namespace Sapphire::ScriptAPI { } - void EventScript::onSaveData( Sapphire::Entity::Player& player, const Common::EventSaveData& data ) + void EventScript::onEventYield( Sapphire::Entity::Player& player, uint16_t scene, std::vector< uint32_t > param ) { } diff --git a/src/world/Script/NativeScriptApi.h b/src/world/Script/NativeScriptApi.h index e01bd15c..072da949 100644 --- a/src/world/Script/NativeScriptApi.h +++ b/src/world/Script/NativeScriptApi.h @@ -175,7 +175,7 @@ namespace Sapphire::ScriptAPI virtual void onEObjHit( Sapphire::Entity::Player& player, uint64_t actorId, uint32_t actionId ); - virtual void onSaveData( Sapphire::Entity::Player& player, const Common::EventSaveData& data ); + virtual void onEventYield( Sapphire::Entity::Player& player, uint16_t scene, std::vector< uint32_t > param ); }; /*! diff --git a/src/world/Script/ScriptMgr.cpp b/src/world/Script/ScriptMgr.cpp index d7e9cb2e..6e1e3595 100644 --- a/src/world/Script/ScriptMgr.cpp +++ b/src/world/Script/ScriptMgr.cpp @@ -588,12 +588,12 @@ bool Sapphire::Scripting::ScriptMgr::onDutyComplete( Sapphire::QuestBattlePtr in return false; } -bool Sapphire::Scripting::ScriptMgr::onSaveData( Sapphire::Entity::Player& player, const Sapphire::Common::EventSaveData& data ) +bool Sapphire::Scripting::ScriptMgr::onEventYield( Sapphire::Entity::Player& player, uint32_t eventId, uint16_t scene, std::vector< uint32_t > param ) { - auto script = m_nativeScriptMgr->getScript< Sapphire::ScriptAPI::EventScript >( data.eventId ); + auto script = m_nativeScriptMgr->getScript< Sapphire::ScriptAPI::EventScript >( eventId ); if( script ) { - script->onSaveData( player, data ); + script->onEventYield( player, scene, param ); return true; } diff --git a/src/world/Script/ScriptMgr.h b/src/world/Script/ScriptMgr.h index 08066519..776d1357 100644 --- a/src/world/Script/ScriptMgr.h +++ b/src/world/Script/ScriptMgr.h @@ -120,7 +120,7 @@ namespace Sapphire::Scripting bool onDutyComplete( QuestBattlePtr instance, Entity::Player& player ); - bool onSaveData( Entity::Player& player, const Common::EventSaveData& data ); + bool onEventYield( Entity::Player& player, uint32_t eventId, uint16_t scene, std::vector< uint32_t > param ); bool onPublicContentInit( PublicContentPtr instance );