eqemu-server/zone/bot_raid.cpp
Aeadoin d6b954a4b9
[Cleanup] Cleaning up Raid.cpp (#3125)
* [Cleanup] Cleanup Raid.cpp

* cleanup

* fix is_bot instances

* bracket cleanup

* bracket cleanup

* rename variables in struct

* fix for merge
2023-03-20 11:39:14 -04:00

273 lines
7.3 KiB
C++

/* EQEMu: Everquest Server Emulator
Copyright (C) 2001-2016 EQEMu Development Team (http://eqemulator.org)
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY except by those people which sell it, which
are required to give you total support for your newly bought product;
without even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "bot.h"
#include "object.h"
#include "raids.h"
#include "doors.h"
#include "quest_parser_collection.h"
#include "../common/data_verification.h"
std::vector<RaidMember> Raid::GetRaidGroupMembers(uint32 gid)
{
std::vector<RaidMember> raid_group_members;
raid_group_members.clear();
for (const auto& m : members)
{
if (m.member && m.group_number == gid)
{
raid_group_members.push_back(m);
}
}
return raid_group_members;
}
// Returns Bot members that are in the raid
// passing in owner will return all Bots that have the same owner.
std::vector<Bot*> Raid::GetRaidBotMembers(uint32 owner)
{
std::vector<Bot*> raid_members_bots;
raid_members_bots.clear();
for (const auto& m : members) {
if (
m.member &&
m.member->IsBot()
) {
auto b_member = m.member->CastToBot();
if (owner && b_member->GetBotOwnerCharacterID() == owner) {
raid_members_bots.emplace_back(b_member);
} else if (!owner) {
raid_members_bots.emplace_back(b_member);
}
}
}
return raid_members_bots;
}
// Returns Bot members that are in the group specified
// passing in owner will return only Bots that have the same owner.
std::vector<Bot*> Raid::GetRaidGroupBotMembers(uint32 gid)
{
std::vector<Bot*> raid_members_bots;
raid_members_bots.clear();
for (const auto& m : members) {
if (
m.member &&
m.member->IsBot() &&
m.group_number == gid
) {
auto b_member = m.member->CastToBot();
raid_members_bots.emplace_back(b_member);
raid_members_bots.emplace_back(b_member);
}
}
return raid_members_bots;
}
void Raid::HandleBotGroupDisband(uint32 owner, uint32 gid)
{
auto raid_members_bots = gid != RAID_GROUPLESS ? GetRaidGroupBotMembers(gid) : GetRaidBotMembers(owner);
// If any of the bots are a group leader then re-create the botgroup on disband, dropping any clients
for (const auto& b: raid_members_bots) {
// Remove the entire BOT group in this case
if (b && gid != RAID_GROUPLESS && IsRaidMember(b->GetName()) && IsGroupLeader(b->GetName())) {
auto r_group_members = GetRaidGroupMembers(GetGroup(b->GetName()));
auto g = new Group(b);
entity_list.AddGroup(g);
database.SetGroupID(b->GetCleanName(), g->GetID(), b->GetBotID());
database.SetGroupLeaderName(g->GetID(), b->GetName());
for (auto m: r_group_members) {
if (m.member->IsBot()) {
auto b_member = m.member->CastToBot();
if (strcmp(b_member->GetName(), b->GetName()) == 0) {
b->SetFollowID(owner);
} else {
Bot::AddBotToGroup(b_member, g);
}
Bot::RemoveBotFromRaid(b_member);
}
}
} else {
Bot::RemoveBotFromRaid(b);
}
}
}
uint8 Bot::GetNumberNeedingHealedInRaidGroup(uint8& need_healed, uint8 hpr, bool includePets, Raid* raid) {
if (raid) {
uint32 r_group = raid->GetGroup(GetName());
for (auto& m: raid->GetRaidGroupMembers(r_group)) {
if (m.member && !m.member->qglobal) {
if (m.member->GetHPRatio() <= hpr) {
need_healed++;
}
if (includePets && m.member->GetPet() && m.member->GetPet()->GetHPRatio() <= hpr) {
need_healed++;
}
}
}
}
return need_healed;
}
void Bot::ProcessRaidInvite(Mob* invitee, Client* invitor, bool group_invite) {
if (!invitee || !invitor) {
return;
}
if (invitee->IsBot() &&
invitor->HasRaid() &&
invitee->GetOwner()->HasRaid() &&
invitor->GetRaid()->IsRaidMember(invitee->GetOwner()->GetName())
) {
// If the Bot Owner is in our raid we need to be able to invite their Bots
}
else if (invitee->IsBot() && (invitee->CastToBot()->GetBotOwnerCharacterID() != invitor->CharacterID())) {
invitor->Message(
Chat::Red,
fmt::format(
"{} is not your Bot. You can only invite your own Bots, or Bots that belong to a Raid member.",
invitee->GetCleanName()
).c_str()
);
return;
}
Raid* raid = entity_list.GetRaidByClient(invitor);
Bot::CreateBotRaid(invitee, invitor, group_invite, raid);
}
void Bot::CreateBotRaid(Mob* invitee, Client* invitor, bool group_invite, Raid* raid) {
Group* g_invitee = invitee->GetGroup();
Group* g_invitor = invitor->GetGroup();
if (g_invitee && invitor->IsClient()) {
if (!g_invitee->IsLeader(invitee)) {
invitor->Message(
Chat::Red,
fmt::format(
"You can only invite group leaders or ungrouped bots. Try {} instead.",
g_invitee->GetLeader()->GetCleanName()
).c_str()
);
return;
}
}
bool new_raid = false;
if (!raid) {
new_raid = true;
raid = new Raid(invitor);
entity_list.AddRaid(raid);
raid->SetRaidDetails();
}
// Add Invitor to new raid
if (new_raid) {
if (g_invitor) {
ProcessBotGroupAdd(g_invitor, raid, nullptr, true, true);
} else {
raid->SendRaidCreate(invitor);
raid->AddMember(invitor, 0xFFFFFFFF, true, false, true);
raid->SendMakeLeaderPacketTo(invitor->GetName(), invitor);
if (raid->IsLocked()) {
raid->SendRaidLockTo(invitor);
}
}
}
// Add Bot Group or Client Bot Group to raid
if (g_invitee) {
ProcessBotGroupAdd(g_invitee, raid);
// Add individual client to raid
} else if (invitee->IsClient()) {
ProcessBotGroupAdd(g_invitee, raid, invitee->CastToClient());
// Add individual bot to raid
} else {
auto gid = raid->GetGroup(invitor->GetName());
auto b = invitee->CastToBot();
// gives us a choice to either invite directly into the clients Raid Group, or just into the Raid
if (group_invite && raid->GroupCount(gid) < MAX_GROUP_MEMBERS) {
raid->AddBot(b, gid);
} else {
raid->AddBot(b);
}
if (new_raid) {
invitee->SetFollowID(invitor->GetID());
}
}
}
void Bot::ProcessBotGroupAdd(Group* group, Raid* raid, Client* client, bool new_raid, bool initial) {
uint32 raid_free_group_id = raid->GetFreeGroup();
if (group) {
for (const auto& m : group->members) {
if (m) {
if (m && m->IsBot()) {
raid->AddBot(m->CastToBot(), raid_free_group_id, false, !raid->GroupCount(raid_free_group_id), false);
} else if (m && m->IsClient()) {
auto c = m->CastToClient();
raid->SendRaidCreate(c);
raid->AddMember(
c,
raid_free_group_id,
new_raid,
!raid->GroupCount(raid_free_group_id),
false
);
raid->SendMakeLeaderPacketTo(raid->leadername, c);
raid->SendBulkRaid(c);
}
}
}
group->JoinRaidXTarget(raid, initial);
group->DisbandGroup(true);
} else if (client) {
raid->SendRaidCreate(client);
raid->AddMember(client, RAID_GROUPLESS, false, false, true);
raid->SendMakeLeaderPacketTo(raid->leadername, client);
raid->SendBulkRaid(client);
if (raid->IsLocked()) {
raid->SendRaidLockTo(client);
}
}
raid->GroupUpdate(raid_free_group_id);
}