From 55515f0ec579462b5704cea78f7e599a395f3605 Mon Sep 17 00:00:00 2001 From: Yunfan Li Date: Sat, 29 Jun 2024 21:57:28 +0800 Subject: [PATCH] [Avoid aoe] Position selection --- src/PlayerbotFactory.cpp | 14 ++++-- src/strategy/actions/ChatShortcutActions.cpp | 1 + src/strategy/actions/MovementActions.cpp | 49 +++++++++++-------- src/strategy/actions/MovementActions.h | 4 ++ .../actions/UseMeetingStoneAction.cpp | 4 +- 5 files changed, 45 insertions(+), 27 deletions(-) diff --git a/src/PlayerbotFactory.cpp b/src/PlayerbotFactory.cpp index 69efb9f6..ec9d5729 100644 --- a/src/PlayerbotFactory.cpp +++ b/src/PlayerbotFactory.cpp @@ -2511,7 +2511,7 @@ void PlayerbotFactory::InitAmmo() uint32 entry = sRandomItemMgr->GetAmmo(level, subClass); uint32 count = bot->GetItemCount(entry); - uint32 maxCount = 5000; + uint32 maxCount = 6000; if (count < maxCount / 2) { @@ -3878,10 +3878,9 @@ float PlayerbotFactory::CalculateItemScore(uint32 item_id, Player* bot) score *= 0.1; } // spec with double hand - // fury with titan's grip, fury without duel wield, arms, bear, retribution, blood dk - if (isDoubleHand && - ((cls == CLASS_WARRIOR && tab == WARRIOR_TAB_FURY && bot->CanTitanGrip()) || - (cls == CLASS_WARRIOR && tab == WARRIOR_TAB_FURY && !bot->CanDualWield()) || + // fury without duel wield, arms, bear, retribution, blood dk + if (isDoubleHand && + ((cls == CLASS_WARRIOR && tab == WARRIOR_TAB_FURY && !bot->CanDualWield()) || (cls == CLASS_WARRIOR && tab == WARRIOR_TAB_ARMS) || (cls == CLASS_DRUID && tab == 1) || (cls == CLASS_PALADIN && tab == 2) || @@ -3889,6 +3888,11 @@ float PlayerbotFactory::CalculateItemScore(uint32 item_id, Player* bot) (cls == CLASS_SHAMAN && tab == 1 && !bot->CanDualWield()))) { 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 (cls == CLASS_HUNTER && proto->SubClass == ITEM_SUBCLASS_WEAPON_THROWN) { diff --git a/src/strategy/actions/ChatShortcutActions.cpp b/src/strategy/actions/ChatShortcutActions.cpp index 92e259fd..be1c4496 100644 --- a/src/strategy/actions/ChatShortcutActions.cpp +++ b/src/strategy/actions/ChatShortcutActions.cpp @@ -33,6 +33,7 @@ bool FollowChatShortcutAction::Execute(Event event) botAI->Reset(); botAI->ChangeStrategy("+follow,-passive,-grind", BOT_STATE_NON_COMBAT); botAI->ChangeStrategy("-follow,-passive,-grind", BOT_STATE_COMBAT); + botAI->GetAiObjectContext()->GetValue("prioritized targets")->Set({}); PositionMap& posMap = context->GetValue("position")->Get(); PositionInfo pos = posMap["return"]; diff --git a/src/strategy/actions/MovementActions.cpp b/src/strategy/actions/MovementActions.cpp index 67cb4902..5c9afbb4 100644 --- a/src/strategy/actions/MovementActions.cpp +++ b/src/strategy/actions/MovementActions.cpp @@ -1648,32 +1648,37 @@ bool AvoidAoeAction::AvoidUnitWithDamageAura() Position AvoidAoeAction::BestPositionForMelee(Position pos, float radius) { Unit* currentTarget = AI_VALUE(Unit*, "current target"); - std::vector possibleAngles; + std::vector possibleAngles; if (currentTarget) { // Normally, move to left or right is the best position bool isTanking = (currentTarget->CanFreeMove()) && (currentTarget->GetVictim() == bot); float angle = bot->GetAngle(currentTarget); float angleLeft = angle + M_PI / 2; float angleRight = angle - M_PI / 2; - possibleAngles.push_back(angleLeft); - possibleAngles.push_back(angleRight); + possibleAngles.push_back({angleLeft, false}); + possibleAngles.push_back({angleRight, false}); + possibleAngles.push_back({angle, true}); if (isTanking) { - possibleAngles.push_back(angle + M_PI); - possibleAngles.push_back(angle); - possibleAngles.push_back(bot->GetAngle(&pos) - M_PI); + possibleAngles.push_back({angle + M_PI, false}); + possibleAngles.push_back({bot->GetAngle(&pos) - M_PI, false}); } } else { float angleTo = bot->GetAngle(&pos) - M_PI; - possibleAngles.push_back(angleTo); + possibleAngles.push_back({angleTo, false}); } float farestDis = 0.0f; Position bestPos; - for (float &angle : possibleAngles) { + for (CheckAngle &checkAngle : possibleAngles) { + float angle = checkAngle.angle; + bool strict = checkAngle.strict; float fleeDis = sPlayerbotAIConfig->fleeDistance; Position fleePos{bot->GetPositionX() + cos(angle) * fleeDis, bot->GetPositionY() + sin(angle) * fleeDis, bot->GetPositionZ()}; - // todo (Yunfan): check carefully + if (strict && currentTarget + && fleePos.GetExactDist(currentTarget) - currentTarget->GetCombatReach() > sPlayerbotAIConfig->tooCloseDistance) { + continue; + } if (pos.GetExactDist(fleePos) > farestDis) { farestDis = pos.GetExactDist(fleePos); bestPos = fleePos; @@ -1688,7 +1693,7 @@ Position AvoidAoeAction::BestPositionForMelee(Position pos, float radius) Position AvoidAoeAction::BestPositionForRanged(Position pos, float radius) { Unit* currentTarget = AI_VALUE(Unit*, "current target"); - std::vector possibleAngles; + std::vector possibleAngles; float angleToTarget = 0.0f; float angleFleeFromCenter = bot->GetAngle(&pos) - M_PI; if (currentTarget) { @@ -1696,27 +1701,29 @@ Position AvoidAoeAction::BestPositionForRanged(Position pos, float radius) angleToTarget = bot->GetAngle(currentTarget); float angleLeft = angleToTarget + M_PI / 2; float angleRight = angleToTarget - M_PI / 2; - possibleAngles.push_back(angleLeft); - possibleAngles.push_back(angleRight); - possibleAngles.push_back(angleToTarget + M_PI); - possibleAngles.push_back(angleToTarget); - possibleAngles.push_back(angleFleeFromCenter); + possibleAngles.push_back({angleLeft, false}); + possibleAngles.push_back({angleRight, false}); + possibleAngles.push_back({angleToTarget + M_PI, true}); + possibleAngles.push_back({angleToTarget, true}); + possibleAngles.push_back({angleFleeFromCenter, true}); } else { - possibleAngles.push_back(angleFleeFromCenter); + possibleAngles.push_back({angleFleeFromCenter, false}); } float farestDis = 0.0f; Position bestPos; - for (float &angle : possibleAngles) { + for (CheckAngle &checkAngle : possibleAngles) { + float angle = checkAngle.angle; + bool strict = checkAngle.strict; float fleeDis = sPlayerbotAIConfig->fleeDistance; Position fleePos{bot->GetPositionX() + cos(angle) * fleeDis, bot->GetPositionY() + sin(angle) * fleeDis, bot->GetPositionZ()}; - if (currentTarget // && (angle == angleToTarget + M_PI || angle == angleFleeFromCenter) - && fleePos.GetExactDist(currentTarget) > sPlayerbotAIConfig->spellDistance) { + if (strict && currentTarget + && fleePos.GetExactDist(currentTarget) - currentTarget->GetCombatReach() > sPlayerbotAIConfig->spellDistance) { continue; } - if (currentTarget // && (angle == angleToTarget || angle == angleFleeFromCenter) - && fleePos.GetExactDist(currentTarget) < (sPlayerbotAIConfig->tooCloseDistance + 5.0f)) { + if (strict && currentTarget + && fleePos.GetExactDist(currentTarget) - currentTarget->GetCombatReach() < (sPlayerbotAIConfig->tooCloseDistance)) { continue; } if (pos.GetExactDist(fleePos) > farestDis) { diff --git a/src/strategy/actions/MovementActions.h b/src/strategy/actions/MovementActions.h index 3cfdc685..f26991a4 100644 --- a/src/strategy/actions/MovementActions.h +++ b/src/strategy/actions/MovementActions.h @@ -82,6 +82,10 @@ class AvoidAoeAction : public MovementAction Position BestPositionForRanged(Position pos, float radius); bool FleePosition(Position pos, float radius, std::string name); time_t lastTellTimer = 0; + struct CheckAngle { + float angle; + bool strict; + }; }; class RunAwayAction : public MovementAction diff --git a/src/strategy/actions/UseMeetingStoneAction.cpp b/src/strategy/actions/UseMeetingStoneAction.cpp index 422fc3e9..3ef46e21 100644 --- a/src/strategy/actions/UseMeetingStoneAction.cpp +++ b/src/strategy/actions/UseMeetingStoneAction.cpp @@ -81,8 +81,10 @@ bool SummonAction::Execute(Event event) pet->GetCharmInfo()->IsReturning(); } - if (master->GetSession()->GetSecurity() >= SEC_PLAYER) + if (master->GetSession()->GetSecurity() >= SEC_PLAYER) { + botAI->GetAiObjectContext()->GetValue("prioritized targets")->Set({}); return Teleport(master, bot); + } if (SummonUsingGos(master, bot) || SummonUsingNpcs(master, bot)) {