mirror of
https://github.com/mod-playerbots/mod-playerbots
synced 2025-11-29 15:58:20 +08:00
[Avoid aoe] Crash fix and cover more spell
This commit is contained in:
@@ -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<float> 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);
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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)
|
||||
// Unit::AuraApplicationMap& map = bot->GetAppliedAuras();
|
||||
Unit::AuraEffectList const& auras = bot->GetAuraEffectsByType(SPELL_AURA_PERIODIC_DAMAGE);
|
||||
for (auto i = auras.begin(); i != auras.end(); ++i)
|
||||
{
|
||||
Aura *aura = i->second->GetBase();
|
||||
if (!aura)
|
||||
continue;
|
||||
|
||||
AuraEffect* aurEff = *i;
|
||||
Aura *aura = aurEff->GetBase();
|
||||
AuraObjectType type = aura->GetType();
|
||||
// bool is_area = aura->IsArea();
|
||||
bool isPositive = aura->GetSpellInfo()->IsPositive();
|
||||
if (type == DYNOBJ_AURA_TYPE && !isPositive) {
|
||||
DynamicObject* dynOwner = aura->GetDynobjOwner();
|
||||
@@ -138,5 +136,22 @@ 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;
|
||||
}
|
||||
@@ -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:
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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<Unit*>& targets)
|
||||
@@ -31,7 +36,26 @@ void PossibleTriggersValue::FindUnits(std::list<Unit*>& 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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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<Unit*>& targets) override;
|
||||
|
||||
Reference in New Issue
Block a user