mirror of
https://github.com/EQEmu/Server.git
synced 2026-05-21 11:18:25 +00:00
Rewrite ^pull logic and handling. **MORE**
Add ^setassistee command to set who your bots will assist. Bots will always assist you first before anyone else. If the rule Bots, AllowCrossGroupRaidAssist is enabled bots will assist the group or raid main assists. Rewrites logic in handling of pull and returning to ensure bots make it back to their location.
This commit is contained in:
@@ -880,6 +880,7 @@ RULE_BOOL(Bots, AllowCommandedResurrect, true, "If enabled bots can be commanded
|
||||
RULE_BOOL(Bots, AllowCommandedSummonCorpse, true, "If enabled bots can be commanded to summon other's corpses.")
|
||||
RULE_INT(Bots, CampTimer, 25, "Number of seconds after /camp has begun before bots camp out.")
|
||||
RULE_BOOL(Bots, SendClassRaceOnHelp, true, "If enabled a reminder of how to check class/race IDs will be sent when using compatible commands.")
|
||||
RULE_BOOL(Bots, AllowCrossGroupRaidAssist, true, "If enabled bots will autodefend group or raid members set as main assist.")
|
||||
RULE_CATEGORY_END()
|
||||
|
||||
RULE_CATEGORY(Chat)
|
||||
|
||||
+133
-25
@@ -2039,6 +2039,7 @@ void Bot::AI_Process()
|
||||
|
||||
auto raid = entity_list.GetRaidByBotName(GetName());
|
||||
uint32 r_group = RAID_GROUPLESS;
|
||||
|
||||
if (raid) {
|
||||
raid->VerifyRaid();
|
||||
r_group = raid->GetGroup(GetName());
|
||||
@@ -2135,7 +2136,6 @@ void Bot::AI_Process()
|
||||
// RETURNING FLAG
|
||||
|
||||
if (GetReturningFlag()) {
|
||||
LogTestDebugDetail("#{}: {} has ReturningFlag", __LINE__, GetCleanName()); //deleteme
|
||||
ReturningFlagChecks(bot_owner, leash_owner, fm_distance);
|
||||
|
||||
return;
|
||||
@@ -2208,6 +2208,7 @@ void Bot::AI_Process()
|
||||
if (!DoLosChecks(this, tar)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (atCombatRange) {
|
||||
if (RuleB(Bots, AllowRangedPulling) && IsBotRanged() && ranged_timer.Check(false)) {
|
||||
StopMoving(CalculateHeadingToTarget(tar->GetX(), tar->GetY()));
|
||||
@@ -2244,8 +2245,8 @@ void Bot::AI_Process()
|
||||
}
|
||||
|
||||
TryPursueTarget(leash_distance, Goal);
|
||||
|
||||
return;
|
||||
//TODO bot rewrite - need pulling checks below to prevent assist
|
||||
}
|
||||
|
||||
// ENGAGED AT COMBAT RANGE
|
||||
@@ -2457,42 +2458,150 @@ bool Bot::TryAutoDefend(Client* bot_owner, float leash_distance) {
|
||||
|
||||
if (
|
||||
m_auto_defend_timer.Check() &&
|
||||
bot_owner->GetAggroCount() &&
|
||||
NOT_HOLDING &&
|
||||
NOT_PASSIVE
|
||||
) {
|
||||
auto xhaters = bot_owner->GetXTargetAutoMgr();
|
||||
XTargetAutoHaters* tempHaters;
|
||||
std::vector<XTargetAutoHaters*> assisteeHaters;
|
||||
std::vector<Client*> assisteeMembers;
|
||||
bool found = false;
|
||||
|
||||
if (xhaters && !xhaters->empty()) {
|
||||
for (auto hater_iter : xhaters->get_list()) {
|
||||
if (!hater_iter.spawn_id) {
|
||||
continue;
|
||||
}
|
||||
if (bot_owner->GetAggroCount()) {
|
||||
tempHaters = bot_owner->GetXTargetAutoMgr();
|
||||
|
||||
if (bot_owner->GetBotPulling() && bot_owner->GetTarget() && hater_iter.spawn_id == bot_owner->GetTarget()->GetID()) {
|
||||
continue;
|
||||
}
|
||||
if (tempHaters && !tempHaters->empty()) {
|
||||
assisteeHaters.emplace_back(tempHaters);
|
||||
assisteeMembers.emplace_back(bot_owner);
|
||||
}
|
||||
}
|
||||
|
||||
auto hater = entity_list.GetMob(hater_iter.spawn_id);
|
||||
if (hater && hater->CastToNPC()->IsOnHatelist(bot_owner) && !hater->IsMezzed() && DistanceSquared(hater->GetPosition(), bot_owner->GetPosition()) <= leash_distance) {
|
||||
// This is roughly equivilent to npc attacking a client pet owner
|
||||
AddToHateList(hater, 1);
|
||||
SetTarget(hater);
|
||||
SetAttackingFlag();
|
||||
if (
|
||||
(!bot_owner->GetAssistee() || !entity_list.GetClientByCharID(bot_owner->GetAssistee())) &&
|
||||
RuleB(Bots, AllowCrossGroupRaidAssist)
|
||||
) {
|
||||
XTargetAutoHaters* temp_xhaters = bot_owner->GetXTargetAutoMgr();
|
||||
bool assisteeFound = false;
|
||||
|
||||
if (HasPet() && (GetClass() != Class::Enchanter || GetPet()->GetPetType() != petAnimation || GetAA(aaAnimationEmpathy) >= 2)) {
|
||||
GetPet()->AddToHateList(hater, 1);
|
||||
GetPet()->SetTarget(hater);
|
||||
if (IsRaidGrouped()) {
|
||||
Raid* r = entity_list.GetRaidByBotName(GetName());
|
||||
if (r) {
|
||||
for (const auto& m : r->members) {
|
||||
if (
|
||||
m.member &&
|
||||
m.member->IsClient() &&
|
||||
m.member->GetAggroCount() &&
|
||||
r->IsAssister(m.member_name)
|
||||
) {
|
||||
temp_xhaters = m.member->GetXTargetAutoMgr();
|
||||
|
||||
if (!temp_xhaters || temp_xhaters->empty()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
assisteeHaters.emplace_back(temp_xhaters);
|
||||
assisteeMembers.emplace_back(m.member);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (HasGroup()) {
|
||||
Group* g = GetGroup();
|
||||
if (g) {
|
||||
for (auto& m : g->members) {
|
||||
if (
|
||||
m &&
|
||||
m->IsClient() &&
|
||||
m->CastToClient()->GetAggroCount() &&
|
||||
g->AmIMainAssist(m->GetName())
|
||||
) {
|
||||
temp_xhaters = m->CastToClient()->GetXTargetAutoMgr();
|
||||
|
||||
m_auto_defend_timer.Disable();
|
||||
if (!temp_xhaters || temp_xhaters->empty()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
return true;
|
||||
assisteeHaters.emplace_back(temp_xhaters);
|
||||
assisteeMembers.emplace_back(m->CastToClient());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (bot_owner->GetAssistee()) {
|
||||
Client* c = entity_list.GetClientByCharID(bot_owner->GetAssistee());
|
||||
|
||||
if (bot_owner->IsInGroupOrRaid(c) && c->GetAggroCount()) {
|
||||
tempHaters = bot_owner->GetXTargetAutoMgr();
|
||||
|
||||
if (tempHaters && !tempHaters->empty()) {
|
||||
assisteeHaters.emplace_back(tempHaters);
|
||||
assisteeMembers.emplace_back(c);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!assisteeHaters.empty()) {
|
||||
for (XTargetAutoHaters* xHaters : assisteeHaters) {
|
||||
if (!xHaters->empty()) {
|
||||
for (auto hater_iter : xHaters->get_list()) {
|
||||
if (!hater_iter.spawn_id) {
|
||||
continue;
|
||||
}
|
||||
|
||||
Mob* hater = nullptr;
|
||||
|
||||
for (Client* xMember : assisteeMembers) {
|
||||
if (
|
||||
xMember &&
|
||||
xMember->GetBotPulling() &&
|
||||
xMember->GetTarget() &&
|
||||
(hater_iter.spawn_id == xMember->GetTarget()->GetID())
|
||||
) {
|
||||
continue;
|
||||
}
|
||||
|
||||
hater = entity_list.GetMob(hater_iter.spawn_id);
|
||||
|
||||
if (
|
||||
hater &&
|
||||
!hater->IsMezzed() &&
|
||||
(DistanceSquared(hater->GetPosition(), bot_owner->GetPosition()) <= leash_distance) &&
|
||||
hater->CastToNPC()->IsOnHatelist(xMember)
|
||||
) {
|
||||
break;
|
||||
}
|
||||
|
||||
hater = nullptr;
|
||||
}
|
||||
|
||||
if (hater) {
|
||||
AddToHateList(hater, 1);
|
||||
SetTarget(hater);
|
||||
SetAttackingFlag();
|
||||
|
||||
if (HasPet() && (GetClass() != Class::Enchanter || GetPet()->GetPetType() != petAnimation || GetAA(aaAnimationEmpathy) >= 2)) {
|
||||
GetPet()->AddToHateList(hater, 1);
|
||||
GetPet()->SetTarget(hater);
|
||||
}
|
||||
|
||||
m_auto_defend_timer.Disable();
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -3052,6 +3161,7 @@ bool Bot::ReturningFlagChecks(Client* bot_owner, Mob* leash_owner, float fm_dist
|
||||
|
||||
Goal = follow_mob->GetPosition();
|
||||
}
|
||||
|
||||
RunTo(Goal.x, Goal.y, Goal.z);
|
||||
}
|
||||
|
||||
@@ -11283,8 +11393,6 @@ void Bot::DoCombatPositioning(
|
||||
bool behindMob,
|
||||
bool frontMob
|
||||
) {
|
||||
//LogTestDebug("{} says, 'DoCombatPositioning. {} #{}", GetCleanName(), __FILE__, __LINE__); //deleteme
|
||||
|
||||
if (HasTargetReflection()) {
|
||||
if (!IsTaunting() && !tar->IsFeared() && !tar->IsStunned()) {
|
||||
if (TryEvade(tar)) {
|
||||
|
||||
@@ -1336,6 +1336,7 @@ int bot_command_init(void)
|
||||
bot_command_add("precombat", "Sets flag used to determine pre-combat behavior", AccountStatus::Player, bot_command_precombat) ||
|
||||
bot_command_add("pull", "Orders a designated bot to 'pull' an enemy", AccountStatus::Player, bot_command_pull) ||
|
||||
bot_command_add("release", "Releases a suspended bot's AI processing (with hate list wipe)", AccountStatus::Player, bot_command_release) ||
|
||||
bot_command_add("setassistee", "Sets your target to be the person your bots assist. Bots will always assist you before others", AccountStatus::Player, bot_command_set_assistee) ||
|
||||
bot_command_add("sithppercent", "HP threshold for a bot to start sitting in combat if allowed", AccountStatus::Player, bot_command_sit_hp_percent) ||
|
||||
bot_command_add("sitincombat", "Toggles whether or a not a bot will attempt to med or sit to heal in combat", AccountStatus::Player, bot_command_sit_in_combat) ||
|
||||
bot_command_add("sitmanapercent", "Mana threshold for a bot to start sitting in combat if allowed", AccountStatus::Player, bot_command_sit_mana_percent) ||
|
||||
@@ -2243,6 +2244,7 @@ void SendSpellTypeWindow(Client* c, const Seperator* sep) {
|
||||
#include "bot_commands/precombat.cpp"
|
||||
#include "bot_commands/pull.cpp"
|
||||
#include "bot_commands/release.cpp"
|
||||
#include "bot_commands/set_assistee.cpp"
|
||||
#include "bot_commands/sit_hp_percent.cpp"
|
||||
#include "bot_commands/sit_in_combat.cpp"
|
||||
#include "bot_commands/sit_mana_percent.cpp"
|
||||
|
||||
@@ -1747,6 +1747,7 @@ void bot_command_heritage(Client *c, const Seperator *sep);
|
||||
void bot_command_inspect_message(Client *c, const Seperator *sep);
|
||||
void bot_command_list_bots(Client *c, const Seperator *sep);
|
||||
void bot_command_report(Client *c, const Seperator *sep);
|
||||
void bot_command_set_assistee(Client* c, const Seperator* sep);
|
||||
void bot_command_spawn(Client *c, const Seperator *sep);
|
||||
void bot_command_stance(Client *c, const Seperator *sep);
|
||||
void bot_command_stop_melee_level(Client *c, const Seperator *sep);
|
||||
|
||||
@@ -0,0 +1,59 @@
|
||||
#include "../bot_command.h"
|
||||
|
||||
void bot_command_set_assistee(Client* c, const Seperator* sep)
|
||||
{
|
||||
if (helper_is_help_or_usage(sep->arg[1])) {
|
||||
std::vector<std::string> description =
|
||||
{
|
||||
"Sets your bots to assist your target in addition to yourself"
|
||||
};
|
||||
|
||||
std::vector<std::string> notes =
|
||||
{
|
||||
"- Your target must be another player in your group or raid.",
|
||||
"- This needs to be set on every zone/camp you do."
|
||||
};
|
||||
|
||||
std::vector<std::string> example_format = { };
|
||||
std::vector<std::string> examples_one = { };
|
||||
std::vector<std::string> examples_two = { };
|
||||
std::vector<std::string> examples_three = { };
|
||||
|
||||
std::vector<std::string> actionables = { };
|
||||
|
||||
std::vector<std::string> options = { };
|
||||
std::vector<std::string> options_one = { };
|
||||
std::vector<std::string> options_two = { };
|
||||
std::vector<std::string> options_three = { };
|
||||
|
||||
std::string popup_text = c->SendCommandHelpWindow(
|
||||
c,
|
||||
description,
|
||||
notes,
|
||||
example_format,
|
||||
examples_one, examples_two, examples_three,
|
||||
actionables,
|
||||
options,
|
||||
options_one, options_two, options_three
|
||||
);
|
||||
|
||||
popup_text = DialogueWindow::Table(popup_text);
|
||||
|
||||
c->SendPopupToClient(sep->arg[0], popup_text.c_str());
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
Mob* assistee = c->GetTarget();
|
||||
|
||||
if (assistee && assistee->IsClient() && c->IsInGroupOrRaid(assistee)) {
|
||||
c->SetAssistee(assistee->CastToClient()->CharacterID());
|
||||
c->Message(Chat::Green, "Your bots will now assist %s.", assistee->GetCleanName());
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
c->Message(Chat::Yellow, "You can only set your bots to assist clients that are in your group or raid.");
|
||||
|
||||
return;
|
||||
}
|
||||
@@ -2221,6 +2221,8 @@ public:
|
||||
|
||||
bool GetBotPulling() { return m_bot_pulling; }
|
||||
void SetBotPulling(bool flag = true) { m_bot_pulling = flag; }
|
||||
uint32 GetAssistee() { return _assistee; }
|
||||
void SetAssistee(uint32 id = 0) { _assistee = id; }
|
||||
|
||||
bool GetBotPrecombat() { return m_bot_precombat; }
|
||||
void SetBotPrecombat(bool flag = true) { m_bot_precombat = flag; }
|
||||
@@ -2257,6 +2259,7 @@ private:
|
||||
uint8 cure_min_threshold;
|
||||
uint8 cure_threshold;
|
||||
bool illusion_block;
|
||||
uint32 _assistee;
|
||||
|
||||
bool CanTradeFVNoDropItem();
|
||||
void SendMobPositions();
|
||||
|
||||
Reference in New Issue
Block a user