mirror of
https://github.com/EQEmu/Server.git
synced 2026-05-16 22:58:34 +00:00
Implement group mentoring while in raids (SoF+ only)
Note: This does not allow the raid leader to share raid leader XP and since the raid leader doesn't gain group leadership, they can't share that either.
This commit is contained in:
+17
-1
@@ -576,6 +576,7 @@ void Client::CompleteConnect()
|
||||
if (grpID < 12){
|
||||
raid->SendRaidGroupRemove(GetName(), grpID);
|
||||
raid->SendRaidGroupAdd(GetName(), grpID);
|
||||
raid->CheckGroupMentor(grpID, this);
|
||||
if (raid->IsGroupLeader(GetName())) { // group leader same thing!
|
||||
raid->UpdateGroupAAs(raid->GetGroup(this));
|
||||
raid->GroupUpdate(grpID, false);
|
||||
@@ -6869,10 +6870,25 @@ void Client::Handle_OP_GroupMentor(const EQApplicationPacket *app)
|
||||
return;
|
||||
}
|
||||
GroupMentor_Struct *gms = (GroupMentor_Struct *)app->pBuffer;
|
||||
gms->name[63] = '\0';
|
||||
|
||||
if (IsRaidGrouped()) {
|
||||
Raid *raid = GetRaid();
|
||||
if (!raid)
|
||||
return;
|
||||
uint32 group_id = raid->GetGroup(this);
|
||||
if (group_id > 11)
|
||||
return;
|
||||
if (strlen(gms->name))
|
||||
raid->SetGroupMentor(group_id, gms->percent, gms->name);
|
||||
else
|
||||
raid->ClearGroupMentor(group_id);
|
||||
return;
|
||||
}
|
||||
|
||||
Group *group = GetGroup();
|
||||
if (!group)
|
||||
return;
|
||||
gms->name[63] = '\0';
|
||||
|
||||
if (strlen(gms->name))
|
||||
group->SetGroupMentor(gms->percent, gms->name);
|
||||
|
||||
+14
-3
@@ -169,9 +169,20 @@ void Client::AddEXP(uint32 in_add_exp, uint8 conlevel, bool resexp) {
|
||||
} else {
|
||||
if (m_pp.group_leadership_points < MaxBankedGroupLeadershipPoints(GetLevel())
|
||||
&& RuleI(Character, KillsPerGroupLeadershipAA) > 0) {
|
||||
// mentoring stuff needs to be added here when raids are have support for it
|
||||
AddLeadershipEXP(0, GROUP_EXP_PER_POINT / RuleI(Character, KillsPerGroupLeadershipAA));
|
||||
Message_StringID(MT_Leadership, GAIN_GROUP_LEADERSHIP_EXP);
|
||||
uint32 group_id = raid->GetGroup(this);
|
||||
uint32 exp = GROUP_EXP_PER_POINT / RuleI(Character, KillsPerGroupLeadershipAA);
|
||||
Client *mentoree = raid->GetMentoree(group_id);
|
||||
if (raid->GetMentorPercent(group_id) && mentoree &&
|
||||
mentoree->GetGroupPoints() < MaxBankedGroupLeadershipPoints(mentoree->GetLevel())) {
|
||||
uint32 mentor_exp = exp * (raid->GetMentorPercent(group_id) / 100.0f);
|
||||
exp -= mentor_exp;
|
||||
mentoree->AddLeadershipEXP(mentor_exp, 0);
|
||||
mentoree->Message_StringID(MT_Leadership, GAIN_GROUP_LEADERSHIP_EXP);
|
||||
}
|
||||
if (exp > 0) {
|
||||
AddLeadershipEXP(exp, 0);
|
||||
Message_StringID(MT_Leadership, GAIN_GROUP_LEADERSHIP_EXP);
|
||||
}
|
||||
} else {
|
||||
Message_StringID(MT_Leadership, MAX_GROUP_LEADERSHIP_POINTS);
|
||||
}
|
||||
|
||||
+65
-2
@@ -31,6 +31,10 @@ Raid::Raid(uint32 raidID)
|
||||
memset(members ,0, (sizeof(RaidMember)*MAX_RAID_MEMBERS));
|
||||
memset(&raid_aa, 0, sizeof(RaidLeadershipAA_Struct));
|
||||
memset(group_aa, 0, sizeof(GroupLeadershipAA_Struct) * MAX_RAID_GROUPS);
|
||||
for (int i = 0; i < MAX_RAID_GROUPS; i++) {
|
||||
group_mentor[i].mentor_percent = 0;
|
||||
group_mentor[i].mentoree = nullptr;
|
||||
}
|
||||
leader = nullptr;
|
||||
memset(leadername, 0, 64);
|
||||
locked = false;
|
||||
@@ -43,6 +47,10 @@ Raid::Raid(Client* nLeader)
|
||||
memset(members ,0, (sizeof(RaidMember)*MAX_RAID_MEMBERS));
|
||||
memset(&raid_aa, 0, sizeof(RaidLeadershipAA_Struct));
|
||||
memset(group_aa, 0, sizeof(GroupLeadershipAA_Struct) * MAX_RAID_GROUPS);
|
||||
for (int i = 0; i < MAX_RAID_GROUPS; i++) {
|
||||
group_mentor[i].mentor_percent = 0;
|
||||
group_mentor[i].mentoree = nullptr;
|
||||
}
|
||||
leader = nLeader;
|
||||
memset(leadername, 0, 64);
|
||||
strn0cpy(leadername, nLeader->GetName(), 64);
|
||||
@@ -1482,13 +1490,19 @@ void Raid::MemberZoned(Client *c)
|
||||
if(!c)
|
||||
return;
|
||||
|
||||
// Raid::GetGroup() goes over the members as well, this way we go over once
|
||||
uint32 gid = RAID_GROUPLESS;
|
||||
for(int x = 0; x < MAX_RAID_MEMBERS; x++)
|
||||
{
|
||||
if(members[x].member == c)
|
||||
{
|
||||
members[x].member = nullptr;
|
||||
gid = members[x].GroupNumber;
|
||||
}
|
||||
}
|
||||
|
||||
if (gid < 12 && group_mentor[gid].mentoree == c)
|
||||
group_mentor[gid].mentoree = nullptr;
|
||||
}
|
||||
|
||||
void Raid::SendHPPacketsTo(Client *c)
|
||||
@@ -1597,7 +1611,56 @@ void Raid::LoadLeadership()
|
||||
{
|
||||
database.GetRaidLeadershipInfo(GetID(), nullptr, nullptr, nullptr, nullptr, &raid_aa);
|
||||
|
||||
for (uint32 group_id = 0; group_id < MAX_RAID_GROUPS; group_id++)
|
||||
database.GetGroupLeadershipInfo(group_id, GetID(), nullptr, nullptr, nullptr, nullptr, &group_aa[group_id]);
|
||||
char mentor_name[64];
|
||||
for (uint32 group_id = 0; group_id < MAX_RAID_GROUPS; group_id++) {
|
||||
database.GetGroupLeadershipInfo(group_id, GetID(), nullptr, nullptr, nullptr, nullptr,
|
||||
mentor_name, &group_mentor[group_id].mentor_percent, &group_aa[group_id]);
|
||||
if (strlen(mentor_name)) {
|
||||
group_mentor[group_id].name = mentor_name;
|
||||
mentor_name[0] = '\0';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Raid::SetGroupMentor(uint32 group_id, int percent, char *name)
|
||||
{
|
||||
if (group_id > 11)
|
||||
return;
|
||||
group_mentor[group_id].name = name;
|
||||
group_mentor[group_id].mentor_percent = percent;
|
||||
Client *client = entity_list.GetClientByName(name);
|
||||
group_mentor[group_id].mentoree = client ? client : nullptr;
|
||||
|
||||
std::string query = StringFormat("UPDATE raid_leaders SET mentoree = '%s', mentor_percent = %i WHERE gid = %i AND rid = %i LIMIT 1",
|
||||
name, percent, group_id, GetID());
|
||||
auto results = database.QueryDatabase(query);
|
||||
if (!results.Success())
|
||||
LogFile->write(EQEMuLog::Error, "Unable to set raid group mentor: %s\n", results.ErrorMessage().c_str());
|
||||
}
|
||||
|
||||
void Raid::ClearGroupMentor(uint32 group_id)
|
||||
{
|
||||
if (group_id > 11)
|
||||
return;
|
||||
group_mentor[group_id].name.clear();
|
||||
group_mentor[group_id].mentor_percent = 0;
|
||||
group_mentor[group_id].mentoree = nullptr;
|
||||
|
||||
std::string query = StringFormat("UPDATE raid_leaders SET mentoree = '', mentor_percent = 0 WHERE gid = %i AND rid = %i LIMIT 1",
|
||||
group_id, GetID());
|
||||
auto results = database.QueryDatabase(query);
|
||||
if (!results.Success())
|
||||
LogFile->write(EQEMuLog::Error, "Unable to clear raid group mentor: %s\n", results.ErrorMessage().c_str());
|
||||
}
|
||||
|
||||
// there isn't a nice place to add this in another function, unlike groups
|
||||
// so we do it here instead
|
||||
void Raid::CheckGroupMentor(uint32 group_id, Client *c)
|
||||
{
|
||||
if (!c || group_id > 11)
|
||||
return;
|
||||
|
||||
if (group_mentor[group_id].name == c->GetName())
|
||||
group_mentor[group_id].mentoree = c;
|
||||
}
|
||||
|
||||
|
||||
@@ -92,6 +92,12 @@ struct RaidMember{
|
||||
bool IsLooter;
|
||||
};
|
||||
|
||||
struct GroupMentor {
|
||||
std::string name;
|
||||
Client *mentoree;
|
||||
int mentor_percent;
|
||||
};
|
||||
|
||||
class Raid : public GroupIDConsumer {
|
||||
public:
|
||||
Raid(Client *nLeader);
|
||||
@@ -221,6 +227,12 @@ public:
|
||||
inline void SetRaidAAs(RaidLeadershipAA_Struct *rlaa)
|
||||
{ memcpy(&raid_aa, rlaa, sizeof(RaidLeadershipAA_Struct)); }
|
||||
|
||||
void SetGroupMentor(uint32 group_id, int percent, char *name);
|
||||
void ClearGroupMentor(uint32 group_id);
|
||||
void CheckGroupMentor(uint32 group_id, Client *c); // this just checks if we should be fixing the pointer in group mentor struct on zone
|
||||
inline int GetMentorPercent(uint32 group_id) { return group_mentor[group_id].mentor_percent; }
|
||||
inline Client *GetMentoree(uint32 group_id) { return group_mentor[group_id].mentoree; }
|
||||
|
||||
RaidMember members[MAX_RAID_MEMBERS];
|
||||
char leadername[64];
|
||||
protected:
|
||||
@@ -233,6 +245,8 @@ protected:
|
||||
std::string motd;
|
||||
RaidLeadershipAA_Struct raid_aa;
|
||||
GroupLeadershipAA_Struct group_aa[MAX_RAID_GROUPS];
|
||||
|
||||
GroupMentor group_mentor[MAX_RAID_GROUPS];
|
||||
};
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user