Commit Graph

2370 Commits

Author SHA1 Message Date
Keleborn
83c6977de5 Refactor guild managment into a singleton (#1913)
The idea is to centralize the creation, assignment, and management of
bot guilds into a single class that can be referenced.

The way this is intended to work.

when the manager is created, if the config option to delete guilds is
set, then it deletes all bot guilds.

On startup 
1. Load all guild names from database. Shuffle keys for some
randomization.
2. Load Guilds from database
3. For existing guilds, identify the guild faction, number of members,
and assess if the guild is 'full' based on the number of bots set in
config.
4. Determine if the leader of the guild is a real player based on the
leader account.
5. Mark any playerbot guild names as not available (false).

The validation process (2-5) is set to run once an hour. 

Guild Creation.
Now guild creation occurs on an as needed bases during the
initialization process. Previously, all of the guilds would be created
at once, and then randomly assigned.
When a bot is not in a guild during initialization, it will check if
there are any partially filled guilds of that bots faction where the bot
can be assigned to. If not, and the cache of bot guilds is less than the
set number in config, it will randomly return the available name. This
then goes to the CreateGuild function where the core guild manager
creates a guild, the guild emblem is set, and the cache updated.
If a bot is assigned to guild, but fails to join then it throws an
error.

Checking for real player guilds function now lives in the guild manager.

---------

Co-authored-by: bashermens <31279994+hermensbas@users.noreply.github.com>
2026-01-03 15:15:28 +01:00
Revision
686fe513b2 Removed strategies for Naxxramas until they can be rewritten without core changes (#1961)
Merging this isn't required but rather to provide an option to core
changes.

The scripts can be written from scratch when someone feels like doing it
without touching the core.

This shouldn't be merged unless
https://github.com/mod-playerbots/azerothcore-wotlk/pull/130 is merged
too.
2026-01-03 14:50:35 +01:00
Revision
61402e83a1 Fixed filename (#1963)
Added missing underscores to the filename
2026-01-03 14:47:31 +01:00
Crow
b16789fa54 Remove "potion" strategy from arenas + code cleanups (#1922)
Lines 481 through 484 are the only substantive changes. Bots were having
the potion strategy added in arenas, and since potions are not allowed
in arenas, this caused them to lock up and attempt to repeatedly drink
potions when under the applicable health or mana trigger thresholds. Now
they won't have the potion strategy in arenas.

Otherwise, I noticed a bunch of magic numbers for spec tabs and so went
ahead and did some refactoring:
1. All references to spec tab numbers now use the appropriate constant
name.
2. A bunch of extra braces were deleted.
3. DEATHKNIGHT_TAB was changed to DEATH_KNIGHT_TAB, and
HUNTER_TAB_BEASTMASTERY was changed to HUNTER_TAB_BEAST_MASTERY, to
reflect the correct names of the class and spec.
4. Deleted some comments that were clearly unneeded. There's much more
that can be cleaned up, and probably the entire logic sequence for
adding/removing strategies in AiFactory.cpp can be redone, but that's
above my pay grade.
2025-12-30 21:17:14 +01:00
BeardBear
8f638b6a66 Add secure login handling for playerbots (#1953)
Introduces PlayerbotsSecureLoginServerScript to handle secure login
scenarios for playerbots. Ensures that if a playerbot is already online
when a login is attempted, it is properly logged out before allowing the
new session. Registers the new script in the Playerbots initialization.
2025-12-30 21:13:36 +01:00
Keleborn
33f5e733dc feat. Enable bots to respond to GM messages. (#1909)
I found an existing config option that allows bots to speak without a
master, and extended its use so that protected commands (nc, co) are
taken from a bot by GM players. This is primarily a debugging tool and
shouldnt be on generally.

My testing of this is the following. 
With the option off, no error is seen, but no text output is shown. 

With the option on 
GM accounts (Whether GM is on or off) will respond to nc and co commands
by just saying the output directly. Strategies can be changed by GMs for
bots whom they are not masters for (Note, im pretty sure that a GM could
change the strategies even before this change, you just couldnt see the
output of that.)

For non GM characters you get "Invite me to your group first" with the
option on/off.
2025-12-30 00:53:37 +01:00
Keleborn
9917863ca1 Feat. Add Fishing action and fish with master. (#1433)
### Update :Thank you to @notOrrytrout from prompting me to work on
this. Its been a huge learning experience.

With @notOrrytrout I started working on enabling bot fishing with
master, but also on their own.
The first commit didnt crash, showing that it was possible to have a bot
cast when master does. Currently it compiles but crashes when you try to
fish with a bot in the group, whether the bot has fishing or not. It
makes me think that the check in FishingValues is broken somehow, but I
cant figure out how.

---------

Co-authored-by: bash <31279994+hermensbas@users.noreply.github.com>
2025-12-27 19:50:18 +01:00
bashermens
2317652d72 Full revert: no xp bot when master has xp disabled (#1948)
Will reimplement the feature later in time.
2025-12-25 03:00:21 +01:00
bashermens
1fcd6c5cda Quickfix: performance problems (XP gain when master has XP turned off) (#1947)
Disable bot XP gain when master has XP turned off feature has a big
performance impact.

Instead of reverting placed back to original code before the feature
PR's for now as quickfix
2025-12-25 02:07:59 +01:00
privatecore
88016789ba Quick fix for CMSG_FORCE_MOVE_ROOT_ACK and CMSG_FORCE_MOVE_UNROOT_ACK (#1937)
**Original issue:**
https://github.com/mod-playerbots/mod-playerbots/issues/1902
**Original cause:** charmed bot (with lost client control) got rooted at
the same time.

**How to reproduce:**
1. Spawn creatures 11350 (x3) and 11830 (x3) using the command: `.npc
add <entry>` in a quiet place.
2. Create any party with random bots or alt bots (should be 60-65
levels), make sure there is at least one healer.
3. Set the healer's mana to a high value, like 100M, using command:
`.mod mana <value>`.
4. Start the fight while continuously respawning creatures with: `.resp
all`.
5. When console starts to spam 'heartbeat' messages, check your party
members' movement flags to identify which one has `MOVEMENTFLAG_ROOT`
0x00000800 (2048) using the command: `.debug move`.

This PR will not fix ALL 'heartbeat' issues, as
`ServerFacade::SetFacingTo` still sends `SendMovementFlagUpdate` while
bots can have the `MOVEMENTFLAG_ROOT` flag.
2025-12-25 00:01:42 +01:00
bashermens
6be860c967 [Stability] Various crash fixes based on Regrad fixes and crashlogs. (#1928)
These contains various fixes, fixes that have history worked one in past
more then once as person as group, aswell @Wishmaster117. But due
various reasons we had to drop them due priority or simply timewise.
These fixes have recollected again by @Regrad based on his crash logs.

Most crash logs we have, i am talking 30+ of them, to many to post here.
@Regrad running a larger server 100+ real players with bots, which means
he will walk into issues that most of us wont or are extremely difficult
to reproduce.

@Regrad used LLM to solve them based on crash log and mentioned his
server crashes almost disappeared, instead of redoing every single PR
and pull them apart. I tried to keep his bunch of changes together as
whole, reviewed them, some redone, verified again etc etc. This is not
how would normally do this. But since i want @Regrad being able to
confirm, we need this in a package as a whole. Pulling them apart in the
current situation is simply to much, to complicated in the verification
process.

So this PR is open and in my opinion has priority above others, but
@Regrad is only person who can give the green light for the
mod-playerbot changes for now.

I, we spend huge amount of time into these issues over last couple of
months. I will put other PR's on hold for abit.

---------

Signed-off-by: Engardium <regradius@gmail.com>
Co-authored-by: Engardium <regradius@gmail.com>
2025-12-24 13:24:29 +01:00
Alex Dcnh
9971622093 Core - Fixe raid markers persists after target dead causes issue with bots running off (#1845)
This PR fixes #1833 where bots could keep chasing a raid target icon
(usually skull) across very large distances or even different maps after
the mark was set. It replaces the previous attempt with a simpler design
that keeps values generic and moves context logic into triggers/actions.

Changes

- RtiTargetValue now ignores RTI targets that are farther than
sPlayerbotAIConfig->sightDistance from the bot or the master (same map
only), while still using AttackersValue::IsValidTarget and LOS checks.
- AttackersValue is reverted to its original behavior (no special RTI +
IsInCombat logic).
- RTI triggers only react to "rti target" in combat, as suggested in
review (“that condition should be check in trigger…”).
- AttackRtiTargetAction keeps a small local fallback: if "rti target" is
null, it resolves the raid icon directly from the group so chat commands
like “attack rti target” still work, including out of combat.

Behavior

- Bots no longer run across the world to chase a stale skull far away
from the group.
- When the group comes back near the marked mob (within sight distance),
the skull is again used as a normal focus hint.
- Automatic RTI behavior is limited to combat via triggers, while
explicit chat commands still work out of combat.

Testing

- Marked a mob with skull, killed it, moved far away / changed zone,
then let it respawn: bots did not chase it from afar.
- In a normal dungeon/raid pack, bots still focus skull in combat.
- Passing near a previously marked mob: bots only react once it is back
within sight distance.

---------

Co-authored-by: Keleborn <22352763+Celandriel@users.noreply.github.com>
2025-12-23 20:42:29 +01:00
Crow
895df9b197 Magtheridon timer keys fix (#1936)
Same deal as Karazhan--changing map id to instance id for timer keys to
prevent conflicts from multiple groups (plus other tweaks with respect
to the timers). This strategy could use a broader refactor, but that's
for another day--this PR is just to address the timer logic.
2025-12-23 09:04:36 +01:00
Crow
467b63b840 Fix Karazhan timers (#1926)
I'm not 100% sure but think that the current implementation of timers
for Attumen, Netherspite, and Nightbane with the instance's map id as
the key would result in the timers being shared across separate raids
running the instance at the same time. I've refactored to use the
instance id as the key for all shared timers so to the extent this was
an issue, it shouldn't be anymore.

I also made some minor tweaks to the tank positioning for BBW and
Curator as I noticed there was some weirdness in the logic that I
neglected to address with the refactor.
2025-12-21 21:40:19 +01:00
HennyWilly
66f5f597bb Re-enable no-xp-feature with better checks (#1935)
The feature `Disable bot XP gain when master has XP turned off` (#1910)
was unintentionally disabled in #1929.
This PR re-enables it with better checks in order to prevent crashes
when playing together with the individual progression module.
2025-12-21 21:28:39 +01:00
privatecore
cafbd4681e Hotfix after recent changes related to the refactoring of IsMovingAllowed (#1933)
Hotfix for the issue where bots can't enter/move on transports
(elevators, zeppelins, ships, etc.). Change the logic to determine if
bot is on a vehicle. According to the current implementation in
AzerothCore, `GetVehicle()` is the most common approach for this.
Additionally, other checks related to the vehicle: `GetBase`, `IsAlive`,
`GetVehicleInfo`, and `GetSeatForPassenger` -- are processed inside
`IsInVehicle`.

This should be more than enough to determine if the bot is on a vehicle
and can/cant control it.

Issue: https://github.com/mod-playerbots/mod-playerbots/issues/1927
2025-12-20 23:51:32 +01:00
bashermens
f5c84ee7ff server_crash_fix: OnPlayerGiveXP (#1929)
[fef0ed4072c8_worldserver.exe_.18-12_23-30-44.txt](https://github.com/user-attachments/files/24258638/fef0ed4072c8_worldserver.exe_.18-12_23-30-44.txt)

- Just added common logic and defense coding
- Optimized isRandombot while at it

Just for clarification i am aware the trigger of bug lies with the
progression mod. Regardless it should not happen.
2025-12-19 23:08:18 +01:00
Keleborn
b6f882886d FixListSpellsWithCache (#1931)
This is based off of Wishmasters rewrite of spell PR. #1912 and #1843,
and partial #1918
I created a new cache singleton with the required code to reference as
needed.
I clarified some variable names for additional clarity in how they
functioned.

This requires a wiki update to better describe the functionality that
was already defined in code.

Commands
Spells - Returns all spells
Spells <Profession> Returns only the spells in that profession
+<profession> Returns only the recipies that the bot has materials to
craft
<profession> `x - y` Craftable items within those levels
<profession> <slot> e.g. Chest, returns craftable items within that
slot.

Its messy whether what combinations work for commands, but fixing that
will come when bot professions are enabled.

Edit:
To test you can teach a bot various professions by going to a trainer
with them.
Using gm command .setskill you increase their skill level and with
maintenance teach the commands.

From wishmasters PR he detailed various commands to test

spells
spells first aid
spells tailoring
spells 20-40
spells +tailoring
spells head

---------

Co-authored-by: Wishmaster117 <140754794+Wishmaster117@users.noreply.github.com>
2025-12-19 23:08:01 +01:00
HennyWilly
c1222da8b0 Disable bot XP gain when master has XP turned off (#1910)
Addresses #1846

This PR disables XP gain for bots whose non-bot master has disabled XP
gain via an "Experience Eliminator" NPC.

If the current master has disabled XP gain, randombots in the group and
addclass-bots belonging to the player won't gain XP.
Randombots not grouped with a player will continue to gain XP as normal.

Discussed points:
- `Should this feature only be enabled via a new configuration value?`:
Comments currently tend towards no config value.

Open points:
- Should bots be allowed to gain XP until they reach the player's level,
even if the player has disabled XP gain?
2025-12-16 22:23:34 +01:00
NoxMax
00cb177c86 Fix: Allow bots to duel in PVP prohibited areas (#1906)
Noticed that if you ask a bot to duel in a PVP prohibited area, it will
accept, and do nothing. I thought about making the bot reject the
request, but if you (the real player) want to duel with it, the duel
should happen. This is just a minor fix to allow bots to duel if you ask
them to in such areas.

Tested with bots in party, random bots of the same faction, and random
bots of the opposite faction. All behaved the same before and after fix.
An example place to test is Zim'Torga in Zul'Drak which is by default is
a PVP prohibited area.

- Before fix, you challenge a bot, they accept and turn red, then they
either just stay where they are or wander off.

- After fix, bot attacks you within the PVP prohibited area when the
duel starts.
2025-12-16 18:38:50 +01:00
privatecore
5f697e806e Rerwite is moving allowed logic + fix root flag heartbeat spam (#1908)
Okay, what have been done:

1. Fix heartbeat spam for root flag: check against `MOVEMENTFLAG_ROOT`
flag (`IsRooted`) instead of `HasRootAura`.
2. Rewrite `IsMovingAllowed` - place checks from most common to the
rarest.
3. Remove unnecessary checks: `HasRootAura`, `HasConfuseAura`,
`HasStunAura` - handled by AuraEffects and set unit state flags
`UNIT_STATE_ROOT`, `UNIT_STATE_CONFUSED`, `UNIT_STATE_STUNNED` -
`UNIT_STATE_LOST_CONTROL` already handles confused and stunned (rooted
checked with `IsRooted` method).
4. Combine traveling state checks for taxi flights:
`UNIT_STATE_IN_FLIGHT` + MM flag `FLIGHT_MOTION_TYPE`.
5. Simplify check against being in vehicle: use
`MOVEMENTFLAG_ONTRANSPORT` as an indicator that the unit is in the
vehicle.

Also, update `UpdateMovementState` method with simplified checks and the
updated logic (common > rare).

This should fix issues:
https://github.com/mod-playerbots/mod-playerbots/issues/1903 and
https://github.com/mod-playerbots/mod-playerbots/issues/1902

NOTE: The `PlayerbotAI` class has a method `CanMove` with the same
checks, but this method is only used once in the code. We should decide
how to properly check if the bot can move or not:

1. Place all logic into `IsMovingAllowed` and drop `CanMove`.
2. Place all logic into `CanMove` and use it inside `IsMovingAllowed`.
3. Use them for different approaches: 
- `CanMove`: simple checks (unit flags, CC state, death state, travel
state, vehicle state);
- `IsMovingAllowed`: everything from `CanMove` + MM flags checks (not
sure about rooted since it still checks for movement flags...).
2025-12-15 15:32:49 +01:00
Crow
934e73ae20 Add Ogri'la and Blackwind Landing to PvP Restricted Areas (#1915)
This PR adds a couple of neutral quest hubs in Outland to PvP restricted
areas (and makes a couple of very minor formatting fixes to the Karazhan
files).

3786: Ogri'la
3973: Blackwind Landing (Sha'tari Skyguard quest hub in Skettis)
2025-12-15 15:26:38 +01:00
Crow
f4b4d8967f Karazhan Refactor + Nightbane Strategy (#1847)
This PR completely refactors the Karazhan raid strategies to clean up
the code and polish up/introduce new strategies, including for
Nightbane.

General changes with respect to the code:
- Moved gating checks for action methods to triggers instead of relying
on isUseful functions
- Got rid of the nonsensical helper class I made and switched to a
helper namespace
- Broke up some longer action classes into separate methods and/or
private members
- Deleted/consolidated some excess code
- Made greater use of early returns
- Renamed methods, multipliers, and triggers to make them easier to
understand
- Generally made edits to conform with AC code standards

Below are the implemented strategies. I’m including all of them, not
just new/modified ones, because I don’t think the first set of
strategies was ever tested. So each boss could probably use complete
testing.

### **Trash**

I added strategies for a trash mob that I find particularly annoying:
- Mana Warp: These are, IMO, the most annoying trash mobs in Karazhan.
They blow up when low on health, and having two blow up in quick
succession is enough to take out a decent chunk of your raid. The
strategy directs bots to use pretty much every stun in the book on Mana
Warps when they’re low on HP, which is the only way to prevent the
explosion.

### **Attumen**

- During the first phase, bots will focus on Midnight (taking either
Midnight or Attumen to 25% starts the next phase). When Attumen spawns,
the assist tank will pick him up and move him away so that bots don’t
get cleaved.
- When Attumen mounts Midnight, starting phase 2, threat is wiped, and
bots will pause DPS for a few seconds to allow the main tank to get
aggro. All bots, other than the main tank and any bot that pulls aggro,
will stack behind Attumen (~6 yards for ranged so Hunters can still
attack).

### **Moroes**

- As before, bots will mark and prioritize adds and the boss in the
recommended kill order: Dorothea, Catriona, Keira, Rafe, Robin, Crispin,
and Moroes. In practice, the enemies will probably be stacked up, and
the bots will AoE them down in accordance with their typical AoE
strategies, but classes without AoE capabilities should still prioritize
the skull.
- Based on testing feedback, added a method for the main tank to
prioritize Moroes

### **Maiden of Virtue**

I’ve made only minor changes to Revision’s original strategy here. 

- The tank with aggro will position Maiden in the middle of the room and
move her to a healer when Repentance is cast so that the Holy Ground
will break the healer’s stun.
- Ranged bots have assigned positions between the columns around the
middle of the room (to prevent chain damage from Holy Wrath).

### **The Big Bad Wolf**

- The tank with aggro brings the boss to the front left of the stage. 
- If a bot gets turned into Little Red Riding Hood, it will run around
the stage in a counter-clockwise rectangle until the transformation
fades. I tweaked this strategy a bit; it's still not perfect, but it
works better than before.

### **Romulo and Julianne**

There are no substantive changes to this strategy. As before, in phase
3, when both bosses are active, the bots switch back-and-forth between
the bosses by alternating the skull icon based on which boss has lower
HP (10% differential).

### **The Wizard of Oz**

There are no substantive changes to this strategy. As before, bots mark
the bosses with a skull icon in their recommended kill order: Dorothee,
Tito (assuming he spawns before you kill Dorothee), Roar, Strawman,
Tinhead, and the Crone. Additionally, Mages will spam Scorch on Strawman
to daze him.

### **The Curator**

- The tank will drag the boss to a fixed spot down the hallway. Ranged
bots will spread out to avoid chain damage from Arcing Sear, and bots
will mark Astral Flares with the skull icon to prioritize them down.
- Those strategies already existed, but now I made the assist tank also
focus on the boss to try to stay second in aggro and therefore absorb
Hateful Bolts.
- Added a multiplier to save Bloodlust/Heroism until Evocation.

### **Terestian Illhoof**

There are no substantive changes to this strategy. The bots will mark
targets with the skull icon in the following order: Demonic Chains,
Kil'rek, and Illhoof.

### **Shade of Aran**
I redid the strategies a bit, and I think (hope) they work better.

- Flame Wreath: Bots will stop moving until the aura fades. There is a
bug in which Flame Wreath will sometimes persist long beyond its
supposed 20-second duration. If Aran casts Arcane Explosion during this
time, you will almost certainly wipe, so that’s frustrating. I made it
so that bots will stay in place still and eat the Arcane Explosion
because it’s the lesser of two evils, and if you are overgeared, you may
be able to survive. In the previous strategy, bots would stop actions
entirely, but now they should keep attacking/casting without moving.
- Arcane Explosion: No substantive changes here--bots will run out
immediately and stay out of range until the cast finishes.
- Conjured Elementals: No substantive changes here--they will be marked
one-by-one by the skull icon, except that the marking will skip any
elemental that is banished.
- Ranged Positioning: I redid this strategy. Ranged bots will now
maintain a distance between 11 and 15 yards from the boss. This keeps
them out of the 10-yard radius in which Aran silences while also keeping
them from getting too far away and getting stuck in the alcoves.

### **Netherspite**

I significantly refactored the action methods here, but substantively
the original strategy remains mostly intact.

- Red (Tank) Beam: One tank will be assigned to block the beam for each
Portal Phase. The assigned tank will dance in and out of the beam (5
seconds in, 5 seconds out). Tanks intentionally do not avoid Void Zones
(it was the lesser of two evils for them to take that damage vs. trying
to dynamically avoid them, moving the boss, and possibly getting
everybody out of position.
- Blue (DPS) Beam: DPS other than Rogues and Warriors are eligible to be
assigned (one-by-one) to block this beam. When the assigned blocker
reaches 25 stacks of the debuff, they will leave the beam, and the next
assigned blocker will take their place. If a Void Zone drops under the
assigned blocker, the bot will move along the beam to get out of the
Void Zone so that they do not stop blocking.
- Green (Healer) Beam: This works the same way as the Blue Beam, except
that eligible blockers are healers, Rogues, and DPS Warriors. Healers
that are assigned to block will swap in the same way as Blue Beam
blockers. If a Rogue or DPS Warrior is the assigned blocker, however,
they will stand in the beam for the entire Portal Phase since they do
not suffer any adverse effects from the beam. In this PR, I made the
strategy prioritize Rogues and DPS Warriors over healers to try to avoid
the need for bots to swap (and to avoid the irritating scenario in which
a healer would block the beam for the first half of a phase and then tag
in a Rogue or DPS Warrior, which would be wasted by blocking only half
of a phase).
- Non-Blockers: They will stay at least 5 yards away from each beam
until called to be an assigned blocker. They will also avoid Void Zones.
- Banish Phase: The only strategy I implemented was for bots to avoid
residual Void Zones from the Portal Phase.
- Phase Transitions: Bots should pause DPS at the beginning of the
encounter and whenever Netherspite transitions back from the Banish
Phase to the Portal Phase (which is an aggro reset). Note that this
doesn't wipe DOTs, and there's not much I can do about that.

### **Prince Malchezaar**

The action methods are significantly refactored, but the strategy
substantively is not changed very much.

- Bots will maintain distance from Infernals. The tank has a larger
avoidance radius to give DPS a little bit of margin to work with.
Depending on Infernal placement, it is possible for bots to get stuck in
some bad positions. In that case, the best solution is to put them on
“flee” and lead them to a better position.
- Bots that get Enfeebled will run out of Shadow Nova range. They should
pick a path that does not cross within any Infernal's Hellfire radius.
- Added a multiplier to save Bloodlust/Heroism until Phase 3.

### **Nightbane**

**Disclaimer**: Bots are terrible at this encounter, in large part
because the map is awful (even before the recent Core changes). So the
strategies are not ideal because they need to operate within the bots’
limitations. I STRONGLY suggest you clear the entire Livery Stables
(including the upper level) because the mobs in them have a high risk of
pulling through the floor of the Master’s Terrace. Ideally, you should
clear out the Scullery too.

The strategy uses waypoints toward the Northeastern door to the Master’s
Terrace. I tried several different locations, and that worked best for
me based on where Nightbane lands (note that he has a different landing
spot for the encounter start vs. the start subsequent ground phases).

- Ground Phase, main tank: The main tank uses two waypoints after it
picks up the boss—the movement pattern should be kind of like a reverse
checkmark, where the tank moves back along the inner edge of the
terrace, then pivots and moves at a bit of an angle to the outer edge. I
did this as a way to get the tank to face Nightbane sideways across the
terrace, which is how he’s supposed to be tanked. The main tank will not
get out of Charred Earth. This is intended. The tank cannot move
dynamically enough to avoid it while also not turning the boss and
wiping the raid.
- Ground phase, ranged: Ranged bots rotate between three waypoints. They
start stacked at the same position. If Charred Earth is dropped on that
position, the bots will rotate to the second position. If Charred Earth
is dropped on that position, they will rotate to the third position. The
maximum number of Charred Earths that can be active is two, so if one is
dropped on the third position, the ranged bots should rotate back to the
first position.
- Ground Phase, other melee: Melee bots have no coded Charred Earth
avoidance strategy. They do decently enough with the general “avoid aoe”
strategy.
- Flight Phase: Bots move to Nightbane’s flight position—Nightbane is
bugged and cannot be attacked in the air in AC, but all bots still need
to stay near him or he will wipe the raid with Fireball Barrage. Bots
stack on the same position; when Rain of Bones is cast (one time,
snapshotted on the target’s location), all bots will move away to a
second nearby position. They will then kill the Restless Skeletons. The
Flight Phase lasts for 45 seconds, but Nightbane emotes after 35 seconds
and goes to land—during the final 10-second period, bots are freed from
all strategies and will follow the master. You need to lead them back to
the Northeastern part of the terrace before Nightbane lands so that bots
can get immediately positioned when he lands.
- Phase Changes: Whenever Nightbane lands, bots should pause DPS for the
main tank to get aggro.
- Managing bots/pets: During the Flight Phase, bots and pets have a
tendency to chase Nightbane outside of the boundaries of the map and
pull mobs from other parts of the instance as well as cause Restless
Skeletons to spawn out of bounds (and then further cause bots/pets to go
out of bounds to attack the skeletons). The strategy should solve for
this, but if there are still issues, it should be noted. My resolution
was to implement the following: (1) when Nightbane takes flight, bots
stop attacking and mark him with the moon icon, and Hunters and Warlocks
put pets on passive and recall them (they will put pets on defensive
again when Nightbane lands), and (2) all temporary pets are disabled for
the duration of the fight (Water Elementals, Shaman wolves, Druid
treants, etc.).

**Known Issues:**

- The approach to getting Nightbane to turn sideways is not always spot
on since it’s a workaround to account for what should be dynamic
movement. He can end up at a bit of an angle. I’ve tweaked the positions
such that if he is at an angle, it should not be a situation in which
any ranged position is exposed to Smoldering Breath or Cleave. That does
increase the risk that poor positioning may expose a ranged position to
Tail Sweep. This is obviously suboptimal, but that attack is much more
survivable.
- Ranged bots move between the three waypoints by reading the presence
of the Charred Earth aura on themselves. Sometimes, a bot may reach the
next waypoint with the Charred Earth aura from the previous waypoint
still on them (depending on timing of ticks), in which case the bot will
keep moving to the next waypoint. This can cause an issue in which the
ranged group gets split. So you could have Charred Earth dropped on
position 1, and some ranged bots will go to position 2 but others will
go to position 3, and then if the second Charred Earth is dropped on
position 3, the bots at position 3 will move back to position 1 (which
is still in Charred Earth) before then moving to position 2. Balancing
spacing between waypoints, positioning with respect to the boss, line of
sight, and maximum distance is very difficult to do. I messed with the
positioning a lot, and I am not sure if this possibility cannot be
entirely avoided without creating other issues. I have at least reached
a result in which I have not seen any bots cycle indefinitely (though if
testing observes this, it is obviously a problem).

Ultimately, I wouldn’t say I’m totally satisfied with the strategy.
Wipes are still possible on account of bad RNG. But I think it does make
the fight a lot more manageable, as it is a fight that is very difficult
with IP nerfs in the absence of any strategy. Previously, I needed to
bring 3 healers, and they would still all be out of mana by the first
Flight Phase and reliant on MP5 for the remainder of the fight, and I
would wipe multiple times before a kill.
2025-12-10 21:08:25 +01:00
Nicolas Lebacq
910b8a9c53 fix: Made bots roll in a more reasonable time on group loots. (#1857)
# Description

This PR changes the way loot rolls are being evaluated.

It puts a maximum priority on the loot action so it does not hang for so
long.
2025-12-09 10:29:57 -08:00
Tecc
bb569b4d39 Fix: Arena - PersonalRating and MMR issue for bot teams (#1789)
# Fix: Arena PersonalRating and MMR issue for bot teams

## Problem
Bot arena teams are created with artificial random ratings (1000-2000
range), but when bots join these teams, their personal ratings and
matchmaker ratings (MMR) use default config values instead of being
adjusted to match the team's artificial rating. This causes matchmaking
issues since the system uses personal ratings for queue calculations.

## Root Cause
The issue occurred because `SetRatingForAll()` was called during team
creation but only affected the captain. When additional bots were added
later via `AddMember()`, they received default values from
`CONFIG_ARENA_START_PERSONAL_RATING` and
`CONFIG_ARENA_START_MATCHMAKER_RATING` instead of values appropriate for
the team's artificial rating.

## Solution
After bots are added to arena teams, the fix:

1. Uses `SetRatingForAll()` to align all personal ratings with team
rating
2. Adjusts matchmaker ratings based on team context vs default
configuration
3. Saves changes to both database tables with proper data types

## Impact
- Personal ratings now match team ratings for artificial bot teams
- MMR values are adjusted for artificial bot team ratings instead of
using default config values
- Arena matchmaking functions correctly for bot teams with random
ratings
- Only affects new arena team assignments after deployment
- Existing player teams and normal config behavior are unaffected

## Manual Database Update

For existing installations, the provided SQL script could be used to fix
bot teams created before this patch.

### Update personal rating
```sql
UPDATE arena_team_member atm
JOIN arena_team at ON atm.arenaTeamId = at.arenaTeamId
JOIN characters c ON atm.guid = c.guid
JOIN auth.account a ON c.account = a.id
SET atm.personalRating = at.rating
WHERE a.username LIKE 'rndbot%'
  AND atm.personalRating != at.rating;
```

### Update MMR for existing entries
```sql
UPDATE character_arena_stats cas
JOIN characters c ON cas.guid = c.guid
JOIN auth.account a ON c.account = a.id
JOIN arena_team_member atm ON cas.guid = atm.guid
JOIN arena_team at ON atm.arenaTeamId = at.arenaTeamId
SET
    cas.matchMakerRating = GREATEST(at.rating, 1500),  -- Use team rating or 1500 minimum
    cas.maxMMR = GREATEST(cas.maxMMR, cas.matchMakerRating)  -- Update maxMMR if needed
WHERE
    a.username LIKE '%rndbot%'
    AND (
        -- Update if MMR doesn't match team context
        (at.rating > 1500 AND cas.matchMakerRating < at.rating) OR
        (at.rating <= 1500 AND cas.matchMakerRating != 1500) OR
        cas.matchMakerRating IS NULL
    )
    AND (
        -- Map arena team type to character_arena_stats slot
        (at.type = 2 AND cas.slot = 0) OR  -- 2v2 teams use slot 0
        (at.type = 3 AND cas.slot = 1) OR  -- 3v3 teams use slot 1
        (at.type = 5 AND cas.slot = 2)     -- 5v5 teams use slot 2
    );
```

### Insert missing MMR records for bots without character_arena_stats
entries
```sql
INSERT INTO character_arena_stats (guid, slot, matchMakerRating, maxMMR)
SELECT
    atm.guid,
    CASE
        WHEN at.type = 2 THEN 0  -- 2v2 -> slot 0
        WHEN at.type = 3 THEN 1  -- 3v3 -> slot 1
        WHEN at.type = 5 THEN 2  -- 5v5 -> slot 2
        ELSE 0
    END as slot,
    GREATEST(at.rating, 1500) as matchMakerRating,
    GREATEST(at.rating, 1500) as maxMMR
FROM arena_team_member atm
JOIN arena_team at ON atm.arenaTeamId = at.arenaTeamId
JOIN characters c ON atm.guid = c.guid
JOIN auth.account a ON c.account = a.id
WHERE
    a.username LIKE '%rndbot%'
    AND NOT EXISTS (
        SELECT 1 FROM character_arena_stats cas2
        WHERE cas2.guid = atm.guid
        AND cas2.slot = CASE
            WHEN at.type = 2 THEN 0
            WHEN at.type = 3 THEN 1
            WHEN at.type = 5 THEN 2
            ELSE 0
        END
    )
    AND at.rating > 0;
```

## Related issues

Fixes: #1787 
Fixes: #1800


## Verification Queries

### Query 1: Check personal rating alignment
```sql
SELECT
    'Personal Rating Check' as check_type,
    COUNT(*) as total_bot_members,
    SUM(CASE WHEN atm.personalRating = at.rating THEN 1 ELSE 0 END) as correct_ratings,
    SUM(CASE WHEN atm.personalRating != at.rating THEN 1 ELSE 0 END) as incorrect_ratings,
    ROUND(AVG(at.rating), 2) as avg_team_rating,
    ROUND(AVG(atm.personalRating), 2) as avg_personal_rating
FROM arena_team_member atm
JOIN arena_team at ON atm.arenaTeamId = at.arenaTeamId
JOIN characters c ON atm.guid = c.guid
JOIN auth.account a ON c.account = a.id
WHERE
    a.username LIKE '%rndbot%';
```

### Query 2: Check MMR alignment
```sql
SELECT
    'MMR Alignment Check' as check_type,
    COUNT(*) as total_mmr_records,
    SUM(CASE
        WHEN at.rating > 1500 AND cas.matchMakerRating >= at.rating THEN 1
        WHEN at.rating <= 1500 AND cas.matchMakerRating = 1500 THEN 1
        ELSE 0
    END) as correct_mmr,
    SUM(CASE
        WHEN at.rating > 1500 AND cas.matchMakerRating < at.rating THEN 1
        WHEN at.rating <= 1500 AND cas.matchMakerRating != 1500 THEN 1
        ELSE 0
    END) as incorrect_mmr,
    ROUND(AVG(at.rating), 2) as avg_team_rating,
    ROUND(AVG(cas.matchMakerRating), 2) as avg_mmr,
    ROUND(AVG(cas.maxMMR), 2) as avg_max_mmr
FROM arena_team_member atm
JOIN arena_team at ON atm.arenaTeamId = at.arenaTeamId
JOIN characters c ON atm.guid = c.guid
JOIN auth.account a ON c.account = a.id
JOIN character_arena_stats cas ON atm.guid = cas.guid
WHERE
    a.username LIKE '%rndbot%'
    AND (
        (at.type = 2 AND cas.slot = 0) OR
        (at.type = 3 AND cas.slot = 1) OR
        (at.type = 5 AND cas.slot = 2)
    );
```

### Query 3: Detailed team-by-team analysis
```sql
SELECT
    at.arenaTeamId,
    at.name as team_name,
    at.type as team_type,
    at.rating as team_rating,
    COUNT(atm.guid) as member_count,
    GROUP_CONCAT(DISTINCT atm.personalRating) as personal_ratings,
    GROUP_CONCAT(DISTINCT cas.matchMakerRating) as mmr_values,
    CASE
        WHEN COUNT(DISTINCT atm.personalRating) = 1 AND MIN(atm.personalRating) = at.rating THEN 'OK'
        ELSE 'MISMATCH'
    END as personal_rating_status,
    CASE
        WHEN COUNT(DISTINCT cas.matchMakerRating) = 1 AND (
            (at.rating > 1500 AND MIN(cas.matchMakerRating) >= at.rating) OR
            (at.rating <= 1500 AND MIN(cas.matchMakerRating) = 1500)
        ) THEN 'OK'
        ELSE 'MISMATCH'
    END as mmr_status
FROM arena_team at
JOIN arena_team_member atm ON at.arenaTeamId = atm.arenaTeamId
JOIN characters c ON atm.guid = c.guid
JOIN auth.account a ON c.account = a.id
LEFT JOIN character_arena_stats cas ON atm.guid = cas.guid
    AND cas.slot = CASE
        WHEN at.type = 2 THEN 0
        WHEN at.type = 3 THEN 1
        WHEN at.type = 5 THEN 2
        ELSE 0
    END
WHERE
    a.username LIKE '%rndbot%'
GROUP BY at.arenaTeamId, at.name, at.type, at.rating
ORDER BY at.rating DESC;
```
2025-12-08 12:35:06 +01:00
NoxMax
dde16674c3 Fix: Stop pets from fighting in PVP prohibited zones (#1829)
Stripped down version of #1818. No new features. Refactors
IsPossibleTarget in AttackersValue.cpp to a better style and makes sure
pets don't attack in prohibited zones.

Testing:
Confirmed that aggro pets no longer attack in PVP prohibited areas, but
still do outside them. Zim'Torga in Zul'Drak is a good example to test
this (ID 4323). Lookout for death knights with a Risen Ally
(uncontrolled and naturally aggro) now they respect PVP prohibition like
their master.

Note: If you manually teleport a bot that is in mid combat to a PVP
prohibited area, its aggro pet might still attack, because its master is
still in combat strategy. Otherwise the pet will not attack if its
master has switched to non-combat.
2025-12-08 12:34:16 +01:00
HennyWilly
e5b2791053 Improve Molten Core Strategy (#1852)
This is my first attempt of implementing playerbot strategies.

A team of 40 can steamroll Molten Core relatively easy, even with lower
item levels.
Regardless, this PR adds resistance triggers and actions to mitigate
some damage.
Additionally, improvements were made for the encounters with Garr, Baron
Geddon, Shazzrah and Golemagg.
A short summary per boss is listed below.
All planned features are included, but feedback is of course
appreciated.

### Lucifron
- Shadow resistance: mitigate damage from [Impending
Doom](https://www.wowhead.com/classic/spell=19702/impending-doom) and
[Shadow
Shock](https://www.wowhead.com/classic/spell=19460/shadow-shock).

### Magmadar
- Fire resistance: mitigate damage from [Lava
Bomb](https://www.wowhead.com/classic/spell=19411/lava-bomb) and [Magma
Spit](https://www.wowhead.com/classic/spell=19450/magma-spit).
- Like King Dred and the fraction commander (Nexus), this fight might
profit from an anti-fear strategy in order to counter
[Panic](https://www.wowhead.com/classic/spell=19408/panic). Not
implemented here.

### Gehennas
- Shadow resistance: mitigate damage from [Shadow
Bolt](https://www.wowhead.com/classic/spell=19728/shadow-bolt) and
increase the chance to resist [Gehennas'
Curse](https://www.wowhead.com/classic/spell=19716/gehennas-curse).

### Garr
- Fire resistance: mitigate damage from the Firesworn adds
([Immolate](https://www.wowhead.com/classic/spell=20294/immolate) and
[Eruption](https://www.wowhead.com/classic/spell=19497/eruption)).
- Disabled dps aoe abilities via multiplier. This one is important
because multiple exploding adds at once might delete bots rather
quick...

### Baron Geddon
- Refactored the existing strategy.
- Fire resistance: mitigate damage from [Ignite
Mana](https://www.wowhead.com/classic/spell=19659/ignite-mana),
[Inferno](https://www.wowhead.com/classic/spell=19695/inferno) and
[Living Bomb](https://www.wowhead.com/classic/spell=20475/living-bomb).
- Better Inferno handling: Before moving away, bots stop attacking and
interrupt their spells. Additionally, the new multiplier prevents bots
from running back to Geddon while Inferno is still active.

### Shazzrah
- Ranged bots now position themselves in a sweet spot that prevents them
from getting hit with [Arcane
Explosion](https://www.wowhead.com/classic/spell=19712/arcane-explosion)
but still close enough to dps and heal.

### Sulfuron Harbinger
- Fire resistance: mitigate damage from [Hand of
Ragnaros](https://www.wowhead.com/classic/spell=19780/hand-of-ragnaros)
and [Immolate](https://www.wowhead.com/classic/spell=20294/immolate). To
be fair, this one is quite negligible...

### Golemagg
- Fire resistance: mitigate damage from [Magma
Splash](https://www.wowhead.com/classic/spell=13880/magma-splash) and
[Pyroblast](https://www.wowhead.com/classic/spell=20228/pyroblast).
- Disabled dps aoe abilities via multiplier. Kind of a preference on my
side. Otherwise, the Core Ragers spam emotes about not wanting to die.

### Majordomo Executus
- Shadow resistance: mitigate damage from [Aegis of
Ragnaros](https://www.wowhead.com/classic/spell=20620/aegis-of-ragnaros),
[Shadow Shock](https://www.wowhead.com/classic/spell=20603/shadow-shock)
and [Shadow
Bolt](https://www.wowhead.com/classic/spell=21077/shadow-bolt). This one
is also negligible, TBF.

### Ragnaros
- Fire resistance: mitigate damage from [Wrath of
Ragnaros](https://www.wowhead.com/classic/spell=20566/wrath-of-ragnaros)
and [Lava
Burst](https://www.wowhead.com/classic/spell=21158/lava-burst).
2025-12-08 12:29:07 +01:00
Keleborn
353c29dfc4 Bug: Fix bots leaving LFG groups before master (#1876)
I removed bots checking if they should leave group every tick, and will
rely on the LeaveGroupFarAway action. I also increased the timer from 5
seconds to 20 seconds. No need to check this that often.
2025-12-08 12:25:40 +01:00
Keleborn
52c3e96641 Rename groupmaster to groupleader and related variables. (#1875)
Fix the naming conventions. 
Master should be reserved to identify a bots Master. 
groupleaders are not necessarily group masters and it should be clear
what the bot is looking for. (In most solo cases leader=master)
2025-12-03 13:25:01 +01:00
Crow
38e2d8584b Add missing break in ApplyInstanceStrategies (#1887)
Well, I hope nobody has tried Magtheridon lately. It looks like this got
inadvertently deleted during the merge.
2025-11-28 19:00:12 +01:00
Keleborn
d5dbc4ddd7 Hotfix: prevent server crash when whisper 'logout' (#1874)
Temp Hotfix to resolve #1870.
2025-11-24 21:49:55 +01:00
Keleborn
2424f73bc4 Core Merge PR - Replace OnPlayerChat with OnPlayerCanUseChat (#1838)
First stab at getting this working. Im not sure if Im missing something,
but it seemed to be a pretty simple change overall.

Based on testing the bots do respond to commands via whisper and group.

Edit: Relevant PR this addresses.

50f8f145d2 (diff-baadebd8cd1117ca48225f316a5ab3fd5fd55b20963394d302341147183db067)
2025-11-23 20:45:31 +01:00
Crow
cf743a186a Fix Wrong Misdirection Spell ID for Gruul's Lair and Magtheridon Strategies (#1867)
Lol oops.

Confirmed with logs/in-game that the prior one was wrong (and thus
always returning false) and current one is correct.
2025-11-23 10:06:19 +01:00
blinkysc
10213d8381 Add thread safety for group operations (#1816)
Fixes crashes and race conditions when bots perform group/guild/arena
operations by moving thread-unsafe code to world thread.

Potentially fixes #1124

## Changes

- Added operation queue system that runs in world thread
- Group operations (invite, remove, convert to raid, set leader) now
queued
- Arena formation refactored to use queue
- Guild operations changed to use packet queueing

## Testing

Set `MapUpdate.Threads` > 1 in worldserver.conf to enable multiple map
threads, then test:
- Group formation and disbanding
- Arena team formation
- Guild operations (invite, promote, demote, remove)

- Run with TSAN
cmake ../ \
  -DCMAKE_CXX_FLAGS="-fsanitize=thread -g -O1" \
  -DCMAKE_C_FLAGS="-fsanitize=thread -g -O1" \
  -DCMAKE_EXE_LINKER_FLAGS="-fsanitize=thread" \
  -DCMAKE_INSTALL_PREFIX=/path/to/install \
  -DCMAKE_BUILD_TYPE=RelWithDebInfo

build

export
TSAN_OPTIONS="log_path=tsan_report:halt_on_error=0:second_deadlock_stack=1"
./worldserver

The crashes/race conditions should no longer occur with concurrent map
threads.

## New Files

- `PlayerbotOperation.h` - Base class defining the operation interface
(Execute, IsValid, GetPriority)
- `PlayerbotOperations.h` - Concrete implementations:
GroupInviteOperation, GroupRemoveMemberOperation,
GroupConvertToRaidOperation, GroupSetLeaderOperation,
ArenaGroupFormationOperation
- `PlayerbotWorldThreadProcessor.h/cpp` - Singleton processor with
mutex-protected queue, processes operations in WorldScript::OnUpdate
hook, handles batch processing and validation

---------

Co-authored-by: blinkysc <blinkysc@users.noreply.github.com>
Co-authored-by: SaW <swerkhoven@outlook.com>
Co-authored-by: bash <hermensb@gmail.com>
2025-11-21 21:55:55 +01:00
bashermens
d97870facd fix: warning updating movement flags while rooted (#1858)
fixes https://github.com/mod-playerbots/mod-playerbots/issues/1854
-----
Also includes fixes for:
-----
* Bots swimming with waterWalk kept switching between swimming and
walking, as result jittering effect swimming under water when water
walking active
* Bots flying close above water they would land on water and start
walking, now they stay flying unless on solid ground they will land and
start walking by design

-----
Moved all flag setting to updateMovementState:
* So all movement flag are handled in updateMovementState which also
contains the restricted movement logic.
* Handle restricted movement logic and preventing SendMovementFlagUpdate
while being restricted.


-----
Known issue when flying the following bots feel a bit jittering, wont
touch for now at least till core movement changes quirks has been dealt
with.

The current code is the extended version of what is originally was
before core merge with refactored movements. Once the core movement
refactors are settled a bit more i would like to revisit this code; as i
would expect more imperative code and less manual flag setting e.g.
bot->SetWaterWalking, SetGravitiy..SetCanFly etc.
2025-11-21 20:45:23 +01:00
Alex Dcnh
0c1700c117 CORE - Improved language detection for bots (#1784)
I've had this problem for a long time, my bots only speak English even
though I'm playing on a French client.
I suppose this must be the case for some other people who do not have a
large number of players with the same local client.
If we use French DBCs, the bots bug because they only recognize US DBCs.
From what I understand, the language is chosen as follows:
On load, the module reads the entire `ai_playerbot_texts` table and
stores each text variant in a dictionary indexed by the locale ID: the
`text` column remains the default value (English), and the `text_loc1`
to `text_loc8` columns fill slots 1 through 8.

Whenever a real player connects, the module increments a counter for
that player's DBC locale using
`AddLocalePriority(player->GetSession()->GetSessionDbcLocale())`.

When a bot needs a text, `GetLocalePriority()` returns the most
frequently used locale index among currently connected players. The
corresponding string is then retrieved. if the box is empty, we fall
back to the English version (text[0]).

### This PR improve language detection.
**Summary**

- log both the client DBC locale and the account database locale when a
player logs in
- fall back to the account locale when the client reports enUS but the
account is configured for another locale
- keep the existing vote-based selection so bots always speak the
majority language among connected players

**Therefore, the original behavior is maintained. Bots still choose the
most represented language among connected players (the counter is simply
more efficient by prioritizing the account's locale when it differs from
the client's English). For example, if more English-speaking players are
connected, the language will revert to English, as the bots always share
the majority locale.**
2025-11-21 15:56:03 +01:00
Alex Dcnh
0b1b0eaecc Core - Fix RTSC SeeSpellAction crash on malformed WorldPacket (#1841)
## Summary

This PR fixes the Crash 1 Source from Issue
[#1840](https://github.com/mod-playerbots/mod-playerbots/issues/1840)
posted in a @Regrad posted logs, in `SeeSpellAction::Execute` when an
RTSC "see spell" event arrives with an empty or malformed `WorldPacket`.
In that case the code used to read from the packet without any
validation, causing a `ByteBufferException` and a crash in the map
thread.

## Fix

- Reset the packet read position and check that the RTSC header
(castCount + spellId + castFlags) fits into the packet before reading.
- Wrap `SpellCastTargets::Read` in a `try { } catch (ByteBufferException
const&) { }` block so truncated RTSC payloads are handled gracefully.
- Check that `targets.GetDst()` is not `nullptr` before accessing its
position.

For valid RTSC packets the behavior is unchanged; malformed packets are
now safely ignored instead of crashing the server.

## Testing

- Sent bots to multiple locations using RTSC and verified they still
move as before.
- Reproduced the previous crash scenario with malformed RTSC packets:
the worldserver no longer crashes and the event is simply ignored.

---------

Co-authored-by: bash <hermensb@gmail.com>
Co-authored-by: bashermens <31279994+hermensbas@users.noreply.github.com>
2025-11-21 13:18:14 +01:00
Gonzalo
8e03371147 Balance-Druid-improve-Starfall-usage-and-add-CC-safety (#1713)
- Move Starfall from default actions to AOE strategy only
- Require 2+ enemies for Starfall usage (prevents single-target casting)
- Add CC safety: avoid casting Starfall near current CC targets
- Prioritize Starfall over Hurricane in medium AOE situations
- Remove Starfall from pull/opener rotation to prevent early
single-target usage

This prevents Balance druids from wasting Starfall on single targets
and breaking crowd control effects in group content.
2025-11-19 21:00:59 +01:00
SaW
27311b734d Revert "feat: Improve bot mount behavior to faster close distance between bot and master" (#1855)
Reverts mod-playerbots/mod-playerbots#1760

This, as it is causing issues in BG, where bots just don't dismount and
just stand there instead.

<img width="2336" height="1374" alt="image"
src="https://github.com/user-attachments/assets/b61d7a77-1561-4f05-a438-edbb9321e113"
/>
2025-11-18 20:06:24 +01:00
SaW
bb5ed37cd3 Update codestyle_cpp.yml for review events and concurrency (#1836)
Include ready_for_review type, to run when draft is converted to ready.

Include concurrency; cancels obsolete tasks on new commits.
2025-11-18 18:48:52 +01:00
Jay
e88c1b779b Minor README.md corrections (#1849)
- Removed double "is" in acknowledgements
- Made the acknowledgements section more grammatical by using "based on"
instead of "based off"
- Corrected misspelling of "implemented"
- Standardized instances of "Playerbots" to `mod-playerbots` or properly
capitalized `Playerbots`
- Minor change of "for the continued contributions" to "for their
continued contributions" in the Acknowledgements section
2025-11-18 18:08:16 +01:00
Tecc
05057ae9b5 feat: Improve bot mount behavior to faster close distance between bot and master (#1760)
# Fix bot mount behavior when master dismounts

## Summary

Improves bot mount/dismount logic to ensure better coordination with the
master player. The bot now remains mounted when closing distance to a
recently dismounted master and mounts up to assist the master in combat.

The changes have been tested using the testcases described in the second
half of the PR description, which provide some directions on how this PR
can be tested and verified.

Closes: #1660

## Changes

- Add masterInCombat variable to track master combat state
- Modify target-based logic to consider master combat state
- Change mount priority when bot is not in combat to favor
master-following
- Remove combatReach from distance calculations (duplicate)

## Implementation

Added two methods:
- `StayMountedToCloseDistance()` - prevents premature dismounting when
the master dismounts
- `ShouldMountToCloseDistance()` - determines when to mount for master
assistance, even if master is not mounted at this time

Modified Execute() method:
- Target-based shouldMount/shouldDismount considers the master's combat
state
- Combat assistance logic separated from general following
- Mount when master in combat, but the bot is not

Distance logic:
- Combat: dismount at CalculateDismountDistance() (18-25 yards)
- Non-combat: dismount at 10 yards
- Mount threshold: 21+ yards

## Result
- Bots mount to assist masters in combat
- Bots stay mounted longer during travel
- Different dismount distances based on context
- Existing mount selection logic unchanged


# Mount Behavior Testing

## Prerequisites

1. Add a test bot: `.playerbots bot add <charactername>` or `.playerbots
bot addclass <class>`
2. Test in a level-appropriate outdoor area (mobs should not die with
one hit, as this makes testing combat assistance impossible)
3. Both master and bot must have mounts available

## Test 1: Combat Assistance Mounting

**Objective**: Verify bot mounts to assist the master in combat

**Detailed Steps**:
1. Position both master and bot dismounted
2. Command bot to stay: `/w <botname> stay`
3. Move master 35+ yards away from bot
4. Target a nearby mob and attack the mob
5. Command bot to assist: `/w <botname> follow`

**Expected Results**:
- Bot immediately mounts up (within 1-2 seconds cast time)
- Bot rides toward master while mounted
- Bot dismounts at ~18-25 yards from master/mob
- Bot engages in combat to assist

**Failure Indicators**:
- Bot runs dismounted (old behavior)
- Bot never mounts despite distance
- Bot mounts but doesn't dismount at proper assist range

## Test 2: Non-Combat Dismount Distance

**Objective**: Verify bot stays mounted longer during peaceful travel

**Detailed Steps**:
1. Both master and bot start dismounted
2. Mount up: use any mount
3. Verify bot also mounts: `/w <botname> follow`
4. Travel together for 10+ seconds to establish following
5. While moving, dismount master but continue running
6. Observe bot behavior as you move away

**Expected Results**:
- Bot stays mounted while master runs dismounted
- Bot only dismounts when within ~10 yards of master

## Test 3: Target Interference Prevention

**Objective**: Verify target selection doesn't prevent mounting when
master needs help

**Detailed Steps**:
1. Position bot 35+ yards from master: `/w <botname> stay` then move
away
2. Find a mob visible to both master and bot
3. Target the mob (do not attack): click on mob to select it
4. Verify bot can see the target: `/w <botname> attack` (bot should
respond about target)
5. Cancel bot attack: `/w <botname> follow`
6. Now attack the mob yourself (master enters combat)
7. Observe bot behavior immediately after master engages

**Expected Results**:
- Bot mounts up despite having the same target selected
- Bot rides toward combat area while mounted
- Bot dismounts at assist range (~18-25 yards)
- Target selection does not prevent proper mount behavior

**Failure Indicators**:
- Bot runs dismounted toward target (target interference)
- Bot doesn't mount because it's "focused on target"

## Test 4: Basic Mount Following

**Objective**: Verify fundamental mount matching still works

**Detailed Steps**:
1. Start both master and bot dismounted
2. Ensure bot is following: `/w <botname> follow`
3. Mount up on any available mount
4. Wait 2-3 seconds and observe bot
5. Test different mount speeds if available (60%, 100%, 280% speed)
6. Test dismounting and remounting

**Expected Results**:
- Bot mounts within 2-3 seconds of master mounting
- Bot uses appropriate mount speed to match master
- Bot dismounts when master dismounts (basic following)
- No regression in basic mount following behavior

## Test 5: Distance-Based Mounting Threshold

**Objective**: Verify bot mounts at efficient distance threshold (21+
yards)

**Detailed Steps**:
1. Both master and bot start dismounted in safe area (no mobs)
2. Command bot to stay: `/w <botname> stay`
3. Record starting position: `.gps`
4. Walk exactly 15 yards away (short distance)
5. Command bot to follow: `/w <botname> follow`
6. Observe: bot should run dismounted (distance too short)
7. Command bot to stay again: `/w <botname> stay`
8. Walk to 25+ yards away from bot
9. Record new position: `.gps`
10. Command bot to follow: `/w <botname> follow`

**Expected Results**:
- At 15 yards: Bot runs dismounted (inefficient to mount)
- At 25+ yards: Bot mounts up immediately (efficient distance)
- Distance threshold should be ~21 yards based on mount cast time
efficiency

**Distance Calculation**: Use coordinates from `.gps` to verify exact
distances

## Test 6: Druid Form Integration (Druid Master Required)

**Objective**: Verify druid form compatibility with mount system

**Detailed Steps**:
1. Master must be druid with travel form available
2. Start both dismounted: `/w <botname> follow`
3. Shift master to travel form
4. Observe bot response (should mount or shift if druid)
5. Travel together for 10+ seconds
6. Shift master to normal form while moving
7. Observe bot dismount behavior
8. If available, test flight form in appropriate zones

**Expected Results**:
- Druid bot: matches master's form (travel form)
- Non-druid bot: uses equivalent mount speed
- Form changes trigger appropriate bot responses
- Speed matching works between forms and mounts

## Test 7: Battleground Mount Behavior

**Objective**: Verify mount behavior works in PvP environments

**Detailed Steps**:
1. Queue for battleground with bot in party
2. Enter battleground together
3. Test basic mount following in BG
4. Test flag-carrying restrictions (WSG/EotS)
5. Test mounting during BG combat scenarios

**Expected Results**:
- Bot mounts appropriately in battlegrounds
- Flag carrying prevents mounting
- Combat assistance mounting still works in PvP
2025-11-16 22:49:12 +01:00
bashermens
610a032379 Bots fly/follow (movePoint core refactor), water walking fixes (#1825)
Closer the original solution, i dont wanna drift to much away without
really good reason. At this point i still see NPC and bots moving
through the levels or even falling out the levels here and there. I
verified whether the MovePoint signature changes and related params
itself in playerbots has anything todo with it, even when params are
hardcoded the behavior remains. It could be deeper problem, but for now
it seems core problem. Therefore i dont wanna change to much until the
dust has settled a bit in core itself.

I havent implemented moveTakeOff or moveLand which are basically
responsible for the transitions phases between ground and air visa
versa. I have version where i use takeOff for the animation, which means
moving vertical. For now i am gonna leave for what it is.

PS: also includes additional movement fix for AreaTriggerAction which we
missed first time after the core update on movements.

@Wishmaster117 Been testing and trying a lot in the background on find
solutions and causes. The general solutions remains removed some tweaks,
altered code here and there. With the general idea to keep closer to the
original code for now at least.

Testing:
- Class abilities: Slow fall (priest), Flight Form (druid) : Green
- BG: Green
- Swimming and walking shallow waters: Green
- Takeoff and land when following master: Green
- Boat and zeppelins: Green
- Flymount and ground walking: Green
- Water Walking (shaman), Path of Frost (DK): Green
- Water Walking (shaman), Path of Frost (DK) transisions; flying,
swimming, water walking: Green


Skipping pets when group water walking, path of frost, once core pathing
changes has settled more i will add it. Which is easy but i dont wanna
add more edge cases and code branches for now.
2025-11-16 22:39:46 +01:00
Jay
ce2a990495 README.md edits (#1779)
I've noticed some sprawl in the README.md. The following edits have been
made around the goal of clarity, brevity, and emphases when needed:

- Removed dead link to the Spanish README.md at the top. The
README_ES.md file itself is not removed from the repo, but is however
out of date and does not seem useful at this time
- Removed the addons section. This seems to be covered by the Wiki in
the Documentation section unless I'm mistaken? We can add these back if
needed
- Reorganized installation instructions to emphasize the importance of
using the Playerbots branch of AzerothCore for all installations
- Moved the platform support from the Frequently Asked Questions section
to the installation instructions
- Modified punctuation of bulleted list. These can return if it irks
someone, but it seems easier to read without them
- Added a encouragement to star the project for updates and gain more
visibility
- Removed the Frequently Asked Questions section. I encourage this to be
covered in a wiki page but it can return if deemed necessary. I think a
lot of it can be moved to other sections if we really need them in there
- Added a "Contributing" section that replaces the Coding Standards
section
- Coding Standards are included in the Contributing section
- Added a second link to the Discord server in the Contributing section
- Removed a link to the main Playerbots branch from the introduction
section. This is covered and emphasized in the installation section
instead
- Migrated the encouragements to make bug reports from the introduction,
along with the message that this is still in active development, to the
contributing section
- Reduced redundant language when not necessary (e.g. "As noted above,")
- Updated language around custom branch and require branch for
uniformity. This will make it more clear to the users about the subject
- Removed "Classic" from the "Classic Installation" terminology for
being inaccurate. The subject is now known simply as "Cloning the
Repositories" while "Docker Installation" still remains distinct. This
will make what was formerly known as "Classic Installation" as de facto
default
- Appended the "Documentation" section with add-on information
- Unified all instances of AddOn to the Blizzard spelling without a
hyphen following the WoW 3.3.5a client spelling
- Appended "AzerothCore" to instances of "branch" to ensure readers they
are, in fact, installing AzerothCore here from our required branch
2025-11-15 22:00:19 +01:00
Alex Dcnh
6effabfa42 Core - Fix Bots can pickup the flag in Eye of the Strom instantly, without cast time from the spawn point (#1704)
# Eye of the Storm Flag Capture Behavior
 
## Previous Behavior
- Bots used to interact with the Netherstorm flag the moment they
reached interaction range, leading to instant pickups even before they
were correctly positioned.
- They did not respect the requirement to stand within the capture ring
or dismount before channeling, so the interaction finished immediately
without the intended delay.
 
## Current Behavior
- Bots now verify they are inside the Eye of the Storm capture circle
and will reposition toward the center flag or base flag until they are
within 2.5 yards of the game object before starting the channel.
- Once inside the circle they dismount, drop shapeshift forms, and come
to a full stop before beginning the channel cast.
- When channeling the center flag capture spell, bots keep checking for
the ongoing `SPELL_CAPTURE_BANNER` cast and wait for it to finish
instead of attempting repeated instant interactions.
- They will be interrupted if they receice any damage
 
These adjustments align the Eye of the Storm flow with the retail
mechanics and prevent bots from taking the flag instantly when it
spawns.

Fixes #1700.
2025-11-15 18:19:16 +01:00
Nicolas Lebacq
cadbcbd447 fix: Resolved an issue where the open spell was being cast by bots on despawned game objects. (#1842)
# Description

This addresses the infamous "Possible hacking attempt" error when bots
were furiously trying to interact with despawned game objects.
The problem was that the game objects were not being as spawned when
evaluating what the bot should do. It was only done when spells were
being cast on entities.
2025-11-15 10:27:33 +01:00
Crow
08c739f918 Align index with section update (#1831)
Update to index to reflect change to section title
2025-11-14 15:17:43 +01:00
privatecore
0729d14787 Fix PlayerbotAI constructors' members order and wrong type comparison (uint32 -> int32) (#1763)
Fix warnings: -Wsign-compare and -Wsign-compare.

I would also like to mention that there are issues with the following
methods:

`IsMainTank` -- in the last loop, it returns the result of comparing the
first alive tank it finds with the current bot, which seems odd.
`IsBotMainTank` -- it is used in only two places in the code (Yogg-Saron
strategy) and has a completely different logic for checking. In the last
loop, it only checks for a suitable tank-bot with a lower index (if it's
not the bot itself). Additionally, there is a logic issue in the loop:
if none of the conditions are met after the first iteration, the method
returns `false`.

Can someone from the maintainers take a look at this section of the code
for possible errors and logic issues?
2025-11-13 00:51:24 +01:00
nick
a37dd2b9ae Clarify random bot timing configuration section and parameter descriptions (#1826)
This update reorganizes and rewrites the random bot timing configuration
section for clarity and accuracy. The previous section was mislabeled as
"INTERVALS" and lacked precise descriptions. The new version:

1. Renames the header to RANDOM BOT TIMING AND BEHAVIOR
2. Adds concise, standardized comments for each parameter
3. Corrects misleading terminology (not all values are intervals)
4. Documents defaults and actual behavior clearly for easier tuning and
maintenance
5. No functional code changes — documentation and readability only.

Note, this is derived information from reading the code.
Please double check if I have captured each param accurately!
2025-11-11 09:21:13 +01:00
SaW
9c8ba42c64 FIX: Battlegrounds - Unset bot's master when current master left BG (#1819)
Adds a check for if current master left the BG and group, if so release
set master and carry on in BG.

This prevents multiple bots in (potentially multiple different) BG's to
still consider you as their master when you yourself have left.

- Applies when you join BGs with a party of bots.
2025-11-11 09:10:09 +01:00