From 4137379853cec4dcf6ab2677470b0b0dae3eb997 Mon Sep 17 00:00:00 2001 From: Adam Date: Sun, 25 Feb 2018 21:46:34 +1100 Subject: [PATCH 1/3] fix possible null pointer access & eobj state update --- src/servers/sapphire_zone/Actor/Actor.cpp | 7 +++++-- src/servers/sapphire_zone/Actor/EventObject.cpp | 9 +++++++++ 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/src/servers/sapphire_zone/Actor/Actor.cpp b/src/servers/sapphire_zone/Actor/Actor.cpp index 7c855c43..560d5b9b 100644 --- a/src/servers/sapphire_zone/Actor/Actor.cpp +++ b/src/servers/sapphire_zone/Actor/Actor.cpp @@ -313,10 +313,13 @@ void Core::Entity::Actor::setCurrentZone( ZonePtr currZone ) m_pCurrentZone = currZone; } -/*! \return InstanceContentPtr to the current instance, null if not an instance or not set */ +/*! \return InstanceContentPtr to the current instance, nullptr if not an instance or not set */ Core::InstanceContentPtr Core::Entity::Actor::getCurrentInstance() const { - return getCurrentZone()->getAsInstanceContent(); + if( m_pCurrentZone ) + return m_pCurrentZone->getAsInstanceContent(); + + return nullptr; } /*! diff --git a/src/servers/sapphire_zone/Actor/EventObject.cpp b/src/servers/sapphire_zone/Actor/EventObject.cpp index 9784e8e1..87fba41a 100644 --- a/src/servers/sapphire_zone/Actor/EventObject.cpp +++ b/src/servers/sapphire_zone/Actor/EventObject.cpp @@ -56,6 +56,15 @@ void Core::Entity::EventObject::setState( uint8_t state ) { m_state = state; + for( const auto& player : m_inRangePlayers ) + { + ZoneChannelPacket< FFXIVIpcActorControl142 > eobjUpdatePacket( getId(), player->getId() ); + eobjUpdatePacket.data().category = Common::ActorControlType::DirectorEObjMod; + eobjUpdatePacket.data().param1 = state; + + player->queuePacket( eobjUpdatePacket ); + } + //m_parentInstance->updateEObj( InstanceObjectPtr( this ) ); } From 4afc9e91b7dafa40ac8122565a406e0603695fe6 Mon Sep 17 00:00:00 2001 From: Adam Date: Tue, 27 Feb 2018 02:13:01 +1100 Subject: [PATCH 2/3] eobj interaction callbacks, eobj spawning fixed, sastasha instance eobjs --- .../Network/PacketDef/Zone/ServerZoneDef.h | 15 +++--- src/servers/sapphire_api/Forwards.h | 4 +- .../sapphire_zone/Actor/EventObject.cpp | 24 ++++++++- src/servers/sapphire_zone/Actor/EventObject.h | 10 ++++ .../Scripts/instances/dungeon/Sastasha.cpp | 50 +++++++++++++++++++ .../dungeon/TheThousandMawsOfTotoRak.cpp | 1 + .../sapphire_zone/Zone/InstanceContent.cpp | 21 +++++++- .../sapphire_zone/Zone/InstanceContent.h | 1 + src/servers/sapphire_zone/Zone/Zone.cpp | 4 +- src/servers/sapphire_zone/Zone/Zone.h | 2 +- 10 files changed, 119 insertions(+), 13 deletions(-) create mode 100644 src/servers/sapphire_zone/Script/Scripts/instances/dungeon/Sastasha.cpp diff --git a/src/common/Network/PacketDef/Zone/ServerZoneDef.h b/src/common/Network/PacketDef/Zone/ServerZoneDef.h index 3899a0a5..985af408 100644 --- a/src/common/Network/PacketDef/Zone/ServerZoneDef.h +++ b/src/common/Network/PacketDef/Zone/ServerZoneDef.h @@ -1319,18 +1319,21 @@ struct FFXIVIpcObjectSpawn : FFXIVIpcBasePacket uint8_t count; uint8_t objKind; uint8_t state; - uint8_t unknown2; + uint8_t unknown3; uint32_t objId; uint32_t actorId; uint32_t levelId; uint32_t unknown10; uint32_t someActorId14; uint32_t hierachyId; - uint32_t unknown1C; - uint32_t unknown20; - uint32_t unknown24; - uint32_t unknown28; - uint32_t unknown2c; + float scale; + int16_t unknown20a; + uint16_t unknown20b; + int16_t unknown24a; + int16_t unknown24b; + uint16_t unknown28a; + int16_t unknown28c; + uint32_t unknown2C; Common::FFXIVARR_POSITION3 position; int16_t rotation; int16_t unknown; diff --git a/src/servers/sapphire_api/Forwards.h b/src/servers/sapphire_api/Forwards.h index cbc8d820..73b6429d 100644 --- a/src/servers/sapphire_api/Forwards.h +++ b/src/servers/sapphire_api/Forwards.h @@ -91,10 +91,10 @@ namespace Core namespace Scripting { - typedef std::function< void( Entity::Player&, uint32_t, uint16_t, uint16_t, uint16_t, uint16_t ) > EventReturnCallback; + using EventReturnCallback = std::function< void( Entity::Player&, uint32_t, uint16_t, uint16_t, uint16_t, uint16_t ) >; } - typedef std::function< void( Entity::Player&, uint32_t, uint64_t ) > ActionCallback; + using ActionCallback = std::function< void( Entity::Player&, uint32_t, uint64_t ) >; } diff --git a/src/servers/sapphire_zone/Actor/EventObject.cpp b/src/servers/sapphire_zone/Actor/EventObject.cpp index 87fba41a..26775c1b 100644 --- a/src/servers/sapphire_zone/Actor/EventObject.cpp +++ b/src/servers/sapphire_zone/Actor/EventObject.cpp @@ -42,6 +42,26 @@ uint32_t Core::Entity::EventObject::getObjectId() const return m_objectId; } +float Core::Entity::EventObject::getScale() const +{ + return m_scale; +} + +void Core::Entity::EventObject::setScale( float scale ) +{ + m_scale = scale; +} + +Core::Entity::EventObject::OnTalkEventHandler Core::Entity::EventObject::getOnTalkHandler() const +{ + return m_onTalkEventHandler; +} + +void Core::Entity::EventObject::setOnTalkHandler( Core::Entity::EventObject::OnTalkEventHandler handler ) +{ + m_onTalkEventHandler = handler; +} + void Core::Entity::EventObject::setMapLinkId( uint32_t mapLinkId ) { m_mapLinkId = mapLinkId; @@ -64,8 +84,6 @@ void Core::Entity::EventObject::setState( uint8_t state ) player->queuePacket( eobjUpdatePacket ); } - - //m_parentInstance->updateEObj( InstanceObjectPtr( this ) ); } void Core::Entity::EventObject::setParentInstance( Core::InstanceContentPtr instance ) @@ -88,6 +106,8 @@ void Core::Entity::EventObject::spawn( Core::Entity::PlayerPtr pTarget ) eobjStatePacket.data().objId = getObjectId(); eobjStatePacket.data().hierachyId = getMapLinkId(); eobjStatePacket.data().position = getPos(); + eobjStatePacket.data().scale = getScale(); + eobjStatePacket.data().actorId = getId(); pTarget->queuePacket( eobjStatePacket ); } diff --git a/src/servers/sapphire_zone/Actor/EventObject.h b/src/servers/sapphire_zone/Actor/EventObject.h index 076a8a85..85dd329d 100644 --- a/src/servers/sapphire_zone/Actor/EventObject.h +++ b/src/servers/sapphire_zone/Actor/EventObject.h @@ -13,12 +13,20 @@ namespace Entity EventObject( uint32_t objectId, uint32_t mapLinkId, uint8_t initialState, Common::FFXIVARR_POSITION3 pos, const std::string& givenName = "none" ); + using OnTalkEventHandler = std::function< void( Entity::Player&, uint64_t ) >; + uint32_t getMapLinkId() const; void setMapLinkId( uint32_t mapLinkId ); uint8_t getState() const; void setState( uint8_t state ); + float getScale() const; + void setScale( float scale ); + + void setOnTalkHandler( OnTalkEventHandler handler ); + OnTalkEventHandler getOnTalkHandler() const; + uint32_t getObjectId() const; const std::string& getName() const; @@ -33,8 +41,10 @@ namespace Entity uint32_t m_mapLinkId; uint32_t m_objectId; uint8_t m_state; + float m_scale; std::string m_name; InstanceContentPtr m_parentInstance; + OnTalkEventHandler m_onTalkEventHandler; }; } } diff --git a/src/servers/sapphire_zone/Script/Scripts/instances/dungeon/Sastasha.cpp b/src/servers/sapphire_zone/Script/Scripts/instances/dungeon/Sastasha.cpp new file mode 100644 index 00000000..9d120479 --- /dev/null +++ b/src/servers/sapphire_zone/Script/Scripts/instances/dungeon/Sastasha.cpp @@ -0,0 +1,50 @@ +#include +#include + +class Sastasha : public InstanceContentScript +{ +private: + static void exitOnTalk( Entity::Player& player, uint64_t actorId ) + { + player.sendDebug( "actor: " + std::to_string( actorId ) ); + } + +public: + Sastasha() : InstanceContentScript( 4 ) + { } + + void onInit( InstanceContentPtr instance ) override + { + auto exit = instance->registerEObj( "Exit", EXIT_OBJECT, 0, EXIT_OBJECT_STATE, { -314, 5.6, 348.73 } ); + exit->setScale( 0.6f ); + exit->setOnTalkHandler( exitOnTalk ); + + instance->registerEObj( "Entrance", START_CIRCLE, START_CIRCLE_MAPLINK, START_CIRCLE_STATE, { 361, 46, -225 } ); + + auto memo = instance->registerEObj( "BloodyMemo", BLOODY_MEMO_1, 0, BLOODY_MEMO_STATE, { 320.81, 47.86, -130.78 } ); + memo->setScale( 0.6f ); + } + + void onUpdate( InstanceContentPtr instance, uint32_t currTime ) override + { + + } + + void onEnterTerritory( Entity::Player &player, uint32_t eventId, uint16_t param1, uint16_t param2 ) override + { + + } + +private: + static constexpr auto EXIT_OBJECT = 2000139; + static constexpr auto EXIT_OBJECT_STATE = 4; + + static constexpr auto START_CIRCLE = 2000182; + static constexpr auto START_CIRCLE_MAPLINK = 4096706; + static constexpr auto START_CIRCLE_STATE = 5; + + static constexpr auto BLOODY_MEMO_1 = 2000212; + static constexpr auto BLOODY_MEMO_2 = 2001548; + static constexpr auto BLOODY_MEMO_3 = 2001549; + static constexpr auto BLOODY_MEMO_STATE = 4; +}; \ No newline at end of file diff --git a/src/servers/sapphire_zone/Script/Scripts/instances/dungeon/TheThousandMawsOfTotoRak.cpp b/src/servers/sapphire_zone/Script/Scripts/instances/dungeon/TheThousandMawsOfTotoRak.cpp index 037db112..4094b7b7 100644 --- a/src/servers/sapphire_zone/Script/Scripts/instances/dungeon/TheThousandMawsOfTotoRak.cpp +++ b/src/servers/sapphire_zone/Script/Scripts/instances/dungeon/TheThousandMawsOfTotoRak.cpp @@ -10,6 +10,7 @@ public: void onInit( InstanceContentPtr instance ) override { instance->registerEObj( "Exit", EXIT_OBJECT, 0, EXIT_OBJECT_STATE, { 237, -39, -144 } ); + instance->getEObjByName( "Exit" )->setScale( 0.6f ); instance->registerEObj( "Entrance", START_CIRCLE, START_CIRCLE_MAPLINK, START_CIRCLE_STATE, { -322, 12, -78 } ); } diff --git a/src/servers/sapphire_zone/Zone/InstanceContent.cpp b/src/servers/sapphire_zone/Zone/InstanceContent.cpp index 2b8682a0..48457c84 100644 --- a/src/servers/sapphire_zone/Zone/InstanceContent.cpp +++ b/src/servers/sapphire_zone/Zone/InstanceContent.cpp @@ -4,6 +4,7 @@ #include #include #include +#include #include "Event/Director.h" #include "Script/ScriptManager.h" @@ -17,6 +18,7 @@ extern Core::Logger g_log; extern Core::Scripting::ScriptManager g_scriptMgr; +extern Core::Data::ExdDataGenerated g_exdDataGen; using namespace Core::Common; using namespace Core::Network::Packets; @@ -230,6 +232,13 @@ void Core::InstanceContent::onRegisterEObj( Entity::EventObjectPtr object ) m_eventObjectMap[object->getName()] = object; if( object->getObjectId() == 2000182 ) // start m_pEntranceEObj = object; + + auto objData = g_exdDataGen.get< Core::Data::EObj >( object->getObjectId() ); + if( objData ) + // todo: data should be renamed to eventId + m_eventIdToObjectMap[objData->data] = object; + else + g_log.error( "InstanceContent::onRegisterEObj Zone " + m_internalName + ": No EObj data found for EObj with ID: " + std::to_string( object->getObjectId() ) ); } void Core::InstanceContent::onBeforeEnterTerritory( Core::Entity::Player &player ) @@ -257,5 +266,15 @@ Core::Entity::EventObjectPtr Core::InstanceContent::getEObjByName( const std::st void Core::InstanceContent::onTalk( Core::Entity::Player& player, uint32_t eventId, uint64_t actorId ) { - auto type = static_cast< Core::Event::EventHandler::EventType >( eventId >> 16 ); + // todo: handle exit (and maybe shortcut?) behaviour here + + auto it = m_eventIdToObjectMap.find( eventId ); + if( it == m_eventIdToObjectMap.end() ) + return; + + if( auto onTalk = it->second->getOnTalkHandler() ) + onTalk( player, actorId ); + else + player.sendDebug( "No onTalk handler found for interactable eobj with EObjID: " + + std::to_string( it->second->getObjectId() ) + ", eventId: " + std::to_string( eventId ) ); } diff --git a/src/servers/sapphire_zone/Zone/InstanceContent.h b/src/servers/sapphire_zone/Zone/InstanceContent.h index b42dc47d..328251c4 100644 --- a/src/servers/sapphire_zone/Zone/InstanceContent.h +++ b/src/servers/sapphire_zone/Zone/InstanceContent.h @@ -57,6 +57,7 @@ private: Entity::EventObjectPtr m_pEntranceEObj; std::map< std::string, Entity::EventObjectPtr > m_eventObjectMap; + std::unordered_map< uint32_t, Entity::EventObjectPtr > m_eventIdToObjectMap; }; } diff --git a/src/servers/sapphire_zone/Zone/Zone.cpp b/src/servers/sapphire_zone/Zone/Zone.cpp index 1df0f389..8bfb0f01 100644 --- a/src/servers/sapphire_zone/Zone/Zone.cpp +++ b/src/servers/sapphire_zone/Zone/Zone.cpp @@ -689,9 +689,11 @@ uint32_t Core::Zone::getNextEObjId() return ++m_nextEObjId; } -void Core::Zone::registerEObj( const std::string &name, uint32_t objectId, uint32_t mapLink, uint8_t state, +Core::Entity::EventObjectPtr Core::Zone::registerEObj( const std::string &name, uint32_t objectId, uint32_t mapLink, uint8_t state, FFXIVARR_POSITION3 pos ) { auto eObj = Entity::make_EventObject( objectId, mapLink, state, pos, name ); registerEObj( eObj ); + + return eObj; } diff --git a/src/servers/sapphire_zone/Zone/Zone.h b/src/servers/sapphire_zone/Zone/Zone.h index 097100c9..a876a00f 100644 --- a/src/servers/sapphire_zone/Zone/Zone.h +++ b/src/servers/sapphire_zone/Zone/Zone.h @@ -108,7 +108,7 @@ public: void updateSessions( bool changedWeather ); - void registerEObj( const std::string& name, uint32_t objectId, uint32_t mapLink, + Entity::EventObjectPtr registerEObj( const std::string& name, uint32_t objectId, uint32_t mapLink, uint8_t state, Common::FFXIVARR_POSITION3 pos ); void registerEObj( Entity::EventObjectPtr object ); From 0e64bf76d253f6f842fdcc021056a7073d828ff2 Mon Sep 17 00:00:00 2001 From: Mordred <30826167+SapphireMordred@users.noreply.github.com> Date: Mon, 26 Feb 2018 19:33:31 +0100 Subject: [PATCH 3/3] Update Sastasha.cpp --- .../Script/Scripts/instances/dungeon/Sastasha.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/servers/sapphire_zone/Script/Scripts/instances/dungeon/Sastasha.cpp b/src/servers/sapphire_zone/Script/Scripts/instances/dungeon/Sastasha.cpp index 9d120479..9e1329af 100644 --- a/src/servers/sapphire_zone/Script/Scripts/instances/dungeon/Sastasha.cpp +++ b/src/servers/sapphire_zone/Script/Scripts/instances/dungeon/Sastasha.cpp @@ -15,13 +15,13 @@ public: void onInit( InstanceContentPtr instance ) override { - auto exit = instance->registerEObj( "Exit", EXIT_OBJECT, 0, EXIT_OBJECT_STATE, { -314, 5.6, 348.73 } ); + auto exit = instance->registerEObj( "Exit", EXIT_OBJECT, 0, EXIT_OBJECT_STATE, { -314.0f, 5.6f, 348.73f } ); exit->setScale( 0.6f ); exit->setOnTalkHandler( exitOnTalk ); - instance->registerEObj( "Entrance", START_CIRCLE, START_CIRCLE_MAPLINK, START_CIRCLE_STATE, { 361, 46, -225 } ); + instance->registerEObj( "Entrance", START_CIRCLE, START_CIRCLE_MAPLINK, START_CIRCLE_STATE, { 361.0f, 46.0f, -225.0f } ); - auto memo = instance->registerEObj( "BloodyMemo", BLOODY_MEMO_1, 0, BLOODY_MEMO_STATE, { 320.81, 47.86, -130.78 } ); + auto memo = instance->registerEObj( "BloodyMemo", BLOODY_MEMO_1, 0, BLOODY_MEMO_STATE, { 320.81f, 47.86f, -130.78f } ); memo->setScale( 0.6f ); } @@ -47,4 +47,4 @@ private: static constexpr auto BLOODY_MEMO_2 = 2001548; static constexpr auto BLOODY_MEMO_3 = 2001549; static constexpr auto BLOODY_MEMO_STATE = 4; -}; \ No newline at end of file +};