mirror of
https://github.com/EQEmu/Server.git
synced 2026-05-17 07:18:37 +00:00
+2
-2
@@ -54,5 +54,5 @@ bin/
|
||||
/Win32
|
||||
/x64
|
||||
/client_files/**/CMakeFiles/
|
||||
|
||||
.idea
|
||||
submodules/libuv
|
||||
.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": ""
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -27,6 +27,7 @@ public:
|
||||
int isgroupleader;
|
||||
int israidleader;
|
||||
int islooter;
|
||||
int isbot;
|
||||
};
|
||||
|
||||
static std::string PrimaryKey()
|
||||
@@ -46,6 +47,7 @@ public:
|
||||
"isgroupleader",
|
||||
"israidleader",
|
||||
"islooter",
|
||||
"isbot",
|
||||
};
|
||||
}
|
||||
|
||||
@@ -90,6 +92,7 @@ public:
|
||||
entry.isgroupleader = 0;
|
||||
entry.israidleader = 0;
|
||||
entry.islooter = 0;
|
||||
entry.isbot = 0;
|
||||
|
||||
return entry;
|
||||
}
|
||||
@@ -133,7 +136,8 @@ public:
|
||||
entry.name = row[5] ? row[5] : "";
|
||||
entry.isgroupleader = atoi(row[6]);
|
||||
entry.israidleader = atoi(row[7]);
|
||||
entry.islooter = atoi(row[8]);
|
||||
entry.islooter = atoi(row[8]);
|
||||
entry.isbot = atoi(row[9]);
|
||||
|
||||
return entry;
|
||||
}
|
||||
@@ -176,6 +180,7 @@ public:
|
||||
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[8] + " = " + std::to_string(raid_members_entry.islooter));
|
||||
update_values.push_back(columns[9] + " = " + std::to_string(raid_members_entry.isbot)); //Mitch
|
||||
|
||||
auto results = db.QueryDatabase(
|
||||
fmt::format(
|
||||
@@ -206,6 +211,7 @@ public:
|
||||
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.islooter));
|
||||
insert_values.push_back(std::to_string(raid_members_entry.isbot));
|
||||
|
||||
auto results = db.QueryDatabase(
|
||||
fmt::format(
|
||||
@@ -244,6 +250,7 @@ public:
|
||||
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.islooter));
|
||||
insert_values.push_back(std::to_string(raid_members_entry.isbot));
|
||||
|
||||
insert_chunks.push_back("(" + implode(",", insert_values) + ")");
|
||||
}
|
||||
@@ -286,6 +293,7 @@ public:
|
||||
entry.isgroupleader = atoi(row[6]);
|
||||
entry.israidleader = atoi(row[7]);
|
||||
entry.islooter = atoi(row[8]);
|
||||
entry.isbot = atoi(row[9]);
|
||||
|
||||
all_entries.push_back(entry);
|
||||
}
|
||||
@@ -319,6 +327,7 @@ public:
|
||||
entry.isgroupleader = atoi(row[6]);
|
||||
entry.israidleader = atoi(row[7]);
|
||||
entry.islooter = atoi(row[8]);
|
||||
entry.isbot = atoi(row[9]);
|
||||
|
||||
all_entries.push_back(entry);
|
||||
}
|
||||
|
||||
@@ -617,10 +617,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, 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, 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, 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, ResurrectionSicknessSpell, 756, "756 is Default Resurrection Sickness Spell")
|
||||
|
||||
RULE_CATEGORY_END()
|
||||
#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_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 H32(i) ((uint32) (i >> 32))
|
||||
#define L16(i) ((uint16) i)
|
||||
|
||||
+130
-29
@@ -49,6 +49,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
extern QueryServ* QServ;
|
||||
extern WorldServer worldserver;
|
||||
extern FastMath g_Math;
|
||||
extern bool Critical;
|
||||
|
||||
#ifdef _WINDOWS
|
||||
#define snprintf _snprintf
|
||||
@@ -3582,7 +3583,7 @@ bool Mob::CheckDoubleAttack()
|
||||
return zone->random.Int(1, 500) <= chance;
|
||||
}
|
||||
|
||||
void Mob::CommonDamage(Mob* attacker, int &damage, const uint16 spell_id, const EQ::skills::SkillType skill_used, bool &avoidable, const int8 buffslot, const bool iBuffTic, eSpecialAttacks special) {
|
||||
void Mob::CommonDamage(Mob* attacker, int& damage, const uint16 spell_id, const EQ::skills::SkillType skill_used, bool& avoidable, const int8 buffslot, const bool iBuffTic, eSpecialAttacks special) {
|
||||
// This method is called with skill_used=ABJURE for Damage Shield damage.
|
||||
bool FromDamageShield = (skill_used == EQ::skills::SkillAbjuration);
|
||||
bool ignore_invul = false;
|
||||
@@ -3652,7 +3653,7 @@ void Mob::CommonDamage(Mob* attacker, int &damage, const uint16 spell_id, const
|
||||
// and remove sitting regen. Removes bug where client clicks sit
|
||||
// during battle and gains pet hp-regen and bugs the sit button.
|
||||
if (IsPet()) {
|
||||
Mob *owner = this->GetOwner();
|
||||
Mob* owner = this->GetOwner();
|
||||
if (owner && owner->IsClient()) {
|
||||
if (GetPetOrder() == SPO_Sit) {
|
||||
SetPetOrder(SPO_Follow);
|
||||
@@ -3665,7 +3666,7 @@ void Mob::CommonDamage(Mob* attacker, int &damage, const uint16 spell_id, const
|
||||
|
||||
} //end `if there is some damage being done and theres anattacker person involved`
|
||||
|
||||
Mob *pet = GetPet();
|
||||
Mob* pet = GetPet();
|
||||
// pets that have GHold will never automatically add NPCs
|
||||
// pets that have Hold and no Focus will add NPCs if they're engaged
|
||||
// pets that have Hold and Focus will not add NPCs
|
||||
@@ -3681,7 +3682,7 @@ void Mob::CommonDamage(Mob* attacker, int &damage, const uint16 spell_id, const
|
||||
!attacker->IsCorpse() &&
|
||||
!pet->IsGHeld() &&
|
||||
!attacker->IsTrap()
|
||||
) {
|
||||
) {
|
||||
if (!pet->IsHeld()) {
|
||||
LogAggro("Sending pet [{}] into battle due to attack", pet->GetName());
|
||||
if (IsClient()) {
|
||||
@@ -3905,12 +3906,12 @@ void Mob::CommonDamage(Mob* attacker, int &damage, const uint16 spell_id, const
|
||||
//Note: if players can become pets, they will not receive damage messages of their own
|
||||
//this was done to simplify the code here (since we can only effectively skip one mob on queue)
|
||||
eqFilterType filter;
|
||||
Mob *skip = attacker;
|
||||
Mob* skip = attacker;
|
||||
if (attacker && attacker->GetOwnerID()) {
|
||||
//attacker is a pet, let pet owners see their pet's damage
|
||||
Mob* owner = attacker->GetOwner();
|
||||
if (owner && owner->IsClient()) {
|
||||
if (((spell_id != SPELL_UNKNOWN) || (FromDamageShield)) && damage>0) {
|
||||
if (((spell_id != SPELL_UNKNOWN) || (FromDamageShield)) && damage > 0) {
|
||||
//special crap for spell damage, looks hackish to me
|
||||
char val1[20] = { 0 };
|
||||
owner->MessageString(Chat::NonMelee, OTHER_HIT_NONMELEE, GetCleanName(), ConvertArray(damage, val1));
|
||||
@@ -3931,6 +3932,33 @@ void Mob::CommonDamage(Mob* attacker, int &damage, const uint16 spell_id, const
|
||||
owner->CastToClient()->QueuePacket(outapp, true, CLIENT_CONNECTED, filter);
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef BOTS
|
||||
else if (owner && owner->IsBot() && RuleB(Bots, DisplaySpellDamage)) {
|
||||
if (((spell_id != SPELL_UNKNOWN) || (FromDamageShield)) && damage > 0) {
|
||||
//special crap for spell damage, looks hackish to me
|
||||
char val1[20] = { 0 };
|
||||
owner->CastToBot()->GetBotOwner()->CastToClient()->MessageString(Chat::NonMelee, OTHER_HIT_NONMELEE, attacker->GetCleanName(), ConvertArray(damage, val1));
|
||||
|
||||
}
|
||||
else {
|
||||
if (damage > 0) {
|
||||
if (spell_id != SPELL_UNKNOWN)
|
||||
filter = iBuffTic ? FilterDOT : FilterSpellDamage;
|
||||
else
|
||||
filter = FilterPetHits;
|
||||
}
|
||||
else if (damage == -5)
|
||||
filter = FilterNone; //cant filter invulnerable
|
||||
else
|
||||
filter = FilterPetMisses;
|
||||
|
||||
if (!FromDamageShield)
|
||||
owner->CastToBot()->GetBotOwner()->CastToClient()->QueuePacket(outapp, true, CLIENT_CONNECTED, filter);
|
||||
|
||||
}
|
||||
}
|
||||
#endif
|
||||
skip = owner;
|
||||
}
|
||||
else {
|
||||
@@ -3969,8 +3997,10 @@ void Mob::CommonDamage(Mob* attacker, int &damage, const uint16 spell_id, const
|
||||
filter = FilterNone; //cant filter invulnerable
|
||||
else
|
||||
filter = FilterMyMisses;
|
||||
|
||||
//set to filter duplicate message to the client if client uses #damage to themselves
|
||||
//if (!attacker->IsClient() && attacker->CastToClient()->GetID() != attacker->GetTarget()->GetID()) {
|
||||
attacker->CastToClient()->QueuePacket(outapp, true, CLIENT_CONNECTED, filter);
|
||||
//}
|
||||
}
|
||||
}
|
||||
skip = attacker;
|
||||
@@ -3992,7 +4022,20 @@ void Mob::CommonDamage(Mob* attacker, int &damage, const uint16 spell_id, const
|
||||
// If this is Damage Shield damage, the correct OP_Damage packets will be sent from Mob::DamageShield, so
|
||||
// we don't send them here.
|
||||
if (!FromDamageShield) {
|
||||
|
||||
#ifdef BOTS
|
||||
// If a bot is the attacker, send a damage message ot the Bot Owner
|
||||
if (attacker->GetTarget() && spell_id != SPELL_UNKNOWN && damage > 0 && !Critical && attacker && attacker != this && attacker->IsBot() && RuleB(Bots, DisplaySpellDamage)) {
|
||||
attacker->CastToBot()->GetBotOwner()->FilteredMessageString(
|
||||
attacker->CastToBot()->GetBotOwner(),
|
||||
Chat::DotDamage,
|
||||
FilterDOT,
|
||||
OTHER_HIT_DOT,
|
||||
attacker->GetTarget()->GetCleanName(),
|
||||
itoa(damage),
|
||||
attacker->GetCleanName(),
|
||||
spells[spell_id].name);
|
||||
}
|
||||
#endif
|
||||
entity_list.QueueCloseClients(
|
||||
this, /* Sender */
|
||||
outapp, /* packet */
|
||||
@@ -4001,10 +4044,10 @@ void Mob::CommonDamage(Mob* attacker, int &damage, const uint16 spell_id, const
|
||||
skip, /* Skip this mob */
|
||||
true, /* Packet ACK */
|
||||
filter /* eqFilterType filter */
|
||||
);
|
||||
);
|
||||
|
||||
//send the damage to ourself if we are a client
|
||||
if (IsClient()) {
|
||||
if (IsClient() && this != attacker) { //need to add a filter to remove duplicate display for #damage to self
|
||||
//I dont think any filters apply to damage affecting us
|
||||
CastToClient()->QueuePacket(outapp);
|
||||
}
|
||||
@@ -4034,11 +4077,25 @@ void Mob::CommonDamage(Mob* attacker, int &damage, const uint16 spell_id, const
|
||||
spells[spell_id].name /* Message4 */
|
||||
);
|
||||
}
|
||||
} //end packet sending
|
||||
#ifdef BOTS
|
||||
// If a bot is the attacker, send a damage message ot the Bot Owner
|
||||
else if (attacker->GetTarget() && spell_id != SPELL_UNKNOWN && attacker->IsBot() && damage > 0 && !Critical && attacker && attacker != this && RuleB(Bots, DisplaySpellDamage)) {
|
||||
attacker->CastToBot()->GetBotOwner()->FilteredMessageString(
|
||||
attacker->CastToBot()->GetBotOwner(),
|
||||
Chat::DotDamage,
|
||||
FilterDOT,
|
||||
OTHER_HIT_DOT,
|
||||
attacker->GetTarget()->GetCleanName(),
|
||||
itoa(damage),
|
||||
attacker->GetCleanName(),
|
||||
spells[spell_id].name);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
}
|
||||
} //end packet sending
|
||||
|
||||
void Mob::HealDamage(uint32 amount, Mob *caster, uint16 spell_id)
|
||||
void Mob::HealDamage(uint32 amount, Mob* caster, uint16 spell_id)
|
||||
{
|
||||
int32 maxhp = GetMaxHP();
|
||||
int32 curhp = GetHP();
|
||||
@@ -4053,15 +4110,16 @@ void Mob::HealDamage(uint32 amount, Mob *caster, uint16 spell_id)
|
||||
if (caster) {
|
||||
if (IsBuffSpell(spell_id)) { // hots
|
||||
// message to caster
|
||||
if (caster->IsClient() && caster == this) {
|
||||
if (caster->CastToClient()->ClientVersionBit() & EQ::versions::maskSoFAndLater)
|
||||
if ((caster->IsClient() && caster == this)) {
|
||||
if (caster->CastToClient()->ClientVersionBit() & EQ::versions::maskSoFAndLater) {
|
||||
FilteredMessageString(caster, Chat::NonMelee, FilterHealOverTime,
|
||||
HOT_HEAL_SELF, itoa(acthealed), spells[spell_id].name);
|
||||
}
|
||||
else
|
||||
FilteredMessageString(caster, Chat::NonMelee, FilterHealOverTime,
|
||||
YOU_HEALED, GetCleanName(), itoa(acthealed));
|
||||
}
|
||||
else if (caster->IsClient() && caster != this) {
|
||||
else if ((caster->IsClient() && caster != this)) {
|
||||
if (caster->CastToClient()->ClientVersionBit() & EQ::versions::maskSoFAndLater)
|
||||
caster->FilteredMessageString(caster, Chat::NonMelee, FilterHealOverTime,
|
||||
HOT_HEAL_OTHER, GetCleanName(), itoa(acthealed),
|
||||
@@ -4070,8 +4128,35 @@ void Mob::HealDamage(uint32 amount, Mob *caster, uint16 spell_id)
|
||||
caster->FilteredMessageString(caster, Chat::NonMelee, FilterHealOverTime,
|
||||
YOU_HEAL, GetCleanName(), itoa(acthealed));
|
||||
}
|
||||
#ifdef BOTS
|
||||
if (caster->IsBot() && this != caster->CastToBot()->GetBotOwner() && RuleB(Bots, DisplayHealDamage)) {
|
||||
|
||||
|
||||
// %1 healed %2 for %3 hit points from %4's %5
|
||||
const char s2[]{ " healed " };
|
||||
const char s4[]{ " for " };
|
||||
const char s6[]{ " hit points from " };
|
||||
const char s8[]{ "'s " };
|
||||
|
||||
caster->CastToBot()->GetBotOwner()->FilteredMessageString(
|
||||
caster->CastToBot()->GetBotOwner(), //send to the Bot Owner's client
|
||||
Chat::NonMelee,
|
||||
FilterHealOverTime,
|
||||
GENERIC_9_STRINGS, //using generic for testing purposes %1 %2 %3 %4 %5 %6 %7 %8 %9
|
||||
caster->GetCleanName(), // %1 caster (bot's) name
|
||||
s2, // %2
|
||||
this->GetCleanName(), // %3 caster (bot's) target
|
||||
s4, // %4
|
||||
itoa(acthealed), // %5 amount healed
|
||||
s6, // %6
|
||||
caster->GetCleanName(), // %7 caster (bot's) name
|
||||
s8, // %8
|
||||
spells[spell_id].name // %9 spell name
|
||||
);
|
||||
}
|
||||
#endif // BOTS
|
||||
// message to target
|
||||
if (IsClient() && caster != this) {
|
||||
if ((IsClient() && caster != this)) {
|
||||
if (CastToClient()->ClientVersionBit() & EQ::versions::maskSoFAndLater)
|
||||
FilteredMessageString(this, Chat::NonMelee, FilterHealOverTime,
|
||||
HOT_HEALED_OTHER, caster->GetCleanName(),
|
||||
@@ -4084,25 +4169,41 @@ void Mob::HealDamage(uint32 amount, Mob *caster, uint16 spell_id)
|
||||
else { // normal heals
|
||||
FilteredMessageString(caster, Chat::NonMelee, FilterSpellDamage,
|
||||
YOU_HEALED, caster->GetCleanName(), itoa(acthealed));
|
||||
#ifndef BOTS
|
||||
if (caster != this)
|
||||
caster->FilteredMessageString(caster, Chat::NonMelee, FilterSpellDamage,
|
||||
YOU_HEAL, GetCleanName(), itoa(acthealed));
|
||||
}
|
||||
}
|
||||
else {
|
||||
Message(Chat::NonMelee, "You have been healed for %d points of damage.", acthealed);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#ifdef BOTS
|
||||
if (caster->IsBot() && RuleB(Bots, DisplayHealDamage)) {
|
||||
caster->CastToBot()->GetBotOwner()->FilteredMessageString(caster->CastToBot()->GetBotOwner(),
|
||||
Chat::NonMelee, FilterSpellDamage, GENERIC_9_STRINGS,
|
||||
caster->GetCleanName(), " healed ", this->GetCleanName(), " for ", itoa(acthealed), " hit points.", " ", " ", " ");
|
||||
}
|
||||
else if (caster != this) {
|
||||
caster->FilteredMessageString(caster, Chat::NonMelee, FilterSpellDamage,
|
||||
YOU_HEAL, GetCleanName(), itoa(acthealed));
|
||||
|
||||
if (curhp < maxhp) {
|
||||
if ((curhp + amount) > maxhp)
|
||||
curhp = maxhp;
|
||||
else
|
||||
curhp += amount;
|
||||
SetHP(curhp);
|
||||
}
|
||||
}
|
||||
#endif // BOTS
|
||||
|
||||
SendHPUpdate();
|
||||
}
|
||||
else {
|
||||
Message(Chat::NonMelee, "You have been healed for %d points of damage.", acthealed);
|
||||
}
|
||||
}
|
||||
|
||||
if (curhp < maxhp) {
|
||||
if ((curhp + amount) > maxhp)
|
||||
curhp = maxhp;
|
||||
else
|
||||
curhp += amount;
|
||||
SetHP(curhp);
|
||||
|
||||
SendHPUpdate();
|
||||
}
|
||||
}
|
||||
|
||||
//proc chance includes proc bonus
|
||||
|
||||
+770
-18
@@ -20,6 +20,7 @@
|
||||
|
||||
#include "bot.h"
|
||||
#include "object.h"
|
||||
#include "raids.h"
|
||||
#include "doors.h"
|
||||
#include "quest_parser_collection.h"
|
||||
#include "lua_parser.h"
|
||||
@@ -27,6 +28,7 @@
|
||||
#include "../common/say_link.h"
|
||||
|
||||
extern volatile bool is_zone_loaded;
|
||||
extern bool Critical;
|
||||
|
||||
// This constructor is used during the bot create command
|
||||
Bot::Bot(NPCType *npcTypeData, Client* botOwner) : NPC(npcTypeData, nullptr, glm::vec4(), Ground, false), rest_timer(1), ping_timer(1) {
|
||||
@@ -2123,7 +2125,11 @@ bool Bot::Process()
|
||||
}
|
||||
|
||||
// Bot AI
|
||||
AI_Process();
|
||||
Raid* bot_raid = entity_list.GetRaidByBotName(this->GetName());
|
||||
if (bot_raid)
|
||||
AI_Process_Raid();
|
||||
else
|
||||
AI_Process();
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -2362,11 +2368,11 @@ void Bot::AI_Process()
|
||||
|
||||
Client* bot_owner = (GetBotOwner() && GetBotOwner()->IsClient() ? GetBotOwner()->CastToClient() : nullptr);
|
||||
Group* bot_group = GetGroup();
|
||||
|
||||
|
||||
//#pragma region PRIMARY AI SKIP CHECKS
|
||||
|
||||
// Primary reasons for not processing AI
|
||||
if (!bot_owner || !bot_group || !IsAIControlled()) {
|
||||
if (!bot_owner || (!bot_group) || !IsAIControlled()) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -2379,7 +2385,12 @@ void Bot::AI_Process()
|
||||
}
|
||||
|
||||
// We also need a leash owner and follow mob (subset of primary AI criteria)
|
||||
Client* leash_owner = (bot_group->GetLeader() && bot_group->GetLeader()->IsClient() ? bot_group->GetLeader()->CastToClient() : bot_owner);
|
||||
Client* leash_owner = nullptr;
|
||||
|
||||
if (bot_group) {
|
||||
leash_owner = (bot_group->GetLeader() && bot_group->GetLeader()->IsClient() ? bot_group->GetLeader()->CastToClient() : bot_owner);
|
||||
}
|
||||
|
||||
if (!leash_owner) {
|
||||
return;
|
||||
}
|
||||
@@ -3810,7 +3821,7 @@ void Bot::Depop() {
|
||||
entity_list.RemoveFromHateLists(this);
|
||||
if(HasGroup())
|
||||
Bot::RemoveBotFromGroup(this, GetGroup());
|
||||
|
||||
|
||||
if(HasPet())
|
||||
GetPet()->Depop();
|
||||
|
||||
@@ -3865,7 +3876,13 @@ bool Bot::Spawn(Client* botCharacterOwner) {
|
||||
this->SendWearChange(materialFromSlot);
|
||||
}
|
||||
}
|
||||
Raid* raid = entity_list.GetRaidByBotName(this->GetName());
|
||||
|
||||
if (raid)
|
||||
{
|
||||
raid->VerifyRaid();
|
||||
this->SetRaidGrouped(true);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -4727,7 +4744,24 @@ bool Bot::Death(Mob *killerMob, int32 damage, uint16 spell_id, EQ::skills::Skill
|
||||
my_owner->CastToClient()->SetBotPulling(false);
|
||||
}
|
||||
|
||||
Raid* raid = entity_list.GetRaidByBotName(this->GetName());
|
||||
|
||||
if (raid)
|
||||
{
|
||||
|
||||
for (int x = 0; x < MAX_RAID_MEMBERS; x++)
|
||||
{
|
||||
if (strcmp(raid->members[x].membername, this->GetName()) == 0)
|
||||
{
|
||||
raid->members[x].member = nullptr;
|
||||
}
|
||||
}
|
||||
}
|
||||
// else
|
||||
// {
|
||||
entity_list.RemoveBot(this->GetID());
|
||||
// }
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -6692,7 +6726,7 @@ int32 Bot::GetActSpellDamage(uint16 spell_id, int32 value, Mob* target) {
|
||||
if (spells[spell_id].target_type == ST_Self)
|
||||
return value;
|
||||
|
||||
bool Critical = false;
|
||||
Critical = false;
|
||||
int32 value_BaseEffect = 0;
|
||||
value_BaseEffect = (value + (value*GetBotFocusEffect(focusFcBaseEffects, spell_id) / 100));
|
||||
// Need to scale HT damage differently after level 40! It no longer scales by the constant value in the spell file. It scales differently, instead of 10 more damage per level, it does 30 more damage per level. So we multiply the level minus 40 times 20 if they are over level 40.
|
||||
@@ -6737,8 +6771,9 @@ int32 Bot::GetActSpellDamage(uint16 spell_id, int32 value, Mob* target) {
|
||||
|
||||
if(itembonuses.SpellDmg && spells[spell_id].classes[(GetClass() % 17) - 1] >= GetLevel() - 5)
|
||||
value += (GetExtraSpellAmt(spell_id, itembonuses.SpellDmg, value) * ratio / 100);
|
||||
|
||||
entity_list.MessageClose(this, false, 100, Chat::SpellCrit, "%s delivers a critical blast! (%d)", GetName(), -value);
|
||||
//Mitch
|
||||
//if (!RuleB(Bots, DisplaySpellDamage))
|
||||
entity_list.MessageClose(this, false, 100, Chat::SpellCrit, "%s\'s %s delivers a critical blast to %s! (%d)", GetName(), spells[spell_id].name, target->GetCleanName(), -value);
|
||||
|
||||
return value;
|
||||
}
|
||||
@@ -6769,7 +6804,7 @@ int32 Bot::GetActSpellHealing(uint16 spell_id, int32 value, Mob* target) {
|
||||
int32 value_BaseEffect = 0;
|
||||
int32 chance = 0;
|
||||
int8 modifier = 1;
|
||||
bool Critical = false;
|
||||
Critical = false; //mitch
|
||||
value_BaseEffect = (value + (value*GetBotFocusEffect(focusFcBaseEffects, spell_id) / 100));
|
||||
value = value_BaseEffect;
|
||||
value += int(value_BaseEffect*GetBotFocusEffect(focusImprovedHeal, spell_id) / 100);
|
||||
@@ -7411,11 +7446,27 @@ bool Bot::DoFinishedSpellSingleTarget(uint16 spell_id, Mob* spellTarget, EQ::spe
|
||||
|
||||
bool Bot::DoFinishedSpellGroupTarget(uint16 spell_id, Mob* spellTarget, EQ::spells::CastingSlot slot, bool& stopLogic) {
|
||||
bool isMainGroupMGB = false;
|
||||
Raid* raid = entity_list.GetRaidByBotName(this->GetName());
|
||||
|
||||
if(isMainGroupMGB && (GetClass() != BARD)) {
|
||||
BotGroupSay(this, "MGB %s", spells[spell_id].name);
|
||||
SpellOnTarget(spell_id, this);
|
||||
entity_list.AESpell(this, this, spell_id, true);
|
||||
} else {
|
||||
}
|
||||
else if (raid)
|
||||
{
|
||||
//for (auto& iter : raid->GetRaidGroupMembers(raid->GetGroup(this->GetName()))) {
|
||||
std::vector<RaidMember> raid_group_members = raid->GetRaidGroupMembers(raid->GetGroup(this->GetName()));
|
||||
for (std::vector<RaidMember>::iterator iter = raid_group_members.begin(); iter != raid_group_members.end(); ++iter) {
|
||||
if (iter->member) {
|
||||
SpellOnTarget(spell_id, iter->member);
|
||||
if (iter->member && iter->member->GetPetID())
|
||||
SpellOnTarget(spell_id, iter->member ->GetPet());
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Group *g = GetGroup();
|
||||
if(g) {
|
||||
for(int i = 0; i < MAX_GROUP_MEMBERS; ++i) {
|
||||
@@ -8084,6 +8135,16 @@ void Bot::Camp(bool databaseSave) {
|
||||
//auto group = GetGroup();
|
||||
if(GetGroup())
|
||||
RemoveBotFromGroup(this, GetGroup());
|
||||
|
||||
//Mitch
|
||||
Raid* bot_raid = entity_list.GetRaidByBotName(this->GetName());
|
||||
if (bot_raid) {
|
||||
uint32 gid = bot_raid->GetGroup(this->GetName());
|
||||
bot_raid->SendRaidGroupRemove(this->GetName(), bot_raid->GetGroup(this->GetName()));
|
||||
bot_raid->RemoveMember(this->GetName());
|
||||
bot_raid->GroupUpdate(gid);
|
||||
}
|
||||
|
||||
|
||||
// RemoveBotFromGroup() code is too complicated for this to work as-is (still needs to be addressed to prevent memory leaks)
|
||||
//if (group->GroupCount() < 2)
|
||||
@@ -8098,9 +8159,14 @@ void Bot::Camp(bool databaseSave) {
|
||||
}
|
||||
|
||||
void Bot::Zone() {
|
||||
if(HasGroup())
|
||||
Raid* raid = entity_list.GetRaidByBotName(this->GetName());
|
||||
if (raid) {
|
||||
raid->MemberZoned(this->CastToClient());
|
||||
}
|
||||
else if (HasGroup()) {
|
||||
GetGroup()->MemberZoned(this);
|
||||
|
||||
}
|
||||
|
||||
Save();
|
||||
Depop();
|
||||
}
|
||||
@@ -8304,8 +8370,9 @@ Bot* Bot::GetBotByBotClientOwnerAndBotName(Client* c, std::string botName) {
|
||||
|
||||
void Bot::ProcessBotGroupInvite(Client* c, std::string botName) {
|
||||
if(c) {
|
||||
// Bot* invitedBot = GetBotByBotClientOwnerAndBotName(entity_list.GetBotByBotName(botName)->GetOwner()->CastToClient(), botName);
|
||||
Bot* invitedBot = GetBotByBotClientOwnerAndBotName(c, botName);
|
||||
|
||||
//Mitch changed entity from c
|
||||
if(invitedBot && !invitedBot->HasGroup()) {
|
||||
if(!c->IsGrouped()) {
|
||||
Group *g = new Group(c);
|
||||
@@ -8349,7 +8416,11 @@ void Bot::ProcessClientZoneChange(Client* botOwner) {
|
||||
Bot* tempBot = *itr;
|
||||
|
||||
if(tempBot) {
|
||||
if(tempBot->HasGroup()) {
|
||||
Raid* raid = entity_list.GetRaidByBotName(tempBot->GetName());
|
||||
if (raid) {
|
||||
tempBot->Zone();
|
||||
}
|
||||
else if(tempBot->HasGroup()) {
|
||||
Group* g = tempBot->GetGroup();
|
||||
if(g && g->IsGroupMember(botOwner)) {
|
||||
if(botOwner && botOwner->IsClient()) {
|
||||
@@ -8900,11 +8971,51 @@ bool EntityList::Bot_AICheckCloseBeneficialSpells(Bot* caster, uint8 iChance, fl
|
||||
}
|
||||
}
|
||||
}
|
||||
#ifdef BOTS
|
||||
else if (caster->IsRaidGrouped())
|
||||
{
|
||||
//added raid check
|
||||
Raid* raid = entity_list.GetRaidByBotName(caster->GetName());
|
||||
uint32 gid = raid->GetGroup(caster->GetName());
|
||||
if (gid < 12) {
|
||||
std::vector<RaidMember> raid_group_members = raid->GetRaidGroupMembers(gid);
|
||||
for (std::vector<RaidMember>::iterator iter = raid_group_members.begin(); iter != raid_group_members.end(); ++iter) {
|
||||
//for (auto& iter : raid->GetRaidGroupMembers(g)) {
|
||||
if (iter->member && !iter->member->qglobal) {
|
||||
if (iter->member->IsClient() && iter->member->GetHPRatio() < 90) {
|
||||
if (caster->AICastSpell(iter->member, 100, SpellType_Heal))
|
||||
return true;
|
||||
}
|
||||
else if ((iter->member->GetClass() == WARRIOR || iter->member->GetClass() == PALADIN || iter->member->GetClass() == SHADOWKNIGHT) && iter->member->GetHPRatio() < 95) {
|
||||
if (caster->AICastSpell(iter->member, 100, SpellType_Heal))
|
||||
return true;
|
||||
}
|
||||
else if (iter->member->GetClass() == ENCHANTER && iter->member->GetHPRatio() < 80) {
|
||||
if (caster->AICastSpell(iter->member, 100, SpellType_Heal))
|
||||
return true;
|
||||
}
|
||||
else if (iter->member->GetHPRatio() < 70) {
|
||||
if (caster->AICastSpell(iter->member, 100, SpellType_Heal))
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (iter->member && !iter->member->qglobal && iter->member->HasPet() && iter->member->GetPet()->GetHPRatio() < 50) {
|
||||
if (iter->member->GetPet()->GetOwner() != caster && caster->IsEngaged() && iter->member->IsCasting() && iter->member->GetClass() != ENCHANTER)
|
||||
continue;
|
||||
|
||||
if (caster->AICastSpell(iter->member->GetPet(), 100, SpellType_Heal))
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
if( botCasterClass == PALADIN || botCasterClass == BEASTLORD || botCasterClass == RANGER) {
|
||||
if(caster->HasGroup()) {
|
||||
Group *g = caster->GetGroup();
|
||||
if(caster->HasGroup() || caster->IsRaidGrouped()) {
|
||||
float hpRatioToHeal = 25.0f;
|
||||
switch(caster->GetBotStance()) {
|
||||
case EQ::constants::stanceReactive:
|
||||
@@ -8921,6 +9032,11 @@ bool EntityList::Bot_AICheckCloseBeneficialSpells(Bot* caster, uint8 iChance, fl
|
||||
hpRatioToHeal = 25.0f;
|
||||
break;
|
||||
}
|
||||
Group* g = caster->GetGroup();
|
||||
uint32 gid = 0xff;
|
||||
Raid* raid = entity_list.GetRaidByBotName(caster->GetName());
|
||||
if (raid)
|
||||
uint32 gid = raid->GetGroup(caster->GetName());
|
||||
|
||||
if(g) {
|
||||
for(int i = 0; i < MAX_GROUP_MEMBERS; i++) {
|
||||
@@ -8949,6 +9065,39 @@ bool EntityList::Bot_AICheckCloseBeneficialSpells(Bot* caster, uint8 iChance, fl
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (gid < 12)
|
||||
{
|
||||
std::vector<RaidMember> raid_group_members = raid->GetRaidGroupMembers(gid);
|
||||
for (std::vector<RaidMember>::iterator iter = raid_group_members.begin(); iter != raid_group_members.end(); ++iter) {
|
||||
//for (auto& iter : raid->GetRaidGroupMembers(gid)) {
|
||||
if (iter->member && !iter->member->qglobal) {
|
||||
if (iter->member->IsClient() && iter->member->GetHPRatio() < hpRatioToHeal) {
|
||||
if (caster->AICastSpell(iter->member, 100, SpellType_Heal))
|
||||
return true;
|
||||
}
|
||||
else if ((iter->member->GetClass() == WARRIOR || iter->member->GetClass() == PALADIN || iter->member->GetClass() == SHADOWKNIGHT) && iter->member->GetHPRatio() < hpRatioToHeal) {
|
||||
if (caster->AICastSpell(iter->member, 100, SpellType_Heal))
|
||||
return true;
|
||||
}
|
||||
else if (iter->member->GetClass() == ENCHANTER && iter->member->GetHPRatio() < hpRatioToHeal) {
|
||||
if (caster->AICastSpell(iter->member, 100, SpellType_Heal))
|
||||
return true;
|
||||
}
|
||||
else if (iter->member->GetHPRatio() < hpRatioToHeal / 2) {
|
||||
if (caster->AICastSpell(iter->member, 100, SpellType_Heal))
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
if (iter->member && !iter->member->qglobal && iter->member->HasPet() && iter->member->GetPet()->GetHPRatio() < 25) {
|
||||
if (iter->member->GetPet()->GetOwner() != caster && caster->IsEngaged() && iter->member->IsCasting() && iter->member->GetClass() != ENCHANTER)
|
||||
continue;
|
||||
|
||||
if (caster->AICastSpell(iter->member->GetPet(), 100, SpellType_Heal))
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -8961,7 +9110,22 @@ bool EntityList::Bot_AICheckCloseBeneficialSpells(Bot* caster, uint8 iChance, fl
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
#ifdef BOTS
|
||||
//added raid check
|
||||
if (caster->IsRaidGrouped()) {
|
||||
Raid* raid = entity_list.GetRaidByBotName(caster->GetName());
|
||||
uint32 g = raid->GetGroup(caster->GetName());
|
||||
if (g < 12) {
|
||||
std::vector<RaidMember> raid_group_members = raid->GetRaidGroupMembers(g);
|
||||
for (std::vector<RaidMember>::iterator iter = raid_group_members.begin(); iter != raid_group_members.end(); ++iter) {
|
||||
if (iter->member) {
|
||||
if (caster->AICastSpell(iter->member, chanceToCast, SpellType_Buff) || caster->AICastSpell(iter->member->GetPet(), chanceToCast, SpellType_Buff))
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
if(caster->HasGroup()) {
|
||||
Group *g = caster->GetGroup();
|
||||
if(g) {
|
||||
@@ -8994,6 +9158,27 @@ bool EntityList::Bot_AICheckCloseBeneficialSpells(Bot* caster, uint8 iChance, fl
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (caster->IsRaidGrouped())
|
||||
{
|
||||
Raid* raid = entity_list.GetRaidByBotName(caster->GetName());
|
||||
uint32 gid = raid->GetGroup(caster->GetName());
|
||||
if (gid < 12) {
|
||||
std::vector<RaidMember> raid_group_members = raid->GetRaidGroupMembers(gid);
|
||||
for (std::vector<RaidMember>::iterator iter = raid_group_members.begin(); iter != raid_group_members.end(); ++iter) {
|
||||
if (iter->member && caster->GetNeedsCured(iter->member)) {
|
||||
if (caster->AICastSpell(iter->member, caster->GetChanceToCastBySpellType(SpellType_Cure), SpellType_Cure))
|
||||
return true;
|
||||
else if (botCasterClass == BARD)
|
||||
return false;
|
||||
}
|
||||
|
||||
if (iter->member && iter->member->GetPet() && caster->GetNeedsCured(iter->member->GetPet())) {
|
||||
if (caster->AICastSpell(iter->member->GetPet(), (int)caster->GetChanceToCastBySpellType(SpellType_Cure) / 4, SpellType_Cure))
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (iSpellTypes == SpellType_HateRedux) {
|
||||
@@ -9011,13 +9196,41 @@ bool EntityList::Bot_AICheckCloseBeneficialSpells(Bot* caster, uint8 iChance, fl
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (caster->IsRaidGrouped())
|
||||
{
|
||||
Raid* raid = entity_list.GetRaidByBotName(caster->GetName());
|
||||
uint32 gid = raid->GetGroup(caster->GetName());
|
||||
if (gid < 12) {
|
||||
std::vector<RaidMember> raid_group_members = raid->GetRaidGroupMembers(gid);
|
||||
for (std::vector<RaidMember>::iterator iter = raid_group_members.begin(); iter != raid_group_members.end(); ++iter) {
|
||||
if (iter->member && caster->GetNeedsHateRedux(iter->member)) {
|
||||
if (caster->AICastSpell(iter->member, caster->GetChanceToCastBySpellType(SpellType_HateRedux), SpellType_HateRedux))
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (iSpellTypes == SpellType_PreCombatBuff) {
|
||||
if (botCasterClass == BARD || caster->IsEngaged())
|
||||
return false;
|
||||
|
||||
if (caster->HasGroup()) {
|
||||
//added raid check
|
||||
if (caster->IsRaidGrouped()) {
|
||||
Raid* raid = entity_list.GetRaidByBotName(caster->GetName());
|
||||
uint32 g = raid->GetGroup(caster->GetName());
|
||||
if (g < 12) {
|
||||
std::vector<RaidMember> raid_group_members = raid->GetRaidGroupMembers(g);
|
||||
for (std::vector<RaidMember>::iterator iter = raid_group_members.begin(); iter != raid_group_members.end(); ++iter) {
|
||||
if (iter->member) {
|
||||
if (caster->AICastSpell(iter->member, iChance, SpellType_PreCombatBuff) || caster->AICastSpell(iter->member->GetPet(), iChance, SpellType_PreCombatBuff))
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (caster->HasGroup()) {
|
||||
Group *g = caster->GetGroup();
|
||||
if (g) {
|
||||
for (int i = 0; i < MAX_GROUP_MEMBERS; i++) {
|
||||
@@ -9808,4 +10021,543 @@ void Bot::StopMoving(float new_heading)
|
||||
|
||||
uint8 Bot::spell_casting_chances[SPELL_TYPE_COUNT][PLAYER_CLASS_COUNT][EQ::constants::STANCE_TYPE_COUNT][cntHSND] = { 0 };
|
||||
|
||||
void Bot::ProcessRaidInvite(Client* invitee, Client* invitor) {
|
||||
|
||||
if (!invitee || !invitor)
|
||||
return;
|
||||
|
||||
Raid* raid = entity_list.GetRaidByClient(invitor);
|
||||
Group* g_invitee = invitee->GetGroup();
|
||||
Group* g_invitor = invitor->GetGroup();
|
||||
|
||||
if (raid)
|
||||
{
|
||||
if (g_invitee)
|
||||
{
|
||||
//As there is already a raid, just add this group
|
||||
raid->SendBulkRaid(invitee);
|
||||
raid->SendMakeLeaderPacketTo(raid->leadername, invitee); //added to resolve Basic's raid window not showing a raid leader
|
||||
uint32 raid_free_group_id = raid->GetFreeGroup();
|
||||
for (int x = 0; x < 6; x++) {
|
||||
if (g_invitee->members[x]) {
|
||||
Client* c = nullptr;
|
||||
Bot* b = nullptr;
|
||||
if (g_invitee->members[x] && g_invitee->members[x]->IsBot()) {
|
||||
b = g_invitee->members[x]->CastToBot();
|
||||
if (x == 0) {
|
||||
raid->AddBot(b, raid_free_group_id, false, true, false);
|
||||
raid->SetGroupLeader(b->GetName());
|
||||
}
|
||||
else {
|
||||
raid->AddBot(b, raid_free_group_id, false, false, false);
|
||||
}
|
||||
}
|
||||
else if (g_invitee->members[x] && g_invitee->members[x]->IsClient()) {
|
||||
c = g_invitee->members[x]->CastToClient();
|
||||
if (x == 0) {
|
||||
raid->SendRaidCreate(c);
|
||||
raid->SendMakeLeaderPacketTo(raid->leadername, c);
|
||||
raid->AddMember(c, raid_free_group_id, false, true, false);
|
||||
raid->SetGroupLeader(c->GetName());
|
||||
if (raid->IsLocked()) {
|
||||
raid->SendRaidLockTo(c);
|
||||
}
|
||||
}
|
||||
else {
|
||||
raid->SendRaidCreate(c);
|
||||
raid->SendMakeLeaderPacketTo(raid->leadername, c);
|
||||
raid->AddMember(c, raid_free_group_id, false, false, false);
|
||||
if (raid->IsLocked()) {
|
||||
raid->SendRaidLockTo(c);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
raid->GroupUpdate(raid_free_group_id);
|
||||
// raid->SendBulkRaid(invitor); //Send a raid updates to the invitor
|
||||
g_invitee->JoinRaidXTarget(raid, true);
|
||||
g_invitee->DisbandGroup(true);
|
||||
if (raid->IsLocked()) {
|
||||
raid->SendRaidLockTo(invitor);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
//As there is already a raid and no group, just add this single client
|
||||
raid->SendRaidCreate(invitee);
|
||||
raid->AddMember(invitee);
|
||||
raid->SendMakeLeaderPacketTo(raid->leadername, invitee); //moved to be after the addmember to resolve raid window not showing a raid leader
|
||||
if (raid->IsLocked()) {
|
||||
raid->SendRaidLockTo(invitee);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
//As there is no raid
|
||||
//First, create the raid
|
||||
raid = new Raid(invitor);
|
||||
entity_list.AddRaid(raid);
|
||||
raid->SetRaidDetails();
|
||||
raid->SendRaidCreate(invitor);
|
||||
raid->SendMakeLeaderPacketTo(raid->leadername, invitor); //added to resolve no raid leader shown in Rola's raid window
|
||||
|
||||
if (g_invitor)
|
||||
{
|
||||
//Second, add the invitor group as group 0
|
||||
for (int x = 0; x < 6; x++) {
|
||||
if (g_invitor->members[x]) {
|
||||
Client* c = nullptr;
|
||||
Bot* b = nullptr;
|
||||
if (g_invitor->members[x] && g_invitor->members[x]->IsBot()) {
|
||||
b = g_invitor->members[x]->CastToBot();
|
||||
if (x == 0) {
|
||||
raid->AddBot(b, 0, false, true, false);
|
||||
raid->SetGroupLeader(b->GetName());
|
||||
raid->GroupUpdate(0);
|
||||
}
|
||||
else {
|
||||
raid->AddBot(b, 0, false, false, false);
|
||||
raid->GroupUpdate(0);
|
||||
}
|
||||
}
|
||||
else if (g_invitor->members[x] && g_invitor->members[x]->IsClient()) {
|
||||
c = g_invitor->members[x]->CastToClient();
|
||||
if (x == 0) {
|
||||
raid->SendRaidCreate(c);
|
||||
raid->SendMakeLeaderPacketTo(raid->leadername, c);
|
||||
raid->AddMember(c, 0, false, true, false);
|
||||
raid->SetGroupLeader(c->GetName());
|
||||
raid->GroupUpdate(0);
|
||||
if (raid->IsLocked()) {
|
||||
raid->SendRaidLockTo(c);
|
||||
}
|
||||
}
|
||||
else {
|
||||
raid->SendRaidCreate(c);
|
||||
raid->SendMakeLeaderPacketTo(raid->leadername, c);
|
||||
raid->AddMember(c, 0, false, false, false);
|
||||
raid->GroupUpdate(0);
|
||||
if (raid->IsLocked()) {
|
||||
raid->SendRaidLockTo(c);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
raid->GroupUpdate(0);
|
||||
raid->SendBulkRaid(invitee); //Send a raid updates to the invitor
|
||||
g_invitor->JoinRaidXTarget(raid, true);
|
||||
g_invitor->DisbandGroup(true);
|
||||
if (raid->IsLocked()) {
|
||||
raid->SendRaidLockTo(invitor);
|
||||
}
|
||||
if (g_invitee)
|
||||
{
|
||||
//Third, add the invitee group
|
||||
uint32 raid_free_group_id = raid->GetFreeGroup();
|
||||
for (int x = 0; x < 6; x++) {
|
||||
if (g_invitee->members[x]) {
|
||||
Client* c = nullptr;
|
||||
Bot* b = nullptr;
|
||||
if (g_invitee->members[x] && g_invitee->members[x]->IsBot()) {
|
||||
b = g_invitee->members[x]->CastToBot();
|
||||
if (x == 0) {
|
||||
raid->AddBot(b, raid_free_group_id, false, true, false);
|
||||
raid->SetGroupLeader(b->GetName());
|
||||
raid->GroupUpdate(raid_free_group_id);
|
||||
}
|
||||
else {
|
||||
raid->AddBot(b, raid_free_group_id, false, false, false);
|
||||
raid->GroupUpdate(raid_free_group_id);
|
||||
}
|
||||
}
|
||||
else if (g_invitee->members[x] && g_invitee->members[x]->IsClient()) {
|
||||
c = g_invitee->members[x]->CastToClient();
|
||||
if (x == 0) {
|
||||
raid->SendRaidCreate(c);
|
||||
raid->SendMakeLeaderPacketTo(raid->leadername, c);
|
||||
raid->AddMember(c, raid_free_group_id, false, true, false);
|
||||
raid->SetGroupLeader(c->GetName());
|
||||
raid->GroupUpdate(raid_free_group_id);
|
||||
if (raid->IsLocked()) {
|
||||
raid->SendRaidLockTo(c);
|
||||
}
|
||||
}
|
||||
else {
|
||||
raid->SendRaidCreate(c);
|
||||
raid->SendMakeLeaderPacketTo(raid->leadername, c);
|
||||
raid->AddMember(c, raid_free_group_id, false, false, false);
|
||||
raid->GroupUpdate(raid_free_group_id);
|
||||
if (raid->IsLocked()) {
|
||||
raid->SendRaidLockTo(c);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
raid->GroupUpdate(raid_free_group_id);
|
||||
// raid->SendBulkRaid(invitee); //Send a raid updates to the invitee
|
||||
g_invitee->JoinRaidXTarget(raid, true);
|
||||
g_invitee->DisbandGroup(true);
|
||||
if (raid->IsLocked()) {
|
||||
raid->SendRaidLockTo(invitor);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
//Third, no group so add the single client
|
||||
raid->SendRaidCreate(invitee);
|
||||
raid->SendMakeLeaderPacketTo(raid->leadername, invitee);
|
||||
raid->AddMember(invitee);
|
||||
// raid->SendBulkRaid(invitee);
|
||||
if (raid->IsLocked()) {
|
||||
raid->SendRaidLockTo(invitee);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
//Second, add the single invitor
|
||||
raid->SendRaidCreate(invitor);
|
||||
raid->SendMakeLeaderPacketTo(raid->leadername, invitor);
|
||||
raid->AddMember(invitor, 0xFFFFFFFF, true, false, true);
|
||||
raid->SendBulkRaid(invitee); //Send a raid updates to the invitee
|
||||
if (raid->IsLocked()) {
|
||||
raid->SendRaidLockTo(invitor);
|
||||
}
|
||||
if (g_invitee)
|
||||
{
|
||||
//Third, add the invitee group
|
||||
uint32 raid_free_group_id = raid->GetFreeGroup();
|
||||
for (int x = 0; x < 6; x++) {
|
||||
if (g_invitee->members[x]) {
|
||||
Client* c = nullptr;
|
||||
Bot* b = nullptr;
|
||||
if (g_invitee->members[x] && g_invitee->members[x]->IsBot()) {
|
||||
b = g_invitee->members[x]->CastToBot();
|
||||
if (x == 0) {
|
||||
raid->AddBot(b, raid_free_group_id, false, true, false);
|
||||
raid->SetGroupLeader(b->GetName());
|
||||
raid->GroupUpdate(raid_free_group_id);
|
||||
}
|
||||
else {
|
||||
raid->AddBot(b, raid_free_group_id, false, false, false);
|
||||
raid->GroupUpdate(raid_free_group_id);
|
||||
}
|
||||
}
|
||||
else if (g_invitee->members[x] && g_invitee->members[x]->IsClient()) {
|
||||
c = g_invitee->members[x]->CastToClient();
|
||||
if (x == 0) {
|
||||
raid->SendRaidCreate(c);
|
||||
raid->SendMakeLeaderPacketTo(raid->leadername, c);
|
||||
raid->AddMember(c, raid_free_group_id, false, true, false);
|
||||
raid->SetGroupLeader(c->GetName());
|
||||
raid->GroupUpdate(raid_free_group_id);
|
||||
if (raid->IsLocked()) {
|
||||
raid->SendRaidLockTo(c);
|
||||
}
|
||||
}
|
||||
else {
|
||||
raid->SendRaidCreate(c);
|
||||
raid->SendMakeLeaderPacketTo(raid->leadername, c);
|
||||
raid->AddMember(c, raid_free_group_id, false, false, false);
|
||||
raid->GroupUpdate(raid_free_group_id);
|
||||
if (raid->IsLocked()) {
|
||||
raid->SendRaidLockTo(c);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
raid->GroupUpdate(raid_free_group_id);
|
||||
g_invitee->JoinRaidXTarget(raid, true);
|
||||
g_invitee->DisbandGroup(true);
|
||||
if (raid->IsLocked()) {
|
||||
raid->SendRaidLockTo(invitor);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
//Third, no group so add the single client invitee
|
||||
raid->SendRaidCreate(invitee);
|
||||
raid->SendMakeLeaderPacketTo(raid->leadername, invitee);
|
||||
raid->AddMember(invitee);
|
||||
if (raid->IsLocked()) {
|
||||
raid->SendRaidLockTo(invitee);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Bot::ProcessRaidInvite(Bot* invitee, Client* invitor) {
|
||||
|
||||
if (!invitee || !invitor)
|
||||
return;
|
||||
|
||||
Raid* raid = entity_list.GetRaidByClient(invitor);
|
||||
Group* g_invitee = invitee->GetGroup();
|
||||
Group* g_invitor = invitor->GetGroup();
|
||||
|
||||
if (raid)
|
||||
{
|
||||
if (g_invitee)
|
||||
{
|
||||
//As there is already a raid, just add this group
|
||||
uint32 raid_free_group_id = raid->GetFreeGroup();
|
||||
for (int x = 0; x < 6; x++) {
|
||||
if (g_invitee->members[x]) {
|
||||
Client* c = nullptr;
|
||||
Bot* b = nullptr;
|
||||
if (g_invitee->members[x] && g_invitee->members[x]->IsBot()) {
|
||||
b = g_invitee->members[x]->CastToBot();
|
||||
if (x == 0) {
|
||||
raid->AddBot(b, raid_free_group_id, false, true, false);
|
||||
raid->SetGroupLeader(b->GetName());
|
||||
raid->GroupUpdate(raid_free_group_id);
|
||||
}
|
||||
else {
|
||||
raid->AddBot(b, raid_free_group_id, false, false, false);
|
||||
raid->GroupUpdate(raid_free_group_id);
|
||||
}
|
||||
}
|
||||
else if (g_invitee->members[x] && g_invitee->members[x]->IsClient()) {
|
||||
c = g_invitee->members[x]->CastToClient();
|
||||
if (x == 0) {
|
||||
raid->SendRaidCreate(c);
|
||||
raid->SendMakeLeaderPacketTo(raid->leadername, c);
|
||||
raid->AddMember(c, raid_free_group_id, false, true, false);
|
||||
raid->SetGroupLeader(c->GetName());
|
||||
raid->GroupUpdate(raid_free_group_id);
|
||||
if (raid->IsLocked()) {
|
||||
raid->SendRaidLockTo(c);
|
||||
}
|
||||
}
|
||||
else {
|
||||
raid->SendRaidCreate(c);
|
||||
raid->SendMakeLeaderPacketTo(raid->leadername, c);
|
||||
raid->AddMember(c, raid_free_group_id, false, false, false);
|
||||
raid->GroupUpdate(raid_free_group_id);
|
||||
if (raid->IsLocked()) {
|
||||
raid->SendRaidLockTo(c);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// raid->SendBulkRaid(invitor); //Send a raid updates to the invitor
|
||||
g_invitee->JoinRaidXTarget(raid, true);
|
||||
g_invitee->DisbandGroup(true);
|
||||
if (raid->IsLocked()) {
|
||||
raid->SendRaidLockTo(invitor);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
//As there is already a raid and no group, just add this single client
|
||||
//raid->SendRaidCreate(invitee);
|
||||
//raid->SendMakeLeaderPacketTo(raid->leadername, invitee);
|
||||
raid->AddBot(invitee);
|
||||
//if (raid->IsLocked()) {
|
||||
// raid->SendRaidLockTo(invitee);
|
||||
//}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
//As there is no raid
|
||||
//First, create the raid
|
||||
raid = new Raid(invitor);
|
||||
entity_list.AddRaid(raid);
|
||||
raid->SetRaidDetails();
|
||||
// raid->SendRaidCreate(invitor);
|
||||
// raid->SetLeader(invitor); //Added Jan 18
|
||||
// raid->SendMakeLeaderPacketTo(raid->leadername, invitor);
|
||||
|
||||
if (g_invitor)
|
||||
{
|
||||
//Second, add the invitor group as group 0
|
||||
for (int x = 0; x < 6; x++) {
|
||||
if (g_invitor->members[x]) {
|
||||
Client* c = nullptr;
|
||||
Bot* b = nullptr;
|
||||
if (g_invitor->members[x] && g_invitor->members[x]->IsBot()) {
|
||||
b = g_invitor->members[x]->CastToBot();
|
||||
if (x == 0) {
|
||||
raid->AddBot(b, 0, false, true, false);
|
||||
raid->SetGroupLeader(b->GetName());
|
||||
//raid->GroupUpdate(0);
|
||||
}
|
||||
else {
|
||||
raid->AddBot(b, 0, false, false, false);
|
||||
//raid->GroupUpdate(0);
|
||||
b->SetFollowID(g_invitor->GetLeader()->GetID());
|
||||
}
|
||||
}
|
||||
else if (g_invitor->members[x] && g_invitor->members[x]->IsClient()) {
|
||||
c = g_invitor->members[x]->CastToClient();
|
||||
if (x == 0) {
|
||||
raid->SendRaidCreate(c);
|
||||
raid->AddMember(c, 0, true, true, true);
|
||||
raid->SendMakeLeaderPacketTo(raid->leadername, c);
|
||||
//raid->SetGroupLeader(c->GetName()); //Mitch Jan 18
|
||||
//raid->GroupUpdate(0, true);
|
||||
if (raid->IsLocked()) {
|
||||
raid->SendRaidLockTo(c);
|
||||
}
|
||||
}
|
||||
else {
|
||||
raid->SendRaidCreate(c);
|
||||
raid->SendMakeLeaderPacketTo(raid->leadername, c);
|
||||
raid->AddMember(c, 0, false, false, false);
|
||||
//raid->GroupUpdate(0, true);
|
||||
if (raid->IsLocked()) {
|
||||
raid->SendRaidLockTo(c);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// raid->GroupUpdate(0, true);
|
||||
// raid->SendBulkRaid(invitee); //Send a raid updates to the invitor
|
||||
g_invitor->JoinRaidXTarget(raid, true);
|
||||
g_invitor->DisbandGroup(true); //Added Jan 23 to fix group database and entity integrity
|
||||
raid->GroupUpdate(0, true);
|
||||
if (raid->IsLocked()) {
|
||||
raid->SendRaidLockTo(invitor);
|
||||
}
|
||||
if (g_invitee)
|
||||
{
|
||||
//Third, add the invitee group
|
||||
uint32 raid_free_group_id = raid->GetFreeGroup();
|
||||
for (int x = 0; x < 6; x++) {
|
||||
if (g_invitee->members[x]) {
|
||||
Client* c = nullptr;
|
||||
Bot* b = nullptr;
|
||||
if (g_invitee->members[x] && g_invitee->members[x]->IsBot()) {
|
||||
b = g_invitee->members[x]->CastToBot();
|
||||
if (x == 0) {
|
||||
raid->AddBot(b, raid_free_group_id, false, true, false);
|
||||
raid->SetGroupLeader(b->GetName());
|
||||
}
|
||||
else {
|
||||
raid->AddBot(b, raid_free_group_id, false, false, false);
|
||||
}
|
||||
}
|
||||
else if (g_invitee->members[x] && g_invitee->members[x]->IsClient()) {
|
||||
c = g_invitee->members[x]->CastToClient();
|
||||
if (x == 0) {
|
||||
raid->SendRaidCreate(c);
|
||||
raid->SendMakeLeaderPacketTo(raid->leadername, c);
|
||||
raid->AddMember(c, raid_free_group_id, false, true, false);
|
||||
raid->SetGroupLeader(c->GetName());
|
||||
if (raid->IsLocked()) {
|
||||
raid->SendRaidLockTo(c);
|
||||
}
|
||||
}
|
||||
else {
|
||||
raid->SendRaidCreate(c);
|
||||
raid->SendMakeLeaderPacketTo(raid->leadername, c);
|
||||
raid->AddMember(c, raid_free_group_id, false, false, false);
|
||||
if (raid->IsLocked()) {
|
||||
raid->SendRaidLockTo(c);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
//raid->SendBulkRaid(invitor); //Send a raid updates to the invitor
|
||||
g_invitee->JoinRaidXTarget(raid, true);
|
||||
g_invitee->DisbandGroup(true);
|
||||
raid->GroupUpdate(raid_free_group_id);
|
||||
if (raid->IsLocked()) {
|
||||
raid->SendRaidLockTo(invitor);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
//Third, no group so add the single client
|
||||
//raid->SendRaidCreate(invitee);
|
||||
//raid->SendMakeLeaderPacketTo(raid->leadername, invitee);
|
||||
raid->AddBot(invitee);
|
||||
// raid->SendBulkRaid(invitee);
|
||||
//if (raid->IsLocked()) {
|
||||
// raid->SendRaidLockTo(invitee);
|
||||
//}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
//Second, add the single invitor
|
||||
raid->SendRaidCreate(invitor);
|
||||
raid->AddMember(invitor, 0xFFFFFFFF, true, false, true);
|
||||
raid->SendMakeLeaderPacketTo(invitor->GetName(), invitor); //Mitch Jan 18
|
||||
if (raid->IsLocked()) {
|
||||
raid->SendRaidLockTo(invitor);
|
||||
}
|
||||
if (g_invitee)
|
||||
{
|
||||
//Third, add the invitee group
|
||||
uint32 raid_free_group_id = raid->GetFreeGroup();
|
||||
for (int x = 0; x < 6; x++) {
|
||||
if (g_invitee->members[x]) {
|
||||
Client* c = nullptr;
|
||||
Bot* b = nullptr;
|
||||
if (g_invitee->members[x] && g_invitee->members[x]->IsBot()) {
|
||||
b = g_invitee->members[x]->CastToBot();
|
||||
if (x == 0) {
|
||||
raid->AddBot(b, raid_free_group_id, false, true, false);
|
||||
raid->SetGroupLeader(b->GetName());
|
||||
}
|
||||
else {
|
||||
raid->AddBot(b, raid_free_group_id, false, false, false);
|
||||
}
|
||||
}
|
||||
else if (g_invitee->members[x] && g_invitee->members[x]->IsClient()) {
|
||||
c = g_invitee->members[x]->CastToClient();
|
||||
if (x == 0) {
|
||||
raid->SendRaidCreate(c);
|
||||
raid->SendMakeLeaderPacketTo(raid->leadername, c);
|
||||
raid->AddMember(c, raid_free_group_id, false, true, false);
|
||||
raid->SetGroupLeader(c->GetName());
|
||||
if (raid->IsLocked()) {
|
||||
raid->SendRaidLockTo(c);
|
||||
}
|
||||
}
|
||||
else {
|
||||
raid->SendRaidCreate(c);
|
||||
raid->SendMakeLeaderPacketTo(raid->leadername, c);
|
||||
raid->AddMember(c, raid_free_group_id, false, false, false);
|
||||
if (raid->IsLocked()) {
|
||||
raid->SendRaidLockTo(c);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// raid->SendBulkRaid(invitor); //Send a raid updates to the invitor
|
||||
g_invitee->JoinRaidXTarget(raid, true);
|
||||
g_invitee->DisbandGroup(true);
|
||||
raid->GroupUpdate(raid_free_group_id);
|
||||
if (raid->IsLocked()) {
|
||||
raid->SendRaidLockTo(invitor);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
//Third, no group so add the single client invitee
|
||||
//raid->SendRaidCreate(invitee);
|
||||
//raid->SendMakeLeaderPacketTo(raid->leadername, invitee);
|
||||
raid->AddBot(invitee);
|
||||
invitee->SetFollowID(invitor->GetID());
|
||||
//if (raid->IsLocked()) {
|
||||
// raid->SendRaidLockTo(invitee);
|
||||
//}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
+17
-2
@@ -35,6 +35,7 @@
|
||||
#include "../common/global_define.h"
|
||||
#include "guild_mgr.h"
|
||||
#include "worldserver.h"
|
||||
#include "raids.h"
|
||||
|
||||
#include <sstream>
|
||||
|
||||
@@ -151,8 +152,8 @@ public:
|
||||
ExtraAttackOptions *opts = nullptr);
|
||||
virtual bool HasRaid() { return (GetRaid() ? true : false); }
|
||||
virtual bool HasGroup() { return (GetGroup() ? true : false); }
|
||||
virtual Raid* GetRaid() { return entity_list.GetRaidByMob(this); }
|
||||
virtual Group* GetGroup() { return entity_list.GetGroupByMob(this); }
|
||||
virtual Raid* GetRaid() { return entity_list.GetRaidByMob(this); } // GetRaidByMob(this);
|
||||
virtual Group* GetGroup() { return entity_list.GetGroupByMob(this); } // GetGroupByMob;
|
||||
|
||||
// Common, but informal "interfaces" with Client object
|
||||
uint32 CharacterID() { return GetBotID(); } // Just returns the Bot Id
|
||||
@@ -377,6 +378,15 @@ public:
|
||||
static bool CheckDisciplineRecastTimers(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); //Mitch
|
||||
static void ProcessRaidInvite(Client* invitee, Client* invitor); //Mitch
|
||||
uint8 GetNumberNeedingHealedInRaidGroup(uint8 hpr, bool includePets); //Mitch
|
||||
inline void SetDirtyAutoHaters() { m_dirtyautohaters = true; } //Mitch
|
||||
|
||||
static std::list<BotSpell> GetBotSpellsForSpellEffect(Bot* botCaster, int spellEffect);
|
||||
static std::list<BotSpell> GetBotSpellsForSpellEffectAndTargetType(Bot* botCaster, int spellEffect, SpellTargetType targetType);
|
||||
static std::list<BotSpell> GetBotSpellsBySpellType(Bot* botCaster, uint32 spellType);
|
||||
@@ -597,6 +607,9 @@ public:
|
||||
int32 GetBaseDR() { return _baseDR; }
|
||||
int32 GetBaseCorrup() { return _baseCorrup; }
|
||||
|
||||
//Raid additions
|
||||
Raid* p_raid_instance;
|
||||
|
||||
protected:
|
||||
virtual void PetAIProcess();
|
||||
virtual void BotMeditate(bool isSitting);
|
||||
@@ -661,6 +674,7 @@ private:
|
||||
Timer m_auto_defend_timer;
|
||||
//Timer m_combat_jitter_timer;
|
||||
//bool m_combat_jitter_flag;
|
||||
bool m_dirtyautohaters;
|
||||
bool m_guard_flag;
|
||||
bool m_hold_flag;
|
||||
bool m_attack_flag;
|
||||
@@ -727,6 +741,7 @@ private:
|
||||
|
||||
public:
|
||||
static uint8 spell_casting_chances[SPELL_TYPE_COUNT][PLAYER_CLASS_COUNT][EQ::constants::STANCE_TYPE_COUNT][cntHSND];
|
||||
|
||||
};
|
||||
|
||||
#endif // BOTS
|
||||
|
||||
+12
-11
@@ -2632,19 +2632,20 @@ bool BotDatabase::LoadGroupedBotsByGroupID(const uint32 owner_id, const uint32 g
|
||||
{
|
||||
if (!group_id || !owner_id)
|
||||
return false;
|
||||
|
||||
//modified query for usecase of a BOTID sharing a CHARACTERID.
|
||||
//in this usecase, when the BOTID=CHARACTERID of BOT OWNER, this BOTID would be added to the GROUP
|
||||
query = StringFormat(
|
||||
"SELECT `charid`"
|
||||
" FROM `group_id`"
|
||||
" WHERE `groupid` = '%u'"
|
||||
" AND `charid` IN ("
|
||||
" SELECT `bot_id`"
|
||||
" FROM `bot_data`"
|
||||
" WHERE `owner_id` = '%u'"
|
||||
" )",
|
||||
"SELECT `mob_id` FROM `vw_groups` "
|
||||
"WHERE `group_id` = '%u' "
|
||||
"AND `mob_type`='B' "
|
||||
"AND `mob_id` IN (SELECT `bot_id` FROM `bot_data` WHERE `owner_id` = '%u');"
|
||||
, group_id, owner_id);
|
||||
/*query = StringFormat(
|
||||
"SELECT `charid` FROM `group_id` WHERE `groupid` = '%u'"
|
||||
" AND `charid` IN (SELECT `bot_id` FROM `bot_data` WHERE `owner_id` = '%u')"
|
||||
" AND `group_id.name` NOT IN (SELECT `name` FROM `character_data`)",
|
||||
group_id,
|
||||
owner_id
|
||||
);
|
||||
owner_id);*/
|
||||
|
||||
auto results = database.QueryDatabase(query);
|
||||
if (!results.Success())
|
||||
|
||||
+2626
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
|
||||
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,
|
||||
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) {
|
||||
|
||||
// Bot AI
|
||||
Raid* raid = entity_list.GetRaidByBotName(this->GetName());
|
||||
if (raid) {
|
||||
return AICastSpell_Raid(tar, iChance, iSpellTypes);
|
||||
//return true;
|
||||
}
|
||||
|
||||
if (!tar) {
|
||||
return false;
|
||||
}
|
||||
|
||||
+5
-4
@@ -804,9 +804,10 @@ void Client::QueuePacket(const EQApplicationPacket* app, bool ack_req, CLIENT_CO
|
||||
// todo: save packets for later use
|
||||
AddPacket(app, ack_req);
|
||||
}
|
||||
else
|
||||
if(eqs)
|
||||
eqs->QueuePacket(app, ack_req);
|
||||
else if (eqs) // && !IsBot()) //Mitch added the BoTcheck for a fail safe on trying to send a packet to a BoT!
|
||||
{
|
||||
eqs->QueuePacket(app, ack_req);
|
||||
}
|
||||
}
|
||||
|
||||
void Client::FastQueuePacket(EQApplicationPacket** app, bool ack_req, CLIENT_CONN_STATUS required_state) {
|
||||
@@ -817,7 +818,7 @@ void Client::FastQueuePacket(EQApplicationPacket** app, bool ack_req, CLIENT_CON
|
||||
return;
|
||||
}
|
||||
else {
|
||||
if(eqs)
|
||||
if(eqs) // && !IsBot()) //Mitch added
|
||||
eqs->FastQueuePacket((EQApplicationPacket **)app, ack_req);
|
||||
else if (app && (*app))
|
||||
delete *app;
|
||||
|
||||
+694
-486
File diff suppressed because it is too large
Load Diff
@@ -31,6 +31,8 @@
|
||||
#include "zone_store.h"
|
||||
#include "position.h"
|
||||
|
||||
extern bool Critical; //Mitch
|
||||
|
||||
float Mob::GetActSpellRange(uint16 spell_id, float range, bool IsBard)
|
||||
{
|
||||
float extrange = 100;
|
||||
@@ -316,6 +318,7 @@ int32 Mob::GetActSpellHealing(uint16 spell_id, int32 value, Mob* target) {
|
||||
value += value * CastToNPC()->GetSpellFocusHeal() / 100;
|
||||
}
|
||||
|
||||
Critical = false;
|
||||
int32 base_value = value;
|
||||
int16 critical_chance = 0;
|
||||
int8 critical_modifier = 1;
|
||||
|
||||
+45
-3
@@ -2088,17 +2088,17 @@ Raid *EntityList::GetRaidByID(uint32 id)
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
Raid *EntityList::GetRaidByClient(Client* client)
|
||||
Raid* EntityList::GetRaidByClient(Client* client)
|
||||
{
|
||||
if (client->p_raid_instance) {
|
||||
return client->p_raid_instance;
|
||||
}
|
||||
|
||||
std::list<Raid *>::iterator iterator;
|
||||
std::list<Raid*>::iterator iterator;
|
||||
iterator = raid_list.begin();
|
||||
|
||||
while (iterator != raid_list.end()) {
|
||||
for (auto &member : (*iterator)->members) {
|
||||
for (auto& member : (*iterator)->members) {
|
||||
if (member.member) {
|
||||
if (member.member == client) {
|
||||
client->p_raid_instance = *iterator;
|
||||
@@ -2113,6 +2113,48 @@ Raid *EntityList::GetRaidByClient(Client* client)
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
|
||||
Raid *EntityList::GetRaidByMob(Mob *mob)
|
||||
{
|
||||
std::list<Raid *>::iterator iterator;
|
||||
|
||||
@@ -198,6 +198,10 @@ public:
|
||||
Raid *GetRaidByClient(Client* client);
|
||||
Raid *GetRaidByID(uint32 id);
|
||||
Raid *GetRaidByLeaderName(const char *leader);
|
||||
#ifdef BOTS
|
||||
Raid* GetRaidByBotName(const char* name);
|
||||
Raid* GetRaidByBot(Bot* bot);
|
||||
#endif
|
||||
|
||||
Corpse *GetCorpseByOwner(Client* client);
|
||||
Corpse *GetCorpseByOwnerWithinRange(Client* client, Mob* center, int range);
|
||||
|
||||
+1
-1
@@ -1097,7 +1097,7 @@ void Raid::SplitExp(uint32 exp, Mob* other) {
|
||||
return;
|
||||
|
||||
for (unsigned int x = 0; x < MAX_RAID_MEMBERS; x++) {
|
||||
if (members[x].member != nullptr) // If Group Member is Client
|
||||
if (members[x].member != nullptr && members[x].member->CastToBot()->GetBotID() == 0) // If Group Member is Client
|
||||
{
|
||||
Client *cmember = members[x].member;
|
||||
// add exp + exp cap
|
||||
|
||||
+60
-3
@@ -248,10 +248,24 @@ bool Group::AddMember(Mob* newmember, const char *NewMemberName, uint32 Characte
|
||||
uint32 i = 0;
|
||||
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;
|
||||
}
|
||||
#else
|
||||
if (!strcasecmp(membername[i], NewMemberName))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
// Put them in the group
|
||||
@@ -1140,7 +1154,13 @@ void Group::TeleportGroup(Mob* sender, uint32 zoneID, uint16 instance_id, float
|
||||
}
|
||||
|
||||
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);
|
||||
if (!results.Success())
|
||||
return false;
|
||||
@@ -1155,7 +1175,7 @@ bool Group::LearnMembers() {
|
||||
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) {
|
||||
if(!row[0])
|
||||
continue;
|
||||
@@ -1165,7 +1185,24 @@ bool Group::LearnMembers() {
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -1176,6 +1213,22 @@ void Group::VerifyGroup() {
|
||||
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;
|
||||
for (i = 0; i < MAX_GROUP_MEMBERS; i++) {
|
||||
if (membername[i][0] == '\0') {
|
||||
@@ -1195,6 +1248,10 @@ void Group::VerifyGroup() {
|
||||
members[i] = nullptr;
|
||||
continue;
|
||||
}
|
||||
//if (them == nullptr && members[i] == nullptr) { //fixes a group bug with bots Mitch added Jan 1 2022
|
||||
// membername[i][0] = '\0';
|
||||
// continue;
|
||||
//}
|
||||
|
||||
if(them != nullptr && members[i] != them) { //our pointer is out of date... not so good.
|
||||
#if EQDEBUG >= 5
|
||||
|
||||
@@ -88,6 +88,7 @@ volatile bool RunLoops = true;
|
||||
#endif
|
||||
|
||||
extern volatile bool is_zone_loaded;
|
||||
extern bool Critical = false;
|
||||
|
||||
EntityList entity_list;
|
||||
WorldServer worldserver;
|
||||
|
||||
+1
-1
@@ -3855,7 +3855,7 @@ void Mob::QuestJournalledSay(Client *QuestInitiator, const char *str, Journal::O
|
||||
|
||||
const char *Mob::GetCleanName()
|
||||
{
|
||||
if (!strlen(clean_name)) {
|
||||
if (clean_name != NULL && !strlen(clean_name)) { //extra check added for crash condition. Mitch
|
||||
CleanMobName(GetName(), clean_name);
|
||||
}
|
||||
|
||||
|
||||
+199
-20
@@ -24,6 +24,7 @@
|
||||
#include "groups.h"
|
||||
#include "mob.h"
|
||||
#include "raids.h"
|
||||
#include "bot.h" //Mitch
|
||||
|
||||
#include "worldserver.h"
|
||||
|
||||
@@ -97,7 +98,7 @@ void Raid::AddMember(Client *c, uint32 group, bool rleader, bool groupleader, bo
|
||||
|
||||
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",
|
||||
"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);
|
||||
@@ -109,6 +110,14 @@ void Raid::AddMember(Client *c, uint32 group, bool rleader, bool groupleader, bo
|
||||
|
||||
LearnMembers();
|
||||
VerifyRaid();
|
||||
|
||||
#ifdef BOTS
|
||||
if (rleader) {
|
||||
database.SetRaidGroupLeaderInfo(group, GetID());
|
||||
UpdateRaidAAs();
|
||||
}
|
||||
else
|
||||
#endif
|
||||
if (rleader) {
|
||||
database.SetRaidGroupLeaderInfo(RAID_GROUPLESS, GetID());
|
||||
UpdateRaidAAs();
|
||||
@@ -162,6 +171,86 @@ void Raid::AddMember(Client *c, uint32 group, bool rleader, bool groupleader, bo
|
||||
worldserver.SendPacket(pack);
|
||||
safe_delete(pack);
|
||||
}
|
||||
//Mitch
|
||||
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();
|
||||
// Bots are being invited and cannot be the raid leader
|
||||
// if (rleader) {
|
||||
// database.SetRaidGroupLeaderInfo(RAID_GROUPLESS, GetID());
|
||||
// UpdateRaidAAs();
|
||||
// }
|
||||
|
||||
// Bots can be group leaders, though they do not have GroupAA
|
||||
// if (group != RAID_GROUPLESS && groupleader) {
|
||||
// database.SetRaidGroupLeaderInfo(group, GetID());
|
||||
// UpdateGroupAAs(group); //Mitch Jan 22
|
||||
// }
|
||||
|
||||
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;
|
||||
//SendRaidMOTD(b->GetOwner()->CastToClient());
|
||||
|
||||
// Mitch What to do here?
|
||||
// xtarget shit ..........
|
||||
//if (group == RAID_GROUPLESS) {
|
||||
// if (rleader) {
|
||||
// GetXTargetAutoMgr()->merge(*c->GetXTargetAutoMgr());
|
||||
// c->GetXTargetAutoMgr()->clear();
|
||||
// c->SetXTargetAutoMgr(GetXTargetAutoMgr());
|
||||
// }
|
||||
// else {
|
||||
// if (!c->GetXTargetAutoMgr()->empty()) {
|
||||
// GetXTargetAutoMgr()->merge(*c->GetXTargetAutoMgr());
|
||||
// c->GetXTargetAutoMgr()->clear();
|
||||
// c->RemoveAutoXTargets();
|
||||
// }
|
||||
|
||||
// c->SetXTargetAutoMgr(GetXTargetAutoMgr());
|
||||
|
||||
// if (!c->GetXTargetAutoMgr()->empty())
|
||||
// c->SetDirtyAutoHaters();
|
||||
// }
|
||||
//}
|
||||
|
||||
// Raid* raid_update = nullptr;
|
||||
// raid_update = b->GetOwner()->GetRaid();
|
||||
// if (raid_update) {
|
||||
// raid_update->SendHPManaEndPacketsTo(b->GetOwner()->CastToClient());
|
||||
// raid_update->SendHPManaEndPacketsFrom(b->GetOwner()->CastToClient());
|
||||
// }
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
void Raid::RemoveMember(const char *characterName)
|
||||
{
|
||||
@@ -169,6 +258,17 @@ void Raid::RemoveMember(const char *characterName)
|
||||
auto results = database.QueryDatabase(query);
|
||||
|
||||
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;
|
||||
SendRaidRemoveAll(characterName);
|
||||
SendRaidDisband(client);
|
||||
@@ -963,7 +1063,7 @@ void Raid::SendRaidAdd(const char *who, Client *to)
|
||||
|
||||
for(int x = 0; x < MAX_RAID_MEMBERS; x++)
|
||||
{
|
||||
if(strcmp(members[x].membername, who) == 0)
|
||||
if(strcmp(members[x].membername, who) == 0)// || !members[x].SentToBotOwner) //Mitch
|
||||
{
|
||||
auto outapp = new EQApplicationPacket(OP_RaidUpdate, sizeof(RaidAddMember_Struct));
|
||||
RaidAddMember_Struct *ram = (RaidAddMember_Struct*)outapp->pBuffer;
|
||||
@@ -983,12 +1083,12 @@ void Raid::SendRaidAdd(const char *who, Client *to)
|
||||
|
||||
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));
|
||||
RaidAddMember_Struct *ram = (RaidAddMember_Struct*)outapp->pBuffer;
|
||||
RaidAddMember_Struct* ram = (RaidAddMember_Struct*)outapp->pBuffer;
|
||||
ram->raidGen.action = raidAdd;
|
||||
ram->raidGen.parameter = members[x].GroupNumber;
|
||||
strcpy(ram->raidGen.leader_name, members[x].membername);
|
||||
@@ -999,6 +1099,7 @@ void Raid::SendRaidAddAll(const char *who)
|
||||
this->QueuePacket(outapp);
|
||||
safe_delete(outapp);
|
||||
return;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1111,11 +1212,14 @@ void Raid::SendBulkRaid(Client *to)
|
||||
if(!to)
|
||||
return;
|
||||
|
||||
if (members[GetPlayerIndex(to)].IsBot)
|
||||
return;
|
||||
|
||||
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 +1228,7 @@ void Raid::QueuePacket(const EQApplicationPacket *app, bool ack_req)
|
||||
{
|
||||
for(int x = 0; x < MAX_RAID_MEMBERS; x++)
|
||||
{
|
||||
if(members[x].member)
|
||||
if(members[x].member && !members[x].IsBot)
|
||||
{
|
||||
members[x].member->QueuePacket(app, ack_req);
|
||||
}
|
||||
@@ -1133,6 +1237,11 @@ void Raid::QueuePacket(const EQApplicationPacket *app, bool ack_req)
|
||||
|
||||
void Raid::SendMakeLeaderPacket(const char *who) //30
|
||||
{
|
||||
|
||||
//if (entity_list.GetBotByBotName(who) && IsRaidMemberBot(entity_list.GetBotByBotName(who)->CastToClient()))
|
||||
if (entity_list.GetBotByBotName(who) && members[GetPlayerIndex(who)].IsBot)
|
||||
return;
|
||||
|
||||
auto outapp = new EQApplicationPacket(OP_RaidUpdate, sizeof(RaidLeadershipUpdate_Struct));
|
||||
RaidLeadershipUpdate_Struct *rg = (RaidLeadershipUpdate_Struct*)outapp->pBuffer;
|
||||
rg->action = raidMakeLeader;
|
||||
@@ -1148,6 +1257,9 @@ void Raid::SendMakeLeaderPacketTo(const char *who, Client *to)
|
||||
if(!to)
|
||||
return;
|
||||
|
||||
if (members[GetPlayerIndex(who)].IsBot)
|
||||
return;
|
||||
|
||||
auto outapp = new EQApplicationPacket(OP_RaidUpdate, sizeof(RaidLeadershipUpdate_Struct));
|
||||
RaidLeadershipUpdate_Struct *rg = (RaidLeadershipUpdate_Struct*)outapp->pBuffer;
|
||||
rg->action = raidMakeLeader;
|
||||
@@ -1178,6 +1290,9 @@ void Raid::SendGroupUpdate(Client *to)
|
||||
if(!to)
|
||||
return;
|
||||
|
||||
if (members[GetPlayerIndex(to)].IsBot)
|
||||
return;
|
||||
|
||||
auto outapp = new EQApplicationPacket(OP_GroupUpdate, sizeof(GroupUpdate2_Struct));
|
||||
GroupUpdate2_Struct* gu = (GroupUpdate2_Struct*)outapp->pBuffer;
|
||||
gu->action = groupActUpdate;
|
||||
@@ -1224,7 +1339,7 @@ void Raid::GroupUpdate(uint32 gid, bool initial)
|
||||
{
|
||||
if(strlen(members[x].membername) > 0){
|
||||
if(members[x].GroupNumber == gid){
|
||||
if(members[x].member) {
|
||||
if (members[x].member) {
|
||||
SendGroupUpdate(members[x].member);
|
||||
SendGroupLeadershipAA(members[x].member, gid);
|
||||
}
|
||||
@@ -1366,6 +1481,9 @@ void Raid::SendRaidMOTDToWorld()
|
||||
|
||||
void Raid::SendGroupLeadershipAA(Client *c, uint32 gid)
|
||||
{
|
||||
if (members[GetPlayerIndex(c)].IsBot)
|
||||
return;
|
||||
|
||||
auto outapp = new EQApplicationPacket(OP_RaidUpdate, sizeof(RaidLeadershipUpdate_Struct));
|
||||
RaidLeadershipUpdate_Struct *rlaa = (RaidLeadershipUpdate_Struct *)outapp->pBuffer;
|
||||
rlaa->action = raidSetLeaderAbilities;
|
||||
@@ -1381,17 +1499,46 @@ void Raid::SendGroupLeadershipAA(Client *c, uint32 gid)
|
||||
void Raid::SendGroupLeadershipAA(uint32 gid)
|
||||
{
|
||||
for (uint32 i = 0; i < MAX_RAID_MEMBERS; i++)
|
||||
if (members[i].member && members[i].GroupNumber == gid)
|
||||
if (members[i].member && members[i].GroupNumber == gid && !members[i].IsBot)
|
||||
SendGroupLeadershipAA(members[i].member, gid);
|
||||
}
|
||||
|
||||
void Raid::SendAllRaidLeadershipAA()
|
||||
{
|
||||
for (uint32 i = 0; i < MAX_RAID_MEMBERS; i++)
|
||||
if (members[i].member)
|
||||
if (members[i].member && !members[i].IsBot)
|
||||
SendGroupLeadershipAA(members[i].member, members[i].GroupNumber);
|
||||
}
|
||||
|
||||
bool Raid::IsRaidMemberBot(Client* client)
|
||||
{
|
||||
std::string query = StringFormat("SELECT mob_type FROM vw_bot_character_mobs WHERE name = '%s' LIMIT 1",
|
||||
client->GetCleanName());
|
||||
auto results = database.QueryDatabase(query);
|
||||
|
||||
if (!results.Success())
|
||||
return true; //return true to avoid sending a packet to a non-existant client as a failsafe
|
||||
|
||||
if (results.RowCount() == 0) {
|
||||
LogError(
|
||||
"Error getting B/C info for character name [{}] for IsRaidMemberBot. Error [{}]",
|
||||
client->GetCleanName(),
|
||||
results.ErrorMessage().c_str()
|
||||
);
|
||||
return true;//return true to avoid sending a packet to a non-existant client as a failsafe
|
||||
}
|
||||
|
||||
auto row = results.begin();
|
||||
const char* c = "C";
|
||||
const char* b = "B";
|
||||
if (strcmp(row[0], c) == 0) {
|
||||
return false; // client is a client
|
||||
}
|
||||
else if (strcmp(row[0], b) == 0) {
|
||||
return true; // client is actually a bot
|
||||
}
|
||||
}
|
||||
|
||||
void Raid::LockRaid(bool lockFlag)
|
||||
{
|
||||
std::string query = StringFormat("UPDATE raid_details SET locked = %d WHERE raidid = %lu",
|
||||
@@ -1458,7 +1605,7 @@ bool Raid::LearnMembers()
|
||||
memset(members, 0, (sizeof(RaidMember)*MAX_RAID_MEMBERS));
|
||||
|
||||
std::string query = StringFormat("SELECT name, groupid, _class, level, "
|
||||
"isgroupleader, israidleader, islooter "
|
||||
"isgroupleader, israidleader, islooter, isbot "
|
||||
"FROM raid_members WHERE raidid = %lu",
|
||||
(unsigned long)GetID());
|
||||
auto results = database.QueryDatabase(query);
|
||||
@@ -1489,6 +1636,7 @@ bool Raid::LearnMembers()
|
||||
members[index].IsGroupLeader = atoi(row[4]);
|
||||
members[index].IsRaidLeader = atoi(row[5]);
|
||||
members[index].IsLooter = atoi(row[6]);
|
||||
members[index].IsBot = atoi(row[7]); //Mitch
|
||||
++index;
|
||||
}
|
||||
|
||||
@@ -1504,14 +1652,25 @@ void Raid::VerifyRaid()
|
||||
}
|
||||
else{
|
||||
Client *c = entity_list.GetClientByName(members[x].membername);
|
||||
#ifdef BOTS
|
||||
Bot* b = entity_list.GetBotByBotName(members[x].membername); //Mitch
|
||||
#endif
|
||||
if(c){
|
||||
members[x].member = c;
|
||||
members[x].IsBot = false;
|
||||
}
|
||||
else{
|
||||
#ifdef BOTS
|
||||
else if(b){
|
||||
members[x].member = b->CastToClient(); //Raid requires client* we are forcing it here to be a BOT
|
||||
members[x].IsBot = true; //Used to identify those members who are Bots
|
||||
}
|
||||
#endif
|
||||
else {
|
||||
members[x].member = nullptr;
|
||||
members[x].IsBot = false;
|
||||
}
|
||||
}
|
||||
if(members[x].IsRaidLeader){
|
||||
if(members[x].IsRaidLeader){
|
||||
if(strlen(members[x].membername) > 0){
|
||||
SetLeader(members[x].member);
|
||||
strn0cpy(leadername, members[x].membername, 64);
|
||||
@@ -1561,7 +1720,7 @@ void Raid::SendHPManaEndPacketsTo(Client *client)
|
||||
EQApplicationPacket outapp(OP_MobManaUpdate, sizeof(MobManaUpdate_Struct));
|
||||
|
||||
for(int x = 0; x < MAX_RAID_MEMBERS; x++) {
|
||||
if(members[x].member) {
|
||||
if(members[x].member && !members[x].IsBot) {
|
||||
if((members[x].member != client) && (members[x].GroupNumber == group_id)) {
|
||||
|
||||
members[x].member->CreateHPPacket(&hp_packet);
|
||||
@@ -1603,7 +1762,7 @@ void Raid::SendHPManaEndPacketsFrom(Mob *mob)
|
||||
mob->CreateHPPacket(&hpapp);
|
||||
|
||||
for(int x = 0; x < MAX_RAID_MEMBERS; x++) {
|
||||
if(members[x].member) {
|
||||
if(members[x].member && !members[x].IsBot) {
|
||||
if(!mob->IsClient() || ((members[x].member != mob->CastToClient()) && (members[x].GroupNumber == group_id))) {
|
||||
members[x].member->QueuePacket(&hpapp, false);
|
||||
if (members[x].member->ClientVersion() >= EQ::versions::ClientVersion::SoD) {
|
||||
@@ -1636,7 +1795,7 @@ void Raid::SendManaPacketFrom(Mob *mob)
|
||||
EQApplicationPacket outapp(OP_MobManaUpdate, sizeof(MobManaUpdate_Struct));
|
||||
|
||||
for (int x = 0; x < MAX_RAID_MEMBERS; x++) {
|
||||
if (members[x].member) {
|
||||
if (members[x].member && !members[x].IsBot) {
|
||||
if (!mob->IsClient() || ((members[x].member != mob->CastToClient()) && (members[x].GroupNumber == group_id))) {
|
||||
if (members[x].member->ClientVersion() >= EQ::versions::ClientVersion::SoD) {
|
||||
outapp.SetOpcode(OP_MobManaUpdate);
|
||||
@@ -1663,7 +1822,7 @@ void Raid::SendEndurancePacketFrom(Mob *mob)
|
||||
EQApplicationPacket outapp(OP_MobManaUpdate, sizeof(MobManaUpdate_Struct));
|
||||
|
||||
for (int x = 0; x < MAX_RAID_MEMBERS; x++) {
|
||||
if (members[x].member) {
|
||||
if (members[x].member && !members[x].IsBot) {
|
||||
if (!mob->IsClient() || ((members[x].member != mob->CastToClient()) && (members[x].GroupNumber == group_id))) {
|
||||
if (members[x].member->ClientVersion() >= EQ::versions::ClientVersion::SoD) {
|
||||
outapp.SetOpcode(OP_MobEnduranceUpdate);
|
||||
@@ -1770,9 +1929,14 @@ void Raid::CheckGroupMentor(uint32 group_id, Client *c)
|
||||
void Raid::SetDirtyAutoHaters()
|
||||
{
|
||||
for (int i = 0; i < MAX_RAID_MEMBERS; ++i)
|
||||
if (members[i].member)
|
||||
if (members[i].member && members[i].IsBot)
|
||||
{
|
||||
members[i].member->CastToBot()->SetDirtyAutoHaters();
|
||||
}
|
||||
else if (members[i].member && !members[i].IsBot)
|
||||
{
|
||||
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*/) {
|
||||
@@ -1791,6 +1955,9 @@ void Raid::QueueClients(Mob *sender, const EQApplicationPacket *app, bool ack_re
|
||||
if (!members[i].member->IsClient())
|
||||
continue;
|
||||
|
||||
if (members[i].IsBot)
|
||||
continue;
|
||||
|
||||
if (ignore_sender && members[i].member == sender)
|
||||
continue;
|
||||
|
||||
@@ -1853,3 +2020,15 @@ bool Raid::DoesAnyMemberHaveExpeditionLockout(
|
||||
return Expedition::HasLockoutByCharacterName(raid_member.membername, expedition_name, event_name);
|
||||
});
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -88,6 +88,16 @@ struct RaidMember{
|
||||
bool IsGroupLeader;
|
||||
bool IsRaidLeader;
|
||||
bool IsLooter;
|
||||
#ifdef BOTS
|
||||
bool IsBot = false;
|
||||
bool IsGroupHealer;
|
||||
bool IsRaidSlower;
|
||||
bool IsRaidMainAssistOne;
|
||||
bool IsRaidMainAssistTwo;
|
||||
bool IsRaidMainTank;
|
||||
bool IsRaidOffTankOne;
|
||||
bool IsRaidOffTankTwo;
|
||||
#endif
|
||||
};
|
||||
|
||||
struct GroupMentor {
|
||||
@@ -112,6 +122,12 @@ public:
|
||||
bool IsRaid() { return true; }
|
||||
|
||||
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); //Mitch
|
||||
void RaidBotGroupSay(Bot* b, uint8 language, uint8 lang_skill, const char* msg, ...); //Mitch
|
||||
static Mob* GetRaidMainAssistOneByName(const char* name);
|
||||
bool IsRaidMemberBot(Client* client);
|
||||
#endif
|
||||
void RemoveMember(const char *c);
|
||||
void DisbandRaid();
|
||||
void MoveMember(const char *name, uint32 newGroup);
|
||||
@@ -121,6 +137,7 @@ public:
|
||||
bool IsGroupLeader(const char *who);
|
||||
bool IsRaidMember(const char *name);
|
||||
void UpdateLevel(const char *name, int newLevel);
|
||||
|
||||
|
||||
uint32 GetFreeGroup();
|
||||
uint8 GroupCount(uint32 gid);
|
||||
@@ -241,6 +258,7 @@ public:
|
||||
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> GetRaidGroupMembers(uint32 gid);
|
||||
|
||||
RaidMember members[MAX_RAID_MEMBERS];
|
||||
char leadername[64];
|
||||
|
||||
+26
-1
@@ -3928,8 +3928,24 @@ bool Mob::SpellOnTarget(uint16 spell_id, Mob *spelltar, int reflect_effectivenes
|
||||
spelltar->MessageString(Chat::SpellFailure, YOU_RESIST, spells[spell_id].name);
|
||||
}
|
||||
else {
|
||||
#ifndef BOTS
|
||||
MessageString(Chat::SpellFailure, TARGET_RESISTED, spells[spell_id].name);
|
||||
spelltar->MessageString(Chat::SpellFailure, YOU_RESIST, spells[spell_id].name);
|
||||
#endif
|
||||
#ifdef BOTS
|
||||
if (this->IsBot() && IsHarmonySpell(spell_id)) {
|
||||
if (IsGrouped() && this->GetGroup()->GetLeader()->IsClient()) {
|
||||
Bot::BotGroupSay(this, "Your target RESISTED %s", spells[spell_id].name);
|
||||
}
|
||||
else {
|
||||
this->CastToBot()->GetBotOwner()->MessageString(Chat::SpellFailure, TARGET_RESISTED, spells[spell_id].name);
|
||||
}
|
||||
}
|
||||
else {
|
||||
MessageString(Chat::SpellFailure, TARGET_RESISTED, spells[spell_id].name);
|
||||
spelltar->MessageString(Chat::SpellFailure, YOU_RESIST, spells[spell_id].name);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
if (spelltar->IsAIControlled()) {
|
||||
@@ -3957,7 +3973,16 @@ bool Mob::SpellOnTarget(uint16 spell_id, Mob *spelltar, int reflect_effectivenes
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef BOTS //Added to display when a HarmonySpell was successful from a bot
|
||||
if (this->IsBot() && IsHarmonySpell(spell_id)) {
|
||||
if (IsGrouped() && this->GetGroup()->GetLeader()->IsClient()) {
|
||||
Bot::BotGroupSay(this, "Your spell was mostly successful.");
|
||||
}
|
||||
else {
|
||||
this->CastToBot()->GetBotOwner()->MessageString(Chat::SpellFailure, SLOW_MOSTLY_SUCCESSFUL);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
if (spelltar->IsClient()){
|
||||
spelltar->CastToClient()->BreakSneakWhenCastOn(this, false);
|
||||
spelltar->CastToClient()->BreakFeignDeathWhenCastOn(false);
|
||||
|
||||
Reference in New Issue
Block a user