This commit is contained in:
neckkola
2022-05-17 22:31:04 -03:00
24 changed files with 3783 additions and 525 deletions
+1 -1
View File
@@ -54,5 +54,5 @@ bin/
/Win32 /Win32
/x64 /x64
/client_files/**/CMakeFiles/ /client_files/**/CMakeFiles/
submodules/libuv
.idea .idea
+15
View File
@@ -0,0 +1,15 @@
{
"configurations": [
{
"name": "x64-Debug",
"generator": "Ninja",
"configurationType": "Debug",
"inheritEnvironments": [ "msvc_x64_x64" ],
"buildRoot": "${projectDir}\\out\\build\\${name}",
"installRoot": "${projectDir}\\out\\install\\${name}",
"cmakeCommandArgs": "",
"buildCommandArgs": "",
"ctestCommandArgs": ""
}
]
}
@@ -28,6 +28,9 @@ public:
int isgroupleader; int isgroupleader;
int israidleader; int israidleader;
int islooter; int islooter;
#ifdef BOTS
int isbot;
#endif
}; };
static std::string PrimaryKey() static std::string PrimaryKey()
@@ -47,6 +50,9 @@ public:
"isgroupleader", "isgroupleader",
"israidleader", "israidleader",
"islooter", "islooter",
#ifdef BOTS
"isbot",
#endif
}; };
} }
@@ -111,6 +117,9 @@ public:
entry.isgroupleader = 0; entry.isgroupleader = 0;
entry.israidleader = 0; entry.israidleader = 0;
entry.islooter = 0; entry.islooter = 0;
#ifdef BOTS
entry.isbot = 0;
#endif
return entry; return entry;
} }
@@ -155,6 +164,9 @@ public:
entry.isgroupleader = atoi(row[6]); entry.isgroupleader = atoi(row[6]);
entry.israidleader = atoi(row[7]); entry.israidleader = atoi(row[7]);
entry.islooter = atoi(row[8]); entry.islooter = atoi(row[8]);
#ifdef BOTS
entry.isbot = atoi(row[9]);
#endif
return entry; return entry;
} }
@@ -197,6 +209,9 @@ public:
update_values.push_back(columns[6] + " = " + std::to_string(raid_members_entry.isgroupleader)); update_values.push_back(columns[6] + " = " + std::to_string(raid_members_entry.isgroupleader));
update_values.push_back(columns[7] + " = " + std::to_string(raid_members_entry.israidleader)); update_values.push_back(columns[7] + " = " + std::to_string(raid_members_entry.israidleader));
update_values.push_back(columns[8] + " = " + std::to_string(raid_members_entry.islooter)); update_values.push_back(columns[8] + " = " + std::to_string(raid_members_entry.islooter));
#ifdef BOTS
update_values.push_back(columns[9] + " = " + std::to_string(raid_members_entry.isbot));
#endif
auto results = db.QueryDatabase( auto results = db.QueryDatabase(
fmt::format( fmt::format(
@@ -227,7 +242,9 @@ public:
insert_values.push_back(std::to_string(raid_members_entry.isgroupleader)); insert_values.push_back(std::to_string(raid_members_entry.isgroupleader));
insert_values.push_back(std::to_string(raid_members_entry.israidleader)); insert_values.push_back(std::to_string(raid_members_entry.israidleader));
insert_values.push_back(std::to_string(raid_members_entry.islooter)); insert_values.push_back(std::to_string(raid_members_entry.islooter));
#ifdef BOTS
insert_values.push_back(std::to_string(raid_members_entry.isbot));
#endif
auto results = db.QueryDatabase( auto results = db.QueryDatabase(
fmt::format( fmt::format(
"{} VALUES ({})", "{} VALUES ({})",
@@ -265,7 +282,9 @@ public:
insert_values.push_back(std::to_string(raid_members_entry.isgroupleader)); insert_values.push_back(std::to_string(raid_members_entry.isgroupleader));
insert_values.push_back(std::to_string(raid_members_entry.israidleader)); insert_values.push_back(std::to_string(raid_members_entry.israidleader));
insert_values.push_back(std::to_string(raid_members_entry.islooter)); insert_values.push_back(std::to_string(raid_members_entry.islooter));
#ifdef BOTS
insert_values.push_back(std::to_string(raid_members_entry.isbot));
#endif
insert_chunks.push_back("(" + implode(",", insert_values) + ")"); insert_chunks.push_back("(" + implode(",", insert_values) + ")");
} }
@@ -307,7 +326,9 @@ public:
entry.isgroupleader = atoi(row[6]); entry.isgroupleader = atoi(row[6]);
entry.israidleader = atoi(row[7]); entry.israidleader = atoi(row[7]);
entry.islooter = atoi(row[8]); entry.islooter = atoi(row[8]);
#ifdef BOTS
entry.isbot = atoi(row[9]);
#endif
all_entries.push_back(entry); all_entries.push_back(entry);
} }
@@ -340,7 +361,9 @@ public:
entry.isgroupleader = atoi(row[6]); entry.isgroupleader = atoi(row[6]);
entry.israidleader = atoi(row[7]); entry.israidleader = atoi(row[7]);
entry.islooter = atoi(row[8]); entry.islooter = atoi(row[8]);
#ifdef BOTS
entry.isbot = atoi(row[9]);
#endif
all_entries.push_back(entry); all_entries.push_back(entry);
} }
+3
View File
@@ -622,10 +622,13 @@ RULE_REAL(Bots, LeashDistance, 562500.0f, "Distance a bot is allowed to travel f
RULE_BOOL(Bots, AllowApplyPoisonCommand, true, "Allows the use of the bot command 'applypoison'") RULE_BOOL(Bots, AllowApplyPoisonCommand, true, "Allows the use of the bot command 'applypoison'")
RULE_BOOL(Bots, AllowApplyPotionCommand, true, "Allows the use of the bot command 'applypotion'") RULE_BOOL(Bots, AllowApplyPotionCommand, true, "Allows the use of the bot command 'applypotion'")
RULE_BOOL(Bots, RestrictApplyPotionToRogue, true, "Restricts the bot command 'applypotion' to rogue-usable potions (i.e., poisons)") RULE_BOOL(Bots, RestrictApplyPotionToRogue, true, "Restricts the bot command 'applypotion' to rogue-usable potions (i.e., poisons)")
RULE_BOOL(Bots, DisplayHealDamage, false, "Enables the display of bot heal damage to the bot owner client")
RULE_BOOL(Bots, DisplaySpellDamage, false, "Enables the display of bot spell damage to the bot owner client")
RULE_BOOL(Bots, OldRaceRezEffects, false, "Older clients had ID 757 for races with high starting STR, but it doesn't seem used anymore") RULE_BOOL(Bots, OldRaceRezEffects, false, "Older clients had ID 757 for races with high starting STR, but it doesn't seem used anymore")
RULE_BOOL(Bots, ResurrectionSickness, true, "Use Resurrection Sickness based on Resurrection spell cast, set to false to disable Resurrection Sickness.") RULE_BOOL(Bots, ResurrectionSickness, true, "Use Resurrection Sickness based on Resurrection spell cast, set to false to disable Resurrection Sickness.")
RULE_INT(Bots, OldResurrectionSicknessSpell, 757, "757 is Default Old Resurrection Sickness Spell") RULE_INT(Bots, OldResurrectionSicknessSpell, 757, "757 is Default Old Resurrection Sickness Spell")
RULE_INT(Bots, ResurrectionSicknessSpell, 756, "756 is Default Resurrection Sickness Spell") RULE_INT(Bots, ResurrectionSicknessSpell, 756, "756 is Default Resurrection Sickness Spell")
RULE_CATEGORY_END() RULE_CATEGORY_END()
#endif #endif
+3
View File
@@ -57,6 +57,9 @@ typedef const char Const_char; //for perl XS
#define safe_delete(d) if(d) { delete d; d=nullptr; } #define safe_delete(d) if(d) { delete d; d=nullptr; }
#define safe_delete_array(d) if(d) { delete[] d; d=nullptr; } #define safe_delete_array(d) if(d) { delete[] d; d=nullptr; }
//#define safe_delete(d)(_RPTF0(_CRT_WARN,"Testing delete function\n"));
//#define safe_delete(d) if(d) { }
//#define safe_delete_array(d) if(d) { }
#define L32(i) ((uint32) i) #define L32(i) ((uint32) i)
#define H32(i) ((uint32) (i >> 32)) #define H32(i) ((uint32) (i >> 32))
#define L16(i) ((uint16) i) #define L16(i) ((uint16) i)
@@ -27,6 +27,7 @@
9026|2019_09_09_bots_owner_options_rework.sql|SHOW COLUMNS FROM `bot_owner_options` LIKE 'option_type'|empty| 9026|2019_09_09_bots_owner_options_rework.sql|SHOW COLUMNS FROM `bot_owner_options` LIKE 'option_type'|empty|
9027|2020_03_30_bots_view_update.sql|SELECT * FROM db_version WHERE bots_version >= 9027|empty| 9027|2020_03_30_bots_view_update.sql|SELECT * FROM db_version WHERE bots_version >= 9027|empty|
9028|2021_06_04_bot_create_combinations.sql|SHOW TABLES LIKE 'bot_create_combinations'|empty| 9028|2021_06_04_bot_create_combinations.sql|SHOW TABLES LIKE 'bot_create_combinations'|empty|
9029|2022_02_08_bots_raid_members.sql|SELECT * FROM db_version WHERE bots_version >= 9028|empty|
# Upgrade conditions: # Upgrade conditions:
# This won't be needed after this system is implemented, but it is used database that are not # This won't be needed after this system is implemented, but it is used database that are not
@@ -0,0 +1 @@
ALTER TABLE `raid_members` ADD COLUMN `isbot` TINYINT(1) NOT NULL DEFAULT 0 COMMENT '';
+1
View File
@@ -11,6 +11,7 @@ SET(zone_sources
beacon.cpp beacon.cpp
bonuses.cpp bonuses.cpp
bot.cpp bot.cpp
bot_raid.cpp
bot_command.cpp bot_command.cpp
bot_database.cpp bot_database.cpp
botspellsai.cpp botspellsai.cpp
+17 -2
View File
@@ -35,6 +35,7 @@
#include "../common/global_define.h" #include "../common/global_define.h"
#include "guild_mgr.h" #include "guild_mgr.h"
#include "worldserver.h" #include "worldserver.h"
#include "raids.h"
#include <sstream> #include <sstream>
@@ -151,8 +152,8 @@ public:
ExtraAttackOptions *opts = nullptr); ExtraAttackOptions *opts = nullptr);
virtual bool HasRaid() { return (GetRaid() ? true : false); } virtual bool HasRaid() { return (GetRaid() ? true : false); }
virtual bool HasGroup() { return (GetGroup() ? true : false); } virtual bool HasGroup() { return (GetGroup() ? true : false); }
virtual Raid* GetRaid() { return entity_list.GetRaidByMob(this); } virtual Raid* GetRaid() { return entity_list.GetRaidByMob(this); } // GetRaidByMob(this);
virtual Group* GetGroup() { return entity_list.GetGroupByMob(this); } virtual Group* GetGroup() { return entity_list.GetGroupByMob(this); } // GetGroupByMob;
// Common, but informal "interfaces" with Client object // Common, but informal "interfaces" with Client object
uint32 CharacterID() { return GetBotID(); } // Just returns the Bot Id uint32 CharacterID() { return GetBotID(); } // Just returns the Bot Id
@@ -375,6 +376,15 @@ public:
static bool CheckDisciplineRecastTimers(Bot *caster, int timer_index); static bool CheckDisciplineRecastTimers(Bot *caster, int timer_index);
static uint32 GetDisciplineRemainingTime(Bot *caster, int timer_index); static uint32 GetDisciplineRemainingTime(Bot *caster, int timer_index);
//Raid methods
void PetAIProcess_Raid();
void AI_Process_Raid();
bool AICastSpell_Raid(Mob* tar, uint8 iChance, uint32 iSpellTypes);
static void ProcessRaidInvite(Bot* invitee, Client* invitor);
static void ProcessRaidInvite(Client* invitee, Client* invitor);
uint8 GetNumberNeedingHealedInRaidGroup(uint8 hpr, bool includePets);
inline void SetDirtyAutoHaters() { m_dirtyautohaters = true; }
static std::list<BotSpell> GetBotSpellsForSpellEffect(Bot* botCaster, int spellEffect); static std::list<BotSpell> GetBotSpellsForSpellEffect(Bot* botCaster, int spellEffect);
static std::list<BotSpell> GetBotSpellsForSpellEffectAndTargetType(Bot* botCaster, int spellEffect, SpellTargetType targetType); static std::list<BotSpell> GetBotSpellsForSpellEffectAndTargetType(Bot* botCaster, int spellEffect, SpellTargetType targetType);
static std::list<BotSpell> GetBotSpellsBySpellType(Bot* botCaster, uint32 spellType); static std::list<BotSpell> GetBotSpellsBySpellType(Bot* botCaster, uint32 spellType);
@@ -610,6 +620,9 @@ public:
int32 GetBaseDR() { return _baseDR; } int32 GetBaseDR() { return _baseDR; }
int32 GetBaseCorrup() { return _baseCorrup; } int32 GetBaseCorrup() { return _baseCorrup; }
//Raid additions
Raid* p_raid_instance;
protected: protected:
virtual void PetAIProcess(); virtual void PetAIProcess();
virtual void BotMeditate(bool isSitting); virtual void BotMeditate(bool isSitting);
@@ -674,6 +687,7 @@ private:
Timer m_auto_defend_timer; Timer m_auto_defend_timer;
//Timer m_combat_jitter_timer; //Timer m_combat_jitter_timer;
//bool m_combat_jitter_flag; //bool m_combat_jitter_flag;
bool m_dirtyautohaters;
bool m_guard_flag; bool m_guard_flag;
bool m_hold_flag; bool m_hold_flag;
bool m_attack_flag; bool m_attack_flag;
@@ -740,6 +754,7 @@ private:
public: public:
static uint8 spell_casting_chances[SPELL_TYPE_COUNT][PLAYER_CLASS_COUNT][EQ::constants::STANCE_TYPE_COUNT][cntHSND]; static uint8 spell_casting_chances[SPELL_TYPE_COUNT][PLAYER_CLASS_COUNT][EQ::constants::STANCE_TYPE_COUNT][cntHSND];
}; };
#endif // BOTS #endif // BOTS
+2630
View File
File diff suppressed because it is too large Load Diff
+47
View File
@@ -0,0 +1,47 @@
/* 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
*/
#ifndef BOT_RAID_H
#define BOT_RAID_H
#ifdef BOTS
#include "bot_structs.h"
#include "mob.h"
#include "client.h"
#include "pets.h"
#include "heal_rotation.h"
#include "groups.h"
#include "corpse.h"
#include "zonedb.h"
#include "zone_store.h"
#include "string_ids.h"
#include "../common/misc_functions.h"
#include "../common/global_define.h"
#include "guild_mgr.h"
#include "worldserver.h"
#include <sstream>
extern WorldServer worldserver;
//void Bot::PetAIProcess_Raid();
#endif // BOTS
#endif // BOT_RAID_H
+8 -1
View File
@@ -3,7 +3,7 @@
This program is free software; you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License. the Free Software Foundation; version 2 ogroupf the License.
This program is distributed in the hope that it will be useful, This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY except by those people which sell it, which but WITHOUT ANY WARRANTY except by those people which sell it, which
@@ -31,6 +31,13 @@
bool Bot::AICastSpell(Mob* tar, uint8 iChance, uint32 iSpellTypes) { bool Bot::AICastSpell(Mob* tar, uint8 iChance, uint32 iSpellTypes) {
// Bot AI
Raid* raid = entity_list.GetRaidByBotName(this->GetName());
if (raid) {
return AICastSpell_Raid(tar, iChance, iSpellTypes);
//return true;
}
if (!tar) { if (!tar) {
return false; return false;
} }
+3 -2
View File
@@ -807,9 +807,10 @@ void Client::QueuePacket(const EQApplicationPacket* app, bool ack_req, CLIENT_CO
// todo: save packets for later use // todo: save packets for later use
AddPacket(app, ack_req); AddPacket(app, ack_req);
} }
else else if (eqs)
if(eqs) {
eqs->QueuePacket(app, ack_req); eqs->QueuePacket(app, ack_req);
}
} }
void Client::FastQueuePacket(EQApplicationPacket** app, bool ack_req, CLIENT_CONN_STATUS required_state) { void Client::FastQueuePacket(EQApplicationPacket** app, bool ack_req, CLIENT_CONN_STATUS required_state) {
+255 -45
View File
@@ -25,6 +25,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#include <zlib.h> #include <zlib.h>
#include "bot.h"
#ifdef _WINDOWS #ifdef _WINDOWS
#define snprintf _snprintf #define snprintf _snprintf
@@ -72,6 +73,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#ifdef BOTS #ifdef BOTS
#include "bot.h" #include "bot.h"
#include "bot_command.h"
#endif #endif
extern QueryServ* QServ; extern QueryServ* QServ;
@@ -588,6 +590,31 @@ void Client::CompleteConnect()
if (raid) { if (raid) {
SetRaidGrouped(true); SetRaidGrouped(true);
raid->LearnMembers(); raid->LearnMembers();
#ifdef BOTS
std::list<BotsAvailableList> bots_list;
database.botdb.LoadBotsList(this->CharacterID(), bots_list);
std::vector<RaidMember> r_members = raid->GetMembers();
for (const RaidMember& iter : r_members) {
if (iter.membername) {
for (const BotsAvailableList& b_iter : bots_list)
{
if (strcmp(iter.membername, b_iter.Name) == 0)
{
char buffer[71] = "^spawn ";
strcat(buffer, iter.membername);
bot_command_real_dispatch(this, buffer);
Bot* b = entity_list.GetBotByBotName(iter.membername);
if (b)
{
b->SetRaidGrouped(true);
b->p_raid_instance = raid;
//b->SetFollowID(this->GetID());
}
}
}
}
}
#endif
raid->VerifyRaid(); raid->VerifyRaid();
raid->GetRaidDetails(); raid->GetRaidDetails();
/* /*
@@ -6966,6 +6993,11 @@ void Client::Handle_OP_GroupInvite2(const EQApplicationPacket *app)
} }
#ifdef BOTS #ifdef BOTS
else if (Invitee->IsBot()) { else if (Invitee->IsBot()) {
Client* inviter = entity_list.GetClientByName(gis->inviter_name);
//Bot* invitee = entity_list.GetBotByBotName(gis->invitee_name);
if (inviter->IsRaidGrouped())
Bot::ProcessRaidInvite(Invitee->CastToBot(), inviter);
else
Bot::ProcessBotGroupInvite(this, std::string(Invitee->GetName())); Bot::ProcessBotGroupInvite(this, std::string(Invitee->GetName()));
} }
#endif #endif
@@ -11405,7 +11437,7 @@ void Client::Handle_OP_QueryUCSServerStatus(const EQApplicationPacket *app)
} }
} }
void Client::Handle_OP_RaidCommand(const EQApplicationPacket *app) void Client::Handle_OP_RaidCommand(const EQApplicationPacket* app)
{ {
if (app->size < sizeof(RaidGeneral_Struct)) { if (app->size < sizeof(RaidGeneral_Struct)) {
LogError("Wrong size: OP_RaidCommand, size=[{}], expected at least [{}]", app->size, sizeof(RaidGeneral_Struct)); LogError("Wrong size: OP_RaidCommand, size=[{}], expected at least [{}]", app->size, sizeof(RaidGeneral_Struct));
@@ -11413,18 +11445,57 @@ void Client::Handle_OP_RaidCommand(const EQApplicationPacket *app)
return; return;
} }
RaidGeneral_Struct *raid_command_packet = (RaidGeneral_Struct*)app->pBuffer; RaidGeneral_Struct* raid_command_packet = (RaidGeneral_Struct*)app->pBuffer;
switch (raid_command_packet->action) switch (raid_command_packet->action)
{ {
case RaidCommandInviteIntoExisting: case RaidCommandInviteIntoExisting:
case RaidCommandInvite: { case RaidCommandInvite: {
Client *player_to_invite = entity_list.GetClientByName(raid_command_packet->player_name); #ifdef BOTS
Bot* player_to_invite = nullptr;
Client* player_to_invite_owner = nullptr;
if (entity_list.GetBotByBotName(raid_command_packet->player_name)) {
Bot* player_to_invite = entity_list.GetBotByBotName(raid_command_packet->player_name);
Client* player_to_invite_owner = player_to_invite->GetOwner()->CastToClient();
Group* player_to_invite_group = player_to_invite->GetGroup();
if (!player_to_invite) {
break;
}
//Not allowed: Invite a bot that is already within a raid.
if (player_to_invite->IsRaidGrouped()) {
MessageString(Chat::White, ALREADY_IN_RAID, GetName()); //must invite members not in raid...
return;
}
// Not allowed: Invite a bot that is not owned by the invitor
if (player_to_invite->IsBot() &&
player_to_invite->CastToBot()->GetOwner()->CastToClient()->CharacterID() !=
player_to_invite_owner->CharacterID()) {
Message(Chat::Red, "%s is not your Bot. You can only invite your Bots, or players grouped with bots.", player_to_invite->GetName());
}
// Not allowed: Invite a bot that is in a group but the bot is not the group leader
if (player_to_invite_group && !player_to_invite_group->IsLeader(player_to_invite->CastToMob())) {
Message(Chat::Red, "You can only invite group leaders or ungrouped bots. Try %s instead.", player_to_invite_group->GetLeader()->GetName());
break;
}
Bot::ProcessRaidInvite(player_to_invite, player_to_invite_owner);
break;
}
else
{
#endif
Client* player_to_invite = entity_list.GetClientByName(raid_command_packet->player_name);
if (!player_to_invite) if (!player_to_invite)
break; break;
Group *player_to_invite_group = player_to_invite->GetGroup(); Group* player_to_invite_group = player_to_invite->GetGroup();
if (player_to_invite->HasRaid()) { if (player_to_invite->HasRaid()) {
Message(Chat::Red, "%s is already in a raid.", player_to_invite->GetName()); Message(Chat::Red, "%s is already in a raid.", player_to_invite->GetName());
@@ -11435,7 +11506,7 @@ void Client::Handle_OP_RaidCommand(const EQApplicationPacket *app)
MessageString(Chat::Red, ALREADY_IN_PARTY); MessageString(Chat::Red, ALREADY_IN_PARTY);
break; break;
} }
// Not allowed: Invite a client that is in a group but not the groupleader
if (player_to_invite_group && !player_to_invite_group->IsLeader(player_to_invite)) { if (player_to_invite_group && !player_to_invite_group->IsLeader(player_to_invite)) {
Message(Chat::Red, "You can only invite an ungrouped player or group leader to join your raid."); Message(Chat::Red, "You can only invite an ungrouped player or group leader to join your raid.");
break; break;
@@ -11443,7 +11514,7 @@ void Client::Handle_OP_RaidCommand(const EQApplicationPacket *app)
/* Send out invite to the client */ /* Send out invite to the client */
auto outapp = new EQApplicationPacket(OP_RaidUpdate, sizeof(RaidGeneral_Struct)); auto outapp = new EQApplicationPacket(OP_RaidUpdate, sizeof(RaidGeneral_Struct));
RaidGeneral_Struct *raid_command = (RaidGeneral_Struct*)outapp->pBuffer; RaidGeneral_Struct* raid_command = (RaidGeneral_Struct*)outapp->pBuffer;
strn0cpy(raid_command->leader_name, raid_command_packet->leader_name, 64); strn0cpy(raid_command->leader_name, raid_command_packet->leader_name, 64);
strn0cpy(raid_command->player_name, raid_command_packet->player_name, 64); strn0cpy(raid_command->player_name, raid_command_packet->player_name, 64);
@@ -11457,17 +11528,73 @@ void Client::Handle_OP_RaidCommand(const EQApplicationPacket *app)
break; break;
} }
#ifdef BOTS
}
#endif
case RaidCommandAcceptInvite: { case RaidCommandAcceptInvite: {
Client *player_accepting_invite = entity_list.GetClientByName(raid_command_packet->player_name); Client* player_accepting_invite = entity_list.GetClientByName(raid_command_packet->player_name);
#ifdef BOTS
// If the accepting client is in a group with a Bot or the invitor is in a group with a Bot, send the invite to Bot:ProcessRaidInvite
// instead of remaining here.
Bot* b = nullptr;
Client* invitee = entity_list.GetClientByName(raid_command_packet->leader_name);
Client* invitor = entity_list.GetClientByName(raid_command_packet->player_name);
Group* g_invitee = invitee->GetGroup();
Group* g_invitor = invitor->GetGroup();
if (invitee && invitee->IsRaidGrouped()) {
invitor->MessageString(Chat::White, ALREADY_IN_RAID, GetName()); //group failed, must invite members not in raid...
return;
}
bool invitor_has_bot = false;
bool invitee_has_bot = false;
if (g_invitor && g_invitor->IsLeader(invitor))
{
for (int x = 0; x < 6; x++)
{
if (g_invitor->members[x] && g_invitor->members[x]->IsBot())
{
b = entity_list.GetBotByBotName(g_invitor->members[x]->GetName());
invitee_has_bot = true;
}
}
}
if (g_invitee && g_invitee->IsLeader(invitee))
{
for (int x = 0; x < 6; x++)
{
if (g_invitee->members[x] && g_invitee->members[x]->IsBot())
{
b = entity_list.GetBotByBotName(g_invitee->members[x]->GetName());
invitee_has_bot = true;
break;
}
}
}
if (invitor_has_bot || invitee_has_bot) {
Bot::ProcessRaidInvite(invitee, invitor); //two clients with one or both having groups with bots
break;
}
else if (invitee && invitee->IsBot())
{
Bot::ProcessRaidInvite(b, player_accepting_invite); //client inviting a bot
break;
}
#endif
if (player_accepting_invite) { if (player_accepting_invite) {
if (IsRaidGrouped()) { if (IsRaidGrouped()) {
player_accepting_invite->MessageString(Chat::White, ALREADY_IN_RAID, GetName()); //group failed, must invite members not in raid... player_accepting_invite->MessageString(Chat::White, ALREADY_IN_RAID, GetName()); //group failed, must invite members not in raid...
return; return;
} }
Raid *raid = entity_list.GetRaidByClient(player_accepting_invite); Raid* raid = entity_list.GetRaidByClient(player_accepting_invite);
if (raid) { if (raid) {
raid->VerifyRaid(); raid->VerifyRaid();
Group *group = GetGroup(); Group* group = GetGroup();
if (group) { if (group) {
if (group->GroupCount() + raid->RaidCount() > MAX_RAID_MEMBERS) { if (group->GroupCount() + raid->RaidCount() > MAX_RAID_MEMBERS) {
player_accepting_invite->Message(Chat::Red, "Invite failed, group invite would create a raid larger than the maximum number of members allowed."); player_accepting_invite->Message(Chat::Red, "Invite failed, group invite would create a raid larger than the maximum number of members allowed.");
@@ -11482,10 +11609,10 @@ void Client::Handle_OP_RaidCommand(const EQApplicationPacket *app)
} }
if (group) {//add us all if (group) {//add us all
uint32 free_group_id = raid->GetFreeGroup(); uint32 free_group_id = raid->GetFreeGroup();
Client *addClient = nullptr; Client* addClient = nullptr;
for (int x = 0; x < 6; x++) { for (int x = 0; x < 6; x++) {
if (group->members[x]) { if (group->members[x]) {
Client *c = nullptr; Client* c = nullptr;
if (group->members[x]->IsClient()) if (group->members[x]->IsClient())
c = group->members[x]->CastToClient(); c = group->members[x]->CastToClient();
else else
@@ -11525,8 +11652,8 @@ void Client::Handle_OP_RaidCommand(const EQApplicationPacket *app)
} }
else else
{ {
Group *player_invited_group = player_accepting_invite->GetGroup(); Group* player_invited_group = player_accepting_invite->GetGroup();
Group *group = GetGroup(); Group* group = GetGroup();
if (group) //if our target has a group if (group) //if our target has a group
{ {
raid = new Raid(player_accepting_invite); raid = new Raid(player_accepting_invite);
@@ -11537,7 +11664,7 @@ void Client::Handle_OP_RaidCommand(const EQApplicationPacket *app)
/* If we already have a group then cycle through adding us... */ /* If we already have a group then cycle through adding us... */
if (player_invited_group) { if (player_invited_group) {
Client *client_to_be_leader = nullptr; Client* client_to_be_leader = nullptr;
for (int x = 0; x < 6; x++) { for (int x = 0; x < 6; x++) {
if (player_invited_group->members[x]) { if (player_invited_group->members[x]) {
if (!client_to_be_leader) { if (!client_to_be_leader) {
@@ -11547,7 +11674,7 @@ void Client::Handle_OP_RaidCommand(const EQApplicationPacket *app)
} }
} }
if (player_invited_group->IsLeader(player_invited_group->members[x])) { if (player_invited_group->IsLeader(player_invited_group->members[x])) {
Client *c = nullptr; Client* c = nullptr;
if (player_invited_group->members[x]->IsClient()) if (player_invited_group->members[x]->IsClient())
c = player_invited_group->members[x]->CastToClient(); c = player_invited_group->members[x]->CastToClient();
@@ -11564,7 +11691,7 @@ void Client::Handle_OP_RaidCommand(const EQApplicationPacket *app)
} }
} }
else { else {
Client *c = nullptr; Client* c = nullptr;
if (player_invited_group->members[x]->IsClient()) if (player_invited_group->members[x]->IsClient())
c = player_invited_group->members[x]->CastToClient(); c = player_invited_group->members[x]->CastToClient();
@@ -11592,7 +11719,7 @@ void Client::Handle_OP_RaidCommand(const EQApplicationPacket *app)
raid->AddMember(player_accepting_invite, 0xFFFFFFFF, true, false, true); raid->AddMember(player_accepting_invite, 0xFFFFFFFF, true, false, true);
} }
Client *client_to_add = nullptr; Client* client_to_add = nullptr;
/* Add client to an existing group */ /* Add client to an existing group */
for (int x = 0; x < 6; x++) { for (int x = 0; x < 6; x++) {
if (group->members[x]) { if (group->members[x]) {
@@ -11603,7 +11730,7 @@ void Client::Handle_OP_RaidCommand(const EQApplicationPacket *app)
} }
} }
if (group->IsLeader(group->members[x])) { if (group->IsLeader(group->members[x])) {
Client *c = nullptr; Client* c = nullptr;
if (group->members[x]->IsClient()) if (group->members[x]->IsClient())
c = group->members[x]->CastToClient(); c = group->members[x]->CastToClient();
@@ -11621,7 +11748,7 @@ void Client::Handle_OP_RaidCommand(const EQApplicationPacket *app)
} }
else else
{ {
Client *c = nullptr; Client* c = nullptr;
if (group->members[x]->IsClient()) if (group->members[x]->IsClient())
c = group->members[x]->CastToClient(); c = group->members[x]->CastToClient();
@@ -11652,7 +11779,7 @@ void Client::Handle_OP_RaidCommand(const EQApplicationPacket *app)
entity_list.AddRaid(raid); entity_list.AddRaid(raid);
raid->SetRaidDetails(); raid->SetRaidDetails();
Client *addClientig = nullptr; Client* addClientig = nullptr;
for (int x = 0; x < 6; x++) { for (int x = 0; x < 6; x++) {
if (player_invited_group->members[x]) { if (player_invited_group->members[x]) {
if (!addClientig) { if (!addClientig) {
@@ -11662,7 +11789,7 @@ void Client::Handle_OP_RaidCommand(const EQApplicationPacket *app)
} }
} }
if (player_invited_group->IsLeader(player_invited_group->members[x])) { if (player_invited_group->IsLeader(player_invited_group->members[x])) {
Client *c = nullptr; Client* c = nullptr;
if (player_invited_group->members[x]->IsClient()) if (player_invited_group->members[x]->IsClient())
c = player_invited_group->members[x]->CastToClient(); c = player_invited_group->members[x]->CastToClient();
@@ -11680,7 +11807,7 @@ void Client::Handle_OP_RaidCommand(const EQApplicationPacket *app)
} }
else else
{ {
Client *c = nullptr; Client* c = nullptr;
if (player_invited_group->members[x]->IsClient()) if (player_invited_group->members[x]->IsClient())
c = player_invited_group->members[x]->CastToClient(); c = player_invited_group->members[x]->CastToClient();
else else
@@ -11727,10 +11854,91 @@ void Client::Handle_OP_RaidCommand(const EQApplicationPacket *app)
break; break;
} }
case RaidCommandDisband: { case RaidCommandDisband: {
Raid *raid = entity_list.GetRaidByClient(this); Raid* raid = entity_list.GetRaidByClient(this);
Client* c_to_disband = entity_list.GetClientByName(raid_command_packet->leader_name);
Client* c_doing_disband = entity_list.GetClientByName(raid_command_packet->player_name);
#ifdef BOTS
Bot* b_to_disband = entity_list.GetBotByBotName(raid_command_packet->leader_name);
#endif
if (raid) { if (raid) {
uint32 group = raid->GetGroup(raid_command_packet->leader_name); uint32 group = raid->GetGroup(raid_command_packet->leader_name);
#ifdef BOTS
//Added to remove all bots if the Bot_Owner is removed from the Raid
//Does not camp the Bots, just removes from the raid
std::vector<Bot*> raid_members_bots;
if (c_to_disband)
{
// Determine if the client has any BOTS in the raid
uint32 owner_id = c_to_disband->CharacterID();
for (int i = 0; i < MAX_RAID_MEMBERS; ++i)
{
if (raid->members[i].member && raid->members[i].member->IsBot() && raid->members[i].member->CastToBot()->GetOwner()->CastToClient()->CharacterID() == owner_id)
{
raid_members_bots.emplace_back(raid->members[i].member->CastToBot());
}
}
// If any of the bots are a group leader then re-create the botgroup on disband, dropping any clients
for (auto bot_iter : raid_members_bots) {
if (bot_iter && raid->IsRaidMember(bot_iter->GetName()) && raid->IsGroupLeader(bot_iter->GetName()))
{
// Remove the entire BOT group in this case
uint32 gid = raid->GetGroup(bot_iter->GetName());
std::vector<RaidMember> r_group_members = raid->GetRaidGroupMembers(gid);
Group* group_inst = new Group(bot_iter);
entity_list.AddGroup(group_inst);
database.SetGroupID(bot_iter->GetCleanName(), group_inst->GetID(), bot_iter->GetBotID());
database.SetGroupLeaderName(group_inst->GetID(), bot_iter->GetCleanName());
for (auto member_iter : r_group_members) {
if (!member_iter.member->IsClient() && strcmp(member_iter.membername, bot_iter->GetName()) == 0)
bot_iter->SetFollowID(owner_id);
else
Bot::AddBotToGroup(member_iter.member->CastToBot(), group_inst);
raid->RemoveMember(bot_iter->GetName());
}
}
else if (bot_iter && raid->IsRaidMember(bot_iter->GetName()))
{
raid->RemoveMember(bot_iter->GetName());
}
}
}
else if (b_to_disband)
{
uint32 gid = raid->GetGroup(b_to_disband->GetName());
if (gid < 12 && raid->IsGroupLeader(b_to_disband->GetName()))
{
// If any of the bots are a group leader then re-create the botgroup on disband, dropping any clients
std::vector<RaidMember> r_group_members = raid->GetRaidGroupMembers(gid);
uint32 owner_id = b_to_disband->CastToBot()->GetOwner()->CastToClient()->CharacterID();
if (raid->IsGroupLeader(b_to_disband->GetName()))
{
// Remove the entire BOT group in this case
Group* group_inst = new Group(b_to_disband);
entity_list.AddGroup(group_inst);
database.SetGroupID(b_to_disband->GetCleanName(), group_inst->GetID(), b_to_disband->GetBotID());
database.SetGroupLeaderName(group_inst->GetID(), b_to_disband->GetCleanName());
for (auto member_iter : r_group_members) {
if (!member_iter.member->IsClient() && strcmp(member_iter.membername, b_to_disband->GetName()) == 0)
b_to_disband->SetFollowID(owner_id);
else
Bot::AddBotToGroup(member_iter.member->CastToBot(), group_inst);
raid->RemoveMember(member_iter.member->CastToBot()->GetName());
}
}
break;
}
else if (gid <12 && raid->GetGroupLeader(gid)->IsBot())
{
c_doing_disband->Message(Chat::Yellow, "%s is in a Bot Group. Please disband %s instead to remove the entire Bot group.",
raid_command_packet->leader_name, raid->GetGroupLeader(gid)->CastToBot()->GetName());
break;
}
}
#endif
if (group < 12) { if (group < 12) {
uint32 i = raid->GetPlayerIndex(raid_command_packet->leader_name); uint32 i = raid->GetPlayerIndex(raid_command_packet->leader_name);
if (raid->members[i].IsGroupLeader) { //assign group leader to someone else if (raid->members[i].IsGroupLeader) { //assign group leader to someone else
@@ -11758,11 +11966,12 @@ void Client::Handle_OP_RaidCommand(const EQApplicationPacket *app)
} }
} }
} }
raid->RemoveMember(raid_command_packet->leader_name); raid->RemoveMember(raid_command_packet->leader_name);
Client *c = entity_list.GetClientByName(raid_command_packet->leader_name); Client* c = entity_list.GetClientByName(raid_command_packet->leader_name);
if (c) if (c) {
raid->SendGroupDisband(c); raid->SendGroupDisband(c);
}
else { else {
auto pack = auto pack =
new ServerPacket(ServerOP_RaidGroupDisband, sizeof(ServerRaidGeneralAction_Struct)); new ServerPacket(ServerOP_RaidGroupDisband, sizeof(ServerRaidGeneralAction_Struct));
@@ -11776,20 +11985,21 @@ void Client::Handle_OP_RaidCommand(const EQApplicationPacket *app)
} }
//r->SendRaidGroupRemove(ri->leader_name, grp); //r->SendRaidGroupRemove(ri->leader_name, grp);
raid->GroupUpdate(group);// break raid->GroupUpdate(group);// break
//} if (!raid->RaidCount())
raid->DisbandRaid();
} }
break; break;
} }
case RaidCommandMoveGroup: case RaidCommandMoveGroup:
{ {
Raid *raid = entity_list.GetRaidByClient(this); Raid* raid = entity_list.GetRaidByClient(this);
if (raid) { if (raid) {
/* Moving to group */ /* Moving to group */
if (raid_command_packet->parameter < 12) { if (raid_command_packet->parameter < 12) {
uint8 group_count = raid->GroupCount(raid_command_packet->parameter); uint8 group_count = raid->GroupCount(raid_command_packet->parameter);
if (group_count < 6) { if (group_count < 6) {
Client *c = entity_list.GetClientByName(raid_command_packet->leader_name); Client* c = entity_list.GetClientByName(raid_command_packet->leader_name);
uint32 old_group = raid->GetGroup(raid_command_packet->leader_name); uint32 old_group = raid->GetGroup(raid_command_packet->leader_name);
if (raid_command_packet->parameter == old_group) //don't rejoin grp if we order to join same group. if (raid_command_packet->parameter == old_group) //don't rejoin grp if we order to join same group.
break; break;
@@ -11806,7 +12016,7 @@ void Client::Handle_OP_RaidCommand(const EQApplicationPacket *app)
raid->SetGroupLeader(raid->members[x].membername); raid->SetGroupLeader(raid->members[x].membername);
raid->UpdateGroupAAs(old_group); raid->UpdateGroupAAs(old_group);
Client *client_to_update = entity_list.GetClientByName(raid->members[x].membername); Client* client_to_update = entity_list.GetClientByName(raid->members[x].membername);
if (client_to_update) { if (client_to_update) {
raid->SendRaidRemove(raid->members[x].membername, client_to_update); raid->SendRaidRemove(raid->members[x].membername, client_to_update);
raid->SendRaidCreate(client_to_update); raid->SendRaidCreate(client_to_update);
@@ -11819,7 +12029,7 @@ void Client::Handle_OP_RaidCommand(const EQApplicationPacket *app)
} }
else { else {
auto pack = new ServerPacket(ServerOP_RaidChangeGroup, sizeof(ServerRaidGeneralAction_Struct)); auto pack = new ServerPacket(ServerOP_RaidChangeGroup, sizeof(ServerRaidGeneralAction_Struct));
ServerRaidGeneralAction_Struct *raid_command_packet = (ServerRaidGeneralAction_Struct*)pack->pBuffer; ServerRaidGeneralAction_Struct* raid_command_packet = (ServerRaidGeneralAction_Struct*)pack->pBuffer;
raid_command_packet->rid = raid->GetID(); raid_command_packet->rid = raid->GetID();
raid_command_packet->zoneid = zone->GetZoneID(); raid_command_packet->zoneid = zone->GetZoneID();
@@ -11867,17 +12077,17 @@ void Client::Handle_OP_RaidCommand(const EQApplicationPacket *app)
} }
/* Move player to ungrouped bank */ /* Move player to ungrouped bank */
else { else {
Client *c = entity_list.GetClientByName(raid_command_packet->leader_name); Client* c = entity_list.GetClientByName(raid_command_packet->leader_name);
uint32 oldgrp = raid->GetGroup(raid_command_packet->leader_name); uint32 oldgrp = raid->GetGroup(raid_command_packet->leader_name);
if (raid->members[raid->GetPlayerIndex(raid_command_packet->leader_name)].IsGroupLeader) { if (raid->members[raid->GetPlayerIndex(raid_command_packet->leader_name)].IsGroupLeader) {
raid->SetGroupLeader(raid_command_packet->leader_name, false); raid->SetGroupLeader(raid_command_packet->leader_name, false);
for (int x = 0; x < MAX_RAID_MEMBERS; x++) { for (int x = 0; x < MAX_RAID_MEMBERS; x++) {
if (raid->members[x].GroupNumber == oldgrp && strlen(raid->members[x].membername) > 0 && strcmp(raid->members[x].membername, raid_command_packet->leader_name) != 0){ if (raid->members[x].GroupNumber == oldgrp && strlen(raid->members[x].membername) > 0 && strcmp(raid->members[x].membername, raid_command_packet->leader_name) != 0) {
raid->SetGroupLeader(raid->members[x].membername); raid->SetGroupLeader(raid->members[x].membername);
raid->UpdateGroupAAs(oldgrp); raid->UpdateGroupAAs(oldgrp);
Client *client_leaving_group = entity_list.GetClientByName(raid->members[x].membername); Client* client_leaving_group = entity_list.GetClientByName(raid->members[x].membername);
if (client_leaving_group) { if (client_leaving_group) {
raid->SendRaidRemove(raid->members[x].membername, client_leaving_group); raid->SendRaidRemove(raid->members[x].membername, client_leaving_group);
raid->SendRaidCreate(client_leaving_group); raid->SendRaidCreate(client_leaving_group);
@@ -11889,8 +12099,8 @@ void Client::Handle_OP_RaidCommand(const EQApplicationPacket *app)
} }
} }
else { else {
auto pack = new ServerPacket( ServerOP_RaidChangeGroup, sizeof(ServerRaidGeneralAction_Struct)); auto pack = new ServerPacket(ServerOP_RaidChangeGroup, sizeof(ServerRaidGeneralAction_Struct));
ServerRaidGeneralAction_Struct *raid_command = (ServerRaidGeneralAction_Struct*)pack->pBuffer; ServerRaidGeneralAction_Struct* raid_command = (ServerRaidGeneralAction_Struct*)pack->pBuffer;
raid_command->rid = raid->GetID(); raid_command->rid = raid->GetID();
strn0cpy(raid_command->playername, raid->members[x].membername, 64); strn0cpy(raid_command->playername, raid->members[x].membername, 64);
@@ -11926,7 +12136,7 @@ void Client::Handle_OP_RaidCommand(const EQApplicationPacket *app)
} }
} }
Client *client_moved = entity_list.GetClientByName(raid_command_packet->leader_name); Client* client_moved = entity_list.GetClientByName(raid_command_packet->leader_name);
if (client_moved && client_moved->GetRaid()) { if (client_moved && client_moved->GetRaid()) {
client_moved->GetRaid()->SendHPManaEndPacketsTo(client_moved); client_moved->GetRaid()->SendHPManaEndPacketsTo(client_moved);
@@ -11942,7 +12152,7 @@ void Client::Handle_OP_RaidCommand(const EQApplicationPacket *app)
} }
case RaidCommandRaidLock: case RaidCommandRaidLock:
{ {
Raid *raid = entity_list.GetRaidByClient(this); Raid* raid = entity_list.GetRaidByClient(this);
if (raid) { if (raid) {
if (!raid->IsLocked()) if (!raid->IsLocked())
raid->LockRaid(true); raid->LockRaid(true);
@@ -11953,7 +12163,7 @@ void Client::Handle_OP_RaidCommand(const EQApplicationPacket *app)
} }
case RaidCommandRaidUnlock: case RaidCommandRaidUnlock:
{ {
Raid *raid = entity_list.GetRaidByClient(this); Raid* raid = entity_list.GetRaidByClient(this);
if (raid) if (raid)
{ {
if (raid->IsLocked()) if (raid->IsLocked())
@@ -11966,7 +12176,7 @@ void Client::Handle_OP_RaidCommand(const EQApplicationPacket *app)
case RaidCommandLootType2: case RaidCommandLootType2:
case RaidCommandLootType: case RaidCommandLootType:
{ {
Raid *raid = entity_list.GetRaidByClient(this); Raid* raid = entity_list.GetRaidByClient(this);
if (raid) { if (raid) {
Message(Chat::Yellow, "Loot type changed to: %d.", raid_command_packet->parameter); Message(Chat::Yellow, "Loot type changed to: %d.", raid_command_packet->parameter);
raid->ChangeLootType(raid_command_packet->parameter); raid->ChangeLootType(raid_command_packet->parameter);
@@ -11977,7 +12187,7 @@ void Client::Handle_OP_RaidCommand(const EQApplicationPacket *app)
case RaidCommandAddLooter2: case RaidCommandAddLooter2:
case RaidCommandAddLooter: case RaidCommandAddLooter:
{ {
Raid *raid = entity_list.GetRaidByClient(this); Raid* raid = entity_list.GetRaidByClient(this);
if (raid) { if (raid) {
Message(Chat::Yellow, "Adding %s as a raid looter.", raid_command_packet->leader_name); Message(Chat::Yellow, "Adding %s as a raid looter.", raid_command_packet->leader_name);
raid->AddRaidLooter(raid_command_packet->leader_name); raid->AddRaidLooter(raid_command_packet->leader_name);
@@ -11988,7 +12198,7 @@ void Client::Handle_OP_RaidCommand(const EQApplicationPacket *app)
case RaidCommandRemoveLooter2: case RaidCommandRemoveLooter2:
case RaidCommandRemoveLooter: case RaidCommandRemoveLooter:
{ {
Raid *raid = entity_list.GetRaidByClient(this); Raid* raid = entity_list.GetRaidByClient(this);
if (raid) { if (raid) {
Message(Chat::Yellow, "Removing %s as a raid looter.", raid_command_packet->leader_name); Message(Chat::Yellow, "Removing %s as a raid looter.", raid_command_packet->leader_name);
raid->RemoveRaidLooter(raid_command_packet->leader_name); raid->RemoveRaidLooter(raid_command_packet->leader_name);
@@ -11998,7 +12208,7 @@ void Client::Handle_OP_RaidCommand(const EQApplicationPacket *app)
case RaidCommandMakeLeader: case RaidCommandMakeLeader:
{ {
Raid *raid = entity_list.GetRaidByClient(this); Raid* raid = entity_list.GetRaidByClient(this);
if (raid) { if (raid) {
if (strcmp(raid->leadername, GetName()) == 0) { if (strcmp(raid->leadername, GetName()) == 0) {
raid->SetRaidLeader(GetName(), raid_command_packet->leader_name); raid->SetRaidLeader(GetName(), raid_command_packet->leader_name);
@@ -12011,11 +12221,11 @@ void Client::Handle_OP_RaidCommand(const EQApplicationPacket *app)
case RaidCommandSetMotd: case RaidCommandSetMotd:
{ {
Raid *raid = entity_list.GetRaidByClient(this); Raid* raid = entity_list.GetRaidByClient(this);
if (!raid) if (!raid)
break; break;
// we don't use the RaidGeneral here! // we don't use the RaidGeneral here!
RaidMOTD_Struct *motd = (RaidMOTD_Struct *)app->pBuffer; RaidMOTD_Struct* motd = (RaidMOTD_Struct*)app->pBuffer;
raid->SetRaidMOTD(std::string(motd->motd)); raid->SetRaidMOTD(std::string(motd->motd));
raid->SaveRaidMOTD(); raid->SaveRaidMOTD();
raid->SendRaidMOTDToWorld(); raid->SendRaidMOTDToWorld();
+47 -3
View File
@@ -2137,17 +2137,17 @@ Raid *EntityList::GetRaidByID(uint32 id)
return nullptr; return nullptr;
} }
Raid *EntityList::GetRaidByClient(Client* client) Raid* EntityList::GetRaidByClient(Client* client)
{ {
if (client->p_raid_instance) { if (client->p_raid_instance) {
return client->p_raid_instance; return client->p_raid_instance;
} }
std::list<Raid *>::iterator iterator; std::list<Raid*>::iterator iterator;
iterator = raid_list.begin(); iterator = raid_list.begin();
while (iterator != raid_list.end()) { while (iterator != raid_list.end()) {
for (auto &member : (*iterator)->members) { for (auto& member : (*iterator)->members) {
if (member.member) { if (member.member) {
if (member.member == client) { if (member.member == client) {
client->p_raid_instance = *iterator; client->p_raid_instance = *iterator;
@@ -2161,6 +2161,50 @@ Raid *EntityList::GetRaidByClient(Client* client)
return nullptr; return nullptr;
} }
#ifdef BOTS
Raid* EntityList::GetRaidByBotName(const char* name)
{
std::list<Raid*>::iterator iterator;
iterator = raid_list.begin();
while (iterator != raid_list.end()) {
for (auto& member : (*iterator)->members) {
if (member.membername) {
if (strcmp(member.membername, name) == 0) {
//client->p_raid_instance = *iterator;
return *iterator;
}
}
}
++iterator;
}
return nullptr;
}
#endif
#ifdef BOTS
Raid* EntityList::GetRaidByBot(Bot* bot)
{
std::list<Raid*>::iterator iterator;
iterator = raid_list.begin();
while (iterator != raid_list.end()) {
for (auto& member : (*iterator)->members) {
if (member.member && member.member->CastToBot() == bot) {
bot->p_raid_instance = *iterator;
return *iterator;
}
}
++iterator;
}
return nullptr;
}
#endif
Raid *EntityList::GetRaidByMob(Mob *mob) Raid *EntityList::GetRaidByMob(Mob *mob)
{ {
+4
View File
@@ -200,6 +200,10 @@ public:
Raid *GetRaidByClient(Client* client); Raid *GetRaidByClient(Client* client);
Raid *GetRaidByID(uint32 id); Raid *GetRaidByID(uint32 id);
Raid *GetRaidByLeaderName(const char *leader); Raid *GetRaidByLeaderName(const char *leader);
#ifdef BOTS
Raid* GetRaidByBotName(const char* name);
Raid* GetRaidByBot(Bot* bot);
#endif
Corpse *GetCorpseByOwner(Client* client); Corpse *GetCorpseByOwner(Client* client);
Corpse *GetCorpseByOwnerWithinRange(Client* client, Mob* center, int range); Corpse *GetCorpseByOwnerWithinRange(Client* client, Mob* center, int range);
+4
View File
@@ -1097,7 +1097,11 @@ void Raid::SplitExp(uint32 exp, Mob* other) {
return; return;
for (unsigned int x = 0; x < MAX_RAID_MEMBERS; x++) { for (unsigned int x = 0; x < MAX_RAID_MEMBERS; x++) {
#ifdef BOTS
if (members[x].member != nullptr && !members[x].IsBot) // If Group Member is Client
#else
if (members[x].member != nullptr) // If Group Member is Client if (members[x].member != nullptr) // If Group Member is Client
#endif
{ {
Client *cmember = members[x].member; Client *cmember = members[x].member;
// add exp + exp cap // add exp + exp cap
+57 -3
View File
@@ -248,10 +248,24 @@ bool Group::AddMember(Mob* newmember, const char *NewMemberName, uint32 Characte
uint32 i = 0; uint32 i = 0;
for (i = 0; i < MAX_GROUP_MEMBERS; ++i) for (i = 0; i < MAX_GROUP_MEMBERS; ++i)
{ {
if(!strcasecmp(membername[i], NewMemberName)) #ifdef BOTSS
if (newmember->IsBot() && !newmember->HasGroup() && !strcasecmp(membername[i], NewMemberName)) // Mitch
{
//Bot::RemoveBotFromGroup(newmember->CastToBot(), members[0]->GetGroup());
//Group::DelMember(newmember);
memset(membername[i], 0, 64);
members[i] = nullptr;
}
else if (!strcasecmp(membername[i], NewMemberName))
{ {
return false; return false;
} }
#else
if (!strcasecmp(membername[i], NewMemberName))
{
return false;
}
#endif
} }
// Put them in the group // Put them in the group
@@ -1140,7 +1154,13 @@ void Group::TeleportGroup(Mob* sender, uint32 zoneID, uint16 instance_id, float
} }
bool Group::LearnMembers() { bool Group::LearnMembers() {
std::string query = StringFormat("SELECT name FROM group_id WHERE groupid = %lu", (unsigned long)GetID()); //std::string query = StringFormat("SELECT name FROM group_id WHERE groupid = %lu", (unsigned long)GetID());
std::string query = StringFormat("SELECT name FROM group_id "
"WHERE group_id.groupid = %lu AND group_id.name NOT "
"IN(SELECT group_leaders.leadername FROM group_leaders WHERE gid = %lu)"
, (unsigned long)GetID()
, (unsigned long)GetID());
auto results = database.QueryDatabase(query); auto results = database.QueryDatabase(query);
if (!results.Success()) if (!results.Success())
return false; return false;
@@ -1155,7 +1175,7 @@ bool Group::LearnMembers() {
return false; return false;
} }
int memberIndex = 0; int memberIndex = 1; //starts at 1 becasuse leader [0] is done specifically
for(auto row = results.begin(); row != results.end(); ++row) { for(auto row = results.begin(); row != results.end(); ++row) {
if(!row[0]) if(!row[0])
continue; continue;
@@ -1165,7 +1185,24 @@ bool Group::LearnMembers() {
memberIndex++; memberIndex++;
} }
// for leader only [0] /Mitch
query = StringFormat("SELECT leadername FROM group_leaders WHERE group_leaders.gid = %lu", (unsigned long)GetID());
auto results2 = database.QueryDatabase(query);
if (!results2.Success())
return false;
if (results2.RowCount() == 0) {
LogError(
"Error getting group leader for group [{}]: [{}]",
(unsigned long)GetID(),
results2.ErrorMessage().c_str()
);
return false;
}
auto row2 = results2.begin();
members[0] = nullptr;
strn0cpy(membername[0], row2[0], 64);
return true; return true;
} }
@@ -1176,6 +1213,22 @@ void Group::VerifyGroup() {
Only called every once in a while (on member re-join for now). Only called every once in a while (on member re-join for now).
*/ */
// To do
// Reset the membername array to match the group_id database records?
// When doing this manually, it seem to have resolved the issue.
// Only want to do this when the database Name does not match the array
// Could this be done from the LearnGroup method?
// reset the members and membername array for this group
// Mitch
for (int i = 0; i < MAX_GROUP_MEMBERS; i++) {
members[i] = nullptr;
memset(membername[i],'\0',64);
//membername[i][0] == '\0');
}
// repopulate the membername array from the database to ensure the local zone instance has accurate information
Group::LearnMembers();
uint32 i; uint32 i;
for (i = 0; i < MAX_GROUP_MEMBERS; i++) { for (i = 0; i < MAX_GROUP_MEMBERS; i++) {
if (membername[i][0] == '\0') { if (membername[i][0] == '\0') {
@@ -1196,6 +1249,7 @@ void Group::VerifyGroup() {
continue; continue;
} }
if(them != nullptr && members[i] != them) { //our pointer is out of date... not so good. if(them != nullptr && members[i] != them) { //our pointer is out of date... not so good.
#if EQDEBUG >= 5 #if EQDEBUG >= 5
LogDebug("Member of group [{}] named [{}] had an out of date pointer!!", (unsigned long)GetID(), membername[i]); LogDebug("Member of group [{}] named [{}] had an out of date pointer!!", (unsigned long)GetID(), membername[i]);
+1
View File
@@ -88,6 +88,7 @@ volatile bool RunLoops = true;
#endif #endif
extern volatile bool is_zone_loaded; extern volatile bool is_zone_loaded;
extern bool Critical = false;
EntityList entity_list; EntityList entity_list;
WorldServer worldserver; WorldServer worldserver;
+191 -9
View File
@@ -24,6 +24,7 @@
#include "groups.h" #include "groups.h"
#include "mob.h" #include "mob.h"
#include "raids.h" #include "raids.h"
#include "bot.h"
#include "worldserver.h" #include "worldserver.h"
@@ -95,12 +96,21 @@ void Raid::AddMember(Client *c, uint32 group, bool rleader, bool groupleader, bo
if(!c) if(!c)
return; return;
#ifdef BOTS
std::string query = StringFormat("INSERT INTO raid_members SET raidid = %lu, charid = %lu, "
"groupid = %lu, _class = %d, level = %d, name = '%s', "
"isgroupleader = %d, israidleader = %d, islooter = %d, isbot = 0",
(unsigned long)GetID(), (unsigned long)c->CharacterID(),
(unsigned long)group, c->GetClass(), c->GetLevel(),
c->GetName(), groupleader, rleader, looter);
#else
std::string query = StringFormat("INSERT INTO raid_members SET raidid = %lu, charid = %lu, " std::string query = StringFormat("INSERT INTO raid_members SET raidid = %lu, charid = %lu, "
"groupid = %lu, _class = %d, level = %d, name = '%s', " "groupid = %lu, _class = %d, level = %d, name = '%s', "
"isgroupleader = %d, israidleader = %d, islooter = %d", "isgroupleader = %d, israidleader = %d, islooter = %d",
(unsigned long)GetID(), (unsigned long)c->CharacterID(), (unsigned long)GetID(), (unsigned long)c->CharacterID(),
(unsigned long)group, c->GetClass(), c->GetLevel(), (unsigned long)group, c->GetClass(), c->GetLevel(),
c->GetName(), groupleader, rleader, looter); c->GetName(), groupleader, rleader, looter);
#endif
auto results = database.QueryDatabase(query); auto results = database.QueryDatabase(query);
if(!results.Success()) { if(!results.Success()) {
@@ -109,6 +119,14 @@ void Raid::AddMember(Client *c, uint32 group, bool rleader, bool groupleader, bo
LearnMembers(); LearnMembers();
VerifyRaid(); VerifyRaid();
#ifdef BOTS
if (rleader) {
database.SetRaidGroupLeaderInfo(group, GetID());
UpdateRaidAAs();
}
else
#endif
if (rleader) { if (rleader) {
database.SetRaidGroupLeaderInfo(RAID_GROUPLESS, GetID()); database.SetRaidGroupLeaderInfo(RAID_GROUPLESS, GetID());
UpdateRaidAAs(); UpdateRaidAAs();
@@ -163,12 +181,65 @@ void Raid::AddMember(Client *c, uint32 group, bool rleader, bool groupleader, bo
safe_delete(pack); safe_delete(pack);
} }
#ifdef BOTS
void Raid::AddBot(Bot* b, uint32 group, bool rleader, bool groupleader, bool looter) {
if (!b)
return;
std::string query = StringFormat("INSERT INTO raid_members SET raidid = %lu, charid = %lu, "
"groupid = %lu, _class = %d, level = %d, name = '%s', "
"isgroupleader = %d, israidleader = %d, islooter = %d, isbot = 1",
(unsigned long)GetID(), (unsigned long)b->GetBotID(),
(unsigned long)group, b->GetClass(), b->GetLevel(),
b->GetName(), groupleader, rleader, looter);
auto results = database.QueryDatabase(query);
if (!results.Success()) {
LogError("Error inserting into raid members: [{}]", results.ErrorMessage().c_str());
}
LearnMembers();
VerifyRaid();
if (group < 12) //Jan22
GroupUpdate(group); //Jan22
else // get raid AAs, GroupUpdate will handles it otherwise Jan 22
SendGroupLeadershipAA(b->GetOwner()->CastToClient(), RAID_GROUPLESS); //Is this needed for bots? Jan 22
SendRaidAddAll(b->GetName());
b->SetRaidGrouped(true);
b->p_raid_instance = this;
auto pack = new ServerPacket(ServerOP_RaidAdd, sizeof(ServerRaidGeneralAction_Struct));
ServerRaidGeneralAction_Struct* rga = (ServerRaidGeneralAction_Struct*)pack->pBuffer;
rga->rid = GetID();
strn0cpy(rga->playername, b->GetName(), 64);
rga->zoneid = zone->GetZoneID();
rga->instance_id = zone->GetInstanceID();
worldserver.SendPacket(pack);
safe_delete(pack);
}
#endif
void Raid::RemoveMember(const char *characterName) void Raid::RemoveMember(const char *characterName)
{ {
std::string query = StringFormat("DELETE FROM raid_members where name='%s'", characterName); std::string query = StringFormat("DELETE FROM raid_members where name='%s'", characterName);
auto results = database.QueryDatabase(query); auto results = database.QueryDatabase(query);
Client *client = entity_list.GetClientByName(characterName); Client *client = entity_list.GetClientByName(characterName);
#ifdef BOTS
Bot* bot = entity_list.GetBotByBotName(characterName);
if (bot) {
bot->SetFollowID(bot->GetOwner()->CastToClient()->GetID());
bot->SetGrouped(false);
bot->SetTarget(nullptr);
bot->SetRaidGrouped(false);
}
#endif
disbandCheck = true; disbandCheck = true;
SendRaidRemoveAll(characterName); SendRaidRemoveAll(characterName);
SendRaidDisband(client); SendRaidDisband(client);
@@ -983,12 +1054,12 @@ void Raid::SendRaidAdd(const char *who, Client *to)
void Raid::SendRaidAddAll(const char *who) void Raid::SendRaidAddAll(const char *who)
{ {
for(int x = 0; x < MAX_RAID_MEMBERS; x++) for (int x = 0; x < MAX_RAID_MEMBERS; x++)
{ {
if(strcmp(members[x].membername, who) == 0) if (strcmp(members[x].membername, who) == 0 )
{ {
auto outapp = new EQApplicationPacket(OP_RaidUpdate, sizeof(RaidAddMember_Struct)); auto outapp = new EQApplicationPacket(OP_RaidUpdate, sizeof(RaidAddMember_Struct));
RaidAddMember_Struct *ram = (RaidAddMember_Struct*)outapp->pBuffer; RaidAddMember_Struct* ram = (RaidAddMember_Struct*)outapp->pBuffer;
ram->raidGen.action = raidAdd; ram->raidGen.action = raidAdd;
ram->raidGen.parameter = members[x].GroupNumber; ram->raidGen.parameter = members[x].GroupNumber;
strcpy(ram->raidGen.leader_name, members[x].membername); strcpy(ram->raidGen.leader_name, members[x].membername);
@@ -999,6 +1070,7 @@ void Raid::SendRaidAddAll(const char *who)
QueuePacket(outapp); QueuePacket(outapp);
safe_delete(outapp); safe_delete(outapp);
return; return;
} }
} }
} }
@@ -1111,9 +1183,14 @@ void Raid::SendBulkRaid(Client *to)
if(!to) if(!to)
return; return;
#ifdef BOTS
if (members[GetPlayerIndex(to)].IsBot)
return;
#endif
for(int x = 0; x < MAX_RAID_MEMBERS; x++) for(int x = 0; x < MAX_RAID_MEMBERS; x++)
{ {
if(strlen(members[x].membername) > 0 && (strcmp(members[x].membername, to->GetName()) != 0)) //don't send ourself if(members[x].member && strlen(members[x].membername) > 0 && (strcmp(members[x].membername, to->GetName()) != 0)) //don't send ourself
{ {
SendRaidAdd(members[x].membername, to); SendRaidAdd(members[x].membername, to);
} }
@@ -1124,7 +1201,11 @@ void Raid::QueuePacket(const EQApplicationPacket *app, bool ack_req)
{ {
for(int x = 0; x < MAX_RAID_MEMBERS; x++) for(int x = 0; x < MAX_RAID_MEMBERS; x++)
{ {
#ifdef BOTS
if(members[x].member && !members[x].IsBot)
#else
if(members[x].member) if(members[x].member)
#endif
{ {
members[x].member->QueuePacket(app, ack_req); members[x].member->QueuePacket(app, ack_req);
} }
@@ -1133,6 +1214,12 @@ void Raid::QueuePacket(const EQApplicationPacket *app, bool ack_req)
void Raid::SendMakeLeaderPacket(const char *who) //30 void Raid::SendMakeLeaderPacket(const char *who) //30
{ {
#ifdef BOTS
if (entity_list.GetBotByBotName(who) && members[GetPlayerIndex(who)].IsBot)
return;
#endif
auto outapp = new EQApplicationPacket(OP_RaidUpdate, sizeof(RaidLeadershipUpdate_Struct)); auto outapp = new EQApplicationPacket(OP_RaidUpdate, sizeof(RaidLeadershipUpdate_Struct));
RaidLeadershipUpdate_Struct *rg = (RaidLeadershipUpdate_Struct*)outapp->pBuffer; RaidLeadershipUpdate_Struct *rg = (RaidLeadershipUpdate_Struct*)outapp->pBuffer;
rg->action = raidMakeLeader; rg->action = raidMakeLeader;
@@ -1148,6 +1235,11 @@ void Raid::SendMakeLeaderPacketTo(const char *who, Client *to)
if(!to) if(!to)
return; return;
#ifdef BOTS
if (members[GetPlayerIndex(who)].IsBot)
return;
#endif
auto outapp = new EQApplicationPacket(OP_RaidUpdate, sizeof(RaidLeadershipUpdate_Struct)); auto outapp = new EQApplicationPacket(OP_RaidUpdate, sizeof(RaidLeadershipUpdate_Struct));
RaidLeadershipUpdate_Struct *rg = (RaidLeadershipUpdate_Struct*)outapp->pBuffer; RaidLeadershipUpdate_Struct *rg = (RaidLeadershipUpdate_Struct*)outapp->pBuffer;
rg->action = raidMakeLeader; rg->action = raidMakeLeader;
@@ -1178,6 +1270,11 @@ void Raid::SendGroupUpdate(Client *to)
if(!to) if(!to)
return; return;
#ifdef BOTS
if (members[GetPlayerIndex(to)].IsBot)
return;
#endif
auto outapp = new EQApplicationPacket(OP_GroupUpdate, sizeof(GroupUpdate2_Struct)); auto outapp = new EQApplicationPacket(OP_GroupUpdate, sizeof(GroupUpdate2_Struct));
GroupUpdate2_Struct* gu = (GroupUpdate2_Struct*)outapp->pBuffer; GroupUpdate2_Struct* gu = (GroupUpdate2_Struct*)outapp->pBuffer;
gu->action = groupActUpdate; gu->action = groupActUpdate;
@@ -1224,7 +1321,7 @@ void Raid::GroupUpdate(uint32 gid, bool initial)
{ {
if(strlen(members[x].membername) > 0){ if(strlen(members[x].membername) > 0){
if(members[x].GroupNumber == gid){ if(members[x].GroupNumber == gid){
if(members[x].member) { if (members[x].member) {
SendGroupUpdate(members[x].member); SendGroupUpdate(members[x].member);
SendGroupLeadershipAA(members[x].member, gid); SendGroupLeadershipAA(members[x].member, gid);
} }
@@ -1366,6 +1463,11 @@ void Raid::SendRaidMOTDToWorld()
void Raid::SendGroupLeadershipAA(Client *c, uint32 gid) void Raid::SendGroupLeadershipAA(Client *c, uint32 gid)
{ {
#ifdef BOTS
if (members[GetPlayerIndex(c)].IsBot)
return;
#endif
auto outapp = new EQApplicationPacket(OP_RaidUpdate, sizeof(RaidLeadershipUpdate_Struct)); auto outapp = new EQApplicationPacket(OP_RaidUpdate, sizeof(RaidLeadershipUpdate_Struct));
RaidLeadershipUpdate_Struct *rlaa = (RaidLeadershipUpdate_Struct *)outapp->pBuffer; RaidLeadershipUpdate_Struct *rlaa = (RaidLeadershipUpdate_Struct *)outapp->pBuffer;
rlaa->action = raidSetLeaderAbilities; rlaa->action = raidSetLeaderAbilities;
@@ -1381,17 +1483,26 @@ void Raid::SendGroupLeadershipAA(Client *c, uint32 gid)
void Raid::SendGroupLeadershipAA(uint32 gid) void Raid::SendGroupLeadershipAA(uint32 gid)
{ {
for (uint32 i = 0; i < MAX_RAID_MEMBERS; i++) for (uint32 i = 0; i < MAX_RAID_MEMBERS; i++)
#ifdef BOTS
if (members[i].member && members[i].GroupNumber == gid && !members[i].IsBot)
#else
if (members[i].member && members[i].GroupNumber == gid) if (members[i].member && members[i].GroupNumber == gid)
#endif
SendGroupLeadershipAA(members[i].member, gid); SendGroupLeadershipAA(members[i].member, gid);
} }
void Raid::SendAllRaidLeadershipAA() void Raid::SendAllRaidLeadershipAA()
{ {
for (uint32 i = 0; i < MAX_RAID_MEMBERS; i++) for (uint32 i = 0; i < MAX_RAID_MEMBERS; i++)
#ifdef BOTS
if (members[i].member && !members[i].IsBot)
#else
if (members[i].member) if (members[i].member)
#endif
SendGroupLeadershipAA(members[i].member, members[i].GroupNumber); SendGroupLeadershipAA(members[i].member, members[i].GroupNumber);
} }
void Raid::LockRaid(bool lockFlag) void Raid::LockRaid(bool lockFlag)
{ {
std::string query = StringFormat("UPDATE raid_details SET locked = %d WHERE raidid = %lu", std::string query = StringFormat("UPDATE raid_details SET locked = %d WHERE raidid = %lu",
@@ -1457,10 +1568,17 @@ bool Raid::LearnMembers()
{ {
memset(members, 0, (sizeof(RaidMember)*MAX_RAID_MEMBERS)); memset(members, 0, (sizeof(RaidMember)*MAX_RAID_MEMBERS));
#ifdef BOTS
std::string query = StringFormat("SELECT name, groupid, _class, level, "
"isgroupleader, israidleader, islooter, isbot "
"FROM raid_members WHERE raidid = %lu",
(unsigned long)GetID());
#else
std::string query = StringFormat("SELECT name, groupid, _class, level, " std::string query = StringFormat("SELECT name, groupid, _class, level, "
"isgroupleader, israidleader, islooter " "isgroupleader, israidleader, islooter "
"FROM raid_members WHERE raidid = %lu", "FROM raid_members WHERE raidid = %lu",
(unsigned long)GetID()); (unsigned long)GetID());
#endif
auto results = database.QueryDatabase(query); auto results = database.QueryDatabase(query);
if (!results.Success()) if (!results.Success())
return false; return false;
@@ -1489,6 +1607,9 @@ bool Raid::LearnMembers()
members[index].IsGroupLeader = atoi(row[4]); members[index].IsGroupLeader = atoi(row[4]);
members[index].IsRaidLeader = atoi(row[5]); members[index].IsRaidLeader = atoi(row[5]);
members[index].IsLooter = atoi(row[6]); members[index].IsLooter = atoi(row[6]);
#ifdef BOTS
members[index].IsBot = atoi(row[7]);
#endif
++index; ++index;
} }
@@ -1504,11 +1625,29 @@ void Raid::VerifyRaid()
} }
else{ else{
Client *c = entity_list.GetClientByName(members[x].membername); Client *c = entity_list.GetClientByName(members[x].membername);
#ifdef BOTS
Bot* b = entity_list.GetBotByBotName(members[x].membername);
#endif
if(c){ if(c){
members[x].member = c; members[x].member = c;
#ifdef BOTS
members[x].IsBot = false;
#endif
} }
else{ #ifdef BOTS
else if(b){
//Raid requires client* we are forcing it here to be a BOT. Care is needed here as any client function that
//does not exist within the Bot Class will likely corrupt memory for the member object. Good practice to test the IsBot
//attribute before calling a client function or casting to client.
members[x].member = b->CastToClient();
members[x].IsBot = true; //Used to identify those members who are Bots
}
#endif
else {
members[x].member = nullptr; members[x].member = nullptr;
#ifdef BOTS
members[x].IsBot = false;
#endif
} }
} }
if(members[x].IsRaidLeader){ if(members[x].IsRaidLeader){
@@ -1561,7 +1700,11 @@ void Raid::SendHPManaEndPacketsTo(Client *client)
EQApplicationPacket outapp(OP_MobManaUpdate, sizeof(MobManaUpdate_Struct)); EQApplicationPacket outapp(OP_MobManaUpdate, sizeof(MobManaUpdate_Struct));
for(int x = 0; x < MAX_RAID_MEMBERS; x++) { for(int x = 0; x < MAX_RAID_MEMBERS; x++) {
if(members[x].member) { #ifdef BOTS
if(members[x].member && !members[x].IsBot) {
#else
if (members[x].member) {
#endif
if((members[x].member != client) && (members[x].GroupNumber == group_id)) { if((members[x].member != client) && (members[x].GroupNumber == group_id)) {
members[x].member->CreateHPPacket(&hp_packet); members[x].member->CreateHPPacket(&hp_packet);
@@ -1603,7 +1746,11 @@ void Raid::SendHPManaEndPacketsFrom(Mob *mob)
mob->CreateHPPacket(&hpapp); mob->CreateHPPacket(&hpapp);
for(int x = 0; x < MAX_RAID_MEMBERS; x++) { for(int x = 0; x < MAX_RAID_MEMBERS; x++) {
if(members[x].member) { #ifdef BOTS
if(members[x].member && !members[x].IsBot) {
#else
if (members[x].member) {
#endif
if(!mob->IsClient() || ((members[x].member != mob->CastToClient()) && (members[x].GroupNumber == group_id))) { if(!mob->IsClient() || ((members[x].member != mob->CastToClient()) && (members[x].GroupNumber == group_id))) {
members[x].member->QueuePacket(&hpapp, false); members[x].member->QueuePacket(&hpapp, false);
if (members[x].member->ClientVersion() >= EQ::versions::ClientVersion::SoD) { if (members[x].member->ClientVersion() >= EQ::versions::ClientVersion::SoD) {
@@ -1636,7 +1783,11 @@ void Raid::SendManaPacketFrom(Mob *mob)
EQApplicationPacket outapp(OP_MobManaUpdate, sizeof(MobManaUpdate_Struct)); EQApplicationPacket outapp(OP_MobManaUpdate, sizeof(MobManaUpdate_Struct));
for (int x = 0; x < MAX_RAID_MEMBERS; x++) { for (int x = 0; x < MAX_RAID_MEMBERS; x++) {
#ifdef BOTS
if (members[x].member && !members[x].IsBot) {
#else
if (members[x].member) { if (members[x].member) {
#endif
if (!mob->IsClient() || ((members[x].member != mob->CastToClient()) && (members[x].GroupNumber == group_id))) { if (!mob->IsClient() || ((members[x].member != mob->CastToClient()) && (members[x].GroupNumber == group_id))) {
if (members[x].member->ClientVersion() >= EQ::versions::ClientVersion::SoD) { if (members[x].member->ClientVersion() >= EQ::versions::ClientVersion::SoD) {
outapp.SetOpcode(OP_MobManaUpdate); outapp.SetOpcode(OP_MobManaUpdate);
@@ -1663,7 +1814,11 @@ void Raid::SendEndurancePacketFrom(Mob *mob)
EQApplicationPacket outapp(OP_MobManaUpdate, sizeof(MobManaUpdate_Struct)); EQApplicationPacket outapp(OP_MobManaUpdate, sizeof(MobManaUpdate_Struct));
for (int x = 0; x < MAX_RAID_MEMBERS; x++) { for (int x = 0; x < MAX_RAID_MEMBERS; x++) {
#ifdef BTOS
if (members[x].member && !members[x].IsBot) {
#else
if (members[x].member) { if (members[x].member) {
#endif
if (!mob->IsClient() || ((members[x].member != mob->CastToClient()) && (members[x].GroupNumber == group_id))) { if (!mob->IsClient() || ((members[x].member != mob->CastToClient()) && (members[x].GroupNumber == group_id))) {
if (members[x].member->ClientVersion() >= EQ::versions::ClientVersion::SoD) { if (members[x].member->ClientVersion() >= EQ::versions::ClientVersion::SoD) {
outapp.SetOpcode(OP_MobEnduranceUpdate); outapp.SetOpcode(OP_MobEnduranceUpdate);
@@ -1770,9 +1925,18 @@ void Raid::CheckGroupMentor(uint32 group_id, Client *c)
void Raid::SetDirtyAutoHaters() void Raid::SetDirtyAutoHaters()
{ {
for (int i = 0; i < MAX_RAID_MEMBERS; ++i) for (int i = 0; i < MAX_RAID_MEMBERS; ++i)
#ifdef BOTS
if (members[i].member && members[i].IsBot)
{
members[i].member->CastToBot()->SetDirtyAutoHaters();
}
else if (members[i].member && !members[i].IsBot)
#else
if (members[i].member) if (members[i].member)
#endif
{
members[i].member->SetDirtyAutoHaters(); members[i].member->SetDirtyAutoHaters();
}
} }
void Raid::QueueClients(Mob *sender, const EQApplicationPacket *app, bool ack_required /*= true*/, bool ignore_sender /*= true*/, float distance /*= 0*/, bool group_only /*= true*/) { void Raid::QueueClients(Mob *sender, const EQApplicationPacket *app, bool ack_required /*= true*/, bool ignore_sender /*= true*/, float distance /*= 0*/, bool group_only /*= true*/) {
@@ -1791,6 +1955,10 @@ void Raid::QueueClients(Mob *sender, const EQApplicationPacket *app, bool ack_re
if (!members[i].member->IsClient()) if (!members[i].member->IsClient())
continue; continue;
#ifdef BOTS
if (members[i].IsBot)
continue;
#endif
if (ignore_sender && members[i].member == sender) if (ignore_sender && members[i].member == sender)
continue; continue;
@@ -1853,3 +2021,17 @@ bool Raid::DoesAnyMemberHaveExpeditionLockout(
return Expedition::HasLockoutByCharacterName(raid_member.membername, expedition_name, event_name); return Expedition::HasLockoutByCharacterName(raid_member.membername, expedition_name, event_name);
}); });
} }
#ifdef BOTS
Mob* Raid::GetRaidMainAssistOneByName(const char* name)
{
Raid* raid = entity_list.GetRaidByBotName(name);
std::vector<RaidMember> raid_members = raid->GetMembers();
for (RaidMember iter : raid_members)
{
if (iter.IsRaidMainAssistOne)
return iter.member->CastToMob();
}
return nullptr;
}
#endif
+11
View File
@@ -88,6 +88,10 @@ struct RaidMember{
bool IsGroupLeader; bool IsGroupLeader;
bool IsRaidLeader; bool IsRaidLeader;
bool IsLooter; bool IsLooter;
#ifdef BOTS
bool IsBot = false;
bool IsRaidMainAssistOne = false;
#endif
}; };
struct GroupMentor { struct GroupMentor {
@@ -112,6 +116,11 @@ public:
bool IsRaid() { return true; } bool IsRaid() { return true; }
void AddMember(Client *c, uint32 group = 0xFFFFFFFF, bool rleader=false, bool groupleader=false, bool looter=false); void AddMember(Client *c, uint32 group = 0xFFFFFFFF, bool rleader=false, bool groupleader=false, bool looter=false);
#ifdef BOTS
void AddBot(Bot* b, uint32 group = 0xFFFFFFFF, bool rleader=false, bool groupleader=false, bool looter=false);
void RaidBotGroupSay(Bot* b, uint8 language, uint8 lang_skill, const char* msg, ...); //Not yet implemented
Mob* GetRaidMainAssistOneByName(const char* name);
#endif
void RemoveMember(const char *c); void RemoveMember(const char *c);
void DisbandRaid(); void DisbandRaid();
void MoveMember(const char *name, uint32 newGroup); void MoveMember(const char *name, uint32 newGroup);
@@ -122,6 +131,7 @@ public:
bool IsRaidMember(const char *name); bool IsRaidMember(const char *name);
void UpdateLevel(const char *name, int newLevel); void UpdateLevel(const char *name, int newLevel);
uint32 GetFreeGroup(); uint32 GetFreeGroup();
uint8 GroupCount(uint32 gid); uint8 GroupCount(uint32 gid);
uint8 RaidCount(); uint8 RaidCount();
@@ -241,6 +251,7 @@ public:
bool DoesAnyMemberHaveExpeditionLockout(const std::string& expedition_name, const std::string& event_name, int max_check_count = 0); bool DoesAnyMemberHaveExpeditionLockout(const std::string& expedition_name, const std::string& event_name, int max_check_count = 0);
std::vector<RaidMember> GetMembers() const; std::vector<RaidMember> GetMembers() const;
std::vector<RaidMember> GetRaidGroupMembers(uint32 gid);
RaidMember members[MAX_RAID_MEMBERS]; RaidMember members[MAX_RAID_MEMBERS];
char leadername[64]; char leadername[64];
+1 -1
View File
@@ -154,7 +154,7 @@ bool Spawn2::Process() {
return true; return true;
} }
if (timer.Check()) { if (timer.Check() && zone->spawn2_timer.Enabled()) {
timer.Disable(); timer.Disable();
LogSpawns("Spawn2 [{}]: Timer has triggered", spawn2_id); LogSpawns("Spawn2 [{}]: Timer has triggered", spawn2_id);
+1
View File
@@ -1742,6 +1742,7 @@ bool Zone::Depop(bool StartSpawnTimer) {
itr = npctable.begin(); itr = npctable.begin();
delete itr->second; delete itr->second;
itr->second = nullptr; itr->second = nullptr;
npctable.erase(itr); npctable.erase(itr);
} }