mirror of
https://github.com/mod-playerbots/mod-playerbots.git
synced 2026-01-28 16:06:25 +00:00
@@ -249,16 +249,17 @@ bool LootObject::IsLootPossible(Player* bot)
|
|||||||
|
|
||||||
bool LootObjectStack::Add(ObjectGuid guid)
|
bool LootObjectStack::Add(ObjectGuid guid)
|
||||||
{
|
{
|
||||||
|
if (availableLoot.size() >= MAX_LOOT_OBJECT_COUNT) {
|
||||||
|
availableLoot.shrink(time(nullptr) - 30);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (availableLoot.size() >= MAX_LOOT_OBJECT_COUNT) {
|
||||||
|
availableLoot.clear();
|
||||||
|
}
|
||||||
|
|
||||||
if (!availableLoot.insert(guid).second)
|
if (!availableLoot.insert(guid).second)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (availableLoot.size() < MAX_LOOT_OBJECT_COUNT)
|
|
||||||
return true;
|
|
||||||
|
|
||||||
std::vector<LootObject> ordered = OrderByDistance();
|
|
||||||
for (size_t i = MAX_LOOT_OBJECT_COUNT; i < ordered.size(); i++)
|
|
||||||
Remove(ordered[i].guid);
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -960,6 +960,8 @@ void PlayerbotAI::ChangeEngine(BotState type)
|
|||||||
case BOT_STATE_DEAD:
|
case BOT_STATE_DEAD:
|
||||||
// LOG_DEBUG("playerbots", "=== {} DEAD ===", bot->GetName().c_str());
|
// LOG_DEBUG("playerbots", "=== {} DEAD ===", bot->GetName().c_str());
|
||||||
break;
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -3123,7 +3125,7 @@ bool PlayerbotAI::HasAuraToDispel(Unit* target, uint32 dispelType)
|
|||||||
#ifndef WIN32
|
#ifndef WIN32
|
||||||
inline int strcmpi(char const* s1, char const* s2)
|
inline int strcmpi(char const* s1, char const* s2)
|
||||||
{
|
{
|
||||||
for (; *s1 && *s2 && (toupper(*s1) == toupper(*s2)); ++s1, ++s2);
|
for (; *s1 && *s2 && (toupper(*s1) == toupper(*s2)); ++s1, ++s2) {}
|
||||||
return *s1 - *s2;
|
return *s1 - *s2;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@@ -3951,6 +3953,8 @@ std::string const PlayerbotAI::HandleRemoteCommand(std::string const command)
|
|||||||
case NeedMoneyFor::guild:
|
case NeedMoneyFor::guild:
|
||||||
out << "guild";
|
out << "guild";
|
||||||
break;
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
out << " | " << ChatHelper::formatMoney(AI_VALUE2(uint32, "free money for", i)) << " / " << ChatHelper::formatMoney(AI_VALUE2(uint32, "money needed for", i)) << "\n";
|
out << " | " << ChatHelper::formatMoney(AI_VALUE2(uint32, "free money for", i)) << " / " << ChatHelper::formatMoney(AI_VALUE2(uint32, "money needed for", i)) << "\n";
|
||||||
|
|||||||
@@ -178,7 +178,7 @@ void PlayerbotFactory::Randomize(bool incremental)
|
|||||||
// {
|
// {
|
||||||
// return;
|
// return;
|
||||||
// }
|
// }
|
||||||
LOG_INFO("playerbots", "{} randomizing {} (level {} class = {})...", (incremental ? "Incremental" : "Full"), bot->GetName().c_str(), bot->GetLevel(), bot->getClass());
|
LOG_INFO("playerbots", "{} randomizing {} (level {} class = {})...", (incremental ? "Incremental" : "Full"), bot->GetName().c_str(), level, bot->getClass());
|
||||||
// LOG_DEBUG("playerbots", "Preparing to {} randomize...", (incremental ? "incremental" : "full"));
|
// LOG_DEBUG("playerbots", "Preparing to {} randomize...", (incremental ? "incremental" : "full"));
|
||||||
Prepare();
|
Prepare();
|
||||||
LOG_DEBUG("playerbots", "Resetting player...");
|
LOG_DEBUG("playerbots", "Resetting player...");
|
||||||
@@ -188,7 +188,7 @@ void PlayerbotFactory::Randomize(bool incremental)
|
|||||||
ClearSkills();
|
ClearSkills();
|
||||||
// bot->SaveToDB(false, false);
|
// bot->SaveToDB(false, false);
|
||||||
ClearSpells();
|
ClearSpells();
|
||||||
bot->SaveToDB(false, false);
|
// bot->SaveToDB(false, false);
|
||||||
if (!incremental)
|
if (!incremental)
|
||||||
{
|
{
|
||||||
ResetQuests();
|
ResetQuests();
|
||||||
@@ -196,12 +196,12 @@ void PlayerbotFactory::Randomize(bool incremental)
|
|||||||
if (!sPlayerbotAIConfig->equipmentPersistence || level < sPlayerbotAIConfig->equipmentPersistenceLevel) {
|
if (!sPlayerbotAIConfig->equipmentPersistence || level < sPlayerbotAIConfig->equipmentPersistenceLevel) {
|
||||||
ClearAllItems();
|
ClearAllItems();
|
||||||
}
|
}
|
||||||
bot->SaveToDB(false, false);
|
// bot->SaveToDB(false, false);
|
||||||
|
|
||||||
bot->GiveLevel(level);
|
bot->GiveLevel(level);
|
||||||
bot->InitStatsForLevel();
|
bot->InitStatsForLevel();
|
||||||
CancelAuras();
|
CancelAuras();
|
||||||
bot->SaveToDB(false, false);
|
// bot->SaveToDB(false, false);
|
||||||
if (pmo)
|
if (pmo)
|
||||||
pmo->finish();
|
pmo->finish();
|
||||||
|
|
||||||
@@ -260,7 +260,7 @@ void PlayerbotFactory::Randomize(bool incremental)
|
|||||||
pmo = sPerformanceMonitor->start(PERF_MON_RNDBOT, "PlayerbotFactory_Mounts");
|
pmo = sPerformanceMonitor->start(PERF_MON_RNDBOT, "PlayerbotFactory_Mounts");
|
||||||
LOG_DEBUG("playerbots", "Initializing mounts...");
|
LOG_DEBUG("playerbots", "Initializing mounts...");
|
||||||
InitMounts();
|
InitMounts();
|
||||||
bot->SaveToDB(false, false);
|
// bot->SaveToDB(false, false);
|
||||||
if (pmo)
|
if (pmo)
|
||||||
pmo->finish();
|
pmo->finish();
|
||||||
|
|
||||||
@@ -349,8 +349,8 @@ void PlayerbotFactory::Randomize(bool incremental)
|
|||||||
pmo->finish();
|
pmo->finish();
|
||||||
|
|
||||||
LOG_DEBUG("playerbots", "Initializing glyphs...");
|
LOG_DEBUG("playerbots", "Initializing glyphs...");
|
||||||
bot->SaveToDB(false, false);
|
|
||||||
InitGlyphs();
|
InitGlyphs();
|
||||||
|
// bot->SaveToDB(false, false);
|
||||||
|
|
||||||
// pmo = sPerformanceMonitor->start(PERF_MON_RNDBOT, "PlayerbotFactory_Guilds");
|
// pmo = sPerformanceMonitor->start(PERF_MON_RNDBOT, "PlayerbotFactory_Guilds");
|
||||||
// LOG_INFO("playerbots", "Initializing guilds...");
|
// LOG_INFO("playerbots", "Initializing guilds...");
|
||||||
@@ -372,13 +372,14 @@ void PlayerbotFactory::Randomize(bool incremental)
|
|||||||
if (!incremental) {
|
if (!incremental) {
|
||||||
bot->RemovePet(nullptr, PET_SAVE_AS_CURRENT, true);
|
bot->RemovePet(nullptr, PET_SAVE_AS_CURRENT, true);
|
||||||
bot->RemovePet(nullptr, PET_SAVE_NOT_IN_SLOT, true);
|
bot->RemovePet(nullptr, PET_SAVE_NOT_IN_SLOT, true);
|
||||||
|
// bot->SaveToDB(false, false);
|
||||||
}
|
}
|
||||||
if (bot->getLevel() >= 10)
|
if (bot->getLevel() >= 10)
|
||||||
{
|
{
|
||||||
pmo = sPerformanceMonitor->start(PERF_MON_RNDBOT, "PlayerbotFactory_Pet");
|
pmo = sPerformanceMonitor->start(PERF_MON_RNDBOT, "PlayerbotFactory_Pet");
|
||||||
LOG_DEBUG("playerbots", "Initializing pet...");
|
LOG_DEBUG("playerbots", "Initializing pet...");
|
||||||
InitPet();
|
InitPet();
|
||||||
bot->SaveToDB(false, false);
|
// bot->SaveToDB(false, false);
|
||||||
InitPetTalents();
|
InitPetTalents();
|
||||||
if (pmo)
|
if (pmo)
|
||||||
pmo->finish();
|
pmo->finish();
|
||||||
@@ -1422,11 +1423,23 @@ void PlayerbotFactory::InitEquipment(bool incremental)
|
|||||||
else if (blevel == 80)
|
else if (blevel == 80)
|
||||||
delta = 9;
|
delta = 9;
|
||||||
|
|
||||||
for(uint8 slot = 0; slot < EQUIPMENT_SLOT_END; ++slot)
|
for (uint8 slot = 0; slot < EQUIPMENT_SLOT_END; ++slot)
|
||||||
{
|
{
|
||||||
if (slot == EQUIPMENT_SLOT_TABARD || slot == EQUIPMENT_SLOT_BODY)
|
if (slot == EQUIPMENT_SLOT_TABARD || slot == EQUIPMENT_SLOT_BODY)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
if (level < 40 && (slot == EQUIPMENT_SLOT_TRINKET1 || slot == EQUIPMENT_SLOT_TRINKET2))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (level < 30 && slot == EQUIPMENT_SLOT_NECK)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (level < 25 && slot == EQUIPMENT_SLOT_HEAD)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (level < 20 && (slot == EQUIPMENT_SLOT_FINGER1 || slot == EQUIPMENT_SLOT_FINGER2))
|
||||||
|
continue;
|
||||||
|
|
||||||
uint32 desiredQuality = itemQuality;
|
uint32 desiredQuality = itemQuality;
|
||||||
if (urand(0, 100) < 100 * sPlayerbotAIConfig->randomGearLoweringChance && desiredQuality > ITEM_QUALITY_NORMAL) {
|
if (urand(0, 100) < 100 * sPlayerbotAIConfig->randomGearLoweringChance && desiredQuality > ITEM_QUALITY_NORMAL) {
|
||||||
desiredQuality--;
|
desiredQuality--;
|
||||||
@@ -1486,6 +1499,15 @@ void PlayerbotFactory::InitEquipment(bool incremental)
|
|||||||
if (slot == EQUIPMENT_SLOT_TABARD || slot == EQUIPMENT_SLOT_BODY)
|
if (slot == EQUIPMENT_SLOT_TABARD || slot == EQUIPMENT_SLOT_BODY)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
if (level < 40 && (slot == EQUIPMENT_SLOT_TRINKET1 || slot == EQUIPMENT_SLOT_TRINKET2))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (level < 25 && slot == EQUIPMENT_SLOT_NECK)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (level < 25 && slot == EQUIPMENT_SLOT_HEAD)
|
||||||
|
continue;
|
||||||
|
|
||||||
std::vector<uint32>& ids = items[slot];
|
std::vector<uint32>& ids = items[slot];
|
||||||
if (ids.empty())
|
if (ids.empty())
|
||||||
{
|
{
|
||||||
@@ -2617,7 +2639,7 @@ void PlayerbotFactory::InitPotions()
|
|||||||
uint32 itemId = sRandomItemMgr->GetRandomPotion(level, effect);
|
uint32 itemId = sRandomItemMgr->GetRandomPotion(level, effect);
|
||||||
if (!itemId)
|
if (!itemId)
|
||||||
{
|
{
|
||||||
LOG_INFO("playerbots", "No potions (type {}) available for bot {} ({} level)", effect, bot->GetName().c_str(), bot->getLevel());
|
// LOG_INFO("playerbots", "No potions (type {}) available for bot {} ({} level)", effect, bot->GetName().c_str(), bot->getLevel());
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1285,7 +1285,7 @@ void RandomPlayerbotMgr::PrepareTeleportCache()
|
|||||||
"ROUND( position_z / 50), "
|
"ROUND( position_z / 50), "
|
||||||
"t.entry "
|
"t.entry "
|
||||||
"HAVING "
|
"HAVING "
|
||||||
"count(*) > 10) AS g "
|
"count(*) > 7) AS g "
|
||||||
"INNER JOIN creature c ON g.guid = c.guid "
|
"INNER JOIN creature c ON g.guid = c.guid "
|
||||||
"INNER JOIN creature_template t on c.id1 = t.entry "
|
"INNER JOIN creature_template t on c.id1 = t.entry "
|
||||||
"ORDER BY "
|
"ORDER BY "
|
||||||
@@ -1332,6 +1332,9 @@ void RandomPlayerbotMgr::PrepareTeleportCache()
|
|||||||
"AND t.faction != 35 "
|
"AND t.faction != 35 "
|
||||||
"AND t.faction != 474 "
|
"AND t.faction != 474 "
|
||||||
"AND t.faction != 69 "
|
"AND t.faction != 69 "
|
||||||
|
"AND t.entry != 30606 "
|
||||||
|
"AND t.entry != 30608 "
|
||||||
|
"AND t.faction != 69 "
|
||||||
"AND map IN ({}) "
|
"AND map IN ({}) "
|
||||||
"ORDER BY "
|
"ORDER BY "
|
||||||
"t.minlevel;", sPlayerbotAIConfig->randomBotMapsAsString.c_str());
|
"t.minlevel;", sPlayerbotAIConfig->randomBotMapsAsString.c_str());
|
||||||
@@ -1347,7 +1350,7 @@ void RandomPlayerbotMgr::PrepareTeleportCache()
|
|||||||
float z = fields[3].Get<float>();
|
float z = fields[3].Get<float>();
|
||||||
float orient = fields[4].Get<float>();
|
float orient = fields[4].Get<float>();
|
||||||
uint32 level = fields[5].Get<uint32>();
|
uint32 level = fields[5].Get<uint32>();
|
||||||
WorldLocation loc(mapId, x + cos(orient) * 10.0f, y + sin(orient) * 10.0f, z, orient + M_PI);
|
WorldLocation loc(mapId, x + cos(orient) * 6.0f, y + sin(orient) * 6.0f, z + 2.0f, orient + M_PI);
|
||||||
collected_locs++;
|
collected_locs++;
|
||||||
for (int32 l = 1; l <= maxLevel; l++) {
|
for (int32 l = 1; l <= maxLevel; l++) {
|
||||||
if (l <= 60 && level >= 60) {
|
if (l <= 60 && level >= 60) {
|
||||||
@@ -1524,7 +1527,7 @@ void RandomPlayerbotMgr::RandomizeFirst(Player* bot)
|
|||||||
|
|
||||||
uint32 level;
|
uint32 level;
|
||||||
|
|
||||||
if (sPlayerbotAIConfig->downgradeMaxLevelBot && bot->GetLevel() == sPlayerbotAIConfig->randomBotMaxLevel) {
|
if (sPlayerbotAIConfig->downgradeMaxLevelBot && bot->GetLevel() >= sPlayerbotAIConfig->randomBotMaxLevel) {
|
||||||
if (bot->getClass() == CLASS_DEATH_KNIGHT) {
|
if (bot->getClass() == CLASS_DEATH_KNIGHT) {
|
||||||
level = sWorld->getIntConfig(CONFIG_START_HEROIC_PLAYER_LEVEL);
|
level = sWorld->getIntConfig(CONFIG_START_HEROIC_PLAYER_LEVEL);
|
||||||
} else {
|
} else {
|
||||||
@@ -1532,7 +1535,7 @@ void RandomPlayerbotMgr::RandomizeFirst(Player* bot)
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
level = urand(sPlayerbotAIConfig->randomBotMinLevel, maxLevel);
|
level = urand(sPlayerbotAIConfig->randomBotMinLevel, maxLevel);
|
||||||
if (urand(0, 100) < 100 * sPlayerbotAIConfig->randomBotMaxLevelChance)
|
if (urand(1, 100) < 100 * sPlayerbotAIConfig->randomBotMaxLevelChance)
|
||||||
level = maxLevel;
|
level = maxLevel;
|
||||||
|
|
||||||
if (bot->getClass() == CLASS_DEATH_KNIGHT)
|
if (bot->getClass() == CLASS_DEATH_KNIGHT)
|
||||||
|
|||||||
@@ -4,6 +4,7 @@
|
|||||||
|
|
||||||
#include "AcceptInvitationAction.h"
|
#include "AcceptInvitationAction.h"
|
||||||
#include "Event.h"
|
#include "Event.h"
|
||||||
|
#include "PlayerbotAIConfig.h"
|
||||||
#include "Playerbots.h"
|
#include "Playerbots.h"
|
||||||
#include "PlayerbotSecurity.h"
|
#include "PlayerbotSecurity.h"
|
||||||
|
|
||||||
@@ -42,7 +43,7 @@ bool AcceptInvitationAction::Execute(Event event)
|
|||||||
|
|
||||||
botAI->TellMaster("Hello");
|
botAI->TellMaster("Hello");
|
||||||
|
|
||||||
if (sPlayerbotAIConfig->summonWhenGroup) {
|
if (sPlayerbotAIConfig->summonWhenGroup && bot->GetDistance(inviter) > sPlayerbotAIConfig->sightDistance) {
|
||||||
Teleport(inviter, bot);
|
Teleport(inviter, bot);
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
|||||||
@@ -110,7 +110,8 @@ bool AttackAction::Attack(Unit* target, bool with_pet /*true*/)
|
|||||||
context->GetValue<Unit*>("current target")->Set(target);
|
context->GetValue<Unit*>("current target")->Set(target);
|
||||||
context->GetValue<LootObjectStack*>("available loot")->Get()->Add(guid);
|
context->GetValue<LootObjectStack*>("available loot")->Get()->Add(guid);
|
||||||
|
|
||||||
bool attacked = bot->Attack(target, true);
|
bool melee = bot->IsWithinMeleeRange(target) || botAI->IsMelee(bot);
|
||||||
|
bot->Attack(target, melee);
|
||||||
|
|
||||||
if (IsMovingAllowed() && !bot->HasInArc(CAST_ANGLE_IN_FRONT, target)) {
|
if (IsMovingAllowed() && !bot->HasInArc(CAST_ANGLE_IN_FRONT, target)) {
|
||||||
sServerFacade->SetFacingTo(bot, target);
|
sServerFacade->SetFacingTo(bot, target);
|
||||||
|
|||||||
@@ -1540,8 +1540,8 @@ bool AvoidAoeAction::AvoidAuraWithDynamicObj()
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
std::ostringstream name;
|
std::ostringstream name;
|
||||||
name << "[" << spellInfo->SpellName[0] << "] (aura)";
|
name << spellInfo->SpellName[0]; // << "] (aura)";
|
||||||
if (FleePostion(dynOwner->GetPosition(), radius, name.str())) {
|
if (FleePosition(dynOwner->GetPosition(), radius, name.str())) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
@@ -1591,8 +1591,8 @@ bool AvoidAoeAction::AvoidGameObjectWithDamage()
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
std::ostringstream name;
|
std::ostringstream name;
|
||||||
name << "[" << spellInfo->SpellName[0] << "] (object)";
|
name << spellInfo->SpellName[0]; // << "] (object)";
|
||||||
if (FleePostion(go->GetPosition(), radius, name.str())) {
|
if (FleePosition(go->GetPosition(), radius, name.str())) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1633,8 +1633,8 @@ bool AvoidAoeAction::AvoidUnitWithDamageAura()
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
std::ostringstream name;
|
std::ostringstream name;
|
||||||
name << "[" << triggerSpellInfo->SpellName[0] << "] (unit)";
|
name << triggerSpellInfo->SpellName[0]; //<< "] (unit)";
|
||||||
if (FleePostion(unit->GetPosition(), radius, name.str())) {
|
if (FleePosition(unit->GetPosition(), radius, name.str())) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1645,7 +1645,7 @@ bool AvoidAoeAction::AvoidUnitWithDamageAura()
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AvoidAoeAction::FleePostion(Position pos, float radius, std::string name)
|
bool AvoidAoeAction::FleePosition(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;
|
||||||
@@ -1674,9 +1674,10 @@ bool AvoidAoeAction::FleePostion(Position pos, float radius, std::string name)
|
|||||||
}
|
}
|
||||||
if (farestDis > 0.0f) {
|
if (farestDis > 0.0f) {
|
||||||
if (MoveTo(bot->GetMapId(), bestPos.GetPositionX(), bestPos.GetPositionY(), bestPos.GetPositionZ(), false, false, true)) {
|
if (MoveTo(bot->GetMapId(), bestPos.GetPositionX(), bestPos.GetPositionY(), bestPos.GetPositionZ(), false, false, true)) {
|
||||||
if (sPlayerbotAIConfig->tellWhenAvoidAoe) {
|
if (sPlayerbotAIConfig->tellWhenAvoidAoe && lastTellTimer < time(NULL) - 10) {
|
||||||
|
lastTellTimer = time(NULL);
|
||||||
std::ostringstream out;
|
std::ostringstream out;
|
||||||
out << "Avoiding spell " << name << "...";
|
out << "I'm avoiding " << name << "...";
|
||||||
bot->Say(out.str(), LANG_UNIVERSAL);
|
bot->Say(out.str(), LANG_UNIVERSAL);
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
|||||||
@@ -78,7 +78,11 @@ class AvoidAoeAction : public MovementAction
|
|||||||
bool AvoidAuraWithDynamicObj();
|
bool AvoidAuraWithDynamicObj();
|
||||||
bool AvoidGameObjectWithDamage();
|
bool AvoidGameObjectWithDamage();
|
||||||
bool AvoidUnitWithDamageAura();
|
bool AvoidUnitWithDamageAura();
|
||||||
bool FleePostion(Position pos, float radius, std::string name);
|
// Position PositionForTank(Position pos, float radius);
|
||||||
|
// Position PositionForMelee(Position pos, float radius);
|
||||||
|
// Position PositionForRanged(Position pos, float radius);
|
||||||
|
bool FleePosition(Position pos, float radius, std::string name);
|
||||||
|
time_t lastTellTimer = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
class RunAwayAction : public MovementAction
|
class RunAwayAction : public MovementAction
|
||||||
|
|||||||
@@ -13,11 +13,12 @@ bool SetHomeAction::Execute(Event event)
|
|||||||
ObjectGuid selection = bot->GetTarget();
|
ObjectGuid selection = bot->GetTarget();
|
||||||
bool isRpgAction = AI_VALUE(GuidPosition, "rpg target") == selection;
|
bool isRpgAction = AI_VALUE(GuidPosition, "rpg target") == selection;
|
||||||
|
|
||||||
if (!isRpgAction)
|
if (!isRpgAction) {
|
||||||
if (master)
|
if (master)
|
||||||
selection = master->GetTarget();
|
selection = master->GetTarget();
|
||||||
else
|
else
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
if (Unit* unit = botAI->GetUnit(selection))
|
if (Unit* unit = botAI->GetUnit(selection))
|
||||||
if (unit->HasFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_INNKEEPER))
|
if (unit->HasFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_INNKEEPER))
|
||||||
|
|||||||
@@ -35,7 +35,7 @@ bool TravelAction::Execute(Event event)
|
|||||||
if (!newTarget->IsAlive())
|
if (!newTarget->IsAlive())
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (!newTarget->GetEntry() != target->getDestination()->getEntry())
|
if (newTarget->GetEntry() == target->getDestination()->getEntry())
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (newTarget->IsInCombat())
|
if (newTarget->IsInCombat())
|
||||||
|
|||||||
@@ -79,7 +79,7 @@ void GenericHunterStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
|
|||||||
{
|
{
|
||||||
CombatStrategy::InitTriggers(triggers);
|
CombatStrategy::InitTriggers(triggers);
|
||||||
|
|
||||||
triggers.push_back(new TriggerNode("enemy is close",
|
triggers.push_back(new TriggerNode("enemy within melee",
|
||||||
NextAction::array(0,
|
NextAction::array(0,
|
||||||
new NextAction("wing clip", ACTION_HIGH + 1),
|
new NextAction("wing clip", ACTION_HIGH + 1),
|
||||||
new NextAction("mongoose bite", ACTION_HIGH),
|
new NextAction("mongoose bite", ACTION_HIGH),
|
||||||
@@ -88,7 +88,7 @@ void GenericHunterStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
|
|||||||
triggers.push_back(new TriggerNode("hunters pet medium health", NextAction::array(0, new NextAction("mend pet", ACTION_HIGH + 2), nullptr)));
|
triggers.push_back(new TriggerNode("hunters pet medium health", NextAction::array(0, new NextAction("mend pet", ACTION_HIGH + 2), nullptr)));
|
||||||
// triggers.push_back(new TriggerNode("no ammo", NextAction::array(0, new NextAction("switch to melee", ACTION_HIGH + 1), new NextAction("say::no ammo", ACTION_HIGH), nullptr)));
|
// triggers.push_back(new TriggerNode("no ammo", NextAction::array(0, new NextAction("switch to melee", ACTION_HIGH + 1), new NextAction("say::no ammo", ACTION_HIGH), nullptr)));
|
||||||
triggers.push_back(new TriggerNode("aspect of the viper", NextAction::array(0, new NextAction("aspect of the viper", ACTION_HIGH), NULL)));
|
triggers.push_back(new TriggerNode("aspect of the viper", NextAction::array(0, new NextAction("aspect of the viper", ACTION_HIGH), NULL)));
|
||||||
triggers.push_back(new TriggerNode("enemy too close for shoot", NextAction::array(0, new NextAction("flee", ACTION_MOVE + 9), nullptr)));
|
triggers.push_back(new TriggerNode("enemy too close for auto shot", NextAction::array(0, new NextAction("flee", ACTION_MOVE + 9), nullptr)));
|
||||||
triggers.push_back(new TriggerNode("misdirection on main tank", NextAction::array(0, new NextAction("misdirection on main tank", ACTION_HIGH + 7), NULL)));
|
triggers.push_back(new TriggerNode("misdirection on main tank", NextAction::array(0, new NextAction("misdirection on main tank", ACTION_HIGH + 7), NULL)));
|
||||||
triggers.push_back(new TriggerNode("tranquilizing shot", NextAction::array(0, new NextAction("tranquilizing shot", 61.0f), NULL)));
|
triggers.push_back(new TriggerNode("tranquilizing shot", NextAction::array(0, new NextAction("tranquilizing shot", 61.0f), NULL)));
|
||||||
|
|
||||||
|
|||||||
@@ -52,29 +52,29 @@ bool EnemyTooCloseForSpellTrigger::IsActive()
|
|||||||
bool EnemyTooCloseForAutoShotTrigger::IsActive()
|
bool EnemyTooCloseForAutoShotTrigger::IsActive()
|
||||||
{
|
{
|
||||||
Unit* target = AI_VALUE(Unit*, "current target");
|
Unit* target = AI_VALUE(Unit*, "current target");
|
||||||
if (!target)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
if (target->GetTarget() == bot->GetGUID() && !bot->GetGroup() && !target->HasUnitState(UNIT_STATE_ROOT) && GetSpeedInMotion(target) > GetSpeedInMotion(bot) * 0.65f)
|
return target && (target->GetVictim() != bot || target->isFrozen() || !target->CanFreeMove()) && bot->IsWithinMeleeRange(target);
|
||||||
return false;
|
|
||||||
|
|
||||||
bool isBoss = false;
|
// if (target->GetTarget() == bot->GetGUID() && !bot->GetGroup() && !target->HasUnitState(UNIT_STATE_ROOT) && GetSpeedInMotion(target) > GetSpeedInMotion(bot) * 0.65f)
|
||||||
bool isRaid = false;
|
// return false;
|
||||||
float combatReach = bot->GetCombatReach() + target->GetCombatReach();
|
|
||||||
float targetDistance = sServerFacade->GetDistance2d(bot, target) + combatReach;
|
|
||||||
if (target->GetTypeId() == TYPEID_UNIT)
|
|
||||||
{
|
|
||||||
Creature* creature = botAI->GetCreature(target->GetGUID());
|
|
||||||
if (creature)
|
|
||||||
{
|
|
||||||
isBoss = creature->isWorldBoss();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (bot->GetMap() && bot->GetMap()->IsRaid())
|
// bool isBoss = false;
|
||||||
isRaid = true;
|
// bool isRaid = false;
|
||||||
|
// float combatReach = bot->GetCombatReach() + target->GetCombatReach();
|
||||||
|
// float targetDistance = sServerFacade->GetDistance2d(bot, target) + combatReach;
|
||||||
|
// if (target->GetTypeId() == TYPEID_UNIT)
|
||||||
|
// {
|
||||||
|
// Creature* creature = botAI->GetCreature(target->GetGUID());
|
||||||
|
// if (creature)
|
||||||
|
// {
|
||||||
|
// isBoss = creature->isWorldBoss();
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
return sServerFacade->IsDistanceLessOrEqualThan(targetDistance, 5.0f);
|
// if (bot->GetMap() && bot->GetMap()->IsRaid())
|
||||||
|
// isRaid = true;
|
||||||
|
|
||||||
|
// return sServerFacade->IsDistanceLessOrEqualThan(targetDistance, 5.0f);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool EnemyTooCloseForShootTrigger::IsActive()
|
bool EnemyTooCloseForShootTrigger::IsActive()
|
||||||
@@ -128,6 +128,12 @@ bool EnemyIsCloseTrigger::IsActive()
|
|||||||
return target && sServerFacade->IsDistanceLessOrEqualThan(AI_VALUE2(float, "distance", "current target"), sPlayerbotAIConfig->tooCloseDistance);
|
return target && sServerFacade->IsDistanceLessOrEqualThan(AI_VALUE2(float, "distance", "current target"), sPlayerbotAIConfig->tooCloseDistance);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool EnemyWithinMeleeTrigger::IsActive()
|
||||||
|
{
|
||||||
|
Unit* target = AI_VALUE(Unit*, "current target");
|
||||||
|
return target && bot->IsWithinMeleeRange(target);
|
||||||
|
}
|
||||||
|
|
||||||
bool OutOfRangeTrigger::IsActive()
|
bool OutOfRangeTrigger::IsActive()
|
||||||
{
|
{
|
||||||
Unit* target = AI_VALUE(Unit*, GetTargetName());
|
Unit* target = AI_VALUE(Unit*, GetTargetName());
|
||||||
|
|||||||
@@ -50,6 +50,14 @@ class EnemyIsCloseTrigger : public Trigger
|
|||||||
bool IsActive() override;
|
bool IsActive() override;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class EnemyWithinMeleeTrigger : public Trigger
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
EnemyWithinMeleeTrigger(PlayerbotAI* botAI) : Trigger(botAI, "enemy within melee") { }
|
||||||
|
|
||||||
|
bool IsActive() override;
|
||||||
|
};
|
||||||
|
|
||||||
class OutOfRangeTrigger : public Trigger
|
class OutOfRangeTrigger : public Trigger
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|||||||
@@ -87,6 +87,7 @@ class TriggerContext : public NamedObjectContext<Trigger>
|
|||||||
creators["enemy too close for auto shot"] = &TriggerContext::enemy_too_close_for_auto_shot;
|
creators["enemy too close for auto shot"] = &TriggerContext::enemy_too_close_for_auto_shot;
|
||||||
creators["enemy too close for melee"] = &TriggerContext::enemy_too_close_for_melee;
|
creators["enemy too close for melee"] = &TriggerContext::enemy_too_close_for_melee;
|
||||||
creators["enemy is close"] = &TriggerContext::enemy_is_close;
|
creators["enemy is close"] = &TriggerContext::enemy_is_close;
|
||||||
|
creators["enemy within melee"] = &TriggerContext::enemy_within_melee;
|
||||||
creators["party member to heal out of spell range"] = &TriggerContext::party_member_to_heal_out_of_spell_range;
|
creators["party member to heal out of spell range"] = &TriggerContext::party_member_to_heal_out_of_spell_range;
|
||||||
|
|
||||||
creators["combo points available"] = &TriggerContext::ComboPointsAvailable;
|
creators["combo points available"] = &TriggerContext::ComboPointsAvailable;
|
||||||
@@ -278,6 +279,7 @@ class TriggerContext : public NamedObjectContext<Trigger>
|
|||||||
static Trigger* enemy_too_close_for_shoot(PlayerbotAI* botAI) { return new EnemyTooCloseForShootTrigger(botAI); }
|
static Trigger* enemy_too_close_for_shoot(PlayerbotAI* botAI) { return new EnemyTooCloseForShootTrigger(botAI); }
|
||||||
static Trigger* enemy_too_close_for_melee(PlayerbotAI* botAI) { return new EnemyTooCloseForMeleeTrigger(botAI); }
|
static Trigger* enemy_too_close_for_melee(PlayerbotAI* botAI) { return new EnemyTooCloseForMeleeTrigger(botAI); }
|
||||||
static Trigger* enemy_is_close(PlayerbotAI* botAI) { return new EnemyIsCloseTrigger(botAI); }
|
static Trigger* enemy_is_close(PlayerbotAI* botAI) { return new EnemyIsCloseTrigger(botAI); }
|
||||||
|
static Trigger* enemy_within_melee(PlayerbotAI* botAI) { return new EnemyWithinMeleeTrigger(botAI); }
|
||||||
static Trigger* party_member_to_heal_out_of_spell_range(PlayerbotAI* botAI) { return new PartyMemberToHealOutOfSpellRangeTrigger(botAI); }
|
static Trigger* party_member_to_heal_out_of_spell_range(PlayerbotAI* botAI) { return new PartyMemberToHealOutOfSpellRangeTrigger(botAI); }
|
||||||
static Trigger* ComboPointsAvailable(PlayerbotAI* botAI) { return new ComboPointsAvailableTrigger(botAI); }
|
static Trigger* ComboPointsAvailable(PlayerbotAI* botAI) { return new ComboPointsAvailableTrigger(botAI); }
|
||||||
static Trigger* ComboPoints3Available(PlayerbotAI* botAI) { return new ComboPointsAvailableTrigger(botAI, 3); }
|
static Trigger* ComboPoints3Available(PlayerbotAI* botAI) { return new ComboPointsAvailableTrigger(botAI, 3); }
|
||||||
|
|||||||
@@ -122,9 +122,10 @@ Aura* AreaDebuffValue::Calculate()
|
|||||||
{
|
{
|
||||||
// Unit::AuraApplicationMap& map = bot->GetAppliedAuras();
|
// Unit::AuraApplicationMap& map = bot->GetAppliedAuras();
|
||||||
Unit::AuraEffectList const& aurasPeriodicDamage = bot->GetAuraEffectsByType(SPELL_AURA_PERIODIC_DAMAGE);
|
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& aurasPeriodicTriggerSpell = bot->GetAuraEffectsByType(SPELL_AURA_PERIODIC_TRIGGER_SPELL);
|
||||||
Unit::AuraEffectList const& aurasPeriodicTriggerWithValueSpell = bot->GetAuraEffectsByType(SPELL_AURA_PERIODIC_TRIGGER_SPELL_WITH_VALUE);
|
Unit::AuraEffectList const& aurasPeriodicTriggerWithValueSpell = bot->GetAuraEffectsByType(SPELL_AURA_PERIODIC_TRIGGER_SPELL_WITH_VALUE);
|
||||||
for (const Unit::AuraEffectList& list : {aurasPeriodicDamage, aurasPeriodicTriggerSpell, aurasPeriodicTriggerWithValueSpell}) {
|
for (const Unit::AuraEffectList& list : {aurasPeriodicDamage, aurasPeriodicDamagePercent, aurasPeriodicTriggerSpell, aurasPeriodicTriggerWithValueSpell}) {
|
||||||
for (auto i = list.begin(); i != list.end(); ++i)
|
for (auto i = list.begin(); i != list.end(); ++i)
|
||||||
{
|
{
|
||||||
AuraEffect* aurEff = *i;
|
AuraEffect* aurEff = *i;
|
||||||
|
|||||||
@@ -35,7 +35,7 @@ GuidVector AttackersValue::Calculate()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (Group* group = bot->GetGroup()) {
|
if (Group* group = bot->GetGroup()) {
|
||||||
ObjectGuid skullGuid = group->GetTargetIcon(4);
|
ObjectGuid skullGuid = group->GetTargetIcon(7);
|
||||||
Unit* skullTarget = botAI->GetUnit(skullGuid);
|
Unit* skullTarget = botAI->GetUnit(skullGuid);
|
||||||
if (skullTarget && IsValidTarget(skullTarget, bot)) {
|
if (skullTarget && IsValidTarget(skullTarget, bot)) {
|
||||||
targets.insert(skullTarget);
|
targets.insert(skullTarget);
|
||||||
|
|||||||
@@ -196,11 +196,13 @@ ItemUsage ItemUsageValue::QueryItemUsageForEquip(ItemTemplate const* itemProto)
|
|||||||
Item* oldItem = bot->GetItemByPos(dest);
|
Item* oldItem = bot->GetItemByPos(dest);
|
||||||
|
|
||||||
//No item equiped
|
//No item equiped
|
||||||
if (!oldItem)
|
if (!oldItem) {
|
||||||
if (shouldEquip)
|
if (shouldEquip)
|
||||||
return ITEM_USAGE_EQUIP;
|
return ITEM_USAGE_EQUIP;
|
||||||
else
|
else {
|
||||||
return ITEM_USAGE_BAD_EQUIP;
|
return ITEM_USAGE_BAD_EQUIP;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
ItemTemplate const* oldItemProto = oldItem->GetTemplate();
|
ItemTemplate const* oldItemProto = oldItem->GetTemplate();
|
||||||
float oldScore = PlayerbotFactory::CalculateItemScore(oldItemProto->ItemId, bot);
|
float oldScore = PlayerbotFactory::CalculateItemScore(oldItemProto->ItemId, bot);
|
||||||
@@ -214,11 +216,13 @@ ItemUsage ItemUsageValue::QueryItemUsageForEquip(ItemTemplate const* itemProto)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Bigger quiver
|
// Bigger quiver
|
||||||
if (itemProto->Class == ITEM_CLASS_QUIVER)
|
if (itemProto->Class == ITEM_CLASS_QUIVER) {
|
||||||
if (!oldItem || oldItemProto->ContainerSlots < itemProto->ContainerSlots)
|
if (!oldItem || oldItemProto->ContainerSlots < itemProto->ContainerSlots) {
|
||||||
return ITEM_USAGE_EQUIP;
|
return ITEM_USAGE_EQUIP;
|
||||||
else
|
} else {
|
||||||
return ITEM_USAGE_NONE;
|
return ITEM_USAGE_NONE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bool existingShouldEquip = true;
|
bool existingShouldEquip = true;
|
||||||
if (oldItemProto->Class == ITEM_CLASS_WEAPON && !sRandomItemMgr->CanEquipWeapon(bot->getClass(), oldItemProto))
|
if (oldItemProto->Class == ITEM_CLASS_WEAPON && !sRandomItemMgr->CanEquipWeapon(bot->getClass(), oldItemProto))
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ class PlayerbotAI;
|
|||||||
class FindPlayerPredicate
|
class FindPlayerPredicate
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
virtual ~FindPlayerPredicate() = default;
|
||||||
virtual bool Check(Unit* /*unit*/) = 0;
|
virtual bool Check(Unit* /*unit*/) = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -104,7 +104,7 @@ bool FindTargetStrategy::IsHighPriority(Unit* attacker)
|
|||||||
{
|
{
|
||||||
if (Group* group = botAI->GetBot()->GetGroup())
|
if (Group* group = botAI->GetBot()->GetGroup())
|
||||||
{
|
{
|
||||||
ObjectGuid guid = group->GetTargetIcon(4);
|
ObjectGuid guid = group->GetTargetIcon(7);
|
||||||
if (guid && attacker->GetGUID() == guid) {
|
if (guid && attacker->GetGUID() == guid) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user