mirror of
https://github.com/UOX3DevTeam/UOX3
synced 2026-08-13 12:27:04 -04:00
Misc code and documentation cleanup: Updated and standardized function comment blocks throughout entire codebase Grouped getters and setters together in pairs and documented them as one Removed empty and/or non-useful information from comment blocks Removed unused function from cItem.cpp/h - IncID() - formerly used to change IDs for doors Added new feature - Instances Objects (characters, items, multis, spawnregions) can now make use of a 5th parameter to determine their location in the game world. In addition to the traditional X, Y, Z and WORLDNUMBER parameters, a new one has been added - INSTANCEID - that allows objects to exist at the same coordinates in the same world, but in different "dimensions". Code has been updated in multiple places to support this, and a default instanceID of 0 is assumed if nothing else is specified. Added support for new DFN tag in town regions, spawn regions and locations - INSTANCEID (defaults to 0 if not present) Added support for another start location parameter after worldNum in UOX.INI representing instanceID (defaults to 0 if not present) Updated TWEAK menu to include WorldNumber and instanceID Fixed BaseWeight option in TWEAK menu Updated CBase_Teleport - now takes an optional 5th parameter instanceID Updated SE_SpawnNPC now takes an optional 5th parameter - instanceID Updated SE_FindMulti now takes an optional 5th parameter - instanceID Updated SE_GetItem now takes an optional 5th parameter - instanceID Updated SE_FindItem now takes an optional 6th parameter - instanceID Added new JS property for Items, Characters, Regions: .instanceID Added JS property for Regions: .members - returns comma-separated list of town member serials Updated JS scripts making use of the above-mentioned JS Methods/Functions Updated dictionaries with new tweak menu entry texts Exposed SpawnRegions to JS engine, and updated JS docs with details: SpawnRegion JS Functions IterateOverSpawnRegions() GetSpawnRegion( spawnRegNum ) GetSpawnRegionCount() SpawnRegion JS Properties name regionNum itemList npcList item npc maxItems maxNpcs itemCount npcCount onlyOutside prefZ x1 y1 x2 y2 world instanceID minTime maxTime call
344 lines
10 KiB
C++
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, int *location )
|
|
//o-----------------------------------------------------------------------------------------------o
|
|
//| Purpose - Check if character is a member of party
|
|
//o-----------------------------------------------------------------------------------------------o
|
|
PartyEntry *Party::Find( CChar *i, int *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 ) )
|
|
{
|
|
int 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 )
|
|
{
|
|
int newLeaderPos;
|
|
PartyEntry *newLeader = Find( member, &newLeaderPos );
|
|
if( newLeader != NULL )
|
|
{
|
|
if( leader != NULL )
|
|
{
|
|
int 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" );
|
|
}
|
|
}
|
|
}
|
|
|