mirror of
https://github.com/mod-playerbots/mod-playerbots
synced 2025-11-29 15:58:20 +08:00
Merge pull request #512 from liyunfan1223/avoid_aoe_whitelist
Avoid aoe whitelist
This commit is contained in:
@@ -357,7 +357,7 @@ AiPlayerbot.HighMana = 65
|
||||
#
|
||||
#
|
||||
|
||||
# Bots pick their quest reward (yes = picks first useful item, no = list all rewards, ask = pick useful item and lists if multiple)
|
||||
# Bots pick their quest reward (yes = picks the most useful item, no = list all rewards, ask = pick useful item and lists if multiple)
|
||||
AiPlayerbot.AutoPickReward = yes
|
||||
|
||||
# Sync quests with player (Bots will complete quests the moment you hand them in. Bots will ignore looting quest items.)
|
||||
@@ -385,9 +385,11 @@ AiPlayerbot.ApplyInstanceStrategies = 1
|
||||
# Default: 1 (enable)
|
||||
AiPlayerbot.AutoAvoidAoe = 1
|
||||
|
||||
# Tell which spell is avoiding (experimental)
|
||||
# Default: 1 (enable)
|
||||
AiPlayerbot.TellWhenAvoidAoe = 1
|
||||
# Only avoid aoe spells with a radius smaller than this value
|
||||
AiPlayerbot.MaxAoeAvoidRadius = 15.0
|
||||
|
||||
# A whitelist of aoe spell IDs that should not be avoided
|
||||
AiPlayerbot.AoeAvoidSpellWhitelist = 50759,57491,13810
|
||||
|
||||
# Enable healer bot save mana
|
||||
# Default: 1 (enable)
|
||||
@@ -1281,6 +1283,10 @@ AiPlayerbot.LogInGroupOnly = 1
|
||||
AiPlayerbot.LogValuesPerTick = 0
|
||||
AiPlayerbot.RandomChangeMultiplier = 1
|
||||
|
||||
# Tell which spell is avoiding (experimental)
|
||||
# Default: 0 (disable)
|
||||
AiPlayerbot.TellWhenAvoidAoe = 0
|
||||
|
||||
# Enables/Disables performance monitor
|
||||
AiPlayerbot.PerfMonEnabled = 0
|
||||
|
||||
|
||||
@@ -1624,10 +1624,10 @@ void PlayerbotAI::ResetStrategies(bool load)
|
||||
// sPlayerbotDbStore->Load(this);
|
||||
}
|
||||
|
||||
bool PlayerbotAI::IsRanged(Player* player)
|
||||
bool PlayerbotAI::IsRanged(Player* player, bool bySpec)
|
||||
{
|
||||
PlayerbotAI* botAi = GET_PLAYERBOT_AI(player);
|
||||
if (botAi)
|
||||
if (!bySpec && botAi)
|
||||
return botAi->ContainsStrategy(STRATEGY_TYPE_RANGED);
|
||||
|
||||
int tab = AiFactory::GetPlayerSpecTab(player);
|
||||
@@ -1660,18 +1660,18 @@ bool PlayerbotAI::IsRanged(Player* player)
|
||||
return true;
|
||||
}
|
||||
|
||||
bool PlayerbotAI::IsMelee(Player* player) { return !IsRanged(player); }
|
||||
bool PlayerbotAI::IsMelee(Player* player, bool bySpec) { return !IsRanged(player, bySpec); }
|
||||
|
||||
bool PlayerbotAI::IsCaster(Player* player) { return IsRanged(player) && player->getClass() != CLASS_HUNTER; }
|
||||
bool PlayerbotAI::IsCaster(Player* player, bool bySpec) { return IsRanged(player, bySpec) && player->getClass() != CLASS_HUNTER; }
|
||||
|
||||
bool PlayerbotAI::IsCombo(Player* player)
|
||||
bool PlayerbotAI::IsCombo(Player* player, bool bySpec)
|
||||
{
|
||||
// int tab = AiFactory::GetPlayerSpecTab(player);
|
||||
return player->getClass() == CLASS_ROGUE ||
|
||||
(player->getClass() == CLASS_DRUID && player->HasAura(768)); // cat druid
|
||||
}
|
||||
|
||||
bool PlayerbotAI::IsRangedDps(Player* player) { return IsRanged(player) && IsDps(player); }
|
||||
bool PlayerbotAI::IsRangedDps(Player* player, bool bySpec) { return IsRanged(player, bySpec) && IsDps(player, bySpec); }
|
||||
|
||||
bool PlayerbotAI::IsHealAssistantOfIndex(Player* player, int index)
|
||||
{
|
||||
@@ -1894,10 +1894,10 @@ int32 PlayerbotAI::GetMeleeIndex(Player* player)
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool PlayerbotAI::IsTank(Player* player)
|
||||
bool PlayerbotAI::IsTank(Player* player, bool bySpec)
|
||||
{
|
||||
PlayerbotAI* botAi = GET_PLAYERBOT_AI(player);
|
||||
if (botAi)
|
||||
if (!bySpec && botAi)
|
||||
return botAi->ContainsStrategy(STRATEGY_TYPE_TANK);
|
||||
|
||||
int tab = AiFactory::GetPlayerSpecTab(player);
|
||||
@@ -1932,10 +1932,10 @@ bool PlayerbotAI::IsTank(Player* player)
|
||||
return false;
|
||||
}
|
||||
|
||||
bool PlayerbotAI::IsHeal(Player* player)
|
||||
bool PlayerbotAI::IsHeal(Player* player, bool bySpec)
|
||||
{
|
||||
PlayerbotAI* botAi = GET_PLAYERBOT_AI(player);
|
||||
if (botAi)
|
||||
if (!bySpec && botAi)
|
||||
return botAi->ContainsStrategy(STRATEGY_TYPE_HEAL);
|
||||
|
||||
int tab = AiFactory::GetPlayerSpecTab(player);
|
||||
@@ -1969,10 +1969,10 @@ bool PlayerbotAI::IsHeal(Player* player)
|
||||
return false;
|
||||
}
|
||||
|
||||
bool PlayerbotAI::IsDps(Player* player)
|
||||
bool PlayerbotAI::IsDps(Player* player, bool bySpec)
|
||||
{
|
||||
PlayerbotAI* botAi = GET_PLAYERBOT_AI(player);
|
||||
if (botAi)
|
||||
if (!bySpec && botAi)
|
||||
return botAi->ContainsStrategy(STRATEGY_TYPE_DPS);
|
||||
|
||||
int tab = AiFactory::GetPlayerSpecTab(player);
|
||||
|
||||
@@ -401,14 +401,14 @@ public:
|
||||
void ResetStrategies(bool load = false);
|
||||
void ReInitCurrentEngine();
|
||||
void Reset(bool full = false);
|
||||
static bool IsTank(Player* player);
|
||||
static bool IsHeal(Player* player);
|
||||
static bool IsDps(Player* player);
|
||||
static bool IsRanged(Player* player);
|
||||
static bool IsMelee(Player* player);
|
||||
static bool IsCaster(Player* player);
|
||||
static bool IsCombo(Player* player);
|
||||
static bool IsRangedDps(Player* player);
|
||||
static bool IsTank(Player* player, bool bySpec = false);
|
||||
static bool IsHeal(Player* player, bool bySpec = false);
|
||||
static bool IsDps(Player* player, bool bySpec = false);
|
||||
static bool IsRanged(Player* player, bool bySpec = false);
|
||||
static bool IsMelee(Player* player, bool bySpec = false);
|
||||
static bool IsCaster(Player* player, bool bySpec = false);
|
||||
static bool IsCombo(Player* player, bool bySpec = false);
|
||||
static bool IsRangedDps(Player* player, bool bySpec = false);
|
||||
static bool IsMainTank(Player* player);
|
||||
bool IsAssistTank(Player* player);
|
||||
bool IsAssistTankOfIndex(Player* player, int index);
|
||||
|
||||
@@ -29,6 +29,19 @@ void LoadList(std::string const value, T& list)
|
||||
}
|
||||
}
|
||||
|
||||
template <class T>
|
||||
void LoadSet(std::string const value, T& set)
|
||||
{
|
||||
std::vector<std::string> ids = split(value, ',');
|
||||
for (std::vector<std::string>::iterator i = ids.begin(); i != ids.end(); i++)
|
||||
{
|
||||
uint32 id = atoi((*i).c_str());
|
||||
// if (!id)
|
||||
// continue;
|
||||
set.insert(id);
|
||||
}
|
||||
}
|
||||
|
||||
template <class T>
|
||||
void LoadListString(std::string const value, T& list)
|
||||
{
|
||||
@@ -98,7 +111,10 @@ bool PlayerbotAIConfig::Initialize()
|
||||
autoSaveMana = sConfigMgr->GetOption<bool>("AiPlayerbot.AutoSaveMana", true);
|
||||
saveManaThreshold = sConfigMgr->GetOption<int32>("AiPlayerbot.SaveManaThreshold", 60);
|
||||
autoAvoidAoe = sConfigMgr->GetOption<bool>("AiPlayerbot.AutoAvoidAoe", true);
|
||||
tellWhenAvoidAoe = sConfigMgr->GetOption<bool>("AiPlayerbot.TellWhenAvoidAoe", true);
|
||||
maxAoeAvoidRadius = sConfigMgr->GetOption<float>("AiPlayerbot.MaxAoeAvoidRadius", 15.0f);
|
||||
LoadSet<std::set<uint32>>(sConfigMgr->GetOption<std::string>("AiPlayerbot.AoeAvoidSpellWhitelist", "50759,57491,13810"),
|
||||
aoeAvoidSpellWhitelist);
|
||||
tellWhenAvoidAoe = sConfigMgr->GetOption<bool>("AiPlayerbot.TellWhenAvoidAoe", false);
|
||||
|
||||
randomGearLoweringChance = sConfigMgr->GetOption<float>("AiPlayerbot.RandomGearLoweringChance", 0.0f);
|
||||
randomGearQualityLimit = sConfigMgr->GetOption<int32>("AiPlayerbot.RandomGearQualityLimit", 3);
|
||||
@@ -792,9 +808,10 @@ std::vector<std::vector<uint32>> PlayerbotAIConfig::ParseTempPetTalentsOrder(uin
|
||||
if (!((1 << spec) & talentTabInfo->petTalentMask))
|
||||
continue;
|
||||
// skip some duplicate spells like dash/dive
|
||||
if (talentInfo->TalentID == 2201 || talentInfo->TalentID == 2208 || talentInfo->TalentID == 2219 || talentInfo->TalentID == 2203)
|
||||
if (talentInfo->TalentID == 2201 || talentInfo->TalentID == 2208 || talentInfo->TalentID == 2219 ||
|
||||
talentInfo->TalentID == 2203)
|
||||
continue;
|
||||
|
||||
|
||||
spells.push_back(talentInfo);
|
||||
}
|
||||
std::sort(spells.begin(), spells.end(),
|
||||
|
||||
@@ -67,6 +67,8 @@ public:
|
||||
bool autoSaveMana;
|
||||
uint32 saveManaThreshold;
|
||||
bool autoAvoidAoe;
|
||||
float maxAoeAvoidRadius;
|
||||
std::set<uint32> aoeAvoidSpellWhitelist;
|
||||
bool tellWhenAvoidAoe;
|
||||
|
||||
uint32 openGoSpell;
|
||||
|
||||
@@ -769,49 +769,61 @@ bool RandomItemMgr::CanEquipWeapon(uint8 clazz, ItemTemplate const* proto)
|
||||
{
|
||||
case CLASS_PRIEST:
|
||||
if (proto->SubClass != ITEM_SUBCLASS_WEAPON_STAFF && proto->SubClass != ITEM_SUBCLASS_WEAPON_WAND &&
|
||||
proto->SubClass != ITEM_SUBCLASS_WEAPON_MACE)
|
||||
proto->SubClass != ITEM_SUBCLASS_WEAPON_MACE && proto->SubClass != ITEM_SUBCLASS_WEAPON_DAGGER)
|
||||
return false;
|
||||
break;
|
||||
case CLASS_MAGE:
|
||||
case CLASS_WARLOCK:
|
||||
if (proto->SubClass != ITEM_SUBCLASS_WEAPON_STAFF && proto->SubClass != ITEM_SUBCLASS_WEAPON_WAND &&
|
||||
proto->SubClass != ITEM_SUBCLASS_WEAPON_SWORD)
|
||||
proto->SubClass != ITEM_SUBCLASS_WEAPON_DAGGER && proto->SubClass != ITEM_SUBCLASS_WEAPON_SWORD)
|
||||
return false;
|
||||
break;
|
||||
case CLASS_WARRIOR:
|
||||
if (proto->SubClass != ITEM_SUBCLASS_WEAPON_MACE2 && proto->SubClass != ITEM_SUBCLASS_WEAPON_SWORD2 &&
|
||||
if (proto->SubClass != ITEM_SUBCLASS_WEAPON_MACE2 && proto->SubClass != ITEM_SUBCLASS_WEAPON_AXE &&
|
||||
proto->SubClass != ITEM_SUBCLASS_WEAPON_POLEARM && proto->SubClass != ITEM_SUBCLASS_WEAPON_SWORD2 &&
|
||||
proto->SubClass != ITEM_SUBCLASS_WEAPON_MACE && proto->SubClass != ITEM_SUBCLASS_WEAPON_SWORD &&
|
||||
proto->SubClass != ITEM_SUBCLASS_WEAPON_GUN && proto->SubClass != ITEM_SUBCLASS_WEAPON_CROSSBOW &&
|
||||
proto->SubClass != ITEM_SUBCLASS_WEAPON_BOW && proto->SubClass != ITEM_SUBCLASS_WEAPON_AXE &&
|
||||
proto->SubClass != ITEM_SUBCLASS_WEAPON_AXE2 && proto->SubClass != ITEM_SUBCLASS_WEAPON_THROWN)
|
||||
proto->SubClass != ITEM_SUBCLASS_WEAPON_BOW && proto->SubClass != ITEM_SUBCLASS_WEAPON_THROWN &&
|
||||
proto->SubClass != ITEM_SUBCLASS_WEAPON_AXE2 && proto->SubClass != ITEM_SUBCLASS_WEAPON_FIST &&
|
||||
proto->SubClass != ITEM_SUBCLASS_WEAPON_DAGGER && proto->SubClass != ITEM_SUBCLASS_WEAPON_STAFF)
|
||||
return false;
|
||||
break;
|
||||
case CLASS_PALADIN:
|
||||
if (proto->SubClass != ITEM_SUBCLASS_WEAPON_MACE2 && proto->SubClass != ITEM_SUBCLASS_WEAPON_SWORD2 &&
|
||||
proto->SubClass != ITEM_SUBCLASS_WEAPON_MACE && proto->SubClass != ITEM_SUBCLASS_WEAPON_SWORD)
|
||||
case CLASS_DEATH_KNIGHT:
|
||||
if (proto->SubClass != ITEM_SUBCLASS_WEAPON_MACE2 && proto->SubClass != ITEM_SUBCLASS_WEAPON_POLEARM &&
|
||||
proto->SubClass != ITEM_SUBCLASS_WEAPON_SWORD2 && proto->SubClass != ITEM_SUBCLASS_WEAPON_AXE2 &&
|
||||
proto->SubClass != ITEM_SUBCLASS_WEAPON_AXE && proto->SubClass != ITEM_SUBCLASS_WEAPON_MACE &&
|
||||
proto->SubClass != ITEM_SUBCLASS_WEAPON_SWORD)
|
||||
return false;
|
||||
break;
|
||||
case CLASS_SHAMAN:
|
||||
if (proto->SubClass != ITEM_SUBCLASS_WEAPON_MACE && proto->SubClass != ITEM_SUBCLASS_WEAPON_MACE2 &&
|
||||
if (proto->SubClass != ITEM_SUBCLASS_WEAPON_MACE && proto->SubClass != ITEM_SUBCLASS_WEAPON_AXE &&
|
||||
proto->SubClass != ITEM_SUBCLASS_WEAPON_FIST && proto->SubClass != ITEM_SUBCLASS_WEAPON_MACE2 &&
|
||||
proto->SubClass != ITEM_SUBCLASS_WEAPON_AXE2 && proto->SubClass != ITEM_SUBCLASS_WEAPON_DAGGER &&
|
||||
proto->SubClass != ITEM_SUBCLASS_WEAPON_STAFF)
|
||||
return false;
|
||||
break;
|
||||
case CLASS_DRUID:
|
||||
if (proto->SubClass != ITEM_SUBCLASS_WEAPON_MACE && proto->SubClass != ITEM_SUBCLASS_WEAPON_MACE2 &&
|
||||
proto->SubClass != ITEM_SUBCLASS_WEAPON_DAGGER && proto->SubClass != ITEM_SUBCLASS_WEAPON_STAFF)
|
||||
proto->SubClass != ITEM_SUBCLASS_WEAPON_DAGGER && proto->SubClass != ITEM_SUBCLASS_WEAPON_STAFF &&
|
||||
proto->SubClass != ITEM_SUBCLASS_WEAPON_POLEARM)
|
||||
return false;
|
||||
break;
|
||||
case CLASS_HUNTER:
|
||||
if (proto->SubClass != ITEM_SUBCLASS_WEAPON_AXE2 && proto->SubClass != ITEM_SUBCLASS_WEAPON_SWORD2 &&
|
||||
proto->SubClass != ITEM_SUBCLASS_WEAPON_GUN && proto->SubClass != ITEM_SUBCLASS_WEAPON_CROSSBOW &&
|
||||
proto->SubClass != ITEM_SUBCLASS_WEAPON_BOW)
|
||||
if (proto->SubClass != ITEM_SUBCLASS_WEAPON_DAGGER && proto->SubClass != ITEM_SUBCLASS_WEAPON_BOW &&
|
||||
proto->SubClass != ITEM_SUBCLASS_WEAPON_AXE2 && proto->SubClass != ITEM_SUBCLASS_WEAPON_AXE &&
|
||||
proto->SubClass != ITEM_SUBCLASS_WEAPON_SWORD2 && proto->SubClass != ITEM_SUBCLASS_WEAPON_SWORD &&
|
||||
proto->SubClass != ITEM_SUBCLASS_WEAPON_FIST && proto->SubClass != ITEM_SUBCLASS_WEAPON_GUN &&
|
||||
proto->SubClass != ITEM_SUBCLASS_WEAPON_CROSSBOW && proto->SubClass != ITEM_SUBCLASS_WEAPON_STAFF &&
|
||||
proto->SubClass != ITEM_SUBCLASS_WEAPON_POLEARM)
|
||||
return false;
|
||||
break;
|
||||
case CLASS_ROGUE:
|
||||
if (proto->SubClass != ITEM_SUBCLASS_WEAPON_DAGGER && proto->SubClass != ITEM_SUBCLASS_WEAPON_SWORD &&
|
||||
proto->SubClass != ITEM_SUBCLASS_WEAPON_MACE && proto->SubClass != ITEM_SUBCLASS_WEAPON_GUN &&
|
||||
proto->SubClass != ITEM_SUBCLASS_WEAPON_CROSSBOW && proto->SubClass != ITEM_SUBCLASS_WEAPON_BOW &&
|
||||
proto->SubClass != ITEM_SUBCLASS_WEAPON_THROWN)
|
||||
proto->SubClass != ITEM_SUBCLASS_WEAPON_FIST && proto->SubClass != ITEM_SUBCLASS_WEAPON_MACE &&
|
||||
proto->SubClass != ITEM_SUBCLASS_WEAPON_GUN && proto->SubClass != ITEM_SUBCLASS_WEAPON_CROSSBOW &&
|
||||
proto->SubClass != ITEM_SUBCLASS_WEAPON_BOW && proto->SubClass != ITEM_SUBCLASS_WEAPON_THROWN &&
|
||||
proto->SubClass != ITEM_SUBCLASS_WEAPON_AXE)
|
||||
return false;
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -1867,6 +1867,7 @@ void RandomPlayerbotMgr::GetBots()
|
||||
PlayerbotsDatabase.GetPreparedStatement(PLAYERBOTS_SEL_RANDOM_BOTS_BY_OWNER_AND_EVENT);
|
||||
stmt->SetData(0, 0);
|
||||
stmt->SetData(1, "add");
|
||||
uint32 maxAllowedBotCount = GetEventValue(0, "bot_count");
|
||||
if (PreparedQueryResult result = PlayerbotsDatabase.Query(stmt))
|
||||
{
|
||||
do
|
||||
@@ -1875,6 +1876,9 @@ void RandomPlayerbotMgr::GetBots()
|
||||
uint32 bot = fields[0].Get<uint32>();
|
||||
if (GetEventValue(bot, "add"))
|
||||
currentBots.push_back(bot);
|
||||
|
||||
if (currentBots.size() >= maxAllowedBotCount)
|
||||
break;
|
||||
} while (result->NextRow());
|
||||
}
|
||||
}
|
||||
@@ -2402,53 +2406,14 @@ void RandomPlayerbotMgr::PrintStats()
|
||||
++engine_combat;
|
||||
else
|
||||
++engine_dead;
|
||||
|
||||
uint8 spec = AiFactory::GetPlayerSpecTab(bot);
|
||||
switch (bot->getClass())
|
||||
{
|
||||
case CLASS_DRUID:
|
||||
if (spec == 2)
|
||||
++heal;
|
||||
else
|
||||
++dps;
|
||||
break;
|
||||
case CLASS_PALADIN:
|
||||
if (spec == 1)
|
||||
++tank;
|
||||
else if (spec == 0)
|
||||
++heal;
|
||||
else
|
||||
++dps;
|
||||
break;
|
||||
case CLASS_PRIEST:
|
||||
if (spec != 2)
|
||||
++heal;
|
||||
else
|
||||
++dps;
|
||||
break;
|
||||
case CLASS_SHAMAN:
|
||||
if (spec == 2)
|
||||
++heal;
|
||||
else
|
||||
++dps;
|
||||
break;
|
||||
case CLASS_WARRIOR:
|
||||
if (spec == 2)
|
||||
++tank;
|
||||
else
|
||||
++dps;
|
||||
break;
|
||||
case CLASS_DEATH_KNIGHT:
|
||||
if (spec == 0)
|
||||
tank++;
|
||||
else
|
||||
dps++;
|
||||
break;
|
||||
default:
|
||||
++dps;
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
if (botAI->IsHeal(bot, true))
|
||||
++heal;
|
||||
else if (botAI->IsTank(bot, true))
|
||||
++tank;
|
||||
else
|
||||
++dps;
|
||||
|
||||
if (TravelTarget* target = botAI->GetAiObjectContext()->GetValue<TravelTarget*>("travel target")->Get())
|
||||
{
|
||||
TravelState state = target->getTravelState();
|
||||
|
||||
@@ -94,7 +94,7 @@ private:
|
||||
{
|
||||
return new ActionNode("mana potion",
|
||||
/*P*/ nullptr,
|
||||
/*A*/ NextAction::array(0, new NextAction("drink"), nullptr),
|
||||
/*A*/ nullptr,
|
||||
/*C*/ nullptr);
|
||||
}
|
||||
|
||||
|
||||
@@ -1819,12 +1819,17 @@ bool AvoidAoeAction::AvoidAuraWithDynamicObj()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (sPlayerbotAIConfig->aoeAvoidSpellWhitelist.find(spellInfo->Id) != sPlayerbotAIConfig->aoeAvoidSpellWhitelist.end())
|
||||
return false;
|
||||
|
||||
DynamicObject* dynOwner = aura->GetDynobjOwner();
|
||||
if (!dynOwner || !dynOwner->IsInWorld())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
float radius = dynOwner->GetRadius();
|
||||
if (!radius || radius > sPlayerbotAIConfig->maxAoeAvoidRadius)
|
||||
return false;
|
||||
if (bot->GetDistance(dynOwner) > radius)
|
||||
{
|
||||
return false;
|
||||
@@ -1838,7 +1843,7 @@ bool AvoidAoeAction::AvoidAuraWithDynamicObj()
|
||||
lastTellTimer = time(NULL);
|
||||
lastMoveTimer = getMSTime();
|
||||
std::ostringstream out;
|
||||
out << "I'm avoiding " << name.str() << "...";
|
||||
out << "I'm avoiding " << name.str() << " (" << spellInfo->Id << ")" << " Radius " << radius << " - [Aura]";
|
||||
bot->Say(out.str(), LANG_UNIVERSAL);
|
||||
}
|
||||
return true;
|
||||
@@ -1869,17 +1874,28 @@ bool AvoidAoeAction::AvoidGameObjectWithDamage()
|
||||
{
|
||||
continue;
|
||||
}
|
||||
// 0 trap with no despawn after cast. 1 trap despawns after cast. 2 bomb casts on spawn.
|
||||
if (goInfo->trap.type != 0)
|
||||
continue;
|
||||
|
||||
uint32 spellId = goInfo->trap.spellId;
|
||||
if (!spellId)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (sPlayerbotAIConfig->aoeAvoidSpellWhitelist.find(spellId) != sPlayerbotAIConfig->aoeAvoidSpellWhitelist.end())
|
||||
continue;
|
||||
|
||||
const SpellInfo* spellInfo = sSpellMgr->GetSpellInfo(spellId);
|
||||
if (!spellInfo || spellInfo->IsPositive())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
float radius = (float)goInfo->trap.diameter / 2;
|
||||
if (!radius || radius > sPlayerbotAIConfig->maxAoeAvoidRadius)
|
||||
continue;
|
||||
// for (int i = 0; i < MAX_SPELL_EFFECTS; i++) {
|
||||
// if (spellInfo->Effects[i].Effect == SPELL_EFFECT_APPLY_AURA) {
|
||||
// if (spellInfo->Effects[i].ApplyAuraName == SPELL_AURA_PERIODIC_DAMAGE) {
|
||||
@@ -1903,7 +1919,7 @@ bool AvoidAoeAction::AvoidGameObjectWithDamage()
|
||||
lastTellTimer = time(NULL);
|
||||
lastMoveTimer = getMSTime();
|
||||
std::ostringstream out;
|
||||
out << "I'm avoiding " << name.str() << "...";
|
||||
out << "I'm avoiding " << name.str() << " (" << spellInfo->Id << ")" << " Radius " << radius << " - [Trap]";
|
||||
bot->Say(out.str(), LANG_UNIVERSAL);
|
||||
}
|
||||
return true;
|
||||
@@ -1946,6 +1962,8 @@ bool AvoidAoeAction::AvoidUnitWithDamageAura()
|
||||
sSpellMgr->GetSpellInfo(spellInfo->Effects[aurEff->GetEffIndex()].TriggerSpell);
|
||||
if (!triggerSpellInfo)
|
||||
continue;
|
||||
if (sPlayerbotAIConfig->aoeAvoidSpellWhitelist.find(triggerSpellInfo->Id) != sPlayerbotAIConfig->aoeAvoidSpellWhitelist.end())
|
||||
return false;
|
||||
for (int j = 0; j < MAX_SPELL_EFFECTS; j++)
|
||||
{
|
||||
if (triggerSpellInfo->Effects[j].Effect == SPELL_EFFECT_SCHOOL_DAMAGE)
|
||||
@@ -1955,6 +1973,8 @@ bool AvoidAoeAction::AvoidUnitWithDamageAura()
|
||||
{
|
||||
break;
|
||||
}
|
||||
if (!radius || radius > sPlayerbotAIConfig->maxAoeAvoidRadius)
|
||||
continue;
|
||||
std::ostringstream name;
|
||||
name << triggerSpellInfo->SpellName[LOCALE_enUS]; //<< "] (unit)";
|
||||
if (FleePosition(unit->GetPosition(), radius))
|
||||
@@ -1964,7 +1984,7 @@ bool AvoidAoeAction::AvoidUnitWithDamageAura()
|
||||
lastTellTimer = time(NULL);
|
||||
lastMoveTimer = getMSTime();
|
||||
std::ostringstream out;
|
||||
out << "I'm avoiding " << name.str() << "...";
|
||||
out << "I'm avoiding " << name.str() << " (" << triggerSpellInfo->Id << ")" << " Radius " << radius << " - [Unit Trigger]";
|
||||
bot->Say(out.str(), LANG_UNIVERSAL);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
#include "Object.h"
|
||||
#include "Playerbots.h"
|
||||
#include "QuestDef.h"
|
||||
#include "StatsWeightCalculator.h"
|
||||
#include "WorldPacket.h"
|
||||
#include "BroadcastHelper.h"
|
||||
|
||||
@@ -176,8 +177,20 @@ void TalkToQuestGiverAction::RewardMultipleItem(Quest const* quest, Object* ques
|
||||
bestIds = BestRewards(quest);
|
||||
if (!bestIds.empty())
|
||||
{
|
||||
ItemTemplate const* item = sObjectMgr->GetItemTemplate(quest->RewardChoiceItemId[*bestIds.begin()]);
|
||||
bot->RewardQuest(quest, *bestIds.begin(), questGiver, true);
|
||||
StatsWeightCalculator calc(bot);
|
||||
uint32 best = 0;
|
||||
float bestScore = 0;
|
||||
for (uint32 id : bestIds)
|
||||
{
|
||||
float score = calc.CalculateItem(quest->RewardChoiceItemId[id]);
|
||||
if (score > bestScore)
|
||||
{
|
||||
bestScore = score;
|
||||
best = id;
|
||||
}
|
||||
}
|
||||
ItemTemplate const* item = sObjectMgr->GetItemTemplate(quest->RewardChoiceItemId[best]);
|
||||
bot->RewardQuest(quest, best, questGiver, true);
|
||||
out << "Rewarded " << ChatHelper::FormatItem(item);
|
||||
}
|
||||
else
|
||||
|
||||
@@ -64,6 +64,7 @@ public:
|
||||
this->prev_phase = 0;
|
||||
this->prev_erupt = 0;
|
||||
this->prev_timer = 0;
|
||||
ResetSafe();
|
||||
waypoints.push_back(std::make_pair(2793.58f, -3665.93f));
|
||||
waypoints.push_back(std::make_pair(2775.49f, -3674.43f));
|
||||
waypoints.push_back(std::make_pair(2762.30f, -3684.59f));
|
||||
|
||||
@@ -145,6 +145,9 @@ Aura* AreaDebuffValue::Calculate()
|
||||
{
|
||||
continue;
|
||||
}
|
||||
// float radius = dynOwner->GetRadius();
|
||||
// if (radius > 12.0f)
|
||||
// continue;
|
||||
return aura;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -65,7 +65,10 @@ void ArmsWarriorStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
|
||||
"victory rush", NextAction::array(0, new NextAction("victory rush", ACTION_INTERRUPT), nullptr)));
|
||||
triggers.push_back(new TriggerNode(
|
||||
"high rage available", NextAction::array(0, new NextAction("heroic strike", ACTION_HIGH + 10), nullptr)));
|
||||
triggers.push_back(new TriggerNode("medium rage available", NextAction::array(0, new NextAction("slam", ACTION_HIGH + 1), nullptr)));
|
||||
triggers.push_back(new TriggerNode("medium rage available",
|
||||
NextAction::array(0, new NextAction("slam", ACTION_HIGH + 1),
|
||||
new NextAction("thunder clap", ACTION_HIGH),
|
||||
nullptr)));
|
||||
triggers.push_back(
|
||||
new TriggerNode("bloodrage", NextAction::array(0, new NextAction("bloodrage", ACTION_HIGH + 2), nullptr)));
|
||||
triggers.push_back(
|
||||
@@ -76,5 +79,5 @@ void ArmsWarriorStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
|
||||
triggers.push_back(new TriggerNode(
|
||||
"critical health", NextAction::array(0, new NextAction("intimidating shout", ACTION_EMERGENCY), nullptr)));
|
||||
triggers.push_back(new TriggerNode("medium aoe",
|
||||
NextAction::array(0, new NextAction("thunder clap", ACTION_HIGH + 1), nullptr)));
|
||||
NextAction::array(0, new NextAction("thunder clap", ACTION_HIGH + 2), nullptr)));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user