Skip to content
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
10 changes: 5 additions & 5 deletions src/modules/Bots/playerbot/PlayerbotFactory.h
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,11 @@ class PlayerbotFactory : public InventoryAction
*/
void Refresh();

/**
* @brief Initializes the pet for the player bot.
*/
void InitPet();

private:
/**
* @brief Randomizes the player bot with an option for incremental changes.
Expand Down Expand Up @@ -148,11 +153,6 @@ class PlayerbotFactory : public InventoryAction
*/
void InitQuests();

/**
* @brief Initializes the pet for the player bot.
*/
void InitPet();

/**
* @brief Clears the inventory of the player bot.
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ class GenericHunterNonCombatStrategyActionNodeFactory : public NamedObjectFactor
creators["rapid fire"] = &rapid_fire;
creators["boost"] = &rapid_fire;
creators["aspect of the pack"] = &aspect_of_the_pack;
creators["aspect of the viper"] = &aspect_of_the_viper;
}
private:
static ActionNode* rapid_fire(PlayerbotAI* ai)
Expand All @@ -29,6 +30,14 @@ class GenericHunterNonCombatStrategyActionNodeFactory : public NamedObjectFactor
/*A*/ NextAction::array(0, new NextAction("aspect of the cheetah"), NULL),
/*C*/ NULL);
}
// aspect of the viper doesn't exist in Vanilla 1.12 - fall back to drinking
static ActionNode* aspect_of_the_viper(PlayerbotAI* ai)
{
return new ActionNode ("aspect of the viper",
/*P*/ NULL,
/*A*/ NextAction::array(0, new NextAction("drink"), NULL),
/*C*/ NULL);
}
};

GenericHunterNonCombatStrategy::GenericHunterNonCombatStrategy(PlayerbotAI* ai) : NonCombatStrategy(ai)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,15 @@ void GenericHunterStrategy::InitTriggers(std::list<TriggerNode*> &triggers)

triggers.push_back(new TriggerNode(
"enemy too close for spell",
NextAction::array(0, new NextAction("wing clip", 50.0f), new NextAction("flee",49.0f), new NextAction("concussive shot", 48.0f), NULL)));
NextAction::array(0,
new NextAction("intimidation", 52.0f),
new NextAction("wing clip", 51.0f),
new NextAction("hunter ensure ranged position", 50.0f),
new NextAction("mongoose bite", 49.5f),
new NextAction("disengage", 49.0f),
new NextAction("hunter melee", 48.5f),
new NextAction("flee", 48.0f),
NULL)));

triggers.push_back(new TriggerNode(
"medium threat",
Expand All @@ -63,4 +71,9 @@ void GenericHunterStrategy::InitTriggers(std::list<TriggerNode*> &triggers)
triggers.push_back(new TriggerNode(
"rapid fire",
NextAction::array(0, new NextAction("rapid fire", 55.0f), NULL)));

triggers.push_back(new TriggerNode(
"bestial wrath",
NextAction::array(0, new NextAction("bestial wrath", 55.0f), NULL)));

}
44 changes: 44 additions & 0 deletions src/modules/Bots/playerbot/strategy/hunter/HunterActions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
#include "../../playerbot.h"
#include "../actions/GenericActions.h"
#include "HunterActions.h"
#include "../../PlayerbotFactory.h"

using namespace ai;

Expand All @@ -24,3 +25,46 @@ Value<Unit*>* CastFreezingTrap::GetTargetValue()
{
return context->GetValue<Unit*>("cc target", "freezing trap");
}

bool CastRevivePetAction::isPossible()
{
if (bot->GetPet())
return CastBuffSpellAction::isPossible();
PetDatabaseStatus status = Pet::GetStatusFromDB(bot);
return status == PET_DB_DEAD || status == PET_DB_NO_PET;
}

bool CastRevivePetAction::Execute(Event event)
{
if (!bot->GetPet() && Pet::GetStatusFromDB(bot) == PET_DB_NO_PET)
{
PlayerbotFactory factory(bot, bot->getLevel());
factory.InitPet();
return true;
}
return CastBuffSpellAction::Execute(event);
}

bool CastIntimidationAction::isUseful()
{
return CastSpellAction::isUseful() && AI_VALUE(Unit*, "pet target") != NULL;
}

bool HunterMeleeAction::isUseful()
{
// Only swing if enemy is already in our face AND targeting us.
// Perhaps in the future a ranged/melee hunter strategy would be nice.
Unit* target = AI_VALUE(Unit*, "current target");
if (!target || !target->IsAlive()) return false;
bool victim = target->getVictim() == bot;
float dist = AI_VALUE2(float, "distance", "current target");
return victim && dist <= ATTACK_DISTANCE;
}

bool HunterMeleeAction::Execute(Event event)
{
Unit* target = AI_VALUE(Unit*, "current target");
if (!target) return false;
bot->Attack(target, true);
return true;
}
67 changes: 66 additions & 1 deletion src/modules/Bots/playerbot/strategy/hunter/HunterActions.h
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,8 @@ namespace ai
{
public:
CastRevivePetAction(PlayerbotAI* ai) : CastBuffSpellAction(ai, "revive pet") {}
virtual bool isPossible();
virtual bool Execute(Event event);
};

class CastTrueshotAuraAction : public CastBuffSpellAction
Expand Down Expand Up @@ -120,7 +122,8 @@ namespace ai
CastWingClipAction(PlayerbotAI* ai) : CastMeleeSpellAction(ai, "wing clip") {}
virtual bool isUseful()
{
return CastMeleeSpellAction::isUseful() && !ai->HasAura(spell, GetTarget());
Unit* target = GetTarget();
return target && target->IsAlive() && CastMeleeSpellAction::isUseful() && !ai->HasAura(spell, target);
}
};

Expand All @@ -129,4 +132,66 @@ namespace ai
public:
CastSerpentStingOnAttackerAction(PlayerbotAI* ai) : CastDebuffSpellOnAttackerAction(ai, "serpent sting") {}
};

BEGIN_MELEE_SPELL_ACTION(CastDisengageAction, "disengage")
END_SPELL_ACTION()

BEGIN_MELEE_SPELL_ACTION(CastImmolationTrapAction, "immolation trap")
END_SPELL_ACTION()

BEGIN_MELEE_SPELL_ACTION(CastFrostTrapAction, "frost trap")
END_SPELL_ACTION()

BEGIN_MELEE_SPELL_ACTION(CastExplosiveTrapAction, "explosive trap")
END_SPELL_ACTION()

BEGIN_RANGED_SPELL_ACTION(CastScatterShotAction, "scatter shot")
END_SPELL_ACTION()

class CastBestialWrathAction : public CastAuraSpellAction
{
public:
CastBestialWrathAction(PlayerbotAI* ai) : CastAuraSpellAction(ai, "bestial wrath") {}
virtual string GetTargetName() { return "pet target"; }
virtual bool isUseful() { return CastAuraSpellAction::isUseful() && AI_VALUE(Unit*, "pet target") != NULL; }
};

class CastMongooseBiteAction : public CastMeleeSpellAction
{
public:
CastMongooseBiteAction(PlayerbotAI* ai) : CastMeleeSpellAction(ai, "mongoose bite") {}
virtual bool isPossible() { return bot->HasAuraState(AURA_STATE_DEFENSE) && CastMeleeSpellAction::isPossible(); }
};

class CastIntimidationAction : public CastSpellAction
{
public:
CastIntimidationAction(PlayerbotAI* ai) : CastSpellAction(ai, "intimidation") {}
virtual bool isUseful();
};

class HunterMeleeAction : public Action
{
public:
HunterMeleeAction(PlayerbotAI* ai) : Action(ai, "hunter melee") {}
virtual bool Execute(Event event);
virtual bool isUseful();
};

class HunterEnsureRangedPositionAction : public MovementAction
{
public:
HunterEnsureRangedPositionAction(PlayerbotAI* ai) : MovementAction(ai, "hunter ensure ranged position") {}
virtual bool Execute(Event event)
{
return MoveTo(AI_VALUE(Unit*, "current target"), sPlayerbotAIConfig.spellDistance);
}
virtual bool isUseful()
{
Unit* target = AI_VALUE(Unit*, "current target");
if (!target || !target->IsAlive()) return false;
return target->getVictim() != bot &&
bot->GetDistance(target) < sPlayerbotAIConfig.spellDistance;
}
};
}
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ namespace ai
creators["freezing trap"] = &TriggerFactoryInternal::freezing_trap;
creators["aspect of the pack"] = &TriggerFactoryInternal::aspect_of_the_pack;
creators["rapid fire"] = &TriggerFactoryInternal::rapid_fire;
creators["bestial wrath"] = &TriggerFactoryInternal::bestial_wrath;
creators["aspect of the hawk"] = &TriggerFactoryInternal::aspect_of_the_hawk;
creators["aspect of the wild"] = &TriggerFactoryInternal::aspect_of_the_wild;
creators["aspect of the viper"] = &TriggerFactoryInternal::aspect_of_the_viper;
Expand All @@ -95,6 +96,7 @@ namespace ai
static Trigger* freezing_trap(PlayerbotAI* ai) { return new FreezingTrapTrigger(ai); }
static Trigger* aspect_of_the_pack(PlayerbotAI* ai) { return new HunterAspectOfThePackTrigger(ai); }
static Trigger* rapid_fire(PlayerbotAI* ai) { return new RapidFireTrigger(ai); }
static Trigger* bestial_wrath(PlayerbotAI* ai) { return new BestialWrathTrigger(ai); }
static Trigger* aspect_of_the_hawk(PlayerbotAI* ai) { return new HunterAspectOfTheHawkTrigger(ai); }
static Trigger* aspect_of_the_wild(PlayerbotAI* ai) { return new HunterAspectOfTheWildTrigger(ai); }
};
Expand Down Expand Up @@ -141,6 +143,16 @@ namespace ai
creators["trueshot aura"] = &AiObjectContextInternal::trueshot_aura;
creators["feign death"] = &AiObjectContextInternal::feign_death;
creators["wing clip"] = &AiObjectContextInternal::wing_clip;
creators["disengage"] = &AiObjectContextInternal::disengage;
creators["immolation trap"] = &AiObjectContextInternal::immolation_trap;
creators["frost trap"] = &AiObjectContextInternal::frost_trap;
creators["explosive trap"] = &AiObjectContextInternal::explosive_trap;
creators["scatter shot"] = &AiObjectContextInternal::scatter_shot;
creators["bestial wrath"] = &AiObjectContextInternal::bestial_wrath;
creators["mongoose bite"] = &AiObjectContextInternal::mongoose_bite;
creators["intimidation"] = &AiObjectContextInternal::intimidation;
creators["hunter melee"] = &AiObjectContextInternal::hunter_melee;
creators["hunter ensure ranged position"] = &AiObjectContextInternal::hunter_ensure_ranged_position;
}

private:
Expand All @@ -167,6 +179,16 @@ namespace ai
static Action* rapid_fire(PlayerbotAI* ai) { return new CastRapidFireAction(ai); }
static Action* aspect_of_the_hawk(PlayerbotAI* ai) { return new CastAspectOfTheHawkAction(ai); }
static Action* aspect_of_the_wild(PlayerbotAI* ai) { return new CastAspectOfTheWildAction(ai); }
static Action* disengage(PlayerbotAI* ai) { return new CastDisengageAction(ai); }
static Action* immolation_trap(PlayerbotAI* ai) { return new CastImmolationTrapAction(ai); }
static Action* frost_trap(PlayerbotAI* ai) { return new CastFrostTrapAction(ai); }
static Action* explosive_trap(PlayerbotAI* ai) { return new CastExplosiveTrapAction(ai); }
static Action* scatter_shot(PlayerbotAI* ai) { return new CastScatterShotAction(ai); }
static Action* bestial_wrath(PlayerbotAI* ai) { return new CastBestialWrathAction(ai); }
static Action* mongoose_bite(PlayerbotAI* ai) { return new CastMongooseBiteAction(ai); }
static Action* intimidation(PlayerbotAI* ai) { return new CastIntimidationAction(ai); }
static Action* hunter_melee(PlayerbotAI* ai) { return new HunterMeleeAction(ai); }
static Action* hunter_ensure_ranged_position(PlayerbotAI* ai) { return new HunterEnsureRangedPositionAction(ai); }
static Action* aspect_of_the_pack(PlayerbotAI* ai) { return new CastAspectOfThePackAction(ai); }
static Action* aspect_of_the_cheetah(PlayerbotAI* ai) { return new CastAspectOfTheCheetahAction(ai); }
static Action* wing_clip(PlayerbotAI* ai) { return new CastWingClipAction(ai); }
Expand Down
10 changes: 9 additions & 1 deletion src/modules/Bots/playerbot/strategy/hunter/HunterTriggers.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,16 @@ bool HunterNoStingsActiveTrigger::IsActive()

bool HuntersPetDeadTrigger::IsActive()
{
if (AI_VALUE2(bool, "mounted", "self target"))
return false;

Unit* pet = AI_VALUE(Unit*, "pet target");
return pet && AI_VALUE2(bool, "dead", "pet target") && !AI_VALUE2(bool, "mounted", "self target");
if (pet)
return AI_VALUE2(bool, "dead", "pet target");

// Pet not in world — check DB to catch the common case where the corpse timer has already expired
PetDatabaseStatus status = Pet::GetStatusFromDB(bot);
return status == PET_DB_DEAD || status == PET_DB_NO_PET;
}


Expand Down
7 changes: 7 additions & 0 deletions src/modules/Bots/playerbot/strategy/hunter/HunterTriggers.h
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,12 @@ namespace ai
RapidFireTrigger(PlayerbotAI* ai) : BoostTrigger(ai, "rapid fire") {}
};

class BestialWrathTrigger : public BoostTrigger
{
public:
BestialWrathTrigger(PlayerbotAI* ai) : BoostTrigger(ai, "bestial wrath") {}
};

class TrueshotAuraTrigger : public BuffTrigger
{
public:
Expand All @@ -83,4 +89,5 @@ namespace ai
public:
SerpentStingOnAttackerTrigger(PlayerbotAI* ai) : DebuffOnAttackerTrigger(ai, "serpent sting") {}
};

}
Loading