mirror of
https://github.com/mod-playerbots/mod-playerbots.git
synced 2026-01-24 22:16:23 +00:00
aq20 ossirian strat
This commit is contained in:
@@ -6,6 +6,7 @@
|
||||
#include "RaidBwlStrategy.h"
|
||||
#include "RaidNaxxStrategy.h"
|
||||
#include "RaidMcStrategy.h"
|
||||
#include "RaidAq20Strategy.h"
|
||||
|
||||
class RaidStrategyContext : public NamedObjectContext<Strategy>
|
||||
{
|
||||
@@ -19,6 +20,7 @@ public:
|
||||
creators["bwl"] = &RaidStrategyContext::bwl;
|
||||
creators["uld"] = &RaidStrategyContext::uld;
|
||||
creators["mc"] = &RaidStrategyContext::mc;
|
||||
creators["aq20"] = &RaidStrategyContext::aq20;
|
||||
}
|
||||
|
||||
private:
|
||||
@@ -26,6 +28,7 @@ private:
|
||||
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); }
|
||||
static Strategy* aq20(PlayerbotAI* botAI) { return new RaidAq20Strategy(botAI); }
|
||||
};
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
||||
20
src/strategy/raids/aq20/RaidAq20ActionContext.h
Normal file
20
src/strategy/raids/aq20/RaidAq20ActionContext.h
Normal file
@@ -0,0 +1,20 @@
|
||||
#ifndef _PLAYERBOT_RAIDAQ20ACTIONCONTEXT_H
|
||||
#define _PLAYERBOT_RAIDAQ20ACTIONCONTEXT_H
|
||||
|
||||
#include "Action.h"
|
||||
#include "NamedObjectContext.h"
|
||||
#include "RaidAq20Actions.h"
|
||||
|
||||
class RaidAq20ActionContext : public NamedObjectContext<Action>
|
||||
{
|
||||
public:
|
||||
RaidAq20ActionContext()
|
||||
{
|
||||
creators["aq20 use crystal"] = &RaidAq20ActionContext::use_crystal;
|
||||
}
|
||||
|
||||
private:
|
||||
static Action* use_crystal(PlayerbotAI* ai) { return new Aq20UseCrystalAction(ai); }
|
||||
};
|
||||
|
||||
#endif
|
||||
49
src/strategy/raids/aq20/RaidAq20Actions.cpp
Normal file
49
src/strategy/raids/aq20/RaidAq20Actions.cpp
Normal file
@@ -0,0 +1,49 @@
|
||||
#include "RaidAq20Actions.h"
|
||||
|
||||
#include "Playerbots.h"
|
||||
#include "RaidAq20Utils.h"
|
||||
|
||||
|
||||
bool Aq20UseCrystalAction::Execute(Event event)
|
||||
{
|
||||
if (Unit* boss = AI_VALUE2(Unit*, "find target", "ossirian the unscarred"))
|
||||
{
|
||||
if (GameObject* crystal = RaidAq20Utils::GetNearestCrystal(boss))
|
||||
{
|
||||
float botDist = bot->GetDistance(crystal);
|
||||
if (botDist > INTERACTION_DISTANCE)
|
||||
return MoveTo(bot->GetMapId(),
|
||||
crystal->GetPositionX() + frand(-3.5f, 3.5f),
|
||||
crystal->GetPositionY() + frand(-3.5f, 3.5f),
|
||||
crystal->GetPositionZ());
|
||||
|
||||
// if we're already in range just wait here until it's time to activate crystal
|
||||
SetNextMovementDelay(500);
|
||||
|
||||
// don't activate crystal if boss too far or its already been activated
|
||||
if (boss->GetDistance(crystal) > 25.0f ||
|
||||
crystal->HasGameObjectFlag(GO_FLAG_IN_USE))
|
||||
return false;
|
||||
|
||||
// don't activate crystal if boss doesn't have buff yet AND isn't going to have it soon
|
||||
// (though ideally bot should activate it ~5 seconds early due to time it takes for
|
||||
// crystal to activate and remove buff)
|
||||
if (!RaidAq20Utils::IsOssirianBuffActive(boss) &&
|
||||
RaidAq20Utils::GetOssirianDebuffTimeRemaining(boss) > 5000)
|
||||
return false;
|
||||
|
||||
// this makes crystal do its animation (then disappear after)
|
||||
WorldPacket data1(CMSG_GAMEOBJ_USE);
|
||||
data1 << crystal->GetGUID();
|
||||
bot->GetSession()->HandleGameObjectUseOpcode(data1);
|
||||
|
||||
// this makes crystal actually remove the buff and put on debuff (took a while to figure that out)
|
||||
WorldPacket data2(CMSG_GAMEOBJ_USE);
|
||||
data2 << crystal->GetGUID();
|
||||
bot->GetSession()->HandleGameobjectReportUse(data2);
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
14
src/strategy/raids/aq20/RaidAq20Actions.h
Normal file
14
src/strategy/raids/aq20/RaidAq20Actions.h
Normal file
@@ -0,0 +1,14 @@
|
||||
#ifndef _PLAYERBOT_RAIDAQ20ACTIONS_H
|
||||
#define _PLAYERBOT_RAIDAQ20ACTIONS_H
|
||||
|
||||
#include "MovementActions.h"
|
||||
#include "PlayerbotAI.h"
|
||||
#include "Playerbots.h"
|
||||
|
||||
class Aq20UseCrystalAction : public MovementAction
|
||||
{
|
||||
public:
|
||||
Aq20UseCrystalAction(PlayerbotAI* botAI, std::string const name = "aq20 use crystal") : MovementAction(botAI, name) {}
|
||||
bool Execute(Event event) override;
|
||||
};
|
||||
#endif
|
||||
11
src/strategy/raids/aq20/RaidAq20Strategy.cpp
Normal file
11
src/strategy/raids/aq20/RaidAq20Strategy.cpp
Normal file
@@ -0,0 +1,11 @@
|
||||
#include "RaidAq20Strategy.h"
|
||||
|
||||
#include "Strategy.h"
|
||||
|
||||
void RaidAq20Strategy::InitTriggers(std::vector<TriggerNode*>& triggers)
|
||||
{
|
||||
triggers.push_back(
|
||||
new TriggerNode("aq20 move to crystal",
|
||||
NextAction::array(0, new NextAction("aq20 use crystal", ACTION_RAID), nullptr)));
|
||||
|
||||
}
|
||||
17
src/strategy/raids/aq20/RaidAq20Strategy.h
Normal file
17
src/strategy/raids/aq20/RaidAq20Strategy.h
Normal file
@@ -0,0 +1,17 @@
|
||||
#ifndef _PLAYERBOT_RAIDAQ20STRATEGY_H
|
||||
#define _PLAYERBOT_RAIDAQ20STRATEGY_H
|
||||
|
||||
#include "AiObjectContext.h"
|
||||
#include "Multiplier.h"
|
||||
#include "Strategy.h"
|
||||
|
||||
class RaidAq20Strategy : public Strategy
|
||||
{
|
||||
public:
|
||||
RaidAq20Strategy(PlayerbotAI* ai) : Strategy(ai) {}
|
||||
virtual std::string const getName() override { return "aq20"; }
|
||||
virtual void InitTriggers(std::vector<TriggerNode*>& triggers) override;
|
||||
// virtual void InitMultipliers(std::vector<Multiplier*> &multipliers) override;
|
||||
};
|
||||
|
||||
#endif
|
||||
20
src/strategy/raids/aq20/RaidAq20TriggerContext.h
Normal file
20
src/strategy/raids/aq20/RaidAq20TriggerContext.h
Normal file
@@ -0,0 +1,20 @@
|
||||
#ifndef _PLAYERBOT_RAIDAQ20TRIGGERCONTEXT_H
|
||||
#define _PLAYERBOT_RAIDAQ20TRIGGERCONTEXT_H
|
||||
|
||||
#include "AiObjectContext.h"
|
||||
#include "NamedObjectContext.h"
|
||||
#include "RaidAq20Triggers.h"
|
||||
|
||||
class RaidAq20TriggerContext : public NamedObjectContext<Trigger>
|
||||
{
|
||||
public:
|
||||
RaidAq20TriggerContext()
|
||||
{
|
||||
creators["aq20 move to crystal"] = &RaidAq20TriggerContext::move_to_crystal;
|
||||
}
|
||||
|
||||
private:
|
||||
static Trigger* move_to_crystal(PlayerbotAI* ai) { return new Aq20MoveToCrystalTrigger(ai); }
|
||||
};
|
||||
|
||||
#endif
|
||||
37
src/strategy/raids/aq20/RaidAq20Triggers.cpp
Normal file
37
src/strategy/raids/aq20/RaidAq20Triggers.cpp
Normal file
@@ -0,0 +1,37 @@
|
||||
#include "RaidAq20Triggers.h"
|
||||
|
||||
#include "SharedDefines.h"
|
||||
#include "RaidAq20Utils.h"
|
||||
|
||||
|
||||
bool Aq20MoveToCrystalTrigger::IsActive()
|
||||
{
|
||||
if (Unit* boss = AI_VALUE2(Unit*, "find target", "ossirian the unscarred"))
|
||||
{
|
||||
if (boss->IsInCombat())
|
||||
{
|
||||
// if buff is active move to crystal
|
||||
if (RaidAq20Utils::IsOssirianBuffActive(boss))
|
||||
return true;
|
||||
|
||||
// if buff is not active a debuff will be, buff becomes active once debuff expires
|
||||
// so move to crystal when debuff almost done, or based debuff time left and
|
||||
// distance bot is from crystal (ie: start moving early enough to make it)
|
||||
int32 debuffTimeRemaining = RaidAq20Utils::GetOssirianDebuffTimeRemaining(boss);
|
||||
if (debuffTimeRemaining < 5000)
|
||||
return true;
|
||||
if (debuffTimeRemaining < 30000)
|
||||
{
|
||||
if (GameObject* crystal = RaidAq20Utils::GetNearestCrystal(boss))
|
||||
{
|
||||
float botDist = bot->GetDistance(crystal);
|
||||
float timeToReach = botDist / bot->GetSpeed(MOVE_RUN);
|
||||
// bot should ideally activate crystal a ~5 seconds early (due to time it takes for crystal
|
||||
// to activate) so aim to get there in time to do so
|
||||
return debuffTimeRemaining - 5000 < timeToReach * 1000.0f;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
14
src/strategy/raids/aq20/RaidAq20Triggers.h
Normal file
14
src/strategy/raids/aq20/RaidAq20Triggers.h
Normal file
@@ -0,0 +1,14 @@
|
||||
#ifndef _PLAYERBOT_RAIDAQ20TRIGGERS_H
|
||||
#define _PLAYERBOT_RAIDAQ20TRIGGERS_H
|
||||
|
||||
#include "PlayerbotAI.h"
|
||||
#include "Playerbots.h"
|
||||
#include "Trigger.h"
|
||||
|
||||
class Aq20MoveToCrystalTrigger : public Trigger
|
||||
{
|
||||
public:
|
||||
Aq20MoveToCrystalTrigger(PlayerbotAI* botAI) : Trigger(botAI, "aq20 move to crystal") {}
|
||||
bool IsActive() override;
|
||||
};
|
||||
#endif
|
||||
38
src/strategy/raids/aq20/RaidAq20Utils.cpp
Normal file
38
src/strategy/raids/aq20/RaidAq20Utils.cpp
Normal file
@@ -0,0 +1,38 @@
|
||||
#include "RaidAq20Utils.h"
|
||||
|
||||
#include "SpellAuras.h"
|
||||
|
||||
uint32 const OSSIRIAN_BUFF = 25176;
|
||||
uint32 const OSSIRIAN_DEBUFFS[] = {25177, 25178, 25180, 25181, 25183};
|
||||
uint32 const OSSIRIAN_CRYSTAL_GO_ENTRY = 180619;
|
||||
|
||||
bool RaidAq20Utils::IsOssirianBuffActive(Unit* ossirian)
|
||||
{
|
||||
return ossirian && ossirian->HasAura(OSSIRIAN_BUFF);
|
||||
}
|
||||
|
||||
int32 RaidAq20Utils::GetOssirianDebuffTimeRemaining(Unit* ossirian)
|
||||
{
|
||||
int32 retVal = 0xffffff;
|
||||
if (ossirian)
|
||||
{
|
||||
for (uint32 debuff : OSSIRIAN_DEBUFFS)
|
||||
{
|
||||
if (AuraApplication* auraApplication = ossirian->GetAuraApplication(debuff))
|
||||
{
|
||||
if (Aura* aura = auraApplication->GetBase())
|
||||
{
|
||||
int32 duration = aura->GetDuration();
|
||||
if (retVal > duration)
|
||||
retVal = duration;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return retVal;
|
||||
}
|
||||
|
||||
GameObject* RaidAq20Utils::GetNearestCrystal(Unit* ossirian)
|
||||
{
|
||||
return ossirian ? ossirian->FindNearestGameObject(OSSIRIAN_CRYSTAL_GO_ENTRY, 200.0f) : nullptr;
|
||||
}
|
||||
15
src/strategy/raids/aq20/RaidAq20Utils.h
Normal file
15
src/strategy/raids/aq20/RaidAq20Utils.h
Normal file
@@ -0,0 +1,15 @@
|
||||
#ifndef _PLAYERBOT_RAIDAQ20UTILS_H
|
||||
#define _PLAYERBOT_RAIDAQ20UTILS_H
|
||||
|
||||
#include "GameObject.h"
|
||||
#include "Unit.h"
|
||||
|
||||
class RaidAq20Utils
|
||||
{
|
||||
public:
|
||||
static bool IsOssirianBuffActive(Unit* ossirian);
|
||||
static int32 GetOssirianDebuffTimeRemaining(Unit* ossirian);
|
||||
static GameObject* GetNearestCrystal(Unit* ossirian);
|
||||
};
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user