1
Fork 0
mirror of https://github.com/SapphireServer/Sapphire.git synced 2025-05-04 01:37:47 +00:00

Basics of instance binding system

This commit is contained in:
Mordred 2018-03-15 23:37:21 +01:00
parent 229443ad57
commit efa0a81d9e
4 changed files with 96 additions and 2 deletions

View file

@ -709,6 +709,47 @@ void Core::DebugCommandHandler::instance( char* data, Entity::Player &player, bo
else
player.sendDebug( "Failed to create instance with id: " + std::to_string( instanceContentId ) );
}
else if( subCommand == "bind" )
{
uint32_t instanceId;
sscanf( params.c_str(), "%d", &instanceId );
auto instance = pTeriMgr->getInstanceZonePtr( instanceId );
if( instance )
{
auto pInstanceContent = instance->getAsInstanceContent();
pInstanceContent->bindPlayer( player.getId() );
player.sendDebug(
"Now bound to instance with id: " + std::to_string( pInstanceContent->getGuId() ) +
" -> " + pInstanceContent->getName() );
}
else
player.sendDebug( "Unknown instance with id: " + std::to_string( instanceId ) );
}
else if( subCommand == "unbind" )
{
uint32_t instanceId;
sscanf( params.c_str(), "%d", &instanceId );
auto instance = pTeriMgr->getInstanceZonePtr( instanceId );
if( !instance )
{
player.sendDebug( "Unknown instance with id: " + std::to_string( instanceId ) );
return;
}
auto pInstanceContent = instance->getAsInstanceContent();
if( pInstanceContent->isPlayerBound( player.getId() ) )
{
pInstanceContent->unbindPlayer( player.getId() );
player.sendDebug(
"Now unbound from instance with id: " + std::to_string( pInstanceContent->getGuId() ) +
" -> " + pInstanceContent->getName() );
}
else
player.sendDebug( "Player not bound to instance with id: " + std::to_string( instanceId ) );
}
else if( subCommand == "createzone" || subCommand == "crz" )
{
uint32_t zoneId;

View file

@ -15,6 +15,7 @@
#include "Zone/TerritoryMgr.h"
#include "Zone/Zone.h"
#include "Zone/InstanceContent.h"
#include "Zone/ZonePosition.h"
#include "Network/GameConnection.h"
@ -415,6 +416,15 @@ void Core::Network::GameConnection::gm1Handler( const Packets::GamePacket& inPac
{
player.sendDebug( "Found instance: " + instance->getName() + ", id: " + std::to_string( param1 ) );
// if the zone is an instanceContent instance, make sure the player is actually bound to it
auto pInstance = instance->getAsInstanceContent();
if( !pInstance->isPlayerBound( player.getId() ) )
{
player.sendUrgent( "Not able to join instance: " + std::to_string( param1 ) );
player.sendUrgent( "Player not bound! ( run !instance bind <instanceId> first ) " + std::to_string( param1 ) );
break;
}
player.setInstance( instance );
}
else if( !pTeriMgr->isValidTerritory( param1 ) )
@ -429,9 +439,11 @@ void Core::Network::GameConnection::gm1Handler( const Packets::GamePacket& inPac
player.sendUrgent( "No zone instance found for " + std::to_string( param1 ) );
break;
}
targetPlayer->setPos( targetPlayer->getPos() );
targetPlayer->performZoning( param1, targetPlayer->getPos(), 0 );
player.sendNotice( targetPlayer->getName() + " was warped to zone " + std::to_string( param1 ) + " (" + pZone->getName() + ")" );
player.sendNotice( targetPlayer->getName() + " was warped to zone " +
std::to_string( param1 ) + " (" + pZone->getName() + ")" );
}
break;
}

View file

@ -101,6 +101,10 @@ void Core::InstanceContent::onLeaveTerritory( Entity::Player& player )
void Core::InstanceContent::onUpdate( uint32_t currTime )
{
// TODO: check all players if still bound, if not, remove
// needs to happen regardless of state
switch( m_state )
{
case Created:
@ -109,6 +113,7 @@ void Core::InstanceContent::onUpdate( uint32_t currTime )
if( m_playerMap.size() < 1 )
return;
// TODO: 1. check all bound players instead of just players in instance at the time
for( const auto& playerIt : m_playerMap )
{
if( !playerIt.second->isLoadingComplete() ||
@ -410,3 +415,27 @@ uint16_t Core::InstanceContent::getCurrentBGM() const
{
return m_currentBgm;
}
bool Core::InstanceContent::bindPlayer( uint32_t playerId )
{
// if player already bound, return false
if( m_boundPlayerIds.count( playerId ) )
return false;
// TODO: do not allow binding of players if instance already has all it can take
// if( m_boundPlayerIds.size() >= party resttrictions )
// return false;
m_boundPlayerIds.insert( playerId );
return true;
}
bool Core::InstanceContent::isPlayerBound( uint32_t playerId ) const
{
return m_boundPlayerIds.count( playerId ) > 0;
}
void Core::InstanceContent::unbindPlayer( uint32_t playerId )
{
m_boundPlayerIds.erase( playerId );
}

View file

@ -64,10 +64,19 @@ public:
Entity::EventObjectPtr getEObjByName( const std::string& name );
/*! binds a player to the instance */
bool bindPlayer( uint32_t playerId );
/*! removes bind of player from the instance */
void unbindPlayer( uint32_t playerId );
/*! return true if the player is bound to the instance */
bool isPlayerBound( uint32_t playerId ) const;
/*! number of milliseconds after all players are ready for the instance to commence (spawn circle removed) */
const uint32_t instanceStartDelay = 1250;
private:
Event::DirectorPtr m_pDirector;
boost::shared_ptr< Core::Data::InstanceContent > m_instanceContentInfo;
uint32_t m_instanceContentId;
InstanceContentState m_state;
@ -81,6 +90,9 @@ private:
std::map< std::string, Entity::EventObjectPtr > m_eventObjectMap;
std::unordered_map< uint32_t, Entity::EventObjectPtr > m_eventIdToObjectMap;
std::set< uint32_t > m_spawnedPlayers;
// the players which are bound to the instance, regardless of inside or offline
std::set< uint32_t > m_boundPlayerIds;
};
}