From 4ec86cdf81c98f3b6fb78854a5260982030a0a46 Mon Sep 17 00:00:00 2001 From: Mordred Date: Tue, 8 Feb 2022 12:46:18 +0100 Subject: [PATCH] Implemented onSay event --- .../Network/PacketDef/Zone/ClientZoneDef.h | 7 ++++ src/world/Manager/WarpMgr.cpp | 4 +- src/world/Network/GameConnection.h | 2 + src/world/Network/Handlers/EventHandlers.cpp | 27 +++++++++++++ src/world/Script/NativeScriptApi.cpp | 4 ++ src/world/Script/NativeScriptApi.h | 2 + src/world/Script/ScriptMgr.cpp | 40 +++++++++++++++++++ src/world/Script/ScriptMgr.h | 2 + 8 files changed, 86 insertions(+), 2 deletions(-) diff --git a/src/common/Network/PacketDef/Zone/ClientZoneDef.h b/src/common/Network/PacketDef/Zone/ClientZoneDef.h index 15463019..066261e3 100644 --- a/src/common/Network/PacketDef/Zone/ClientZoneDef.h +++ b/src/common/Network/PacketDef/Zone/ClientZoneDef.h @@ -476,6 +476,13 @@ struct FFXIVIpcShopEventHandler : FFXIVIpcBasePacket< StartUIEvent > /* 0004 */ uint32_t param; }; +struct FFXIVIpcStartSayEventHandler : FFXIVIpcBasePacket< StartSayEvent > +{ + uint64_t targetId; + uint32_t handlerId; + uint32_t sayId; +}; + struct FFXIVIpcClientInventoryItemOperation : FFXIVIpcBasePacket< ClientItemOperation > { uint32_t ContextId; diff --git a/src/world/Manager/WarpMgr.cpp b/src/world/Manager/WarpMgr.cpp index 0cf614c4..324638f9 100644 --- a/src/world/Manager/WarpMgr.cpp +++ b/src/world/Manager/WarpMgr.cpp @@ -27,8 +27,6 @@ using namespace Sapphire::Network::Packets::WorldPackets::Server; void WarpMgr::requestMoveTerritory( Entity::Player& player, Common::WarpType warpType, uint32_t targetTerritoryId, Common::FFXIVARR_POSITION3 targetPos, float targetRot ) { - m_entityIdToWarpInfoMap[ player.getId() ] = { targetTerritoryId, warpType, targetPos, targetRot }; - auto& teriMgr = Common::Service< TerritoryMgr >::ref(); auto& server = Common::Service< WorldServer >::ref(); @@ -36,6 +34,8 @@ void WarpMgr::requestMoveTerritory( Entity::Player& player, Common::WarpType war if( !pTeri ) return; + m_entityIdToWarpInfoMap[ player.getId() ] = { targetTerritoryId, warpType, targetPos, targetRot }; + player.updatePrevTerritory(); player.sendToInRangeSet( makeActorControl( player.getId(), WarpStart, warpType, 1, pTeri->getTerritoryTypeId() ), true ); diff --git a/src/world/Network/GameConnection.h b/src/world/Network/GameConnection.h index b4d9c765..a9c371bc 100644 --- a/src/world/Network/GameConnection.h +++ b/src/world/Network/GameConnection.h @@ -173,6 +173,8 @@ namespace Sapphire::Network DECLARE_HANDLER( startUiEvent ); + DECLARE_HANDLER( startEventSayHandler ); + DECLARE_HANDLER( yieldEventString ); DECLARE_HANDLER( yieldEventSceneIntAndString ); diff --git a/src/world/Network/Handlers/EventHandlers.cpp b/src/world/Network/Handlers/EventHandlers.cpp index 71cf5dd2..02e568db 100644 --- a/src/world/Network/Handlers/EventHandlers.cpp +++ b/src/world/Network/Handlers/EventHandlers.cpp @@ -449,6 +449,33 @@ void Sapphire::Network::GameConnection::yieldEventSceneIntAndString( const Packe eventMgr.handleReturnIntAndStringEventScene( player, data.handlerId, data.sceneId, inString, data.integer ); } +void Sapphire::Network::GameConnection::startEventSayHandler( const Packets::FFXIVARR_PACKET_RAW& inPacket, Entity::Player& player ) +{ + auto& eventMgr = Common::Service< World::Manager::EventMgr >::ref(); + auto& scriptMgr = Common::Service< Scripting::ScriptMgr >::ref(); + + const auto packet = ZoneChannelPacket< FFXIVIpcStartSayEventHandler >( inPacket ); + const auto actorId = packet.data().targetId; + const auto eventId = packet.data().handlerId; + const auto sayId = packet.data().sayId; + + auto eventType = static_cast< uint16_t >( eventId >> 16 ); + + std::string eventName = "onSay"; + std::string objName = eventMgr.getEventName( eventId ); + + World::Manager::PlayerMgr::sendDebug( player, "Chara: {0} -> {1} \neventId: {2} ({3:08X})", + actorId, eventMgr.mapEventActorToRealActor( static_cast< uint32_t >( actorId ) ), + eventId, eventId ); + + World::Manager::PlayerMgr::sendDebug( player, "Calling: {0}.{1}", objName, eventName ); + eventMgr.eventStart( player, actorId, eventId, Event::EventHandler::Say, 0, 0 ); + scriptMgr.onSay( player, actorId, eventId, sayId ); + + eventMgr.checkEvent( player, eventId ); + +} + void Sapphire::Network::GameConnection::startUiEvent( const Packets::FFXIVARR_PACKET_RAW& inPacket, Entity::Player& player ) { diff --git a/src/world/Script/NativeScriptApi.cpp b/src/world/Script/NativeScriptApi.cpp index 181b3aa9..dcf124c6 100644 --- a/src/world/Script/NativeScriptApi.cpp +++ b/src/world/Script/NativeScriptApi.cpp @@ -142,6 +142,10 @@ namespace Sapphire::ScriptAPI { } + void QuestScript::onSay( World::Quest& quest, Entity::Player& player, uint64_t actorId, uint32_t sayId ) + { + } + void QuestScript::onEventItem( World::Quest& quest, Entity::Player& player, uint64_t actorId ) { } diff --git a/src/world/Script/NativeScriptApi.h b/src/world/Script/NativeScriptApi.h index f6b8eb57..4d5153de 100644 --- a/src/world/Script/NativeScriptApi.h +++ b/src/world/Script/NativeScriptApi.h @@ -217,6 +217,8 @@ namespace Sapphire::ScriptAPI virtual void onTalk( World::Quest& quest, Sapphire::Entity::Player& player, uint64_t actorId ); + virtual void onSay( World::Quest& quest, Sapphire::Entity::Player& player, uint64_t actorId, uint32_t sayId ); + virtual void onEventItem( World::Quest& quest, Sapphire::Entity::Player& player, uint64_t actorId ); virtual void onBNpcKill( World::Quest& quest, uint16_t nameId, uint32_t entityId, Sapphire::Entity::Player& player ); diff --git a/src/world/Script/ScriptMgr.cpp b/src/world/Script/ScriptMgr.cpp index 2bbabfd0..49a741fb 100644 --- a/src/world/Script/ScriptMgr.cpp +++ b/src/world/Script/ScriptMgr.cpp @@ -725,3 +725,43 @@ Sapphire::Scripting::ScriptMgr::onDutyComplete( QuestBattle& instance, Sapphire: return false; } + +bool Sapphire::Scripting::ScriptMgr::onSay( Sapphire::Entity::Player& player, uint64_t actorId, uint32_t eventId, uint32_t sayId ) +{ + auto eventType = static_cast< uint16_t >( eventId >> 16 ); + auto& exdData = Common::Service< Data::ExdData >::ref(); + if( eventType == Event::EventHandler::EventHandlerType::Quest ) + { + auto script = m_nativeScriptMgr->getScript< Sapphire::ScriptAPI::QuestScript >( eventId ); + if( !script ) + { + auto questInfo = exdData.getRow< Excel::Quest >( eventId ); + if( questInfo ) + { + World::Manager::PlayerMgr::sendUrgent( player, "Quest not implemented: {0} ({1})", questInfo->getString( questInfo->data().Text.Name ), eventId ); + return false; + } + } + + auto& pEventMgr = Common::Service< World::Manager::EventMgr >::ref(); + auto actor = pEventMgr.mapEventActorToRealActor( static_cast< uint32_t >( actorId ) ); + + auto questId = static_cast< uint16_t >( eventId ); + if( player.hasQuest( eventId ) ) + { + World::Quest preQ; + auto questIdx = player.getQuestIndex( questId ); + auto& quest = player.getQuestByIndex( questIdx ); + preQ = quest; + script->onSay( quest, player, actor, sayId ); + if( quest != preQ ) + player.updateQuest( quest ); + } + else + { + auto newQuest = World::Quest( questId, 0, 0 ); + script->onSay( newQuest, player, actor, sayId ); + } + return true; + } +} diff --git a/src/world/Script/ScriptMgr.h b/src/world/Script/ScriptMgr.h index 86042338..aeb000c9 100644 --- a/src/world/Script/ScriptMgr.h +++ b/src/world/Script/ScriptMgr.h @@ -56,6 +56,8 @@ namespace Sapphire::Scripting bool onTalk( Entity::Player& player, uint64_t actorId, uint32_t eventId ); + bool onSay( Entity::Player& player, uint64_t actorId, uint32_t eventId, uint32_t sayId ); + bool onEnterTerritory( Entity::Player& player, uint32_t eventId, uint16_t param1, uint16_t param2 ); bool onWithinRange( Entity::Player& player, uint32_t eventId, uint32_t param1, float x, float y, float z );