mirror of
https://github.com/liyunfan1223/mod-playerbots.git
synced 2026-06-20 15:39:25 +02:00
fix(Core/RPG): Scope do-quest yield-to-grind to current objective only
This commit is contained in:
parent
8c027e3a70
commit
4e8e3e2afe
@ -331,8 +331,11 @@ bool NewRpgDoQuestAction::DoIncompleteQuest(NewRpgInfo::DoQuest& data)
|
||||
|
||||
if (bot->GetDistance(data.pos) > 10.0f && !data.lastReachPOI)
|
||||
{
|
||||
// yield to attack-anything if a quest mob is right next to us
|
||||
if (HasNearbyQuestMob(15.0f))
|
||||
// Yield to attack-anything ONLY if a mob needed by this exact
|
||||
// quest+objective is right next to us. The broad variant (any
|
||||
// quest in the log) yielded for every nearby mob and derailed
|
||||
// turn-ins / cross-zone travel through other quests' clusters.
|
||||
if (HasNearbyQuestMobForObjective(15.0f, data.questId, data.objectiveIdx))
|
||||
return false;
|
||||
|
||||
// Note: previously yielded ~10%/tick when any hostile was
|
||||
|
||||
@ -1558,6 +1558,79 @@ bool NewRpgBaseAction::HasNearbyQuestMob(float range)
|
||||
return false;
|
||||
}
|
||||
|
||||
bool NewRpgBaseAction::HasNearbyQuestMobForObjective(float range, uint32 questId, int32 objectiveIdx)
|
||||
{
|
||||
if (!questId)
|
||||
return false;
|
||||
|
||||
Quest const* quest = sObjectMgr->GetQuestTemplate(questId);
|
||||
if (!quest)
|
||||
return false;
|
||||
|
||||
// Turn-in path: completed quest has no remaining mob objective.
|
||||
if (bot->GetQuestStatus(questId) == QUEST_STATUS_COMPLETE)
|
||||
return false;
|
||||
|
||||
QuestStatusData const& qs = bot->getQuestStatusMap().at(questId);
|
||||
|
||||
uint32 neededCreatureEntry = 0;
|
||||
uint32 neededItemId = 0;
|
||||
|
||||
if (objectiveIdx >= 0 && objectiveIdx < QUEST_OBJECTIVES_COUNT)
|
||||
{
|
||||
int32 entry = quest->RequiredNpcOrGo[objectiveIdx];
|
||||
if (entry > 0 &&
|
||||
qs.CreatureOrGOCount[objectiveIdx] < quest->RequiredNpcOrGoCount[objectiveIdx])
|
||||
{
|
||||
neededCreatureEntry = uint32(entry);
|
||||
}
|
||||
// Item objective sometimes lives in the same slot range.
|
||||
if (objectiveIdx < QUEST_ITEM_OBJECTIVES_COUNT &&
|
||||
quest->RequiredItemId[objectiveIdx] &&
|
||||
qs.ItemCount[objectiveIdx] < quest->RequiredItemCount[objectiveIdx])
|
||||
{
|
||||
neededItemId = quest->RequiredItemId[objectiveIdx];
|
||||
}
|
||||
}
|
||||
else if (objectiveIdx >= QUEST_OBJECTIVES_COUNT &&
|
||||
objectiveIdx < QUEST_OBJECTIVES_COUNT + QUEST_ITEM_OBJECTIVES_COUNT)
|
||||
{
|
||||
int32 itemSlot = objectiveIdx - QUEST_OBJECTIVES_COUNT;
|
||||
if (quest->RequiredItemId[itemSlot] &&
|
||||
qs.ItemCount[itemSlot] < quest->RequiredItemCount[itemSlot])
|
||||
{
|
||||
neededItemId = quest->RequiredItemId[itemSlot];
|
||||
}
|
||||
}
|
||||
|
||||
if (!neededCreatureEntry && !neededItemId)
|
||||
return false;
|
||||
|
||||
GuidVector possibleTargets = AI_VALUE(GuidVector, "possible targets");
|
||||
for (ObjectGuid guid : possibleTargets)
|
||||
{
|
||||
Creature* c = botAI->GetCreature(guid);
|
||||
if (!c || !c->IsInWorld() || !c->IsAlive())
|
||||
continue;
|
||||
if (!(c->GetPhaseMask() & bot->GetPhaseMask()))
|
||||
continue;
|
||||
if (bot->GetDistance(c) > range)
|
||||
continue;
|
||||
|
||||
if (neededCreatureEntry && c->GetEntry() == neededCreatureEntry)
|
||||
return true;
|
||||
|
||||
if (neededItemId)
|
||||
{
|
||||
CreatureTemplate const* tmpl = c->GetCreatureTemplate();
|
||||
if (tmpl && tmpl->lootid &&
|
||||
LootTemplates_Creature.HaveQuestLootForPlayer(tmpl->lootid, bot))
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
ObjectGuid NewRpgBaseAction::ChooseNpcOrGameObjectToInteract(bool questgiverOnly, float distanceLimit)
|
||||
{
|
||||
|
||||
@ -68,6 +68,12 @@ protected:
|
||||
// travel so we yield to attack-anything instead of running past.
|
||||
bool HasNearbyQuestMob(float range = 20.0f);
|
||||
|
||||
// Narrower variant: only yields for mobs needed by the SPECIFIC
|
||||
// quest+objective the bot is currently working on. Without this,
|
||||
// do-quest yields for any quest in the log, derailing turn-ins
|
||||
// and cross-zone travel through other quests' mob clusters.
|
||||
bool HasNearbyQuestMobForObjective(float range, uint32 questId, int32 objectiveIdx);
|
||||
|
||||
protected:
|
||||
bool GetQuestPOIPosAndObjectiveIdx(uint32 questId, std::vector<POIInfo>& poiInfo, bool toComplete = false);
|
||||
static WorldPosition SelectRandomGrindPos(Player* bot);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user