mirror of
https://github.com/mod-playerbots/mod-playerbots
synced 2025-11-29 15:58:20 +08:00
Pet attack (fix shadowfiend)
This commit is contained in:
@@ -225,7 +225,7 @@ class ActionContext : public NamedObjectContext<Action>
|
|||||||
creators["rpg mount anim"] = &ActionContext::rpg_mount_anim;
|
creators["rpg mount anim"] = &ActionContext::rpg_mount_anim;
|
||||||
|
|
||||||
creators["toggle pet spell"] = &ActionContext::toggle_pet_spell;
|
creators["toggle pet spell"] = &ActionContext::toggle_pet_spell;
|
||||||
|
creators["pet attack"] = &ActionContext::pet_attack;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -390,7 +390,7 @@ class ActionContext : public NamedObjectContext<Action>
|
|||||||
static Action* rpg_mount_anim(PlayerbotAI* botAI) { return new RpgMountAnimAction(botAI); }
|
static Action* rpg_mount_anim(PlayerbotAI* botAI) { return new RpgMountAnimAction(botAI); }
|
||||||
|
|
||||||
static Action* toggle_pet_spell(PlayerbotAI* ai) { return new TogglePetSpellAutoCastAction(ai); }
|
static Action* toggle_pet_spell(PlayerbotAI* ai) { return new TogglePetSpellAutoCastAction(ai); }
|
||||||
|
static Action* pet_attack(PlayerbotAI* ai) { return new PetAttackAction(ai); }
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -116,22 +116,22 @@ bool AttackAction::Attack(Unit* target, bool with_pet /*true*/)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
/* prevent pet dead immediately in group */
|
/* prevent pet dead immediately in group */
|
||||||
if (bot->GetMap()->IsDungeon() && bot->GetGroup() && !target->IsInCombat()) {
|
// if (bot->GetMap()->IsDungeon() && bot->GetGroup() && !target->IsInCombat()) {
|
||||||
with_pet = false;
|
// with_pet = false;
|
||||||
}
|
// }
|
||||||
if (Pet* pet = bot->GetPet())
|
// if (Pet* pet = bot->GetPet())
|
||||||
{
|
// {
|
||||||
if (with_pet) {
|
// if (with_pet) {
|
||||||
pet->SetReactState(REACT_DEFENSIVE);
|
// pet->SetReactState(REACT_DEFENSIVE);
|
||||||
pet->SetTarget(target->GetGUID());
|
// pet->SetTarget(target->GetGUID());
|
||||||
pet->GetCharmInfo()->SetIsCommandAttack(true);
|
// pet->GetCharmInfo()->SetIsCommandAttack(true);
|
||||||
pet->AI()->AttackStart(target);
|
// pet->AI()->AttackStart(target);
|
||||||
} else {
|
// } else {
|
||||||
pet->SetReactState(REACT_PASSIVE);
|
// pet->SetReactState(REACT_PASSIVE);
|
||||||
pet->GetCharmInfo()->SetIsCommandFollow(true);
|
// pet->GetCharmInfo()->SetIsCommandFollow(true);
|
||||||
pet->GetCharmInfo()->IsReturning();
|
// pet->GetCharmInfo()->IsReturning();
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "GenericActions.h"
|
#include "GenericActions.h"
|
||||||
|
#include "CreatureAI.h"
|
||||||
#include "Playerbots.h"
|
#include "Playerbots.h"
|
||||||
|
|
||||||
bool MeleeAction::isUseful()
|
bool MeleeAction::isUseful()
|
||||||
@@ -40,3 +41,28 @@ bool TogglePetSpellAutoCastAction::Execute(Event event) {
|
|||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool PetAttackAction::Execute(Event event)
|
||||||
|
{
|
||||||
|
Guardian* pet = bot->GetGuardianPet();
|
||||||
|
if (!pet) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
Unit* target = AI_VALUE(Unit*, "current target");
|
||||||
|
if (!target) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
// pet->SetReactState(REACT_DEFENSIVE);
|
||||||
|
pet->ClearUnitState(UNIT_STATE_FOLLOW);
|
||||||
|
pet->AttackStop();
|
||||||
|
pet->SetTarget(target->GetGUID());
|
||||||
|
|
||||||
|
pet->GetCharmInfo()->SetIsCommandAttack(true);
|
||||||
|
pet->GetCharmInfo()->SetIsAtStay(false);
|
||||||
|
pet->GetCharmInfo()->SetIsFollowing(false);
|
||||||
|
pet->GetCharmInfo()->SetIsCommandFollow(false);
|
||||||
|
pet->GetCharmInfo()->SetIsReturning(false);
|
||||||
|
|
||||||
|
pet->ToCreature()->AI()->AttackStart(target);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
@@ -25,4 +25,12 @@ public:
|
|||||||
virtual bool Execute(Event event) override;
|
virtual bool Execute(Event event) override;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class PetAttackAction: public Action
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
PetAttackAction(PlayerbotAI* ai): Action(ai, "pet attack") {}
|
||||||
|
virtual bool Execute(Event event) override;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ void CombatStrategy::InitTriggers(std::vector<TriggerNode*> &triggers)
|
|||||||
// triggers.push_back(new TriggerNode("out of react range", NextAction::array(0, new NextAction("flee to master", 55), nullptr)));
|
// triggers.push_back(new TriggerNode("out of react range", NextAction::array(0, new NextAction("flee to master", 55), nullptr)));
|
||||||
triggers.push_back(new TriggerNode("combat stuck", NextAction::array(0, new NextAction("reset", 1.0f), nullptr)));
|
triggers.push_back(new TriggerNode("combat stuck", NextAction::array(0, new NextAction("reset", 1.0f), nullptr)));
|
||||||
triggers.push_back(new TriggerNode("not facing target", NextAction::array(0, new NextAction("set facing", ACTION_MOVE + 7), nullptr)));
|
triggers.push_back(new TriggerNode("not facing target", NextAction::array(0, new NextAction("set facing", ACTION_MOVE + 7), nullptr)));
|
||||||
|
triggers.push_back(new TriggerNode("pet attack", NextAction::array(0, new NextAction("pet attack", ACTION_NORMAL), nullptr)));
|
||||||
// triggers.push_back(new TriggerNode("combat long stuck", NextAction::array(0, new NextAction("hearthstone", 0.9f), new NextAction("repop", 0.8f), nullptr)));
|
// triggers.push_back(new TriggerNode("combat long stuck", NextAction::array(0, new NextAction("hearthstone", 0.9f), new NextAction("repop", 0.8f), nullptr)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -45,7 +45,6 @@ void GenericPriestStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
|
|||||||
NextAction::array(0, new NextAction("hymn of hope", ACTION_HIGH), NULL)));
|
NextAction::array(0, new NextAction("hymn of hope", ACTION_HIGH), NULL)));
|
||||||
|
|
||||||
triggers.push_back(new TriggerNode("enemy too close for spell", NextAction::array(0, new NextAction("flee", ACTION_MOVE + 9), nullptr)));
|
triggers.push_back(new TriggerNode("enemy too close for spell", NextAction::array(0, new NextAction("flee", ACTION_MOVE + 9), nullptr)));
|
||||||
|
|
||||||
triggers.push_back(new TriggerNode("often", NextAction::array(0, new NextAction("apply oil", 1.0f), nullptr)));
|
triggers.push_back(new TriggerNode("often", NextAction::array(0, new NextAction("apply oil", 1.0f), nullptr)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
#include "RaidNaxxMultipliers.h"
|
#include "RaidNaxxMultipliers.h"
|
||||||
|
#include "GenericActions.h"
|
||||||
#include "MovementActions.h"
|
#include "MovementActions.h"
|
||||||
#include "ScriptedCreature.h"
|
#include "ScriptedCreature.h"
|
||||||
#include "RaidNaxxActions.h"
|
#include "RaidNaxxActions.h"
|
||||||
@@ -173,7 +174,8 @@ float KelthuzadGenericMultiplier::GetValue(Action* action)
|
|||||||
dynamic_cast<CastRaiseDeadAction*>(action) ||
|
dynamic_cast<CastRaiseDeadAction*>(action) ||
|
||||||
dynamic_cast<CastFeignDeathAction*>(action) ||
|
dynamic_cast<CastFeignDeathAction*>(action) ||
|
||||||
dynamic_cast<CastInvisibilityAction*>(action) ||
|
dynamic_cast<CastInvisibilityAction*>(action) ||
|
||||||
dynamic_cast<CastVanishAction*>(action)) {
|
dynamic_cast<CastVanishAction*>(action) ||
|
||||||
|
dynamic_cast<PetAttackAction*>(action)) {
|
||||||
return 0.0f;
|
return 0.0f;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -268,5 +270,11 @@ float GluthGenericMultiplier::GetValue(Action* action)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (dynamic_cast<PetAttackAction*>(action)) {
|
||||||
|
Unit* target = AI_VALUE(Unit*, "current target");
|
||||||
|
if (target && target->GetEntry() == NPC_ZOMBIE_CHOW) {
|
||||||
|
return 0.0f;
|
||||||
|
}
|
||||||
|
}
|
||||||
return 1.0f;
|
return 1.0f;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,6 +4,7 @@
|
|||||||
|
|
||||||
#include "GenericTriggers.h"
|
#include "GenericTriggers.h"
|
||||||
#include "BattlegroundWS.h"
|
#include "BattlegroundWS.h"
|
||||||
|
#include "CreatureAI.h"
|
||||||
#include "ObjectGuid.h"
|
#include "ObjectGuid.h"
|
||||||
#include "Playerbots.h"
|
#include "Playerbots.h"
|
||||||
#include "SharedDefines.h"
|
#include "SharedDefines.h"
|
||||||
@@ -34,6 +35,25 @@ bool HasPetTrigger::IsActive() {
|
|||||||
return (AI_VALUE(Unit*, "pet target")) && !AI_VALUE2(bool, "mounted", "self target");;
|
return (AI_VALUE(Unit*, "pet target")) && !AI_VALUE2(bool, "mounted", "self target");;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool PetAttackTrigger::IsActive()
|
||||||
|
{
|
||||||
|
Guardian* pet = bot->GetGuardianPet();
|
||||||
|
if (!pet) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
Unit* target = AI_VALUE(Unit*, "current target");
|
||||||
|
if (!target) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (pet->GetVictim() == target && pet->GetCharmInfo()->IsCommandAttack()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (bot->GetMap()->IsDungeon() && bot->GetGroup() && !target->IsInCombat()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
bool HighManaTrigger::IsActive()
|
bool HighManaTrigger::IsActive()
|
||||||
{
|
{
|
||||||
return AI_VALUE2(bool, "has mana", "self target") && AI_VALUE2(uint8, "mana", "self target") < 65;
|
return AI_VALUE2(bool, "has mana", "self target") && AI_VALUE2(uint8, "mana", "self target") < 65;
|
||||||
|
|||||||
@@ -453,6 +453,14 @@ public:
|
|||||||
virtual bool IsActive() override;
|
virtual bool IsActive() override;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class PetAttackTrigger : public Trigger
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
PetAttackTrigger(PlayerbotAI* ai) : Trigger(ai, "pet attack") {}
|
||||||
|
|
||||||
|
virtual bool IsActive() override;
|
||||||
|
};
|
||||||
|
|
||||||
class ItemCountTrigger : public Trigger
|
class ItemCountTrigger : public Trigger
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|||||||
@@ -101,6 +101,8 @@ class TriggerContext : public NamedObjectContext<Trigger>
|
|||||||
creators["combat party member dead"] = &TriggerContext::CombatPartyMemberDead;
|
creators["combat party member dead"] = &TriggerContext::CombatPartyMemberDead;
|
||||||
creators["no pet"] = &TriggerContext::no_pet;
|
creators["no pet"] = &TriggerContext::no_pet;
|
||||||
creators["has pet"] = &TriggerContext::has_pet;
|
creators["has pet"] = &TriggerContext::has_pet;
|
||||||
|
creators["pet attack"] = &TriggerContext::pet_attack;
|
||||||
|
|
||||||
creators["has attackers"] = &TriggerContext::has_attackers;
|
creators["has attackers"] = &TriggerContext::has_attackers;
|
||||||
creators["no possible targets"] = &TriggerContext::no_possible_targets;
|
creators["no possible targets"] = &TriggerContext::no_possible_targets;
|
||||||
creators["possible adds"] = &TriggerContext::possible_adds;
|
creators["possible adds"] = &TriggerContext::possible_adds;
|
||||||
@@ -289,6 +291,7 @@ class TriggerContext : public NamedObjectContext<Trigger>
|
|||||||
static Trigger* protect_party_member(PlayerbotAI* botAI) { return new ProtectPartyMemberTrigger(botAI); }
|
static Trigger* protect_party_member(PlayerbotAI* botAI) { return new ProtectPartyMemberTrigger(botAI); }
|
||||||
static Trigger* no_pet(PlayerbotAI* botAI) { return new NoPetTrigger(botAI); }
|
static Trigger* no_pet(PlayerbotAI* botAI) { return new NoPetTrigger(botAI); }
|
||||||
static Trigger* has_pet(PlayerbotAI* botAI) { return new HasPetTrigger(botAI); }
|
static Trigger* has_pet(PlayerbotAI* botAI) { return new HasPetTrigger(botAI); }
|
||||||
|
static Trigger* pet_attack(PlayerbotAI* botAI) { return new PetAttackTrigger(botAI); }
|
||||||
static Trigger* has_attackers(PlayerbotAI* botAI) { return new HasAttackersTrigger(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* random_bot_update_trigger(PlayerbotAI* botAI) { return new RandomBotUpdateTrigger(botAI); }
|
||||||
static Trigger* no_non_bot_players_around(PlayerbotAI* botAI) { return new NoNonBotPlayersAroundTrigger(botAI); }
|
static Trigger* no_non_bot_players_around(PlayerbotAI* botAI) { return new NoNonBotPlayersAroundTrigger(botAI); }
|
||||||
|
|||||||
@@ -31,12 +31,12 @@ class TankWarriorStrategyActionNodeFactory : public NamedObjectFactory<ActionNod
|
|||||||
ACTION_NODE_A(devastate, "devastate", "sunder armor");
|
ACTION_NODE_A(devastate, "devastate", "sunder armor");
|
||||||
ACTION_NODE_A(last_stand, "last stand", "intimidating shout");
|
ACTION_NODE_A(last_stand, "last stand", "intimidating shout");
|
||||||
ACTION_NODE_A(heroic_throw_on_snare_target, "heroic throw on snare target", "taunt on snare target");
|
ACTION_NODE_A(heroic_throw_on_snare_target, "heroic throw on snare target", "taunt on snare target");
|
||||||
ACTION_NODE_A(heroic_throw_taunt, "heroic throw", "taunt");
|
ACTION_NODE_A(heroic_throw_taunt, "heroic throw", "shield slam");
|
||||||
static ActionNode* taunt(PlayerbotAI* botAI)
|
static ActionNode* taunt(PlayerbotAI* botAI)
|
||||||
{
|
{
|
||||||
return new ActionNode("taunt",
|
return new ActionNode("taunt",
|
||||||
/*P*/ nullptr,
|
/*P*/ nullptr,
|
||||||
/*A*/ NextAction::array(0, new NextAction("shield slam"), nullptr),
|
/*A*/ NextAction::array(0, new NextAction("heroic throw taunt"), nullptr),
|
||||||
/*C*/ nullptr);
|
/*C*/ nullptr);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user