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 "FellowshipManager.h"
# include "World.h"
# include "WeenieObject.h"
# include "Player.h"
# include "ChatMsgs.h"
2019-09-03 14:18:02 +00:00
# include "Config.h"
2018-03-29 17:01:57 -04:00
# define MAX_FELLOWSHIP_MEMBERS 9
# define FELLOWSHIP_OPTIONAL_UPDATING 1
2019-09-03 14:18:02 +00:00
Fellow : : Fellow ( uint32_t player_id ) : Fellow : : Fellow ( g_pWorld - > FindPlayer ( player_id ) )
{
}
Fellow : : Fellow ( CWeenieObject * weenie )
{
if ( weenie )
{
_cachedWeenie = weenie ;
_name = weenie - > GetName ( ) ;
_level = weenie - > InqIntQuality ( LEVEL_INT , 0 ) ;
// share loot from char options?
CPlayerWeenie * player = weenie - > AsPlayer ( ) ;
2019-09-08 09:15:04 -07:00
_share_loot = ( player - > GetCharacterOptions ( ) & FellowshipShareLoot_CharacterOption ) ! = 0 ;
2019-09-03 14:18:02 +00:00
if ( _share_loot ) _share_loot = 0x0010 ;
_current_health = weenie - > GetHealth ( ) ;
_current_stamina = weenie - > GetStamina ( ) ;
_current_mana = weenie - > GetMana ( ) ;
_max_health = weenie - > GetMaxHealth ( ) ;
_max_stamina = weenie - > GetMaxStamina ( ) ;
_max_mana = weenie - > GetMaxMana ( ) ;
}
}
Fellow & Fellow : : operator = ( const Fellow & other )
{
_cachedWeenie = other . _cachedWeenie ;
_name = other . _name ;
_level = other . _level ;
_share_loot = other . _share_loot ;
_current_health = other . _current_health ;
_current_stamina = other . _current_stamina ;
_current_mana = other . _current_mana ;
_max_health = other . _max_health ;
_max_stamina = other . _max_stamina ;
_max_mana = other . _max_mana ;
return * this ;
}
bool Fellow : : updated ( const Fellow & other ) const
{
if ( ! _cachedWeenie | | ! other . _cachedWeenie )
return false ;
if ( _cachedWeenie - > GetID ( ) ! = other . _cachedWeenie - > GetID ( ) )
return false ;
if ( _level ! = other . _level )
return true ;
if ( _max_health ! = other . _max_health | | _max_stamina ! = other . _max_stamina | | _max_mana ! = other . _max_mana )
return true ;
// this is a noisy packet, so we'll apply a threshold to updates
if ( other . _max_health > 0 & & ( float ) abs ( ( int ) _current_health - ( int ) other . _current_health ) / ( float ) other . _max_health > = g_pConfig - > GetFellowHealthThreshold ( ) )
return true ;
if ( other . _max_stamina > 0 & & ( float ) abs ( ( int ) _current_stamina - ( int ) other . _current_stamina ) / ( float ) other . _max_stamina > = g_pConfig - > GetFellowStamThreshold ( ) )
return true ;
if ( other . _max_mana > 0 & & ( float ) abs ( ( int ) _current_mana - ( int ) other . _current_mana ) / ( float ) other . _max_mana > = g_pConfig - > GetFellowManaThreshold ( ) )
return true ;
return false ;
}
2018-03-29 17:01:57 -04:00
DEFINE_PACK ( Fellow )
{
pWriter - > Write < unsigned int > ( _cp_cache ) ;
pWriter - > Write < unsigned int > ( _lum_cache ) ;
pWriter - > Write < unsigned int > ( _level ) ;
pWriter - > Write < unsigned int > ( _max_health ) ;
pWriter - > Write < unsigned int > ( _max_stamina ) ;
pWriter - > Write < unsigned int > ( _max_mana ) ;
pWriter - > Write < unsigned int > ( _current_health ) ;
pWriter - > Write < unsigned int > ( _current_stamina ) ;
pWriter - > Write < unsigned int > ( _current_mana ) ;
pWriter - > Write < unsigned int > ( _share_loot ) ;
pWriter - > WriteString ( _name ) ;
}
DEFINE_UNPACK ( Fellow )
{
return true ;
}
DEFINE_PACK ( Fellowship )
{
_fellowship_table . Pack ( pWriter ) ;
pWriter - > WriteString ( _name ) ;
2019-07-07 20:56:15 +00:00
pWriter - > Write < uint32_t > ( _leader ) ;
2018-03-29 17:01:57 -04:00
pWriter - > Write < int > ( _share_xp ) ;
pWriter - > Write < int > ( _even_xp_split ) ;
pWriter - > Write < int > ( _open_fellow ) ;
pWriter - > Write < int > ( _locked ) ;
_fellows_departed . Pack ( pWriter ) ;
2019-09-03 14:18:02 +00:00
if ( _fellows_departed . empty ( ) )
{
// Bad Decal, it needs another int
pWriter - > Write < int > ( 0 ) ;
}
2018-03-29 17:01:57 -04:00
}
DEFINE_UNPACK ( Fellowship )
{
return true ;
}
void Fellowship : : UpdateData ( )
{
bool bAllOver50 = false ;
int minLevel = - 1 ;
int maxLevel = - 1 ;
int leaderLevel = - 1 ;
for ( auto & entry : _fellowship_table )
{
2019-09-03 14:18:02 +00:00
CPlayerWeenie * player = g_pWorld - > FindPlayer ( entry . first ) ;
2018-03-29 17:01:57 -04:00
if ( player )
{
2019-09-03 14:18:02 +00:00
//entry.second._name = player->GetName();
unsigned int level = entry . second . _level ;
2018-03-29 17:01:57 -04:00
2019-09-03 14:18:02 +00:00
//entry.second._current_health = player->GetHealth();
//entry.second._current_stamina = player->GetStamina();
//entry.second._current_mana = player->GetMana();
2018-03-29 17:01:57 -04:00
2019-09-03 14:18:02 +00:00
//entry.second._max_health = player->GetMaxHealth();
//entry.second._max_stamina = player->GetMaxStamina();
//entry.second._max_mana = player->GetMaxMana();
2018-03-29 17:01:57 -04:00
2019-09-03 14:18:02 +00:00
//entry.second._cp_cache = 0; // TODO
//entry.second._lum_cache = 0; // TODO
//entry.second._share_loot = _share_loot ? 0x0010 : 0;
2018-03-29 17:01:57 -04:00
if ( minLevel < = 0 | | level < minLevel )
minLevel = level ;
if ( maxLevel < = 0 | | level > maxLevel )
maxLevel = level ;
2019-09-03 14:18:02 +00:00
//entry.second._cachedWeenie = player;
2018-03-29 17:01:57 -04:00
if ( entry . first = = _leader )
leaderLevel = level ;
}
}
if ( minLevel > = 50 )
bAllOver50 = true ;
/*
int levelSpread = maxLevel - minLevel ;
_even_xp_split = ( bAllOver50 | | levelSpread < = 5 ) & & _desiredShareXP ;
_share_xp = ( bAllOver50 | | levelSpread < = 10 ) & & _desiredShareXP ;
*/
bool bWithin5Levels = ( ( abs ( leaderLevel - maxLevel ) < = 5 ) & & ( abs ( leaderLevel - minLevel ) < = 5 ) ) ? true : false ;
bool bWithin10Levels = ( ( abs ( leaderLevel - maxLevel ) < = 10 ) & & ( abs ( leaderLevel - minLevel ) < = 10 ) ) ? true : false ;
_even_xp_split = ( bAllOver50 | | bWithin5Levels ) & & _desiredShareXP ;
_share_xp = ( bAllOver50 | | bWithin10Levels ) & & _desiredShareXP ;
unsigned int xpPortionSum = CalculateExperienceProportionSum ( ) ;
2018-10-08 20:23:38 -05:00
double xpPortionPctg = 1.0 / ( double ) xpPortionSum ;
2018-03-29 17:01:57 -04:00
for ( auto & entry : _fellowship_table )
{
if ( _even_xp_split )
2019-07-07 20:56:15 +00:00
entry . second . splitPercent = FellowshipManager : : GetEvenSplitXPPctg ( ( uint32_t ) _fellowship_table . size ( ) ) ;
2018-03-29 17:01:57 -04:00
else
2018-10-08 20:23:38 -05:00
entry . second . splitPercent = xpPortionPctg * ( double ) entry . second . _level ;
2018-03-29 17:01:57 -04:00
}
}
2018-07-12 14:41:21 -07:00
double Fellowship : : CalculateDegradeMod ( CWeenieObject * source , CWeenieObject * target )
2018-03-29 17:01:57 -04:00
{
WORD source_block_id = source - > m_Position . objcell_id > > 16 ;
WORD source_cell_id = source - > m_Position . objcell_id & 0xFFFF ;
WORD target_block_id = target - > m_Position . objcell_id > > 16 ;
WORD target_cell_id = target - > m_Position . objcell_id & 0xFFFF ;
if ( source_cell_id > = 0x100 | | target_cell_id > = 0x100 )
{
if ( source_block_id ! = target_block_id )
return 0.0 ;
}
// both are outside, or in a building/dungeon in the same land block
double dist = source - > DistanceTo ( target ) ;
double numClicks = ( dist / 24.0 ) ;
if ( numClicks < = 25 )
return 1.0 ; // full XP within 2.5 map units
if ( numClicks > = 50 )
return 0.0 ; // no XP beyond 5.0 map units
return max ( 0.0 , min ( 1.0 , 1.0 - ( ( numClicks - 25.0 ) / 25.0 ) ) ) ;
}
2019-07-30 02:19:05 +00:00
void Fellowship : : GiveXP ( CWeenieObject * source , int64_t amount , ExperienceHandlingType flags , bool bShowText )
2018-03-29 17:01:57 -04:00
{
UpdateData ( ) ;
2019-07-30 02:19:05 +00:00
flags_clear ( flags , ExperienceHandlingType : : ShareWithFellows ) ;
// TODO: Apply fellowship experience handling
2018-03-29 17:01:57 -04:00
if ( ! _share_xp )
{
2019-07-30 02:19:05 +00:00
source - > GiveXP ( amount , flags , bShowText ) ;
2018-03-29 17:01:57 -04:00
}
else
{
for ( auto & entry : _fellowship_table )
{
if ( entry . first = = source - > GetID ( ) )
entry . second . _cp_cache + = amount ;
2018-07-12 14:41:21 -07:00
CWeenieObject * other = entry . second . _cachedWeenie ;
2018-03-29 17:01:57 -04:00
if ( other )
{
double degradeMod = CalculateDegradeMod ( source , other ) ;
2019-07-07 20:56:15 +00:00
int64_t xpGained = ( int64_t ) ( amount * entry . second . splitPercent * degradeMod ) ;
2018-03-29 17:01:57 -04:00
if ( xpGained > 0 )
2019-07-30 02:19:05 +00:00
other - > GiveXP ( xpGained , flags , bShowText ) ;
2018-03-29 17:01:57 -04:00
}
}
}
}
2019-07-07 20:56:15 +00:00
void Fellowship : : GiveLum ( CWeenieObject * source , int64_t amount , bool bShowText )
2018-12-18 17:02:31 -06:00
{
2019-05-29 13:47:28 -07:00
2018-12-18 17:02:31 -06:00
if ( ! _share_xp )
{
source - > GiveLum ( amount , bShowText ) ;
}
else
{
for ( auto & entry : _fellowship_table )
{
if ( entry . first = = source - > GetID ( ) )
entry . second . _cp_cache + = amount ;
CWeenieObject * other = entry . second . _cachedWeenie ;
if ( other )
{
double degradeMod = CalculateDegradeMod ( source , other ) ;
2019-07-07 20:56:15 +00:00
int64_t xpGained = ( int64_t ) ( amount * entry . second . splitPercent * degradeMod ) ;
2018-12-18 17:02:31 -06:00
if ( xpGained > 0 )
other - > GiveLum ( xpGained , bShowText ) ;
}
}
}
}
2018-03-29 17:01:57 -04:00
unsigned int Fellowship : : CalculateExperienceProportionSum ( )
{
// make sure the levels are correct in the data before calling this
unsigned int sum = 0 ;
for ( auto & entry : _fellowship_table )
2018-09-21 06:16:42 -07:00
sum + = entry . second . _level ;
2018-03-29 17:01:57 -04:00
return sum ;
}
2019-09-03 14:18:02 +00:00
bool Fellowship : : ShouldUpdate ( uint32_t fellow_id )
{
CPlayerWeenie * player = g_pWorld - > FindPlayer ( fellow_id ) ;
if ( ! player )
return false ;
Fellow updated ( player ) ;
Fellow * current = _fellowship_table . lookup ( fellow_id ) ;
if ( current & & current - > updated ( updated ) )
{
* current = updated ;
return true ;
}
return false ;
}
2019-05-29 13:47:28 -07:00
void Fellowship : : FullUpdate ( )
2018-03-29 17:01:57 -04:00
{
UpdateData ( ) ;
BinaryWriter updateMessage ;
2019-07-07 20:56:15 +00:00
updateMessage . Write < uint32_t > ( 0x2BE ) ;
2018-03-29 17:01:57 -04:00
Pack ( & updateMessage ) ;
for ( auto & entry : _fellowship_table )
{
2019-05-29 13:47:28 -07:00
CPlayerWeenie * player = g_pWorld - > FindPlayer ( entry . first ) ;
if ( player )
player - > SendNetMessage ( & updateMessage , PRIVATE_MSG , TRUE , FALSE ) ;
2018-03-29 17:01:57 -04:00
}
}
2019-07-07 20:56:15 +00:00
void Fellowship : : VitalsUpdate ( uint32_t player_id )
2018-03-29 17:01:57 -04:00
{
2019-09-03 14:18:02 +00:00
if ( ShouldUpdate ( player_id ) )
2018-03-29 17:01:57 -04:00
{
2019-09-03 14:18:02 +00:00
UpdateData ( ) ;
Fellow * f = _fellowship_table . lookup ( player_id ) ;
if ( ! f )
return ;
BinaryWriter updateMessage ;
updateMessage . Write < uint32_t > ( 0x2C0 ) ;
updateMessage . Write < uint32_t > ( player_id ) ;
f - > Pack ( & updateMessage ) ;
updateMessage . Write < uint32_t > ( Fellow_UpdateVitals ) ;
2019-05-29 13:47:28 -07:00
for ( auto & entry : _fellowship_table )
2018-03-29 17:01:57 -04:00
{
2019-05-29 13:47:28 -07:00
if ( CPlayerWeenie * player = g_pWorld - > FindPlayer ( entry . first ) )
2018-03-29 17:01:57 -04:00
{
2019-05-29 13:47:28 -07:00
player - > SendNetMessage ( & updateMessage , PRIVATE_MSG , TRUE , FALSE ) ;
2018-03-29 17:01:57 -04:00
}
}
}
}
2019-07-07 20:56:15 +00:00
void Fellowship : : StatsUpdate ( uint32_t player_id )
2018-07-17 00:42:27 -05:00
{
2019-09-03 14:18:02 +00:00
if ( ShouldUpdate ( player_id ) )
2018-07-17 00:42:27 -05:00
{
2019-09-03 14:18:02 +00:00
UpdateData ( ) ;
Fellow * f = _fellowship_table . lookup ( player_id ) ;
if ( ! f )
return ;
BinaryWriter updateMessage ;
updateMessage . Write < uint32_t > ( 0x2C0 ) ;
updateMessage . Write < uint32_t > ( player_id ) ;
f - > Pack ( & updateMessage ) ;
updateMessage . Write < uint32_t > ( Fellow_UpdateStats ) ;
2019-05-28 14:44:51 +00:00
for ( auto & entry : _fellowship_table )
2018-07-17 00:42:27 -05:00
{
2019-05-28 14:44:51 +00:00
if ( CPlayerWeenie * player = g_pWorld - > FindPlayer ( entry . first ) )
2018-07-17 00:42:27 -05:00
{
2019-05-28 14:44:51 +00:00
player - > SendNetMessage ( & updateMessage , PRIVATE_MSG , TRUE , FALSE ) ;
2018-07-17 00:42:27 -05:00
}
}
}
}
2018-03-29 17:01:57 -04:00
bool Fellowship : : IsEmpty ( )
{
return _fellowship_table . empty ( ) ;
}
bool Fellowship : : IsLocked ( )
{
return _locked ? true : false ;
}
bool Fellowship : : IsOpen ( )
{
return _open_fellow ? true : false ;
}
bool Fellowship : : IsFull ( )
{
if ( _fellowship_table . size ( ) > = MAX_FELLOWSHIP_MEMBERS )
return true ;
return false ;
}
2019-07-07 20:56:15 +00:00
void Fellowship : : Disband ( uint32_t disbander_id )
2018-03-29 17:01:57 -04:00
{
BinaryWriter disbandMessage ;
2019-07-07 20:56:15 +00:00
disbandMessage . Write < uint32_t > ( 0x2BF ) ;
2018-03-29 17:01:57 -04:00
for ( auto & entry : _fellowship_table )
{
2018-07-12 14:41:21 -07:00
CPlayerWeenie * player = g_pWorld - > FindPlayer ( entry . first ) ;
2018-03-29 17:01:57 -04:00
if ( player )
{
player - > SendNetMessage ( & disbandMessage , PRIVATE_MSG , TRUE , FALSE ) ;
2019-09-03 14:18:02 +00:00
player - > LeaveFellowship ( ) ;
2018-03-29 17:01:57 -04:00
}
}
_fellowship_table . clear ( ) ;
}
2019-07-07 20:56:15 +00:00
void Fellowship : : RemoveFellow ( uint32_t dismissee_id )
2018-03-29 17:01:57 -04:00
{
BinaryWriter dismissMessage ;
2019-07-07 20:56:15 +00:00
dismissMessage . Write < uint32_t > ( 0xA4 ) ;
dismissMessage . Write < uint32_t > ( dismissee_id ) ;
2018-03-29 17:01:57 -04:00
for ( auto & entry : _fellowship_table )
{
2018-07-12 14:41:21 -07:00
if ( CPlayerWeenie * player = g_pWorld - > FindPlayer ( entry . first ) )
2018-03-29 17:01:57 -04:00
{
player - > SendNetMessage ( & dismissMessage , PRIVATE_MSG , TRUE , FALSE ) ;
}
}
_fellowship_table . remove ( dismissee_id ) ;
2018-07-12 14:41:21 -07:00
if ( CPlayerWeenie * player = g_pWorld - > FindPlayer ( dismissee_id ) )
2018-03-29 17:01:57 -04:00
{
2019-09-03 14:18:02 +00:00
player - > LeaveFellowship ( ) ;
2018-03-29 17:01:57 -04:00
}
2019-05-29 13:47:28 -07:00
FullUpdate ( ) ;
2018-03-29 17:01:57 -04:00
}
2019-07-07 20:56:15 +00:00
void Fellowship : : Quit ( uint32_t quitter_id )
2018-03-29 17:01:57 -04:00
{
BinaryWriter quitMessage ;
2019-07-07 20:56:15 +00:00
quitMessage . Write < uint32_t > ( 0xA3 ) ;
quitMessage . Write < uint32_t > ( quitter_id ) ;
2018-03-29 17:01:57 -04:00
std : : string quitter_name ;
2018-07-12 14:41:21 -07:00
if ( CPlayerWeenie * player = g_pWorld - > FindPlayer ( quitter_id ) )
2018-03-29 17:01:57 -04:00
{
2019-09-03 14:18:02 +00:00
player - > LeaveFellowship ( ) ;
2018-03-29 17:01:57 -04:00
quitter_name = player - > GetName ( ) ;
}
// BinaryWriter *quitText = ServerText(csprintf("%s has left the Fellowship.", quitter_name.c_str()), LTT_DEFAULT);
for ( auto & entry : _fellowship_table )
{
2018-07-12 14:41:21 -07:00
if ( CPlayerWeenie * player = g_pWorld - > FindPlayer ( entry . first ) )
2018-03-29 17:01:57 -04:00
{
player - > SendNetMessage ( & quitMessage , PRIVATE_MSG , TRUE , FALSE ) ;
// player->SendNetMessage(quitText, PRIVATE_MSG, FALSE, FALSE);
}
}
// delete quitText;
_fellowship_table . remove ( quitter_id ) ;
if ( quitter_id = = _leader & & _fellowship_table . size ( ) > = 1 )
{
AssignNewLeader ( _fellowship_table . begin ( ) - > first ) ;
}
2019-09-03 14:18:02 +00:00
if ( IsLocked ( ) )
{
uint32_t what = 0 ;
_fellows_departed . add ( quitter_id , & what ) ;
}
2019-05-29 13:47:28 -07:00
FullUpdate ( ) ;
2018-03-29 17:01:57 -04:00
}
2019-09-03 14:18:02 +00:00
bool Fellowship : : CanJoin ( uint32_t recruitee_id )
{
if ( IsLocked ( ) )
{
fellows_departed_table : : iterator itr = _fellows_departed . find ( recruitee_id ) ;
if ( itr ! = _fellows_departed . end ( ) )
{
return true ;
}
return false ;
}
return true ;
}
2019-07-07 20:56:15 +00:00
void Fellowship : : AddFellow ( uint32_t recruitee_id )
2018-03-29 17:01:57 -04:00
{
2019-09-03 14:18:02 +00:00
Fellow newFellow ( recruitee_id ) ;
2018-03-29 17:01:57 -04:00
_fellowship_table . add ( recruitee_id , & newFellow ) ;
UpdateData ( ) ;
Fellow * f = _fellowship_table . lookup ( recruitee_id ) ;
BinaryWriter recruitMessage ;
2019-07-07 20:56:15 +00:00
recruitMessage . Write < uint32_t > ( 0x2C0 ) ;
recruitMessage . Write < uint32_t > ( recruitee_id ) ;
2018-03-29 17:01:57 -04:00
f - > Pack ( & recruitMessage ) ;
2019-07-07 20:56:15 +00:00
recruitMessage . Write < uint32_t > ( Fellow_UpdateFull ) ;
2018-03-29 17:01:57 -04:00
for ( auto & entry : _fellowship_table )
{
2018-07-12 14:41:21 -07:00
if ( CPlayerWeenie * player = g_pWorld - > FindPlayer ( entry . first ) )
2018-03-29 17:01:57 -04:00
{
if ( entry . first = = recruitee_id )
{
// full update to the new recruit
BinaryWriter updateMessage ;
2019-07-07 20:56:15 +00:00
updateMessage . Write < uint32_t > ( 0x2BE ) ;
2018-03-29 17:01:57 -04:00
Pack ( & updateMessage ) ;
player - > SendNetMessage ( & updateMessage , PRIVATE_MSG , TRUE , FALSE ) ;
}
else
{
// partial update to everyone else
player - > SendNetMessage ( & recruitMessage , PRIVATE_MSG , TRUE , FALSE ) ;
}
}
}
2019-09-03 14:18:02 +00:00
fellows_departed_table : : iterator itr = _fellows_departed . find ( recruitee_id ) ;
if ( itr ! = _fellows_departed . end ( ) )
{
_fellows_departed . erase ( itr ) ;
}
2018-03-29 17:01:57 -04:00
}
void Fellowship : : ChangeOpen ( BOOL open )
{
2018-07-22 12:12:29 -07:00
if ( _open_fellow = = open )
return ;
2018-03-29 17:01:57 -04:00
_open_fellow = open ;
std : : string leader_name ;
2018-07-12 14:41:21 -07:00
CWeenieObject * leader_weenie = g_pWorld - > FindPlayer ( _leader ) ;
2018-03-29 17:01:57 -04:00
if ( leader_weenie )
leader_name = leader_weenie - > GetName ( ) ;
for ( auto & entry : _fellowship_table )
{
2018-07-12 14:41:21 -07:00
CPlayerWeenie * player = g_pWorld - > FindPlayer ( entry . first ) ;
2018-03-29 17:01:57 -04:00
if ( player )
{
if ( entry . first = = _leader )
player - > SendNetMessage ( ServerText ( csprintf ( " You have %s your Fellowship. " , open ? " opened " : " closed " ) , LTT_DEFAULT ) , PRIVATE_MSG , FALSE , TRUE ) ;
else
player - > SendNetMessage ( ServerText ( csprintf ( " %s has %s your Fellowship. " , leader_name . c_str ( ) , open ? " opened " : " closed " ) , LTT_DEFAULT ) , PRIVATE_MSG , FALSE , TRUE ) ;
}
}
2019-09-03 14:18:02 +00:00
FullUpdate ( ) ;
2018-03-29 17:01:57 -04:00
}
2019-07-07 20:56:15 +00:00
void Fellowship : : AssignNewLeader ( uint32_t new_leader_id )
2018-03-29 17:01:57 -04:00
{
_leader = new_leader_id ;
2018-07-12 14:41:21 -07:00
CWeenieObject * leader_weenie = g_pWorld - > FindPlayer ( new_leader_id ) ;
2018-03-29 17:01:57 -04:00
if ( leader_weenie )
{
std : : string new_leader_name = leader_weenie - > GetName ( ) ;
for ( auto & entry : _fellowship_table )
{
2018-07-12 14:41:21 -07:00
CPlayerWeenie * player = g_pWorld - > FindPlayer ( entry . first ) ;
2018-03-29 17:01:57 -04:00
if ( player )
{
if ( entry . first = = new_leader_id )
player - > SendNetMessage ( ServerText ( " You are now the leader of your Fellowship. " , LTT_DEFAULT ) , PRIVATE_MSG , FALSE , TRUE ) ;
else
player - > SendNetMessage ( ServerText ( csprintf ( " %s is now the leader of your Fellowship. " , new_leader_name . c_str ( ) ) , LTT_DEFAULT ) , PRIVATE_MSG , FALSE , TRUE ) ;
}
}
}
2019-05-29 13:47:28 -07:00
FullUpdate ( ) ;
2018-03-29 17:01:57 -04:00
}
2019-07-07 20:56:15 +00:00
void Fellowship : : Chat ( uint32_t sender_id , const char * text )
2018-03-29 17:01:57 -04:00
{
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 )
{
std : : string sender_name = sender_weenie - > GetName ( ) ;
2018-09-06 22:04:21 -05:00
2018-09-06 22:40:43 -05:00
sender_weenie - > SendNetMessage ( ChannelChat ( Fellow_ChannelID , NULL , text ) , PRIVATE_MSG , FALSE , TRUE ) ;
2018-09-06 22:04:21 -05:00
2018-03-29 17:01:57 -04:00
for ( auto & entry : _fellowship_table )
{
if ( entry . first ! = sender_id )
{
2018-07-12 14:41:21 -07:00
CPlayerWeenie * player = g_pWorld - > FindPlayer ( entry . first ) ;
2018-03-29 17:01:57 -04:00
if ( player )
2018-09-06 22:04:21 -05:00
player - > SendNetMessage ( ChannelChat ( Fellow_ChannelID , sender_name . c_str ( ) , text ) , PRIVATE_MSG , FALSE , TRUE ) ;
2018-03-29 17:01:57 -04:00
}
}
}
}
2019-07-07 20:56:15 +00:00
void Fellowship : : SetUpdates ( uint32_t fellow_id , BOOL on )
2018-03-29 17:01:57 -04:00
{
Fellow * f = _fellowship_table . lookup ( fellow_id ) ;
if ( ! f )
return ;
f - > _updates = on ;
}
void FellowshipManager : : Tick ( )
{
}
2019-07-07 20:56:15 +00:00
int FellowshipManager : : Create ( const std : : string & name , uint32_t creator_id , BOOL shareXP )
2018-03-29 17:01:57 -04:00
{
2018-07-12 14:41:21 -07:00
CWeenieObject * playerWeenie = g_pWorld - > FindPlayer ( creator_id ) ;
if ( CPlayerWeenie * player = playerWeenie - > AsPlayer ( ) )
2018-03-29 17:01:57 -04:00
{
2019-09-03 14:18:02 +00:00
fellowship_ptr_t fs = std : : make_shared < Fellowship > ( ) ;
fs - > _name = name ;
fs - > _leader = creator_id ;
fs - > _desiredShareXP = shareXP ;
fs - > _locked = false ;
fs - > _open_fellow = false ;
fs - > _even_xp_split = true ;
fs - > _share_loot = false ;
Fellow f ( player ) ;
fs - > _fellowship_table . add ( creator_id , & f ) ;
2018-03-29 17:01:57 -04:00
fs - > _share_loot = player - > ShareFellowshipLoot ( ) ;
2019-09-03 14:18:02 +00:00
player - > JoinFellowship ( fs ) ;
fs - > FullUpdate ( ) ;
}
2018-03-29 17:01:57 -04:00
return WERROR_NONE ;
}
2019-09-03 14:18:02 +00:00
int FellowshipManager : : Disband ( const fellowship_ptr_t & fellowship , uint32_t disbander_id )
{
if ( ! fellowship )
2018-03-29 17:01:57 -04:00
return WERROR_FELLOWSHIP_NO_FELLOWSHIP ;
2019-09-03 14:18:02 +00:00
if ( fellowship - > _leader ! = disbander_id )
2018-03-29 17:01:57 -04:00
return WERROR_FELLOWSHIP_NOT_LEADER ;
2019-09-03 14:18:02 +00:00
fellowship - > Disband ( disbander_id ) ;
2018-03-29 17:01:57 -04:00
return WERROR_NONE ;
}
2019-09-03 14:18:02 +00:00
int FellowshipManager : : Quit ( const fellowship_ptr_t & fellowship , uint32_t quitter_id )
2018-03-29 17:01:57 -04:00
{
2019-09-03 14:18:02 +00:00
if ( ! fellowship )
2018-03-29 17:01:57 -04:00
return WERROR_FELLOWSHIP_NO_FELLOWSHIP ;
2019-09-03 14:18:02 +00:00
fellowship - > Quit ( quitter_id ) ;
2018-03-29 17:01:57 -04:00
return WERROR_NONE ;
}
2019-09-03 14:18:02 +00:00
int FellowshipManager : : Dismiss ( const fellowship_ptr_t & fellowship , uint32_t dismisser_id , uint32_t dismissee_id )
2018-03-29 17:01:57 -04:00
{
2019-09-03 14:18:02 +00:00
if ( ! fellowship )
2018-03-29 17:01:57 -04:00
return WERROR_FELLOWSHIP_NO_FELLOWSHIP ;
2019-09-03 14:18:02 +00:00
if ( fellowship - > _leader ! = dismisser_id )
2018-03-29 17:01:57 -04:00
return WERROR_FELLOWSHIP_NOT_LEADER ;
2018-07-12 14:41:21 -07:00
CWeenieObject * dismissee_weenie = g_pWorld - > FindPlayer ( dismissee_id ) ;
2018-03-29 17:01:57 -04:00
if ( ! dismissee_weenie )
return WERROR_NO_OBJECT ;
if ( ! dismissee_weenie - > HasFellowship ( ) )
return WERROR_NO_OBJECT ;
2019-09-03 14:18:02 +00:00
fellowship_ptr_t other = dismissee_weenie - > GetFellowship ( ) ;
if ( fellowship ! = other )
2018-03-29 17:01:57 -04:00
return WERROR_NO_OBJECT ;
2019-09-03 14:18:02 +00:00
fellowship - > RemoveFellow ( dismissee_id ) ;
2018-03-29 17:01:57 -04:00
return WERROR_NONE ;
}
2019-09-03 14:18:02 +00:00
int FellowshipManager : : Recruit ( const fellowship_ptr_t & fellowship , uint32_t recruiter_id , uint32_t recruitee_id )
2018-03-29 17:01:57 -04:00
{
2019-09-03 14:18:02 +00:00
if ( ! fellowship )
2018-03-29 17:01:57 -04:00
return WERROR_FELLOWSHIP_NO_FELLOWSHIP ;
2019-09-03 14:18:02 +00:00
if ( fellowship - > IsFull ( ) )
2018-03-29 17:01:57 -04:00
return WERROR_FELLOWSHIP_FULL ;
2019-09-03 14:18:02 +00:00
if ( ! fellowship - > IsOpen ( ) & & fellowship - > _leader ! = recruiter_id )
2018-03-29 17:01:57 -04:00
return WERROR_FELLOWSHIP_NOT_LEADER ;
2018-07-12 14:41:21 -07:00
CPlayerWeenie * recruiter_weenie = g_pWorld - > FindPlayer ( recruiter_id ) ;
2018-03-29 17:01:57 -04:00
if ( ! recruiter_weenie )
return WERROR_NO_OBJECT ;
if ( recruiter_weenie - > IsBusyOrInAction ( ) )
return WERROR_ACTIONS_LOCKED ;
2018-07-12 14:41:21 -07:00
CPlayerWeenie * recruited_weenie = g_pWorld - > FindPlayer ( recruitee_id ) ;
2018-03-29 17:01:57 -04:00
if ( ! recruited_weenie )
return WERROR_NO_OBJECT ;
2019-09-03 14:18:02 +00:00
if ( ! fellowship - > CanJoin ( recruitee_id ) )
{
recruiter_weenie - > NotifyWeenieErrorWithString ( WERROR_FELLOWSHIP_LOCKED_RECRUITER , recruited_weenie - > GetName ( ) . c_str ( ) ) ;
recruited_weenie - > NotifyWeenieError ( WERROR_FELLOWSHIP_LOCKED_RECRUITEE ) ;
return WERROR_NONE ;
}
2019-09-06 07:36:22 -07:00
if ( recruiter_weenie - > DistanceTo ( recruited_weenie , true ) > = 16.0 )
2018-03-29 17:01:57 -04:00
return WERROR_TOO_FAR ;
if ( recruited_weenie - > IsBusyOrInAction ( ) )
return WERROR_ACTIONS_LOCKED ;
if ( recruited_weenie - > HasFellowship ( ) )
return WERROR_FELLOWSHIP_MEMBER ;
if ( recruited_weenie - > GetCharacterOptions ( ) & IgnoreFellowshipRequests_CharacterOption )
return WERROR_FELLOWSHIP_IGNORING_REQUESTS ;
2019-09-03 14:18:02 +00:00
fellowship - > AddFellow ( recruitee_id ) ;
recruited_weenie - > JoinFellowship ( fellowship ) ;
2018-03-29 17:01:57 -04:00
recruiter_weenie - > DoForcedMotion ( Motion_BowDeep ) ;
return WERROR_NONE ;
}
2019-09-03 14:18:02 +00:00
int FellowshipManager : : ChangeOpen ( const fellowship_ptr_t & fellowship , uint32_t changer_id , BOOL open )
2018-03-29 17:01:57 -04:00
{
2019-09-03 14:18:02 +00:00
if ( ! fellowship )
2018-03-29 17:01:57 -04:00
return WERROR_FELLOWSHIP_NO_FELLOWSHIP ;
2019-09-03 14:18:02 +00:00
if ( fellowship - > _leader ! = changer_id )
2018-03-29 17:01:57 -04:00
return WERROR_FELLOWSHIP_NOT_LEADER ;
2019-09-03 14:18:02 +00:00
if ( fellowship - > IsLocked ( ) )
return WERROR_FELLOWSHIP_FELLOW_LOCKED_CAN_NOT_OPEN ;
fellowship - > ChangeOpen ( open ) ;
2018-03-29 17:01:57 -04:00
return WERROR_NONE ;
}
2019-09-03 14:18:02 +00:00
int FellowshipManager : : AssignNewLeader ( const fellowship_ptr_t & fellowship , uint32_t changer_id , uint32_t new_leader_id )
2018-03-29 17:01:57 -04:00
{
2019-09-03 14:18:02 +00:00
if ( ! fellowship )
2018-03-29 17:01:57 -04:00
return WERROR_FELLOWSHIP_NO_FELLOWSHIP ;
if ( changer_id = = new_leader_id )
return WERROR_FELLOWSHIP_MEMBER ;
2019-09-03 14:18:02 +00:00
if ( fellowship - > _leader ! = changer_id )
2018-03-29 17:01:57 -04:00
return WERROR_FELLOWSHIP_NOT_LEADER ;
2019-09-03 14:18:02 +00:00
if ( ! fellowship - > _fellowship_table . lookup ( new_leader_id ) )
2018-03-29 17:01:57 -04:00
return WERROR_NO_OBJECT ;
2019-09-03 14:18:02 +00:00
fellowship - > AssignNewLeader ( new_leader_id ) ;
2018-03-29 17:01:57 -04:00
return WERROR_NONE ;
}
2019-09-03 14:18:02 +00:00
int FellowshipManager : : RequestUpdates ( const fellowship_ptr_t & fellowship , uint32_t requester_id , BOOL on )
2018-03-29 17:01:57 -04:00
{
2019-09-03 14:18:02 +00:00
if ( ! fellowship )
2018-03-29 17:01:57 -04:00
return WERROR_FELLOWSHIP_NO_FELLOWSHIP ;
2019-09-03 14:18:02 +00:00
fellowship - > SetUpdates ( requester_id , on ) ;
2018-03-29 17:01:57 -04:00
return WERROR_NONE ;
}
double FellowshipManager : : GetEvenSplitXPPctg ( unsigned int uiNumFellows )
{
switch ( uiNumFellows )
{
case 1 :
return 1.0 ;
case 2 :
return 0.75 ;
case 3 :
return 0.6 ;
case 4 :
return 0.55 ;
case 5 :
return 0.5 ;
case 6 :
return 0.45 ;
case 7 :
return 0.4 ;
case 8 :
return 0.35 ;
case 9 :
return 0.31111111 ;
case 0xA :
return 0.28 ;
default :
return 0.0 ;
}
}
2019-07-07 20:56:15 +00:00
uint64_t FellowshipManager : : GetExperienceProportion ( unsigned int level )
2018-03-29 17:01:57 -04:00
{
return ExperienceSystem : : ExperienceToRaiseLevel ( level , level + 1 ) ;
}
2019-09-03 14:18:02 +00:00
void FellowshipManager : : Chat ( const fellowship_ptr_t & fellowship , uint32_t sender_id , const char * text )
2018-03-29 17:01:57 -04:00
{
2019-09-03 14:18:02 +00:00
if ( ! fellowship )
2018-03-29 17:01:57 -04:00
return ;
2019-09-03 14:18:02 +00:00
fellowship - > Chat ( sender_id , text ) ;
2019-07-30 02:19:05 +00:00
}