From 37e7c2e51bed81b9e40a0b5ba97c8128402de26f Mon Sep 17 00:00:00 2001 From: Mordred Date: Mon, 5 Mar 2018 23:01:55 +0100 Subject: [PATCH] Basic event play for directors, still buggy. Also some small fixes all around --- src/common/Network/PacketDef/Ipcs.h | 9 ++- .../Network/PacketDef/Zone/ServerZoneDef.h | 26 +++++++-- src/servers/sapphire_zone/Actor/Chara.cpp | 3 + .../sapphire_zone/Actor/EventObject.cpp | 14 ++--- src/servers/sapphire_zone/Actor/EventObject.h | 8 +-- src/servers/sapphire_zone/Actor/Player.cpp | 6 +- src/servers/sapphire_zone/Actor/Player.h | 3 + .../sapphire_zone/Actor/PlayerEvent.cpp | 22 ++++++++ .../Network/Handlers/ActionHandler.cpp | 7 +++ .../PacketWrappers/DirectorPlayScenePacket.h | 55 +++++++++++++++++++ .../Scripts/instances/dungeons/Sastasha.cpp | 3 +- .../sapphire_zone/Zone/InstanceContent.cpp | 6 ++ .../sapphire_zone/Zone/InstanceContent.h | 1 + src/servers/sapphire_zone/Zone/Zone.h | 1 + 14 files changed, 143 insertions(+), 21 deletions(-) create mode 100644 src/servers/sapphire_zone/Network/PacketWrappers/DirectorPlayScenePacket.h diff --git a/src/common/Network/PacketDef/Ipcs.h b/src/common/Network/PacketDef/Ipcs.h index 49b67bd9..fe3785af 100644 --- a/src/common/Network/PacketDef/Ipcs.h +++ b/src/common/Network/PacketDef/Ipcs.h @@ -102,16 +102,18 @@ namespace Packets { NpcSpawn = 0x015D, // updated 4.2 ActorMove = 0x015E, // updated 4.2 ActorSetPos = 0x0160, // updated 4.2 + ActorCast = 0x0162, // updated 4.2 + HateList = 0x0165, // updated 4.2 + ObjectSpawn = 0x0167, // updated 4.2 ObjectDespawn = 0x0168, // updated 4.2 UpdateClassInfo = 0x0169, // updated 4.2 + InitUI = 0x016B, // updated 4.2 - - ActorOwner = 0x016D, // updated 4.2 ? - PlayerStats = 0x016C, // updated 4.2 + ActorOwner = 0x016D, // updated 4.2 ? PlayerStateFlags = 0x016E, // updated 4.2 PlayerClassInfo = 0x016F, // updated 4.2 ModelEquip = 0x0170, // updated 4.2 @@ -126,6 +128,7 @@ namespace Packets { UpdateInventorySlot = 0x0181, // updated 4.2 EventPlay = 0x018E, // updated 4.2 + DirectorPlayScene = 0x0192, // updated 4.2 EventStart = 0x0198, // updated 4.2 EventFinish = 0x0199, // updated 4.2 diff --git a/src/common/Network/PacketDef/Zone/ServerZoneDef.h b/src/common/Network/PacketDef/Zone/ServerZoneDef.h index 4cd5349b..55f83697 100644 --- a/src/common/Network/PacketDef/Zone/ServerZoneDef.h +++ b/src/common/Network/PacketDef/Zone/ServerZoneDef.h @@ -188,7 +188,7 @@ struct FFXIVIpcLinkshellList : FFXIVIpcBasePacket struct FFXIVIpcStatusEffectList : FFXIVIpcBasePacket { uint8_t classId; - uint8_t classId1; + uint8_t level1; uint16_t level; uint32_t current_hp; uint32_t max_hp; @@ -414,7 +414,7 @@ struct FFXIVIpcPlayerSpawn : FFXIVIpcBasePacket */ struct FFXIVIpcNpcSpawn : FFXIVIpcBasePacket { - uint32_t mapLinkId; // needs to be existing in the map, mob will snap to it + uint32_t gimmickId; // needs to be existing in the map, mob will snap to it uint8_t u2b; uint8_t u2ab; uint8_t gmRank; @@ -565,7 +565,7 @@ struct FFXIVIpcHateList : FFXIVIpcBasePacket struct FFXIVIpcUpdateClassInfo : FFXIVIpcBasePacket { uint8_t classId; - uint8_t classId1; + uint8_t level1; uint16_t level; uint32_t nextLevelIndex; uint32_t currentExp; @@ -1021,6 +1021,24 @@ struct FFXIVIpcEventPlay : FFXIVIpcBasePacket uint8_t unknown[8]; }; + /** +* Structural representation of the packet sent by the server +* to play an event +*/ +struct FFXIVIpcDirectorPlayScene : FFXIVIpcBasePacket +{ + uint64_t actorId; + uint32_t eventId; + uint16_t scene; + uint16_t padding; + uint32_t flags; + uint32_t param3; + uint8_t param4; + uint8_t padding1[3]; + uint32_t param5; + uint8_t unknown[0x40]; +}; + /** * Structural representation of the packet sent by the server * to finish an event @@ -1324,7 +1342,7 @@ struct FFXIVIpcObjectSpawn : FFXIVIpcBasePacket uint32_t levelId; uint32_t unknown10; uint32_t someActorId14; - uint32_t hierachyId; + uint32_t gimmickId; float scale; int16_t unknown20a; uint16_t rotation; diff --git a/src/servers/sapphire_zone/Actor/Chara.cpp b/src/servers/sapphire_zone/Actor/Chara.cpp index eb6e0896..425fa411 100644 --- a/src/servers/sapphire_zone/Actor/Chara.cpp +++ b/src/servers/sapphire_zone/Actor/Chara.cpp @@ -663,6 +663,9 @@ void Core::Entity::Chara::sendStatusEffectUpdate() ZoneChannelPacket< Server::FFXIVIpcStatusEffectList > statusEffectList( getId() ); + statusEffectList.data().classId = static_cast< uint8_t >( getClass() ); + statusEffectList.data().level = getLevel(); + statusEffectList.data().level1 = getLevel(); statusEffectList.data().current_hp = getHp(); statusEffectList.data().current_mp = getMp(); statusEffectList.data().currentTp = getTp(); diff --git a/src/servers/sapphire_zone/Actor/EventObject.cpp b/src/servers/sapphire_zone/Actor/EventObject.cpp index 11fa13a3..1f683ec0 100644 --- a/src/servers/sapphire_zone/Actor/EventObject.cpp +++ b/src/servers/sapphire_zone/Actor/EventObject.cpp @@ -18,11 +18,11 @@ using namespace Core::Network::Packets::Server; extern Core::Logger g_log; -Core::Entity::EventObject::EventObject( uint32_t actorId, uint32_t objectId, uint32_t mapLinkId, +Core::Entity::EventObject::EventObject( uint32_t actorId, uint32_t objectId, uint32_t gimmickId, uint8_t initialState, Common::FFXIVARR_POSITION3 pos, float rotation, const std::string& givenName ) : Core::Entity::Actor( ObjKind::EventObj ), - m_mapLinkId( mapLinkId ), + m_gimmickId( gimmickId ), m_state( initialState ), m_objectId( objectId ), m_name( givenName ) @@ -34,9 +34,9 @@ Core::Entity::EventObject::EventObject( uint32_t actorId, uint32_t objectId, uin m_rot = rotation; } -uint32_t Core::Entity::EventObject::getMapLinkId() const +uint32_t Core::Entity::EventObject::getGimmickId() const { - return m_mapLinkId; + return m_gimmickId; } uint32_t Core::Entity::EventObject::getObjectId() const @@ -64,9 +64,9 @@ void Core::Entity::EventObject::setOnTalkHandler( Core::Entity::EventObject::OnT m_onTalkEventHandler = handler; } -void Core::Entity::EventObject::setMapLinkId( uint32_t mapLinkId ) +void Core::Entity::EventObject::setGimmickId( uint32_t gimmickId ) { - m_mapLinkId = mapLinkId; + m_gimmickId = gimmickId; } uint8_t Core::Entity::EventObject::getState() const @@ -110,7 +110,7 @@ void Core::Entity::EventObject::spawn( Core::Entity::PlayerPtr pTarget ) eobjStatePacket.data().objKind = getObjKind(); eobjStatePacket.data().state = getState(); eobjStatePacket.data().objId = getObjectId(); - eobjStatePacket.data().hierachyId = getMapLinkId(); + eobjStatePacket.data().gimmickId = getGimmickId(); eobjStatePacket.data().position = getPos(); eobjStatePacket.data().scale = getScale(); eobjStatePacket.data().actorId = getId(); diff --git a/src/servers/sapphire_zone/Actor/EventObject.h b/src/servers/sapphire_zone/Actor/EventObject.h index f1762b52..363d5077 100644 --- a/src/servers/sapphire_zone/Actor/EventObject.h +++ b/src/servers/sapphire_zone/Actor/EventObject.h @@ -10,13 +10,13 @@ namespace Entity class EventObject : public Actor { public: - EventObject( uint32_t actorId, uint32_t objectId, uint32_t mapLinkId, uint8_t initialState, Common::FFXIVARR_POSITION3 pos, + EventObject( uint32_t actorId, uint32_t objectId, uint32_t gimmickId, uint8_t initialState, Common::FFXIVARR_POSITION3 pos, float rotation, const std::string& givenName = "none" ); using OnTalkEventHandler = std::function< void( Entity::Player&, Entity::EventObjectPtr, InstanceContentPtr, uint64_t ) >; - uint32_t getMapLinkId() const; - void setMapLinkId( uint32_t mapLinkId ); + uint32_t getGimmickId() const; + void setGimmickId( uint32_t gimmickId ); uint8_t getState() const; void setState( uint8_t state ); @@ -38,7 +38,7 @@ namespace Entity void despawn( PlayerPtr pTarget ) override; protected: - uint32_t m_mapLinkId; + uint32_t m_gimmickId; uint32_t m_objectId; uint8_t m_state; float m_scale; diff --git a/src/servers/sapphire_zone/Actor/Player.cpp b/src/servers/sapphire_zone/Actor/Player.cpp index 5d94a554..61566635 100644 --- a/src/servers/sapphire_zone/Actor/Player.cpp +++ b/src/servers/sapphire_zone/Actor/Player.cpp @@ -630,7 +630,7 @@ void Core::Entity::Player::gainLevel() ZoneChannelPacket< FFXIVIpcStatusEffectList > effectListPacket( getId() ); effectListPacket.data().classId = static_cast< uint8_t > ( getClass() ); - effectListPacket.data().classId1 = static_cast< uint8_t > ( getClass() ); + effectListPacket.data().level1 = getLevel(); effectListPacket.data().level = getLevel(); effectListPacket.data().current_hp = getMaxHp(); effectListPacket.data().current_mp = getMaxMp(); @@ -645,7 +645,7 @@ void Core::Entity::Player::gainLevel() ZoneChannelPacket< FFXIVIpcUpdateClassInfo > classInfoPacket( getId() ); classInfoPacket.data().classId = static_cast< uint8_t > ( getClass() ); - classInfoPacket.data().classId1 = static_cast< uint8_t > ( getClass() ); + classInfoPacket.data().level1 = getLevel(); classInfoPacket.data().level = getLevel(); classInfoPacket.data().nextLevelIndex = getLevel(); classInfoPacket.data().currentExp = getExp(); @@ -1683,3 +1683,5 @@ bool Core::Entity::Player::isOnEnterEventDone() const { return m_onEnterEventDone; } + + diff --git a/src/servers/sapphire_zone/Actor/Player.h b/src/servers/sapphire_zone/Actor/Player.h index 39806a55..89233164 100644 --- a/src/servers/sapphire_zone/Actor/Player.h +++ b/src/servers/sapphire_zone/Actor/Player.h @@ -57,6 +57,9 @@ public: void eventStart( uint64_t actorId, uint32_t eventId, Event::EventHandler::EventType eventParam, uint8_t eventParam1, uint32_t eventParam2, uint32_t contentId = 0 ); /*! play a subevent */ void eventPlay( uint32_t eventId, uint32_t scene, uint32_t flags, uint32_t eventParam2, uint32_t eventParam3 ); + + void directorPlayScene( uint32_t eventId, uint32_t scene, uint32_t flags, uint32_t eventParam2, uint32_t eventParam3 ); + /*! play a subevent */ void eventPlay( uint32_t eventId, uint32_t scene, uint32_t flags, uint32_t eventParam2, uint32_t eventParam3, Event::EventHandler::SceneReturnCallback eventReturnCallback ); diff --git a/src/servers/sapphire_zone/Actor/PlayerEvent.cpp b/src/servers/sapphire_zone/Actor/PlayerEvent.cpp index c9f25c82..d7de126a 100644 --- a/src/servers/sapphire_zone/Actor/PlayerEvent.cpp +++ b/src/servers/sapphire_zone/Actor/PlayerEvent.cpp @@ -17,6 +17,7 @@ #include "Network/PacketWrappers/EventStartPacket.h" #include "Network/PacketWrappers/EventPlayPacket.h" #include "Network/PacketWrappers/EventFinishPacket.h" +#include "Network/PacketWrappers/DirectorPlayScenePacket.h" #include "Action/EventAction.h" #include "Action/EventItemAction.h" @@ -75,6 +76,27 @@ void Core::Entity::Player::checkEvent( uint32_t eventId ) } +void Core::Entity::Player::directorPlayScene( uint32_t eventId, uint32_t scene, uint32_t flags, uint32_t eventParam2, + uint32_t eventParam3 ) +{ + if( flags & 0x02 ) + setStateFlag( PlayerStateFlag::WatchingCutscene ); + + auto pEvent = getEvent( eventId ); + if( !pEvent ) + { + g_log.error( "Could not find event " + std::to_string( eventId ) + ", event has not been started!" ); + return; + } + + pEvent->setPlayedScene( true ); + pEvent->setEventReturnCallback( nullptr ); + DirectorPlayScenePacket eventPlay( getId(), getId(), pEvent->getId(), + scene, flags, eventParam2, eventParam3 ); + + queuePacket( eventPlay ); +} + void Core::Entity::Player::eventStart( uint64_t actorId, uint32_t eventId, Event::EventHandler::EventType eventType, uint8_t eventParam1, uint32_t eventParam2, uint32_t contentId ) diff --git a/src/servers/sapphire_zone/Network/Handlers/ActionHandler.cpp b/src/servers/sapphire_zone/Network/Handlers/ActionHandler.cpp index 6915f69b..b7bda7da 100644 --- a/src/servers/sapphire_zone/Network/Handlers/ActionHandler.cpp +++ b/src/servers/sapphire_zone/Network/Handlers/ActionHandler.cpp @@ -88,6 +88,8 @@ enum ClientTrigger DirectorInitFinish = 0x321, + SomeDirectorEvent = 0x328, // unsure what exactly triggers it, starts director when returning to instance though + EnterTerritoryEventFinished = 0x330, AchievementCritReq = 0x3E8, @@ -254,6 +256,11 @@ void Core::Network::GameConnection::actionHandler( const Packets::GamePacket& in player.getCurrentZone()->onInitDirector( player ); break; } + case ClientTrigger::SomeDirectorEvent: // Director init finish + { + player.getCurrentZone()->onSomeDirectorEvent( player ); + break; + } case ClientTrigger::EnterTerritoryEventFinished:// this may still be something else. I think i have seen it elsewhere { player.setOnEnterEventDone( true ); diff --git a/src/servers/sapphire_zone/Network/PacketWrappers/DirectorPlayScenePacket.h b/src/servers/sapphire_zone/Network/PacketWrappers/DirectorPlayScenePacket.h new file mode 100644 index 00000000..1c37c123 --- /dev/null +++ b/src/servers/sapphire_zone/Network/PacketWrappers/DirectorPlayScenePacket.h @@ -0,0 +1,55 @@ +#ifndef _DIRECTORPLAYSCENE_H +#define _DIRECTORPLAYSCENE_H + +#include +#include "Forwards.h" + +namespace Core { +namespace Network { +namespace Packets { +namespace Server { + +/** +* @brief The packet sent to play an event. +*/ +class DirectorPlayScenePacket : public ZoneChannelPacket< FFXIVIpcDirectorPlayScene > +{ +public: + DirectorPlayScenePacket( uint32_t playerId, + uint64_t actorId, + uint32_t eventId, + uint16_t scene, + uint32_t flags, + uint8_t param3, + uint32_t param4 = 0, + uint32_t param5 = 0 ) : + ZoneChannelPacket< FFXIVIpcDirectorPlayScene >( playerId, playerId ) + { + initialize( actorId, eventId, scene, flags, param3, param4, param5 ); + }; + +private: + void initialize( uint64_t actorId, + uint32_t eventId, + uint16_t scene, + uint32_t flags, + uint8_t param3, + uint32_t param4, + uint32_t param5 ) + { + m_data.actorId = actorId; + m_data.eventId = eventId; + m_data.scene = scene; + m_data.flags = flags; + m_data.param3 = param3; + m_data.param4 = param4; + m_data.param5 = param5; + }; +}; + +} +} +} +} + +#endif /*_EVENTPLAY_H*/ diff --git a/src/servers/sapphire_zone/Script/Scripts/instances/dungeons/Sastasha.cpp b/src/servers/sapphire_zone/Script/Scripts/instances/dungeons/Sastasha.cpp index e08c8f9a..9a2d1377 100644 --- a/src/servers/sapphire_zone/Script/Scripts/instances/dungeons/Sastasha.cpp +++ b/src/servers/sapphire_zone/Script/Scripts/instances/dungeons/Sastasha.cpp @@ -1,5 +1,6 @@ #include #include +#include class Sastasha : public InstanceContentScript { @@ -70,7 +71,7 @@ public: void onEnterTerritory( Entity::Player &player, uint32_t eventId, uint16_t param1, uint16_t param2 ) override { - + player.directorPlayScene( getId(), 1, NO_DEFAULT_CAMERA | HIDE_HOTBAR, 0, 0xA ); } }; \ No newline at end of file diff --git a/src/servers/sapphire_zone/Zone/InstanceContent.cpp b/src/servers/sapphire_zone/Zone/InstanceContent.cpp index 14bb06b1..c25121d9 100644 --- a/src/servers/sapphire_zone/Zone/InstanceContent.cpp +++ b/src/servers/sapphire_zone/Zone/InstanceContent.cpp @@ -151,6 +151,12 @@ void Core::InstanceContent::onInitDirector( Entity::Player& player ) player.setDirectorInitialized( true ); } +void Core::InstanceContent::onSomeDirectorEvent( Entity::Player& player ) +{ + player.queuePacket( ActorControlPacket143( player.getId(), DirectorUpdate, 0x00110001, 0x80000000, 1 ) ); +} + + void Core::InstanceContent::setVar( uint8_t index, uint8_t value ) { if( index > 19 ) diff --git a/src/servers/sapphire_zone/Zone/InstanceContent.h b/src/servers/sapphire_zone/Zone/InstanceContent.h index fb5305e5..d487f86f 100644 --- a/src/servers/sapphire_zone/Zone/InstanceContent.h +++ b/src/servers/sapphire_zone/Zone/InstanceContent.h @@ -35,6 +35,7 @@ public: void onLeaveTerritory( Entity::Player& player ) override; void onFinishLoading( Entity::Player& player ) override; void onInitDirector( Entity::Player& player ) override; + void onSomeDirectorEvent( Entity::Player& player ) override; void onUpdate( uint32_t currTime ) override; void onTalk( Entity::Player& player, uint32_t eventId, uint64_t actorId ); void onEnterTerritory( Entity::Player& player, uint32_t eventId, uint16_t param1, uint16_t param2 ) override; diff --git a/src/servers/sapphire_zone/Zone/Zone.h b/src/servers/sapphire_zone/Zone/Zone.h index ae747869..58e165a4 100644 --- a/src/servers/sapphire_zone/Zone/Zone.h +++ b/src/servers/sapphire_zone/Zone/Zone.h @@ -77,6 +77,7 @@ public: virtual void onPlayerZoneIn( Entity::Player &player ); virtual void onFinishLoading( Entity::Player& player ); virtual void onInitDirector( Entity::Player& player ); + virtual void onSomeDirectorEvent( Entity::Player& player ) {}; virtual void onLeaveTerritory( Entity::Player& player ); virtual void onUpdate( uint32_t currTime ); virtual void onRegisterEObj( Entity::EventObjectPtr object ) {};