[Avoid aoe] Position selection

This commit is contained in:
Yunfan Li
2024-06-29 21:57:28 +08:00
parent b9b4362bdd
commit 55515f0ec5
5 changed files with 45 additions and 27 deletions

View File

@@ -2511,7 +2511,7 @@ void PlayerbotFactory::InitAmmo()
uint32 entry = sRandomItemMgr->GetAmmo(level, subClass); uint32 entry = sRandomItemMgr->GetAmmo(level, subClass);
uint32 count = bot->GetItemCount(entry); uint32 count = bot->GetItemCount(entry);
uint32 maxCount = 5000; uint32 maxCount = 6000;
if (count < maxCount / 2) if (count < maxCount / 2)
{ {
@@ -3878,10 +3878,9 @@ float PlayerbotFactory::CalculateItemScore(uint32 item_id, Player* bot)
score *= 0.1; score *= 0.1;
} }
// spec with double hand // spec with double hand
// fury with titan's grip, fury without duel wield, arms, bear, retribution, blood dk // fury without duel wield, arms, bear, retribution, blood dk
if (isDoubleHand && if (isDoubleHand &&
((cls == CLASS_WARRIOR && tab == WARRIOR_TAB_FURY && bot->CanTitanGrip()) || ((cls == CLASS_WARRIOR && tab == WARRIOR_TAB_FURY && !bot->CanDualWield()) ||
(cls == CLASS_WARRIOR && tab == WARRIOR_TAB_FURY && !bot->CanDualWield()) ||
(cls == CLASS_WARRIOR && tab == WARRIOR_TAB_ARMS) || (cls == CLASS_WARRIOR && tab == WARRIOR_TAB_ARMS) ||
(cls == CLASS_DRUID && tab == 1) || (cls == CLASS_DRUID && tab == 1) ||
(cls == CLASS_PALADIN && tab == 2) || (cls == CLASS_PALADIN && tab == 2) ||
@@ -3889,6 +3888,11 @@ float PlayerbotFactory::CalculateItemScore(uint32 item_id, Player* bot)
(cls == CLASS_SHAMAN && tab == 1 && !bot->CanDualWield()))) { (cls == CLASS_SHAMAN && tab == 1 && !bot->CanDualWield()))) {
score *= 10; score *= 10;
} }
// fury with titan's grip
if (isDoubleHand && proto->SubClass != ITEM_SUBCLASS_WEAPON_POLEARM &&
(cls == CLASS_WARRIOR && tab == WARRIOR_TAB_FURY && bot->CanTitanGrip())) {
score *= 0.1;
}
} }
if (proto->Class == ITEM_CLASS_WEAPON) { if (proto->Class == ITEM_CLASS_WEAPON) {
if (cls == CLASS_HUNTER && proto->SubClass == ITEM_SUBCLASS_WEAPON_THROWN) { if (cls == CLASS_HUNTER && proto->SubClass == ITEM_SUBCLASS_WEAPON_THROWN) {

View File

@@ -33,6 +33,7 @@ bool FollowChatShortcutAction::Execute(Event event)
botAI->Reset(); botAI->Reset();
botAI->ChangeStrategy("+follow,-passive,-grind", BOT_STATE_NON_COMBAT); botAI->ChangeStrategy("+follow,-passive,-grind", BOT_STATE_NON_COMBAT);
botAI->ChangeStrategy("-follow,-passive,-grind", BOT_STATE_COMBAT); botAI->ChangeStrategy("-follow,-passive,-grind", BOT_STATE_COMBAT);
botAI->GetAiObjectContext()->GetValue<GuidVector>("prioritized targets")->Set({});
PositionMap& posMap = context->GetValue<PositionMap&>("position")->Get(); PositionMap& posMap = context->GetValue<PositionMap&>("position")->Get();
PositionInfo pos = posMap["return"]; PositionInfo pos = posMap["return"];

View File

@@ -1648,32 +1648,37 @@ bool AvoidAoeAction::AvoidUnitWithDamageAura()
Position AvoidAoeAction::BestPositionForMelee(Position pos, float radius) Position AvoidAoeAction::BestPositionForMelee(Position pos, float radius)
{ {
Unit* currentTarget = AI_VALUE(Unit*, "current target"); Unit* currentTarget = AI_VALUE(Unit*, "current target");
std::vector<float> possibleAngles; std::vector<CheckAngle> possibleAngles;
if (currentTarget) { if (currentTarget) {
// Normally, move to left or right is the best position // Normally, move to left or right is the best position
bool isTanking = (currentTarget->CanFreeMove()) && (currentTarget->GetVictim() == bot); bool isTanking = (currentTarget->CanFreeMove()) && (currentTarget->GetVictim() == bot);
float angle = bot->GetAngle(currentTarget); float angle = bot->GetAngle(currentTarget);
float angleLeft = angle + M_PI / 2; float angleLeft = angle + M_PI / 2;
float angleRight = angle - M_PI / 2; float angleRight = angle - M_PI / 2;
possibleAngles.push_back(angleLeft); possibleAngles.push_back({angleLeft, false});
possibleAngles.push_back(angleRight); possibleAngles.push_back({angleRight, false});
possibleAngles.push_back({angle, true});
if (isTanking) { if (isTanking) {
possibleAngles.push_back(angle + M_PI); possibleAngles.push_back({angle + M_PI, false});
possibleAngles.push_back(angle); possibleAngles.push_back({bot->GetAngle(&pos) - M_PI, false});
possibleAngles.push_back(bot->GetAngle(&pos) - M_PI);
} }
} else { } else {
float angleTo = bot->GetAngle(&pos) - M_PI; float angleTo = bot->GetAngle(&pos) - M_PI;
possibleAngles.push_back(angleTo); possibleAngles.push_back({angleTo, false});
} }
float farestDis = 0.0f; float farestDis = 0.0f;
Position bestPos; Position bestPos;
for (float &angle : possibleAngles) { for (CheckAngle &checkAngle : possibleAngles) {
float angle = checkAngle.angle;
bool strict = checkAngle.strict;
float fleeDis = sPlayerbotAIConfig->fleeDistance; float fleeDis = sPlayerbotAIConfig->fleeDistance;
Position fleePos{bot->GetPositionX() + cos(angle) * fleeDis, Position fleePos{bot->GetPositionX() + cos(angle) * fleeDis,
bot->GetPositionY() + sin(angle) * fleeDis, bot->GetPositionY() + sin(angle) * fleeDis,
bot->GetPositionZ()}; bot->GetPositionZ()};
// todo (Yunfan): check carefully if (strict && currentTarget
&& fleePos.GetExactDist(currentTarget) - currentTarget->GetCombatReach() > sPlayerbotAIConfig->tooCloseDistance) {
continue;
}
if (pos.GetExactDist(fleePos) > farestDis) { if (pos.GetExactDist(fleePos) > farestDis) {
farestDis = pos.GetExactDist(fleePos); farestDis = pos.GetExactDist(fleePos);
bestPos = fleePos; bestPos = fleePos;
@@ -1688,7 +1693,7 @@ Position AvoidAoeAction::BestPositionForMelee(Position pos, float radius)
Position AvoidAoeAction::BestPositionForRanged(Position pos, float radius) Position AvoidAoeAction::BestPositionForRanged(Position pos, float radius)
{ {
Unit* currentTarget = AI_VALUE(Unit*, "current target"); Unit* currentTarget = AI_VALUE(Unit*, "current target");
std::vector<float> possibleAngles; std::vector<CheckAngle> possibleAngles;
float angleToTarget = 0.0f; float angleToTarget = 0.0f;
float angleFleeFromCenter = bot->GetAngle(&pos) - M_PI; float angleFleeFromCenter = bot->GetAngle(&pos) - M_PI;
if (currentTarget) { if (currentTarget) {
@@ -1696,27 +1701,29 @@ Position AvoidAoeAction::BestPositionForRanged(Position pos, float radius)
angleToTarget = bot->GetAngle(currentTarget); angleToTarget = bot->GetAngle(currentTarget);
float angleLeft = angleToTarget + M_PI / 2; float angleLeft = angleToTarget + M_PI / 2;
float angleRight = angleToTarget - M_PI / 2; float angleRight = angleToTarget - M_PI / 2;
possibleAngles.push_back(angleLeft); possibleAngles.push_back({angleLeft, false});
possibleAngles.push_back(angleRight); possibleAngles.push_back({angleRight, false});
possibleAngles.push_back(angleToTarget + M_PI); possibleAngles.push_back({angleToTarget + M_PI, true});
possibleAngles.push_back(angleToTarget); possibleAngles.push_back({angleToTarget, true});
possibleAngles.push_back(angleFleeFromCenter); possibleAngles.push_back({angleFleeFromCenter, true});
} else { } else {
possibleAngles.push_back(angleFleeFromCenter); possibleAngles.push_back({angleFleeFromCenter, false});
} }
float farestDis = 0.0f; float farestDis = 0.0f;
Position bestPos; Position bestPos;
for (float &angle : possibleAngles) { for (CheckAngle &checkAngle : possibleAngles) {
float angle = checkAngle.angle;
bool strict = checkAngle.strict;
float fleeDis = sPlayerbotAIConfig->fleeDistance; float fleeDis = sPlayerbotAIConfig->fleeDistance;
Position fleePos{bot->GetPositionX() + cos(angle) * fleeDis, Position fleePos{bot->GetPositionX() + cos(angle) * fleeDis,
bot->GetPositionY() + sin(angle) * fleeDis, bot->GetPositionY() + sin(angle) * fleeDis,
bot->GetPositionZ()}; bot->GetPositionZ()};
if (currentTarget // && (angle == angleToTarget + M_PI || angle == angleFleeFromCenter) if (strict && currentTarget
&& fleePos.GetExactDist(currentTarget) > sPlayerbotAIConfig->spellDistance) { && fleePos.GetExactDist(currentTarget) - currentTarget->GetCombatReach() > sPlayerbotAIConfig->spellDistance) {
continue; continue;
} }
if (currentTarget // && (angle == angleToTarget || angle == angleFleeFromCenter) if (strict && currentTarget
&& fleePos.GetExactDist(currentTarget) < (sPlayerbotAIConfig->tooCloseDistance + 5.0f)) { && fleePos.GetExactDist(currentTarget) - currentTarget->GetCombatReach() < (sPlayerbotAIConfig->tooCloseDistance)) {
continue; continue;
} }
if (pos.GetExactDist(fleePos) > farestDis) { if (pos.GetExactDist(fleePos) > farestDis) {

View File

@@ -82,6 +82,10 @@ class AvoidAoeAction : public MovementAction
Position BestPositionForRanged(Position pos, float radius); Position BestPositionForRanged(Position pos, float radius);
bool FleePosition(Position pos, float radius, std::string name); bool FleePosition(Position pos, float radius, std::string name);
time_t lastTellTimer = 0; time_t lastTellTimer = 0;
struct CheckAngle {
float angle;
bool strict;
};
}; };
class RunAwayAction : public MovementAction class RunAwayAction : public MovementAction

View File

@@ -81,8 +81,10 @@ bool SummonAction::Execute(Event event)
pet->GetCharmInfo()->IsReturning(); pet->GetCharmInfo()->IsReturning();
} }
if (master->GetSession()->GetSecurity() >= SEC_PLAYER) if (master->GetSession()->GetSecurity() >= SEC_PLAYER) {
botAI->GetAiObjectContext()->GetValue<GuidVector>("prioritized targets")->Set({});
return Teleport(master, bot); return Teleport(master, bot);
}
if (SummonUsingGos(master, bot) || SummonUsingNpcs(master, bot)) if (SummonUsingGos(master, bot) || SummonUsingNpcs(master, bot))
{ {