Partial implementation of leadership in raids

Currently working: stat bonuses and client side only effects
Currently not working: Mark NPC and others that need more server side work

Currently only tested on UF, Ti and 62 may work, but not tested
SoF, SoD, and RoF need packet translators, which are most likely the same as UF
This commit is contained in:
Michael Cook (mackal)
2014-10-13 21:36:59 -04:00
parent 15cec40ed5
commit be0621de42
19 changed files with 891 additions and 42 deletions
+152
View File
@@ -1550,6 +1550,41 @@ void Client::ResetAA(){
int Client::GroupLeadershipAAHealthEnhancement()
{
if (IsRaidGrouped()) {
int bonus = 0;
Raid *raid = GetRaid();
if (!raid)
return 0;
uint32 group_id = raid->GetGroup(this);
if (group_id < 12 && raid->GroupCount(group_id) >= 3) {
switch (raid->GetLeadershipAA(groupAAHealthEnhancement, group_id)) {
case 1:
bonus = 30;
break;
case 2:
bonus = 60;
break;
case 3:
bonus = 100;
break;
}
}
if (raid->RaidCount() >= 18) {
switch (raid->GetLeadershipAA(raidAAHealthEnhancement)) {
case 1:
bonus += 30;
break;
case 2:
bonus += 60;
break;
case 3:
bonus += 100;
break;
}
}
return bonus;
}
Group *g = GetGroup();
if(!g || (g->GroupCount() < 3))
@@ -1572,6 +1607,41 @@ int Client::GroupLeadershipAAHealthEnhancement()
int Client::GroupLeadershipAAManaEnhancement()
{
if (IsRaidGrouped()) {
int bonus = 0;
Raid *raid = GetRaid();
if (!raid)
return 0;
uint32 group_id = raid->GetGroup(this);
if (group_id < 12 && raid->GroupCount(group_id) >= 3) {
switch (raid->GetLeadershipAA(groupAAManaEnhancement, group_id)) {
case 1:
bonus = 30;
break;
case 2:
bonus = 60;
break;
case 3:
bonus = 100;
break;
}
}
if (raid->RaidCount() >= 18) {
switch (raid->GetLeadershipAA(raidAAManaEnhancement)) {
case 1:
bonus += 30;
break;
case 2:
bonus += 60;
break;
case 3:
bonus += 100;
break;
}
}
return bonus;
}
Group *g = GetGroup();
if(!g || (g->GroupCount() < 3))
@@ -1594,6 +1664,41 @@ int Client::GroupLeadershipAAManaEnhancement()
int Client::GroupLeadershipAAHealthRegeneration()
{
if (IsRaidGrouped()) {
int bonus = 0;
Raid *raid = GetRaid();
if (!raid)
return 0;
uint32 group_id = raid->GetGroup(this);
if (group_id < 12 && raid->GroupCount(group_id) >= 3) {
switch (raid->GetLeadershipAA(groupAAHealthRegeneration, group_id)) {
case 1:
bonus = 4;
break;
case 2:
bonus = 6;
break;
case 3:
bonus = 8;
break;
}
}
if (raid->RaidCount() >= 18) {
switch (raid->GetLeadershipAA(raidAAHealthRegeneration)) {
case 1:
bonus += 4;
break;
case 2:
bonus += 6;
break;
case 3:
bonus += 8;
break;
}
}
return bonus;
}
Group *g = GetGroup();
if(!g || (g->GroupCount() < 3))
@@ -1616,6 +1721,53 @@ int Client::GroupLeadershipAAHealthRegeneration()
int Client::GroupLeadershipAAOffenseEnhancement()
{
if (IsRaidGrouped()) {
int bonus = 0;
Raid *raid = GetRaid();
if (!raid)
return 0;
uint32 group_id = raid->GetGroup(this);
if (group_id < 12 && raid->GroupCount(group_id) >= 3) {
switch (raid->GetLeadershipAA(groupAAOffenseEnhancement, group_id)) {
case 1:
bonus = 10;
break;
case 2:
bonus = 19;
break;
case 3:
bonus = 28;
break;
case 4:
bonus = 34;
break;
case 5:
bonus = 40;
break;
}
}
if (raid->RaidCount() >= 18) {
switch (raid->GetLeadershipAA(raidAAOffenseEnhancement)) {
case 1:
bonus += 10;
break;
case 2:
bonus += 19;
break;
case 3:
bonus += 28;
break;
case 4:
bonus += 34;
break;
case 5:
bonus += 40;
break;
}
}
return bonus;
}
Group *g = GetGroup();
if(!g || (g->GroupCount() < 3))
+5 -1
View File
@@ -3670,7 +3670,11 @@ void Client::LogSQL(const char *fmt, ...) {
}
void Client::GetGroupAAs(GroupLeadershipAA_Struct *into) const {
memcpy(into, &m_pp.leader_abilities, sizeof(GroupLeadershipAA_Struct));
memcpy(into, &m_pp.leader_abilities.group, sizeof(GroupLeadershipAA_Struct));
}
void Client::GetRaidAAs(RaidLeadershipAA_Struct *into) const {
memcpy(into, &m_pp.leader_abilities.raid, sizeof(RaidLeadershipAA_Struct));
}
void Client::EnteringMessages(Client* client)
+4
View File
@@ -559,6 +559,9 @@ public:
void SendLeadershipEXPUpdate();
bool IsLeadershipEXPOn();
inline int GetLeadershipAA(int AAID) { return m_pp.leader_abilities.ranks[AAID]; }
inline LeadershipAA_Struct &GetLeadershipAA() { return m_pp.leader_abilities; }
inline GroupLeadershipAA_Struct &GetGroupLeadershipAA() { return m_pp.leader_abilities.group; }
inline RaidLeadershipAA_Struct &GetRaidLeadershipAA() { return m_pp.leader_abilities.raid; }
int GroupLeadershipAAHealthEnhancement();
int GroupLeadershipAAManaEnhancement();
int GroupLeadershipAAHealthRegeneration();
@@ -585,6 +588,7 @@ public:
bool CheckLoreConflict(const Item_Struct* item);
void ChangeLastName(const char* in_lastname);
void GetGroupAAs(GroupLeadershipAA_Struct *into) const;
void GetRaidAAs(RaidLeadershipAA_Struct *into) const;
void ClearGroupAAs();
void UpdateGroupAAs(int32 points, uint32 type);
void SacrificeConfirm(Client* caster);
+28 -3
View File
@@ -546,6 +546,7 @@ void Client::CompleteConnect()
raid = new Raid(raidid);
if (raid->GetID() != 0){
entity_list.AddRaid(raid, raidid);
raid->LoadLeadership(); // Recreating raid in new zone, get leadership from DB
}
else
raid = nullptr;
@@ -566,11 +567,20 @@ void Client::CompleteConnect()
raid->SendBulkRaid(this);
raid->SendGroupUpdate(this);
raid->SendRaidMOTD(this);
if (raid->IsLeader(this)) { // We're a raid leader, lets update just in case!
raid->UpdateRaidAAs();
raid->SendAllRaidLeadershipAA();
}
uint32 grpID = raid->GetGroup(GetName());
if (grpID < 12){
raid->SendRaidGroupRemove(GetName(), grpID);
raid->SendRaidGroupAdd(GetName(), grpID);
if (raid->IsGroupLeader(GetName())) { // group leader same thing!
raid->UpdateGroupAAs(raid->GetGroup(this));
raid->GroupUpdate(grpID, false);
}
}
raid->SendGroupLeadershipAA(this, grpID); // this may get sent an extra time ...
if (raid->IsLocked())
raid->SendRaidLockTo(this);
}
@@ -10606,10 +10616,23 @@ void Client::Handle_OP_PurchaseLeadershipAA(const EQApplicationPacket *app)
u->pointsleft = m_pp.group_leadership_points;
FastQueuePacket(&outapp);
Group *g = GetGroup();
// Update all group members with the new AA the leader has purchased.
if (g) {
if (IsRaidGrouped()) {
Raid *r = GetRaid();
if (!r)
return;
if (aaid >= raidAAMarkNPC) {
r->UpdateRaidAAs();
r->SendAllRaidLeadershipAA();
} else {
uint32 gid = r->GetGroup(this);
r->UpdateGroupAAs(gid);
r->GroupUpdate(gid, false);
}
} else if (IsGrouped()) {
Group *g = GetGroup();
if (!g)
return;
g->UpdateGroupAAs();
g->SendLeadershipAAUpdate();
}
@@ -11228,6 +11251,8 @@ void Client::Handle_OP_RaidCommand(const EQApplicationPacket *app)
{
if (strcmp(r->leadername, GetName()) == 0){
r->SetRaidLeader(GetName(), ri->leader_name);
r->UpdateRaidAAs();
r->SendAllRaidLeadershipAA();
}
}
break;
+119 -1
View File
@@ -29,6 +29,8 @@ Raid::Raid(uint32 raidID)
: GroupIDConsumer(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);
leader = nullptr;
memset(leadername, 0, 64);
locked = false;
@@ -39,6 +41,8 @@ Raid::Raid(Client* nLeader)
: GroupIDConsumer()
{
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);
leader = nLeader;
memset(leadername, 0, 64);
strn0cpy(leadername, nLeader->GetName(), 64);
@@ -84,8 +88,18 @@ void Raid::AddMember(Client *c, uint32 group, bool rleader, bool groupleader, bo
LearnMembers();
VerifyRaid();
if (rleader) {
database.SetRaidGroupLeaderInfo(RAID_GROUPLESS, GetID());
UpdateRaidAAs();
}
if (group != RAID_GROUPLESS && groupleader) {
database.SetRaidGroupLeaderInfo(group, GetID());
UpdateGroupAAs(group);
}
if(group < 12)
GroupUpdate(group);
else // get raid AAs, GroupUpdate will handles it otherwise
SendGroupLeadershipAA(c, RAID_GROUPLESS);
SendRaidAddAll(c->GetName());
c->SetRaidGrouped(true);
@@ -186,6 +200,18 @@ void Raid::SetGroupLeader(const char *who, bool glFlag)
safe_delete(pack);
}
Client *Raid::GetGroupLeader(uint32 group_id)
{
if (group_id == RAID_GROUPLESS)
return nullptr;
for (uint32 i = 0; i < MAX_RAID_MEMBERS; i++)
if (members[i].member && members[i].IsGroupLeader && members[i].GroupNumber == group_id)
return members[i].member;
return nullptr;
}
void Raid::SetRaidLeader(const char *wasLead, const char *name)
{
std::string query = StringFormat("UPDATE raid_members SET israidleader = 0 WHERE name = '%s'", wasLead);
@@ -218,6 +244,59 @@ void Raid::SetRaidLeader(const char *wasLead, const char *name)
safe_delete(pack);
}
void Raid::SaveGroupLeaderAA(uint32 gid)
{
char *queryBuffer = new char[sizeof(GroupLeadershipAA_Struct) * 2 + 1];
database.DoEscapeString(queryBuffer, (char*)&group_aa[gid], sizeof(GroupLeadershipAA_Struct));
std::string query = "UPDATE raid_leaders SET leadershipaa = '";
query += queryBuffer;
query += StringFormat("' WHERE gid = %lu AND rid = %lu LIMIT 1", gid, GetID());
safe_delete_array(queryBuffer);
auto results = database.QueryDatabase(query);
if (!results.Success())
LogFile->write(EQEMuLog::Error, "Unable to store LeadershipAA: %s\n", results.ErrorMessage().c_str());
}
void Raid::SaveRaidLeaderAA()
{
char *queryBuffer = new char[sizeof(RaidLeadershipAA_Struct) * 2 + 1];
database.DoEscapeString(queryBuffer, (char*)&raid_aa, sizeof(RaidLeadershipAA_Struct));
_hex(NET__ERROR, queryBuffer, sizeof(RaidLeadershipAA_Struct));
std::string query = "UPDATE raid_leaders SET leadershipaa = '";
query += queryBuffer;
query += StringFormat("' WHERE gid = %lu AND rid = %lu LIMIT 1", RAID_GROUPLESS, GetID());
safe_delete_array(queryBuffer);
auto results = database.QueryDatabase(query);
if (!results.Success())
LogFile->write(EQEMuLog::Error, "Unable to store LeadershipAA: %s\n", results.ErrorMessage().c_str());
}
void Raid::UpdateGroupAAs(uint32 gid)
{
Client *gl = GetGroupLeader(gid);
if (gl)
gl->GetGroupAAs(&group_aa[gid]);
else
memset(&group_aa[gid], 0, sizeof(GroupLeadershipAA_Struct));
SaveGroupLeaderAA(gid);
}
void Raid::UpdateRaidAAs()
{
Client *rl = GetLeader();
if (rl)
rl->GetRaidAAs(&raid_aa);
else
memset(&raid_aa, 0, sizeof(RaidLeadershipAA_Struct));
SaveRaidLeaderAA();
}
bool Raid::IsGroupLeader(const char *who)
{
for(int x = 0; x < MAX_RAID_MEMBERS; x++)
@@ -1094,6 +1173,7 @@ void Raid::SendGroupUpdate(Client *to)
strn0cpy(gu->leadersname, to->GetName(), 64);
}
strn0cpy(gu->yourname, to->GetName(), 64);
memcpy(&gu->leader_aas, &group_aa[grp], sizeof(GroupLeadershipAA_Struct));
to->FastQueuePacket(&outapp);
}
@@ -1106,8 +1186,10 @@ void Raid::GroupUpdate(uint32 gid, bool initial)
{
if(strlen(members[x].membername) > 0){
if(members[x].GroupNumber == gid){
if(members[x].member)
if(members[x].member) {
SendGroupUpdate(members[x].member);
SendGroupLeadershipAA(members[x].member, gid);
}
}
}
}
@@ -1244,6 +1326,34 @@ void Raid::SendRaidMOTDToWorld()
safe_delete(pack);
}
void Raid::SendGroupLeadershipAA(Client *c, uint32 gid)
{
EQApplicationPacket *outapp = new EQApplicationPacket(OP_RaidUpdate, sizeof(RaidLeadershipUpdate_Struct));
RaidLeadershipUpdate_Struct *rlaa = (RaidLeadershipUpdate_Struct *)outapp->pBuffer;
rlaa->action = raidSetLeaderAbilities;
strn0cpy(rlaa->leader_name, c->GetName(), 64);
strn0cpy(rlaa->player_name, c->GetName(), 64);
if (gid != RAID_GROUPLESS)
memcpy(&rlaa->group, &group_aa[gid], sizeof(GroupLeadershipAA_Struct));
memcpy(&rlaa->raid, &raid_aa, sizeof(RaidLeadershipAA_Struct));
c->QueuePacket(outapp);
safe_delete(outapp);
}
void Raid::SendGroupLeadershipAA(uint32 gid)
{
for (uint32 i = 0; i < MAX_RAID_MEMBERS; i++)
if (members[i].member && members[i].GroupNumber == gid)
SendGroupLeadershipAA(members[i].member, gid);
}
void Raid::SendAllRaidLeadershipAA()
{
for (uint32 i = 0; i < MAX_RAID_MEMBERS; i++)
if (members[i].member)
SendGroupLeadershipAA(members[i].member, members[i].GroupNumber);
}
void Raid::LockRaid(bool lockFlag)
{
std::string query = StringFormat("UPDATE raid_details SET locked = %d WHERE raidid = %lu",
@@ -1484,3 +1594,11 @@ void Raid::RaidMessage_StringID(Mob* sender, uint32 type, uint32 string_id, cons
}
}
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]);
}
+22 -2
View File
@@ -43,8 +43,8 @@ enum { //raid packet types:
raidChangeLootType = 11,
raidStringID = 12,
raidChangeGroupLeader = 13, //136 raid leader, new group leader, group_id?
raidBecomeGroupLeader = 14, //472
raidUnknown2 = 15,
raidSetLeaderAbilities = 14, //472
raidSetLeaderData = 15, // 14,15 SoE names, not sure on difference, 14 packet has 0x100 bytes 15 0x214 in addition to raid general
raidChangeGroup = 16, //?? len 136 old leader, new leader, 0 (preceeded with a remove2)
raidLock = 17, //len 136 leader?, leader, 0
raidUnlock = 18, //len 136 leader?, leader, 0
@@ -79,6 +79,7 @@ enum { //raid command types
#define MAX_RAID_GROUPS 12
#define MAX_RAID_MEMBERS 72
const uint32 RAID_GROUPLESS = 0xFFFFFFFF;
struct RaidMember{
char membername[64];
@@ -111,6 +112,7 @@ public:
void DisbandRaid();
void MoveMember(const char *name, uint32 newGroup);
void SetGroupLeader(const char *who, bool glFlag = true);
Client *GetGroupLeader(uint32 group_id);
void RemoveGroupLeader(const char *who);
bool IsGroupLeader(const char *who);
bool IsRaidMember(const char *name);
@@ -203,6 +205,22 @@ public:
void QueuePacket(const EQApplicationPacket *app, bool ack_req = true);
// Leadership
void UpdateGroupAAs(uint32 gid);
void SaveGroupLeaderAA(uint32 gid);
void UpdateRaidAAs();
void SaveRaidLeaderAA();
void SendGroupLeadershipAA(Client *c, uint32 gid);
void SendGroupLeadershipAA(uint32 gid);
void SendAllRaidLeadershipAA();
void LoadLeadership();
inline int GetLeadershipAA(int AAID, uint32 gid = 0)
{ if (AAID >= 16) return raid_aa.ranks[AAID - 16]; else return group_aa[gid].ranks[AAID]; }
inline void SetGroupAAs(uint32 gid, GroupLeadershipAA_Struct *glaa)
{ memcpy(&group_aa[gid], glaa, sizeof(GroupLeadershipAA_Struct)); }
inline void SetRaidAAs(RaidLeadershipAA_Struct *rlaa)
{ memcpy(&raid_aa, rlaa, sizeof(RaidLeadershipAA_Struct)); }
RaidMember members[MAX_RAID_MEMBERS];
char leadername[64];
protected:
@@ -213,6 +231,8 @@ protected:
bool disbandCheck;
bool forceDisband;
std::string motd;
RaidLeadershipAA_Struct raid_aa;
GroupLeadershipAA_Struct group_aa[MAX_RAID_GROUPS];
};