mirror of
https://github.com/kadeshar/mod-player-bot-level-brackets.git
synced 2026-01-13 01:08:36 +00:00
Merge pull request #35 from DustinHendrickson/Dustin/ConfBasedBrackets
Adding support to change bracket ranges/number of brackets in the conf
This commit is contained in:
189
README.md
189
README.md
@@ -13,46 +13,29 @@ The Bot Level Brackets module for AzerothCore ensures an even spread of player b
|
|||||||
Features
|
Features
|
||||||
--------
|
--------
|
||||||
- **Configurable Faction-Specific Level Brackets:**
|
- **Configurable Faction-Specific Level Brackets:**
|
||||||
Define nine distinct level brackets for Alliance and Horde bots with configurable lower and upper bounds:
|
Define level brackets for Alliance and Horde bots with configurable lower and upper bounds.
|
||||||
- 1-9, 10-19, 20-29, 30-39, 40-49, 50-59, 60-69, 70-79, 80
|
|
||||||
|
|
||||||
- **Desired Percentage Distribution:**
|
- **Desired Percentage Distribution:**
|
||||||
Target percentages can be set for the number of bots within each level bracket. The sum of percentages for each faction must equal 100. If it does not, the system will balance out the remaining percentages automatically.
|
Specify a desired percentage for bots in each bracket. The percentages for each faction must sum to 100.
|
||||||
|
|
||||||
- **Dynamic Bot Adjustment:**
|
- **Dynamic Bot Adjustment:**
|
||||||
Bots in overpopulated brackets are automatically adjusted to a random level within a bracket with a deficit. Adjustments include resetting XP, removing equipped items, trade skills, learned spells, quests, and active auras, and dismissing pets.
|
Bots in overpopulated brackets are adjusted to a random level within a bracket with a deficit.
|
||||||
|
|
||||||
- **Death Knight Level Safeguard:**
|
- **Death Knight Level Safeguard:**
|
||||||
Death Knight bots are enforced a minimum level of 55, ensuring they are only assigned to higher brackets.
|
Death Knight bots are enforced a minimum level of 55.
|
||||||
|
|
||||||
- **Support for Random Bots:**
|
|
||||||
The module applies exclusively to bots managed by the RandomPlayerbotMgr.
|
|
||||||
|
|
||||||
- **Dynamic Distribution Toggle:**
|
|
||||||
Enable or disable the dynamic recalculation of bot distribution percentages based on the number of non-bot players in each level bracket via the `BotLevelBrackets.UseDynamicDistribution` option.
|
|
||||||
|
|
||||||
- **Dynamic Real Player Weighting with Inverse Scaling:**
|
|
||||||
When dynamic distribution is enabled, the module uses a configurable weight multiplier (set via `BotLevelBrackets.RealPlayerWeight`) to boost each real player's contribution to the desired distribution. This weight is further scaled inversely by the total number of real players online, ensuring that when few players are active, each player's impact on the bot distribution is significantly increased.
|
|
||||||
**Note:** The `RealPlayerWeight` option only takes effect when `BotLevelBrackets.UseDynamicDistribution` is enabled.
|
|
||||||
|
|
||||||
- **Guild Bot Exclusion:**
|
- **Guild Bot Exclusion:**
|
||||||
When enabled via the new configuration option `BotLevelBrackets.IgnoreGuildBotsWithRealPlayers` (default enabled), bots that are in a guild with at least one real (non-bot) player online are excluded from bot bracket calculations. These bots are not counted in the totals, nor are they subject to level changes or flagged for pending reset.
|
When enabled, bots that are in a guild with at least one real (non-bot) player online are excluded from bot bracket calculations and will not be adjusted.
|
||||||
> **NOTE:** At this time Guild Bot Exclusion only works with **online** real players. I'm investigating how to accomplish the same thing even if the real player is offline.
|
- **Friend List Exclusion:**
|
||||||
|
When enabled, bots that are on real players' friend lists are excluded from level bracket adjustments.
|
||||||
|
- **Dynamic Distribution:**
|
||||||
|
Optionally enable dynamic recalculation of bot distribution percentages based on the number of non-bot players present in each bracket.
|
||||||
|
- **Debug Modes:**
|
||||||
|
Full and Lite debug modes provide detailed logging for troubleshooting and monitoring bot adjustments.
|
||||||
|
|
||||||
- **Debug Mode:**
|
Minimum and Maximum Bot Level Support
|
||||||
Optional debug modes (full and lite) provide detailed logging for monitoring bot adjustments and troubleshooting module operations.
|
----------------------------------------
|
||||||
|
This module supports setting minimum and maximum levels for random bots via Playerbots options:
|
||||||
|
- **AiPlayerbot.RandomBotMinLevel:** Default is 1.
|
||||||
|
- **AiPlayerbot.RandomBotMaxLevel:** Default is 80.
|
||||||
|
|
||||||
### Minimum and Maximum Bot Level Support
|
> **Warning:** If you configure the maximum bot level to a value below 55, ensure that Death Knight bots are disabled.
|
||||||
|
|
||||||
This module now supports setting a minimum and maximum level for random bots via the Playerbots `playerbots.conf` options:
|
|
||||||
|
|
||||||
- **AiPlayerbot.RandomBotMinLevel:**
|
|
||||||
Sets the minimum level allowed for random bots. The default value is 1.
|
|
||||||
|
|
||||||
- **AiPlayerbot.RandomBotMaxLevel:**
|
|
||||||
Sets the maximum level allowed for random bots. The default value is 80.
|
|
||||||
|
|
||||||
> **Warning:** If you configure the maximum bot level to a value below 55, ensure that Death Knight bots are disabled. The module enforces a minimum level of 55 for Death Knight bots; therefore, setting the maximum level under 55 would conflict with this safeguard and could lead to unintended behavior and Death Knight bots not moving brackets.
|
|
||||||
|
|
||||||
Installation
|
Installation
|
||||||
------------
|
------------
|
||||||
@@ -82,7 +65,7 @@ Installation
|
|||||||
|
|
||||||
Configuration Options
|
Configuration Options
|
||||||
---------------------
|
---------------------
|
||||||
Customize the module’s behavior by editing the `mod_player_bot_level_brackets.conf` file. The configuration options are separated for Alliance and Horde bots:
|
Customize the module’s behavior by editing the `mod_player_bot_level_brackets.conf` file. The configuration options are split into global settings and faction-specific level bracket settings.
|
||||||
|
|
||||||
### Global Settings
|
### Global Settings
|
||||||
|
|
||||||
@@ -93,49 +76,129 @@ BotLevelBrackets.FullDebugMode | Enables full debug logging for th
|
|||||||
BotLevelBrackets.LiteDebugMode | Enables lite debug logging for the Bot Level Brackets module. | 0 | 0 (off) / 1 (on)
|
BotLevelBrackets.LiteDebugMode | Enables lite debug logging for the Bot Level Brackets module. | 0 | 0 (off) / 1 (on)
|
||||||
BotLevelBrackets.CheckFrequency | Frequency (in seconds) at which the bot level distribution check is performed. | 300 | Positive Integer
|
BotLevelBrackets.CheckFrequency | Frequency (in seconds) at which the bot level distribution check is performed. | 300 | Positive Integer
|
||||||
BotLevelBrackets.CheckFlaggedFrequency | Frequency (in seconds) at which the bot level reset is performed for flagged bots that initially failed safety checks. | 15 | Positive Integer
|
BotLevelBrackets.CheckFlaggedFrequency | Frequency (in seconds) at which the bot level reset is performed for flagged bots that initially failed safety checks. | 15 | Positive Integer
|
||||||
BotLevelBrackets.UseDynamicDistribution | Enables dynamic recalculation of bot distribution percentages based on the number of non-bot players present in each bracket. | 0 | 0 (off) / 1 (on)
|
BotLevelBrackets.UseDynamicDistribution | Enables dynamic recalculation of bot distribution percentages based on non-bot player counts per bracket. | 0 | 0 (off) / 1 (on)
|
||||||
BotLevelBrackets.RealPlayerWeight | Multiplier applied to each real player's contribution in their level bracket. **Active only if dynamic distribution is enabled.** | 1.0 | Floating point number
|
BotLevelBrackets.RealPlayerWeight | Multiplier applied to each real player's contribution (active only if dynamic distribution is enabled). | 1.0 | Floating point number
|
||||||
**BotLevelBrackets.IgnoreGuildBotsWithRealPlayers** | When enabled, bots in a guild with at least one real (non-bot) player online are excluded from bot bracket calculations and will not be level changed or flagged. | 1 | 0 (disabled) / 1 (enabled)
|
BotLevelBrackets.IgnoreFriendListed | Ignores bots that are on real players' friend lists from any bracket calculations. | 1 | 0 (off) / 1 (on)
|
||||||
|
BotLevelBrackets.IgnoreGuildBotsWithRealPlayers | Excludes bots in a guild with at least one real (non-bot) player online from adjustments. | 1 | 0 (disabled) / 1 (enabled)
|
||||||
|
BotLevelBrackets.NumRanges | Number of level brackets used for bot distribution. Both factions must have the same number defined. | 9 | Positive Integer
|
||||||
|
|
||||||
|
**IMPORTANT:** If you extend the number of brackets beyond the default 9, you must update both your `mod_player_bot_level_brackets.conf` file and the accompanying `mod_player_bot_level_brackets.conf.dist` file to include configuration lines for the additional ranges (e.g. Range10, Range11, etc.), ensuring that the sum of the Pct values remains 100.
|
||||||
|
|
||||||
### Alliance Level Brackets Configuration
|
### Alliance Level Brackets Configuration
|
||||||
*The percentages below must sum to 100.*
|
*The percentages below must sum to 100.*
|
||||||
|
|
||||||
Setting | Description | Default | Valid Values
|
For each bracket, define:
|
||||||
--------------------------------------------|---------------------------------------------------------------|---------|--------------------
|
|
||||||
BotLevelBrackets.Alliance.Range1Pct | Desired percentage of Alliance bots within level range 1-9. | 12 | 0-100
|
- **BotLevelBrackets.Alliance.RangeX.Lower:**
|
||||||
BotLevelBrackets.Alliance.Range2Pct | Desired percentage of Alliance bots within level range 10-19. | 11 | 0-100
|
The lower bound (inclusive) of bracket X.
|
||||||
BotLevelBrackets.Alliance.Range3Pct | Desired percentage of Alliance bots within level range 20-29. | 11 | 0-100
|
|
||||||
BotLevelBrackets.Alliance.Range4Pct | Desired percentage of Alliance bots within level range 30-39. | 11 | 0-100
|
- **BotLevelBrackets.Alliance.RangeX.Upper:**
|
||||||
BotLevelBrackets.Alliance.Range5Pct | Desired percentage of Alliance bots within level range 40-49. | 11 | 0-100
|
The upper bound (inclusive) of bracket X.
|
||||||
BotLevelBrackets.Alliance.Range6Pct | Desired percentage of Alliance bots within level range 50-59. | 11 | 0-100
|
|
||||||
BotLevelBrackets.Alliance.Range7Pct | Desired percentage of Alliance bots within level range 60-69. | 11 | 0-100
|
- **BotLevelBrackets.Alliance.RangeX.Pct:**
|
||||||
BotLevelBrackets.Alliance.Range8Pct | Desired percentage of Alliance bots within level range 70-79. | 11 | 0-100
|
The desired percentage of Alliance bots that should fall into bracket X.
|
||||||
BotLevelBrackets.Alliance.Range9Pct | Desired percentage of Alliance bots at level 80. | 11 | 0-100
|
|
||||||
|
**EXAMPLE:**
|
||||||
|
The default configuration below defines 9 brackets:
|
||||||
|
- Range1 covers levels 1–9
|
||||||
|
`BotLevelBrackets.Alliance.Range1.Lower = 1`
|
||||||
|
`BotLevelBrackets.Alliance.Range1.Upper = 9`
|
||||||
|
`BotLevelBrackets.Alliance.Range1.Pct = 12`
|
||||||
|
- Range2 covers levels 10–19
|
||||||
|
`BotLevelBrackets.Alliance.Range2.Lower = 10`
|
||||||
|
`BotLevelBrackets.Alliance.Range2.Upper = 19`
|
||||||
|
`BotLevelBrackets.Alliance.Range2.Pct = 11`
|
||||||
|
- Range3 covers levels 20–29
|
||||||
|
`BotLevelBrackets.Alliance.Range3.Lower = 20`
|
||||||
|
`BotLevelBrackets.Alliance.Range3.Upper = 29`
|
||||||
|
`BotLevelBrackets.Alliance.Range3.Pct = 11`
|
||||||
|
- Range4 covers levels 30–39
|
||||||
|
`BotLevelBrackets.Alliance.Range4.Lower = 30`
|
||||||
|
`BotLevelBrackets.Alliance.Range4.Upper = 39`
|
||||||
|
`BotLevelBrackets.Alliance.Range4.Pct = 11`
|
||||||
|
- Range5 covers levels 40–49
|
||||||
|
`BotLevelBrackets.Alliance.Range5.Lower = 40`
|
||||||
|
`BotLevelBrackets.Alliance.Range5.Upper = 49`
|
||||||
|
`BotLevelBrackets.Alliance.Range5.Pct = 11`
|
||||||
|
- Range6 covers levels 50–59
|
||||||
|
`BotLevelBrackets.Alliance.Range6.Lower = 50`
|
||||||
|
`BotLevelBrackets.Alliance.Range6.Upper = 59`
|
||||||
|
`BotLevelBrackets.Alliance.Range6.Pct = 11`
|
||||||
|
- Range7 covers levels 60–69
|
||||||
|
`BotLevelBrackets.Alliance.Range7.Lower = 60`
|
||||||
|
`BotLevelBrackets.Alliance.Range7.Upper = 69`
|
||||||
|
`BotLevelBrackets.Alliance.Range7.Pct = 11`
|
||||||
|
- Range8 covers levels 70–79
|
||||||
|
`BotLevelBrackets.Alliance.Range8.Lower = 70`
|
||||||
|
`BotLevelBrackets.Alliance.Range8.Upper = 79`
|
||||||
|
`BotLevelBrackets.Alliance.Range8.Pct = 11`
|
||||||
|
- Range9 covers level 80 only
|
||||||
|
`BotLevelBrackets.Alliance.Range9.Lower = 80`
|
||||||
|
`BotLevelBrackets.Alliance.Range9.Upper = 80`
|
||||||
|
`BotLevelBrackets.Alliance.Range9.Pct = 11`
|
||||||
|
|
||||||
|
To isolate a specific level (e.g., level 60) into its own bracket, set the Lower and Upper for that range to the same value (e.g., 60) and adjust the adjacent ranges accordingly.
|
||||||
|
|
||||||
### Horde Level Brackets Configuration
|
### Horde Level Brackets Configuration
|
||||||
*The percentages below must sum to 100.*
|
*The percentages below must sum to 100.*
|
||||||
|
|
||||||
Setting | Description | Default | Valid Values
|
For each bracket, define:
|
||||||
-------------------------------------------|---------------------------------------------------------------|---------|--------------------
|
|
||||||
BotLevelBrackets.Horde.Range1Pct | Desired percentage of Horde bots within level range 1-9. | 12 | 0-100
|
- **BotLevelBrackets.Horde.RangeX.Lower:**
|
||||||
BotLevelBrackets.Horde.Range2Pct | Desired percentage of Horde bots within level range 10-19. | 11 | 0-100
|
The lower bound (inclusive) of bracket X.
|
||||||
BotLevelBrackets.Horde.Range3Pct | Desired percentage of Horde bots within level range 20-29. | 11 | 0-100
|
|
||||||
BotLevelBrackets.Horde.Range4Pct | Desired percentage of Horde bots within level range 30-39. | 11 | 0-100
|
- **BotLevelBrackets.Horde.RangeX.Upper:**
|
||||||
BotLevelBrackets.Horde.Range5Pct | Desired percentage of Horde bots within level range 40-49. | 11 | 0-100
|
The upper bound (inclusive) of bracket X.
|
||||||
BotLevelBrackets.Horde.Range6Pct | Desired percentage of Horde bots within level range 50-59. | 11 | 0-100
|
|
||||||
BotLevelBrackets.Horde.Range7Pct | Desired percentage of Horde bots within level range 60-69. | 11 | 0-100
|
- **BotLevelBrackets.Horde.RangeX.Pct:**
|
||||||
BotLevelBrackets.Horde.Range8Pct | Desired percentage of Horde bots within level range 70-79. | 11 | 0-100
|
The desired percentage of Horde bots that should fall into bracket X.
|
||||||
BotLevelBrackets.Horde.Range9Pct | Desired percentage of Horde bots at level 80. | 11 | 0-100
|
|
||||||
|
**EXAMPLE:**
|
||||||
|
The default configuration below defines 9 brackets:
|
||||||
|
- Range1 covers levels 1–9
|
||||||
|
`BotLevelBrackets.Horde.Range1.Lower = 1`
|
||||||
|
`BotLevelBrackets.Horde.Range1.Upper = 9`
|
||||||
|
`BotLevelBrackets.Horde.Range1.Pct = 12`
|
||||||
|
- Range2 covers levels 10–19
|
||||||
|
`BotLevelBrackets.Horde.Range2.Lower = 10`
|
||||||
|
`BotLevelBrackets.Horde.Range2.Upper = 19`
|
||||||
|
`BotLevelBrackets.Horde.Range2.Pct = 11`
|
||||||
|
- Range3 covers levels 20–29
|
||||||
|
`BotLevelBrackets.Horde.Range3.Lower = 20`
|
||||||
|
`BotLevelBrackets.Horde.Range3.Upper = 29`
|
||||||
|
`BotLevelBrackets.Horde.Range3.Pct = 11`
|
||||||
|
- Range4 covers levels 30–39
|
||||||
|
`BotLevelBrackets.Horde.Range4.Lower = 30`
|
||||||
|
`BotLevelBrackets.Horde.Range4.Upper = 39`
|
||||||
|
`BotLevelBrackets.Horde.Range4.Pct = 11`
|
||||||
|
- Range5 covers levels 40–49
|
||||||
|
`BotLevelBrackets.Horde.Range5.Lower = 40`
|
||||||
|
`BotLevelBrackets.Horde.Range5.Upper = 49`
|
||||||
|
`BotLevelBrackets.Horde.Range5.Pct = 11`
|
||||||
|
- Range6 covers levels 50–59
|
||||||
|
`BotLevelBrackets.Horde.Range6.Lower = 50`
|
||||||
|
`BotLevelBrackets.Horde.Range6.Upper = 59`
|
||||||
|
`BotLevelBrackets.Horde.Range6.Pct = 11`
|
||||||
|
- Range7 covers levels 60–69
|
||||||
|
`BotLevelBrackets.Horde.Range7.Lower = 60`
|
||||||
|
`BotLevelBrackets.Horde.Range7.Upper = 69`
|
||||||
|
`BotLevelBrackets.Horde.Range7.Pct = 11`
|
||||||
|
- Range8 covers levels 70–79
|
||||||
|
`BotLevelBrackets.Horde.Range8.Lower = 70`
|
||||||
|
`BotLevelBrackets.Horde.Range8.Upper = 79`
|
||||||
|
`BotLevelBrackets.Horde.Range8.Pct = 11`
|
||||||
|
- Range9 covers level 80 only
|
||||||
|
`BotLevelBrackets.Horde.Range9.Lower = 80`
|
||||||
|
`BotLevelBrackets.Horde.Range9.Upper = 80`
|
||||||
|
`BotLevelBrackets.Horde.Range9.Pct = 11`
|
||||||
|
|
||||||
Debugging
|
Debugging
|
||||||
---------
|
---------
|
||||||
To enable detailed debug logging, update the configuration file:
|
To enable detailed debug logging, update the configuration file with one of the following:
|
||||||
|
|
||||||
BotLevelBrackets.FullDebugMode = 1
|
BotLevelBrackets.FullDebugMode = 1
|
||||||
BotLevelBrackets.LiteDebugMode = 1
|
BotLevelBrackets.LiteDebugMode = 1
|
||||||
|
|
||||||
Choose one of these debug modes to output logs detailing bot level adjustments, percentages, and distribution to the server console.
|
|
||||||
|
|
||||||
Troubleshooting
|
Troubleshooting
|
||||||
---------------
|
---------------
|
||||||
> **Bots are not randomizing their levels within the range brackets.**
|
> **Bots are not randomizing their levels within the range brackets.**
|
||||||
|
|||||||
@@ -10,36 +10,44 @@
|
|||||||
# Valid values: 0 (off) / 1 (on)
|
# Valid values: 0 (off) / 1 (on)
|
||||||
BotLevelBrackets.Enabled = 1
|
BotLevelBrackets.Enabled = 1
|
||||||
|
|
||||||
|
#
|
||||||
# BotLevelBrackets.FullDebugMode
|
# BotLevelBrackets.FullDebugMode
|
||||||
# Description: Enables full debug logging for the Bot Level Brackets module.
|
# Description: Enables full debug logging for the Bot Level Brackets module.
|
||||||
# Default: 0 (disabled)
|
# Default: 0 (disabled)
|
||||||
# Valid values: 0 (off) / 1 (on)
|
# Valid values: 0 (off) / 1 (on)
|
||||||
BotLevelBrackets.FullDebugMode = 0
|
BotLevelBrackets.FullDebugMode = 0
|
||||||
|
|
||||||
|
#
|
||||||
# BotLevelBrackets.LiteDebugMode
|
# BotLevelBrackets.LiteDebugMode
|
||||||
# Description: Enables lite debug logging for the Bot Level Brackets module.
|
# Description: Enables lite debug logging for the Bot Level Brackets module.
|
||||||
# Default: 0 (disabled)
|
# Default: 0 (disabled)
|
||||||
# Valid values: 0 (off) / 1 (on)
|
# Valid values: 0 (off) / 1 (on)
|
||||||
BotLevelBrackets.LiteDebugMode = 0
|
BotLevelBrackets.LiteDebugMode = 0
|
||||||
|
|
||||||
|
#
|
||||||
# BotLevelBrackets.CheckFrequency
|
# BotLevelBrackets.CheckFrequency
|
||||||
# Description: The frequency (in seconds) at which the bot level distribution check is performed.
|
# Description: The frequency (in seconds) at which the bot level distribution check is performed.
|
||||||
# Default: 300
|
# Default: 300
|
||||||
BotLevelBrackets.CheckFrequency = 300
|
BotLevelBrackets.CheckFrequency = 300
|
||||||
|
|
||||||
|
#
|
||||||
# BotLevelBrackets.CheckFlaggedFrequency
|
# BotLevelBrackets.CheckFlaggedFrequency
|
||||||
# Description: The frequency (in seconds) at which the bot level reset is performed for flagged bots that failed safety checks initially.
|
# Description: The frequency (in seconds) at which the bot level reset is performed for flagged bots that failed safety checks initially.
|
||||||
# Default: 15
|
# Default: 15
|
||||||
BotLevelBrackets.CheckFlaggedFrequency = 15
|
BotLevelBrackets.CheckFlaggedFrequency = 15
|
||||||
|
|
||||||
|
#
|
||||||
# BotLevelBrackets.IgnoreGuildBotsWithRealPlayers
|
# BotLevelBrackets.IgnoreGuildBotsWithRealPlayers
|
||||||
# Description: When enabled, bots that are in a guild with at least one real (non-bot) player online are excluded from bot bracket calculations and will not be level changed or flagged.
|
# Description: When enabled, bots that are in a guild with at least one real (non-bot) player online are excluded
|
||||||
|
# from bot bracket calculations and will not be level changed or flagged.
|
||||||
# Default: 1 (enabled)
|
# Default: 1 (enabled)
|
||||||
# Valid values: 0 (disabled) / 1 (enabled)
|
# Valid values: 0 (disabled) / 1 (enabled)
|
||||||
BotLevelBrackets.IgnoreGuildBotsWithRealPlayers = 1
|
BotLevelBrackets.IgnoreGuildBotsWithRealPlayers = 1
|
||||||
|
|
||||||
|
#
|
||||||
# BotLevelBrackets.UseDynamicDistribution
|
# BotLevelBrackets.UseDynamicDistribution
|
||||||
# Description: Enables dynamic recalculation of bot distribution percentages based on the number of non-bot players present in each level bracket.
|
# Description: Enables dynamic recalculation of bot distribution percentages based on the number of non-bot players
|
||||||
|
# present in each level bracket.
|
||||||
# Default: 0 (disabled)
|
# Default: 0 (disabled)
|
||||||
# Valid values: 0 (off) / 1 (on)
|
# Valid values: 0 (off) / 1 (on)
|
||||||
BotLevelBrackets.UseDynamicDistribution = 0
|
BotLevelBrackets.UseDynamicDistribution = 0
|
||||||
@@ -54,105 +62,147 @@ BotLevelBrackets.RealPlayerWeight = 1.0
|
|||||||
|
|
||||||
#
|
#
|
||||||
# BotLevelBrackets.IgnoreFriendListed
|
# BotLevelBrackets.IgnoreFriendListed
|
||||||
# Description: Ignore bots that are on real players friend's lists from any brackets
|
# Description: Ignore bots that are on real players friend's lists from any brackets.
|
||||||
# Default: 1 (enabled)
|
# Default: 1 (enabled)
|
||||||
# Valid values: 0 (off) / 1 (on)
|
# Valid values: 0 (off) / 1 (on)
|
||||||
BotLevelBrackets.IgnoreFriendListed = 1
|
BotLevelBrackets.IgnoreFriendListed = 1
|
||||||
|
|
||||||
#
|
#
|
||||||
|
# BotLevelBrackets.NumRanges
|
||||||
|
# Description: The number of level brackets used for bot distribution.
|
||||||
|
# Both Alliance and Horde should have the same number of brackets defined below.
|
||||||
|
# Default: 9
|
||||||
|
#
|
||||||
|
# IMPORTANT: If you are extending the number of brackets beyond 9, you must update your
|
||||||
|
# mod_player_bot_level_brackets.conf file AND the corresponding mod_player_bot_level_brackets.conf.dist file to include configuration
|
||||||
|
# lines for the additional bracket lines added below (e.g. Range10, Range11, etc.). Ensure that the
|
||||||
|
# sum of the Pct values for each faction remains 100.
|
||||||
|
BotLevelBrackets.NumRanges = 9
|
||||||
|
|
||||||
|
##############################################
|
||||||
# Alliance Level Brackets Configuration
|
# Alliance Level Brackets Configuration
|
||||||
# The percentages below must sum to 100.
|
##############################################
|
||||||
|
# The following settings define the level brackets for Alliance bots.
|
||||||
|
# For each bracket, you must specify three parameters:
|
||||||
#
|
#
|
||||||
# BotLevelBrackets.Alliance.Range1Pct
|
# BotLevelBrackets.Alliance.RangeX.Lower
|
||||||
# Description: Desired percentage of Alliance bots within level range 1-9.
|
# Description: The lower bound (inclusive) of bracket X.
|
||||||
# Default: 12
|
|
||||||
BotLevelBrackets.Alliance.Range1Pct = 12
|
|
||||||
|
|
||||||
# BotLevelBrackets.Alliance.Range2Pct
|
|
||||||
# Description: Desired percentage of Alliance bots within level range 10-19.
|
|
||||||
# Default: 11
|
|
||||||
BotLevelBrackets.Alliance.Range2Pct = 11
|
|
||||||
|
|
||||||
# BotLevelBrackets.Alliance.Range3Pct
|
|
||||||
# Description: Desired percentage of Alliance bots within level range 20-29.
|
|
||||||
# Default: 11
|
|
||||||
BotLevelBrackets.Alliance.Range3Pct = 11
|
|
||||||
|
|
||||||
# BotLevelBrackets.Alliance.Range4Pct
|
|
||||||
# Description: Desired percentage of Alliance bots within level range 30-39.
|
|
||||||
# Default: 11
|
|
||||||
BotLevelBrackets.Alliance.Range4Pct = 11
|
|
||||||
|
|
||||||
# BotLevelBrackets.Alliance.Range5Pct
|
|
||||||
# Description: Desired percentage of Alliance bots within level range 40-49.
|
|
||||||
# Default: 11
|
|
||||||
BotLevelBrackets.Alliance.Range5Pct = 11
|
|
||||||
|
|
||||||
# BotLevelBrackets.Alliance.Range6Pct
|
|
||||||
# Description: Desired percentage of Alliance bots within level range 50-59.
|
|
||||||
# Default: 11
|
|
||||||
BotLevelBrackets.Alliance.Range6Pct = 11
|
|
||||||
|
|
||||||
# BotLevelBrackets.Alliance.Range7Pct
|
|
||||||
# Description: Desired percentage of Alliance bots within level range 60-69.
|
|
||||||
# Default: 11
|
|
||||||
BotLevelBrackets.Alliance.Range7Pct = 11
|
|
||||||
|
|
||||||
# BotLevelBrackets.Alliance.Range8Pct
|
|
||||||
# Description: Desired percentage of Alliance bots within level range 70-79.
|
|
||||||
# Default: 11
|
|
||||||
BotLevelBrackets.Alliance.Range8Pct = 11
|
|
||||||
|
|
||||||
# BotLevelBrackets.Alliance.Range9Pct
|
|
||||||
# Description: Desired percentage of Alliance bots within level range 80.
|
|
||||||
# Default: 11
|
|
||||||
BotLevelBrackets.Alliance.Range9Pct = 11
|
|
||||||
|
|
||||||
#
|
#
|
||||||
|
# BotLevelBrackets.Alliance.RangeX.Upper
|
||||||
|
# Description: The upper bound (inclusive) of bracket X.
|
||||||
|
#
|
||||||
|
# BotLevelBrackets.Alliance.RangeX.Pct
|
||||||
|
# Description: The desired percentage of Alliance bots that should fall into bracket X.
|
||||||
|
#
|
||||||
|
# EXAMPLE:
|
||||||
|
# The default configuration below defines 9 brackets:
|
||||||
|
#
|
||||||
|
# Range1 covers levels 1-9, Range2 covers levels 10-19, Range3 covers levels 20-29, and so on.
|
||||||
|
#
|
||||||
|
# To customize or add a new bracket (for example, to isolate level 60 in its own bracket), you can:
|
||||||
|
# - Set Range7.Lower = 60 and Range7.Upper = 60, then adjust the Pct values for Range6 and Range8 accordingly.
|
||||||
|
#
|
||||||
|
# Also, if you want to add an extra bracket beyond the default 9, you must:
|
||||||
|
# 1. Increase BotLevelBrackets.NumRanges to the desired number.
|
||||||
|
# 2. Add configuration lines for the new RangeX.Lower, RangeX.Upper, and RangeX.Pct.
|
||||||
|
#
|
||||||
|
# NOTE:
|
||||||
|
# The sum of all Pct values for the Alliance brackets must equal 100.
|
||||||
|
#
|
||||||
|
BotLevelBrackets.Alliance.Range1.Lower = 1
|
||||||
|
BotLevelBrackets.Alliance.Range1.Upper = 9
|
||||||
|
BotLevelBrackets.Alliance.Range1.Pct = 12
|
||||||
|
|
||||||
|
BotLevelBrackets.Alliance.Range2.Lower = 10
|
||||||
|
BotLevelBrackets.Alliance.Range2.Upper = 19
|
||||||
|
BotLevelBrackets.Alliance.Range2.Pct = 11
|
||||||
|
|
||||||
|
BotLevelBrackets.Alliance.Range3.Lower = 20
|
||||||
|
BotLevelBrackets.Alliance.Range3.Upper = 29
|
||||||
|
BotLevelBrackets.Alliance.Range3.Pct = 11
|
||||||
|
|
||||||
|
BotLevelBrackets.Alliance.Range4.Lower = 30
|
||||||
|
BotLevelBrackets.Alliance.Range4.Upper = 39
|
||||||
|
BotLevelBrackets.Alliance.Range4.Pct = 11
|
||||||
|
|
||||||
|
BotLevelBrackets.Alliance.Range5.Lower = 40
|
||||||
|
BotLevelBrackets.Alliance.Range5.Upper = 49
|
||||||
|
BotLevelBrackets.Alliance.Range5.Pct = 11
|
||||||
|
|
||||||
|
BotLevelBrackets.Alliance.Range6.Lower = 50
|
||||||
|
BotLevelBrackets.Alliance.Range6.Upper = 59
|
||||||
|
BotLevelBrackets.Alliance.Range6.Pct = 11
|
||||||
|
|
||||||
|
BotLevelBrackets.Alliance.Range7.Lower = 60
|
||||||
|
BotLevelBrackets.Alliance.Range7.Upper = 69
|
||||||
|
BotLevelBrackets.Alliance.Range7.Pct = 11
|
||||||
|
|
||||||
|
BotLevelBrackets.Alliance.Range8.Lower = 70
|
||||||
|
BotLevelBrackets.Alliance.Range8.Upper = 79
|
||||||
|
BotLevelBrackets.Alliance.Range8.Pct = 11
|
||||||
|
|
||||||
|
BotLevelBrackets.Alliance.Range9.Lower = 80
|
||||||
|
BotLevelBrackets.Alliance.Range9.Upper = 80
|
||||||
|
BotLevelBrackets.Alliance.Range9.Pct = 11
|
||||||
|
|
||||||
|
##############################################
|
||||||
# Horde Level Brackets Configuration
|
# Horde Level Brackets Configuration
|
||||||
# The percentages below must sum to 100.
|
##############################################
|
||||||
|
# The following settings define the level brackets for Horde bots.
|
||||||
|
# For each bracket, you must specify:
|
||||||
#
|
#
|
||||||
# BotLevelBrackets.Horde.Range1Pct
|
# BotLevelBrackets.Horde.RangeX.Lower
|
||||||
# Description: Desired percentage of Horde bots within level range 1-9.
|
# Description: The lower bound (inclusive) of bracket X.
|
||||||
# Default: 12
|
#
|
||||||
BotLevelBrackets.Horde.Range1Pct = 12
|
# BotLevelBrackets.Horde.RangeX.Upper
|
||||||
|
# Description: The upper bound (inclusive) of bracket X.
|
||||||
|
#
|
||||||
|
# BotLevelBrackets.Horde.RangeX.Pct
|
||||||
|
# Description: The desired percentage of Horde bots that should fall into bracket X.
|
||||||
|
#
|
||||||
|
# EXAMPLE:
|
||||||
|
# The default configuration below defines 9 brackets:
|
||||||
|
#
|
||||||
|
# Range1 covers levels 1-9, Range2 covers levels 10-19, Range3 covers levels 20-29, and so on.
|
||||||
|
#
|
||||||
|
# To customize or add a new bracket (for example, to isolate level 70 in its own bracket), you can:
|
||||||
|
# - Set Range8.Lower = 70 and Range8.Upper = 70, then adjust the Pct values for the adjacent ranges.
|
||||||
|
#
|
||||||
|
# NOTE:
|
||||||
|
# The sum of all Pct values for the Horde brackets must equal 100.
|
||||||
|
#
|
||||||
|
BotLevelBrackets.Horde.Range1.Lower = 1
|
||||||
|
BotLevelBrackets.Horde.Range1.Upper = 9
|
||||||
|
BotLevelBrackets.Horde.Range1.Pct = 12
|
||||||
|
|
||||||
# BotLevelBrackets.Horde.Range2Pct
|
BotLevelBrackets.Horde.Range2.Lower = 10
|
||||||
# Description: Desired percentage of Horde bots within level range 10-19.
|
BotLevelBrackets.Horde.Range2.Upper = 19
|
||||||
# Default: 11
|
BotLevelBrackets.Horde.Range2.Pct = 11
|
||||||
BotLevelBrackets.Horde.Range2Pct = 11
|
|
||||||
|
|
||||||
# BotLevelBrackets.Horde.Range3Pct
|
BotLevelBrackets.Horde.Range3.Lower = 20
|
||||||
# Description: Desired percentage of Horde bots within level range 20-29.
|
BotLevelBrackets.Horde.Range3.Upper = 29
|
||||||
# Default: 11
|
BotLevelBrackets.Horde.Range3.Pct = 11
|
||||||
BotLevelBrackets.Horde.Range3Pct = 11
|
|
||||||
|
|
||||||
# BotLevelBrackets.Horde.Range4Pct
|
BotLevelBrackets.Horde.Range4.Lower = 30
|
||||||
# Description: Desired percentage of Horde bots within level range 30-39.
|
BotLevelBrackets.Horde.Range4.Upper = 39
|
||||||
# Default: 11
|
BotLevelBrackets.Horde.Range4.Pct = 11
|
||||||
BotLevelBrackets.Horde.Range4Pct = 11
|
|
||||||
|
|
||||||
# BotLevelBrackets.Horde.Range5Pct
|
BotLevelBrackets.Horde.Range5.Lower = 40
|
||||||
# Description: Desired percentage of Horde bots within level range 40-49.
|
BotLevelBrackets.Horde.Range5.Upper = 49
|
||||||
# Default: 11
|
BotLevelBrackets.Horde.Range5.Pct = 11
|
||||||
BotLevelBrackets.Horde.Range5Pct = 11
|
|
||||||
|
|
||||||
# BotLevelBrackets.Horde.Range6Pct
|
BotLevelBrackets.Horde.Range6.Lower = 50
|
||||||
# Description: Desired percentage of Horde bots within level range 50-59.
|
BotLevelBrackets.Horde.Range6.Upper = 59
|
||||||
# Default: 11
|
BotLevelBrackets.Horde.Range6.Pct = 11
|
||||||
BotLevelBrackets.Horde.Range6Pct = 11
|
|
||||||
|
|
||||||
# BotLevelBrackets.Horde.Range7Pct
|
BotLevelBrackets.Horde.Range7.Lower = 60
|
||||||
# Description: Desired percentage of Horde bots within level range 60-69.
|
BotLevelBrackets.Horde.Range7.Upper = 69
|
||||||
# Default: 11
|
BotLevelBrackets.Horde.Range7.Pct = 11
|
||||||
BotLevelBrackets.Horde.Range7Pct = 11
|
|
||||||
|
|
||||||
# BotLevelBrackets.Horde.Range8Pct
|
BotLevelBrackets.Horde.Range8.Lower = 70
|
||||||
# Description: Desired percentage of Horde bots within level range 70-79.
|
BotLevelBrackets.Horde.Range8.Upper = 79
|
||||||
# Default: 11
|
BotLevelBrackets.Horde.Range8.Pct = 11
|
||||||
BotLevelBrackets.Horde.Range8Pct = 11
|
|
||||||
|
|
||||||
# BotLevelBrackets.Horde.Range9Pct
|
BotLevelBrackets.Horde.Range9.Lower = 80
|
||||||
# Description: Desired percentage of Horde bots within level range 80.
|
BotLevelBrackets.Horde.Range9.Upper = 80
|
||||||
# Default: 11
|
BotLevelBrackets.Horde.Range9.Pct = 11
|
||||||
BotLevelBrackets.Horde.Range9Pct = 11
|
|
||||||
|
|||||||
@@ -17,8 +17,9 @@
|
|||||||
#include "PlayerbotFactory.h"
|
#include "PlayerbotFactory.h"
|
||||||
#include "DatabaseEnv.h"
|
#include "DatabaseEnv.h"
|
||||||
#include "QueryResult.h"
|
#include "QueryResult.h"
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
// Forward declarations.
|
||||||
static bool IsAlliancePlayerBot(Player* bot);
|
static bool IsAlliancePlayerBot(Player* bot);
|
||||||
static bool IsHordePlayerBot(Player* bot);
|
static bool IsHordePlayerBot(Player* bot);
|
||||||
static void ClampAndBalanceBrackets();
|
static void ClampAndBalanceBrackets();
|
||||||
@@ -34,7 +35,8 @@ struct LevelRangeConfig
|
|||||||
uint8 desiredPercent;///< Desired percentage of bots in this range
|
uint8 desiredPercent;///< Desired percentage of bots in this range
|
||||||
};
|
};
|
||||||
|
|
||||||
static const uint8 NUM_RANGES = 9;
|
// Instead of a fixed constant, load the number of brackets from configuration.
|
||||||
|
static uint8 g_NumRanges = 9;
|
||||||
|
|
||||||
// Global variables to restrict bot levels.
|
// Global variables to restrict bot levels.
|
||||||
static uint8 g_RandomBotMinLevel = 1;
|
static uint8 g_RandomBotMinLevel = 1;
|
||||||
@@ -45,10 +47,9 @@ static bool g_BotLevelBracketsEnabled = true;
|
|||||||
// New configuration option to ignore bots in guilds with a real player online. Default is true.
|
// New configuration option to ignore bots in guilds with a real player online. Default is true.
|
||||||
static bool g_IgnoreGuildBotsWithRealPlayers = true;
|
static bool g_IgnoreGuildBotsWithRealPlayers = true;
|
||||||
|
|
||||||
// Separate arrays for Alliance and Horde.
|
// Use vectors to store the level ranges.
|
||||||
static LevelRangeConfig g_BaseLevelRanges[NUM_RANGES];
|
static std::vector<LevelRangeConfig> g_AllianceLevelRanges;
|
||||||
static LevelRangeConfig g_AllianceLevelRanges[NUM_RANGES];
|
static std::vector<LevelRangeConfig> g_HordeLevelRanges;
|
||||||
static LevelRangeConfig g_HordeLevelRanges[NUM_RANGES];
|
|
||||||
|
|
||||||
static uint32 g_BotDistCheckFrequency = 300; // in seconds
|
static uint32 g_BotDistCheckFrequency = 300; // in seconds
|
||||||
static uint32 g_BotDistFlaggedCheckFrequency = 15; // in seconds
|
static uint32 g_BotDistFlaggedCheckFrequency = 15; // in seconds
|
||||||
@@ -69,7 +70,6 @@ std::vector<int> SocialFriendsList;
|
|||||||
static void LoadBotLevelBracketsConfig()
|
static void LoadBotLevelBracketsConfig()
|
||||||
{
|
{
|
||||||
g_BotLevelBracketsEnabled = sConfigMgr->GetOption<bool>("BotLevelBrackets.Enabled", true);
|
g_BotLevelBracketsEnabled = sConfigMgr->GetOption<bool>("BotLevelBrackets.Enabled", true);
|
||||||
// Load the new option to ignore guild bots with a real player online.
|
|
||||||
g_IgnoreGuildBotsWithRealPlayers = sConfigMgr->GetOption<bool>("BotLevelBrackets.IgnoreGuildBotsWithRealPlayers", true);
|
g_IgnoreGuildBotsWithRealPlayers = sConfigMgr->GetOption<bool>("BotLevelBrackets.IgnoreGuildBotsWithRealPlayers", true);
|
||||||
|
|
||||||
g_BotDistFullDebugMode = sConfigMgr->GetOption<bool>("BotLevelBrackets.FullDebugMode", false);
|
g_BotDistFullDebugMode = sConfigMgr->GetOption<bool>("BotLevelBrackets.FullDebugMode", false);
|
||||||
@@ -84,27 +84,28 @@ static void LoadBotLevelBracketsConfig()
|
|||||||
g_RandomBotMinLevel = static_cast<uint8>(sConfigMgr->GetOption<uint32>("AiPlayerbot.RandomBotMinLevel", 1));
|
g_RandomBotMinLevel = static_cast<uint8>(sConfigMgr->GetOption<uint32>("AiPlayerbot.RandomBotMinLevel", 1));
|
||||||
g_RandomBotMaxLevel = static_cast<uint8>(sConfigMgr->GetOption<uint32>("AiPlayerbot.RandomBotMaxLevel", 80));
|
g_RandomBotMaxLevel = static_cast<uint8>(sConfigMgr->GetOption<uint32>("AiPlayerbot.RandomBotMaxLevel", 80));
|
||||||
|
|
||||||
// Alliance configuration.
|
// Load the custom number of brackets.
|
||||||
g_AllianceLevelRanges[0] = { 1, 9, static_cast<uint8>(sConfigMgr->GetOption<uint32>("BotLevelBrackets.Alliance.Range1Pct", 12)) };
|
g_NumRanges = static_cast<uint8>(sConfigMgr->GetOption<uint32>("BotLevelBrackets.NumRanges", 9));
|
||||||
g_AllianceLevelRanges[1] = { 10, 19, static_cast<uint8>(sConfigMgr->GetOption<uint32>("BotLevelBrackets.Alliance.Range2Pct", 11)) };
|
g_AllianceLevelRanges.resize(g_NumRanges);
|
||||||
g_AllianceLevelRanges[2] = { 20, 29, static_cast<uint8>(sConfigMgr->GetOption<uint32>("BotLevelBrackets.Alliance.Range3Pct", 11)) };
|
g_HordeLevelRanges.resize(g_NumRanges);
|
||||||
g_AllianceLevelRanges[3] = { 30, 39, static_cast<uint8>(sConfigMgr->GetOption<uint32>("BotLevelBrackets.Alliance.Range4Pct", 11)) };
|
|
||||||
g_AllianceLevelRanges[4] = { 40, 49, static_cast<uint8>(sConfigMgr->GetOption<uint32>("BotLevelBrackets.Alliance.Range5Pct", 11)) };
|
|
||||||
g_AllianceLevelRanges[5] = { 50, 59, static_cast<uint8>(sConfigMgr->GetOption<uint32>("BotLevelBrackets.Alliance.Range6Pct", 11)) };
|
|
||||||
g_AllianceLevelRanges[6] = { 60, 69, static_cast<uint8>(sConfigMgr->GetOption<uint32>("BotLevelBrackets.Alliance.Range7Pct", 11)) };
|
|
||||||
g_AllianceLevelRanges[7] = { 70, 79, static_cast<uint8>(sConfigMgr->GetOption<uint32>("BotLevelBrackets.Alliance.Range8Pct", 11)) };
|
|
||||||
g_AllianceLevelRanges[8] = { 80, 80, static_cast<uint8>(sConfigMgr->GetOption<uint32>("BotLevelBrackets.Alliance.Range9Pct", 11)) };
|
|
||||||
|
|
||||||
// Horde configuration.
|
// Load Alliance configuration.
|
||||||
g_HordeLevelRanges[0] = { 1, 9, static_cast<uint8>(sConfigMgr->GetOption<uint32>("BotLevelBrackets.Horde.Range1Pct", 12)) };
|
for (uint8 i = 0; i < g_NumRanges; ++i)
|
||||||
g_HordeLevelRanges[1] = { 10, 19, static_cast<uint8>(sConfigMgr->GetOption<uint32>("BotLevelBrackets.Horde.Range2Pct", 11)) };
|
{
|
||||||
g_HordeLevelRanges[2] = { 20, 29, static_cast<uint8>(sConfigMgr->GetOption<uint32>("BotLevelBrackets.Horde.Range3Pct", 11)) };
|
std::string idx = std::to_string(i + 1);
|
||||||
g_HordeLevelRanges[3] = { 30, 39, static_cast<uint8>(sConfigMgr->GetOption<uint32>("BotLevelBrackets.Horde.Range4Pct", 11)) };
|
g_AllianceLevelRanges[i].lower = static_cast<uint8>(sConfigMgr->GetOption<uint32>("BotLevelBrackets.Alliance.Range" + idx + ".Lower", (i == 0 ? 1 : i * 10)));
|
||||||
g_HordeLevelRanges[4] = { 40, 49, static_cast<uint8>(sConfigMgr->GetOption<uint32>("BotLevelBrackets.Horde.Range5Pct", 11)) };
|
g_AllianceLevelRanges[i].upper = static_cast<uint8>(sConfigMgr->GetOption<uint32>("BotLevelBrackets.Alliance.Range" + idx + ".Upper", (i < g_NumRanges - 1 ? i * 10 + 9 : g_RandomBotMaxLevel)));
|
||||||
g_HordeLevelRanges[5] = { 50, 59, static_cast<uint8>(sConfigMgr->GetOption<uint32>("BotLevelBrackets.Horde.Range6Pct", 11)) };
|
g_AllianceLevelRanges[i].desiredPercent = static_cast<uint8>(sConfigMgr->GetOption<uint32>("BotLevelBrackets.Alliance.Range" + idx + ".Pct", 11));
|
||||||
g_HordeLevelRanges[6] = { 60, 69, static_cast<uint8>(sConfigMgr->GetOption<uint32>("BotLevelBrackets.Horde.Range7Pct", 11)) };
|
}
|
||||||
g_HordeLevelRanges[7] = { 70, 79, static_cast<uint8>(sConfigMgr->GetOption<uint32>("BotLevelBrackets.Horde.Range8Pct", 11)) };
|
|
||||||
g_HordeLevelRanges[8] = { 80, 80, static_cast<uint8>(sConfigMgr->GetOption<uint32>("BotLevelBrackets.Horde.Range9Pct", 11)) };
|
// Load Horde configuration.
|
||||||
|
for (uint8 i = 0; i < g_NumRanges; ++i)
|
||||||
|
{
|
||||||
|
std::string idx = std::to_string(i + 1);
|
||||||
|
g_HordeLevelRanges[i].lower = static_cast<uint8>(sConfigMgr->GetOption<uint32>("BotLevelBrackets.Horde.Range" + idx + ".Lower", (i == 0 ? 1 : i * 10)));
|
||||||
|
g_HordeLevelRanges[i].upper = static_cast<uint8>(sConfigMgr->GetOption<uint32>("BotLevelBrackets.Horde.Range" + idx + ".Upper", (i < g_NumRanges - 1 ? i * 10 + 9 : g_RandomBotMaxLevel)));
|
||||||
|
g_HordeLevelRanges[i].desiredPercent = static_cast<uint8>(sConfigMgr->GetOption<uint32>("BotLevelBrackets.Horde.Range" + idx + ".Pct", 11));
|
||||||
|
}
|
||||||
|
|
||||||
ClampAndBalanceBrackets();
|
ClampAndBalanceBrackets();
|
||||||
}
|
}
|
||||||
@@ -118,11 +119,13 @@ static void LoadSocialFriendList()
|
|||||||
QueryResult result = CharacterDatabase.Query("SELECT friend FROM character_social WHERE flags = 1");
|
QueryResult result = CharacterDatabase.Query("SELECT friend FROM character_social WHERE flags = 1");
|
||||||
|
|
||||||
if (!result)
|
if (!result)
|
||||||
|
{
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
if (result->GetRowCount() == 0)
|
if (result->GetRowCount() == 0)
|
||||||
|
{
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
if (g_BotDistFullDebugMode)
|
if (g_BotDistFullDebugMode)
|
||||||
{
|
{
|
||||||
LOG_INFO("server.loading", "[BotLevelBrackets] Fetching Social Friend List GUIDs into array");
|
LOG_INFO("server.loading", "[BotLevelBrackets] Fetching Social Friend List GUIDs into array");
|
||||||
@@ -137,34 +140,37 @@ static void LoadSocialFriendList()
|
|||||||
LOG_INFO("server.load", "[BotLevelBrackets] Adding GUID {} to Social Friend List", socialFriendGUID);
|
LOG_INFO("server.load", "[BotLevelBrackets] Adding GUID {} to Social Friend List", socialFriendGUID);
|
||||||
}
|
}
|
||||||
} while (result->NextRow());
|
} while (result->NextRow());
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Returns the index of the level range bracket that the given level belongs to.
|
// Returns the index of the level bracket that the given level belongs to.
|
||||||
// If the bot is out of range, it returns -1
|
// If the bot is out of range, it returns -1
|
||||||
static int GetLevelRangeIndex(uint8 level, uint8 teamID)
|
static int GetLevelRangeIndex(uint8 level, uint8 teamID)
|
||||||
{
|
{
|
||||||
// If the bot's level is outside the allowed global bounds, signal an invalid bracket.
|
|
||||||
if (level < g_RandomBotMinLevel || level > g_RandomBotMaxLevel)
|
if (level < g_RandomBotMinLevel || level > g_RandomBotMaxLevel)
|
||||||
return -1;
|
|
||||||
|
|
||||||
if(teamID == TEAM_ALLIANCE)
|
|
||||||
{
|
{
|
||||||
for (int i = 0; i < NUM_RANGES; ++i)
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (teamID == TEAM_ALLIANCE)
|
||||||
|
{
|
||||||
|
for (uint8 i = 0; i < g_NumRanges; ++i)
|
||||||
{
|
{
|
||||||
if (level >= g_AllianceLevelRanges[i].lower && level <= g_AllianceLevelRanges[i].upper)
|
if (level >= g_AllianceLevelRanges[i].lower && level <= g_AllianceLevelRanges[i].upper)
|
||||||
|
{
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
if(teamID == TEAM_HORDE)
|
else if (teamID == TEAM_HORDE)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < NUM_RANGES; ++i)
|
for (uint8 i = 0; i < g_NumRanges; ++i)
|
||||||
{
|
{
|
||||||
if (level >= g_HordeLevelRanges[i].lower && level <= g_HordeLevelRanges[i].upper)
|
if (level >= g_HordeLevelRanges[i].lower && level <= g_HordeLevelRanges[i].upper)
|
||||||
|
{
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@@ -178,8 +184,10 @@ static uint8 GetRandomLevelInRange(const LevelRangeConfig& range)
|
|||||||
// Adjusts a bot's level by selecting a random level within the target range.
|
// Adjusts a bot's level by selecting a random level within the target range.
|
||||||
static void AdjustBotToRange(Player* bot, int targetRangeIndex, const LevelRangeConfig* factionRanges)
|
static void AdjustBotToRange(Player* bot, int targetRangeIndex, const LevelRangeConfig* factionRanges)
|
||||||
{
|
{
|
||||||
if (!bot || targetRangeIndex < 0 || targetRangeIndex >= NUM_RANGES)
|
if (!bot || targetRangeIndex < 0 || targetRangeIndex >= g_NumRanges)
|
||||||
|
{
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (bot->IsMounted())
|
if (bot->IsMounted())
|
||||||
{
|
{
|
||||||
@@ -206,7 +214,9 @@ static void AdjustBotToRange(Player* bot, int targetRangeIndex, const LevelRange
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (lowerBound < 55)
|
if (lowerBound < 55)
|
||||||
|
{
|
||||||
lowerBound = 55;
|
lowerBound = 55;
|
||||||
|
}
|
||||||
newLevel = urand(lowerBound, upperBound);
|
newLevel = urand(lowerBound, upperBound);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -215,7 +225,6 @@ static void AdjustBotToRange(Player* bot, int targetRangeIndex, const LevelRange
|
|||||||
}
|
}
|
||||||
|
|
||||||
PlayerbotFactory newFactory(bot, newLevel);
|
PlayerbotFactory newFactory(bot, newLevel);
|
||||||
|
|
||||||
newFactory.Randomize(false);
|
newFactory.Randomize(false);
|
||||||
|
|
||||||
if (g_BotDistFullDebugMode)
|
if (g_BotDistFullDebugMode)
|
||||||
@@ -238,7 +247,9 @@ static void AdjustBotToRange(Player* bot, int targetRangeIndex, const LevelRange
|
|||||||
static bool IsPlayerBot(Player* player)
|
static bool IsPlayerBot(Player* player)
|
||||||
{
|
{
|
||||||
if (!player)
|
if (!player)
|
||||||
|
{
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
PlayerbotAI* botAI = sPlayerbotsMgr->GetPlayerbotAI(player);
|
PlayerbotAI* botAI = sPlayerbotsMgr->GetPlayerbotAI(player);
|
||||||
return botAI && botAI->IsBotAI();
|
return botAI && botAI->IsBotAI();
|
||||||
}
|
}
|
||||||
@@ -246,20 +257,19 @@ static bool IsPlayerBot(Player* player)
|
|||||||
static bool IsPlayerRandomBot(Player* player)
|
static bool IsPlayerRandomBot(Player* player)
|
||||||
{
|
{
|
||||||
if (!player)
|
if (!player)
|
||||||
|
{
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
return sRandomPlayerbotMgr->IsRandomBot(player);
|
return sRandomPlayerbotMgr->IsRandomBot(player);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Helper functions to determine faction.
|
|
||||||
static bool IsAlliancePlayerBot(Player* bot)
|
static bool IsAlliancePlayerBot(Player* bot)
|
||||||
{
|
{
|
||||||
// Assumes GetTeam() returns TEAM_ALLIANCE for Alliance bots.
|
|
||||||
return bot && (bot->GetTeamId() == TEAM_ALLIANCE);
|
return bot && (bot->GetTeamId() == TEAM_ALLIANCE);
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool IsHordePlayerBot(Player* bot)
|
static bool IsHordePlayerBot(Player* bot)
|
||||||
{
|
{
|
||||||
// Assumes GetTeam() returns TEAM_HORDE for Horde bots.
|
|
||||||
return bot && (bot->GetTeamId() == TEAM_HORDE);
|
return bot && (bot->GetTeamId() == TEAM_HORDE);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -272,11 +282,14 @@ static void LogAllBotLevels()
|
|||||||
{
|
{
|
||||||
Player* player = itr.second;
|
Player* player = itr.second;
|
||||||
if (!player || !player->IsInWorld())
|
if (!player || !player->IsInWorld())
|
||||||
|
{
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
if (!IsPlayerBot(player))
|
if (!IsPlayerBot(player))
|
||||||
|
{
|
||||||
continue;
|
continue;
|
||||||
uint8 level = player->GetLevel();
|
}
|
||||||
botLevelCount[level]++;
|
botLevelCount[player->GetLevel()]++;
|
||||||
}
|
}
|
||||||
for (const auto& entry : botLevelCount)
|
for (const auto& entry : botLevelCount)
|
||||||
{
|
{
|
||||||
@@ -291,28 +304,36 @@ static void LogAllBotLevels()
|
|||||||
static bool BotInGuildWithRealPlayer(Player* bot)
|
static bool BotInGuildWithRealPlayer(Player* bot)
|
||||||
{
|
{
|
||||||
if (!bot)
|
if (!bot)
|
||||||
|
{
|
||||||
return false;
|
return false;
|
||||||
// If the bot is not in a guild, nothing to do.
|
}
|
||||||
uint32 guildId = bot->GetGuildId();
|
uint32 guildId = bot->GetGuildId();
|
||||||
if (guildId == 0)
|
if (guildId == 0)
|
||||||
|
{
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
// Iterate over all players and check for an online, non-bot member in the same guild.
|
|
||||||
for (auto const& itr : ObjectAccessor::GetPlayers())
|
for (auto const& itr : ObjectAccessor::GetPlayers())
|
||||||
{
|
{
|
||||||
Player* member = itr.second;
|
Player* member = itr.second;
|
||||||
if (!member || !member->IsInWorld())
|
if (!member || !member->IsInWorld())
|
||||||
|
{
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
if (!IsPlayerBot(member) && member->GetGuildId() == guildId)
|
if (!IsPlayerBot(member) && member->GetGuildId() == guildId)
|
||||||
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool BotInFriendList(Player* bot)
|
static bool BotInFriendList(Player* bot)
|
||||||
{
|
{
|
||||||
if (!bot)
|
if (!bot)
|
||||||
|
{
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
for (size_t i = 0; i < SocialFriendsList.size(); ++i)
|
for (size_t i = 0; i < SocialFriendsList.size(); ++i)
|
||||||
{
|
{
|
||||||
@@ -334,51 +355,55 @@ static bool BotInFriendList(Player* bot)
|
|||||||
|
|
||||||
static void ClampAndBalanceBrackets()
|
static void ClampAndBalanceBrackets()
|
||||||
{
|
{
|
||||||
// First, adjust Alliance brackets.
|
for (uint8 i = 0; i < g_NumRanges; ++i)
|
||||||
for (uint8 i = 0; i < NUM_RANGES; ++i)
|
|
||||||
{
|
{
|
||||||
if (g_AllianceLevelRanges[i].lower < g_RandomBotMinLevel)
|
if (g_AllianceLevelRanges[i].lower < g_RandomBotMinLevel)
|
||||||
|
{
|
||||||
g_AllianceLevelRanges[i].lower = g_RandomBotMinLevel;
|
g_AllianceLevelRanges[i].lower = g_RandomBotMinLevel;
|
||||||
|
}
|
||||||
if (g_AllianceLevelRanges[i].upper > g_RandomBotMaxLevel)
|
if (g_AllianceLevelRanges[i].upper > g_RandomBotMaxLevel)
|
||||||
|
{
|
||||||
g_AllianceLevelRanges[i].upper = g_RandomBotMaxLevel;
|
g_AllianceLevelRanges[i].upper = g_RandomBotMaxLevel;
|
||||||
// If the adjusted bracket is invalid, mark it to not be used.
|
}
|
||||||
if (g_AllianceLevelRanges[i].lower > g_AllianceLevelRanges[i].upper)
|
if (g_AllianceLevelRanges[i].lower > g_AllianceLevelRanges[i].upper)
|
||||||
|
{
|
||||||
g_AllianceLevelRanges[i].desiredPercent = 0;
|
g_AllianceLevelRanges[i].desiredPercent = 0;
|
||||||
}
|
}
|
||||||
// Then, adjust Horde brackets similarly.
|
}
|
||||||
for (uint8 i = 0; i < NUM_RANGES; ++i)
|
for (uint8 i = 0; i < g_NumRanges; ++i)
|
||||||
{
|
{
|
||||||
if (g_HordeLevelRanges[i].lower < g_RandomBotMinLevel)
|
if (g_HordeLevelRanges[i].lower < g_RandomBotMinLevel)
|
||||||
|
{
|
||||||
g_HordeLevelRanges[i].lower = g_RandomBotMinLevel;
|
g_HordeLevelRanges[i].lower = g_RandomBotMinLevel;
|
||||||
|
}
|
||||||
if (g_HordeLevelRanges[i].upper > g_RandomBotMaxLevel)
|
if (g_HordeLevelRanges[i].upper > g_RandomBotMaxLevel)
|
||||||
|
{
|
||||||
g_HordeLevelRanges[i].upper = g_RandomBotMaxLevel;
|
g_HordeLevelRanges[i].upper = g_RandomBotMaxLevel;
|
||||||
|
}
|
||||||
if (g_HordeLevelRanges[i].lower > g_HordeLevelRanges[i].upper)
|
if (g_HordeLevelRanges[i].lower > g_HordeLevelRanges[i].upper)
|
||||||
|
{
|
||||||
g_HordeLevelRanges[i].desiredPercent = 0;
|
g_HordeLevelRanges[i].desiredPercent = 0;
|
||||||
}
|
}
|
||||||
// Balance desired percentages so the sum is 100.
|
}
|
||||||
uint32 totalAlliance = 0;
|
uint32 totalAlliance = 0;
|
||||||
uint32 totalHorde = 0;
|
uint32 totalHorde = 0;
|
||||||
for (uint8 i = 0; i < NUM_RANGES; ++i)
|
for (uint8 i = 0; i < g_NumRanges; ++i)
|
||||||
{
|
{
|
||||||
totalAlliance += g_AllianceLevelRanges[i].desiredPercent;
|
totalAlliance += g_AllianceLevelRanges[i].desiredPercent;
|
||||||
totalHorde += g_HordeLevelRanges[i].desiredPercent;
|
totalHorde += g_HordeLevelRanges[i].desiredPercent;
|
||||||
}
|
}
|
||||||
// If totals are not 100, then distribute the missing percent among valid brackets.
|
if (totalAlliance != 100 && totalAlliance > 0)
|
||||||
if(totalAlliance != 100 && totalAlliance > 0)
|
|
||||||
{
|
{
|
||||||
|
|
||||||
if (g_BotDistFullDebugMode)
|
if (g_BotDistFullDebugMode)
|
||||||
{
|
{
|
||||||
LOG_INFO("server.loading", "[BotLevelBrackets] Alliance: Sum of percentages is {} (expected 100). Auto adjusting.", totalAlliance);
|
LOG_INFO("server.loading", "[BotLevelBrackets] Alliance: Sum of percentages is {} (expected 100). Auto adjusting.", totalAlliance);
|
||||||
}
|
}
|
||||||
|
|
||||||
int missing = 100 - totalAlliance;
|
int missing = 100 - totalAlliance;
|
||||||
while(missing > 0)
|
while (missing > 0)
|
||||||
{
|
{
|
||||||
for (uint8 i = 0; i < NUM_RANGES && missing > 0; ++i)
|
for (uint8 i = 0; i < g_NumRanges && missing > 0; ++i)
|
||||||
{
|
{
|
||||||
if(g_AllianceLevelRanges[i].lower <= g_AllianceLevelRanges[i].upper &&
|
if (g_AllianceLevelRanges[i].lower <= g_AllianceLevelRanges[i].upper && g_AllianceLevelRanges[i].desiredPercent > 0)
|
||||||
g_AllianceLevelRanges[i].desiredPercent > 0)
|
|
||||||
{
|
{
|
||||||
g_AllianceLevelRanges[i].desiredPercent++;
|
g_AllianceLevelRanges[i].desiredPercent++;
|
||||||
missing--;
|
missing--;
|
||||||
@@ -386,20 +411,18 @@ static void ClampAndBalanceBrackets()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(totalHorde != 100 && totalHorde > 0)
|
if (totalHorde != 100 && totalHorde > 0)
|
||||||
{
|
{
|
||||||
if (g_BotDistFullDebugMode)
|
if (g_BotDistFullDebugMode)
|
||||||
{
|
{
|
||||||
LOG_INFO("server.loading", "[BotLevelBrackets] Horde: Sum of percentages is {} (expected 100). Auto adjusting.", totalHorde);
|
LOG_INFO("server.loading", "[BotLevelBrackets] Horde: Sum of percentages is {} (expected 100). Auto adjusting.", totalHorde);
|
||||||
}
|
}
|
||||||
|
|
||||||
int missing = 100 - totalHorde;
|
int missing = 100 - totalHorde;
|
||||||
while(missing > 0)
|
while (missing > 0)
|
||||||
{
|
{
|
||||||
for (uint8 i = 0; i < NUM_RANGES && missing > 0; ++i)
|
for (uint8 i = 0; i < g_NumRanges && missing > 0; ++i)
|
||||||
{
|
{
|
||||||
if(g_HordeLevelRanges[i].lower <= g_HordeLevelRanges[i].upper &&
|
if (g_HordeLevelRanges[i].lower <= g_HordeLevelRanges[i].upper && g_HordeLevelRanges[i].desiredPercent > 0)
|
||||||
g_HordeLevelRanges[i].desiredPercent > 0)
|
|
||||||
{
|
{
|
||||||
g_HordeLevelRanges[i].desiredPercent++;
|
g_HordeLevelRanges[i].desiredPercent++;
|
||||||
missing--;
|
missing--;
|
||||||
@@ -477,11 +500,9 @@ static bool IsBotSafeForLevelReset(Player* bot)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Global container to hold bots flagged for pending level reset.
|
// Global container to hold bots flagged for pending level reset.
|
||||||
// Each entry is a pair: the bot and the target level range index along with a pointer to the faction config.
|
// Each entry is a pair: the bot and the target level range index along with a pointer to the faction config.
|
||||||
struct PendingResetEntry
|
struct PendingResetEntry
|
||||||
@@ -498,15 +519,15 @@ static void ProcessPendingLevelResets()
|
|||||||
{
|
{
|
||||||
LOG_INFO("server.loading", "[BotLevelBrackets] Processing {} pending resets...", g_PendingLevelResets.size());
|
LOG_INFO("server.loading", "[BotLevelBrackets] Processing {} pending resets...", g_PendingLevelResets.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (g_PendingLevelResets.empty())
|
if (g_PendingLevelResets.empty())
|
||||||
|
{
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
for (auto it = g_PendingLevelResets.begin(); it != g_PendingLevelResets.end(); )
|
for (auto it = g_PendingLevelResets.begin(); it != g_PendingLevelResets.end(); )
|
||||||
{
|
{
|
||||||
Player* bot = it->bot;
|
Player* bot = it->bot;
|
||||||
int targetRange = it->targetRange;
|
int targetRange = it->targetRange;
|
||||||
// If the bot is in a guild with a real player online and the option is enabled, remove it from pending resets.
|
|
||||||
if (g_IgnoreGuildBotsWithRealPlayers && BotInGuildWithRealPlayer(bot))
|
if (g_IgnoreGuildBotsWithRealPlayers && BotInGuildWithRealPlayer(bot))
|
||||||
{
|
{
|
||||||
it = g_PendingLevelResets.erase(it);
|
it = g_PendingLevelResets.erase(it);
|
||||||
@@ -541,29 +562,41 @@ static int GetOrFlagPlayerBracket(Player* player)
|
|||||||
{
|
{
|
||||||
int rangeIndex = GetLevelRangeIndex(player->GetLevel(), player->GetTeamId());
|
int rangeIndex = GetLevelRangeIndex(player->GetLevel(), player->GetTeamId());
|
||||||
if (rangeIndex >= 0)
|
if (rangeIndex >= 0)
|
||||||
|
{
|
||||||
return rangeIndex;
|
return rangeIndex;
|
||||||
|
}
|
||||||
|
|
||||||
LevelRangeConfig* factionRanges = nullptr;
|
LevelRangeConfig* factionRanges = nullptr;
|
||||||
if (IsAlliancePlayerBot(player))
|
if (IsAlliancePlayerBot(player))
|
||||||
factionRanges = g_AllianceLevelRanges;
|
{
|
||||||
|
factionRanges = g_AllianceLevelRanges.data();
|
||||||
|
}
|
||||||
else if (IsHordePlayerBot(player))
|
else if (IsHordePlayerBot(player))
|
||||||
factionRanges = g_HordeLevelRanges;
|
{
|
||||||
|
factionRanges = g_HordeLevelRanges.data();
|
||||||
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
return -1; // Unknown faction
|
return -1; // Unknown faction
|
||||||
|
}
|
||||||
|
|
||||||
// Player's level did not fall into any base range; compute the closest valid bracket.
|
|
||||||
int targetRange = -1;
|
int targetRange = -1;
|
||||||
int smallestDiff = std::numeric_limits<int>::max();
|
int smallestDiff = std::numeric_limits<int>::max();
|
||||||
for (int i = 0; i < NUM_RANGES; ++i)
|
for (int i = 0; i < g_NumRanges; ++i)
|
||||||
{
|
{
|
||||||
// Only consider valid brackets (those not disabled by ClampAndBalanceBrackets)
|
|
||||||
if (factionRanges[i].lower > factionRanges[i].upper)
|
if (factionRanges[i].lower > factionRanges[i].upper)
|
||||||
|
{
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
int diff = 0;
|
int diff = 0;
|
||||||
if (player->GetLevel() < factionRanges[i].lower)
|
if (player->GetLevel() < factionRanges[i].lower)
|
||||||
|
{
|
||||||
diff = factionRanges[i].lower - player->GetLevel();
|
diff = factionRanges[i].lower - player->GetLevel();
|
||||||
|
}
|
||||||
else if (player->GetLevel() > factionRanges[i].upper)
|
else if (player->GetLevel() > factionRanges[i].upper)
|
||||||
|
{
|
||||||
diff = player->GetLevel() - factionRanges[i].upper;
|
diff = player->GetLevel() - factionRanges[i].upper;
|
||||||
|
}
|
||||||
if (diff < smallestDiff)
|
if (diff < smallestDiff)
|
||||||
{
|
{
|
||||||
smallestDiff = diff;
|
smallestDiff = diff;
|
||||||
@@ -573,7 +606,6 @@ static int GetOrFlagPlayerBracket(Player* player)
|
|||||||
|
|
||||||
if (targetRange >= 0)
|
if (targetRange >= 0)
|
||||||
{
|
{
|
||||||
// Add the player to the pending reset list if not already flagged.
|
|
||||||
bool alreadyFlagged = false;
|
bool alreadyFlagged = false;
|
||||||
for (const auto &entry : g_PendingLevelResets)
|
for (const auto &entry : g_PendingLevelResets)
|
||||||
{
|
{
|
||||||
@@ -612,12 +644,12 @@ public:
|
|||||||
if (g_BotDistFullDebugMode || g_BotDistLiteDebugMode)
|
if (g_BotDistFullDebugMode || g_BotDistLiteDebugMode)
|
||||||
{
|
{
|
||||||
LOG_INFO("server.loading", "[BotLevelBrackets] Module loaded. Check frequency: {} seconds, Check flagged frequency: {}.", g_BotDistCheckFrequency, g_BotDistFlaggedCheckFrequency);
|
LOG_INFO("server.loading", "[BotLevelBrackets] Module loaded. Check frequency: {} seconds, Check flagged frequency: {}.", g_BotDistCheckFrequency, g_BotDistFlaggedCheckFrequency);
|
||||||
for (uint8 i = 0; i < NUM_RANGES; ++i)
|
for (uint8 i = 0; i < g_NumRanges; ++i)
|
||||||
{
|
{
|
||||||
LOG_INFO("server.loading", "[BotLevelBrackets] Alliance Range {}: {}-{}, Desired Percentage: {}%",
|
LOG_INFO("server.loading", "[BotLevelBrackets] Alliance Range {}: {}-{}, Desired Percentage: {}%",
|
||||||
i + 1, g_AllianceLevelRanges[i].lower, g_AllianceLevelRanges[i].upper, g_AllianceLevelRanges[i].desiredPercent);
|
i + 1, g_AllianceLevelRanges[i].lower, g_AllianceLevelRanges[i].upper, g_AllianceLevelRanges[i].desiredPercent);
|
||||||
}
|
}
|
||||||
for (uint8 i = 0; i < NUM_RANGES; ++i)
|
for (uint8 i = 0; i < g_NumRanges; ++i)
|
||||||
{
|
{
|
||||||
LOG_INFO("server.loading", "[BotLevelBrackets] Horde Range {}: {}-{}, Desired Percentage: {}%",
|
LOG_INFO("server.loading", "[BotLevelBrackets] Horde Range {}: {}-{}, Desired Percentage: {}%",
|
||||||
i + 1, g_HordeLevelRanges[i].lower, g_HordeLevelRanges[i].upper, g_HordeLevelRanges[i].desiredPercent);
|
i + 1, g_HordeLevelRanges[i].lower, g_HordeLevelRanges[i].upper, g_HordeLevelRanges[i].desiredPercent);
|
||||||
@@ -628,12 +660,13 @@ public:
|
|||||||
void OnUpdate(uint32 diff) override
|
void OnUpdate(uint32 diff) override
|
||||||
{
|
{
|
||||||
if (!g_BotLevelBracketsEnabled)
|
if (!g_BotLevelBracketsEnabled)
|
||||||
|
{
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
m_timer += diff;
|
m_timer += diff;
|
||||||
m_flaggedTimer += diff;
|
m_flaggedTimer += diff;
|
||||||
|
|
||||||
// Process pending level resets.
|
|
||||||
if (m_flaggedTimer >= g_BotDistFlaggedCheckFrequency * 1000)
|
if (m_flaggedTimer >= g_BotDistFlaggedCheckFrequency * 1000)
|
||||||
{
|
{
|
||||||
if (g_BotDistFullDebugMode)
|
if (g_BotDistFullDebugMode)
|
||||||
@@ -644,32 +677,36 @@ public:
|
|||||||
m_flaggedTimer = 0;
|
m_flaggedTimer = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Continue with distribution adjustments once the timer expires.
|
|
||||||
if (m_timer < g_BotDistCheckFrequency * 1000)
|
if (m_timer < g_BotDistCheckFrequency * 1000)
|
||||||
|
{
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
m_timer = 0;
|
m_timer = 0;
|
||||||
|
|
||||||
// Refresh Social Friends List Array
|
|
||||||
LoadSocialFriendList();
|
LoadSocialFriendList();
|
||||||
|
|
||||||
// Dynamic distribution: recalc desired percentages based on non-bot players.
|
|
||||||
if (g_UseDynamicDistribution)
|
if (g_UseDynamicDistribution)
|
||||||
{
|
{
|
||||||
int allianceRealCounts[NUM_RANGES] = {0};
|
std::vector<int> allianceRealCounts(g_NumRanges, 0);
|
||||||
int hordeRealCounts[NUM_RANGES] = {0};
|
std::vector<int> hordeRealCounts(g_NumRanges, 0);
|
||||||
uint32 totalAllianceReal = 0;
|
uint32 totalAllianceReal = 0;
|
||||||
uint32 totalHordeReal = 0;
|
uint32 totalHordeReal = 0;
|
||||||
// Iterate over all players and count non-bot players.
|
|
||||||
for (auto const& itr : ObjectAccessor::GetPlayers())
|
for (auto const& itr : ObjectAccessor::GetPlayers())
|
||||||
{
|
{
|
||||||
Player* player = itr.second;
|
Player* player = itr.second;
|
||||||
if (!player || !player->IsInWorld())
|
if (!player || !player->IsInWorld())
|
||||||
|
{
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
if (IsPlayerBot(player))
|
if (IsPlayerBot(player))
|
||||||
|
{
|
||||||
continue; // Skip bots.
|
continue; // Skip bots.
|
||||||
|
}
|
||||||
int rangeIndex = GetOrFlagPlayerBracket(player);
|
int rangeIndex = GetOrFlagPlayerBracket(player);
|
||||||
if (rangeIndex < 0)
|
if (rangeIndex < 0)
|
||||||
|
{
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
if (player->GetTeamId() == TEAM_ALLIANCE)
|
if (player->GetTeamId() == TEAM_ALLIANCE)
|
||||||
{
|
{
|
||||||
allianceRealCounts[rangeIndex]++;
|
allianceRealCounts[rangeIndex]++;
|
||||||
@@ -681,34 +718,39 @@ public:
|
|||||||
totalHordeReal++;
|
totalHordeReal++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Use a baseline weight to ensure an equal share when no real players are present.
|
|
||||||
const float baseline = 1.0f;
|
const float baseline = 1.0f;
|
||||||
|
std::vector<float> allianceWeights(g_NumRanges, 0.0f);
|
||||||
|
std::vector<float> hordeWeights(g_NumRanges, 0.0f);
|
||||||
float allianceTotalWeight = 0.0f;
|
float allianceTotalWeight = 0.0f;
|
||||||
float hordeTotalWeight = 0.0f;
|
float hordeTotalWeight = 0.0f;
|
||||||
float allianceWeights[NUM_RANGES] = {0};
|
for (int i = 0; i < g_NumRanges; ++i)
|
||||||
float hordeWeights[NUM_RANGES] = {0};
|
|
||||||
for (int i = 0; i < NUM_RANGES; ++i)
|
|
||||||
{
|
{
|
||||||
// Only count valid brackets.
|
|
||||||
if (g_AllianceLevelRanges[i].lower > g_AllianceLevelRanges[i].upper)
|
if (g_AllianceLevelRanges[i].lower > g_AllianceLevelRanges[i].upper)
|
||||||
|
{
|
||||||
allianceWeights[i] = 0.0f;
|
allianceWeights[i] = 0.0f;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
allianceWeights[i] = baseline + g_RealPlayerWeight *
|
allianceWeights[i] = baseline + g_RealPlayerWeight *
|
||||||
(totalAllianceReal > 0 ? (1.0f / totalAllianceReal) : 1.0f) *
|
(totalAllianceReal > 0 ? (1.0f / totalAllianceReal) : 1.0f) *
|
||||||
log(1 + allianceRealCounts[i]);
|
log(1 + allianceRealCounts[i]);
|
||||||
|
}
|
||||||
|
|
||||||
if (g_HordeLevelRanges[i].lower > g_HordeLevelRanges[i].upper)
|
if (g_HordeLevelRanges[i].lower > g_HordeLevelRanges[i].upper)
|
||||||
|
{
|
||||||
hordeWeights[i] = 0.0f;
|
hordeWeights[i] = 0.0f;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
hordeWeights[i] = baseline + g_RealPlayerWeight *
|
hordeWeights[i] = baseline + g_RealPlayerWeight *
|
||||||
(totalHordeReal > 0 ? (1.0f / totalHordeReal) : 1.0f) *
|
(totalHordeReal > 0 ? (1.0f / totalHordeReal) : 1.0f) *
|
||||||
log(1 + hordeRealCounts[i]);
|
log(1 + hordeRealCounts[i]);
|
||||||
|
}
|
||||||
|
|
||||||
allianceTotalWeight += allianceWeights[i];
|
allianceTotalWeight += allianceWeights[i];
|
||||||
hordeTotalWeight += hordeWeights[i];
|
hordeTotalWeight += hordeWeights[i];
|
||||||
}
|
}
|
||||||
// Recalculate desired percentages for each range.
|
for (int i = 0; i < g_NumRanges; ++i)
|
||||||
for (int i = 0; i < NUM_RANGES; ++i)
|
|
||||||
{
|
{
|
||||||
g_AllianceLevelRanges[i].desiredPercent = static_cast<uint8>(round((allianceWeights[i] / allianceTotalWeight) * 100));
|
g_AllianceLevelRanges[i].desiredPercent = static_cast<uint8>(round((allianceWeights[i] / allianceTotalWeight) * 100));
|
||||||
if (g_BotDistFullDebugMode || g_BotDistLiteDebugMode)
|
if (g_BotDistFullDebugMode || g_BotDistLiteDebugMode)
|
||||||
@@ -719,8 +761,10 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
uint8 sumAlliance = 0;
|
uint8 sumAlliance = 0;
|
||||||
for (int i = 0; i < NUM_RANGES; ++i)
|
for (int i = 0; i < g_NumRanges; ++i)
|
||||||
|
{
|
||||||
sumAlliance += g_AllianceLevelRanges[i].desiredPercent;
|
sumAlliance += g_AllianceLevelRanges[i].desiredPercent;
|
||||||
|
}
|
||||||
if (sumAlliance < 100 && allianceTotalWeight > 0)
|
if (sumAlliance < 100 && allianceTotalWeight > 0)
|
||||||
{
|
{
|
||||||
uint8 missing = 100 - sumAlliance;
|
uint8 missing = 100 - sumAlliance;
|
||||||
@@ -730,10 +774,9 @@ public:
|
|||||||
}
|
}
|
||||||
while (missing > 0)
|
while (missing > 0)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < NUM_RANGES && missing > 0; ++i)
|
for (int i = 0; i < g_NumRanges && missing > 0; ++i)
|
||||||
{
|
{
|
||||||
if (g_AllianceLevelRanges[i].lower <= g_AllianceLevelRanges[i].upper &&
|
if (g_AllianceLevelRanges[i].lower <= g_AllianceLevelRanges[i].upper && allianceWeights[i] > 0)
|
||||||
allianceWeights[i] > 0)
|
|
||||||
{
|
{
|
||||||
g_AllianceLevelRanges[i].desiredPercent++;
|
g_AllianceLevelRanges[i].desiredPercent++;
|
||||||
missing--;
|
missing--;
|
||||||
@@ -743,18 +786,15 @@ public:
|
|||||||
if (g_BotDistFullDebugMode || g_BotDistLiteDebugMode)
|
if (g_BotDistFullDebugMode || g_BotDistLiteDebugMode)
|
||||||
{
|
{
|
||||||
LOG_INFO("server.loading", "[BotLevelBrackets] Alliance normalized percentages:");
|
LOG_INFO("server.loading", "[BotLevelBrackets] Alliance normalized percentages:");
|
||||||
for (int i = 0; i < NUM_RANGES; ++i)
|
for (int i = 0; i < g_NumRanges; ++i)
|
||||||
{
|
{
|
||||||
LOG_INFO("server.loading", " Range {}: {}% ({}-{})", i + 1,
|
LOG_INFO("server.loading", " Range {}: {}% ({}-{})", i + 1, g_AllianceLevelRanges[i].desiredPercent,
|
||||||
g_AllianceLevelRanges[i].desiredPercent,
|
g_AllianceLevelRanges[i].lower, g_AllianceLevelRanges[i].upper);
|
||||||
g_AllianceLevelRanges[i].lower,
|
|
||||||
g_AllianceLevelRanges[i].upper);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < g_NumRanges; ++i)
|
||||||
for (int i = 0; i < NUM_RANGES; ++i)
|
|
||||||
{
|
{
|
||||||
g_HordeLevelRanges[i].desiredPercent = static_cast<uint8>(round((hordeWeights[i] / hordeTotalWeight) * 100));
|
g_HordeLevelRanges[i].desiredPercent = static_cast<uint8>(round((hordeWeights[i] / hordeTotalWeight) * 100));
|
||||||
if (g_BotDistFullDebugMode || g_BotDistLiteDebugMode)
|
if (g_BotDistFullDebugMode || g_BotDistLiteDebugMode)
|
||||||
@@ -765,8 +805,10 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
uint8 sumHorde = 0;
|
uint8 sumHorde = 0;
|
||||||
for (int i = 0; i < NUM_RANGES; ++i)
|
for (int i = 0; i < g_NumRanges; ++i)
|
||||||
|
{
|
||||||
sumHorde += g_HordeLevelRanges[i].desiredPercent;
|
sumHorde += g_HordeLevelRanges[i].desiredPercent;
|
||||||
|
}
|
||||||
if (sumHorde < 100 && hordeTotalWeight > 0)
|
if (sumHorde < 100 && hordeTotalWeight > 0)
|
||||||
{
|
{
|
||||||
uint8 missing = 100 - sumHorde;
|
uint8 missing = 100 - sumHorde;
|
||||||
@@ -776,10 +818,9 @@ public:
|
|||||||
}
|
}
|
||||||
while (missing > 0)
|
while (missing > 0)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < NUM_RANGES && missing > 0; ++i)
|
for (int i = 0; i < g_NumRanges && missing > 0; ++i)
|
||||||
{
|
{
|
||||||
if (g_HordeLevelRanges[i].lower <= g_HordeLevelRanges[i].upper &&
|
if (g_HordeLevelRanges[i].lower <= g_HordeLevelRanges[i].upper && hordeWeights[i] > 0)
|
||||||
hordeWeights[i] > 0)
|
|
||||||
{
|
{
|
||||||
g_HordeLevelRanges[i].desiredPercent++;
|
g_HordeLevelRanges[i].desiredPercent++;
|
||||||
missing--;
|
missing--;
|
||||||
@@ -789,32 +830,28 @@ public:
|
|||||||
if (g_BotDistFullDebugMode || g_BotDistLiteDebugMode)
|
if (g_BotDistFullDebugMode || g_BotDistLiteDebugMode)
|
||||||
{
|
{
|
||||||
LOG_INFO("server.loading", "[BotLevelBrackets] Horde normalized percentages:");
|
LOG_INFO("server.loading", "[BotLevelBrackets] Horde normalized percentages:");
|
||||||
for (int i = 0; i < NUM_RANGES; ++i)
|
for (int i = 0; i < g_NumRanges; ++i)
|
||||||
{
|
{
|
||||||
LOG_INFO("server.loading", " Range {}: {}% ({}-{})", i + 1,
|
LOG_INFO("server.loading", " Range {}: {}% ({}-{})", i + 1, g_HordeLevelRanges[i].desiredPercent,
|
||||||
g_HordeLevelRanges[i].desiredPercent,
|
g_HordeLevelRanges[i].lower, g_HordeLevelRanges[i].upper);
|
||||||
g_HordeLevelRanges[i].lower,
|
}
|
||||||
g_HordeLevelRanges[i].upper);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
// Containers for Alliance bots.
|
|
||||||
uint32 totalAllianceBots = 0;
|
uint32 totalAllianceBots = 0;
|
||||||
int allianceActualCounts[NUM_RANGES] = {0};
|
std::vector<int> allianceActualCounts(g_NumRanges, 0);
|
||||||
std::vector<Player*> allianceBotsByRange[NUM_RANGES];
|
std::vector< std::vector<Player*> > allianceBotsByRange(g_NumRanges);
|
||||||
|
|
||||||
// Containers for Horde bots.
|
|
||||||
uint32 totalHordeBots = 0;
|
uint32 totalHordeBots = 0;
|
||||||
int hordeActualCounts[NUM_RANGES] = {0};
|
std::vector<int> hordeActualCounts(g_NumRanges, 0);
|
||||||
std::vector<Player*> hordeBotsByRange[NUM_RANGES];
|
std::vector< std::vector<Player*> > hordeBotsByRange(g_NumRanges);
|
||||||
|
|
||||||
// Iterate only over player bots.
|
|
||||||
auto const& allPlayers = ObjectAccessor::GetPlayers();
|
auto const& allPlayers = ObjectAccessor::GetPlayers();
|
||||||
if (g_BotDistFullDebugMode)
|
if (g_BotDistFullDebugMode)
|
||||||
|
{
|
||||||
LOG_INFO("server.loading", "[BotLevelBrackets] Starting processing of {} players.", allPlayers.size());
|
LOG_INFO("server.loading", "[BotLevelBrackets] Starting processing of {} players.", allPlayers.size());
|
||||||
|
}
|
||||||
|
|
||||||
for (auto const& itr : allPlayers)
|
for (auto const& itr : allPlayers)
|
||||||
{
|
{
|
||||||
@@ -822,29 +859,35 @@ public:
|
|||||||
if (!player)
|
if (!player)
|
||||||
{
|
{
|
||||||
if (g_BotDistFullDebugMode)
|
if (g_BotDistFullDebugMode)
|
||||||
|
{
|
||||||
LOG_INFO("server.loading", "[BotLevelBrackets] Skipping null player.");
|
LOG_INFO("server.loading", "[BotLevelBrackets] Skipping null player.");
|
||||||
|
}
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (!player->IsInWorld())
|
if (!player->IsInWorld())
|
||||||
{
|
{
|
||||||
if (g_BotDistFullDebugMode)
|
if (g_BotDistFullDebugMode)
|
||||||
|
{
|
||||||
LOG_INFO("server.loading", "[BotLevelBrackets] Skipping player '{}' as they are not in world.", player->GetName());
|
LOG_INFO("server.loading", "[BotLevelBrackets] Skipping player '{}' as they are not in world.", player->GetName());
|
||||||
|
}
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (!IsPlayerBot(player) || !IsPlayerRandomBot(player))
|
if (!IsPlayerBot(player) || !IsPlayerRandomBot(player))
|
||||||
{
|
{
|
||||||
if (g_BotDistFullDebugMode)
|
if (g_BotDistFullDebugMode)
|
||||||
|
{
|
||||||
LOG_INFO("server.loading", "[BotLevelBrackets] Skipping player '{}' as they are not a random bot.", player->GetName());
|
LOG_INFO("server.loading", "[BotLevelBrackets] Skipping player '{}' as they are not a random bot.", player->GetName());
|
||||||
|
}
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
// If the bot is in a guild with a real player online and the option is enabled, skip it.
|
|
||||||
if (g_IgnoreGuildBotsWithRealPlayers && BotInGuildWithRealPlayer(player))
|
if (g_IgnoreGuildBotsWithRealPlayers && BotInGuildWithRealPlayer(player))
|
||||||
|
{
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
// If the bot is a friend with a real player and the option is enabled, skip it.
|
|
||||||
if (g_IgnoreFriendListed && BotInFriendList(player))
|
if (g_IgnoreFriendListed && BotInFriendList(player))
|
||||||
|
{
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
if (IsAlliancePlayerBot(player))
|
if (IsAlliancePlayerBot(player))
|
||||||
{
|
{
|
||||||
totalAllianceBots++;
|
totalAllianceBots++;
|
||||||
@@ -854,13 +897,14 @@ public:
|
|||||||
allianceActualCounts[rangeIndex]++;
|
allianceActualCounts[rangeIndex]++;
|
||||||
allianceBotsByRange[rangeIndex].push_back(player);
|
allianceBotsByRange[rangeIndex].push_back(player);
|
||||||
if (g_BotDistFullDebugMode)
|
if (g_BotDistFullDebugMode)
|
||||||
|
{
|
||||||
LOG_INFO("server.loading", "[BotLevelBrackets] Alliance bot '{}' with level {} added to range {}.",
|
LOG_INFO("server.loading", "[BotLevelBrackets] Alliance bot '{}' with level {} added to range {}.",
|
||||||
player->GetName(), player->GetLevel(), rangeIndex + 1);
|
player->GetName(), player->GetLevel(), rangeIndex + 1);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
else if (g_BotDistFullDebugMode)
|
else if (g_BotDistFullDebugMode)
|
||||||
{
|
{
|
||||||
LOG_INFO("server.loading", "[BotLevelBrackets] Alliance bot '{}' with level {} does not fall into any defined range.",
|
LOG_INFO("server.loading", "[BotLevelBrackets] Alliance bot '{}' with level {} does not fall into any defined range.", player->GetName(), player->GetLevel());
|
||||||
player->GetName(), player->GetLevel());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (IsHordePlayerBot(player))
|
else if (IsHordePlayerBot(player))
|
||||||
@@ -872,13 +916,14 @@ public:
|
|||||||
hordeActualCounts[rangeIndex]++;
|
hordeActualCounts[rangeIndex]++;
|
||||||
hordeBotsByRange[rangeIndex].push_back(player);
|
hordeBotsByRange[rangeIndex].push_back(player);
|
||||||
if (g_BotDistFullDebugMode)
|
if (g_BotDistFullDebugMode)
|
||||||
|
{
|
||||||
LOG_INFO("server.loading", "[BotLevelBrackets] Horde bot '{}' with level {} added to range {}.",
|
LOG_INFO("server.loading", "[BotLevelBrackets] Horde bot '{}' with level {} added to range {}.",
|
||||||
player->GetName(), player->GetLevel(), rangeIndex + 1);
|
player->GetName(), player->GetLevel(), rangeIndex + 1);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
else if (g_BotDistFullDebugMode)
|
else if (g_BotDistFullDebugMode)
|
||||||
{
|
{
|
||||||
LOG_INFO("server.loading", "[BotLevelBrackets] Horde bot '{}' with level {} does not fall into any defined range.",
|
LOG_INFO("server.loading", "[BotLevelBrackets] Horde bot '{}' with level {} does not fall into any defined range.", player->GetName(), player->GetLevel());
|
||||||
player->GetName(), player->GetLevel());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -898,8 +943,8 @@ public:
|
|||||||
{
|
{
|
||||||
LOG_INFO("server.loading", "[BotLevelBrackets] =========================================");
|
LOG_INFO("server.loading", "[BotLevelBrackets] =========================================");
|
||||||
}
|
}
|
||||||
int allianceDesiredCounts[NUM_RANGES] = {0};
|
std::vector<int> allianceDesiredCounts(g_NumRanges, 0);
|
||||||
for (int i = 0; i < NUM_RANGES; ++i)
|
for (int i = 0; i < g_NumRanges; ++i)
|
||||||
{
|
{
|
||||||
allianceDesiredCounts[i] = static_cast<int>(round((g_AllianceLevelRanges[i].desiredPercent / 100.0) * totalAllianceBots));
|
allianceDesiredCounts[i] = static_cast<int>(round((g_AllianceLevelRanges[i].desiredPercent / 100.0) * totalAllianceBots));
|
||||||
if (g_BotDistFullDebugMode || g_BotDistLiteDebugMode)
|
if (g_BotDistFullDebugMode || g_BotDistLiteDebugMode)
|
||||||
@@ -909,16 +954,12 @@ public:
|
|||||||
allianceDesiredCounts[i], allianceActualCounts[i]);
|
allianceDesiredCounts[i], allianceActualCounts[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (g_BotDistFullDebugMode || g_BotDistLiteDebugMode)
|
for (int i = 0; i < g_NumRanges; ++i)
|
||||||
{
|
|
||||||
LOG_INFO("server.loading", "[BotLevelBrackets] =========================================");
|
|
||||||
}
|
|
||||||
// Adjust overpopulated ranges.
|
|
||||||
for (int i = 0; i < NUM_RANGES; ++i)
|
|
||||||
{
|
{
|
||||||
if (g_BotDistFullDebugMode)
|
if (g_BotDistFullDebugMode)
|
||||||
|
{
|
||||||
LOG_INFO("server.loading", "[BotLevelBrackets] >>> Processing Alliance bots in range {}.", i + 1);
|
LOG_INFO("server.loading", "[BotLevelBrackets] >>> Processing Alliance bots in range {}.", i + 1);
|
||||||
|
}
|
||||||
std::vector<Player*> safeBots;
|
std::vector<Player*> safeBots;
|
||||||
std::vector<Player*> flaggedBots;
|
std::vector<Player*> flaggedBots;
|
||||||
for (Player* bot : allianceBotsByRange[i])
|
for (Player* bot : allianceBotsByRange[i])
|
||||||
@@ -926,19 +967,17 @@ public:
|
|||||||
if (IsBotSafeForLevelReset(bot))
|
if (IsBotSafeForLevelReset(bot))
|
||||||
{
|
{
|
||||||
safeBots.push_back(bot);
|
safeBots.push_back(bot);
|
||||||
if (g_BotDistFullDebugMode)
|
|
||||||
{
|
|
||||||
//LOG_INFO("server.loading", "[BotLevelBrackets] Alliance bot '{}' is safe for level reset in range {}.", bot->GetName(), i + 1);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
flaggedBots.push_back(bot);
|
flaggedBots.push_back(bot);
|
||||||
if (g_BotDistFullDebugMode)
|
if (g_BotDistFullDebugMode)
|
||||||
|
{
|
||||||
LOG_INFO("server.loading", "[BotLevelBrackets] Alliance bot '{}' is NOT safe for level reset in range {}.",
|
LOG_INFO("server.loading", "[BotLevelBrackets] Alliance bot '{}' is NOT safe for level reset in range {}.",
|
||||||
bot->GetName(), i + 1);
|
bot->GetName(), i + 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
while (allianceActualCounts[i] > allianceDesiredCounts[i] && !safeBots.empty())
|
while (allianceActualCounts[i] > allianceDesiredCounts[i] && !safeBots.empty())
|
||||||
{
|
{
|
||||||
Player* bot = safeBots.back();
|
Player* bot = safeBots.back();
|
||||||
@@ -950,7 +989,7 @@ public:
|
|||||||
int targetRange = -1;
|
int targetRange = -1;
|
||||||
if (bot->getClass() == CLASS_DEATH_KNIGHT)
|
if (bot->getClass() == CLASS_DEATH_KNIGHT)
|
||||||
{
|
{
|
||||||
for (int j = 0; j < NUM_RANGES; ++j)
|
for (int j = 0; j < g_NumRanges; ++j)
|
||||||
{
|
{
|
||||||
if (allianceActualCounts[j] < allianceDesiredCounts[j] && g_AllianceLevelRanges[j].upper >= 55)
|
if (allianceActualCounts[j] < allianceDesiredCounts[j] && g_AllianceLevelRanges[j].upper >= 55)
|
||||||
{
|
{
|
||||||
@@ -961,7 +1000,7 @@ public:
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
for (int j = 0; j < NUM_RANGES; ++j)
|
for (int j = 0; j < g_NumRanges; ++j)
|
||||||
{
|
{
|
||||||
if (allianceActualCounts[j] < allianceDesiredCounts[j])
|
if (allianceActualCounts[j] < allianceDesiredCounts[j])
|
||||||
{
|
{
|
||||||
@@ -980,9 +1019,10 @@ public:
|
|||||||
}
|
}
|
||||||
if (g_BotDistFullDebugMode)
|
if (g_BotDistFullDebugMode)
|
||||||
{
|
{
|
||||||
LOG_INFO("server.loading", "[BotLevelBrackets] !!!! Adjusting alliance bot '{}' from range {} to range {} ({}-{}).", bot->GetName(), i + 1, targetRange + 1, g_AllianceLevelRanges[targetRange].lower, g_AllianceLevelRanges[targetRange].upper);
|
LOG_INFO("server.loading", "[BotLevelBrackets] !!!! Adjusting alliance bot '{}' from range {} to range {} ({}-{}).",
|
||||||
|
bot->GetName(), i + 1, targetRange + 1, g_AllianceLevelRanges[targetRange].lower, g_AllianceLevelRanges[targetRange].upper);
|
||||||
}
|
}
|
||||||
AdjustBotToRange(bot, targetRange, g_AllianceLevelRanges);
|
AdjustBotToRange(bot, targetRange, g_AllianceLevelRanges.data());
|
||||||
allianceActualCounts[i]--;
|
allianceActualCounts[i]--;
|
||||||
allianceActualCounts[targetRange]++;
|
allianceActualCounts[targetRange]++;
|
||||||
}
|
}
|
||||||
@@ -990,7 +1030,6 @@ public:
|
|||||||
{
|
{
|
||||||
Player* bot = flaggedBots.back();
|
Player* bot = flaggedBots.back();
|
||||||
flaggedBots.pop_back();
|
flaggedBots.pop_back();
|
||||||
|
|
||||||
if (g_BotDistFullDebugMode)
|
if (g_BotDistFullDebugMode)
|
||||||
{
|
{
|
||||||
LOG_INFO("server.loading", "[BotLevelBrackets] Alliance flagged bot '{}' from range {} will be processed for pending reset.", bot->GetName(), i + 1);
|
LOG_INFO("server.loading", "[BotLevelBrackets] Alliance flagged bot '{}' from range {} will be processed for pending reset.", bot->GetName(), i + 1);
|
||||||
@@ -998,7 +1037,7 @@ public:
|
|||||||
int targetRange = -1;
|
int targetRange = -1;
|
||||||
if (bot->getClass() == CLASS_DEATH_KNIGHT)
|
if (bot->getClass() == CLASS_DEATH_KNIGHT)
|
||||||
{
|
{
|
||||||
for (int j = 0; j < NUM_RANGES; ++j)
|
for (int j = 0; j < g_NumRanges; ++j)
|
||||||
{
|
{
|
||||||
if (allianceActualCounts[j] < allianceDesiredCounts[j] && g_AllianceLevelRanges[j].upper >= 55)
|
if (allianceActualCounts[j] < allianceDesiredCounts[j] && g_AllianceLevelRanges[j].upper >= 55)
|
||||||
{
|
{
|
||||||
@@ -1009,7 +1048,7 @@ public:
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
for (int j = 0; j < NUM_RANGES; ++j)
|
for (int j = 0; j < g_NumRanges; ++j)
|
||||||
{
|
{
|
||||||
if (allianceActualCounts[j] < allianceDesiredCounts[j])
|
if (allianceActualCounts[j] < allianceDesiredCounts[j])
|
||||||
{
|
{
|
||||||
@@ -1037,10 +1076,11 @@ public:
|
|||||||
}
|
}
|
||||||
if (!alreadyFlagged)
|
if (!alreadyFlagged)
|
||||||
{
|
{
|
||||||
g_PendingLevelResets.push_back({bot, targetRange, g_AllianceLevelRanges});
|
g_PendingLevelResets.push_back({bot, targetRange, g_AllianceLevelRanges.data()});
|
||||||
if (g_BotDistFullDebugMode)
|
if (g_BotDistFullDebugMode)
|
||||||
{
|
{
|
||||||
LOG_INFO("server.loading", "[BotLevelBrackets] Alliance bot '{}' flagged for pending level reset to range {}-{}.", bot->GetName(), g_AllianceLevelRanges[targetRange].lower, g_AllianceLevelRanges[targetRange].upper);
|
LOG_INFO("server.loading", "[BotLevelBrackets] Alliance bot '{}' flagged for pending level reset to range {}-{}.",
|
||||||
|
bot->GetName(), g_AllianceLevelRanges[targetRange].lower, g_AllianceLevelRanges[targetRange].upper);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1054,8 +1094,8 @@ public:
|
|||||||
{
|
{
|
||||||
LOG_INFO("server.loading", "[BotLevelBrackets] =========================================");
|
LOG_INFO("server.loading", "[BotLevelBrackets] =========================================");
|
||||||
}
|
}
|
||||||
int hordeDesiredCounts[NUM_RANGES] = {0};
|
std::vector<int> hordeDesiredCounts(g_NumRanges, 0);
|
||||||
for (int i = 0; i < NUM_RANGES; ++i)
|
for (int i = 0; i < g_NumRanges; ++i)
|
||||||
{
|
{
|
||||||
hordeDesiredCounts[i] = static_cast<int>(round((g_HordeLevelRanges[i].desiredPercent / 100.0) * totalHordeBots));
|
hordeDesiredCounts[i] = static_cast<int>(round((g_HordeLevelRanges[i].desiredPercent / 100.0) * totalHordeBots));
|
||||||
if (g_BotDistFullDebugMode || g_BotDistLiteDebugMode)
|
if (g_BotDistFullDebugMode || g_BotDistLiteDebugMode)
|
||||||
@@ -1065,15 +1105,12 @@ public:
|
|||||||
hordeDesiredCounts[i], hordeActualCounts[i]);
|
hordeDesiredCounts[i], hordeActualCounts[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (g_BotDistFullDebugMode || g_BotDistLiteDebugMode)
|
for (int i = 0; i < g_NumRanges; ++i)
|
||||||
{
|
|
||||||
LOG_INFO("server.loading", "[BotLevelBrackets] =========================================");
|
|
||||||
}
|
|
||||||
for (int i = 0; i < NUM_RANGES; ++i)
|
|
||||||
{
|
{
|
||||||
if (g_BotDistFullDebugMode)
|
if (g_BotDistFullDebugMode)
|
||||||
|
{
|
||||||
LOG_INFO("server.loading", "[BotLevelBrackets] Processing Horde bots in range {}.", i + 1);
|
LOG_INFO("server.loading", "[BotLevelBrackets] Processing Horde bots in range {}.", i + 1);
|
||||||
|
}
|
||||||
std::vector<Player*> safeBots;
|
std::vector<Player*> safeBots;
|
||||||
std::vector<Player*> flaggedBots;
|
std::vector<Player*> flaggedBots;
|
||||||
for (Player* bot : hordeBotsByRange[i])
|
for (Player* bot : hordeBotsByRange[i])
|
||||||
@@ -1081,33 +1118,29 @@ public:
|
|||||||
if (IsBotSafeForLevelReset(bot))
|
if (IsBotSafeForLevelReset(bot))
|
||||||
{
|
{
|
||||||
safeBots.push_back(bot);
|
safeBots.push_back(bot);
|
||||||
if (g_BotDistFullDebugMode)
|
|
||||||
{
|
|
||||||
//LOG_INFO("server.loading", "[BotLevelBrackets] Horde bot '{}' is safe for level reset in range {}.", bot->GetName(), i + 1);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
flaggedBots.push_back(bot);
|
flaggedBots.push_back(bot);
|
||||||
if (g_BotDistFullDebugMode)
|
if (g_BotDistFullDebugMode)
|
||||||
|
{
|
||||||
LOG_INFO("server.loading", "[BotLevelBrackets] Horde bot '{}' is NOT safe for level reset in range {}.",
|
LOG_INFO("server.loading", "[BotLevelBrackets] Horde bot '{}' is NOT safe for level reset in range {}.",
|
||||||
bot->GetName(), i + 1);
|
bot->GetName(), i + 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
while (hordeActualCounts[i] > hordeDesiredCounts[i] && !safeBots.empty())
|
while (hordeActualCounts[i] > hordeDesiredCounts[i] && !safeBots.empty())
|
||||||
{
|
{
|
||||||
Player* bot = safeBots.back();
|
Player* bot = safeBots.back();
|
||||||
safeBots.pop_back();
|
safeBots.pop_back();
|
||||||
|
|
||||||
if (g_BotDistFullDebugMode)
|
if (g_BotDistFullDebugMode)
|
||||||
{
|
{
|
||||||
LOG_INFO("server.loading", "[BotLevelBrackets] Horde safe bot '{}' from range {} will be moved.", bot->GetName(), i + 1);
|
LOG_INFO("server.loading", "[BotLevelBrackets] Horde safe bot '{}' from range {} will be moved.", bot->GetName(), i + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
int targetRange = -1;
|
int targetRange = -1;
|
||||||
if (bot->getClass() == CLASS_DEATH_KNIGHT)
|
if (bot->getClass() == CLASS_DEATH_KNIGHT)
|
||||||
{
|
{
|
||||||
for (int j = 0; j < NUM_RANGES; ++j)
|
for (int j = 0; j < g_NumRanges; ++j)
|
||||||
{
|
{
|
||||||
if (hordeActualCounts[j] < hordeDesiredCounts[j] && g_HordeLevelRanges[j].upper >= 55)
|
if (hordeActualCounts[j] < hordeDesiredCounts[j] && g_HordeLevelRanges[j].upper >= 55)
|
||||||
{
|
{
|
||||||
@@ -1118,7 +1151,7 @@ public:
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
for (int j = 0; j < NUM_RANGES; ++j)
|
for (int j = 0; j < g_NumRanges; ++j)
|
||||||
{
|
{
|
||||||
if (hordeActualCounts[j] < hordeDesiredCounts[j])
|
if (hordeActualCounts[j] < hordeDesiredCounts[j])
|
||||||
{
|
{
|
||||||
@@ -1137,9 +1170,10 @@ public:
|
|||||||
}
|
}
|
||||||
if (g_BotDistFullDebugMode)
|
if (g_BotDistFullDebugMode)
|
||||||
{
|
{
|
||||||
LOG_INFO("server.loading", "[BotLevelBrackets] !!!! Adjusting horde bot '{}' from range {} to range {} ({}-{}).", bot->GetName(), i + 1, targetRange + 1, g_HordeLevelRanges[targetRange].lower, g_HordeLevelRanges[targetRange].upper);
|
LOG_INFO("server.loading", "[BotLevelBrackets] !!!! Adjusting horde bot '{}' from range {} to range {} ({}-{}).",
|
||||||
|
bot->GetName(), i + 1, targetRange + 1, g_HordeLevelRanges[targetRange].lower, g_HordeLevelRanges[targetRange].upper);
|
||||||
}
|
}
|
||||||
AdjustBotToRange(bot, targetRange, g_HordeLevelRanges);
|
AdjustBotToRange(bot, targetRange, g_HordeLevelRanges.data());
|
||||||
hordeActualCounts[i]--;
|
hordeActualCounts[i]--;
|
||||||
hordeActualCounts[targetRange]++;
|
hordeActualCounts[targetRange]++;
|
||||||
}
|
}
|
||||||
@@ -1154,7 +1188,7 @@ public:
|
|||||||
int targetRange = -1;
|
int targetRange = -1;
|
||||||
if (bot->getClass() == CLASS_DEATH_KNIGHT)
|
if (bot->getClass() == CLASS_DEATH_KNIGHT)
|
||||||
{
|
{
|
||||||
for (int j = 0; j < NUM_RANGES; ++j)
|
for (int j = 0; j < g_NumRanges; ++j)
|
||||||
{
|
{
|
||||||
if (hordeActualCounts[j] < hordeDesiredCounts[j] && g_HordeLevelRanges[j].upper >= 55)
|
if (hordeActualCounts[j] < hordeDesiredCounts[j] && g_HordeLevelRanges[j].upper >= 55)
|
||||||
{
|
{
|
||||||
@@ -1165,7 +1199,7 @@ public:
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
for (int j = 0; j < NUM_RANGES; ++j)
|
for (int j = 0; j < g_NumRanges; ++j)
|
||||||
{
|
{
|
||||||
if (hordeActualCounts[j] < hordeDesiredCounts[j])
|
if (hordeActualCounts[j] < hordeDesiredCounts[j])
|
||||||
{
|
{
|
||||||
@@ -1193,27 +1227,25 @@ public:
|
|||||||
}
|
}
|
||||||
if (!alreadyFlagged)
|
if (!alreadyFlagged)
|
||||||
{
|
{
|
||||||
g_PendingLevelResets.push_back({bot, targetRange, g_HordeLevelRanges});
|
g_PendingLevelResets.push_back({bot, targetRange, g_HordeLevelRanges.data()});
|
||||||
if (g_BotDistFullDebugMode)
|
if (g_BotDistFullDebugMode)
|
||||||
{
|
{
|
||||||
LOG_INFO("server.loading", "[BotLevelBrackets] Horde bot '{}' flagged for pending level reset to range {}-{}.", bot->GetName(), g_HordeLevelRanges[targetRange].lower, g_HordeLevelRanges[targetRange].upper);
|
LOG_INFO("server.loading", "[BotLevelBrackets] Horde bot '{}' flagged for pending level reset to range {}-{}.",
|
||||||
|
bot->GetName(), g_HordeLevelRanges[targetRange].lower, g_HordeLevelRanges[targetRange].upper);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (g_BotDistFullDebugMode || g_BotDistLiteDebugMode)
|
if (g_BotDistFullDebugMode || g_BotDistLiteDebugMode)
|
||||||
{
|
{
|
||||||
LOG_INFO("server.loading", "[BotLevelBrackets] ========================================= COMPLETE");
|
LOG_INFO("server.loading", "[BotLevelBrackets] ========================================= COMPLETE");
|
||||||
LOG_INFO("server.loading", "[BotLevelBrackets] Distribution adjustment complete. Alliance bots: {}, Horde bots: {}.",
|
LOG_INFO("server.loading", "[BotLevelBrackets] Distribution adjustment complete. Alliance bots: {}, Horde bots: {}.",
|
||||||
totalAllianceBots, totalHordeBots);
|
totalAllianceBots, totalHordeBots);
|
||||||
LOG_INFO("server.loading", "[BotLevelBrackets] =========================================");
|
LOG_INFO("server.loading", "[BotLevelBrackets] =========================================");
|
||||||
LogAllBotLevels();
|
std::vector<int> allianceDesiredCounts(g_NumRanges, 0);
|
||||||
LOG_INFO("server.loading", "[BotLevelBrackets] =========================================");
|
for (int i = 0; i < g_NumRanges; ++i)
|
||||||
int allianceDesiredCounts[NUM_RANGES] = {0};
|
|
||||||
for (int i = 0; i < NUM_RANGES; ++i)
|
|
||||||
{
|
{
|
||||||
allianceDesiredCounts[i] = static_cast<int>(round((g_AllianceLevelRanges[i].desiredPercent / 100.0) * totalAllianceBots));
|
allianceDesiredCounts[i] = static_cast<int>(round((g_AllianceLevelRanges[i].desiredPercent / 100.0) * totalAllianceBots));
|
||||||
LOG_INFO("server.loading", "[BotLevelBrackets] Alliance Range {} ({}-{}): Desired = {}, Actual = {}.",
|
LOG_INFO("server.loading", "[BotLevelBrackets] Alliance Range {} ({}-{}): Desired = {}, Actual = {}.",
|
||||||
@@ -1221,8 +1253,8 @@ public:
|
|||||||
allianceDesiredCounts[i], allianceActualCounts[i]);
|
allianceDesiredCounts[i], allianceActualCounts[i]);
|
||||||
}
|
}
|
||||||
LOG_INFO("server.loading", "[BotLevelBrackets] ----------------------------------------");
|
LOG_INFO("server.loading", "[BotLevelBrackets] ----------------------------------------");
|
||||||
int hordeDesiredCounts[NUM_RANGES] = {0};
|
std::vector<int> hordeDesiredCounts(g_NumRanges, 0);
|
||||||
for (int i = 0; i < NUM_RANGES; ++i)
|
for (int i = 0; i < g_NumRanges; ++i)
|
||||||
{
|
{
|
||||||
hordeDesiredCounts[i] = static_cast<int>(round((g_HordeLevelRanges[i].desiredPercent / 100.0) * totalHordeBots));
|
hordeDesiredCounts[i] = static_cast<int>(round((g_HordeLevelRanges[i].desiredPercent / 100.0) * totalHordeBots));
|
||||||
LOG_INFO("server.loading", "[BotLevelBrackets] Horde Range {} ({}-{}): Desired = {}, Actual = {}.",
|
LOG_INFO("server.loading", "[BotLevelBrackets] Horde Range {} ({}-{}): Desired = {}, Actual = {}.",
|
||||||
@@ -1230,7 +1262,6 @@ public:
|
|||||||
hordeDesiredCounts[i], hordeActualCounts[i]);
|
hordeDesiredCounts[i], hordeActualCounts[i]);
|
||||||
}
|
}
|
||||||
LOG_INFO("server.loading", "[BotLevelBrackets] =========================================");
|
LOG_INFO("server.loading", "[BotLevelBrackets] =========================================");
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user