mirror of
https://github.com/mod-playerbots/mod-playerbots.git
synced 2026-01-24 05:56:23 +00:00
Merge branch 'master' into Tame-Chat-Action-/-Pet-Chat-Action-(stances/commands)
This commit is contained in:
@@ -38,6 +38,7 @@
|
||||
#include "InviteToGroupAction.h"
|
||||
#include "LeaveGroupAction.h"
|
||||
#include "LootAction.h"
|
||||
#include "LootRollAction.h"
|
||||
#include "MoveToRpgTargetAction.h"
|
||||
#include "MoveToTravelTargetAction.h"
|
||||
#include "MovementActions.h"
|
||||
@@ -190,6 +191,7 @@ public:
|
||||
creators["buy tabard"] = &ActionContext::buy_tabard;
|
||||
creators["guild manage nearby"] = &ActionContext::guild_manage_nearby;
|
||||
creators["clean quest log"] = &ActionContext::clean_quest_log;
|
||||
creators["roll"] = &ActionContext::roll_action;
|
||||
creators["cancel channel"] = &ActionContext::cancel_channel;
|
||||
|
||||
// BG Tactics
|
||||
@@ -378,6 +380,7 @@ private:
|
||||
static Action* buy_tabard(PlayerbotAI* botAI) { return new BuyTabardAction(botAI); }
|
||||
static Action* guild_manage_nearby(PlayerbotAI* botAI) { return new GuildManageNearbyAction(botAI); }
|
||||
static Action* clean_quest_log(PlayerbotAI* botAI) { return new CleanQuestLogAction(botAI); }
|
||||
static Action* roll_action(PlayerbotAI* botAI) { return new RollAction(botAI); }
|
||||
|
||||
// BG Tactics
|
||||
static Action* bg_tactics(PlayerbotAI* botAI) { return new BGTactics(botAI); }
|
||||
|
||||
@@ -157,16 +157,23 @@ void AutoMaintenanceOnLevelupAction::LearnSpell(uint32 spellId, std::ostringstre
|
||||
void AutoMaintenanceOnLevelupAction::AutoUpgradeEquip()
|
||||
{
|
||||
if (!sPlayerbotAIConfig->autoUpgradeEquip || !sRandomPlayerbotMgr->IsRandomBot(bot))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
PlayerbotFactory factory(bot, bot->GetLevel());
|
||||
|
||||
// Clean up old consumables before adding new ones
|
||||
factory.CleanupConsumables();
|
||||
|
||||
factory.InitAmmo();
|
||||
factory.InitReagents();
|
||||
factory.InitFood();
|
||||
factory.InitConsumables();
|
||||
factory.InitPotions();
|
||||
|
||||
if (!sPlayerbotAIConfig->equipmentPersistence || bot->GetLevel() < sPlayerbotAIConfig->equipmentPersistenceLevel)
|
||||
{
|
||||
if (sPlayerbotAIConfig->incrementalGearInit)
|
||||
factory.InitEquipment(true);
|
||||
}
|
||||
factory.InitAmmo();
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -50,3 +50,16 @@ bool BossNatureResistanceAction::Execute(Event event)
|
||||
botAI->ChangeStrategy(ADD_STRATEGY_CHAR + hunterNatureResistanceStrategy.getName(), BotState::BOT_STATE_COMBAT);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool BossShadowResistanceAction::isUseful()
|
||||
{
|
||||
BossShadowResistanceTrigger bossShadowResistanceTrigger(botAI, bossName);
|
||||
return bossShadowResistanceTrigger.IsActive();
|
||||
}
|
||||
|
||||
bool BossShadowResistanceAction::Execute(Event event)
|
||||
{
|
||||
PaladinShadowResistanceStrategy paladinShadowResistanceStrategy(botAI);
|
||||
botAI->ChangeStrategy(ADD_STRATEGY_CHAR + paladinShadowResistanceStrategy.getName(), BotState::BOT_STATE_COMBAT);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -54,4 +54,18 @@ private:
|
||||
std::string bossName;
|
||||
};
|
||||
|
||||
class BossShadowResistanceAction : public Action
|
||||
{
|
||||
public:
|
||||
BossShadowResistanceAction(PlayerbotAI* botAI, std::string const bossName)
|
||||
: Action(botAI, bossName + " shadow resistance action"), bossName(bossName)
|
||||
{
|
||||
}
|
||||
bool Execute(Event event) override;
|
||||
bool isUseful() override;
|
||||
|
||||
private:
|
||||
std::string bossName;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -36,6 +36,7 @@
|
||||
#include "ListSpellsAction.h"
|
||||
#include "LogLevelAction.h"
|
||||
#include "LootStrategyAction.h"
|
||||
#include "LootRollAction.h"
|
||||
#include "MailAction.h"
|
||||
#include "NamedObjectContext.h"
|
||||
#include "NewRpgAction.h"
|
||||
@@ -192,10 +193,11 @@ public:
|
||||
creators["calc"] = &ChatActionContext::calc;
|
||||
creators["wipe"] = &ChatActionContext::wipe;
|
||||
creators["tame"] = &ChatActionContext::tame;
|
||||
creators["glyphs"] = &ChatActionContext::glyphs; // Added for custom Glyphs
|
||||
creators["glyph equip"] = &ChatActionContext::glyph_equip; // Added for custom Glyphs
|
||||
creators["glyphs"] = &ChatActionContext::glyphs; // Added for custom Glyphs
|
||||
creators["glyph equip"] = &ChatActionContext::glyph_equip; // Added for custom Glyphs
|
||||
creators["pet"] = &ChatActionContext::pet;
|
||||
creators["pet attack"] = &ChatActionContext::pet_attack;
|
||||
creators["roll"] = &ChatActionContext::roll_action;
|
||||
}
|
||||
|
||||
private:
|
||||
@@ -303,10 +305,11 @@ private:
|
||||
static Action* calc(PlayerbotAI* ai) { return new TellCalculateItemAction(ai); }
|
||||
static Action* wipe(PlayerbotAI* ai) { return new WipeAction(ai); }
|
||||
static Action* tame(PlayerbotAI* botAI) { return new TameAction(botAI); }
|
||||
static Action* glyphs(PlayerbotAI* botAI) { return new TellGlyphsAction(botAI); } // Added for custom Glyphs
|
||||
static Action* glyph_equip(PlayerbotAI* ai) { return new EquipGlyphsAction(ai); } // Added for custom Glyphs
|
||||
static Action* glyphs(PlayerbotAI* botAI) { return new TellGlyphsAction(botAI); } // Added for custom Glyphs
|
||||
static Action* glyph_equip(PlayerbotAI* ai) { return new EquipGlyphsAction(ai); } // Added for custom Glyphs
|
||||
static Action* pet(PlayerbotAI* botAI) { return new PetAction(botAI); }
|
||||
static Action* pet_attack(PlayerbotAI* botAI) { return new PetAction(botAI, "attack"); }
|
||||
static Action* roll_action(PlayerbotAI* botAI) { return new RollAction(botAI); }
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -19,22 +19,51 @@ bool ImbueWithPoisonAction::Execute(Event event)
|
||||
if (bot->HasAura(SPELL_AURA_MOD_STEALTH))
|
||||
bot->RemoveAurasByType(SPELL_AURA_MOD_STEALTH);
|
||||
|
||||
// hp check
|
||||
if (bot->getStandState() != UNIT_STAND_STATE_STAND)
|
||||
bot->SetStandState(UNIT_STAND_STATE_STAND);
|
||||
|
||||
// Search and apply poison to weapons
|
||||
// Mainhand ...
|
||||
static const std::vector<uint32_t> prioritizedInstantPoisons = {
|
||||
INSTANT_POISON_IX, INSTANT_POISON_VIII, INSTANT_POISON_VII, INSTANT_POISON_VI, INSTANT_POISON_V, INSTANT_POISON_IV,
|
||||
INSTANT_POISON_III, INSTANT_POISON_II, INSTANT_POISON
|
||||
};
|
||||
|
||||
static const std::vector<uint32_t> prioritizedDeadlyPoisons = {
|
||||
DEADLY_POISON_IX, DEADLY_POISON_VIII, DEADLY_POISON_VII, DEADLY_POISON_VI, DEADLY_POISON_V, DEADLY_POISON_IV,
|
||||
DEADLY_POISON_III, DEADLY_POISON_II, DEADLY_POISON
|
||||
};
|
||||
|
||||
// Check if we have any deadly or instant poisons
|
||||
Item* deadlyPoison = nullptr;
|
||||
for (auto id : prioritizedDeadlyPoisons)
|
||||
{
|
||||
deadlyPoison = botAI->FindConsumable(id);
|
||||
if (deadlyPoison) break;
|
||||
}
|
||||
|
||||
Item* instantPoison = nullptr;
|
||||
for (auto id : prioritizedInstantPoisons)
|
||||
{
|
||||
instantPoison = botAI->FindConsumable(id);
|
||||
if (instantPoison) break;
|
||||
}
|
||||
|
||||
// Mainhand
|
||||
Item* poison = nullptr;
|
||||
Item* weapon = bot->GetItemByPos(INVENTORY_SLOT_BAG_0, EQUIPMENT_SLOT_MAINHAND);
|
||||
if (weapon && weapon->GetEnchantmentId(TEMP_ENCHANTMENT_SLOT) == 0)
|
||||
{
|
||||
poison = botAI->FindConsumable(INSTANT_POISON_DISPLAYID);
|
||||
if (!poison)
|
||||
poison = botAI->FindConsumable(DEADLY_POISON_DISPLAYID);
|
||||
|
||||
if (!poison)
|
||||
poison = botAI->FindConsumable(WOUND_POISON_DISPLAYID);
|
||||
if (instantPoison && deadlyPoison)
|
||||
{
|
||||
poison = instantPoison;
|
||||
}
|
||||
else if (deadlyPoison)
|
||||
{
|
||||
poison = deadlyPoison;
|
||||
}
|
||||
else if (instantPoison)
|
||||
{
|
||||
poison = instantPoison;
|
||||
}
|
||||
|
||||
if (poison)
|
||||
{
|
||||
@@ -43,16 +72,23 @@ bool ImbueWithPoisonAction::Execute(Event event)
|
||||
}
|
||||
}
|
||||
|
||||
//... and offhand
|
||||
// Offhand
|
||||
poison = nullptr;
|
||||
weapon = bot->GetItemByPos(INVENTORY_SLOT_BAG_0, EQUIPMENT_SLOT_OFFHAND);
|
||||
if (weapon && weapon->GetEnchantmentId(TEMP_ENCHANTMENT_SLOT) == 0)
|
||||
{
|
||||
poison = botAI->FindConsumable(DEADLY_POISON_DISPLAYID);
|
||||
if (!poison)
|
||||
poison = botAI->FindConsumable(WOUND_POISON_DISPLAYID);
|
||||
|
||||
if (!poison)
|
||||
poison = botAI->FindConsumable(INSTANT_POISON_DISPLAYID);
|
||||
if (deadlyPoison && instantPoison)
|
||||
{
|
||||
poison = deadlyPoison;
|
||||
}
|
||||
else if (instantPoison)
|
||||
{
|
||||
poison = instantPoison;
|
||||
}
|
||||
else if (deadlyPoison)
|
||||
{
|
||||
poison = deadlyPoison;
|
||||
}
|
||||
|
||||
if (poison)
|
||||
{
|
||||
@@ -141,8 +177,8 @@ bool ImbueWithOilAction::Execute(Event event)
|
||||
return true;
|
||||
}
|
||||
|
||||
static const uint32 uPriorizedHealingItemIds[19] = {
|
||||
HEALTHSTONE_DISPLAYID,
|
||||
static const uint32 uPrioritizedHealingItemIds[19] = {
|
||||
HEALTHSTONE,
|
||||
FEL_REGENERATION_POTION,
|
||||
SUPER_HEALING_POTION,
|
||||
CRYSTAL_HEALING_POTION,
|
||||
@@ -182,9 +218,9 @@ bool TryEmergencyAction::Execute(Event event)
|
||||
}
|
||||
|
||||
// Else loop over the list of health consumable to pick one
|
||||
for (uint8 i = 0; i < std::size(uPriorizedHealingItemIds); ++i)
|
||||
for (uint8 i = 0; i < std::size(uPrioritizedHealingItemIds); ++i)
|
||||
{
|
||||
if (Item* healthItem = botAI->FindConsumable(uPriorizedHealingItemIds[i]))
|
||||
if (Item* healthItem = botAI->FindConsumable(uPrioritizedHealingItemIds[i]))
|
||||
{
|
||||
botAI->ImbueItem(healthItem);
|
||||
}
|
||||
|
||||
@@ -224,3 +224,37 @@ bool RollUniqueCheck(ItemTemplate const* proto, Player* bot)
|
||||
}
|
||||
return false; // Item is not equipped or in bags, roll for it
|
||||
}
|
||||
|
||||
bool RollAction::Execute(Event event)
|
||||
{
|
||||
std::string link = event.getParam();
|
||||
|
||||
if (link.empty())
|
||||
{
|
||||
bot->DoRandomRoll(0,100);
|
||||
return false;
|
||||
}
|
||||
ItemIds itemIds = chat->parseItems(link);
|
||||
if (itemIds.empty())
|
||||
return false;
|
||||
uint32 itemId = *itemIds.begin();
|
||||
ItemTemplate const* proto = sObjectMgr->GetItemTemplate(itemId);
|
||||
if (!proto)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
std::string itemUsageParam;
|
||||
itemUsageParam = std::to_string(itemId);
|
||||
|
||||
ItemUsage usage = AI_VALUE2(ItemUsage, "item usage", itemUsageParam);
|
||||
switch (proto->Class)
|
||||
{
|
||||
case ITEM_CLASS_WEAPON:
|
||||
case ITEM_CLASS_ARMOR:
|
||||
if (usage == ITEM_USAGE_EQUIP || usage == ITEM_USAGE_REPLACE || usage == ITEM_USAGE_BAD_EQUIP)
|
||||
{
|
||||
bot->DoRandomRoll(0,100);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -37,4 +37,12 @@ public:
|
||||
bool Execute(Event event) override;
|
||||
};
|
||||
|
||||
class RollAction : public Action
|
||||
{
|
||||
public:
|
||||
RollAction(PlayerbotAI* botAI) : Action(botAI, "roll") {}
|
||||
|
||||
bool Execute(Event event) override;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -175,6 +175,8 @@ bool MaintenanceAction::Execute(Event event)
|
||||
factory.InitAmmo();
|
||||
factory.InitFood();
|
||||
factory.InitReagents();
|
||||
factory.InitConsumables();
|
||||
factory.InitPotions();
|
||||
factory.InitTalentsTree(true);
|
||||
factory.InitPet();
|
||||
factory.InitPetTalents();
|
||||
@@ -186,7 +188,6 @@ bool MaintenanceAction::Execute(Event event)
|
||||
factory.InitMounts();
|
||||
factory.InitGlyphs(false);
|
||||
factory.InitKeyring();
|
||||
factory.InitPotions();
|
||||
if (bot->GetLevel() >= sPlayerbotAIConfig->minEnchantingBotLevel)
|
||||
factory.ApplyEnchantAndGemsNew();
|
||||
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
#include "GenericDruidNonCombatStrategy.h"
|
||||
|
||||
#include "Playerbots.h"
|
||||
#include "AiFactory.h"
|
||||
|
||||
class GenericDruidNonCombatStrategyActionNodeFactory : public NamedObjectFactory<ActionNode>
|
||||
{
|
||||
@@ -109,18 +110,16 @@ void GenericDruidNonCombatStrategy::InitTriggers(std::vector<TriggerNode*>& trig
|
||||
{
|
||||
NonCombatStrategy::InitTriggers(triggers);
|
||||
|
||||
triggers.push_back(
|
||||
new TriggerNode("mark of the wild", NextAction::array(0, new NextAction("mark of the wild", 14.0f), nullptr)));
|
||||
triggers.push_back(new TriggerNode("mark of the wild", NextAction::array(0, new NextAction("mark of the wild", 14.0f), nullptr)));
|
||||
// triggers.push_back(new TriggerNode("thorns", NextAction::array(0, new NextAction("thorns", 12.0f), nullptr)));
|
||||
// triggers.push_back(new TriggerNode("cure poison", NextAction::array(0, new NextAction("abolish poison", 21.0f),
|
||||
// nullptr)));
|
||||
triggers.push_back(new TriggerNode(
|
||||
"party member cure poison", NextAction::array(0, new NextAction("abolish poison on party", 20.0f), nullptr)));
|
||||
triggers.push_back(new TriggerNode(
|
||||
"party member dead", NextAction::array(0, new NextAction("revive", ACTION_CRITICAL_HEAL + 10), nullptr)));
|
||||
triggers.push_back(new TriggerNode("party member cure poison", NextAction::array(0, new NextAction("abolish poison on party", 20.0f), nullptr)));
|
||||
triggers.push_back(new TriggerNode("party member dead", NextAction::array(0, new NextAction("revive", ACTION_CRITICAL_HEAL + 10), nullptr)));
|
||||
// triggers.push_back(new TriggerNode("low mana", NextAction::array(0, new NextAction("innervate", ACTION_EMERGENCY
|
||||
// + 5), nullptr))); triggers.push_back(new TriggerNode("swimming", NextAction::array(0, new NextAction("aquatic
|
||||
// form", 1.0f), nullptr)));
|
||||
|
||||
triggers.push_back(new TriggerNode("often", NextAction::array(0, new NextAction("apply oil", 1.0f), nullptr)));
|
||||
|
||||
triggers.push_back(
|
||||
@@ -155,6 +154,36 @@ void GenericDruidNonCombatStrategy::InitTriggers(std::vector<TriggerNode*>& trig
|
||||
NextAction::array(0, new NextAction("remove curse on party", ACTION_DISPEL + 7), nullptr)));
|
||||
triggers.push_back(
|
||||
new TriggerNode("new pet", NextAction::array(0, new NextAction("set pet stance", 60.0f), nullptr)));
|
||||
|
||||
triggers.push_back(new TriggerNode("party member critical health", NextAction::array(0,
|
||||
new NextAction("wild growth on party", ACTION_MEDIUM_HEAL + 7),
|
||||
new NextAction("regrowth on party", ACTION_MEDIUM_HEAL + 6),
|
||||
new NextAction("rejuvenation on party", ACTION_MEDIUM_HEAL + 5),
|
||||
nullptr)));
|
||||
triggers.push_back(new TriggerNode("party member low health", NextAction::array(0,
|
||||
new NextAction("wild growth on party", ACTION_MEDIUM_HEAL + 5),
|
||||
new NextAction("regrowth on party", ACTION_MEDIUM_HEAL + 4),
|
||||
new NextAction("rejuvenation on party", ACTION_MEDIUM_HEAL + 3),
|
||||
nullptr)));
|
||||
triggers.push_back(new TriggerNode("party member medium health", NextAction::array(0,
|
||||
new NextAction("wild growth on party", ACTION_MEDIUM_HEAL + 3),
|
||||
new NextAction("regrowth on party", ACTION_MEDIUM_HEAL + 2),
|
||||
new NextAction("rejuvenation on party", ACTION_MEDIUM_HEAL + 1),
|
||||
nullptr)));
|
||||
triggers.push_back(new TriggerNode("party member almost full health", NextAction::array(0,
|
||||
new NextAction("wild growth on party", ACTION_LIGHT_HEAL + 3),
|
||||
new NextAction("rejuvenation on party", ACTION_LIGHT_HEAL + 2),
|
||||
nullptr)));
|
||||
triggers.push_back(new TriggerNode("party member remove curse", NextAction::array(0,
|
||||
new NextAction("remove curse on party", ACTION_DISPEL + 7),
|
||||
nullptr)));
|
||||
|
||||
int specTab = AiFactory::GetPlayerSpecTab(botAI->GetBot());
|
||||
if (specTab == 0 || specTab == 2) // Balance or Restoration
|
||||
triggers.push_back(new TriggerNode("often", NextAction::array(0, new NextAction("apply oil", 1.0f), nullptr)));
|
||||
if (specTab == 1) // Feral
|
||||
triggers.push_back(new TriggerNode("often", NextAction::array(0, new NextAction("apply stone", 1.0f), nullptr)));
|
||||
|
||||
}
|
||||
|
||||
GenericDruidBuffStrategy::GenericDruidBuffStrategy(PlayerbotAI* botAI) : NonCombatStrategy(botAI)
|
||||
@@ -166,11 +195,13 @@ void GenericDruidBuffStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
|
||||
{
|
||||
NonCombatStrategy::InitTriggers(triggers);
|
||||
|
||||
triggers.push_back(
|
||||
new TriggerNode("mark of the wild on party",
|
||||
NextAction::array(0, new NextAction("mark of the wild on party", 13.0f), nullptr)));
|
||||
triggers.push_back(new TriggerNode("thorns on main tank",
|
||||
NextAction::array(0, new NextAction("thorns on main tank", 11.0f), nullptr)));
|
||||
triggers.push_back(new TriggerNode("thorns",
|
||||
NextAction::array(0, new NextAction("thorns", 10.0f), nullptr)));
|
||||
triggers.push_back(new TriggerNode("mark of the wild on party", NextAction::array(0,
|
||||
new NextAction("mark of the wild on party", 13.0f),
|
||||
nullptr)));
|
||||
triggers.push_back(new TriggerNode("thorns on main tank", NextAction::array(0,
|
||||
new NextAction("thorns on main tank", 11.0f),
|
||||
nullptr)));
|
||||
triggers.push_back(new TriggerNode("thorns", NextAction::array(0,
|
||||
new NextAction("thorns", 10.0f),
|
||||
nullptr)));
|
||||
}
|
||||
|
||||
@@ -107,6 +107,7 @@ void ChatCommandHandlerStrategy::InitTriggers(std::vector<TriggerNode*>& trigger
|
||||
triggers.push_back(new TriggerNode("glyph equip", NextAction::array(0, new NextAction("glyph equip", relevance), nullptr))); // Added for custom Glyphs
|
||||
triggers.push_back(new TriggerNode("pet", NextAction::array(0, new NextAction("pet", relevance), nullptr)));
|
||||
triggers.push_back(new TriggerNode("pet attack", NextAction::array(0, new NextAction("pet attack", relevance), nullptr)));
|
||||
triggers.push_back(new TriggerNode("roll", NextAction::array(0, new NextAction("roll", relevance), nullptr)));
|
||||
}
|
||||
|
||||
ChatCommandHandlerStrategy::ChatCommandHandlerStrategy(PlayerbotAI* botAI) : PassTroughStrategy(botAI)
|
||||
|
||||
@@ -44,15 +44,14 @@ void GenericHunterNonCombatStrategy::InitTriggers(std::vector<TriggerNode*>& tri
|
||||
{
|
||||
NonCombatStrategy::InitTriggers(triggers);
|
||||
|
||||
triggers.push_back(
|
||||
new TriggerNode("trueshot aura", NextAction::array(0, new NextAction("trueshot aura", 2.0f), nullptr)));
|
||||
triggers.push_back(new TriggerNode("often", NextAction::array(0, new NextAction("apply oil", 1.0f), nullptr)));
|
||||
triggers.push_back(
|
||||
new TriggerNode("low ammo", NextAction::array(0, new NextAction("say::low ammo", ACTION_NORMAL), nullptr)));
|
||||
triggers.push_back(
|
||||
new TriggerNode("no track", NextAction::array(0, new NextAction("track humanoids", ACTION_NORMAL), nullptr)));
|
||||
triggers.push_back(new TriggerNode("no ammo",
|
||||
NextAction::array(0, new NextAction("equip upgrades", ACTION_HIGH + 1), nullptr)));
|
||||
triggers.push_back(new TriggerNode("trueshot aura", NextAction::array(0, new NextAction("trueshot aura", 2.0f), nullptr)));
|
||||
triggers.push_back(new TriggerNode("often", NextAction::array(0,
|
||||
new NextAction("apply stone", 1.0f),
|
||||
new NextAction("apply oil", 1.0f),
|
||||
nullptr)));
|
||||
triggers.push_back(new TriggerNode("low ammo", NextAction::array(0, new NextAction("say::low ammo", ACTION_NORMAL), nullptr)));
|
||||
triggers.push_back(new TriggerNode("no track", NextAction::array(0, new NextAction("track humanoids", ACTION_NORMAL), nullptr)));
|
||||
triggers.push_back(new TriggerNode("no ammo", NextAction::array(0, new NextAction("equip upgrades", ACTION_HIGH + 1), nullptr)));
|
||||
// triggers.push_back(new TriggerNode("no ammo", NextAction::array(0, new NextAction("switch to melee",
|
||||
// ACTION_NORMAL + 1), new NextAction("say::no ammo", ACTION_NORMAL), nullptr))); triggers.push_back(new
|
||||
// TriggerNode("has ammo", NextAction::array(0, new NextAction("switch to ranged", ACTION_NORMAL), nullptr)));
|
||||
@@ -61,14 +60,9 @@ void GenericHunterNonCombatStrategy::InitTriggers(std::vector<TriggerNode*>& tri
|
||||
void HunterPetStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
|
||||
{
|
||||
triggers.push_back(new TriggerNode("no pet", NextAction::array(0, new NextAction("call pet", 60.0f), nullptr)));
|
||||
triggers.push_back(
|
||||
new TriggerNode("has pet", NextAction::array(0, new NextAction("toggle pet spell", 60.0f), nullptr)));
|
||||
triggers.push_back(
|
||||
new TriggerNode("new pet", NextAction::array(0, new NextAction("set pet stance", 60.0f), nullptr)));
|
||||
triggers.push_back(
|
||||
new TriggerNode("pet not happy", NextAction::array(0, new NextAction("feed pet", 60.0f), nullptr)));
|
||||
triggers.push_back(
|
||||
new TriggerNode("hunters pet medium health", NextAction::array(0, new NextAction("mend pet", 60.0f), nullptr)));
|
||||
triggers.push_back(
|
||||
new TriggerNode("hunters pet dead", NextAction::array(0, new NextAction("revive pet", 60.0f), nullptr)));
|
||||
triggers.push_back(new TriggerNode("has pet", NextAction::array(0, new NextAction("toggle pet spell", 60.0f), nullptr)));
|
||||
triggers.push_back(new TriggerNode("new pet", NextAction::array(0, new NextAction("set pet stance", 60.0f), nullptr)));
|
||||
triggers.push_back(new TriggerNode("pet not happy", NextAction::array(0, new NextAction("feed pet", 60.0f), nullptr)));
|
||||
triggers.push_back(new TriggerNode("hunters pet medium health", NextAction::array(0, new NextAction("mend pet", 60.0f), nullptr)));
|
||||
triggers.push_back(new TriggerNode("hunters pet dead", NextAction::array(0, new NextAction("revive pet", 60.0f), nullptr)));
|
||||
}
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
|
||||
#include "GenericPaladinStrategyActionNodeFactory.h"
|
||||
#include "Playerbots.h"
|
||||
#include "AiFactory.h"
|
||||
|
||||
GenericPaladinNonCombatStrategy::GenericPaladinNonCombatStrategy(PlayerbotAI* botAI) : NonCombatStrategy(botAI)
|
||||
{
|
||||
@@ -17,14 +18,15 @@ void GenericPaladinNonCombatStrategy::InitTriggers(std::vector<TriggerNode*>& tr
|
||||
{
|
||||
NonCombatStrategy::InitTriggers(triggers);
|
||||
|
||||
triggers.push_back(new TriggerNode(
|
||||
"party member dead", NextAction::array(0, new NextAction("redemption", ACTION_CRITICAL_HEAL + 10), nullptr)));
|
||||
triggers.push_back(new TriggerNode("party member almost full health",
|
||||
NextAction::array(0, new NextAction("flash of light on party", 25.0f), NULL)));
|
||||
triggers.push_back(new TriggerNode("party member medium health",
|
||||
NextAction::array(0, new NextAction("flash of light on party", 26.0f), NULL)));
|
||||
triggers.push_back(new TriggerNode("party member low health",
|
||||
NextAction::array(0, new NextAction("holy light on party", 27.0f), NULL)));
|
||||
triggers.push_back(new TriggerNode("party member critical health",
|
||||
NextAction::array(0, new NextAction("holy light on party", 28.0f), NULL)));
|
||||
triggers.push_back(new TriggerNode("party member dead", NextAction::array(0, new NextAction("redemption", ACTION_CRITICAL_HEAL + 10), nullptr)));
|
||||
triggers.push_back(new TriggerNode("party member almost full health", NextAction::array(0, new NextAction("flash of light on party", 25.0f), nullptr)));
|
||||
triggers.push_back(new TriggerNode("party member medium health", NextAction::array(0, new NextAction("flash of light on party", 26.0f), nullptr)));
|
||||
triggers.push_back(new TriggerNode("party member low health", NextAction::array(0, new NextAction("holy light on party", 27.0f), nullptr)));
|
||||
triggers.push_back(new TriggerNode("party member critical health", NextAction::array(0, new NextAction("holy light on party", 28.0f), nullptr)));
|
||||
|
||||
int specTab = AiFactory::GetPlayerSpecTab(botAI->GetBot());
|
||||
if (specTab == 0 || specTab == 1) // Holy or Protection
|
||||
triggers.push_back(new TriggerNode("often", NextAction::array(0, new NextAction("apply oil", 1.0f), nullptr)));
|
||||
if (specTab == 2) // Retribution
|
||||
triggers.push_back(new TriggerNode("often", NextAction::array(0, new NextAction("apply stone", 1.0f), nullptr)));
|
||||
}
|
||||
|
||||
@@ -240,6 +240,21 @@ void RaidUlduarStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
|
||||
triggers.push_back(new TriggerNode(
|
||||
"vezax mark of the faceless trigger",
|
||||
NextAction::array(0, new NextAction("vezax mark of the faceless action", ACTION_RAID), nullptr)));
|
||||
|
||||
triggers.push_back(new TriggerNode(
|
||||
"vezax shadow resistance trigger",
|
||||
NextAction::array(0, new NextAction("vezax shadow resistance action", ACTION_RAID), nullptr)));
|
||||
|
||||
//
|
||||
// Yogg-Saron
|
||||
//
|
||||
triggers.push_back(new TriggerNode(
|
||||
"sara shadow resistance trigger",
|
||||
NextAction::array(0, new NextAction("sara shadow resistance action", ACTION_RAID), nullptr)));
|
||||
|
||||
triggers.push_back(new TriggerNode(
|
||||
"yogg-saron shadow resistance trigger",
|
||||
NextAction::array(0, new NextAction("yogg-saron shadow resistance action", ACTION_RAID), nullptr)));
|
||||
}
|
||||
|
||||
void RaidUlduarStrategy::InitMultipliers(std::vector<Multiplier*>& multipliers)
|
||||
|
||||
@@ -23,7 +23,9 @@ bool BossFireResistanceTrigger::IsActive()
|
||||
return false;
|
||||
|
||||
// Check if bot have fire resistance aura
|
||||
if (bot->HasAura(SPELL_FIRE_RESISTANCE_AURA))
|
||||
if (bot->HasAura(SPELL_FIRE_RESISTANCE_AURA_RANK_5) || bot->HasAura(SPELL_FIRE_RESISTANCE_AURA_RANK_4) ||
|
||||
bot->HasAura(SPELL_FIRE_RESISTANCE_AURA_RANK_3) || bot->HasAura(SPELL_FIRE_RESISTANCE_AURA_RANK_2) ||
|
||||
bot->HasAura(SPELL_FIRE_RESISTANCE_AURA_RANK_1))
|
||||
return false;
|
||||
|
||||
// Check if bot dont have already have fire resistance strategy
|
||||
@@ -32,7 +34,11 @@ bool BossFireResistanceTrigger::IsActive()
|
||||
return false;
|
||||
|
||||
// Check that the bot actually knows the spell
|
||||
if (!bot->HasActiveSpell(SPELL_FIRE_RESISTANCE_AURA))
|
||||
if (!bot->HasActiveSpell(SPELL_FIRE_RESISTANCE_AURA_RANK_5) &&
|
||||
!bot->HasActiveSpell(SPELL_FIRE_RESISTANCE_AURA_RANK_4) &&
|
||||
!bot->HasActiveSpell(SPELL_FIRE_RESISTANCE_AURA_RANK_3) &&
|
||||
!bot->HasActiveSpell(SPELL_FIRE_RESISTANCE_AURA_RANK_2) &&
|
||||
!bot->HasActiveSpell(SPELL_FIRE_RESISTANCE_AURA_RANK_1))
|
||||
return false;
|
||||
|
||||
// Get the group and ensure it's a raid group
|
||||
@@ -47,7 +53,7 @@ bool BossFireResistanceTrigger::IsActive()
|
||||
if (!member || !member->IsAlive())
|
||||
continue;
|
||||
|
||||
// Check if the member is a hunter
|
||||
// Check if the member is a paladin
|
||||
if (member->getClass() == CLASS_PALADIN)
|
||||
{
|
||||
// Return true only if the current bot is the first alive paladin
|
||||
@@ -70,7 +76,9 @@ bool BossFrostResistanceTrigger::IsActive()
|
||||
return false;
|
||||
|
||||
// Check if bot have frost resistance aura
|
||||
if (bot->HasAura(SPELL_FROST_RESISTANCE_AURA))
|
||||
if (bot->HasAura(SPELL_FROST_RESISTANCE_AURA_RANK_5) || bot->HasAura(SPELL_FROST_RESISTANCE_AURA_RANK_4) ||
|
||||
bot->HasAura(SPELL_FROST_RESISTANCE_AURA_RANK_3) || bot->HasAura(SPELL_FROST_RESISTANCE_AURA_RANK_2) ||
|
||||
bot->HasAura(SPELL_FROST_RESISTANCE_AURA_RANK_1))
|
||||
return false;
|
||||
|
||||
// Check if bot dont have already have frost resistance strategy
|
||||
@@ -79,7 +87,11 @@ bool BossFrostResistanceTrigger::IsActive()
|
||||
return false;
|
||||
|
||||
// Check that the bot actually knows the spell
|
||||
if (!bot->HasActiveSpell(SPELL_FROST_RESISTANCE_AURA))
|
||||
if (!bot->HasActiveSpell(SPELL_FROST_RESISTANCE_AURA_RANK_5) &&
|
||||
!bot->HasActiveSpell(SPELL_FROST_RESISTANCE_AURA_RANK_4) &&
|
||||
!bot->HasActiveSpell(SPELL_FROST_RESISTANCE_AURA_RANK_3) &&
|
||||
!bot->HasActiveSpell(SPELL_FROST_RESISTANCE_AURA_RANK_2) &&
|
||||
!bot->HasActiveSpell(SPELL_FROST_RESISTANCE_AURA_RANK_1))
|
||||
return false;
|
||||
|
||||
// Get the group and ensure it's a raid group
|
||||
@@ -94,7 +106,7 @@ bool BossFrostResistanceTrigger::IsActive()
|
||||
if (!member || !member->IsAlive())
|
||||
continue;
|
||||
|
||||
// Check if the member is a hunter
|
||||
// Check if the member is a paladin
|
||||
if (member->getClass() == CLASS_PALADIN)
|
||||
{
|
||||
// Return true only if the current bot is the first alive paladin
|
||||
@@ -121,7 +133,8 @@ bool BossNatureResistanceTrigger::IsActive()
|
||||
return false;
|
||||
|
||||
// Check if bot have nature resistance aura
|
||||
if (bot->HasAura(SPELL_ASPECT_OF_THE_WILD))
|
||||
if (bot->HasAura(SPELL_ASPECT_OF_THE_WILD_RANK_4) || bot->HasAura(SPELL_ASPECT_OF_THE_WILD_RANK_3) ||
|
||||
bot->HasAura(SPELL_ASPECT_OF_THE_WILD_RANK_2) || bot->HasAura(SPELL_ASPECT_OF_THE_WILD_RANK_1))
|
||||
return false;
|
||||
|
||||
// Check if bot dont have already setted nature resistance aura
|
||||
@@ -130,7 +143,10 @@ bool BossNatureResistanceTrigger::IsActive()
|
||||
return false;
|
||||
|
||||
// Check that the bot actually knows Aspect of the Wild
|
||||
if (!bot->HasActiveSpell(SPELL_ASPECT_OF_THE_WILD))
|
||||
if (!bot->HasActiveSpell(SPELL_ASPECT_OF_THE_WILD_RANK_4) &&
|
||||
!bot->HasActiveSpell(SPELL_ASPECT_OF_THE_WILD_RANK_3) &&
|
||||
!bot->HasActiveSpell(SPELL_ASPECT_OF_THE_WILD_RANK_2) &&
|
||||
!bot->HasActiveSpell(SPELL_ASPECT_OF_THE_WILD_RANK_1))
|
||||
return false;
|
||||
|
||||
// Get the group and ensure it's a raid group
|
||||
@@ -155,3 +171,58 @@ bool BossNatureResistanceTrigger::IsActive()
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool BossShadowResistanceTrigger::IsActive()
|
||||
{
|
||||
// Check boss and it is alive
|
||||
Unit* boss = AI_VALUE2(Unit*, "find target", bossName);
|
||||
if (!boss || !boss->IsAlive())
|
||||
return false;
|
||||
|
||||
// Check if bot is paladin
|
||||
if (bot->getClass() != CLASS_PALADIN)
|
||||
return false;
|
||||
|
||||
// Check if bot have shadow resistance aura
|
||||
if (bot->HasAura(SPELL_SHADOW_RESISTANCE_AURA_RANK_5) ||
|
||||
bot->HasAura(SPELL_SHADOW_RESISTANCE_AURA_RANK_4) ||
|
||||
bot->HasAura(SPELL_SHADOW_RESISTANCE_AURA_RANK_3) ||
|
||||
bot->HasAura(SPELL_SHADOW_RESISTANCE_AURA_RANK_2) ||
|
||||
bot->HasAura(SPELL_SHADOW_RESISTANCE_AURA_RANK_1))
|
||||
return false;
|
||||
|
||||
// Check if bot dont have already have shadow resistance strategy
|
||||
PaladinShadowResistanceStrategy paladinShadowResistanceStrategy(botAI);
|
||||
if (botAI->HasStrategy(paladinShadowResistanceStrategy.getName(), BotState::BOT_STATE_COMBAT))
|
||||
return false;
|
||||
|
||||
// Check that the bot actually knows the spell
|
||||
if (!bot->HasActiveSpell(SPELL_SHADOW_RESISTANCE_AURA_RANK_5) &&
|
||||
!bot->HasActiveSpell(SPELL_SHADOW_RESISTANCE_AURA_RANK_4) &&
|
||||
!bot->HasActiveSpell(SPELL_SHADOW_RESISTANCE_AURA_RANK_3) &&
|
||||
!bot->HasActiveSpell(SPELL_SHADOW_RESISTANCE_AURA_RANK_2) &&
|
||||
!bot->HasActiveSpell(SPELL_SHADOW_RESISTANCE_AURA_RANK_1))
|
||||
return false;
|
||||
|
||||
// Get the group and ensure it's a raid group
|
||||
Group* group = bot->GetGroup();
|
||||
if (!group || !group->isRaidGroup())
|
||||
return false;
|
||||
|
||||
// Iterate through group members to find the first alive paladin
|
||||
for (GroupReference* gref = group->GetFirstMember(); gref; gref = gref->next())
|
||||
{
|
||||
Player* member = gref->GetSource();
|
||||
if (!member || !member->IsAlive())
|
||||
continue;
|
||||
|
||||
// Check if the member is a paladin
|
||||
if (member->getClass() == CLASS_PALADIN)
|
||||
{
|
||||
// Return true only if the current bot is the first alive paladin
|
||||
return member == bot;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -12,9 +12,25 @@ class PlayerbotAI;
|
||||
|
||||
enum BossAuraIDs
|
||||
{
|
||||
SPELL_FROST_RESISTANCE_AURA = 48945,
|
||||
SPELL_FIRE_RESISTANCE_AURA = 48947,
|
||||
SPELL_ASPECT_OF_THE_WILD = 49071,
|
||||
SPELL_SHADOW_RESISTANCE_AURA_RANK_1 = 19876,
|
||||
SPELL_FROST_RESISTANCE_AURA_RANK_1 = 19888,
|
||||
SPELL_FIRE_RESISTANCE_AURA_RANK_1 = 19891,
|
||||
SPELL_SHADOW_RESISTANCE_AURA_RANK_2 = 19895,
|
||||
SPELL_SHADOW_RESISTANCE_AURA_RANK_3 = 19896,
|
||||
SPELL_FROST_RESISTANCE_AURA_RANK_2 = 19897,
|
||||
SPELL_FROST_RESISTANCE_AURA_RANK_3 = 19898,
|
||||
SPELL_FIRE_RESISTANCE_AURA_RANK_2 = 19899,
|
||||
SPELL_FIRE_RESISTANCE_AURA_RANK_3 = 19900,
|
||||
SPELL_ASPECT_OF_THE_WILD_RANK_1 = 20043,
|
||||
SPELL_ASPECT_OF_THE_WILD_RANK_2 = 20190,
|
||||
SPELL_ASPECT_OF_THE_WILD_RANK_3 = 27045,
|
||||
SPELL_SHADOW_RESISTANCE_AURA_RANK_4 = 27151,
|
||||
SPELL_FROST_RESISTANCE_AURA_RANK_4 = 27152,
|
||||
SPELL_FIRE_RESISTANCE_AURA_RANK_4 = 27153,
|
||||
SPELL_SHADOW_RESISTANCE_AURA_RANK_5 = 48943,
|
||||
SPELL_FROST_RESISTANCE_AURA_RANK_5 = 48945,
|
||||
SPELL_FIRE_RESISTANCE_AURA_RANK_5 = 48947,
|
||||
SPELL_ASPECT_OF_THE_WILD_RANK_4 = 49071
|
||||
};
|
||||
|
||||
class BossFireResistanceTrigger : public Trigger
|
||||
@@ -47,7 +63,20 @@ class BossNatureResistanceTrigger : public Trigger
|
||||
{
|
||||
public:
|
||||
BossNatureResistanceTrigger(PlayerbotAI* ai, std::string const bossName)
|
||||
: Trigger(ai, "kologarn nature resistance trigger"), bossName(bossName)
|
||||
: Trigger(ai, " nature resistance trigger"), bossName(bossName)
|
||||
{
|
||||
}
|
||||
bool IsActive() override;
|
||||
|
||||
private:
|
||||
std::string bossName;
|
||||
};
|
||||
|
||||
class BossShadowResistanceTrigger : public Trigger
|
||||
{
|
||||
public:
|
||||
BossShadowResistanceTrigger(PlayerbotAI* ai, std::string const bossName)
|
||||
: Trigger(ai, " shadow resistance trigger"), bossName(bossName)
|
||||
{
|
||||
}
|
||||
bool IsActive() override;
|
||||
|
||||
@@ -138,6 +138,7 @@ public:
|
||||
creators["glyph equip"] = &ChatTriggerContext::glyph_equip; // Added for custom Glyphs
|
||||
creators["pet"] = &ChatTriggerContext::pet;
|
||||
creators["pet attack"] = &ChatTriggerContext::pet_attack;
|
||||
creators["roll"] = &ChatTriggerContext::roll_action;
|
||||
}
|
||||
|
||||
private:
|
||||
@@ -255,6 +256,7 @@ private:
|
||||
static Trigger* glyph_equip(PlayerbotAI* ai) { return new ChatCommandTrigger(ai, "glyph equip"); } // Added for custom Glyphs
|
||||
static Trigger* pet(PlayerbotAI* botAI) { return new ChatCommandTrigger(botAI, "pet"); }
|
||||
static Trigger* pet_attack(PlayerbotAI* botAI) { return new ChatCommandTrigger(botAI, "pet attack"); }
|
||||
static Trigger* roll_action(PlayerbotAI* botAI) { return new ChatCommandTrigger(botAI, "roll"); }
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user