2018-03-06 22:22:19 +01:00
|
|
|
#include <Logging/Logger.h>
|
|
|
|
#include <Database/DatabaseDef.h>
|
|
|
|
#include <Exd/ExdDataGenerated.h>
|
2018-01-27 23:52:49 +01:00
|
|
|
|
2019-01-28 20:48:33 +11:00
|
|
|
#include "ServerMgr.h"
|
|
|
|
|
2018-02-28 10:26:03 +01:00
|
|
|
#include <unordered_map>
|
|
|
|
|
2018-01-28 22:36:43 +01:00
|
|
|
#include "Actor/Player.h"
|
|
|
|
|
2019-07-21 22:33:33 +10:00
|
|
|
#include "Territory/Territory.h"
|
2018-12-01 00:27:16 +11:00
|
|
|
#include "Territory/ZonePosition.h"
|
|
|
|
#include "Territory/InstanceContent.h"
|
2019-03-31 23:45:03 +02:00
|
|
|
#include "Territory/QuestBattle.h"
|
2018-03-02 07:22:25 -03:00
|
|
|
#include "TerritoryMgr.h"
|
2018-12-01 18:18:29 +11:00
|
|
|
#include "HousingMgr.h"
|
2018-03-02 07:22:25 -03:00
|
|
|
#include "Framework.h"
|
2018-01-27 23:52:49 +01:00
|
|
|
|
2018-12-01 18:18:29 +11:00
|
|
|
#include "Territory/Land.h"
|
|
|
|
#include "Territory/House.h"
|
|
|
|
#include "Territory/Housing/HousingInteriorTerritory.h"
|
2019-01-23 19:23:49 +01:00
|
|
|
#include "NaviMgr.h"
|
2018-12-01 18:18:29 +11:00
|
|
|
|
2018-12-22 22:25:03 +01:00
|
|
|
Sapphire::World::Manager::TerritoryMgr::TerritoryMgr( Sapphire::FrameworkPtr pFw ) :
|
|
|
|
BaseManager( pFw ),
|
2018-08-29 21:40:59 +02:00
|
|
|
m_lastInstanceId( 10000 )
|
2018-01-27 23:52:49 +01:00
|
|
|
{
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2018-12-01 00:27:16 +11:00
|
|
|
void Sapphire::World::Manager::TerritoryMgr::loadTerritoryTypeDetailCache()
|
2018-01-27 23:52:49 +01:00
|
|
|
{
|
2018-12-22 22:25:03 +01:00
|
|
|
auto pExdData = framework()->get< Data::ExdDataGenerated >();
|
2018-08-29 21:40:59 +02:00
|
|
|
auto idList = pExdData->getTerritoryTypeIdList();
|
2018-01-27 23:52:49 +01:00
|
|
|
|
2018-08-29 21:40:59 +02:00
|
|
|
for( auto id : idList )
|
|
|
|
{
|
2018-11-29 16:55:48 +01:00
|
|
|
auto teri1 = pExdData->get< Sapphire::Data::TerritoryType >( id );
|
2018-01-27 23:52:49 +01:00
|
|
|
|
2018-08-29 21:40:59 +02:00
|
|
|
if( !teri1->name.empty() )
|
|
|
|
m_territoryTypeDetailCacheMap[ id ] = teri1;
|
|
|
|
}
|
2019-04-11 00:16:04 +02:00
|
|
|
|
|
|
|
for( auto id : pExdData->getContentFinderConditionIdList() )
|
|
|
|
{
|
|
|
|
auto cfc = pExdData->get< Sapphire::Data::ContentFinderCondition >( id );
|
|
|
|
if( !cfc || cfc->contentLinkType != 5 )
|
|
|
|
continue;
|
|
|
|
|
|
|
|
m_questBattleToContentFinderMap[ cfc->content ] = id;
|
|
|
|
}
|
2018-01-27 23:52:49 +01:00
|
|
|
}
|
|
|
|
|
2018-12-01 00:27:16 +11:00
|
|
|
bool Sapphire::World::Manager::TerritoryMgr::isValidTerritory( uint32_t territoryTypeId ) const
|
2018-01-27 23:52:49 +01:00
|
|
|
{
|
2018-08-29 21:40:59 +02:00
|
|
|
return !( m_territoryTypeDetailCacheMap.find( territoryTypeId ) == m_territoryTypeDetailCacheMap.end() );
|
2018-01-27 23:52:49 +01:00
|
|
|
}
|
|
|
|
|
2018-12-01 00:27:16 +11:00
|
|
|
bool Sapphire::World::Manager::TerritoryMgr::init()
|
2018-01-27 23:52:49 +01:00
|
|
|
{
|
2018-12-16 14:26:38 +01:00
|
|
|
try
|
|
|
|
{
|
|
|
|
loadTerritoryTypeDetailCache();
|
|
|
|
loadTerritoryPositionMap();
|
2018-01-27 23:52:49 +01:00
|
|
|
|
2018-12-16 14:26:38 +01:00
|
|
|
createDefaultTerritories();
|
|
|
|
createHousingTerritories();
|
|
|
|
}
|
2019-04-29 19:59:19 +10:00
|
|
|
catch( const std::runtime_error& ex )
|
2018-12-16 14:26:38 +01:00
|
|
|
{
|
2019-04-29 19:59:19 +10:00
|
|
|
Logger::fatal( "Caught exception during territory init: {}", ex.what() );
|
2018-12-16 14:26:38 +01:00
|
|
|
return false;
|
|
|
|
}
|
2018-01-27 23:52:49 +01:00
|
|
|
|
2019-01-28 20:48:33 +11:00
|
|
|
auto& cfg = framework()->get< World::ServerMgr >()->getConfig();
|
|
|
|
|
|
|
|
m_inRangeDistance = cfg.network.inRangeDistance;
|
|
|
|
|
2018-08-29 21:40:59 +02:00
|
|
|
return true;
|
2018-01-27 23:52:49 +01:00
|
|
|
}
|
|
|
|
|
2018-12-01 00:27:16 +11:00
|
|
|
uint32_t Sapphire::World::Manager::TerritoryMgr::getNextInstanceId()
|
2018-01-27 23:52:49 +01:00
|
|
|
{
|
2018-08-29 21:40:59 +02:00
|
|
|
return ++m_lastInstanceId;
|
2018-01-27 23:52:49 +01:00
|
|
|
}
|
|
|
|
|
2018-12-01 00:27:16 +11:00
|
|
|
Sapphire::Data::TerritoryTypePtr Sapphire::World::Manager::TerritoryMgr::getTerritoryDetail( uint32_t territoryTypeId ) const
|
2018-01-27 23:52:49 +01:00
|
|
|
{
|
2018-08-29 21:40:59 +02:00
|
|
|
auto tIt = m_territoryTypeDetailCacheMap.find( territoryTypeId );
|
|
|
|
if( tIt == m_territoryTypeDetailCacheMap.end() )
|
|
|
|
return nullptr;
|
2018-01-27 23:52:49 +01:00
|
|
|
|
2018-08-29 21:40:59 +02:00
|
|
|
return tIt->second;
|
2018-01-27 23:52:49 +01:00
|
|
|
}
|
|
|
|
|
2018-12-01 00:27:16 +11:00
|
|
|
bool Sapphire::World::Manager::TerritoryMgr::isInstanceContentTerritory( uint32_t territoryTypeId ) const
|
2018-01-27 23:52:49 +01:00
|
|
|
{
|
2018-08-29 21:40:59 +02:00
|
|
|
auto pTeri = getTerritoryDetail( territoryTypeId );
|
|
|
|
|
|
|
|
if( !pTeri )
|
|
|
|
return false;
|
|
|
|
|
|
|
|
auto intendedUse = pTeri->territoryIntendedUse;
|
|
|
|
|
|
|
|
return intendedUse == TerritoryIntendedUse::AllianceRaid ||
|
|
|
|
intendedUse == TerritoryIntendedUse::BeforeTrialDung ||
|
|
|
|
intendedUse == TerritoryIntendedUse::Trial ||
|
|
|
|
intendedUse == TerritoryIntendedUse::Dungeon ||
|
|
|
|
intendedUse == TerritoryIntendedUse::OpenWorldInstanceBattle ||
|
|
|
|
intendedUse == TerritoryIntendedUse::PalaceOfTheDead ||
|
|
|
|
intendedUse == TerritoryIntendedUse::RaidFights ||
|
|
|
|
intendedUse == TerritoryIntendedUse::Raids ||
|
|
|
|
intendedUse == TerritoryIntendedUse::TreasureMapInstance ||
|
|
|
|
intendedUse == TerritoryIntendedUse::EventTrial;
|
2018-01-27 23:52:49 +01:00
|
|
|
}
|
|
|
|
|
2018-12-01 00:27:16 +11:00
|
|
|
bool Sapphire::World::Manager::TerritoryMgr::isPrivateTerritory( uint32_t territoryTypeId ) const
|
2018-01-27 23:52:49 +01:00
|
|
|
{
|
2018-08-29 21:40:59 +02:00
|
|
|
auto pTeri = getTerritoryDetail( territoryTypeId );
|
2018-01-27 23:52:49 +01:00
|
|
|
|
2018-08-29 21:40:59 +02:00
|
|
|
if( !pTeri )
|
|
|
|
return false;
|
2018-01-27 23:52:49 +01:00
|
|
|
|
2018-08-29 21:40:59 +02:00
|
|
|
return pTeri->territoryIntendedUse == TerritoryIntendedUse::OpeningArea ||
|
|
|
|
pTeri->territoryIntendedUse == TerritoryIntendedUse::Inn ||
|
|
|
|
pTeri->territoryIntendedUse == TerritoryIntendedUse::JailArea ||
|
|
|
|
pTeri->territoryIntendedUse == TerritoryIntendedUse::MSQPrivateArea;
|
2018-01-27 23:52:49 +01:00
|
|
|
}
|
|
|
|
|
2018-12-28 19:45:04 +11:00
|
|
|
bool Sapphire::World::Manager::TerritoryMgr::isInternalEstateTerritory( uint32_t territoryTypeId ) const
|
|
|
|
{
|
|
|
|
auto pTeri = getTerritoryDetail( territoryTypeId );
|
|
|
|
|
|
|
|
if( !pTeri )
|
|
|
|
return false;
|
|
|
|
|
|
|
|
return pTeri->territoryIntendedUse == TerritoryIntendedUse::HousingPrivateArea;
|
|
|
|
}
|
|
|
|
|
2018-12-01 00:27:16 +11:00
|
|
|
bool Sapphire::World::Manager::TerritoryMgr::isDefaultTerritory( uint32_t territoryTypeId ) const
|
2018-11-06 11:11:07 +01:00
|
|
|
{
|
|
|
|
auto pTeri = getTerritoryDetail( territoryTypeId );
|
|
|
|
|
|
|
|
if( !pTeri )
|
|
|
|
return false;
|
|
|
|
|
|
|
|
return pTeri->territoryIntendedUse == TerritoryIntendedUse::Inn ||
|
|
|
|
pTeri->territoryIntendedUse == TerritoryIntendedUse::Town ||
|
|
|
|
pTeri->territoryIntendedUse == TerritoryIntendedUse::OpenWorld ||
|
|
|
|
pTeri->territoryIntendedUse == TerritoryIntendedUse::OpeningArea;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2018-12-01 00:27:16 +11:00
|
|
|
bool Sapphire::World::Manager::TerritoryMgr::isHousingTerritory( uint32_t territoryTypeId ) const
|
2018-11-06 11:11:07 +01:00
|
|
|
{
|
|
|
|
auto pTeri = getTerritoryDetail( territoryTypeId );
|
|
|
|
|
|
|
|
if( !pTeri )
|
|
|
|
return false;
|
|
|
|
|
|
|
|
return pTeri->territoryIntendedUse == TerritoryIntendedUse::HousingArea;
|
|
|
|
}
|
2018-01-27 23:52:49 +01:00
|
|
|
|
2018-12-01 00:27:16 +11:00
|
|
|
bool Sapphire::World::Manager::TerritoryMgr::createDefaultTerritories()
|
2018-01-27 23:52:49 +01:00
|
|
|
{
|
2018-12-22 22:25:03 +01:00
|
|
|
auto pExdData = framework()->get< Data::ExdDataGenerated >();
|
2018-08-29 21:40:59 +02:00
|
|
|
// for each entry in territoryTypeExd, check if it is a normal and if so, add the zone object
|
|
|
|
for( const auto& territory : m_territoryTypeDetailCacheMap )
|
|
|
|
{
|
2018-11-05 23:07:39 +01:00
|
|
|
auto territoryTypeId = territory.first;
|
2018-08-29 21:40:59 +02:00
|
|
|
auto territoryInfo = territory.second;
|
|
|
|
|
|
|
|
// if the zone has no name set
|
|
|
|
if( territoryInfo->name.empty() )
|
|
|
|
continue;
|
|
|
|
|
2018-11-29 16:55:48 +01:00
|
|
|
auto pPlaceName = pExdData->get< Sapphire::Data::PlaceName >( territoryInfo->placeName );
|
2018-08-29 21:40:59 +02:00
|
|
|
|
2018-11-05 23:07:39 +01:00
|
|
|
if( !pPlaceName || pPlaceName->name.empty() || !isDefaultTerritory( territoryTypeId ) )
|
2018-08-29 21:40:59 +02:00
|
|
|
continue;
|
|
|
|
|
|
|
|
uint32_t guid = getNextInstanceId();
|
2019-01-04 22:37:01 +11:00
|
|
|
|
2019-07-21 22:33:33 +10:00
|
|
|
auto pZone = make_Territory( territoryTypeId, guid, territoryInfo->name, pPlaceName->name, framework() );
|
2019-04-19 00:39:42 +02:00
|
|
|
pZone->init();
|
|
|
|
|
2019-01-25 08:31:20 +01:00
|
|
|
std::string bgPath = territoryInfo->bg;
|
2019-04-19 00:39:42 +02:00
|
|
|
|
|
|
|
bool hasNaviMesh = pZone->getNaviProvider() != nullptr;
|
2019-01-20 16:10:48 +01:00
|
|
|
|
2019-01-25 12:34:21 +11:00
|
|
|
Logger::info( "{0}\t{1}\t{2}\t{3:<10}\t{4}\t{5}\t{6}",
|
2019-01-04 22:59:09 +11:00
|
|
|
territoryTypeId,
|
|
|
|
guid,
|
|
|
|
territoryInfo->territoryIntendedUse,
|
|
|
|
territoryInfo->name,
|
|
|
|
( isPrivateTerritory( territoryTypeId ) ? "PRIVATE" : "PUBLIC" ),
|
2019-01-25 12:23:38 +11:00
|
|
|
hasNaviMesh ? "NAVI" : "",
|
|
|
|
pPlaceName->name );
|
2019-01-23 19:23:49 +01:00
|
|
|
|
2019-07-21 22:33:33 +10:00
|
|
|
InstanceIdToTerritoryPtrMap instanceMap;
|
2018-08-29 21:40:59 +02:00
|
|
|
instanceMap[ guid ] = pZone;
|
2019-07-21 22:33:33 +10:00
|
|
|
m_guIdToTerritoryPtrMap[ guid ] = pZone;
|
2018-11-05 23:07:39 +01:00
|
|
|
m_territoryTypeIdToInstanceGuidMap[ territoryTypeId ] = instanceMap;
|
2019-07-24 21:58:48 +10:00
|
|
|
m_territorySet.insert( { pZone } );
|
2018-08-29 21:40:59 +02:00
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
2018-01-27 23:52:49 +01:00
|
|
|
|
2018-12-01 00:27:16 +11:00
|
|
|
bool Sapphire::World::Manager::TerritoryMgr::createHousingTerritories()
|
2018-08-29 21:40:59 +02:00
|
|
|
{
|
|
|
|
//separate housing zones from default
|
2018-12-22 22:25:03 +01:00
|
|
|
auto pExdData = framework()->get< Data::ExdDataGenerated >();
|
2018-08-29 21:40:59 +02:00
|
|
|
for( const auto& territory : m_territoryTypeDetailCacheMap )
|
|
|
|
{
|
2018-11-05 23:07:39 +01:00
|
|
|
auto territoryTypeId = territory.first;
|
2018-08-29 21:40:59 +02:00
|
|
|
auto territoryInfo = territory.second;
|
|
|
|
uint32_t wardNum;
|
2019-01-25 12:34:21 +11:00
|
|
|
uint32_t wardMaxNum = 18;
|
2018-08-29 21:40:59 +02:00
|
|
|
|
|
|
|
if( territoryInfo->name.empty() )
|
|
|
|
continue;
|
|
|
|
|
2018-11-29 16:55:48 +01:00
|
|
|
auto pPlaceName = pExdData->get< Sapphire::Data::PlaceName >( territoryInfo->placeName );
|
2018-08-29 21:40:59 +02:00
|
|
|
|
2018-11-05 23:07:39 +01:00
|
|
|
if( !pPlaceName || pPlaceName->name.empty() || !isHousingTerritory( territoryTypeId ) )
|
2018-08-29 21:40:59 +02:00
|
|
|
continue;
|
|
|
|
|
|
|
|
for( wardNum = 0; wardNum < wardMaxNum; wardNum++ )
|
|
|
|
{
|
2018-01-27 23:52:49 +01:00
|
|
|
uint32_t guid = getNextInstanceId();
|
2019-01-04 22:37:01 +11:00
|
|
|
|
2019-01-25 12:34:21 +11:00
|
|
|
Logger::info( "{0}\t{1}\t{2}\t{3:<10}\tHOUSING\t\t{4}#{5}",
|
2019-01-04 22:37:01 +11:00
|
|
|
territoryTypeId,
|
|
|
|
guid,
|
|
|
|
territoryInfo->territoryIntendedUse,
|
|
|
|
territoryInfo->name,
|
|
|
|
pPlaceName->name,
|
|
|
|
wardNum );
|
2018-01-27 23:52:49 +01:00
|
|
|
|
2018-12-29 00:53:52 +01:00
|
|
|
auto pHousingZone = make_HousingZone( wardNum, territoryTypeId, guid, territoryInfo->name,
|
|
|
|
pPlaceName->name, framework() );
|
2018-08-29 21:40:59 +02:00
|
|
|
pHousingZone->init();
|
2018-01-27 23:52:49 +01:00
|
|
|
|
2019-07-21 22:33:33 +10:00
|
|
|
InstanceIdToTerritoryPtrMap instanceMap;
|
2018-08-29 21:40:59 +02:00
|
|
|
instanceMap[ guid ] = pHousingZone;
|
2019-07-21 22:33:33 +10:00
|
|
|
m_guIdToTerritoryPtrMap[ guid ] = pHousingZone;
|
2018-11-05 23:07:39 +01:00
|
|
|
m_territoryTypeIdToInstanceGuidMap[ territoryTypeId ][ guid ] = pHousingZone;
|
2019-07-21 22:33:33 +10:00
|
|
|
m_landSetIdToTerritoryPtrMap[ pHousingZone->getLandSetId() ] = pHousingZone;
|
2019-07-24 21:58:48 +10:00
|
|
|
m_territorySet.insert( { pHousingZone } );
|
2018-08-29 21:40:59 +02:00
|
|
|
}
|
2018-01-27 23:52:49 +01:00
|
|
|
|
2018-08-29 21:40:59 +02:00
|
|
|
}
|
2018-01-27 23:52:49 +01:00
|
|
|
|
2018-08-29 21:40:59 +02:00
|
|
|
return true;
|
2018-07-15 23:59:15 +02:00
|
|
|
}
|
|
|
|
|
2019-07-21 22:33:33 +10:00
|
|
|
Sapphire::TerritoryPtr Sapphire::World::Manager::TerritoryMgr::createTerritoryInstance( uint32_t territoryTypeId )
|
2018-01-28 23:53:58 +11:00
|
|
|
{
|
2018-08-29 21:40:59 +02:00
|
|
|
if( !isValidTerritory( territoryTypeId ) )
|
|
|
|
return nullptr;
|
2018-01-28 23:53:58 +11:00
|
|
|
|
2019-05-07 22:16:18 +10:00
|
|
|
// nb: disabled for now because there's not a real reason to have this constraint, makes testing some stuff easier too
|
|
|
|
// if( isInstanceContentTerritory( territoryTypeId ) )
|
|
|
|
// return nullptr;
|
2018-01-29 19:40:27 +11:00
|
|
|
|
2018-12-22 22:25:03 +01:00
|
|
|
auto pExdData = framework()->get< Data::ExdDataGenerated >();
|
2018-08-29 21:40:59 +02:00
|
|
|
auto pTeri = getTerritoryDetail( territoryTypeId );
|
2018-11-29 16:55:48 +01:00
|
|
|
auto pPlaceName = pExdData->get< Sapphire::Data::PlaceName >( pTeri->placeName );
|
2018-01-28 23:53:58 +11:00
|
|
|
|
2018-08-29 21:40:59 +02:00
|
|
|
if( !pTeri || !pPlaceName )
|
|
|
|
return nullptr;
|
2018-01-28 23:53:58 +11:00
|
|
|
|
2019-01-04 22:37:01 +11:00
|
|
|
Logger::debug( "Starting instance for territory: {0} ({1})", territoryTypeId, pPlaceName->name );
|
2018-01-28 23:53:58 +11:00
|
|
|
|
2019-07-21 22:33:33 +10:00
|
|
|
auto pZone = make_Territory( territoryTypeId, getNextInstanceId(), pTeri->name, pPlaceName->name, framework() );
|
2018-08-29 21:40:59 +02:00
|
|
|
pZone->init();
|
2018-01-28 23:53:58 +11:00
|
|
|
|
2019-07-21 22:33:33 +10:00
|
|
|
m_guIdToTerritoryPtrMap[ pZone->getGuId() ] = pZone;
|
2018-11-05 23:07:39 +01:00
|
|
|
m_territoryTypeIdToInstanceGuidMap[ pZone->getTerritoryTypeId() ][ pZone->getGuId() ] = pZone;
|
2019-07-24 21:58:48 +10:00
|
|
|
m_territorySet.insert( { pZone } );
|
2018-01-28 23:53:58 +11:00
|
|
|
|
2018-08-29 21:40:59 +02:00
|
|
|
return pZone;
|
2018-01-28 23:53:58 +11:00
|
|
|
}
|
|
|
|
|
2019-07-21 22:33:33 +10:00
|
|
|
Sapphire::TerritoryPtr Sapphire::World::Manager::TerritoryMgr::createQuestBattle( uint32_t questBattleId )
|
2019-03-31 23:45:03 +02:00
|
|
|
{
|
|
|
|
|
2019-04-11 00:16:04 +02:00
|
|
|
auto it = m_questBattleToContentFinderMap.find( questBattleId );
|
|
|
|
if( it == m_questBattleToContentFinderMap.end() )
|
|
|
|
return nullptr;
|
|
|
|
|
|
|
|
auto contentFinderConditionId = it->second;
|
|
|
|
|
2019-03-31 23:45:03 +02:00
|
|
|
auto pExdData = framework()->get< Data::ExdDataGenerated >();
|
|
|
|
auto pContentFinderCondition = pExdData->get< Sapphire::Data::ContentFinderCondition >( contentFinderConditionId );
|
|
|
|
if( !pContentFinderCondition )
|
|
|
|
return nullptr;
|
|
|
|
|
|
|
|
auto pQuestBattleInfo = pExdData->get< Sapphire::Data::QuestBattle >( questBattleId );
|
|
|
|
if( !pQuestBattleInfo )
|
|
|
|
return nullptr;
|
|
|
|
|
|
|
|
auto pQuestInfo = pExdData->get< Sapphire::Data::Quest >( pQuestBattleInfo->quest );
|
|
|
|
if( !pQuestInfo )
|
|
|
|
return nullptr;
|
|
|
|
|
|
|
|
if( !isInstanceContentTerritory( pContentFinderCondition->territoryType ) )
|
|
|
|
return nullptr;
|
|
|
|
|
|
|
|
auto pTeri = getTerritoryDetail( pContentFinderCondition->territoryType );
|
|
|
|
|
|
|
|
if( !pTeri || pQuestInfo->name.empty() )
|
|
|
|
return nullptr;
|
|
|
|
|
2019-04-11 00:16:04 +02:00
|
|
|
Logger::debug( "Starting instance for QuestBattle id: {0} ({1})", questBattleId, pQuestInfo->name );
|
2019-03-31 23:45:03 +02:00
|
|
|
|
|
|
|
auto pZone = make_QuestBattle( pQuestBattleInfo, pContentFinderCondition->territoryType, getNextInstanceId(),
|
|
|
|
pTeri->name, pQuestInfo->name, questBattleId, framework() );
|
|
|
|
pZone->init();
|
|
|
|
|
2019-04-07 16:01:53 +02:00
|
|
|
m_questBattleIdToInstanceMap[ questBattleId ][ pZone->getGuId() ] = pZone;
|
2019-07-21 22:33:33 +10:00
|
|
|
m_guIdToTerritoryPtrMap[ pZone->getGuId() ] = pZone;
|
2019-03-31 23:45:03 +02:00
|
|
|
m_instanceZoneSet.insert( pZone );
|
|
|
|
|
|
|
|
return pZone;
|
|
|
|
}
|
|
|
|
|
2019-07-21 22:33:33 +10:00
|
|
|
Sapphire::TerritoryPtr Sapphire::World::Manager::TerritoryMgr::createInstanceContent( uint32_t contentFinderConditionId )
|
2018-01-29 19:40:27 +11:00
|
|
|
{
|
2018-09-19 23:04:23 +02:00
|
|
|
|
2018-12-22 22:25:03 +01:00
|
|
|
auto pExdData = framework()->get< Data::ExdDataGenerated >();
|
2018-11-29 16:55:48 +01:00
|
|
|
auto pContentFinderCondition = pExdData->get< Sapphire::Data::ContentFinderCondition >( contentFinderConditionId );
|
2018-09-19 23:04:23 +02:00
|
|
|
if( !pContentFinderCondition )
|
|
|
|
return nullptr;
|
2018-11-23 21:16:02 +01:00
|
|
|
auto instanceContentId = pContentFinderCondition->content;
|
2018-09-19 23:04:23 +02:00
|
|
|
|
2018-11-29 16:55:48 +01:00
|
|
|
auto pInstanceContent = pExdData->get< Sapphire::Data::InstanceContent >( instanceContentId );
|
2018-08-29 21:40:59 +02:00
|
|
|
if( !pInstanceContent )
|
|
|
|
return nullptr;
|
2018-01-29 19:40:27 +11:00
|
|
|
|
2018-09-19 23:04:23 +02:00
|
|
|
if( !isInstanceContentTerritory( pContentFinderCondition->territoryType ) )
|
2018-08-29 21:40:59 +02:00
|
|
|
return nullptr;
|
2018-01-29 19:40:27 +11:00
|
|
|
|
2018-09-19 23:04:23 +02:00
|
|
|
auto pTeri = getTerritoryDetail( pContentFinderCondition->territoryType );
|
2018-01-29 19:40:27 +11:00
|
|
|
|
2019-11-23 02:57:29 -05:00
|
|
|
if( !pTeri || pContentFinderCondition->name.empty() )
|
2018-08-29 21:40:59 +02:00
|
|
|
return nullptr;
|
2018-01-29 19:40:27 +11:00
|
|
|
|
2019-01-04 22:37:01 +11:00
|
|
|
Logger::debug( "Starting instance for InstanceContent id: {0} ({1})", instanceContentId, pInstanceContent->name );
|
2018-01-29 19:40:27 +11:00
|
|
|
|
2018-09-19 23:04:23 +02:00
|
|
|
auto pZone = make_InstanceContent( pInstanceContent, pContentFinderCondition->territoryType, getNextInstanceId(),
|
2019-11-23 02:57:29 -05:00
|
|
|
pTeri->name, pContentFinderCondition->name, instanceContentId, framework() );
|
2018-08-29 21:40:59 +02:00
|
|
|
pZone->init();
|
2018-01-29 19:40:27 +11:00
|
|
|
|
2018-12-30 18:48:45 +11:00
|
|
|
m_instanceContentIdToInstanceMap[ instanceContentId ][ pZone->getGuId() ] = pZone;
|
2019-07-21 22:33:33 +10:00
|
|
|
m_guIdToTerritoryPtrMap[ pZone->getGuId() ] = pZone;
|
2018-08-29 21:40:59 +02:00
|
|
|
m_instanceZoneSet.insert( pZone );
|
2018-01-29 19:40:27 +11:00
|
|
|
|
2018-08-29 21:40:59 +02:00
|
|
|
return pZone;
|
2018-01-29 19:40:27 +11:00
|
|
|
}
|
|
|
|
|
2019-07-21 22:33:33 +10:00
|
|
|
Sapphire::TerritoryPtr Sapphire::World::Manager::TerritoryMgr::findOrCreateHousingInterior( const Common::LandIdent landIdent )
|
2018-12-01 00:27:16 +11:00
|
|
|
{
|
2018-12-01 18:18:29 +11:00
|
|
|
// check if zone already spawned first
|
|
|
|
auto ident = *reinterpret_cast< const uint64_t* >( &landIdent );
|
|
|
|
|
2019-07-21 22:33:33 +10:00
|
|
|
auto it = m_landIdentToTerritoryPtrMap.find( ident );
|
|
|
|
if( it != m_landIdentToTerritoryPtrMap.end() )
|
2018-12-01 18:18:29 +11:00
|
|
|
{
|
|
|
|
return it->second;
|
|
|
|
}
|
|
|
|
|
|
|
|
// otherwise, create it
|
2018-12-22 22:25:03 +01:00
|
|
|
auto housingMgr = framework()->get< Manager::HousingMgr >();
|
2018-12-01 18:18:29 +11:00
|
|
|
|
|
|
|
auto parentZone = std::dynamic_pointer_cast< HousingZone >(
|
2018-12-02 02:01:41 +01:00
|
|
|
getZoneByLandSetId( housingMgr->toLandSetId( static_cast< uint16_t >( landIdent.territoryTypeId ),
|
|
|
|
static_cast< uint8_t >( landIdent.wardNum ) ) ) );
|
2018-12-01 18:18:29 +11:00
|
|
|
|
|
|
|
if( !parentZone )
|
|
|
|
return nullptr;
|
|
|
|
|
|
|
|
auto land = parentZone->getLand( landIdent.landId );
|
|
|
|
if( !land )
|
|
|
|
return nullptr;
|
|
|
|
|
|
|
|
auto house = land->getHouse();
|
|
|
|
if( !house )
|
|
|
|
return nullptr;
|
|
|
|
|
|
|
|
// get house instance id
|
|
|
|
uint16_t territoryTypeId = 0;
|
|
|
|
switch( landIdent.territoryTypeId )
|
|
|
|
{
|
|
|
|
case 339: // mist
|
|
|
|
territoryTypeId = 282;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 340: // lavender beds
|
|
|
|
territoryTypeId = 342;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 341: // goblet
|
|
|
|
territoryTypeId = 345;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 641: // shirogane
|
|
|
|
territoryTypeId = 649;
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
|
|
|
|
// zones are sequential in the exd for small, med, large
|
|
|
|
territoryTypeId += land->getSize();
|
|
|
|
|
|
|
|
auto terriInfo = getTerritoryDetail( territoryTypeId );
|
|
|
|
if( !terriInfo )
|
|
|
|
return nullptr;
|
|
|
|
|
2018-12-29 00:53:52 +01:00
|
|
|
auto zone = World::Territory::Housing::make_HousingInteriorTerritory( landIdent, territoryTypeId,
|
|
|
|
getNextInstanceId(), terriInfo->name,
|
|
|
|
house->getHouseName(), framework() );
|
2018-12-01 18:18:29 +11:00
|
|
|
|
|
|
|
zone->init();
|
|
|
|
|
2019-07-21 22:33:33 +10:00
|
|
|
m_landIdentToTerritoryPtrMap[ ident ] = zone;
|
|
|
|
m_guIdToTerritoryPtrMap[ zone->getGuId() ] = zone;
|
2019-07-24 21:58:48 +10:00
|
|
|
m_territorySet.insert( { zone } );
|
2018-12-01 00:27:16 +11:00
|
|
|
|
2018-12-01 18:18:29 +11:00
|
|
|
return zone;
|
2018-12-01 00:27:16 +11:00
|
|
|
}
|
|
|
|
|
2019-04-07 16:01:53 +02:00
|
|
|
bool Sapphire::World::Manager::TerritoryMgr::removeTerritoryInstance( uint32_t guId )
|
2018-01-29 00:52:11 +11:00
|
|
|
{
|
2019-07-21 22:33:33 +10:00
|
|
|
TerritoryPtr pZone;
|
2019-05-07 22:10:55 +10:00
|
|
|
if( ( pZone = getTerritoryByGuId( guId ) ) == nullptr )
|
2018-08-29 21:40:59 +02:00
|
|
|
return false;
|
2018-01-29 00:52:11 +11:00
|
|
|
|
2019-07-21 22:33:33 +10:00
|
|
|
m_guIdToTerritoryPtrMap.erase( pZone->getGuId() );
|
2018-01-29 20:40:32 +11:00
|
|
|
|
2018-08-29 21:40:59 +02:00
|
|
|
m_instanceZoneSet.erase( pZone );
|
2019-07-24 21:58:48 +10:00
|
|
|
m_territorySet.erase( pZone );
|
2018-02-01 23:32:59 +01:00
|
|
|
|
2018-11-05 23:07:39 +01:00
|
|
|
if( isInstanceContentTerritory( pZone->getTerritoryTypeId() ) )
|
2018-08-29 21:40:59 +02:00
|
|
|
{
|
2018-10-25 12:44:51 +11:00
|
|
|
auto instance = std::dynamic_pointer_cast< InstanceContent >( pZone );
|
2018-12-30 18:48:45 +11:00
|
|
|
m_instanceContentIdToInstanceMap[ instance->getInstanceContentId() ].erase( pZone->getGuId() );
|
2018-08-29 21:40:59 +02:00
|
|
|
}
|
|
|
|
else
|
2018-11-05 23:07:39 +01:00
|
|
|
m_territoryTypeIdToInstanceGuidMap[ pZone->getTerritoryTypeId() ].erase( pZone->getGuId() );
|
2018-01-29 20:40:32 +11:00
|
|
|
|
2018-08-29 21:40:59 +02:00
|
|
|
return true;
|
2018-01-29 00:52:11 +11:00
|
|
|
}
|
|
|
|
|
2019-07-21 22:33:33 +10:00
|
|
|
Sapphire::TerritoryPtr Sapphire::World::Manager::TerritoryMgr::getTerritoryByGuId( uint32_t guId ) const
|
2018-01-28 23:53:58 +11:00
|
|
|
{
|
2019-07-21 22:33:33 +10:00
|
|
|
auto it = m_guIdToTerritoryPtrMap.find( guId );
|
|
|
|
if( it == m_guIdToTerritoryPtrMap.end() )
|
2018-08-29 21:40:59 +02:00
|
|
|
return nullptr;
|
2018-01-28 23:53:58 +11:00
|
|
|
|
2018-08-29 21:40:59 +02:00
|
|
|
return it->second;
|
2018-01-28 23:53:58 +11:00
|
|
|
}
|
|
|
|
|
2018-12-01 00:27:16 +11:00
|
|
|
void Sapphire::World::Manager::TerritoryMgr::loadTerritoryPositionMap()
|
2018-01-27 23:52:49 +01:00
|
|
|
{
|
2018-12-22 22:25:03 +01:00
|
|
|
auto pDb = framework()->get< Db::DbWorkerPool< Db::ZoneDbConnection > >();
|
2018-08-29 21:40:59 +02:00
|
|
|
auto pQR = pDb->query( "SELECT id, target_zone_id, pos_x, pos_y, pos_z, pos_o, radius FROM zonepositions;" );
|
|
|
|
|
|
|
|
while( pQR->next() )
|
|
|
|
{
|
|
|
|
uint32_t id = pQR->getUInt( 1 );
|
|
|
|
uint32_t targetZoneId = pQR->getUInt( 2 );
|
|
|
|
Common::FFXIVARR_POSITION3 pos{};
|
|
|
|
pos.x = pQR->getFloat( 3 );
|
|
|
|
pos.y = pQR->getFloat( 4 );
|
|
|
|
pos.z = pQR->getFloat( 5 );
|
|
|
|
float posO = pQR->getFloat( 6 );
|
|
|
|
uint32_t radius = pQR->getUInt( 7 );
|
|
|
|
|
|
|
|
m_territoryPositionMap[ id ] = make_ZonePosition( id, targetZoneId, pos, radius, posO );
|
|
|
|
}
|
2018-01-27 23:52:49 +01:00
|
|
|
}
|
|
|
|
|
2018-12-01 00:27:16 +11:00
|
|
|
Sapphire::ZonePositionPtr Sapphire::World::Manager::TerritoryMgr::getTerritoryPosition( uint32_t territoryPositionId ) const
|
2018-01-27 23:52:49 +01:00
|
|
|
{
|
2018-08-29 21:40:59 +02:00
|
|
|
auto it = m_territoryPositionMap.find( territoryPositionId );
|
2018-01-27 23:52:49 +01:00
|
|
|
|
2018-08-29 21:40:59 +02:00
|
|
|
if( it != m_territoryPositionMap.end() )
|
|
|
|
return it->second;
|
2018-01-27 23:52:49 +01:00
|
|
|
|
2018-08-29 21:40:59 +02:00
|
|
|
return nullptr;
|
2018-01-27 23:52:49 +01:00
|
|
|
}
|
|
|
|
|
2019-07-21 22:33:33 +10:00
|
|
|
Sapphire::TerritoryPtr Sapphire::World::Manager::TerritoryMgr::getZoneByTerritoryTypeId( uint32_t territoryTypeId ) const
|
2018-01-27 23:52:49 +01:00
|
|
|
{
|
2018-11-05 23:07:39 +01:00
|
|
|
auto zoneMap = m_territoryTypeIdToInstanceGuidMap.find( territoryTypeId );
|
|
|
|
if( zoneMap == m_territoryTypeIdToInstanceGuidMap.end() )
|
2018-08-29 21:40:59 +02:00
|
|
|
return nullptr;
|
2018-01-27 23:52:49 +01:00
|
|
|
|
2018-08-29 21:40:59 +02:00
|
|
|
// TODO: actually select the proper one
|
|
|
|
return zoneMap->second.begin()->second;
|
2018-01-27 23:52:49 +01:00
|
|
|
}
|
|
|
|
|
2019-07-21 22:33:33 +10:00
|
|
|
Sapphire::TerritoryPtr Sapphire::World::Manager::TerritoryMgr::getZoneByLandSetId( uint32_t landSetId ) const
|
2018-11-06 11:11:07 +01:00
|
|
|
{
|
2019-07-21 22:33:33 +10:00
|
|
|
auto zoneMap = m_landSetIdToTerritoryPtrMap.find( landSetId );
|
|
|
|
if( zoneMap == m_landSetIdToTerritoryPtrMap.end() )
|
2018-11-06 11:11:07 +01:00
|
|
|
return nullptr;
|
|
|
|
|
|
|
|
return zoneMap->second;
|
|
|
|
}
|
|
|
|
|
2019-04-04 23:29:52 +02:00
|
|
|
void Sapphire::World::Manager::TerritoryMgr::updateTerritoryInstances( uint64_t tickCount )
|
2018-01-27 23:52:49 +01:00
|
|
|
{
|
2019-07-24 21:58:48 +10:00
|
|
|
for( auto& zone : m_territorySet )
|
2018-08-29 21:40:59 +02:00
|
|
|
{
|
2019-04-04 23:29:52 +02:00
|
|
|
zone->update( tickCount );
|
2018-08-29 21:40:59 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
for( auto& zone : m_instanceZoneSet )
|
|
|
|
{
|
2019-04-04 23:29:52 +02:00
|
|
|
zone->update( tickCount );
|
2018-08-29 21:40:59 +02:00
|
|
|
}
|
2018-12-02 18:05:50 +11:00
|
|
|
|
|
|
|
// remove internal house zones with nobody in them
|
2019-07-21 22:33:33 +10:00
|
|
|
for( auto it = m_landIdentToTerritoryPtrMap.begin(); it != m_landIdentToTerritoryPtrMap.end(); )
|
2018-12-02 18:05:50 +11:00
|
|
|
{
|
|
|
|
auto zone = std::dynamic_pointer_cast< Territory::Housing::HousingInteriorTerritory >( it->second );
|
|
|
|
assert( zone ); // wtf??
|
|
|
|
|
2019-04-04 23:29:52 +02:00
|
|
|
auto diff = std::difftime( tickCount, zone->getLastActivityTime() );
|
2018-12-02 18:05:50 +11:00
|
|
|
|
|
|
|
// todo: make this timeout configurable, though should be pretty relaxed in any case
|
2019-04-07 23:42:24 +02:00
|
|
|
if( diff > 60000 )
|
2018-12-02 18:05:50 +11:00
|
|
|
{
|
2019-01-04 22:37:01 +11:00
|
|
|
Logger::info( "Removing HousingInteriorTerritory#{0} - has been inactive for 60 seconds", zone->getGuId() );
|
2018-12-02 18:05:50 +11:00
|
|
|
|
|
|
|
// remove zone from maps
|
2019-07-24 21:58:48 +10:00
|
|
|
m_territorySet.erase( zone );
|
2019-07-21 22:33:33 +10:00
|
|
|
it = m_landIdentToTerritoryPtrMap.erase( it );
|
2018-12-02 18:05:50 +11:00
|
|
|
}
|
|
|
|
else
|
|
|
|
it++;
|
|
|
|
}
|
2019-04-07 16:01:53 +02:00
|
|
|
|
|
|
|
// remove internal house zones with nobody in them
|
|
|
|
for( auto it = m_questBattleIdToInstanceMap.begin(); it != m_questBattleIdToInstanceMap.end(); ++it )
|
|
|
|
{
|
|
|
|
for( auto inIt = it->second.begin(); inIt != it->second.end(); )
|
|
|
|
{
|
|
|
|
auto zone = std::dynamic_pointer_cast< QuestBattle >( inIt->second );
|
|
|
|
if( !zone )
|
|
|
|
continue;
|
|
|
|
|
|
|
|
auto diff = std::difftime( tickCount, zone->getLastActivityTime() );
|
|
|
|
|
|
|
|
// todo: make this timeout configurable, though should be pretty relaxed in any case
|
2019-04-07 23:42:24 +02:00
|
|
|
if( diff > 60000 )
|
2019-04-07 16:01:53 +02:00
|
|
|
{
|
|
|
|
Logger::info( "Removing QuestBattle#{0} - has been inactive for 60 seconds", zone->getGuId() );
|
|
|
|
|
|
|
|
// remove zone from maps
|
|
|
|
m_instanceZoneSet.erase( zone );
|
2019-07-21 22:33:33 +10:00
|
|
|
m_guIdToTerritoryPtrMap.erase( zone->getGuId() );
|
2019-04-07 16:01:53 +02:00
|
|
|
inIt = m_questBattleIdToInstanceMap[ zone->getQuestBattleId() ].erase( inIt );
|
|
|
|
}
|
|
|
|
else
|
|
|
|
inIt++;
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
2018-01-28 13:49:51 +01:00
|
|
|
}
|
|
|
|
|
2019-04-07 16:01:53 +02:00
|
|
|
Sapphire::World::Manager::TerritoryMgr::InstanceIdList
|
|
|
|
Sapphire::World::Manager::TerritoryMgr::getInstanceContentIdList( uint16_t instanceContentId ) const
|
2018-01-28 13:49:51 +01:00
|
|
|
{
|
2018-08-29 21:40:59 +02:00
|
|
|
std::vector< uint32_t > idList;
|
2018-12-30 18:48:45 +11:00
|
|
|
auto zoneMap = m_instanceContentIdToInstanceMap.find( instanceContentId );
|
|
|
|
if( zoneMap == m_instanceContentIdToInstanceMap.end() )
|
2018-08-29 21:40:59 +02:00
|
|
|
return idList;
|
2018-01-28 13:49:51 +01:00
|
|
|
|
2018-08-29 21:40:59 +02:00
|
|
|
for( auto& entry : zoneMap->second )
|
|
|
|
{
|
|
|
|
idList.push_back( entry.first );
|
|
|
|
}
|
2018-01-27 23:52:49 +01:00
|
|
|
|
2018-08-29 21:40:59 +02:00
|
|
|
return idList;
|
2018-01-27 23:52:49 +01:00
|
|
|
}
|
|
|
|
|
2018-12-01 00:27:16 +11:00
|
|
|
bool Sapphire::World::Manager::TerritoryMgr::movePlayer( uint32_t territoryTypeId, Sapphire::Entity::PlayerPtr pPlayer )
|
2018-01-28 22:36:43 +01:00
|
|
|
{
|
2018-11-05 23:07:39 +01:00
|
|
|
auto pZone = getZoneByTerritoryTypeId( territoryTypeId );
|
2018-08-29 21:40:59 +02:00
|
|
|
assert( pZone );
|
|
|
|
return movePlayer( pZone, pPlayer );
|
2018-01-28 22:36:43 +01:00
|
|
|
}
|
|
|
|
|
2019-07-21 22:33:33 +10:00
|
|
|
bool Sapphire::World::Manager::TerritoryMgr::movePlayer( TerritoryPtr pZone, Sapphire::Entity::PlayerPtr pPlayer )
|
2018-01-28 22:36:43 +01:00
|
|
|
{
|
2018-08-29 21:40:59 +02:00
|
|
|
if( !pZone )
|
|
|
|
{
|
2019-07-21 22:33:33 +10:00
|
|
|
Logger::error( "Territory not found on this server." );
|
2018-08-29 21:40:59 +02:00
|
|
|
return false;
|
|
|
|
}
|
2018-01-28 22:36:43 +01:00
|
|
|
|
2018-08-29 21:40:59 +02:00
|
|
|
pPlayer->initSpawnIdQueue();
|
2018-02-23 23:47:21 +01:00
|
|
|
|
2018-11-05 23:07:39 +01:00
|
|
|
pPlayer->setTerritoryTypeId( pZone->getTerritoryTypeId() );
|
2018-01-28 22:36:43 +01:00
|
|
|
|
2018-11-06 11:11:07 +01:00
|
|
|
if( isHousingTerritory( pZone->getTerritoryTypeId() ) )
|
|
|
|
{
|
|
|
|
auto pHousing = std::dynamic_pointer_cast< HousingZone >( pZone );
|
2018-11-23 16:48:32 +11:00
|
|
|
if( pHousing )
|
2018-11-06 11:11:07 +01:00
|
|
|
pPlayer->setTerritoryId( pHousing->getLandSetId() );
|
2018-11-23 16:48:32 +11:00
|
|
|
}
|
|
|
|
else if( isInstanceContentTerritory( pZone->getTerritoryTypeId() ) )
|
|
|
|
{
|
|
|
|
pPlayer->setTerritoryId( pZone->getGuId() );
|
|
|
|
}
|
2018-11-06 11:11:07 +01:00
|
|
|
else
|
|
|
|
{
|
|
|
|
pPlayer->setTerritoryId( 0 );
|
|
|
|
}
|
2018-11-23 16:48:32 +11:00
|
|
|
|
2018-08-29 21:40:59 +02:00
|
|
|
// mark character as zoning in progress
|
|
|
|
pPlayer->setLoadingComplete( false );
|
2018-01-28 22:36:43 +01:00
|
|
|
|
2019-07-21 22:50:11 +10:00
|
|
|
if( pPlayer->getLastPing() != 0 && pPlayer->getCurrentTerritory() )
|
|
|
|
pPlayer->getCurrentTerritory()->removeActor( pPlayer );
|
2018-01-28 22:36:43 +01:00
|
|
|
|
2019-07-29 22:22:45 +10:00
|
|
|
pPlayer->setCurrentZone( pZone );
|
2018-08-29 21:40:59 +02:00
|
|
|
pZone->pushActor( pPlayer );
|
2018-01-28 22:36:43 +01:00
|
|
|
|
2018-08-29 21:40:59 +02:00
|
|
|
// map player to instanceId so it can be tracked.
|
|
|
|
m_playerIdToInstanceMap[ pPlayer->getId() ] = pZone->getGuId();
|
2018-02-04 17:46:46 +01:00
|
|
|
|
2019-01-14 22:29:52 +01:00
|
|
|
pPlayer->sendZonePackets();
|
|
|
|
|
2018-08-29 21:40:59 +02:00
|
|
|
return true;
|
2018-01-28 22:36:43 +01:00
|
|
|
}
|
|
|
|
|
2019-07-21 22:33:33 +10:00
|
|
|
Sapphire::TerritoryPtr Sapphire::World::Manager::TerritoryMgr::getLinkedInstance( uint32_t playerId ) const
|
2018-02-04 17:46:46 +01:00
|
|
|
{
|
2018-08-29 21:40:59 +02:00
|
|
|
auto it = m_playerIdToInstanceMap.find( playerId );
|
|
|
|
if( it != m_playerIdToInstanceMap.end() )
|
|
|
|
{
|
2019-05-07 22:10:55 +10:00
|
|
|
return getTerritoryByGuId( it->second );
|
2018-08-29 21:40:59 +02:00
|
|
|
}
|
|
|
|
return nullptr;
|
2018-02-04 17:46:46 +01:00
|
|
|
}
|
|
|
|
|
2018-12-01 00:27:16 +11:00
|
|
|
const std::pair< uint16_t, uint16_t >& Sapphire::World::Manager::TerritoryMgr::getCurrentFestival() const
|
2018-03-20 20:30:05 +11:00
|
|
|
{
|
2018-08-29 21:40:59 +02:00
|
|
|
return m_currentFestival;
|
2018-03-20 20:30:05 +11:00
|
|
|
}
|
|
|
|
|
2018-12-01 00:27:16 +11:00
|
|
|
void Sapphire::World::Manager::TerritoryMgr::setCurrentFestival( uint16_t festivalId, uint16_t additionalFestival )
|
2018-03-20 20:30:05 +11:00
|
|
|
{
|
2018-09-01 20:55:28 +10:00
|
|
|
m_currentFestival = { festivalId, additionalFestival };
|
2018-03-20 20:30:05 +11:00
|
|
|
|
2019-07-24 21:58:48 +10:00
|
|
|
for( const auto& zone : m_territorySet )
|
2018-08-29 21:40:59 +02:00
|
|
|
{
|
2018-09-01 20:55:28 +10:00
|
|
|
zone->setCurrentFestival( festivalId, additionalFestival );
|
2018-08-29 21:40:59 +02:00
|
|
|
}
|
2018-03-20 20:30:05 +11:00
|
|
|
}
|
|
|
|
|
2018-12-01 00:27:16 +11:00
|
|
|
void Sapphire::World::Manager::TerritoryMgr::disableCurrentFestival()
|
2018-03-20 20:30:05 +11:00
|
|
|
{
|
2018-08-29 21:40:59 +02:00
|
|
|
setCurrentFestival( 0 );
|
2018-03-20 20:30:05 +11:00
|
|
|
}
|
|
|
|
|
2019-01-28 20:48:33 +11:00
|
|
|
float Sapphire::World::Manager::TerritoryMgr::getInRangeDistance() const
|
|
|
|
{
|
|
|
|
return m_inRangeDistance;
|
|
|
|
}
|
2018-01-27 23:52:49 +01:00
|
|
|
|
2019-04-11 00:16:04 +02:00
|
|
|
void Sapphire::World::Manager::TerritoryMgr::createAndJoinQuestBattle( Entity::Player& player, uint16_t questBattleId )
|
|
|
|
{
|
|
|
|
auto qb = createQuestBattle( questBattleId );
|
|
|
|
if( !qb )
|
|
|
|
return;
|
|
|
|
|
|
|
|
player.setInstance( qb );
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2018-01-28 13:49:51 +01:00
|
|
|
|