From 19ffe0227a685a28b247000a4eea12e229655c5d Mon Sep 17 00:00:00 2001 From: Yunfan Li Date: Thu, 18 Apr 2024 22:41:14 +0800 Subject: [PATCH] [Avoid aoe] Crash fix and cover more spell --- src/strategy/actions/MovementActions.cpp | 95 +++----------------- src/strategy/actions/TellLosAction.cpp | 1 - src/strategy/values/AoeValues.cpp | 35 +++++--- src/strategy/values/NearestGameObjects.h | 2 +- src/strategy/values/NearestUnitsValue.h | 4 +- src/strategy/values/PossibleTargetsValue.cpp | 28 +++++- src/strategy/values/PossibleTargetsValue.h | 4 +- 7 files changed, 67 insertions(+), 102 deletions(-) diff --git a/src/strategy/actions/MovementActions.cpp b/src/strategy/actions/MovementActions.cpp index 880ed74a..c6770a16 100644 --- a/src/strategy/actions/MovementActions.cpp +++ b/src/strategy/actions/MovementActions.cpp @@ -14,8 +14,6 @@ #include "PlayerbotAIConfig.h" #include "Random.h" #include "SharedDefines.h" -#include "SpellAuraEffects.h" -#include "SpellAuraEffects.h" #include "SpellInfo.h" #include "TargetedMovementGenerator.h" #include "Event.h" @@ -1415,13 +1413,13 @@ const Movement::PointsArray MovementAction::SearchForBestPath(float x, float y, PathGenerator gen(bot); gen.CalculatePath(x, y, tempZ); Movement::PointsArray result = gen.GetPath(); - modified_z = tempZ; float min_length = gen.getPathLength(); if (gen.GetPathType() == PATHFIND_NORMAL && abs(tempZ - z) < 0.5f) { + modified_z = tempZ; return result; } // Start searching - if (gen.GetPathType() == PATHFIND_NORMAL) { + if (gen.GetPathType() & PATHFIND_NORMAL) { found = true; } int count = 1; @@ -1432,7 +1430,7 @@ const Movement::PointsArray MovementAction::SearchForBestPath(float x, float y, } PathGenerator gen(bot); gen.CalculatePath(x, y, tempZ); - if (gen.GetPathType() == PATHFIND_NORMAL && gen.getPathLength() < min_length) { + if (gen.GetPathType() & PATHFIND_NORMAL && gen.getPathLength() < min_length) { found = true; min_length = gen.getPathLength(); result = gen.GetPath(); @@ -1446,7 +1444,7 @@ const Movement::PointsArray MovementAction::SearchForBestPath(float x, float y, } PathGenerator gen(bot); gen.CalculatePath(x, y, tempZ); - if (gen.GetPathType() == PATHFIND_NORMAL && gen.getPathLength() < min_length) { + if (gen.GetPathType() & PATHFIND_NORMAL && gen.getPathLength() < min_length) { found = true; min_length = gen.getPathLength(); result = gen.GetPath(); @@ -1520,16 +1518,17 @@ bool AvoidAoeAction::Execute(Event event) bool AvoidAoeAction::AvoidAuraWithDynamicObj() { Aura* aura = AI_VALUE(Aura*, "area debuff"); - if (!aura) { + if (!aura || aura->IsRemoved() || aura->IsExpired()) { + return false; + } + // Crash fix: maybe change owner due to check interval + if (aura->GetType() != DYNOBJ_AURA_TYPE) { return false; } const SpellInfo* spellInfo = aura->GetSpellInfo(); if (!spellInfo) { return false; } - if (!bot->HasAura(spellInfo->Id)) { - return false; - } DynamicObject* dynOwner = aura->GetDynobjOwner(); if (!dynOwner || !dynOwner->IsInWorld()) { return false; @@ -1599,84 +1598,12 @@ bool AvoidAoeAction::AvoidGameObjectWithDamage() return false; } -bool AvoidAoeAction::AvoidUnitWithDamageAura() -{ - GuidVector traps = AI_VALUE(GuidVector, "possible triggers"); - if (traps.empty()) { - return false; - } - for (ObjectGuid &guid : traps) { - Unit* unit = botAI->GetUnit(guid); - if (!unit || !unit->IsInWorld()) { - continue; - } - if (!unit->HasUnitFlag(UNIT_FLAG_NOT_SELECTABLE)) { - return false; - } - Unit::AuraEffectList const& auras = unit->GetAuraEffectsByType(SPELL_AURA_PERIODIC_TRIGGER_SPELL); - for (auto i = auras.begin(); i != auras.end(); ++i) - { - AuraEffect* aurEff = *i; - const SpellInfo* spellInfo = aurEff->GetSpellInfo(); - if (!spellInfo) - continue; - const SpellInfo* triggerSpellInfo = sSpellMgr->GetSpellInfo(spellInfo->Effects[aurEff->GetEffIndex()].TriggerSpell); - if (!triggerSpellInfo) - continue; - for (int j = 0; j < MAX_SPELL_EFFECTS; j++) { - if (triggerSpellInfo->Effects[j].Effect == SPELL_EFFECT_SCHOOL_DAMAGE) { - float radius = triggerSpellInfo->Effects[j].CalcRadius(); - if (bot->GetDistance(unit) > radius) { - break; - } - std::ostringstream name; - name << "[" << triggerSpellInfo->SpellName[0] << "] (unit)"; - if (FleePostion(unit->GetPosition(), radius, name.str())) { - return true; - } - } - } - } - // Unit::AuraApplicationMap& map = unit->GetAppliedAuras(); - // for (Unit::AuraApplicationMap::iterator i = map.begin(); i != map.end(); ++i) - // { - // Aura *aura = i->second->GetBase(); - // if (!aura) - // continue; - // const SpellInfo* spellInfo = aura->GetSpellInfo(); - // if (!spellInfo) - // continue; - // for (int i = 0; i < MAX_SPELL_EFFECTS; i++) { - // if (spellInfo->Effects[i].Effect == SPELL_EFFECT_APPLY_AURA && - // spellInfo->Effects[i].ApplyAuraName == SPELL_AURA_PERIODIC_TRIGGER_SPELL) { - // const SpellInfo* triggerSpellInfo = sSpellMgr->GetSpellInfo(spellInfo->Effects[i].TriggerSpell); - // if (!triggerSpellInfo) - // continue; - // for (int j = 0; j < MAX_SPELL_EFFECTS; j++) { - // if (triggerSpellInfo->Effects[j].Effect == SPELL_EFFECT_SCHOOL_DAMAGE) { - // float radius = triggerSpellInfo->Effects[j].CalcRadius(); - // if (bot->GetDistance(unit) > radius) { - // break; - // } - // std::ostringstream name; - // name << "[" << triggerSpellInfo->SpellName[0] << "] (unit)"; - // if (FleePostion(unit->GetPosition(), radius, name.str())) { - // return true; - // } - // } - // } - // } - // } - // } - } - return false; -} - bool AvoidAoeAction::FleePostion(Position pos, float radius, std::string name) { Unit* currentTarget = AI_VALUE(Unit*, "current target"); std::vector possibleAngles; if (currentTarget) { + // Normally, move to left or right is the best position float angleLeft = bot->GetAngle(currentTarget) + M_PI / 2; float angleRight = bot->GetAngle(currentTarget) - M_PI / 2; possibleAngles.push_back(angleLeft); @@ -1859,4 +1786,4 @@ bool RotateAroundTheCenterPointAction::Execute(Event event) return true; } return false; -} \ No newline at end of file +} diff --git a/src/strategy/actions/TellLosAction.cpp b/src/strategy/actions/TellLosAction.cpp index 234bebcc..8c729cf3 100644 --- a/src/strategy/actions/TellLosAction.cpp +++ b/src/strategy/actions/TellLosAction.cpp @@ -78,7 +78,6 @@ bool TellAuraAction::Execute(Event event) Aura * aura = i->second->GetBase(); if (!aura) continue; - const std::string auraName = aura->GetSpellInfo()->SpellName[0]; sLog->outMessage("playerbot", LOG_LEVEL_DEBUG, "Info of Aura - name: " + auraName); AuraObjectType type = aura->GetType(); diff --git a/src/strategy/values/AoeValues.cpp b/src/strategy/values/AoeValues.cpp index 3d93640c..7f355949 100644 --- a/src/strategy/values/AoeValues.cpp +++ b/src/strategy/values/AoeValues.cpp @@ -120,15 +120,13 @@ bool HasAreaDebuffValue::Calculate() Aura* AreaDebuffValue::Calculate() { - Unit::AuraApplicationMap& map = bot->GetAppliedAuras(); - for (Unit::AuraApplicationMap::iterator i = map.begin(); i != map.end(); ++i) - { - Aura *aura = i->second->GetBase(); - if (!aura) - continue; - - AuraObjectType type = aura->GetType(); - // bool is_area = aura->IsArea(); + // Unit::AuraApplicationMap& map = bot->GetAppliedAuras(); + Unit::AuraEffectList const& auras = bot->GetAuraEffectsByType(SPELL_AURA_PERIODIC_DAMAGE); + for (auto i = auras.begin(); i != auras.end(); ++i) + { + AuraEffect* aurEff = *i; + Aura *aura = aurEff->GetBase(); + AuraObjectType type = aura->GetType(); bool isPositive = aura->GetSpellInfo()->IsPositive(); if (type == DYNOBJ_AURA_TYPE && !isPositive) { DynamicObject* dynOwner = aura->GetDynobjOwner(); @@ -137,6 +135,23 @@ Aura* AreaDebuffValue::Calculate() } return aura; } - } + } + // for (Unit::AuraApplicationMap::iterator i = map.begin(); i != map.end(); ++i) + // { + // Aura *aura = i->second->GetBase(); + // if (!aura) + // continue; + + // AuraObjectType type = aura->GetType(); + // // bool is_area = aura->IsArea(); + // bool isPositive = aura->GetSpellInfo()->IsPositive(); + // if (type == DYNOBJ_AURA_TYPE && !isPositive) { + // DynamicObject* dynOwner = aura->GetDynobjOwner(); + // if (!dynOwner) { + // continue; + // } + // return aura; + // } + // } return nullptr; } \ No newline at end of file diff --git a/src/strategy/values/NearestGameObjects.h b/src/strategy/values/NearestGameObjects.h index d0e7850f..399222cc 100644 --- a/src/strategy/values/NearestGameObjects.h +++ b/src/strategy/values/NearestGameObjects.h @@ -27,7 +27,7 @@ class NearestGameObjects : public ObjectGuidListCalculatedValue class NearestTrapWithDamageValue : public ObjectGuidListCalculatedValue { public: - NearestTrapWithDamageValue(PlayerbotAI* botAI, float range = 10.0f) : + NearestTrapWithDamageValue(PlayerbotAI* botAI, float range = 15.0f) : ObjectGuidListCalculatedValue(botAI, "nearest trap with damage", 1 * 1000), range(range) { } protected: diff --git a/src/strategy/values/NearestUnitsValue.h b/src/strategy/values/NearestUnitsValue.h index 7b262370..6f154e4e 100644 --- a/src/strategy/values/NearestUnitsValue.h +++ b/src/strategy/values/NearestUnitsValue.h @@ -14,8 +14,8 @@ class PlayerbotAI; class NearestUnitsValue : public ObjectGuidListCalculatedValue { public: - NearestUnitsValue(PlayerbotAI* botAI, std::string const name = "nearest units", float range = sPlayerbotAIConfig->sightDistance, bool ignoreLos = false) : - ObjectGuidListCalculatedValue(botAI, name, 1), range(range), ignoreLos(ignoreLos) { } + NearestUnitsValue(PlayerbotAI* botAI, std::string const name = "nearest units", float range = sPlayerbotAIConfig->sightDistance, bool ignoreLos = false, uint32 checkInterval = 1) : + ObjectGuidListCalculatedValue(botAI, name, checkInterval), range(range), ignoreLos(ignoreLos) { } GuidVector Calculate() override; diff --git a/src/strategy/values/PossibleTargetsValue.cpp b/src/strategy/values/PossibleTargetsValue.cpp index 729c0ae0..904cfc01 100644 --- a/src/strategy/values/PossibleTargetsValue.cpp +++ b/src/strategy/values/PossibleTargetsValue.cpp @@ -5,9 +5,14 @@ #include "PossibleTargetsValue.h" #include "AttackersValue.h" #include "CellImpl.h" +#include "DBCStructure.h" #include "GridNotifiers.h" #include "GridNotifiersImpl.h" #include "Playerbots.h" +#include "SharedDefines.h" +#include "SpellAuraDefines.h" +#include "SpellAuraEffects.h" +#include "SpellMgr.h" #include "Unit.h" void PossibleTargetsValue::FindUnits(std::list& targets) @@ -31,7 +36,26 @@ void PossibleTriggersValue::FindUnits(std::list& targets) bool PossibleTriggersValue::AcceptUnit(Unit* unit) { - return unit->HasUnitFlag(UNIT_FLAG_NON_ATTACKABLE) && unit->HasUnitFlag(UNIT_FLAG_NOT_SELECTABLE); - return true; // AttackersValue::IsPossibleTarget(unit, bot, range); + if (!unit->HasUnitFlag(UNIT_FLAG_NOT_SELECTABLE)) { + return false; + } + Unit::AuraEffectList const& auras = unit->GetAuraEffectsByType(SPELL_AURA_PERIODIC_TRIGGER_SPELL); + for (auto i = auras.begin(); i != auras.end(); ++i) + { + AuraEffect* aurEff = *i; + const SpellInfo* spellInfo = aurEff->GetSpellInfo(); + if (!spellInfo) + continue; + const SpellInfo* triggerSpellInfo = sSpellMgr->GetSpellInfo(spellInfo->Effects[aurEff->GetEffIndex()].TriggerSpell); + if (!triggerSpellInfo) + continue; + for (int j = 0; j < MAX_SPELL_EFFECTS; j++) { + if (triggerSpellInfo->Effects[j].Effect == SPELL_EFFECT_SCHOOL_DAMAGE) { + return true; + } + } + } + return false; + // return true; // AttackersValue::IsPossibleTarget(unit, bot, range); } diff --git a/src/strategy/values/PossibleTargetsValue.h b/src/strategy/values/PossibleTargetsValue.h index 81cd2bd3..1ffcdd51 100644 --- a/src/strategy/values/PossibleTargetsValue.h +++ b/src/strategy/values/PossibleTargetsValue.h @@ -30,8 +30,8 @@ class AllTargetsValue : public PossibleTargetsValue class PossibleTriggersValue : public NearestUnitsValue { public: - PossibleTriggersValue(PlayerbotAI* botAI, std::string const name = "possible targets", float range = sPlayerbotAIConfig->sightDistance, bool ignoreLos = true): - NearestUnitsValue(botAI, name, range, ignoreLos) { } + PossibleTriggersValue(PlayerbotAI* botAI, std::string const name = "possible triggers", float range = 15.0f, bool ignoreLos = true): + NearestUnitsValue(botAI, name, range, ignoreLos, 1 * 1000) { } protected: void FindUnits(std::list& targets) override;