mirror of
https://github.com/mod-playerbots/mod-playerbots
synced 2025-11-29 15:58:20 +08:00
@@ -844,7 +844,8 @@ void PlayerbotAI::HandleBotOutgoingPacket(WorldPacket const& packet)
|
|||||||
// vcos, vsin, horizontalSpeed, verticalSpeed, x, y, z, bot->GetRelativeAngle(vcos, vsin), bot->GetOrientation());
|
// vcos, vsin, horizontalSpeed, verticalSpeed, x, y, z, bot->GetRelativeAngle(vcos, vsin), bot->GetOrientation());
|
||||||
// bot->Say(speak, LANG_UNIVERSAL);
|
// bot->Say(speak, LANG_UNIVERSAL);
|
||||||
// bot->GetClosePoint(x, y, z, bot->GetObjectSize(), dist, bot->GetAngle(vcos, vsin));
|
// bot->GetClosePoint(x, y, z, bot->GetObjectSize(), dist, bot->GetAngle(vcos, vsin));
|
||||||
bot->GetMotionMaster()->MoveJump(x, y, z, horizontalSpeed, verticalSpeed, 0, bot->GetSelectedUnit());
|
Unit* currentTarget = GetAiObjectContext()->GetValue<Unit*>("current target")->Get();
|
||||||
|
bot->GetMotionMaster()->MoveJump(x, y, z, horizontalSpeed, verticalSpeed, 0, currentTarget);
|
||||||
// bot->AddUnitMovementFlag(MOVEMENTFLAG_FALLING);
|
// bot->AddUnitMovementFlag(MOVEMENTFLAG_FALLING);
|
||||||
// bot->AddUnitMovementFlag(MOVEMENTFLAG_FORWARD);
|
// bot->AddUnitMovementFlag(MOVEMENTFLAG_FORWARD);
|
||||||
// bot->m_movementInfo.AddMovementFlag(MOVEMENTFLAG_PENDING_STOP);
|
// bot->m_movementInfo.AddMovementFlag(MOVEMENTFLAG_PENDING_STOP);
|
||||||
@@ -2477,9 +2478,8 @@ bool PlayerbotAI::CastSpell(uint32 spellId, Unit* target, Item* itemTarget)
|
|||||||
|
|
||||||
ObjectGuid oldSel = bot->GetSelectedUnit() ? bot->GetSelectedUnit()->GetGUID() : ObjectGuid();
|
ObjectGuid oldSel = bot->GetSelectedUnit() ? bot->GetSelectedUnit()->GetGUID() : ObjectGuid();
|
||||||
bot->SetSelection(target->GetGUID());
|
bot->SetSelection(target->GetGUID());
|
||||||
|
|
||||||
WorldObject* faceTo = target;
|
WorldObject* faceTo = target;
|
||||||
if (!bot->HasInArc(CAST_ANGLE_IN_FRONT, faceTo))
|
if (!bot->HasInArc(CAST_ANGLE_IN_FRONT, faceTo) && (spellInfo->FacingCasterFlags & SPELL_FACING_FLAG_INFRONT))
|
||||||
{
|
{
|
||||||
sServerFacade->SetFacingTo(bot, faceTo);
|
sServerFacade->SetFacingTo(bot, faceTo);
|
||||||
//failWithDelay = true;
|
//failWithDelay = true;
|
||||||
@@ -4409,10 +4409,11 @@ InventoryResult PlayerbotAI::CanEquipItem(uint8 slot, uint16& dest, Item* pItem,
|
|||||||
if (pItem->IsBindedNotWith(bot))
|
if (pItem->IsBindedNotWith(bot))
|
||||||
return EQUIP_ERR_DONT_OWN_THAT_ITEM;
|
return EQUIP_ERR_DONT_OWN_THAT_ITEM;
|
||||||
|
|
||||||
// check count of items (skip for auto move for same player from bank)
|
// Yunfan: skip it
|
||||||
InventoryResult res = bot->CanTakeMoreSimilarItems(pItem);
|
// // check count of items (skip for auto move for same player from bank)
|
||||||
if (res != EQUIP_ERR_OK)
|
// InventoryResult res = bot->CanTakeMoreSimilarItems(pItem);
|
||||||
return res;
|
// if (res != EQUIP_ERR_OK)
|
||||||
|
// return res;
|
||||||
|
|
||||||
ScalingStatDistributionEntry const* ssd = pProto->ScalingStatDistribution ? sScalingStatDistributionStore.LookupEntry(pProto->ScalingStatDistribution) : 0;
|
ScalingStatDistributionEntry const* ssd = pProto->ScalingStatDistribution ? sScalingStatDistributionStore.LookupEntry(pProto->ScalingStatDistribution) : 0;
|
||||||
// check allowed level (extend range to upper values if MaxLevel more or equal max player level, this let GM set high level with 1...max range items)
|
// check allowed level (extend range to upper values if MaxLevel more or equal max player level, this let GM set high level with 1...max range items)
|
||||||
@@ -4427,7 +4428,7 @@ InventoryResult PlayerbotAI::CanEquipItem(uint8 slot, uint16& dest, Item* pItem,
|
|||||||
if (!bot->CanUseAttackType(bot->GetAttackBySlot(eslot)))
|
if (!bot->CanUseAttackType(bot->GetAttackBySlot(eslot)))
|
||||||
return EQUIP_ERR_NOT_WHILE_DISARMED;
|
return EQUIP_ERR_NOT_WHILE_DISARMED;
|
||||||
|
|
||||||
res = bot->CanUseItem(pItem, not_loading);
|
InventoryResult res = bot->CanUseItem(pItem, not_loading);
|
||||||
if (res != EQUIP_ERR_OK)
|
if (res != EQUIP_ERR_OK)
|
||||||
return res;
|
return res;
|
||||||
|
|
||||||
|
|||||||
@@ -3593,9 +3593,9 @@ float PlayerbotFactory::CalculateItemScore(uint32 item_id, Player* bot)
|
|||||||
int meleeDps = 0, rangeDps = 0;
|
int meleeDps = 0, rangeDps = 0;
|
||||||
float score = 0;
|
float score = 0;
|
||||||
if (proto->IsRangedWeapon()) {
|
if (proto->IsRangedWeapon()) {
|
||||||
rangeDps = (proto->Damage[0].DamageMin + proto->Damage[0].DamageMax) / 2 * proto->Delay / 1000;
|
rangeDps = (proto->Damage[0].DamageMin + proto->Damage[0].DamageMax) / 2 * 1000 / proto->Delay;
|
||||||
} else if (proto->IsWeapon()) {
|
} else if (proto->IsWeapon()) {
|
||||||
meleeDps = (proto->Damage[0].DamageMin + proto->Damage[0].DamageMax) / 2 * proto->Delay / 1000;
|
meleeDps = (proto->Damage[0].DamageMin + proto->Damage[0].DamageMax) / 2 * 1000 / proto->Delay;
|
||||||
}
|
}
|
||||||
armor += proto->Armor;
|
armor += proto->Armor;
|
||||||
block += proto->Block;
|
block += proto->Block;
|
||||||
|
|||||||
@@ -14,6 +14,7 @@
|
|||||||
#include "PlayerbotAIConfig.h"
|
#include "PlayerbotAIConfig.h"
|
||||||
#include "Random.h"
|
#include "Random.h"
|
||||||
#include "SharedDefines.h"
|
#include "SharedDefines.h"
|
||||||
|
#include "SpellAuraEffects.h"
|
||||||
#include "SpellInfo.h"
|
#include "SpellInfo.h"
|
||||||
#include "TargetedMovementGenerator.h"
|
#include "TargetedMovementGenerator.h"
|
||||||
#include "Event.h"
|
#include "Event.h"
|
||||||
@@ -177,7 +178,7 @@ bool MovementAction::MoveTo(uint32 mapId, float x, float y, float z, bool idle,
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
float modifiedZ;
|
float modifiedZ;
|
||||||
Movement::PointsArray path = SearchForBestPath(x, y, z, modifiedZ, sPlayerbotAIConfig->maxMovementSearchTime);
|
Movement::PointsArray path = SearchForBestPath(x, y, z, modifiedZ, sPlayerbotAIConfig->maxMovementSearchTime, normal_only);
|
||||||
if (modifiedZ == INVALID_HEIGHT) {
|
if (modifiedZ == INVALID_HEIGHT) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -1409,26 +1410,29 @@ const Movement::PointsArray MovementAction::SearchForBestPath(float x, float y,
|
|||||||
{
|
{
|
||||||
bool found = false;
|
bool found = false;
|
||||||
modified_z = INVALID_HEIGHT;
|
modified_z = INVALID_HEIGHT;
|
||||||
float tempZ = bot->GetMapWaterOrGroundLevel(x, y, z);
|
float tempZ = bot->GetMapHeight(x, y, z);
|
||||||
PathGenerator gen(bot);
|
PathGenerator gen(bot);
|
||||||
gen.CalculatePath(x, y, tempZ);
|
gen.CalculatePath(x, y, tempZ);
|
||||||
Movement::PointsArray result = gen.GetPath();
|
Movement::PointsArray result = gen.GetPath();
|
||||||
float min_length = gen.getPathLength();
|
float min_length = gen.getPathLength();
|
||||||
if (gen.GetPathType() == PATHFIND_NORMAL && abs(tempZ - z) < 0.5f) {
|
if ((gen.GetPathType() & PATHFIND_NORMAL) && abs(tempZ - z) < 0.5f) {
|
||||||
modified_z = tempZ;
|
modified_z = tempZ;
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
// Start searching
|
// Start searching
|
||||||
if (gen.GetPathType() == PATHFIND_NORMAL) {
|
if (gen.GetPathType() & PATHFIND_NORMAL) {
|
||||||
found = true;
|
|
||||||
modified_z = tempZ;
|
modified_z = tempZ;
|
||||||
|
found = true;
|
||||||
}
|
}
|
||||||
int count = 1;
|
int count = 1;
|
||||||
for (float delta = step; count < maxSearchCount / 2 + 1; count++, delta += step) {
|
for (float delta = step; count < maxSearchCount / 2 + 1; count++, delta += step) {
|
||||||
tempZ = bot->GetMapWaterOrGroundLevel(x, y, z + delta);
|
tempZ = bot->GetMapHeight(x, y, z + delta);
|
||||||
|
if (tempZ == INVALID_HEIGHT) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
PathGenerator gen(bot);
|
PathGenerator gen(bot);
|
||||||
gen.CalculatePath(x, y, tempZ);
|
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;
|
found = true;
|
||||||
min_length = gen.getPathLength();
|
min_length = gen.getPathLength();
|
||||||
result = gen.GetPath();
|
result = gen.GetPath();
|
||||||
@@ -1436,10 +1440,13 @@ const Movement::PointsArray MovementAction::SearchForBestPath(float x, float y,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (float delta = -step; count < maxSearchCount; count++, delta -= step) {
|
for (float delta = -step; count < maxSearchCount; count++, delta -= step) {
|
||||||
tempZ = bot->GetMapWaterOrGroundLevel(x, y, z + delta);
|
tempZ = bot->GetMapHeight(x, y, z + delta);
|
||||||
|
if (tempZ == INVALID_HEIGHT) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
PathGenerator gen(bot);
|
PathGenerator gen(bot);
|
||||||
gen.CalculatePath(x, y, tempZ);
|
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;
|
found = true;
|
||||||
min_length = gen.getPathLength();
|
min_length = gen.getPathLength();
|
||||||
result = gen.GetPath();
|
result = gen.GetPath();
|
||||||
@@ -1447,6 +1454,7 @@ const Movement::PointsArray MovementAction::SearchForBestPath(float x, float y,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!found && normal_only) {
|
if (!found && normal_only) {
|
||||||
|
modified_z = INVALID_HEIGHT;
|
||||||
return Movement::PointsArray{};
|
return Movement::PointsArray{};
|
||||||
}
|
}
|
||||||
if (!found && !normal_only) {
|
if (!found && !normal_only) {
|
||||||
@@ -1488,7 +1496,8 @@ bool FleeWithPetAction::Execute(Event event)
|
|||||||
bool AvoidAoeAction::isUseful()
|
bool AvoidAoeAction::isUseful()
|
||||||
{
|
{
|
||||||
GuidVector traps = AI_VALUE(GuidVector, "nearest trap with damage");
|
GuidVector traps = AI_VALUE(GuidVector, "nearest trap with damage");
|
||||||
return AI_VALUE(Aura*, "area debuff") || !traps.empty();
|
GuidVector triggers = AI_VALUE(GuidVector, "possible triggers");
|
||||||
|
return AI_VALUE(Aura*, "area debuff") || !traps.empty() || !triggers.empty();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AvoidAoeAction::Execute(Event event)
|
bool AvoidAoeAction::Execute(Event event)
|
||||||
@@ -1502,22 +1511,26 @@ bool AvoidAoeAction::Execute(Event event)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
// Case #3: Trigger npc (e.g. Lesser shadow fissure)
|
// Case #3: Trigger npc (e.g. Lesser shadow fissure)
|
||||||
|
if (AvoidUnitWithDamageAura()) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AvoidAoeAction::AvoidAuraWithDynamicObj()
|
bool AvoidAoeAction::AvoidAuraWithDynamicObj()
|
||||||
{
|
{
|
||||||
Aura* aura = AI_VALUE(Aura*, "area debuff");
|
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;
|
return false;
|
||||||
}
|
}
|
||||||
const SpellInfo* spellInfo = aura->GetSpellInfo();
|
const SpellInfo* spellInfo = aura->GetSpellInfo();
|
||||||
if (!spellInfo) {
|
if (!spellInfo) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (!bot->HasAura(spellInfo->Id)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
DynamicObject* dynOwner = aura->GetDynobjOwner();
|
DynamicObject* dynOwner = aura->GetDynobjOwner();
|
||||||
if (!dynOwner || !dynOwner->IsInWorld()) {
|
if (!dynOwner || !dynOwner->IsInWorld()) {
|
||||||
return false;
|
return false;
|
||||||
@@ -1575,7 +1588,7 @@ bool AvoidAoeAction::AvoidGameObjectWithDamage()
|
|||||||
// }
|
// }
|
||||||
// }
|
// }
|
||||||
if (bot->GetDistance(go) > radius) {
|
if (bot->GetDistance(go) > radius) {
|
||||||
return false;
|
continue;
|
||||||
}
|
}
|
||||||
std::ostringstream name;
|
std::ostringstream name;
|
||||||
name << "[" << spellInfo->SpellName[0] << "] (object)";
|
name << "[" << spellInfo->SpellName[0] << "] (object)";
|
||||||
@@ -1587,11 +1600,57 @@ bool AvoidAoeAction::AvoidGameObjectWithDamage()
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool AvoidAoeAction::AvoidUnitWithDamageAura()
|
||||||
|
{
|
||||||
|
GuidVector triggers = AI_VALUE(GuidVector, "possible triggers");
|
||||||
|
if (triggers.empty()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
for (ObjectGuid &guid : triggers) {
|
||||||
|
Unit* unit = botAI->GetUnit(guid);
|
||||||
|
if (!unit || !unit->IsInWorld()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (!unit->HasUnitFlag(UNIT_FLAG_NOT_SELECTABLE)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
Unit::AuraEffectList const& aurasPeriodicTriggerSpell = unit->GetAuraEffectsByType(SPELL_AURA_PERIODIC_TRIGGER_SPELL);
|
||||||
|
Unit::AuraEffectList const& aurasPeriodicTriggerWithValueSpell = unit->GetAuraEffectsByType(SPELL_AURA_PERIODIC_TRIGGER_SPELL_WITH_VALUE);
|
||||||
|
for (const Unit::AuraEffectList& list : {aurasPeriodicTriggerSpell, aurasPeriodicTriggerWithValueSpell}) {
|
||||||
|
for (auto i = list.begin(); i != list.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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
bool AvoidAoeAction::FleePostion(Position pos, float radius, std::string name)
|
bool AvoidAoeAction::FleePostion(Position pos, float radius, std::string name)
|
||||||
{
|
{
|
||||||
Unit* currentTarget = AI_VALUE(Unit*, "current target");
|
Unit* currentTarget = AI_VALUE(Unit*, "current target");
|
||||||
std::vector<float> possibleAngles;
|
std::vector<float> possibleAngles;
|
||||||
if (currentTarget) {
|
if (currentTarget) {
|
||||||
|
// Normally, move to left or right is the best position
|
||||||
float angleLeft = bot->GetAngle(currentTarget) + M_PI / 2;
|
float angleLeft = bot->GetAngle(currentTarget) + M_PI / 2;
|
||||||
float angleRight = bot->GetAngle(currentTarget) - M_PI / 2;
|
float angleRight = bot->GetAngle(currentTarget) - M_PI / 2;
|
||||||
possibleAngles.push_back(angleLeft);
|
possibleAngles.push_back(angleLeft);
|
||||||
|
|||||||
@@ -77,6 +77,7 @@ class AvoidAoeAction : public MovementAction
|
|||||||
protected:
|
protected:
|
||||||
bool AvoidAuraWithDynamicObj();
|
bool AvoidAuraWithDynamicObj();
|
||||||
bool AvoidGameObjectWithDamage();
|
bool AvoidGameObjectWithDamage();
|
||||||
|
bool AvoidUnitWithDamageAura();
|
||||||
bool FleePostion(Position pos, float radius, std::string name);
|
bool FleePostion(Position pos, float radius, std::string name);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -78,7 +78,6 @@ bool TellAuraAction::Execute(Event event)
|
|||||||
Aura * aura = i->second->GetBase();
|
Aura * aura = i->second->GetBase();
|
||||||
if (!aura)
|
if (!aura)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
const std::string auraName = aura->GetSpellInfo()->SpellName[0];
|
const std::string auraName = aura->GetSpellInfo()->SpellName[0];
|
||||||
sLog->outMessage("playerbot", LOG_LEVEL_DEBUG, "Info of Aura - name: " + auraName);
|
sLog->outMessage("playerbot", LOG_LEVEL_DEBUG, "Info of Aura - name: " + auraName);
|
||||||
AuraObjectType type = aura->GetType();
|
AuraObjectType type = aura->GetType();
|
||||||
|
|||||||
@@ -41,7 +41,7 @@ bool CastAutoShotAction::isUseful()
|
|||||||
if (botAI->IsInVehicle() && !botAI->IsInVehicle(false, false, true))
|
if (botAI->IsInVehicle() && !botAI->IsInVehicle(false, false, true))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (bot->GetCurrentSpell(CURRENT_AUTOREPEAT_SPELL) && bot->GetCurrentSpell(CURRENT_AUTOREPEAT_SPELL)->m_targets.GetUnitTargetGUID() == AI_VALUE(Unit*, "current target")->GetGUID()) {
|
if (AI_VALUE(Unit*, "current target") && bot->GetCurrentSpell(CURRENT_AUTOREPEAT_SPELL) && bot->GetCurrentSpell(CURRENT_AUTOREPEAT_SPELL)->m_targets.GetUnitTargetGUID() == AI_VALUE(Unit*, "current target")->GetGUID()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return AI_VALUE(uint32, "active spell") != AI_VALUE2(uint32, "spell id", getName());
|
return AI_VALUE(uint32, "active spell") != AI_VALUE2(uint32, "spell id", getName());
|
||||||
|
|||||||
@@ -120,15 +120,16 @@ bool HasAreaDebuffValue::Calculate()
|
|||||||
|
|
||||||
Aura* AreaDebuffValue::Calculate()
|
Aura* AreaDebuffValue::Calculate()
|
||||||
{
|
{
|
||||||
Unit::AuraApplicationMap& map = bot->GetAppliedAuras();
|
// Unit::AuraApplicationMap& map = bot->GetAppliedAuras();
|
||||||
for (Unit::AuraApplicationMap::iterator i = map.begin(); i != map.end(); ++i)
|
Unit::AuraEffectList const& aurasPeriodicDamage = bot->GetAuraEffectsByType(SPELL_AURA_PERIODIC_DAMAGE);
|
||||||
|
Unit::AuraEffectList const& aurasPeriodicTriggerSpell = bot->GetAuraEffectsByType(SPELL_AURA_PERIODIC_TRIGGER_SPELL);
|
||||||
|
Unit::AuraEffectList const& aurasPeriodicTriggerWithValueSpell = bot->GetAuraEffectsByType(SPELL_AURA_PERIODIC_TRIGGER_SPELL_WITH_VALUE);
|
||||||
|
for (const Unit::AuraEffectList& list : {aurasPeriodicDamage, aurasPeriodicTriggerSpell, aurasPeriodicTriggerWithValueSpell}) {
|
||||||
|
for (auto i = list.begin(); i != list.end(); ++i)
|
||||||
{
|
{
|
||||||
Aura *aura = i->second->GetBase();
|
AuraEffect* aurEff = *i;
|
||||||
if (!aura)
|
Aura *aura = aurEff->GetBase();
|
||||||
continue;
|
|
||||||
|
|
||||||
AuraObjectType type = aura->GetType();
|
AuraObjectType type = aura->GetType();
|
||||||
// bool is_area = aura->IsArea();
|
|
||||||
bool isPositive = aura->GetSpellInfo()->IsPositive();
|
bool isPositive = aura->GetSpellInfo()->IsPositive();
|
||||||
if (type == DYNOBJ_AURA_TYPE && !isPositive) {
|
if (type == DYNOBJ_AURA_TYPE && !isPositive) {
|
||||||
DynamicObject* dynOwner = aura->GetDynobjOwner();
|
DynamicObject* dynOwner = aura->GetDynobjOwner();
|
||||||
@@ -138,5 +139,6 @@ Aura* AreaDebuffValue::Calculate()
|
|||||||
return aura;
|
return aura;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
@@ -45,7 +45,7 @@ WorldLocation ArrowFormation::GetLocationInternal()
|
|||||||
float y = master->GetPositionY() - masterUnit->GetY() + botUnit->GetY();
|
float y = master->GetPositionY() - masterUnit->GetY() + botUnit->GetY();
|
||||||
float z = master->GetPositionZ();
|
float z = master->GetPositionZ();
|
||||||
|
|
||||||
float ground = master->GetMap()->GetHeight(x, y, z + 30.0f);
|
float ground = master->GetMapHeight(x, y, z + 30.0f);
|
||||||
if (ground <= INVALID_HEIGHT)
|
if (ground <= INVALID_HEIGHT)
|
||||||
return Formation::NullLocation;
|
return Formation::NullLocation;
|
||||||
// master->UpdateGroundPositionZ(x, y, z);
|
// master->UpdateGroundPositionZ(x, y, z);
|
||||||
|
|||||||
@@ -88,7 +88,8 @@ class NearFormation : public MoveAheadFormation
|
|||||||
float x = master->GetPositionX() + cos(angle) * range;
|
float x = master->GetPositionX() + cos(angle) * range;
|
||||||
float y = master->GetPositionY() + sin(angle) * range;
|
float y = master->GetPositionY() + sin(angle) * range;
|
||||||
float z = master->GetPositionZ();
|
float z = master->GetPositionZ();
|
||||||
float ground = master->GetMap()->GetHeight(x, y, z + 30.0f);
|
|
||||||
|
float ground = master->GetMapHeight(x, y, z + 30.0f);
|
||||||
if (ground <= INVALID_HEIGHT)
|
if (ground <= INVALID_HEIGHT)
|
||||||
return Formation::NullLocation;
|
return Formation::NullLocation;
|
||||||
|
|
||||||
@@ -126,7 +127,7 @@ class ChaosFormation : public MoveAheadFormation
|
|||||||
float x = master->GetPositionX() + cos(angle) * range + dx;
|
float x = master->GetPositionX() + cos(angle) * range + dx;
|
||||||
float y = master->GetPositionY() + sin(angle) * range + dy;
|
float y = master->GetPositionY() + sin(angle) * range + dy;
|
||||||
float z = master->GetPositionZ();
|
float z = master->GetPositionZ();
|
||||||
float ground = master->GetMap()->GetHeight(x, y, z + 30.0f);
|
float ground = master->GetMapHeight(x, y, z + 30.0f);
|
||||||
if (ground <= INVALID_HEIGHT)
|
if (ground <= INVALID_HEIGHT)
|
||||||
return Formation::NullLocation;
|
return Formation::NullLocation;
|
||||||
|
|
||||||
@@ -183,7 +184,7 @@ class CircleFormation : public MoveFormation
|
|||||||
float x = target->GetPositionX() + cos(angle) * range;
|
float x = target->GetPositionX() + cos(angle) * range;
|
||||||
float y = target->GetPositionY() + sin(angle) * range;
|
float y = target->GetPositionY() + sin(angle) * range;
|
||||||
float z = target->GetPositionZ();
|
float z = target->GetPositionZ();
|
||||||
float ground = target->GetMap()->GetHeight(x, y, z + 30.0f);
|
float ground = target->GetMapHeight(x, y, z + 30.0f);
|
||||||
if (ground <= INVALID_HEIGHT)
|
if (ground <= INVALID_HEIGHT)
|
||||||
return Formation::NullLocation;
|
return Formation::NullLocation;
|
||||||
|
|
||||||
@@ -327,7 +328,7 @@ class FarFormation : public FollowFormation
|
|||||||
float y = master->GetPositionY() + sin(angle) * range + sin(followAngle) * followRange;
|
float y = master->GetPositionY() + sin(angle) * range + sin(followAngle) * followRange;
|
||||||
float z = master->GetPositionZ();
|
float z = master->GetPositionZ();
|
||||||
|
|
||||||
float ground = master->GetMap()->GetHeight(x, y, z + 30.0f);
|
float ground = master->GetMapHeight(x, y, z + 30.0f);
|
||||||
if (ground <= INVALID_HEIGHT)
|
if (ground <= INVALID_HEIGHT)
|
||||||
{
|
{
|
||||||
float minDist = 0, minX = 0, minY = 0;
|
float minDist = 0, minX = 0, minY = 0;
|
||||||
@@ -336,7 +337,7 @@ class FarFormation : public FollowFormation
|
|||||||
x = master->GetPositionX() + cos(angle) * range + cos(followAngle) * followRange;
|
x = master->GetPositionX() + cos(angle) * range + cos(followAngle) * followRange;
|
||||||
y = master->GetPositionY() + sin(angle) * range + sin(followAngle) * followRange;
|
y = master->GetPositionY() + sin(angle) * range + sin(followAngle) * followRange;
|
||||||
float dist = sServerFacade->GetDistance2d(bot, x, y);
|
float dist = sServerFacade->GetDistance2d(bot, x, y);
|
||||||
float ground = master->GetMap()->GetHeight(x, y, z + 30.0f);
|
float ground = master->GetMapHeight(x, y, z + 30.0f);
|
||||||
if (ground > INVALID_HEIGHT && (!minDist || minDist > dist))
|
if (ground > INVALID_HEIGHT && (!minDist || minDist > dist))
|
||||||
{
|
{
|
||||||
minDist = dist;
|
minDist = dist;
|
||||||
@@ -613,7 +614,7 @@ WorldLocation MoveFormation::MoveSingleLine(std::vector<Player*> line, float dif
|
|||||||
float lx = x + cos(angle) * radius;
|
float lx = x + cos(angle) * radius;
|
||||||
float ly = y + sin(angle) * radius;
|
float ly = y + sin(angle) * radius;
|
||||||
float lz = cz;
|
float lz = cz;
|
||||||
float ground = bot->GetMap()->GetHeight(lx, ly, lz + 30.0f);
|
float ground = bot->GetMapHeight(lx, ly, lz + 30.0f);
|
||||||
if (ground <= INVALID_HEIGHT)
|
if (ground <= INVALID_HEIGHT)
|
||||||
return Formation::NullLocation;
|
return Formation::NullLocation;
|
||||||
|
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ class NearestGameObjects : public ObjectGuidListCalculatedValue
|
|||||||
class NearestTrapWithDamageValue : public ObjectGuidListCalculatedValue
|
class NearestTrapWithDamageValue : public ObjectGuidListCalculatedValue
|
||||||
{
|
{
|
||||||
public:
|
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) { }
|
ObjectGuidListCalculatedValue(botAI, "nearest trap with damage", 1 * 1000), range(range) { }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|||||||
@@ -43,7 +43,7 @@ class NearestTriggersValue : public NearestUnitsValue
|
|||||||
class NearestTotemsValue : public NearestUnitsValue
|
class NearestTotemsValue : public NearestUnitsValue
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
NearestTotemsValue(PlayerbotAI* botAI, float range = 30.0f) : NearestUnitsValue(botAI, "nearest npcs", range, true) { }
|
NearestTotemsValue(PlayerbotAI* botAI, float range = 30.0f) : NearestUnitsValue(botAI, "nearest totems", range, true) { }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void FindUnits(std::list<Unit*>& targets) override;
|
void FindUnits(std::list<Unit*>& targets) override;
|
||||||
|
|||||||
@@ -14,8 +14,8 @@ class PlayerbotAI;
|
|||||||
class NearestUnitsValue : public ObjectGuidListCalculatedValue
|
class NearestUnitsValue : public ObjectGuidListCalculatedValue
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
NearestUnitsValue(PlayerbotAI* botAI, std::string const name = "nearest units", float range = sPlayerbotAIConfig->sightDistance, bool ignoreLos = false) :
|
NearestUnitsValue(PlayerbotAI* botAI, std::string const name = "nearest units", float range = sPlayerbotAIConfig->sightDistance, bool ignoreLos = false, uint32 checkInterval = 1) :
|
||||||
ObjectGuidListCalculatedValue(botAI, name, 1), range(range), ignoreLos(ignoreLos) { }
|
ObjectGuidListCalculatedValue(botAI, name, checkInterval), range(range), ignoreLos(ignoreLos) { }
|
||||||
|
|
||||||
GuidVector Calculate() override;
|
GuidVector Calculate() override;
|
||||||
|
|
||||||
|
|||||||
@@ -5,9 +5,14 @@
|
|||||||
#include "PossibleTargetsValue.h"
|
#include "PossibleTargetsValue.h"
|
||||||
#include "AttackersValue.h"
|
#include "AttackersValue.h"
|
||||||
#include "CellImpl.h"
|
#include "CellImpl.h"
|
||||||
|
#include "DBCStructure.h"
|
||||||
#include "GridNotifiers.h"
|
#include "GridNotifiers.h"
|
||||||
#include "GridNotifiersImpl.h"
|
#include "GridNotifiersImpl.h"
|
||||||
#include "Playerbots.h"
|
#include "Playerbots.h"
|
||||||
|
#include "SharedDefines.h"
|
||||||
|
#include "SpellAuraDefines.h"
|
||||||
|
#include "SpellAuraEffects.h"
|
||||||
|
#include "SpellMgr.h"
|
||||||
#include "Unit.h"
|
#include "Unit.h"
|
||||||
|
|
||||||
void PossibleTargetsValue::FindUnits(std::list<Unit*>& targets)
|
void PossibleTargetsValue::FindUnits(std::list<Unit*>& targets)
|
||||||
@@ -31,7 +36,27 @@ void PossibleTriggersValue::FindUnits(std::list<Unit*>& targets)
|
|||||||
|
|
||||||
bool PossibleTriggersValue::AcceptUnit(Unit* unit)
|
bool PossibleTriggersValue::AcceptUnit(Unit* unit)
|
||||||
{
|
{
|
||||||
return unit->HasUnitFlag(UNIT_FLAG_NON_ATTACKABLE) && unit->HasUnitFlag(UNIT_FLAG_NOT_SELECTABLE);
|
if (!unit->HasUnitFlag(UNIT_FLAG_NOT_SELECTABLE)) {
|
||||||
return true; // AttackersValue::IsPossibleTarget(unit, bot, range);
|
return false;
|
||||||
|
}
|
||||||
|
Unit::AuraEffectList const& aurasPeriodicTriggerSpell = unit->GetAuraEffectsByType(SPELL_AURA_PERIODIC_TRIGGER_SPELL);
|
||||||
|
Unit::AuraEffectList const& aurasPeriodicTriggerWithValueSpell = unit->GetAuraEffectsByType(SPELL_AURA_PERIODIC_TRIGGER_SPELL_WITH_VALUE);
|
||||||
|
for (const Unit::AuraEffectList& list : {aurasPeriodicTriggerSpell, aurasPeriodicTriggerWithValueSpell}) {
|
||||||
|
for (auto i = list.begin(); i != list.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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -30,8 +30,8 @@ class AllTargetsValue : public PossibleTargetsValue
|
|||||||
class PossibleTriggersValue : public NearestUnitsValue
|
class PossibleTriggersValue : public NearestUnitsValue
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
PossibleTriggersValue(PlayerbotAI* botAI, std::string const name = "possible targets", float range = sPlayerbotAIConfig->sightDistance, bool ignoreLos = true):
|
PossibleTriggersValue(PlayerbotAI* botAI, std::string const name = "possible triggers", float range = 15.0f, bool ignoreLos = true):
|
||||||
NearestUnitsValue(botAI, name, range, ignoreLos) { }
|
NearestUnitsValue(botAI, name, range, ignoreLos, 1 * 1000) { }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void FindUnits(std::list<Unit*>& targets) override;
|
void FindUnits(std::list<Unit*>& targets) override;
|
||||||
|
|||||||
Reference in New Issue
Block a user