mirror of
https://github.com/EQEmu/Server.git
synced 2026-05-31 00:46:46 +00:00
Merge branch 'master' of https://github.com/neckkola/Server
This commit is contained in:
+2
-2
@@ -54,5 +54,5 @@ bin/
|
|||||||
/Win32
|
/Win32
|
||||||
/x64
|
/x64
|
||||||
/client_files/**/CMakeFiles/
|
/client_files/**/CMakeFiles/
|
||||||
|
submodules/libuv
|
||||||
.idea
|
.idea
|
||||||
@@ -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;
|
||||||
}
|
}
|
||||||
@@ -154,7 +163,10 @@ public:
|
|||||||
entry.name = row[5] ? row[5] : "";
|
entry.name = row[5] ? row[5] : "";
|
||||||
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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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
|
||||||
|
|
||||||
|
|||||||
@@ -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 '';
|
||||||
@@ -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
@@ -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
File diff suppressed because it is too large
Load Diff
@@ -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
|
||||||
@@ -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;
|
||||||
}
|
}
|
||||||
|
|||||||
+5
-4
@@ -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) {
|
||||||
@@ -820,7 +821,7 @@ void Client::FastQueuePacket(EQApplicationPacket** app, bool ack_req, CLIENT_CON
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if(eqs)
|
if(eqs)
|
||||||
eqs->FastQueuePacket((EQApplicationPacket **)app, ack_req);
|
eqs->FastQueuePacket((EQApplicationPacket **)app, ack_req);
|
||||||
else if (app && (*app))
|
else if (app && (*app))
|
||||||
delete *app;
|
delete *app;
|
||||||
|
|||||||
+695
-485
File diff suppressed because it is too large
Load Diff
+47
-3
@@ -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)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -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
@@ -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]);
|
||||||
|
|||||||
+2
-1
@@ -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;
|
||||||
@@ -578,7 +579,7 @@ int main(int argc, char** argv) {
|
|||||||
|
|
||||||
EQ::Timer process_timer(loop_fn);
|
EQ::Timer process_timer(loop_fn);
|
||||||
process_timer.Start(32, true);
|
process_timer.Start(32, true);
|
||||||
|
|
||||||
EQ::EventLoop::Get().Run();
|
EQ::EventLoop::Get().Run();
|
||||||
|
|
||||||
entity_list.Clear();
|
entity_list.Clear();
|
||||||
|
|||||||
+1
-1
@@ -3987,7 +3987,7 @@ void Mob::QuestJournalledSay(Client *QuestInitiator, const char *str, Journal::O
|
|||||||
|
|
||||||
const char *Mob::GetCleanName()
|
const char *Mob::GetCleanName()
|
||||||
{
|
{
|
||||||
if (!strlen(clean_name)) {
|
if (!strlen(clean_name)) {
|
||||||
CleanMobName(GetName(), clean_name);
|
CleanMobName(GetName(), clean_name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+199
-17
@@ -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,13 +96,22 @@ 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, "
|
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, isbot = 0",
|
||||||
(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);
|
||||||
auto results = database.QueryDatabase(query);
|
#else
|
||||||
|
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",
|
||||||
|
(unsigned long)GetID(), (unsigned long)c->CharacterID(),
|
||||||
|
(unsigned long)group, c->GetClass(), c->GetLevel(),
|
||||||
|
c->GetName(), groupleader, rleader, looter);
|
||||||
|
#endif
|
||||||
|
auto results = database.QueryDatabase(query);
|
||||||
|
|
||||||
if(!results.Success()) {
|
if(!results.Success()) {
|
||||||
LogError("Error inserting into raid members: [{}]", results.ErrorMessage().c_str());
|
LogError("Error inserting into raid members: [{}]", results.ErrorMessage().c_str());
|
||||||
@@ -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,11 +1183,16 @@ 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)
|
||||||
SendGroupLeadershipAA(members[i].member, members[i].GroupNumber);
|
#endif
|
||||||
|
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,11 +1568,18 @@ 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, "
|
std::string query = StringFormat("SELECT name, groupid, _class, level, "
|
||||||
"isgroupleader, israidleader, islooter "
|
"isgroupleader, israidleader, islooter, isbot "
|
||||||
"FROM raid_members WHERE raidid = %lu",
|
"FROM raid_members WHERE raidid = %lu",
|
||||||
(unsigned long)GetID());
|
(unsigned long)GetID());
|
||||||
auto results = database.QueryDatabase(query);
|
#else
|
||||||
|
std::string query = StringFormat("SELECT name, groupid, _class, level, "
|
||||||
|
"isgroupleader, israidleader, islooter "
|
||||||
|
"FROM raid_members WHERE raidid = %lu",
|
||||||
|
(unsigned long)GetID());
|
||||||
|
#endif
|
||||||
|
auto results = database.QueryDatabase(query);
|
||||||
if (!results.Success())
|
if (!results.Success())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
@@ -1489,7 +1607,10 @@ 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]);
|
||||||
++index;
|
#ifdef BOTS
|
||||||
|
members[index].IsBot = atoi(row[7]);
|
||||||
|
#endif
|
||||||
|
++index;
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
@@ -1504,14 +1625,32 @@ 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){
|
||||||
if(strlen(members[x].membername) > 0){
|
if(strlen(members[x].membername) > 0){
|
||||||
SetLeader(members[x].member);
|
SetLeader(members[x].member);
|
||||||
strn0cpy(leadername, members[x].membername, 64);
|
strn0cpy(leadername, members[x].membername, 64);
|
||||||
@@ -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
|
||||||
|
|||||||
@@ -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);
|
||||||
@@ -121,6 +130,7 @@ public:
|
|||||||
bool IsGroupLeader(const char *who);
|
bool IsGroupLeader(const char *who);
|
||||||
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);
|
||||||
@@ -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
@@ -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);
|
||||||
|
|||||||
@@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user