mirror of
https://github.com/mod-playerbots/mod-playerbots
synced 2025-11-29 15:58:20 +08:00
fix party member dispel.
This commit is contained in:
@@ -2568,7 +2568,7 @@ bool PlayerbotAI::HasAuraToDispel(Unit* target, uint32 dispelType)
|
||||
continue;
|
||||
|
||||
if (sPlayerbotAIConfig->dispelAuraDuration && aura->GetDuration() && aura->GetDuration() < (int32)sPlayerbotAIConfig->dispelAuraDuration)
|
||||
return false;
|
||||
continue;
|
||||
|
||||
if (canDispel(spellInfo, dispelType))
|
||||
return true;
|
||||
@@ -2946,7 +2946,7 @@ void PlayerbotAI::RemoveShapeshift()
|
||||
RemoveAura("swift flight form");
|
||||
RemoveAura("aquatic form");
|
||||
RemoveAura("ghost wolf");
|
||||
RemoveAura("tree of life");
|
||||
// RemoveAura("tree of life");
|
||||
}
|
||||
|
||||
uint32 PlayerbotAI::GetEquipGearScore(Player* player, bool withBags, bool withBank)
|
||||
|
||||
@@ -219,6 +219,8 @@ class ActionContext : public NamedObjectContext<Action>
|
||||
creators["rpg trade useful"] = &ActionContext::rpg_trade_useful;
|
||||
creators["rpg duel"] = &ActionContext::rpg_duel;
|
||||
creators["rpg mount anim"] = &ActionContext::rpg_mount_anim;
|
||||
|
||||
creators["toggle pet spell"] = &ActionContext::toggle_pet_spell;
|
||||
}
|
||||
|
||||
private:
|
||||
@@ -378,6 +380,8 @@ class ActionContext : public NamedObjectContext<Action>
|
||||
static Action* rpg_trade_useful(PlayerbotAI* botAI) { return new RpgTradeUsefulAction(botAI); }
|
||||
static Action* rpg_duel(PlayerbotAI* botAI) { return new RpgDuelAction(botAI); }
|
||||
static Action* rpg_mount_anim(PlayerbotAI* botAI) { return new RpgMountAnimAction(botAI); }
|
||||
|
||||
static Action* toggle_pet_spell(PlayerbotAI* ai) { return new TogglePetSpellAutoCastAction(ai); }
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -85,6 +85,7 @@ class ChatActionContext : public NamedObjectContext<Action>
|
||||
creators["reputation"] = &ChatActionContext::reputation;
|
||||
creators["log"] = &ChatActionContext::log;
|
||||
creators["los"] = &ChatActionContext::los;
|
||||
creators["aura"] = &ChatActionContext::aura;
|
||||
creators["drop"] = &ChatActionContext::drop;
|
||||
creators["clean quest log"] = &ChatActionContext::clean_quest_log;
|
||||
creators["share"] = &ChatActionContext::share;
|
||||
@@ -238,6 +239,7 @@ class ChatActionContext : public NamedObjectContext<Action>
|
||||
static Action* reputation(PlayerbotAI* botAI) { return new TellReputationAction(botAI); }
|
||||
static Action* log(PlayerbotAI* botAI) { return new LogLevelAction(botAI); }
|
||||
static Action* los(PlayerbotAI* botAI) { return new TellLosAction(botAI); }
|
||||
static Action* aura(PlayerbotAI* ai) { return new TellAuraAction(ai); }
|
||||
static Action* ll(PlayerbotAI* botAI) { return new LootStrategyAction(botAI); }
|
||||
static Action* ss(PlayerbotAI* botAI) { return new SkipSpellsListAction(botAI); }
|
||||
static Action* add_all_loot(PlayerbotAI* botAI) { return new AddAllLootAction(botAI); }
|
||||
|
||||
@@ -13,3 +13,30 @@ bool MeleeAction::isUseful()
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool TogglePetSpellAutoCastAction::Execute(Event event) {
|
||||
Pet* pet = bot->GetPet();
|
||||
if (!pet) {
|
||||
return false;
|
||||
}
|
||||
for (PetSpellMap::const_iterator itr = pet->m_spells.begin(); itr != pet->m_spells.end(); ++itr)
|
||||
{
|
||||
if(itr->second.state == PETSPELL_REMOVED)
|
||||
continue;
|
||||
|
||||
uint32 spellId = itr->first;
|
||||
const SpellInfo* spellInfo = sSpellMgr->GetSpellInfo(spellId);
|
||||
if (spellInfo->IsPassive())
|
||||
continue;
|
||||
|
||||
// imp's spell, felhunte's intelligence, ghoul's leap
|
||||
if (spellId == 4511 || spellId == 1742 ||
|
||||
spellId == 54424 || spellId == 57564 || spellId == 57565 || spellId == 57566 || spellId == 57567 ||
|
||||
spellId == 47482) {
|
||||
pet->ToggleAutocast(spellInfo, false);
|
||||
} else {
|
||||
pet->ToggleAutocast(spellInfo, true);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@@ -18,4 +18,11 @@ class MeleeAction : public AttackAction
|
||||
bool isUseful() override;
|
||||
};
|
||||
|
||||
class TogglePetSpellAutoCastAction: public Action
|
||||
{
|
||||
public:
|
||||
TogglePetSpellAutoCastAction(PlayerbotAI* ai): Action(ai, "toggle pet spell") {}
|
||||
virtual bool Execute(Event event) override;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -61,3 +61,68 @@ void TellLosAction::ListGameObjects(std::string const title, GuidVector gos)
|
||||
botAI->TellMaster(chat->FormatGameobject(go));
|
||||
}
|
||||
}
|
||||
|
||||
bool TellAuraAction::Execute(Event event)
|
||||
{
|
||||
botAI->TellMaster("--- Auras ---");
|
||||
sLog->outMessage("playerbot", LOG_LEVEL_DEBUG, "--- Auras ---");
|
||||
Unit::AuraApplicationMap& map = bot->GetAppliedAuras();
|
||||
for (Unit::AuraApplicationMap::iterator i = map.begin(); i != map.end(); ++i)
|
||||
{
|
||||
Aura * aura = i->second->GetBase();
|
||||
if (!aura)
|
||||
continue;
|
||||
|
||||
const std::string auraName = aura->GetSpellInfo()->SpellName[0];
|
||||
sLog->outMessage("playerbot", LOG_LEVEL_DEBUG, "Info of Aura - name: " + auraName);
|
||||
AuraObjectType type = aura->GetType();
|
||||
WorldObject* owner = aura->GetOwner();
|
||||
std::string owner_name = owner ? owner->GetName() : "unknown";
|
||||
float distance = bot->GetDistance2d(owner);
|
||||
Unit* caster = aura->GetCaster();
|
||||
std::string caster_name = caster ? caster->GetName() : "unknown";
|
||||
bool is_area = aura->IsArea();
|
||||
int32 duration = aura->GetDuration();
|
||||
const SpellInfo* spellInfo = aura->GetSpellInfo();
|
||||
int32 spellId = aura->GetSpellInfo()->Id;
|
||||
bool isPositive = aura->GetSpellInfo()->IsPositive();
|
||||
sLog->outMessage("playerbot", LOG_LEVEL_DEBUG, "Info of Aura - name: " + auraName +
|
||||
" caster: " + caster_name +
|
||||
" type: " + std::to_string(type) +
|
||||
" owner: " + owner_name +
|
||||
" distance: " + std::to_string(distance) +
|
||||
" isArea: " + std::to_string(is_area) +
|
||||
" duration: " + std::to_string(duration) +
|
||||
" spellId: " + std::to_string(spellId) +
|
||||
" isPositive: " + std::to_string(isPositive));
|
||||
|
||||
botAI->TellMaster("Info of Aura - name: " + auraName +
|
||||
" caster: " + caster_name +
|
||||
" type: " + std::to_string(type) +
|
||||
" owner: " + owner_name +
|
||||
" distance: " + std::to_string(distance) +
|
||||
" isArea: " + std::to_string(is_area) +
|
||||
" duration: " + std::to_string(duration) +
|
||||
" spellId: " + std::to_string(spellId) +
|
||||
" isPositive: " + std::to_string(isPositive));
|
||||
|
||||
if (type == DYNOBJ_AURA_TYPE) {
|
||||
DynamicObject* dyn_owner = aura->GetDynobjOwner();
|
||||
float radius = dyn_owner->GetRadius();
|
||||
int32 spellId = dyn_owner->GetSpellId();
|
||||
int32 duration = dyn_owner->GetDuration();
|
||||
sLog->outMessage("playerbot", LOG_LEVEL_DEBUG, std::string("Info of DynamicObject -") +
|
||||
" name: " + dyn_owner->GetName() +
|
||||
" radius: " + std::to_string(radius) +
|
||||
" spell id: " + std::to_string(spellId) +
|
||||
" duration: " + std::to_string(duration));
|
||||
|
||||
botAI->TellMaster(std::string("Info of DynamicObject -") +
|
||||
" name: " + dyn_owner->GetName() +
|
||||
" radius: " + std::to_string(radius) +
|
||||
" spell id: " + std::to_string(spellId) +
|
||||
" duration: " + std::to_string(duration));
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@@ -21,4 +21,11 @@ class TellLosAction : public Action
|
||||
void ListGameObjects(std::string const title, GuidVector gos);
|
||||
};
|
||||
|
||||
class TellAuraAction : public Action
|
||||
{
|
||||
public:
|
||||
TellAuraAction(PlayerbotAI* ai) : Action(ai, "aura") {}
|
||||
|
||||
virtual bool Execute(Event event);
|
||||
};
|
||||
#endif
|
||||
|
||||
@@ -44,9 +44,10 @@ void GenericDKNonCombatStrategy::InitTriggers(std::vector<TriggerNode*>& trigger
|
||||
triggers.push_back(new TriggerNode("no pet", NextAction::array(0, new NextAction("raise dead", ACTION_NORMAL + 1), nullptr)));
|
||||
triggers.push_back(new TriggerNode("horn of winter", NextAction::array(0, new NextAction("horn of winter", 21.0f), nullptr)));
|
||||
triggers.push_back(new TriggerNode("bone shield", NextAction::array(0, new NextAction("bone shield", 21.0f), nullptr)));
|
||||
triggers.push_back(new TriggerNode("has pet", NextAction::array(0, new NextAction("toggle pet spell", 11.0f), NULL)));
|
||||
}
|
||||
|
||||
void DKBuffDpsStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
|
||||
{
|
||||
triggers.push_back(new TriggerNode("improved icy talons", NextAction::array(0, new NextAction("improved icy talons", 19.0f), nullptr)));
|
||||
// triggers.push_back(new TriggerNode("improved icy talons", NextAction::array(0, new NextAction("improved icy talons", 19.0f), nullptr)));
|
||||
}
|
||||
|
||||
@@ -236,4 +236,21 @@ class CastNaturesSwiftnessAction : public CastBuffSpellAction
|
||||
CastNaturesSwiftnessAction(PlayerbotAI* botAI) : CastBuffSpellAction(botAI, "nature's swiftness") { }
|
||||
};
|
||||
|
||||
class CastWildGrowthOnPartyAction : public HealPartyMemberAction
|
||||
{
|
||||
public:
|
||||
CastWildGrowthOnPartyAction(PlayerbotAI* ai) : HealPartyMemberAction(ai, "wild growth") {}
|
||||
};
|
||||
|
||||
class CastPartySwiftmendAction : public HealPartyMemberAction
|
||||
{
|
||||
public:
|
||||
CastPartySwiftmendAction(PlayerbotAI* ai) : HealPartyMemberAction(ai, "swiftmend") {}
|
||||
};
|
||||
|
||||
class CastPartyNourishAction : public HealPartyMemberAction
|
||||
{
|
||||
public:
|
||||
CastPartyNourishAction(PlayerbotAI* ai) : HealPartyMemberAction(ai, "nourish") {}
|
||||
};
|
||||
#endif
|
||||
|
||||
@@ -199,6 +199,9 @@ class DruidAiObjectContextInternal : public NamedObjectContext<Action>
|
||||
creators["shred"] = &DruidAiObjectContextInternal::shred;
|
||||
creators["ravage"] = &DruidAiObjectContextInternal::ravage;
|
||||
creators["pounce"] = &DruidAiObjectContextInternal::pounce;
|
||||
creators["wild growth on party"] = &DruidAiObjectContextInternal::wild_growth_on_party;
|
||||
creators["swiftmend on party"] = &DruidAiObjectContextInternal::swiftmend_on_party;
|
||||
creators["nourish on party"] = &DruidAiObjectContextInternal::nourish_on_party;
|
||||
}
|
||||
|
||||
private:
|
||||
@@ -270,6 +273,9 @@ class DruidAiObjectContextInternal : public NamedObjectContext<Action>
|
||||
static Action* prowl(PlayerbotAI* botAI) { return new CastProwlAction(botAI); }
|
||||
static Action* dash(PlayerbotAI* botAI) { return new CastDashAction(botAI); }
|
||||
static Action* shred(PlayerbotAI* botAI) { return new CastShredAction(botAI); }
|
||||
static Action* wild_growth_on_party(PlayerbotAI* ai) { return new CastWildGrowthOnPartyAction(ai); }
|
||||
static Action* swiftmend_on_party(PlayerbotAI *ai) { return new CastPartySwiftmendAction(ai); }
|
||||
static Action* nourish_on_party(PlayerbotAI *ai) { return new CastPartyNourishAction(ai); }
|
||||
};
|
||||
|
||||
DruidAiObjectContext::DruidAiObjectContext(PlayerbotAI* botAI) : AiObjectContext(botAI)
|
||||
|
||||
@@ -39,3 +39,8 @@ bool CastCasterFormAction::Execute(Event event)
|
||||
botAI->RemoveShapeshift();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CastTreeFormAction::isUseful() {
|
||||
return GetTarget() && (GetTarget() != nullptr) && (GetTarget() != nullptr) &&
|
||||
CastSpellAction::isUseful() && !botAI->HasAura(33891, bot);
|
||||
}
|
||||
@@ -36,6 +36,7 @@ class CastTreeFormAction : public CastBuffSpellAction
|
||||
{
|
||||
public:
|
||||
CastTreeFormAction(PlayerbotAI* botAI) : CastBuffSpellAction(botAI, "tree of life") { }
|
||||
bool isUseful() override;
|
||||
};
|
||||
|
||||
class CastMoonkinFormAction : public CastBuffSpellAction
|
||||
|
||||
@@ -42,7 +42,7 @@ bool BearFormTrigger::IsActive()
|
||||
|
||||
bool TreeFormTrigger::IsActive()
|
||||
{
|
||||
return !botAI->HasAura("tree of life", bot);
|
||||
return !botAI->HasAura(33891, bot);
|
||||
}
|
||||
|
||||
bool CatFormTrigger::IsActive()
|
||||
|
||||
@@ -14,7 +14,7 @@ class GenericDruidNonCombatStrategyActionNodeFactory : public NamedObjectFactory
|
||||
creators["thorns on party"] = þs_on_party;
|
||||
creators["mark of the wild"] = &mark_of_the_wild;
|
||||
creators["mark of the wild on party"] = &mark_of_the_wild_on_party;
|
||||
creators["innervate"] = &innervate;
|
||||
// creators["innervate"] = &innervate;
|
||||
}
|
||||
|
||||
private:
|
||||
@@ -50,13 +50,13 @@ class GenericDruidNonCombatStrategyActionNodeFactory : public NamedObjectFactory
|
||||
/*C*/ nullptr);
|
||||
}
|
||||
|
||||
static ActionNode* innervate([[maybe_unused]] PlayerbotAI* botAI)
|
||||
{
|
||||
return new ActionNode ("innervate",
|
||||
/*P*/ nullptr,
|
||||
/*A*/ NextAction::array(0, new NextAction("drink"), nullptr),
|
||||
/*C*/ nullptr);
|
||||
}
|
||||
// static ActionNode* innervate([[maybe_unused]] PlayerbotAI* botAI)
|
||||
// {
|
||||
// return new ActionNode ("innervate",
|
||||
// /*P*/ nullptr,
|
||||
// /*A*/ NextAction::array(0, new NextAction("drink"), nullptr),
|
||||
// /*C*/ nullptr);
|
||||
// }
|
||||
};
|
||||
|
||||
GenericDruidNonCombatStrategy::GenericDruidNonCombatStrategy(PlayerbotAI* botAI) : NonCombatStrategy(botAI)
|
||||
@@ -70,12 +70,27 @@ void GenericDruidNonCombatStrategy::InitTriggers(std::vector<TriggerNode*>& trig
|
||||
|
||||
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("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", 22.0f), 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("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(new TriggerNode("party member critical health",
|
||||
NextAction::array(0, new NextAction("rejuvenation on party", ACTION_MEDIUM_HEAL + 5),
|
||||
new NextAction("regrowth on party", ACTION_MEDIUM_HEAL + 6), NULL)));
|
||||
|
||||
triggers.push_back(new TriggerNode("party member low health",
|
||||
NextAction::array(0, new NextAction("rejuvenation on party", ACTION_MEDIUM_HEAL + 3),
|
||||
new NextAction("regrowth on party", ACTION_MEDIUM_HEAL + 4), NULL)));
|
||||
|
||||
triggers.push_back(new TriggerNode("party member medium health",
|
||||
NextAction::array(0, new NextAction("rejuvenation on party", ACTION_MEDIUM_HEAL + 1),
|
||||
new NextAction("regrowth on party", ACTION_MEDIUM_HEAL + 2), NULL)));
|
||||
|
||||
triggers.push_back(new TriggerNode("party member almost full health",
|
||||
NextAction::array(0, new NextAction("rejuvenation on party", ACTION_LIGHT_HEAL + 2), NULL)));
|
||||
}
|
||||
|
||||
GenericDruidBuffStrategy::GenericDruidBuffStrategy(PlayerbotAI* botAI) : NonCombatStrategy(botAI)
|
||||
|
||||
@@ -104,17 +104,17 @@ void GenericDruidStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
|
||||
{
|
||||
CombatStrategy::InitTriggers(triggers);
|
||||
|
||||
triggers.push_back(new TriggerNode("low health", NextAction::array(0, new NextAction("regrowth", ACTION_MEDIUM_HEAL + 2), nullptr)));
|
||||
triggers.push_back(new TriggerNode("party member low health", NextAction::array(0, new NextAction("regrowth on party", ACTION_MEDIUM_HEAL + 1), nullptr)));
|
||||
triggers.push_back(new TriggerNode("critical health", NextAction::array(0, new NextAction("regrowth", ACTION_CRITICAL_HEAL + 2), new NextAction("healing touch", ACTION_CRITICAL_HEAL + 2), nullptr)));
|
||||
triggers.push_back(new TriggerNode("party member critical health", NextAction::array(0, new NextAction("regrowth on party", ACTION_CRITICAL_HEAL + 1), new NextAction("healing touch on party", ACTION_CRITICAL_HEAL + 1), nullptr)));
|
||||
triggers.push_back(new TriggerNode("party member dead", NextAction::array(0, new NextAction("rebirth", ACTION_HIGH + 1), nullptr)));
|
||||
triggers.push_back(new TriggerNode("low mana", NextAction::array(0, new NextAction("innervate", ACTION_EMERGENCY + 5), nullptr)));
|
||||
// triggers.push_back(new TriggerNode("low health", NextAction::array(0, new NextAction("regrowth", ACTION_MEDIUM_HEAL + 2), nullptr)));
|
||||
// triggers.push_back(new TriggerNode("party member low health", NextAction::array(0, new NextAction("regrowth on party", ACTION_MEDIUM_HEAL + 1), nullptr)));
|
||||
// triggers.push_back(new TriggerNode("critical health", NextAction::array(0, new NextAction("regrowth", ACTION_CRITICAL_HEAL + 2), new NextAction("healing touch", ACTION_CRITICAL_HEAL + 2), nullptr)));
|
||||
// triggers.push_back(new TriggerNode("party member critical health", NextAction::array(0, new NextAction("regrowth on party", ACTION_CRITICAL_HEAL + 1), new NextAction("healing touch on party", ACTION_CRITICAL_HEAL + 1), nullptr)));
|
||||
// triggers.push_back(new TriggerNode("party member dead", NextAction::array(0, new NextAction("rebirth", ACTION_HIGH + 1), nullptr)));
|
||||
// triggers.push_back(new TriggerNode("low mana", NextAction::array(0, new NextAction("innervate", ACTION_EMERGENCY + 5), nullptr)));
|
||||
}
|
||||
|
||||
void DruidCureStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
|
||||
{
|
||||
triggers.push_back(new TriggerNode("cure poison", NextAction::array(0, new NextAction("abolish poison", ACTION_DISPEL + 2), nullptr)));
|
||||
// triggers.push_back(new TriggerNode("cure poison", NextAction::array(0, new NextAction("abolish poison", ACTION_DISPEL + 2), nullptr)));
|
||||
triggers.push_back(new TriggerNode("party member cure poison", NextAction::array(0, new NextAction("abolish poison on party", ACTION_DISPEL + 1), nullptr)));
|
||||
}
|
||||
|
||||
|
||||
@@ -22,10 +22,58 @@ void HealDruidStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
|
||||
|
||||
triggers.push_back(new TriggerNode("enemy out of spell", NextAction::array(0, new NextAction("reach spell", ACTION_NORMAL + 9), nullptr)));
|
||||
triggers.push_back(new TriggerNode("tree form", NextAction::array(0, new NextAction("tree form", ACTION_HIGH + 1), nullptr)));
|
||||
triggers.push_back(new TriggerNode("medium health", NextAction::array(0, new NextAction("regrowth", ACTION_MEDIUM_HEAL + 2), nullptr)));
|
||||
triggers.push_back(new TriggerNode("party member medium health", NextAction::array(0, new NextAction("regrowth on party", ACTION_MEDIUM_HEAL + 1), nullptr)));
|
||||
triggers.push_back(new TriggerNode("almost full health", NextAction::array(0, new NextAction("rejuvenation", ACTION_LIGHT_HEAL + 2), nullptr)));
|
||||
triggers.push_back(new TriggerNode("party member almost full health", NextAction::array(0, new NextAction("rejuvenation on party", ACTION_LIGHT_HEAL + 1), nullptr)));
|
||||
triggers.push_back(new TriggerNode("medium aoe heal", NextAction::array(0, new NextAction("tranquility", ACTION_MEDIUM_HEAL + 3), nullptr)));
|
||||
triggers.push_back(new TriggerNode("party member to heal out of spell range", NextAction::array(0, new NextAction("reach party member to heal", ACTION_CRITICAL_HEAL + 1), nullptr)));
|
||||
triggers.push_back(new TriggerNode("party member to heal out of spell range", NextAction::array(0, new NextAction("reach party member to heal", ACTION_CRITICAL_HEAL + 9), nullptr)));
|
||||
|
||||
// CRITICAL
|
||||
triggers.push_back(new TriggerNode(
|
||||
"party member critical health",
|
||||
NextAction::array(0,
|
||||
new NextAction("swiftmend on party", ACTION_CRITICAL_HEAL + 3),
|
||||
new NextAction("wild growth", ACTION_CRITICAL_HEAL + 2),
|
||||
new NextAction("nourish on party", ACTION_CRITICAL_HEAL + 1),
|
||||
// new NextAction("healing touch on party", ACTION_CRITICAL_HEAL + 0),
|
||||
NULL)));
|
||||
|
||||
triggers.push_back(new TriggerNode(
|
||||
"party member critical health",
|
||||
NextAction::array(0, new NextAction("nature's swiftness", ACTION_CRITICAL_HEAL + 4), NULL)));
|
||||
|
||||
triggers.push_back(new TriggerNode(
|
||||
"group heal occasion",
|
||||
NextAction::array(0, new NextAction("tranquility", ACTION_CRITICAL_HEAL + 5), NULL)));
|
||||
|
||||
// LOW
|
||||
triggers.push_back(new TriggerNode(
|
||||
"party member low health",
|
||||
NextAction::array(0, new NextAction("wild growth on party", ACTION_MEDIUM_HEAL + 9),
|
||||
new NextAction("regrowth on party", ACTION_MEDIUM_HEAL + 8),
|
||||
new NextAction("swiftmend on party", ACTION_MEDIUM_HEAL + 7),
|
||||
new NextAction("nourish on party", ACTION_MEDIUM_HEAL + 6),
|
||||
// new NextAction("healing touch on party", ACTION_MEDIUM_HEAL + 5),
|
||||
NULL)));
|
||||
|
||||
// MEDIUM
|
||||
triggers.push_back(new TriggerNode(
|
||||
"party member medium health",
|
||||
NextAction::array(0, new NextAction("wild growth on party", ACTION_MEDIUM_HEAL + 4),
|
||||
new NextAction("rejuvenation on party", ACTION_MEDIUM_HEAL + 3),
|
||||
new NextAction("regrowth on party", ACTION_MEDIUM_HEAL + 2),
|
||||
new NextAction("nourish on party", ACTION_MEDIUM_HEAL + 1),
|
||||
NULL)));
|
||||
|
||||
// almost full
|
||||
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),
|
||||
new NextAction("regrowth on party", ACTION_LIGHT_HEAL + 1),
|
||||
NULL)));
|
||||
|
||||
triggers.push_back(new TriggerNode(
|
||||
"medium mana",
|
||||
NextAction::array(0, new NextAction("innervate", ACTION_HIGH + 5), NULL)));
|
||||
|
||||
triggers.push_back(new TriggerNode(
|
||||
"enemy too close for spell",
|
||||
NextAction::array(0, new NextAction("flee", 49.0f), NULL)));
|
||||
}
|
||||
|
||||
@@ -70,6 +70,7 @@ ChatCommandHandlerStrategy::ChatCommandHandlerStrategy(PlayerbotAI* botAI) : Pas
|
||||
supported.push_back("reputation");
|
||||
supported.push_back("log");
|
||||
supported.push_back("los");
|
||||
supported.push_back("aura");
|
||||
supported.push_back("drop");
|
||||
supported.push_back("share");
|
||||
supported.push_back("ll");
|
||||
|
||||
@@ -52,6 +52,7 @@ 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("pet not happy", NextAction::array(0, new NextAction("feed pet", 60.0f), nullptr)));
|
||||
triggers.push_back(new TriggerNode("hunters pet low 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)));
|
||||
|
||||
@@ -22,6 +22,7 @@ class ChatTriggerContext : public NamedObjectContext<Trigger>
|
||||
creators["reputation"] = &ChatTriggerContext::reputation;
|
||||
creators["log"] = &ChatTriggerContext::log;
|
||||
creators["los"] = &ChatTriggerContext::los;
|
||||
creators["aura"] = &ChatTriggerContext::aura;
|
||||
creators["drop"] = &ChatTriggerContext::drop;
|
||||
creators["share"] = &ChatTriggerContext::share;
|
||||
creators["q"] = &ChatTriggerContext::q;
|
||||
@@ -187,6 +188,7 @@ class ChatTriggerContext : public NamedObjectContext<Trigger>
|
||||
static Trigger* reputation(PlayerbotAI* botAI) { return new ChatCommandTrigger(botAI, "reputation"); }
|
||||
static Trigger* log(PlayerbotAI* botAI) { return new ChatCommandTrigger(botAI, "log"); }
|
||||
static Trigger* los(PlayerbotAI* botAI) { return new ChatCommandTrigger(botAI, "los"); }
|
||||
static Trigger* aura(PlayerbotAI* ai) { return new ChatCommandTrigger(ai, "aura"); }
|
||||
static Trigger* loot_all(PlayerbotAI* botAI) { return new ChatCommandTrigger(botAI, "add all loot"); }
|
||||
static Trigger* release(PlayerbotAI* botAI) { return new ChatCommandTrigger(botAI, "release"); }
|
||||
static Trigger* reset_ai(PlayerbotAI* botAI) { return new ChatCommandTrigger(botAI, "reset botAI"); }
|
||||
|
||||
@@ -13,7 +13,7 @@ class Unit;
|
||||
class NeedCureTrigger : public SpellTrigger
|
||||
{
|
||||
public:
|
||||
NeedCureTrigger(PlayerbotAI* botAI, std::string const spell, uint32 dispelType) : SpellTrigger(botAI, spell, 5), dispelType(dispelType) { }
|
||||
NeedCureTrigger(PlayerbotAI* botAI, std::string const spell, uint32 dispelType) : SpellTrigger(botAI, spell, 1), dispelType(dispelType) { }
|
||||
|
||||
std::string const GetTargetName() override { return "self target"; }
|
||||
bool IsActive() override;
|
||||
|
||||
@@ -21,6 +21,10 @@ bool NoPetTrigger::IsActive()
|
||||
return !AI_VALUE(Unit*, "pet target") && !AI_VALUE2(bool, "mounted", "self target");
|
||||
}
|
||||
|
||||
bool HasPetTrigger::IsActive() {
|
||||
return AI_VALUE(Unit*, "pet target") && !AI_VALUE2(bool, "mounted", "self target");;
|
||||
}
|
||||
|
||||
bool HighManaTrigger::IsActive()
|
||||
{
|
||||
return AI_VALUE2(bool, "has mana", "self target") && AI_VALUE2(uint8, "mana", "self target") < 65;
|
||||
|
||||
@@ -418,6 +418,14 @@ class NoPetTrigger : public Trigger
|
||||
bool IsActive() override;
|
||||
};
|
||||
|
||||
class HasPetTrigger : public Trigger
|
||||
{
|
||||
public:
|
||||
HasPetTrigger(PlayerbotAI* ai) : Trigger(ai, "no pet", 5) {}
|
||||
|
||||
virtual bool IsActive() override;
|
||||
};
|
||||
|
||||
class ItemCountTrigger : public Trigger
|
||||
{
|
||||
public:
|
||||
|
||||
@@ -30,3 +30,8 @@ bool AoeHealTrigger::IsActive()
|
||||
return AI_VALUE2(uint8, "aoe heal", type) >= count;
|
||||
}
|
||||
|
||||
bool AoeInGroupTrigger::IsActive()
|
||||
{
|
||||
Group *group = bot->GetGroup();
|
||||
return group && AI_VALUE2(uint8, "aoe heal", type) >= (group->GetMembersCount() * ratio);
|
||||
}
|
||||
@@ -132,4 +132,14 @@ class AoeHealTrigger : public Trigger
|
||||
std::string const type;
|
||||
};
|
||||
|
||||
class AoeInGroupTrigger : public Trigger {
|
||||
public:
|
||||
AoeInGroupTrigger(PlayerbotAI* ai, std::string name, std::string type, float ratio) :
|
||||
Trigger(ai, name), ratio(ratio), type(type) {}
|
||||
virtual bool IsActive();
|
||||
protected:
|
||||
float ratio;
|
||||
std::string type;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -97,6 +97,7 @@ class TriggerContext : public NamedObjectContext<Trigger>
|
||||
creators["corpse near"] = &TriggerContext::corpse_near;
|
||||
creators["party member dead"] = &TriggerContext::PartyMemberDead;
|
||||
creators["no pet"] = &TriggerContext::no_pet;
|
||||
creators["has pet"] = &TriggerContext::has_pet;
|
||||
creators["has attackers"] = &TriggerContext::has_attackers;
|
||||
creators["no possible targets"] = &TriggerContext::no_possible_targets;
|
||||
creators["possible adds"] = &TriggerContext::possible_adds;
|
||||
@@ -118,6 +119,7 @@ class TriggerContext : public NamedObjectContext<Trigger>
|
||||
creators["critical aoe heal"] = &TriggerContext::critical_aoe_heal;
|
||||
creators["low aoe heal"] = &TriggerContext::low_aoe_heal;
|
||||
creators["medium aoe heal"] = &TriggerContext::medium_aoe_heal;
|
||||
creators["group heal occasion"] = &TriggerContext::group_heal_occasion;
|
||||
creators["invalid target"] = &TriggerContext::invalid_target;
|
||||
creators["lfg proposal active"] = &TriggerContext::lfg_proposal_active;
|
||||
|
||||
@@ -210,6 +212,7 @@ class TriggerContext : public NamedObjectContext<Trigger>
|
||||
static Trigger* critical_aoe_heal(PlayerbotAI* botAI) { return new AoeHealTrigger(botAI, "critical aoe heal", "critical", 2); }
|
||||
static Trigger* low_aoe_heal(PlayerbotAI* botAI) { return new AoeHealTrigger(botAI, "low aoe heal", "low", 2); }
|
||||
static Trigger* medium_aoe_heal(PlayerbotAI* botAI) { return new AoeHealTrigger(botAI, "medium aoe heal", "medium", 2); }
|
||||
static Trigger* group_heal_occasion(PlayerbotAI* ai) { return new AoeInGroupTrigger(ai, "group heal occasion", "almost full", 0.4); }
|
||||
static Trigger* target_changed(PlayerbotAI* botAI) { return new TargetChangedTrigger(botAI); }
|
||||
static Trigger* swimming(PlayerbotAI* botAI) { return new IsSwimmingTrigger(botAI); }
|
||||
static Trigger* no_possible_targets(PlayerbotAI* botAI) { return new NoPossibleTargetsTrigger(botAI); }
|
||||
@@ -277,6 +280,7 @@ class TriggerContext : public NamedObjectContext<Trigger>
|
||||
static Trigger* PartyMemberCriticalHealth(PlayerbotAI* botAI) { return new PartyMemberCriticalHealthTrigger(botAI); }
|
||||
static Trigger* protect_party_member(PlayerbotAI* botAI) { return new ProtectPartyMemberTrigger(botAI); }
|
||||
static Trigger* no_pet(PlayerbotAI* botAI) { return new NoPetTrigger(botAI); }
|
||||
static Trigger* has_pet(PlayerbotAI* botAI) { return new HasPetTrigger(botAI); }
|
||||
static Trigger* has_attackers(PlayerbotAI* botAI) { return new HasAttackersTrigger(botAI); }
|
||||
static Trigger* random_bot_update_trigger(PlayerbotAI* botAI) { return new RandomBotUpdateTrigger(botAI); }
|
||||
static Trigger* no_non_bot_players_around(PlayerbotAI* botAI) { return new NoNonBotPlayersAroundTrigger(botAI); }
|
||||
|
||||
@@ -29,77 +29,54 @@ inline bool compareByHealth(Unit const* u1, Unit const* u2)
|
||||
|
||||
Unit* PartyMemberToHeal::Calculate()
|
||||
{
|
||||
IsTargetOfHealingSpell predicate;
|
||||
std::vector<Unit*> needHeals;
|
||||
std::vector<Unit*> tankTargets;
|
||||
|
||||
if (bot->GetTarget())
|
||||
{
|
||||
Unit* target = botAI->GetUnit(bot->GetTarget());
|
||||
if (target && target->IsFriendlyTo(bot) && target->HealthBelowPct(100))
|
||||
needHeals.push_back(target);
|
||||
}
|
||||
IsTargetOfHealingSpell predicate;
|
||||
|
||||
Group* group = bot->GetGroup();
|
||||
if (!group && needHeals.empty())
|
||||
return nullptr;
|
||||
if (!group)
|
||||
return bot;
|
||||
|
||||
if (group)
|
||||
bool isRaid = bot->GetGroup()->isRaidGroup();
|
||||
MinValueCalculator calc(100);
|
||||
|
||||
for (GroupReference *gref = group->GetFirstMember(); gref; gref = gref->next())
|
||||
{
|
||||
for (GroupReference* gref = group->GetFirstMember(); gref; gref = gref->next())
|
||||
{
|
||||
Player* player = gref->GetSource();
|
||||
if (!Check(player) || !player->IsAlive())
|
||||
continue;
|
||||
|
||||
// do not heal dueling members
|
||||
if (player->duel && player->duel->Opponent)
|
||||
continue;
|
||||
|
||||
Player* player = gref->GetSource();
|
||||
if (player && Check(player) && player->IsAlive()) {
|
||||
uint8 health = player->GetHealthPct();
|
||||
if (health < sPlayerbotAIConfig->almostFullHealth || !IsTargetOfSpellCast(player, predicate))
|
||||
needHeals.push_back(player);
|
||||
|
||||
if (botAI->IsTank(player) && bot->IsInSameRaidWith(player))
|
||||
tankTargets.push_back(player);
|
||||
}
|
||||
}
|
||||
|
||||
if (needHeals.empty() && tankTargets.empty())
|
||||
return nullptr;
|
||||
|
||||
if (needHeals.empty() && !tankTargets.empty())
|
||||
needHeals = tankTargets;
|
||||
|
||||
std::sort(needHeals.begin(), needHeals.end(), compareByHealth);
|
||||
|
||||
uint32 healerIndex = 0;
|
||||
if (group)
|
||||
{
|
||||
for (GroupReference* gref = group->GetFirstMember(); gref; gref = gref->next())
|
||||
{
|
||||
Player* player = gref->GetSource();
|
||||
if (!player) continue;
|
||||
if (player == bot) break;
|
||||
if (botAI->IsHeal(player))
|
||||
{
|
||||
float percent = (float)player->GetPower(POWER_MANA) / (float)player->GetMaxPower(POWER_MANA) * 100.0;
|
||||
if (percent > sPlayerbotAIConfig->lowMana)
|
||||
healerIndex++;
|
||||
if (isRaid || health < sPlayerbotAIConfig->mediumHealth || !IsTargetOfSpellCast(player, predicate)) {
|
||||
if (player->GetDistance2d(bot) > sPlayerbotAIConfig->spellDistance) {
|
||||
calc.probe(health + 30, player);
|
||||
} else {
|
||||
calc.probe(health + player->GetDistance2d(bot) / 10, player);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
healerIndex = 1;
|
||||
|
||||
healerIndex = healerIndex % needHeals.size();
|
||||
return needHeals[healerIndex];
|
||||
Pet* pet = player->GetPet();
|
||||
if (pet && Check(pet) && pet->IsAlive()) {
|
||||
uint8 health = ((Unit*)pet)->GetHealthPct();
|
||||
if (isRaid || health < sPlayerbotAIConfig->mediumHealth)
|
||||
calc.probe(health + 30, pet);
|
||||
}
|
||||
|
||||
Unit* charm = player->GetCharm();
|
||||
if (charm && Check(charm) && charm->IsAlive()) {
|
||||
uint8 health = charm->GetHealthPct();
|
||||
if (isRaid || health < sPlayerbotAIConfig->mediumHealth)
|
||||
calc.probe(health, charm);
|
||||
}
|
||||
}
|
||||
return (Unit*)calc.param;
|
||||
}
|
||||
|
||||
bool PartyMemberToHeal::Check(Unit* player)
|
||||
{
|
||||
return player && player != bot && player->GetMapId() == bot->GetMapId() && player->IsInWorld() &&
|
||||
sServerFacade->GetDistance2d(bot, player) < (player->IsPlayer() && botAI->IsTank((Player*)player) ? 50.0f : 40.0f);
|
||||
// return player && player != bot && player->GetMapId() == bot->GetMapId() && player->IsInWorld() &&
|
||||
// sServerFacade->GetDistance2d(bot, player) < (player->IsPlayer() && botAI->IsTank((Player*)player) ? 50.0f : 40.0f);
|
||||
return player && player->GetMapId() == bot->GetMapId() &&
|
||||
bot->GetDistance(player) < sPlayerbotAIConfig->spellDistance * 2 &&
|
||||
bot->IsWithinLOS(player->GetPositionX(), player->GetPositionY(), player->GetPositionZ());
|
||||
}
|
||||
|
||||
Unit* PartyMemberToProtect::Calculate()
|
||||
|
||||
@@ -45,12 +45,19 @@ Unit* PartyMemberValue::FindPartyMember(FindPlayerPredicate& predicate, bool ign
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
std::vector<Player*> vec;
|
||||
vec.push_back(bot);
|
||||
Unit* target = FindPartyMember(&vec, predicate);
|
||||
if (target)
|
||||
return target;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!ignoreOutOfGroup && !nearestPlayers.empty() && nearestPlayers.size() < 100)
|
||||
nearestGroupPlayers.insert(nearestGroupPlayers.end(), nearestPlayers.begin(), nearestPlayers.end());
|
||||
|
||||
nearestPlayers.insert(nearestPlayers.end(), nearestGroupPlayers.begin(), nearestGroupPlayers.end());
|
||||
// nearestPlayers.insert(nearestP layers.end(), nearestGroupPlayers.begin(), nearestGroupPlayers.end());
|
||||
|
||||
std::vector<Player*> healers;
|
||||
std::vector<Player*> tanks;
|
||||
@@ -93,7 +100,10 @@ Unit* PartyMemberValue::FindPartyMember(FindPlayerPredicate& predicate, bool ign
|
||||
|
||||
bool PartyMemberValue::Check(Unit* player)
|
||||
{
|
||||
return player && player != bot && player->GetMapId() == bot->GetMapId() && bot->IsWithinDistInMap(player, sPlayerbotAIConfig->sightDistance, false);
|
||||
// return player && player != bot && player->GetMapId() == bot->GetMapId() && bot->IsWithinDistInMap(player, sPlayerbotAIConfig->sightDistance, false);
|
||||
return player && player->GetMapId() == bot->GetMapId() &&
|
||||
bot->GetDistance(player) < sPlayerbotAIConfig->spellDistance * 2 &&
|
||||
bot->IsWithinLOS(player->GetPositionX(), player->GetPositionY(), player->GetPositionZ());
|
||||
}
|
||||
|
||||
bool PartyMemberValue::IsTargetOfSpellCast(Player* target, SpellEntryPredicate &predicate)
|
||||
|
||||
Reference in New Issue
Block a user