mirror of
https://github.com/liyunfan1223/mod-playerbots.git
synced 2026-06-20 15:39:25 +02:00
Compare commits
49 Commits
502df01436
...
b51f4b3c70
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b51f4b3c70 | ||
|
|
974faf0cb0 | ||
|
|
e052ec3b17 | ||
|
|
4a991c194d | ||
|
|
ed31f8f8a7 | ||
|
|
479794b66b | ||
|
|
337fbca8c0 | ||
|
|
fe12f1a708 | ||
|
|
8916cf83c0 | ||
|
|
77caf85fd1 | ||
|
|
5e5d41f878 | ||
|
|
63c5d674d6 | ||
|
|
43ee732003 | ||
|
|
f42f37399f | ||
|
|
c7929482c4 | ||
|
|
e1489f213e | ||
|
|
007189fd5c | ||
|
|
eabefb1d33 | ||
|
|
2208c80caa | ||
|
|
a472fc2d68 | ||
|
|
bac63e2a8c | ||
|
|
690288b5cc | ||
|
|
57134918cb | ||
|
|
324b50f1be | ||
|
|
7d8d8c6b31 | ||
|
|
34b0432aaa | ||
|
|
edc999c8ac | ||
|
|
85e2a940a1 | ||
|
|
6754a95890 | ||
|
|
d0fac16c85 | ||
|
|
a64c721f35 | ||
|
|
27503a9c37 | ||
|
|
1a7e6db0c9 | ||
|
|
6ae973bb8e | ||
|
|
101da6ecd3 | ||
|
|
605e7586c5 | ||
|
|
129cb252cf | ||
|
|
088537277c | ||
|
|
6944da8d69 | ||
|
|
980c1b8cd8 | ||
|
|
ad14420400 | ||
|
|
1d0aeec7b9 | ||
|
|
7741626631 | ||
|
|
806013a4c9 | ||
|
|
3269d1a4b3 | ||
|
|
1ae72b0888 | ||
|
|
0a9bf70305 | ||
|
|
e18fdd02cd | ||
|
|
a23158ef52 |
File diff suppressed because it is too large
Load Diff
@ -1,13 +0,0 @@
|
||||
DELETE FROM ai_playerbot_texts WHERE name IN (
|
||||
'send_mail_disabled'
|
||||
);
|
||||
|
||||
DELETE FROM ai_playerbot_texts_chance WHERE name IN (
|
||||
'send_mail_disabled'
|
||||
);
|
||||
|
||||
INSERT INTO ai_playerbot_texts (id, name, text, say_type, reply_type, text_loc1, text_loc2, text_loc3, text_loc4, text_loc5, text_loc6, text_loc7, text_loc8) VALUES
|
||||
(1899, 'send_mail_disabled', 'I cannot send mail', 0, 0, '우편을 보낼 수 없습니다', 'Je ne peux pas envoyer de courrier', 'Ich kann keine Post senden', '我不能寄送邮件', '我不能寄送郵件', 'No puedo enviar correo', 'No puedo enviar correo', 'Я не могу отправить почту');
|
||||
|
||||
INSERT INTO ai_playerbot_texts_chance (name, probability) VALUES
|
||||
('send_mail_disabled', 100);
|
||||
@ -12,8 +12,8 @@ bool AutoMaintenanceOnLevelupAction::Execute(Event /*event*/)
|
||||
{
|
||||
AutoPickTalents();
|
||||
AutoLearnSpell();
|
||||
AutoTeleportForLevel();
|
||||
AutoUpgradeEquip();
|
||||
AutoTeleportForLevel();
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -21,11 +21,13 @@ bool AutoMaintenanceOnLevelupAction::Execute(Event /*event*/)
|
||||
void AutoMaintenanceOnLevelupAction::AutoTeleportForLevel()
|
||||
{
|
||||
if (!sPlayerbotAIConfig.autoTeleportForLevel || !sRandomPlayerbotMgr.IsRandomBot(bot))
|
||||
{
|
||||
return;
|
||||
|
||||
}
|
||||
if (botAI->HasRealPlayerMaster())
|
||||
{
|
||||
return;
|
||||
|
||||
}
|
||||
sRandomPlayerbotMgr.RandomTeleportForLevel(bot);
|
||||
return;
|
||||
}
|
||||
@ -87,17 +89,21 @@ void AutoMaintenanceOnLevelupAction::LearnQuestSpells(std::ostringstream* out)
|
||||
{
|
||||
Quest const* quest = i->second;
|
||||
|
||||
if (!quest->GetRequiredClasses() || quest->IsRepeatable() || quest->GetMinLevel() < 10 ||
|
||||
quest->GetMinLevel() > bot->GetLevel())
|
||||
{
|
||||
// only process class-specific quests to learn class-related spells, cuz
|
||||
// we don't want all these bunch of entries to be handled!
|
||||
if (!quest->GetRequiredClasses())
|
||||
continue;
|
||||
}
|
||||
|
||||
// skip quests that are repeatable, too low level, or above bots' level
|
||||
if (quest->IsRepeatable() || quest->GetMinLevel() < 10 || quest->GetMinLevel() > bot->GetLevel())
|
||||
continue;
|
||||
|
||||
// skip if bot doesnt satisfy class, race, or skill requirements
|
||||
if (!bot->SatisfyQuestClass(quest, false) || !bot->SatisfyQuestRace(quest, false) ||
|
||||
!bot->SatisfyQuestSkill(quest, false))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// use the same logic and impl from Player::learnQuestRewardedSpells
|
||||
|
||||
int32 spellId = quest->GetRewSpellCast();
|
||||
if (!spellId)
|
||||
@ -107,26 +113,31 @@ void AutoMaintenanceOnLevelupAction::LearnQuestSpells(std::ostringstream* out)
|
||||
if (!spellInfo)
|
||||
continue;
|
||||
|
||||
// xinef: find effect with learn spell and check if we have this spell
|
||||
bool found = false;
|
||||
for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
|
||||
{
|
||||
if (spellInfo->Effects[i].Effect == SPELL_EFFECT_LEARN_SPELL && spellInfo->Effects[i].TriggerSpell &&
|
||||
!bot->HasSpell(spellInfo->Effects[i].TriggerSpell))
|
||||
{
|
||||
// pusywizard: don't re-add profession specialties!
|
||||
if (SpellInfo const* triggeredInfo = sSpellMgr->GetSpellInfo(spellInfo->Effects[i].TriggerSpell))
|
||||
if (triggeredInfo->Effects[0].Effect == SPELL_EFFECT_TRADE_SKILL)
|
||||
break;
|
||||
break; // pussywizard: break and not cast the spell (found is false)
|
||||
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// xinef: we know the spell, continue
|
||||
if (!found)
|
||||
continue;
|
||||
|
||||
bot->CastSpell(bot, spellId, true);
|
||||
|
||||
// Check if RewardDisplaySpell is set to output the proper spell learned
|
||||
// after processing quests. Output the original RewardSpell otherwise.
|
||||
uint32 rewSpellId = quest->GetRewSpell();
|
||||
if (rewSpellId)
|
||||
{
|
||||
@ -156,11 +167,12 @@ std::string const AutoMaintenanceOnLevelupAction::FormatSpell(SpellInfo const* s
|
||||
|
||||
void AutoMaintenanceOnLevelupAction::AutoUpgradeEquip()
|
||||
{
|
||||
if (!sRandomPlayerbotMgr.IsRandomBot(bot))
|
||||
if (!sPlayerbotAIConfig.autoUpgradeEquip || !sRandomPlayerbotMgr.IsRandomBot(bot))
|
||||
return;
|
||||
|
||||
PlayerbotFactory factory(bot, bot->GetLevel());
|
||||
|
||||
// Clean up old consumables before adding new ones
|
||||
factory.CleanupConsumables();
|
||||
|
||||
factory.InitAmmo();
|
||||
@ -169,6 +181,9 @@ void AutoMaintenanceOnLevelupAction::AutoUpgradeEquip()
|
||||
factory.InitConsumables();
|
||||
factory.InitPotions();
|
||||
|
||||
if (sPlayerbotAIConfig.autoUpgradeEquip)
|
||||
factory.InitEquipment(true);
|
||||
if (!sPlayerbotAIConfig.equipmentPersistence || bot->GetLevel() < sPlayerbotAIConfig.equipmentPersistenceLevel)
|
||||
{
|
||||
if (sPlayerbotAIConfig.incrementalGearInit)
|
||||
factory.InitEquipment(true);
|
||||
}
|
||||
}
|
||||
|
||||
@ -154,11 +154,9 @@ void EquipAction::EquipItem(Item* item)
|
||||
calculator.SetOverflowPenalty(false);
|
||||
|
||||
// Calculate item scores once and store them
|
||||
float newItemScore = calculator.CalculateItem(itemId, item->GetItemRandomPropertyId());
|
||||
float mainHandScore = mainHandItem
|
||||
? calculator.CalculateItem(mainHandItem->GetTemplate()->ItemId, mainHandItem->GetItemRandomPropertyId()) : 0.0f;
|
||||
float offHandScore = offHandItem
|
||||
? calculator.CalculateItem(offHandItem->GetTemplate()->ItemId, offHandItem->GetItemRandomPropertyId()) : 0.0f;
|
||||
float newItemScore = calculator.CalculateItem(itemId);
|
||||
float mainHandScore = mainHandItem ? calculator.CalculateItem(mainHandItem->GetTemplate()->ItemId) : 0.0f;
|
||||
float offHandScore = offHandItem ? calculator.CalculateItem(offHandItem->GetTemplate()->ItemId) : 0.0f;
|
||||
|
||||
// Determine where this weapon can go
|
||||
bool canGoMain = (invType == INVTYPE_WEAPON ||
|
||||
|
||||
@ -86,7 +86,7 @@ bool TogglePetSpellAutoCastAction::Execute(Event /*event*/)
|
||||
|
||||
uint32 spellId = itr->first;
|
||||
const SpellInfo* spellInfo = sSpellMgr->GetSpellInfo(spellId);
|
||||
if (!spellInfo || !spellInfo->IsAutocastable())
|
||||
if (!spellInfo->IsAutocastable())
|
||||
continue;
|
||||
|
||||
bool shouldApply = true;
|
||||
|
||||
@ -6,7 +6,6 @@
|
||||
#include "GenericSpellActions.h"
|
||||
|
||||
#include <ctime>
|
||||
#include <unordered_set>
|
||||
|
||||
#include "Event.h"
|
||||
#include "ItemTemplate.h"
|
||||
@ -24,116 +23,6 @@
|
||||
using ai::buff::MakeAuraQualifierForBuff;
|
||||
using ai::spell::HasSpellOrCategoryCooldown;
|
||||
|
||||
namespace
|
||||
{
|
||||
std::unordered_set<uint32> const& GetMixedTriggerTrinketSpellIds()
|
||||
{
|
||||
static std::unordered_set<uint32> const mixedTriggerSpellIds = []()
|
||||
{
|
||||
std::unordered_set<uint32> onUseSpellIds;
|
||||
std::unordered_set<uint32> onEquipSpellIds;
|
||||
std::unordered_set<uint32> mixedSpellIds;
|
||||
|
||||
auto const* itemTemplates = sObjectMgr->GetItemTemplateStore();
|
||||
if (!itemTemplates)
|
||||
return mixedSpellIds;
|
||||
|
||||
auto const markSpellId = [&](int32 spellId, uint8 spellTrigger)
|
||||
{
|
||||
if (spellId <= 0)
|
||||
return;
|
||||
|
||||
if (spellTrigger == ITEM_SPELLTRIGGER_ON_USE)
|
||||
{
|
||||
if (onEquipSpellIds.find(spellId) != onEquipSpellIds.end())
|
||||
mixedSpellIds.insert(spellId);
|
||||
|
||||
onUseSpellIds.insert(spellId);
|
||||
}
|
||||
else if (spellTrigger == ITEM_SPELLTRIGGER_ON_EQUIP)
|
||||
{
|
||||
if (onUseSpellIds.find(spellId) != onUseSpellIds.end())
|
||||
mixedSpellIds.insert(spellId);
|
||||
|
||||
onEquipSpellIds.insert(spellId);
|
||||
}
|
||||
};
|
||||
|
||||
for (auto const& itr : *itemTemplates)
|
||||
{
|
||||
ItemTemplate const& proto = itr.second;
|
||||
if (proto.InventoryType != INVTYPE_TRINKET)
|
||||
continue;
|
||||
|
||||
for (uint8 spellIndex = 0; spellIndex < MAX_ITEM_PROTO_SPELLS; ++spellIndex)
|
||||
{
|
||||
auto const& spellData = proto.Spells[spellIndex];
|
||||
markSpellId(spellData.SpellId, spellData.SpellTrigger);
|
||||
}
|
||||
}
|
||||
|
||||
return mixedSpellIds;
|
||||
}();
|
||||
|
||||
return mixedTriggerSpellIds;
|
||||
}
|
||||
|
||||
bool IsManaRestoreEffect(SpellEffectInfo const& effectInfo)
|
||||
{
|
||||
return (effectInfo.Effect == SPELL_EFFECT_ENERGIZE &&
|
||||
effectInfo.MiscValue == POWER_MANA) ||
|
||||
(effectInfo.Effect == SPELL_EFFECT_APPLY_AURA &&
|
||||
effectInfo.ApplyAuraName == SPELL_AURA_PERIODIC_ENERGIZE &&
|
||||
effectInfo.MiscValue == POWER_MANA);
|
||||
}
|
||||
|
||||
bool IsManaEfficiencyEffect(SpellEffectInfo const& effectInfo)
|
||||
{
|
||||
return effectInfo.Effect == SPELL_EFFECT_APPLY_AURA &&
|
||||
(((effectInfo.ApplyAuraName == SPELL_AURA_MOD_POWER_REGEN ||
|
||||
effectInfo.ApplyAuraName == SPELL_AURA_MOD_POWER_REGEN_PERCENT) &&
|
||||
effectInfo.MiscValue == POWER_MANA) ||
|
||||
effectInfo.ApplyAuraName == SPELL_AURA_MOD_POWER_COST_SCHOOL ||
|
||||
effectInfo.ApplyAuraName == SPELL_AURA_MOD_POWER_COST_SCHOOL_PCT ||
|
||||
effectInfo.ApplyAuraName == SPELL_AURA_MOD_MANA_REGEN_INTERRUPT);
|
||||
}
|
||||
|
||||
bool IsDefensiveTankEffect(SpellEffectInfo const& effectInfo)
|
||||
{
|
||||
if (effectInfo.Effect != SPELL_EFFECT_APPLY_AURA)
|
||||
return false;
|
||||
|
||||
uint32 const tankRatingsMask =
|
||||
(1u << CR_DEFENSE_SKILL) |
|
||||
(1u << CR_DODGE) |
|
||||
(1u << CR_PARRY) |
|
||||
(1u << CR_BLOCK) |
|
||||
(1u << CR_HIT_TAKEN_MELEE) |
|
||||
(1u << CR_HIT_TAKEN_RANGED) |
|
||||
(1u << CR_HIT_TAKEN_SPELL) |
|
||||
(1u << CR_CRIT_TAKEN_MELEE) |
|
||||
(1u << CR_CRIT_TAKEN_RANGED) |
|
||||
(1u << CR_CRIT_TAKEN_SPELL);
|
||||
|
||||
switch (effectInfo.ApplyAuraName)
|
||||
{
|
||||
case SPELL_AURA_MOD_RESISTANCE:
|
||||
return (effectInfo.MiscValue & SPELL_SCHOOL_MASK_NORMAL) != 0;
|
||||
case SPELL_AURA_MOD_RATING:
|
||||
return (effectInfo.MiscValue & tankRatingsMask) != 0;
|
||||
case SPELL_AURA_MOD_INCREASE_HEALTH:
|
||||
case SPELL_AURA_MOD_INCREASE_HEALTH_PERCENT:
|
||||
case SPELL_AURA_MOD_PARRY_PERCENT:
|
||||
case SPELL_AURA_MOD_DODGE_PERCENT:
|
||||
case SPELL_AURA_MOD_BLOCK_PERCENT:
|
||||
case SPELL_AURA_MOD_DAMAGE_PERCENT_TAKEN:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
CastSpellAction::CastSpellAction(PlayerbotAI* botAI, std::string const spell)
|
||||
: Action(botAI, spell), range(botAI->GetRange("spell")), spell(spell) {}
|
||||
|
||||
@ -540,109 +429,52 @@ bool UseTrinketAction::UseTrinket(Item* item)
|
||||
|
||||
uint8 bagIndex = item->GetBagSlot();
|
||||
uint8 slot = item->GetSlot();
|
||||
// uint8 spell_index = 0; //not used, line marked for removal.
|
||||
uint8 cast_count = 1;
|
||||
ObjectGuid item_guid = item->GetGUID();
|
||||
uint32 glyphIndex = 0;
|
||||
uint8 castFlags = 0;
|
||||
uint32 targetFlag = TARGET_FLAG_NONE;
|
||||
uint32 spellId = 0;
|
||||
int32 itemSpellCooldown = 0;
|
||||
uint32 itemSpellCategory = 0;
|
||||
int32 itemSpellCategoryCooldown = 0;
|
||||
|
||||
for (uint8 i = 0; i < MAX_ITEM_PROTO_SPELLS; ++i)
|
||||
{
|
||||
if (item->GetTemplate()->Spells[i].SpellId > 0 &&
|
||||
item->GetTemplate()->Spells[i].SpellTrigger == ITEM_SPELLTRIGGER_ON_USE)
|
||||
{
|
||||
spellId = item->GetTemplate()->Spells[i].SpellId;
|
||||
itemSpellCooldown = item->GetTemplate()->Spells[i].SpellCooldown;
|
||||
itemSpellCategory = item->GetTemplate()->Spells[i].SpellCategory;
|
||||
itemSpellCategoryCooldown = item->GetTemplate()->Spells[i].SpellCategoryCooldown;
|
||||
uint64 const itemCooldownKey = (static_cast<uint64>(item->GetEntry()) << 32) | spellId;
|
||||
uint32 const now = getMSTime();
|
||||
|
||||
if (itemSpellCooldown > 0)
|
||||
{
|
||||
auto const itemCooldownItr = trinketItemCooldownExpiries.find(itemCooldownKey);
|
||||
if (itemCooldownItr != trinketItemCooldownExpiries.end())
|
||||
{
|
||||
if (itemCooldownItr->second > now)
|
||||
return false;
|
||||
|
||||
trinketItemCooldownExpiries.erase(itemCooldownItr);
|
||||
}
|
||||
}
|
||||
|
||||
if (itemSpellCategory && itemSpellCategoryCooldown > 0)
|
||||
{
|
||||
auto const categoryCooldownItr = trinketCategoryCooldownExpiries.find(itemSpellCategory);
|
||||
if (categoryCooldownItr != trinketCategoryCooldownExpiries.end())
|
||||
{
|
||||
if (categoryCooldownItr->second > now)
|
||||
return false;
|
||||
|
||||
trinketCategoryCooldownExpiries.erase(categoryCooldownItr);
|
||||
}
|
||||
}
|
||||
|
||||
const SpellInfo* spellInfo = sSpellMgr->GetSpellInfo(spellId);
|
||||
|
||||
if (!spellInfo || !spellInfo->IsPositive())
|
||||
return false;
|
||||
|
||||
bool applyAura = false;
|
||||
bool restoresMana = false;
|
||||
bool improvesManaEfficiency = false;
|
||||
bool defensiveTankEffect = false;
|
||||
for (int i = 0; i < MAX_SPELL_EFFECTS; i++)
|
||||
{
|
||||
const SpellEffectInfo& effectInfo = spellInfo->Effects[i];
|
||||
if (effectInfo.Effect == SPELL_EFFECT_APPLY_AURA)
|
||||
applyAura = true;
|
||||
|
||||
restoresMana = restoresMana || IsManaRestoreEffect(effectInfo);
|
||||
improvesManaEfficiency = improvesManaEfficiency || IsManaEfficiencyEffect(effectInfo);
|
||||
defensiveTankEffect = defensiveTankEffect || IsDefensiveTankEffect(effectInfo);
|
||||
}
|
||||
|
||||
if (!applyAura && !restoresMana)
|
||||
return false;
|
||||
|
||||
if (restoresMana || improvesManaEfficiency)
|
||||
{
|
||||
if (!AI_VALUE2(bool, "has mana", "self target"))
|
||||
return false;
|
||||
|
||||
uint8 const manaPct = AI_VALUE2(uint8, "mana", "self target");
|
||||
if ((restoresMana && manaPct >= sPlayerbotAIConfig.mediumMana) ||
|
||||
manaPct >= sPlayerbotAIConfig.highMana)
|
||||
{
|
||||
return false;
|
||||
applyAura = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (defensiveTankEffect)
|
||||
{
|
||||
uint8 const healthPct = AI_VALUE2(uint8, "health", "self target");
|
||||
if (healthPct > sPlayerbotAIConfig.lowHealth)
|
||||
return false;
|
||||
}
|
||||
|
||||
auto const& mixedTriggerTrinketSpellIds = GetMixedTriggerTrinketSpellIds();
|
||||
// Exclude trinkets that expose the same spell as both ON_EQUIP and ON_USE across
|
||||
// item templates. Those are equip/proc effects leaking into the active-use path,
|
||||
// as seen with the error versions of Oracle Talisman of Ablution (44870) and
|
||||
// Frenzyheart Insignia of Fury (44869).
|
||||
if (mixedTriggerTrinketSpellIds.find(spellId) != mixedTriggerTrinketSpellIds.end())
|
||||
if (!applyAura)
|
||||
return false;
|
||||
|
||||
if (!botAI->CanCastSpell(spellId, bot, false, nullptr, item))
|
||||
return false;
|
||||
uint32 spellProcFlag = spellInfo->ProcFlags;
|
||||
|
||||
// Handle items with procflag "if you kill a target that grants honor or experience"
|
||||
// Bots will "learn" the trinket proc, so CanCastSpell() will be true
|
||||
// e.g. on Item https://www.wowhead.com/wotlk/item=44074/oracle-talisman-of-ablution leading to
|
||||
// constant casting of the proc spell onto themselfes https://www.wowhead.com/wotlk/spell=59787/oracle-ablutions
|
||||
// This will lead to multiple hundreds of entries in m_appliedAuras -> Once killing an enemy -> Big diff time spikes
|
||||
if (spellProcFlag != 0) return false;
|
||||
|
||||
if (!botAI->CanCastSpell(spellId, bot, false))
|
||||
return false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!spellId)
|
||||
return false;
|
||||
|
||||
@ -651,25 +483,7 @@ bool UseTrinketAction::UseTrinket(Item* item)
|
||||
|
||||
targetFlag = TARGET_FLAG_NONE;
|
||||
packet << targetFlag << bot->GetPackGUID();
|
||||
|
||||
bot->GetSession()->HandleUseItemOpcode(packet);
|
||||
|
||||
uint32 const now = getMSTime();
|
||||
uint32 const cooldownDelay = bot->GetSpellCooldownDelay(spellId);
|
||||
if (cooldownDelay > 0)
|
||||
{
|
||||
if (itemSpellCooldown > 0)
|
||||
{
|
||||
uint64 const itemCooldownKey = (static_cast<uint64>(item->GetEntry()) << 32) | spellId;
|
||||
trinketItemCooldownExpiries[itemCooldownKey] = now + static_cast<uint32>(itemSpellCooldown);
|
||||
}
|
||||
|
||||
if (itemSpellCategory && itemSpellCategoryCooldown > 0)
|
||||
{
|
||||
trinketCategoryCooldownExpiries[itemSpellCategory] = now + static_cast<uint32>(itemSpellCategoryCooldown);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@ -334,10 +334,6 @@ public:
|
||||
|
||||
protected:
|
||||
bool UseTrinket(Item* trinket);
|
||||
|
||||
private:
|
||||
std::unordered_map<uint64, uint32> trinketItemCooldownExpiries;
|
||||
std::unordered_map<uint32, uint32> trinketCategoryCooldownExpiries;
|
||||
};
|
||||
|
||||
class CastSpellOnEnemyHealerAction : public CastSpellAction
|
||||
|
||||
@ -44,21 +44,6 @@ bool ResetAiAction::Execute(Event event)
|
||||
}
|
||||
}
|
||||
}
|
||||
if (Player* master = botAI->GetMaster())
|
||||
{
|
||||
Group* botGroup = bot->GetGroup();
|
||||
Group* masterGroup = master->GetGroup();
|
||||
if (botGroup && (!masterGroup || masterGroup != botGroup))
|
||||
botAI->SetMaster(nullptr);
|
||||
}
|
||||
if (sRandomPlayerbotMgr.IsRandomBot(bot) && !bot->InBattleground())
|
||||
{
|
||||
if (bot->GetGroup() && (!botAI->GetMaster() || GET_PLAYERBOT_AI(botAI->GetMaster())))
|
||||
{
|
||||
if (Player* newMaster = botAI->FindNewMaster())
|
||||
botAI->SetMaster(newMaster);
|
||||
}
|
||||
}
|
||||
PlayerbotRepository::instance().Reset(botAI);
|
||||
botAI->ResetStrategies(false);
|
||||
botAI->TellMaster("AI was reset to defaults");
|
||||
|
||||
@ -34,23 +34,24 @@ bool SendMailAction::Execute(Event event)
|
||||
Player* receiver = GetMaster();
|
||||
Player* tellTo = receiver;
|
||||
|
||||
std::vector<std::string> ss = split(text, ' ');
|
||||
if (ss.size() > 1)
|
||||
{
|
||||
if (Player* p = ObjectAccessor::FindPlayer(ObjectGuid(uint64(ss[ss.size() - 1].c_str()))))
|
||||
receiver = p;
|
||||
}
|
||||
|
||||
if (!receiver)
|
||||
receiver = event.getOwner();
|
||||
|
||||
if (!receiver || receiver == bot)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!tellTo)
|
||||
tellTo = receiver;
|
||||
|
||||
if (!sPlayerbotAIConfig.botSendMailEnabled)
|
||||
{
|
||||
bot->Whisper(PlayerbotTextMgr::instance().GetBotTextOrDefault(
|
||||
"send_mail_disabled", "I cannot send mail", {}),
|
||||
LANG_UNIVERSAL, tellTo);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!mailboxFound && !randomBot)
|
||||
{
|
||||
bot->Whisper(PlayerbotTextMgr::instance().GetBotTextOrDefault(
|
||||
|
||||
@ -16,7 +16,7 @@ void WorldPacketHandlerStrategy::InitTriggers(std::vector<TriggerNode*>& trigger
|
||||
triggers.push_back(
|
||||
new TriggerNode("uninvite guid", { NextAction("uninvite", relevance) }));
|
||||
triggers.push_back(
|
||||
new TriggerNode("group set leader", { NextAction("reset botAI", relevance) }));
|
||||
new TriggerNode("group set leader", { /*NextAction("leader", relevance),*/ }));
|
||||
triggers.push_back(new TriggerNode(
|
||||
"not enough money", { NextAction("tell not enough money", relevance) }));
|
||||
triggers.push_back(
|
||||
|
||||
@ -161,7 +161,9 @@ void ShamanAoeStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
|
||||
}
|
||||
else if (tab == SHAMAN_TAB_ENHANCEMENT)
|
||||
{
|
||||
triggers.push_back(new TriggerNode("medium aoe",{ NextAction("fire nova", 23.0f), }));
|
||||
triggers.push_back(new TriggerNode("medium aoe",{ NextAction("magma totem", 24.0f),
|
||||
NextAction("fire nova", 23.0f), }));
|
||||
|
||||
triggers.push_back(new TriggerNode("maelstrom weapon 5 and medium aoe", { NextAction("chain lightning", 22.0f), }));
|
||||
triggers.push_back(new TriggerNode("maelstrom weapon 4 and medium aoe", { NextAction("chain lightning", 21.0f), }));
|
||||
triggers.push_back(new TriggerNode("enemy within melee", { NextAction("fire nova", 5.1f), }));
|
||||
|
||||
@ -5,7 +5,6 @@
|
||||
|
||||
#include "WarriorActions.h"
|
||||
|
||||
#include "AiFactory.h"
|
||||
#include "Playerbots.h"
|
||||
|
||||
bool CastBerserkerRageAction::isPossible()
|
||||
@ -37,27 +36,6 @@ bool CastBerserkerRageAction::isUseful()
|
||||
|
||||
bool CastSunderArmorAction::isUseful()
|
||||
{
|
||||
Group* group = bot->GetGroup();
|
||||
if (!group)
|
||||
return false;
|
||||
|
||||
if (!botAI->IsTank(bot, false))
|
||||
{
|
||||
for (GroupReference* ref = group->GetFirstMember(); ref; ref = ref->next())
|
||||
{
|
||||
Player* member = ref->GetSource();
|
||||
if (!member || member == bot || !member->IsAlive() || !member->IsInWorld() ||
|
||||
member->GetMapId() != bot->GetMapId())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (member->getClass() == CLASS_WARRIOR &&
|
||||
botAI->IsTank(member, false))
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
Aura* aura = botAI->GetAura("sunder armor", GetTarget(), false, true);
|
||||
return !aura || aura->GetStackAmount() < 5 || aura->GetDuration() <= 6000;
|
||||
}
|
||||
@ -112,7 +112,6 @@ std::vector<NextAction> ArmsWarriorStrategy::getDefaultActions()
|
||||
return {
|
||||
NextAction("bladestorm", ACTION_DEFAULT + 0.2f),
|
||||
NextAction("mortal strike", ACTION_DEFAULT + 0.1f),
|
||||
NextAction("sunder armor", ACTION_DEFAULT + 0.05f),
|
||||
NextAction("melee", ACTION_DEFAULT)
|
||||
};
|
||||
}
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
#include "Playerbots.h"
|
||||
#include "AiFactory.h"
|
||||
#include "ACTriggers.h"
|
||||
#include "ACActions.h"
|
||||
#include "AuchenaiCryptsTriggers.h"
|
||||
#include "AuchenaiCryptsActions.h"
|
||||
|
||||
// Shirrak the Dead Watcher
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
|
||||
#include "AttackAction.h"
|
||||
#include "MovementActions.h"
|
||||
#include "ACTriggers.h"
|
||||
#include "AuchenaiCryptsTriggers.h"
|
||||
|
||||
// Shirrak the Dead Watcher
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
|
||||
#include "AiObjectContext.h"
|
||||
#include "Action.h"
|
||||
#include "ACActions.h"
|
||||
#include "AuchenaiCryptsActions.h"
|
||||
|
||||
class TbcDungeonAuchenaiCryptsActionContext : public NamedObjectContext<Action>
|
||||
{
|
||||
@ -3,7 +3,7 @@
|
||||
|
||||
#include "AiObjectContext.h"
|
||||
#include "TriggerContext.h"
|
||||
#include "ACTriggers.h"
|
||||
#include "AuchenaiCryptsTriggers.h"
|
||||
|
||||
class TbcDungeonAuchenaiCryptsTriggerContext : public NamedObjectContext<Trigger>
|
||||
{
|
||||
@ -1,6 +1,6 @@
|
||||
#include "ACMultipliers.h"
|
||||
#include "ACActions.h"
|
||||
#include "ACTriggers.h"
|
||||
#include "AuchenaiCryptsMultipliers.h"
|
||||
#include "AuchenaiCryptsActions.h"
|
||||
#include "AuchenaiCryptsTriggers.h"
|
||||
#include "MovementActions.h"
|
||||
#include "ReachTargetActions.h"
|
||||
#include "FollowActions.h"
|
||||
@ -1,6 +1,6 @@
|
||||
#include "ACTriggers.h"
|
||||
#include "ACStrategy.h"
|
||||
#include "ACMultipliers.h"
|
||||
#include "AuchenaiCryptsTriggers.h"
|
||||
#include "AuchenaiCryptsStrategy.h"
|
||||
#include "AuchenaiCryptsMultipliers.h"
|
||||
|
||||
void TbcDungeonAuchenaiCryptsStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
|
||||
{
|
||||
@ -1,5 +1,5 @@
|
||||
#include "Playerbots.h"
|
||||
#include "ACTriggers.h"
|
||||
#include "AuchenaiCryptsTriggers.h"
|
||||
#include "AiObject.h"
|
||||
#include "AiObjectContext.h"
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
#include "Playerbots.h"
|
||||
#include "ANActions.h"
|
||||
#include "AzjolNerubActions.h"
|
||||
|
||||
bool AttackWebWrapAction::isUseful() { return !botAI->IsHeal(bot); }
|
||||
bool AttackWebWrapAction::Execute(Event /*event*/)
|
||||
@ -5,7 +5,7 @@
|
||||
#include "AttackAction.h"
|
||||
#include "PlayerbotAI.h"
|
||||
#include "Playerbots.h"
|
||||
#include "ANTriggers.h"
|
||||
#include "AzjolNerubTriggers.h"
|
||||
|
||||
class AttackWebWrapAction : public AttackAction
|
||||
{
|
||||
@ -3,7 +3,7 @@
|
||||
|
||||
#include "Action.h"
|
||||
#include "NamedObjectContext.h"
|
||||
#include "ANActions.h"
|
||||
#include "AzjolNerubActions.h"
|
||||
|
||||
class WotlkDungeonANActionContext : public NamedObjectContext<Action>
|
||||
{
|
||||
@ -3,7 +3,7 @@
|
||||
|
||||
#include "NamedObjectContext.h"
|
||||
#include "AiObjectContext.h"
|
||||
#include "ANTriggers.h"
|
||||
#include "AzjolNerubTriggers.h"
|
||||
|
||||
class WotlkDungeonANTriggerContext : public NamedObjectContext<Trigger>
|
||||
{
|
||||
@ -1,9 +1,9 @@
|
||||
#include "ANMultipliers.h"
|
||||
#include "ANActions.h"
|
||||
#include "AzjolNerubMultipliers.h"
|
||||
#include "AzjolNerubActions.h"
|
||||
#include "GenericSpellActions.h"
|
||||
#include "ChooseTargetActions.h"
|
||||
#include "MovementActions.h"
|
||||
#include "ANTriggers.h"
|
||||
#include "AzjolNerubTriggers.h"
|
||||
#include "Action.h"
|
||||
|
||||
float KrikthirMultiplier::GetValue(Action* action)
|
||||
@ -1,5 +1,5 @@
|
||||
#include "ANStrategy.h"
|
||||
#include "ANMultipliers.h"
|
||||
#include "AzjolNerubStrategy.h"
|
||||
#include "AzjolNerubMultipliers.h"
|
||||
|
||||
void WotlkDungeonANStrategy::InitTriggers(std::vector<TriggerNode*> &triggers)
|
||||
{
|
||||
@ -1,5 +1,5 @@
|
||||
#include "Playerbots.h"
|
||||
#include "ANTriggers.h"
|
||||
#include "AzjolNerubTriggers.h"
|
||||
#include "AiObject.h"
|
||||
#include "AiObjectContext.h"
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
#include "Playerbots.h"
|
||||
#include "CoSActions.h"
|
||||
#include "CullingOfStratholmeActions.h"
|
||||
|
||||
bool ExplodeGhoulSpreadAction::Execute(Event /*event*/)
|
||||
{
|
||||
@ -6,7 +6,7 @@
|
||||
#include "GenericSpellActions.h"
|
||||
#include "PlayerbotAI.h"
|
||||
#include "Playerbots.h"
|
||||
#include "CoSTriggers.h"
|
||||
#include "CullingOfStratholmeTriggers.h"
|
||||
|
||||
class ExplodeGhoulSpreadAction : public MovementAction
|
||||
{
|
||||
@ -3,7 +3,7 @@
|
||||
|
||||
#include "Action.h"
|
||||
#include "NamedObjectContext.h"
|
||||
#include "CoSActions.h"
|
||||
#include "CullingOfStratholmeActions.h"
|
||||
|
||||
class WotlkDungeonCoSActionContext : public NamedObjectContext<Action>
|
||||
{
|
||||
@ -3,7 +3,7 @@
|
||||
|
||||
#include "NamedObjectContext.h"
|
||||
#include "AiObjectContext.h"
|
||||
#include "CoSTriggers.h"
|
||||
#include "CullingOfStratholmeTriggers.h"
|
||||
|
||||
class WotlkDungeonCoSTriggerContext : public NamedObjectContext<Trigger>
|
||||
{
|
||||
@ -1,9 +1,9 @@
|
||||
#include "CoSMultipliers.h"
|
||||
#include "CoSActions.h"
|
||||
#include "CullingOfStratholmeMultipliers.h"
|
||||
#include "CullingOfStratholmeActions.h"
|
||||
#include "GenericSpellActions.h"
|
||||
#include "ChooseTargetActions.h"
|
||||
#include "MovementActions.h"
|
||||
#include "CoSTriggers.h"
|
||||
#include "CullingOfStratholmeTriggers.h"
|
||||
#include "Action.h"
|
||||
|
||||
float EpochMultiplier::GetValue(Action* action)
|
||||
@ -1,5 +1,5 @@
|
||||
#include "CoSStrategy.h"
|
||||
#include "CoSMultipliers.h"
|
||||
#include "CullingOfStratholmeStrategy.h"
|
||||
#include "CullingOfStratholmeMultipliers.h"
|
||||
|
||||
void WotlkDungeonCoSStrategy::InitTriggers(std::vector<TriggerNode*> &triggers)
|
||||
{
|
||||
@ -1,5 +1,5 @@
|
||||
#include "Playerbots.h"
|
||||
#include "CoSTriggers.h"
|
||||
#include "CullingOfStratholmeTriggers.h"
|
||||
#include "AiObject.h"
|
||||
#include "AiObjectContext.h"
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
#include "Playerbots.h"
|
||||
#include "DTKActions.h"
|
||||
#include "DrakTharonKeepActions.h"
|
||||
|
||||
bool CorpseExplodeSpreadAction::Execute(Event /*event*/)
|
||||
{
|
||||
@ -6,7 +6,7 @@
|
||||
#include "GenericSpellActions.h"
|
||||
#include "PlayerbotAI.h"
|
||||
#include "Playerbots.h"
|
||||
#include "DTKTriggers.h"
|
||||
#include "DrakTharonKeepTriggers.h"
|
||||
|
||||
const Position NOVOS_PARTY_POSITION = Position(-378.852f, -760.349f, 28.587f);
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
|
||||
#include "Action.h"
|
||||
#include "NamedObjectContext.h"
|
||||
#include "DTKActions.h"
|
||||
#include "DrakTharonKeepActions.h"
|
||||
|
||||
class WotlkDungeonDTKActionContext : public NamedObjectContext<Action>
|
||||
{
|
||||
@ -3,7 +3,7 @@
|
||||
|
||||
#include "NamedObjectContext.h"
|
||||
#include "AiObjectContext.h"
|
||||
#include "DTKTriggers.h"
|
||||
#include "DrakTharonKeepTriggers.h"
|
||||
|
||||
class WotlkDungeonDTKTriggerContext : public NamedObjectContext<Trigger>
|
||||
{
|
||||
@ -1,9 +1,9 @@
|
||||
#include "DTKMultipliers.h"
|
||||
#include "DTKActions.h"
|
||||
#include "DrakTharonKeepMultipliers.h"
|
||||
#include "DrakTharonKeepActions.h"
|
||||
#include "GenericSpellActions.h"
|
||||
#include "ChooseTargetActions.h"
|
||||
#include "MovementActions.h"
|
||||
#include "DTKTriggers.h"
|
||||
#include "DrakTharonKeepTriggers.h"
|
||||
#include "Action.h"
|
||||
|
||||
float NovosMultiplier::GetValue(Action* action)
|
||||
@ -1,5 +1,5 @@
|
||||
#include "DTKStrategy.h"
|
||||
#include "DTKMultipliers.h"
|
||||
#include "DrakTharonKeepStrategy.h"
|
||||
#include "DrakTharonKeepMultipliers.h"
|
||||
|
||||
void WotlkDungeonDTKStrategy::InitTriggers(std::vector<TriggerNode*> &triggers)
|
||||
{
|
||||
@ -1,5 +1,5 @@
|
||||
#include "Playerbots.h"
|
||||
#include "DTKTriggers.h"
|
||||
#include "DrakTharonKeepTriggers.h"
|
||||
#include "AiObject.h"
|
||||
#include "AiObjectContext.h"
|
||||
|
||||
@ -2,22 +2,22 @@
|
||||
#define _PLAYERBOT_DUNGEONSTRATEGYCONTEXT_H
|
||||
|
||||
#include "Strategy.h"
|
||||
#include "ACStrategy.h"
|
||||
#include "UKStrategy.h"
|
||||
#include "NexStrategy.h"
|
||||
#include "ANStrategy.h"
|
||||
#include "AKStrategy.h"
|
||||
#include "DTKStrategy.h"
|
||||
#include "VHStrategy.h"
|
||||
#include "GDStrategy.h"
|
||||
#include "HoSStrategy.h"
|
||||
#include "HoLStrategy.h"
|
||||
#include "OCStrategy.h"
|
||||
#include "UPStrategy.h"
|
||||
#include "CoSStrategy.h"
|
||||
#include "FoSStrategy.h"
|
||||
#include "PoSStrategy.h"
|
||||
#include "TOCStrategy.h"
|
||||
#include "AuchenaiCrypts/Strategy/AuchenaiCryptsStrategy.h"
|
||||
#include "UtgardeKeep/Strategy/UtgardeKeepStrategy.h"
|
||||
#include "Nexus/Strategy/NexusStrategy.h"
|
||||
#include "AzjolNerub/Strategy/AzjolNerubStrategy.h"
|
||||
#include "OldKingdom/Strategy/OldKingdomStrategy.h"
|
||||
#include "DraktharonKeep/Strategy/DrakTharonKeepStrategy.h"
|
||||
#include "VioletHold/Strategy/VioletHoldStrategy.h"
|
||||
#include "Gundrak/Strategy/GundrakStrategy.h"
|
||||
#include "HallsOfStone/Strategy/HallsOfStoneStrategy.h"
|
||||
#include "HallsOfLightning/Strategy/HallsOfLightningStrategy.h"
|
||||
#include "Oculus/Strategy/OculusStrategy.h"
|
||||
#include "UtgardePinnacle/Strategy/UtgardePinnacleStrategy.h"
|
||||
#include "CullingOfStratholme/Strategy/CullingOfStratholmeStrategy.h"
|
||||
#include "ForgeOfSouls/Strategy/ForgeOfSoulsStrategy.h"
|
||||
#include "PitOfSaron/Strategy/PitOfSaronStrategy.h"
|
||||
#include "TrialOfTheChampion/Strategy/TrialOfTheChampionStrategy.h"
|
||||
|
||||
/*
|
||||
Full list/TODO:
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
#include "Playerbots.h"
|
||||
#include "FoSActions.h"
|
||||
#include "ForgeOfSoulsActions.h"
|
||||
|
||||
bool MoveFromBronjahmAction::Execute(Event /*event*/)
|
||||
{
|
||||
@ -5,7 +5,7 @@
|
||||
#include "AttackAction.h"
|
||||
#include "PlayerbotAI.h"
|
||||
#include "Playerbots.h"
|
||||
#include "FoSTriggers.h"
|
||||
#include "ForgeOfSoulsTriggers.h"
|
||||
|
||||
const Position BRONJAHM_TANK_POSITION = Position(5297.920f, 2506.698f, 686.068f);
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
|
||||
#include "Action.h"
|
||||
#include "NamedObjectContext.h"
|
||||
#include "FoSActions.h"
|
||||
#include "ForgeOfSoulsActions.h"
|
||||
|
||||
class WotlkDungeonFoSActionContext : public NamedObjectContext<Action>
|
||||
{
|
||||
@ -3,7 +3,7 @@
|
||||
|
||||
#include "NamedObjectContext.h"
|
||||
#include "AiObjectContext.h"
|
||||
#include "FoSTriggers.h"
|
||||
#include "ForgeOfSoulsTriggers.h"
|
||||
|
||||
class WotlkDungeonFoSTriggerContext : public NamedObjectContext<Trigger>
|
||||
{
|
||||
@ -1,10 +1,10 @@
|
||||
#include "FoSMultipliers.h"
|
||||
#include "FoSActions.h"
|
||||
#include "ForgeOfSoulsMultipliers.h"
|
||||
#include "ForgeOfSoulsActions.h"
|
||||
#include "GenericSpellActions.h"
|
||||
#include "ChooseTargetActions.h"
|
||||
#include "MovementActions.h"
|
||||
#include "FoSTriggers.h"
|
||||
#include "FoSActions.h"
|
||||
#include "ForgeOfSoulsTriggers.h"
|
||||
#include "ForgeOfSoulsActions.h"
|
||||
|
||||
float BronjahmMultiplier::GetValue(Action* action) {
|
||||
Unit* boss = AI_VALUE2(Unit *, "find target", "bronjahm");
|
||||
@ -1,5 +1,5 @@
|
||||
#include "FoSStrategy.h"
|
||||
#include "FoSMultipliers.h"
|
||||
#include "ForgeOfSoulsStrategy.h"
|
||||
#include "ForgeOfSoulsMultipliers.h"
|
||||
|
||||
void WotlkDungeonFoSStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
|
||||
{
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user