mirror of
https://github.com/liyunfan1223/mod-playerbots.git
synced 2026-06-20 15:39:25 +02:00
## Pull Request Description
Undead and Draenei bots get stuck in an idle/rest loop in their starting
zones because the default NPC scan range (150f) and quest giver filter
(80f) are too small and not enough. NPCs fall within range for
`WANDER_NPC` to activate (requires >= 3).
This adds a configurable area-based override that increases both ranges
to 200f only in affected areas. All other zones remain at default
values.
## Feature Evaluation
- **Minimum logic**: One `std::set::count()` lookup per `Calculate()`
call to check if the bot's current area is in the override list. If yes,
scan range is 200f instead of 150f.
- **Processing cost**: `GetAreaId()` is a cached uint32 read (~1ns).
`std::set::count()` on a 2-element set is O(log n) ≈ 1 comparison.
Negligible compared to the grid scan itself (~33,000-53,000ns).
## How to Test the Changes
1. Create Undead or Draenei bots (level 1)
2. Observe that they pick up quests and start moving in Deathknell/Ammen
Vale
3. Without this fix, they sit in REST status indefinitely
4. Optionally add/remove area IDs via
`AiPlayerbot.RpgScanRangeOverrideAreaIds` in playerbots.conf
## Impact Assessment
- Does this change increase per-bot/per-tick processing or risk scaling
poorly with thousands of bots?
- [x] Minimal impact
- pmon data (500 bots, extended run):
- Default 150f: 0.033ms avg
- Global 200f: 0.053ms avg
- Area check (this PR): 0.042ms avg
- The 0.009ms increase over default is caused by bots currently in
starting zones scanning at 200f. Bots outside override areas are
unaffected.
- Does this change modify default bot behavior?
- [x] No
- Does this change add new decision branches or increase maintenance
complexity?
- [x] No
- Uses the existing `LoadSet`/`std::set` config pattern already used
throughout the codebase.
## AI Assistance
- [x] Yes
- Used AI to speed up understanding the codebase, locate relevant
functions, and compare with the cmangos playerbots implementation. All
code was reviewed and tested manually.
## Final Checklist
- [x] Stability is not compromised.
- [x] Performance impact is understood, tested, and acceptable.
- [x] Added logic complexity is justified and explained.
- [x] Any new bot dialogue lines are translated.
- [x] Documentation updated if needed (Conf comments, WiKi commands).
## Notes for Reviewers
The root cause is that `WANDER_NPC` requires `possibleTargets.size() >=
3`, but sparse starting zones have fewer than 3 NPC-flagged units within
150f. Increasing the scan range to 200f brings enough NPCs into range
for the status check to pass. The override is configurable via
`AiPlayerbot.RpgScanRangeOverrideAreaIds` so server admins can add more
areas without code changes.
63 lines
1.7 KiB
C++
63 lines
1.7 KiB
C++
/*
|
|
* Copyright (C) 2016+ AzerothCore <www.azerothcore.org>, released under GNU AGPL v3 license, you may redistribute it
|
|
* and/or modify it under version 3 of the License, or (at your option), any later version.
|
|
*/
|
|
|
|
#ifndef _PLAYERBOT_POSSIBLERPGTARGETSVALUE_H
|
|
#define _PLAYERBOT_POSSIBLERPGTARGETSVALUE_H
|
|
|
|
#include "NearestGameObjects.h"
|
|
#include "NearestUnitsValue.h"
|
|
#include "PlayerbotAIConfig.h"
|
|
#include "SharedDefines.h"
|
|
|
|
class PlayerbotAI;
|
|
|
|
class PossibleRpgTargetsValue : public NearestUnitsValue
|
|
{
|
|
public:
|
|
PossibleRpgTargetsValue(PlayerbotAI* botAI, float range = 70.0f);
|
|
|
|
static std::vector<uint32> allowedNpcFlags;
|
|
|
|
protected:
|
|
void FindUnits(std::list<Unit*>& targets) override;
|
|
bool AcceptUnit(Unit* unit) override;
|
|
};
|
|
|
|
class PossibleNewRpgTargetsValue : public NearestUnitsValue
|
|
{
|
|
public:
|
|
PossibleNewRpgTargetsValue(PlayerbotAI* botAI, float range = 150.0f);
|
|
|
|
static std::vector<uint32> allowedNpcFlags;
|
|
GuidVector Calculate() override;
|
|
protected:
|
|
void FindUnits(std::list<Unit*>& targets) override;
|
|
bool AcceptUnit(Unit* unit) override;
|
|
private:
|
|
float defaultRange;
|
|
};
|
|
|
|
class PossibleNewRpgGameObjectsValue : public ObjectGuidListCalculatedValue
|
|
{
|
|
public:
|
|
PossibleNewRpgGameObjectsValue(PlayerbotAI* botAI, float range = 150.0f, bool ignoreLos = true)
|
|
: ObjectGuidListCalculatedValue(botAI, "possible new rpg game objects"), range(range), ignoreLos(ignoreLos)
|
|
{
|
|
if (allowedGOFlags.empty())
|
|
{
|
|
allowedGOFlags.push_back(GAMEOBJECT_TYPE_QUESTGIVER);
|
|
}
|
|
}
|
|
|
|
static std::vector<GameobjectTypes> allowedGOFlags;
|
|
GuidVector Calculate() override;
|
|
|
|
private:
|
|
float range;
|
|
bool ignoreLos;
|
|
};
|
|
|
|
#endif
|