2025-03-18 19:19:03 -04:00

156 lines
4.9 KiB
C++

/*
* Copyright (C) 2016+ AzerothCore <www.azerothcore.org>, released under GNU GPL v2 license, you may redistribute it
* and/or modify it under version 2 of the License, or (at your option), any later version.
*/
#include "AoeValues.h"
#include "Playerbots.h"
#include "ServerFacade.h"
#include "SpellAuraEffects.h"
GuidVector FindMaxDensity(Player* bot)
{
PlayerbotAI* botAI = GET_PLAYERBOT_AI(bot);
GuidVector units = *botAI->GetAiObjectContext()->GetValue<GuidVector>("possible targets");
std::map<ObjectGuid, GuidVector> groups;
uint32 maxCount = 0;
ObjectGuid maxGroup;
for (GuidVector::iterator i = units.begin(); i != units.end(); ++i)
{
Unit* unit = botAI->GetUnit(*i);
if (!unit)
continue;
for (GuidVector::iterator j = units.begin(); j != units.end(); ++j)
{
Unit* other = botAI->GetUnit(*j);
if (!other)
continue;
float d = sServerFacade->GetDistance2d(unit, other);
if (sServerFacade->IsDistanceLessOrEqualThan(d, sPlayerbotAIConfig->aoeRadius * 2))
groups[*i].push_back(*j);
}
if (maxCount < groups[*i].size())
{
maxCount = groups[*i].size();
maxGroup = *i;
}
}
if (!maxCount)
return GuidVector();
return groups[maxGroup];
}
WorldLocation AoePositionValue::Calculate()
{
GuidVector group = FindMaxDensity(bot);
if (group.empty())
return WorldLocation();
// Note: don't know where these values come from or even used.
float x1 = 0.f;
float y1 = 0.f;
float x2 = 0.f;
float y2 = 0.f;
for (GuidVector::iterator i = group.begin(); i != group.end(); ++i)
{
Unit* unit = GET_PLAYERBOT_AI(bot)->GetUnit(*i);
if (!unit)
continue;
if (i == group.begin() || x1 > unit->GetPositionX())
x1 = unit->GetPositionX();
if (i == group.begin() || x2 < unit->GetPositionX())
x2 = unit->GetPositionX();
if (i == group.begin() || y1 > unit->GetPositionY())
y1 = unit->GetPositionY();
if (i == group.begin() || y2 < unit->GetPositionY())
y2 = unit->GetPositionY();
}
float x = (x1 + x2) / 2;
float y = (y1 + y2) / 2;
float z = bot->GetPositionZ() + CONTACT_DISTANCE;
;
bot->UpdateAllowedPositionZ(x, y, z);
return WorldLocation(bot->GetMapId(), x, y, z, 0);
}
uint8 AoeCountValue::Calculate() { return FindMaxDensity(bot).size(); }
bool HasAreaDebuffValue::Calculate()
{
for (uint32 auraType = SPELL_AURA_BIND_SIGHT; auraType < TOTAL_AURAS; auraType++)
{
Unit::AuraEffectList const& auras = botAI->GetBot()->GetAuraEffectsByType((AuraType)auraType);
if (auras.empty())
continue;
for (AuraEffect const* aurEff : auras)
{
SpellInfo const* proto = aurEff->GetSpellInfo();
if (!proto)
continue;
uint32 trigger_spell_id = proto->Effects[aurEff->GetEffIndex()].TriggerSpell;
if (trigger_spell_id == 29767) // Overload
{
return true;
}
else
{
return (!proto->IsPositive() && aurEff->IsPeriodic() && proto->HasAreaAuraEffect());
}
}
}
return false;
}
Aura* AreaDebuffValue::Calculate()
{
// Unit::AuraApplicationMap& map = bot->GetAppliedAuras();
Unit::AuraEffectList const& aurasPeriodicDamage = bot->GetAuraEffectsByType(SPELL_AURA_PERIODIC_DAMAGE);
Unit::AuraEffectList const& aurasPeriodicDamagePercent =
bot->GetAuraEffectsByType(SPELL_AURA_PERIODIC_DAMAGE_PERCENT);
Unit::AuraEffectList const& aurasPeriodicTriggerSpell =
bot->GetAuraEffectsByType(SPELL_AURA_PERIODIC_TRIGGER_SPELL);
Unit::AuraEffectList const& aurasPeriodicTriggerWithValueSpell =
bot->GetAuraEffectsByType(SPELL_AURA_PERIODIC_TRIGGER_SPELL_WITH_VALUE);
Unit::AuraEffectList const& aurasDummy = bot->GetAuraEffectsByType(SPELL_AURA_DUMMY);
for (const Unit::AuraEffectList& list : {aurasPeriodicDamage, aurasPeriodicDamagePercent, aurasPeriodicTriggerSpell,
aurasPeriodicTriggerWithValueSpell, aurasDummy})
{
for (auto i = list.begin(); i != list.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();
if (!dynOwner)
{
continue;
}
// float radius = dynOwner->GetRadius();
// if (radius > 12.0f)
// continue;
return aura;
}
}
}
return nullptr;
}