Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Utgarde Pinnacle, CoS & additional value entry #632

Merged
merged 2 commits into from
Oct 21, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions src/strategy/AiObjectContext.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,8 @@ AiObjectContext::AiObjectContext(PlayerbotAI* botAI) : PlayerbotAIAware(botAI)
actionContexts.Add(new WotlkDungeonGDActionContext());
actionContexts.Add(new WotlkDungeonHoSActionContext());
actionContexts.Add(new WotlkDungeonHoLActionContext());
actionContexts.Add(new WotlkDungeonUPActionContext());
actionContexts.Add(new WotlkDungeonCoSActionContext());

triggerContexts.Add(new TriggerContext());
triggerContexts.Add(new ChatTriggerContext());
Expand All @@ -78,6 +80,8 @@ AiObjectContext::AiObjectContext(PlayerbotAI* botAI) : PlayerbotAIAware(botAI)
triggerContexts.Add(new WotlkDungeonGDTriggerContext());
triggerContexts.Add(new WotlkDungeonHoSTriggerContext());
triggerContexts.Add(new WotlkDungeonHoLTriggerContext());
triggerContexts.Add(new WotlkDungeonUPTriggerContext());
triggerContexts.Add(new WotlkDungeonCoSTriggerContext());

valueContexts.Add(new ValueContext());

Expand Down
15 changes: 7 additions & 8 deletions src/strategy/dungeons/DungeonStrategyContext.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,16 +11,14 @@
#include "wotlk/gundrak/GundrakStrategy.h"
#include "wotlk/hallsofstone/HallsOfStoneStrategy.h"
#include "wotlk/hallsoflightning/HallsOfLightningStrategy.h"
#include "wotlk/utgardepinnacle/UtgardePinnacleStrategy.h"
#include "wotlk/cullingofstratholme/CullingOfStratholmeStrategy.h"

/*
Full list/TODO:

The Oculus - Occ
Drakos the Interrogator, Varos Cloudstrider, Mage-Lord Urom, Ley-Guardian Eregos
Utgarde Pinnacle - UP
Svala Sorrowgrave, Gortok Palehoof, Skadi the Ruthless, King Ymiron
The Culling of Stratholme - CoS
Meathook, Salramm the Fleshcrafter, Chrono-Lord Epoch, Mal'Ganis, Infinite Corruptor (Heroic only)
Trial of the Champion - ToC
Alliance Champions: Deathstalker Visceri, Eressea Dawnsinger, Mokra the Skullcrusher, Runok Wildmane, Zul'tore
Horde Champions: Ambrose Boltspark, Colosos, Jacob Alerius, Jaelyne Evensong, Lana Stouthammer
Expand Down Expand Up @@ -76,11 +74,12 @@ class DungeonStrategyContext : public NamedObjectContext<Strategy>
static Strategy* wotlk_gd(PlayerbotAI* botAI) { return new WotlkDungeonGDStrategy(botAI); }
static Strategy* wotlk_hos(PlayerbotAI* botAI) { return new WotlkDungeonHoSStrategy(botAI); }
static Strategy* wotlk_hol(PlayerbotAI* botAI) { return new WotlkDungeonHoLStrategy(botAI); }

// static Strategy* wotlk_occ(PlayerbotAI* botAI) { return new WotlkDungeonOccStrategy(botAI); }
static Strategy* wotlk_occ(PlayerbotAI* botAI) { return new WotlkDungeonUKStrategy(botAI); }
static Strategy* wotlk_up(PlayerbotAI* botAI) { return new WotlkDungeonUKStrategy(botAI); }
static Strategy* wotlk_cos(PlayerbotAI* botAI) { return new WotlkDungeonUKStrategy(botAI); }
static Strategy* wotlk_toc(PlayerbotAI* botAI) { return new WotlkDungeonUKStrategy(botAI); }
static Strategy* wotlk_up(PlayerbotAI* botAI) { return new WotlkDungeonUPStrategy(botAI); }
static Strategy* wotlk_cos(PlayerbotAI* botAI) { return new WotlkDungeonCoSStrategy(botAI); }

static Strategy* wotlk_toc(PlayerbotAI* botAI) { return new WotlkDungeonUKStrategy(botAI); } // NYI from here down
static Strategy* wotlk_hor(PlayerbotAI* botAI) { return new WotlkDungeonUKStrategy(botAI); }
static Strategy* wotlk_pos(PlayerbotAI* botAI) { return new WotlkDungeonUKStrategy(botAI); }
static Strategy* wotlk_fos(PlayerbotAI* botAI) { return new WotlkDungeonUKStrategy(botAI); }
Expand Down
4 changes: 2 additions & 2 deletions src/strategy/dungeons/wotlk/WotlkDungeonActionContext.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@
#include "hallsofstone/HallsOfStoneActionContext.h"
#include "hallsoflightning/HallsOfLightningActionContext.h"
// #include "oculus/OculusActionContext.h"
// #include "utgardepinnacle/UtgardePinnacleActionContext.h"
// #include "cullingofstratholme/CullingOfStratholmeActionContext.h"
#include "utgardepinnacle/UtgardePinnacleActionContext.h"
#include "cullingofstratholme/CullingOfStratholmeActionContext.h"
// #include "trialofthechampion/TrialOfTheChampionActionContext.h"
// #include "hallsofreflection/HallsOfReflectionActionContext.h"
// #include "pitofsaron/PitOfSaronActionContext.h"
Expand Down
4 changes: 2 additions & 2 deletions src/strategy/dungeons/wotlk/WotlkDungeonTriggerContext.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@
#include "hallsofstone/HallsOfStoneTriggerContext.h"
#include "hallsoflightning/HallsOfLightningTriggerContext.h"
// #include "oculus/OculusTriggerContext.h"
// #include "utgardepinnacle/UtgardePinnacleTriggerContext.h"
// #include "cullingofstratholme/CullingOfStratholmeTriggerContext.h"
#include "utgardepinnacle/UtgardePinnacleTriggerContext.h"
#include "cullingofstratholme/CullingOfStratholmeTriggerContext.h"
// #include "trialofthechampion/TrialOfTheChampionTriggerContext.h"
// #include "hallsofreflection/HallsOfReflectionTriggerContext.h"
// #include "pitofsaron/PitOfSaronTriggerContext.h"
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
#ifndef _PLAYERBOT_WOTLKDUNGEONCOSACTIONCONTEXT_H
#define _PLAYERBOT_WOTLKDUNGEONCOSACTIONCONTEXT_H

#include "Action.h"
#include "NamedObjectContext.h"
#include "CullingOfStratholmeActions.h"

class WotlkDungeonCoSActionContext : public NamedObjectContext<Action>
{
public:
WotlkDungeonCoSActionContext() {
creators["explode ghoul spread"] = &WotlkDungeonCoSActionContext::explode_ghoul_spread;
creators["epoch stack"] = &WotlkDungeonCoSActionContext::epoch_stack;
}
private:
static Action* explode_ghoul_spread(PlayerbotAI* ai) { return new ExplodeGhoulSpreadAction(ai); }
static Action* epoch_stack(PlayerbotAI* ai) { return new EpochStackAction(ai); }
};

#endif
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
#include "Playerbots.h"
#include "CullingOfStratholmeActions.h"
#include "CullingOfStratholmeStrategy.h"


bool ExplodeGhoulSpreadAction::Execute(Event event)
{
Unit* boss = AI_VALUE2(Unit*, "find target", "salramm the fleshcrafter");
if (!boss) { return false; }

float distance = 10.0f;
float distanceExtra = 2.0f;
GuidVector corpses = AI_VALUE(GuidVector, "nearest corpses");
for (auto i = corpses.begin(); i != corpses.end(); ++i)
{
Unit* unit = botAI->GetUnit(*i);
if (unit && unit->GetEntry() == NPC_GHOUL_MINION)
{
float currentDistance = bot->GetExactDist2d(unit);
if (currentDistance < distance + distanceExtra)
{
return MoveAway(unit, distance + distanceExtra - currentDistance);
}
}
}
return false;
}

bool EpochStackAction::isUseful()
{
// Minimum hunter range is 5, but values too close to this seem to cause issues..
// Hunter bots will try and melee in between ranged attacks, or just melee entirely at 5 as they are in range.
// 7.5 or 8.0 solves this for this boss.
// Unfortunately at this range the boss will charge. So I guess just don't stack as a hunter..
// if(bot->getClass() == CLASS_HUNTER)
// {
// return AI_VALUE2(float, "distance", "current target") > 7.5f;
// }
// else
return !(bot->getClass() == CLASS_HUNTER) && AI_VALUE2(float, "distance", "current target") > 5.0f;
}
bool EpochStackAction::Execute(Event event)
{
Unit* boss = AI_VALUE2(Unit*, "find target", "chrono-lord epoch");
if (!boss) { return false; }

float maxMovement = 10.0f;
// if(bot->getClass() == CLASS_HUNTER)
// {
// return Move(bot->GetAngle(boss), fmin(bot->GetExactDist2d(boss) - 6.5f, maxMovement));
// }
// else
return Move(bot->GetAngle(boss), fmin(bot->GetExactDist2d(boss), maxMovement));
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
#ifndef _PLAYERBOT_WOTLKDUNGEONCOSACTIONS_H
#define _PLAYERBOT_WOTLKDUNGEONCOSACTIONS_H

#include "Action.h"
#include "AttackAction.h"
#include "GenericSpellActions.h"
#include "PlayerbotAI.h"
#include "Playerbots.h"
#include "CullingOfStratholmeTriggers.h"

class ExplodeGhoulSpreadAction : public MovementAction
{
public:
ExplodeGhoulSpreadAction(PlayerbotAI* ai) : MovementAction(ai, "explode ghoul spread") {}
bool Execute(Event event) override;
};

class EpochStackAction : public MovementAction
{
public:
EpochStackAction(PlayerbotAI* ai) : MovementAction(ai, "epoch stack") {}
bool Execute(Event event) override;
bool isUseful() override;
};

#endif
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
#include "CullingOfStratholmeMultipliers.h"
#include "CullingOfStratholmeActions.h"
#include "GenericSpellActions.h"
#include "ChooseTargetActions.h"
#include "MovementActions.h"
#include "CullingOfStratholmeTriggers.h"
#include "Action.h"

float EpochMultiplier::GetValue(Action* action)
{
Unit* boss = AI_VALUE2(Unit*, "find target", "chrono-lord epoch");
if (!boss) { return 1.0f; }

if (bot->getClass() == CLASS_HUNTER) { return 1.0f; }

if (dynamic_cast<FleeAction*>(action)) { return 0.0f; }

return 1.0f;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
#ifndef _PLAYERBOT_WOTLKDUNGEONCOSMULTIPLIERS_H
#define _PLAYERBOT_WOTLKDUNGEONCOSMULTIPLIERS_H

#include "Multiplier.h"

class EpochMultiplier : public Multiplier
{
public:
EpochMultiplier(PlayerbotAI* ai) : Multiplier(ai, "chrono-lord epoch") {}

public:
virtual float GetValue(Action* action);
};

#endif
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
#include "CullingOfStratholmeStrategy.h"
#include "CullingOfStratholmeMultipliers.h"


void WotlkDungeonCoSStrategy::InitTriggers(std::vector<TriggerNode*> &triggers)
{
// Meathook
// Can tank this in a fixed position to allow healer to LoS the stun, probably not necessary

// Salramm the Fleshcrafter
triggers.push_back(new TriggerNode("explode ghoul",
NextAction::array(0, new NextAction("explode ghoul spread", ACTION_MOVE + 5), nullptr)));

// Chrono-Lord Epoch
// Not sure if this actually works, I think I've seen him charge melee characters..?
triggers.push_back(new TriggerNode("epoch ranged",
NextAction::array(0, new NextAction("epoch stack", ACTION_MOVE + 5), nullptr)));

// Mal'Ganis

// Infinite Corruptor (Heroic only)
}

void WotlkDungeonCoSStrategy::InitMultipliers(std::vector<Multiplier*> &multipliers)
{
multipliers.push_back(new EpochMultiplier(botAI));
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
#ifndef _PLAYERBOT_WOTLKDUNGEONCOSSTRATEGY_H
#define _PLAYERBOT_WOTLKDUNGEONCOSSTRATEGY_H

#include "Multiplier.h"
#include "AiObjectContext.h"
#include "Strategy.h"


class WotlkDungeonCoSStrategy : public Strategy
{
public:
WotlkDungeonCoSStrategy(PlayerbotAI* ai) : Strategy(ai) {}
virtual std::string const getName() override { return "culling of stratholme"; }
virtual void InitTriggers(std::vector<TriggerNode*> &triggers) override;
virtual void InitMultipliers(std::vector<Multiplier*> &multipliers) override;
};

#endif
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
#ifndef _PLAYERBOT_WOTLKDUNGEONCOSTRIGGERCONTEXT_H
#define _PLAYERBOT_WOTLKDUNGEONCOSTRIGGERCONTEXT_H

#include "NamedObjectContext.h"
#include "AiObjectContext.h"
#include "CullingOfStratholmeTriggers.h"

class WotlkDungeonCoSTriggerContext : public NamedObjectContext<Trigger>
{
public:
WotlkDungeonCoSTriggerContext()
{
creators["explode ghoul"] = &WotlkDungeonCoSTriggerContext::explode_ghoul;
creators["epoch ranged"] = &WotlkDungeonCoSTriggerContext::epoch_ranged;

}
private:
static Trigger* explode_ghoul(PlayerbotAI* ai) { return new ExplodeGhoulTrigger(ai); }
static Trigger* epoch_ranged(PlayerbotAI* ai) { return new EpochRangedTrigger(ai); }
};

#endif
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
#include "Playerbots.h"
#include "CullingOfStratholmeTriggers.h"
#include "AiObject.h"
#include "AiObjectContext.h"


bool ExplodeGhoulTrigger::IsActive()
{
Unit* boss = AI_VALUE2(Unit*, "find target", "salramm the fleshcrafter");
if (!boss) { return false; }

float distance = 10.0f;
float distanceExtra = 2.0f;
GuidVector corpses = AI_VALUE(GuidVector, "nearest corpses");
for (auto i = corpses.begin(); i != corpses.end(); ++i)
{
Unit* unit = botAI->GetUnit(*i);
if (unit && unit->GetEntry() == NPC_RISEN_GHOUL)
{
if (bot->GetExactDist2d(unit) < distance + distanceExtra)
{
return true;
}
}
}
return false;
}

bool EpochRangedTrigger::IsActive()
{
return !botAI->IsMelee(bot) && AI_VALUE2(Unit*, "find target", "chrono-lord epoch");
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
#ifndef _PLAYERBOT_WOTLKDUNGEONCOSTRIGGERS_H
#define _PLAYERBOT_WOTLKDUNGEONCOSTRIGGERS_H

#include "Trigger.h"
#include "PlayerbotAIConfig.h"
#include "GenericTriggers.h"
#include "DungeonStrategyUtils.h"

enum CullingOfStratholmeIDs
{
// Salramm the Fleshcrafter
NPC_GHOUL_MINION = 27733,
};

class ExplodeGhoulTrigger : public Trigger
{
public:
ExplodeGhoulTrigger(PlayerbotAI* ai) : Trigger(ai, "explode ghoul") {}
bool IsActive() override;
};

class EpochRangedTrigger : public Trigger
{
public:
EpochRangedTrigger(PlayerbotAI* ai) : Trigger(ai, "chrono-lord epoch ranged") {}
bool IsActive() override;
};

#endif
Empty file.
Original file line number Diff line number Diff line change
Expand Up @@ -8,16 +8,18 @@ bool CorpseExplodeSpreadAction::Execute(Event event)
Unit* boss = AI_VALUE2(Unit*, "find target", "trollgore");
if (!boss) { return false; }

float distance = 6.0f; // 5 unit radius, 1 unit added as buffer
float distance = 5.0f;
float distanceExtra = 2.0f;
GuidVector corpses = AI_VALUE(GuidVector, "nearest corpses");
for (auto i = corpses.begin(); i != corpses.end(); ++i)
{
Unit* unit = botAI->GetUnit(*i);
if (unit && unit->GetEntry() == NPC_DRAKKARI_INVADER)
{
if (bot->GetExactDist2d(unit) < distance)
float currentDistance = bot->GetExactDist2d(unit);
if (currentDistance < distance + distanceExtra)
{
return MoveAway(unit, distance - bot->GetExactDist2d(unit));
return MoveAway(unit, distance + distanceExtra - currentDistance);
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,7 @@ bool LokenStackAction::isUseful()
{
// Minimum hunter range is 5, but values too close to this seem to cause issues..
// Hunter bots will try and melee in between ranged attacks, or just melee entirely at 5 as they are in range.
// 6.5 or 7.0 solves this.
// 6.5 or 7.0 solves this for this boss.
if(bot->getClass() == CLASS_HUNTER)
{
return AI_VALUE2(float, "distance", "current target") > 6.5f;
Expand All @@ -138,14 +138,15 @@ bool LokenStackAction::Execute(Event event)
Unit* boss = AI_VALUE2(Unit*, "find target", "loken");
if (!boss) { return false; }

float maxMovement = 10.0f;
if (!boss->HasUnitState(UNIT_STATE_CASTING))
{
if(bot->getClass() == CLASS_HUNTER)
{
return Move(bot->GetAngle(boss), fmin(bot->GetExactDist2d(boss) - 6.5f, 10.0f));
return Move(bot->GetAngle(boss), fmin(bot->GetExactDist2d(boss) - 6.5f, maxMovement));
}
// else
return Move(bot->GetAngle(boss), fmin(bot->GetExactDist2d(boss), 10.0f));
return Move(bot->GetAngle(boss), fmin(bot->GetExactDist2d(boss), maxMovement));
}

return false;
Expand Down
Empty file.
Loading
Loading