mirror of
https://github.com/SapphireServer/Sapphire.git
synced 2025-04-25 05:57:45 +00:00
parent
b1e430cf39
commit
23b7b052a1
44 changed files with 1037 additions and 64 deletions
|
@ -1248,9 +1248,6 @@ namespace Sapphire::Common
|
|||
GetGil = 9, // p1: gil
|
||||
EmptyCoffer = 11, // seems like no param
|
||||
};
|
||||
|
||||
using PlayerStateFlagList = std::vector< PlayerStateFlag >;
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -111,6 +111,8 @@ namespace Sapphire::Network::ActorControl
|
|||
|
||||
ScreenFadeOut = 0xAA,
|
||||
|
||||
CeremonyDecoration = 0xB9,
|
||||
|
||||
ZoneIn = 0xC8,
|
||||
ZoneInDefaultPos = 0xC9,
|
||||
|
||||
|
@ -364,6 +366,7 @@ namespace Sapphire::Network::ActorControl
|
|||
TitleList = 0x12F,
|
||||
|
||||
UpdatedSeenHowTos = 0x133,
|
||||
CutscenePlayed = 0x134, // param1 = cutscene id
|
||||
AllotAttribute = 0x135,
|
||||
|
||||
ClearFieldMarkers = 0x13A,
|
||||
|
|
|
@ -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
|
||||
|
@ -274,6 +267,8 @@ namespace Sapphire::Network::Packets
|
|||
|
||||
LandSetMap = 0x02F6, // updated 5.58
|
||||
|
||||
CeremonySetActorAppearance = 0x00EB, // updated 5.58
|
||||
|
||||
//////////////////////////////////////////////////
|
||||
|
||||
DuelChallenge = 0x0277, // 4.2; this is responsible for opening the ui
|
||||
|
@ -390,7 +385,7 @@ namespace Sapphire::Network::Packets
|
|||
BuildPresetHandler = 0x00DC, // updated 5.58
|
||||
|
||||
TalkEventHandler = 0x012D, // updated 5.58
|
||||
EmoteEventHandler = 0xF35A, // updated 5.55 hotfix
|
||||
EmoteEventHandler = 0x039E, // updated 5.58
|
||||
WithinRangeEventHandler = 0x022C, // updated 5.58
|
||||
OutOfRangeEventHandler = 0x0294, // updated 5.58
|
||||
EnterTeriEventHandler = 0x00C1, // updated 5.58
|
||||
|
@ -398,7 +393,8 @@ namespace Sapphire::Network::Packets
|
|||
EventYieldHandler = 0x03A2, // updated 5.58
|
||||
ReturnEventHandler = 0x0333, // updated 5.58
|
||||
TradeReturnEventHandler = 0x0179, // updated 5.58
|
||||
TradeReturnEventHandler2 = 0x0169, // updated 5.55 hotfix
|
||||
TradeReturnEventHandler2 = 0x02E1, // updated 5.58
|
||||
EventYield16Handler = 0x03D7, // updated 5.58
|
||||
|
||||
LinkshellEventHandler = 0x016B, // updated 4.5
|
||||
LinkshellEventHandler1 = 0x016C, // updated 4.5
|
||||
|
|
|
@ -446,6 +446,24 @@ struct FFXIVIpcHousingEditInterior :
|
|||
uint16_t slot[10];
|
||||
};
|
||||
|
||||
struct FFXIVIpcEventYieldHandler :
|
||||
FFXIVIpcBasePacket< EventYieldHandler >
|
||||
{
|
||||
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 :
|
||||
FFXIVIpcBasePacket< CFCommenceHandler >
|
||||
{
|
||||
|
|
|
@ -1439,6 +1439,20 @@ namespace Sapphire::Network::Packets::Server
|
|||
uint8_t unknown[8];
|
||||
};
|
||||
|
||||
struct FFXIVIpcEventPlay16 : FFXIVIpcBasePacket< EventPlay16 >
|
||||
{
|
||||
uint64_t actorId;
|
||||
uint32_t eventId;
|
||||
uint16_t scene;
|
||||
uint16_t padding;
|
||||
uint32_t flags;
|
||||
uint32_t param3;
|
||||
uint8_t paramSize;
|
||||
uint8_t padding1[3];
|
||||
uint32_t param[16];
|
||||
uint32_t padding2;
|
||||
};
|
||||
|
||||
template< int ArgCount >
|
||||
struct FFXIVIpcEventPlayN
|
||||
{
|
||||
|
@ -1835,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];
|
||||
};
|
||||
|
||||
|
||||
|
@ -2238,6 +2252,43 @@ namespace Sapphire::Network::Packets::Server
|
|||
char memberName[32];
|
||||
uint8_t padding[3];
|
||||
};
|
||||
|
||||
struct FFXIVIpcEventContinue : FFXIVIpcBasePacket< EventContinue >
|
||||
{
|
||||
uint32_t eventId;
|
||||
uint16_t scene;
|
||||
uint16_t unknown;
|
||||
uint64_t unknown2;
|
||||
};
|
||||
|
||||
struct FFXIVDirectorUnk4 : FFXIVIpcBasePacket< SomeDirectorUnk4 >
|
||||
{
|
||||
uint32_t param[4];
|
||||
uint64_t unknown;
|
||||
};
|
||||
|
||||
struct FFXIVCeremonySetActorAppearance : FFXIVIpcBasePacket< CeremonySetActorAppearance >
|
||||
{
|
||||
uint8_t u1;
|
||||
uint8_t questBL;
|
||||
uint16_t padding1;
|
||||
uint32_t u3;
|
||||
struct
|
||||
{
|
||||
uint64_t mainWeaponModel;
|
||||
uint64_t secWeaponModel;
|
||||
uint64_t craftToolModel;
|
||||
uint32_t c_u6;
|
||||
uint32_t c_u7;
|
||||
uint32_t charId;
|
||||
uint16_t u4;
|
||||
uint16_t guardianDeity;
|
||||
uint32_t u5;
|
||||
uint32_t models[10];
|
||||
uint8_t look[26];
|
||||
uint16_t padding3;
|
||||
} actors[2];
|
||||
};
|
||||
}
|
||||
|
||||
#endif /*_CORE_NETWORK_PACKETS_SERVER_IPC_H*/
|
||||
|
|
|
@ -77,3 +77,8 @@ uint8_t Util::floatToUInt8Rot( float val )
|
|||
{
|
||||
return static_cast< uint8_t >( 0x80 * ( ( val + PI ) ) / PI );
|
||||
}
|
||||
|
||||
float Util::floatFromUInt16Rot( uint16_t rot )
|
||||
{
|
||||
return rot / 32768.0f * PI - PI;
|
||||
}
|
|
@ -25,6 +25,8 @@ namespace Sapphire::Common::Util
|
|||
|
||||
uint16_t floatToUInt16Rot( float val );
|
||||
|
||||
float floatFromUInt16Rot( uint16_t rot );
|
||||
|
||||
uint8_t floatToUInt8Rot( float val );
|
||||
|
||||
template < typename T >
|
||||
|
|
|
@ -32,7 +32,7 @@ public:
|
|||
// todo: this is fucked
|
||||
};
|
||||
|
||||
player.playScene( getId(), 1, 0xFB2EC8F8, 0, 1, returnScene, callback );
|
||||
player.playScene( getId(), 1, FADE_OUT | CONDITION_CUTSCENE | HIDE_UI, 0, 1, returnScene, callback );
|
||||
}
|
||||
|
||||
void onTalk( uint32_t eventId, Entity::Player& player, uint64_t actorId ) override
|
||||
|
|
|
@ -78,7 +78,7 @@ public:
|
|||
return;
|
||||
}
|
||||
|
||||
player.setInstance( internalZone, pos );
|
||||
player.setInstance( internalZone, pos, player.getRot() );
|
||||
} );
|
||||
}
|
||||
};
|
||||
|
|
|
@ -351,7 +351,7 @@ Sapphire::InstanceContentPtr Sapphire::Entity::Actor::getCurrentInstance() const
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
/*! \return QuestBattlePtr to the current instance, nullptr if not an instance or not set */
|
||||
/*! \return QuestBattlePtr to the current instance, nullptr if not a quest battle or not set */
|
||||
Sapphire::QuestBattlePtr Sapphire::Entity::Actor::getCurrentQuestBattle() const
|
||||
{
|
||||
if( m_pCurrentTerritory )
|
||||
|
@ -360,6 +360,15 @@ Sapphire::QuestBattlePtr Sapphire::Entity::Actor::getCurrentQuestBattle() const
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
/*! \return PublicContentPtr to the current instance, nullptr if not a public content or not set */
|
||||
Sapphire::PublicContentPtr Sapphire::Entity::Actor::getCurrentPublicContent() const
|
||||
{
|
||||
if( m_pCurrentTerritory )
|
||||
return m_pCurrentTerritory->getAsPublicContent();
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
/*!
|
||||
Get the current cell of a region the actor is in
|
||||
|
||||
|
|
|
@ -130,6 +130,8 @@ namespace Sapphire::Entity
|
|||
|
||||
QuestBattlePtr getCurrentQuestBattle() const;
|
||||
|
||||
PublicContentPtr getCurrentPublicContent() const;
|
||||
|
||||
// get the current cell of a region the actor is in
|
||||
Cell* getCellPtr();
|
||||
|
||||
|
|
|
@ -13,7 +13,7 @@ namespace Sapphire::Entity
|
|||
Common::FFXIVARR_POSITION3 pos, float rotation, const std::string& givenName = "none" );
|
||||
|
||||
using OnTalkEventHandler = std::function< void( Entity::Player&, Entity::EventObjectPtr,
|
||||
TerritoryPtr, uint64_t ) >;
|
||||
TerritoryPtr, uint32_t, uint64_t ) >;
|
||||
|
||||
uint32_t getGimmickId() const;
|
||||
|
||||
|
|
|
@ -23,6 +23,8 @@
|
|||
#include "Territory/Territory.h"
|
||||
#include "Territory/ZonePosition.h"
|
||||
#include "Territory/InstanceContent.h"
|
||||
#include "Territory/QuestBattle.h"
|
||||
#include "Territory/PublicContent.h"
|
||||
#include "Territory/InstanceObjectCache.h"
|
||||
#include "Territory/Land.h"
|
||||
|
||||
|
@ -472,7 +474,7 @@ bool Sapphire::Entity::Player::setInstance( TerritoryPtr instance )
|
|||
return teriMgr.movePlayer( instance, getAsPlayer() );
|
||||
}
|
||||
|
||||
bool Sapphire::Entity::Player::setInstance( TerritoryPtr instance, Common::FFXIVARR_POSITION3 pos )
|
||||
bool Sapphire::Entity::Player::setInstance( TerritoryPtr instance, Common::FFXIVARR_POSITION3 pos, float rot )
|
||||
{
|
||||
m_onEnterEventDone = false;
|
||||
if( !instance )
|
||||
|
@ -490,11 +492,17 @@ bool Sapphire::Entity::Player::setInstance( TerritoryPtr instance, Common::FFXIV
|
|||
m_prevTerritoryId = getTerritoryId();
|
||||
}
|
||||
|
||||
m_pos = pos;
|
||||
m_rot = rot;
|
||||
if( teriMgr.movePlayer( instance, getAsPlayer() ) )
|
||||
{
|
||||
m_pos = pos;
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_pos = m_prevPos;
|
||||
m_rot= m_prevRot;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
@ -503,8 +511,18 @@ bool Sapphire::Entity::Player::exitInstance()
|
|||
{
|
||||
auto& teriMgr = Common::Service< TerritoryMgr >::ref();
|
||||
|
||||
auto pZone = getCurrentTerritory();
|
||||
auto pInstance = pZone->getAsInstanceContent();
|
||||
auto d = getCurrentTerritory()->getAsDirector();
|
||||
if( d && d->getContentFinderConditionId() > 0 )
|
||||
{
|
||||
auto p = makeZonePacket< FFXIVDirectorUnk4 >( getId() );
|
||||
p->data().param[0] = d->getDirectorId();
|
||||
p->data().param[1] = 1534;
|
||||
p->data().param[2] = 1;
|
||||
p->data().param[3] = d->getContentFinderConditionId();
|
||||
queuePacket( p );
|
||||
|
||||
prepareZoning( 0, 1, 1, 0, 0, 1, 9 );
|
||||
}
|
||||
|
||||
resetHp();
|
||||
resetMp();
|
||||
|
@ -1755,14 +1773,14 @@ void Sapphire::Entity::Player::sendZonePackets()
|
|||
//setStateFlag( PlayerStateFlag::BetweenAreas );
|
||||
//setStateFlag( PlayerStateFlag::BetweenAreas1 );
|
||||
|
||||
if( isActionLearned( static_cast< uint8_t >( Common::UnlockEntry::HuntingLog ) ) )
|
||||
sendHuntingLog();
|
||||
|
||||
sendStats();
|
||||
|
||||
// only initialize the UI if the player in fact just logged in.
|
||||
if( isLogin() )
|
||||
{
|
||||
if( isActionLearned( static_cast< uint8_t >( Common::UnlockEntry::HuntingLog ) ) )
|
||||
sendHuntingLog();
|
||||
|
||||
auto contentFinderList = makeZonePacket< FFXIVIpcCFAvailableContents >( getId() );
|
||||
|
||||
for( auto i = 0; i < sizeof( contentFinderList->data().contents ); i++ )
|
||||
|
@ -1812,6 +1830,12 @@ void Sapphire::Entity::Player::sendZonePackets()
|
|||
initZonePacket->data().pos.x = getPos().x;
|
||||
initZonePacket->data().pos.y = getPos().y;
|
||||
initZonePacket->data().pos.z = getPos().z;
|
||||
if( auto d = getCurrentTerritory()->getAsDirector() )
|
||||
{
|
||||
initZonePacket->data().contentfinderConditionId = d->getContentFinderConditionId();
|
||||
initZonePacket->data().bitmask = 0xFF;
|
||||
initZonePacket->data().bitmask1 = 0x2A;
|
||||
}
|
||||
queuePacket( initZonePacket );
|
||||
|
||||
getCurrentTerritory()->onPlayerZoneIn( *this );
|
||||
|
|
|
@ -111,6 +111,8 @@ 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, 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 );
|
||||
|
||||
|
@ -490,7 +492,7 @@ namespace Sapphire::Entity
|
|||
bool setInstance( TerritoryPtr instance );
|
||||
|
||||
/*! sets the players instance & initiates zoning process */
|
||||
bool setInstance( Sapphire::TerritoryPtr instance, Sapphire::Common::FFXIVARR_POSITION3 pos );
|
||||
bool setInstance( Sapphire::TerritoryPtr instance, Sapphire::Common::FFXIVARR_POSITION3 pos, float rot );
|
||||
|
||||
/*! returns the player to their position before zoning into an instance */
|
||||
bool exitInstance();
|
||||
|
@ -992,6 +994,8 @@ namespace Sapphire::Entity
|
|||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void setPosAndNotifyClient( float x, float y, float z, float rot );
|
||||
|
||||
Common::HuntingLogEntry& getHuntingLogEntry( uint8_t index );
|
||||
|
||||
void sendHuntingLog();
|
||||
|
|
|
@ -323,6 +323,33 @@ 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, std::vector< uint32_t > paramList, Event::EventHandler::SceneReturnCallback eventReturnCallback )
|
||||
{
|
||||
auto pEvent = bootstrapSceneEvent( eventId, flags );
|
||||
if( !pEvent )
|
||||
return;
|
||||
|
||||
pEvent->setPlayedScene( true );
|
||||
pEvent->setEventReturnCallback( eventReturnCallback );
|
||||
pEvent->setSceneChainCallback( nullptr );
|
||||
auto eventPlay16 = makeZonePacket< FFXIVIpcEventPlay16 >( getId() );
|
||||
eventPlay16->data().actorId = pEvent->getActorId();
|
||||
eventPlay16->data().eventId = pEvent->getId();
|
||||
eventPlay16->data().scene = scene;
|
||||
eventPlay16->data().flags = flags;
|
||||
eventPlay16->data().param3 = param3;
|
||||
eventPlay16->data().paramSize = paramList.size();
|
||||
int i = 0;
|
||||
for( auto p : paramList )
|
||||
{
|
||||
assert( i < 16 );
|
||||
eventPlay16->data().param[ i ] = paramList.at( i );
|
||||
i++;
|
||||
}
|
||||
|
||||
queuePacket( eventPlay16 );
|
||||
}
|
||||
|
||||
void Sapphire::Entity::Player::eventActionStart( uint32_t eventId,
|
||||
uint32_t action,
|
||||
World::Action::ActionCallback finishCallback,
|
||||
|
|
|
@ -16,9 +16,10 @@ using namespace Sapphire::Network::Packets;
|
|||
using namespace Sapphire::Network::Packets::Server;
|
||||
using namespace Sapphire::Network::ActorControl;
|
||||
|
||||
Sapphire::Event::Director::Director( Sapphire::Event::Director::DirectorType type, uint16_t contentId ) :
|
||||
Sapphire::Event::Director::Director( Sapphire::Event::Director::DirectorType type, uint16_t contentId, uint16_t contentFinderConditionId ) :
|
||||
m_contentId( contentId ),
|
||||
m_type( type ),
|
||||
m_contentFinderConditionId( contentFinderConditionId ),
|
||||
m_directorId( ( static_cast< uint32_t >( type ) << 16 ) | contentId ),
|
||||
m_sequence( 1 ),
|
||||
m_branch( 0 ),
|
||||
|
@ -37,6 +38,11 @@ uint16_t Sapphire::Event::Director::getContentId() const
|
|||
return m_contentId;
|
||||
}
|
||||
|
||||
uint16_t Sapphire::Event::Director::getContentFinderConditionId() const
|
||||
{
|
||||
return m_contentFinderConditionId;
|
||||
}
|
||||
|
||||
uint8_t Sapphire::Event::Director::getSequence() const
|
||||
{
|
||||
return m_sequence;
|
||||
|
@ -52,14 +58,18 @@ void Sapphire::Event::Director::sendDirectorVars( Sapphire::Entity::Player& play
|
|||
auto varPacket = makeZonePacket< FFXIVIpcDirectorVars >( player.getId() );
|
||||
varPacket->data().m_directorId = getDirectorId();
|
||||
varPacket->data().m_sequence = getSequence();
|
||||
varPacket->data().m_branch = 0;
|
||||
varPacket->data().m_branch = getBranch();
|
||||
memcpy( varPacket->data().m_unionData, m_unionData.arrData, sizeof( varPacket->data().m_unionData ) );
|
||||
player.queuePacket( varPacket );
|
||||
player.sendDebug( "DirectorVar#{}: {:02X}{:02X}{:02X}{:02X}{:02X}{:02X}{:02X}{:02X}{:02X}{:02X} seq{}, b{}", getDirectorId(),
|
||||
m_unionData.ui8.UI8A, m_unionData.ui8.UI8B, m_unionData.ui8.UI8C, m_unionData.ui8.UI8D, m_unionData.ui8.UI8E,
|
||||
m_unionData.ui8.UI8F, m_unionData.ui8.UI8G, m_unionData.ui8.UI8H, m_unionData.ui8.UI8I, m_unionData.ui8.UI8J,
|
||||
getSequence(), getBranch() );
|
||||
}
|
||||
|
||||
void Sapphire::Event::Director::sendDirectorInit( Sapphire::Entity::Player& player ) const
|
||||
{
|
||||
Logger::debug( "DirectorID#{}, QuestBattleID#{}", m_directorId, m_contentId );
|
||||
Logger::debug( "DirectorID#{}, ContentId#{}, ContentFinderConditionId#{}", m_directorId, m_contentId, m_contentFinderConditionId );
|
||||
player.queuePacket( makeActorControlSelf( player.getId(), DirectorInit, m_directorId, m_contentId ) );
|
||||
}
|
||||
|
||||
|
@ -183,12 +193,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() )
|
||||
|
|
|
@ -42,12 +42,14 @@ namespace Sapphire::Event
|
|||
DutyFailed
|
||||
};
|
||||
|
||||
Director( DirectorType type, uint16_t contentId );
|
||||
Director( DirectorType type, uint16_t contentId, uint16_t contentFinderConditionId = 0 );
|
||||
|
||||
uint32_t getDirectorId() const;
|
||||
|
||||
uint16_t getContentId() const;
|
||||
|
||||
uint16_t getContentFinderConditionId() const;
|
||||
|
||||
DirectorType getType() const;
|
||||
|
||||
uint8_t getSequence() const;
|
||||
|
@ -104,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 */
|
||||
|
@ -114,6 +116,8 @@ namespace Sapphire::Event
|
|||
/*! DirectorType | ContentId */
|
||||
uint32_t m_directorId;
|
||||
|
||||
uint16_t m_contentFinderConditionId;
|
||||
|
||||
/*! currect sequence */
|
||||
uint8_t m_sequence;
|
||||
|
||||
|
@ -183,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;
|
||||
|
||||
};
|
||||
|
||||
|
|
|
@ -79,6 +79,7 @@ namespace Sapphire::Event
|
|||
Adventure = 0x0021,
|
||||
DailyQuestSupply = 0x0022,
|
||||
ICDirector = 0x8003,
|
||||
PublicContentDirector = 0x8004,
|
||||
QuestBattleDirector = 0x8006,
|
||||
};
|
||||
|
||||
|
|
|
@ -24,6 +24,7 @@ TYPE_FORWARD( HousingZone );
|
|||
TYPE_FORWARD( House );
|
||||
TYPE_FORWARD( InstanceContent );
|
||||
TYPE_FORWARD( QuestBattle );
|
||||
TYPE_FORWARD( PublicContent );
|
||||
TYPE_FORWARD( Item );
|
||||
TYPE_FORWARD( ItemContainer );
|
||||
TYPE_FORWARD( ZonePosition );
|
||||
|
|
|
@ -32,6 +32,7 @@
|
|||
#include "Territory/HousingZone.h"
|
||||
#include "Territory/InstanceContent.h"
|
||||
#include "Territory/QuestBattle.h"
|
||||
#include "Territory/PublicContent.h"
|
||||
#include "Manager/TerritoryMgr.h"
|
||||
#include "Event/EventDefs.h"
|
||||
|
||||
|
@ -60,6 +61,8 @@ Sapphire::World::Manager::DebugCommandMgr::DebugCommandMgr()
|
|||
registerCommand( "script", &DebugCommandMgr::script, "Server script utilities.", 1 );
|
||||
registerCommand( "instance", &DebugCommandMgr::instance, "Instance utilities", 1 );
|
||||
registerCommand( "questbattle", &DebugCommandMgr::questBattle, "Quest battle utilities", 1 );
|
||||
registerCommand( "pc", &DebugCommandMgr::pc, "Public content utilities", 1 );
|
||||
registerCommand( "publiccontent", &DebugCommandMgr::pc, "Public content utilities", 1 );
|
||||
registerCommand( "qb", &DebugCommandMgr::questBattle, "Quest battle utilities", 1 );
|
||||
registerCommand( "housing", &DebugCommandMgr::housing, "Housing utilities", 1 );
|
||||
}
|
||||
|
@ -583,9 +586,23 @@ void Sapphire::World::Manager::DebugCommandMgr::get( char* data, Entity::Player&
|
|||
|
||||
int16_t map_id = exdData.get< Sapphire::Data::TerritoryType >( player.getCurrentTerritory()->getTerritoryTypeId() )->map;
|
||||
|
||||
player.sendNotice( "Pos:\n {0}\n {1}\n {2}\n {3}\n MapId: {4}\n ZoneId:{5}",
|
||||
player.sendNotice( "Pos: x: {0}, y: {1}, z: {2}, r: {3}\n MapId: {4}, ZoneId:{5}, Weather:{6}, Festival:{7}, {8}",
|
||||
player.getPos().x, player.getPos().y, player.getPos().z,
|
||||
player.getRot(), map_id, player.getCurrentTerritory()->getTerritoryTypeId() );
|
||||
player.getRot(), map_id, player.getCurrentTerritory()->getTerritoryTypeId(),
|
||||
static_cast< uint8_t >( player.getCurrentTerritory()->getCurrentWeather() ), player.getCurrentTerritory()->getCurrentFestival().first,
|
||||
player.getCurrentTerritory()->getCurrentFestival().second );
|
||||
if( auto instance = player.getCurrentInstance() )
|
||||
{
|
||||
player.sendNotice( "Instance info:\nContentId: {}, DirectorId: {}\nSequence: {}, Branch: {}, BGM: {}",
|
||||
instance->getInstanceContentId(), instance->getDirectorId(), instance->getSequence(),
|
||||
instance->getBranch(), instance->getCurrentBGM() );
|
||||
}
|
||||
else if( auto instance = player.getCurrentPublicContent() )
|
||||
{
|
||||
player.sendNotice( "Public content info:\nContentId: {}, DirectorId: {}\nSequence: {}, Branch: {}",
|
||||
instance->getContentId(), instance->getDirectorId(), instance->getSequence(),
|
||||
instance->getBranch() );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1282,3 +1299,137 @@ void Sapphire::World::Manager::DebugCommandMgr::housing( char* data, Entity::Pla
|
|||
player.sendDebug( "Unknown sub command." );
|
||||
}
|
||||
}
|
||||
|
||||
void Sapphire::World::Manager::DebugCommandMgr::pc( char* data, Entity::Player& player, std::shared_ptr< DebugCommand > command )
|
||||
{
|
||||
auto& terriMgr = Common::Service< TerritoryMgr >::ref();
|
||||
std::string cmd( data ), params, subCommand;
|
||||
auto cmdPos = cmd.find_first_of( ' ' );
|
||||
|
||||
if( cmdPos != std::string::npos )
|
||||
{
|
||||
params = cmd.substr( cmdPos + 1 );
|
||||
|
||||
auto p = params.find_first_of( ' ' );
|
||||
|
||||
if( p != std::string::npos )
|
||||
{
|
||||
subCommand = params.substr( 0, p );
|
||||
params = params.substr( subCommand.length() + 1 );
|
||||
}
|
||||
else
|
||||
subCommand = params;
|
||||
}
|
||||
|
||||
if( subCommand == "create" || subCommand == "cr" )
|
||||
{
|
||||
uint32_t contentFinderConditionId;
|
||||
sscanf( params.c_str(), "%d", &contentFinderConditionId );
|
||||
|
||||
auto instance = terriMgr.createPublicContent( contentFinderConditionId );
|
||||
if( instance )
|
||||
player.sendDebug( "Created instance with id#{0} -> {1}", instance->getGuId(), instance->getName() );
|
||||
else
|
||||
player.sendDebug( "Failed to create instance with id#{0}", contentFinderConditionId );
|
||||
}
|
||||
else if ( subCommand == "create2" || subCommand == "cr2" )
|
||||
{
|
||||
uint16_t contentId, terriId;
|
||||
sscanf( params.c_str(), "%hu %hu", &contentId, &terriId );
|
||||
|
||||
auto instance = terriMgr.createPublicContent( contentId, terriId );
|
||||
if( instance )
|
||||
player.sendDebug( "Created instance with id#{0} -> {1}", instance->getGuId(), instance->getName() );
|
||||
else
|
||||
player.sendDebug( "Failed to create instance with id#{0}, territory#{1}. Server console output may contain additional info.", contentId, terriId );
|
||||
}
|
||||
else if( subCommand == "remove" || subCommand == "rm" )
|
||||
{
|
||||
uint32_t terriId;
|
||||
sscanf( params.c_str(), "%d", &terriId );
|
||||
|
||||
if( terriMgr.removeTerritoryInstance( terriId ) )
|
||||
player.sendDebug( "Removed instance with id#{0}", terriId );
|
||||
else
|
||||
player.sendDebug( "Failed to remove instance with id#{0}", terriId );
|
||||
}
|
||||
else if( subCommand == "return" || subCommand == "ret" )
|
||||
{
|
||||
player.exitInstance();
|
||||
}
|
||||
else if( subCommand == "set" )
|
||||
{
|
||||
uint32_t index;
|
||||
uint32_t value;
|
||||
sscanf( params.c_str(), "%d %d", &index, &value );
|
||||
|
||||
|
||||
auto instance = std::dynamic_pointer_cast< PublicContent >( player.getCurrentTerritory() );
|
||||
if( !instance )
|
||||
return;
|
||||
|
||||
instance->setVar( static_cast< uint8_t >( index ), static_cast< uint8_t >( value ) );
|
||||
}
|
||||
else if( subCommand == "seq" )
|
||||
{
|
||||
uint8_t seq;
|
||||
|
||||
sscanf( params.c_str(), "%hhu", &seq );
|
||||
|
||||
auto instance = std::dynamic_pointer_cast< PublicContent >( player.getCurrentTerritory() );
|
||||
if( !instance )
|
||||
return;
|
||||
|
||||
instance->setSequence( seq );
|
||||
}
|
||||
else if( subCommand == "branch" )
|
||||
{
|
||||
uint8_t branch;
|
||||
|
||||
sscanf( params.c_str(), "%hhu", &branch );
|
||||
|
||||
auto instance = std::dynamic_pointer_cast< PublicContent >( player.getCurrentTerritory() );
|
||||
if( !instance )
|
||||
return;
|
||||
|
||||
instance->setBranch( branch );
|
||||
}
|
||||
else if( subCommand == "objstate" )
|
||||
{
|
||||
char objName[128];
|
||||
uint8_t state;
|
||||
|
||||
sscanf( params.c_str(), "%s %hhu", objName, &state );
|
||||
|
||||
auto instance = std::dynamic_pointer_cast< PublicContent >( player.getCurrentTerritory() );
|
||||
if( !instance )
|
||||
return;
|
||||
|
||||
auto obj = instance->getEObjByName( objName );
|
||||
if( !obj )
|
||||
return;
|
||||
|
||||
obj->setState( state );
|
||||
}
|
||||
else if( subCommand == "objflag" )
|
||||
{
|
||||
char objName[256];
|
||||
uint32_t state1;
|
||||
uint32_t state2;
|
||||
|
||||
sscanf( params.c_str(), "%s %i %i", objName, &state1, &state2 );
|
||||
|
||||
auto instance = std::dynamic_pointer_cast< PublicContent >( player.getCurrentTerritory() );
|
||||
if( !instance )
|
||||
return;
|
||||
|
||||
auto obj = instance->getEObjByName( objName );
|
||||
if( !obj )
|
||||
{
|
||||
player.sendDebug( "No eobj found." );
|
||||
return;
|
||||
}
|
||||
|
||||
obj->setAnimationFlag( state1, state2 );
|
||||
}
|
||||
}
|
||||
|
|
|
@ -53,6 +53,7 @@ namespace Sapphire::World::Manager
|
|||
|
||||
void instance( char* data, Entity::Player& player, std::shared_ptr< DebugCommand > command );
|
||||
void questBattle( char* data, Entity::Player& player, std::shared_ptr< DebugCommand > command );
|
||||
void pc( char* data, Entity::Player& player, std::shared_ptr< DebugCommand > command );
|
||||
|
||||
void housing( char* data, Entity::Player& player, std::shared_ptr< DebugCommand > command) ;
|
||||
|
||||
|
|
|
@ -74,6 +74,13 @@ std::string Sapphire::World::Manager::EventMgr::getEventName( uint32_t eventId )
|
|||
name[ 0 ] = toupper( name[ 0 ] );
|
||||
return name;
|
||||
}
|
||||
case Event::EventHandler::EventHandlerType::PublicContentDirector:
|
||||
{
|
||||
auto pcInfo = exdData.get< Sapphire::Data::PublicContent >( eventId & 0x0000FFFF );
|
||||
if( !pcInfo )
|
||||
return "unknown";
|
||||
return pcInfo->name;
|
||||
}
|
||||
|
||||
|
||||
case Event::EventHandler::EventHandlerType::Warp:
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
#include "Territory/ZonePosition.h"
|
||||
#include "Territory/InstanceContent.h"
|
||||
#include "Territory/QuestBattle.h"
|
||||
#include "Territory/PublicContent.h"
|
||||
#include "TerritoryMgr.h"
|
||||
#include "HousingMgr.h"
|
||||
|
||||
|
@ -316,7 +317,7 @@ Sapphire::TerritoryPtr Sapphire::World::Manager::TerritoryMgr::createQuestBattle
|
|||
Logger::debug( "Starting instance for QuestBattle id: {0} ({1})", questBattleId, pQuestInfo->name );
|
||||
|
||||
auto pZone = make_QuestBattle( pQuestBattleInfo, pContentFinderCondition->territoryType, getNextInstanceId(),
|
||||
pTeri->name, pQuestInfo->name, questBattleId );
|
||||
pTeri->name, pQuestInfo->name, questBattleId, contentFinderConditionId );
|
||||
pZone->init();
|
||||
|
||||
m_questBattleIdToInstanceMap[ questBattleId ][ pZone->getGuId() ] = pZone;
|
||||
|
@ -350,7 +351,7 @@ Sapphire::TerritoryPtr Sapphire::World::Manager::TerritoryMgr::createInstanceCon
|
|||
Logger::debug( "Starting instance for InstanceContent id: {0} ({1})", instanceContentId, pContentFinderCondition->name );
|
||||
|
||||
auto pZone = make_InstanceContent( pInstanceContent, pContentFinderCondition->territoryType, getNextInstanceId(),
|
||||
pTeri->name, pContentFinderCondition->name, instanceContentId );
|
||||
pTeri->name, pContentFinderCondition->name, instanceContentId, contentFinderConditionId );
|
||||
pZone->init();
|
||||
|
||||
m_instanceContentIdToInstanceMap[ instanceContentId ][ pZone->getGuId() ] = pZone;
|
||||
|
@ -360,6 +361,68 @@ Sapphire::TerritoryPtr Sapphire::World::Manager::TerritoryMgr::createInstanceCon
|
|||
return pZone;
|
||||
}
|
||||
|
||||
Sapphire::TerritoryPtr Sapphire::World::Manager::TerritoryMgr::createPublicContent( uint32_t contentFinderConditionId )
|
||||
{
|
||||
auto& exdData = Common::Service< Data::ExdDataGenerated >::ref();
|
||||
|
||||
auto pContentFinderCondition = exdData.get< Sapphire::Data::ContentFinderCondition >( contentFinderConditionId );
|
||||
if( !pContentFinderCondition )
|
||||
return nullptr;
|
||||
auto contentId = pContentFinderCondition->content;
|
||||
|
||||
auto pPublicContent = exdData.get< Sapphire::Data::PublicContent >( contentId );
|
||||
if( !pPublicContent )
|
||||
return nullptr;
|
||||
|
||||
auto pTeri = getTerritoryDetail( pContentFinderCondition->territoryType );
|
||||
|
||||
if( !pTeri || pContentFinderCondition->name.empty() )
|
||||
return nullptr;
|
||||
|
||||
Logger::debug( "Starting instance for PublicContent id: {0} ({1})", contentId, pContentFinderCondition->name );
|
||||
|
||||
auto pZone = make_PublicContent( pPublicContent, pContentFinderCondition->territoryType, getNextInstanceId(),
|
||||
pTeri->name, pContentFinderCondition->name, contentId, contentFinderConditionId );
|
||||
pZone->init();
|
||||
|
||||
m_publicContentIdToInstanceMap[ contentId ][ pZone->getGuId() ] = pZone;
|
||||
m_guIdToTerritoryPtrMap[ pZone->getGuId() ] = pZone;
|
||||
m_instanceZoneSet.insert( pZone );
|
||||
|
||||
return pZone;
|
||||
}
|
||||
|
||||
Sapphire::TerritoryPtr Sapphire::World::Manager::TerritoryMgr::createPublicContent( uint16_t contentId, uint16_t territoryId )
|
||||
{
|
||||
auto& exdData = Common::Service< Data::ExdDataGenerated >::ref();
|
||||
|
||||
auto pPublicContent = exdData.get< Sapphire::Data::PublicContent >( contentId );
|
||||
if( !pPublicContent )
|
||||
return nullptr;
|
||||
|
||||
if( pPublicContent->contentFinderCondition > 0 )
|
||||
{
|
||||
Logger::warn( "the public content {} has a ContentFinderCondition value of {}, create the instance using it instead.", contentId, pPublicContent->contentFinderCondition );
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
auto pTeri = getTerritoryDetail( territoryId );
|
||||
|
||||
if( !pTeri )
|
||||
return nullptr;
|
||||
|
||||
Logger::debug( "Starting instance for PublicContent id: {0} ({1})", contentId, pPublicContent->name );
|
||||
|
||||
auto pZone = make_PublicContent( pPublicContent, territoryId, getNextInstanceId(), pTeri->name, pPublicContent->name, contentId, 0 );
|
||||
pZone->init();
|
||||
|
||||
m_publicContentIdToInstanceMap[ contentId ][ pZone->getGuId() ] = pZone;
|
||||
m_guIdToTerritoryPtrMap[ pZone->getGuId() ] = pZone;
|
||||
m_instanceZoneSet.insert( pZone );
|
||||
|
||||
return pZone;
|
||||
}
|
||||
|
||||
Sapphire::TerritoryPtr Sapphire::World::Manager::TerritoryMgr::findOrCreateHousingInterior( const Common::LandIdent landIdent )
|
||||
{
|
||||
// check if zone already spawned first
|
||||
|
@ -444,11 +507,21 @@ bool Sapphire::World::Manager::TerritoryMgr::removeTerritoryInstance( uint32_t g
|
|||
m_instanceZoneSet.erase( pZone );
|
||||
m_territorySet.erase( pZone );
|
||||
|
||||
if( isInstanceContentTerritory( pZone->getTerritoryTypeId() ) )
|
||||
if( pZone->getAsInstanceContent() )
|
||||
{
|
||||
auto instance = std::dynamic_pointer_cast< InstanceContent >( pZone );
|
||||
m_instanceContentIdToInstanceMap[ instance->getInstanceContentId() ].erase( pZone->getGuId() );
|
||||
}
|
||||
else if( pZone->getAsPublicContent() )
|
||||
{
|
||||
auto instance = std::dynamic_pointer_cast< PublicContent >( pZone );
|
||||
m_publicContentIdToInstanceMap[ instance->getContentId() ].erase( pZone->getGuId() );
|
||||
}
|
||||
else if( pZone->getAsQuestBattle() )
|
||||
{
|
||||
auto instance = std::dynamic_pointer_cast< QuestBattle >( pZone );
|
||||
m_questBattleIdToInstanceMap[ instance->getQuestBattleId() ].erase( pZone->getGuId() );
|
||||
}
|
||||
else
|
||||
m_territoryTypeIdToInstanceGuidMap[ pZone->getTerritoryTypeId() ].erase( pZone->getGuId() );
|
||||
|
||||
|
@ -616,7 +689,7 @@ bool Sapphire::World::Manager::TerritoryMgr::movePlayer( TerritoryPtr pZone, Sap
|
|||
if( pHousing )
|
||||
pPlayer->setTerritoryId( pHousing->getLandSetId() );
|
||||
}
|
||||
else if( isInstanceContentTerritory( pZone->getTerritoryTypeId() ) )
|
||||
else if( pZone->getAsInstanceContent() || pZone->getAsQuestBattle() || pZone->getAsPublicContent() )
|
||||
{
|
||||
pPlayer->setTerritoryId( pZone->getGuId() );
|
||||
}
|
||||
|
|
|
@ -118,6 +118,9 @@ namespace Sapphire::World::Manager
|
|||
|
||||
TerritoryPtr createQuestBattle( uint32_t contentFinderConditionId );
|
||||
|
||||
TerritoryPtr createPublicContent( uint32_t contentFinderConditionId );
|
||||
TerritoryPtr createPublicContent( uint16_t contentId, uint16_t territoryId );
|
||||
|
||||
void createAndJoinQuestBattle( Entity::Player& player, uint16_t contentFinderConditionId );
|
||||
|
||||
TerritoryPtr findOrCreateHousingInterior( const Common::LandIdent landIdent );
|
||||
|
@ -179,6 +182,7 @@ namespace Sapphire::World::Manager
|
|||
using InstanceContentIdToInstanceMap = std::unordered_map< uint16_t, InstanceIdToTerritoryPtrMap >;
|
||||
using QuestBattleIdToInstanceMap = std::unordered_map< uint16_t, InstanceIdToTerritoryPtrMap >;
|
||||
using QuestBattleIdToContentFinderCondMap = std::unordered_map< uint16_t, uint16_t >;
|
||||
using PublicContentIdToInstanceMap = std::unordered_map< uint16_t, InstanceIdToTerritoryPtrMap >;
|
||||
using PlayerIdToInstanceIdMap = std::unordered_map< uint32_t, uint32_t >;
|
||||
using PositionMap = std::unordered_map< int32_t, ZonePositionPtr >;
|
||||
using InstanceIdList = std::vector< uint32_t >;
|
||||
|
@ -196,9 +200,12 @@ namespace Sapphire::World::Manager
|
|||
/*! map holding actual instances of InstanceContent */
|
||||
InstanceContentIdToInstanceMap m_instanceContentIdToInstanceMap;
|
||||
|
||||
/*! map holding actual instances of InstanceContent */
|
||||
/*! map holding actual instances of QuestBattle */
|
||||
QuestBattleIdToInstanceMap m_questBattleIdToInstanceMap;
|
||||
|
||||
/*! map holding actual instances of PublicContent */
|
||||
PublicContentIdToInstanceMap m_publicContentIdToInstanceMap;
|
||||
|
||||
/*! flat map for easier lookup of instances by guid */
|
||||
InstanceIdToTerritoryPtrMap m_guIdToTerritoryPtrMap;
|
||||
|
||||
|
|
|
@ -106,6 +106,8 @@ Sapphire::Network::GameConnection::GameConnection( Sapphire::Network::HivePtr pH
|
|||
setZoneHandler( ClientZoneIpcType::TradeReturnEventHandler, "TradeReturnEventHandler",
|
||||
&GameConnection::eventHandlerReturn );
|
||||
setZoneHandler( ClientZoneIpcType::TradeReturnEventHandler2, "TradeReturnEventHandler2", &GameConnection::eventHandlerReturn );
|
||||
setZoneHandler( ClientZoneIpcType::EventYieldHandler, "EventYieldHandler", &GameConnection::eventYieldHandler );
|
||||
setZoneHandler( ClientZoneIpcType::EventYield16Handler, "EventYield16Handler", &GameConnection::eventYieldHandler );
|
||||
|
||||
setZoneHandler( ClientZoneIpcType::ShopEventHandler, "ShopEventHandler",
|
||||
&GameConnection::eventHandlerShop );
|
||||
|
|
|
@ -194,6 +194,8 @@ namespace Sapphire::Network
|
|||
DECLARE_HANDLER( worldInteractionhandler );
|
||||
|
||||
DECLARE_HANDLER( diveHandler );
|
||||
|
||||
DECLARE_HANDLER( eventYieldHandler );
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -103,7 +103,6 @@ void Sapphire::Network::GameConnection::cfDutyAccepted( const Packets::FFXIVARR_
|
|||
|
||||
player.prepareZoning( pInstance->getTerritoryTypeId(), true, 1, 0, 0, 1, 9 );
|
||||
|
||||
auto sourceZoneGuId = player.getCurrentTerritory()->getGuId();
|
||||
player.setInstance( instance );
|
||||
}
|
||||
}
|
||||
|
|
|
@ -494,6 +494,11 @@ void Sapphire::Network::GameConnection::clientTriggerHandler( const Packets::FFX
|
|||
player.sendDebug( "event battle p1: {0}, p11: {1}, p12: {2}, p2: {3}, p3: {4}, p4: {5}, p5: {6}", param1, param11, param12, param2, param3, param4, param5 );
|
||||
break;
|
||||
}
|
||||
case ClientTriggerType::CutscenePlayed:
|
||||
{
|
||||
player.sendDebug( "cutscene: {}", param1 );
|
||||
break;
|
||||
}
|
||||
case ClientTriggerType::OpenPerformInstrumentUI:
|
||||
{
|
||||
//param11 = instrument, 0 = end
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
|
||||
#include "Territory/InstanceContent.h"
|
||||
#include "Territory/QuestBattle.h"
|
||||
#include "Territory/PublicContent.h"
|
||||
|
||||
#include "Session.h"
|
||||
|
||||
|
@ -59,6 +60,14 @@ void Sapphire::Network::GameConnection::eventHandlerTalk( const Packets::FFXIVAR
|
|||
{
|
||||
instance->onTalk( player, eventId, actorId );
|
||||
}
|
||||
else if( auto instance = player.getCurrentQuestBattle() )
|
||||
{
|
||||
instance->onTalk( player, eventId, actorId );
|
||||
}
|
||||
else if( auto instance = player.getCurrentPublicContent() )
|
||||
{
|
||||
instance->onTalk( player, eventId, actorId );
|
||||
}
|
||||
else if( !scriptMgr.onTalk( player, actorId, eventId ) &&
|
||||
eventType == Event::EventHandler::EventHandlerType::Quest )
|
||||
{
|
||||
|
@ -180,6 +189,11 @@ void Sapphire::Network::GameConnection::eventHandlerEnterTerritory( const Packet
|
|||
player.eventStart( player.getId(), eventId, Event::EventHandler::EnterTerritory, 1, player.getZoneId() );
|
||||
instance->onEnterTerritory( player, eventId, param1, param2 );
|
||||
}
|
||||
else if( auto instance = player.getCurrentPublicContent() )
|
||||
{
|
||||
player.eventStart( player.getId(), eventId, Event::EventHandler::EnterTerritory, 1, player.getZoneId() );
|
||||
instance->onEnterTerritory( player, eventId, param1, param2 );
|
||||
}
|
||||
else
|
||||
{
|
||||
player.eventStart( player.getId(), eventId, Event::EventHandler::EnterTerritory, 0, player.getZoneId() );
|
||||
|
@ -273,5 +287,39 @@ void Sapphire::Network::GameConnection::eventHandlerShop( const Packets::FFXIVAR
|
|||
scriptMgr.onTalk( player, player.getId(), eventId );
|
||||
}
|
||||
|
||||
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();
|
||||
|
||||
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;
|
||||
|
||||
switch( opcode )
|
||||
{
|
||||
case EventYield16Handler:
|
||||
{
|
||||
for( int i = 0; i < 16; i++ )
|
||||
{
|
||||
param.push_back( pParam[ i ] );
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
std::string eventName = "onEventYield";
|
||||
std::string objName = eventMgr.getEventName( eventId );
|
||||
player.sendDebug( "Calling: {0}.{1} - {2} scene: {3}", objName, eventName, eventId, scene );
|
||||
|
||||
scriptMgr.onEventYield( player, eventId, scene, param );
|
||||
|
||||
auto response = makeZonePacket< FFXIVIpcEventContinue >( player.getId() );
|
||||
response->data().eventId = eventId;
|
||||
response->data().scene = scene;
|
||||
player.queuePacket( response );
|
||||
}
|
||||
|
||||
|
|
|
@ -387,15 +387,18 @@ void Sapphire::Network::GameConnection::pingHandler( const Packets::FFXIVARR_PAC
|
|||
void Sapphire::Network::GameConnection::finishLoadingHandler( const Packets::FFXIVARR_PACKET_RAW& inPacket,
|
||||
Entity::Player& player )
|
||||
{
|
||||
player.sendQuestInfo();
|
||||
if( player.isLogin() )
|
||||
{
|
||||
player.sendQuestInfo();
|
||||
|
||||
// TODO: load and save this data instead of hardcoding
|
||||
auto gcPacket = makeZonePacket< FFXIVGCAffiliation >( player.getId() );
|
||||
gcPacket->data().gcId = player.getGc();
|
||||
gcPacket->data().gcRank[ 0 ] = player.getGcRankArray()[ 0 ];
|
||||
gcPacket->data().gcRank[ 1 ] = player.getGcRankArray()[ 1 ];
|
||||
gcPacket->data().gcRank[ 2 ] = player.getGcRankArray()[ 2 ];
|
||||
player.queuePacket( gcPacket );
|
||||
// TODO: load and save this data instead of hardcoding
|
||||
auto gcPacket = makeZonePacket< FFXIVGCAffiliation >( player.getId() );
|
||||
gcPacket->data().gcId = player.getGc();
|
||||
gcPacket->data().gcRank[ 0 ] = player.getGcRankArray()[ 0 ];
|
||||
gcPacket->data().gcRank[ 1 ] = player.getGcRankArray()[ 1 ];
|
||||
gcPacket->data().gcRank[ 2 ] = player.getGcRankArray()[ 2 ];
|
||||
player.queuePacket( gcPacket );
|
||||
}
|
||||
|
||||
player.getCurrentTerritory()->onFinishLoading( player );
|
||||
|
||||
|
|
|
@ -22,15 +22,15 @@ namespace Sapphire::Network::Packets::Server
|
|||
uint32_t param3 = 0,
|
||||
uint32_t param4 = 0,
|
||||
uint32_t param5 = 0,
|
||||
uint32_t padding1 = 0 ) :
|
||||
uint32_t param6 = 0 ) :
|
||||
ZoneChannelPacket< FFXIVIpcActorControlSelf >( actorId, actorId )
|
||||
{
|
||||
initialize( category, param1, param2, param3, param4, param5 );
|
||||
initialize( category, param1, param2, param3, param4, param5, param6 );
|
||||
};
|
||||
|
||||
private:
|
||||
void initialize( uint16_t category, uint32_t param1, uint32_t param2, uint32_t param3, uint32_t param4,
|
||||
uint32_t param5 )
|
||||
uint32_t param5, uint32_t param6 )
|
||||
{
|
||||
m_data.padding = 0;
|
||||
m_data.category = category;
|
||||
|
@ -39,6 +39,7 @@ namespace Sapphire::Network::Packets::Server
|
|||
m_data.param3 = param3;
|
||||
m_data.param4 = param4;
|
||||
m_data.param5 = param5;
|
||||
m_data.param6 = param6;
|
||||
};
|
||||
};
|
||||
|
||||
|
|
|
@ -8,6 +8,8 @@
|
|||
#include "Forwards.h"
|
||||
#include "Inventory/Item.h"
|
||||
#include "StatusEffect/StatusEffect.h"
|
||||
#include "Territory/Territory.h"
|
||||
#include "Event/Director.h"
|
||||
|
||||
namespace Sapphire::Network::Packets::Server
|
||||
{
|
||||
|
@ -143,6 +145,10 @@ namespace Sapphire::Network::Packets::Server
|
|||
m_data.effect[ effect.first ].param = effect.second->getParam();
|
||||
}
|
||||
|
||||
if( auto d = player.getCurrentTerritory()->getAsDirector() )
|
||||
{
|
||||
m_data.directorId = d->getDirectorId();
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
|
|
|
@ -134,6 +134,10 @@ namespace Sapphire::ScriptAPI
|
|||
{
|
||||
}
|
||||
|
||||
void EventScript::onEventYield( Sapphire::Entity::Player& player, uint16_t scene, std::vector< uint32_t > param )
|
||||
{
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
|
||||
EventObjectScript::EventObjectScript( uint32_t eobjId ) :
|
||||
|
@ -216,5 +220,31 @@ namespace Sapphire::ScriptAPI
|
|||
{
|
||||
}
|
||||
|
||||
PublicContentScript::PublicContentScript( uint32_t contentId ) :
|
||||
ScriptObject( uint32_t{ 0x8004 } << 16 | contentId, typeid( PublicContentScript ).hash_code() )
|
||||
{
|
||||
}
|
||||
|
||||
void PublicContentScript::onInit( PublicContent& instance )
|
||||
{
|
||||
}
|
||||
|
||||
void PublicContentScript::onUpdate( PublicContent& instance, uint64_t tickCount )
|
||||
{
|
||||
}
|
||||
|
||||
void PublicContentScript::onPlayerZoneIn( PublicContent& instance, Entity::Player& player )
|
||||
{
|
||||
}
|
||||
|
||||
void PublicContentScript::onLeaveTerritory( PublicContent& instance, Entity::Player& player )
|
||||
{
|
||||
}
|
||||
|
||||
void PublicContentScript::onEnterTerritory( PublicContent& instance, Entity::Player& player, uint32_t eventId,
|
||||
uint16_t param1, uint16_t param2 )
|
||||
{
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -166,6 +166,8 @@ namespace Sapphire::ScriptAPI
|
|||
uint32_t catalogId );
|
||||
|
||||
virtual void onEObjHit( Sapphire::Entity::Player& player, uint64_t actorId, uint32_t actionId );
|
||||
|
||||
virtual void onEventYield( Sapphire::Entity::Player& player, uint16_t scene, std::vector< uint32_t > param );
|
||||
};
|
||||
|
||||
/*!
|
||||
|
@ -237,6 +239,23 @@ namespace Sapphire::ScriptAPI
|
|||
uint16_t param1, uint16_t param2 );
|
||||
};
|
||||
|
||||
class PublicContentScript : public ScriptObject
|
||||
{
|
||||
public:
|
||||
explicit PublicContentScript( uint32_t contentId );
|
||||
|
||||
virtual void onInit( Sapphire::PublicContent& instance );
|
||||
|
||||
virtual void onUpdate( Sapphire::PublicContent& instance, uint64_t tickCount );
|
||||
|
||||
virtual void onPlayerZoneIn( Sapphire::PublicContent& instance, Sapphire::Entity::Player& player );
|
||||
|
||||
virtual void onLeaveTerritory( Sapphire::PublicContent& instance, Sapphire::Entity::Player& player );
|
||||
|
||||
virtual void onEnterTerritory( Sapphire::PublicContent& instance, Sapphire::Entity::Player& player, uint32_t eventId,
|
||||
uint16_t param1, uint16_t param2 );
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
#include "Territory/Territory.h"
|
||||
#include "Territory/InstanceContent.h"
|
||||
#include "Territory/QuestBattle.h"
|
||||
#include "Territory/PublicContent.h"
|
||||
#include "Actor/Player.h"
|
||||
#include "Actor/EventObject.h"
|
||||
#include "ServerMgr.h"
|
||||
|
@ -530,8 +531,7 @@ Sapphire::Scripting::NativeScriptMgr& Sapphire::Scripting::ScriptMgr::getNativeS
|
|||
return *m_nativeScriptMgr;
|
||||
}
|
||||
|
||||
bool
|
||||
Sapphire::Scripting::ScriptMgr::onDutyComplete( Sapphire::QuestBattlePtr instance, Sapphire::Entity::Player& player )
|
||||
bool Sapphire::Scripting::ScriptMgr::onDutyComplete( Sapphire::QuestBattlePtr instance, Sapphire::Entity::Player& player )
|
||||
{
|
||||
auto script = m_nativeScriptMgr->getScript< Sapphire::ScriptAPI::QuestBattleScript >( instance->getDirectorId() );
|
||||
if( script )
|
||||
|
@ -542,3 +542,77 @@ Sapphire::Scripting::ScriptMgr::onDutyComplete( Sapphire::QuestBattlePtr instanc
|
|||
|
||||
return false;
|
||||
}
|
||||
|
||||
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 >( eventId );
|
||||
if( script )
|
||||
{
|
||||
script->onEventYield( player, scene, param );
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Sapphire::Scripting::ScriptMgr::onPublicContentInit( PublicContentPtr instance )
|
||||
{
|
||||
auto script = m_nativeScriptMgr->getScript< Sapphire::ScriptAPI::PublicContentScript >( instance->getDirectorId() );
|
||||
if( script )
|
||||
{
|
||||
script->onInit( *instance );
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Sapphire::Scripting::ScriptMgr::onPublicContentUpdate( PublicContentPtr instance, uint64_t tickCount )
|
||||
{
|
||||
auto script = m_nativeScriptMgr->getScript< Sapphire::ScriptAPI::PublicContentScript >( instance->getDirectorId() );
|
||||
|
||||
if( script )
|
||||
{
|
||||
script->onUpdate( *instance, tickCount );
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Sapphire::Scripting::ScriptMgr::onPublicContentPlayerZoneIn( PublicContentPtr instance, Entity::Player& player )
|
||||
{
|
||||
auto script = m_nativeScriptMgr->getScript< Sapphire::ScriptAPI::PublicContentScript >( instance->getDirectorId() );
|
||||
if( script )
|
||||
{
|
||||
script->onPlayerZoneIn( *instance, player );
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Sapphire::Scripting::ScriptMgr::onPublicContentLeaveTerritory( PublicContentPtr instance, Entity::Player& player )
|
||||
{
|
||||
auto script = m_nativeScriptMgr->getScript< Sapphire::ScriptAPI::PublicContentScript >( instance->getDirectorId() );
|
||||
if( script )
|
||||
{
|
||||
script->onLeaveTerritory( *instance, player );
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Sapphire::Scripting::ScriptMgr::onPublicContentEnterTerritory( PublicContentPtr instance, Entity::Player& player,
|
||||
uint32_t eventId, uint16_t param1, uint16_t param2 )
|
||||
{
|
||||
auto script = m_nativeScriptMgr->getScript< Sapphire::ScriptAPI::PublicContentScript >( instance->getDirectorId() );
|
||||
if( script )
|
||||
{
|
||||
script->onEnterTerritory( *instance, player, eventId, param1, param2 );
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
|
@ -112,6 +112,18 @@ namespace Sapphire::Scripting
|
|||
|
||||
bool onDutyComplete( QuestBattlePtr instance, Entity::Player& player );
|
||||
|
||||
bool onEventYield( Entity::Player& player, uint32_t eventId, uint16_t scene, std::vector< uint32_t > param );
|
||||
|
||||
bool onPublicContentInit( PublicContentPtr instance );
|
||||
|
||||
bool onPublicContentUpdate( PublicContentPtr instance, uint64_t tickCount );
|
||||
|
||||
bool onPublicContentPlayerZoneIn( PublicContentPtr instance, Entity::Player& player );
|
||||
|
||||
bool onPublicContentLeaveTerritory( PublicContentPtr instance, Entity::Player& player );
|
||||
|
||||
bool onPublicContentEnterTerritory( PublicContentPtr instance, Entity::Player& player, uint32_t eventId, uint16_t param1, uint16_t param2 );
|
||||
|
||||
bool loadDir( const std::string& dirname, std::set< std::string >& files, const std::string& ext );
|
||||
|
||||
NativeScriptMgr& getNativeScriptHandler();
|
||||
|
|
|
@ -32,9 +32,9 @@ Sapphire::InstanceContent::InstanceContent( std::shared_ptr< Sapphire::Data::Ins
|
|||
uint32_t guId,
|
||||
const std::string& internalName,
|
||||
const std::string& contentName,
|
||||
uint32_t instanceContentId ) :
|
||||
uint32_t instanceContentId, uint16_t contentFinderConditionId ) :
|
||||
Territory( static_cast< uint16_t >( territoryType ), guId, internalName, contentName ),
|
||||
Director( Event::Director::InstanceContent, instanceContentId ),
|
||||
Director( Event::Director::InstanceContent, instanceContentId, contentFinderConditionId ),
|
||||
m_instanceConfiguration( pInstanceConfiguration ),
|
||||
m_instanceContentId( instanceContentId ),
|
||||
m_state( Created ),
|
||||
|
@ -310,6 +310,8 @@ void Sapphire::InstanceContent::onRegisterEObj( Entity::EventObjectPtr object )
|
|||
m_eventObjectMap[ object->getName() ] = object;
|
||||
if( object->getObjectId() == 2000182 ) // start
|
||||
m_pEntranceEObj = object;
|
||||
if( m_pEntranceEObj == nullptr && object->getName() == "Entrance" )
|
||||
m_pEntranceEObj = object;
|
||||
|
||||
auto& exdData = Common::Service< Data::ExdDataGenerated >::ref();
|
||||
auto objData = exdData.get< Sapphire::Data::EObj >( object->getObjectId() );
|
||||
|
@ -375,7 +377,7 @@ void Sapphire::InstanceContent::onTalk( Sapphire::Entity::Player& player, uint32
|
|||
return;
|
||||
|
||||
if( auto onTalk = it->second->getOnTalkHandler() )
|
||||
onTalk( player, it->second, getAsInstanceContent(), actorId );
|
||||
onTalk( player, it->second, getAsInstanceContent(), eventId, actorId );
|
||||
else
|
||||
player.sendDebug( "No onTalk handler found for interactable eobj with EObjID#{0}, eventId#{1} ",
|
||||
it->second->getObjectId(), eventId );
|
||||
|
|
|
@ -28,7 +28,7 @@ namespace Sapphire
|
|||
uint32_t guId,
|
||||
const std::string& internalName,
|
||||
const std::string& contentName,
|
||||
uint32_t instanceContentId );
|
||||
uint32_t instanceContentId, uint16_t contentFinderConditionId = 0 );
|
||||
|
||||
virtual ~InstanceContent();
|
||||
|
||||
|
|
271
src/world/Territory/PublicContent.cpp
Normal file
271
src/world/Territory/PublicContent.cpp
Normal file
|
@ -0,0 +1,271 @@
|
|||
#include <Common.h>
|
||||
#include <Logging/Logger.h>
|
||||
#include <Util/Util.h>
|
||||
#include <Util/UtilMath.h>
|
||||
#include <Exd/ExdDataGenerated.h>
|
||||
#include <Network/CommonActorControl.h>
|
||||
#include <Service.h>
|
||||
|
||||
#include "Actor/Player.h"
|
||||
#include "Actor/EventObject.h"
|
||||
#include "Event/Director.h"
|
||||
#include "Event/EventDefs.h"
|
||||
#include "Event/EventHandler.h"
|
||||
#include "Script/ScriptMgr.h"
|
||||
|
||||
#include "Network/PacketWrappers/ActorControlPacket.h"
|
||||
#include "Network/PacketWrappers/ActorControlSelfPacket.h"
|
||||
|
||||
#include "PublicContent.h"
|
||||
|
||||
using namespace Sapphire::Common;
|
||||
using namespace Sapphire::Network::Packets;
|
||||
using namespace Sapphire::Network::Packets::Server;
|
||||
using namespace Sapphire::Network::ActorControl;
|
||||
|
||||
Sapphire::PublicContent::PublicContent( std::shared_ptr< Sapphire::Data::PublicContent > pConfiguration,
|
||||
uint16_t territoryType,
|
||||
uint32_t guId,
|
||||
const std::string& internalName,
|
||||
const std::string& contentName,
|
||||
uint32_t contentId, uint16_t contentFinderConditionId ) :
|
||||
Territory( static_cast< uint16_t >( territoryType ), guId, internalName, contentName ),
|
||||
Director( Event::Director::PublicContent, contentId, contentFinderConditionId ),
|
||||
m_Configuration( pConfiguration ),
|
||||
m_ContentId( contentId )
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
bool Sapphire::PublicContent::init()
|
||||
{
|
||||
if( !Territory::init() )
|
||||
return false;
|
||||
|
||||
auto& scriptMgr = Common::Service< Scripting::ScriptMgr >::ref();
|
||||
scriptMgr.onPublicContentInit( getAsPublicContent() );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
Sapphire::PublicContent::~PublicContent()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
uint32_t Sapphire::PublicContent::getContentId() const
|
||||
{
|
||||
return m_ContentId;
|
||||
}
|
||||
|
||||
Sapphire::Data::ExdDataGenerated::PublicContentPtr Sapphire::PublicContent::getConfiguration() const
|
||||
{
|
||||
return m_Configuration;
|
||||
}
|
||||
|
||||
void Sapphire::PublicContent::onPlayerZoneIn( Entity::Player& player )
|
||||
{
|
||||
Logger::debug( "PublicContent::onPlayerZoneIn: Territory#{0}|{1}, Entity#{2}", getGuId(), getTerritoryTypeId(), player.getId() );
|
||||
sendDirectorInit( player );
|
||||
|
||||
auto& scriptMgr = Common::Service< Scripting::ScriptMgr >::ref();
|
||||
scriptMgr.onPublicContentPlayerZoneIn( getAsPublicContent(), player );
|
||||
}
|
||||
|
||||
void Sapphire::PublicContent::onLeaveTerritory( Entity::Player& player )
|
||||
{
|
||||
Logger::debug( "PublicContent::onLeaveTerritory: Territory#{0}|{1}, Entity#{2}", getGuId(), getTerritoryTypeId(), player.getId() );
|
||||
clearDirector( player );
|
||||
|
||||
auto& scriptMgr = Common::Service< Scripting::ScriptMgr >::ref();
|
||||
scriptMgr.onPublicContentLeaveTerritory( getAsPublicContent(), player );
|
||||
}
|
||||
|
||||
void Sapphire::PublicContent::onUpdate( uint64_t tickCount )
|
||||
{
|
||||
updateBNpcs( tickCount );
|
||||
auto& scriptMgr = Common::Service< Scripting::ScriptMgr >::ref();
|
||||
scriptMgr.onPublicContentUpdate( getAsPublicContent(), tickCount );
|
||||
}
|
||||
|
||||
void Sapphire::PublicContent::onFinishLoading( Entity::Player& player )
|
||||
{
|
||||
sendDirectorInit( player );
|
||||
}
|
||||
|
||||
void Sapphire::PublicContent::onInitDirector( Entity::Player& player )
|
||||
{
|
||||
sendDirectorVars( player );
|
||||
player.setDirectorInitialized( true );
|
||||
}
|
||||
|
||||
void Sapphire::PublicContent::onDirectorSync( Entity::Player& player )
|
||||
{
|
||||
player.queuePacket( makeActorControlSelf( player.getId(), DirectorUpdate, 0x00110001, 0x80000000, 1 ) );
|
||||
}
|
||||
|
||||
void Sapphire::PublicContent::onBeforePlayerZoneIn( Sapphire::Entity::Player& player )
|
||||
{
|
||||
/*if( m_pEntranceEObj != nullptr )
|
||||
{
|
||||
player.setRot( PI );
|
||||
player.setPos( m_pEntranceEObj->getPos() );
|
||||
}
|
||||
else
|
||||
{
|
||||
player.setRot( PI );
|
||||
player.setPos( { 0.f, 0.f, 0.f } );
|
||||
}*/
|
||||
player.resetObjSpawnIndex();
|
||||
}
|
||||
|
||||
void Sapphire::PublicContent::onEnterTerritory( Entity::Player& player, uint32_t eventId, uint16_t param1, uint16_t param2 )
|
||||
{
|
||||
auto& scriptMgr = Common::Service< Scripting::ScriptMgr >::ref();
|
||||
scriptMgr.onPublicContentEnterTerritory( getAsPublicContent(), player, eventId, param1, param2 );
|
||||
}
|
||||
|
||||
void Sapphire::PublicContent::onRegisterEObj( Entity::EventObjectPtr object )
|
||||
{
|
||||
if( object->getName() != "none" )
|
||||
m_eventObjectMap[ object->getName() ] = object;
|
||||
if( object->getObjectId() == 2000182 ) // start
|
||||
m_pEntranceEObj = object;
|
||||
if( m_pEntranceEObj == nullptr && object->getName() == "Entrance" )
|
||||
m_pEntranceEObj = object;
|
||||
|
||||
auto& exdData = Common::Service< Data::ExdDataGenerated >::ref();
|
||||
auto objData = exdData.get< Sapphire::Data::EObj >( object->getObjectId() );
|
||||
if( objData )
|
||||
m_eventIdToObjectMap[ objData->data ] = object;
|
||||
else
|
||||
Logger::error( "PublicContent::onRegisterEObj Territory " +
|
||||
m_internalName + ": No EObj data found for EObj with ID: " +
|
||||
std::to_string( object->getObjectId() ) );
|
||||
}
|
||||
|
||||
Sapphire::Entity::EventObjectPtr Sapphire::PublicContent::getEObjByName( const std::string& name )
|
||||
{
|
||||
auto it = m_eventObjectMap.find( name );
|
||||
if( it == m_eventObjectMap.end() )
|
||||
return nullptr;
|
||||
|
||||
return it->second;
|
||||
}
|
||||
|
||||
void Sapphire::PublicContent::clearDirector( Entity::Player& player )
|
||||
{
|
||||
sendDirectorClear( player );
|
||||
player.setDirectorInitialized( false );
|
||||
}
|
||||
|
||||
void Sapphire::PublicContent::onTalk( Sapphire::Entity::Player& player, uint32_t eventId, uint64_t actorId )
|
||||
{
|
||||
auto it = m_eventIdToObjectMap.find( eventId );
|
||||
if( it == m_eventIdToObjectMap.end() )
|
||||
return;
|
||||
|
||||
if( auto onTalk = it->second->getOnTalkHandler() )
|
||||
onTalk( player, it->second, getAsPublicContent(), eventId, actorId );
|
||||
else
|
||||
player.sendDebug( "No onTalk handler found for interactable eobj with EObjID#{0}, eventId#{1} ",
|
||||
it->second->getObjectId(), eventId );
|
||||
}
|
||||
|
||||
void Sapphire::PublicContent::setVar( uint8_t index, uint8_t value )
|
||||
{
|
||||
if( index > 19 )
|
||||
return;
|
||||
|
||||
switch( index )
|
||||
{
|
||||
case 0:
|
||||
setDirectorUI8AL( value );
|
||||
break;
|
||||
case 1:
|
||||
setDirectorUI8AH( value );
|
||||
break;
|
||||
case 2:
|
||||
setDirectorUI8BL( value );
|
||||
break;
|
||||
case 3:
|
||||
setDirectorUI8BH( value );
|
||||
break;
|
||||
case 4:
|
||||
setDirectorUI8CL( value );
|
||||
break;
|
||||
case 5:
|
||||
setDirectorUI8CH( value );
|
||||
break;
|
||||
case 6:
|
||||
setDirectorUI8DL( value );
|
||||
break;
|
||||
case 7:
|
||||
setDirectorUI8DH( value );
|
||||
break;
|
||||
case 8:
|
||||
setDirectorUI8EL( value );
|
||||
break;
|
||||
case 9:
|
||||
setDirectorUI8EH( value );
|
||||
break;
|
||||
case 10:
|
||||
setDirectorUI8FL( value );
|
||||
break;
|
||||
case 11:
|
||||
setDirectorUI8FH( value );
|
||||
break;
|
||||
case 12:
|
||||
setDirectorUI8GL( value );
|
||||
break;
|
||||
case 13:
|
||||
setDirectorUI8GH( value );
|
||||
break;
|
||||
case 14:
|
||||
setDirectorUI8HL( value );
|
||||
break;
|
||||
case 15:
|
||||
setDirectorUI8HH( value );
|
||||
break;
|
||||
case 16:
|
||||
setDirectorUI8IL( value );
|
||||
break;
|
||||
case 17:
|
||||
setDirectorUI8IH( value );
|
||||
break;
|
||||
case 18:
|
||||
setDirectorUI8JL( value );
|
||||
break;
|
||||
case 19:
|
||||
setDirectorUI8JH( value );
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
// todo: genericise this?
|
||||
for( const auto& playerIt : m_playerMap )
|
||||
{
|
||||
sendDirectorVars( *playerIt.second );
|
||||
}
|
||||
}
|
||||
|
||||
void Sapphire::PublicContent::setSequence( uint8_t value )
|
||||
{
|
||||
setDirectorSequence( value );
|
||||
|
||||
for( const auto& playerIt : m_playerMap )
|
||||
{
|
||||
sendDirectorVars( *playerIt.second );
|
||||
}
|
||||
}
|
||||
|
||||
void Sapphire::PublicContent::setBranch( uint8_t value )
|
||||
{
|
||||
setDirectorBranch( value );
|
||||
|
||||
for( const auto& playerIt : m_playerMap )
|
||||
{
|
||||
sendDirectorVars( *playerIt.second );
|
||||
}
|
||||
}
|
72
src/world/Territory/PublicContent.h
Normal file
72
src/world/Territory/PublicContent.h
Normal file
|
@ -0,0 +1,72 @@
|
|||
#ifndef SAPPHIRE_PUBLICCONTENT_H
|
||||
#define SAPPHIRE_PUBLICCONTENT_H
|
||||
|
||||
#include "Territory.h"
|
||||
#include "Event/Director.h"
|
||||
#include "Forwards.h"
|
||||
|
||||
namespace Sapphire::Data
|
||||
{
|
||||
struct PublicContent;
|
||||
}
|
||||
|
||||
namespace Sapphire
|
||||
{
|
||||
class PublicContent : public Event::Director, public Territory
|
||||
{
|
||||
public:
|
||||
PublicContent( std::shared_ptr< Sapphire::Data::PublicContent > pConfiguration,
|
||||
uint16_t territoryType,
|
||||
uint32_t guId,
|
||||
const std::string& internalName,
|
||||
const std::string& contentName,
|
||||
uint32_t contentId, uint16_t contentFinderConditionId = 0 );
|
||||
|
||||
virtual ~PublicContent();
|
||||
|
||||
bool init() override;
|
||||
|
||||
void onBeforePlayerZoneIn( Entity::Player& player ) override;
|
||||
|
||||
void onPlayerZoneIn( Entity::Player& player ) override;
|
||||
|
||||
void onLeaveTerritory( Entity::Player& player ) override;
|
||||
|
||||
void onUpdate( uint64_t tickCount ) override;
|
||||
|
||||
void onFinishLoading( Entity::Player& player ) override;
|
||||
|
||||
void onInitDirector( Entity::Player& player ) override;
|
||||
|
||||
void onDirectorSync( Entity::Player& player ) override;
|
||||
|
||||
void onEnterTerritory( Entity::Player& player, uint32_t eventId, uint16_t param1, uint16_t param2 ) override;
|
||||
|
||||
void onRegisterEObj( Entity::EventObjectPtr object ) override;
|
||||
|
||||
std::shared_ptr< Sapphire::Data::PublicContent > getConfiguration() const;
|
||||
|
||||
uint32_t getContentId() const;
|
||||
|
||||
Entity::EventObjectPtr getEObjByName( const std::string& name );
|
||||
|
||||
void clearDirector( Entity::Player& player );
|
||||
|
||||
void onTalk( Entity::Player& player, uint32_t eventId, uint64_t actorId );
|
||||
|
||||
void setSequence( uint8_t value );
|
||||
|
||||
void setBranch( uint8_t value );
|
||||
|
||||
void setVar( uint8_t index, uint8_t value );
|
||||
|
||||
private:
|
||||
std::shared_ptr< Sapphire::Data::PublicContent > m_Configuration;
|
||||
uint32_t m_ContentId;
|
||||
Entity::EventObjectPtr m_pEntranceEObj;
|
||||
std::map< std::string, Entity::EventObjectPtr > m_eventObjectMap;
|
||||
std::unordered_map< uint32_t, Entity::EventObjectPtr > m_eventIdToObjectMap;
|
||||
};
|
||||
|
||||
}
|
||||
#endif //SAPPHIRE_PUBLICCONTENT_H
|
|
@ -34,9 +34,9 @@ Sapphire::QuestBattle::QuestBattle( std::shared_ptr< Sapphire::Data::QuestBattle
|
|||
uint32_t guId,
|
||||
const std::string& internalName,
|
||||
const std::string& contentName,
|
||||
uint32_t questBattleId ) :
|
||||
uint32_t questBattleId, uint16_t contentFinderConditionId ) :
|
||||
Territory( static_cast< uint16_t >( territoryType ), guId, internalName, contentName ),
|
||||
Director( Event::Director::QuestBattle, questBattleId ),
|
||||
Director( Event::Director::QuestBattle, questBattleId, contentFinderConditionId ),
|
||||
m_pBattleDetails( pBattleDetails ),
|
||||
m_questBattleId( questBattleId ),
|
||||
m_state( Created ),
|
||||
|
@ -330,7 +330,7 @@ void Sapphire::QuestBattle::onTalk( Sapphire::Entity::Player& player, uint32_t e
|
|||
return;
|
||||
|
||||
if( auto onTalkHandler = it->second->getOnTalkHandler() )
|
||||
onTalkHandler( player, it->second, getAsQuestBattle(), actorId );
|
||||
onTalkHandler( player, it->second, getAsQuestBattle(), eventId, actorId );
|
||||
else
|
||||
player.sendDebug( "No onTalk handler found for interactable eobj with EObjID#{0}, eventId#{1} ",
|
||||
it->second->getObjectId(), eventId );
|
||||
|
|
|
@ -20,7 +20,7 @@ namespace Sapphire
|
|||
uint32_t guId,
|
||||
const std::string& internalName,
|
||||
const std::string& contentName,
|
||||
uint32_t questBattleId );
|
||||
uint32_t questBattleId, uint16_t contentFinderConditionId = 0 );
|
||||
|
||||
virtual ~QuestBattle() = default;
|
||||
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
#include "Territory.h"
|
||||
#include "InstanceContent.h"
|
||||
#include "QuestBattle.h"
|
||||
#include "PublicContent.h"
|
||||
#include "Manager/TerritoryMgr.h"
|
||||
#include "Navi/NaviProvider.h"
|
||||
|
||||
|
@ -780,6 +781,11 @@ Sapphire::Entity::EventObjectPtr Sapphire::Territory::getEObj( uint32_t objId )
|
|||
return obj->second;
|
||||
}
|
||||
|
||||
Sapphire::Event::DirectorPtr Sapphire::Territory::getAsDirector()
|
||||
{
|
||||
return std::dynamic_pointer_cast< Event::Director, Territory >( shared_from_this() );
|
||||
}
|
||||
|
||||
Sapphire::InstanceContentPtr Sapphire::Territory::getAsInstanceContent()
|
||||
{
|
||||
return std::dynamic_pointer_cast< InstanceContent, Territory >( shared_from_this() );
|
||||
|
@ -790,6 +796,11 @@ Sapphire::QuestBattlePtr Sapphire::Territory::getAsQuestBattle()
|
|||
return std::dynamic_pointer_cast< QuestBattle, Territory >( shared_from_this() );
|
||||
}
|
||||
|
||||
Sapphire::PublicContentPtr Sapphire::Territory::getAsPublicContent()
|
||||
{
|
||||
return std::dynamic_pointer_cast< PublicContent, Territory >( shared_from_this() );
|
||||
}
|
||||
|
||||
uint32_t Sapphire::Territory::getNextEObjId()
|
||||
{
|
||||
return ++m_nextEObjId;
|
||||
|
@ -1044,3 +1055,18 @@ void Sapphire::Territory::processEffectResults( uint64_t tickCount )
|
|||
it = m_effectResults.erase( it );
|
||||
}
|
||||
}
|
||||
|
||||
Sapphire::Entity::PlayerPtr Sapphire::Territory::getPlayer( uint32_t charId )
|
||||
{
|
||||
return m_playerMap[ charId ];
|
||||
}
|
||||
|
||||
void Sapphire::Territory::foreachPlayer( std::function< void( Sapphire::Entity::PlayerPtr player ) > callback )
|
||||
{
|
||||
if( !callback )
|
||||
return;
|
||||
for( auto entry : m_playerMap )
|
||||
{
|
||||
callback( entry.second );
|
||||
}
|
||||
}
|
|
@ -166,10 +166,14 @@ namespace Sapphire
|
|||
|
||||
Entity::EventObjectPtr getEObj( uint32_t objId );
|
||||
|
||||
Event::DirectorPtr getAsDirector();
|
||||
|
||||
InstanceContentPtr getAsInstanceContent();
|
||||
|
||||
QuestBattlePtr getAsQuestBattle();
|
||||
|
||||
PublicContentPtr getAsPublicContent();
|
||||
|
||||
void updateSpawnPoints();
|
||||
|
||||
uint32_t getNextEffectSequence();
|
||||
|
@ -179,6 +183,10 @@ namespace Sapphire
|
|||
void addEffectResult( World::Action::EffectResultPtr result );
|
||||
|
||||
void processEffectResults( uint64_t tickCount );
|
||||
|
||||
Entity::PlayerPtr getPlayer( uint32_t charId );
|
||||
|
||||
void foreachPlayer( std::function< void( Entity::PlayerPtr player ) > callback );
|
||||
};
|
||||
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue