Added bot command 'precombat' to manually set pre-combat mode rather than the 'assumption' process used before; Added rule Bot:AllowOwnerOptionAltCombat to allow admins control over its use

This commit is contained in:
Uleat 2019-10-13 22:24:06 -04:00
parent 7edfdbd9db
commit 99ee4e04d9
8 changed files with 78 additions and 25 deletions

View File

@ -596,7 +596,8 @@ RULE_INT(Bots, CasterStopMeleeLevel, 13, "Level at which caster bots stop melee
RULE_INT(Bots, AllowedClasses, 0xFFFFFFFF, "Bitmask of allowed bot classes")
RULE_INT(Bots, AllowedRaces, 0xFFFFFFFF, "Bitmask of allowed bot races")
RULE_INT(Bots, AllowedGenders, 0x3, "Bitmask of allowed bot genders")
RULE_BOOL(Bots, AllowOwnerAutoDefend, false, "When active, bots will defend their owner on enemy aggro")
RULE_BOOL(Bots, AllowOwnerOptionAltCombat, true, "When option is enabled, bots will use an auto-/shared-aggro combat model")
RULE_BOOL(Bots, AllowOwnerOptionAutoDefend, true, "When option is enabled, bots will defend their owner on enemy aggro")
RULE_REAL(Bots, LeashDistance, 562500.0f, "Distance a bot is allowed to travel from leash owner before being pulled back (squared value)")
RULE_CATEGORY_END()
#endif

View File

@ -2465,7 +2465,7 @@ void Bot::AI_Process()
//#pragma endregion
bool bo_alt_combat = bot_owner->GetBotOption(Client::booAltCombat);
bool bo_alt_combat = (RuleB(Bots, AllowOwnerOptionAltCombat) && bot_owner->GetBotOption(Client::booAltCombat));
//#pragma region ATTACK FLAG
@ -3402,7 +3402,7 @@ void Bot::AI_Process()
// 'class Client' doesn't make use of hate_list...
if (bot_owner->GetAggroCount() && bot_owner->GetBotOption(Client::booAutoDefend)) {
if (RuleB(Bots, AllowOwnerAutoDefend)) {
if (RuleB(Bots, AllowOwnerOptionAutoDefend)) {
if (NOT_HOLDING && NOT_PASSIVE) {

View File

@ -1411,6 +1411,7 @@ int bot_command_init(void)
bot_command_add("petremove", "Orders a bot to remove its charmed pet", 0, bot_subcommand_pet_remove) ||
bot_command_add("petsettype", "Orders a Magician bot to use a specified pet type", 0, bot_subcommand_pet_set_type) ||
bot_command_add("picklock", "Orders a capable bot to pick the lock of the closest door", 0, bot_command_pick_lock) ||
bot_command_add("precombat", "Sets flag used to determine pre-combat behavior", 0, bot_command_precombat) ||
bot_command_add("portal", "Orders a Wizard bot to open a magical doorway to a specified destination", 0, bot_subcommand_portal) ||
bot_command_add("pull", "Orders a designated bot to 'pull' an enemy", 0, bot_command_pull) ||
bot_command_add("release", "Releases a suspended bot's AI processing (with hate list wipe)", 0, bot_command_release) ||
@ -3752,24 +3753,30 @@ void bot_command_owner_option(Client *c, const Seperator *sep)
c->Message(m_action, "Bot 'spawn message' is now %s.", argument.c_str());
}
else if (!owner_option.compare("altcombat")) {
if (RuleB(Bots, AllowOwnerOptionAltCombat)) {
if (!argument.compare("enable")) {
c->SetBotOption(Client::booAltCombat, true);
}
else if (!argument.compare("disable")) {
c->SetBotOption(Client::booAltCombat, false);
if (!argument.compare("enable")) {
c->SetBotOption(Client::booAltCombat, true);
}
else if (!argument.compare("disable")) {
c->SetBotOption(Client::booAltCombat, false);
}
else {
c->SetBotOption(Client::booAltCombat, !c->GetBotOption(Client::booAltCombat));
}
database.botdb.SaveOwnerOption(c->CharacterID(), Client::booAltCombat, c->GetBotOption(Client::booAltCombat));
c->Message(m_action, "Bot 'alt combat' is now %s.", (c->GetBotOption(Client::booAltCombat) == true ? "enabled" : "disabled"));
}
else {
c->SetBotOption(Client::booAltCombat, !c->GetBotOption(Client::booAltCombat));
c->Message(m_fail, "Bot owner option 'altcombat' is not allowed on this server.");
}
database.botdb.SaveOwnerOption(c->CharacterID(), Client::booAltCombat, c->GetBotOption(Client::booAltCombat));
c->Message(m_action, "Bot 'alt combat' is now %s.", (c->GetBotOption(Client::booAltCombat) == true ? "enabled" : "disabled"));
}
else if (!owner_option.compare("autodefend")) {
if (RuleB(Bots, AllowOwnerAutoDefend)) {
if (RuleB(Bots, AllowOwnerOptionAutoDefend)) {
if (!argument.compare("enable")) {
c->SetBotOption(Client::booAutoDefend, true);
@ -3809,8 +3816,8 @@ void bot_command_owner_option(Client *c, const Seperator *sep)
(c->GetBotOption(Client::booStatsUpdate) ? "enabled" : "disabled"),
(c->GetBotOption(Client::booSpawnMessageSay) ? "say" : (c->GetBotOption(Client::booSpawnMessageTell) ? "tell" : "silent")),
(c->GetBotOption(Client::booSpawnMessageClassSpecific) ? "class" : "default"),
(c->GetBotOption(Client::booAltCombat) ? "enabled" : "disabled"),
(c->GetBotOption(Client::booAutoDefend) ? "enabled" : "disabled")
(RuleB(Bots, AllowOwnerOptionAltCombat) ? (c->GetBotOption(Client::booAltCombat) ? "enabled" : "disabled") : "restricted"),
(RuleB(Bots, AllowOwnerOptionAutoDefend) ? (c->GetBotOption(Client::booAutoDefend) ? "enabled" : "disabled") : "restricted")
);
c->SendPopupToClient(window_title.c_str(), window_text.c_str());
@ -3896,6 +3903,38 @@ void bot_command_pick_lock(Client *c, const Seperator *sep)
c->Message(m_action, "%i door%s attempted - %i door%s successful", door_count, ((door_count != 1) ? ("s") : ("")), open_count, ((open_count != 1) ? ("s") : ("")));
}
void bot_command_precombat(Client* c, const Seperator* sep)
{
if (helper_command_alias_fail(c, "bot_command_precombat", sep->arg[0], "precombat")) {
return;
}
if (helper_is_help_or_usage(sep->arg[1])) {
c->Message(m_usage, "usage: %s ([set | clear])", sep->arg[0]);
return;
}
if (!c->GetTarget() || !c->IsAttackAllowed(c->GetTarget())) {
c->Message(m_fail, "This command requires an attackable target.");
return;
}
std::string argument(sep->arg[1]);
if (!argument.compare("set")) {
c->SetBotPrecombat(true);
}
else if (!argument.compare("clear")) {
c->SetBotPrecombat(false);
}
else {
c->SetBotPrecombat(!c->GetBotPrecombat());
}
c->Message(m_action, "Precombat flag is now %s.", (c->GetBotPrecombat() == true ? "set" : "clear"));
}
// TODO: Rework to allow owner specificed criteria for puller
void bot_command_pull(Client *c, const Seperator *sep)
{

View File

@ -578,6 +578,7 @@ void bot_command_movement_speed(Client *c, const Seperator *sep);
void bot_command_owner_option(Client *c, const Seperator *sep);
void bot_command_pet(Client *c, const Seperator *sep);
void bot_command_pick_lock(Client *c, const Seperator *sep);
void bot_command_precombat(Client* c, const Seperator* sep);
void bot_command_pull(Client *c, const Seperator *sep);
void bot_command_release(Client *c, const Seperator *sep);
void bot_command_resistance(Client *c, const Seperator *sep);

View File

@ -1167,15 +1167,18 @@ bool Bot::AI_IdleCastCheck() {
AIautocastspell_timer->Disable(); //prevent the timer from going off AGAIN while we are casting.
bool pre_combat = false;
Mob* test_against = nullptr;
Client* test_against = nullptr;
if (HasGroup() && GetGroup()->GetLeader() && GetGroup()->GetLeader()->IsClient())
test_against = GetGroup()->GetLeader();
else if (GetOwner() && GetOwner()->IsClient())
test_against = GetOwner();
if (HasGroup() && GetGroup()->GetLeader() && GetGroup()->GetLeader()->IsClient()) {
test_against = GetGroup()->GetLeader()->CastToClient();
}
else if (GetOwner() && GetOwner()->IsClient()) {
test_against = GetOwner()->CastToClient();
}
if (test_against && test_against->GetTarget() && test_against->GetTarget()->IsNPC() && !test_against->GetTarget()->IsPet())
pre_combat = true;
if (test_against) {
pre_combat = test_against->GetBotPrecombat();
}
//Ok, IdleCastCheck depends of class.
switch (GetClass()) {

View File

@ -352,10 +352,11 @@ Client::Client(EQStreamInterface* ieqs)
bot_owner_options[booSpawnMessageSay] = false;
bot_owner_options[booSpawnMessageTell] = true;
bot_owner_options[booSpawnMessageClassSpecific] = true;
bot_owner_options[booAltCombat] = false;
bot_owner_options[booAutoDefend] = RuleB(Bots, AllowOwnerAutoDefend);
bot_owner_options[booAltCombat] = RuleB(Bots, AllowOwnerOptionAltCombat);
bot_owner_options[booAutoDefend] = RuleB(Bots, AllowOwnerOptionAutoDefend);
SetBotPulling(false);
SetBotPrecombat(false);
#endif
AI_Init();

View File

@ -1646,9 +1646,13 @@ public:
bool GetBotPulling() { return m_bot_pulling; }
void SetBotPulling(bool flag = true) { m_bot_pulling = flag; }
bool GetBotPrecombat() { return m_bot_precombat; }
void SetBotPrecombat(bool flag = true) { m_bot_precombat = flag; }
private:
bool bot_owner_options[_booCount];
bool m_bot_pulling;
bool m_bot_precombat;
#endif
};

View File

@ -3203,6 +3203,10 @@ void Mob::SetTarget(Mob *mob)
if (this->CastToClient()->admin > 200) {
this->DisplayInfo(mob);
}
#ifdef BOTS
CastToClient()->SetBotPrecombat(false); // Any change in target will nullify this flag (target == mob checked above)
#endif
}
if (IsPet() && GetOwner() && GetOwner()->IsClient()) {