mirror of
https://github.com/polserver/polserver
synced 2026-08-13 08:23:08 -04:00
290 lines
7 KiB
C++
290 lines
7 KiB
C++
|
|
#include "guilds.h"
|
|
|
|
#include <stddef.h>
|
|
#include <string>
|
|
|
|
#include "../clib/cfgelem.h"
|
|
#include "../clib/cfgfile.h"
|
|
#include "../clib/cfgsect.h"
|
|
#include "../clib/fileutil.h"
|
|
#include "../clib/streamsaver.h"
|
|
#include "../plib/systemstate.h"
|
|
#include "fnsearch.h"
|
|
#include "globals/uvars.h"
|
|
#include "mobile/charactr.h"
|
|
#include "ufunc.h"
|
|
#include "uobject.h"
|
|
|
|
namespace Pol
|
|
{
|
|
namespace Core
|
|
{
|
|
SerialSet::SerialSet( Clib::ConfigElem& elem, const char* tag )
|
|
{
|
|
unsigned int tmp;
|
|
while ( elem.remove_prop( tag, &tmp ) )
|
|
{
|
|
insert( tmp );
|
|
}
|
|
}
|
|
|
|
void SerialSet::writeOn( Clib::StreamWriter& os, const char* tag ) const
|
|
{
|
|
for ( const_iterator citr = begin(), citrend = end(); citr != citrend; ++citr )
|
|
{
|
|
os() << "\t" << tag << "\t0x" << fmt::hex( *citr ) << pf_endl;
|
|
}
|
|
}
|
|
|
|
Guild::Guild( Clib::ConfigElem& elem )
|
|
: _guildid( elem.remove_ushort( "GUILDID" ) ),
|
|
_member_serials( elem, "MEMBER" ),
|
|
_allyguild_serials( elem, "ALLYGUILD" ),
|
|
_enemyguild_serials( elem, "ENEMYGUILD" ),
|
|
_proplist( Core::CPropProfiler::Type::GUILD ),
|
|
_disbanded( false )
|
|
{
|
|
_proplist.readProperties( elem );
|
|
}
|
|
|
|
Guild::Guild( unsigned int guildid )
|
|
: _guildid( guildid ),
|
|
_member_serials(),
|
|
_allyguild_serials(),
|
|
_enemyguild_serials(),
|
|
_proplist( Core::CPropProfiler::Type::GUILD ),
|
|
_disbanded( false )
|
|
{
|
|
if ( _guildid >= Core::gamestate.nextguildid )
|
|
Core::gamestate.nextguildid = _guildid + 1;
|
|
}
|
|
|
|
void Guild::registerWithMembers()
|
|
{
|
|
for ( SerialSet::iterator itr = _member_serials.begin(); itr != _member_serials.end(); /* */ )
|
|
{
|
|
unsigned int mserial = ( *itr );
|
|
SerialSet::iterator last_itr = itr;
|
|
++itr;
|
|
|
|
Mobile::Character* chr = system_find_mobile( mserial );
|
|
if ( chr != nullptr )
|
|
{
|
|
chr->guild( this );
|
|
}
|
|
else
|
|
{
|
|
_member_serials.erase( last_itr );
|
|
}
|
|
}
|
|
}
|
|
|
|
void Guild::update_online_members()
|
|
{
|
|
// FIXME : All of guilds.cpp iterator's need rewritten. Turley found a much better method
|
|
// used in the party system.
|
|
// NOTE: stlport seems to not return save itr on erase, but with a list container the iterator
|
|
// should stay valid
|
|
for ( SerialSet::iterator itr = _member_serials.begin(), end = _member_serials.end(); itr != end;
|
|
/* */ )
|
|
{
|
|
unsigned int mserial = ( *itr );
|
|
SerialSet::iterator last_itr = itr;
|
|
++itr;
|
|
|
|
Mobile::Character* chr = Core::system_find_mobile( mserial );
|
|
if ( chr != nullptr )
|
|
{
|
|
if ( chr->client )
|
|
{
|
|
send_move( chr->client, chr );
|
|
send_remove_character_to_nearby_cansee( chr );
|
|
send_create_mobile_to_nearby_cansee( chr );
|
|
}
|
|
}
|
|
else
|
|
{
|
|
_member_serials.erase( last_itr );
|
|
}
|
|
}
|
|
}
|
|
|
|
void Guild::update_online_members_remove( Mobile::Character* chr )
|
|
{
|
|
if ( chr->client )
|
|
{
|
|
send_move( chr->client, chr );
|
|
send_remove_character_to_nearby_cansee( chr );
|
|
send_create_mobile_to_nearby_cansee( chr );
|
|
}
|
|
}
|
|
|
|
unsigned int Guild::guildid() const
|
|
{
|
|
return _guildid;
|
|
}
|
|
|
|
bool Guild::disbanded() const
|
|
{
|
|
return _disbanded;
|
|
}
|
|
|
|
void Guild::disband()
|
|
{
|
|
_disbanded = true;
|
|
}
|
|
|
|
bool Guild::hasMembers() const
|
|
{
|
|
return !_member_serials.empty();
|
|
}
|
|
|
|
bool Guild::hasAllies() const
|
|
{
|
|
return !_allyguild_serials.empty();
|
|
}
|
|
bool Guild::hasAlly( const Guild* g2 ) const
|
|
{
|
|
return _allyguild_serials.count( g2->guildid() ) != 0;
|
|
}
|
|
|
|
bool Guild::hasEnemies() const
|
|
{
|
|
return !_enemyguild_serials.empty();
|
|
}
|
|
bool Guild::hasEnemy( const Guild* g2 ) const
|
|
{
|
|
return _enemyguild_serials.count( g2->guildid() ) != 0;
|
|
}
|
|
|
|
|
|
void Guild::printOn( Clib::StreamWriter& sw ) const
|
|
{
|
|
sw() << "Guild" << pf_endl << "{" << pf_endl << "\tGuildId\t" << _guildid << pf_endl;
|
|
_member_serials.writeOn( sw, "Member" );
|
|
_allyguild_serials.writeOn( sw, "AllyGuild" );
|
|
_enemyguild_serials.writeOn( sw, "EnemyGuild" );
|
|
_proplist.printProperties( sw );
|
|
sw() << "}" << pf_endl << pf_endl;
|
|
// sw.flush();
|
|
}
|
|
|
|
void Guild::addMember( unsigned int serial )
|
|
{
|
|
_member_serials.insert( serial );
|
|
}
|
|
|
|
std::vector<Mobile::Character*> Guild::get_members( bool include_offline ) const
|
|
{
|
|
std::vector<Mobile::Character*> ret;
|
|
|
|
for ( auto& serial : _member_serials )
|
|
{
|
|
Mobile::Character* chr = Core::system_find_mobile( serial );
|
|
if ( chr && ( include_offline || chr->logged_in() ) )
|
|
ret.push_back( chr );
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
bool Guild::AreAllies( Guild* g1, Guild* g2 )
|
|
{
|
|
return ( g1 == g2 || g1->hasAlly( g2 ) );
|
|
}
|
|
bool Guild::AreEnemies( Guild* g1, Guild* g2 )
|
|
{
|
|
return g1->hasEnemy( g2 );
|
|
}
|
|
|
|
void register_guilds()
|
|
{
|
|
for ( Guilds::iterator itr = Core::gamestate.guilds.begin(); itr != Core::gamestate.guilds.end();
|
|
++itr )
|
|
{
|
|
Guild* guild = ( *itr ).second.get();
|
|
guild->registerWithMembers();
|
|
}
|
|
}
|
|
|
|
void read_guilds_dat()
|
|
{
|
|
std::string guildsfile = Plib::systemstate.config.world_data_path + "guilds.txt";
|
|
|
|
if ( !Clib::FileExists( guildsfile ) )
|
|
return;
|
|
|
|
Clib::ConfigFile cf( guildsfile );
|
|
Clib::ConfigSection sect_general( cf, "GENERAL", Clib::CST_UNIQUE );
|
|
Clib::ConfigSection sect_guild( cf, "GUILD", Clib::CST_NORMAL );
|
|
Clib::ConfigElem elem;
|
|
while ( cf.read( elem ) )
|
|
{
|
|
if ( sect_general.matches( elem ) )
|
|
{
|
|
Core::gamestate.nextguildid = elem.remove_ulong( "NEXTGUILDID", 1 );
|
|
}
|
|
else if ( sect_guild.matches( elem ) )
|
|
{
|
|
Guild* guild = new Guild( elem );
|
|
Core::gamestate.guilds[guild->guildid()].set( guild );
|
|
}
|
|
}
|
|
|
|
register_guilds();
|
|
}
|
|
|
|
void write_guilds( Clib::StreamWriter& sw )
|
|
{
|
|
sw() << "General" << pf_endl << "{" << pf_endl << "\tNextGuildId\t" << Core::gamestate.nextguildid
|
|
<< pf_endl << "}" << pf_endl << pf_endl;
|
|
|
|
for ( const auto& _guild : Core::gamestate.guilds )
|
|
{
|
|
const Guild* guild = _guild.second.get();
|
|
guild->printOn( sw );
|
|
}
|
|
}
|
|
|
|
Guild* Guild::FindOrCreateGuild( unsigned int guildid, unsigned int memberserial )
|
|
{
|
|
Guilds::iterator itr = Core::gamestate.guilds.find( guildid );
|
|
Guild* guild = nullptr;
|
|
if ( itr != Core::gamestate.guilds.end() )
|
|
guild = ( *itr ).second.get();
|
|
else
|
|
{
|
|
guild = new Guild( guildid );
|
|
Core::gamestate.guilds[guildid].set( guild );
|
|
}
|
|
|
|
// this is called from Character::readCommonProperties, which assigns
|
|
// chr->guild (so we don't do it here)
|
|
guild->addMember( memberserial );
|
|
|
|
return guild;
|
|
}
|
|
Guild* Guild::FindGuild( unsigned int guildid )
|
|
{
|
|
Guilds::iterator itr = Core::gamestate.guilds.find( guildid );
|
|
Guild* guild = nullptr;
|
|
|
|
if ( itr != Core::gamestate.guilds.end() )
|
|
guild = ( *itr ).second.get();
|
|
|
|
return guild;
|
|
}
|
|
|
|
size_t Guild::estimateSize() const
|
|
{
|
|
return sizeof( unsigned int ) /*_guildid*/
|
|
+ 3 * sizeof( void* ) +
|
|
_member_serials.size() * ( sizeof( unsigned int ) + 3 * sizeof( void* ) ) +
|
|
3 * sizeof( void* ) +
|
|
_allyguild_serials.size() * ( sizeof( unsigned int ) + 3 * sizeof( void* ) ) +
|
|
3 * sizeof( void* ) +
|
|
_enemyguild_serials.size() * ( sizeof( unsigned int ) + 3 * sizeof( void* ) ) +
|
|
_proplist.estimatedSize() + sizeof( bool ); /*_disbanded*/
|
|
}
|
|
} // namespace Core
|
|
} // namespace Pol
|