mirror of
https://github.com/mod-playerbots/mod-playerbots
synced 2025-11-29 15:58:20 +08:00
Merge pull request #180 from liyunfan1223/perf
Performance optimization
This commit is contained in:
@@ -256,6 +256,10 @@ AiPlayerbot.GlobalCooldown = 500
|
|||||||
# Max wait time when moving
|
# Max wait time when moving
|
||||||
AiPlayerbot.MaxWaitForMove = 5000
|
AiPlayerbot.MaxWaitForMove = 5000
|
||||||
|
|
||||||
|
# Max search time for movement (higher for better movement on slopes)
|
||||||
|
# default: 3
|
||||||
|
AiPlayerbot.MaxMovementSearchTime = 3
|
||||||
|
|
||||||
# Action expiration time
|
# Action expiration time
|
||||||
AiPlayerbot.ExpireActionTime = 5000
|
AiPlayerbot.ExpireActionTime = 5000
|
||||||
|
|
||||||
|
|||||||
@@ -1993,7 +1993,7 @@ bool PlayerbotAI::HasAura(std::string const name, Unit* unit, bool maxStack, boo
|
|||||||
{
|
{
|
||||||
SpellInfo const* spellInfo = aurEff->GetSpellInfo();
|
SpellInfo const* spellInfo = aurEff->GetSpellInfo();
|
||||||
|
|
||||||
std::string const auraName = spellInfo->SpellName[0];
|
std::string_view const auraName = spellInfo->SpellName[0];
|
||||||
if (auraName.empty() || auraName.length() != wnamepart.length() || !Utf8FitTo(auraName, wnamepart))
|
if (auraName.empty() || auraName.length() != wnamepart.length() || !Utf8FitTo(auraName, wnamepart))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
|||||||
@@ -53,6 +53,7 @@ bool PlayerbotAIConfig::Initialize()
|
|||||||
|
|
||||||
globalCoolDown = sConfigMgr->GetOption<int32>("AiPlayerbot.GlobalCooldown", 1500);
|
globalCoolDown = sConfigMgr->GetOption<int32>("AiPlayerbot.GlobalCooldown", 1500);
|
||||||
maxWaitForMove = sConfigMgr->GetOption<int32>("AiPlayerbot.MaxWaitForMove", 5000);
|
maxWaitForMove = sConfigMgr->GetOption<int32>("AiPlayerbot.MaxWaitForMove", 5000);
|
||||||
|
maxMovementSearchTime = sConfigMgr->GetOption<int32>("AiPlayerbot.MaxMovementSearchTime", 3);
|
||||||
expireActionTime = sConfigMgr->GetOption<int32>("AiPlayerbot.ExpireActionTime", 5000);
|
expireActionTime = sConfigMgr->GetOption<int32>("AiPlayerbot.ExpireActionTime", 5000);
|
||||||
dispelAuraDuration = sConfigMgr->GetOption<int32>("AiPlayerbot.DispelAuraDuration", 7000);
|
dispelAuraDuration = sConfigMgr->GetOption<int32>("AiPlayerbot.DispelAuraDuration", 7000);
|
||||||
reactDelay = sConfigMgr->GetOption<int32>("AiPlayerbot.ReactDelay", 500);
|
reactDelay = sConfigMgr->GetOption<int32>("AiPlayerbot.ReactDelay", 500);
|
||||||
|
|||||||
@@ -54,7 +54,8 @@ class PlayerbotAIConfig
|
|||||||
|
|
||||||
bool enabled;
|
bool enabled;
|
||||||
bool allowGuildBots, allowPlayerBots;
|
bool allowGuildBots, allowPlayerBots;
|
||||||
uint32 globalCoolDown, reactDelay, maxWaitForMove, expireActionTime, dispelAuraDuration, passiveDelay, repeatDelay,
|
uint32 globalCoolDown, reactDelay, maxWaitForMove, maxMovementSearchTime, expireActionTime,
|
||||||
|
dispelAuraDuration, passiveDelay, repeatDelay,
|
||||||
errorDelay, rpgDelay, sitDelay, returnDelay, lootDelay;
|
errorDelay, rpgDelay, sitDelay, returnDelay, lootDelay;
|
||||||
float sightDistance, spellDistance, reactDistance, grindDistance, lootDistance, shootDistance,
|
float sightDistance, spellDistance, reactDistance, grindDistance, lootDistance, shootDistance,
|
||||||
fleeDistance, tooCloseDistance, meleeDistance, followDistance, whisperDistance, contactDistance,
|
fleeDistance, tooCloseDistance, meleeDistance, followDistance, whisperDistance, contactDistance,
|
||||||
|
|||||||
@@ -605,7 +605,7 @@ void PlayerbotFactory::InitPetTalents()
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
pet->resetTalents();
|
pet->resetTalents();
|
||||||
std::map<uint32, std::vector<TalentEntry const*> > spells;
|
std::unordered_map<uint32, std::vector<TalentEntry const*> > spells;
|
||||||
for (uint32 i = 0; i < sTalentStore.GetNumRows(); ++i)
|
for (uint32 i = 0; i < sTalentStore.GetNumRows(); ++i)
|
||||||
{
|
{
|
||||||
TalentEntry const *talentInfo = sTalentStore.LookupEntry(i);
|
TalentEntry const *talentInfo = sTalentStore.LookupEntry(i);
|
||||||
@@ -625,7 +625,7 @@ void PlayerbotFactory::InitPetTalents()
|
|||||||
uint32 maxTalentPoints = pet->GetMaxTalentPointsForLevel(pet->GetLevel());
|
uint32 maxTalentPoints = pet->GetMaxTalentPointsForLevel(pet->GetLevel());
|
||||||
int row = 0;
|
int row = 0;
|
||||||
// LOG_INFO("playerbots", "{} learning, max talent points: {}, cur: {}", bot->GetName().c_str(), maxTalentPoints, curTalentPoints);
|
// LOG_INFO("playerbots", "{} learning, max talent points: {}, cur: {}", bot->GetName().c_str(), maxTalentPoints, curTalentPoints);
|
||||||
for (std::map<uint32, std::vector<TalentEntry const*> >::iterator i = spells.begin(); i != spells.end(); ++i, ++row)
|
for (auto i = spells.begin(); i != spells.end(); ++i, ++row)
|
||||||
{
|
{
|
||||||
std::vector<TalentEntry const*> &spells_row = i->second;
|
std::vector<TalentEntry const*> &spells_row = i->second;
|
||||||
if (spells_row.empty())
|
if (spells_row.empty())
|
||||||
@@ -893,7 +893,7 @@ void PlayerbotFactory::InitTalentsBySpecNo(Player* bot, int specNo, bool reset)
|
|||||||
uint32 cls = bot->getClass();
|
uint32 cls = bot->getClass();
|
||||||
int startLevel = bot->GetLevel();
|
int startLevel = bot->GetLevel();
|
||||||
uint32 classMask = bot->getClassMask();
|
uint32 classMask = bot->getClassMask();
|
||||||
std::map<uint32, std::vector<TalentEntry const*> > spells_row;
|
std::unordered_map<uint32, std::vector<TalentEntry const*> > spells_row;
|
||||||
for (uint32 i = 0; i < sTalentStore.GetNumRows(); ++i)
|
for (uint32 i = 0; i < sTalentStore.GetNumRows(); ++i)
|
||||||
{
|
{
|
||||||
TalentEntry const *talentInfo = sTalentStore.LookupEntry(i);
|
TalentEntry const *talentInfo = sTalentStore.LookupEntry(i);
|
||||||
@@ -954,7 +954,7 @@ void PlayerbotFactory::InitTalentsByParsedSpecLink(Player* bot, std::vector<std:
|
|||||||
bot->resetTalents(true);
|
bot->resetTalents(true);
|
||||||
}
|
}
|
||||||
uint32 classMask = bot->getClassMask();
|
uint32 classMask = bot->getClassMask();
|
||||||
std::map<uint32, std::vector<TalentEntry const*> > spells_row;
|
std::unordered_map<uint32, std::vector<TalentEntry const*> > spells_row;
|
||||||
for (uint32 i = 0; i < sTalentStore.GetNumRows(); ++i)
|
for (uint32 i = 0; i < sTalentStore.GetNumRows(); ++i)
|
||||||
{
|
{
|
||||||
TalentEntry const *talentInfo = sTalentStore.LookupEntry(i);
|
TalentEntry const *talentInfo = sTalentStore.LookupEntry(i);
|
||||||
@@ -2248,7 +2248,7 @@ void PlayerbotFactory::InitSpecialSpells()
|
|||||||
void PlayerbotFactory::InitTalents(uint32 specNo)
|
void PlayerbotFactory::InitTalents(uint32 specNo)
|
||||||
{
|
{
|
||||||
uint32 classMask = bot->getClassMask();
|
uint32 classMask = bot->getClassMask();
|
||||||
std::map<uint32, std::vector<TalentEntry const*> > spells;
|
std::unordered_map<uint32, std::vector<TalentEntry const*> > spells;
|
||||||
for (uint32 i = 0; i < sTalentStore.GetNumRows(); ++i)
|
for (uint32 i = 0; i < sTalentStore.GetNumRows(); ++i)
|
||||||
{
|
{
|
||||||
TalentEntry const *talentInfo = sTalentStore.LookupEntry(i);
|
TalentEntry const *talentInfo = sTalentStore.LookupEntry(i);
|
||||||
@@ -2266,7 +2266,7 @@ void PlayerbotFactory::InitTalents(uint32 specNo)
|
|||||||
}
|
}
|
||||||
|
|
||||||
uint32 freePoints = bot->GetFreeTalentPoints();
|
uint32 freePoints = bot->GetFreeTalentPoints();
|
||||||
for (std::map<uint32, std::vector<TalentEntry const*> >::iterator i = spells.begin(); i != spells.end(); ++i)
|
for (auto i = spells.begin(); i != spells.end(); ++i)
|
||||||
{
|
{
|
||||||
std::vector<TalentEntry const*> &spells_row = i->second;
|
std::vector<TalentEntry const*> &spells_row = i->second;
|
||||||
if (spells_row.empty())
|
if (spells_row.empty())
|
||||||
@@ -2308,7 +2308,7 @@ void PlayerbotFactory::InitTalentsByTemplate(uint32 specTab)
|
|||||||
int startLevel = bot->GetLevel();
|
int startLevel = bot->GetLevel();
|
||||||
uint32 specIndex = sPlayerbotAIConfig->randomClassSpecIndex[cls][specTab];
|
uint32 specIndex = sPlayerbotAIConfig->randomClassSpecIndex[cls][specTab];
|
||||||
uint32 classMask = bot->getClassMask();
|
uint32 classMask = bot->getClassMask();
|
||||||
std::map<uint32, std::vector<TalentEntry const*> > spells_row;
|
std::unordered_map<uint32, std::vector<TalentEntry const*> > spells_row;
|
||||||
for (uint32 i = 0; i < sTalentStore.GetNumRows(); ++i)
|
for (uint32 i = 0; i < sTalentStore.GetNumRows(); ++i)
|
||||||
{
|
{
|
||||||
TalentEntry const *talentInfo = sTalentStore.LookupEntry(i);
|
TalentEntry const *talentInfo = sTalentStore.LookupEntry(i);
|
||||||
@@ -2648,7 +2648,7 @@ void PlayerbotFactory::InitFood()
|
|||||||
if (sPlayerbotAIConfig->freeFood) {
|
if (sPlayerbotAIConfig->freeFood) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
std::map<uint32, std::vector<uint32> > items;
|
std::unordered_map<uint32, std::vector<uint32> > items;
|
||||||
ItemTemplateContainer const* itemTemplateContainer = sObjectMgr->GetItemTemplateStore();
|
ItemTemplateContainer const* itemTemplateContainer = sObjectMgr->GetItemTemplateStore();
|
||||||
for (ItemTemplateContainer::const_iterator i = itemTemplateContainer->begin(); i != itemTemplateContainer->end(); ++i)
|
for (ItemTemplateContainer::const_iterator i = itemTemplateContainer->begin(); i != itemTemplateContainer->end(); ++i)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -900,7 +900,7 @@ std::vector<std::string> PlayerbotHolder::HandlePlayerbotCommand(char const* arg
|
|||||||
|
|
||||||
std::string const cmdStr = cmd;
|
std::string const cmdStr = cmd;
|
||||||
|
|
||||||
std::set<std::string> bots;
|
std::unordered_set<std::string> bots;
|
||||||
if (charnameStr == "*" && master)
|
if (charnameStr == "*" && master)
|
||||||
{
|
{
|
||||||
Group* group = master->GetGroup();
|
Group* group = master->GetGroup();
|
||||||
@@ -958,7 +958,7 @@ std::vector<std::string> PlayerbotHolder::HandlePlayerbotCommand(char const* arg
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (std::set<std::string>::iterator i = bots.begin(); i != bots.end(); ++i)
|
for (auto i = bots.begin(); i != bots.end(); ++i)
|
||||||
{
|
{
|
||||||
std::string const bot = *i;
|
std::string const bot = *i;
|
||||||
|
|
||||||
|
|||||||
@@ -7,8 +7,9 @@
|
|||||||
|
|
||||||
#include "Common.h"
|
#include "Common.h"
|
||||||
|
|
||||||
#include <map>
|
#include <unordered_map>
|
||||||
#include <set>
|
#include <set>
|
||||||
|
#include <unordered_set>
|
||||||
#include <list>
|
#include <list>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
@@ -46,7 +47,7 @@ class NamedObjectFactory
|
|||||||
{
|
{
|
||||||
protected:
|
protected:
|
||||||
typedef T*(*ActionCreator)(PlayerbotAI* botAI);
|
typedef T*(*ActionCreator)(PlayerbotAI* botAI);
|
||||||
std::map<std::string, ActionCreator> creators;
|
std::unordered_map<std::string, ActionCreator> creators;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
T* create(std::string name, PlayerbotAI* botAI)
|
T* create(std::string name, PlayerbotAI* botAI)
|
||||||
@@ -77,7 +78,7 @@ class NamedObjectFactory
|
|||||||
std::set<std::string> supports()
|
std::set<std::string> supports()
|
||||||
{
|
{
|
||||||
std::set<std::string> keys;
|
std::set<std::string> keys;
|
||||||
for (typename std::map<std::string, ActionCreator>::iterator it = creators.begin(); it != creators.end(); it++)
|
for (typename std::unordered_map<std::string, ActionCreator>::iterator it = creators.begin(); it != creators.end(); it++)
|
||||||
keys.insert(it->first);
|
keys.insert(it->first);
|
||||||
|
|
||||||
return keys;
|
return keys;
|
||||||
@@ -106,7 +107,7 @@ class NamedObjectContext : public NamedObjectFactory<T>
|
|||||||
|
|
||||||
void Clear()
|
void Clear()
|
||||||
{
|
{
|
||||||
for (typename std::map<std::string, T*>::iterator i = created.begin(); i != created.end(); i++)
|
for (typename std::unordered_map<std::string, T*>::iterator i = created.begin(); i != created.end(); i++)
|
||||||
{
|
{
|
||||||
if (i->second)
|
if (i->second)
|
||||||
delete i->second;
|
delete i->second;
|
||||||
@@ -117,7 +118,7 @@ class NamedObjectContext : public NamedObjectFactory<T>
|
|||||||
|
|
||||||
void Update()
|
void Update()
|
||||||
{
|
{
|
||||||
for (typename std::map<std::string, T*>::iterator i = created.begin(); i != created.end(); i++)
|
for (typename std::unordered_map<std::string, T*>::iterator i = created.begin(); i != created.end(); i++)
|
||||||
{
|
{
|
||||||
if (i->second)
|
if (i->second)
|
||||||
i->second->Update();
|
i->second->Update();
|
||||||
@@ -126,7 +127,7 @@ class NamedObjectContext : public NamedObjectFactory<T>
|
|||||||
|
|
||||||
void Reset()
|
void Reset()
|
||||||
{
|
{
|
||||||
for (typename std::map<std::string, T*>::iterator i = created.begin(); i != created.end(); i++)
|
for (typename std::unordered_map<std::string, T*>::iterator i = created.begin(); i != created.end(); i++)
|
||||||
{
|
{
|
||||||
if (i->second)
|
if (i->second)
|
||||||
i->second->Reset();
|
i->second->Reset();
|
||||||
@@ -139,14 +140,14 @@ class NamedObjectContext : public NamedObjectFactory<T>
|
|||||||
std::set<std::string> GetCreated()
|
std::set<std::string> GetCreated()
|
||||||
{
|
{
|
||||||
std::set<std::string> keys;
|
std::set<std::string> keys;
|
||||||
for (typename std::map<std::string, T*>::iterator it = created.begin(); it != created.end(); it++)
|
for (typename std::unordered_map<std::string, T*>::iterator it = created.begin(); it != created.end(); it++)
|
||||||
keys.insert(it->first);
|
keys.insert(it->first);
|
||||||
|
|
||||||
return keys;
|
return keys;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
std::map<std::string, T*> created;
|
std::unordered_map<std::string, T*> created;
|
||||||
bool shared;
|
bool shared;
|
||||||
bool supportsSiblings;
|
bool supportsSiblings;
|
||||||
};
|
};
|
||||||
@@ -264,7 +265,7 @@ class NamedObjectFactoryList
|
|||||||
factories.push_front(context);
|
factories.push_front(context);
|
||||||
}
|
}
|
||||||
|
|
||||||
T* GetContextObject(std::string const name, PlayerbotAI* botAI)
|
T* GetContextObject(std::string const &name, PlayerbotAI* botAI)
|
||||||
{
|
{
|
||||||
for (typename std::list<NamedObjectFactory<T>*>::iterator i = factories.begin(); i != factories.end(); i++)
|
for (typename std::list<NamedObjectFactory<T>*>::iterator i = factories.begin(); i != factories.end(); i++)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -3,7 +3,9 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "MovementActions.h"
|
#include "MovementActions.h"
|
||||||
|
#include "Map.h"
|
||||||
#include "MotionMaster.h"
|
#include "MotionMaster.h"
|
||||||
|
#include "MoveSplineInitArgs.h"
|
||||||
#include "MovementGenerator.h"
|
#include "MovementGenerator.h"
|
||||||
#include "ObjectDefines.h"
|
#include "ObjectDefines.h"
|
||||||
#include "ObjectGuid.h"
|
#include "ObjectGuid.h"
|
||||||
@@ -151,13 +153,8 @@ bool MovementAction::MoveTo(uint32 mapId, float x, float y, float z, bool idle,
|
|||||||
// }
|
// }
|
||||||
bool generatePath = !bot->HasAuraType(SPELL_AURA_MOD_INCREASE_MOUNTED_FLIGHT_SPEED) &&
|
bool generatePath = !bot->HasAuraType(SPELL_AURA_MOD_INCREASE_MOUNTED_FLIGHT_SPEED) &&
|
||||||
!bot->IsFlying() && !bot->HasUnitMovementFlag(MOVEMENTFLAG_SWIMMING) && !bot->IsInWater();
|
!bot->IsFlying() && !bot->HasUnitMovementFlag(MOVEMENTFLAG_SWIMMING) && !bot->IsInWater();
|
||||||
float modifiedZ = SearchBestGroundZForPath(x, y, z, generatePath, 20.0f, normal_only, 8.0f);
|
if (!generatePath) {
|
||||||
if (modifiedZ == INVALID_HEIGHT) {
|
float distance = bot->GetExactDist(x, y, z);
|
||||||
return false;
|
|
||||||
}
|
|
||||||
float distance = bot->GetExactDist(x, y, modifiedZ);
|
|
||||||
if (distance > sPlayerbotAIConfig->contactDistance)
|
|
||||||
{
|
|
||||||
WaitForReach(distance);
|
WaitForReach(distance);
|
||||||
|
|
||||||
if (bot->IsSitState())
|
if (bot->IsSitState())
|
||||||
@@ -171,9 +168,36 @@ bool MovementAction::MoveTo(uint32 mapId, float x, float y, float z, bool idle,
|
|||||||
MotionMaster &mm = *bot->GetMotionMaster();
|
MotionMaster &mm = *bot->GetMotionMaster();
|
||||||
|
|
||||||
mm.Clear();
|
mm.Clear();
|
||||||
mm.MovePoint(mapId, x, y, modifiedZ, generatePath);
|
mm.MovePoint(mapId, x, y, z, generatePath);
|
||||||
AI_VALUE(LastMovement&, "last movement").Set(mapId, x, y, z, bot->GetOrientation());
|
AI_VALUE(LastMovement&, "last movement").Set(mapId, x, y, z, bot->GetOrientation());
|
||||||
return true;
|
return true;
|
||||||
|
} else {
|
||||||
|
float modifiedZ;
|
||||||
|
Movement::PointsArray path = SearchForBestPath(x, y, z, modifiedZ, sPlayerbotAIConfig->maxMovementSearchTime);
|
||||||
|
if (modifiedZ == INVALID_HEIGHT) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
float distance = bot->GetExactDist(x, y, modifiedZ);
|
||||||
|
if (distance > sPlayerbotAIConfig->contactDistance)
|
||||||
|
{
|
||||||
|
WaitForReach(distance);
|
||||||
|
|
||||||
|
if (bot->IsSitState())
|
||||||
|
bot->SetStandState(UNIT_STAND_STATE_STAND);
|
||||||
|
|
||||||
|
if (bot->IsNonMeleeSpellCast(true))
|
||||||
|
{
|
||||||
|
bot->CastStop();
|
||||||
|
botAI->InterruptSpell();
|
||||||
|
}
|
||||||
|
MotionMaster &mm = *bot->GetMotionMaster();
|
||||||
|
|
||||||
|
mm.Clear();
|
||||||
|
mm.MoveSplinePath(&path);
|
||||||
|
AI_VALUE(LastMovement&, "last movement").Set(mapId, x, y, z, bot->GetOrientation());
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
@@ -1324,60 +1348,109 @@ bool MovementAction::MoveInside(uint32 mapId, float x, float y, float z, float d
|
|||||||
return MoveNear(mapId, x, y, z, distance);
|
return MoveNear(mapId, x, y, z, distance);
|
||||||
}
|
}
|
||||||
|
|
||||||
float MovementAction::SearchBestGroundZForPath(float x, float y, float z, bool generatePath, float range, bool normal_only, float step)
|
// float MovementAction::SearchBestGroundZForPath(float x, float y, float z, bool generatePath, float range, bool normal_only, float step)
|
||||||
{
|
// {
|
||||||
if (!generatePath) {
|
// if (!generatePath) {
|
||||||
return z;
|
// return z;
|
||||||
}
|
// }
|
||||||
float min_length = 100000.0f;
|
// float min_length = 100000.0f;
|
||||||
float current_z = INVALID_HEIGHT;
|
// float current_z = INVALID_HEIGHT;
|
||||||
float modified_z;
|
// float modified_z;
|
||||||
float delta;
|
// float delta;
|
||||||
for (delta = 0.0f; delta <= range / 2; delta += step) {
|
// for (delta = 0.0f; delta <= range / 2; delta += step) {
|
||||||
modified_z = bot->GetMapWaterOrGroundLevel(x, y, z + delta);
|
// modified_z = bot->GetMapWaterOrGroundLevel(x, y, z + delta);
|
||||||
PathGenerator gen(bot);
|
// PathGenerator gen(bot);
|
||||||
gen.CalculatePath(x, y, modified_z);
|
// gen.CalculatePath(x, y, modified_z);
|
||||||
if (gen.GetPathType() == PATHFIND_NORMAL && gen.getPathLength() < min_length) {
|
// if (gen.GetPathType() == PATHFIND_NORMAL && gen.getPathLength() < min_length) {
|
||||||
min_length = gen.getPathLength();
|
// min_length = gen.getPathLength();
|
||||||
current_z = modified_z;
|
// current_z = modified_z;
|
||||||
if (abs(current_z - z) < 0.5f) {
|
// if (abs(current_z - z) < 0.5f) {
|
||||||
return current_z;
|
// return current_z;
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
for (delta = -step; delta >= -range / 2; delta -= step) {
|
// for (delta = -step; delta >= -range / 2; delta -= step) {
|
||||||
modified_z = bot->GetMapWaterOrGroundLevel(x, y, z + delta);
|
// modified_z = bot->GetMapWaterOrGroundLevel(x, y, z + delta);
|
||||||
PathGenerator gen(bot);
|
// PathGenerator gen(bot);
|
||||||
gen.CalculatePath(x, y, modified_z);
|
// gen.CalculatePath(x, y, modified_z);
|
||||||
if (gen.GetPathType() == PATHFIND_NORMAL && gen.getPathLength() < min_length) {
|
// if (gen.GetPathType() == PATHFIND_NORMAL && gen.getPathLength() < min_length) {
|
||||||
min_length = gen.getPathLength();
|
// min_length = gen.getPathLength();
|
||||||
current_z = modified_z;
|
// current_z = modified_z;
|
||||||
if (abs(current_z - z) < 0.5f) {
|
// if (abs(current_z - z) < 0.5f) {
|
||||||
return current_z;
|
// return current_z;
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
for (delta = range / 2 + step; delta <= range; delta += 2) {
|
// for (delta = range / 2 + step; delta <= range; delta += 2) {
|
||||||
modified_z = bot->GetMapWaterOrGroundLevel(x, y, z + delta);
|
// modified_z = bot->GetMapWaterOrGroundLevel(x, y, z + delta);
|
||||||
PathGenerator gen(bot);
|
// PathGenerator gen(bot);
|
||||||
gen.CalculatePath(x, y, modified_z);
|
// gen.CalculatePath(x, y, modified_z);
|
||||||
if (gen.GetPathType() == PATHFIND_NORMAL && gen.getPathLength() < min_length) {
|
// if (gen.GetPathType() == PATHFIND_NORMAL && gen.getPathLength() < min_length) {
|
||||||
min_length = gen.getPathLength();
|
// min_length = gen.getPathLength();
|
||||||
current_z = modified_z;
|
// current_z = modified_z;
|
||||||
if (abs(current_z - z) < 0.5f) {
|
// if (abs(current_z - z) < 0.5f) {
|
||||||
return current_z;
|
// return current_z;
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
if (current_z == INVALID_HEIGHT && normal_only) {
|
// if (current_z == INVALID_HEIGHT && normal_only) {
|
||||||
return INVALID_HEIGHT;
|
// return INVALID_HEIGHT;
|
||||||
}
|
// }
|
||||||
if (current_z == INVALID_HEIGHT && !normal_only) {
|
// if (current_z == INVALID_HEIGHT && !normal_only) {
|
||||||
return z;
|
// return z;
|
||||||
}
|
// }
|
||||||
return current_z;
|
// return current_z;
|
||||||
}
|
// }
|
||||||
|
|
||||||
|
const Movement::PointsArray MovementAction::SearchForBestPath(float x, float y, float z, float &modified_z, int maxSearchCount, bool normal_only, float step)
|
||||||
|
{
|
||||||
|
bool found = false;
|
||||||
|
modified_z = INVALID_HEIGHT;
|
||||||
|
float tempZ = bot->GetMapWaterOrGroundLevel(x, y, z);
|
||||||
|
PathGenerator gen(bot);
|
||||||
|
gen.CalculatePath(x, y, tempZ);
|
||||||
|
Movement::PointsArray result = gen.GetPath();
|
||||||
|
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) {
|
||||||
|
found = true;
|
||||||
|
modified_z = tempZ;
|
||||||
|
}
|
||||||
|
int count = 1;
|
||||||
|
for (float delta = step; count < maxSearchCount / 2 + 1; count++, delta += step) {
|
||||||
|
tempZ = bot->GetMapWaterOrGroundLevel(x, y, z + delta);
|
||||||
|
PathGenerator gen(bot);
|
||||||
|
gen.CalculatePath(x, y, tempZ);
|
||||||
|
if (gen.GetPathType() == PATHFIND_NORMAL && gen.getPathLength() < min_length) {
|
||||||
|
found = true;
|
||||||
|
min_length = gen.getPathLength();
|
||||||
|
result = gen.GetPath();
|
||||||
|
modified_z = tempZ;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (float delta = -step; count < maxSearchCount; count++, delta -= step) {
|
||||||
|
tempZ = bot->GetMapWaterOrGroundLevel(x, y, z + delta);
|
||||||
|
PathGenerator gen(bot);
|
||||||
|
gen.CalculatePath(x, y, tempZ);
|
||||||
|
if (gen.GetPathType() == PATHFIND_NORMAL && gen.getPathLength() < min_length) {
|
||||||
|
found = true;
|
||||||
|
min_length = gen.getPathLength();
|
||||||
|
result = gen.GetPath();
|
||||||
|
modified_z = tempZ;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!found && normal_only) {
|
||||||
|
return Movement::PointsArray{};
|
||||||
|
}
|
||||||
|
if (!found && !normal_only) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
bool FleeAction::Execute(Event event)
|
bool FleeAction::Execute(Event event)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -42,7 +42,8 @@ class MovementAction : public Action
|
|||||||
bool MoveInside(uint32 mapId, float x, float y, float z, float distance = sPlayerbotAIConfig->followDistance);
|
bool MoveInside(uint32 mapId, float x, float y, float z, float distance = sPlayerbotAIConfig->followDistance);
|
||||||
void CreateWp(Player* wpOwner, float x, float y, float z, float o, uint32 entry, bool important = false);
|
void CreateWp(Player* wpOwner, float x, float y, float z, float o, uint32 entry, bool important = false);
|
||||||
private:
|
private:
|
||||||
float SearchBestGroundZForPath(float x, float y, float z, bool generatePath, float range = 20.0f, bool normal_only = false, float step = 8.0f);
|
// float SearchBestGroundZForPath(float x, float y, float z, bool generatePath, float range = 20.0f, bool normal_only = false, float step = 8.0f);
|
||||||
|
const Movement::PointsArray SearchForBestPath(float x, float y, float z, float &modified_z, int maxSearchCount = 5, bool normal_only = false, float step = 8.0f);
|
||||||
};
|
};
|
||||||
|
|
||||||
class FleeAction : public MovementAction
|
class FleeAction : public MovementAction
|
||||||
|
|||||||
@@ -9,24 +9,59 @@ char* strstri(char const* str1, char const* str2);
|
|||||||
|
|
||||||
bool HasTotemValue::Calculate()
|
bool HasTotemValue::Calculate()
|
||||||
{
|
{
|
||||||
GuidVector units = *context->GetValue<GuidVector>("nearest npcs");
|
for (uint8 i = 0; i < MAX_SUMMON_SLOT; ++i)
|
||||||
for (ObjectGuid const guid : units)
|
|
||||||
{
|
{
|
||||||
Unit* unit = botAI->GetUnit(guid);
|
if (!bot->m_SummonSlot[i])
|
||||||
if (!unit)
|
{
|
||||||
continue;
|
|
||||||
|
|
||||||
Creature* creature = dynamic_cast<Creature*>(unit);
|
|
||||||
if (!creature || !creature->IsTotem())
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (creature->GetOwner() != bot) {
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (strstri(creature->GetName().c_str(), qualifier.c_str()) && bot->GetDistance(creature) <= botAI->GetRange("spell"))
|
if (Creature* OldTotem = bot->GetMap()->GetCreature(bot->m_SummonSlot[i]))
|
||||||
return true;
|
{
|
||||||
|
if (OldTotem->IsSummon() && OldTotem->GetDistance(bot) <= 30.0f)
|
||||||
|
{
|
||||||
|
if (strstri(OldTotem->GetName().c_str(), qualifier.c_str()))
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// bool HasTotemValue::Calculate()
|
||||||
|
// {
|
||||||
|
// for (uint8 i = 0; i < MAX_SUMMON_SLOT; ++i)
|
||||||
|
// {
|
||||||
|
// if (!bot->m_SummonSlot[i])
|
||||||
|
// {
|
||||||
|
// continue;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// if (Creature* OldTotem = bot->GetMap()->GetCreature(bot->m_SummonSlot[i]))
|
||||||
|
// {
|
||||||
|
// if (OldTotem->IsSummon())
|
||||||
|
// {
|
||||||
|
// if (strstri(creature->GetName().c_str(), qualifier.c_str()))
|
||||||
|
// return true;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
// GuidVector units = *context->GetValue<GuidVector>("nearest totems");
|
||||||
|
// for (ObjectGuid const guid : units)
|
||||||
|
// {
|
||||||
|
// Unit* unit = botAI->GetUnit(guid);
|
||||||
|
// if (!unit)
|
||||||
|
// continue;
|
||||||
|
// Creature* creature = dynamic_cast<Creature*>(unit);
|
||||||
|
|
||||||
|
// if (creature->GetOwner() != bot) {
|
||||||
|
// continue;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// if (strstri(creature->GetName().c_str(), qualifier.c_str()))
|
||||||
|
// return true;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// return false;
|
||||||
|
// }
|
||||||
|
|||||||
@@ -51,3 +51,15 @@ bool NearestTriggersValue::AcceptUnit(Unit* unit)
|
|||||||
{
|
{
|
||||||
return !unit->IsPlayer();
|
return !unit->IsPlayer();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void NearestTotemsValue::FindUnits(std::list<Unit*>& targets)
|
||||||
|
{
|
||||||
|
Acore::AnyUnitInObjectRangeCheck u_check(bot, range);
|
||||||
|
Acore::UnitListSearcher<Acore::AnyUnitInObjectRangeCheck> searcher(bot, targets, u_check);
|
||||||
|
Cell::VisitAllObjects(bot, searcher, range);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool NearestTotemsValue::AcceptUnit(Unit* unit)
|
||||||
|
{
|
||||||
|
return unit->IsTotem();
|
||||||
|
}
|
||||||
@@ -39,4 +39,15 @@ class NearestTriggersValue : public NearestUnitsValue
|
|||||||
void FindUnits(std::list<Unit*>& targets) override;
|
void FindUnits(std::list<Unit*>& targets) override;
|
||||||
bool AcceptUnit(Unit* unit) override;
|
bool AcceptUnit(Unit* unit) override;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class NearestTotemsValue : public NearestUnitsValue
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
NearestTotemsValue(PlayerbotAI* botAI, float range = 30.0f) : NearestUnitsValue(botAI, "nearest npcs", range, true) { }
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void FindUnits(std::list<Unit*>& targets) override;
|
||||||
|
bool AcceptUnit(Unit* unit) override;
|
||||||
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -103,6 +103,7 @@ class ValueContext : public NamedObjectContext<UntypedValue>
|
|||||||
creators["nearest game objects no los"] = &ValueContext::nearest_game_objects_no_los;
|
creators["nearest game objects no los"] = &ValueContext::nearest_game_objects_no_los;
|
||||||
creators["closest game objects"] = &ValueContext::closest_game_objects;
|
creators["closest game objects"] = &ValueContext::closest_game_objects;
|
||||||
creators["nearest npcs"] = &ValueContext::nearest_npcs;
|
creators["nearest npcs"] = &ValueContext::nearest_npcs;
|
||||||
|
creators["nearest totems"] = &ValueContext::nearest_totems;
|
||||||
creators["nearest vehicles"] = &ValueContext::nearest_vehicles;
|
creators["nearest vehicles"] = &ValueContext::nearest_vehicles;
|
||||||
creators["nearest friendly players"] = &ValueContext::nearest_friendly_players;
|
creators["nearest friendly players"] = &ValueContext::nearest_friendly_players;
|
||||||
creators["closest friendly players"] = &ValueContext::closest_friendly_players;
|
creators["closest friendly players"] = &ValueContext::closest_friendly_players;
|
||||||
@@ -367,6 +368,7 @@ class ValueContext : public NamedObjectContext<UntypedValue>
|
|||||||
static UntypedValue* closest_game_objects(PlayerbotAI* botAI) { return new NearestGameObjects(botAI, INTERACTION_DISTANCE); }
|
static UntypedValue* closest_game_objects(PlayerbotAI* botAI) { return new NearestGameObjects(botAI, INTERACTION_DISTANCE); }
|
||||||
static UntypedValue* log_level(PlayerbotAI* botAI) { return new LogLevelValue(botAI); }
|
static UntypedValue* log_level(PlayerbotAI* botAI) { return new LogLevelValue(botAI); }
|
||||||
static UntypedValue* nearest_npcs(PlayerbotAI* botAI) { return new NearestNpcsValue(botAI); }
|
static UntypedValue* nearest_npcs(PlayerbotAI* botAI) { return new NearestNpcsValue(botAI); }
|
||||||
|
static UntypedValue* nearest_totems(PlayerbotAI* botAI) { return new NearestTotemsValue(botAI); }
|
||||||
static UntypedValue* nearest_vehicles(PlayerbotAI* botAI) { return new NearestVehiclesValue(botAI); }
|
static UntypedValue* nearest_vehicles(PlayerbotAI* botAI) { return new NearestVehiclesValue(botAI); }
|
||||||
static UntypedValue* nearest_friendly_players(PlayerbotAI* botAI) { return new NearestFriendlyPlayersValue(botAI); }
|
static UntypedValue* nearest_friendly_players(PlayerbotAI* botAI) { return new NearestFriendlyPlayersValue(botAI); }
|
||||||
static UntypedValue* closest_friendly_players(PlayerbotAI* botAI) { return new NearestFriendlyPlayersValue(botAI, INTERACTION_DISTANCE); }
|
static UntypedValue* closest_friendly_players(PlayerbotAI* botAI) { return new NearestFriendlyPlayersValue(botAI, INTERACTION_DISTANCE); }
|
||||||
|
|||||||
Reference in New Issue
Block a user