mirror of
https://github.com/EQEmu/Server.git
synced 2026-05-17 07:18:37 +00:00
Implement spell AI pulling, fix throw stone
This commit is contained in:
+3
-1
@@ -834,8 +834,10 @@ RULE_BOOL(Bots, AllowMagicianEpicPet, false, "If enabled, magician bots can summ
|
||||
RULE_INT(Bots, AllowMagicianEpicPetLevel, 50, "If AllowMagicianEpicPet is enabled, bots can start using their epic pets at this level")
|
||||
RULE_INT(Bots, RequiredMagicianEpicPetItemID, 28034, "If AllowMagicianEpicPet is enabled and this is set, bots will be required to have this item ID equipped to cast their epic. Takes in to account AllowMagicianEpicPetLevel as well. Set to 0 to disable requirement")
|
||||
RULE_STRING(Bots, EpicPetSpellName, "", "'teleport_zone' in the spell to be cast for epic pets. This must be in their spell list to cast.")
|
||||
RULE_BOOL(Bots, AllowSpellPulling, true, "If enabled bots will use a spell to pull when within range. Uses PullSpellID.")
|
||||
RULE_BOOL(Bots, UseSpellPulling, true, "If enabled bots will use a spell to pull when within range. Uses PullSpellID.")
|
||||
RULE_INT(Bots, PullSpellID, 5225, "Default 5225 - Throw Stone. Spell that will be cast to pull by bots")
|
||||
RULE_BOOL(Bots, AllowRangedPulling, true, "If enabled bots will pull with their ranged items if set to ranged.")
|
||||
RULE_BOOL(Bots, AllowAISpellPulling, true, "If enabled bots will rely on their detrimental AI to pull when within range.")
|
||||
RULE_BOOL(Bots, AllowBotEquipAnyClassGear, false, "Allows Bots to wear Equipment even if their class is not valid")
|
||||
RULE_BOOL(Bots, BotArcheryConsumesAmmo, true, "Set to false to disable Archery Ammo Consumption")
|
||||
RULE_BOOL(Bots, BotThrowingConsumesAmmo, true, "Set to false to disable Throwing Ammo Consumption")
|
||||
|
||||
@@ -3279,6 +3279,25 @@ bool IsCommandedSpellType(uint16 spellType) {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool IsPullingSpellType(uint16 spellType) {
|
||||
switch (spellType) {
|
||||
case BotSpellTypes::Nuke:
|
||||
case BotSpellTypes::Lifetap:
|
||||
case BotSpellTypes::Snare:
|
||||
case BotSpellTypes::DOT:
|
||||
case BotSpellTypes::Dispel:
|
||||
case BotSpellTypes::Slow:
|
||||
case BotSpellTypes::Debuff:
|
||||
case BotSpellTypes::Stun:
|
||||
case BotSpellTypes::HateLine:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool BotSpellTypeRequiresLoS(uint16 spellType, uint8 cls) {
|
||||
switch (spellType) {
|
||||
case BotSpellTypes::Nuke:
|
||||
|
||||
+1
-1
@@ -740,7 +740,6 @@ bool IsBotSpellTypeDetrimental (uint16 spellType, uint8 cls = 0);
|
||||
bool IsBotSpellTypeBeneficial (uint16 spellType, uint8 cls = 0);
|
||||
bool IsBotSpellTypeOtherBeneficial(uint16 spellType);
|
||||
bool IsBotSpellTypeInnate (uint16 spellType);
|
||||
bool IsBotSpellType (uint16 spellType);
|
||||
bool IsAEBotSpellType(uint16 spellType);
|
||||
bool IsGroupBotSpellType(uint16 spellType);
|
||||
bool IsGroupTargetOnlyBotSpellType(uint16 spellType);
|
||||
@@ -752,6 +751,7 @@ bool SpellTypeRequiresTarget(uint16 spellType, uint16 cls = 0);
|
||||
bool SpellTypeRequiresCastChecks(uint16 spellType);
|
||||
bool SpellTypeRequiresAEChecks(uint16 spellType);
|
||||
bool IsCommandedSpellType(uint16 spellType);
|
||||
bool IsPullingSpellType(uint16 spellType);
|
||||
bool BotSpellTypeRequiresLoS(uint16 spellType, uint8 cls);
|
||||
|
||||
// These should not be used to determine spell category..
|
||||
|
||||
+36
-13
@@ -101,6 +101,7 @@ Bot::Bot(NPCType *npcTypeData, Client* botOwner) : NPC(npcTypeData, nullptr, glm
|
||||
LoadDefaultBotSettings();
|
||||
SetCastedSpellType(UINT16_MAX);
|
||||
SetCommandedSpell(false);
|
||||
SetPullingSpell(false);
|
||||
//DisableBotSpellTimers();
|
||||
|
||||
// Do this once and only in this constructor
|
||||
@@ -178,6 +179,7 @@ Bot::Bot(
|
||||
SetBotCharmer(false);
|
||||
SetCastedSpellType(UINT16_MAX);
|
||||
SetCommandedSpell(false);
|
||||
SetPullingSpell(false);
|
||||
|
||||
bool stance_flag = false;
|
||||
if (!database.botdb.LoadStance(this, stance_flag) && bot_owner) {
|
||||
@@ -2200,36 +2202,53 @@ void Bot::AI_Process()
|
||||
// PULLING FLAG (ACTIONABLE RANGE)
|
||||
|
||||
if (GetPullingFlag()) {
|
||||
if (!IsBotNonSpellFighter() && !HOLDING && AI_HasSpells() && AI_EngagedCastCheck()) {
|
||||
return;
|
||||
if (!IsBotNonSpellFighter() && !HOLDING && AI_HasSpells()) {
|
||||
SetPullingSpell(true);
|
||||
|
||||
if (AI_EngagedCastCheck()) {
|
||||
SetPullingSpell(false);
|
||||
return;
|
||||
}
|
||||
|
||||
SetPullingSpell(false);
|
||||
}
|
||||
|
||||
if (RuleB(Bots, AllowSpellPulling)) {
|
||||
if (RuleB(Bots, UseSpellPulling)) {
|
||||
uint16 pullSpell = RuleI(Bots, PullSpellID);
|
||||
|
||||
if (tar_distance <= (spells[pullSpell].range * spells[pullSpell].range)) {
|
||||
if (tar_distance <= spells[pullSpell].range) {
|
||||
StopMoving();
|
||||
|
||||
if (!TargetValidation(tar)) { return; }
|
||||
|
||||
CastSpell(pullSpell, tar->GetID());
|
||||
SetPullingSpell(false);
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
else {
|
||||
//TODO bot rewrite - add casting AI to this
|
||||
if (atCombatRange && IsBotRanged() && ranged_timer.Check(false)) {
|
||||
StopMoving(CalculateHeadingToTarget(tar->GetX(), tar->GetY()));
|
||||
if (atCombatRange) {
|
||||
if (RuleB(Bots, AllowRangedPulling) && IsBotRanged() && ranged_timer.Check(false)) {
|
||||
StopMoving(CalculateHeadingToTarget(tar->GetX(), tar->GetY()));
|
||||
|
||||
if (BotRangedAttack(tar) && CheckDoubleRangedAttack()) {
|
||||
BotRangedAttack(tar, true);
|
||||
if (BotRangedAttack(tar) && CheckDoubleRangedAttack()) {
|
||||
BotRangedAttack(tar, true);
|
||||
}
|
||||
|
||||
ranged_timer.Start();
|
||||
SetPullingSpell(false);
|
||||
|
||||
return;
|
||||
}
|
||||
else if (RuleB(Bots, AllowAISpellPulling) && !IsBotNonSpellFighter() && !HOLDING && AI_HasSpells() && AI_EngagedCastCheck()) {
|
||||
SetPullingSpell(false);
|
||||
|
||||
ranged_timer.Start();
|
||||
|
||||
return;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2624,7 +2643,7 @@ void Bot::DoAttackRounds(Mob* target, int hand) {
|
||||
NPC_FLURRY,
|
||||
GetCleanName(),
|
||||
target->GetCleanName()
|
||||
); //TODO bot rewrite - add output to others hits with flurry message
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -9346,6 +9365,10 @@ bool Bot::PrecastChecks(Mob* tar, uint16 spellType) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (IsPullingSpell() && IsPullingSpellType(spellType)) { //Skip remaining checks for commanded
|
||||
return true;
|
||||
}
|
||||
|
||||
if (GetManaRatio() < GetSpellTypeMinManaLimit(spellType) || GetManaRatio() > GetSpellTypeMaxManaLimit(spellType)) {
|
||||
LogBotPreChecksDetail("{} says, 'Cancelling cast of [{}] on [{}] due to GetSpellTypeMinManaLimit or GetSpellTypeMaxManaLimit.'", GetCleanName(), GetSpellTypeNameByID(spellType), tar->GetCleanName()); //deleteme
|
||||
return false;
|
||||
|
||||
@@ -410,6 +410,8 @@ public:
|
||||
void SetPauseAI(bool pause_flag) { _pauseAI = pause_flag; }
|
||||
bool IsCommandedSpell() const { return _commandedSpell; }
|
||||
void SetCommandedSpell(bool value) { _commandedSpell = value; }
|
||||
bool IsPullingSpell() const { return _pullingSpell; }
|
||||
void SetPullingSpell(bool value) { _pullingSpell = value; }
|
||||
|
||||
void SetGuardMode();
|
||||
void SetHoldMode();
|
||||
@@ -1083,6 +1085,7 @@ private:
|
||||
uint16 _castedSpellType;
|
||||
bool _hasLoS;
|
||||
bool _commandedSpell;
|
||||
bool _pullingSpell;
|
||||
|
||||
// Private "base stats" Members
|
||||
int32 _baseMR;
|
||||
|
||||
Reference in New Issue
Block a user