1
Fork 0
mirror of https://github.com/SapphireServer/Sapphire.git synced 2025-05-25 19:17:45 +00:00

core update needed for "the_movie"

This commit is contained in:
collett 2020-06-22 17:44:39 +09:00
parent f427e21942
commit 87b49a137c
10 changed files with 188 additions and 80 deletions

View file

@ -360,6 +360,7 @@ namespace Sapphire::Network::Packets
ReturnEventHandler = 0x00BB, // updated 5.25 ReturnEventHandler = 0x00BB, // updated 5.25
TradeReturnEventHandler = 0x03B6, // updated 5.25 TradeReturnEventHandler = 0x03B6, // updated 5.25
TradeMultipleReturnEventHander = 0x02B0, // updated 5.25
LinkshellEventHandler = 0x016B, // updated 4.5 LinkshellEventHandler = 0x016B, // updated 4.5
LinkshellEventHandler1 = 0x016C, // updated 4.5 LinkshellEventHandler1 = 0x016C, // updated 4.5

View file

@ -142,7 +142,8 @@ class ManFst005 : public Sapphire::ScriptAPI::EventScript
{ {
if( result.param2 == 1 ) if( result.param2 == 1 )
{ {
auto& pTeriMgr = Common::Service< Sapphire::World::Manager::TerritoryMgr >::ref(); //auto& pTeriMgr = Common::Service< Sapphire::World::Manager::TerritoryMgr >::ref();
auto& pTeriMgr = *reinterpret_cast< Sapphire::World::Manager::TerritoryMgr* >( player.getTerritoryMgr() );
player.eventFinish( result.eventId, 0 ); player.eventFinish( result.eventId, 0 );
pTeriMgr.createAndJoinQuestBattle( player, Questbattle0 ); pTeriMgr.createAndJoinQuestBattle( player, Questbattle0 );

View file

@ -19,6 +19,8 @@
#include "Manager/HousingMgr.h" #include "Manager/HousingMgr.h"
#include "Manager/TerritoryMgr.h" #include "Manager/TerritoryMgr.h"
#include "Manager/RNGMgr.h" #include "Manager/RNGMgr.h"
#include <Manager/PlayerMgr.h>
#include "Manager/EventMgr.h"
#include "Territory/Territory.h" #include "Territory/Territory.h"
#include "Territory/ZonePosition.h" #include "Territory/ZonePosition.h"
@ -2525,7 +2527,69 @@ bool Sapphire::Entity::Player::gaugeSamHasAnySen()
return static_cast< uint8_t >( m_gauge.sam.sen ) > 0; return static_cast< uint8_t >( m_gauge.sam.sen ) > 0;
} }
void* Sapphire::Entity::Player::getEventMgr()
{
return &Common::Service< Sapphire::World::Manager::EventMgr >::ref();
}
void* Sapphire::Entity::Player::getExdData() void* Sapphire::Entity::Player::getExdData()
{ {
return &Common::Service< Data::ExdDataGenerated >::ref(); return &Common::Service< Data::ExdDataGenerated >::ref();
} }
void* Sapphire::Entity::Player::getPlayerMgr()
{
return &Common::Service< Sapphire::World::Manager::PlayerMgr >::ref();
}
void* Sapphire::Entity::Player::getInstanceObjectCache()
{
return &Common::Service< Sapphire::InstanceObjectCache >::ref();
}
void* Sapphire::Entity::Player::getTerritoryMgr()
{
return &Common::Service< Sapphire::World::Manager::TerritoryMgr >::ref();
}
Sapphire::TerritoryPtr Sapphire::Entity::Player::getOrCreatePrivateInstance( uint32_t zoneId )
{
auto instance = m_privateInstanceMap[ zoneId ];
if( instance )
return instance;
auto& terriMgr = Common::Service< Sapphire::World::Manager::TerritoryMgr >::ref();
instance = terriMgr.createTerritoryInstance( zoneId );
if( instance )
{
sendDebug( "Created instance with id: " + std::to_string( instance->getGuId() ) + " -> " + instance->getName() );
m_privateInstanceMap[ zoneId ] = instance;
return instance;
}
else
{
sendDebug( "Failed to create instance with id#{0}", zoneId );
return nullptr;
}
}
bool Sapphire::Entity::Player::enterPredefinedPrivateInstance( uint32_t zoneId )
{
auto it = Sapphire::World::Manager::TerritoryMgr::instanceSpawnInfo.find( zoneId );
if( it != Sapphire::World::Manager::TerritoryMgr::instanceSpawnInfo.end() )
{
auto info = it->second;
auto instance = getOrCreatePrivateInstance( zoneId );
if( instance )
{
auto result = setInstance( instance, info.pos );
if( result )
setRot( info.rot );
return result;
}
}
sendUrgent( "instance id: {} is not defined.", zoneId );
auto instance = getOrCreatePrivateInstance( zoneId );
if( instance )
return setInstance( instance );
}

View file

@ -1024,7 +1024,15 @@ namespace Sapphire::Entity
////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////
std::unordered_map< uint32_t, TerritoryPtr > m_privateInstanceMap;
TerritoryPtr getOrCreatePrivateInstance( uint32_t zoneId );
bool enterPredefinedPrivateInstance( uint32_t zoneId );
void* getEventMgr();
void* getExdData(); void* getExdData();
void* getPlayerMgr();
void* getInstanceObjectCache();
void* getTerritoryMgr();
Common::HuntingLogEntry& getHuntingLogEntry( uint8_t index ); Common::HuntingLogEntry& getHuntingLogEntry( uint8_t index );

View file

@ -64,63 +64,6 @@ bool Sapphire::Entity::Player::load( uint32_t charId, World::SessionPtr pSession
m_prevPos.z = res->getFloat( "OPosZ" ); m_prevPos.z = res->getFloat( "OPosZ" );
m_prevRot = res->getFloat( "OPosR" ); m_prevRot = res->getFloat( "OPosR" );
TerritoryPtr pCurrZone = nullptr;
// if the zone is an instanceContent zone, we need to actually find the instance
if( teriMgr.isInstanceContentTerritory( zoneId ) )
{
// try to find an instance actually linked to this player
pCurrZone = teriMgr.getLinkedInstance( m_id );
// if none found, revert to previous zone and position
if( !pCurrZone )
{
zoneId = m_prevTerritoryTypeId;
m_pos.x = m_prevPos.x;
m_pos.y = m_prevPos.y;
m_pos.z = m_prevPos.z;
setRot( m_prevRot );
pCurrZone = teriMgr.getZoneByTerritoryTypeId( zoneId );
}
}
else if( teriMgr.isInternalEstateTerritory( zoneId ) )
{
// todo: this needs to go to the area just outside of the plot door
pCurrZone = teriMgr.getZoneByLandSetId( m_prevTerritoryId );
zoneId = m_prevTerritoryTypeId;
m_pos.x = m_prevPos.x;
m_pos.y = m_prevPos.y;
m_pos.z = m_prevPos.z;
setRot( m_prevRot );
}
else if( teriMgr.isHousingTerritory( zoneId ) )
{
pCurrZone = teriMgr.getZoneByLandSetId( m_territoryId );
}
else
{
pCurrZone = teriMgr.getZoneByTerritoryTypeId( zoneId );
}
m_territoryTypeId = zoneId;
// TODO: logic for instances needs to be added here
// see if a valid zone could be found for the character
if( !pCurrZone )
{
Logger::error( "[{0}] Territory #{1} not found!", char_id_str, zoneId );
Logger::error( "[{0}] Setting default zone instead", char_id_str );
// default to new gridania
// TODO: should probably just abort and mark character as corrupt
pCurrZone = teriMgr.getZoneByTerritoryTypeId( 132 );
m_pos.x = 0.0f;
m_pos.y = 0.0f;
m_pos.z = 0.0f;
setRot( 0.0f );
}
// Model // Model
auto custom = res->getBlobVector( "Customize" ); auto custom = res->getBlobVector( "Customize" );
memcpy( reinterpret_cast< char* >( m_customize ), custom.data(), custom.size() ); memcpy( reinterpret_cast< char* >( m_customize ), custom.data(), custom.size() );
@ -197,6 +140,72 @@ bool Sapphire::Entity::Player::load( uint32_t charId, World::SessionPtr pSession
res->free(); res->free();
TerritoryPtr pCurrZone = nullptr;
// if the zone is an instanceContent zone, we need to actually find the instance
if( teriMgr.isInstanceContentTerritory( zoneId ) )
{
// try to find an instance actually linked to this player
pCurrZone = teriMgr.getLinkedInstance( m_id );
// if none found, revert to previous zone and position
if( !pCurrZone )
{
zoneId = m_prevTerritoryTypeId;
m_pos.x = m_prevPos.x;
m_pos.y = m_prevPos.y;
m_pos.z = m_prevPos.z;
setRot( m_prevRot );
pCurrZone = teriMgr.getZoneByTerritoryTypeId( zoneId );
}
}
else if( teriMgr.isInternalEstateTerritory( zoneId ) )
{
// todo: this needs to go to the area just outside of the plot door
pCurrZone = teriMgr.getZoneByLandSetId( m_prevTerritoryId );
zoneId = m_prevTerritoryTypeId;
m_pos.x = m_prevPos.x;
m_pos.y = m_prevPos.y;
m_pos.z = m_prevPos.z;
setRot( m_prevRot );
}
else if( teriMgr.isHousingTerritory( zoneId ) )
{
pCurrZone = teriMgr.getZoneByLandSetId( m_territoryId );
}
else
{
pCurrZone = teriMgr.getZoneByTerritoryTypeId( zoneId );
}
m_territoryTypeId = zoneId;
// TODO: logic for instances needs to be added here
if( !pCurrZone )
{
auto it = Sapphire::World::Manager::TerritoryMgr::instanceSpawnInfo.find( zoneId );
if( it != Sapphire::World::Manager::TerritoryMgr::instanceSpawnInfo.end() )
{
auto info = it->second;
pCurrZone = getOrCreatePrivateInstance( zoneId );
}
}
// see if a valid zone could be found for the character
if( !pCurrZone )
{
Logger::error( "[{0}] Territory #{1} not found!", char_id_str, zoneId );
Logger::error( "[{0}] Setting default zone instead", char_id_str );
// default to new gridania
// TODO: should probably just abort and mark character as corrupt
pCurrZone = teriMgr.getZoneByTerritoryTypeId( 132 );
m_pos.x = 0.0f;
m_pos.y = 0.0f;
m_pos.z = 0.0f;
setRot( 0.0f );
}
m_pCell = nullptr; m_pCell = nullptr;
if( !loadActiveQuests() || !loadClassData() || !loadSearchInfo() || !loadHuntingLog() ) if( !loadActiveQuests() || !loadClassData() || !loadSearchInfo() || !loadHuntingLog() )

View file

@ -1022,6 +1022,15 @@ void Sapphire::World::Manager::DebugCommandMgr::instance( char* data, Entity::Pl
if( auto instance = player.getCurrentInstance() ) if( auto instance = player.getCurrentInstance() )
instance->setCurrentBGM( bgmId ); instance->setCurrentBGM( bgmId );
} }
else if( subCommand == "private" )
{
uint32_t zoneId = 0;
sscanf( params.c_str(), "%d", &zoneId );
if( zoneId > 0 )
{
player.enterPredefinedPrivateInstance( zoneId );
}
}
else else
{ {
player.sendDebug( "Unknown sub command." ); player.sendDebug( "Unknown sub command." );

View file

@ -687,3 +687,12 @@ void Sapphire::World::Manager::TerritoryMgr::createAndJoinQuestBattle( Entity::P
} }
std::unordered_map< uint32_t, Sapphire::World::Manager::TerritoryMgr::InstanceSpawnInfo > Sapphire::World::Manager::TerritoryMgr::instanceSpawnInfo =
{
{ 210, { { 0, -0.2f, 8 }, -3.1415 } },
};
std::unordered_map< uint32_t, uint32_t > Sapphire::World::Manager::TerritoryMgr::instanceExitEvent =
{
{ 131085, 210 },
};

View file

@ -222,6 +222,14 @@ namespace Sapphire::World::Manager
/*! returns a list of instanceContent InstanceIds currently active */ /*! returns a list of instanceContent InstanceIds currently active */
InstanceIdList getInstanceContentIdList( uint16_t instanceContentId ) const; InstanceIdList getInstanceContentIdList( uint16_t instanceContentId ) const;
struct InstanceSpawnInfo
{
Common::FFXIVARR_POSITION3 pos;
float rot;
};
static std::unordered_map< uint32_t, InstanceSpawnInfo > instanceSpawnInfo;
static std::unordered_map< uint32_t, uint32_t > instanceExitEvent;
}; };
} }

View file

@ -103,6 +103,7 @@ Sapphire::Network::GameConnection::GameConnection( Sapphire::Network::HivePtr pH
setZoneHandler( ClientZoneIpcType::ReturnEventHandler, "EventHandlerReturn", &GameConnection::eventHandlerReturn ); setZoneHandler( ClientZoneIpcType::ReturnEventHandler, "EventHandlerReturn", &GameConnection::eventHandlerReturn );
setZoneHandler( ClientZoneIpcType::TradeReturnEventHandler, "EventHandlerReturn", setZoneHandler( ClientZoneIpcType::TradeReturnEventHandler, "EventHandlerReturn",
&GameConnection::eventHandlerReturn ); &GameConnection::eventHandlerReturn );
setZoneHandler( ClientZoneIpcType::TradeMultipleReturnEventHander, "EventHandlerReturn", &GameConnection::eventHandlerReturn );
setZoneHandler( ClientZoneIpcType::ShopEventHandler, "ShopEventHandler", setZoneHandler( ClientZoneIpcType::ShopEventHandler, "ShopEventHandler",
&GameConnection::eventHandlerShop ); &GameConnection::eventHandlerShop );

View file

@ -20,6 +20,7 @@
#include "Event/EventHandler.h" #include "Event/EventHandler.h"
#include "Manager/EventMgr.h" #include "Manager/EventMgr.h"
#include "Manager/TerritoryMgr.h"
#include "Territory/InstanceContent.h" #include "Territory/InstanceContent.h"
#include "Territory/QuestBattle.h" #include "Territory/QuestBattle.h"
@ -59,29 +60,26 @@ void Sapphire::Network::GameConnection::eventHandlerTalk( const Packets::FFXIVAR
{ {
instance->onTalk( player, eventId, actorId ); instance->onTalk( player, eventId, actorId );
} }
else if( !scriptMgr.onTalk( player, actorId, eventId ) &&
bool eventCalled = false;
if( eventType == Event::EventHandler::EventHandlerType::Warp )
{
auto it = Sapphire::World::Manager::TerritoryMgr::instanceExitEvent.find( eventId );
if( it != Sapphire::World::Manager::TerritoryMgr::instanceExitEvent.end() )
{
player.eventFinish( eventId, 1 );
player.exitInstance();
eventCalled = true;
}
}
if( !eventCalled )
{
if( !scriptMgr.onTalk( player, actorId, eventId ) &&
eventType == Event::EventHandler::EventHandlerType::Quest ) eventType == Event::EventHandler::EventHandlerType::Quest )
{ {
auto questInfo = exdData.get< Sapphire::Data::Quest >( eventId ); auto questInfo = exdData.get< Sapphire::Data::Quest >( eventId );
if( questInfo ) if( questInfo )
{
player.sendUrgent( "Quest not implemented: {0} ({1})", questInfo->name, questInfo->id ); player.sendUrgent( "Quest not implemented: {0} ({1})", questInfo->name, questInfo->id );
if( player.hasQuest( eventId ) )
{
player.giveQuestRewards( eventId, 0 );
player.finishQuest( eventId );
}
else
{
player.playScene( eventId, 0, 0,
[ eventId ]( Entity::Player& player, const Event::SceneResult& result )
{
if( result.param2 == 1 )
{
player.updateQuest( eventId, 255 );
}
});
}
} }
} }