* dont apply XPRate if bot is in group with real player
https://github.com/liyunfan1223/mod-playerbots/issues/1490
* Optimize code
* Oops minor correction
* Defense check on the player itself
* Safer way to check the leader is real player.
* Added abit more defense programming, should be needed still ..why not
Hello everyone,
This is a small change to warlocks that accomplishes 2 things:
1. Changes the firestone and spellstone weapon enchants so only one of them can be active - players reported to me that both strategies could be present before, resulting in a bug where the bot repeatedly applied the enchant.
2. Changes the soul shard deletion cap from 6 or more to 26 or more - players will now be able to stockpile soul shards up to 25 in a bot's inventory before the bot starts deleting them one at a time back down 25. I chose 25 because if it was higher, drain soul would get multiple shards above the 32 unique cap, and spam the player "I can't carry any more of those". It was super annoying, and with testing, I have not seen this error at 25. This aims to address issue #1502 .
Hello everyone,
This PR is to address #1489, where the warlock summons a pet when they dismount.
A tester found that the cause was the "wrong pet" triggering "summon (pet)". I looked into the "wrong pet" trigger, and noticed that there was not a clause if there was no active pet. It was inadvertently casting "summon (pet)" because for a brief second after dismounting, the warlock didn't technically have a pet.
I was able to recreate the issue based on tester feedback (dismounting with a warlock bot that has a pet). I tested this fix locally - it seems to work as intended. The warlock no longer attempts to summon a pet when dismounting. I tested it with nc +debug, and noticed that the "wrong pet" trigger was no longer firing. I also checked the logs - nothing.
Thank y'all for the testing and feedback!
* New roll for item action
* Add general roll command as well.
* Update ChatCommandHandlerStrategy.cpp
Add accidental removal of glyph equip
---------
Co-authored-by: bash <31279994+hermensbas@users.noreply.github.com>
Bots will now add level- and spec-appropriate oils and stones when maintaining and, with respect to randombots, leveling. All bots (other than those with class-specific temporary weapon enchants) will apply oils and stones to their weapons. General clean-ups to associated code were made.
This update enhances bot behavior by adding a check for both line of sight (LoS) and significant vertical height differences between the bot and its target. If the bot cannot see its target or if the height difference exceeds 5.0f, it calculates a valid path and moves closer to regain visibility and combat effectiveness. This resolves cases where bots would previously stand still when enemies jumped from elevated terrain or were behind obstacles.
Hello everyone,
I liked the channel cancel I did on mage recently, where they cancel blizzard if there is only 1 enemy left. I decided to do the same for the following classes:
Druid: Hurricane
Hunter: Volley
Priest: Mind Sear
Warlock: Rain of Fire
I moved the "ChannelCancel" action to it's own file, so other classes could benefit from it. I removed it from the mageactions.
This update enhances bot behavior in arena scenarios by addressing the issue where bots remain idle if their target moves behind line-of-sight (LoS obstacles). The bot now attempts to reposition near the target to regain LoS instead of standing still, preventing situations where enemies can recover without pressure.
Could someone test it?
Hello everyone,
This is a fix for issue #1233
I have added a clause in the CanCastSpell check that checks if the bot is in flight form/swift flight form & not in combat. It will no longer attempt to shift into a caster form and repetitively try and heal/buff party members while flying. Tested on my PC with the changes and druid now successfully flies as fast as the player with no stopping.
This was causing the issue:
static ActionNode* thorns([[maybe_unused]] PlayerbotAI* botAI)
{
return new ActionNode("thorns",
/*P*/ NextAction::array(0, new NextAction("caster form"), nullptr),
/*A*/ nullptr,
/*C*/ nullptr);
}
static ActionNode* thorns_on_party([[maybe_unused]] PlayerbotAI* botAI)
{
return new ActionNode("thorns on party",
/*P*/ NextAction::array(0, new NextAction("caster form"), nullptr),
/*A*/ nullptr,
/*C*/ nullptr);
}
static ActionNode* mark_of_the_wild([[maybe_unused]] PlayerbotAI* botAI)
{
return new ActionNode("mark of the wild",
/*P*/ NextAction::array(0, new NextAction("caster form"), nullptr),
/*A*/ nullptr,
/*C*/ nullptr);
}
static ActionNode* mark_of_the_wild_on_party([[maybe_unused]] PlayerbotAI* botAI)
{
return new ActionNode("mark of the wild on party",
/*P*/ NextAction::array(0, new NextAction("caster form"), nullptr),
/*A*/ nullptr,
/*C*/ nullptr);
}
static ActionNode* regrowth_on_party([[maybe_unused]] PlayerbotAI* botAI)
{
return new ActionNode("regrowth on party",
/*P*/ NextAction::array(0, new NextAction("caster form"), nullptr),
/*A*/ NULL,
/*C*/ NULL);
}
static ActionNode* rejuvenation_on_party([[maybe_unused]] PlayerbotAI* botAI)
{
return new ActionNode("rejuvenation on party",
/*P*/ NextAction::array(0, new NextAction("caster form"), nullptr),
/*A*/ NULL,
/*C*/ NULL);
}
static ActionNode* remove_curse_on_party([[maybe_unused]] PlayerbotAI* botAI)
{
return new ActionNode("remove curse on party",
/*P*/ NextAction::array(0, new NextAction("caster form"), nullptr),
/*A*/ NULL,
/*C*/ NULL);
}
static ActionNode* abolish_poison_on_party([[maybe_unused]] PlayerbotAI* botAI)
{
return new ActionNode("abolish poison on party",
/*P*/ NextAction::array(0, new NextAction("caster form"), nullptr),
/*A*/ NULL,
/*C*/ NULL);
}
static ActionNode* revive([[maybe_unused]] PlayerbotAI* botAI)
{
return new ActionNode("revive",
/*P*/ NextAction::array(0, new NextAction("caster form"), nullptr),
/*A*/ NULL,
/*C*/ NULL);
}
The *P* stands for prior, aka before this action is taken, do this other action "caster form". This is the Caster Form action:
class CastCasterFormAction : public CastBuffSpellAction
{
public:
CastCasterFormAction(PlayerbotAI* botAI) : CastBuffSpellAction(botAI, "caster form") {}
bool isUseful() override;
bool isPossible() override { return true; }
bool Execute(Event event) override;
};
And this:
bool CastCasterFormAction::isUseful()
{
return botAI->HasAnyAuraOf(GetTarget(), "dire bear form", "bear form", "cat form", "travel form", "aquatic form",
"flight form", "swift flight form", "moonkin form", nullptr) &&
AI_VALUE2(uint8, "mana", "self target") > sPlayerbotAIConfig->mediumHealth;
}
bool CastCasterFormAction::Execute(Event event)
{
botAI->RemoveShapeshift();
return true;
}
So basically, the druid was triggering to heal/buff the party, and before it could do that, it had to switch into "caster form" which executed RemoveShapeshift(). After it did that, mounting back up into flight form/swift flight form had the highest priority, so it would loop the triggers/actions.
This commit focuses on the changes requested - Migrate important cooldowns over to BoostStrategy.
Just tested it, and it is working fine - The player has more control over when they can boost. Also, added Mirror Image to the Boost Strategy, after other cooldowns are used - this way the mirror images get the buffs.