From d29569e9eaeaa078d19a253a9536653915a8c436 Mon Sep 17 00:00:00 2001 From: Fuzz Date: Mon, 26 Aug 2024 22:30:36 +1000 Subject: [PATCH 1/2] added 'move from group' action/strat/shortcut-action --- src/strategy/PassiveMultiplier.cpp | 1 + src/strategy/StrategyContext.h | 3 + src/strategy/actions/ActionContext.h | 2 + src/strategy/actions/ChatActionContext.h | 2 + src/strategy/actions/ChatShortcutActions.cpp | 23 ++++- src/strategy/actions/ChatShortcutActions.h | 8 ++ src/strategy/actions/FollowActions.cpp | 14 ++-- src/strategy/actions/MovementActions.cpp | 83 +++++++++++++++++-- src/strategy/actions/MovementActions.h | 12 ++- src/strategy/actions/StayActions.cpp | 6 ++ .../generic/ChatCommandHandlerStrategy.cpp | 2 + .../generic/MoveFromGroupStrategy.cpp | 18 ++++ src/strategy/generic/MoveFromGroupStrategy.h | 23 +++++ src/strategy/triggers/ChatTriggerContext.h | 2 + 14 files changed, 180 insertions(+), 19 deletions(-) create mode 100644 src/strategy/generic/MoveFromGroupStrategy.cpp create mode 100644 src/strategy/generic/MoveFromGroupStrategy.h diff --git a/src/strategy/PassiveMultiplier.cpp b/src/strategy/PassiveMultiplier.cpp index ef4329ac..ddcef847 100644 --- a/src/strategy/PassiveMultiplier.cpp +++ b/src/strategy/PassiveMultiplier.cpp @@ -24,6 +24,7 @@ PassiveMultiplier::PassiveMultiplier(PlayerbotAI* botAI) : Multiplier(botAI, "pa if (allowedParts.empty()) { allowedParts.push_back("follow"); + allowedParts.push_back("move from group"); allowedParts.push_back("stay"); allowedParts.push_back("chat shortcut"); } diff --git a/src/strategy/StrategyContext.h b/src/strategy/StrategyContext.h index 0a2501bb..2679a59d 100644 --- a/src/strategy/StrategyContext.h +++ b/src/strategy/StrategyContext.h @@ -29,6 +29,7 @@ #include "MaintenanceStrategy.h" #include "MarkRtiStrategy.h" #include "MeleeCombatStrategy.h" +#include "MoveFromGroupStrategy.h" #include "NamedObjectContext.h" #include "NonCombatStrategy.h" #include "PassiveStrategy.h" @@ -115,6 +116,7 @@ public: creators["aaoe"] = &StrategyContext::avoid_aoe; creators["move random"] = &StrategyContext::move_random; creators["formation"] = &StrategyContext::combat_formation; + creators["move from group"] = &StrategyContext::move_from_group; } private: @@ -179,6 +181,7 @@ private: static Strategy* avoid_aoe(PlayerbotAI* botAI) { return new AvoidAoeStrategy(botAI); } static Strategy* move_random(PlayerbotAI* ai) { return new MoveRandomStrategy(ai); } static Strategy* combat_formation(PlayerbotAI* ai) { return new CombatFormationStrategy(ai); } + static Strategy* move_from_group(PlayerbotAI* botAI) { return new MoveFromGroupStrategy(botAI); } }; class MovementStrategyContext : public NamedObjectContext diff --git a/src/strategy/actions/ActionContext.h b/src/strategy/actions/ActionContext.h index be2fa613..1b798f29 100644 --- a/src/strategy/actions/ActionContext.h +++ b/src/strategy/actions/ActionContext.h @@ -115,6 +115,7 @@ public: creators["release loot"] = &ActionContext::release_loot; creators["shoot"] = &ActionContext::shoot; creators["follow"] = &ActionContext::follow; + creators["move from group"] = &ActionContext::move_from_group; creators["flee to master"] = &ActionContext::flee_to_master; creators["runaway"] = &ActionContext::runaway; creators["stay"] = &ActionContext::stay; @@ -294,6 +295,7 @@ private: static Action* sit(PlayerbotAI* botAI) { return new SitAction(botAI); } static Action* runaway(PlayerbotAI* botAI) { return new RunAwayAction(botAI); } static Action* follow(PlayerbotAI* botAI) { return new FollowAction(botAI); } + static Action* move_from_group(PlayerbotAI* botAI) { return new MoveFromGroupAction(botAI); } static Action* flee_to_master(PlayerbotAI* botAI) { return new FleeToMasterAction(botAI); } static Action* add_gathering_loot(PlayerbotAI* botAI) { return new AddGatheringLootAction(botAI); } static Action* add_loot(PlayerbotAI* botAI) { return new AddLootAction(botAI); } diff --git a/src/strategy/actions/ChatActionContext.h b/src/strategy/actions/ChatActionContext.h index 0513c930..76c1bc54 100644 --- a/src/strategy/actions/ChatActionContext.h +++ b/src/strategy/actions/ChatActionContext.h @@ -132,6 +132,7 @@ public: creators["stay chat shortcut"] = &ChatActionContext::stay_chat_shortcut; creators["flee chat shortcut"] = &ChatActionContext::flee_chat_shortcut; creators["runaway chat shortcut"] = &ChatActionContext::runaway_chat_shortcut; + creators["move from group chat shortcut"] = &ChatActionContext::move_from_group_chat_shortcut; creators["grind chat shortcut"] = &ChatActionContext::grind_chat_shortcut; creators["tank attack chat shortcut"] = &ChatActionContext::tank_attack_chat_shortcut; creators["gossip hello"] = &ChatActionContext::gossip_hello; @@ -208,6 +209,7 @@ private: static Action* runaway_chat_shortcut(PlayerbotAI* botAI) { return new GoawayChatShortcutAction(botAI); } static Action* stay_chat_shortcut(PlayerbotAI* botAI) { return new StayChatShortcutAction(botAI); } static Action* follow_chat_shortcut(PlayerbotAI* botAI) { return new FollowChatShortcutAction(botAI); } + static Action* move_from_group_chat_shortcut(PlayerbotAI* botAI) { return new MoveFromGroupChatShortcutAction(botAI); } static Action* gb(PlayerbotAI* botAI) { return new GuildBankAction(botAI); } static Action* bank(PlayerbotAI* botAI) { return new BankAction(botAI); } static Action* help(PlayerbotAI* botAI) { return new HelpAction(botAI); } diff --git a/src/strategy/actions/ChatShortcutActions.cpp b/src/strategy/actions/ChatShortcutActions.cpp index 0d5163eb..f158ca29 100644 --- a/src/strategy/actions/ChatShortcutActions.cpp +++ b/src/strategy/actions/ChatShortcutActions.cpp @@ -33,8 +33,8 @@ bool FollowChatShortcutAction::Execute(Event event) return false; // botAI->Reset(); - botAI->ChangeStrategy("+follow,-passive,-grind", BOT_STATE_NON_COMBAT); - botAI->ChangeStrategy("-follow,-passive,-grind", BOT_STATE_COMBAT); + botAI->ChangeStrategy("+follow,-passive,-grind,-move from group", BOT_STATE_NON_COMBAT); + botAI->ChangeStrategy("-follow,-passive,-grind,-move from group", BOT_STATE_COMBAT); botAI->GetAiObjectContext()->GetValue("prioritized targets")->Set({}); PositionMap& posMap = context->GetValue("position")->Get(); @@ -102,8 +102,8 @@ bool StayChatShortcutAction::Execute(Event event) return false; botAI->Reset(); - botAI->ChangeStrategy("+stay,-passive", BOT_STATE_NON_COMBAT); - botAI->ChangeStrategy("-follow,-passive", BOT_STATE_COMBAT); + botAI->ChangeStrategy("+stay,-passive,-move from group", BOT_STATE_NON_COMBAT); + botAI->ChangeStrategy("-follow,-passive,-move from group", BOT_STATE_COMBAT); SetReturnPosition(bot->GetPositionX(), bot->GetPositionY(), bot->GetPositionZ()); @@ -111,6 +111,21 @@ bool StayChatShortcutAction::Execute(Event event) return true; } +bool MoveFromGroupChatShortcutAction::Execute(Event event) +{ + Player* master = GetMaster(); + if (!master) + return false; + + // dont need to remove stay or follow, move from group takes priority over both + // (see their isUseful() methods) + botAI->ChangeStrategy("+move from group", BOT_STATE_NON_COMBAT); + botAI->ChangeStrategy("+move from group", BOT_STATE_COMBAT); + + botAI->TellMaster("Moving away from group"); + return true; +} + bool FleeChatShortcutAction::Execute(Event event) { Player* master = GetMaster(); diff --git a/src/strategy/actions/ChatShortcutActions.h b/src/strategy/actions/ChatShortcutActions.h index b1348341..3ee02407 100644 --- a/src/strategy/actions/ChatShortcutActions.h +++ b/src/strategy/actions/ChatShortcutActions.h @@ -35,6 +35,14 @@ public: bool Execute(Event event) override; }; +class MoveFromGroupChatShortcutAction : public Action +{ +public: + MoveFromGroupChatShortcutAction(PlayerbotAI* botAI) : Action(botAI, "move from group chat shortcut") {} + + bool Execute(Event event) override; +}; + class FleeChatShortcutAction : public ReturnPositionResetAction { public: diff --git a/src/strategy/actions/FollowActions.cpp b/src/strategy/actions/FollowActions.cpp index 10d15933..3c6ea0c9 100644 --- a/src/strategy/actions/FollowActions.cpp +++ b/src/strategy/actions/FollowActions.cpp @@ -48,15 +48,19 @@ bool FollowAction::Execute(Event event) bool FollowAction::isUseful() { - if (bot->GetCurrentSpell(CURRENT_CHANNELED_SPELL) != nullptr) - { + // move from group takes priority over follow as it's added and removed automatically + // (without removing/adding follow) + if (botAI->HasStrategy("move from group", BOT_STATE_COMBAT) || + botAI->HasStrategy("move from group", BOT_STATE_NON_COMBAT)) return false; - } + + if (bot->GetCurrentSpell(CURRENT_CHANNELED_SPELL) != nullptr) + return false; + Formation* formation = AI_VALUE(Formation*, "formation"); if (!formation) - { return false; - } + std::string const target = formation->GetTargetName(); Unit* fTarget = nullptr; diff --git a/src/strategy/actions/MovementActions.cpp b/src/strategy/actions/MovementActions.cpp index 8c5eccb1..7f47f9e3 100644 --- a/src/strategy/actions/MovementActions.cpp +++ b/src/strategy/actions/MovementActions.cpp @@ -1501,7 +1501,7 @@ void MovementAction::ClearIdleState() context->GetValue("position")->Get()["random"].Reset(); } -bool MovementAction::MoveAway(Unit* target) +bool MovementAction::MoveAway(Unit* target, float distance) { if (!target) { @@ -1511,16 +1511,16 @@ bool MovementAction::MoveAway(Unit* target) for (float delta = 0; delta <= M_PI / 2; delta += M_PI / 8) { float angle = init_angle + delta; - float dx = bot->GetPositionX() + cos(angle) * sPlayerbotAIConfig->fleeDistance; - float dy = bot->GetPositionY() + sin(angle) * sPlayerbotAIConfig->fleeDistance; + float dx = bot->GetPositionX() + cos(angle) * distance; + float dy = bot->GetPositionY() + sin(angle) * distance; float dz = bot->GetPositionZ(); bool exact = true; if (!bot->GetMap()->CheckCollisionAndGetValidCoords(bot, bot->GetPositionX(), bot->GetPositionY(), bot->GetPositionZ(), dx, dy, dz)) { // disable prediction if position is invalid - dx = bot->GetPositionX() + cos(angle) * sPlayerbotAIConfig->fleeDistance; - dy = bot->GetPositionY() + sin(angle) * sPlayerbotAIConfig->fleeDistance; + dx = bot->GetPositionX() + cos(angle) * distance; + dy = bot->GetPositionY() + sin(angle) * distance; dz = bot->GetPositionZ(); exact = false; } @@ -1534,15 +1534,15 @@ bool MovementAction::MoveAway(Unit* target) } exact = true; angle = init_angle - delta; - dx = bot->GetPositionX() + cos(angle) * sPlayerbotAIConfig->fleeDistance; - dy = bot->GetPositionY() + sin(angle) * sPlayerbotAIConfig->fleeDistance; + dx = bot->GetPositionX() + cos(angle) * distance; + dy = bot->GetPositionY() + sin(angle) * distance; dz = bot->GetPositionZ(); if (!bot->GetMap()->CheckCollisionAndGetValidCoords(bot, bot->GetPositionX(), bot->GetPositionY(), bot->GetPositionZ(), dx, dy, dz)) { // disable prediction if position is invalid - dx = bot->GetPositionX() + cos(angle) * sPlayerbotAIConfig->fleeDistance; - dy = bot->GetPositionY() + sin(angle) * sPlayerbotAIConfig->fleeDistance; + dx = bot->GetPositionX() + cos(angle) * distance; + dy = bot->GetPositionY() + sin(angle) * distance; dz = bot->GetPositionZ(); exact = false; } @@ -1554,6 +1554,63 @@ bool MovementAction::MoveAway(Unit* target) return false; } +// just calculates average position of group and runs away from that position +bool MovementAction::MoveFromGroup(float distance) +{ + LOG_ERROR("playerbots", "MovementAction::MoveFromGroup"); + //if (Player* master = botAI->GetMaster()) + //{ + // return MoveAway(master); + //} + if (Group* group = bot->GetGroup()) + { + uint32 mapId = bot->GetMapId(); + float closestDist = FLT_MAX; + float x = 0.0f; + float y = 0.0f; + uint32 count = 0; + + for (GroupReference* gref = group->GetFirstMember(); gref; gref = gref->next()) + { + Player* player = gref->GetSource(); + if (!player || player == bot || !player->IsAlive() || player->GetMapId() != mapId) + continue; + float dist = bot->GetDistance2d(player); + if (closestDist > dist) + closestDist = dist; + x += player->GetPositionX(); + y += player->GetPositionY(); + count++; + } + + if (count && closestDist < distance) + { + x /= count; + y /= count; + // x and y are now average position of the group members + float angle = bot->GetAngle(x, y) + M_PI; + return Move(angle, distance - closestDist); + } + } + return false; +} + +bool MovementAction::Move(float angle, float distance) +{ + float x = bot->GetPositionX() + cos(angle) * distance; + float y = bot->GetPositionY() + sin(angle) * distance; + + //TODO do we need GetMapWaterOrGroundLevel() if we're using CheckCollisionAndGetValidCoords() ? + float z = bot->GetMapWaterOrGroundLevel(x, y, bot->GetPositionZ()); + if (z == -100000.0f || z == -200000.0f) + z = bot->GetPositionZ(); + if (!bot->GetMap()->CheckCollisionAndGetValidCoords(bot, bot->GetPositionX(), bot->GetPositionY(), + bot->GetPositionZ(), x, y, z, false)) + return false; + + return MoveTo(bot->GetMapId(), x, y, z); +} + bool MovementAction::MoveInside(uint32 mapId, float x, float y, float z, float distance, MovementPriority priority) { if (bot->GetDistance2d(x, y) <= distance) @@ -2411,3 +2468,11 @@ bool RotateAroundTheCenterPointAction::Execute(Event event) } return false; } + +bool MoveFromGroupAction::Execute(Event event) +{ + float distance = atoi(event.getParam().c_str()); + if (!distance) + distance = 20.0f; // flee distance from config is too small for this + return MoveFromGroup(distance); +} diff --git a/src/strategy/actions/MovementActions.h b/src/strategy/actions/MovementActions.h index 5b0f3c7a..6ef93475 100644 --- a/src/strategy/actions/MovementActions.h +++ b/src/strategy/actions/MovementActions.h @@ -47,7 +47,9 @@ protected: bool Flee(Unit* target); void ClearIdleState(); void UpdateMovementState(); - bool MoveAway(Unit* target); + bool MoveAway(Unit* target, float distance = sPlayerbotAIConfig -> fleeDistance); + bool MoveFromGroup(float distance); + bool Move(float angle, float distance); bool MoveInside(uint32 mapId, float x, float y, float z, float distance = sPlayerbotAIConfig->followDistance, MovementPriority priority = MovementPriority::MOVEMENT_NORMAL); void CreateWp(Player* wpOwner, float x, float y, float z, float o, uint32 entry, bool important = false); Position BestPositionForMeleeToFlee(Position pos, float radius); @@ -248,4 +250,12 @@ protected: bool clockwise; std::vector> waypoints; }; + +class MoveFromGroupAction : public MovementAction +{ +public: + MoveFromGroupAction(PlayerbotAI* botAI, std::string const name = "move from group") : MovementAction(botAI, name) {} + + bool Execute(Event event) override; +}; #endif diff --git a/src/strategy/actions/StayActions.cpp b/src/strategy/actions/StayActions.cpp index f725c046..b041f4e2 100644 --- a/src/strategy/actions/StayActions.cpp +++ b/src/strategy/actions/StayActions.cpp @@ -42,6 +42,12 @@ bool StayAction::Execute(Event event) { return Stay(); } bool StayAction::isUseful() { + // move from group takes priority over stay as it's added and removed automatically + // (without removing/adding stay) + if (botAI->HasStrategy("move from group", BOT_STATE_COMBAT) || + botAI->HasStrategy("move from group", BOT_STATE_NON_COMBAT)) + return false; + // Only useful if the bot is currently moving return AI_VALUE2(bool, "moving", "self target"); } diff --git a/src/strategy/generic/ChatCommandHandlerStrategy.cpp b/src/strategy/generic/ChatCommandHandlerStrategy.cpp index c86e774b..78c5aef7 100644 --- a/src/strategy/generic/ChatCommandHandlerStrategy.cpp +++ b/src/strategy/generic/ChatCommandHandlerStrategy.cpp @@ -51,6 +51,8 @@ void ChatCommandHandlerStrategy::InitTriggers(std::vector& trigger new TriggerNode("follow", NextAction::array(0, new NextAction("follow chat shortcut", relevance), nullptr))); triggers.push_back( new TriggerNode("stay", NextAction::array(0, new NextAction("stay chat shortcut", relevance), nullptr))); + triggers.push_back( + new TriggerNode("move from group", NextAction::array(0, new NextAction("move from group chat shortcut", relevance), nullptr))); triggers.push_back( new TriggerNode("flee", NextAction::array(0, new NextAction("flee chat shortcut", relevance), nullptr))); triggers.push_back(new TriggerNode( diff --git a/src/strategy/generic/MoveFromGroupStrategy.cpp b/src/strategy/generic/MoveFromGroupStrategy.cpp new file mode 100644 index 00000000..5d084510 --- /dev/null +++ b/src/strategy/generic/MoveFromGroupStrategy.cpp @@ -0,0 +1,18 @@ +/* + * Copyright (C) 2016+ AzerothCore , released under GNU GPL v2 license, you may redistribute it + * and/or modify it under version 2 of the License, or (at your option), any later version. + */ + +#include "MoveFromGroupStrategy.h" +#include "PassiveMultiplier.h" +#include "Playerbots.h" + +NextAction** MoveFromGroupStrategy::getDefaultActions() +{ + return NextAction::array(0, new NextAction("move from group", 1.0f), nullptr); +} + +void MoveFromGroupStrategy::InitMultipliers(std::vector& multipliers) +{ + multipliers.push_back(new PassiveMultiplier(botAI)); +} diff --git a/src/strategy/generic/MoveFromGroupStrategy.h b/src/strategy/generic/MoveFromGroupStrategy.h new file mode 100644 index 00000000..a28c61b9 --- /dev/null +++ b/src/strategy/generic/MoveFromGroupStrategy.h @@ -0,0 +1,23 @@ +/* + * Copyright (C) 2016+ AzerothCore , released under GNU GPL v2 license, you may redistribute it + * and/or modify it under version 2 of the License, or (at your option), any later version. + */ + +#ifndef _PLAYERBOT_MOVEFROMGROUPSTRATEGY_H +#define _PLAYERBOT_MOVEFROMGROUPSTRATEGY_H + +#include "Strategy.h" + +class PlayerbotAI; + +class MoveFromGroupStrategy : public Strategy +{ +public: + MoveFromGroupStrategy(PlayerbotAI* botAI) : Strategy(botAI) {} + + std::string const getName() override { return "move from group"; } + NextAction** getDefaultActions() override; + void InitMultipliers(std::vector& multipliers) override; +}; + +#endif diff --git a/src/strategy/triggers/ChatTriggerContext.h b/src/strategy/triggers/ChatTriggerContext.h index f146e08f..f232203a 100644 --- a/src/strategy/triggers/ChatTriggerContext.h +++ b/src/strategy/triggers/ChatTriggerContext.h @@ -72,6 +72,7 @@ public: creators["gbank"] = &ChatTriggerContext::gb; creators["bank"] = &ChatTriggerContext::bank; creators["follow"] = &ChatTriggerContext::follow; + creators["move from group"] = &ChatTriggerContext::move_from_group; creators["stay"] = &ChatTriggerContext::stay; creators["flee"] = &ChatTriggerContext::flee; creators["grind"] = &ChatTriggerContext::grind; @@ -164,6 +165,7 @@ private: static Trigger* tank_attack(PlayerbotAI* botAI) { return new ChatCommandTrigger(botAI, "tank attack"); } static Trigger* stay(PlayerbotAI* botAI) { return new ChatCommandTrigger(botAI, "stay"); } static Trigger* follow(PlayerbotAI* botAI) { return new ChatCommandTrigger(botAI, "follow"); } + static Trigger* move_from_group(PlayerbotAI* botAI) { return new ChatCommandTrigger(botAI, "move from group"); } static Trigger* gb(PlayerbotAI* botAI) { return new ChatCommandTrigger(botAI, "gb"); } static Trigger* bank(PlayerbotAI* botAI) { return new ChatCommandTrigger(botAI, "bank"); } static Trigger* help(PlayerbotAI* botAI) { return new ChatCommandTrigger(botAI, "help"); } From 37a2721ff52b4acaee2f9f2ceacd91d07bbd8110 Mon Sep 17 00:00:00 2001 From: Fuzz Date: Mon, 26 Aug 2024 22:43:13 +1000 Subject: [PATCH 2/2] added mc/moltencore strat (just for baron geddon's inferno and living-bomb) --- src/PlayerbotAI.cpp | 3 ++ src/strategy/AiObjectContext.cpp | 4 ++ src/strategy/raids/RaidStrategyContext.h | 6 +++ .../raids/moltencore/RaidMcActionContext.h | 22 ++++++++++ .../raids/moltencore/RaidMcActions.cpp | 43 +++++++++++++++++++ src/strategy/raids/moltencore/RaidMcActions.h | 24 +++++++++++ .../raids/moltencore/RaidMcStrategy.cpp | 13 ++++++ .../raids/moltencore/RaidMcStrategy.h | 17 ++++++++ .../raids/moltencore/RaidMcTriggerContext.h | 22 ++++++++++ .../raids/moltencore/RaidMcTriggers.cpp | 22 ++++++++++ .../raids/moltencore/RaidMcTriggers.h | 22 ++++++++++ 11 files changed, 198 insertions(+) create mode 100644 src/strategy/raids/moltencore/RaidMcActionContext.h create mode 100644 src/strategy/raids/moltencore/RaidMcActions.cpp create mode 100644 src/strategy/raids/moltencore/RaidMcActions.h create mode 100644 src/strategy/raids/moltencore/RaidMcStrategy.cpp create mode 100644 src/strategy/raids/moltencore/RaidMcStrategy.h create mode 100644 src/strategy/raids/moltencore/RaidMcTriggerContext.h create mode 100644 src/strategy/raids/moltencore/RaidMcTriggers.cpp create mode 100644 src/strategy/raids/moltencore/RaidMcTriggers.h diff --git a/src/PlayerbotAI.cpp b/src/PlayerbotAI.cpp index 4fb38ed9..07b07293 100644 --- a/src/PlayerbotAI.cpp +++ b/src/PlayerbotAI.cpp @@ -1504,6 +1504,9 @@ void PlayerbotAI::ApplyInstanceStrategies(uint32 mapId, bool tellMaster) case 469: strategyName = "bwl"; break; + case 409: + strategyName = "mc"; + break; default: break; } diff --git a/src/strategy/AiObjectContext.cpp b/src/strategy/AiObjectContext.cpp index 5c4237d7..9052b61b 100644 --- a/src/strategy/AiObjectContext.cpp +++ b/src/strategy/AiObjectContext.cpp @@ -22,6 +22,8 @@ #include "raids/RaidTriggerContext.h" #include "raids/naxxramas/RaidNaxxActionContext.h" #include "raids/naxxramas/RaidNaxxTriggerContext.h" +#include "raids/moltencore/RaidMcActionContext.h" +#include "raids/moltencore/RaidMcTriggerContext.h" AiObjectContext::AiObjectContext(PlayerbotAI* botAI) : PlayerbotAIAware(botAI) { @@ -37,6 +39,7 @@ AiObjectContext::AiObjectContext(PlayerbotAI* botAI) : PlayerbotAIAware(botAI) actionContexts.Add(new RaidActionContext()); actionContexts.Add(new RaidNaxxActionContext()); actionContexts.Add(new RaidUlduarActionContext()); + actionContexts.Add(new RaidMcActionContext()); triggerContexts.Add(new TriggerContext()); triggerContexts.Add(new ChatTriggerContext()); @@ -44,6 +47,7 @@ AiObjectContext::AiObjectContext(PlayerbotAI* botAI) : PlayerbotAIAware(botAI) triggerContexts.Add(new RaidTriggerContext()); triggerContexts.Add(new RaidNaxxTriggerContext()); triggerContexts.Add(new RaidUlduarTriggerContext()); + triggerContexts.Add(new RaidMcTriggerContext()); valueContexts.Add(new ValueContext()); diff --git a/src/strategy/raids/RaidStrategyContext.h b/src/strategy/raids/RaidStrategyContext.h index f0092302..29e997d2 100644 --- a/src/strategy/raids/RaidStrategyContext.h +++ b/src/strategy/raids/RaidStrategyContext.h @@ -5,21 +5,27 @@ #include "Strategy.h" #include "RaidBwlStrategy.h" #include "RaidNaxxStrategy.h" +#include "RaidMcStrategy.h" class RaidStrategyContext : public NamedObjectContext { public: RaidStrategyContext() : NamedObjectContext(false, true) { + // TODO should we give these prefixes (eg: "naxx" -> "raid naxx")? because if we don't it's going to end up + // very crowded (with possible conflicts) once we have strats for all raids and some dungeons + // (mc already very similiar to nc) creators["naxx"] = &RaidStrategyContext::naxx; creators["bwl"] = &RaidStrategyContext::bwl; creators["uld"] = &RaidStrategyContext::uld; + creators["mc"] = &RaidStrategyContext::mc; } private: static Strategy* naxx(PlayerbotAI* botAI) { return new RaidNaxxStrategy(botAI); } static Strategy* bwl(PlayerbotAI* botAI) { return new RaidBwlStrategy(botAI); } static Strategy* uld(PlayerbotAI* botAI) { return new RaidUlduarStrategy(botAI); } + static Strategy* mc(PlayerbotAI* botAI) { return new RaidMcStrategy(botAI); } }; #endif \ No newline at end of file diff --git a/src/strategy/raids/moltencore/RaidMcActionContext.h b/src/strategy/raids/moltencore/RaidMcActionContext.h new file mode 100644 index 00000000..45e6e056 --- /dev/null +++ b/src/strategy/raids/moltencore/RaidMcActionContext.h @@ -0,0 +1,22 @@ +#ifndef _PLAYERBOT_RAIDMCACTIONCONTEXT_H +#define _PLAYERBOT_RAIDMCACTIONCONTEXT_H + +#include "Action.h" +#include "NamedObjectContext.h" +#include "RaidMcActions.h" + +class RaidMcActionContext : public NamedObjectContext +{ +public: + RaidMcActionContext() + { + creators["mc check should move from group"] = &RaidMcActionContext::check_should_move_from_group; + creators["mc move from baron geddon"] = &RaidMcActionContext::move_from_baron_geddon; + } + +private: + static Action* check_should_move_from_group(PlayerbotAI* ai) { return new McCheckShouldMoveFromGroupAction(ai); } + static Action* move_from_baron_geddon(PlayerbotAI* ai) { return new McMoveFromBaronGeddonAction(ai); } +}; + +#endif diff --git a/src/strategy/raids/moltencore/RaidMcActions.cpp b/src/strategy/raids/moltencore/RaidMcActions.cpp new file mode 100644 index 00000000..f58f344d --- /dev/null +++ b/src/strategy/raids/moltencore/RaidMcActions.cpp @@ -0,0 +1,43 @@ +#include "RaidMcActions.h" + +#include "Playerbots.h" + +bool McCheckShouldMoveFromGroupAction::Execute(Event event) +{ + if (bot->HasAura(20475)) // barron geddon's living bomb + { + if (!botAI->HasStrategy("move from group", BotState::BOT_STATE_COMBAT)) + { + // add/remove from both for now as it will make it more obvious to + // player if this strat remains on after fight somehow + botAI->ChangeStrategy("+move from group", BOT_STATE_NON_COMBAT); + botAI->ChangeStrategy("+move from group", BOT_STATE_COMBAT); + return true; + } + } + else if (botAI->HasStrategy("move from group", BotState::BOT_STATE_COMBAT)) + { + // add/remove from both for now as it will make it more obvious to + // player if this strat remains on after fight somehow + botAI->ChangeStrategy("-move from group", BOT_STATE_NON_COMBAT); + botAI->ChangeStrategy("-move from group", BOT_STATE_COMBAT); + return true; + } + return false; +} + +bool McMoveFromBaronGeddonAction::Execute(Event event) +{ + const float radius = 25.0f; // more than should be needed but bots keep trying to run back in + if (Unit* boss = AI_VALUE2(Unit*, "find target", "baron geddon")) + { + long distToTravel = radius - bot->GetDistance(boss); + if (distToTravel > 0) + { + // float angle = bot->GetAngle(boss) + M_PI; + // return Move(angle, distToTravel); + return MoveAway(boss, distToTravel); + } + } + return false; +} diff --git a/src/strategy/raids/moltencore/RaidMcActions.h b/src/strategy/raids/moltencore/RaidMcActions.h new file mode 100644 index 00000000..6ff18513 --- /dev/null +++ b/src/strategy/raids/moltencore/RaidMcActions.h @@ -0,0 +1,24 @@ +#ifndef _PLAYERBOT_RAIDMCACTIONS_H +#define _PLAYERBOT_RAIDMCACTIONS_H + +#include "MovementActions.h" +#include "PlayerbotAI.h" +#include "Playerbots.h" + +class McCheckShouldMoveFromGroupAction : public Action +{ +public: + McCheckShouldMoveFromGroupAction(PlayerbotAI* botAI, std::string const name = "mc check should move from group") + : Action(botAI, name) {} + bool Execute(Event event) override; +}; + +class McMoveFromBaronGeddonAction : public MovementAction +{ +public: + McMoveFromBaronGeddonAction(PlayerbotAI* botAI, std::string const name = "mc move from baron geddon") + : MovementAction(botAI, name) {} + bool Execute(Event event) override; +}; + +#endif diff --git a/src/strategy/raids/moltencore/RaidMcStrategy.cpp b/src/strategy/raids/moltencore/RaidMcStrategy.cpp new file mode 100644 index 00000000..67793de9 --- /dev/null +++ b/src/strategy/raids/moltencore/RaidMcStrategy.cpp @@ -0,0 +1,13 @@ +#include "RaidMcStrategy.h" + +#include "Strategy.h" + +void RaidMcStrategy::InitTriggers(std::vector& triggers) +{ + triggers.push_back( + new TriggerNode("mc living bomb debuff", + NextAction::array(0, new NextAction("mc check should move from group", ACTION_RAID), nullptr))); + triggers.push_back( + new TriggerNode("mc baron geddon inferno", + NextAction::array(0, new NextAction("mc move from baron geddon", ACTION_RAID), nullptr))); +} diff --git a/src/strategy/raids/moltencore/RaidMcStrategy.h b/src/strategy/raids/moltencore/RaidMcStrategy.h new file mode 100644 index 00000000..82b7d8f2 --- /dev/null +++ b/src/strategy/raids/moltencore/RaidMcStrategy.h @@ -0,0 +1,17 @@ +#ifndef _PLAYERBOT_RAIDMCSTRATEGY_H +#define _PLAYERBOT_RAIDMCSTRATEGY_H + +#include "AiObjectContext.h" +#include "Multiplier.h" +#include "Strategy.h" + +class RaidMcStrategy : public Strategy +{ +public: + RaidMcStrategy(PlayerbotAI* ai) : Strategy(ai) {} + virtual std::string const getName() override { return "mc"; } + virtual void InitTriggers(std::vector& triggers) override; + // virtual void InitMultipliers(std::vector &multipliers) override; +}; + +#endif diff --git a/src/strategy/raids/moltencore/RaidMcTriggerContext.h b/src/strategy/raids/moltencore/RaidMcTriggerContext.h new file mode 100644 index 00000000..93fe6df0 --- /dev/null +++ b/src/strategy/raids/moltencore/RaidMcTriggerContext.h @@ -0,0 +1,22 @@ +#ifndef _PLAYERBOT_RAIDMCTRIGGERCONTEXT_H +#define _PLAYERBOT_RAIDMCTRIGGERCONTEXT_H + +#include "AiObjectContext.h" +#include "NamedObjectContext.h" +#include "RaidMcTriggers.h" + +class RaidMcTriggerContext : public NamedObjectContext +{ +public: + RaidMcTriggerContext() + { + creators["mc living bomb debuff"] = &RaidMcTriggerContext::living_bomb_debuff; + creators["mc baron geddon inferno"] = &RaidMcTriggerContext::baron_geddon_inferno; + } + +private: + static Trigger* living_bomb_debuff(PlayerbotAI* ai) { return new McLivingBombDebuffTrigger(ai); } + static Trigger* baron_geddon_inferno(PlayerbotAI* ai) { return new McBaronGeddonInfernoTrigger(ai); } +}; + +#endif diff --git a/src/strategy/raids/moltencore/RaidMcTriggers.cpp b/src/strategy/raids/moltencore/RaidMcTriggers.cpp new file mode 100644 index 00000000..f77b70f2 --- /dev/null +++ b/src/strategy/raids/moltencore/RaidMcTriggers.cpp @@ -0,0 +1,22 @@ +#include "RaidMcTriggers.h" + +#include "SharedDefines.h" + +bool McLivingBombDebuffTrigger::IsActive() +{ + // if bot has barron geddon's living bomb, we need to add strat, otherwise we need to remove + // only do when fighting baron geddon (to avoid modifying strat set by player outside this fight) + if (Unit* boss = AI_VALUE2(Unit*, "find target", "baron geddon")) + { + if (boss->IsInCombat()) + return bot->HasAura(20475) != botAI->HasStrategy("move from group", BotState::BOT_STATE_COMBAT); + } + return false; +} + +bool McBaronGeddonInfernoTrigger::IsActive() +{ + if (Unit* boss = AI_VALUE2(Unit*, "find target", "baron geddon")) + return boss->HasAura(19695); + return false; +} diff --git a/src/strategy/raids/moltencore/RaidMcTriggers.h b/src/strategy/raids/moltencore/RaidMcTriggers.h new file mode 100644 index 00000000..9d2fb985 --- /dev/null +++ b/src/strategy/raids/moltencore/RaidMcTriggers.h @@ -0,0 +1,22 @@ +#ifndef _PLAYERBOT_RAIDMCTRIGGERS_H +#define _PLAYERBOT_RAIDMCTRIGGERS_H + +#include "PlayerbotAI.h" +#include "Playerbots.h" +#include "Trigger.h" + +class McLivingBombDebuffTrigger : public Trigger +{ +public: + McLivingBombDebuffTrigger(PlayerbotAI* botAI) : Trigger(botAI, "mc living bomb debuff") {} + bool IsActive() override; +}; + +class McBaronGeddonInfernoTrigger : public Trigger +{ +public: + McBaronGeddonInfernoTrigger(PlayerbotAI* botAI) : Trigger(botAI, "mc baron geddon inferno") {} + bool IsActive() override; +}; + +#endif