Added some extra checks and clean-up related to Groups and Mercenaries.

This commit is contained in:
Trevius 2015-01-08 17:08:20 -06:00
parent c8278608a3
commit 94be9e9162
2 changed files with 35 additions and 43 deletions

View File

@ -1,5 +1,8 @@
EQEMu Changelog (Started on Sept 24, 2003 15:50)
-------------------------------------------------------
== 01/08/2015 ==
Trevius: Added some extra checks and clean-up related to Groups and Mercenaries.
== 01/07/2015 ==
Uleat: Excluded text link body from message scrambling in Client::GarbleMessage()
Trevius: Mercenaries now load directly from tables only. The vwMercNpcTypes view is no longer required and can be deleted.

View File

@ -26,23 +26,16 @@
extern EntityList entity_list;
extern WorldServer worldserver;
//
// Xorlac: This will need proper synchronization to make it work correctly.
// Also, should investigate client ack for packet to ensure proper synch.
//
/*
note about how groups work:
A group contains 2 list, a list of pointers to members and a
list of member names. All members of a group should have their
name in the membername array, wether they are in the zone or not.
name in the membername array, whether they are in the zone or not.
Only members in this zone will have non-null pointers in the
members array.
*/
//create a group which should allready exist in the database
//create a group which should already exist in the database
Group::Group(uint32 gid)
: GroupIDConsumer(gid)
{
@ -112,8 +105,7 @@ Group::~Group()
}
}
//Cofruben:Split money used in OP_Split.
//Rewritten by Father Nitwit
//Split money used in OP_Split (/split and /autosplit).
void Group::SplitMoney(uint32 copper, uint32 silver, uint32 gold, uint32 platinum, Client *splitter) {
//avoid unneeded work
if(copper == 0 && silver == 0 && gold == 0 && platinum == 0)
@ -197,7 +189,7 @@ void Group::SplitMoney(uint32 copper, uint32 silver, uint32 gold, uint32 platinu
for (i = 0; i < MAX_GROUP_MEMBERS; i++) {
if (members[i] != nullptr && members[i]->IsClient()) { // If Group Member is Client
Client *c = members[i]->CastToClient();
Client *c = members[i]->CastToClient();
//I could not get MoneyOnCorpse to work, so we use this
c->AddMoneyToPP(cpsplit, spsplit, gpsplit, ppsplit, true);
c->Message(2, msg.c_str());
@ -368,7 +360,6 @@ bool Group::AddMember(Mob* newmember, const char *NewMemberName, uint32 Characte
void Group::AddMember(const char *NewMemberName)
{
// This method should be called when both the new member and the group leader are in a different zone to this one.
//
for (uint32 i = 0; i < MAX_GROUP_MEMBERS; ++i)
if(!strcasecmp(membername[i], NewMemberName))
{
@ -395,9 +386,8 @@ void Group::QueuePacket(const EQApplicationPacket *app, bool ack_req)
members[i]->CastToClient()->QueuePacket(app, ack_req);
}
// solar: sends the rest of the group's hps to member. this is useful when
// someone first joins a group, but otherwise there shouldn't be a need to
// call it
// Sends the rest of the group's hps to member. this is useful when someone
// first joins a group, but otherwise there shouldn't be a need to call it
void Group::SendHPPacketsTo(Mob *member)
{
if(member && member->IsClient())
@ -459,9 +449,11 @@ void Group::SendHPPacketsFrom(Mob *member)
}
//updates a group member's client pointer when they zone in
//if the group was in the zone allready
//if the group was in the zone already
bool Group::UpdatePlayer(Mob* update){
bool updateSuccess = false;
VerifyGroup();
uint32 i=0;
@ -487,7 +479,8 @@ bool Group::UpdatePlayer(Mob* update){
{
members[i] = update;
members[i]->SetGrouped(true);
return true;
updateSuccess = true;
break;
}
}
@ -495,7 +488,7 @@ bool Group::UpdatePlayer(Mob* update){
if (update->IsClient() && !mentoree && mentoree_name.length() && !mentoree_name.compare(update->GetName()))
mentoree = update->CastToClient();
return false;
return updateSuccess;
}
@ -520,6 +513,7 @@ void Group::MemberZoned(Mob* removemob) {
}
#endif //BOTS
}
if(removemob->IsClient() && HasRole(removemob, RoleAssist))
SetGroupAssistTarget(0);
@ -592,7 +586,7 @@ bool Group::DelMemberOOZ(const char *Name) {
return false;
}
bool Group::DelMember(Mob* oldmember,bool ignoresender)
bool Group::DelMember(Mob* oldmember, bool ignoresender)
{
if (oldmember == nullptr)
{
@ -689,6 +683,8 @@ bool Group::DelMember(Mob* oldmember,bool ignoresender)
if(oldmember->IsClient())
oldmember->CastToClient()->QueuePacket(outapp);
}
safe_delete(outapp);
if(oldmember->IsClient())
{
@ -707,8 +703,6 @@ bool Group::DelMember(Mob* oldmember,bool ignoresender)
oldmember->SetGrouped(false);
disbandcheck = true;
safe_delete(outapp);
if(HasRole(oldmember, RoleTank))
{
SetGroupTankTarget(0);
@ -998,24 +992,21 @@ void Group::SendLeadershipAAUpdate()
// aware of it until they are next in the same zone as the leader.
EQApplicationPacket* outapp = new EQApplicationPacket(OP_GroupUpdate,sizeof(GroupJoin_Struct));
GroupJoin_Struct* gu = (GroupJoin_Struct*)outapp->pBuffer;
gu->action = groupActAAUpdate;
uint32 i = 0;
gu->leader_aas = LeaderAbilities;
gu->NPCMarkerID = GetNPCMarkerID();
uint32 i = 0;
for (i = 0;i < MAX_GROUP_MEMBERS; ++i)
{
if(members[i] && members[i]->IsClient())
{
strcpy(gu->yourname, members[i]->GetName());
strcpy(gu->membername, members[i]->GetName());
members[i]->CastToClient()->QueuePacket(outapp);
}
}
safe_delete(outapp);
}
@ -1037,8 +1028,8 @@ uint8 Group::GroupCount() {
uint32 Group::GetHighestLevel()
{
uint32 level = 1;
uint32 i;
uint32 level = 1;
uint32 i;
for (i = 0; i < MAX_GROUP_MEMBERS; i++)
{
if (members[i])
@ -1049,10 +1040,11 @@ uint32 i;
}
return level;
}
uint32 Group::GetLowestLevel()
{
uint32 level = 255;
uint32 i;
uint32 level = 255;
uint32 i;
for (i = 0; i < MAX_GROUP_MEMBERS; i++)
{
if (members[i])
@ -1112,16 +1104,14 @@ void Group::VerifyGroup() {
for (i = 0; i < MAX_GROUP_MEMBERS; i++) {
if (membername[i][0] == '\0') {
#if EQDEBUG >= 7
LogFile->write(EQEMuLog::Debug, "Group %lu: Verify %d: Empty.\n", (unsigned long)GetID(), i);
LogFile->write(EQEMuLog::Debug, "Group %lu: Verify %d: Empty.\n", (unsigned long)GetID(), i);
#endif
members[i] = nullptr;
continue;
}
//it should be safe to use GetClientByName, but Group is trying
//to be generic, so we'll go for general Mob
Mob *them = entity_list.GetMob(membername[i]);
if(them == nullptr && members[i] != nullptr) { //they arnt here anymore....
if(them == nullptr && members[i] != nullptr) { //they aren't in zone
#if EQDEBUG >= 6
LogFile->write(EQEMuLog::Debug, "Member of group %lu named '%s' has disappeared!!", (unsigned long)GetID(), membername[i]);
#endif
@ -1143,7 +1133,6 @@ LogFile->write(EQEMuLog::Debug, "Group %lu: Verify %d: Empty.\n", (unsigned long
}
}
void Group::GroupMessage_StringID(Mob* sender, uint32 type, uint32 string_id, const char* message,const char* message2,const char* message3,const char* message4,const char* message5,const char* message6,const char* message7,const char* message8,const char* message9, uint32 distance) {
uint32 i;
for (i = 0; i < MAX_GROUP_MEMBERS; i++) {
@ -1152,13 +1141,14 @@ void Group::GroupMessage_StringID(Mob* sender, uint32 type, uint32 string_id, co
if(members[i] == sender)
continue;
if(!members[i]->IsClient())
continue;
members[i]->Message_StringID(type, string_id, message, message2, message3, message4, message5, message6, message7, message8, message9, 0);
}
}
void Client::LeaveGroup() {
Group *g = GetGroup();
@ -1178,7 +1168,7 @@ void Client::LeaveGroup() {
else
{
g->DelMember(this);
if (GetMerc() && GetMerc()->HasGroup() && GetMerc()->GetGroup() == g)
if (GetMerc() != nullptr && g == GetMerc()->GetGroup() )
{
GetMerc()->RemoveMercFromGroup(GetMerc(), GetMerc()->GetGroup());
}
@ -1363,7 +1353,7 @@ void Group::MarkNPC(Mob* Target, int Number)
// Send a packet to all group members in this zone causing the client to prefix the Target mob's name
// with the specified Number.
//
if(!Target || Target->IsClient())
if(!Target || Target->IsClient() || Target->IsMerc())
return;
if((Number < 1) || (Number > MAX_MARKED_NPCS))
@ -2166,7 +2156,6 @@ int8 Group::GetNumberNeedingHealedInGroup(int8 hpr, bool includePets) {
}
}
return needHealed;
}
@ -2228,7 +2217,7 @@ void Group::ChangeLeader(Mob* newleader)
// this changes the current group leader, notifies other members, and updates leadship AA
// if the new leader is invalid, do nothing
if (!newleader)
if (!newleader || !newleader->IsClient())
return;
Mob* oldleader = GetLeader();