mirror of
https://github.com/SapphireServer/Sapphire.git
synced 2025-04-28 23:27:45 +00:00
Merge pull request #255 from GokuWeedLord/actor_rewrite
fix possible null pointer access & eobj state update
This commit is contained in:
commit
c4cbf256e3
11 changed files with 132 additions and 14 deletions
|
@ -1319,18 +1319,21 @@ struct FFXIVIpcObjectSpawn : FFXIVIpcBasePacket<ObjectSpawn>
|
|||
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;
|
||||
|
|
|
@ -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 ) >;
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
/*!
|
||||
|
|
|
@ -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;
|
||||
|
@ -56,7 +76,14 @@ void Core::Entity::EventObject::setState( uint8_t state )
|
|||
{
|
||||
m_state = state;
|
||||
|
||||
//m_parentInstance->updateEObj( InstanceObjectPtr( this ) );
|
||||
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 );
|
||||
}
|
||||
}
|
||||
|
||||
void Core::Entity::EventObject::setParentInstance( Core::InstanceContentPtr instance )
|
||||
|
@ -79,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 );
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,50 @@
|
|||
#include <ScriptObject.h>
|
||||
#include <Zone/InstanceContent.h>
|
||||
|
||||
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.0f, 5.6f, 348.73f } );
|
||||
exit->setScale( 0.6f );
|
||||
exit->setOnTalkHandler( exitOnTalk );
|
||||
|
||||
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.81f, 47.86f, -130.78f } );
|
||||
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;
|
||||
};
|
|
@ -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 } );
|
||||
}
|
||||
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
#include <common/Logging/Logger.h>
|
||||
#include <common/Util/Util.h>
|
||||
#include <common/Util/UtilMath.h>
|
||||
#include <common/Exd/ExdDataGenerated.h>
|
||||
|
||||
#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 ) );
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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 );
|
||||
|
|
Loading…
Add table
Reference in a new issue