uox3/source/PartySystem.cpp
Xoduz 3e8006c648 Code cleanup
Embraced the usage of R32, R64, SI16, UI16, SI32, UI32, SI64 and UI64 typedef aliases as replacement for built-in types throughout the sourcecode:
	typedef float				R32;
	typedef double				R64;
	typedef signed char			SI08;
	typedef unsigned char		UI08;
	typedef signed short int	SI16;
	typedef unsigned short int	UI16;
	typedef signed int			SI32;
	typedef unsigned int		UI32;
	typedef signed long long	SI64;
	typedef unsigned long long	UI64;
As part of this process, UI32 was redefined from unsigned long int to unsigned int, and SI32 from signed long int to signed int to ensure the size of variables using these remain the same (32bit) across both Windows, Linux and MacOS for both 32bit and 64bit platforms
Replaced instances of toLong() with toInt(), and toULong() to toUInt()
Replaced instances of "long" and "int" with SI32 where possible
Replaced instances of "unsigned long" and "unsigned int" with UI32 where possible
Replaced instances of "float" with R32 where possible
2020-08-12 23:46:33 +08:00

344 lines
10 KiB
C++

#include "PartySystem.h"
#include "uox3.h"
#include "network.h"
#include "CPacketSend.h"
namespace UOX
{
// PartyEntry code goes here
const size_t BIT_LEADER = 0;
const size_t BIT_LOOTABLE = 1;
CChar * PartyEntry::Member( void ) const { return member; }
bool PartyEntry::IsLeader( void ) const { return settings.test( BIT_LEADER ); }
bool PartyEntry::IsLootable( void ) const { return settings.test( BIT_LOOTABLE ); }
void PartyEntry::Member( CChar *valid ) { member = valid; }
void PartyEntry::IsLeader( bool value ) { settings.set( BIT_LEADER, true ); }
void PartyEntry::IsLootable( bool value ) { settings.set( BIT_LOOTABLE, true ); }
PartyEntry::PartyEntry() : member( NULL ) { settings.reset(); }
PartyEntry::PartyEntry( CChar *m, bool isLeader, bool isLootable ) : member( m )
{
settings.set( BIT_LEADER, isLeader );
settings.set( BIT_LOOTABLE, isLootable );
}
//o-----------------------------------------------------------------------------------------------o
//| Function - bool AddMember( CChar *i )
//o-----------------------------------------------------------------------------------------------o
//| Purpose - Add new member to party
//o-----------------------------------------------------------------------------------------------o
bool Party::AddMember( CChar *i )
{
bool retVal = false;
if( ValidateObject( i ) )
{
if( !HasMember( i ) )
{
PartyEntry *toAdd = new PartyEntry( i );
PartyFactory::getSingleton().AddLookup( this, i );
members.push_back( toAdd );
SendList( NULL );
retVal = true;
}
}
return retVal;
}
//o-----------------------------------------------------------------------------------------------o
//| Function - PartyEntry *Find( CChar *i, SI32 *location )
//o-----------------------------------------------------------------------------------------------o
//| Purpose - Check if character is a member of party
//o-----------------------------------------------------------------------------------------------o
PartyEntry *Party::Find( CChar *i, SI32 *location )
{
if( ValidateObject( i ) )
{
for( size_t j = 0; j < members.size(); ++j )
{
PartyEntry *toFind = members[j];
if( toFind->Member() == i )
{
if( location != NULL )
(*location) = j;
return toFind;
}
}
}
return NULL;
}
bool Party::HasMember( CChar *find )
{
return ( Find( find ) != NULL );
}
//o-----------------------------------------------------------------------------------------------o
//| Function - bool RemoveMember( CChar *i )
//o-----------------------------------------------------------------------------------------------o
//| Purpose - Remove a character from the party
//o-----------------------------------------------------------------------------------------------o
bool Party::RemoveMember( CChar *i )
{
bool retVal = false;
if( ValidateObject( i ) )
{
SI32 removeSpot;
PartyEntry *toFind = Find( i, &removeSpot );
if( toFind != NULL )
{
delete members[removeSpot];
members.erase( members.begin() + removeSpot );
PartyFactory::getSingleton().RemoveLookup( i );
CPPartyMemberRemove toSend( i );
for( size_t j = 0; j < members.size(); ++j )
{
PartyEntry *toFind = members[j];
toSend.AddMember( toFind->Member() );
}
SendPacket( &toSend, NULL );
if( i->GetSocket() != NULL )
SendPacket( &toSend, i->GetSocket() );
retVal = true;
}
}
return retVal;
}
//o-----------------------------------------------------------------------------------------------o
//| Function - void Leader( CChar *member )
//o-----------------------------------------------------------------------------------------------o
//| Purpose - Set a party member as party leader
//o-----------------------------------------------------------------------------------------------o
void Party::Leader( CChar *member )
{
SI32 newLeaderPos;
PartyEntry *newLeader = Find( member, &newLeaderPos );
if( newLeader != NULL )
{
if( leader != NULL )
{
SI32 oldLeaderPos;
PartyEntry *mFind = Find( leader, &oldLeaderPos );
if( mFind != NULL )
{
mFind->IsLeader( false );
// We need to swap their position in the array, because the first cab
// off the rank is the leader, and the client makes assumptions about
// this
members[oldLeaderPos] = newLeader;
members[newLeaderPos] = mFind;
}
}
leader = newLeader->Member();
newLeader->IsLeader( true );
}
}
CChar *Party::Leader( void ) { return leader; }
Party::Party( bool npc ) : leader( NULL ), isNPC( npc ) { }
Party::Party( CChar *ldr, bool npc ) : leader( NULL ), isNPC( npc )
{
if( ValidateObject( ldr ) )
{
AddMember( ldr );
Leader( ldr );
}
}
//o-----------------------------------------------------------------------------------------------o
//| Function - void SendPacket( CPUOXBuffer *toSend, CSocket *toSendTo )
//o-----------------------------------------------------------------------------------------------o
//| Purpose - Send list of party members to client
//o-----------------------------------------------------------------------------------------------o
void Party::SendPacket( CPUOXBuffer *toSend, CSocket *toSendTo )
{
if( toSendTo != NULL )
toSendTo->Send( toSend );
else
{
for( size_t k = 0; k < members.size(); ++k )
{
PartyEntry *toFind = members[k];
CSocket *tSock = toFind->Member()->GetSocket();
if( tSock != NULL )
tSock->Send( toSend );
}
}
}
void Party::SendList( CSocket *toSendTo )
{
CPPartyMemberList toSend;
for( size_t j = 0; j < members.size(); ++j )
{
PartyEntry *toFind = members[j];
toSend.AddMember( toFind->Member() );
}
SendPacket( &toSend, toSendTo );
}
bool Party::IsNPC( void ) const
{
return isNPC;
}
void Party::IsNPC( bool value )
{
isNPC = value;
}
/** This class is responsible for the creation and destruction of parties
*/
//-------------------------------------------------------------------------------------------------
template<> PartyFactory * Singleton< PartyFactory >::ms_Singleton = 0;
PartyFactory* PartyFactory::getSingletonPtr( void )
{
return ms_Singleton;
}
PartyFactory& PartyFactory::getSingleton( void )
{
assert( ms_Singleton ); return ( *ms_Singleton );
}
//-------------------------------------------------------------------------------------------------
void PartyFactory::AddLookup( Party *toQuickLook, CChar *toSave )
{
if( ValidateObject( toSave ) )
partyQuickLook[toSave->GetSerial()] = toQuickLook;
}
void PartyFactory::RemoveLookup( CChar *toRemove )
{
if( ValidateObject( toRemove ) )
{
std::map< SERIAL, Party * >::iterator toFind = partyQuickLook.find( toRemove->GetSerial() );
if( toFind != partyQuickLook.end() )
partyQuickLook.erase( toFind );
}
}
PartyFactory::PartyFactory()
{
partyQuickLook.clear();
}
PartyFactory::~PartyFactory()
{
for( Party *obj = parties.First(); !parties.Finished(); obj = parties.Next() )
{
delete obj;
obj = NULL;
}
}
Party *PartyFactory::Create( CChar *leader )
{
Party *toAdd = NULL;
if( ValidateObject( leader ) )
{
toAdd = new Party( leader );
parties.Add( toAdd );
}
return toAdd;
}
void PartyFactory::Destroy( CChar *member )
{
Party *toRemove = Get( member );
Destroy( toRemove );
}
void PartyFactory::Destroy( Party *toRemove )
{
if( toRemove != NULL )
{
std::vector< PartyEntry * > *mList = toRemove->MemberList();
if( mList != NULL )
{
for( size_t j = 0; j < mList->size(); ++j )
{
PartyEntry *mEntry = (*mList)[j];
RemoveLookup( mEntry->Member() );
}
}
parties.Remove( toRemove );
delete toRemove;
}
}
Party *PartyFactory::Get( CChar *member )
{
if( ValidateObject( member ) )
{
std::map< SERIAL, Party * >::iterator toFind = partyQuickLook.find( member->GetSerial() );
if( toFind != partyQuickLook.end() )
return toFind->second;
else
return NULL;
}
else
return NULL;
}
//o-----------------------------------------------------------------------------------------------o
//| Function - void CreateInvite( CSocket *inviter )
//o-----------------------------------------------------------------------------------------------o
//| Purpose - Invite a player to the party
//o-----------------------------------------------------------------------------------------------o
void PartyFactory::CreateInvite( CSocket *inviter )
{
SERIAL serial = inviter->GetDWord( 7 );
CChar *toInvite = calcCharObjFromSer( serial );
if( !ValidateObject( toInvite ) || toInvite->IsNpc() )
{
inviter->sysmessage( "You cannot invite an npc or unknown player" );
return;
}
CChar *inviterChar = inviter->CurrcharObj();
if( ValidateObject( inviterChar ) && inviterChar == toInvite )
{
inviter->sysmessage( "You cannot invite yourself to a party" );
return;
}
Party *ourParty = Get( inviterChar );
if( ourParty == NULL )
{
Party *tParty = Create( inviterChar );
}
CSocket *targSock = toInvite->GetSocket();
if( targSock != NULL )
{
CPPartyInvitation toSend;
toSend.Leader( inviterChar );
targSock->Send( &toSend );
targSock->sysmessage( "You have been invited to join a party, type /accept or /decline to deal with the invitation" );
}
else
{
inviter->sysmessage( "That player is not online" );
}
}
//o-----------------------------------------------------------------------------------------------o
//| Function - void Kick( CSocket *inviter )
//o-----------------------------------------------------------------------------------------------o
//| Purpose - Kick a member from the party
//o-----------------------------------------------------------------------------------------------o
void PartyFactory::Kick( CSocket *inviter )
{
SERIAL serial = inviter->GetDWord( 7 );
CChar *toRemove = calcCharObjFromSer( serial );
if( !ValidateObject( toRemove ) || toRemove->IsNpc() )
{
inviter->sysmessage( "You cannot kick an npc or unknown player" );
return;
}
Party *ourParty = Get( inviter->CurrcharObj() );
if( ourParty == NULL )
{
inviter->sysmessage( "You are not in a party and cannot kick them out" );
return;
}
if( ( ourParty->Leader() != inviter->CurrcharObj() ) && ( inviter->CurrcharObj() != toRemove ) )
{
inviter->sysmessage( "Only the leader can kick someone out" );
return;
}
if( ourParty->HasMember( toRemove ) )
{ // even if they're offline, we can kick them out
ourParty->RemoveMember( toRemove );
inviter->sysmessage( "The player has been removed" );
}
}
}