57 Commits

Author SHA1 Message Date
Keleborn
866a73dfbf
Clean up unused variables (#2268)
<!--
Thank you for contributing to mod-playerbots, please make sure that
you...
1. Submit your PR to the test-staging branch, not master.
2. Read the guidelines below before submitting.
3. Don't delete parts of this template.

DESIGN PHILOSOPHY: We prioritize STABILITY, PERFORMANCE, AND
PREDICTABILITY over behavioral realism.

Every action and decision executes PER BOT AND PER TRIGGER. Small
increases in logic complexity scale
poorly across thousands of bots and negatively affect all. We prioritize
a stable system over a smarter
one. Bots don't need to behave perfectly; believable behavior is the
goal, not human simulation.
Default behavior must be cheap in processing; expensive behavior must be
opt-in.

Before submitting, make sure your changes aligns with these principles.
-->

## Pull Request Description
<!-- Describe what this change does and why it is needed -->
Clean up a bunch of additional unused variable warnings. 


## Feature Evaluation
<!--
If your PR is very minimal (comment typo, wrong ID reference, etc), and
it is very obvious it will not have
any impact on performance, you may skip these question. If necessary, a
maintainer may ask you for them later.
-->

<!-- Please answer the following: -->
- Describe the **minimum logic** required to achieve the intended
behavior.
- Describe the **processing cost** when this logic executes across many
bots.



## How to Test the Changes
<!--
- Step-by-step instructions to test the change.
- Any required setup (e.g. multiple players, number of bots, specific
configuration).
- Expected behavior and how to verify it.
-->



## Impact Assessment
<!-- As a generic test, before and after measure of pmon (playerbot pmon
tick) can help you here. -->
- Does this change increase per-bot/per-tick processing or risk scaling
poorly with thousands of bots?
    - - [x] No, not at all
    - - [ ] Minimal impact (**explain below**)
    - - [ ] Moderate impact (**explain below**)



- Does this change modify default bot behavior?
    - - [x] No
    - - [ ] Yes (**explain why**)



- Does this change add new decision branches or increase maintenance
complexity?
    - - [x] No
    - - [ ] Yes (**explain below**)



## Messages to Translate
<!--
Bot messages have to be translatable, but you don't need to do the
translations here. You only need to make sure
the message is in a translatable format, and list in the table the
message_key and the default English message.
Search for GetBotTextOrDefault in the codebase for examples.
-->
- Does this change add bot messages to translate?
    - - [x] No
    - - [ ] Yes (**list messages in the table**)

| Message key  | Default message |
| --------------- | ------------------ |
|			 |			      |
|			 |			      |

## AI Assistance
<!--
AI assistance is allowed, but all submitted code must be fully
understood, reviewed, and owned by the contributor.
We expect contributors to be honest about what they do and do not
understand.
-->
- Was AI assistance used while working on this change?
    - - [ ] No
    - - [x] Yes (**explain below**)
<!--
If yes, please specify:
- Purpose of usage (e.g. brainstorming, refactoring, documentation, code
generation).
- Which parts of the change were influenced or generated, and whether it
was thoroughly reviewed.
-->
Claude reviewed the warnings log from a build and suggested a series of
changes. I focused just on these warnings for now. Every line was
reviewed. Some sections need to be reviewed by author for intent.



## Final Checklist

- - [x] Stability is not compromised.
- - [x] Performance impact is understood, tested, and acceptable.
- - [x] Added logic complexity is justified and explained.
- - [x] Documentation updated if needed (Conf comments, WiKi commands).

## Notes for Reviewers
<!-- Anything else that's helpful to review or test your pull request.
-->
2026-04-24 23:03:36 +02:00
Keleborn
a4b37c9fbc
Revert "Feat: Reintroduce timed logouts" (#2329)
Reverts mod-playerbots/mod-playerbots#2289
2026-04-24 12:27:06 -07:00
kadeshar
19249e90a0
Pull strategy migration (#2310)
<!--
Thank you for contributing to mod-playerbots, please make sure that
you...
1. Submit your PR to the test-staging branch, not master.
2. Read the guidelines below before submitting.
3. Don't delete parts of this template.

DESIGN PHILOSOPHY: We prioritize STABILITY, PERFORMANCE, AND
PREDICTABILITY over behavioral realism.

Every action and decision executes PER BOT AND PER TRIGGER. Small
increases in logic complexity scale
poorly across thousands of bots and negatively affect all. We prioritize
a stable system over a smarter
one. Bots don't need to behave perfectly; believable behavior is the
goal, not human simulation.
Default behavior must be cheap in processing; expensive behavior must be
opt-in.

Before submitting, make sure your changes aligns with these principles.
-->

## Pull Request Description
<!-- Describe what this change does and why it is needed -->

Pull strategy migration from cmangos for tank specializations

## How to Test the Changes
<!--
- Step-by-step instructions to test the change.
- Any required setup (e.g. multiple players, number of bots, specific
configuration).
- Expected behavior and how to verify it.
-->

1. Invite bot tank
2. Use `reset boAI` or `nc +pull,+pull back` + `co +pull,+pull back`
3. Order bot to pull using command `pull my target` or `pull rti target`
4. Bot should run to mob, use ranged skill and back to point where he
started pull
Without `pull back` strategy bot run to mob, use ranged skill and wait
on mob until he come to bot

## Impact Assessment
<!-- As a generic test, before and after measure of pmon (playerbot pmon
tick) can help you here. -->
- Does this change increase per-bot/per-tick processing or risk scaling
poorly with thousands of bots?
    - - [x] No, not at all
    - - [ ] Minimal impact (**explain below**)
    - - [ ] Moderate impact (**explain below**)



- Does this change modify default bot behavior?
    - - [x] No
    - - [ ] Yes (**explain why**)



- Does this change add new decision branches or increase maintenance
complexity?
    - - [x] No
    - - [ ] Yes (**explain below**)



## AI Assistance
<!--
AI assistance is allowed, but all submitted code must be fully
understood, reviewed, and owned by the contributor.
We expect contributors to be honest about what they do and do not
understand.
-->
Was AI assistance used while working on this change?
- - [ ] No
- - [x] Yes (**explain below**)
<!--
If yes, please specify:
- Purpose of usage (e.g. brainstorming, refactoring, documentation, code
generation).
- Which parts of the change were influenced or generated, and whether it
was thoroughly reviewed.
-->

Help with migration and solving some problems

<!--
TRANSLATIONS:
Anything new that the bots say in chat must be in a translatable format.
This is done using GetBotTextOrDefault,
which you can search for in the codebase to find examples. Your code
needs to have English as the default fallback,
while the full translations need to be in an SQL update file. The
languages in the file are the nine language
options supported by AzerothCore: English, Korean, French, German,
Chinese, Taiwanese, Spanish, Spanish Mexico, and
Russian. See
data/sql/playerbots/updates/2025_12_27_ai_playerbot_fishing_text.sql as
an example of a translation SQL
update, whose content are called within the codebase at
src/strategy/actions/FishingAction.cpp
-->

## 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.
- - [ ] Documentation updated if needed (Conf comments, WiKi commands).

## Notes for Reviewers
<!-- Anything else that's helpful to review or test your pull request.
-->

Stability test after randomize new bots
<img width="465" height="172" alt="obraz"
src="https://github.com/user-attachments/assets/6e39a8c0-f23b-47cc-852a-71fa98044a31"
/>

---------

Co-authored-by: Keleborn <22352763+Celandriel@users.noreply.github.com>
2026-04-17 14:07:47 -07:00
Scarecr0w12
c0c2b6ab5b
feat(Core/Playerbots): Initialize bot professions and specializations (#2287)
## Pull Request Description

Initialize random bot professions from the factory using class-matching
or weighted-random profession pairs, respect the active primary
profession cap, and restore required profession tools during bot
init/refresh.

This PR also initializes profession specializations for eligible bots so
crafted professions are not left in an unspecialized state after
profession assignment. Supported specialization families include:

- Alchemy: Transmute / Elixir / Potion
- Engineering: Goblin / Gnomish
- Leatherworking: Dragonscale / Elemental / Tribal
- Tailoring: Spellfire / Mooncloth / Shadoweave
- Blacksmithing: Armorsmith / Weaponsmith, plus Hammersmith / Axesmith /
Swordsmith for eligible Weaponsmith bots

Specialization choices are stored in bot values so they remain stable
across later refreshes. Required tool items are also restored for
relevant professions during maintenance.

## Feature Evaluation

- Describe the **minimum logic** required to achieve the intended
behavior.
- Select one or two professions during factory initialization from a
small weighted list.
- Clamp the assigned professions to the configured primary profession
limit.
- Learn the profession starter spell and set skill to the bot’s
profession cap.
- For professions with supported specialization branches, assign exactly
one valid specialization when the bot meets the same level/skill gates
used by AzerothCore profession scripts.
- Persist the specialization selection in stored bot values so the
choice is stable and does not need to be recalculated repeatedly.
- Restore missing profession tools only when the bot has the related
profession and the tool is absent.

- Describe the **processing cost** when this logic executes across many
bots.
- The added logic executes only during bot init/refresh, not as part of
per-tick combat or trigger evaluation.
- Runtime cost is limited to a few small switch statements, stored value
lookups, spell checks, and item presence checks.
- No expensive repeated searches, map scans, or per-trigger decision
trees were added.
- The design keeps specialization selection deterministic after first
assignment by storing the result, avoiding repeated random branching
later.

## How to Test the Changes

1. Build and restart the server with this branch.
2. Trigger random bot creation, refresh, or level-based reroll for
multiple bots.
3. Verify in `Playerbots.log` that bots receive profession pairs and,
when eligible, profession specializations.
4. Check that low-level bots do not receive specializations before the
required thresholds.
5. Check that eligible bots do receive one specialization for supported
profession families.
6. Verify that specialization choices remain stable across subsequent
refreshes.
7. Verify that profession tools are restored when missing:
   - Mining Pick
   - Blacksmith Hammer
   - Arclight Spanner
   - Runed Arcanite Rod
   - Skinning Knife
8. For a few bots, inspect in game or via debug tooling that profession
spells/specialization spells are present as expected.

Expected behavior:
- Bots receive professions that respect the configured primary
profession limit.
- Profession skill values are initialized to the level-based cap.
- Eligible bots receive exactly one valid specialization for supported
profession families.
- Specialization assignments are logged and persist across refreshes.
- Profession tools are restored only when required.

## Impact Assessment

- Does this change increase per-bot/per-tick processing or risk scaling
poorly with thousands of bots?
    - - [ ] No, not at all
    - - [x] Minimal impact (**explain below**)
    - - [ ] Moderate impact (**explain below**)

  Explanation:
- The added work runs during initialization/refresh rather than normal
per-tick behavior.
- Logic is bounded, data-local, and based on direct skill/spell/value
checks.

- Does this change modify default bot behavior?
    - - [ ] No
    - - [x] Yes (**explain why**)

  Explanation:
- Bots can now start with initialized professions, required tools, and
eligible profession specializations instead of remaining partially
configured or unspecialized.

- Does this change add new decision branches or increase maintenance
complexity?
    - - [ ] No
    - - [x] Yes (**explain below**)

  Explanation:
- The factory now contains specialization assignment branches for
supported profession families.
- Complexity is intentionally limited to init-time switch-based logic
with stored specialization values to preserve predictability.

## AI Assistance

Was AI assistance used while working on this change?
- - [ ] No
- - [x] Yes (**explain below**)

AI assistance was used for:
- code generation and refactoring in `PlayerbotFactory`
- drafting and refining profession/specialization initialization logic
- PR description preparation

All generated and suggested code was reviewed, adjusted, built locally,
and validated before submission.

## 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

- Target branch is `test-staging`.
- Profession/specialization logic is intentionally limited to
init/refresh paths to avoid per-tick cost.
- Specialization selections are stored to keep bot behavior stable
across later refreshes.
- Recent changes also add debug logging for assigned specializations and
save the bot after specialization learning so assignments are visible
and persisted.

---------

Co-authored-by: Keleborn <22352763+Celandriel@users.noreply.github.com>
Co-authored-by: bash <hermensb@gmail.com>
Co-authored-by: Revision <tkn963@gmail.com>
Co-authored-by: kadeshar <kadeshar@gmail.com>
2026-04-17 13:54:36 -07:00
NoxMax
6c517eb9d1
Feat: Reintroduce timed logouts (#2289)
<!--
Thank you for contributing to mod-playerbots, please make sure that
you...
1. Submit your PR to the test-staging branch, not master.
2. Read the guidelines below before submitting.
3. Don't delete parts of this template.

DESIGN PHILOSOPHY: We prioritize STABILITY, PERFORMANCE, AND
PREDICTABILITY over behavioral realism.

Every action and decision executes PER BOT AND PER TRIGGER. Small
increases in logic complexity scale
poorly across thousands of bots and negatively affect all. We prioritize
a stable system over a smarter
one. Bots don't need to behave perfectly; believable behavior is the
goal, not human simulation.
Default behavior must be cheap in processing; expensive behavior must be
opt-in.

Before submitting, make sure your changes aligns with these principles.
-->

## Pull Request Description
<!-- Describe what this change does and why it is needed -->
Timed logouts was enabled in the past, but was disabled due to a
misdiagnosis on an issue that caused crashes. That issue was better
understood and resolved in #2131. Now timed logouts are reintroduced for
alt-bots and addclass-bots. As before, random-bots do not and should not
accept logout commands.

Note that if the bot's master has instant logout privileges according to
`InstantLogout` in worldserver.conf, so would the bot. If not, neither
would the bot.

## Feature Evaluation
<!--
If your PR is very minimal (comment typo, wrong ID reference, etc), and
it is very obvious it will not have
any impact on performance, you may skip these question. If necessary, a
maintainer may ask you for them later.
-->

<!-- Please answer the following: -->
- Describe the **minimum logic** required to achieve the intended
behavior.
- Describe the **processing cost** when this logic executes across many
bots.
Feature at minimum logic needed to implement. No measurable processing
cost.


## How to Test the Changes
<!--
- Step-by-step instructions to test the change.
- Any required setup (e.g. multiple players, number of bots, specific
configuration).
- Expected behavior and how to verify it.
-->
1. Have your account gmlevel set to 2 in acore_auth>account_access just
to test how it works with security parameters.
2. Set `InstantLogout = 3` in worldserver.conf.
3. Invite an addclass or alt-bot.
4. Bot should logout if whispered "logout" to or if you logout.
5. If not in a resting place, neither you nor the bot should be able to
instant logout according to the security setting.
6. After the bot logout, log it back in and whisper "logout" again, but
right after whisper "cancel logout" or "logout cancel". That should
cancel the logout.
7. Have your account gmlevel set to 3 in acore_auth>account_access.
(when you change your gmlevel, you need to log out of your account for
the change to take effect)
8. You are now at admin gmlevel, and with `InstantLogout = 3`, you and
any bot under your command should be able to logout instantly.


## Impact Assessment
<!-- As a generic test, before and after measure of pmon (playerbot pmon
tick) can help you here. -->
- Does this change increase per-bot/per-tick processing or risk scaling
poorly with thousands of bots?
    - - [x] No, not at all
    - - [ ] Minimal impact (**explain below**)
    - - [ ] Moderate impact (**explain below**)



- Does this change modify default bot behavior?
    - - [ ] No
    - - [x] Yes (**explain why**)
Bots now trigger instant or timed logout under the same circumstances
that would apply to their master.


- Does this change add new decision branches or increase maintenance
complexity?
    - - [ ] No
    - - [x] Yes (**explain below**)
Checks if bot is eligible for instant logout or not. If not, timed
logout applies to them.


## AI Assistance
<!--
AI assistance is allowed, but all submitted code must be fully
understood, reviewed, and owned by the contributor.
We expect contributors to be honest about what they do and do not
understand.
-->
Was AI assistance used while working on this change?
- - [x] No
- - [ ] Yes (**explain below**)
<!--
If yes, please specify:
- Purpose of usage (e.g. brainstorming, refactoring, documentation, code
generation).
- Which parts of the change were influenced or generated, and whether it
was thoroughly reviewed.
-->



<!--
TRANSLATIONS:
Anything new that the bots say in chat must be in a translatable format.
This is done using GetBotTextOrDefault,
which you can search for in the codebase to find examples. Your code
needs to have English as the default fallback,
while the full translations need to be in an SQL update file. The
languages in the file are the nine language
options supported by AzerothCore: English, Korean, French, German,
Chinese, Taiwanese, Spanish, Spanish Mexico, and
Russian. See
data/sql/playerbots/updates/2025_12_27_ai_playerbot_fishing_text.sql as
an example of a translation SQL
update, whose content are called within the codebase at
src/strategy/actions/FishingAction.cpp
-->

## 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
<!-- Anything else that's helpful to review or test your pull request.
-->
While testing this I was having some odd issues with the command
`account set gmlevel`. Not sure what's going on there, but for purposes
of testing this and changing your account security level, doing it
directly in the DB at "acore_auth>account_access" is going to be most
reliable.
2026-04-17 11:27:44 -07:00
Crow
a34681bd7e
Modify UpdateAI to Allow Future Methods to Interrupt Bot Spells (#2295)
Note: Resubmitted because the prior PR had master for the source

<!--
Thank you for contributing to mod-playerbots, please make sure that
you...
1. Submit your PR to the test-staging branch, not master.
2. Read the guidelines below before submitting.
3. Don't delete parts of this template.

DESIGN PHILOSOPHY: We prioritize STABILITY, PERFORMANCE, AND
PREDICTABILITY over behavioral realism.

Every action and decision executes PER BOT AND PER TRIGGER. Small
increases in logic complexity scale
poorly across thousands of bots and negatively affect all. We prioritize
a stable system over a smarter
one. Bots don't need to behave perfectly; believable behavior is the
goal, not human simulation.
Default behavior must be cheap in processing; expensive behavior must be
opt-in.

Before submitting, make sure your changes aligns with these principles.
-->

## Pull Request Description
<!-- Describe what this change does and why it is needed -->

This PR adds to PlayerbotAI::UpdateAI a boolean variable,
pendingCastInterrupt, and a public function, RequestCastInterrupt(),
that toggles the variable and would then call InterruptSpells in
UpdateAI. This lets an external script hook into UpdateAI to interrupt a
spell that is in the process of being cast. This should allow
raid/dungeon strategies to actually interrupt spells, such as for
avoiding hazards, as you cannot do so by calling InterruptSpells() or
Reset() or anything else with a raid/dungeon action method.

## Feature Evaluation
<!--
If your PR is very minimal (comment typo, wrong ID reference, etc), and
it is very obvious it will not have
any impact on performance, you may skip these question. If necessary, a
maintainer may ask you for them later.
-->

<!-- Please answer the following: -->
- Describe the **minimum logic** required to achieve the intended
behavior.
- Describe the **processing cost** when this logic executes across many
bots.

There is no processing cost from this PR itself since it just adds a
simple boolean check that will always return false unless other methods
are implemented to call RequestCastInterrupt().

## How to Test the Changes
<!--
- Step-by-step instructions to test the change.
- Any required setup (e.g. multiple players, number of bots, specific
configuration).
- Expected behavior and how to verify it.
-->

This PR doesn't do anything by itself, but confirmation of no
performance impact can be tested by just playing with the PR merged. I
tested this by introducing scripts that called RequestCastInterrupt()
for Archimonde (included in the Hyjal PR now) and for Auchenai Crypts
(built on the strategy from flashtate's PR just for test purposes), and
spells were interrupted as intended.

## Impact Assessment
<!-- As a generic test, before and after measure of pmon (playerbot pmon
tick) can help you here. -->
- Does this change increase per-bot/per-tick processing or risk scaling
poorly with thousands of bots?
    - - [x] No, not at all
    - - [ ] Minimal impact (**explain below**)
    - - [ ] Moderate impact (**explain below**)



- Does this change modify default bot behavior?
    - - [x] No
    - - [ ] Yes (**explain why**)



- Does this change add new decision branches or increase maintenance
complexity?
    - - [ ] No
    - - [x] Yes (**explain below**)

I'm not sure if it counts as "yes" here, but this PR opens up the
ability for scripts to be added that would add real checks to UpdateAI.
The impact of such scripts will depend on how they are implemented,
however. It is possible (and intended) for the external calls to be
highly limited in scope (e.g., only bots in a particular circumstance in
a particular boss fight).

## AI Assistance
<!--
AI assistance is allowed, but all submitted code must be fully
understood, reviewed, and owned by the contributor.
We expect contributors to be honest about what they do and do not
understand.
-->
Was AI assistance used while working on this change?
- - [ ] No
- - [x] Yes (**explain below**)
<!--
If yes, please specify:
- Purpose of usage (e.g. brainstorming, refactoring, documentation, code
generation).
- Which parts of the change were influenced or generated, and whether it
was thoroughly reviewed.
-->

Claude Sonnet 4.6 was used to brainstorm different possibilities to
allow external scripts to interrupt spells. I considered different
options before settling on this one due to it not requiring core
changes, being easily usable in boss strategies, and not having any
performance impact on its own.

<!--
TRANSLATIONS:
Anything new that the bots say in chat must be in a translatable format.
This is done using GetBotTextOrDefault,
which you can search for in the codebase to find examples. Your code
needs to have English as the default fallback,
while the full translations need to be in an SQL update file. The
languages in the file are the nine language
options supported by AzerothCore: English, Korean, French, German,
Chinese, Taiwanese, Spanish, Spanish Mexico, and
Russian. See
data/sql/playerbots/updates/2025_12_27_ai_playerbot_fishing_text.sql as
an example of a translation SQL
update, whose content are called within the codebase at
src/strategy/actions/FishingAction.cpp
-->

## 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
<!-- Anything else that's helpful to review or test your pull request.
-->

---------

Co-authored-by: Keleborn <22352763+Celandriel@users.noreply.github.com>
Co-authored-by: bash <hermensb@gmail.com>
Co-authored-by: Revision <tkn963@gmail.com>
Co-authored-by: kadeshar <kadeshar@gmail.com>
2026-04-17 11:27:11 -07:00
Hokken
ce1adebc78
fix(Core): scope AddPlayerBot loading count to master account (#2307)
## Problem

`AddPlayerBot()` falsely rejects player bot additions with *"You have
added too many bots (more than 40)"* even when the player has zero
personal bots.

This happens because the `MaxAddedBots` check at `PlayerbotMgr.cpp:124`
adds `botLoading.size()` to the player's personal bot count:

```cpp
uint32 count = mgr->GetPlayerbotsCount() + botLoading.size();
```

`botLoading` is a `static std::unordered_set<ObjectGuid>` on
`PlayerbotHolder` — shared by both `PlayerbotMgr` (per-player) and
`RandomPlayerbotMgr` (singleton). When `RandomPlayerbotMgr` loads random
bots at startup (up to 60 per interval via `RandomBotsPerInterval`),
their GUIDs go into the same global set. During the startup loading
window, `botLoading.size()` can easily reach 100–300, far exceeding the
default `MaxAddedBots = 40` limit.

The result: any player who logs in during the random bot loading window
and tries `.playerbot add <name>` gets blocked, even though the limit is
intended to be per-player.

### How to reproduce

1. Set `AiPlayerbot.RandomBotAutologin = 1` (default) with 500 random
bots
2. Start the server
3. Log in immediately while random bots are still loading
4. Run `.playerbot add <character_name>` for an offline character on
your account
5. Get *"You have added too many bots (more than 40)"* despite having 0
personal bots
6. Wait 1–2 minutes for random bot loading to finish, try again — works

### Root cause

- `PlayerbotHolder::botLoading` is declared `static` at
`PlayerbotMgr.h:60`, so both `PlayerbotMgr` and `RandomPlayerbotMgr`
share the same set
- `AddPlayerBot()` inserts into `botLoading` at line 147 for ALL callers
— both player-initiated adds (`masterAccountId > 0`) and random bot
spawns (`masterAccountId = 0`)
- The count check at line 124 uses `botLoading.size()` (the entire
global set) instead of filtering to bots being loaded for the requesting
player
- The config comment confirms the intended scope: *"The maximum number
of bots that a player can control simultaneously"*

## Fix

Change `botLoading` from `unordered_set<ObjectGuid>` to
`unordered_map<ObjectGuid, uint32>` where the value is the
`masterAccountId` passed to `AddPlayerBot()`. Random bots are loaded
with `masterAccountId = 0`.

The count check now iterates the map and only counts entries matching
the current player's `masterAccountId`:

```cpp
uint32 loadingForMaster = 0;
for (auto const& [guid, acctId] : botLoading)
{
    if (acctId == masterAccountId)
        ++loadingForMaster;
}
uint32 count = mgr->GetPlayerbotsCount() + loadingForMaster;
```

### Callsite compatibility

All 10 existing `botLoading` callsites were audited:

| Callsite | Operation | Compatible |
|----------|-----------|-----------|
| `PlayerbotMgr.cpp:85` | `find()` by key | Yes |
| `PlayerbotMgr.cpp:153` | `emplace()` (was `insert()`) | Changed |
| `PlayerbotMgr.cpp:174` | `erase()` by key | Yes |
| `PlayerbotMgr.cpp:209` | `erase()` by key | Yes |
| `PlayerbotMgr.cpp:229` | `erase()` by key | Yes |
| `PlayerbotMgr.cpp:1163` | `find()` by key | Yes |
| `RandomPlayerbotMgr.cpp:429` | `empty()` | Yes |

The six unchanged callsites use `find()`, `erase()`, and `empty()` which
operate on keys identically for both `unordered_set` and
`unordered_map`.

## Files changed

| File | Change |
|------|--------|
| `src/Bot/PlayerbotMgr.h` | `botLoading` type:
`unordered_set<ObjectGuid>` → `unordered_map<ObjectGuid, uint32>` |
| `src/Bot/PlayerbotMgr.cpp` | Definition type updated, `insert` →
`emplace` with `masterAccountId`, count check filters by
`masterAccountId` |

## What is NOT changed

- `MaxAddedBots` config key and default value (40) — unchanged
- Random bot loading behavior — unchanged
- The `botLoading.empty()` throttle in `RandomPlayerbotMgr` — unchanged
- In-game group invite flow — unaffected (does not go through
`AddPlayerBot`)
- No new config keys, no schema changes, no API changes

---------

Co-authored-by: Keleborn <22352763+Celandriel@users.noreply.github.com>
Co-authored-by: bash <hermensb@gmail.com>
Co-authored-by: Revision <tkn963@gmail.com>
Co-authored-by: kadeshar <kadeshar@gmail.com>
Co-authored-by: Hokken <Hokken@users.noreply.github.com>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-17 11:26:42 -07:00
Flashtate98
8f7d352f7e
Implement Auchenai Crypts Strategies and TBC Dungeon Contexts (#2229)
<!--
Thank you for contributing to mod-playerbots, please make sure that
you...
1. Submit your PR to the test-staging branch, not master.
2. Read the guidelines below before submitting.
3. Don't delete parts of this template.

DESIGN PHILOSOPHY: We prioritize STABILITY, PERFORMANCE, AND
PREDICTABILITY over behavioral realism.

Every action and decision executes PER BOT AND PER TRIGGER. Small
increases in logic complexity scale
poorly across thousands of bots and negatively affect all. We prioritize
a stable system over a smarter
one. Bots don't need to behave perfectly; believable behavior is the
goal, not human simulation.
Default behavior must be cheap in processing; expensive behavior must be
opt-in.

Before submitting, make sure your changes aligns with these principles.
-->

## Pull Request Description
<!-- Describe what this change does and why it is needed -->

This PR aims to add bot strategies to the Auchenai Crypts dungeon,
specifically for the boss Shirrak the Dead Watcher, as his focus fire
mechanic is really annoying to deal with.

Additionally I have added TbcDungeonActionContext.h and
TbcDungeonTriggerContext.h for future reference as I add more strategies
to TBC dungeons that need it.

A HUGE thank you to @brighton-chi for all his help. This has been a fun
learning experience!

## Feature Evaluation
<!--
If your PR is very minimal (comment typo, wrong ID reference, etc), and
it is very obvious it will not have
any impact on performance, you may skip these question. If necessary, a
maintainer may ask you for them later.
-->

<!-- Please answer the following: -->
- Describe the **minimum logic** required to achieve the intended
behavior.

Trigger: A 20 yard radius grid search is performed to locate the focus
fire trigger NPC

Action: Bots will flee from the trigger NPC using MoveAway with a 5 yard
safety buffer

Multiplier: A for loop that prevents bots from running back into the
focus fire mechanic while its active.

Tanking: Tanks have a set coordinate to drag the boss to for the
duration of the fight.

- Describe the **processing cost** when this logic executes across many
bots.

Minimal, these scripts only execute when Shirrak has been engaged.

## How to Test the Changes
<!--
- Step-by-step instructions to test the change.
- Any required setup (e.g. multiple players, number of bots, specific
configuration).
- Expected behavior and how to verify it.
-->

Go into Auchenai Crypts (Normal or Heroic) and engage Shirrak the Dead
Watcher

## Impact Assessment
<!-- As a generic test, before and after measure of pmon (playerbot pmon
tick) can help you here. -->
- Does this change increase per-bot/per-tick processing or risk scaling
poorly with thousands of bots?
    - - [ ] No, not at all
    - - [X] Minimal impact (**explain below**)
    - - [ ] Moderate impact (**explain below**)

This logic is only applied to Auchenai Crypts and activates during
Shirrak's encounter.


- Does this change modify default bot behavior?
    - - [ ] No
    - - [X] Yes (**explain why**)

Behavior only applies when in the instance and when engaged with
Shirrak.

- Does this change add new decision branches or increase maintenance
complexity?
    - - [ ] No
    - - [X] Yes (**explain below**)

New dungeon contexts were added (TbcDungeonActionContext and
TbcDungeonTriggerContext) to provide a clean and dedicated structure for
future TBC dungeon strategies that will be developed. This was done to
be in alignment with the existing WOTLK contexts that already exist.

## Messages to Translate
<!--
Bot messages have to be translatable, but you don't need to do the
translations here. You only need to make sure
the message is in a translatable format, and list in the table the
message_key and the default English message.
Search for GetBotTextOrDefault in the codebase for examples.
-->
Does this change add bot messages to translate?
    - - [X] No
    - - [ ] Yes (**list messages in the table**)

| Message key  | Default message |
| --------------- | ------------------ |
|			 |			      |
|			 |			      |

## AI Assistance
<!--
AI assistance is allowed, but all submitted code must be fully
understood, reviewed, and owned by the contributor.
We expect contributors to be honest about what they do and do not
understand.
-->
Was AI assistance used while working on this change?
    - - [ ] No
    - - [X] Yes (**explain below**)
<!--
If yes, please specify:
- Purpose of usage (e.g. brainstorming, refactoring, documentation, code
generation).
- Which parts of the change were influenced or generated, and whether it
was thoroughly reviewed.
-->
Gemini was used to help me understand existing code in the module I was
referencing and reusing to develop this strategy as I am not a
programmer and hardly know anything about C++.


## Final Checklist

- - [X] Stability is not compromised.
- - [ ] Performance impact is understood, tested, and acceptable.
- - [ ] Added logic complexity is justified and explained.
- - [ ] Documentation updated if needed (Conf comments, WiKi commands).

## Notes for Reviewers
<!-- Anything else that's helpful to review or test your pull request.
-->

If there are any better alternatives that could be used to help improve
the strategy in any way, please suggest it. I am very new to this and
want to learn and improve.

---------

Co-authored-by: Keleborn <22352763+Celandriel@users.noreply.github.com>
Co-authored-by: bash <hermensb@gmail.com>
Co-authored-by: Revision <tkn963@gmail.com>
Co-authored-by: kadeshar <kadeshar@gmail.com>
2026-04-17 11:26:08 -07:00
Keleborn
53a607e147
Enable bots to do Outdoor pvp (#2217)
## Pull Request Description
Bots will now engage with outdoor pvp targets when in an area with them.
I carved this out of the guildrpg system Im working on since it should
work just fine as a standalone. Note this requires a core update
https://github.com/azerothcore/azerothcore-wotlk/pull/25103

## Feature Evaluation

Its not expensive. the status checks are fairly light and simple. Should
be on par with current rpg system actions

## How to Test the Changes

You can try to use selfbot to enable this while in EPL, or set the
probability of all other rpg actions to 0.


## Impact Assessment
<!-- As a generic test, before and after measure of pmon (playerbot pmon
tick) can help you here. -->
- Does this change increase per-bot/per-tick processing or risk scaling
poorly with thousands of bots?
    - [ ] No, not at all
    - [x] Minimal impact (**explain below**)
    - [ ] Moderate impact (**explain below**)

There is some impact, but should be minimal overall. 

- Does this change modify default bot behavior?
    - [ ] No
    - [x] Yes (**explain why**)
It will activate automatically based on default config. 


- Does this change add new decision branches or increase maintenance
complexity?
    - [ ] No
    - [x] Yes (**explain below**)

## AI Assistance
Was AI assistance used while working on this change?
- [ ] No
- [x] Yes (**explain below**)
<!--
If yes, please specify:
- Purpose of usage (e.g. brainstorming, refactoring, documentation, code
generation).
- Which parts of the change were influenced or generated, and whether it
was thoroughly reviewed.
-->
Nothing beyond search functionality and autocomplete. 


## Final Checklist

- [x] Stability is not compromised.
- [x] Performance impact is understood, tested, and acceptable.
- [x] Added logic complexity is justified and explained.
- [x] Documentation updated if needed (Conf comments, WiKi commands).

## Notes for Reviewers
<!-- Anything else that's helpful to review or test your pull request.
-->

---------

Co-authored-by: bash <hermensb@gmail.com>
Co-authored-by: Revision <tkn963@gmail.com>
Co-authored-by: kadeshar <kadeshar@gmail.com>
2026-04-10 22:16:58 -07:00
kadeshar
e13aa7d2f6
IsTank fix for Death Knight (#2296)
<!--
Thank you for contributing to mod-playerbots, please make sure that
you...
1. Submit your PR to the test-staging branch, not master.
2. Read the guidelines below before submitting.
3. Don't delete parts of this template.

DESIGN PHILOSOPHY: We prioritize STABILITY, PERFORMANCE, AND
PREDICTABILITY over behavioral realism.

Every action and decision executes PER BOT AND PER TRIGGER. Small
increases in logic complexity scale
poorly across thousands of bots and negatively affect all. We prioritize
a stable system over a smarter
one. Bots don't need to behave perfectly; believable behavior is the
goal, not human simulation.
Default behavior must be cheap in processing; expensive behavior must be
opt-in.

Before submitting, make sure your changes aligns with these principles.
-->

## Pull Request Description
<!-- Describe what this change does and why it is needed -->

Death Knights with Frost Presents are recognized by bots as tank

Related with: #2290 

## How to Test the Changes
<!--
- Step-by-step instructions to test the change.
- Any required setup (e.g. multiple players, number of bots, specific
configuration).
- Expected behavior and how to verify it.
-->

1. Create Death Knight and apply Frost Presence 
2. Invite Restoration Druid bot to party
3. Bot should apply "Thorns" on you

## Impact Assessment
<!-- As a generic test, before and after measure of pmon (playerbot pmon
tick) can help you here. -->
- Does this change increase per-bot/per-tick processing or risk scaling
poorly with thousands of bots?
    - - [x] No, not at all
    - - [ ] Minimal impact (**explain below**)
    - - [ ] Moderate impact (**explain below**)



- Does this change modify default bot behavior?
    - - [ ] No
    - - [x] Yes (**explain why**)

Bots now identify Death Knight with Frost Presence as tank


- Does this change add new decision branches or increase maintenance
complexity?
    - - [x] No
    - - [ ] Yes (**explain below**)



## AI Assistance
<!--
AI assistance is allowed, but all submitted code must be fully
understood, reviewed, and owned by the contributor.
We expect contributors to be honest about what they do and do not
understand.
-->
Was AI assistance used while working on this change?
- - [x] No
- - [ ] Yes (**explain below**)
<!--
If yes, please specify:
- Purpose of usage (e.g. brainstorming, refactoring, documentation, code
generation).
- Which parts of the change were influenced or generated, and whether it
was thoroughly reviewed.
-->



<!--
TRANSLATIONS:
Anything new that the bots say in chat must be in a translatable format.
This is done using GetBotTextOrDefault,
which you can search for in the codebase to find examples. Your code
needs to have English as the default fallback,
while the full translations need to be in an SQL update file. The
languages in the file are the nine language
options supported by AzerothCore: English, Korean, French, German,
Chinese, Taiwanese, Spanish, Spanish Mexico, and
Russian. See
data/sql/playerbots/updates/2025_12_27_ai_playerbot_fishing_text.sql as
an example of a translation SQL
update, whose content are called within the codebase at
src/strategy/actions/FishingAction.cpp
-->

## 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
<!-- Anything else that's helpful to review or test your pull request.
-->

Example of non Blood Death Knight tank build
https://forum.warmane.com/showthread.php?325582
2026-04-10 22:15:57 -07:00
bashermens
4bcf8fd2c4
Performance(Core): Some activity sec to ms init fixes, global activity loop check and some additional minor fixes (#2288)
<!--
Thank you for contributing to mod-playerbots, please make sure that
you...
1. Submit your PR to the test-staging branch, not master.
2. Read the guidelines below before submitting.
3. Don't delete parts of this template.

DESIGN PHILOSOPHY: We prioritize STABILITY, PERFORMANCE, AND
PREDICTABILITY over behavioral realism.

Every action and decision executes PER BOT AND PER TRIGGER. Small
increases in logic complexity scale
poorly across thousands of bots and negatively affect all. We prioritize
a stable system over a smarter
one. Bots don't need to behave perfectly; believable behavior is the
goal, not human simulation.
Default behavior must be cheap in processing; expensive behavior must be
opt-in.

Before submitting, make sure your changes aligns with these principles.
-->

## Pull Request Description

1. Corrected the init activity times; Since ive changed (previous) the
calc from seconds to ms to increase more scope for the offset execute
jitter (removed timer(), 0 is correct way todo now with MS) (also broke
self-bot)
2. Global loop checks in activityAllowed instead vs multiple loops, this
function is called very often so we better optimize it.
3 Fixed the broken 'HasManyPlayersNearby' function and then deleted it
:O To fragile due various edge cases and rather expensive call, besides
lets activeAlone deal with this situation which is way more controlled.
4. Some additional small fixes that where unnoticed overtime.
5. Added/Changed inline comments which makes more sense and explains
what it does.
6. Removed dead code freeze bots during init.
7. self-bot fix

## Impact Assessment
<!-- As a generic test, before and after measure of pmon (playerbot pmon
tick) can help you here. -->
- Does this change increase per-bot/per-tick processing or risk scaling
poorly with thousands of bots?
    - - [ ] No, not at all
    - - [ ] Minimal impact (**explain below**)
    - - [x] Moderate impact (**explain below**)

When playing with larger amount of real players makes the allowed
activity perform better.

- Does this change modify default bot behavior?
    - - [x] No
    - - [ ] Yes (**explain why**)



- Does this change add new decision branches or increase maintenance
complexity?
    - - [x] No
    - - [ ] Yes (**explain below**)



## AI Assistance
<!--
AI assistance is allowed, but all submitted code must be fully
understood, reviewed, and owned by the contributor.
We expect contributors to be honest about what they do and do not
understand.
-->
Was AI assistance used while working on this change?
- - [x] No
- - [ ] Yes (**explain below**)
<!--
If yes, please specify:
- Purpose of usage (e.g. brainstorming, refactoring, documentation, code
generation).
- Which parts of the change were influenced or generated, and whether it
was thoroughly reviewed.
-->



<!--
TRANSLATIONS:
Anything new that the bots say in chat must be in a translatable format.
This is done using GetBotTextOrDefault,
which you can search for in the codebase to find examples. Your code
needs to have English as the default fallback,
while the full translations need to be in an SQL update file. The
languages in the file are the nine language
options supported by AzerothCore: English, Korean, French, German,
Chinese, Taiwanese, Spanish, Spanish Mexico, and
Russian. See
data/sql/playerbots/updates/2025_12_27_ai_playerbot_fishing_text.sql as
an example of a translation SQL
update, whose content are called within the codebase at
src/strategy/actions/FishingAction.cpp
-->

## 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
<!-- Anything else that's helpful to review or test your pull request.
-->
2026-04-08 19:35:18 +02:00
Benjamin Jackson
7b04c56956
Add default case to mount initialization for bots. (#2276)
## Pull Request Description
<!-- Describe what this change does and why it is needed -->
This PR adds a default case for the mount initialization function for
player bots, allowing custom race additions to not crash when added to
an AzerothCore server (such as
[`mod-worgoblin`](https://github.com/heyitsbench/mod-worgoblin)).

## Feature Evaluation
This feature ideally does not get touched in standard `mod-playerbots`
usage, as it only adds a case to a switch statement, and would not be
getting taken with Blizzlike data (which the vast majority of users
likely use).

## How to Test the Changes
1. Add custom races to your AzerothCore instance (most easily
accomplished with the above linked module).
2. Start the server and configure it to create random player bots (that
fall under the added custom races).
3. Observe no crash.

## Impact Assessment
- Does this change increase per-bot/per-tick processing or risk scaling
poorly with thousands of bots?
    - - [X] No, not at all

- Does this change modify default bot behavior?
    - - [X] No

- Does this change add new decision branches or increase maintenance
complexity?
    - - [X] Yes (**explain below**)
This does add another path in a switch statement. It also creates
another set of data for that case. This could have been avoided by
consolidating the human/orc cases into the default case, but I elected
not to do that in case players make their own changes. If preferred, I
can definitely consolidate the cases to not have those redundant data
points.

## Messages to Translate
- Does this change add bot messages to translate?
    - - [X] No

## AI Assistance
- Was AI assistance used while working on this change?
    - - [X] No

## Final Checklist
- - [X] Stability is not compromised.
- - [X] Performance impact is understood, tested, and acceptable.
- - [X] Added logic complexity is justified and explained.
- - [ ] Documentation updated if needed (Conf comments, WiKi commands).

## Notes for Reviewers
Pretty please? 🥹

---------

Co-authored-by: Keleborn <22352763+Celandriel@users.noreply.github.com>
2026-04-04 13:22:27 +02:00
kadeshar
4c9b0adb72
Fire mage cc (#2281)
<!--
Thank you for contributing to mod-playerbots, please make sure that
you...
1. Submit your PR to the test-staging branch, not master.
2. Read the guidelines below before submitting.
3. Don't delete parts of this template.

DESIGN PHILOSOPHY: We prioritize STABILITY, PERFORMANCE, AND
PREDICTABILITY over behavioral realism.

Every action and decision executes PER BOT AND PER TRIGGER. Small
increases in logic complexity scale
poorly across thousands of bots and negatively affect all. We prioritize
a stable system over a smarter
one. Bots don't need to behave perfectly; believable behavior is the
goal, not human simulation.
Default behavior must be cheap in processing; expensive behavior must be
opt-in.

Before submitting, make sure your changes aligns with these principles.
-->

## Pull Request Description
<!-- Describe what this change does and why it is needed -->

Added support for fire mage cc spells like: Dragon's Breath (disorient)
and Blast Wave (knockback)

## How to Test the Changes
<!--
- Step-by-step instructions to test the change.
- Any required setup (e.g. multiple players, number of bots, specific
configuration).
- Expected behavior and how to verify it.
-->

1. Invite fire mage to party
2. Add strategy `nc +duel`
3. Start duel and go near bot
4. Bot should use frost nova/dragon's breath/blast wave depends of
cooldowns

## Impact Assessment
<!-- As a generic test, before and after measure of pmon (playerbot pmon
tick) can help you here. -->
- Does this change increase per-bot/per-tick processing or risk scaling
poorly with thousands of bots?
    - - [x] No, not at all
    - - [ ] Minimal impact (**explain below**)
    - - [ ] Moderate impact (**explain below**)



- Does this change modify default bot behavior?
    - - [ ] No
    - - [x] Yes (**explain why**)

Mages cc by default

- Does this change add new decision branches or increase maintenance
complexity?
    - - [x] No
    - - [ ] Yes (**explain below**)



## Messages to Translate
<!--
Bot messages have to be translatable, but you don't need to do the
translations here. You only need to make sure
the message is in a translatable format, and list in the table the
message_key and the default English message.
Search for GetBotTextOrDefault in the codebase for examples.
-->
- Does this change add bot messages to translate?
    - - [x] No
    - - [ ] Yes (**list messages in the table**)

| Message key  | Default message |
| --------------- | ------------------ |
|			 |			      |
|			 |			      |

## AI Assistance
<!--
AI assistance is allowed, but all submitted code must be fully
understood, reviewed, and owned by the contributor.
We expect contributors to be honest about what they do and do not
understand.
-->
- Was AI assistance used while working on this change?
    - - [ ] No
    - - [x] Yes (**explain below**)
<!--
If yes, please specify:
- Purpose of usage (e.g. brainstorming, refactoring, documentation, code
generation).
- Which parts of the change were influenced or generated, and whether it
was thoroughly reviewed.
-->

OpenCode, for research differences between CcStrategy implementation
between cmangos and ac playerbots

## Final Checklist

- - [x] Stability is not compromised.
- - [x] Performance impact is understood, tested, and acceptable.
- - [x] Added logic complexity is justified and explained.
- - [x] Documentation updated if needed (Conf comments, WiKi commands).

## Notes for Reviewers
<!-- Anything else that's helpful to review or test your pull request.
-->
2026-04-04 13:00:51 +02:00
Keleborn
ca54cff6f5
Bug fix. Edge case where bots would get stuck in cities. (#2269)
<!--
Thank you for contributing to mod-playerbots, please make sure that
you...
1. Submit your PR to the test-staging branch, not master.
2. Read the guidelines below before submitting.
3. Don't delete parts of this template.

DESIGN PHILOSOPHY: We prioritize STABILITY, PERFORMANCE, AND
PREDICTABILITY over behavioral realism.

Every action and decision executes PER BOT AND PER TRIGGER. Small
increases in logic complexity scale
poorly across thousands of bots and negatively affect all. We prioritize
a stable system over a smarter
one. Bots don't need to behave perfectly; believable behavior is the
goal, not human simulation.
Default behavior must be cheap in processing; expensive behavior must be
opt-in.

Before submitting, make sure your changes aligns with these principles.
-->

## Pull Request Description
<!-- Describe what this change does and why it is needed -->
When I refactored flight destinations, I wanted to make where bots go
more intentional. so I made it dependent on the
allianceHubsPerLevelCache and hodeHubsPerLevelCache. This system relied
on there being an innkeeper in each area that the bots would fly to.
However, not every zone has an innkeeper, and so there was an odd
situation where bots had nowhere to fly to. (Most notably at level 53.)
This solves that by hardcoding the flightmasters in those areas into the
cache.

I also put back in the city teleport probability check which was forcing
every bot to teleport to a city on level up.


## Feature Evaluation
<!--
If your PR is very minimal (comment typo, wrong ID reference, etc), and
it is very obvious it will not have
any impact on performance, you may skip these question. If necessary, a
maintainer may ask you for them later.
-->

<!-- Please answer the following: -->
- Describe the **minimum logic** required to achieve the intended
behavior.
- Describe the **processing cost** when this logic executes across many
bots.



## How to Test the Changes
<!--
- Step-by-step instructions to test the change.
- Any required setup (e.g. multiple players, number of bots, specific
configuration).
- Expected behavior and how to verify it.
-->



## Impact Assessment
<!-- As a generic test, before and after measure of pmon (playerbot pmon
tick) can help you here. -->
- Does this change increase per-bot/per-tick processing or risk scaling
poorly with thousands of bots?
    - - [x] No, not at all
    - - [ ] Minimal impact (**explain below**)
    - - [ ] Moderate impact (**explain below**)



- Does this change modify default bot behavior?
    - - [x] No
    - - [ ] Yes (**explain why**)



- Does this change add new decision branches or increase maintenance
complexity?
    - - [x] No
    - - [ ] Yes (**explain below**)



## Messages to Translate
<!--
Bot messages have to be translatable, but you don't need to do the
translations here. You only need to make sure
the message is in a translatable format, and list in the table the
message_key and the default English message.
Search for GetBotTextOrDefault in the codebase for examples.
-->
- Does this change add bot messages to translate?
    - - [x] No
    - - [ ] Yes (**list messages in the table**)

| Message key  | Default message |
| --------------- | ------------------ |
|			 |			      |
|			 |			      |

## AI Assistance
<!--
AI assistance is allowed, but all submitted code must be fully
understood, reviewed, and owned by the contributor.
We expect contributors to be honest about what they do and do not
understand.
-->
- Was AI assistance used while working on this change?
    - - [ ] No
    - - [x] Yes (**explain below**)
<!--
If yes, please specify:
- Purpose of usage (e.g. brainstorming, refactoring, documentation, code
generation).
- Which parts of the change were influenced or generated, and whether it
was thoroughly reviewed.
-->
Debugging and comments.



## Final Checklist

- - [x] Stability is not compromised.
- - [x] Performance impact is understood, tested, and acceptable.
- - [x] Added logic complexity is justified and explained.
- - [x] Documentation updated if needed (Conf comments, WiKi commands).

## Notes for Reviewers
<!-- Anything else that's helpful to review or test your pull request.
-->
2026-04-04 13:00:01 +02:00
bashermens
c0390a24fd
feat(Performance): BotActiveAlone activity interval fixes and default settings for avg player (#2250)
<!--
Thank you for contributing to mod-playerbots, please make sure that
you...
1. Submit your PR to the test-staging branch, not master.
2. Read the guidelines below before submitting.
3. Don't delete parts of this template.

DESIGN PHILOSOPHY: We prioritize STABILITY, PERFORMANCE, AND
PREDICTABILITY over behavioral realism.

Every action and decision executes PER BOT AND PER TRIGGER. Small
increases in logic complexity scale
poorly across thousands of bots and negatively affect all. We prioritize
a stable system over a smarter
one. Bots don't need to behave perfectly; believable behavior is the
goal, not human simulation.
Default behavior must be cheap in processing; expensive behavior must be
opt-in.

Before submitting, make sure your changes aligns with these principles.
-->

## Pull Request Description

- Bugfix the jittering on/off of botAlone activity
- BotActiveAlone activity duration configurable
- Updated the default config values for general user for a smoother
experience
- Added offset jittering for the check allowedActivity and check next AI
delay to prevent cpu spikes

(disabled WhenIsFriend can cause race conditions)

## Feature Evaluation
<!--
If your PR is very minimal (comment typo, wrong ID reference, etc), and
it is very obvious it will not have
any impact on performance, you may skip these question. If necessary, a
maintainer may ask you for them later.
-->

<!-- Please answer the following: -->
- Describe the **minimum logic** required to achieve the intended
behavior.
- Describe the **processing cost** when this logic executes across many
bots.



## How to Test the Changes
<!--
- Step-by-step instructions to test the change.
- Any required setup (e.g. multiple players, number of bots, specific
configuration).
- Expected behavior and how to verify it.
-->



## Impact Assessment
<!-- As a generic test, before and after measure of pmon (playerbot pmon
tick) can help you here. -->
- Does this change increase per-bot/per-tick processing or risk scaling
poorly with thousands of bots?
    - - [ ] No, not at all
    - - [ ] Minimal impact (**explain below**)
    - - [x] Moderate impact (**explain below**)

In a positive way, bots in your zone and 150 radius will always be
active, meanwhile other bots will be active 40%
of the time with intervals for 60 seconds per bot. With much lower
latencies. All configurable without say.

40% and 60 seconds for more balance for those who seek bots create world
feel more natural and live vs bots leveling without killing the server
performance. Why not 50 due activity of bots itself 40% will result more
into 45-50% like behavior and 50% prolly more 55%-60%. This it not
something we want incorporate when calculating the value since it
depends on various config and situation. But 40% is good base with
default config.

- Does this change modify default bot behavior?
    - - [x] No
    - - [ ] Yes (**explain why**)



- Does this change add new decision branches or increase maintenance
complexity?
    - - [x] No
    - - [ ] Yes (**explain below**)



## Messages to Translate
<!--
Bot messages have to be translatable, but you don't need to do the
translations here. You only need to make sure
the message is in a translatable format, and list in the table the
message_key and the default English message.
Search for GetBotTextOrDefault in the codebase for examples.
-->
- Does this change add bot messages to translate?
    - - [x] No
    - - [ ] Yes (**list messages in the table**)

| Message key  | Default message |
| --------------- | ------------------ |
|			 |			      |
|			 |			      |

## AI Assistance
<!--
AI assistance is allowed, but all submitted code must be fully
understood, reviewed, and owned by the contributor.
We expect contributors to be honest about what they do and do not
understand.
-->
- Was AI assistance used while working on this change?
    - - [x] No
    - - [ ] Yes (**explain below**)
<!--
If yes, please specify:
- Purpose of usage (e.g. brainstorming, refactoring, documentation, code
generation).
- Which parts of the change were influenced or generated, and whether it
was thoroughly reviewed.
-->



## Final Checklist

- - [x] Stability is not compromised.
- - [x] Performance impact is understood, tested, and acceptable.
- - [x] Added logic complexity is justified and explained.
- - [x] Documentation updated if needed (Conf comments, WiKi commands).

## Notes for Reviewers
<!-- Anything else that's helpful to review or test your pull request.
-->

---------

Co-authored-by: Keleborn <22352763+Celandriel@users.noreply.github.com>
Co-authored-by: Revision <tkn963@gmail.com>
Co-authored-by: kadeshar <kadeshar@gmail.com>
2026-04-03 14:54:46 -07:00
kadeshar
76dd91c4fa
Hand of Freedom support (#2233)
<!--
Thank you for contributing to mod-playerbots, please make sure that
you...
1. Submit your PR to the test-staging branch, not master.
2. Read the guidelines below before submitting.
3. Don't delete parts of this template.

DESIGN PHILOSOPHY: We prioritize STABILITY, PERFORMANCE, AND
PREDICTABILITY over behavioral realism.

Every action and decision executes PER BOT AND PER TRIGGER. Small
increases in logic complexity scale
poorly across thousands of bots and negatively affect all. We prioritize
a stable system over a smarter
one. Bots don't need to behave perfectly; believable behavior is the
goal, not human simulation.
Default behavior must be cheap in processing; expensive behavior must be
opt-in.

Before submitting, make sure your changes aligns with these principles.
-->

## Pull Request Description
Added Hand of Freedom action for paladin.
Related with: #2002 

## How to Test the Changes
<!--
- Step-by-step instructions to test the change.
- Any required setup (e.g. multiple players, number of bots, specific
configuration).
- Expected behavior and how to verify it.
-->

- invite paladin bot to party
- start fight (can use dummy target)
- apply some snare effect to bot or yourself (for example `.aura 1715`)
- bot should use hand of freedom

## Impact Assessment
<!-- As a generic test, before and after measure of pmon (playerbot pmon
tick) can help you here. -->
- Does this change increase per-bot/per-tick processing or risk scaling
poorly with thousands of bots?
    - - [x] No, not at all
    - - [ ] Minimal impact (**explain below**)
    - - [ ] Moderate impact (**explain below**)



- Does this change modify default bot behavior?
    - - [ ] No
    - - [x] Yes (**explain why**)

Yes, paladin bots start using Hand of Freedom

- Does this change add new decision branches or increase maintenance
complexity?
    - - [x] No
    - - [ ] Yes (**explain below**)



## Messages to Translate
<!--
Bot messages have to be translatable, but you don't need to do the
translations here. You only need to make sure
the message is in a translatable format, and list in the table the
message_key and the default English message.
Search for GetBotTextOrDefault in the codebase for examples.
-->
- Does this change add bot messages to translate?
    - - [x] No
    - - [ ] Yes (**list messages in the table**)

| Message key  | Default message |
| --------------- | ------------------ |
|			 |			      |
|			 |			      |

## AI Assistance
<!--
AI assistance is allowed, but all submitted code must be fully
understood, reviewed, and owned by the contributor.
We expect contributors to be honest about what they do and do not
understand.
-->
- Was AI assistance used while working on this change?
    - - [ ] No
    - - [x] Yes (**explain below**)
<!--
If yes, please specify:
- Purpose of usage (e.g. brainstorming, refactoring, documentation, code
generation).
- Which parts of the change were influenced or generated, and whether it
was thoroughly reviewed.
-->

OpenCode, as helper to create and review code

## Final Checklist

- - [x] Stability is not compromised.
- - [x] Performance impact is understood, tested, and acceptable.
- - [x] Added logic complexity is justified and explained.
- - [x] Documentation updated if needed (Conf comments, WiKi commands).

## Notes for Reviewers
<!-- Anything else that's helpful to review or test your pull request.
-->
<img width="424" height="93" alt="obraz"
src="https://github.com/user-attachments/assets/3cac4454-35af-474d-8ea0-67c462973c79"
/>
2026-04-03 13:25:29 -07:00
Crow
79562be2e5
Fix Hunter Aspect Switching + Trigger Cleanups (#2203)
# Pull Request

Note: When I reference Aspect of the Hawk below, it also means Aspect of
the Dragonhawk (the code will use Dragonhawk if the Hunter has it, Hawk
if not, they share actions, triggers, and strategies).

Hunter Aspects are currently bugged. All Hunters, regardless of spec or
strategy, are hardcoded to use Aspect of the Hawk when mana is at 70%+
and Aspect of the Viper when mana drops to "lowMana" from the config
(default is 15%), divided by 2.

This means the following:

- Hawk (bdps) and Viper (bmana) strategies are useless
- Pack (bspeed) and Wild (rnature) strategies are applied, but bots will
rapidly switch back and forth between Pack/Wild and Hawk/Viper,
depending on strategy and mana level.

This PR addresses the issues by doing the following:

- Global Hawk strategy is removed. Now you need to set bdps for Hunters
to use Hawk, but bdps remains the default Aspect strategy for all
Hunters.
- Dedicated Viper strategy is removed, leaving the global strategy.
However, Viper will be used (when lowMana/2) ONLY if the bot is set to
bdps. If the bot has the Wild or Pack strategy, they will not switch to
Viper at all. I did this because I am assuming if you are using Wild or
Pack, you need them for reasons other than to pump DPS.
- The threshold to switch back to Hawk is lowered from 70% to 60%. The
gap between lowMana/2 and 60% is now filled--if bdps is on, Hunters will
switch to Hawk whenever above the Viper threshold, _except_ for when
they have the Viper aura, in which case they will not switch to Hawk
until 60% mana. This lets the Hunter build back mana before swapping
back to Hawk (more like general player behavior) while still letting
them swap from other Aspects to Hawk without needing to be all the way
at 60% mana.
- Gets rid of a weird condition in the Hawk trigger that would make it
so that Hunters would switch to Hawk when at exactly 0 mana. I'm not
sure what the point of that is.

Also, I refactored the triggers a bit because I noticed there was some
dead code in there. I didn't do a comprehensive refactor, but there was
a lot of stuff that clearly didn't make sense even to my eyes, like
back-to-back returns. I think there's more unnecessary code even just in
the triggers, but I didn't want to get too into the weeds with this PR.

---

## Design Philosophy

We prioritize **stability, performance, and predictability** over
behavioral realism.
Complex player-mimicking logic is intentionally limited due to its
negative impact on scalability, maintainability, and
long-term robustness.

Excessive processing overhead can lead to server hiccups, increased CPU
usage, and degraded performance for all
participants. Because every action and
decision tree is executed **per bot and per trigger**, even small
increases in logic complexity can scale poorly and
negatively affect both players and
world (random) bots. Bots are not expected to behave perfectly, and
perfect simulation of human decision-making is not a
project goal. Increased behavioral
realism often introduces disproportionate cost, reduced predictability,
and significantly higher maintenance overhead.

Every additional branch of logic increases long-term responsibility. All
decision paths must be tested, validated, and
maintained continuously as the system evolves.
If advanced or AI-intensive behavior is introduced, the **default
configuration must remain the lightweight decision
model**. More complex behavior should only be
available as an **explicit opt-in option**, clearly documented as having
a measurable performance cost.

Principles:

- **Stability before intelligence**  
  A stable system is always preferred over a smarter one.

- **Performance is a shared resource**  
  Any increase in bot cost affects all players and all bots.

- **Simple logic scales better than smart logic**  
Predictable behavior under load is more valuable than perfect decisions.

- **Complexity must justify itself**  
  If a feature cannot clearly explain its cost, it should not exist.

- **Defaults must be cheap**  
  Expensive behavior must always be optional and clearly communicated.

- **Bots should look reasonable, not perfect**  
  The goal is believable behavior, not human simulation.

Before submitting, confirm that this change aligns with those
principles.

---

## Feature Evaluation

Please answer the following:

- Describe the **minimum logic** required to achieve the intended
behavior?
- Describe the **cheapest implementation** that produces an acceptable
result?
- Describe the **runtime cost** when this logic executes across many
bots?

I don't expect there to be any impact on costs, and if anything this PR
removes some unneeded checks from triggers.

---

## How to Test the Changes

- Step-by-step instructions to test the change
- Any required setup (e.g. multiple players, bots, specific
configuration)
- Expected behavior and how to verify it

The easiest way is to go shoot a dummy with Volley until low on mana and
then toggle on selfbot. You can do this with various Aspects active to
test.

## Complexity & Impact

Does this change add new decision branches?
- - [X] No
- - [ ] Yes (**explain below**)

Does this change increase per-bot or per-tick processing?
- - [X] No
- - [ ] Yes (**describe and justify impact**)

Could this logic scale poorly under load?
- - [X] No
- - [ ] Yes (**explain why**)
---

## Defaults & Configuration

Does this change modify default bot behavior?
- - [ ] No
- - [X] Yes (**explain why**)

Described above. Default behavior is broken.

If this introduces more advanced or AI-heavy logic:
- - [X] Lightweight mode remains the default
- - [ ] More complex behavior is optional and thereby configurable
---

## AI Assistance

Was AI assistance (e.g. ChatGPT or similar tools) used while working on
this change?
- - [ ] No
- - [X] Yes (**explain below**)

I asked Claude some questions about the triggers to make sure I didn't
screw anything up.

If yes, please specify:

- AI tool or model used (e.g. ChatGPT, GPT-4, Claude, etc.)
- Purpose of usage (e.g. brainstorming, refactoring, documentation, code
generation)
- Which parts of the change were influenced or generated
- Whether the result was manually reviewed and adapted

AI assistance is allowed, but all submitted code must be fully
understood, reviewed, and owned by the contributor.
Any AI-influenced changes must be verified against existing CORE and PB
logic. We expect contributors to be honest
about what they do and do not understand.

---

## Final Checklist

- - [X] Stability is not compromised
- - [X] Performance impact is understood, tested, and acceptable
- - [X] Added logic complexity is justified and explained
- - [X] Documentation updated if needed

---

## Notes for Reviewers

Anything that significantly improves realism at the cost of stability or
performance should be carefully discussed
before merging.

---------

Co-authored-by: Keleborn <22352763+Celandriel@users.noreply.github.com>
Co-authored-by: bash <hermensb@gmail.com>
Co-authored-by: Revision <tkn963@gmail.com>
Co-authored-by: kadeshar <kadeshar@gmail.com>
2026-04-03 13:24:37 -07:00
Crow
91eac70ca2
Implement Zul'Aman Strategies (#2186)
# Pull Request

_Implement strategies for all bosses in Zul'Aman. See next post for
overview of implemented strategies._

---

## Design Philosophy

We prioritize **stability, performance, and predictability** over
behavioral realism.
Complex player-mimicking logic is intentionally limited due to its
negative impact on scalability, maintainability, and
long-term robustness.

Excessive processing overhead can lead to server hiccups, increased CPU
usage, and degraded performance for all
participants. Because every action and
decision tree is executed **per bot and per trigger**, even small
increases in logic complexity can scale poorly and
negatively affect both players and
world (random) bots. Bots are not expected to behave perfectly, and
perfect simulation of human decision-making is not a
project goal. Increased behavioral
realism often introduces disproportionate cost, reduced predictability,
and significantly higher maintenance overhead.

Every additional branch of logic increases long-term responsibility. All
decision paths must be tested, validated, and
maintained continuously as the system evolves.
If advanced or AI-intensive behavior is introduced, the **default
configuration must remain the lightweight decision
model**. More complex behavior should only be
available as an **explicit opt-in option**, clearly documented as having
a measurable performance cost.

Principles:

- **Stability before intelligence**  
  A stable system is always preferred over a smarter one.

- **Performance is a shared resource**  
  Any increase in bot cost affects all players and all bots.

- **Simple logic scales better than smart logic**  
Predictable behavior under load is more valuable than perfect decisions.

- **Complexity must justify itself**  
  If a feature cannot clearly explain its cost, it should not exist.

- **Defaults must be cheap**  
  Expensive behavior must always be optional and clearly communicated.

- **Bots should look reasonable, not perfect**  
  The goal is believable behavior, not human simulation.

Before submitting, confirm that this change aligns with those
principles.

---

## Feature Evaluation

Please answer the following:

- Describe the **minimum logic** required to achieve the intended
behavior?
- Describe the **cheapest implementation** that produces an acceptable
result?
- Describe the **runtime cost** when this logic executes across many
bots?

_I have attempted to order checks while taking into account cost and
likelihood and have opted to find lower-cost methods where possible. I
have also not gone as in depth as I have with other strategies,
partially because it is not necessary to complete encounters but also to
try to limit the performance impact. From my observation, including with
pmon, none of the methods should be overly taxing._

---

## How to Test the Changes

- Step-by-step instructions to test the change
- Any required setup (e.g. multiple players, bots, specific
configuration)
- Expected behavior and how to verify it

_Run Zul'Aman. See next post for strategies to test._

## Complexity & Impact

Does this change add new decision branches?
- - [ ] No
- - [x] Yes (**explain below**)

_Only in the context of raid strategies, with new methods to consider
and new multipliers to evaluate when bots perform actions with the
instance strategy active._

Does this change increase per-bot or per-tick processing?
- - [ ] No
- - [x] Yes (**describe and justify impact**)

_The impact is only with the "zulaman" strategy active, which will be
applied only in the instance. There is currently a PR open to also
remove instance strategies when leaving the map to get rid of the
residual performance impact._

Could this logic scale poorly under load?
- - [ ] No
- - [x] Yes (**explain why**)

_Technically yes, but I think it is unlikely to have an appreciable
difference unless there are many groups running the instance at the same
time on a large server._

## Defaults & Configuration

Does this change modify default bot behavior?
- - [ ] No
- - [x] Yes (**explain why**)

_Only in the instance. It is a necessary trade-off to consider with raid
strategies that I always keep in mind (degree of automation vs. player
choice)._

If this introduces more advanced or AI-heavy logic:
- - [x] Lightweight mode remains the default
- - [ ] More complex behavior is optional and thereby configurable

_Not exactly sure how to address this question in the context of this
PR, but there aren't any techniques or methods for this strategy that I
have not tried before (or something very similar)._

## AI Assistance

Was AI assistance (e.g. ChatGPT or similar tools) used while working on
this change?
- - [ ] No
- - [x] Yes (**explain below**)

If yes, please specify:

- AI tool or model used (e.g. ChatGPT, GPT-4, Claude, etc.)
- Purpose of usage (e.g. brainstorming, refactoring, documentation, code
generation)
- Which parts of the change were influenced or generated
- Whether the result was manually reviewed and adapted

_Gemini and GPT for some questions about the codebase and C++ and
assistance with drafting a few things like containers that I find more
tedious to do myself._

AI assistance is allowed, but all submitted code must be fully
understood, reviewed, and owned by the contributor.
Any AI-influenced changes must be verified against existing CORE and PB
logic. We expect contributors to be honest
about what they do and do not understand.

---

## Final Checklist

- - [x] Stability is not compromised
- - [x] Performance impact is understood, tested, and acceptable
- - [x] Added logic complexity is justified and explained
- - [x] Documentation updated if needed

---

## Notes for Reviewers

Anything that significantly improves realism at the cost of stability or
performance should be carefully discussed
before merging.

---------

Co-authored-by: Keleborn <22352763+Celandriel@users.noreply.github.com>
Co-authored-by: bash <hermensb@gmail.com>
Co-authored-by: Revision <tkn963@gmail.com>
Co-authored-by: kadeshar <kadeshar@gmail.com>
2026-03-27 10:38:12 -07:00
NoxMax
c7ac849fbe
Fix: Logout refactor and RNDbot logout error handling (#2131)
# Pull Request

* Improper crash fix by 297f11d3e59f52a29f68188245e6b786c9fa838e. That
fix worked not because setting `logout = true` stops the server from
crashing, but because it stopped the following `if (!logout)` block from
executing at all. In that block `delete target;` was the actual cause of
the crashing and this was recreated in testing.
`botWorldSessionPtr->LogoutPlayer(true);` already deleted target
internally, then comes `delete target;` to delete already freed memory
and the whole thing crashes.

* Players had the ability to logout anyone's alt/addClass bots. Now
there's a check to make sure command is from master.

* When commanded to logout, RNDbots in player's party used to reply with
"I'm logging out!", but they don't, because they shouldn't, because they
are not alt/adClass bots. Now they say "You can't command me to logout!"

* Added early exits for the "logout cancel" block, then I remembered
bots were made to always instantly logout because of past issues with
timed logout. Need to review whether or not we should re-implement timed
logout, or if it's not worth it and its dead code removed with instant
logout remaining the only option.

---

## Design Philosophy

We prioritize **stability, performance, and predictability** over
behavioral realism.
Complex player-mimicking logic is intentionally limited due to its
negative impact on scalability, maintainability, and
long-term robustness.

Excessive processing overhead can lead to server hiccups, increased CPU
usage, and degraded performance for all
participants. Because every action and
decision tree is executed **per bot and per trigger**, even small
increases in logic complexity can scale poorly and
negatively affect both players and
world (random) bots. Bots are not expected to behave perfectly, and
perfect simulation of human decision-making is not a
project goal. Increased behavioral
realism often introduces disproportionate cost, reduced predictability,
and significantly higher maintenance overhead.

Every additional branch of logic increases long-term responsibility. All
decision paths must be tested, validated, and
maintained continuously as the system evolves.
If advanced or AI-intensive behavior is introduced, the **default
configuration must remain the lightweight decision
model**. More complex behavior should only be
available as an **explicit opt-in option**, clearly documented as having
a measurable performance cost.

Principles:

- **Stability before intelligence**  
  A stable system is always preferred over a smarter one.

- **Performance is a shared resource**  
  Any increase in bot cost affects all players and all bots.

- **Simple logic scales better than smart logic**  
Predictable behavior under load is more valuable than perfect decisions.

- **Complexity must justify itself**  
  If a feature cannot clearly explain its cost, it should not exist.

- **Defaults must be cheap**  
  Expensive behavior must always be optional and clearly communicated.

- **Bots should look reasonable, not perfect**  
  The goal is believable behavior, not human simulation.

Before submitting, confirm that this change aligns with those
principles.

---

## Feature Evaluation

Please answer the following:

- Describe the **minimum logic** required to achieve the intended
behavior?
- Describe the **cheapest implementation** that produces an acceptable
result?
- Describe the **runtime cost** when this logic executes across many
bots?

This PR removes more code than it adds, and makes sure that exits happen
as early as possible. It has no effect on processing power and makes the
code slightly more maintainable.

---

## How to Test the Changes

1. Whisper `logout` to any bot whose master is not you. The bot can be
RND/alt/addClass. The bot may have someone else as a master or may not
have a master at all. The bot may be part of a party or not. Regardless,
you are not its master. It should tell you "You are not my master!". Two
players or two instances of the client from two different accounts are
needed for this test, in order for Player A to command a bot to logout,
when the bot's master is Player B.

2. Invite an RND bot to your party. As along as it's in your party, you
are it's master, but RND bots cannot be logged out through chat
commands. If you whisper `logout` to it, it should say "You can't
command me to logout!", and not logout.

3. Whisper to an alt/addClass bot `logout`. The bot can be in your party
or could've been uninvited. All that matters is that you are its master.
It should reply "I'm logging out!"

## Complexity & Impact

Does this change add new decision branches?
- - [x] No
- - [ ] Yes (**explain below**)

Does this change increase per-bot or per-tick processing?
- - [x] No
- - [ ] Yes (**describe and justify impact**)

Could this logic scale poorly under load?
- - [x] No
- - [ ] Yes (**explain why**)
---

## Defaults & Configuration

Does this change modify default bot behavior?
- - [ ] No
- - [x] Yes (**explain why**)
In that it fixes wrong behavior.

If this introduces more advanced or AI-heavy logic:
- - [x] Lightweight mode remains the default
- - [x] More complex behavior is optional and thereby configurable
---

## AI Assistance

Was AI assistance (e.g. ChatGPT or similar tools) used while working on
this change?
- - [ ] No
- - [x] Yes (**explain below**)
Used Claude for code review, and translations.

If yes, please specify:

- AI tool or model used (e.g. ChatGPT, GPT-4, Claude, etc.)
- Purpose of usage (e.g. brainstorming, refactoring, documentation, code
generation)
- Which parts of the change were influenced or generated
- Whether the result was manually reviewed and adapted

AI assistance is allowed, but all submitted code must be fully
understood, reviewed, and owned by the contributor.
Any AI-influenced changes must be verified against existing CORE and PB
logic. We expect contributors to be honest
about what they do and do not understand.

---

## Lines to Translate

These are keys and defaults of lines that were added/edited, and to be
translated at a later SQL update.

| Key | Default line |
| --- | --- |
| bot_not_your_master | You are not my master! |
| bot_rndbot_no_logout | You can't command me to logout! |
---

## Final Checklist

- - [x] Stability is not compromised
- - [x] Performance impact is understood, tested, and acceptable
- - [x] Added logic complexity is justified and explained
- - [x] Documentation updated if needed

---

## Notes for Reviewers

Anything that significantly improves realism at the cost of stability or
performance should be carefully discussed
before merging.
2026-03-27 10:38:02 -07:00
oskov
f160420d70
Fix/talent tree ordered map (#2222)
Fixes #2050

InitTalents builds a map of talentRow → [TalentEntry*] and iterates it
to teach talents row by row. WoW's talent system requires each row to be
filled before unlocking the next, so iteration must happen in ascending
row order. Commit
b474dc4 ("Performance optim") changed the container from std::map to
std::unordered_map, which has no guaranteed key ordering. As a result,
bots would frequently attempt to learn talents in a row whose
prerequisites hadn't been met
  yet, silently skipping them. I belive it's the reason of #2050 issue.

The fix is a one-character type change: restoring std::map<uint32, ...>,
which guarantees ascending key (row) order.

  How to Test the Changes

   1. Make fresh installation
   2. Create new character
   3. Observe talents tree of fresh rnd bots
  

  Was AI assistance used while working on this change?

- [X] Yes — GitHub Copilot CLI was used to identify the root cause
(unordered_map introduced in b474dc4 breaking talent row ordering),
stage the one-line fix, and draft this PR description. The code change
was reviewed and fully
  understood before submission.

Root cause commit: b474dc44bb6323430a84fc17c1ec046f9919a101
("Performance optim") — changed std::map to std::unordered_map in
InitTalents, breaking the row-ordering guarantee that WoW's talent
prerequisite system depends on.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-03-20 20:42:07 +01:00
Crow
d5762b7e0f
Remove Vertical Speed Limit from Knockback Packet (#2223)
<!--
Thank you for contributing to mod-playerbots, please make sure that
you...
1. Submit your PR to the test-staging branch, not master.
2. Read the guidelines below before submitting.
3. Don't delete parts of this template.

DESIGN PHILOSOPHY: We prioritize STABILITY, PERFORMANCE, AND
PREDICTABILITY over behavioral realism.

Every action and decision executes PER BOT AND PER TRIGGER. Small
increases in logic complexity scale
poorly across thousands of bots and negatively affect all. We prioritize
a stable system over a smarter
one. Bots don't need to behave perfectly; believable behavior is the
goal, not human simulation.
Default behavior must be cheap in processing; expensive behavior must be
opt-in.

Before submitting, make sure your changes aligns with these principles.
-->

## Pull Request Description
This PR removes the break from SMSG_MOVE_KNOCK_BACK for knockbacks with
vertical speed of >35.0f. This break is the reason for many vertical
knockbacks having no effect on bots, including Shade of Aran's Flame
Wreath, High Astromancer Solarian's Wrath of the Astromancer, and
Archimonde's Air Burst. There is a comment that indicates that the limit
was originally added due to bots getting stuck from high-speed vertical
knockbacks. I have not observed this at all and have been playing with
this break removed for several months.

## Feature Evaluation
<!--
If your PR is very minimal (comment typo, wrong ID reference, etc), and
it is very obvious it will not have
any impact on performance, you may skip these question. If necessary, a
maintainer may ask you for them later.
-->

<!-- Please answer the following: -->
- Describe the **minimum logic** required to achieve the intended
behavior.
- Describe the **processing cost** when this logic executes across many
bots.

I honestly cannot say if there is impact on processing cost because I
have no understanding of packets. I would be surprised if there are any
performance issues since knockback packets are ordinarily getting sent
all the time, it's just a small number of moves that get skipped due to
this break.

## How to Test the Changes
<!--
- Step-by-step instructions to test the change.
- Any required setup (e.g. multiple players, number of bots, specific
configuration).
- Expected behavior and how to verify it.
-->

1. .go creature name High Astromancer Solarian
2. Start combat and wait until a bot gets hit with Wrath of the
Astromancer
3. Wait for the aura to expire and watch the bot fly to Mars and fall
back down

## Impact Assessment
<!-- As a generic test, before and after measure of pmon (playerbot pmon
tick) can help you here. -->
- Does this change increase per-bot/per-tick processing or risk scaling
poorly with thousands of bots?
    - [ ] No, not at all
    - [x] Minimal impact (**explain below**)
    - [ ] Moderate impact (**explain below**)

I do not know for sure, but as noted above, I would be surprised if
there was any notable performance impact.

- Does this change modify default bot behavior?
    - [x] No
    - [ ] Yes (**explain why**)



- Does this change add new decision branches or increase maintenance
complexity?
    - [x] No
    - [ ] Yes (**explain below**)



## Messages to Translate
<!--
Bot messages have to be translatable, but you don't need to do the
translations here. You only need to make sure
the message is in a translatable format, and list in the table the
message_key and the default English message.
Search for GetBotTextOrDefault in the codebase for examples.
-->
Does this change add bot messages to translate?
- [x] No
- [ ] Yes (**list messages in the table**)

| Message key  | Default message |
| --------------- | ------------------ |
|			 |			      |
|			 |			      |

## AI Assistance
<!--
AI assistance is allowed, but all submitted code must be fully
understood, reviewed, and owned by the contributor.
We expect contributors to be honest about what they do and do not
understand.
-->
Was AI assistance used while working on this change?
- [x] No
- [ ] Yes (**explain below**)
<!--
If yes, please specify:
- Purpose of usage (e.g. brainstorming, refactoring, documentation, code
generation).
- Which parts of the change were influenced or generated, and whether it
was thoroughly reviewed.
-->



## Final Checklist

- [x] Stability is not compromised.
- [ ] Performance impact is understood, tested, and acceptable. <- I
can't say for sure, but I've not had any issues. I would appreciate
getting thoughts from somebody knowledgeable about packet use, however.
- [x] Added logic complexity is justified and explained.
- [x] Documentation updated if needed (Conf comments, WiKi commands).

## Notes for Reviewers
<!-- Anything else that's helpful to review or test your pull request.
-->

---------

Co-authored-by: Keleborn <22352763+Celandriel@users.noreply.github.com>
Co-authored-by: bash <hermensb@gmail.com>
Co-authored-by: Revision <tkn963@gmail.com>
Co-authored-by: kadeshar <kadeshar@gmail.com>
2026-03-20 20:41:47 +01:00
Keleborn
957eca0263
Feat. Enable multi node flying, and refactor into travel manager (#2156)
# Pull Request

Feature - Enable multi node flying for bots
- Bots currently only do node to node flying. This PR makes it so they
can connect multiple noted.
-- This is enabled by sending a vector containing the node sequence
instead of a single destination node
-- To minimize the run-time cost of searching for available nodes and
connection, a cache of all possible connections is prepared at start up
using a BFS search algorithm.

Refactor 
- Move all world destination logic (cities, banks, inns) to existing
Travel manager
- Eliminate flightmastercache and integrate to new manager
- replace SQLs calls with in-memory data search by core
- Add in new map that stores creature areas by template. 

Clean up
- Move other rpg files to related folder. 
(Next steps) The selection for where bots fly to should be smarter than
it is. Instead of trying to determine where a bot can go, it should
first decide where it should go, and then identify the correct way to
get there.
---

## Feature Evaluation

Please answer the following:

- Describe the **minimum logic** required to achieve the intended
behavior?
- Describe the **cheapest implementation** that produces an acceptable
result?
- Describe the **runtime cost** when this logic executes across many
bots?

---

## How to Test the Changes

- Step-by-step instructions to test the change
- Any required setup (e.g. multiple players, bots, specific
configuration)
- Expected behavior and how to verify it

## Complexity & Impact

Does this change add new decision branches?
- - [x[ No
- - [ ] Yes (**explain below**)

Does this change increase per-bot or per-tick processing?
- - [x] No
- - [ ] Yes (**describe and justify impact**)

Could this logic scale poorly under load?
- - [x] No
- - [ ] Yes (**explain why**)
The call itself is fairly infrequent, and although now there are a
greater number of paths available for the bots, I dont think it would be
significant.

## Defaults & Configuration

Does this change modify default bot behavior?
- - [ ] No
- - [x] Yes (**explain why**)

If this introduces more advanced or AI-heavy logic:
- - [x] Lightweight mode remains the default
- - [ ] More complex behavior is optional and thereby configurable
---

## AI Assistance

Was AI assistance (e.g. ChatGPT or similar tools) used while working on
this change?
- - [ ] No
- - [x] Yes (**explain below**)
Gemini first suggested the use of a BFS algorithm. This was rewritten by
me to actually work as intended. Verification by additional logging not
present in final code.

Claude code converted the SQL filtering to the atrocious if statements
found in PrepareDestinationCache, but after verifying them it works. If
there are better ways to do this Im open to it.

---

## Final Checklist

- - [x] Stability is not compromised
- - [x] Performance impact is understood, tested, and acceptable
- - [x] Added logic complexity is justified and explained
- - [x] Documentation updated if needed

---

## Notes for Reviewers

Anything that significantly improves realism at the cost of stability or
performance should be carefully discussed
before merging.
2026-03-20 20:39:53 +01:00
Aldori
4877dcc573
fix: ByteBufferException error (opcode: 149) (#2206)
Fixes #2204 

## Pull Request Description
Fixes an opcode 149 ByteBufferException when Questie-335 (or other
addons that send addon messages) is used in a party with Playerbots.

The issue was caused by addon-language packets reaching parsing logic
they should not have reached. This change adjusts the early return for
`LANG_ADDON` packets before further handling.

## Feature Evaluation
- Describe the **minimum logic** required to achieve the intended
behavior.
- Moved the early return for `LANG_ADDON` packets in the outgoing packet
handler.

- Describe the **processing cost** when this logic executes across many
bots.
  - Negligible. It's a simple conditional check with an early return.

## How to Test the Changes
1. Install and enable Questie-335.
2. Invite at least 1 Playerbot to a party.
3. Accept a quest, abandon a quest, or progress a quest objective such
as kill credit or looting a quest item.
4. Verify the worldserver no longer logs opcode 149 ByteBufferException
errors.

## Impact Assessment
- Does this change increase per-bot/per-tick processing or risk scaling
poorly with thousands of bots?
    - [x] No, not at all
    - [ ] Minimal impact (**explain below**)
    - [ ] Moderate impact (**explain below**)

- Does this change modify default bot behavior?
    - [x] No
    - [ ] Yes (**explain why**)

- Does this change add new decision branches or increase maintenance
complexity?
    - [x] No
    - [ ] Yes (**explain below**)

## Messages to Translate
Does this change add bot messages to translate?
- [x] No
- [ ] Yes (**list messages in the table**)

| Message key  | Default message |
| --------------- | ------------------ |
|			 |			      |
|			 |			      |

## AI Assistance
Was AI assistance used while working on this change?
- [x] No
- [ ] Yes (**explain below**)

## Final Checklist

- [x] Stability is not compromised.
- [x] Performance impact is understood, tested, and acceptable.
- [x] Added logic complexity is justified and explained.
- [ ] Documentation updated if needed (Conf comments, WiKi commands).

## Notes for Reviewers
This is a small fix intended only to prevent addon language packets from
reaching incompatible packet parsing logic.

---------

Co-authored-by: Keleborn <22352763+Celandriel@users.noreply.github.com>
Co-authored-by: bash <hermensb@gmail.com>
Co-authored-by: Revision <tkn963@gmail.com>
Co-authored-by: kadeshar <kadeshar@gmail.com>
2026-03-20 20:38:57 +01:00
Crow
35a0282ca6
Add Sense Undead for Paladins (#2200)
# Pull Request

This PR adds the sense undead ability for Paladins, which they will keep
active at all times. This is mildly useful because the associated minor
glyph provides a 1% damage increase against undead while the ability is
active.

Sense undead is also added to InitClassSpells(). I understand that it is
a trainer spell so would normally be covered by InitAvailableSpells(),
but those playing with mod-individual-progression will not receive the
spell through InitAvailableSpells() because it is removed from trainers
by the mod (in TBC, a quest was required to obtain the spell).

Finally, the minor glyph of sense undead is now added to the config as a
default glyph for all PvE specs. It is not added for PvP specs because
Forsaken do not count as undead so the glyph is useless in PvP. I also
made some other tweaks to Paladin default minor glyphs that are not
worth spending any time talking about.

Edit: I also did some minor reformatting of code and replaced some
numbers with existing constants.

---

## Design Philosophy

We prioritize **stability, performance, and predictability** over
behavioral realism.
Complex player-mimicking logic is intentionally limited due to its
negative impact on scalability, maintainability, and
long-term robustness.

Excessive processing overhead can lead to server hiccups, increased CPU
usage, and degraded performance for all
participants. Because every action and
decision tree is executed **per bot and per trigger**, even small
increases in logic complexity can scale poorly and
negatively affect both players and
world (random) bots. Bots are not expected to behave perfectly, and
perfect simulation of human decision-making is not a
project goal. Increased behavioral
realism often introduces disproportionate cost, reduced predictability,
and significantly higher maintenance overhead.

Every additional branch of logic increases long-term responsibility. All
decision paths must be tested, validated, and
maintained continuously as the system evolves.
If advanced or AI-intensive behavior is introduced, the **default
configuration must remain the lightweight decision
model**. More complex behavior should only be
available as an **explicit opt-in option**, clearly documented as having
a measurable performance cost.

Principles:

- **Stability before intelligence**  
  A stable system is always preferred over a smarter one.

- **Performance is a shared resource**  
  Any increase in bot cost affects all players and all bots.

- **Simple logic scales better than smart logic**  
Predictable behavior under load is more valuable than perfect decisions.

- **Complexity must justify itself**  
  If a feature cannot clearly explain its cost, it should not exist.

- **Defaults must be cheap**  
  Expensive behavior must always be optional and clearly communicated.

- **Bots should look reasonable, not perfect**  
  The goal is believable behavior, not human simulation.

Before submitting, confirm that this change aligns with those
principles.

---

## Feature Evaluation

Please answer the following:

- Describe the **minimum logic** required to achieve the intended
behavior?
- Describe the **cheapest implementation** that produces an acceptable
result?
- Describe the **runtime cost** when this logic executes across many
bots?

The implementation just checks if a Paladin has the sense undead aura,
and if not, the Paladin will activate sense undead. It is simple and
cheap.

---

## How to Test the Changes

- Step-by-step instructions to test the change
- Any required setup (e.g. multiple players, bots, specific
configuration)
- Expected behavior and how to verify it

## Complexity & Impact

Does this change add new decision branches?
- - [x] No
- - [ ] Yes (**explain below**)

Does this change increase per-bot or per-tick processing?
- - [ ] No
- - [x] Yes (**describe and justify impact**)

Infinitesimally 

Could this logic scale poorly under load?
- - [x] No
- - [ ] Yes (**explain why**)

## Defaults & Configuration

Does this change modify default bot behavior?
- - [ ] No
- - [x] Yes (**explain why**)

Paladin bots will by default have sense undead enabled. There is no
disadvantage to this.

If this introduces more advanced or AI-heavy logic:
- - [x] Lightweight mode remains the default
- - [ ] More complex behavior is optional and thereby configurable
---

## AI Assistance

Was AI assistance (e.g. ChatGPT or similar tools) used while working on
this change?
- - [x] No
- - [ ] Yes (**explain below**)

If yes, please specify:

- AI tool or model used (e.g. ChatGPT, GPT-4, Claude, etc.)
- Purpose of usage (e.g. brainstorming, refactoring, documentation, code
generation)
- Which parts of the change were influenced or generated
- Whether the result was manually reviewed and adapted

AI assistance is allowed, but all submitted code must be fully
understood, reviewed, and owned by the contributor.
Any AI-influenced changes must be verified against existing CORE and PB
logic. We expect contributors to be honest
about what they do and do not understand.

---

## Final Checklist

- - [x] Stability is not compromised
- - [x] Performance impact is understood, tested, and acceptable
- - [x] Added logic complexity is justified and explained
- - [x] Documentation updated if needed

---

## Notes for Reviewers

Anything that significantly improves realism at the cost of stability or
performance should be carefully discussed
before merging.

---------

Co-authored-by: Keleborn <22352763+Celandriel@users.noreply.github.com>
Co-authored-by: bash <hermensb@gmail.com>
Co-authored-by: Revision <tkn963@gmail.com>
Co-authored-by: kadeshar <kadeshar@gmail.com>
2026-03-20 20:38:06 +01:00
XYUU
473b2ab5c6
Fix: WLK shaman totem quest vs relic totems: avoid keeping 4 totem items when relic exists #2119 (#2197)
## Summary
* Detects shaman relics (relic type, totem subclass) in bags/equipment.
* Skips adding the four classic totem items (5175–5178) when a relic
exists.
* Cleans up any existing totem items from bags/equipment/bank when a
relic exists, while keeping Ankh handling intact.
## Test plan
Verified manually (local environment).

---------

Co-authored-by: Keleborn <22352763+Celandriel@users.noreply.github.com>
Co-authored-by: bash <hermensb@gmail.com>
Co-authored-by: Revision <tkn963@gmail.com>
Co-authored-by: kadeshar <kadeshar@gmail.com>
Co-authored-by: github-actions <github-actions@users.noreply.github.com>
2026-03-20 20:37:44 +01:00
Keleborn
5e7613f719
Change reinterpret cast to dynamic cast. (#2182)
# Pull Request

In a few instances the code used reinterpret cast. This is potentially
risky if the object is incorrect. This is a safer approach.

---

## Design Philosophy

We prioritize **stability, performance, and predictability** over
behavioral realism.
Complex player-mimicking logic is intentionally limited due to its
negative impact on scalability, maintainability, and
long-term robustness.

Excessive processing overhead can lead to server hiccups, increased CPU
usage, and degraded performance for all
participants. Because every action and
decision tree is executed **per bot and per trigger**, even small
increases in logic complexity can scale poorly and
negatively affect both players and
world (random) bots. Bots are not expected to behave perfectly, and
perfect simulation of human decision-making is not a
project goal. Increased behavioral
realism often introduces disproportionate cost, reduced predictability,
and significantly higher maintenance overhead.

Every additional branch of logic increases long-term responsibility. All
decision paths must be tested, validated, and
maintained continuously as the system evolves.
If advanced or AI-intensive behavior is introduced, the **default
configuration must remain the lightweight decision
model**. More complex behavior should only be
available as an **explicit opt-in option**, clearly documented as having
a measurable performance cost.

Principles:

- **Stability before intelligence**  
  A stable system is always preferred over a smarter one.

- **Performance is a shared resource**  
  Any increase in bot cost affects all players and all bots.

- **Simple logic scales better than smart logic**  
Predictable behavior under load is more valuable than perfect decisions.

- **Complexity must justify itself**  
  If a feature cannot clearly explain its cost, it should not exist.

- **Defaults must be cheap**  
  Expensive behavior must always be optional and clearly communicated.

- **Bots should look reasonable, not perfect**  
  The goal is believable behavior, not human simulation.

Before submitting, confirm that this change aligns with those
principles.

---

## Feature Evaluation

Please answer the following:

- Describe the **minimum logic** required to achieve the intended
behavior?
- Describe the **cheapest implementation** that produces an acceptable
result?
- Describe the **runtime cost** when this logic executes across many
bots?

---

## How to Test the Changes

- Step-by-step instructions to test the change
- Any required setup (e.g. multiple players, bots, specific
configuration)
- Expected behavior and how to verify it

## Complexity & Impact

Does this change add new decision branches?
- - [x] No
- - [ ] Yes (**explain below**)

Does this change increase per-bot or per-tick processing?
- - [x] No
- - [ ] Yes (**describe and justify impact**)

Could this logic scale poorly under load?
- - [x] No
- - [ ] Yes (**explain why**)
---

## Defaults & Configuration

Does this change modify default bot behavior?
- - [x] No
- - [ ] Yes (**explain why**)

If this introduces more advanced or AI-heavy logic:
- - [x] Lightweight mode remains the default
- - [ ] More complex behavior is optional and thereby configurable
---

## AI Assistance

Was AI assistance (e.g. ChatGPT or similar tools) used while working on
this change?
- - [x] No
- - [ ] Yes (**explain below**)

If yes, please specify:

- AI tool or model used (e.g. ChatGPT, GPT-4, Claude, etc.)
- Purpose of usage (e.g. brainstorming, refactoring, documentation, code
generation)
- Which parts of the change were influenced or generated
- Whether the result was manually reviewed and adapted

AI assistance is allowed, but all submitted code must be fully
understood, reviewed, and owned by the contributor.
Any AI-influenced changes must be verified against existing CORE and PB
logic. We expect contributors to be honest
about what they do and do not understand.

---

## Final Checklist

- - [x] Stability is not compromised
- - [x] Performance impact is understood, tested, and acceptable
- - [x] Added logic complexity is justified and explained
- - [x] Documentation updated if needed

---

## Notes for Reviewers

Anything that significantly improves realism at the cost of stability or
performance should be carefully discussed
before merging.
2026-03-13 22:21:55 +01:00
kadeshar
a8dda550ad
Requirement fix to use bigobj parameter to compile (#2176)
# Pull Request
Compilation fix which making possible compiling without bigobj parameter

---

## How to Test the Changes

- compile using Visual Studio without bigobj parameter

## Complexity & Impact

Does this change add new decision branches?
- - [x] No
- - [ ] Yes (**explain below**)

Does this change increase per-bot or per-tick processing?
- - [x] No
- - [ ] Yes (**describe and justify impact**)

Could this logic scale poorly under load?
- - [x] No
- - [ ] Yes (**explain why**)
---

## Defaults & Configuration

Does this change modify default bot behavior?
- - [x] No
- - [ ] Yes (**explain why**)

## AI Assistance

Was AI assistance (e.g. ChatGPT or similar tools) used while working on
this change?
- - [ ] No
- - [x] Yes (**explain below**)

Automate file creation

---

## Final Checklist

- - [x] Stability is not compromised
- - [x] Performance impact is understood, tested, and acceptable
- - [x] Added logic complexity is justified and explained
- - [x] Documentation updated if needed
2026-03-08 08:49:45 +01:00
killerzwelch
660a5c0543
make playerbots compatible with 515aeca (#2181)
# Pull Request

needed changes for
515aeca570

---

## Design Philosophy

We prioritize **stability, performance, and predictability** over
behavioral realism.
Complex player-mimicking logic is intentionally limited due to its
negative impact on scalability, maintainability, and
long-term robustness.

Excessive processing overhead can lead to server hiccups, increased CPU
usage, and degraded performance for all
participants. Because every action and
decision tree is executed **per bot and per trigger**, even small
increases in logic complexity can scale poorly and
negatively affect both players and
world (random) bots. Bots are not expected to behave perfectly, and
perfect simulation of human decision-making is not a
project goal. Increased behavioral
realism often introduces disproportionate cost, reduced predictability,
and significantly higher maintenance overhead.

Every additional branch of logic increases long-term responsibility. All
decision paths must be tested, validated, and
maintained continuously as the system evolves.
If advanced or AI-intensive behavior is introduced, the **default
configuration must remain the lightweight decision
model**. More complex behavior should only be
available as an **explicit opt-in option**, clearly documented as having
a measurable performance cost.

Principles:

- **Stability before intelligence**  
  A stable system is always preferred over a smarter one.

- **Performance is a shared resource**  
  Any increase in bot cost affects all players and all bots.

- **Simple logic scales better than smart logic**  
Predictable behavior under load is more valuable than perfect decisions.

- **Complexity must justify itself**  
  If a feature cannot clearly explain its cost, it should not exist.

- **Defaults must be cheap**  
  Expensive behavior must always be optional and clearly communicated.

- **Bots should look reasonable, not perfect**  
  The goal is believable behavior, not human simulation.

Before submitting, confirm that this change aligns with those
principles.

---

## Feature Evaluation

Please answer the following:

- Describe the **minimum logic** required to achieve the intended
behavior?
- Describe the **cheapest implementation** that produces an acceptable
result?
- Describe the **runtime cost** when this logic executes across many
bots?

---

## How to Test the Changes

- Step-by-step instructions to test the change
- Any required setup (e.g. multiple players, bots, specific
configuration)
- Expected behavior and how to verify it

## Complexity & Impact

Does this change add new decision branches?
- - [x] No
- - [ ] Yes (**explain below**)

Does this change increase per-bot or per-tick processing?
- - [x] No
- - [ ] Yes (**describe and justify impact**)

Could this logic scale poorly under load?
- - [x] No
- - [ ] Yes (**explain why**)
---

## Defaults & Configuration

Does this change modify default bot behavior?
- - [x] No
- - [ ] Yes (**explain why**)

If this introduces more advanced or AI-heavy logic:
- - [x] Lightweight mode remains the default
- - [ ] More complex behavior is optional and thereby configurable
---

## AI Assistance

Was AI assistance (e.g. ChatGPT or similar tools) used while working on
this change?
- - [x] No
- - [ ] Yes (**explain below**)

If yes, please specify:

- AI tool or model used (e.g. ChatGPT, GPT-4, Claude, etc.)
- Purpose of usage (e.g. brainstorming, refactoring, documentation, code
generation)
- Which parts of the change were influenced or generated
- Whether the result was manually reviewed and adapted

AI assistance is allowed, but all submitted code must be fully
understood, reviewed, and owned by the contributor.
Any AI-influenced changes must be verified against existing CORE and PB
logic. We expect contributors to be honest
about what they do and do not understand.

---

## Final Checklist

- - [x] Stability is not compromised
- - [x] Performance impact is understood, tested, and acceptable
- - [x] Added logic complexity is justified and explained
- - [x] Documentation updated if needed

---

## Notes for Reviewers

Anything that significantly improves realism at the cost of stability or
performance should be carefully discussed
before merging.

---------

Co-authored-by: Keleborn <22352763+Celandriel@users.noreply.github.com>
Co-authored-by: bash <hermensb@gmail.com>
Co-authored-by: Revision <tkn963@gmail.com>
Co-authored-by: kadeshar <kadeshar@gmail.com>
2026-03-06 20:03:32 +01:00
Crow
14c77b1e7b
Remove instance strategies when leaving map (#2163)
# Pull Request

Currently, dungeon and raid strategies, which are automatically added
when entering the applicable instance (unless disabled in config), will
persist until manually removed or until a different instance strategy is
applied. This is pretty bad because then bots will continue to check
triggers for the instance when outside of it.

This has been discussed for a long time, but after finally considering
it today, I think the solution is pretty simple because the existing
framework is already there. PlayerbotAI::ApplyInstanceStrategies() is
the function for enabling strategies when entering an instance, and it's
called whenever a bot changes maps. So all we need to do is to remove
all instance strategies first when calling it. I tested these changes,
and they worked for me, but obviously others should test too, and
especially the code should be examined since that is not my area of
expertise.

---

## Design Philosophy

We prioritize **stability, performance, and predictability** over
behavioral realism.
Complex player-mimicking logic is intentionally limited due to its
negative impact on scalability, maintainability, and
long-term robustness.

Excessive processing overhead can lead to server hiccups, increased CPU
usage, and degraded performance for all
participants. Because every action and
decision tree is executed **per bot and per trigger**, even small
increases in logic complexity can scale poorly and
negatively affect both players and
world (random) bots. Bots are not expected to behave perfectly, and
perfect simulation of human decision-making is not a
project goal. Increased behavioral
realism often introduces disproportionate cost, reduced predictability,
and significantly higher maintenance overhead.

Every additional branch of logic increases long-term responsibility. All
decision paths must be tested, validated, and
maintained continuously as the system evolves.
If advanced or AI-intensive behavior is introduced, the **default
configuration must remain the lightweight decision
model**. More complex behavior should only be
available as an **explicit opt-in option**, clearly documented as having
a measurable performance cost.

Principles:

- **Stability before intelligence**  
  A stable system is always preferred over a smarter one.

- **Performance is a shared resource**  
  Any increase in bot cost affects all players and all bots.

- **Simple logic scales better than smart logic**  
Predictable behavior under load is more valuable than perfect decisions.

- **Complexity must justify itself**  
  If a feature cannot clearly explain its cost, it should not exist.

- **Defaults must be cheap**  
  Expensive behavior must always be optional and clearly communicated.

- **Bots should look reasonable, not perfect**  
  The goal is believable behavior, not human simulation.

Before submitting, confirm that this change aligns with those
principles.

---

## Feature Evaluation

Please answer the following:

- Describe the **minimum logic** required to achieve the intended
behavior?
- Describe the **cheapest implementation** that produces an acceptable
result?
- Describe the **runtime cost** when this logic executes across many
bots?

---

## How to Test the Changes

- Step-by-step instructions to test the change
- Any required setup (e.g. multiple players, bots, specific
configuration)
- Expected behavior and how to verify it

## Complexity & Impact

Does this change add new decision branches?
- - [x] No
- - [ ] Yes (**explain below**)

Does this change increase per-bot or per-tick processing?
- - [x] No
- - [ ] Yes (**describe and justify impact**)

Could this logic scale poorly under load?
- - [x] No
- - [ ] Yes (**explain why**)
---

## Defaults & Configuration

Does this change modify default bot behavior?
- - [x] No
- - [ ] Yes (**explain why**)

If this introduces more advanced or AI-heavy logic:
- - [x] Lightweight mode remains the default
- - [ ] More complex behavior is optional and thereby configurable
---

## AI Assistance

Was AI assistance (e.g. ChatGPT or similar tools) used while working on
this change?
- - [ ] No
- - [x] Yes (**explain below**)

If yes, please specify:

- AI tool or model used (e.g. ChatGPT, GPT-4, Claude, etc.)
- Purpose of usage (e.g. brainstorming, refactoring, documentation, code
generation)
- Which parts of the change were influenced or generated
- Whether the result was manually reviewed and adapted

AI assistance is allowed, but all submitted code must be fully
understood, reviewed, and owned by the contributor.
Any AI-influenced changes must be verified against existing CORE and PB
logic. We expect contributors to be honest
about what they do and do not understand.

I used Gemini to verify that my idea would work and had it put together
the actual code for me.

---

## Final Checklist

- - [x] Stability is not compromised
- - [x] Performance impact is understood, tested, and acceptable
- - [x] Added logic complexity is justified and explained
- - [x] Documentation updated if needed

---

## Notes for Reviewers

Anything that significantly improves realism at the cost of stability or
performance should be carefully discussed
before merging.

---------

Co-authored-by: Keleborn <22352763+Celandriel@users.noreply.github.com>
Co-authored-by: bash <hermensb@gmail.com>
Co-authored-by: Revision <tkn963@gmail.com>
Co-authored-by: kadeshar <kadeshar@gmail.com>
2026-03-06 10:50:00 -08:00
Hokken
788c7b025b
Fix quest links triggering trade window (#2155)
## Summary

`ChatHelper::parseable()` matched any hyperlink containing `|H`,
including quest links (`|Hquest:`), achievement links, spell links, etc.
This caused bots to interpret quest links shared in party chat as item
trade requests, opening the trade window instead of ignoring them.

Narrowed the check from `"|H"` to `"|Hitem:"` so only actual item links
trigger the parseable/trade logic.

**One-line change** in `src/Bot/Cmd/ChatHelper.cpp:603`

## Root Cause

The WoW client uses `|H<type>:<id>|h[Name]|h` hyperlinks for many object
types:
- `|Hitem:12345|h[Item Name]|h` — items
- `|Hquest:678|h[Quest Name]|h` — quests  
- `|Hspell:890|h[Spell Name]|h` — spells
- `|Hachievement:...|h` — achievements

The old check `text.find("|H")` matched ALL of these, so sharing a quest
link in party chat would cause the bot to enter the item parsing/trade
flow.

## Test Scenarios

| Scenario | Before | After |
|----------|--------|-------|
| Share `[Quest Name]` in party chat | Trade window opens | No reaction
(correct) |
| Share `[Item Name]` in party chat | Trade window opens | Trade window
opens (unchanged) |
| Say "questitem" in chat | Parsed correctly | Parsed correctly
(unchanged) |
| Share `[Spell Name]` in party chat | Trade window opens | No reaction
(correct) |

Tested on AzerothCore 3.3.5a with mod-playerbots, confirmed fix resolves
the issue.

---------

Co-authored-by: Keleborn <22352763+Celandriel@users.noreply.github.com>
Co-authored-by: bash <hermensb@gmail.com>
Co-authored-by: Hokken <Hokken@users.noreply.github.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-06 09:41:40 -08:00
Alex Dcnh
18bd655869
Restore Naxx Strategies without core dependencies (#2031)
### Summary
This PR restores the Naxxramas raid strategies that were removed in
commit 686fe513b25bbb20ccfcc89f08ee8c4b498a263e .
The reintroduced logic is core‑friendly (no AzerothCore script headers
or internal boss AI/EventMap dependencies), and the Naxxramas actions
have been refactored into per‑boss files for better maintainability.

### Motivation
The previous removal was meant to avoid core modifications and unblock
upstreaming.
This PR brings the strategies back while adhering to that requirement,
using only observable state and mod‑playerbots helpers.

### What’s included

- Re‑enabled the Naxxramas strategies previously removed.
- Replaced core script header dependencies with observable checks
(auras, casts, unit flags, flight state, etc.).
- Split the Naxxramas action logic into per‑boss source files to avoid a
“god file” and ease future maintenance.
- Minor, non‑intrusive behavior improvements aligned with existing
helpers.

### Future work
Some strategies may still require refinement or more advanced handling
later.
This PR focuses on restoring the baseline logic without core
dependencies, while keeping changes minimal and safe.

**Any contributions are welcome to further improve and fine‑tune the
Naxxramas strategies.**

### Testing
Tested in some Naxx boxx.
No server crash and boss killed :D

Note: I'll make another PR with revised scripts when this one are merged

---------

Co-authored-by: Keleborn <22352763+Celandriel@users.noreply.github.com>
Co-authored-by: bash <hermensb@gmail.com>
Co-authored-by: Revision <tkn963@gmail.com>
Co-authored-by: kadeshar <kadeshar@gmail.com>
2026-03-06 07:57:21 -08:00
Keleborn
439293e100
Warnings PR 2 clean unused variables (#2107)
# Pull Request

Removed unused variables and fixed styling issues. 


## How to Test the Changes

- Step-by-step instructions to test the change
- Any required setup (e.g. multiple players, bots, specific
configuration)
- Expected behavior and how to verify it

## Complexity & Impact

- Does this change add new decision branches?
    - [x] No
    - [] Yes (**explain below**)

- Does this change increase per-bot or per-tick processing?
    - [x] No
    - [ ] Yes (**describe and justify impact**)

- Could this logic scale poorly under load?
    - [x] No
    - [ ] Yes (**explain why**)

---

## Defaults & Configuration

- Does this change modify default bot behavior?
    - [x] No
    - [ ] Yes (**explain why**)

If this introduces more advanced or AI-heavy logic:

- [ ] Lightweight mode remains the default
- [ ] More complex behavior is optional and thereby configurable

---

## AI Assistance

- Was AI assistance (e.g. ChatGPT or similar tools) used while working
on this change?
    - [x] No
    - [ ] Yes (**explain below**)


---

## Final Checklist

- [x] Stability is not compromised
- [x] Performance impact is understood, tested, and acceptable
- [x] Added logic complexity is justified and explained
- [x] Documentation updated if needed

---

## Notes for Reviewers

This was filtered from the code provided by SmashingQuasar. Eliminated
variables were confirmed to be not used, but unclear at times if that is
due to mistakes in writing.

---------

Co-authored-by: bashermens <31279994+hermensbas@users.noreply.github.com>
2026-02-27 16:04:33 -08:00
Crow
be2cf436ea
Implement Tempest Keep: The Eye Strategies (#1943)
Edit: Descriptions of methods are out of date right now. To be updated.

This one comes with the same caveats as SSC about requiring ownership
from somebody with C++ knowledge, except I think the matter is even more
acute here because these strategies incorporate a novel approach
proposed by Timberpoes. By redeclaring the entire bossai class for
Kael’thas, it was possible to add new member functions to the class in
order to access its private member variables. This allows bots to have
visibility into boss mechanics beyond what they could do with ordinary
techniques and is similar in approach to what was done by the Naxx
strategies, except that this approach does not require any modifications
to the core. I used it for only one mechanic, which was to detect
Kael’thas’s phase. That was very helpful because the fight is divided
into 5 phases, and distinguishing between them with traditional
techniques requires lookups of a dozen NPCs and comparisons of their
various unit states, react states, and auras; by accessing his bossai,
this can all be avoided. However, there is far more potential beyond
this if the approach is an acceptable one.

On with the (shit)show.

### Trash
In a perfect world, there would be many strategies for TK trash, which
is easily more difficult than two of the bosses. It’s a real pain to do
though because to solve the biggest issues properly, each pack would
have to be handled a little differently. So the only thing I’ve included
is for Mages to cast polymorph on the Crimson Hand Centurions when they
are channeling Arcane Flurry. The purpose is not to actually keep them
CC’d but to interrupt their channel.

### Al’ar
This fight sucked so much to write a strategy for. The only silver
lining is that being the post-nerf version, the boss moves between only
4 platform locations (instead of 6), and movement between them is on a
fixed rotation (interrupted by Flame Quills) instead of being random.
Thus, a strategy can be consistently replicated, and the fight can be
done with only 3 tanks (2 on the platforms for the boss and 1 below for
adds).

**Phase 1:**
I’m going to call the platform that Al’ar lands at after the pull
“platform 0” because that reflects the indices in the code. In a
clockwise direction, the remaining platforms will be referred to as
platforms 1, 2, and 3, respectively.
The best way to pull is to first put all ranged, as well as tanks other
than your main tank and first assistant tank, on nc +stay below platform
0. Then, go up the ramp to platform 0 with your main tank, first
assistant tank, and melee dps following you, then hit Al’ar with any
ranged attack or spell to start the fight.

- Your main tank will start at platform 0, and your first assistant tank
will immediately move to platform 1. When Al’ar moves to platform 1,
your main tank will move to platform 2. When Al’ar moves to platform 2,
your first assistant tank will move to platform 3. When Al’ar moves to
platform 3, your main tank will move back to platform 0. This assures a
tank is available to receive Al’ar after every platform movement (every
30 seconds).
- Melee DPS will follow Al’ar as it moves between platforms.
- Each platform is mapped to a corresponding ground location below it.
Ranged DPS and healers will follow Al’ar by moving to the corresponding
ground location as it flies between platforms.
- After each platform move, an Ember of Al’ar will spawn. Your second
assistant tank will pick up the Ember and move it to the point that is
25 yards away from the ground position corresponding to Al’ar’s platform
(on an invisible line between such ground position and the middle of the
room). Ranged DPS will then focus down the Ember before switching back
to Al’ar (this positioning is so that ranged are not hit by the Ember
Blast explosion that happens whenever an Ember dies).
- Each time Al’ar leaves a platform, it has a chance to instead fly up
high in the middle of the room to perform Flame Quills, which will
one-shot anybody on the upper level or ramps. When Al’ar begins the
Flame Quills sequence, all bots on the top level will jump off. FYI,
Al’ar’s usage of Flame Quills is not entirely random: there is a 20%
chance for it to do so after the first platform move, and the chance
increases by another 20% after each subsequent platform move that does
not trigger Flame Quills (reset after each Flame Quills sequence).
- After Flame Quills, Al’ar will randomly land at either platform 0 or
3. To prepare for this, bots will move to assigned positions during the
Flame Quills sequence:
- Ranged and the second assistant tank will wait in the middle of the
room.
- Melee DPS will wait at a point that is between the base of each ramp.
  - The main tank will wait at the base of the ramp to platform 0.
- The first assistant tank will wait at the base of the ramp to platform
3.
- Once Al’ar lands, the regular Phase 1 strategies resume.
- When Al’ar “dies,” it disappears and moves to the center of the room,
where it casts Rebirth and returns to full HP. Bots will wait outside of
the radius of the Rebirth explosion for Phase 2 to start.

Phase 2:

- Your main tank will tank Al’ar initially. When Al’ar casts Melt Armor,
your first assistant tank will taunt Al’ar and take over. The tank swaps
will continue back and forth every time Melt Armor is cast.
- Bots will avoid Flame Patches. FWIW, the standard co +avoid aoe
strategy does work for Flame Patches, but avoid aoe provides no buffer
distance so as you’ve probably noticed, it doesn’t provide for
preemptive avoidance. Also, avoid aoe does not consider multiple hazards
together so it can be an issue when movement needs to take into account
more than one hazard, plus when a strategy requires particular bot
movement, it’s better to account for the hazards within that movement
strategy instead of relying on separate methods that can create
conflicts.
- When Al’ar takes to the sky to perform Dive Bomb, bots will spread out
(and continue to avoid Flame Patches). After the Dive Bomb, Al’ar does
another Rebirth explosion. I have tried a million different things to
properly detect this full sequence (even accessing the bossAI like I did
with Kael’thas) and cannot get it to work properly. Ultimately, all I’ve
been able to get to work at all with respect to the final explosion is
for bots to detect the 2-second cast of the Rebirth and run out. It is
not enough time for bots that are too close when the cast happens so
some bots may get hit, but if you have adequate gear, they should
survive.
- After each Dive Bomb, 2 Embers will spawn. Your second assistant tank
will tank one Ember, and either the main tank or first assistant tank,
whichever one is not tanking Al’ar at the time, will tank the other
Ember. They will both move the Embers away from bots, and ranged DPS
will focus both Embers down before switching back to Al’ar.
- Because the room is so large, it is possible for bots to get too far
away from active combat (particularly if they are thrown across the room
by Ember Blast) so there is also a method for them to run back toward
the center if they get too far away.

### Void Reaver
Ironically, what was often considered the easiest boss in 25-player
content in TBC is the only boss with an ability (Arcane Orb) that I do
not believe can be avoided by bots, even with access to Void Reaver’s
boss script. Therefore, every single Arcane Orb is going to hit its
target, so the strategy can only try to limit the damage by spreading
ranged bots in two rings around Void Reaver (one for healers and one for
ranged DPS, to try to ensure sufficient distribution of healers). The
tanks will all fight for aggro (necessary due to Knock Away) and try to
keep Void Reaver in the middle of the room. Bots that can wipe aggro or
otherwise gain invulnerability are directed to use the applicable
abilities as soon as they pick up aggro (e.g., Soulshatter). He’s still
easy, but if you have IP nerfs, it’s a little bit of a gear check.

### High Astromancer Solarian
No boss was hit harder by nerfs in TBC than Solarian, whose encounter
went from a totally unique fight that required arcane resistance to a
fight that is kind of just an easier Baron Geddon. IMO, she is the
easiest boss in TBC 25-player raids.

- Ranged bots stack up at a distance from Solarian; this leaves all bots
with plenty of space to run away from other bots when they get Wrath of
the Astromancer.
- When Solarian vanishes, all bots will stack to AoE down the Solarium
Agents that spawn.
- When Solarian returns with two Solarium Priests, melee will divide
into two groups, with one focused on each Solarium Priest. I think this
method is not working correctly right now because when one Priest dies,
the bots still on the second Priest are leaving it. I’ll need to decide
whether I want to figure it out or just get rid of it because this fight
is so easy regardless.
- Priest bots will cast Fear Ward on the main tank to block the Psychic
Scream during the final tank-and-spank Voidwalker phase, and the main
tank will pick up Voidwalker Solarian as soon as she transforms.

Note that the bots will not be knocked into the air by Wrath of the
Astromancer. The issue is due to the presence of a check for knockbacks
in Playerbots that causes bots to ignore knockbacks that would launch
them at a velocity beyond a hardcoded value. I’ve increased that
velocity limit on my own fork, and it does allow Wrath of the
Astromancer (and other knockbacks that otherwise don’t work) to work on
bots. But that’s obviously a broader issue and not addressed in this PR,
and bots don’t take fall damage in any case.

### Kael’thas Sunstrider

So this strategy has 23(!) action methods. But like in retail, this is
actually an easy fight once it is learned because it is highly scripted.

Unlike in other strategies I’ve done, the bots probably cannot do this
fight by themselves unless they are way overgeared. This is because
there are a few windows during which bots need to position themselves
properly based on dynamic factors. But no RTSC is needed—you just need
to have bots follow you to the right locations. Also note that the gear
check for this strategy is higher than in retail because you have to get
all of the legendary weapons down and looted before the advisors aggro
in Phase 3, or it’s going to be an absolute shitshow (with human
players, you can deal with there still being a couple of weapons up).
For a point of reference, when I was first working on this strategy with
damage reduced to 50% and bots pretty close to T4 BiS, I had almost no
margin of error (I would usually get the weapons down with barely a
second to spare).

You will need at least 2 tanks, but 3 is better. Your main tank will
need to be able to equip the legendary shield so you must use a Warrior
or Paladin. However, it is ideal for the first assistant tank to be a
Druid because they can equip the legendary staff.

**Phase 1:**
Fun fact—when you “kill” the advisors in this phase, they don’t actually
die but get an aura applied called “Permanent Feign Death” (nice
oxymoron).

- _Thaladred_: You’re supposed to kite him, and bots can’t really kite,
so the method is a poor man’s method of having the bot move away from
him in a straight line when fixated. You want him to die in the far
Southern part of the room. If he dies in a bad location, you may as well
call a wipe and restart. What will work best for you will depend on your
DPS since you don’t want to kill him before he gets to the location you
want but also don’t want bots to be trapped up against a wall since they
can’t properly kite him. The way that works best for me is to have bots
stay back while I aggro the boss, and wait until right before Thaladred
switches to his second fixate target before attacking. Note that if you
do put bots on stay, when you put them back on follow, the bot that is
then being fixated will remain on stay (because they need to disregard
movement orders other than running away from Thaladred). So after
Thaladred dies, make sure to manually type /follow or the bot that was
fixated when you took the bots off of stay will not rejoin the fight.
- _Sanguinar_: He will be tanked by your main tank, who will be targeted
by your Priests for Fear Ward. Bots will wait to engage him; I made it a
very generous time (12 seconds) because there is absolutely no rush in
Phase 1. There’s no sense in being aggressive. During that time, the
main tank will drag Sanguinar to the West wall.
- _Capernian_: This is the first make-or-break part of the fight. Phase
1 Capernian was the most frequent cause for wipes for me.
- She should be tanked by a Warlock. If you want to pick your Warlock
tank, you can do so by the assistant flag, but if you don’t, the
strategy will just pick your highest HP Warlock. If you raid without a
Warlock, then you’re insane, but at least there’s a guard so your server
won’t crash?
- You do not need to add the tank strategy to your Warlock. There is a
method that will automatically switch your selected tank Warlock between
DPS and tank strategies at appropriate times because you need to squeeze
out every drop of DPS you can get, particularly for Phase 2, where
you’ll need your Warlock to be blowing up weapons with Seed of
Corruption instead of spamming Searing Pain. You’ll want your Warlock to
start with a DPS strategy as usual (since they should be DPSing
Thaladred).
- To engage Capernian, start running East right before Sanguinar dies.
She will activate quickly, and you want to try to get in front of her
(but not too close) before she aggros.
- When Capernian aggros, your Warlock tank will immediately switch to
the tank strategy and attack. Your main tank will run toward Capernian
but not actually attack; their purpose will be to bait her Conflagration
to reduce the chance that it hits your Warlock tank. Other melee will
not engage Capernian. Ranged DPS will be idle for 12 seconds; during
this time, you should run South to make sure they are not in range of
Capernian. After 12 seconds, your ranged DPS will activate, move into
range and spread out, and attack (it doesn’t seem possible to outrange
Conflagrate, so if bots don’t spread, she will annihilate the entire
ranged group with a single cast). Ideally, you kill her not too far from
her starting position. If she ends up in the middle of the room, you
should probably wipe and start over.
- _Telonicus_: He is very easy in retail but actually is a big risk for
wipes with respect to bots because his bombs will one-shot any non-tank,
and bots will stupidly stand in front of him without a proper strategy.
You should keep some distance from him before he aggros. Your first
assistant tank will pick him up and move him to the West wall near
Sanguinar. Again, there is a 12-second delay before DPS starts. Your
melee DPS are coded to stay directly behind him and not get too close so
they don’t get hit by bombs.

**Phase 2:**
Kael’thas will summon all weapons immediately after Telonicus is down.
Just before Telonicus is down, you should move to the platform where the
advisors originally were—you’ll be in better position for the raid to
AoE down the weapons.

- Your main tank will pick up the axe and move it away from the group.
The axe is the biggest threat during this phase and can easily one-shot
casters if not pulled away.
- One of your Hunters will attempt to get aggro on the bow and move away
from the group (as a hacky way of trying to turn the bow away from the
group because you can’t really get a bot to do that directly). This
method is hit or miss, but it shouldn’t be that big of a deal if your
Hunter doesn’t pull it off properly.
- Everybody else will prioritize weapons in the following order (but
most damage will come from AoE, which is what you want or you will not
beat the timer): staff, mace, sword, dagger, axe (ranged only), bow, and
shield.
- As weapons are defeated, bots will loot and equip them. If you have
not disabled bot announcements in your config, you get to see your
entire raid go nuts because they looted legendary items.
- Here is what weapons bots will loot and equip. I don't know anything
about DKs, having never played WotLK, so tell me if anything is wrong
for them.
- _Healers:_ Mace (if a healer normally uses a staff, it's best if they
keep an OH in their bags for this fight)
- _Tanks:_ Shield and sword for Paladins and DK, shield and dagger for
warriors, staff for Druid
  - _Offensive_ casters: Staff
- _Rogues:_ Sword and dagger if Combat or Subtlety, dagger only if
Assassination
  - _DPS Death Knights, Retribution Paladins, Arms Warriors_: Axe
- _Fury Warriors_: Dagger. I understand that due to Titan Grip, they
should also have the Axe for best DPS; however, Fury Warriors have awful
DPS (we’re talking barely above Prot-level) at this stage. Thus, my view
is it is better to give them only the dagger so they will MH it and help
break MC in Phase 4, since they will contribute hardly any DPS
regardless.
  - _Cat Druids_: Staff
  - _Enhancement Shamans_: Dagger
- _Hunters:_ Bow and dagger. Note that I do NOT have them loot the sword
because they need the dagger in their mainhand to use to break MC in
Phase 4; whatever marginal benefit they get from the sword as a stat
stick is not worth losing this capability. If your Hunter uses a 2H, it
is best to have them carry a 1H in their inventory so they can put
something in the OH after they equip the dagger.
- After looting weapons, bots with the staff will use it (once) to
activate the Mental Protection Field. Hunters will use the bow to
generate the legendary arrows and equip those (and will continue to do
so during the fight if they use up the arrows).
- If you wipe from this point forward, everybody will lose their
legendary weapons, and by default, most bots will not automatically
reequip their own weapons until a loot event occurs. This was extremely
annoying, and therefore there is a noncombat method implemented that
causes everybody to equip upgrades when they get within 150 yards of
Kael’thas. I considered applying this to the whole instance, but I’m not
sure if some people would not like that so I decided to limit things to
the Kael’thas encounter.

**Phase 3:**
I highly recommend you have your Shamans drop Tremor Totems (co +tremor)
during this phase. Doing so is not coded because I wanted to leave
flexibility, but I think it is very helpful for Sanguinar. After the
weapons die, you want to move your bots to a central location between
the advisors. If Thaladred died closer to the middle of the room,
ideally you position to the side of Thaladred so when he fixates he will
not chase bots North into the other advisors.

- Shamans will immediately use Heroism/Bloodlust.
- Your melee tanks will bring Sanguinar and Telonicus to their tanking
positions (same as Phase 1). If your first assistant tank is a Druid,
they will be immune to Telonicus’s Remote Toy due to having the
legendary staff’s aura activated and will also make your main tank
immune.
- One healer will stay by the Sanguinar and Telonicus tanking positions
to heal the tanks. Once IsHealAssistantOfIndex() is fixed, you will be
able to select this healer with the assistant flag. Right now, this will
just be the last healer that joined your raid (per standard AC logic).
- DPS priority will be Thaladred, Capernian (ranged only), Sanguinar,
Telonicus. As with retail, the most chaotic period will be before
Thaladred is killed, particularly if he chases bots into other advisors.
I don’t have a great solution for this, but Capernian is significantly
less dangerous during this phase thanks to the legendary staff. This is
the last true breakpoint—if you get Thaladred down with your raid mostly
intact, you are very likely to get the kill.

**Phase 4:**
Kael’thas will aggro immediately after all advisors are dead.

- Your main tank will position Kael’thas at his original position.
- Bots will move out of Flame Strikes.
- Assist tanks will pick up Phoenixes. Since they die over time anyway,
bots will not waste time attacking them. When Phoenixes die, they turn
into an Egg—at that point, bots will switch to the Egg to destroy it
before the Phoenix is reborn.
- When Kael’thas puts up Shock Barrier and starts casting Pyroblast on
your main tank (a one-shot), all bots will focus DPS on him (even if
there is an egg up). You have 4 seconds to break the barrier (80K HP)
and interrupt his Pyroblast. It is likely that you will not be able to
if you are playing with IP nerfs and are in T4 gear. However, the main
tank will use the legendary shield’s ability, which will allow them to
absorb one cast, giving you 8 seconds to break the barrier and interrupt
Pyroblast. Bots will put top priority on interrupting Pyroblast as soon
as the barrier is down.
- If a bot (or player) is mind controlled, bots with the legendary
dagger (other than tanks) will move to MC’d players and use the
following attacks to break MC: Shiv (Rogues), Hamstring (Warriors), Wing
Clip (Hunters), and Stormstrike (Shamans).

**Phase 5:**
At 50% HP, Kael’thas enters a long RP sequence. This is a good time to
kill any remaining Phoenixes and/or Eggs.
- Kael’thas stops casting Pyroblast and Mind Control.
- His main new ability is Gravity Lapse, and it doesn’t work properly on
bots... He sucks in the entire raid then knocks everybody back in a
different direction. What is supposed to happen is that players will end
up floating in midair in different directions and at different heights.
However, bots will immediately fall to the ground after getting knocked
back. They will not actually hit the ground though and instead remain in
a flying state right above the floor.
- If you could move in 3D space, Netherbeam would be very easy to deal
with. However, because that is not available to bots, they can spread
only in 2D space and thus need to move farther to get properly spread,
and they waste the first moments falling straight down. As a result, the
damage from Netherbeam can be quite high, and the beginning of Gravity
Lapse requires a lot of healing. I don’t really have a better way of
dealing with this.
- FWIW, I don’t think there is any existing method to make bots disperse
in 3D anyway.
- Kael’thas is supposed to use Nether Void when players are in midair,
which creates clouds that reduce your max HP and thus make it more
challenging to maneuver, but AC is bugged and he doesn’t use the ability
at all (there’s been an open issue about this forever).

For fuck's sake, that's all.

---------

Co-authored-by: Keleborn <22352763+Celandriel@users.noreply.github.com>
Co-authored-by: bash <hermensb@gmail.com>
Co-authored-by: Revision <tkn963@gmail.com>
2026-02-27 16:04:10 -08:00
Rikus Louw
ea60b38eb9
Add Serpentshrine Cavern attunement quest to bot factory (#2136)
# Pull Request

I've being getting ready to test Serpentshrine Cavern strategy on
`test-staging`, but noticed the bots don't currently have attunement
setup.

Added attunement quest.

---

## Design Philosophy

We prioritize **stability, performance, and predictability** over
behavioral realism.
Complex player-mimicking logic is intentionally limited due to its
negative impact on scalability, maintainability, and
long-term robustness.

Excessive processing overhead can lead to server hiccups, increased CPU
usage, and degraded performance for all
participants. Because every action and
decision tree is executed **per bot and per trigger**, even small
increases in logic complexity can scale poorly and
negatively affect both players and
world (random) bots. Bots are not expected to behave perfectly, and
perfect simulation of human decision-making is not a
project goal. Increased behavioral
realism often introduces disproportionate cost, reduced predictability,
and significantly higher maintenance overhead.

Every additional branch of logic increases long-term responsibility. All
decision paths must be tested, validated, and
maintained continuously as the system evolves.
If advanced or AI-intensive behavior is introduced, the **default
configuration must remain the lightweight decision
model**. More complex behavior should only be
available as an **explicit opt-in option**, clearly documented as having
a measurable performance cost.

Principles:

- **Stability before intelligence**  
  A stable system is always preferred over a smarter one.

- **Performance is a shared resource**  
  Any increase in bot cost affects all players and all bots.

- **Simple logic scales better than smart logic**  
Predictable behavior under load is more valuable than perfect decisions.

- **Complexity must justify itself**  
  If a feature cannot clearly explain its cost, it should not exist.

- **Defaults must be cheap**  
  Expensive behavior must always be optional and clearly communicated.

- **Bots should look reasonable, not perfect**  
  The goal is believable behavior, not human simulation.

Before submitting, confirm that this change aligns with those
principles.

---

## Feature Evaluation

Please answer the following:

- Describe the **minimum logic** required to achieve the intended
behavior?
- Describe the **cheapest implementation** that produces an acceptable
result?
- Describe the **runtime cost** when this logic executes across many
bots?

---

## How to Test the Changes

- Add bots and convert to raid
- Make sure you have attunement by completing
[this](https://www.wowhead.com/tbc/quest=13431/the-cudgel-of-kardesh)
quest
- Teleport to SSC and summon bots. The bots should appear in the raid.

## Complexity & Impact

Does this change add new decision branches?
- - [x] No
- - [ ] Yes (**explain below**)

Does this change increase per-bot or per-tick processing?
- - [x] No
- - [ ] Yes (**describe and justify impact**)

Could this logic scale poorly under load?
- - [x] No
- - [ ] Yes (**explain why**)
---

## Defaults & Configuration

Does this change modify default bot behavior?
- - [ ] No
- - [x] Yes (**explain why**)

This adds the attunement quest for SSC by default

If this introduces more advanced or AI-heavy logic:
- - [x] Lightweight mode remains the default
- - [ ] More complex behavior is optional and thereby configurable
---

## AI Assistance

Was AI assistance (e.g. ChatGPT or similar tools) used while working on
this change?
- - [x] No
- - [ ] Yes (**explain below**)

If yes, please specify:

- AI tool or model used (e.g. ChatGPT, GPT-4, Claude, etc.)
- Purpose of usage (e.g. brainstorming, refactoring, documentation, code
generation)
- Which parts of the change were influenced or generated
- Whether the result was manually reviewed and adapted

AI assistance is allowed, but all submitted code must be fully
understood, reviewed, and owned by the contributor.
Any AI-influenced changes must be verified against existing CORE and PB
logic. We expect contributors to be honest
about what they do and do not understand.

---

## Final Checklist

- - [x] Stability is not compromised
- - [x] Performance impact is understood, tested, and acceptable
- - [x] Added logic complexity is justified and explained
- - [x] Documentation updated if needed

---

## Notes for Reviewers

Anything that significantly improves realism at the cost of stability or
performance should be carefully discussed
before merging.
2026-02-23 11:02:11 -08:00
Keleborn
441f9f7552
Warnings PR 1: Event warnings and headers (#2106)
# Pull Request

This is the first in a series of PRs intended to eliminate warnings in
the module. The design intent is to eliminate the calling event when not
needed in the body of the function. Based off of SmashingQuasars work.

---

## How to Test the Changes

- Step-by-step instructions to test the change
- Any required setup (e.g. multiple players, bots, specific
configuration)
- Expected behavior and how to verify it

## Complexity & Impact

- Does this change add new decision branches?
    - [x] No
    - [ ] Yes (**explain below**)

- Does this change increase per-bot or per-tick processing?
    - [x] No
    - [ ] Yes (**describe and justify impact**)

- Could this logic scale poorly under load?
    - [x] No
    - [ ] Yes (**explain why**)

---

## Defaults & Configuration

- Does this change modify default bot behavior?
    - [x] No
    - [ ] Yes (**explain why**)

If this introduces more advanced or AI-heavy logic:

- [ ] Lightweight mode remains the default
- [ ] More complex behavior is optional and thereby configurable

---

## AI Assistance

- Was AI assistance (e.g. ChatGPT or similar tools) used while working
on this change?
    - [x] No
    - [ ] Yes (**explain below**)

---

## Final Checklist

- [x] Stability is not compromised
- [x] Performance impact is understood, tested, and acceptable
- [x] Added logic complexity is justified and explained
- [x] Documentation updated if needed

---

## Notes for Reviewers

Anything that significantly improves realism at the cost of stability or
performance should be carefully discussed
before merging.

---------

Co-authored-by: bashermens <31279994+hermensbas@users.noreply.github.com>
2026-02-14 20:55:10 +01:00
Alex Dcnh
17b8d7f68b
Stage1 refactor world position method names (#2126)
# Pull Request

This change replaces the non‑standard
WorldPosition::getX/getY/getZ/getO/getMapId wrappers with the core
getters (GetPositionX/Y/Z, GetOrientation, GetMapId) and removes the
redundant wrappers.
Goal: align the module with AzerothCore conventions, reduce local
adapters, and improve long‑term maintainability.

---

## Design Philosophy

This is a structural cleanup only (coordinate access) and does not alter
any AI behavior or decision logic.
It follows the stability/performance-first philosophy and does not add
branches or extra runtime work.

Before submitting: yes, this change aligns with the principles of
stability, performance, and predictability.

Principles:

- **Stability before intelligence**  
  A stable system is always preferred over a smarter one.

- **Performance is a shared resource**  
  Any increase in bot cost affects all players and all bots.

- **Simple logic scales better than smart logic**  
Predictable behavior under load is more valuable than perfect decisions.

- **Complexity must justify itself**  
  If a feature cannot clearly explain its cost, it should not exist.

- **Defaults must be cheap**  
  Expensive behavior must always be optional and clearly communicated.

- **Bots should look reasonable, not perfect**  
  The goal is believable behavior, not human simulation.

Before submitting, confirm that this change aligns with those
principles.

---

## Feature Evaluation

Please answer the following:

- Minimum logic required: use core getters (GetPositionX/Y/Z, GetMapId,
GetOrientation) wherever coordinates are needed.
- Cheapest implementation: direct call replacement and removal of
redundant wrappers.
- Runtime cost: negligible (same data access, no additional logic).

---

## How to Test the Changes

- No functional testing required (behavior‑neutral refactor).
- Recommended: compile the module and run a normal server startup as
validation.

## Complexity & Impact

Does this change add new decision branches?
- - [x] No
- - [x] Yes (**explain below**)

Does this change increase per-bot or per-tick processing?
- - [x] No
- - [ ] Yes (**describe and justify impact**)

Could this logic scale poorly under load?
- - [x] No
- - [ ] Yes (**explain why**)
---

## Defaults & Configuration

Does this change modify default bot behavior?
- - [x] No
- - [ ] Yes (**explain why**)

If this introduces more advanced or AI-heavy logic:
- - [x] Lightweight mode remains the default
- - [x] More complex behavior is optional and thereby configurable
---

## AI Assistance

Was AI assistance (e.g. ChatGPT or similar tools) used while working on
this change?
- - [ ] No
- - [x] Yes (**explain below**)

If yes, please specify:

- AI tool or model used: Copilot
- Purpose of usage: Translate this PR text from french to English

---

## Final Checklist

- - [x] Stability is not compromised
- - [x] Performance impact is understood, tested, and acceptable
- - [x] Added logic complexity is justified and explained
- - [x] Documentation updated if needed

---

## Notes for Reviewers

This is a core-friendly cleanup only, with no behavioral change.
No additional logic or CPU cost is introduced.
2026-02-13 09:24:42 -08:00
privatecore
a0a50204ec
Fix action validation checks: isUseful -> isPossible + codestyle fixes and corrections (#2125)
# Pull Request

Fix the incorrect logic flaw when processing actions from different
sources. It should be: `isUseful` -> `isPossible`. The original logic is
based on the Mangosbot code and the impl presented inside
`Engine::DoNextAction`. This should fix all wrong validation orders for
triggers and direct/specific actions.

Code style is based on the AzerothCore style guide + clang-format.

---

## Design Philosophy

We prioritize **stability, performance, and predictability** over
behavioral realism.
Complex player-mimicking logic is intentionally limited due to its
negative impact on scalability, maintainability, and
long-term robustness.

Excessive processing overhead can lead to server hiccups, increased CPU
usage, and degraded performance for all
participants. Because every action and
decision tree is executed **per bot and per trigger**, even small
increases in logic complexity can scale poorly and
negatively affect both players and
world (random) bots. Bots are not expected to behave perfectly, and
perfect simulation of human decision-making is not a
project goal. Increased behavioral
realism often introduces disproportionate cost, reduced predictability,
and significantly higher maintenance overhead.

Every additional branch of logic increases long-term responsibility. All
decision paths must be tested, validated, and
maintained continuously as the system evolves.
If advanced or AI-intensive behavior is introduced, the **default
configuration must remain the lightweight decision
model**. More complex behavior should only be
available as an **explicit opt-in option**, clearly documented as having
a measurable performance cost.

Principles:

- **Stability before intelligence**  
  A stable system is always preferred over a smarter one.

- **Performance is a shared resource**  
  Any increase in bot cost affects all players and all bots.

- **Simple logic scales better than smart logic**  
Predictable behavior under load is more valuable than perfect decisions.

- **Complexity must justify itself**  
  If a feature cannot clearly explain its cost, it should not exist.

- **Defaults must be cheap**  
  Expensive behavior must always be optional and clearly communicated.

- **Bots should look reasonable, not perfect**  
  The goal is believable behavior, not human simulation.

Before submitting, confirm that this change aligns with those
principles.

---

## Feature Evaluation

Please answer the following:

- Describe the **minimum logic** required to achieve the intended
behavior?
- Describe the **cheapest implementation** that produces an acceptable
result?
- Describe the **runtime cost** when this logic executes across many
bots?

---

## How to Test the Changes

- Step-by-step instructions to test the change
- Any required setup (e.g. multiple players, bots, specific
configuration)
- Expected behavior and how to verify it

## Complexity & Impact

Does this change add new decision branches?
- - [x] No
- - [ ] Yes (**explain below**)

Does this change increase per-bot or per-tick processing?
- - [x] No
- - [ ] Yes (**describe and justify impact**)

Could this logic scale poorly under load?
- - [x] No
- - [ ] Yes (**explain why**)
---

## Defaults & Configuration

Does this change modify default bot behavior?
- - [x] No
- - [ ] Yes (**explain why**)

If this introduces more advanced or AI-heavy logic:
- - [ ] Lightweight mode remains the default
- - [ ] More complex behavior is optional and thereby configurable
---

## AI Assistance

Was AI assistance (e.g. ChatGPT or similar tools) used while working on
this change?
- - [x] No
- - [ ] Yes (**explain below**)

If yes, please specify:

- AI tool or model used (e.g. ChatGPT, GPT-4, Claude, etc.)
- Purpose of usage (e.g. brainstorming, refactoring, documentation, code
generation)
- Which parts of the change were influenced or generated
- Whether the result was manually reviewed and adapted

AI assistance is allowed, but all submitted code must be fully
understood, reviewed, and owned by the contributor.
Any AI-influenced changes must be verified against existing CORE and PB
logic. We expect contributors to be honest
about what they do and do not understand.

---

## Final Checklist

- - [x] Stability is not compromised
- - [x] Performance impact is understood, tested, and acceptable
- - [x] Added logic complexity is justified and explained
- - [x] Documentation updated if needed

---

## Notes for Reviewers

Anything that significantly improves realism at the cost of stability or
performance should be carefully discussed
before merging.
2026-02-13 09:24:11 -08:00
Keleborn
80b3823f12
Warnings PR 3, remove std::move when not necessary. (#2108)
# Pull Request

std::move was being used in a few places to return a vector. Its not
necessary. A direct return allows for some optimizations that moving
wouldnt.

## How to Test the Changes

-Bots should initialize correctly 

## Complexity & Impact

- Does this change add new decision branches?
    - [x] No
    - [ ] Yes (**explain below**)

- Does this change increase per-bot or per-tick processing?
    - [x] No
    - [ ] Yes (**describe and justify impact**)

- Could this logic scale poorly under load?
    - [x] No
    - [ ] Yes (**explain why**)

---

## Defaults & Configuration

- Does this change modify default bot behavior?
    - [x] No
    - [ ] Yes (**explain why**)

If this introduces more advanced or AI-heavy logic:

- [x] Lightweight mode remains the default
- [ ] More complex behavior is optional and thereby configurable

---

## AI Assistance

- Was AI assistance (e.g. ChatGPT or similar tools) used while working
on this change?
    - [x] No
    - [ ] Yes (**explain below**)

---

## Final Checklist

- [ ] Stability is not compromised
- [ ] Performance impact is understood, tested, and acceptable
- [ ] Added logic complexity is justified and explained
- [ ] Documentation updated if needed

---

## Notes for Reviewers

Anything that significantly improves realism at the cost of stability or
performance should be carefully discussed
before merging.

---------

Co-authored-by: bashermens <31279994+hermensbas@users.noreply.github.com>
2026-02-13 09:22:27 -08:00
Keleborn
ee2a399ac8
Refactor newrpginfo data union to std::variant (#2079)
# Pull Request

As I began modifying the newrpginfo to change the types of data it
stored, or add new data I found myself with the issue of ending up
either with garbage memory if the information wasnt properly stored on
status change, or needing complicated destructor patterns for non
trivial data sets.

---

## Design Philosophy

Make rpginfo able to handle more complicated information in a strongly 

---

## Feature Evaluation

No Feature changes

---

## How to Test the Changes

-  Server should be stable for an extended period of time. 
- Bots should be able to complete quests, fly, etc as they did before.

## Complexity & Impact

- Does this change add new decision branches?
    - [X ] No
    - [ ] Yes (**explain below**)

- Does this change increase per-bot or per-tick processing?
    - [ ] No
    - [ X] Yes (**describe and justify impact**)
Potentially as there can be more memory involved in the object.

- Could this logic scale poorly under load?
    - [X ] No
    - [ ] Yes (**explain why**)

---

## Defaults & Configuration

- Does this change modify default bot behavior?
    - [ X] No
    - [ ] Yes (**explain why**)

If this introduces more advanced or AI-heavy logic:

- [ ] Lightweight mode remains the default
- [ ] More complex behavior is optional and thereby configurable

---

## AI Assistance

- Was AI assistance (e.g. ChatGPT or similar tools) used while working
on this change?
    - [ ] No
    - [ X] Yes (**explain below**)

If yes, please specify:

- Gemini suggested the use of std::variant as an alternative data
structure. I found additinal external references that correlated with
the same suggestion of moving away from a union.
- Implementation was performed manually with Co-pilot auto-complete

---

## Final Checklist 
In progress.
- [ ] Stability is not compromised
- [ ] Performance impact is understood, tested, and acceptable
- [ ] Added logic complexity is justified and explained
- [ ] Documentation updated if needed

---

## Notes for Reviewers

Im not 100% sure if this is a good design choice. There are some things
I didnt quite like by the end of this, specifically having to double
check whenever accessing data whether exists or not even though an
action has already been triggered. But I have a PR in the works where I
want to store a full flight path vector, and the union was giving me
issues. (It appears that state changes may be occuring in the same tick
between RPG status update and the stated action, leading to incorrect
data gathering.

I ended up solving it by first checking a pointer to the object, and
then getting the reference.
```c++
    auto* dataPtr = std::get_if<NewRpgInfo::DoQuest>(&info.data);
    if (!dataPtr)
        return false;
    auto& data = *dataPtr;
```

---------

Co-authored-by: bashermens <31279994+hermensbas@users.noreply.github.com>
2026-02-13 09:19:54 -08:00
kadeshar
cfb2ed4bf3
Merge pull request #2124 from kadeshar/oculus-drake-fix
Oculus drake mounting fix
2026-02-08 17:10:18 +01:00
Keleborn
3db2a5a193
Refactor of EquipActions (#1994)
#PR Description 

The root cause of issue #1987 was the AI Value item usage becoming a
very expensive call when bots gained professions accidentally.

My original approach was to eliminate it entirely, but after inputs and
testing I decided to introduce a more focused Ai value "Item upgrade"
that only checks equipment and ammo inheriting directly from item usage,
so the logic is unified between them.

Upgrades are now only assessed when receiving an item that can be
equipped.

Additionally, I noticed that winning loot rolls did not trigger the
upgrade action, so I added a new package handler for that.


Performance needs to be re-evaluated, but I expect a reduction in calls
and in the cost of each call.

I tested with bots and selfbot in deadmines and ahadowfang keep.

---------

Co-authored-by: bashermens <31279994+hermensbas@users.noreply.github.com>
2026-02-08 12:41:33 +01:00
Crow
8585f10f48
Implement Serpentshrine Cavern Strategies (#1888)
Edited: Below description of methods were brought up to date as of the
PR coming off of draft.

### General
I've starting leveraging, to the extent possible, an out-of-combat
method to erase map keys. This is mostly useful for timers that need to
start upon the pull because I dislike having to rely on a check for a
boss to be at 100% HP (or 99.9% or whatever) because it can be
unreliable sometimes.

### Trash
Underbog Colossi: Some Colossi leave behind a lake of toxin when they
die that quickly kills any player that is standing in it. The pool is a
dynamic-object-generated AoE, and bots will not avoid it on their own (I
think because the AoE is out of combat, plus the radius is much larger
than the default avoidance radius in the config). The method does not
require bots to be in combat, and simply gets bots to run out of the
toxin. You will probably still get a couple of idiots who drink in the
middle of it, but in my experience, the vast majority of the raid gets
out, and healers that escape can easily keep up a couple of fools until
they've drank to full.

Greyheart Tidecallers: Bots will mark and destroy Water Elemental Totems
immediately.

### Hydross the Unstable
The strategy uses 2 tanks, with the main tank assigned to the frost
phase and the 1st assistant tank assigned to the nature phase.

- The main tank will tank the frost phase, and the first assistant tank
will tank the nature phase. They each have designated spots and will
wait at their spots twiddling their thumbs while Hydross is in the other
phase.
- Hunters will misdirect to the applicable tank upon the pull and after
each phase change.
- The phase change process begins 1 second after Hydross reaches 100%
Marks. The current tank will begin moving to the next phase tank's spot
for the next tank to take over as soon as Hydross transitions.
- DPS is ordered to stop after Hydross reaches 100% Marks until 5
seconds after he transitions.
- Bots will prioritize the elementals adds after every phase change,
unless Hydross is under 10% HP, in which case they should ignore the
adds and burn the boss.
- Ranged bots should spread during the frost phase to mitigate the
impact of Water Tombs.

### The Lurker Below

- There is a designated spot for the main tank.
- Ranged DPS will fan out over a 120-degree arc that is centered
directly across from the tank spot (to try to spread to reduce Geyser
damage while also keeping them behind Lurker).
- When Spout begins, all bots will run around behind Lurker. The intent
is to keep a distance with a radius of 20 or 21 yards and within 45
degrees (either side) of directly behind him. Movement is specifically
tangential along an arc so bots don't run in front of Lurker.
- Spout's duration is tracked by a timer. The mechanics of the spell
itself are rather unique and don't involve a continuous cast or aura to
track easily so I settled for the timer.
- If you have 3 (or more) tanks, each of the first 3 tanks will be
assigned to one of the 3 Coilfang Guardians during the submerge phase.

### Leotheras the Blind
The fight is designed for a Warlock tank. You can choose the Warlock
tank by giving a Warlock the Assistant flag. If you don't do that, your
highest HP Warlock will be picked. Do NOT switch the Warlock tank to a
co +tank strategy--the designated Warlock is hardcoded to spam Searing
Pain on Demon Leo and otherwise will engage in normal DPS strategies. If
you don't have a Warlock at all, the strategy has some methods built in
to try to make things work as best as possible with a melee tank.

- The Spellbinders get marked with skulls and killed in order.
- There is no designated spot or designated tank for the human phase.
Your tanks will fight for aggro. Ranged bots will attempt to keep some
distance, and when Whirlwind starts, everybody will run away from
Leotheras.
- During the demon phase, your melee tanks should take a backseat to
your Warlock tank, who will receive help in the form of Misdirection.
Bots will get the hell away from the Warlock tank so the Warlock tank
should be taking every Chaos Blast alone.
- During the final phase, your regular tanks will tank Leotheras, and
the Warlock tank will tank his Shadow. The melee tanks will attempt to
separate Leotheras from his Shadow so bots can focus down Leotheras
without getting hit with Chaos Blasts.
- Bots will wait 5 seconds to DPS after every transition into human
phase, 12 seconds to DPS after every transition into demon phase, and 8
seconds to DPS after the transition into the final phase. There is no
waiting on DPS after Whirlwinds, even though it would be ideal. It's not
a big deal to live without, and for various reasons, it would have been
a pain in the ass to deal with.
- Bots will save Bloodlust/Heroism until after Spellbinders are down.
- To deal with the Inner Demons, I disabled DPS assist for bots who are
targeted and force them to focus only on their Inner Demons. This is
sufficient in my experience for all DPS bots and Protection Warriors and
Paladins to kill their Inner Demons, even at 50% damage. Feral Tank
Druids and Healers still need help, so the strategy hardcodes their
actions while fighting Inner Demons. For example, Resto Druids are coded
to shift out of Tree Form, cast Barkskin on themselves, and just spam
Wrath until the Inner Demon is dead. There are no bot strategy changes
used for this method.

### Fathom-Lord Karathress
You will need 4 tanks. Your main tank will tank Karathress, and an
assistant tank will tank each Fathom Guard. If you have fewer than 4
tanks, then the priority order for tank assignment will be Karathress,
Caribdis, Sharkkis, and then Tidalvess.

- Roughly, the tank spots are (1) for Karathress, near where he starts
but closer to the ledge for LoS reasons, (2) for Sharkkis, North from
his starting location on the other side of the ramp, (3) for Tidalvess,
Northwest from his starting location near the pillar, and (4) for
Caribdis, far to the West of her starting position, near the corner.
- Note that the tanks will probably clip through the terrain a bit when
going to their positions. This is due to me implementing a forced MoveTo
to the tank position coordinates. There is something weird about the
maps in Karathress's room, and the tanks will take some really screwed
up paths without making them go directly to the exact coordinates. So
this looks stupid but is necessary.
- One healer will be assigned to heal the Caribdis tank. Because AC
Playerbots does not yet have a focus heal strategy, this just means that
such healer has a designated location near the Caribdis tank's location.
This healer can be selected with the Assistant flag.
- Hunters will misdirect the Fathom Guards onto their applicable tanks.
If you don't have three Hunters, the priority is Caribdis, Tidalvess,
then Sharkkis.
- DPS will wait 12 seconds to begin attacking. After that, they will
prioritize targets as follows:
- (1): Melee will always prioritize Spitfire Totems as soon as they
spawn. This will continue through the duration of the fight.
- (2): All bots will kill Tidalvess first.
- (3): Melee bots will move to Sharkkis, and ranged bots will move to
Caribdis. I understand this is not the standard kill order for players,
which would have the entire raid kill Sharkkis next. The reasons I have
done this differently are because melee DPS is much stronger with 3.3.5
talents vs. in retail TBC, and because bots get really thrown off by
Cyclones and therefore they struggle to kill Caribdis quickly. You do
not want Karathress below 75% HP before all Fathom-Guards are dead or he
gets a huge damage buff.
- (4) If Caribdis dies first, ranged bots will help with Sharkkis.
- (5) Everybody kills Sharkkis's pet.
- (6) Everybody kills Karathress.

### Morogrim Tidewalker

- The main tank will pull the boss to the Northeast pillar, with the
tank's back against the pillar.
- A hunter will misdirect the boss onto the main tank upon the pull.
- When the boss gets to 26% HP, the main tank will begin moving the boss
to the Northeast corner of the room in preparation for Phase 2 (which
begins at 25%). The tank will move in two steps to get around the
pillar.
- When the boss gets to 25% HP, ranged will follow the main tank to the
corner and stack up right behind the boss. They will also move in two
steps.
- There is no method for melee since they will just naturally follow the
boss anyway.

### Lady Vashj

**Phase 1**:
- The main tank will tank Vashj in the center of the arena.
- If a Shaman is in the main tank's group, that Shaman will attempt to
keep a Grounding Totem down in range of the main tank to absorb Shock
Blast. This should continue in Phase 3.
- Ranged bots will spread out in a semicircle around the center of the
arena.
- If any bot other than the main tank gets Static Charge, it will run
away from other bots. If the main tank gets Static Charge, other bots
will run away from the main tank. This method should continue in Phase
3.
- If any bot is Entangled and has Static Charge, the bot will attempt to
use Cloak of Shadows if it is a Rogue, and Paladins will attempt to use
Hand of Freedom. This method should continue in Phase 3 (with some
modifications).
- Bots will not use Bloodlust or Heroism (saved for Phase 3). Bots will
not use any other major cooldowns, either, such as Metamorphosis (saved
for Phase 2 and 3).

**Phase 2**:
There are two central mechanics to this phase, both of which were
challenging to get bots to execute properly. First is the system of
prioritizing adds. The large playing field and multiple types of adds
coming from random directions make this phase not doable with realistic
DPS under the standard Playerbots target selection system. Therefore, I
took inspiration from liyunfan's Naxx strategy for Phase 1 of Kel'Thuzad
to disable dps assist and create a custom target selection system.

First, a cheat with respect to the Coilfang Striders: 
- Tanks will permanently have the Fear Ward aura applied to them if you
have raid cheats enabled. This allows them to tank the Coilfang
Striders. The standard strategy was to have an Elemental Shaman kite the
Strider around the perimeter of the arena, with ranged players
(including healers) spamming DoTs on the Strider. If you can make bots
do this, then great, but it's far beyond my capabilities. Therefore,
with the cheat, the first assistant tank is responsible for tanking
Striders and keeping them away from Core passers (described below) and
Vashj. Evidently it was (and is, in TBC Classic) possible to tank (and
melee DPS) Striders by wearing a Dire Maul Ogre Suit, which would give
you enough reach to stay out of the Strider's fear. I actually tried
that, and it does not work, either because AC's radiuses are not the
same or just because bots do not maintain the same level of precise
positioning. But anyway, the point is that technically the Striders are
tankable by real players, so maybe that will make you feel better about
using this cheat (it's fine enough rationalizing for me). I found this
fight to be unmanageable without this cheat (i.e., using a method that
would only have bots try to run away from Striders) because each Strider
was guaranteed to wipe out a couple of bots, and you really cannot
afford to lose anyone. YMMV though.
- If cheats are enabled for Striders, Hunters will attempt to Misdirect
the Striders to the first assist tank.
- If cheats are not enabled, bots will attempt to use slows/roots to
stop the Striders. I have some logic for them to use Netherweave Nets,
but I suspect it does not actually work so I may remove it instead of
trying to get it to function properly.

Target priority is as follows:
- Hunters and Mages: Enchanted Elementals, Coilfang Striders, Coilfang
Elites.
- Other Ranged Bots: Elites, Striders, Elementals. 
- Melee DPS: Elementals, Elites.
- Tanks: Elites, Elementals (except if cheats are enabled, the first
assistant tank will instead prioritize Striders and then Elementals)
- Everybody else (basically means healers): Elementals, Elites, Striders
- If there is more than one of the same target, bots will prioritize the
one that is closer to Vashj.
- In all cases, the valid attack ranged is limited so that bots should
not leave the central platform.
- If somehow a bot ends up too far from the center of the room and is
not actively attacking anything, there is logic to make them run back.

Handling Tainted Elementals and the Tainted Core: I will make another
post about this later. It is easily the most complicated strategy I've
ever worked on (far beyond anything on Kael'thas even) so will
necessitate a long explanation. The tl;dr is that there is a chain of
two-to-four bots that receive/pass the Tainted Core before using it on a
Shield Generator, and if you are playing by yourself, you probably need
to turn raid cheats on, in which case there will also be a bot that
teleports to, kills, and loots the Tainted Elementals (i.e., the bots
will then handle the entire sequence of shutting down Shield
Generators).

**Phase 3**:
- The main tank will pick up Vashj immediately and try to keep her away
from Enchanted Elementals.
- DPS will burn down residual adds from Phase 2 in the order of (1)
elementals, (2) strider for ranged only (if you have more than one up,
you're dead), and (3) elites (hopefully you have only one up, but two
with one almost dead is possible).
- Hunters will kill Toxic Sporebats. This works quite well, but they
(and anybody else if ordered to target Sporebats) have a tendency to
levitate up into the pipes at the top of the room when killing the
Sporebats. To counteract this, a method forcibly teleports bots to the
ground if they get more than 2 yards above the ground.
- The Phase 1 Cloak of Shadows/Hand of Freedom method is now expanded to
include bots Entangled in the Sporebat poison pools (with Hand of
Freedom usage prioritized on the main tank).
- There is a specific method to avoid the Sporebat poison pools. The
Vashj tank will move backwards when avoiding poison.

---------

Co-authored-by: kadeshar <kadeshar@gmail.com>
2026-02-08 12:31:23 +01:00
kadeshar
79fb3a5bbc - Fixed Oculus drake mounting 2026-02-07 17:53:55 +01:00
kadeshar
026df0dabe
Chilton wand fix (#2115)
# Pull Request

Added Chilton wand to excluded to equipment items for bots and unified 2
exclusion lists to single one.
Resolves: https://github.com/mod-playerbots/mod-playerbots/issues/2093

---

## How to Test the Changes

Couldnt reproduce Chilton wand bug then testing sound impossible.
Someone can try getting this items on shaman.

## Complexity & Impact

Does this change add new decision branches?
- - [x] No
- - [ ] Yes

Does this change increase per-bot or per-tick processing?
- - [x] No
- - [ ] Yes

Could this logic scale poorly under load?
- - [x] No
- - [ ] Yes
---

## Defaults & Configuration

Does this change modify default bot behavior?
- - [x] No
- - [ ] Yes

If this introduces more advanced or AI-heavy logic:
- - [ ] Lightweight mode remains the default
- - [ ] More complex behavior is optional and thereby configurable
---

## AI Assistance

Was AI assistance (e.g. ChatGPT or similar tools) used while working on
this change?
- - [x] No
- - [ ] Yes
---

## Final Checklist

- - [x] Stability is not compromised
- - [x] Performance impact is understood, tested, and acceptable
- - [x] Added logic complexity is justified and explained
- - [x] Documentation updated if needed

---
2026-02-06 11:57:48 -08:00
Crow
b31bda85ee
Refactor raid strategy framework (#2069)
# Pull Request

The purposes of this PR are to (1) establish a general raid helper
framework for the benefit of future raid strategies and (2) make some
improvements to problematic areas of the raid strategy code.

List of changes:
1. Added new RaidBossHelpers.cpp and RaidBossHelpers.h files in the Raid
folder.

3. Moved reused helpers from Karazhan, Gruul, and Magtheridon strategies
to the new helper files.
4. Modified the prior function that assigned a DPS bot to store and
erase timers and trackers in associative containers--the function now
includes parameters for mapId (so a bot that is not in the instance will
not be assigned) and for the ability to exclude a bot (useful for
excluding particular important roles, such as a Warlock tank, so they
are not bogged down by these extra tasks at critical moments). I also
renamed it from IsInstanceTimerManager to IsMechanicTrackerBot.
5. Moved all helper files in raid strategies to Util folders (was needed
for ICC, MC, and Ulduar).
6. Renamed and reordered includes of Ulduar files in AiObjectContext.cpp
to match other raid strategies.
a. This initially caused compile errors which made me realize that the
existing code had several problems with missing includes and was
compiling only due to the prior ordering in AiObjectContext.cpp.
Therefore, I added the missing includes to Molten Core, Ulduar, and
Vault of Archavon strategies.
b. Ulduar and Old Kingdom were also using the same constant name for a
spell--the reordering caused a compile error here as well, which just
highlighted an existing problem that was being hidden. I renamed the
constant for Ulduar to fix this, but I think the better approach going
forward would be to use a namespace or enum class. But that is for
another time and probably another person.
7. Several changes with respect to Ulduar files:
a. The position constants and enums for spells and NPCs and such were in
the trigger header file. I did not think that made sense so moved them
to existing helper files.
b. Since the strategy does not use multipliers, I removed all files and
references to multipliers in it.
c. I removed some unneeded includes. I did not do a detailed review to
determine what else could be removed--I just took some out that I could
tell right away were not needed.
d. I renamed the ingame strategy name from "uld" to "ulduar," which I
think is clearer and is still plenty short.
8. Partial refactor of Gruul and Magtheridon strategies:
a. I did not due a full refactoring but made some quick changes to
things I did previously that were rather stupid like repeating
calculations, having useless logic like pointless IsAlive() checks for
creatures already on the hostile references list, and not using the
existing Position class for coordinates.
b. There were a few substantive changes, such as allowing players to
pick Maulgar mage and moonkin tanks with the assistant flag, but a
greater refactoring of the strategies themselves is beyond this PR.
c. I was clearing some containers used for Gruul and Magtheridon
strategies; the methods are now fixed to erase only the applicable keys
so that in the unlikely event that one server has multiple groups
running Gruul or Magtheridon at the same time, there won't be timer or
position tracker conflicts.

## How to Test the Changes

1. Enter any raid instance that has any code impacted by this PR
2. Engage bosses and observe if any strategies are now broken

I personally tested Maulgar, Gruul, and Magtheridon and confirmed that
they still work as intended.

## Complexity & Impact

I do not expect this PR to have any relevant changes to in-game
performance, but I will defer to those more knowledgeable than I if
there are concerns in this area. As I've mentioned before, you can
consider me to be like a person who has taken half an intro C++ course
at best.

## AI Assistance

None beyond autocomplete of repetitive changes.

---------

Co-authored-by: bashermens <31279994+hermensbas@users.noreply.github.com>
2026-02-06 11:55:43 -08:00
kadeshar
bebac60c51
test-staging alignment (#2121)
# Pull Request

Describe what this change does and why it is needed...

---

## Design Philosophy

We prioritize **stability, performance, and predictability** over
behavioral realism.
Complex player-mimicking logic is intentionally limited due to its
negative impact on scalability, maintainability, and
long-term robustness.

Excessive processing overhead can lead to server hiccups, increased CPU
usage, and degraded performance for all
participants. Because every action and
decision tree is executed **per bot and per trigger**, even small
increases in logic complexity can scale poorly and
negatively affect both players and
world (random) bots. Bots are not expected to behave perfectly, and
perfect simulation of human decision-making is not a
project goal. Increased behavioral
realism often introduces disproportionate cost, reduced predictability,
and significantly higher maintenance overhead.

Every additional branch of logic increases long-term responsibility. All
decision paths must be tested, validated, and
maintained continuously as the system evolves.
If advanced or AI-intensive behavior is introduced, the **default
configuration must remain the lightweight decision
model**. More complex behavior should only be
available as an **explicit opt-in option**, clearly documented as having
a measurable performance cost.

Principles:

- **Stability before intelligence**  
  A stable system is always preferred over a smarter one.

- **Performance is a shared resource**  
  Any increase in bot cost affects all players and all bots.

- **Simple logic scales better than smart logic**  
Predictable behavior under load is more valuable than perfect decisions.

- **Complexity must justify itself**  
  If a feature cannot clearly explain its cost, it should not exist.

- **Defaults must be cheap**  
  Expensive behavior must always be optional and clearly communicated.

- **Bots should look reasonable, not perfect**  
  The goal is believable behavior, not human simulation.

Before submitting, confirm that this change aligns with those
principles.

---

## Feature Evaluation

Please answer the following:

- Describe the **minimum logic** required to achieve the intended
behavior?
- Describe the **cheapest implementation** that produces an acceptable
result?
- Describe the **runtime cost** when this logic executes across many
bots?

---

## How to Test the Changes

- Step-by-step instructions to test the change
- Any required setup (e.g. multiple players, bots, specific
configuration)
- Expected behavior and how to verify it

## Complexity & Impact

Does this change add new decision branches?
- - [ ] No
- - [ ] Yes (**explain below**)

Does this change increase per-bot or per-tick processing?
- - [ ] No
- - [ ] Yes (**describe and justify impact**)

Could this logic scale poorly under load?
- - [ ] No
- - [ ] Yes (**explain why**)
---

## Defaults & Configuration

Does this change modify default bot behavior?
- - [ ] No
- - [ ] Yes (**explain why**)

If this introduces more advanced or AI-heavy logic:
- - [ ] Lightweight mode remains the default
- - [ ] More complex behavior is optional and thereby configurable
---

## AI Assistance

Was AI assistance (e.g. ChatGPT or similar tools) used while working on
this change?
- - [ ] No
- - [ ] Yes (**explain below**)

If yes, please specify:

- AI tool or model used (e.g. ChatGPT, GPT-4, Claude, etc.)
- Purpose of usage (e.g. brainstorming, refactoring, documentation, code
generation)
- Which parts of the change were influenced or generated
- Whether the result was manually reviewed and adapted

AI assistance is allowed, but all submitted code must be fully
understood, reviewed, and owned by the contributor.
Any AI-influenced changes must be verified against existing CORE and PB
logic. We expect contributors to be honest
about what they do and do not understand.

---

## Final Checklist

- - [ ] Stability is not compromised
- - [ ] Performance impact is understood, tested, and acceptable
- - [ ] Added logic complexity is justified and explained
- - [ ] Documentation updated if needed

---

## Notes for Reviewers

Anything that significantly improves realism at the cost of stability or
performance should be carefully discussed
before merging.

---------

Co-authored-by: Crow <pengchengw@me.com>
2026-02-06 11:55:28 -08:00
Crow
52d4191b43
Correct Zone ID 10 in config (Deadwind Pass -> Duskwood) (#2109)
Simple fix to config--zone ID 10 is Duskwood, not Deadwind Pass, as pointed out by @privatecore
2026-02-04 16:01:18 -08:00
Alex Dcnh
ba835250c8
New whisper command "pvp stats" that allows players to ask a bot to report its current Arena Points, Honor Points, and Arena Teams (#2071)
# Pull Request

This PR adds a new whisper command "pvp stats" that allows players to
ask a bot to report its current Arena Points, Honor Points, and Arena
Teams (name and team rating).

Reason:
Due to a client limitation in WoW 3.3.5a, the inspection window does not
display another player's Arena or Honor points , only team data.
This command provides an easy in-game way to check a bot’s PvP
currencies without modifying the client or core packets.

---

## Design Philosophy

Uses existing core getters (GetArenaPoints, GetHonorPoints,
GetArenaTeamId, etc.).
Fully integrated into the chat command system (ChatTriggerContext,
ChatActionContext).
Safe, no gameplay changes, purely informational.
No harcoded texts, use database local instead

---

## How to Test the Changes

/w BotName pvp stats

Bot reply:

[PVP] Arena Points: 302 | Honor Points: 11855
[PVP] 2v2: <The Fighters> (rating 2000)
[PVP] 3v3: <The Trio> (rating 573)

## Complexity & Impact

- Does this change add new decision branches?
    - [x] No
    - [ ] Yes (**explain below**)

- Does this change increase per-bot or per-tick processing?
    - [x] No
    - [ ] Yes (**describe and justify impact**)

- Could this logic scale poorly under load?
    - [x] No
    - [ ] Yes (**explain why**)

---

## Defaults & Configuration

- Does this change modify default bot behavior?
    - [x] No
    - [ ] Yes (**explain why**)

If this introduces more advanced or AI-heavy logic:

- [x] Lightweight mode remains the default
- [ ] More complex behavior is optional and thereby configurable

---

## AI Assistance

- Was AI assistance (e.g. ChatGPT or similar tools) used while working
on this change?
    - [x] No
    - [ ] Yes (**explain below**)

---

## Final Checklist

- [x] Stability is not compromised
- [x] Performance impact is understood, tested, and acceptable
- [x] Added logic complexity is justified and explained
- [x] Documentation updated if needed

---

Multibot already ready

Here is a sample of multibot when merged:
<img width="706" height="737" alt="image"
src="https://github.com/user-attachments/assets/5bcdd9f8-e2fc-4c29-a497-9fffba5dfd4e"
/>

---

## Notes for Reviewers

Anything that significantly improves realism at the cost of stability or
performance should be carefully discussed
before merging.

---------

Co-authored-by: bashermens <31279994+hermensbas@users.noreply.github.com>
2026-02-02 22:40:12 +01:00
bashermens
13fff46fa0
Improper singletons migration to clean Meyer's singletons (cherry-pick) (#2082)
# Pull Request

- Applies the clean and corrected singletons, Meyer pattern. (cherry
picked from @SmashingQuasar )

Testing by just playing the game in various ways. Been tested by myself
@Celandriel and @SmashingQuasar
---

## Complexity & Impact

- Does this change add new decision branches?
    - [x] No
    - [ ] Yes (**explain below**)

- Does this change increase per-bot or per-tick processing?
    - [x] No
    - [ ] Yes (**describe and justify impact**)

- Could this logic scale poorly under load?
    - [x] No
    - [ ] Yes (**explain why**)

---

## Defaults & Configuration

- Does this change modify default bot behavior?
    - [x] No
    - [ ] Yes (**explain why**)

---

## AI Assistance

- Was AI assistance (e.g. ChatGPT or similar tools) used while working
on this change?
    - [x] No
    - [ ] Yes (**explain below**)
---

## Final Checklist

- [x] Stability is not compromised
- [x] Performance impact is understood, tested, and acceptable
- [x] Added logic complexity is justified and explained
- [x] Documentation updated if needed

---

## Notes for Reviewers

Anything that significantly improves realism at the cost of stability or
performance should be carefully discussed
before merging.

---------

Co-authored-by: Nicolas Lebacq <nicolas.cordier@outlook.com>
Co-authored-by: Keleborn <22352763+Celandriel@users.noreply.github.com>
2026-01-30 21:49:37 +01:00
Crow
378254af3f
Fix Assistant Assignment Functions (#1930)
IsHealAssistantOfIndex() and IsRangedDpsAssistantOfIndex() are supposed
to iterate through the group and first return members with the
applicable role that have the assistant flag, and then iterate through
non-assistants only if there are not enough assistants for the
designated index. They are not written properly and actually completely
ignore the assistant flag.

I rely on these functions for significant roles in SSC and TK (which I
have decided I'll PR in the same way as SSC, as a long-term draft). I
have them fixed on my own fork, but it is problematic for testers if
these functions do not work.

So I've done three things here:
1. Fixed the functions to prefer members with the assistant flag.
2. Added a third parameter for ignoreDeadPlayers, like
IsAssistTankOfIndex() has. Note that the parameter is by default false
for IsAssistTankOfIndex(), meaning dead players are _not_ ignored. This
is not my preferred design choice--I think the default should be to
ignore dead players, but I have not changed the default and have made
the default the same for IsAssistHealOfIndex() and
IsAssistRangedDpsOfIndex(), since I don't know the intent of the
pre-existing boss strats that use the functions.
3. Changed the names to IsAssistHealOfIndex() and
IsAssistRangedDpsOfIndex() so they parallel IsAssistTankOfIndex(), and
made corresponding changes in the few boss strats that use the
functions.

Also, note that the functions _do _not_ exclude real players. I think
there are arguments for and against excluding real players. A fourth
parameter for this could be useful, but I've not made any change in that
regard.
2026-01-24 21:26:49 +01:00