mirror of
https://github.com/mod-playerbots/mod-playerbots.git
synced 2026-01-22 21:16:24 +00:00
Auto avoid aoe config
This commit is contained in:
@@ -322,6 +322,9 @@ AiPlayerbot.AutoSaveMana = 1
|
|||||||
# Default: 60 (60%)
|
# Default: 60 (60%)
|
||||||
AiPlayerbot.SaveManaThreshold = 60
|
AiPlayerbot.SaveManaThreshold = 60
|
||||||
|
|
||||||
|
# Enable auto avoid aoe (experimental)
|
||||||
|
# Default: 0 (disable)
|
||||||
|
AiPlayerbot.AutoAvoidAoe = 0
|
||||||
|
|
||||||
# Random bot default strategies (applied after defaults)
|
# Random bot default strategies (applied after defaults)
|
||||||
AiPlayerbot.RandomBotCombatStrategies = "+dps,+dps assist,-threat"
|
AiPlayerbot.RandomBotCombatStrategies = "+dps,+dps assist,-threat"
|
||||||
|
|||||||
@@ -266,9 +266,14 @@ void AiFactory::AddDefaultCombatStrategies(Player* player, PlayerbotAI* const fa
|
|||||||
{
|
{
|
||||||
engine->addStrategies("racials", "chat", "default", "cast time", "duel", "boost", nullptr);
|
engine->addStrategies("racials", "chat", "default", "cast time", "duel", "boost", nullptr);
|
||||||
}
|
}
|
||||||
if (sPlayerbotAIConfig->autoSaveMana) {
|
if (sPlayerbotAIConfig->autoSaveMana)
|
||||||
|
{
|
||||||
engine->addStrategy("auto save mana");
|
engine->addStrategy("auto save mana");
|
||||||
}
|
}
|
||||||
|
if (sPlayerbotAIConfig->autoAvoidAoe && facade->HasRealPlayerMaster())
|
||||||
|
{
|
||||||
|
engine->addStrategy("avoid aoe");
|
||||||
|
}
|
||||||
switch (player->getClass())
|
switch (player->getClass())
|
||||||
{
|
{
|
||||||
case CLASS_PRIEST:
|
case CLASS_PRIEST:
|
||||||
|
|||||||
@@ -91,6 +91,7 @@ bool PlayerbotAIConfig::Initialize()
|
|||||||
mediumMana = sConfigMgr->GetOption<int32>("AiPlayerbot.MediumMana", 40);
|
mediumMana = sConfigMgr->GetOption<int32>("AiPlayerbot.MediumMana", 40);
|
||||||
autoSaveMana = sConfigMgr->GetOption<bool>("AiPlayerbot.AutoSaveMana", true);
|
autoSaveMana = sConfigMgr->GetOption<bool>("AiPlayerbot.AutoSaveMana", true);
|
||||||
saveManaThreshold = sConfigMgr->GetOption<int32>("AiPlayerbot.SaveManaThreshold", 60);
|
saveManaThreshold = sConfigMgr->GetOption<int32>("AiPlayerbot.SaveManaThreshold", 60);
|
||||||
|
autoAvoidAoe = sConfigMgr->GetOption<bool>("AiPlayerbot.AutoAvoidAoe", false);
|
||||||
|
|
||||||
randomGearLoweringChance = sConfigMgr->GetOption<float>("AiPlayerbot.RandomGearLoweringChance", 0.15f);
|
randomGearLoweringChance = sConfigMgr->GetOption<float>("AiPlayerbot.RandomGearLoweringChance", 0.15f);
|
||||||
randomBotMaxLevelChance = sConfigMgr->GetOption<float>("AiPlayerbot.RandomBotMaxLevelChance", 0.15f);
|
randomBotMaxLevelChance = sConfigMgr->GetOption<float>("AiPlayerbot.RandomBotMaxLevelChance", 0.15f);
|
||||||
|
|||||||
@@ -64,7 +64,8 @@ class PlayerbotAIConfig
|
|||||||
uint32 lowMana, mediumMana;
|
uint32 lowMana, mediumMana;
|
||||||
bool autoSaveMana;
|
bool autoSaveMana;
|
||||||
uint32 saveManaThreshold;
|
uint32 saveManaThreshold;
|
||||||
|
bool autoAvoidAoe;
|
||||||
|
|
||||||
uint32 openGoSpell;
|
uint32 openGoSpell;
|
||||||
bool randomBotAutologin;
|
bool randomBotAutologin;
|
||||||
bool botAutologin;
|
bool botAutologin;
|
||||||
|
|||||||
@@ -1492,6 +1492,16 @@ bool AvoidAoeAction::isUseful()
|
|||||||
bool AvoidAoeAction::Execute(Event event)
|
bool AvoidAoeAction::Execute(Event event)
|
||||||
{
|
{
|
||||||
// Case #1: Aura with dynamic object
|
// Case #1: Aura with dynamic object
|
||||||
|
if (AvoidAuraWithDynamicObj()) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
// Case #2: Trap game object with spell
|
||||||
|
// Case #3: Trigger npc
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool AvoidAoeAction::AvoidAuraWithDynamicObj()
|
||||||
|
{
|
||||||
Aura* aura = AI_VALUE(Aura*, "area debuff");
|
Aura* aura = AI_VALUE(Aura*, "area debuff");
|
||||||
if (!aura) {
|
if (!aura) {
|
||||||
return false;
|
return false;
|
||||||
@@ -1523,24 +1533,24 @@ bool AvoidAoeAction::Execute(Event event)
|
|||||||
}
|
}
|
||||||
float farestDis = 0.0f;
|
float farestDis = 0.0f;
|
||||||
Position bestPos;
|
Position bestPos;
|
||||||
// float disToDyn = bot->GetExactDist(dynOwner);
|
|
||||||
// float maxDisToGo = radius > disToDyn ? std::sqrt(radius * radius - disToDyn * disToDyn) + 0.5f : 0.5f;
|
|
||||||
for (float &angle : possibleAngles) {
|
for (float &angle : possibleAngles) {
|
||||||
float fleeDis = sPlayerbotAIConfig->fleeDistance;
|
float fleeDis = sPlayerbotAIConfig->fleeDistance;
|
||||||
Position pos{bot->GetPositionX() + cos(angle) * fleeDis,
|
Position pos{bot->GetPositionX() + cos(angle) * fleeDis,
|
||||||
bot->GetPositionY() + sin(angle) * fleeDis,
|
bot->GetPositionY() + sin(angle) * fleeDis,
|
||||||
bot->GetPositionZ()};
|
bot->GetPositionZ()};
|
||||||
// todo(Yunfan): check carefully
|
// todo (Yunfan): check carefully
|
||||||
if (dynOwner->GetExactDist(pos) > farestDis) {
|
if (dynOwner->GetExactDist(pos) > farestDis) {
|
||||||
farestDis = dynOwner->GetExactDist(pos);
|
farestDis = dynOwner->GetExactDist(pos);
|
||||||
bestPos = pos;
|
bestPos = pos;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (farestDis > 0.0f) {
|
if (farestDis > 0.0f) {
|
||||||
std::ostringstream out;
|
if (MoveTo(bot->GetMapId(), bestPos.GetPositionX(), bestPos.GetPositionY(), bestPos.GetPositionZ(), false, false, true)) {
|
||||||
out << "I'm avoiding aoe spell [" << aura->GetSpellInfo()->SpellName[0] << "]...";
|
std::ostringstream out;
|
||||||
bot->Say(out.str(), LANG_UNIVERSAL);
|
out << "I'm avoiding aoe spell [" << aura->GetSpellInfo()->SpellName[0] << "]...";
|
||||||
return MoveTo(bot->GetMapId(), bestPos.GetPositionX(), bestPos.GetPositionY(), bestPos.GetPositionZ(), false, false, true);
|
bot->Say(out.str(), LANG_UNIVERSAL);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -73,6 +73,9 @@ class AvoidAoeAction : public MovementAction
|
|||||||
|
|
||||||
bool isUseful() override;
|
bool isUseful() override;
|
||||||
bool Execute(Event event) override;
|
bool Execute(Event event) override;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
bool AvoidAuraWithDynamicObj();
|
||||||
};
|
};
|
||||||
|
|
||||||
class RunAwayAction : public MovementAction
|
class RunAwayAction : public MovementAction
|
||||||
|
|||||||
@@ -5,6 +5,7 @@
|
|||||||
#ifndef _PLAYERBOT_AOEVALUES_H
|
#ifndef _PLAYERBOT_AOEVALUES_H
|
||||||
#define _PLAYERBOT_AOEVALUES_H
|
#define _PLAYERBOT_AOEVALUES_H
|
||||||
|
|
||||||
|
#include "GameObject.h"
|
||||||
#include "Object.h"
|
#include "Object.h"
|
||||||
#include "Value.h"
|
#include "Value.h"
|
||||||
#include "AiObjectContext.h"
|
#include "AiObjectContext.h"
|
||||||
|
|||||||
@@ -7,6 +7,7 @@
|
|||||||
#include "GridNotifiers.h"
|
#include "GridNotifiers.h"
|
||||||
#include "GridNotifiersImpl.h"
|
#include "GridNotifiersImpl.h"
|
||||||
#include "Playerbots.h"
|
#include "Playerbots.h"
|
||||||
|
#include "SharedDefines.h"
|
||||||
|
|
||||||
class AnyGameObjectInObjectRangeCheck
|
class AnyGameObjectInObjectRangeCheck
|
||||||
{
|
{
|
||||||
@@ -42,3 +43,30 @@ GuidVector NearestGameObjects::Calculate()
|
|||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
GuidVector NearestTrapWithDamageValue::Calculate()
|
||||||
|
{
|
||||||
|
std::list<GameObject*> targets;
|
||||||
|
AnyGameObjectInObjectRangeCheck u_check(bot, range);
|
||||||
|
Acore::GameObjectListSearcher<AnyGameObjectInObjectRangeCheck> searcher(bot, targets, u_check);
|
||||||
|
Cell::VisitAllObjects(bot, searcher, range);
|
||||||
|
|
||||||
|
GuidVector result;
|
||||||
|
for (GameObject* go : targets)
|
||||||
|
{
|
||||||
|
if (go->GetGoType() != GAMEOBJECT_TYPE_TRAP)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
uint32 spellId = go->GetSpellId();
|
||||||
|
if (!spellId)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
// if (ignoreLos || bot->IsWithinLOSInMap(go))
|
||||||
|
result.push_back(go->GetGUID());
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -24,4 +24,17 @@ class NearestGameObjects : public ObjectGuidListCalculatedValue
|
|||||||
bool ignoreLos;
|
bool ignoreLos;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class NearestTrapWithDamageValue : public ObjectGuidListCalculatedValue
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
NearestTrapWithDamageValue(PlayerbotAI* botAI, float range = sPlayerbotAIConfig->sightDistance) :
|
||||||
|
ObjectGuidListCalculatedValue(botAI, "nearest trap with damage", 1 * 1000), range(range) { }
|
||||||
|
|
||||||
|
protected:
|
||||||
|
GuidVector Calculate() override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
float range;
|
||||||
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -299,6 +299,7 @@ class ValueContext : public NamedObjectContext<UntypedValue>
|
|||||||
creators["expected lifetime"] = &ValueContext::expected_lifetime;
|
creators["expected lifetime"] = &ValueContext::expected_lifetime;
|
||||||
creators["expected group dps"] = &ValueContext::expected_group_dps;
|
creators["expected group dps"] = &ValueContext::expected_group_dps;
|
||||||
creators["area debuff"] = &ValueContext::area_debuff;
|
creators["area debuff"] = &ValueContext::area_debuff;
|
||||||
|
creators["nearest trap with damage"] = &ValueContext::nearest_trap_with_damange;
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@@ -501,6 +502,7 @@ class ValueContext : public NamedObjectContext<UntypedValue>
|
|||||||
static UntypedValue* expected_lifetime(PlayerbotAI* ai) { return new ExpectedLifetimeValue(ai); }
|
static UntypedValue* expected_lifetime(PlayerbotAI* ai) { return new ExpectedLifetimeValue(ai); }
|
||||||
static UntypedValue* expected_group_dps(PlayerbotAI* ai) { return new ExpectedGroupDpsValue(ai); }
|
static UntypedValue* expected_group_dps(PlayerbotAI* ai) { return new ExpectedGroupDpsValue(ai); }
|
||||||
static UntypedValue* area_debuff(PlayerbotAI* ai) { return new AreaDebuffValue(ai); }
|
static UntypedValue* area_debuff(PlayerbotAI* ai) { return new AreaDebuffValue(ai); }
|
||||||
|
static UntypedValue* nearest_trap_with_damange(PlayerbotAI* ai) { return new NearestTrapWithDamageValue(ai); }
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
Reference in New Issue
Block a user