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

Basics of instance binding system

This commit is contained in:
Mordred 2018-03-15 23:37:21 +01:00
parent ac94e9beff
commit f5ff43857e
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 else
player.sendDebug( "Failed to create instance with id: " + std::to_string( instanceContentId ) ); 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" ) else if( subCommand == "createzone" || subCommand == "crz" )
{ {
uint32_t zoneId; uint32_t zoneId;

View file

@ -15,6 +15,7 @@
#include "Zone/TerritoryMgr.h" #include "Zone/TerritoryMgr.h"
#include "Zone/Zone.h" #include "Zone/Zone.h"
#include "Zone/InstanceContent.h"
#include "Zone/ZonePosition.h" #include "Zone/ZonePosition.h"
#include "Network/GameConnection.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 ) ); 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 ); player.setInstance( instance );
} }
else if( !pTeriMgr->isValidTerritory( param1 ) ) 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 ) ); player.sendUrgent( "No zone instance found for " + std::to_string( param1 ) );
break; break;
} }
targetPlayer->setPos( targetPlayer->getPos() ); targetPlayer->setPos( targetPlayer->getPos() );
targetPlayer->performZoning( param1, targetPlayer->getPos(), 0 ); 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; break;
} }

View file

@ -101,6 +101,10 @@ void Core::InstanceContent::onLeaveTerritory( Entity::Player& player )
void Core::InstanceContent::onUpdate( uint32_t currTime ) 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 ) switch( m_state )
{ {
case Created: case Created:
@ -109,6 +113,7 @@ void Core::InstanceContent::onUpdate( uint32_t currTime )
if( m_playerMap.size() < 1 ) if( m_playerMap.size() < 1 )
return; return;
// TODO: 1. check all bound players instead of just players in instance at the time
for( const auto& playerIt : m_playerMap ) for( const auto& playerIt : m_playerMap )
{ {
if( !playerIt.second->isLoadingComplete() || if( !playerIt.second->isLoadingComplete() ||
@ -410,3 +415,27 @@ uint16_t Core::InstanceContent::getCurrentBGM() const
{ {
return m_currentBgm; 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 ); 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) */ /*! number of milliseconds after all players are ready for the instance to commence (spawn circle removed) */
const uint32_t instanceStartDelay = 1250; const uint32_t instanceStartDelay = 1250;
private: private:
Event::DirectorPtr m_pDirector;
boost::shared_ptr< Core::Data::InstanceContent > m_instanceContentInfo; boost::shared_ptr< Core::Data::InstanceContent > m_instanceContentInfo;
uint32_t m_instanceContentId; uint32_t m_instanceContentId;
InstanceContentState m_state; InstanceContentState m_state;
@ -81,6 +90,9 @@ private:
std::map< std::string, Entity::EventObjectPtr > m_eventObjectMap; std::map< std::string, Entity::EventObjectPtr > m_eventObjectMap;
std::unordered_map< uint32_t, Entity::EventObjectPtr > m_eventIdToObjectMap; std::unordered_map< uint32_t, Entity::EventObjectPtr > m_eventIdToObjectMap;
std::set< uint32_t > m_spawnedPlayers; 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;
}; };
} }