2018-03-29 17:01:57 -04:00
2019-07-07 20:56:15 +00:00
# include <StdAfx.h>
2018-03-29 17:01:57 -04:00
# include "AllegianceManager.h"
# include "World.h"
# include "Player.h"
# include "DatabaseIO.h"
# include "ChatMsgs.h"
2018-07-28 15:21:38 +01:00
# include "InferredPortalData.h"
# include "Util.h"
2018-08-14 19:46:16 +01:00
# include "Config.h"
2018-03-29 17:01:57 -04:00
DEFINE_PACK ( AllegianceInfo )
{
_info . Pack ( pWriter ) ;
}
DEFINE_UNPACK ( AllegianceInfo )
{
_info . UnPack ( pReader ) ;
return true ;
}
AllegianceTreeNode : : AllegianceTreeNode ( )
{
}
AllegianceTreeNode : : ~ AllegianceTreeNode ( )
{
for ( auto & entry : _vassals )
delete entry . second ;
_vassals . clear ( ) ;
}
AllegianceTreeNode * AllegianceTreeNode : : FindCharByNameRecursivelySlow ( const std : : string & charName )
{
const char * targetName = charName . c_str ( ) ;
if ( targetName [ 0 ] = = ' + ' )
targetName + + ;
const char * compareName = _charName . c_str ( ) ;
if ( compareName [ 0 ] = = ' + ' )
compareName + + ;
2019-07-07 20:56:15 +00:00
if ( ! stricmp ( targetName , compareName ) )
2018-03-29 17:01:57 -04:00
{
return this ;
}
2018-04-30 22:39:01 -07:00
AllegianceTreeNode * node = nullptr ;
2018-03-29 17:01:57 -04:00
for ( auto & entry : _vassals )
{
if ( node = entry . second - > FindCharByNameRecursivelySlow ( charName ) )
break ;
}
return node ;
}
void AllegianceTreeNode : : FillAllegianceNode ( AllegianceNode * node )
{
node - > _data . _rank = _rank ;
node - > _data . _level = _level ;
2019-07-07 20:56:15 +00:00
node - > _data . _cp_cached = min ( uint64_t ( 4294967295ul ) , _cp_cached ) ;
node - > _data . _cp_tithed = min ( uint64_t ( 4294967295ul ) , _cp_tithed ) ;
2018-03-29 17:01:57 -04:00
node - > _data . _gender = _gender ;
node - > _data . _hg = _hg ;
node - > _data . _leadership = _leadership ;
node - > _data . _loyalty = _loyalty ;
node - > _data . _name = _charName ;
node - > _data . _id = _charID ;
2018-04-25 11:01:03 +00:00
// node->_data._allegiance_age = _unixTimeSwornAt; what unit is this and what does the client do with this information?
// node->_data._time_online = _ingameSecondsSworn; what unit is this and what does the client do with this information?
2018-03-29 17:01:57 -04:00
}
2018-07-12 14:41:21 -07:00
void AllegianceTreeNode : : UpdateWithWeenie ( CWeenieObject * weenie )
2018-03-29 17:01:57 -04:00
{
_charID = weenie - > GetID ( ) ;
_charName = weenie - > GetName ( ) ;
2018-04-30 22:39:01 -07:00
_hg = static_cast < HeritageGroup > ( weenie - > InqIntQuality ( HERITAGE_GROUP_INT , Invalid_HeritageGroup ) ) ;
_gender = static_cast < Gender > ( weenie - > InqIntQuality ( GENDER_INT , Invalid_Gender ) ) ;
2018-03-29 17:01:57 -04:00
_level = weenie - > InqIntQuality ( LEVEL_INT , 1 ) ;
_leadership = 0 ;
2019-07-07 20:56:15 +00:00
weenie - > m_Qualities . InqSkill ( LEADERSHIP_SKILL , * reinterpret_cast < uint32_t * > ( & _leadership ) , FALSE ) ;
2018-03-29 17:01:57 -04:00
_loyalty = 0 ;
2019-07-07 20:56:15 +00:00
weenie - > m_Qualities . InqSkill ( LOYALTY_SKILL , * reinterpret_cast < uint32_t * > ( & _loyalty ) , FALSE ) ;
2018-03-29 17:01:57 -04:00
}
DEFINE_PACK ( AllegianceTreeNode )
{
2019-07-07 20:56:15 +00:00
pWriter - > Write < uint32_t > ( 2 ) ; // version
pWriter - > Write < uint32_t > ( _charID ) ;
2018-03-29 17:01:57 -04:00
pWriter - > WriteString ( _charName ) ;
2019-07-07 20:56:15 +00:00
pWriter - > Write < uint32_t > ( _monarchID ) ;
pWriter - > Write < uint32_t > ( _patronID ) ;
2018-03-29 17:01:57 -04:00
pWriter - > Write < int > ( _hg ) ;
pWriter - > Write < int > ( _gender ) ;
2019-07-07 20:56:15 +00:00
pWriter - > Write < uint32_t > ( _rank ) ;
pWriter - > Write < uint32_t > ( _level ) ;
pWriter - > Write < uint32_t > ( _leadership ) ;
pWriter - > Write < uint32_t > ( _loyalty ) ;
pWriter - > Write < uint32_t > ( _numFollowers ) ;
pWriter - > Write < uint64_t > ( _cp_cached ) ;
pWriter - > Write < uint64_t > ( _cp_tithed ) ;
pWriter - > Write < uint64_t > ( _cp_pool_to_unload ) ;
pWriter - > Write < uint64_t > ( _unixTimeSwornAt ) ;
pWriter - > Write < uint64_t > ( _ingameSecondsSworn ) ;
pWriter - > Write < uint32_t > ( _vassals . size ( ) ) ;
2018-03-29 17:01:57 -04:00
for ( auto & entry : _vassals )
entry . second - > Pack ( pWriter ) ;
}
DEFINE_UNPACK ( AllegianceTreeNode )
{
2019-07-07 20:56:15 +00:00
uint32_t version = pReader - > Read < uint32_t > ( ) ; // version
_charID = pReader - > Read < uint32_t > ( ) ;
2018-03-29 17:01:57 -04:00
_charName = pReader - > ReadString ( ) ;
2019-07-07 20:56:15 +00:00
_monarchID = pReader - > Read < uint32_t > ( ) ;
_patronID = pReader - > Read < uint32_t > ( ) ;
2018-03-29 17:01:57 -04:00
_hg = ( HeritageGroup ) pReader - > Read < int > ( ) ;
_gender = ( Gender ) pReader - > Read < int > ( ) ;
2019-07-07 20:56:15 +00:00
_rank = pReader - > Read < uint32_t > ( ) ;
_level = pReader - > Read < uint32_t > ( ) ;
_leadership = pReader - > Read < uint32_t > ( ) ;
_loyalty = pReader - > Read < uint32_t > ( ) ;
_numFollowers = pReader - > Read < uint32_t > ( ) ;
_cp_cached = pReader - > Read < uint64_t > ( ) ;
_cp_tithed = pReader - > Read < uint64_t > ( ) ;
_cp_pool_to_unload = pReader - > Read < uint64_t > ( ) ;
2018-04-25 11:01:03 +00:00
if ( version < 2 ) {
_unixTimeSwornAt = time ( 0 ) ; // set to now
_ingameSecondsSworn = 1 ;
} else {
2019-07-07 20:56:15 +00:00
_unixTimeSwornAt = pReader - > Read < uint64_t > ( ) ;
_ingameSecondsSworn = pReader - > Read < uint64_t > ( ) ;
2018-04-25 11:01:03 +00:00
}
2018-03-29 17:01:57 -04:00
2019-07-07 20:56:15 +00:00
uint32_t numVassals = pReader - > Read < uint32_t > ( ) ;
for ( uint32_t i = 0 ; i < numVassals ; i + + )
2018-03-29 17:01:57 -04:00
{
AllegianceTreeNode * node = new AllegianceTreeNode ( ) ;
node - > UnPack ( pReader ) ;
_vassals [ node - > _charID ] = node ;
2019-01-15 14:11:21 -06:00
assert ( node - > _charID > = 0x50000000 & & node - > _charID < 0x60000000 ) ;
2018-03-29 17:01:57 -04:00
}
2019-01-15 14:11:21 -06:00
assert ( _charID > = 0x50000000 & & _charID < 0x60000000 ) ;
2018-03-29 17:01:57 -04:00
return true ;
}
AllegianceManager : : AllegianceManager ( )
{
Load ( ) ;
}
AllegianceManager : : ~ AllegianceManager ( )
{
Save ( ) ;
for ( auto & entry : _monarchs )
delete entry . second ;
_monarchs . clear ( ) ;
_directNodes . clear ( ) ;
for ( auto & entry : _allegInfos )
delete entry . second ;
_allegInfos . clear ( ) ;
}
void AllegianceManager : : Load ( )
{
void * data = NULL ;
2019-07-07 20:56:15 +00:00
unsigned long length = 0 ;
2018-03-29 17:01:57 -04:00
if ( g_pDBIO - > GetGlobalData ( DBIO_GLOBAL_ALLEGIANCE_DATA , & data , & length ) )
{
2019-01-15 14:11:21 -06:00
// convert to new table schema
2018-03-29 17:01:57 -04:00
BinaryReader reader ( data , length ) ;
UnPack ( & reader ) ;
2019-01-15 14:11:21 -06:00
2018-08-14 19:46:16 +01:00
int count = 0 ;
for ( auto alleg : _allegInfos ) {
if ( alleg . second - > _info . m_officerTitleList . empty ( ) ) {
2019-01-15 14:11:21 -06:00
alleg . second - > _info . m_officerTitleList = { " Speaker " , " Seneschal " , " Castellan " } ;
2018-08-14 19:46:16 +01:00
count + + ;
}
}
2019-01-15 14:11:21 -06:00
2018-08-14 19:46:16 +01:00
if ( ! count ) {
allAllegiancesUpdated = true ;
Save ( ) ;
WINLOG ( Temp , Normal , " Successfully updated all allegiances! \n " ) ;
}
2018-03-29 17:01:57 -04:00
}
2018-04-25 11:01:03 +00:00
m_LastSave = Timer : : cur_time ;
2018-03-29 17:01:57 -04:00
}
void AllegianceManager : : Save ( )
{
2018-08-14 19:46:16 +01:00
for ( auto ai : _allegInfos ) {
ai . second - > _info . packForDB = true ;
}
2018-03-29 17:01:57 -04:00
BinaryWriter data ;
Pack ( & data ) ;
2018-08-14 19:46:16 +01:00
bool success = g_pDBIO - > CreateOrUpdateGlobalData ( DBIO_GLOBAL_ALLEGIANCE_DATA , data . GetData ( ) , data . GetSize ( ) ) ;
if ( ! success )
WINLOG ( Temp , Normal , " Problem saving allegiance data to DB! \n " ) ;
2018-03-29 17:01:57 -04:00
}
2018-04-25 11:01:03 +00:00
void AllegianceManager : : WalkTreeAndBumpOnlineTime ( AllegianceTreeNode * node , int onlineSecondsDelta ) {
// Walk allegiance tree and bump _ingameSecondsSworn for all online characters.
// There's probably a better way of maintaining number of seconds of online-time.
for ( auto & entry : node - > _vassals ) {
AllegianceTreeNode * vassal = entry . second ;
2018-07-12 14:41:21 -07:00
CPlayerWeenie * target = g_pWorld - > FindPlayer ( vassal - > _charID ) ;
2018-04-25 11:01:03 +00:00
if ( target )
vassal - > _ingameSecondsSworn + = onlineSecondsDelta ;
WalkTreeAndBumpOnlineTime ( vassal , onlineSecondsDelta ) ;
}
}
2018-03-29 17:01:57 -04:00
void AllegianceManager : : Tick ( )
{
2018-04-25 11:01:03 +00:00
if ( m_LastSave < = ( Timer : : cur_time - 300.0 ) ) // every 5 minutes save
2018-03-29 17:01:57 -04:00
{
2018-04-25 11:01:03 +00:00
for ( auto & entry : _monarchs )
WalkTreeAndBumpOnlineTime ( entry . second , ( ( int ) round ( Timer : : cur_time - m_LastSave ) ) ) ;
2018-03-29 17:01:57 -04:00
Save ( ) ;
2018-04-25 11:01:03 +00:00
m_LastSave = Timer : : cur_time ;
2018-03-29 17:01:57 -04:00
}
2018-08-12 01:10:53 +01:00
// check for expired chat gags
if ( m_LastGagCheck < = ( Timer : : cur_time - 5 ) )
{
for ( auto entry : _allegInfos ) {
auto gagList = entry . second - > _info . m_chatGagList ;
2019-07-07 20:56:15 +00:00
std : : vector < uint32_t > toRemove ;
2018-08-12 01:10:53 +01:00
for ( auto gagged : gagList ) {
if ( gagged . second < = Timer : : cur_time ) {
toRemove . push_back ( gagged . first ) ;
}
}
for ( auto id : toRemove ) {
gagList . erase ( id ) ;
}
}
m_LastGagCheck = Timer : : cur_time ;
}
2018-03-29 17:01:57 -04:00
}
DEFINE_PACK ( AllegianceManager )
{
2019-07-07 20:56:15 +00:00
pWriter - > Write < uint32_t > ( 1 ) ; // version
pWriter - > Write < uint32_t > ( _monarchs . size ( ) ) ;
2018-03-29 17:01:57 -04:00
for ( auto & entry : _monarchs )
entry . second - > Pack ( pWriter ) ;
2019-07-07 20:56:15 +00:00
pWriter - > Write < uint32_t > ( _allegInfos . size ( ) ) ;
2018-03-29 17:01:57 -04:00
for ( auto & entry : _allegInfos )
{
2019-07-07 20:56:15 +00:00
pWriter - > Write < uint32_t > ( entry . first ) ;
2018-03-29 17:01:57 -04:00
entry . second - > Pack ( pWriter ) ;
}
}
DEFINE_UNPACK ( AllegianceManager )
{
2019-07-07 20:56:15 +00:00
uint32_t version = pReader - > Read < uint32_t > ( ) ;
uint32_t numMonarchs = pReader - > Read < uint32_t > ( ) ;
2018-03-29 17:01:57 -04:00
2019-07-07 20:56:15 +00:00
for ( uint32_t i = 0 ; i < numMonarchs ; i + + )
2018-03-29 17:01:57 -04:00
{
AllegianceTreeNode * node = new AllegianceTreeNode ( ) ;
2019-01-15 14:11:21 -06:00
if ( node - > UnPack ( pReader ) )
{
_monarchs [ node - > _charID ] = node ;
CacheInitialDataRecursively ( node , NULL ) ;
}
2018-03-29 17:01:57 -04:00
}
2019-07-07 20:56:15 +00:00
uint32_t numInfos = pReader - > Read < uint32_t > ( ) ;
2018-03-29 17:01:57 -04:00
2019-07-07 20:56:15 +00:00
for ( uint32_t i = 0 ; i < numInfos ; i + + )
2018-03-29 17:01:57 -04:00
{
2019-07-07 20:56:15 +00:00
uint32_t monarchID = pReader - > Read < uint32_t > ( ) ;
2018-03-29 17:01:57 -04:00
AllegianceInfo * info = new AllegianceInfo ( ) ;
info - > UnPack ( pReader ) ;
_allegInfos [ monarchID ] = info ;
}
return true ;
}
void AllegianceManager : : CacheInitialDataRecursively ( AllegianceTreeNode * node , AllegianceTreeNode * parent )
{
if ( ! node )
return ;
_directNodes [ node - > _charID ] = node ;
node - > _monarchID = parent ? parent - > _monarchID : node - > _charID ;
node - > _patronID = parent ? parent - > _charID : 0 ;
node - > _rank = 1 ;
node - > _numFollowers = 0 ;
unsigned int highestVassalRank = 0 ;
bool bRankUp = false ;
for ( auto & entry : node - > _vassals )
{
AllegianceTreeNode * vassal = entry . second ;
CacheInitialDataRecursively ( vassal , node ) ;
if ( vassal - > _rank > highestVassalRank )
{
highestVassalRank = vassal - > _rank ;
bRankUp = false ;
}
else if ( vassal - > _rank = = highestVassalRank )
{
bRankUp = true ;
}
node - > _numFollowers + = vassal - > _numFollowers + 1 ;
}
if ( ! highestVassalRank )
{
node - > _rank = 1 ;
}
else
{
node - > _rank = highestVassalRank ;
if ( bRankUp )
node - > _rank + + ;
}
}
void AllegianceManager : : CacheDataRecursively ( AllegianceTreeNode * node , AllegianceTreeNode * parent )
{
if ( ! node )
return ;
node - > _monarchID = parent ? parent - > _monarchID : node - > _charID ;
node - > _patronID = parent ? parent - > _charID : 0 ;
node - > _rank = 1 ;
node - > _numFollowers = 0 ;
unsigned int highestVassalRank = 0 ;
bool bRankUp = false ;
for ( auto & entry : node - > _vassals )
{
AllegianceTreeNode * vassal = entry . second ;
CacheDataRecursively ( vassal , node ) ;
if ( vassal - > _rank > highestVassalRank )
{
highestVassalRank = vassal - > _rank ;
bRankUp = false ;
}
else if ( vassal - > _rank = = highestVassalRank )
{
bRankUp = true ;
}
node - > _numFollowers + = vassal - > _numFollowers + 1 ;
}
if ( ! highestVassalRank )
{
node - > _rank = 1 ;
}
else
{
node - > _rank = highestVassalRank ;
if ( bRankUp )
node - > _rank + + ;
}
}
void AllegianceManager : : NotifyTreeRefreshRecursively ( AllegianceTreeNode * node )
{
if ( ! node )
return ;
2018-07-12 14:41:21 -07:00
CWeenieObject * weenie = g_pWorld - > FindPlayer ( node - > _charID ) ;
2018-03-29 17:01:57 -04:00
if ( weenie )
{
/*
unsigned int rank = 0 ;
AllegianceProfile * prof = CreateAllegianceProfile ( weenie , & rank ) ;
BinaryWriter allegianceUpdate ;
2019-07-07 20:56:15 +00:00
allegianceUpdate . Write < uint32_t > ( 0x20 ) ;
allegianceUpdate . Write < uint32_t > ( rank ) ;
2018-03-29 17:01:57 -04:00
prof - > Pack ( & allegianceUpdate ) ;
weenie - > SendNetMessage ( & allegianceUpdate , PRIVATE_MSG , TRUE , FALSE ) ;
delete prof ;
*/
SetWeenieAllegianceQualities ( weenie ) ;
}
for ( auto & entry : node - > _vassals )
NotifyTreeRefreshRecursively ( entry . second ) ;
}
2019-07-07 20:56:15 +00:00
AllegianceTreeNode * AllegianceManager : : GetTreeNode ( uint32_t charID )
2018-03-29 17:01:57 -04:00
{
auto i = _directNodes . find ( charID ) ;
if ( i ! = _directNodes . end ( ) )
return i - > second ;
return NULL ;
}
2019-07-07 20:56:15 +00:00
AllegianceInfo * AllegianceManager : : GetInfo ( uint32_t monarchID )
2018-03-29 17:01:57 -04:00
{
auto i = _allegInfos . find ( monarchID ) ;
if ( i ! = _allegInfos . end ( ) )
return i - > second ;
return NULL ;
}
2018-07-12 14:41:21 -07:00
void AllegianceManager : : SetWeenieAllegianceQualities ( CWeenieObject * weenie )
2018-03-29 17:01:57 -04:00
{
if ( ! weenie )
return ;
AllegianceTreeNode * monarch ;
AllegianceTreeNode * patron ;
AllegianceTreeNode * node = GetTreeNode ( weenie - > GetID ( ) ) ;
if ( node )
{
monarch = GetTreeNode ( node - > _monarchID ) ;
patron = GetTreeNode ( node - > _patronID ) ;
weenie - > m_Qualities . SetInt ( ALLEGIANCE_FOLLOWERS_INT , node - > _numFollowers ) ;
weenie - > m_Qualities . SetInt ( ALLEGIANCE_RANK_INT , node - > _rank ) ;
2018-08-14 19:46:16 +01:00
weenie - > NotifyIntStatUpdated ( ALLEGIANCE_RANK_INT ) ;
2018-03-29 17:01:57 -04:00
// wrong weenie->m_Qualities.SetInt(ALLEGIANCE_CP_POOL_INT, node->_cp_cached);
}
else
{
monarch = NULL ;
patron = NULL ;
weenie - > m_Qualities . RemoveInt ( ALLEGIANCE_FOLLOWERS_INT ) ;
weenie - > m_Qualities . RemoveInt ( ALLEGIANCE_RANK_INT ) ;
// wrong weenie->m_Qualities.RemoveInt(ALLEGIANCE_CP_POOL_INT);
}
if ( monarch )
{
weenie - > m_Qualities . SetInstanceID ( MONARCH_IID , monarch - > _charID ) ;
weenie - > m_Qualities . SetInt ( MONARCHS_RANK_INT , monarch - > _rank ) ;
if ( monarch - > _charID ! = weenie - > GetID ( ) )
{
weenie - > m_Qualities . SetString ( MONARCHS_NAME_STRING , monarch - > _charName ) ;
2018-08-14 19:46:16 +01:00
std : : string title = GetRankTitle ( monarch - > _gender , monarch - > _hg , monarch - > _rank ) + " " + monarch - > _charName ;
weenie - > m_Qualities . SetString ( MONARCHS_TITLE_STRING , title ) ;
2018-03-29 17:01:57 -04:00
}
else
{
weenie - > m_Qualities . RemoveString ( MONARCHS_NAME_STRING ) ;
weenie - > m_Qualities . RemoveString ( MONARCHS_TITLE_STRING ) ;
}
2018-08-14 19:46:16 +01:00
if ( AllegianceInfo * ai = GetInfo ( monarch - > _charID ) )
{
if ( ! ai - > _info . m_AllegianceName . empty ( ) )
weenie - > m_Qualities . SetString ( ALLEGIANCE_NAME_STRING , ai - > _info . m_AllegianceName ) ;
}
2018-03-29 17:01:57 -04:00
}
else
{
weenie - > m_Qualities . RemoveInstanceID ( MONARCH_IID ) ;
weenie - > m_Qualities . RemoveInt ( MONARCHS_RANK_INT ) ;
weenie - > m_Qualities . RemoveString ( MONARCHS_NAME_STRING ) ;
weenie - > m_Qualities . RemoveString ( MONARCHS_TITLE_STRING ) ;
2018-08-14 19:46:16 +01:00
weenie - > m_Qualities . RemoveString ( ALLEGIANCE_NAME_STRING ) ;
2018-03-29 17:01:57 -04:00
}
if ( patron )
{
weenie - > m_Qualities . SetInstanceID ( PATRON_IID , patron - > _charID ) ;
2018-08-14 19:46:16 +01:00
std : : string title = GetRankTitle ( patron - > _gender , patron - > _hg , patron - > _rank ) + " " + patron - > _charName ;
weenie - > m_Qualities . SetString ( PATRONS_TITLE_STRING , title ) ;
2018-03-29 17:01:57 -04:00
}
else
{
weenie - > m_Qualities . RemoveInstanceID ( PATRON_IID ) ;
weenie - > m_Qualities . RemoveString ( PATRONS_TITLE_STRING ) ;
}
}
2019-07-07 20:56:15 +00:00
AllegianceProfile * AllegianceManager : : CreateAllegianceProfile ( uint32_t char_id , unsigned int * pRank )
2018-03-29 17:01:57 -04:00
{
AllegianceProfile * prof = new AllegianceProfile ;
* pRank = 0 ;
AllegianceTreeNode * node = GetTreeNode ( char_id ) ;
if ( node )
{
* pRank = node - > _rank ;
AllegianceTreeNode * monarch = GetTreeNode ( node - > _monarchID ) ;
AllegianceTreeNode * patron = GetTreeNode ( node - > _patronID ) ;
AllegianceInfo * info = GetInfo ( node - > _monarchID ) ;
RELEASE_ASSERT ( monarch ) ;
if ( monarch )
prof - > _total_members = monarch - > _numFollowers ;
prof - > _total_vassals = node - > _numFollowers ;
if ( ! info )
{
info = new AllegianceInfo ( ) ;
_allegInfos [ node - > _monarchID ] = info ;
}
if ( info )
{
RELEASE_ASSERT ( ! info - > _info . _nodes . size ( ) ) ;
prof - > _allegiance = info - > _info ;
}
if ( monarch )
{
AllegianceNode * patronNode = NULL ;
if ( monarch ! = node )
{
AllegianceNode * monarchNode = new AllegianceNode ;
monarch - > FillAllegianceNode ( monarchNode ) ;
if ( g_pWorld - > FindPlayer ( monarch - > _charID ) )
monarchNode - > _data . _bitfield | = LoggedIn_AllegianceIndex ;
prof - > _allegiance . _nodes . push_back ( monarchNode ) ;
patronNode = monarchNode ;
if ( patron & & patron ! = monarch )
{
patronNode = new AllegianceNode ;
patron - > FillAllegianceNode ( patronNode ) ;
patronNode - > _patron = monarchNode ;
if ( g_pWorld - > FindPlayer ( patron - > _charID ) )
patronNode - > _data . _bitfield | = LoggedIn_AllegianceIndex ;
prof - > _allegiance . _nodes . push_back ( patronNode ) ;
}
}
AllegianceNode * selfNode = new AllegianceNode ;
node - > FillAllegianceNode ( selfNode ) ;
selfNode - > _patron = patronNode ;
selfNode - > _data . _bitfield | = LoggedIn_AllegianceIndex ;
prof - > _allegiance . _nodes . push_back ( selfNode ) ;
for ( auto & entry : node - > _vassals )
{
AllegianceTreeNode * vassal = entry . second ;
AllegianceNode * vassalNode = new AllegianceNode ;
vassal - > FillAllegianceNode ( vassalNode ) ;
vassalNode - > _patron = selfNode ;
if ( g_pWorld - > FindPlayer ( vassal - > _charID ) )
vassalNode - > _data . _bitfield | = LoggedIn_AllegianceIndex ;
prof - > _allegiance . _nodes . push_back ( vassalNode ) ;
}
}
}
return prof ;
}
const unsigned int MAX_DIRECT_VASSALS = 11 ;
2018-09-25 12:54:26 -07:00
void AllegianceManager : : TrySwearAllegiance ( CWeenieObject * vassal , CWeenieObject * patron )
2018-03-29 17:01:57 -04:00
{
2018-09-25 12:54:26 -07:00
if ( vassal - > IsBusyOrInAction ( ) )
2018-07-28 15:21:38 +01:00
{
2018-09-25 12:54:26 -07:00
vassal - > NotifyWeenieError ( WERROR_ACTIONS_LOCKED ) ;
2018-07-28 15:21:38 +01:00
return ;
}
2018-09-25 12:54:26 -07:00
if ( patron - > IsBusyOrInAction ( ) )
2018-07-28 15:21:38 +01:00
{
2018-09-25 12:54:26 -07:00
vassal - > NotifyWeenieError ( WERROR_ALLEGIANCE_PATRON_BUSY ) ;
2018-07-28 15:21:38 +01:00
return ;
}
2018-09-25 12:54:26 -07:00
if ( vassal - > DistanceTo ( patron ) > = 4.0 )
2018-07-28 15:21:38 +01:00
{
2018-09-25 12:54:26 -07:00
vassal - > NotifyWeenieError ( WERROR_MISSILE_OUT_OF_RANGE ) ;
2018-07-28 15:21:38 +01:00
return ;
}
2018-09-25 12:54:26 -07:00
if ( vassal - > GetID ( ) = = patron - > GetID ( ) )
2018-08-06 01:40:33 -05:00
return ;
2018-03-29 17:01:57 -04:00
2019-02-02 10:41:43 -08:00
if ( g_pDBIO - > GetCharacterInfo ( vassal - > GetID ( ) ) . account_id = = g_pDBIO - > GetCharacterInfo ( patron - > GetID ( ) ) . account_id )
return ;
2018-09-25 12:54:26 -07:00
if ( CPlayerWeenie * player = patron - > AsPlayer ( ) )
2018-03-29 17:01:57 -04:00
{
if ( player - > GetCharacterOptions ( ) & IgnoreAllegianceRequests_CharacterOption )
2018-07-28 15:21:38 +01:00
{
2018-09-25 12:54:26 -07:00
vassal - > NotifyWeenieError ( WERROR_ALLEGIANCE_IGNORING_REQUESTS ) ;
2018-07-28 15:21:38 +01:00
return ;
}
2018-03-29 17:01:57 -04:00
}
2018-09-25 12:54:26 -07:00
AllegianceTreeNode * vassalTreeNode = g_pAllegianceManager - > GetTreeNode ( vassal - > GetID ( ) ) ;
if ( vassalTreeNode & & vassalTreeNode - > _patronID )
2018-03-29 17:01:57 -04:00
{
// already sworn to someone
2018-09-25 12:54:26 -07:00
vassal - > NotifyWeenieError ( WERROR_ALLEGIANCE_PATRON_EXISTS ) ;
if ( vassalTreeNode - > _patronID = = patron - > GetID ( ) )
2018-07-28 15:21:38 +01:00
{
2018-09-25 12:54:26 -07:00
patron - > NotifyWeenieErrorWithString ( WERROR_ALLEGIANCE_ADD_HIERARCHY_FAILURE , vassal - > GetName ( ) . c_str ( ) ) ;
2018-07-28 15:21:38 +01:00
}
return ;
2018-03-29 17:01:57 -04:00
}
2018-09-25 12:54:26 -07:00
AllegianceTreeNode * patronTreeNode = GetTreeNode ( patron - > GetID ( ) ) ;
if ( patronTreeNode )
2018-03-29 17:01:57 -04:00
{
2018-09-25 12:54:26 -07:00
if ( IsBanned ( vassal - > GetID ( ) , patronTreeNode - > _monarchID ) )
2018-07-28 15:21:38 +01:00
{
2018-09-25 12:54:26 -07:00
vassal - > NotifyWeenieErrorWithString ( WERROR_ALLEGIANCE_YOU_ARE_BANNED , patron - > GetName ( ) . c_str ( ) ) ;
patron - > NotifyWeenieErrorWithString ( WERROR_ALLEGIANCE_BANNED , vassal - > GetName ( ) . c_str ( ) ) ;
2018-07-28 15:21:38 +01:00
return ;
}
2018-09-25 12:54:26 -07:00
AllegianceInfo * ai = GetInfo ( patronTreeNode - > _monarchID ) ;
if ( ! IsOfficerWithLevel ( patronTreeNode , Castellan_AllegianceOfficerLevel ) ) // If a player swears allegiance to a monarch or Castellan-level officer in a locked allegiance, the action proceeds as normal.
2018-07-30 10:08:39 +01:00
{
2018-09-25 12:54:26 -07:00
if ( ai & & ai - > _info . m_isLocked & & ( vassal - > GetID ( ) ! = ai - > _info . m_ApprovedVassal ) ) // bypass the lock if it's the approved vassal
{
vassal - > NotifyWeenieErrorWithString ( WERROR_ALLEGIANCE_LOCK_PREVENTS_VASSAL , patron - > GetName ( ) . c_str ( ) ) ;
patron - > NotifyWeenieErrorWithString ( WERROR_ALLEGIANCE_LOCK_PREVENTS_PATRON , vassal - > GetName ( ) . c_str ( ) ) ;
return ;
}
2018-07-30 10:08:39 +01:00
}
2018-07-28 15:21:38 +01:00
2018-09-25 12:54:26 -07:00
if ( vassalTreeNode & & vassalTreeNode - > _charID = = patronTreeNode - > _monarchID )
2018-03-29 17:01:57 -04:00
{
// Clearly he doesn't have updated data.
2018-09-25 12:54:26 -07:00
SendAllegianceProfile ( vassal ) ;
2018-03-29 17:01:57 -04:00
2018-07-28 15:21:38 +01:00
return ;
2018-03-29 17:01:57 -04:00
}
2018-09-25 12:54:26 -07:00
if ( patronTreeNode - > _vassals . size ( ) > = MAX_DIRECT_VASSALS )
2018-03-29 17:01:57 -04:00
{
// too many vassals
2018-09-25 12:54:26 -07:00
patron - > NotifyWeenieErrorWithString ( WERROR_ALLEGIANCE_MAX_VASSALS , " You " ) ;
vassal - > NotifyWeenieErrorWithString ( WERROR_ALLEGIANCE_MAX_VASSALS , patron - > GetName ( ) . c_str ( ) ) ;
2018-07-28 15:21:38 +01:00
return ;
2018-03-29 17:01:57 -04:00
}
}
2018-09-25 12:54:26 -07:00
if ( ! patronTreeNode )
2018-03-29 17:01:57 -04:00
{
// target wasn't in an allegiance already
// make one...
2018-09-25 12:54:26 -07:00
patronTreeNode = new AllegianceTreeNode ( ) ;
patronTreeNode - > _monarchID = patron - > GetID ( ) ;
_directNodes [ patron - > GetID ( ) ] = patronTreeNode ;
_monarchs [ patron - > GetID ( ) ] = patronTreeNode ;
2018-03-29 17:01:57 -04:00
AllegianceInfo * info = new AllegianceInfo ( ) ;
2018-09-25 12:54:26 -07:00
_allegInfos [ patron - > GetID ( ) ] = info ;
2018-03-29 17:01:57 -04:00
}
2018-09-25 12:54:26 -07:00
patronTreeNode - > UpdateWithWeenie ( patron ) ;
2018-03-29 17:01:57 -04:00
2018-09-25 12:54:26 -07:00
if ( vassalTreeNode )
2018-03-29 17:01:57 -04:00
{
// must be a current monarch
2018-09-25 12:54:26 -07:00
_monarchs . erase ( vassal - > GetID ( ) ) ;
2018-03-29 17:01:57 -04:00
2018-09-25 12:54:26 -07:00
auto i = _allegInfos . find ( vassal - > GetID ( ) ) ;
2018-03-29 17:01:57 -04:00
if ( i ! = _allegInfos . end ( ) )
{
delete i - > second ;
_allegInfos . erase ( i ) ;
}
}
else
{
2018-09-25 12:54:26 -07:00
vassalTreeNode = new AllegianceTreeNode ( ) ;
_directNodes [ vassal - > GetID ( ) ] = vassalTreeNode ;
2018-03-29 17:01:57 -04:00
}
2018-09-25 12:54:26 -07:00
vassalTreeNode - > UpdateWithWeenie ( vassal ) ;
vassalTreeNode - > _rank = 1 ;
vassalTreeNode - > _numFollowers = 0 ;
vassalTreeNode - > _patronID = patronTreeNode - > _charID ;
vassalTreeNode - > _monarchID = patronTreeNode - > _monarchID ;
vassalTreeNode - > _unixTimeSwornAt = time ( 0 ) ;
vassalTreeNode - > _ingameSecondsSworn = 1 ;
2018-03-29 17:01:57 -04:00
2018-09-25 12:54:26 -07:00
if ( vassalTreeNode - > _level < = patronTreeNode - > _level )
vassal - > m_Qualities . SetBool ( EXISTED_BEFORE_ALLEGIANCE_XP_CHANGES_BOOL , true ) ;
2018-08-20 13:00:37 +01:00
else
2018-09-25 12:54:26 -07:00
vassal - > m_Qualities . SetBool ( EXISTED_BEFORE_ALLEGIANCE_XP_CHANGES_BOOL , false ) ;
2018-08-20 13:00:37 +01:00
2018-09-25 12:54:26 -07:00
patronTreeNode - > _vassals [ vassalTreeNode - > _charID ] = vassalTreeNode ;
2018-03-29 17:01:57 -04:00
// not efficient, can revise later
2018-09-25 12:54:26 -07:00
RELEASE_ASSERT ( _monarchs . find ( patronTreeNode - > _monarchID ) ! = _monarchs . end ( ) ) ;
2018-03-29 17:01:57 -04:00
2018-09-25 12:54:26 -07:00
AllegianceTreeNode * monarchTreeNode = _monarchs [ patronTreeNode - > _monarchID ] ;
2018-03-29 17:01:57 -04:00
CacheDataRecursively ( monarchTreeNode , NULL ) ;
NotifyTreeRefreshRecursively ( monarchTreeNode ) ;
2018-09-25 12:54:26 -07:00
vassal - > SendText ( csprintf ( " %s has accepted your oath of Allegiance! " , patron - > GetName ( ) . c_str ( ) ) , LTT_DEFAULT ) ;
patron - > SendText ( csprintf ( " %s has sworn Allegiance to you. " , vassal - > GetName ( ) . c_str ( ) ) , LTT_DEFAULT ) ;
2018-03-29 17:01:57 -04:00
2018-09-25 12:54:26 -07:00
vassal - > DoForcedMotion ( Motion_Kneel ) ;
2018-03-29 17:01:57 -04:00
Save ( ) ;
}
bool AllegianceManager : : ShouldRemoveAllegianceNode ( AllegianceTreeNode * node )
{
if ( ! node - > _patronID & & ! node - > _vassals . size ( ) )
return true ;
return false ;
}
void AllegianceManager : : RemoveAllegianceNode ( AllegianceTreeNode * node )
{
_monarchs . erase ( node - > _charID ) ;
_directNodes . erase ( node - > _charID ) ;
auto allegInfoEntry = _allegInfos . find ( node - > _charID ) ;
if ( allegInfoEntry ! = _allegInfos . end ( ) )
{
delete allegInfoEntry - > second ;
_allegInfos . erase ( allegInfoEntry ) ;
}
delete node ;
}
2018-08-14 19:46:16 +01:00
std : : string AllegianceManager : : GetRankTitle ( Gender gender , HeritageGroup heritage , unsigned int rank )
{
std : : string title ;
switch ( heritage )
{
case Aluvian_HeritageGroup :
if ( gender = = Male_Gender )
title = AluvianMaleRanks [ rank - 1 ] ;
else
title = AluvianFemaleRanks [ rank - 1 ] ;
break ;
case Gharundim_HeritageGroup :
if ( gender = = Male_Gender )
title = GharundimMaleRanks [ rank - 1 ] ;
else
title = GharundimFemaleRanks [ rank - 1 ] ;
break ;
case Sho_HeritageGroup :
if ( gender = = Male_Gender )
title = ShoMaleRanks [ rank - 1 ] ;
else
title = ShoFemaleRanks [ rank - 1 ] ;
break ;
case Viamontian_HeritageGroup :
if ( gender = = Male_Gender )
title = ViamontianMaleRanks [ rank - 1 ] ;
else
title = ViamontianFemaleRanks [ rank - 1 ] ;
break ;
case Shadowbound_HeritageGroup :
if ( gender = = Male_Gender )
title = ShadowMaleRanks [ rank - 1 ] ;
else
title = ShadowFemaleRanks [ rank - 1 ] ;
break ;
case Gearknight_HeritageGroup :
if ( gender = = Male_Gender )
title = GearKnightMaleRanks [ rank - 1 ] ;
else
title = GearKnightFemaleRanks [ rank - 1 ] ;
break ;
case Tumerok_HeritageGroup :
if ( gender = = Male_Gender )
title = TumerokMaleRanks [ rank - 1 ] ;
else
title = TumerokFemaleRanks [ rank - 1 ] ;
break ;
case Lugian_HeritageGroup :
if ( gender = = Male_Gender )
title = LugianMaleRanks [ rank - 1 ] ;
else
title = LugianFemaleRanks [ rank - 1 ] ;
break ;
case Empyrean_HeritageGroup :
if ( gender = = Male_Gender )
title = EmpyreanMaleRanks [ rank - 1 ] ;
else
title = EmpyreanFemaleRanks [ rank - 1 ] ;
break ;
case Penumbraen_HeritageGroup :
if ( gender = = Male_Gender )
title = ShadowMaleRanks [ rank - 1 ] ;
else
title = ShadowFemaleRanks [ rank - 1 ] ;
break ;
case Undead_HeritageGroup :
if ( gender = = Male_Gender )
title = UndeadMaleRanks [ rank - 1 ] ;
else
title = UndeadFemaleRanks [ rank - 1 ] ;
break ;
}
return title ;
}
2018-03-29 17:01:57 -04:00
void AllegianceManager : : BreakAllegiance ( AllegianceTreeNode * patronNode , AllegianceTreeNode * vassalNode )
{
// the target is a vassal
patronNode - > _vassals . erase ( vassalNode - > _charID ) ;
vassalNode - > _monarchID = vassalNode - > _charID ;
vassalNode - > _patronID = 0 ;
_monarchs [ vassalNode - > _charID ] = vassalNode ;
AllegianceInfo * info = new AllegianceInfo ( ) ;
_allegInfos [ vassalNode - > _charID ] = info ;
{
RELEASE_ASSERT ( _monarchs . find ( patronNode - > _monarchID ) ! = _monarchs . end ( ) ) ;
AllegianceTreeNode * patronMonarchNode = _monarchs [ patronNode - > _monarchID ] ;
CacheDataRecursively ( patronMonarchNode , NULL ) ;
NotifyTreeRefreshRecursively ( patronMonarchNode ) ;
// check if i should even have allegiance data anymore (no vassals/patron)
if ( ShouldRemoveAllegianceNode ( patronNode ) )
{
// don't need allegiance data anymore
RemoveAllegianceNode ( patronNode ) ;
}
}
{
RELEASE_ASSERT ( _monarchs . find ( vassalNode - > _monarchID ) ! = _monarchs . end ( ) ) ;
// check if i should even have allegiance data anymore (no vassals/patron)
AllegianceTreeNode * vassalMonarchNode = _monarchs [ vassalNode - > _monarchID ] ;
CacheDataRecursively ( vassalMonarchNode , NULL ) ;
NotifyTreeRefreshRecursively ( vassalMonarchNode ) ;
// check if i should even have allegiance data anymore (no vassals/patron)
if ( ShouldRemoveAllegianceNode ( vassalNode ) )
{
// don't need allegiance data anymore
RemoveAllegianceNode ( vassalNode ) ;
}
}
Save ( ) ;
}
2019-07-07 20:56:15 +00:00
void AllegianceManager : : TryBreakAllegiance ( CWeenieObject * source , uint32_t target_id )
2018-07-28 15:21:38 +01:00
{
TryBreakAllegiance ( source - > GetID ( ) , target_id ) ;
}
2019-07-07 20:56:15 +00:00
void AllegianceManager : : TryBreakAllegiance ( uint32_t source_id , uint32_t target_id )
2018-07-28 15:21:38 +01:00
{
AllegianceTreeNode * selfTreeNode = GetTreeNode ( source_id ) ;
2018-03-29 17:01:57 -04:00
if ( ! selfTreeNode )
{
2018-07-28 15:21:38 +01:00
// source doesn't have patron or vassals, shouldn't be here
return ;
2018-03-29 17:01:57 -04:00
}
2018-07-28 15:21:38 +01:00
AllegianceTreeNode * targetTreeNode = GetTreeNode ( target_id ) ;
2018-03-29 17:01:57 -04:00
if ( ! targetTreeNode )
{
2018-07-28 15:21:38 +01:00
// target doesn't have patron or vassals, shouldn't be here
return ;
2018-03-29 17:01:57 -04:00
}
std : : string targetCharName = targetTreeNode - > _charName ;
if ( selfTreeNode - > _charID = = targetTreeNode - > _patronID )
{
// the target is a vassal
BreakAllegiance ( selfTreeNode , targetTreeNode ) ;
2018-08-29 15:19:04 -07:00
2018-03-29 17:01:57 -04:00
}
else if ( selfTreeNode - > _patronID = = target_id )
{
// the target is the patron
BreakAllegiance ( targetTreeNode , selfTreeNode ) ;
}
else
{
2018-07-28 15:21:38 +01:00
return ;
2018-03-29 17:01:57 -04:00
}
2018-07-28 15:21:38 +01:00
CWeenieObject * source = g_pWorld - > FindPlayer ( source_id ) ;
if ( source )
{
source - > SendText ( csprintf ( " You have broken your Allegiance to %s! " , targetCharName . c_str ( ) ) , LTT_DEFAULT ) ;
2020-08-07 10:58:05 -07:00
source - > m_Qualities . SetBool ( IS_ALLEGIANCE_GAGGED_BOOL , false ) ;
2018-07-28 15:21:38 +01:00
}
2018-03-29 17:01:57 -04:00
2018-07-12 14:41:21 -07:00
CWeenieObject * target = g_pWorld - > FindPlayer ( target_id ) ;
2018-12-19 23:15:54 -06:00
if ( target & & source )
2018-07-28 15:21:38 +01:00
{
2018-03-29 17:01:57 -04:00
target - > SendText ( csprintf ( " %s has broken their Allegiance to you! " , source - > GetName ( ) . c_str ( ) ) , LTT_DEFAULT ) ;
2018-07-28 15:21:38 +01:00
}
2018-03-29 17:01:57 -04:00
}
2019-07-07 20:56:15 +00:00
void AllegianceManager : : BreakAllAllegiance ( uint32_t char_id )
2018-03-29 17:01:57 -04:00
{
2018-07-28 15:21:38 +01:00
AllegianceTreeNode * selfTreeNode = GetTreeNode ( char_id ) ;
2018-03-29 17:01:57 -04:00
if ( ! selfTreeNode )
{
// not in an allegiance
return ;
}
if ( selfTreeNode - > _patronID )
{
2018-07-28 15:21:38 +01:00
AllegianceTreeNode * patronTreeNode = GetTreeNode ( selfTreeNode - > _patronID ) ;
2018-03-29 17:01:57 -04:00
if ( patronTreeNode )
{
BreakAllegiance ( patronTreeNode , selfTreeNode ) ;
}
}
2018-07-28 15:21:38 +01:00
while ( ( selfTreeNode = GetTreeNode ( char_id ) ) & & ! selfTreeNode - > _vassals . empty ( ) )
2018-03-29 17:01:57 -04:00
{
AllegianceTreeNodeMap : : iterator vassalEntry = selfTreeNode - > _vassals . begin ( ) ;
if ( vassalEntry - > second )
{
BreakAllegiance ( selfTreeNode , vassalEntry - > second ) ;
}
else
{
selfTreeNode - > _vassals . erase ( vassalEntry ) ;
}
}
// should not be necessary
2018-07-28 15:21:38 +01:00
assert ( selfTreeNode ! = GetTreeNode ( char_id ) ) ;
2018-03-29 17:01:57 -04:00
2018-07-28 15:21:38 +01:00
if ( selfTreeNode = GetTreeNode ( char_id ) )
2018-03-29 17:01:57 -04:00
{
if ( ShouldRemoveAllegianceNode ( selfTreeNode ) )
{
RemoveAllegianceNode ( selfTreeNode ) ;
}
}
}
2019-07-07 20:56:15 +00:00
void AllegianceManager : : HandleAllegiancePassup ( uint32_t source_id , int64_t amount , bool direct )
2018-03-29 17:01:57 -04:00
{
AllegianceTreeNode * node = GetTreeNode ( source_id ) ;
if ( ! node ) // no allegiance
return ;
if ( ! node - > _patronID ) // no patron (only vassals)
return ;
AllegianceTreeNode * patron = GetTreeNode ( node - > _patronID ) ;
RELEASE_ASSERT ( patron ) ;
if ( ! patron ) // shouldn't happen
return ;
2018-08-20 13:00:37 +01:00
CPlayerWeenie * source = g_pWorld - > FindPlayer ( source_id ) ;
if ( ! source )
return ;
if ( ! source - > InqBoolQuality ( EXISTED_BEFORE_ALLEGIANCE_XP_CHANGES_BOOL , false ) ) // if bool was set to false at swear time or doesn't have it flagged
{
2018-09-01 14:30:40 +01:00
if ( node - > _unixTimeSwornAt < 1534765700 | | patron - > _level > = node - > _level ) // if sworn before allegiance patch (20/08/18) or patron has since outleveled source, allow passup
2018-08-20 19:38:31 +01:00
{
2018-08-20 13:00:37 +01:00
source - > m_Qualities . SetBool ( EXISTED_BEFORE_ALLEGIANCE_XP_CHANGES_BOOL , true ) ;
2018-08-20 19:38:31 +01:00
}
2018-08-20 13:00:37 +01:00
else
2018-09-01 14:30:40 +01:00
return ;
2018-08-20 13:00:37 +01:00
}
2018-04-25 11:01:03 +00:00
time_t currentTime = time ( 0 ) ;
2018-03-29 17:01:57 -04:00
double realDaysSworn = 0 ;
double ingameHoursSworn = 0 ;
double avgRealDaysVassalsSworn = 0 ;
double avgIngameHoursVassalsSworn = 0 ;
2018-04-25 11:01:03 +00:00
for ( auto & entry : patron - > _vassals ) {
AllegianceTreeNode * vassal = entry . second ;
double vassalDaysSworn = ( ( currentTime - vassal - > _unixTimeSwornAt ) / 86400.0 ) ;
double vassalIngameHours = ( vassal - > _ingameSecondsSworn / 3600.0 ) ;
if ( vassal - > _charID = = node - > _charID ) {
realDaysSworn = vassalDaysSworn ;
ingameHoursSworn = vassalIngameHours ;
}
avgRealDaysVassalsSworn + = vassalDaysSworn ;
avgIngameHoursVassalsSworn + = vassalIngameHours ;
}
2018-05-10 21:18:00 +00:00
2018-08-27 15:47:05 -05:00
avgRealDaysVassalsSworn / = max ( size_t { 1 } , patron - > _vassals . size ( ) ) ;
avgIngameHoursVassalsSworn / = max ( size_t { 1 } , patron - > _vassals . size ( ) ) ;
2018-04-25 11:01:03 +00:00
double vassalFactor = min ( 1.0 , max ( 0.0 , 0.25 * patron - > _vassals . size ( ) ) ) ;
double realDaysSwornFactor = min ( realDaysSworn , 730.0 ) / 730.0 ;
double ingameHoursSwornFactor = min ( ingameHoursSworn , 720.0 ) / 720.0 ;
double avgRealDaysVassalsSwornFactor = min ( avgRealDaysVassalsSworn , 730.0 ) / 730.0 ;
double avgIngameHoursVassalsSwornFactor = min ( avgIngameHoursVassalsSworn , 720.0 ) / 720.0 ;
2018-08-27 15:47:05 -05:00
double loyaltyFactor = min ( node - > _loyalty , 291u ) / 291.0 ;
double leadershipFactor = min ( patron - > _leadership , 291u ) / 291.0 ;
2018-03-29 17:01:57 -04:00
double factor1 = direct ? 50.0 : 16.0 ;
double factor2 = direct ? 22.5 : 8.0 ;
2018-04-25 11:01:03 +00:00
double generatedPercent = 0.01 * ( factor1 + factor2 * loyaltyFactor * ( 1.0 + realDaysSwornFactor * ingameHoursSwornFactor ) ) ;
double receivedPercent = 0.01 * ( factor1 + factor2 * leadershipFactor * ( 1.0 + vassalFactor * avgRealDaysVassalsSwornFactor * avgIngameHoursVassalsSwornFactor ) ) ;
2018-03-29 17:01:57 -04:00
double passup = generatedPercent * receivedPercent ;
2019-07-07 20:56:15 +00:00
uint64_t passupAmount = amount * passup ;
2018-03-29 17:01:57 -04:00
2018-08-20 13:00:37 +01:00
if ( passupAmount > 0 )
2018-03-29 17:01:57 -04:00
{
2018-05-11 02:18:56 +01:00
node - > _cp_tithed + = passupAmount ;
2018-03-29 17:01:57 -04:00
patron - > _cp_cached + = passupAmount ;
2019-07-07 20:56:15 +00:00
patron - > _cp_pool_to_unload = min ( uint64_t ( 4294967295ul ) , patron - > _cp_pool_to_unload + passupAmount ) ;
2018-03-29 17:01:57 -04:00
2018-08-20 13:00:37 +01:00
CWeenieObject * patron_weenie = g_pWorld - > FindPlayer ( patron - > _charID ) ; // pass up now if the patron is online (otherwise remains in cp_cached until their next login)
2018-03-29 17:01:57 -04:00
if ( patron_weenie )
patron_weenie - > TryToUnloadAllegianceXP ( false ) ;
2018-03-29 21:40:02 -04:00
HandleAllegiancePassup ( patron - > _charID , passupAmount , false ) ;
2018-03-29 17:01:57 -04:00
}
}
2019-07-07 20:56:15 +00:00
void AllegianceManager : : ChatMonarch ( uint32_t sender_id , const char * text )
2018-03-29 17:01:57 -04:00
{
AllegianceTreeNode * node = GetTreeNode ( sender_id ) ;
if ( ! node | | ! node - > _monarchID | | node - > _monarchID = = sender_id ) // no allegiance
return ;
2018-07-12 14:41:21 -07:00
CWeenieObject * sender_weenie = g_pWorld - > FindPlayer ( sender_id ) ;
2018-03-29 17:01:57 -04:00
if ( ! sender_weenie )
return ;
2018-07-12 14:41:21 -07:00
CWeenieObject * target = g_pWorld - > FindPlayer ( node - > _monarchID ) ;
2018-03-29 17:01:57 -04:00
if ( ! target )
return ;
2018-09-06 22:40:43 -05:00
sender_weenie - > SendNetMessage ( ChannelChat ( Monarch_ChannelID , NULL , text ) , PRIVATE_MSG , FALSE , TRUE ) ;
target - > SendNetMessage ( ChannelChat ( Monarch_ChannelID , sender_weenie - > GetName ( ) . c_str ( ) , text ) , PRIVATE_MSG , FALSE , TRUE ) ;
2018-03-29 17:01:57 -04:00
}
2019-07-07 20:56:15 +00:00
void AllegianceManager : : ChatPatron ( uint32_t sender_id , const char * text )
2018-03-29 17:01:57 -04:00
{
AllegianceTreeNode * node = GetTreeNode ( sender_id ) ;
if ( ! node | | ! node - > _patronID ) // no allegiance
return ;
2018-07-12 14:41:21 -07:00
CWeenieObject * sender_weenie = g_pWorld - > FindPlayer ( sender_id ) ;
2018-03-29 17:01:57 -04:00
if ( ! sender_weenie )
return ;
2018-07-12 14:41:21 -07:00
CWeenieObject * target = g_pWorld - > FindPlayer ( node - > _patronID ) ;
2018-03-29 17:01:57 -04:00
if ( ! target )
return ;
2018-09-06 22:40:43 -05:00
sender_weenie - > SendNetMessage ( ChannelChat ( Patron_ChannelID , NULL , text ) , PRIVATE_MSG , FALSE , TRUE ) ;
target - > SendNetMessage ( ChannelChat ( Patron_ChannelID , sender_weenie - > GetName ( ) . c_str ( ) , text ) , PRIVATE_MSG , FALSE , TRUE ) ;
2018-03-29 17:01:57 -04:00
}
2019-07-07 20:56:15 +00:00
void AllegianceManager : : ChatVassals ( uint32_t sender_id , const char * text )
2018-03-29 17:01:57 -04:00
{
AllegianceTreeNode * node = GetTreeNode ( sender_id ) ;
if ( ! node ) // no allegiance
return ;
2018-07-12 14:41:21 -07:00
CWeenieObject * sender_weenie = g_pWorld - > FindPlayer ( sender_id ) ;
2018-03-29 17:01:57 -04:00
if ( ! sender_weenie )
return ;
2018-09-06 22:40:43 -05:00
sender_weenie - > SendNetMessage ( ChannelChat ( Vassals_ChannelID , NULL , text ) , PRIVATE_MSG , FALSE , TRUE ) ;
2018-03-29 17:01:57 -04:00
for ( auto & entry : node - > _vassals )
{
2018-07-12 14:41:21 -07:00
CWeenieObject * target = g_pWorld - > FindPlayer ( entry . second - > _charID ) ;
2018-03-29 17:01:57 -04:00
if ( ! target )
continue ;
2018-09-06 22:40:43 -05:00
target - > SendNetMessage ( ChannelChat ( Vassals_ChannelID , sender_weenie - > GetName ( ) . c_str ( ) , text ) , PRIVATE_MSG , FALSE , TRUE ) ;
2018-03-29 17:01:57 -04:00
}
}
2019-07-07 20:56:15 +00:00
void AllegianceManager : : ChatCovassals ( uint32_t sender_id , const char * text )
2018-03-29 17:01:57 -04:00
{
AllegianceTreeNode * node = GetTreeNode ( sender_id ) ;
if ( ! node | | ! node - > _patronID ) // no allegiance
return ;
AllegianceTreeNode * patron_node = GetTreeNode ( node - > _patronID ) ;
if ( ! patron_node ) // no patron
return ;
2018-07-12 14:41:21 -07:00
CWeenieObject * sender_weenie = g_pWorld - > FindPlayer ( sender_id ) ;
2018-03-29 17:01:57 -04:00
if ( ! sender_weenie )
return ;
2018-09-06 22:40:43 -05:00
sender_weenie - > SendNetMessage ( ChannelChat ( Covassals_ChannelID , NULL , text ) , PRIVATE_MSG , FALSE , TRUE ) ;
2018-03-29 17:01:57 -04:00
for ( auto & entry : patron_node - > _vassals )
{
if ( entry . second - > _charID = = sender_id )
continue ;
2018-07-12 14:41:21 -07:00
CWeenieObject * target = g_pWorld - > FindPlayer ( entry . second - > _charID ) ;
2018-03-29 17:01:57 -04:00
if ( target )
2018-09-06 22:40:43 -05:00
target - > SendNetMessage ( ChannelChat ( Covassals_ChannelID , sender_weenie - > GetName ( ) . c_str ( ) , text ) , PRIVATE_MSG , FALSE , TRUE ) ;
2018-03-29 17:01:57 -04:00
}
2018-07-12 14:41:21 -07:00
CWeenieObject * patron_weenie = g_pWorld - > FindPlayer ( node - > _patronID ) ;
2018-03-29 17:01:57 -04:00
if ( patron_weenie )
2018-09-06 22:40:43 -05:00
patron_weenie - > SendNetMessage ( ChannelChat ( Covassals_ChannelID , sender_weenie - > GetName ( ) . c_str ( ) , text ) , PRIVATE_MSG , FALSE , TRUE ) ;
2018-03-29 17:01:57 -04:00
}
2018-07-12 14:41:21 -07:00
void AllegianceManager : : SendAllegianceProfile ( CWeenieObject * pPlayer )
2018-03-29 17:01:57 -04:00
{
unsigned int rank = 0 ;
AllegianceProfile * prof = g_pAllegianceManager - > CreateAllegianceProfile ( pPlayer - > GetID ( ) , & rank ) ;
BinaryWriter allegianceUpdate ;
2019-07-07 20:56:15 +00:00
allegianceUpdate . Write < uint32_t > ( 0x20 ) ;
allegianceUpdate . Write < uint32_t > ( rank ) ;
2018-03-29 17:01:57 -04:00
prof - > Pack ( & allegianceUpdate ) ;
2019-05-12 09:21:34 -07:00
pPlayer - > SendNetMessage ( & allegianceUpdate , PRIVATE_MSG , TRUE , FALSE , true ) ;
2018-03-29 17:01:57 -04:00
2019-05-28 14:44:51 +00:00
// Not found in end of retail pcaps
//BinaryWriter allegianceUpdateDone;
2019-07-07 20:56:15 +00:00
//allegianceUpdateDone.Write<uint32_t>(0x1C8);
//allegianceUpdateDone.Write<uint32_t>(0);
2019-05-28 14:44:51 +00:00
//pPlayer->SendNetMessage(&allegianceUpdateDone, PRIVATE_MSG, TRUE, FALSE);
2018-03-29 17:01:57 -04:00
delete prof ;
}
2019-07-07 20:56:15 +00:00
uint32_t AllegianceManager : : GetCachedMonarchIDForPlayer ( CPlayerWeenie * player )
2018-03-29 17:01:57 -04:00
{
// this data may not be trustworthy, should use tree node for anything important
return player - > InqIIDQuality ( MONARCH_IID , 0 ) ;
2018-07-28 15:21:38 +01:00
}
2018-08-07 17:23:52 +01:00
// This will return true if they are an officer or the monarch
2018-07-28 15:21:38 +01:00
bool AllegianceManager : : IsOfficer ( AllegianceTreeNode * playerNode )
{
2018-08-07 17:23:52 +01:00
if ( playerNode )
2018-07-28 15:21:38 +01:00
{
2018-08-07 17:23:52 +01:00
if ( IsMonarch ( playerNode ) )
return true ;
2018-08-12 01:10:53 +01:00
if ( AllegianceInfo * ai = GetInfo ( playerNode - > _monarchID ) ) {
for ( auto officer : ai - > _info . m_officerList )
2018-07-28 15:21:38 +01:00
{
2018-08-12 01:10:53 +01:00
if ( officer . first = = playerNode - > _charID )
{
return true ;
}
2018-07-28 15:21:38 +01:00
}
}
}
return false ;
}
bool AllegianceManager : : IsMonarch ( AllegianceTreeNode * playerNode )
{
if ( playerNode )
{
2018-08-07 17:23:52 +01:00
if ( playerNode - > _monarchID = = playerNode - > _charID )
2018-07-28 15:21:38 +01:00
{
2018-08-07 17:23:52 +01:00
return true ;
2018-07-28 15:21:38 +01:00
}
}
return false ;
}
eAllegianceOfficerLevel AllegianceManager : : GetOfficerLevel ( std : : string player_name )
{
2019-07-07 20:56:15 +00:00
uint32_t playerID = g_pDBIO - > GetPlayerCharacterId ( player_name . c_str ( ) ) ;
2018-07-28 15:21:38 +01:00
return GetOfficerLevel ( playerID ) ;
}
2019-07-07 20:56:15 +00:00
eAllegianceOfficerLevel AllegianceManager : : GetOfficerLevel ( uint32_t player_id )
2018-07-28 15:21:38 +01:00
{
if ( AllegianceTreeNode * playerNode = GetTreeNode ( player_id ) )
{
if ( IsOfficer ( playerNode ) )
{
2018-08-07 17:23:52 +01:00
if ( IsMonarch ( playerNode ) )
return Castellan_AllegianceOfficerLevel ;
2018-08-12 01:10:53 +01:00
if ( AllegianceInfo * ai = GetInfo ( playerNode - > _monarchID ) ) {
for ( auto officer : ai - > _info . m_officerList )
2018-07-28 15:21:38 +01:00
{
2018-08-12 01:10:53 +01:00
if ( officer . first = = player_id )
{
return officer . second ;
}
2018-07-28 15:21:38 +01:00
}
}
}
}
return Undef_AllegianceOfficerLevel ;
}
std : : string AllegianceManager : : GetOfficerTitle ( std : : string player_name )
{
2019-07-07 20:56:15 +00:00
uint32_t playerID = g_pDBIO - > GetPlayerCharacterId ( player_name . c_str ( ) ) ;
2018-07-28 15:21:38 +01:00
return GetOfficerTitle ( playerID ) ;
}
2019-07-07 20:56:15 +00:00
std : : string AllegianceManager : : GetOfficerTitle ( uint32_t player_id )
2018-07-28 15:21:38 +01:00
{
eAllegianceOfficerLevel officerLevel = GetOfficerLevel ( player_id ) ;
if ( officerLevel ) // player is actually an officer
{
if ( AllegianceTreeNode * playerNode = GetTreeNode ( player_id ) )
{
2018-08-12 01:10:53 +01:00
if ( IsMonarch ( playerNode ) ) {
return " Monarch " ;
}
if ( AllegianceInfo * ai = GetInfo ( playerNode - > _monarchID ) )
{
return ai - > _info . m_officerTitleList [ officerLevel - 1 ] ;
}
2018-07-28 15:21:38 +01:00
}
}
return " " ;
}
2018-08-07 17:23:52 +01:00
// this will always return true for the monarch
2018-07-28 15:21:38 +01:00
bool AllegianceManager : : IsOfficerWithLevel ( AllegianceTreeNode * playerNode , eAllegianceOfficerLevel min , eAllegianceOfficerLevel max )
{
2018-08-07 17:23:52 +01:00
if ( playerNode )
2018-07-28 15:21:38 +01:00
{
2018-08-07 17:23:52 +01:00
if ( IsMonarch ( playerNode ) )
return true ;
2018-08-12 01:10:53 +01:00
if ( AllegianceInfo * ai = GetInfo ( playerNode - > _monarchID ) ) {
for ( auto officer : ai - > _info . m_officerList )
2018-07-28 15:21:38 +01:00
{
2018-08-12 01:10:53 +01:00
if ( officer . first = = playerNode - > _charID & & officer . second > = min & & officer . second < = max )
{
return true ;
}
2018-07-28 15:21:38 +01:00
}
}
}
return false ;
}
void AllegianceManager : : SetMOTD ( CPlayerWeenie * player , std : : string msg )
{
2018-08-12 01:10:53 +01:00
if ( msg . empty ( ) )
return ;
2018-07-28 15:21:38 +01:00
AllegianceTreeNode * playerNode = GetTreeNode ( player - > GetID ( ) ) ;
if ( ! playerNode )
{
player - > NotifyWeenieError ( WERROR_ALLEGIANCE_NONEXISTENT ) ;
return ;
}
2018-08-07 17:23:52 +01:00
if ( ! IsOfficer ( playerNode ) )
2018-07-28 15:21:38 +01:00
{
player - > NotifyWeenieError ( WERROR_ALLEGIANCE_NOT_AUTHORIZED ) ;
return ;
}
2018-08-12 01:10:53 +01:00
if ( AllegianceInfo * ai = GetInfo ( playerNode - > _monarchID ) )
2018-07-28 15:21:38 +01:00
{
2019-08-23 09:43:52 -05:00
std : : string rank = GetRankTitle ( playerNode - > _gender , playerNode - > _hg , playerNode - > _rank ) ;
2018-08-12 01:10:53 +01:00
ai - > _info . m_storedMOTD = msg ;
2019-08-23 09:43:52 -05:00
ai - > _info . m_storedMOTDSetBy = rank + " " + player - > GetName ( ) ;
2018-07-28 15:21:38 +01:00
player - > SendText ( " Your allegiance message of the day has been set. " , LTT_DEFAULT ) ;
2018-08-07 17:23:52 +01:00
Save ( ) ;
2018-07-28 15:21:38 +01:00
}
}
void AllegianceManager : : LoginMOTD ( CPlayerWeenie * player )
{
AllegianceTreeNode * self = GetTreeNode ( player - > GetID ( ) ) ;
if ( ! self )
return ;
2018-08-12 01:10:53 +01:00
AllegianceInfo * ai = GetInfo ( self - > _monarchID ) ;
if ( ! ai )
2018-07-28 15:21:38 +01:00
return ;
2018-08-12 01:10:53 +01:00
if ( ! ai - > _info . m_storedMOTD . empty ( ) )
2018-07-28 15:21:38 +01:00
{
2019-08-23 09:43:52 -05:00
player - > SendText ( csprintf ( " \" %s \" -- %s " , ai - > _info . m_storedMOTD . c_str ( ) , ai - > _info . m_storedMOTDSetBy . c_str ( ) ) , LTT_DEFAULT ) ;
2018-07-28 15:21:38 +01:00
}
}
void AllegianceManager : : ClearMOTD ( CPlayerWeenie * player )
{
AllegianceTreeNode * playerNode = GetTreeNode ( player - > GetID ( ) ) ;
if ( ! playerNode )
{
player - > NotifyWeenieError ( WERROR_ALLEGIANCE_NONEXISTENT ) ;
return ;
}
2018-08-07 17:23:52 +01:00
if ( ! IsOfficer ( playerNode ) )
2018-07-28 15:21:38 +01:00
{
player - > NotifyWeenieError ( WERROR_ALLEGIANCE_NOT_AUTHORIZED ) ;
return ;
}
2018-08-12 01:10:53 +01:00
if ( AllegianceInfo * ai = GetInfo ( playerNode - > _monarchID ) )
2018-07-28 15:21:38 +01:00
{
2018-08-12 01:10:53 +01:00
ai - > _info . m_storedMOTD . clear ( ) ;
ai - > _info . m_storedMOTDSetBy . clear ( ) ;
2018-07-28 15:21:38 +01:00
player - > SendText ( " Your allegiance message of the day has been cleared. " , LTT_DEFAULT ) ;
2018-08-07 17:23:52 +01:00
Save ( ) ;
2018-07-28 15:21:38 +01:00
}
}
void AllegianceManager : : QueryMOTD ( CPlayerWeenie * player )
{
AllegianceTreeNode * playerNode = GetTreeNode ( player - > GetID ( ) ) ;
if ( ! playerNode )
{
player - > NotifyWeenieError ( WERROR_ALLEGIANCE_NONEXISTENT ) ;
return ;
}
2018-08-12 01:10:53 +01:00
if ( AllegianceInfo * ai = GetInfo ( playerNode - > _monarchID ) )
2018-07-28 15:21:38 +01:00
{
2018-08-12 01:10:53 +01:00
if ( ai - > _info . m_storedMOTD . empty ( ) )
2018-07-28 15:21:38 +01:00
{
player - > SendText ( " Your allegiance has not set a message of the day. " , LTT_DEFAULT ) ;
}
else
{
2018-08-12 01:10:53 +01:00
player - > SendText ( csprintf ( " %s -- %s %s " , ai - > _info . m_storedMOTD . c_str ( ) , GetOfficerTitle ( ai - > _info . m_storedMOTDSetBy ) . c_str ( ) , ai - > _info . m_storedMOTDSetBy . c_str ( ) ) , LTT_DEFAULT ) ;
2018-07-28 15:21:38 +01:00
}
}
}
void AllegianceManager : : SetAllegianceName ( CPlayerWeenie * player , std : : string name )
{
AllegianceTreeNode * playerNode = GetTreeNode ( player - > GetID ( ) ) ;
if ( ! playerNode )
{
player - > NotifyWeenieError ( WERROR_ALLEGIANCE_NONEXISTENT ) ;
return ;
}
2018-08-07 17:23:52 +01:00
if ( ! IsOfficerWithLevel ( playerNode , Castellan_AllegianceOfficerLevel ) )
2018-07-28 15:21:38 +01:00
{
player - > NotifyWeenieError ( WERROR_ALLEGIANCE_NOT_AUTHORIZED ) ;
return ;
}
2018-08-12 01:10:53 +01:00
if ( AllegianceInfo * ai = GetInfo ( playerNode - > _monarchID ) )
2018-07-28 15:21:38 +01:00
{
2018-08-12 01:10:53 +01:00
if ( ai - > _info . m_NameLastSetTime + 86400 < = time ( 0 ) ) // check if 24 hours since last change
2018-07-28 15:21:38 +01:00
{
2018-08-12 01:10:53 +01:00
if ( name = = ai - > _info . m_AllegianceName )
2018-07-28 15:21:38 +01:00
{
player - > NotifyWeenieError ( WERROR_ALLEGIANCE_NAME_SAME_NAME ) ;
return ;
}
if ( name . empty ( ) )
{
player - > NotifyWeenieError ( WERROR_ALLEGIANCE_NAME_EMPTY ) ;
return ;
}
if ( name . length ( ) > 40 )
{
player - > NotifyWeenieError ( WERROR_ALLEGIANCE_NAME_TOO_LONG ) ;
}
for ( auto info : _allegInfos )
{
if ( info . second - > _info . m_AllegianceName = = name )
{
player - > NotifyWeenieError ( WERROR_ALLEGIANCE_NAME_IN_USE ) ;
return ;
}
}
2018-08-07 17:23:52 +01:00
if ( containsBadCharacters ( name , 2 ) ) // space, single quote, hyphen, A-Z, a-z
2018-07-28 15:21:38 +01:00
{
2018-08-07 17:23:52 +01:00
player - > NotifyWeenieError ( WERROR_ALLEGIANCE_NAME_BAD_CHARACTER ) ;
return ;
2018-07-28 15:21:38 +01:00
}
2019-07-07 20:56:15 +00:00
for ( auto const & value : g_pPortalDataEx - > GetBannedwords ( ) )
2018-07-28 15:21:38 +01:00
{
if ( name . find ( value ) ! = std : : string : : npos )
{
player - > NotifyWeenieError ( WERROR_ALLEGIANCE_NAME_NOT_APPROPRIATE ) ;
return ;
}
}
2018-08-12 01:10:53 +01:00
ai - > _info . m_AllegianceName = name ;
2018-07-28 15:21:38 +01:00
player - > SendText ( " Your allegiance name has been set. " , LTT_DEFAULT ) ;
2018-08-12 01:10:53 +01:00
ai - > _info . m_NameLastSetTime = time ( 0 ) ;
2018-08-14 19:46:16 +01:00
Save ( ) ;
NotifyTreeRefreshRecursively ( GetTreeNode ( playerNode - > _monarchID ) ) ;
2018-07-28 15:21:38 +01:00
}
else
{
2018-08-12 01:10:53 +01:00
int nextSetTime = ( ai - > _info . m_NameLastSetTime + 86400 ) - time ( 0 ) ; // how long before it can be changed again in seconds
2018-07-28 15:21:38 +01:00
player - > NotifyWeenieErrorWithString ( WERROR_ALLEGIANCE_NAME_TIMER , TimeToString ( nextSetTime ) . c_str ( ) ) ;
}
}
}
void AllegianceManager : : ClearAllegianceName ( CPlayerWeenie * player )
{
AllegianceTreeNode * playerNode = GetTreeNode ( player - > GetID ( ) ) ;
if ( ! playerNode )
{
player - > NotifyWeenieError ( WERROR_ALLEGIANCE_NONEXISTENT ) ;
return ;
}
2018-08-07 17:23:52 +01:00
if ( ! IsOfficerWithLevel ( playerNode , Castellan_AllegianceOfficerLevel ) )
2018-07-28 15:21:38 +01:00
{
player - > NotifyWeenieError ( WERROR_ALLEGIANCE_NOT_AUTHORIZED ) ;
return ;
}
2018-08-12 01:10:53 +01:00
if ( AllegianceInfo * ai = GetInfo ( playerNode - > _monarchID ) )
2018-07-28 15:21:38 +01:00
{
2018-08-12 01:10:53 +01:00
ai - > _info . m_AllegianceName . clear ( ) ;
2018-07-28 15:21:38 +01:00
player - > SendText ( " Your allegiance name has been cleared. " , LTT_DEFAULT ) ;
2018-08-07 17:23:52 +01:00
Save ( ) ;
2018-08-14 19:46:16 +01:00
NotifyTreeRefreshRecursively ( GetTreeNode ( playerNode - > _monarchID ) ) ;
2018-07-28 15:21:38 +01:00
}
}
void AllegianceManager : : QueryAllegianceName ( CPlayerWeenie * player )
{
AllegianceTreeNode * playerNode = GetTreeNode ( player - > GetID ( ) ) ;
if ( ! playerNode )
{
player - > NotifyWeenieError ( WERROR_ALLEGIANCE_NONEXISTENT ) ;
return ;
}
2018-08-12 01:10:53 +01:00
if ( AllegianceInfo * ai = GetInfo ( playerNode - > _monarchID ) )
2018-07-28 15:21:38 +01:00
{
2018-08-12 01:10:53 +01:00
if ( ai - > _info . m_AllegianceName . empty ( ) )
2018-07-28 15:21:38 +01:00
{
player - > SendText ( " Your allegiance hasn't set an allegiance name. " , LTT_DEFAULT ) ;
}
else
{
2018-08-12 01:10:53 +01:00
player - > SendText ( csprintf ( " Your allegiance name is %s " , ai - > _info . m_AllegianceName . c_str ( ) ) , LTT_DEFAULT ) ;
2018-07-28 15:21:38 +01:00
}
}
}
void AllegianceManager : : SetOfficerTitle ( CPlayerWeenie * player , int level , std : : string title )
{
AllegianceTreeNode * playerNode = GetTreeNode ( player - > GetID ( ) ) ;
if ( ! playerNode )
{
player - > NotifyWeenieError ( WERROR_ALLEGIANCE_NONEXISTENT ) ;
return ;
}
2018-08-07 17:23:52 +01:00
if ( ! IsOfficer ( playerNode ) )
2018-07-28 15:21:38 +01:00
{
player - > NotifyWeenieError ( WERROR_ALLEGIANCE_NOT_AUTHORIZED ) ;
return ;
}
if ( level > 3 | | level < 1 )
{
player - > NotifyWeenieError ( WERROR_ALLEGIANCE_OFFICER_INVALID_LEVEL ) ;
return ;
}
if ( title . length ( ) > 20 )
{
player - > NotifyWeenieError ( WERROR_ALLEGIANCE_OFFICER_TITLE_TOO_LONG ) ;
return ;
}
2018-08-07 17:23:52 +01:00
if ( containsBadCharacters ( title , 2 ) )
2018-07-28 15:21:38 +01:00
{
2018-08-07 17:23:52 +01:00
player - > NotifyWeenieError ( WERROR_ALLEGIANCE_OFFICER_TITLE_BAD_CHARACTER ) ;
return ;
2018-07-28 15:21:38 +01:00
}
2019-07-07 20:56:15 +00:00
for ( auto const & value : g_pPortalDataEx - > GetBannedwords ( ) )
2018-07-28 15:21:38 +01:00
{
if ( title . find ( value ) ! = std : : string : : npos )
{
player - > NotifyWeenieError ( WERROR_ALLEGIANCE_OFFICER_TITLE_NOT_APPROPRIATE ) ;
return ;
}
}
2018-08-12 01:10:53 +01:00
if ( AllegianceInfo * ai = GetInfo ( playerNode - > _monarchID ) )
2018-07-28 15:21:38 +01:00
{
2018-08-12 01:10:53 +01:00
ai - > _info . m_officerTitleList [ level - 1 ] = title ;
2018-07-28 15:21:38 +01:00
player - > NotifyWeenieErrorWithString ( WERROR_ALLEGIANCE_OFFICER_TITLE_SET , title . c_str ( ) ) ;
2018-08-07 17:23:52 +01:00
Save ( ) ;
2018-07-28 15:21:38 +01:00
}
}
void AllegianceManager : : ClearOfficerTitles ( CPlayerWeenie * player )
{
AllegianceTreeNode * playerNode = GetTreeNode ( player - > GetID ( ) ) ;
if ( ! playerNode )
{
player - > NotifyWeenieError ( WERROR_ALLEGIANCE_NONEXISTENT ) ;
return ;
}
2018-08-07 17:23:52 +01:00
if ( ! IsOfficerWithLevel ( playerNode , Castellan_AllegianceOfficerLevel ) )
2018-07-28 15:21:38 +01:00
{
player - > NotifyWeenieError ( WERROR_ALLEGIANCE_NOT_AUTHORIZED ) ;
return ;
}
2018-08-12 01:10:53 +01:00
if ( AllegianceInfo * ai = GetInfo ( playerNode - > _monarchID ) )
2018-07-28 15:21:38 +01:00
{
2018-08-12 01:10:53 +01:00
ai - > _info . m_officerTitleList . clear ( ) ;
ai - > _info . m_officerTitleList = { " Speaker " , " Seneschal " , " Castellan " } ;
2018-07-28 15:21:38 +01:00
player - > NotifyWeenieError ( WERROR_ALLEGIANCE_OFFICER_TITLE_CLEARED ) ;
2018-08-07 17:23:52 +01:00
Save ( ) ;
2018-07-28 15:21:38 +01:00
}
}
void AllegianceManager : : ListOfficerTitles ( CPlayerWeenie * player )
{
AllegianceTreeNode * playerNode = GetTreeNode ( player - > GetID ( ) ) ;
if ( ! playerNode )
{
player - > NotifyWeenieError ( WERROR_ALLEGIANCE_NONEXISTENT ) ;
return ;
}
2018-08-12 01:10:53 +01:00
if ( AllegianceInfo * ai = GetInfo ( playerNode - > _monarchID ) )
2018-07-28 15:21:38 +01:00
{
2018-08-12 01:10:53 +01:00
if ( ai - > _info . m_officerTitleList . empty ( ) ) {
ai - > _info . m_officerTitleList = { " Speaker " , " Seneschal " , " Castellan " } ;
}
2018-07-28 15:21:38 +01:00
player - > SendText ( " Allegiance Officer Titles: " , LTT_DEFAULT ) ;
2018-08-07 17:23:52 +01:00
for ( int i = 0 ; i < 3 ; i + + )
2018-07-28 15:21:38 +01:00
{
2018-08-12 01:10:53 +01:00
player - > SendText ( csprintf ( " %d. %s " , i + 1 , ai - > _info . m_officerTitleList [ i ] . c_str ( ) ) , LTT_DEFAULT ) ;
2018-07-28 15:21:38 +01:00
}
}
}
void AllegianceManager : : SetOfficer ( CPlayerWeenie * player , std : : string officer_name , eAllegianceOfficerLevel level )
{
2018-08-07 17:23:52 +01:00
AllegianceTreeNode * playerNode = GetTreeNode ( player - > GetID ( ) ) ;
if ( ! playerNode )
{
player - > NotifyWeenieError ( WERROR_ALLEGIANCE_NONEXISTENT ) ;
return ;
}
if ( ! IsOfficer ( playerNode ) )
{
player - > NotifyWeenieError ( WERROR_ALLEGIANCE_NOT_AUTHORIZED ) ;
return ;
}
2019-07-07 20:56:15 +00:00
uint32_t officerID = g_pDBIO - > GetPlayerCharacterId ( officer_name . c_str ( ) ) ;
2018-08-14 19:46:16 +01:00
if ( ! officerID )
return ;
2018-07-28 15:21:38 +01:00
if ( AllegianceTreeNode * officerNode = GetTreeNode ( officerID ) )
{
2018-08-07 17:23:52 +01:00
if ( IsMonarch ( officerNode ) )
{
player - > NotifyWeenieErrorWithString ( WERROR_ALLEGIANCE_OFFICER_NOT_SET , officer_name . c_str ( ) ) ;
return ;
}
2018-07-28 15:21:38 +01:00
if ( IsOfficer ( officerNode ) & & GetOfficerLevel ( officerID ) = = level )
{
player - > NotifyWeenieErrorWithString ( WERROR_ALLEGIANCE_OFFICER_ALREADY_OFFICER , officer_name . c_str ( ) ) ;
return ;
}
if ( level < = 0 | | level > 3 )
{
player - > NotifyWeenieError ( WERROR_ALLEGIANCE_OFFICER_INVALID_LEVEL ) ;
return ;
}
2018-08-12 01:10:53 +01:00
if ( AllegianceInfo * ai = GetInfo ( playerNode - > _monarchID ) )
2018-07-28 15:21:38 +01:00
{
2018-08-12 01:10:53 +01:00
if ( ai - > _info . m_officerList . size ( ) > = 12 ) {
2018-07-28 15:21:38 +01:00
player - > NotifyWeenieError ( WERROR_ALLEGIANCE_OFFICER_FULL ) ;
return ;
}
2018-08-07 17:23:52 +01:00
if ( IsOfficer ( officerNode ) ) {
2018-08-12 01:10:53 +01:00
ai - > _info . m_officerList [ officerID ] = level ;
player - > SendText ( csprintf ( " %s's allegiance officer status has been modified. %s now holds the position of: %s. " , officer_name . c_str ( ) , officer_name . c_str ( ) , ai - > _info . m_officerTitleList [ level - 1 ] . c_str ( ) ) , LTT_DEFAULT ) ;
2018-07-28 15:21:38 +01:00
}
2018-08-07 17:23:52 +01:00
else {
2018-08-12 01:10:53 +01:00
ai - > _info . m_officerList . emplace ( officerID , level ) ;
player - > NotifyWeenieErrorWithString ( WERROR_ALLEGIANCE_OFFICER_SET , officer_name . c_str ( ) ) ;
2018-07-28 15:21:38 +01:00
}
2018-08-12 01:10:53 +01:00
2018-08-07 17:23:52 +01:00
if ( CPlayerWeenie * officer = g_pWorld - > FindPlayer ( officerID ) ) {
officer - > NotifyWeenieErrorWithString ( WERROR_ALLEGIANCE_YOU_ARE_NOW_AN_OFFICER , GetOfficerTitle ( officer_name ) . c_str ( ) ) ;
}
Save ( ) ;
2018-07-28 15:21:38 +01:00
}
}
2018-08-07 17:23:52 +01:00
else
player - > NotifyWeenieErrorWithString ( WERROR_ALLEGIANCE_OFFICER_NOT_SET , officer_name . c_str ( ) ) ;
2018-07-28 15:21:38 +01:00
}
void AllegianceManager : : RemoveOfficer ( CPlayerWeenie * player , std : : string officer_name )
{
2018-08-07 17:23:52 +01:00
AllegianceTreeNode * playerNode = GetTreeNode ( player - > GetID ( ) ) ;
if ( ! playerNode )
{
player - > NotifyWeenieError ( WERROR_ALLEGIANCE_NONEXISTENT ) ;
return ;
}
// only monarchs and level 2+ officers are authorized to remove officers
if ( ! IsOfficerWithLevel ( playerNode , Seneschal_AllegianceOfficerLevel ) )
{
player - > NotifyWeenieError ( WERROR_ALLEGIANCE_NOT_AUTHORIZED ) ;
return ;
}
2019-07-07 20:56:15 +00:00
uint32_t officerID = g_pDBIO - > GetPlayerCharacterId ( officer_name . c_str ( ) ) ;
2018-07-28 15:21:38 +01:00
if ( AllegianceTreeNode * officerNode = GetTreeNode ( officerID ) )
{
2018-08-07 17:23:52 +01:00
if ( ! IsOfficer ( officerNode ) | | IsMonarch ( officerNode ) ) // can't remove someone who isn't on the list or the monarch
2018-07-28 15:21:38 +01:00
{
player - > SendText ( csprintf ( " %s is not an allegiance officer! " , officer_name . c_str ( ) ) , LTT_DEFAULT ) ;
return ;
}
// only level 3 officers and monarchs can remove level 2+ officers
if ( IsOfficerWithLevel ( officerNode , Seneschal_AllegianceOfficerLevel ) )
{
2018-08-07 17:23:52 +01:00
if ( ! IsOfficerWithLevel ( playerNode , Castellan_AllegianceOfficerLevel ) )
2018-07-28 15:21:38 +01:00
{
player - > NotifyWeenieError ( WERROR_ALLEGIANCE_NOT_AUTHORIZED ) ;
return ;
}
}
2018-08-12 01:10:53 +01:00
if ( AllegianceInfo * ai = GetInfo ( playerNode - > _monarchID ) )
2018-07-28 15:21:38 +01:00
{
2018-08-12 01:10:53 +01:00
for ( auto officer : ai - > _info . m_officerList )
2018-07-28 15:21:38 +01:00
{
if ( officer . first = = officerID )
{
2018-08-12 01:10:53 +01:00
ai - > _info . m_officerList . remove ( officerID ) ;
2018-07-28 15:21:38 +01:00
player - > NotifyWeenieErrorWithString ( WERROR_ALLEGIANCE_OFFICER_REMOVED , officer_name . c_str ( ) ) ;
2018-08-12 01:10:53 +01:00
2018-08-07 17:23:52 +01:00
if ( CPlayerWeenie * officer = g_pWorld - > FindPlayer ( officerID ) ) {
officer - > NotifyWeenieError ( WERROR_ALLEGIANCE_YOU_ARE_NO_LONGER_AN_OFFICER ) ;
}
2018-08-12 01:10:53 +01:00
Save ( ) ;
return ;
2018-07-28 15:21:38 +01:00
}
}
}
}
2018-08-12 01:10:53 +01:00
player - > NotifyWeenieErrorWithString ( WERROR_ALLEGIANCE_OFFICER_NOT_REMOVED , officer_name . c_str ( ) ) ;
2018-07-28 15:21:38 +01:00
}
void AllegianceManager : : ListOfficers ( CPlayerWeenie * player )
{
AllegianceTreeNode * playerNode = GetTreeNode ( player - > GetID ( ) ) ;
if ( ! playerNode )
{
player - > NotifyWeenieError ( WERROR_ALLEGIANCE_NONEXISTENT ) ;
return ;
}
2018-08-12 01:10:53 +01:00
if ( AllegianceInfo * ai = GetInfo ( playerNode - > _monarchID ) )
2018-07-28 15:21:38 +01:00
{
player - > SendText ( " Allegiance Officers: " , LTT_DEFAULT ) ;
2018-09-25 12:54:26 -07:00
player - > SendText ( csprintf ( " %s (Monarch) " , g_pDBIO - > GetPlayerCharacterName ( playerNode - > _monarchID ) . c_str ( ) ) , LTT_DEFAULT ) ;
2018-08-12 01:10:53 +01:00
for ( auto officer : ai - > _info . m_officerList )
2018-07-28 15:21:38 +01:00
{
2018-09-25 12:54:26 -07:00
player - > SendText ( csprintf ( " %s (%s) " , g_pDBIO - > GetPlayerCharacterName ( officer . first ) . c_str ( ) , GetOfficerTitle ( officer . first ) . c_str ( ) ) , LTT_DEFAULT ) ;
2018-07-28 15:21:38 +01:00
}
}
}
void AllegianceManager : : ClearOfficers ( CPlayerWeenie * player )
{
AllegianceTreeNode * playerNode = GetTreeNode ( player - > GetID ( ) ) ;
if ( ! playerNode )
{
player - > NotifyWeenieError ( WERROR_ALLEGIANCE_NONEXISTENT ) ;
return ;
}
2018-08-07 17:23:52 +01:00
// only monarch or level 3 officers can clear officer list
if ( ! IsOfficerWithLevel ( playerNode , Castellan_AllegianceOfficerLevel ) )
2018-07-28 15:21:38 +01:00
{
player - > NotifyWeenieError ( WERROR_ALLEGIANCE_NOT_AUTHORIZED ) ;
return ;
}
2018-08-12 01:10:53 +01:00
if ( AllegianceInfo * ai = GetInfo ( playerNode - > _monarchID ) )
2018-07-28 15:21:38 +01:00
{
2018-08-12 01:10:53 +01:00
for ( auto officer : ai - > _info . m_officerList )
2018-07-28 15:21:38 +01:00
{
2018-08-07 17:23:52 +01:00
if ( CPlayerWeenie * player = g_pWorld - > FindPlayer ( officer . first ) )
2018-07-28 15:21:38 +01:00
{
2018-08-07 17:23:52 +01:00
player - > NotifyWeenieError ( WERROR_ALLEGIANCE_YOU_ARE_NO_LONGER_AN_OFFICER ) ;
2018-07-28 15:21:38 +01:00
}
}
2018-08-12 01:10:53 +01:00
ai - > _info . m_officerList . clear ( ) ;
2018-07-28 15:21:38 +01:00
player - > NotifyWeenieError ( WERROR_ALLEGIANCE_OFFICERS_CLEARED ) ;
2018-08-07 17:23:52 +01:00
Save ( ) ;
2018-07-28 15:21:38 +01:00
}
}
2018-08-12 01:10:53 +01:00
// TODO info request time limit
2018-07-28 15:21:38 +01:00
void AllegianceManager : : AllegianceInfoRequest ( CPlayerWeenie * player , std : : string target_name )
{
AllegianceTreeNode * myNode = GetTreeNode ( player - > GetID ( ) ) ;
if ( ! myNode )
{
player - > NotifyWeenieError ( WERROR_ALLEGIANCE_NONEXISTENT ) ;
return ;
}
2018-08-07 17:23:52 +01:00
if ( ! IsOfficerWithLevel ( myNode , Seneschal_AllegianceOfficerLevel ) )
2018-07-28 15:21:38 +01:00
{
player - > NotifyWeenieError ( WERROR_ALLEGIANCE_NOT_AUTHORIZED ) ;
return ;
}
if ( target_name . empty ( ) )
{
player - > NotifyWeenieError ( WERROR_ALLEGIANCE_INFO_EMPTY_NAME ) ;
return ;
}
if ( target_name = = player - > GetName ( ) )
{
player - > NotifyWeenieError ( WERROR_ALLEGIANCE_INFO_SELF ) ;
return ;
}
2019-07-07 20:56:15 +00:00
uint32_t targetID = g_pWorld - > GetPlayerId ( target_name . c_str ( ) , true ) ;
2018-07-28 15:21:38 +01:00
AllegianceTreeNode * myTargetNode = GetTreeNode ( targetID ) ;
if ( ! myTargetNode )
{
player - > SendText ( " Could not find allegiance member. " , LTT_DEFAULT ) ;
return ;
}
if ( myTargetNode - > _monarchID ! = myNode - > _monarchID )
{
player - > SendText ( csprintf ( " %s is not a member of your allegiance. " , target_name . c_str ( ) ) , LTT_DEFAULT ) ;
return ;
2018-08-07 17:23:52 +01:00
}
2018-07-28 15:21:38 +01:00
// TODO: convert this to server to client message
unsigned int rank = 0 ;
if ( AllegianceProfile * profile = CreateAllegianceProfile ( myTargetNode - > _charID , & rank ) )
{
BinaryWriter allegianceUpdate ;
2019-07-07 20:56:15 +00:00
allegianceUpdate . Write < uint32_t > ( 0x27C ) ;
allegianceUpdate . Write < uint32_t > ( myTargetNode - > _charID ) ;
2018-07-28 15:21:38 +01:00
profile - > Pack ( & allegianceUpdate ) ;
player - > SendNetMessage ( & allegianceUpdate , PRIVATE_MSG , TRUE , FALSE ) ;
delete profile ;
}
else
{
player - > SendText ( " Error retrieving allegiance member information. " , LTT_DEFAULT ) ;
}
}
2019-07-07 20:56:15 +00:00
void AllegianceManager : : AllegianceLockAction ( CPlayerWeenie * player , uint32_t lock_action )
2018-07-28 15:21:38 +01:00
{
if ( AllegianceTreeNode * playerNode = GetTreeNode ( player - > GetID ( ) ) )
{
2018-08-07 17:23:52 +01:00
if ( IsOfficerWithLevel ( playerNode , Seneschal_AllegianceOfficerLevel ) )
2018-07-28 15:21:38 +01:00
{
2018-08-12 01:10:53 +01:00
if ( AllegianceInfo * ai = GetInfo ( playerNode - > _monarchID ) )
2018-07-28 15:21:38 +01:00
{
switch ( lock_action )
{
case LockedOff :
{
2018-08-12 01:10:53 +01:00
ai - > _info . m_isLocked = false ;
2018-07-28 15:21:38 +01:00
player - > NotifyWeenieErrorWithString ( WERROR_ALLEGIANCE_LOCK_SET , " Unlocked " ) ;
2018-08-07 17:23:52 +01:00
Save ( ) ;
2018-07-28 15:21:38 +01:00
break ;
}
case LockedOn :
{
2018-08-12 01:10:53 +01:00
ai - > _info . m_isLocked = true ;
2018-07-28 15:21:38 +01:00
player - > NotifyWeenieErrorWithString ( WERROR_ALLEGIANCE_LOCK_SET , " Locked " ) ;
2018-08-07 17:23:52 +01:00
Save ( ) ;
2018-07-28 15:21:38 +01:00
break ;
}
case ToggleLocked :
{
2018-08-12 01:10:53 +01:00
if ( ai - > _info . m_isLocked = = false )
2018-07-28 15:21:38 +01:00
{
2018-08-12 01:10:53 +01:00
ai - > _info . m_isLocked = true ;
2018-07-28 15:21:38 +01:00
player - > NotifyWeenieErrorWithString ( WERROR_ALLEGIANCE_LOCK_SET , " Locked " ) ;
2018-08-07 17:23:52 +01:00
Save ( ) ;
2018-07-28 15:21:38 +01:00
break ;
}
else
{
2018-08-12 01:10:53 +01:00
ai - > _info . m_isLocked = false ;
2018-07-28 15:21:38 +01:00
player - > NotifyWeenieErrorWithString ( WERROR_ALLEGIANCE_LOCK_SET , " Unlocked " ) ;
2018-08-07 17:23:52 +01:00
Save ( ) ;
2018-07-28 15:21:38 +01:00
break ;
}
}
case CheckLocked :
{
2018-08-12 01:10:53 +01:00
player - > NotifyWeenieErrorWithString ( WERROR_ALLEGIANCE_LOCK_DISPLAY , ai - > _info . m_isLocked ? " Locked " : " Unlocked " ) ;
2018-07-28 15:21:38 +01:00
break ;
}
case DisplayBypass : // show approved vassal
{
2018-08-12 01:10:53 +01:00
if ( ! ai - > _info . m_ApprovedVassal )
2018-07-28 15:21:38 +01:00
{
player - > NotifyWeenieError ( WERROR_ALLEGIANCE_LOCK_NO_APPROVED ) ;
break ;
}
else
{
2018-08-12 01:10:53 +01:00
std : : string vassal = g_pWorld - > GetPlayerName ( ai - > _info . m_ApprovedVassal , true ) ;
2018-07-28 15:21:38 +01:00
player - > NotifyWeenieErrorWithString ( WERROR_ALLEGIANCE_LOCK_APPROVED_DISPLAY , vassal . c_str ( ) ) ;
break ;
}
}
case ClearBypass : // clear approved vassal
{
2018-08-12 01:10:53 +01:00
ai - > _info . m_ApprovedVassal = 0 ;
2018-07-28 15:21:38 +01:00
player - > NotifyWeenieError ( WERROR_ALLEGIANCE_APPROVED_CLEARED ) ;
2018-08-07 17:23:52 +01:00
Save ( ) ;
2018-07-28 15:21:38 +01:00
break ;
}
}
}
}
else
{
player - > NotifyWeenieError ( WERROR_ALLEGIANCE_NOT_AUTHORIZED ) ;
}
}
}
2018-07-30 10:08:39 +01:00
void AllegianceManager : : RecallHometown ( CPlayerWeenie * player )
{
if ( player - > CheckPKActivity ( ) )
{
player - > NotifyWeenieError ( WERROR_PORTAL_PK_ATTACKED_TOO_RECENTLY ) ;
return ;
}
AllegianceTreeNode * allegianceNode = GetTreeNode ( player - > GetID ( ) ) ;
if ( ! allegianceNode )
{
player - > NotifyWeenieError ( WERROR_ALLEGIANCE_NONEXISTENT ) ;
return ;
}
2018-08-12 01:10:53 +01:00
AllegianceInfo * ai = GetInfo ( allegianceNode - > _monarchID ) ;
2018-07-30 10:08:39 +01:00
2018-08-12 01:10:53 +01:00
if ( ai & & ai - > _info . m_BindPoint . objcell_id ) // TODO change to server side store?
2018-07-30 10:08:39 +01:00
{
player - > ExecuteUseEvent ( new CAllegianceHometownRecallUseEvent ( ) ) ;
}
else
{
player - > NotifyWeenieError ( WERROR_ALLEGIANCE_HOMETOWN_NOT_SET ) ;
}
}
2018-07-28 15:21:38 +01:00
void AllegianceManager : : ApproveVassal ( CPlayerWeenie * player , std : : string vassal_name )
{
2019-07-07 20:56:15 +00:00
uint32_t approvedVassalID = g_pWorld - > GetPlayerId ( vassal_name . c_str ( ) , true ) ;
uint32_t playerID = player - > GetID ( ) ;
2018-07-28 15:21:38 +01:00
AllegianceTreeNode * playerNode = GetTreeNode ( playerID ) ;
2018-09-25 12:54:26 -07:00
if ( playerNode & & IsOfficerWithLevel ( playerNode , Castellan_AllegianceOfficerLevel ) ) // either a monarch or a level 3 officer
2018-07-28 15:21:38 +01:00
{
if ( IsBanned ( approvedVassalID , playerNode - > _monarchID ) ) // check potential approved vassal's account isn't banned from the allegiance
{
player - > NotifyWeenieErrorWithString ( WERROR_ALLEGIANCE_BANNED , vassal_name . c_str ( ) ) ;
return ;
}
2018-09-25 12:54:26 -07:00
if ( AllegianceInfo * ai = GetInfo ( playerNode - > _monarchID ) )
{
2018-08-07 17:23:52 +01:00
ai - > _info . m_ApprovedVassal = approvedVassalID ;
player - > NotifyWeenieErrorWithString ( WERROR_ALLEGIANCE_APPROVED_SET , vassal_name . c_str ( ) ) ;
}
2018-07-28 15:21:38 +01:00
}
else
{
player - > NotifyWeenieError ( WERROR_ALLEGIANCE_NOT_AUTHORIZED ) ;
}
}
void AllegianceManager : : BootPlayer ( CPlayerWeenie * player , std : : string bootee , bool whole_account )
{
AllegianceTreeNode * playerNode = GetTreeNode ( player - > GetID ( ) ) ;
if ( ! playerNode ) // check caller even has an allegiance
{
player - > NotifyWeenieError ( WERROR_ALLEGIANCE_NONEXISTENT ) ;
return ;
}
if ( bootee . empty ( ) )
{
player - > NotifyWeenieError ( WERROR_ALLEGIANCE_BOOT_EMPTY_NAME ) ;
return ;
}
if ( bootee = = player - > GetName ( ) )
{
player - > NotifyWeenieError ( WERROR_ALLEGIANCE_BOOT_SELF ) ;
return ;
}
2018-08-07 17:23:52 +01:00
if ( IsOfficerWithLevel ( playerNode , Seneschal_AllegianceOfficerLevel ) ) // check caller has correct authority
2018-07-28 15:21:38 +01:00
{
2019-07-07 20:56:15 +00:00
uint32_t booteeID = g_pWorld - > GetPlayerId ( bootee . c_str ( ) , true ) ;
2018-07-28 15:21:38 +01:00
if ( AllegianceTreeNode * booteeNode = GetTreeNode ( booteeID ) )
{
if ( booteeNode - > _monarchID = = playerNode - > _monarchID )
{
if ( whole_account )
{
std : : list < CharacterDesc_t > bootees = g_pDBIO - > GetCharacterList ( g_pDBIO - > GetCharacterInfo ( booteeID ) . account_id ) ;
for ( auto bootee : bootees )
{
if ( AllegianceTreeNode * bNode = GetTreeNode ( bootee . weenie_id ) )
{
if ( bNode - > _monarchID = = playerNode - > _monarchID )
{
2018-08-12 01:10:53 +01:00
TryBreakAllegiance ( bNode - > _patronID , bNode - > _charID ) ;
2018-07-28 15:21:38 +01:00
}
}
}
player - > SendText ( csprintf ( " You have successfully booted the account of %s from the allegiance. " , bootee . c_str ( ) ) , LTT_DEFAULT ) ;
return ;
}
2018-08-12 01:10:53 +01:00
TryBreakAllegiance ( booteeNode - > _patronID , booteeID ) ;
2018-07-28 15:21:38 +01:00
player - > SendText ( csprintf ( " You have successfully booted %s from the allegiance. " , bootee . c_str ( ) ) , LTT_DEFAULT ) ;
2018-08-07 17:23:52 +01:00
Save ( ) ;
2018-07-28 15:21:38 +01:00
}
}
}
2018-07-30 10:08:39 +01:00
else
{
player - > NotifyWeenieError ( WERROR_ALLEGIANCE_NOT_AUTHORIZED ) ;
}
2018-07-28 15:21:38 +01:00
}
2019-07-07 20:56:15 +00:00
bool AllegianceManager : : IsGagged ( uint32_t player_id )
2018-08-12 01:10:53 +01:00
{
if ( AllegianceTreeNode * playerNode = GetTreeNode ( player_id ) ) {
if ( AllegianceInfo * ai = GetInfo ( playerNode - > _monarchID ) ) {
auto it = ai - > _info . m_chatGagList . find ( player_id ) ;
if ( it ! = ai - > _info . m_chatGagList . end ( ) ) {
return true ;
}
}
}
return false ;
}
void AllegianceManager : : ChatGag ( CPlayerWeenie * player , std : : string target , bool toggle )
2018-07-28 15:21:38 +01:00
{
AllegianceTreeNode * playerNode = GetTreeNode ( player - > GetID ( ) ) ;
if ( ! playerNode )
{
player - > NotifyWeenieError ( WERROR_ALLEGIANCE_NONEXISTENT ) ;
return ;
}
if ( target . empty ( ) )
{
player - > NotifyWeenieError ( WERROR_ALLEGIANCE_BOOT_EMPTY_NAME ) ;
return ;
}
2018-08-12 01:10:53 +01:00
if ( ! IsOfficer ( playerNode ) ) // all officers can gag/ungag
2018-07-28 15:21:38 +01:00
{
player - > NotifyWeenieError ( WERROR_ALLEGIANCE_NOT_AUTHORIZED ) ;
return ;
}
2019-07-07 20:56:15 +00:00
uint32_t gagTargetID = g_pDBIO - > GetPlayerCharacterId ( target . c_str ( ) ) ;
2018-08-12 01:10:53 +01:00
AllegianceTreeNode * gagTargetNode = GetTreeNode ( gagTargetID ) ;
if ( ! gagTargetNode )
return ;
2018-07-28 15:21:38 +01:00
2018-08-12 01:10:53 +01:00
if ( gagTargetNode - > _monarchID ! = playerNode - > _monarchID )
return ;
if ( AllegianceInfo * ai = GetInfo ( playerNode - > _monarchID ) )
{
CPlayerWeenie * gagTarget = g_pWorld - > FindPlayer ( gagTargetID ) ;
auto it = ai - > _info . m_chatGagList . find ( gagTargetID ) ;
if ( it ! = ai - > _info . m_chatGagList . end ( ) ) { // target is in the gag list
if ( toggle ) { // adding a gag, fail
player - > NotifyWeenieError ( WERROR_ALLEGIANCE_GAG_ALREADY ) ;
return ;
}
else { // removing a gag, success
ai - > _info . m_chatGagList . erase ( it ) ;
player - > NotifyWeenieErrorWithString ( WERROR_ALLEGIANCE_GAG_UNGAG_OFFICER , target . c_str ( ) ) ;
if ( gagTarget ) {
gagTarget - > NotifyWeenieErrorWithString ( WERROR_ALLEGIANCE_GAG_UNGAG_TARGET , player - > GetName ( ) . c_str ( ) ) ;
}
return ;
}
}
else { // target not on gag list
if ( toggle ) { // adding a gag, success
int gagEndTime = Timer : : cur_time + 300 ;
ai - > _info . m_chatGagList . add ( gagTargetID , & gagEndTime ) ;
player - > NotifyWeenieErrorWithString ( WERROR_ALLEGIANCE_GAG_OFFICER , target . c_str ( ) ) ;
if ( gagTarget ) {
gagTarget - > NotifyWeenieErrorWithString ( WERROR_ALLEGIANCE_GAG_TARGET , player - > GetName ( ) . c_str ( ) ) ;
}
return ;
}
else { // removing a gag, fail
player - > NotifyWeenieError ( WERROR_ALLEGIANCE_GAG_NOT_ALREADY ) ;
return ;
}
}
}
// TODO: WERROR_ALLEGIANCE_GAG_AUTO_UNGAG once time is up
// check player on F7DE send/receive to allegiance channel for a gag
}
void AllegianceManager : : ChatBoot ( CPlayerWeenie * player , std : : string target , std : : string reason )
{
AllegianceTreeNode * playerNode = GetTreeNode ( player - > GetID ( ) ) ;
if ( ! playerNode )
{
player - > NotifyWeenieError ( WERROR_ALLEGIANCE_NONEXISTENT ) ;
return ;
}
if ( target . empty ( ) )
{
player - > NotifyWeenieError ( WERROR_ALLEGIANCE_BOOT_EMPTY_NAME ) ;
return ;
}
if ( ! IsOfficer ( playerNode ) ) // all officers can boot from allegiance chat
{
player - > NotifyWeenieError ( WERROR_ALLEGIANCE_NOT_AUTHORIZED ) ;
return ;
}
2018-08-14 19:46:16 +01:00
CPlayerWeenie * targetPlayer = g_pWorld - > FindPlayer ( target . c_str ( ) ) ;
if ( ! targetPlayer )
return ;
AllegianceTreeNode * targetNode = GetTreeNode ( targetPlayer - > GetID ( ) ) ;
if ( ! targetNode )
return ;
if ( targetNode - > _monarchID ! = playerNode - > _monarchID )
return ;
if ( targetPlayer - > _playerModule . options_ )
targetPlayer - > _playerModule . options_ & = ~ HearAllegianceChat_CharacterOption ;
// TODO: set player option for hear allegiance chat to off
2018-07-28 15:21:38 +01:00
}
2019-07-07 20:56:15 +00:00
bool AllegianceManager : : IsBanned ( uint32_t player_to_check_id , uint32_t monarch_id )
2018-07-28 15:21:38 +01:00
{
CharacterDesc_t potentialVassal = g_pDBIO - > GetCharacterInfo ( player_to_check_id ) ; // get chardesc for account id
if ( AllegianceInfo * ai = GetInfo ( monarch_id ) )
{
2018-08-12 01:10:53 +01:00
if ( ai - > _info . m_BanList . find ( potentialVassal . account_id ) ! = ai - > _info . m_BanList . end ( ) ) // if account id is on the ban list, return true
2018-07-28 15:21:38 +01:00
{
2018-08-12 01:10:53 +01:00
return true ;
2018-07-28 15:21:38 +01:00
}
}
return false ;
}
2018-07-30 10:08:39 +01:00
void AllegianceManager : : AddBan ( CPlayerWeenie * player , std : : string char_name )
2018-07-28 15:21:38 +01:00
{
2019-07-07 20:56:15 +00:00
uint32_t bannedPlayerID = g_pWorld - > GetPlayerId ( char_name . c_str ( ) ) ;
2018-07-28 15:21:38 +01:00
AllegianceTreeNode * playerNode = GetTreeNode ( player - > GetID ( ) ) ;
if ( ! playerNode ) // check caller even has an allegiance
{
player - > NotifyWeenieError ( WERROR_ALLEGIANCE_NONEXISTENT ) ;
return ;
}
2019-07-07 20:56:15 +00:00
uint32_t monarchID = playerNode - > _monarchID ;
2018-07-28 15:21:38 +01:00
2018-08-07 17:23:52 +01:00
if ( IsOfficerWithLevel ( playerNode , Seneschal_AllegianceOfficerLevel ) ) // check caller has correct authority
2018-07-28 15:21:38 +01:00
{
2018-07-30 10:08:39 +01:00
CharacterDesc_t bannedCharInfo = g_pDBIO - > GetCharacterInfo ( bannedPlayerID ) ;
2018-08-12 01:10:53 +01:00
if ( AllegianceInfo * ai = GetInfo ( monarchID ) )
2018-07-28 15:21:38 +01:00
{
2018-08-12 01:10:53 +01:00
if ( ai - > _info . m_BanList . size ( ) > 50 ) // max ban list as of 01/06 patch notes
{
player - > NotifyWeenieError ( WERROR_ALLEGIANCE_BANNED_LIST_FULL ) ;
return ;
}
2018-07-28 15:21:38 +01:00
2018-08-12 01:10:53 +01:00
if ( ai - > _info . m_BanList . find ( bannedCharInfo . account_id ) ! = ai - > _info . m_BanList . end ( ) ) // check if their account is already banned
2018-07-28 15:21:38 +01:00
{
player - > NotifyWeenieErrorWithString ( WERROR_ALLEGIANCE_CHAR_ALREADY_BANNED , bannedCharInfo . name . c_str ( ) ) ;
return ;
}
2018-08-12 01:10:53 +01:00
ai - > _info . m_BanList . add ( bannedCharInfo . account_id , & bannedCharInfo . name ) ; // add account id & name of character to ban list of allegiance
2018-07-28 15:21:38 +01:00
2018-08-12 01:10:53 +01:00
std : : list < CharacterDesc_t > bannedCharacters = g_pDBIO - > GetCharacterList ( bannedCharInfo . account_id ) ;
for ( auto character : bannedCharacters )
2018-07-28 15:21:38 +01:00
{
2018-08-12 01:10:53 +01:00
AllegianceTreeNode * characterNode = GetTreeNode ( character . weenie_id ) ;
if ( characterNode & & characterNode - > _monarchID = = monarchID ) // if any characters are currently in the allegiance...
{
TryBreakAllegiance ( characterNode - > _patronID , character . weenie_id ) ; // ...boot them from allegiance
}
2018-07-28 15:21:38 +01:00
}
2018-08-12 01:10:53 +01:00
player - > NotifyWeenieErrorWithString ( WERROR_ALLEGIANCE_CHAR_BANNED_SUCCESSFULLY , char_name . c_str ( ) ) ;
Save ( ) ; // TODO should we send updated allegiance profile here?
2018-07-28 15:21:38 +01:00
}
}
else
{
player - > NotifyWeenieError ( WERROR_ALLEGIANCE_NOT_AUTHORIZED ) ;
}
}
void AllegianceManager : : RemoveBan ( CPlayerWeenie * player , std : : string char_name )
{
AllegianceTreeNode * playerNode = GetTreeNode ( player - > GetID ( ) ) ;
if ( ! playerNode ) // check caller even has an allegiance
{
player - > NotifyWeenieError ( WERROR_ALLEGIANCE_NONEXISTENT ) ;
return ;
}
2019-07-07 20:56:15 +00:00
uint32_t monarchID = playerNode - > _monarchID ;
2018-07-28 15:21:38 +01:00
2018-08-07 17:23:52 +01:00
if ( IsOfficerWithLevel ( playerNode , Seneschal_AllegianceOfficerLevel ) ) // check caller has correct authority
2018-07-28 15:21:38 +01:00
{
2018-08-07 17:23:52 +01:00
if ( AllegianceInfo * ai = GetInfo ( monarchID ) ) {
2018-07-28 15:21:38 +01:00
2018-08-07 17:23:52 +01:00
for ( auto c : ai - > _info . m_BanList ) // check if their account is already banned
2018-07-28 15:21:38 +01:00
{
2018-08-07 17:23:52 +01:00
if ( c . second = = char_name )
{
ai - > _info . m_BanList . remove ( c . first ) ;
player - > NotifyWeenieErrorWithString ( WERROR_ALLEGIANCE_CHAR_UNBANNED_SUCCESSFULLY , char_name . c_str ( ) ) ;
Save ( ) ;
return ;
}
2018-07-28 15:21:38 +01:00
}
}
player - > NotifyWeenieErrorWithString ( WERROR_ALLEGIANCE_CHAR_NOT_BANNED , char_name . c_str ( ) ) ;
}
else
{
player - > NotifyWeenieError ( WERROR_ALLEGIANCE_NOT_AUTHORIZED ) ;
}
}
void AllegianceManager : : GetBanList ( CPlayerWeenie * player )
{
AllegianceTreeNode * playerNode = GetTreeNode ( player - > GetID ( ) ) ;
if ( ! playerNode ) // check caller even has an allegiance
{
player - > NotifyWeenieError ( WERROR_ALLEGIANCE_NONEXISTENT ) ;
return ;
}
2019-07-07 20:56:15 +00:00
uint32_t monarchID = playerNode - > _monarchID ;
2018-07-28 15:21:38 +01:00
2018-08-07 17:23:52 +01:00
if ( IsOfficerWithLevel ( playerNode , Seneschal_AllegianceOfficerLevel ) ) // check caller has correct authority
2018-07-28 15:21:38 +01:00
{
if ( AllegianceInfo * ai = GetInfo ( monarchID ) )
{
2018-08-12 01:10:53 +01:00
std : : string bans ;
2018-07-28 15:21:38 +01:00
for ( auto banned : ai - > _info . m_BanList )
{
2018-08-12 01:10:53 +01:00
bans + = banned . second ;
bans + = " \n " ;
2018-07-28 15:21:38 +01:00
}
2018-08-12 01:10:53 +01:00
player - > NotifyWeenieErrorWithString ( WERROR_ALLEGIANCE_LIST_BANNED_CHARACTERS , bans . c_str ( ) ) ;
2018-07-28 15:21:38 +01:00
}
}
else
{
player - > NotifyWeenieError ( WERROR_ALLEGIANCE_NOT_AUTHORIZED ) ;
}
}