1
Fork 0
mirror of https://github.com/SapphireServer/Sapphire.git synced 2025-04-24 21:57:44 +00:00
sapphire/src/servers/sapphire_zone/Zone/Zone.cpp

733 lines
19 KiB
C++
Raw Normal View History

2017-08-08 13:53:47 +02:00
#include <stdio.h>
#include <vector>
#include <common/Logging/Logger.h>
#include <common/Util/Util.h>
#include <common/Util/UtilMath.h>
#include <common/Network/GamePacket.h>
#include <common/Network/GamePacketNew.h>
2018-01-31 11:43:22 +01:00
#include <common/Exd/ExdDataGenerated.h>
#include <common/Network/CommonNetwork.h>
#include <common/Network/PacketDef/Zone/ServerZoneDef.h>
#include <common/Network/PacketContainer.h>
#include <common/Database/DatabaseDef.h>
2017-08-08 13:53:47 +02:00
#include "Zone.h"
2018-01-27 23:52:49 +01:00
#include "TerritoryMgr.h"
2017-08-08 13:53:47 +02:00
#include "Session.h"
#include "Actor/Chara.h"
#include "Actor/Player.h"
2017-08-08 13:53:47 +02:00
#include "Forwards.h"
2017-08-08 13:53:47 +02:00
#include "Network/GameConnection.h"
#include "ServerZone.h"
#include "Script/ScriptManager.h"
2017-08-08 13:53:47 +02:00
#include "CellHandler.h"
#include <time.h>
extern Core::Logger g_log;
extern Core::ServerZone g_serverZone;
2018-01-31 11:43:22 +01:00
extern Core::Data::ExdDataGenerated g_exdDataGen;
2017-08-08 13:53:47 +02:00
extern Core::Scripting::ScriptManager g_scriptMgr;
extern Core::TerritoryMgr g_territoryMgr;
2017-08-08 13:53:47 +02:00
/**
* \brief
*/
2018-02-11 23:52:44 +01:00
Core::Zone::Zone() :
m_territoryId( 0 ),
m_guId( 0 ),
m_currentWeather( Common::Weather::FairSkies ),
m_weatherOverride( Common::Weather::None ),
m_lastMobUpdate( 0 ),
m_currentFestivalId( 0 )
2017-08-08 13:53:47 +02:00
{
}
2018-02-11 23:52:44 +01:00
Core::Zone::Zone( uint16_t territoryId, uint32_t guId, const std::string& internalName, const std::string& placeName ) :
m_currentWeather( Common::Weather::FairSkies )
2017-08-08 13:53:47 +02:00
{
2018-01-27 23:52:49 +01:00
m_guId = guId;
2017-08-08 13:53:47 +02:00
2018-01-27 23:52:49 +01:00
m_territoryId = territoryId;
m_internalName = internalName;
m_placeName = placeName;
2017-08-08 13:53:47 +02:00
m_lastMobUpdate = 0;
m_weatherOverride = Common::Weather::None;
2018-02-14 12:31:47 +01:00
m_territoryTypeInfo = g_exdDataGen.get< Core::Data::TerritoryType >( territoryId );
loadWeatherRates();
m_currentWeather = getNextWeather();
}
void Core::Zone::loadWeatherRates()
{
if( !m_territoryTypeInfo )
{
g_log.error( std::string( __FUNCTION__ ) + " TerritoryTypeInfo not loaded!" );
return;
}
uint8_t weatherRateId = m_territoryTypeInfo->weatherRate > g_exdDataGen.getWeatherRateIdList().size() ?
uint8_t{ 0 } : m_territoryTypeInfo->weatherRate;
uint8_t sumPc = 0;
auto weatherRateFields = g_exdDataGen.m_WeatherRateDat.get_row( weatherRateId );
for( size_t i = 0; i < 16; )
{
int32_t weatherId = boost::get< int32_t >( weatherRateFields[i] );
if( weatherId == 0 )
break;
sumPc += boost::get< uint8_t >( weatherRateFields[i + 1] );
m_weatherRateMap[sumPc] = weatherId;
i += 2;
}
2017-08-08 13:53:47 +02:00
}
2018-02-11 23:52:44 +01:00
Core::Zone::~Zone()
2017-08-08 13:53:47 +02:00
{
}
2018-02-11 23:52:44 +01:00
bool Core::Zone::init()
2017-08-08 13:53:47 +02:00
{
if( g_scriptMgr.onZoneInit( shared_from_this() ) )
{
// all good
}
return true;
}
void Core::Zone::setWeatherOverride( Common::Weather weather )
2017-08-08 13:53:47 +02:00
{
m_weatherOverride = weather;
}
Core::Common::Weather Core::Zone::getCurrentWeather() const
2017-08-08 13:53:47 +02:00
{
return m_currentWeather;
}
2018-02-11 23:52:44 +01:00
uint16_t Core::Zone::getCurrentFestival() const
2018-02-03 02:11:29 +11:00
{
return m_currentFestivalId;
}
2018-02-11 23:52:44 +01:00
void Core::Zone::setCurrentFestival( uint16_t festivalId )
2018-02-03 02:11:29 +11:00
{
m_currentFestivalId = festivalId;
}
2017-08-08 13:53:47 +02:00
2018-02-11 23:52:44 +01:00
void Core::Zone::loadCellCache()
2017-08-08 13:53:47 +02:00
{
}
Core::Common::Weather Core::Zone::getNextWeather()
2017-08-08 13:53:47 +02:00
{
2018-01-27 23:52:49 +01:00
uint32_t unixTime = static_cast< uint32_t >( Util::getTimeSeconds() );
2017-08-08 13:53:47 +02:00
// Get Eorzea hour for weather start
2017-08-09 23:49:00 +01:00
uint32_t bell = unixTime / 175;
2017-08-08 13:53:47 +02:00
// Do the magic 'cause for calculations 16:00 is 0, 00:00 is 8 and 08:00 is 16
int32_t increment = ( ( bell + 8 - ( bell % 8 ) ) ) % 24;
// Take Eorzea days since unix epoch
2017-08-09 23:49:00 +01:00
uint32_t totalDays = ( unixTime / 4200 );
2017-08-08 13:53:47 +02:00
uint32_t calcBase = ( totalDays * 0x64 ) + increment;
uint32_t step1 = ( calcBase << 0xB ) ^ calcBase;
uint32_t step2 = ( step1 >> 8 ) ^ step1;
2018-01-27 23:52:49 +01:00
auto rate = static_cast< uint8_t >( step2 % 0x64 );
2017-08-08 13:53:47 +02:00
for( auto entry : m_weatherRateMap )
2017-08-08 13:53:47 +02:00
{
uint8_t sRate = entry.first;
auto weatherId = static_cast< Common::Weather >( entry.second );
2017-08-08 13:53:47 +02:00
if( rate <= sRate )
return weatherId;
}
return Common::Weather::FairSkies;
2017-08-08 13:53:47 +02:00
}
void Core::Zone::pushActor( Entity::CharaPtr pChara )
2017-08-08 13:53:47 +02:00
{
float mx = pChara->getPos().x;
float my = pChara->getPos().z;
2017-08-08 13:53:47 +02:00
uint32_t cx = getPosX( mx );
uint32_t cy = getPosY( my );
Cell* pCell = getCell( cx, cy );
if( !pCell )
{
pCell = create( cx, cy );
pCell->init( cx, cy, shared_from_this() );
}
pCell->addChara(pChara);
2017-08-08 13:53:47 +02:00
pChara->setCell( pCell );
2017-08-08 13:53:47 +02:00
uint32_t cellX = getPosX( pChara->getPos().x );
uint32_t cellY = getPosY( pChara->getPos().z );
2017-08-08 13:53:47 +02:00
uint32_t endX = cellX <= _sizeX ? cellX + 1 : ( _sizeX - 1 );
uint32_t endY = cellY <= _sizeY ? cellY + 1 : ( _sizeY - 1 );
uint32_t startX = cellX > 0 ? cellX - 1 : 0;
uint32_t startY = cellY > 0 ? cellY - 1 : 0;
uint32_t posX, posY;
for( posX = startX; posX <= endX; ++posX )
{
for( posY = startY; posY <= endY; ++posY )
{
pCell = getCell( posX, posY );
if( pCell )
updateInRangeSet( pChara, pCell );
2017-08-08 13:53:47 +02:00
}
}
if( pChara->isPlayer() )
2017-08-08 13:53:47 +02:00
{
auto pPlayer = pChara->getAsPlayer();
2017-08-08 13:53:47 +02:00
auto pSession = g_serverZone.getSession( pPlayer->getId() );
if( pSession )
m_sessionSet.insert( pSession );
m_playerMap[pPlayer->getId()] = pPlayer;
updateCellActivity( cx, cy, 2 );
}
2018-02-21 12:48:27 +01:00
}
2017-08-08 13:53:47 +02:00
void Core::Zone::removeActor( Entity::CharaPtr pChara )
2017-08-08 13:53:47 +02:00
{
if( pChara->m_pCell )
2017-08-08 13:53:47 +02:00
{
pChara->m_pCell->removeChara(pChara);
pChara->m_pCell = nullptr;
2017-08-08 13:53:47 +02:00
}
if( pChara->isPlayer() )
2017-08-08 13:53:47 +02:00
{
// If it's a player and he's inside boundaries - update his nearby cells
if( pChara->getPos().x <= _maxX && pChara->getPos().x >= _minX &&
pChara->getPos().z <= _maxY && pChara->getPos().z >= _minY )
2017-08-08 13:53:47 +02:00
{
uint32_t x = getPosX( pChara->getPos().x );
uint32_t y = getPosY( pChara->getPos().z );
2017-08-08 13:53:47 +02:00
updateCellActivity( x, y, 3 );
}
m_playerMap.erase( pChara->getId() );
2017-08-08 13:53:47 +02:00
onLeaveTerritory( *pChara->getAsPlayer() );
2017-08-08 13:53:47 +02:00
}
// remove from lists of other actors
pChara->removeFromInRange();
pChara->clearInRangeSet();
2017-08-08 13:53:47 +02:00
}
2018-02-11 23:52:44 +01:00
void Core::Zone::queueOutPacketForRange( Entity::Player& sourcePlayer, uint32_t range, Network::Packets::GamePacketPtr pPacketEntry )
2017-08-08 13:53:47 +02:00
{
if( g_territoryMgr.isPrivateTerritory( getTerritoryId() ) )
return;
2017-08-08 13:53:47 +02:00
for( auto it = m_playerMap.begin(); it != m_playerMap.end(); ++it )
{
float distance = Math::Util::distance( sourcePlayer.getPos().x,
sourcePlayer.getPos().y,
sourcePlayer.getPos().z,
2017-08-08 13:53:47 +02:00
( *it ).second->getPos().x,
( *it ).second->getPos().y,
( *it ).second->getPos().z );
if( ( distance < range ) && sourcePlayer.getId() != ( *it ).second->getId() )
2017-08-08 13:53:47 +02:00
{
auto pSession = g_serverZone.getSession( ( *it ).second->getId() );
pPacketEntry->setValAt< uint32_t >( 0x08, ( *it ).second->getId() );
2017-08-08 13:53:47 +02:00
if( pSession )
pSession->getZoneConnection()->queueOutPacket( pPacketEntry );
}
}
}
2018-02-11 23:52:44 +01:00
uint32_t Core::Zone::getTerritoryId() const
2017-08-08 13:53:47 +02:00
{
2018-01-27 23:52:49 +01:00
return m_territoryId;
2017-08-08 13:53:47 +02:00
}
2018-02-11 23:52:44 +01:00
uint32_t Core::Zone::getGuId() const
2017-08-08 13:53:47 +02:00
{
2018-01-27 23:52:49 +01:00
return m_guId;
2017-08-08 13:53:47 +02:00
}
2018-02-11 23:52:44 +01:00
const std::string& Core::Zone::getName() const
2017-08-08 13:53:47 +02:00
{
2018-01-27 23:52:49 +01:00
return m_placeName;
2017-08-08 13:53:47 +02:00
}
2018-02-11 23:52:44 +01:00
const std::string& Core::Zone::getInternalName() const
2017-08-08 13:53:47 +02:00
{
2018-01-27 23:52:49 +01:00
return m_internalName;
2017-08-08 13:53:47 +02:00
}
2018-02-11 23:52:44 +01:00
std::size_t Core::Zone::getPopCount() const
2017-08-08 13:53:47 +02:00
{
return m_playerMap.size();
}
2018-02-11 23:52:44 +01:00
bool Core::Zone::checkWeather()
2017-08-08 13:53:47 +02:00
{
if( m_weatherOverride != Common::Weather::None )
2017-08-08 13:53:47 +02:00
{
if( m_weatherOverride != m_currentWeather )
2017-08-08 13:53:47 +02:00
{
m_currentWeather = m_weatherOverride;
g_log.debug( "[Zone:" + m_internalName + "] overriding weather to : " +
std::to_string( static_cast< uint8_t >( m_weatherOverride ) ) );
2017-08-08 13:53:47 +02:00
return true;
}
}
else
{
auto nextWeather = getNextWeather();
if( nextWeather != m_currentWeather )
2017-08-08 13:53:47 +02:00
{
m_currentWeather = nextWeather;
g_log.debug( "[Zone:" + m_internalName + "] changing weather to : " +
std::to_string( static_cast< uint8_t >( nextWeather ) ) );
2017-08-08 13:53:47 +02:00
return true;
}
}
return false;
}
2018-02-21 12:48:27 +01:00
/*
2018-02-11 23:52:44 +01:00
void Core::Zone::updateBnpcs( int64_t tickCount )
2017-08-08 13:53:47 +02:00
{
if( ( tickCount - m_lastMobUpdate ) > 250 )
{
m_lastMobUpdate = tickCount;
uint32_t currTime = static_cast< uint32_t >( time( nullptr ) );
for( auto it3 = m_BattleNpcDeadMap.begin(); it3 != m_BattleNpcDeadMap.end(); ++it3 )
{
Entity::BattleNpcPtr pBNpc = *it3;
if( ( currTime - pBNpc->getTimeOfDeath() ) > 60 )
{
pBNpc->resetHp();
pBNpc->resetMp();
pBNpc->resetPos();
pushActor( pBNpc );
m_BattleNpcDeadMap.erase( it3 );
break;
}
}
for( auto entry : m_BattleNpcMap )
{
Entity::BattleNpcPtr pBNpc = entry.second;
2017-08-08 13:53:47 +02:00
if( !pBNpc )
continue;
if( !pBNpc->isAlive() && currTime - pBNpc->getTimeOfDeath() > ( 10 ) )
{
removeActor( pBNpc );
m_BattleNpcDeadMap.insert( pBNpc );
break;
}
2017-08-08 13:53:47 +02:00
pBNpc->update( tickCount );
}
}
}
2018-02-21 12:48:27 +01:00
*/
2017-08-08 13:53:47 +02:00
2018-02-11 23:52:44 +01:00
bool Core::Zone::update( uint32_t currTime )
2017-08-08 13:53:47 +02:00
{
int64_t tickCount = Util::getTimeMs();
//TODO: this should be moved to a updateWeather call and pulled out of updateSessions
2017-08-08 13:53:47 +02:00
bool changedWeather = checkWeather();
updateSessions( changedWeather );
2018-02-21 12:48:27 +01:00
//updateBnpcs( tickCount );
onUpdate( currTime );
return true;
}
void Core::Zone::updateSessions( bool changedWeather )
{
2017-08-08 13:53:47 +02:00
auto it = m_sessionSet.begin();
2017-08-08 13:53:47 +02:00
// update sessions in this zone
for( ; it != m_sessionSet.end(); )
{
auto pSession = ( *it );
2017-08-08 13:53:47 +02:00
if( !pSession )
{
it = m_sessionSet.erase(it );
2017-08-08 13:53:47 +02:00
continue;
}
// this session is not linked to this area anymore, remove it from zone session list
if( ( !pSession->getPlayer()->getCurrentZone() ) ||
( pSession->getPlayer()->getCurrentZone() != shared_from_this() ) )
2017-08-08 13:53:47 +02:00
{
if( pSession->getPlayer()->getCell() )
removeActor(pSession->getPlayer() );
2017-08-08 13:53:47 +02:00
it = m_sessionSet.erase(it );
2017-08-08 13:53:47 +02:00
continue;
}
if( changedWeather )
{
Core::Network::Packets::ZoneChannelPacket< Core::Network::Packets::Server::FFXIVIpcWeatherChange >
weatherChangePacket( pSession->getPlayer()->getId() );
weatherChangePacket.data().weatherId = static_cast< uint8_t >( m_currentWeather );
2017-08-08 13:53:47 +02:00
weatherChangePacket.data().delay = 5.0f;
pSession->getPlayer()->queuePacket( weatherChangePacket );
}
// perform session duties
pSession->update();
++it;
}
}
2018-02-11 23:52:44 +01:00
bool Core::Zone::isCellActive( uint32_t x, uint32_t y )
2017-08-08 13:53:47 +02:00
{
uint32_t endX = ( ( x + 1 ) <= _sizeX ) ? x + 1 : ( _sizeX - 1 );
uint32_t endY = ( ( y + 1 ) <= _sizeY ) ? y + 1 : ( _sizeY - 1 );
uint32_t startX = x > 0 ? x - 1 : 0;
uint32_t startY = y > 0 ? y - 1 : 0;
uint32_t posX;
uint32_t posY;
Cell* pCell;
for( posX = startX; posX <= endX; posX++ )
{
for( posY = startY; posY <= endY; posY++ )
{
pCell = getCell( posX, posY );
if( pCell && ( pCell->hasPlayers() || pCell->isForcedActive() ) )
return true;
}
}
return false;
}
2018-02-11 23:52:44 +01:00
void Core::Zone::updateCellActivity( uint32_t x, uint32_t y, int32_t radius )
2017-08-08 13:53:47 +02:00
{
uint32_t endX = ( x + radius ) <= _sizeX ? x + radius : ( _sizeX - 1 );
uint32_t endY = ( y + radius ) <= _sizeY ? y + radius : ( _sizeY - 1 );
uint32_t startX = x - radius > 0 ? x - radius : 0;
uint32_t startY = y - radius > 0 ? y - radius : 0;
uint32_t posX, posY;
Cell* pCell;
for( posX = startX; posX <= endX; posX++ )
{
for( posY = startY; posY <= endY; posY++ )
{
pCell = getCell( posX, posY );
if( !pCell )
{
if( isCellActive( posX, posY ) )
{
pCell = create( posX, posY );
pCell->init( posX, posY, shared_from_this() );
pCell->setActivity( true );
assert( !pCell->isLoaded() );
}
}
else
{
//Cell is now active
if( isCellActive( posX, posY ) && !pCell->isActive() )
{
pCell->setActivity( true );
if( !pCell->isLoaded() )
{
2018-02-21 12:48:27 +01:00
2017-08-08 13:53:47 +02:00
}
}
else if( !isCellActive( posX, posY ) && pCell->isActive() )
pCell->setActivity( false );
}
}
}
}
void Core::Zone::updateActorPosition( Entity::Chara &actor )
2017-08-08 13:53:47 +02:00
{
if( actor.getCurrentZone() != shared_from_this() )
2017-08-08 13:53:47 +02:00
return;
2018-02-18 22:53:12 +01:00
//actor.checkInRangeActors();
2017-08-08 13:53:47 +02:00
uint32_t cellX = getPosX( actor.getPos().x );
uint32_t cellY = getPosY( actor.getPos().z );
2017-08-08 13:53:47 +02:00
if( cellX >= _sizeX || cellY >= _sizeY )
return;
Cell* pCell = getCell( cellX, cellY );
Cell* pOldCell = actor.m_pCell;
2017-08-08 13:53:47 +02:00
if( !pCell )
{
pCell = create( cellX, cellY );
pCell->init( cellX, cellY, shared_from_this() );
}
// If object moved cell
if( pCell != pOldCell )
{
if( pOldCell )
pOldCell->removeChara(actor.getAsChara());
2017-08-08 13:53:47 +02:00
pCell->addChara(actor.getAsChara());
actor.m_pCell = pCell;
2017-08-08 13:53:47 +02:00
// if player we need to update cell activity
// radius = 2 is used in order to update both
// old and new cells
if( actor.isPlayer() )
2017-08-08 13:53:47 +02:00
{
updateCellActivity( cellX, cellY, 2 );
if( pOldCell != nullptr )
{
// only do the second check if theres -/+ 2 difference
if( abs( ( int32_t ) cellX - ( int32_t ) pOldCell->m_posX ) > 2 ||
abs( ( int32_t ) cellY - ( int32_t ) pOldCell->m_posY ) > 2 )
2017-08-08 13:53:47 +02:00
updateCellActivity( pOldCell->m_posX, pOldCell->m_posY, 2 );
}
}
}
// update in range actor set
uint32_t endX = cellX <= _sizeX ? cellX + 1 : ( _sizeX - 1 );
uint32_t endY = cellY <= _sizeY ? cellY + 1 : ( _sizeY - 1 );
uint32_t startX = cellX > 0 ? cellX - 1 : 0;
uint32_t startY = cellY > 0 ? cellY - 1 : 0;
uint32_t posX, posY;
for( posX = startX; posX <= endX; ++posX )
{
for( posY = startY; posY <= endY; ++posY )
{
pCell = getCell( posX, posY );
if( pCell )
updateInRangeSet( actor.getAsChara(), pCell );
2017-08-08 13:53:47 +02:00
}
}
}
void Core::Zone::updateInRangeSet( Entity::CharaPtr pChara, Cell* pCell )
2017-08-08 13:53:47 +02:00
{
if( pCell == nullptr )
return;
2018-02-08 15:29:46 +01:00
// TODO: make sure gms can overwrite this. Potentially temporary solution
2018-02-08 15:25:59 +01:00
if( g_territoryMgr.isPrivateTerritory( getTerritoryId() ) )
return;
Entity::CharaPtr pCurAct;
2017-08-08 13:53:47 +02:00
auto iter = pCell->m_charas.begin();
2017-08-08 13:53:47 +02:00
float fRange = 70.0f;
int32_t count = 0;
while( iter != pCell->m_charas.end() )
2017-08-08 13:53:47 +02:00
{
pCurAct = *iter;
++iter;
if( !pCurAct || pCurAct == pChara )
2017-08-08 13:53:47 +02:00
continue;
float distance = Math::Util::distance( pCurAct->getPos().x, pCurAct->getPos().y, pCurAct->getPos().z,
pChara->getPos().x, pChara->getPos().y, pChara->getPos().z );
2017-08-08 13:53:47 +02:00
2018-02-18 22:53:12 +01:00
bool isInRange = ( fRange == 0.0f || distance <= fRange );
bool isInRangeSet = pChara->isInRangeSet( pCurAct );
2017-08-08 13:53:47 +02:00
2018-02-18 22:53:12 +01:00
// Add if we are not ourself and range == 0 or distance is withing range.
if( isInRange && !isInRangeSet )
{
2017-08-08 13:53:47 +02:00
if( pChara->isPlayer() )
2017-08-08 13:53:47 +02:00
{
auto pOwnPlayer = pChara->getAsPlayer();
2017-08-08 13:53:47 +02:00
if( !pOwnPlayer->isLoadingComplete() )
continue;
// this is a hack to limit actor spawn in one packetset
2017-08-08 13:53:47 +02:00
count++;
if( count > 12 )
2017-08-08 13:53:47 +02:00
break;
pChara->addInRangeChara( pCurAct );
pCurAct->addInRangeChara( pChara );
2017-08-08 13:53:47 +02:00
// spawn the actor for the player
pCurAct->spawn( pOwnPlayer );
if( pCurAct->isPlayer() )
{
auto pPlayer = pCurAct->getAsPlayer();
if( !pPlayer->isLoadingComplete() )
continue;
pChara->spawn( pPlayer );
2017-08-08 13:53:47 +02:00
}
}
else if( ( pChara->isBattleNpc() ) && pCurAct->isPlayer() && pChara->isAlive() )
2017-08-08 13:53:47 +02:00
{
auto pPlayer = pCurAct->getAsPlayer();
if( pPlayer->isLoadingComplete() )
{
pChara->spawn( pPlayer );
pCurAct->addInRangeChara( pChara );
pChara->addInRangeChara( pCurAct );
2017-08-08 13:53:47 +02:00
}
}
else
{
pChara->addInRangeChara( pCurAct );
pCurAct->addInRangeChara( pChara );
2017-08-08 13:53:47 +02:00
}
}
2018-02-18 22:53:12 +01:00
else if( !isInRange && isInRangeSet )
{
pCurAct->removeInRangeChara( *pChara );
2018-02-18 22:53:12 +01:00
if( pChara->getCurrentZone() != pCurAct->getCurrentZone() )
2018-02-18 22:53:12 +01:00
continue;
pChara->removeInRangeChara( *pCurAct );
2018-02-18 22:53:12 +01:00
}
2017-08-08 13:53:47 +02:00
}
}
2018-02-11 23:52:44 +01:00
void Core::Zone::onEnterTerritory( Entity::Player& player )
{
g_log.debug( "Zone::onEnterTerritory: Zone#" + std::to_string( getGuId() ) + "|" + std::to_string( getTerritoryId() ) +
+ ", Entity#" + std::to_string( player.getId() ) );
}
2018-02-11 23:52:44 +01:00
void Core::Zone::onLeaveTerritory( Entity::Player& player )
{
g_log.debug( "Zone::onLeaveTerritory: Zone#" + std::to_string( getGuId() ) + "|" + std::to_string( getTerritoryId() ) +
+ ", Entity#" + std::to_string( player.getId() ) );
}
2018-02-11 23:52:44 +01:00
void Core::Zone::onUpdate( uint32_t currTime )
{
}
2018-02-11 23:52:44 +01:00
void Core::Zone::onFinishLoading( Entity::Player& player )
{
}
2018-02-11 23:52:44 +01:00
void Core::Zone::onInitDirector( Entity::Player& player )
{
}
void Core::Zone::registerEObj( Entity::EventObjectPtr object )
{
if( !object )
return;
//object->setParentInstance( InstanceContentPtr( this ) );
2018-02-21 11:28:34 +01:00
m_eventObjects[object->getId()] = object;
g_log.debug( "Registered instance eobj: " + std::to_string( object->getId() ) );
}
Core::Entity::EventObjectPtr Core::Zone::getEObj( uint32_t objId )
{
2018-02-21 11:28:34 +01:00
auto obj = m_eventObjects.find( objId );
if( obj == m_eventObjects.end() )
return nullptr;
return obj->second;
}
void Core::Zone::updateEObj( Entity::EventObjectPtr object )
{
if( !object )
return;
for( const auto& playerIt : m_playerMap )
{
// send that packet with le data
Network::Packets::ZoneChannelPacket< Network::Packets::Server::FFXIVIpcObjectSpawn > eobjStatePacket( playerIt.second->getId() );
eobjStatePacket.data().objKind = object->getObjKind();
eobjStatePacket.data().state = object->getState();
eobjStatePacket.data().objId = object->getId();
eobjStatePacket.data().hierachyId = object->getHierachyId();
eobjStatePacket.data().position = object->getPos();
// ????
//eobjStatePacket.data().levelId = 4236873;
//eobjStatePacket.data().unknown2 = 5;
//eobjStatePacket.data().unknown1C = 1065353216;
//eobjStatePacket.data().unknown20 = 2147423605;
//eobjStatePacket.data().actorId = 1074105831;
//eobjStatePacket.data().unknown = 1;
playerIt.second->queuePacket( eobjStatePacket );
}
}