mirror of
https://github.com/mod-playerbots/mod-playerbots.git
synced 2026-02-02 18:33:48 +00:00
Compare commits
38 Commits
02e8465a3b
...
test/buid
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f0dc6de606 | ||
|
|
8c2a27b9fe | ||
|
|
8e316cd321 | ||
|
|
cafb95e7bd | ||
|
|
8529654f8f | ||
|
|
6ee1684e9b | ||
|
|
9546363d41 | ||
|
|
00d19dbf9c | ||
|
|
caae524a0a | ||
|
|
13fff46fa0 | ||
|
|
a92886032c | ||
|
|
f5711dc6f7 | ||
|
|
43e8e31980 | ||
|
|
c59a02ed89 | ||
|
|
7abd836971 | ||
|
|
5365ba86b5 | ||
|
|
378254af3f | ||
|
|
3d467ce3bb | ||
|
|
3e21563669 | ||
|
|
bf456ee07f | ||
|
|
a5bd0b9a41 | ||
|
|
34bab48dd4 | ||
|
|
41c53365ae | ||
|
|
fd07e02a8a | ||
|
|
6cf7f1aaef | ||
|
|
9f54d7e702 | ||
|
|
aeaaee15da | ||
|
|
a1137dbddc | ||
|
|
2eb98c3233 | ||
|
|
29613e29b7 | ||
|
|
e2c203a35e | ||
|
|
1b1ed18a23 | ||
|
|
2ab73c1fd5 | ||
|
|
6b97c379ba | ||
|
|
965d300203 | ||
|
|
dc55ecfd9c | ||
|
|
59d6eb139e | ||
|
|
00171a8c82 |
19
.github/workflows/check_pr_source.yml
vendored
Normal file
19
.github/workflows/check_pr_source.yml
vendored
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
name: Enforce test-staging → main
|
||||||
|
|
||||||
|
on:
|
||||||
|
pull_request:
|
||||||
|
branches:
|
||||||
|
- master
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
require-test-staging:
|
||||||
|
runs-on: ubuntu-22.04
|
||||||
|
steps:
|
||||||
|
- name: Ensure PR source is test-staging
|
||||||
|
run: |
|
||||||
|
echo "Base: ${{ github.event.pull_request.base.ref }}"
|
||||||
|
echo "Head: ${{ github.event.pull_request.head.ref }}"
|
||||||
|
if [ "${{ github.event.pull_request.head.ref }}" != "test-staging" ]; then
|
||||||
|
echo "✖ Pull request must come from test-staging"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
6
.github/workflows/windows_build.yml
vendored
6
.github/workflows/windows_build.yml
vendored
@@ -25,21 +25,25 @@ jobs:
|
|||||||
with:
|
with:
|
||||||
repository: 'mod-playerbots/azerothcore-wotlk'
|
repository: 'mod-playerbots/azerothcore-wotlk'
|
||||||
ref: 'Playerbot'
|
ref: 'Playerbot'
|
||||||
|
path: 'ac'
|
||||||
- name: Checkout Playerbot Module
|
- name: Checkout Playerbot Module
|
||||||
uses: actions/checkout@v3
|
uses: actions/checkout@v3
|
||||||
with:
|
with:
|
||||||
repository: 'mod-playerbots/mod-playerbots'
|
repository: 'mod-playerbots/mod-playerbots'
|
||||||
path: 'modules/mod-playerbots'
|
#path: 'modules/mod-playerbots'
|
||||||
|
path: ac/modules/mod-playerbots
|
||||||
- name: ccache
|
- name: ccache
|
||||||
uses: hendrikmuhs/ccache-action@v1.2.13
|
uses: hendrikmuhs/ccache-action@v1.2.13
|
||||||
- name: Configure OS
|
- name: Configure OS
|
||||||
shell: bash
|
shell: bash
|
||||||
|
working-directory: ac
|
||||||
env:
|
env:
|
||||||
CONTINUOUS_INTEGRATION: true
|
CONTINUOUS_INTEGRATION: true
|
||||||
run: |
|
run: |
|
||||||
./acore.sh install-deps
|
./acore.sh install-deps
|
||||||
- name: Build
|
- name: Build
|
||||||
shell: bash
|
shell: bash
|
||||||
|
working-directory: ac
|
||||||
run: |
|
run: |
|
||||||
export CTOOLS_BUILD=all
|
export CTOOLS_BUILD=all
|
||||||
./acore.sh compiler build
|
./acore.sh compiler build
|
||||||
|
|||||||
127
PULL_REQUEST_TEMPLATE.md
Normal file
127
PULL_REQUEST_TEMPLATE.md
Normal file
@@ -0,0 +1,127 @@
|
|||||||
|
# Pull Request
|
||||||
|
|
||||||
|
Describe what this change does and why it is needed...
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Design Philosophy
|
||||||
|
|
||||||
|
We prioritize **stability, performance, and predictability** over behavioral realism.
|
||||||
|
Complex player-mimicking logic is intentionally limited due to its negative impact on scalability, maintainability, and
|
||||||
|
long-term robustness.
|
||||||
|
|
||||||
|
Excessive processing overhead can lead to server hiccups, increased CPU usage, and degraded performance for all
|
||||||
|
participants. Because every action and
|
||||||
|
decision tree is executed **per bot and per trigger**, even small increases in logic complexity can scale poorly and
|
||||||
|
negatively affect both players and
|
||||||
|
world (random) bots. Bots are not expected to behave perfectly, and perfect simulation of human decision-making is not a
|
||||||
|
project goal. Increased behavioral
|
||||||
|
realism often introduces disproportionate cost, reduced predictability, and significantly higher maintenance overhead.
|
||||||
|
|
||||||
|
Every additional branch of logic increases long-term responsibility. All decision paths must be tested, validated, and
|
||||||
|
maintained continuously as the system evolves.
|
||||||
|
If advanced or AI-intensive behavior is introduced, the **default configuration must remain the lightweight decision
|
||||||
|
model**. More complex behavior should only be
|
||||||
|
available as an **explicit opt-in option**, clearly documented as having a measurable performance cost.
|
||||||
|
|
||||||
|
Principles:
|
||||||
|
|
||||||
|
- **Stability before intelligence**
|
||||||
|
A stable system is always preferred over a smarter one.
|
||||||
|
|
||||||
|
- **Performance is a shared resource**
|
||||||
|
Any increase in bot cost affects all players and all bots.
|
||||||
|
|
||||||
|
- **Simple logic scales better than smart logic**
|
||||||
|
Predictable behavior under load is more valuable than perfect decisions.
|
||||||
|
|
||||||
|
- **Complexity must justify itself**
|
||||||
|
If a feature cannot clearly explain its cost, it should not exist.
|
||||||
|
|
||||||
|
- **Defaults must be cheap**
|
||||||
|
Expensive behavior must always be optional and clearly communicated.
|
||||||
|
|
||||||
|
- **Bots should look reasonable, not perfect**
|
||||||
|
The goal is believable behavior, not human simulation.
|
||||||
|
|
||||||
|
Before submitting, confirm that this change aligns with those principles.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Feature Evaluation
|
||||||
|
|
||||||
|
Please answer the following:
|
||||||
|
|
||||||
|
- Describe the **minimum logic** required to achieve the intended behavior?
|
||||||
|
- Describe the **cheapest implementation** that produces an acceptable result?
|
||||||
|
- Describe the **runtime cost** when this logic executes across many bots?
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## How to Test the Changes
|
||||||
|
|
||||||
|
- Step-by-step instructions to test the change
|
||||||
|
- Any required setup (e.g. multiple players, bots, specific configuration)
|
||||||
|
- Expected behavior and how to verify it
|
||||||
|
|
||||||
|
## Complexity & Impact
|
||||||
|
|
||||||
|
- Does this change add new decision branches?
|
||||||
|
- [ ] No
|
||||||
|
- [ ] Yes (**explain below**)
|
||||||
|
|
||||||
|
- Does this change increase per-bot or per-tick processing?
|
||||||
|
- [ ] No
|
||||||
|
- [ ] Yes (**describe and justify impact**)
|
||||||
|
|
||||||
|
- Could this logic scale poorly under load?
|
||||||
|
- [ ] No
|
||||||
|
- [ ] Yes (**explain why**)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Defaults & Configuration
|
||||||
|
|
||||||
|
- Does this change modify default bot behavior?
|
||||||
|
- [ ] No
|
||||||
|
- [ ] Yes (**explain why**)
|
||||||
|
|
||||||
|
If this introduces more advanced or AI-heavy logic:
|
||||||
|
|
||||||
|
- [ ] Lightweight mode remains the default
|
||||||
|
- [ ] More complex behavior is optional and thereby configurable
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## AI Assistance
|
||||||
|
|
||||||
|
- Was AI assistance (e.g. ChatGPT or similar tools) used while working on this change?
|
||||||
|
- [ ] No
|
||||||
|
- [ ] Yes (**explain below**)
|
||||||
|
|
||||||
|
If yes, please specify:
|
||||||
|
|
||||||
|
- AI tool or model used (e.g. ChatGPT, GPT-4, Claude, etc.)
|
||||||
|
- Purpose of usage (e.g. brainstorming, refactoring, documentation, code generation)
|
||||||
|
- Which parts of the change were influenced or generated
|
||||||
|
- Whether the result was manually reviewed and adapted
|
||||||
|
|
||||||
|
AI assistance is allowed, but all submitted code must be fully understood, reviewed, and owned by the contributor.
|
||||||
|
Any AI-influenced changes must be verified against existing CORE and PB logic. We expect contributors to be honest
|
||||||
|
about what they do and do not understand.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Final Checklist
|
||||||
|
|
||||||
|
- [ ] Stability is not compromised
|
||||||
|
- [ ] Performance impact is understood, tested, and acceptable
|
||||||
|
- [ ] Added logic complexity is justified and explained
|
||||||
|
- [ ] Documentation updated if needed
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Notes for Reviewers
|
||||||
|
|
||||||
|
Anything that significantly improves realism at the cost of stability or performance should be carefully discussed
|
||||||
|
before merging.
|
||||||
71
README_CN.md
71
README_CN.md
@@ -1,71 +0,0 @@
|
|||||||
[English](README.md) | [Español](README_ES.md) | [中文](README_CN.md)
|
|
||||||
|
|
||||||
# 玩家机器人模块
|
|
||||||
|
|
||||||
欢迎使用AzerothCore的玩家机器人模块,这是一个基于IKE3玩家机器人的正在进行中的项目。这些玩家机器人利用实际的玩家数据,使您能够与您自己的替身进行交互,组建队伍,升级角色等等。
|
|
||||||
|
|
||||||
如果您遇到任何错误或出现崩溃,请您将它们报告为GitHub问题。您宝贵的反馈将帮助我们协作改进和增强这个项目。
|
|
||||||
|
|
||||||
## 安装
|
|
||||||
|
|
||||||
请注意,此模块需要对AzerothCore进行特定的自定义更改。为了确保兼容性,您必须使用我fork的自定义分支来编译它,可以在这里找到:[mod-playerbots/azerothcore-wotlk/tree/Playerbot](https://github.com/mod-playerbots/azerothcore-wotlk/tree/Playerbot)。
|
|
||||||
|
|
||||||
要安装此模块,请参考AzerothCore Wiki的详细说明:[AzerothCore安装指南](https://www.azerothcore.org/wiki/installation)。
|
|
||||||
|
|
||||||
我们提供了一个简单的方法来克隆该模块:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
git clone https://github.com/mod-playerbots/azerothcore-wotlk.git --branch=Playerbot
|
|
||||||
cd azerothcore-wotlk/modules
|
|
||||||
git clone https://github.com/mod-playerbots/mod-playerbots.git --branch=master
|
|
||||||
```
|
|
||||||
|
|
||||||
## 快速开始与文档
|
|
||||||
|
|
||||||
要快速开始并了解一系列命令,您可以参考ike3原版playerbots的手册。该模块提供了大部分基本命令。您可以在此找到文档:[IKE3 Playerbots 文档](https://ike3.github.io/mangosbot-docs/)。请注意,在我们的模块中,您需要将文档中所有的 `.bot` 替换为 `.playerbot bot`。
|
|
||||||
|
|
||||||
请注意,由于项目仍在开发中,新添加的命令的文档目前尚不完善。
|
|
||||||
|
|
||||||
## 进展
|
|
||||||
|
|
||||||
该模块主要强调以下关键功能,并在这些领域实施了改进:
|
|
||||||
|
|
||||||
- **世界中的机器人(随机机器人):** 我们增强了随机机器人的行为,使它们更接近真实玩家的表现,从而创建了更真实的玩家服务器环境。
|
|
||||||
|
|
||||||
- **团队副本中的机器人:** 我们赋予机器人征服具有挑战性的团队副本内容的能力,通过为各种Boss实施特定策略,使团队副本更加吸引人。此外,我们增强了机器人在DPS、治疗和坦克等各种角色中的能力,确保它们有效地为团队的成功做出贡献。
|
|
||||||
|
|
||||||
- **战场中的机器人:** 机器人现在能够与真实玩家一起积极参与战场,为这些PvP场景增添了深度和刺激。
|
|
||||||
|
|
||||||
- **与机器人的交互:** 我们改进了真实玩家和机器人之间的交互,使玩家能够在与机器人伙伴合作时完成任务并升级多个角色。
|
|
||||||
|
|
||||||
- **玩家进阶路径:** 我们设计了一个改进的玩家进阶路径,辅以机器人,为玩家提供了一种替代且引人入胜的游戏体验。
|
|
||||||
|
|
||||||
- **稳定性:** 我们的努力主要集中在增强使用Playerbots模块时AzerothCore的整体稳定性。这些改进旨在防止服务器崩溃,并确保所有用户都能获得更流畅的体验。
|
|
||||||
|
|
||||||
- **配置:** 我们引入了一系列可配置的选项,以满足不同需求的玩家,从而提供更个性化的体验。
|
|
||||||
|
|
||||||
值得注意的是,随着我们继续改进项目,还有大量工作需要完成。我们欢迎每个人以不同的方式做出贡献。
|
|
||||||
|
|
||||||
## 插件
|
|
||||||
|
|
||||||
为了更好地控制机器人并简化命令的使用,您还可以使用我们的插件:[Unbot Addon](https://github.com/liyunfan1223/unbot-addon)。目前,该插件仅对简体中文客户端提供更好的支持。
|
|
||||||
|
|
||||||
## 常见问题
|
|
||||||
|
|
||||||
**机器人无法释放技能**
|
|
||||||
|
|
||||||
- 请确保必要的英文DBC文件(enUS)存在。
|
|
||||||
|
|
||||||
**编译错误**
|
|
||||||
|
|
||||||
- 我们支持Ubuntu、Windows和macOS。
|
|
||||||
|
|
||||||
- 我们建立了持续集成工作流。您可以在[GitHub Actions](https://github.com/mod-playerbots/mod-playerbots/actions)中查看构建状态。
|
|
||||||
|
|
||||||
- 如果最新的构建状态失败,请恢复到上一个提交。我们将尽快解决此问题。
|
|
||||||
|
|
||||||
## 致谢
|
|
||||||
|
|
||||||
该模块的代码来自[ZhengPeiRu21/mod-playerbots](https://github.com/ZhengPeiRu21/mod-playerbots)和[celguar/mangosbot-bots](https://github.com/celguar/mangosbot-bots)。我们衷心感谢@ZhengPeiRu21和@celguar对维护该模块的持续努力。
|
|
||||||
|
|
||||||
我们还要向所有为playerbot开发做出贡献的个人表示诚挚的感谢。您的奉献和努力对塑造这个项目至关重要,我们对您的贡献表示感谢。
|
|
||||||
@@ -3,8 +3,9 @@
|
|||||||
##################################################
|
##################################################
|
||||||
|
|
||||||
# Overview
|
# Overview
|
||||||
# "Randombot": randomly generated bots that log in separately from players and populate the world. Depending on settings, randombots may automatically grind, quest, and upgrade equipment and can be invited to groups and given commands.
|
# "Randombot": randomly generated bots that log in separately from players and populate the world. Randombots may automatically grind, quest, level up, and upgrade equipment and can be invited to groups and given commands.
|
||||||
# "Altbot": characters created on player accounts, which may be logged in by the player and invited to groups and given commands like randombots. Depending on settings, altbots can be limited to characters on the active player's account or in the active player's guild.
|
# "AddClass bot": bots from the AddClassAccountPoolSize accounts. They are used for quickly adding a leveled and geared bot of any class to your party. They are recommended for a quick formation of a party.
|
||||||
|
# "Altbot": characters created on player accounts, which may be logged in by the player and invited to groups and given commands like randombots. They are best suited for long-progression playthroughs.
|
||||||
# Information about commands to control bots and set their strategies can be found on the wiki at https://github.com/mod-playerbots/mod-playerbots/wiki/Playerbot-Commands.
|
# Information about commands to control bots and set their strategies can be found on the wiki at https://github.com/mod-playerbots/mod-playerbots/wiki/Playerbot-Commands.
|
||||||
|
|
||||||
####################################################################################################
|
####################################################################################################
|
||||||
@@ -21,7 +22,7 @@
|
|||||||
# THRESHOLDS
|
# THRESHOLDS
|
||||||
# QUESTS
|
# QUESTS
|
||||||
# COMBAT
|
# COMBAT
|
||||||
# PALADIN BUFFS STRATEGIES
|
# GREATER BUFFS STRATEGIES
|
||||||
# CHEATS
|
# CHEATS
|
||||||
# SPELLS
|
# SPELLS
|
||||||
# FLIGHTPATH
|
# FLIGHTPATH
|
||||||
@@ -91,17 +92,20 @@ AiPlayerbot.MinRandomBots = 500
|
|||||||
AiPlayerbot.MaxRandomBots = 500
|
AiPlayerbot.MaxRandomBots = 500
|
||||||
|
|
||||||
# Randombot accounts
|
# Randombot accounts
|
||||||
# If you are not using any expansion at all, you may have to set this manually, in which case please ensure that RandomBotAccountCount is at least greater than (MaxRandomBots / 10 + AddClassAccountPoolSize)
|
# If you are not using any expansion at all, you may have to set this manually, in which case please
|
||||||
|
# ensure that RandomBotAccountCount is at least greater than (MaxRandomBots / 10 + AddClassAccountPoolSize)
|
||||||
# Default: 0 (automatic)
|
# Default: 0 (automatic)
|
||||||
AiPlayerbot.RandomBotAccountCount = 0
|
AiPlayerbot.RandomBotAccountCount = 0
|
||||||
|
|
||||||
# Delete all randombot accounts
|
# Delete all randombot accounts
|
||||||
# To apply this, set the number to 1 and run the Worldserver. Once deletion is complete, if you would like to recreate randombots, set the number back to 0 and rerun the Worldserver.
|
# To apply this, set the number to 1 and run the Worldserver. Once deletion is complete, if you would
|
||||||
|
# like to recreate randombots, set the number back to 0 and rerun the Worldserver.
|
||||||
AiPlayerbot.DeleteRandomBotAccounts = 0
|
AiPlayerbot.DeleteRandomBotAccounts = 0
|
||||||
|
|
||||||
# Disable randombots when no real players are logged in
|
# Disable randombots when no real players are logged in
|
||||||
# Default: 0 (randombots will login when server starts)
|
# Default: 0 (randombots will login when server starts)
|
||||||
# If enabled, randombots will only log in 30 seconds (default) after a real player logs in, and will log out 300 seconds (default) after all real players log out
|
# If enabled, randombots will only log in 30 seconds (default) after a real player logs in, and will
|
||||||
|
# log out 300 seconds (default) after all real players log out
|
||||||
AiPlayerbot.DisabledWithoutRealPlayer = 0
|
AiPlayerbot.DisabledWithoutRealPlayer = 0
|
||||||
AiPlayerbot.DisabledWithoutRealPlayerLoginDelay = 30
|
AiPlayerbot.DisabledWithoutRealPlayerLoginDelay = 30
|
||||||
AiPlayerbot.DisabledWithoutRealPlayerLogoutDelay = 300
|
AiPlayerbot.DisabledWithoutRealPlayerLogoutDelay = 300
|
||||||
@@ -153,7 +157,8 @@ AiPlayerbot.AllowGuildBots = 1
|
|||||||
AiPlayerbot.AllowTrustedAccountBots = 1
|
AiPlayerbot.AllowTrustedAccountBots = 1
|
||||||
|
|
||||||
# Randombots will create guilds with nearby randombots
|
# Randombots will create guilds with nearby randombots
|
||||||
# Note: currently, randombots will not invite more bots after a guild is created (i.e., randombot guilds will have only the 10 initial randombots needed to sign the charter)
|
# Note: currently, randombots will not invite more bots after a guild is created,
|
||||||
|
# meaning randombot guilds will have only the 10 initial randombots needed to sign the charter
|
||||||
# Default: 0 (disabled)
|
# Default: 0 (disabled)
|
||||||
AiPlayerbot.RandomBotGuildNearby = 0
|
AiPlayerbot.RandomBotGuildNearby = 0
|
||||||
|
|
||||||
@@ -187,7 +192,8 @@ AiPlayerbot.AutoInitOnly = 0
|
|||||||
# Default: 1.0 (same with the player)
|
# Default: 1.0 (same with the player)
|
||||||
AiPlayerbot.AutoInitEquipLevelLimitRatio = 1.0
|
AiPlayerbot.AutoInitEquipLevelLimitRatio = 1.0
|
||||||
|
|
||||||
# Bot automatically trains spells when talking to trainer (yes = train all available spells as long as the bot has the money, free = auto trains with no money cost, no = only list spells)
|
# Bot automatically trains spells when talking to trainer
|
||||||
|
# yes = train all available spells as long as the bot has the money, free = auto trains with no money cost, no = only list spells
|
||||||
AiPlayerbot.AutoTrainSpells = yes
|
AiPlayerbot.AutoTrainSpells = yes
|
||||||
|
|
||||||
#
|
#
|
||||||
@@ -264,7 +270,7 @@ AiPlayerbot.UseFastFlyMountAtMinLevel = 70
|
|||||||
AiPlayerbot.RandomBotShowHelmet = 1
|
AiPlayerbot.RandomBotShowHelmet = 1
|
||||||
AiPlayerbot.RandomBotShowCloak = 1
|
AiPlayerbot.RandomBotShowCloak = 1
|
||||||
|
|
||||||
# Randombots and altbots automatically equip upgrades (bots will equip any item obtained from looting or a quest if they are sufficient upgrades)
|
# Toggles whether altbots will automatically equip items in their inventory that are sufficient upgrades
|
||||||
# Default: 1 (enabled)
|
# Default: 1 (enabled)
|
||||||
AiPlayerbot.AutoEquipUpgradeLoot = 1
|
AiPlayerbot.AutoEquipUpgradeLoot = 1
|
||||||
|
|
||||||
@@ -312,7 +318,8 @@ AiPlayerbot.GlobalCooldown = 500
|
|||||||
# Max wait time when moving
|
# Max wait time when moving
|
||||||
AiPlayerbot.MaxWaitForMove = 5000
|
AiPlayerbot.MaxWaitForMove = 5000
|
||||||
|
|
||||||
# Disable use of MoveSplinePath for bot movement, will result in more erratic bot movement but means stun/snare/root/etc will work on bots (they wont reliably work when MoveSplinePath is enabled, though slowing effects still work ok)
|
# Enable/disable use of MoveSplinePath for bot movement
|
||||||
|
# Disabling will result in more erratic movement but is required for stuns, snares, and roots to work on bots
|
||||||
# Default: 0 - MoveSplinePath enabled
|
# Default: 0 - MoveSplinePath enabled
|
||||||
# 1 - MoveSplinePath disabled in BG/Arena only
|
# 1 - MoveSplinePath disabled in BG/Arena only
|
||||||
# 2 - MoveSplinePath disabled everywhere
|
# 2 - MoveSplinePath disabled everywhere
|
||||||
@@ -406,10 +413,11 @@ AiPlayerbot.HighMana = 65
|
|||||||
#
|
#
|
||||||
#
|
#
|
||||||
|
|
||||||
# Bots pick their quest rewards (yes = picks the most useful item, no = list all rewards, ask = pick useful item and lists if multiple)
|
# Bots pick their quest rewards
|
||||||
|
# yes = picks the most useful item, no = list all rewards, ask = pick useful item and lists if multiple
|
||||||
AiPlayerbot.AutoPickReward = yes
|
AiPlayerbot.AutoPickReward = yes
|
||||||
|
|
||||||
# Sync quests with player (Bots will complete quests the moment you hand them in and will not loot quest items.)
|
# Sync quests with player (bots will complete quests the moment you hand them in and will not loot quest items.)
|
||||||
# Default: 1 (enabled)
|
# Default: 1 (enabled)
|
||||||
AiPlayerbot.SyncQuestWithPlayer = 1
|
AiPlayerbot.SyncQuestWithPlayer = 1
|
||||||
|
|
||||||
@@ -434,7 +442,7 @@ AiPlayerbot.DropObsoleteQuests = 1
|
|||||||
# Auto add dungeon/raid strategies when entering the instance if implemented
|
# Auto add dungeon/raid strategies when entering the instance if implemented
|
||||||
AiPlayerbot.ApplyInstanceStrategies = 1
|
AiPlayerbot.ApplyInstanceStrategies = 1
|
||||||
|
|
||||||
# Enable auto avoid aoe strategy (experimental)
|
# Enable auto avoid aoe strategy
|
||||||
# Default: 1 (enabled)
|
# Default: 1 (enabled)
|
||||||
AiPlayerbot.AutoAvoidAoe = 1
|
AiPlayerbot.AutoAvoidAoe = 1
|
||||||
|
|
||||||
@@ -461,7 +469,7 @@ AiPlayerbot.FleeingEnabled = 1
|
|||||||
####################################################################################################
|
####################################################################################################
|
||||||
|
|
||||||
####################################################################################################
|
####################################################################################################
|
||||||
# PALADIN BUFFS STRATEGIES
|
# GREATER BUFFS STRATEGIES
|
||||||
#
|
#
|
||||||
#
|
#
|
||||||
|
|
||||||
@@ -484,12 +492,13 @@ AiPlayerbot.RPWarningCooldown = 30
|
|||||||
#
|
#
|
||||||
|
|
||||||
# Enable/Disable maintenance command
|
# Enable/Disable maintenance command
|
||||||
# Learn all available spells and skills, refresh consumables, repair, enchant equipment and socket gems if bot's level is above AiPlayerbot.MinEnchantingBotLevel
|
# Learn all available spells and skills, assign talent points, refresh consumables, repair, enchant equipment, socket gems, etc.
|
||||||
|
# Applies if bot's level is above AiPlayerbot.MinEnchantingBotLevel
|
||||||
# Default: 1 (enabled)
|
# Default: 1 (enabled)
|
||||||
AiPlayerbot.MaintenanceCommand = 1
|
AiPlayerbot.MaintenanceCommand = 1
|
||||||
|
|
||||||
# Enable/Disable specific maintenance command functionality for alt bots
|
# Enable/Disable specific maintenance command functionality for alt bots
|
||||||
# Disable to prevent players from giving free bags, spells, skill levels etc to their alt bots
|
# Disable to prevent players from giving free bags, spells, skill levels, etc. to their alt bots
|
||||||
# Default: 1 (enabled)
|
# Default: 1 (enabled)
|
||||||
AiPlayerbot.AltMaintenanceAmmo = 1
|
AiPlayerbot.AltMaintenanceAmmo = 1
|
||||||
AiPlayerbot.AltMaintenanceFood = 1
|
AiPlayerbot.AltMaintenanceFood = 1
|
||||||
@@ -501,6 +510,7 @@ AiPlayerbot.AltMaintenanceBags = 1
|
|||||||
AiPlayerbot.AltMaintenanceMounts = 1
|
AiPlayerbot.AltMaintenanceMounts = 1
|
||||||
AiPlayerbot.AltMaintenanceSkills = 1
|
AiPlayerbot.AltMaintenanceSkills = 1
|
||||||
|
|
||||||
|
# "Special Spells" consist of any spells listed in AiPlayerbot.RandomBotSpellIds and Death Gate for Death Knights
|
||||||
AiPlayerbot.AltMaintenanceClassSpells = 1
|
AiPlayerbot.AltMaintenanceClassSpells = 1
|
||||||
AiPlayerbot.AltMaintenanceAvailableSpells = 1
|
AiPlayerbot.AltMaintenanceAvailableSpells = 1
|
||||||
AiPlayerbot.AltMaintenanceSpecialSpells = 1
|
AiPlayerbot.AltMaintenanceSpecialSpells = 1
|
||||||
@@ -515,8 +525,8 @@ AiPlayerbot.AltMaintenanceReputation = 1
|
|||||||
AiPlayerbot.AltMaintenanceAttunementQuests = 1
|
AiPlayerbot.AltMaintenanceAttunementQuests = 1
|
||||||
AiPlayerbot.AltMaintenanceKeyring = 1
|
AiPlayerbot.AltMaintenanceKeyring = 1
|
||||||
|
|
||||||
|
# Enable/Disable autogear command, which automatically upgrades bots' gear
|
||||||
# Enable/Disable autogear command, which automatically upgrades bots' gear; the quality is limited by AutoGearQualityLimit and AutoGearScoreLimit
|
# The quality is limited by AutoGearQualityLimit and AutoGearScoreLimit
|
||||||
# Default: 1 (enabled)
|
# Default: 1 (enabled)
|
||||||
AiPlayerbot.AutoGearCommand = 1
|
AiPlayerbot.AutoGearCommand = 1
|
||||||
|
|
||||||
@@ -534,8 +544,8 @@ AiPlayerbot.AutoGearQualityLimit = 3
|
|||||||
# Max iLVL Phase 1(MC, Ony, ZG) = 78 | Phase 2(BWL) = 83 | Phase 2.5(AQ40) = 88 | Phase 3(Naxx40) = 92
|
# Max iLVL Phase 1(MC, Ony, ZG) = 78 | Phase 2(BWL) = 83 | Phase 2.5(AQ40) = 88 | Phase 3(Naxx40) = 92
|
||||||
# TBC
|
# TBC
|
||||||
# Max iLVL Tier 4 = 120 | Tier 5 = 133 | Tier 6 = 164
|
# Max iLVL Tier 4 = 120 | Tier 5 = 133 | Tier 6 = 164
|
||||||
# Max iLVL Phase 1(Kara, Gruul, Mag) = 125 | Phase 1.5(ZA) = 138 | Phase 2(SC, TK) = 141 | Phase 3(Hyjal, BT) = 156 | Phase 4(Sunwell) = 164
|
# Max iLVL Phase 1(Kara, Gruul, Mag) = 125 | Phase 2(SSC, TK, ZA) = 141 | Phase 3(Hyjal, BT) = 156 | Phase 4(Sunwell) = 164
|
||||||
# Wotlk
|
# WotLK
|
||||||
# Max iLVL Tier 7(10/25) = 200/213 | Tier 8(10/25) = 225/232 | Tier 9(10/25) = 232/245 | Tier 10(10/25/HC) = 251/264/290
|
# Max iLVL Tier 7(10/25) = 200/213 | Tier 8(10/25) = 225/232 | Tier 9(10/25) = 232/245 | Tier 10(10/25/HC) = 251/264/290
|
||||||
# Max iLVL Phase 1(Naxx) = 224 | Phase 2(Ulduar) = 245 | Phase 3(ToC) = 258 | Phase 4(ICC) = 290
|
# Max iLVL Phase 1(Naxx) = 224 | Phase 2(Ulduar) = 245 | Phase 3(ToC) = 258 | Phase 4(ICC) = 290
|
||||||
# Default: 0 (no limit)
|
# Default: 0 (no limit)
|
||||||
@@ -582,15 +592,21 @@ AiPlayerbot.BotTaxiGapJitterMs = 100
|
|||||||
|
|
||||||
####################################################################################################
|
####################################################################################################
|
||||||
# PROFESSIONS
|
# PROFESSIONS
|
||||||
# Random bots currently do not get professions.
|
# Note: Random bots currently do not get professions
|
||||||
#
|
#
|
||||||
|
|
||||||
# EnableFishingWithMaster automatically adds the 'master fishing' strategy to bots that can fish that can.
|
# Automatically adds the 'master fishing' strategy to bots that have the fishing skill when the bots master fishes.
|
||||||
# Default: 1 (Enabled)
|
# Default: 1 (Enabled)
|
||||||
AiPlayerbot.EnableFishingWithMaster = 1
|
AiPlayerbot.EnableFishingWithMaster = 1
|
||||||
#FishingDistance sets how far a bot without a master will search for water, while FishingDistanceFromMaster limits it to a closer range, and overrides the following distance to the same value. EndFishingWithMaster sets the distance from water a bot needs to have to automatically drop the 'master fishing' strategy.
|
|
||||||
|
# Distance from itself (in yards) that a bot with a master will search for water to fish
|
||||||
AiPlayerbot.FishingDistanceFromMaster = 10.0
|
AiPlayerbot.FishingDistanceFromMaster = 10.0
|
||||||
|
|
||||||
|
# Distance from itself (in yards) that a bot without a master will search for water to fish
|
||||||
|
# Currently not relevant since masterless bots will not fish
|
||||||
AiPlayerbot.FishingDistance = 40.0
|
AiPlayerbot.FishingDistance = 40.0
|
||||||
|
|
||||||
|
# Distance from water (in yards) beyond which a bot will remove the 'master fishing' strategy
|
||||||
AiPlayerbot.EndFishingWithMaster = 30.0
|
AiPlayerbot.EndFishingWithMaster = 30.0
|
||||||
|
|
||||||
#
|
#
|
||||||
@@ -654,7 +670,7 @@ AiPlayerbot.DisableDeathKnightLogin = 0
|
|||||||
# Default: 0 (disabled)
|
# Default: 0 (disabled)
|
||||||
AiPlayerbot.LimitTalentsExpansion = 0
|
AiPlayerbot.LimitTalentsExpansion = 0
|
||||||
|
|
||||||
# Configure randombots and addClass bot trading (0: Disabled, 1: Enabled, 2: Only Buy, 3: Only Sell)
|
# Configure randombot trading (0: Disabled, 1: Enabled, 2: Only Buy, 3: Only Sell)
|
||||||
# Default: 1 (enabled)
|
# Default: 1 (enabled)
|
||||||
AiPlayerbot.EnableRandomBotTrading = 1
|
AiPlayerbot.EnableRandomBotTrading = 1
|
||||||
|
|
||||||
@@ -719,8 +735,8 @@ AiPlayerbot.RandomGearQualityLimit = 3
|
|||||||
# Max iLVL Phase 1(MC, Ony, ZG) = 78 | Phase 2(BWL) = 83 | Phase 2.5(AQ40) = 88 | Phase 3(Naxx40) = 92
|
# Max iLVL Phase 1(MC, Ony, ZG) = 78 | Phase 2(BWL) = 83 | Phase 2.5(AQ40) = 88 | Phase 3(Naxx40) = 92
|
||||||
# TBC
|
# TBC
|
||||||
# Max iLVL Tier 4 = 120 | Tier 5 = 133 | Tier 6 = 164
|
# Max iLVL Tier 4 = 120 | Tier 5 = 133 | Tier 6 = 164
|
||||||
# Max iLVL Phase 1(Kara, Gruul, Mag) = 125 | Phase 1.5(ZA) = 138 | Phase 2(SC, TK) = 141 | Phase 3(Hyjal, BT) = 156 | Phase 4(Sunwell) = 164
|
# Max iLVL Phase 1(Kara, Gruul, Mag) = 125 | Phase 2(SSC, TK, ZA) = 141 | Phase 3(Hyjal, BT) = 156 | Phase 4(Sunwell) = 164
|
||||||
# Wotlk
|
# WotLK
|
||||||
# Max iLVL Tier 7(10/25) = 200/213 | Tier 8(10/25) = 225/232 | Tier 9(10/25) = 232/245 | Tier 10(10/25/HC) = 251/264/290
|
# Max iLVL Tier 7(10/25) = 200/213 | Tier 8(10/25) = 225/232 | Tier 9(10/25) = 232/245 | Tier 10(10/25/HC) = 251/264/290
|
||||||
# Max iLVL Phase 1(Naxx) = 224 | Phase 2(Ulduar) = 245 | Phase 3(ToC) = 258 | Phase 4(ICC) = 290
|
# Max iLVL Phase 1(Naxx) = 224 | Phase 2(Ulduar) = 245 | Phase 3(ToC) = 258 | Phase 4(ICC) = 290
|
||||||
# Default: 0 (no limit)
|
# Default: 0 (no limit)
|
||||||
@@ -730,7 +746,8 @@ AiPlayerbot.RandomGearScoreLimit = 0
|
|||||||
# Default: 1 (enabled)
|
# Default: 1 (enabled)
|
||||||
AiPlayerbot.IncrementalGearInit = 1
|
AiPlayerbot.IncrementalGearInit = 1
|
||||||
|
|
||||||
# Set minimum level of bots that will enchant their equipment (if greater than RandomBotMaxlevel, bots will not enchant equipment)
|
# Set minimum level of bots that will enchant and socket gems into their equipment with maintenance
|
||||||
|
# If greater than RandomBotMaxlevel, bots will not automatically enchant equipment or socket gems
|
||||||
# Default: 60
|
# Default: 60
|
||||||
AiPlayerbot.MinEnchantingBotLevel = 60
|
AiPlayerbot.MinEnchantingBotLevel = 60
|
||||||
|
|
||||||
@@ -882,13 +899,15 @@ AiPlayerbot.OpenGoSpell = 6477
|
|||||||
#
|
#
|
||||||
|
|
||||||
# Additional randombot strategies
|
# Additional randombot strategies
|
||||||
# Strategies added here are applied to all randombots, in addition (or subtraction) to spec/role-based default strategies. These rules are processed after the defaults.
|
# Strategies added here are applied to all randombots, in addition (or subtraction) to spec/role-based default strategies.
|
||||||
|
# These rules are processed after the defaults.
|
||||||
# Example: "+threat,-potions"
|
# Example: "+threat,-potions"
|
||||||
AiPlayerbot.RandomBotCombatStrategies = ""
|
AiPlayerbot.RandomBotCombatStrategies = ""
|
||||||
AiPlayerbot.RandomBotNonCombatStrategies = ""
|
AiPlayerbot.RandomBotNonCombatStrategies = ""
|
||||||
|
|
||||||
# Additional altbot strategies
|
# Additional altbot strategies
|
||||||
# Strategies added here are applied to all altbots, in addition (or subtraction) to spec/role-based default strategies. These rules are processed after the defaults.
|
# Strategies added here are applied to all altbots, in addition (or subtraction) to spec/role-based default strategies.
|
||||||
|
# These rules are processed after the defaults.
|
||||||
AiPlayerbot.CombatStrategies = ""
|
AiPlayerbot.CombatStrategies = ""
|
||||||
AiPlayerbot.NonCombatStrategies = ""
|
AiPlayerbot.NonCombatStrategies = ""
|
||||||
|
|
||||||
@@ -1605,7 +1624,7 @@ AiPlayerbot.PremadeSpecLink.9.1.60 = -003203301135112530135201051
|
|||||||
AiPlayerbot.PremadeSpecLink.9.1.70 = -003203301135112530135201051-55
|
AiPlayerbot.PremadeSpecLink.9.1.70 = -003203301135112530135201051-55
|
||||||
AiPlayerbot.PremadeSpecLink.9.1.80 = -003203301135112530135221351-55000005
|
AiPlayerbot.PremadeSpecLink.9.1.80 = -003203301135112530135221351-55000005
|
||||||
AiPlayerbot.PremadeSpecName.9.2 = destro pve
|
AiPlayerbot.PremadeSpecName.9.2 = destro pve
|
||||||
AiPlayerbot.PremadeSpecGlyph.9.2 = 45785,43390,50077,43394,43393,42454
|
AiPlayerbot.PremadeSpecGlyph.9.2 = 45785,43390,42454,43394,43393,45785
|
||||||
AiPlayerbot.PremadeSpecLink.9.2.60 = --05203215200231051305031151
|
AiPlayerbot.PremadeSpecLink.9.2.60 = --05203215200231051305031151
|
||||||
AiPlayerbot.PremadeSpecLink.9.2.80 = 23-0302-05203215220331051335231351
|
AiPlayerbot.PremadeSpecLink.9.2.80 = 23-0302-05203215220331051335231351
|
||||||
AiPlayerbot.PremadeSpecName.9.3 = affli pvp
|
AiPlayerbot.PremadeSpecName.9.3 = affli pvp
|
||||||
|
|||||||
@@ -46,10 +46,10 @@ bool AcceptInvitationAction::Execute(Event event)
|
|||||||
if (!bot->GetGroup() || !bot->GetGroup()->IsMember(inviter->GetGUID()))
|
if (!bot->GetGroup() || !bot->GetGroup()->IsMember(inviter->GetGUID()))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (sRandomPlayerbotMgr->IsRandomBot(bot))
|
if (sRandomPlayerbotMgr.IsRandomBot(bot))
|
||||||
botAI->SetMaster(inviter);
|
botAI->SetMaster(inviter);
|
||||||
// else
|
// else
|
||||||
// sPlayerbotDbStore->Save(botAI);
|
// PlayerbotRepository::instance().Save(botAI);
|
||||||
|
|
||||||
botAI->ResetStrategies();
|
botAI->ResetStrategies();
|
||||||
botAI->ChangeStrategy("+follow,-lfg,-bg", BOT_STATE_NON_COMBAT);
|
botAI->ChangeStrategy("+follow,-lfg,-bg", BOT_STATE_NON_COMBAT);
|
||||||
@@ -57,7 +57,7 @@ bool AcceptInvitationAction::Execute(Event event)
|
|||||||
|
|
||||||
botAI->TellMaster("Hello");
|
botAI->TellMaster("Hello");
|
||||||
|
|
||||||
if (sPlayerbotAIConfig->summonWhenGroup && bot->GetDistance(inviter) > sPlayerbotAIConfig->sightDistance)
|
if (sPlayerbotAIConfig.summonWhenGroup && bot->GetDistance(inviter) > sPlayerbotAIConfig.sightDistance)
|
||||||
{
|
{
|
||||||
Teleport(inviter, bot, true);
|
Teleport(inviter, bot, true);
|
||||||
}
|
}
|
||||||
@@ -50,7 +50,7 @@ bool ReachAreaTriggerAction::Execute(Event event)
|
|||||||
/*forceDestination*/ false);
|
/*forceDestination*/ false);
|
||||||
|
|
||||||
float distance = bot->GetDistance(at->x, at->y, at->z);
|
float distance = bot->GetDistance(at->x, at->y, at->z);
|
||||||
float delay = 1000.0f * distance / bot->GetSpeed(MOVE_RUN) + sPlayerbotAIConfig->reactDelay;
|
float delay = 1000.0f * distance / bot->GetSpeed(MOVE_RUN) + sPlayerbotAIConfig.reactDelay;
|
||||||
botAI->TellError("Wait for me");
|
botAI->TellError("Wait for me");
|
||||||
botAI->SetNextCheckDelay(delay);
|
botAI->SetNextCheckDelay(delay);
|
||||||
context->GetValue<LastMovement&>("last area trigger")->Get().lastAreaTrigger = triggerId;
|
context->GetValue<LastMovement&>("last area trigger")->Get().lastAreaTrigger = triggerId;
|
||||||
@@ -87,8 +87,8 @@ bool AttackAction::Attack(Unit* target, bool /*with_pet*/ /*true*/)
|
|||||||
// Check if bot OR target is in prohibited zone/area (skip for duels)
|
// Check if bot OR target is in prohibited zone/area (skip for duels)
|
||||||
if ((target->IsPlayer() || target->IsPet()) &&
|
if ((target->IsPlayer() || target->IsPet()) &&
|
||||||
(!bot->duel || bot->duel->Opponent != target) &&
|
(!bot->duel || bot->duel->Opponent != target) &&
|
||||||
(sPlayerbotAIConfig->IsPvpProhibited(bot->GetZoneId(), bot->GetAreaId()) ||
|
(sPlayerbotAIConfig.IsPvpProhibited(bot->GetZoneId(), bot->GetAreaId()) ||
|
||||||
sPlayerbotAIConfig->IsPvpProhibited(target->GetZoneId(), target->GetAreaId())))
|
sPlayerbotAIConfig.IsPvpProhibited(target->GetZoneId(), target->GetAreaId())))
|
||||||
{
|
{
|
||||||
if (verbose)
|
if (verbose)
|
||||||
botAI->TellError("I cannot attack other players in PvP prohibited areas.");
|
botAI->TellError("I cannot attack other players in PvP prohibited areas.");
|
||||||
@@ -160,7 +160,7 @@ bool AttackAction::Attack(Unit* target, bool /*with_pet*/ /*true*/)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (botAI->CanMove() && !bot->HasInArc(CAST_ANGLE_IN_FRONT, target))
|
if (botAI->CanMove() && !bot->HasInArc(CAST_ANGLE_IN_FRONT, target))
|
||||||
sServerFacade->SetFacingTo(bot, target);
|
ServerFacade::instance().SetFacingTo(bot, target);
|
||||||
|
|
||||||
botAI->ChangeEngine(BOT_STATE_COMBAT);
|
botAI->ChangeEngine(BOT_STATE_COMBAT);
|
||||||
|
|
||||||
@@ -19,7 +19,7 @@ bool AutoMaintenanceOnLevelupAction::Execute(Event event)
|
|||||||
|
|
||||||
void AutoMaintenanceOnLevelupAction::AutoTeleportForLevel()
|
void AutoMaintenanceOnLevelupAction::AutoTeleportForLevel()
|
||||||
{
|
{
|
||||||
if (!sPlayerbotAIConfig->autoTeleportForLevel || !sRandomPlayerbotMgr->IsRandomBot(bot))
|
if (!sPlayerbotAIConfig.autoTeleportForLevel || !sRandomPlayerbotMgr.IsRandomBot(bot))
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -27,13 +27,13 @@ void AutoMaintenanceOnLevelupAction::AutoTeleportForLevel()
|
|||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
sRandomPlayerbotMgr->RandomTeleportForLevel(bot);
|
sRandomPlayerbotMgr.RandomTeleportForLevel(bot);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
void AutoMaintenanceOnLevelupAction::AutoPickTalents()
|
void AutoMaintenanceOnLevelupAction::AutoPickTalents()
|
||||||
{
|
{
|
||||||
if (!sPlayerbotAIConfig->autoPickTalents || !sRandomPlayerbotMgr->IsRandomBot(bot))
|
if (!sPlayerbotAIConfig.autoPickTalents || !sRandomPlayerbotMgr.IsRandomBot(bot))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (bot->GetFreeTalentPoints() <= 0)
|
if (bot->GetFreeTalentPoints() <= 0)
|
||||||
@@ -65,46 +65,89 @@ void AutoMaintenanceOnLevelupAction::AutoLearnSpell()
|
|||||||
void AutoMaintenanceOnLevelupAction::LearnSpells(std::ostringstream* out)
|
void AutoMaintenanceOnLevelupAction::LearnSpells(std::ostringstream* out)
|
||||||
{
|
{
|
||||||
BroadcastHelper::BroadcastLevelup(botAI, bot);
|
BroadcastHelper::BroadcastLevelup(botAI, bot);
|
||||||
if (sPlayerbotAIConfig->autoLearnTrainerSpells && sRandomPlayerbotMgr->IsRandomBot(bot))
|
if (sPlayerbotAIConfig.autoLearnTrainerSpells && sRandomPlayerbotMgr.IsRandomBot(bot))
|
||||||
LearnTrainerSpells(out);
|
LearnTrainerSpells(out);
|
||||||
|
|
||||||
if (sPlayerbotAIConfig->autoLearnQuestSpells && sRandomPlayerbotMgr->IsRandomBot(bot))
|
if (sPlayerbotAIConfig.autoLearnQuestSpells && sRandomPlayerbotMgr.IsRandomBot(bot))
|
||||||
LearnQuestSpells(out);
|
LearnQuestSpells(out);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AutoMaintenanceOnLevelupAction::LearnTrainerSpells(std::ostringstream* out)
|
void AutoMaintenanceOnLevelupAction::LearnTrainerSpells(std::ostringstream* out)
|
||||||
{
|
{
|
||||||
PlayerbotFactory factory(bot, bot->GetLevel());
|
PlayerbotFactory factory(bot, bot->GetLevel());
|
||||||
|
factory.InitSkills();
|
||||||
factory.InitClassSpells();
|
factory.InitClassSpells();
|
||||||
factory.InitAvailableSpells();
|
factory.InitAvailableSpells();
|
||||||
factory.InitSkills();
|
|
||||||
factory.InitPet();
|
factory.InitPet();
|
||||||
}
|
}
|
||||||
|
|
||||||
void AutoMaintenanceOnLevelupAction::LearnQuestSpells(std::ostringstream* out)
|
void AutoMaintenanceOnLevelupAction::LearnQuestSpells(std::ostringstream* out)
|
||||||
{
|
{
|
||||||
// CreatureTemplate const* co = sCreatureStorage.LookupEntry<CreatureTemplate>(id);
|
|
||||||
ObjectMgr::QuestMap const& questTemplates = sObjectMgr->GetQuestTemplates();
|
ObjectMgr::QuestMap const& questTemplates = sObjectMgr->GetQuestTemplates();
|
||||||
for (ObjectMgr::QuestMap::const_iterator i = questTemplates.begin(); i != questTemplates.end(); ++i)
|
for (ObjectMgr::QuestMap::const_iterator i = questTemplates.begin(); i != questTemplates.end(); ++i)
|
||||||
{
|
{
|
||||||
//uint32 questId = i->first; //not used, line marked for removal.
|
|
||||||
Quest const* quest = i->second;
|
Quest const* quest = i->second;
|
||||||
|
|
||||||
if (!quest->GetRequiredClasses() || quest->IsRepeatable() || quest->GetMinLevel() < 10)
|
// only process class-specific quests to learn class-related spells, cuz
|
||||||
|
// we don't want all these bunch of entries to be handled!
|
||||||
|
if (!quest->GetRequiredClasses())
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (!bot->SatisfyQuestClass(quest, false) || quest->GetMinLevel() > bot->GetLevel() ||
|
// skip quests that are repeatable, too low level, or above bots' level
|
||||||
!bot->SatisfyQuestRace(quest, false))
|
if (quest->IsRepeatable() || quest->GetMinLevel() < 10 || quest->GetMinLevel() > bot->GetLevel())
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (quest->GetRewSpellCast() > 0)
|
// skip if bot doesnt satisfy class, race, or skill requirements
|
||||||
|
if (!bot->SatisfyQuestClass(quest, false) || !bot->SatisfyQuestRace(quest, false) ||
|
||||||
|
!bot->SatisfyQuestSkill(quest, false))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// use the same logic and impl from Player::learnQuestRewardedSpells
|
||||||
|
|
||||||
|
int32 spellId = quest->GetRewSpellCast();
|
||||||
|
if (!spellId)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spellId);
|
||||||
|
if (!spellInfo)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// xinef: find effect with learn spell and check if we have this spell
|
||||||
|
bool found = false;
|
||||||
|
for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
|
||||||
{
|
{
|
||||||
LearnSpell(quest->GetRewSpellCast(), out);
|
if (spellInfo->Effects[i].Effect == SPELL_EFFECT_LEARN_SPELL && spellInfo->Effects[i].TriggerSpell &&
|
||||||
|
!bot->HasSpell(spellInfo->Effects[i].TriggerSpell))
|
||||||
|
{
|
||||||
|
// pusywizard: don't re-add profession specialties!
|
||||||
|
if (SpellInfo const* triggeredInfo = sSpellMgr->GetSpellInfo(spellInfo->Effects[i].TriggerSpell))
|
||||||
|
if (triggeredInfo->Effects[0].Effect == SPELL_EFFECT_TRADE_SKILL)
|
||||||
|
break; // pussywizard: break and not cast the spell (found is false)
|
||||||
|
|
||||||
|
found = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if (quest->GetRewSpell() > 0)
|
|
||||||
|
// xinef: we know the spell, continue
|
||||||
|
if (!found)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
bot->CastSpell(bot, spellId, true);
|
||||||
|
|
||||||
|
// Check if RewardDisplaySpell is set to output the proper spell learned
|
||||||
|
// after processing quests. Output the original RewardSpell otherwise.
|
||||||
|
uint32 rewSpellId = quest->GetRewSpell();
|
||||||
|
if (rewSpellId)
|
||||||
{
|
{
|
||||||
LearnSpell(quest->GetRewSpell(), out);
|
if (SpellInfo const* rewSpellInfo = sSpellMgr->GetSpellInfo(rewSpellId))
|
||||||
|
{
|
||||||
|
*out << FormatSpell(rewSpellInfo) << ", ";
|
||||||
|
continue;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
*out << FormatSpell(spellInfo) << ", ";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -121,42 +164,9 @@ std::string const AutoMaintenanceOnLevelupAction::FormatSpell(SpellInfo const* s
|
|||||||
return out.str();
|
return out.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
void AutoMaintenanceOnLevelupAction::LearnSpell(uint32 spellId, std::ostringstream* out)
|
|
||||||
{
|
|
||||||
SpellInfo const* proto = sSpellMgr->GetSpellInfo(spellId);
|
|
||||||
if (!proto)
|
|
||||||
return;
|
|
||||||
|
|
||||||
bool learned = false;
|
|
||||||
for (uint8 j = 0; j < 3; ++j)
|
|
||||||
{
|
|
||||||
if (proto->Effects[j].Effect == SPELL_EFFECT_LEARN_SPELL)
|
|
||||||
{
|
|
||||||
uint32 learnedSpell = proto->Effects[j].TriggerSpell;
|
|
||||||
|
|
||||||
if (!bot->HasSpell(learnedSpell))
|
|
||||||
{
|
|
||||||
bot->learnSpell(learnedSpell);
|
|
||||||
*out << FormatSpell(sSpellMgr->GetSpellInfo(learnedSpell)) << ", ";
|
|
||||||
}
|
|
||||||
|
|
||||||
learned = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!learned)
|
|
||||||
{
|
|
||||||
if (!bot->HasSpell(spellId))
|
|
||||||
{
|
|
||||||
bot->learnSpell(spellId);
|
|
||||||
*out << FormatSpell(proto) << ", ";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void AutoMaintenanceOnLevelupAction::AutoUpgradeEquip()
|
void AutoMaintenanceOnLevelupAction::AutoUpgradeEquip()
|
||||||
{
|
{
|
||||||
if (!sPlayerbotAIConfig->autoUpgradeEquip || !sRandomPlayerbotMgr->IsRandomBot(bot))
|
if (!sPlayerbotAIConfig.autoUpgradeEquip || !sRandomPlayerbotMgr.IsRandomBot(bot))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
PlayerbotFactory factory(bot, bot->GetLevel());
|
PlayerbotFactory factory(bot, bot->GetLevel());
|
||||||
@@ -170,9 +180,9 @@ void AutoMaintenanceOnLevelupAction::AutoUpgradeEquip()
|
|||||||
factory.InitConsumables();
|
factory.InitConsumables();
|
||||||
factory.InitPotions();
|
factory.InitPotions();
|
||||||
|
|
||||||
if (!sPlayerbotAIConfig->equipmentPersistence || bot->GetLevel() < sPlayerbotAIConfig->equipmentPersistenceLevel)
|
if (!sPlayerbotAIConfig.equipmentPersistence || bot->GetLevel() < sPlayerbotAIConfig.equipmentPersistenceLevel)
|
||||||
{
|
{
|
||||||
if (sPlayerbotAIConfig->incrementalGearInit)
|
if (sPlayerbotAIConfig.incrementalGearInit)
|
||||||
factory.InitEquipment(true);
|
factory.InitEquipment(true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -28,7 +28,6 @@ protected:
|
|||||||
void LearnSpells(std::ostringstream* out);
|
void LearnSpells(std::ostringstream* out);
|
||||||
void LearnTrainerSpells(std::ostringstream* out);
|
void LearnTrainerSpells(std::ostringstream* out);
|
||||||
void LearnQuestSpells(std::ostringstream* out);
|
void LearnQuestSpells(std::ostringstream* out);
|
||||||
void LearnSpell(uint32 spellId, std::ostringstream* out);
|
|
||||||
std::string const FormatSpell(SpellInfo const* sInfo);
|
std::string const FormatSpell(SpellInfo const* sInfo);
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -89,7 +89,7 @@ bool BGJoinAction::gatherArenaTeam(ArenaType type)
|
|||||||
// continue;
|
// continue;
|
||||||
|
|
||||||
if (offline)
|
if (offline)
|
||||||
sRandomPlayerbotMgr->AddPlayerBot(itr->Guid, 0);
|
sRandomPlayerbotMgr.AddPlayerBot(itr->Guid, 0);
|
||||||
|
|
||||||
if (member)
|
if (member)
|
||||||
{
|
{
|
||||||
@@ -100,7 +100,7 @@ bool BGJoinAction::gatherArenaTeam(ArenaType type)
|
|||||||
if (member->GetGroup() && memberBotAI->HasRealPlayerMaster())
|
if (member->GetGroup() && memberBotAI->HasRealPlayerMaster())
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (!sPlayerbotAIConfig->IsInRandomAccountList(member->GetSession()->GetAccountId()))
|
if (!sPlayerbotAIConfig.IsInRandomAccountList(member->GetSession()->GetAccountId()))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (member->IsInCombat())
|
if (member->IsInCombat())
|
||||||
@@ -250,13 +250,13 @@ bool BGJoinAction::shouldJoinBg(BattlegroundQueueTypeId queueTypeId, Battlegroun
|
|||||||
TeamSize = (uint32)type;
|
TeamSize = (uint32)type;
|
||||||
|
|
||||||
// Check if bots should join Rated Arena (Only captains can queue)
|
// Check if bots should join Rated Arena (Only captains can queue)
|
||||||
uint32 ratedArenaBotCount = sRandomPlayerbotMgr->BattlegroundData[queueTypeId][bracketId].ratedArenaBotCount;
|
uint32 ratedArenaBotCount = sRandomPlayerbotMgr.BattlegroundData[queueTypeId][bracketId].ratedArenaBotCount;
|
||||||
uint32 ratedArenaPlayerCount =
|
uint32 ratedArenaPlayerCount =
|
||||||
sRandomPlayerbotMgr->BattlegroundData[queueTypeId][bracketId].ratedArenaPlayerCount;
|
sRandomPlayerbotMgr.BattlegroundData[queueTypeId][bracketId].ratedArenaPlayerCount;
|
||||||
uint32 ratedArenaInstanceCount =
|
uint32 ratedArenaInstanceCount =
|
||||||
sRandomPlayerbotMgr->BattlegroundData[queueTypeId][bracketId].ratedArenaInstanceCount;
|
sRandomPlayerbotMgr.BattlegroundData[queueTypeId][bracketId].ratedArenaInstanceCount;
|
||||||
uint32 activeRatedArenaQueue =
|
uint32 activeRatedArenaQueue =
|
||||||
sRandomPlayerbotMgr->BattlegroundData[queueTypeId][bracketId].activeRatedArenaQueue;
|
sRandomPlayerbotMgr.BattlegroundData[queueTypeId][bracketId].activeRatedArenaQueue;
|
||||||
|
|
||||||
bool isRated = (ratedArenaBotCount + ratedArenaPlayerCount) <
|
bool isRated = (ratedArenaBotCount + ratedArenaPlayerCount) <
|
||||||
(BracketSize * (activeRatedArenaQueue + ratedArenaInstanceCount));
|
(BracketSize * (activeRatedArenaQueue + ratedArenaInstanceCount));
|
||||||
@@ -265,7 +265,7 @@ bool BGJoinAction::shouldJoinBg(BattlegroundQueueTypeId queueTypeId, Battlegroun
|
|||||||
{
|
{
|
||||||
if (sArenaTeamMgr->GetArenaTeamByCaptain(bot->GetGUID(), type))
|
if (sArenaTeamMgr->GetArenaTeamByCaptain(bot->GetGUID(), type))
|
||||||
{
|
{
|
||||||
sRandomPlayerbotMgr->BattlegroundData[queueTypeId][bracketId].ratedArenaBotCount += TeamSize;
|
sRandomPlayerbotMgr.BattlegroundData[queueTypeId][bracketId].ratedArenaBotCount += TeamSize;
|
||||||
ratedList.push_back(queueTypeId);
|
ratedList.push_back(queueTypeId);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -274,13 +274,13 @@ bool BGJoinAction::shouldJoinBg(BattlegroundQueueTypeId queueTypeId, Battlegroun
|
|||||||
// Check if bots should join Skirmish Arena
|
// Check if bots should join Skirmish Arena
|
||||||
// We have extra bots queue because same faction can vs each other but can't be in the same group.
|
// We have extra bots queue because same faction can vs each other but can't be in the same group.
|
||||||
uint32 skirmishArenaBotCount =
|
uint32 skirmishArenaBotCount =
|
||||||
sRandomPlayerbotMgr->BattlegroundData[queueTypeId][bracketId].skirmishArenaBotCount;
|
sRandomPlayerbotMgr.BattlegroundData[queueTypeId][bracketId].skirmishArenaBotCount;
|
||||||
uint32 skirmishArenaPlayerCount =
|
uint32 skirmishArenaPlayerCount =
|
||||||
sRandomPlayerbotMgr->BattlegroundData[queueTypeId][bracketId].skirmishArenaPlayerCount;
|
sRandomPlayerbotMgr.BattlegroundData[queueTypeId][bracketId].skirmishArenaPlayerCount;
|
||||||
uint32 skirmishArenaInstanceCount =
|
uint32 skirmishArenaInstanceCount =
|
||||||
sRandomPlayerbotMgr->BattlegroundData[queueTypeId][bracketId].skirmishArenaInstanceCount;
|
sRandomPlayerbotMgr.BattlegroundData[queueTypeId][bracketId].skirmishArenaInstanceCount;
|
||||||
uint32 activeSkirmishArenaQueue =
|
uint32 activeSkirmishArenaQueue =
|
||||||
sRandomPlayerbotMgr->BattlegroundData[queueTypeId][bracketId].activeSkirmishArenaQueue;
|
sRandomPlayerbotMgr.BattlegroundData[queueTypeId][bracketId].activeSkirmishArenaQueue;
|
||||||
uint32 maxRequiredSkirmishBots = BracketSize * (activeSkirmishArenaQueue + skirmishArenaInstanceCount);
|
uint32 maxRequiredSkirmishBots = BracketSize * (activeSkirmishArenaQueue + skirmishArenaInstanceCount);
|
||||||
if (maxRequiredSkirmishBots != 0)
|
if (maxRequiredSkirmishBots != 0)
|
||||||
maxRequiredSkirmishBots = maxRequiredSkirmishBots + TeamSize;
|
maxRequiredSkirmishBots = maxRequiredSkirmishBots + TeamSize;
|
||||||
@@ -294,12 +294,12 @@ bool BGJoinAction::shouldJoinBg(BattlegroundQueueTypeId queueTypeId, Battlegroun
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Check if bots should join Battleground
|
// Check if bots should join Battleground
|
||||||
uint32 bgAllianceBotCount = sRandomPlayerbotMgr->BattlegroundData[queueTypeId][bracketId].bgAllianceBotCount;
|
uint32 bgAllianceBotCount = sRandomPlayerbotMgr.BattlegroundData[queueTypeId][bracketId].bgAllianceBotCount;
|
||||||
uint32 bgAlliancePlayerCount = sRandomPlayerbotMgr->BattlegroundData[queueTypeId][bracketId].bgAlliancePlayerCount;
|
uint32 bgAlliancePlayerCount = sRandomPlayerbotMgr.BattlegroundData[queueTypeId][bracketId].bgAlliancePlayerCount;
|
||||||
uint32 bgHordeBotCount = sRandomPlayerbotMgr->BattlegroundData[queueTypeId][bracketId].bgHordeBotCount;
|
uint32 bgHordeBotCount = sRandomPlayerbotMgr.BattlegroundData[queueTypeId][bracketId].bgHordeBotCount;
|
||||||
uint32 bgHordePlayerCount = sRandomPlayerbotMgr->BattlegroundData[queueTypeId][bracketId].bgHordePlayerCount;
|
uint32 bgHordePlayerCount = sRandomPlayerbotMgr.BattlegroundData[queueTypeId][bracketId].bgHordePlayerCount;
|
||||||
uint32 activeBgQueue = sRandomPlayerbotMgr->BattlegroundData[queueTypeId][bracketId].activeBgQueue;
|
uint32 activeBgQueue = sRandomPlayerbotMgr.BattlegroundData[queueTypeId][bracketId].activeBgQueue;
|
||||||
uint32 bgInstanceCount = sRandomPlayerbotMgr->BattlegroundData[queueTypeId][bracketId].bgInstanceCount;
|
uint32 bgInstanceCount = sRandomPlayerbotMgr.BattlegroundData[queueTypeId][bracketId].bgInstanceCount;
|
||||||
|
|
||||||
if (teamId == TEAM_ALLIANCE)
|
if (teamId == TEAM_ALLIANCE)
|
||||||
{
|
{
|
||||||
@@ -318,7 +318,7 @@ bool BGJoinAction::shouldJoinBg(BattlegroundQueueTypeId queueTypeId, Battlegroun
|
|||||||
bool BGJoinAction::isUseful()
|
bool BGJoinAction::isUseful()
|
||||||
{
|
{
|
||||||
// do not try if BG bots disabled
|
// do not try if BG bots disabled
|
||||||
if (!sPlayerbotAIConfig->randomBotJoinBG)
|
if (!sPlayerbotAIConfig.randomBotJoinBG)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// can't queue while in BG/Arena
|
// can't queue while in BG/Arena
|
||||||
@@ -440,7 +440,7 @@ bool BGJoinAction::JoinQueue(uint32 type)
|
|||||||
|
|
||||||
// get battlemaster
|
// get battlemaster
|
||||||
// Unit* unit = botAI->GetUnit(AI_VALUE2(CreatureData const*, "bg master", bgTypeId));
|
// Unit* unit = botAI->GetUnit(AI_VALUE2(CreatureData const*, "bg master", bgTypeId));
|
||||||
Unit* unit = botAI->GetUnit(sRandomPlayerbotMgr->GetBattleMasterGUID(bot, bgTypeId));
|
Unit* unit = botAI->GetUnit(sRandomPlayerbotMgr.GetBattleMasterGUID(bot, bgTypeId));
|
||||||
if (!unit && isArena)
|
if (!unit && isArena)
|
||||||
{
|
{
|
||||||
botAI->GetAiObjectContext()->GetValue<uint32>("bg type")->Set(0);
|
botAI->GetAiObjectContext()->GetValue<uint32>("bg type")->Set(0);
|
||||||
@@ -450,7 +450,7 @@ bool BGJoinAction::JoinQueue(uint32 type)
|
|||||||
|
|
||||||
// This breaks groups as refresh includes a remove from group function call.
|
// This breaks groups as refresh includes a remove from group function call.
|
||||||
// refresh food/regs
|
// refresh food/regs
|
||||||
// sRandomPlayerbotMgr->Refresh(bot);
|
// sRandomPlayerbotMgr.Refresh(bot);
|
||||||
|
|
||||||
bool joinAsGroup = bot->GetGroup() && bot->GetGroup()->GetLeaderGUID() == bot->GetGUID();
|
bool joinAsGroup = bot->GetGroup() && bot->GetGroup()->GetLeaderGUID() == bot->GetGUID();
|
||||||
|
|
||||||
@@ -523,23 +523,23 @@ bool BGJoinAction::JoinQueue(uint32 type)
|
|||||||
{
|
{
|
||||||
if (!isRated)
|
if (!isRated)
|
||||||
{
|
{
|
||||||
sRandomPlayerbotMgr->BattlegroundData[queueTypeId][bracketId].skirmishArenaBotCount++;
|
sRandomPlayerbotMgr.BattlegroundData[queueTypeId][bracketId].skirmishArenaBotCount++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (!joinAsGroup)
|
else if (!joinAsGroup)
|
||||||
{
|
{
|
||||||
if (teamId == TEAM_ALLIANCE)
|
if (teamId == TEAM_ALLIANCE)
|
||||||
sRandomPlayerbotMgr->BattlegroundData[queueTypeId][bracketId].bgAllianceBotCount++;
|
sRandomPlayerbotMgr.BattlegroundData[queueTypeId][bracketId].bgAllianceBotCount++;
|
||||||
else
|
else
|
||||||
sRandomPlayerbotMgr->BattlegroundData[queueTypeId][bracketId].bgHordeBotCount++;
|
sRandomPlayerbotMgr.BattlegroundData[queueTypeId][bracketId].bgHordeBotCount++;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (teamId == TEAM_ALLIANCE)
|
if (teamId == TEAM_ALLIANCE)
|
||||||
sRandomPlayerbotMgr->BattlegroundData[queueTypeId][bracketId].bgAllianceBotCount +=
|
sRandomPlayerbotMgr.BattlegroundData[queueTypeId][bracketId].bgAllianceBotCount +=
|
||||||
bot->GetGroup()->GetMembersCount();
|
bot->GetGroup()->GetMembersCount();
|
||||||
else
|
else
|
||||||
sRandomPlayerbotMgr->BattlegroundData[queueTypeId][bracketId].bgHordeBotCount +=
|
sRandomPlayerbotMgr.BattlegroundData[queueTypeId][bracketId].bgHordeBotCount +=
|
||||||
bot->GetGroup()->GetMembersCount();
|
bot->GetGroup()->GetMembersCount();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -588,13 +588,13 @@ bool FreeBGJoinAction::shouldJoinBg(BattlegroundQueueTypeId queueTypeId, Battleg
|
|||||||
TeamSize = (uint32)type;
|
TeamSize = (uint32)type;
|
||||||
|
|
||||||
// Check if bots should join Rated Arena (Only captains can queue)
|
// Check if bots should join Rated Arena (Only captains can queue)
|
||||||
uint32 ratedArenaBotCount = sRandomPlayerbotMgr->BattlegroundData[queueTypeId][bracketId].ratedArenaBotCount;
|
uint32 ratedArenaBotCount = sRandomPlayerbotMgr.BattlegroundData[queueTypeId][bracketId].ratedArenaBotCount;
|
||||||
uint32 ratedArenaPlayerCount =
|
uint32 ratedArenaPlayerCount =
|
||||||
sRandomPlayerbotMgr->BattlegroundData[queueTypeId][bracketId].ratedArenaPlayerCount;
|
sRandomPlayerbotMgr.BattlegroundData[queueTypeId][bracketId].ratedArenaPlayerCount;
|
||||||
uint32 ratedArenaInstanceCount =
|
uint32 ratedArenaInstanceCount =
|
||||||
sRandomPlayerbotMgr->BattlegroundData[queueTypeId][bracketId].ratedArenaInstanceCount;
|
sRandomPlayerbotMgr.BattlegroundData[queueTypeId][bracketId].ratedArenaInstanceCount;
|
||||||
uint32 activeRatedArenaQueue =
|
uint32 activeRatedArenaQueue =
|
||||||
sRandomPlayerbotMgr->BattlegroundData[queueTypeId][bracketId].activeRatedArenaQueue;
|
sRandomPlayerbotMgr.BattlegroundData[queueTypeId][bracketId].activeRatedArenaQueue;
|
||||||
|
|
||||||
bool isRated = (ratedArenaBotCount + ratedArenaPlayerCount) <
|
bool isRated = (ratedArenaBotCount + ratedArenaPlayerCount) <
|
||||||
(BracketSize * (activeRatedArenaQueue + ratedArenaInstanceCount));
|
(BracketSize * (activeRatedArenaQueue + ratedArenaInstanceCount));
|
||||||
@@ -603,7 +603,7 @@ bool FreeBGJoinAction::shouldJoinBg(BattlegroundQueueTypeId queueTypeId, Battleg
|
|||||||
{
|
{
|
||||||
if (sArenaTeamMgr->GetArenaTeamByCaptain(bot->GetGUID(), type))
|
if (sArenaTeamMgr->GetArenaTeamByCaptain(bot->GetGUID(), type))
|
||||||
{
|
{
|
||||||
sRandomPlayerbotMgr->BattlegroundData[queueTypeId][bracketId].ratedArenaBotCount += TeamSize;
|
sRandomPlayerbotMgr.BattlegroundData[queueTypeId][bracketId].ratedArenaBotCount += TeamSize;
|
||||||
ratedList.push_back(queueTypeId);
|
ratedList.push_back(queueTypeId);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -612,13 +612,13 @@ bool FreeBGJoinAction::shouldJoinBg(BattlegroundQueueTypeId queueTypeId, Battleg
|
|||||||
// Check if bots should join Skirmish Arena
|
// Check if bots should join Skirmish Arena
|
||||||
// We have extra bots queue because same faction can vs each other but can't be in the same group.
|
// We have extra bots queue because same faction can vs each other but can't be in the same group.
|
||||||
uint32 skirmishArenaBotCount =
|
uint32 skirmishArenaBotCount =
|
||||||
sRandomPlayerbotMgr->BattlegroundData[queueTypeId][bracketId].skirmishArenaBotCount;
|
sRandomPlayerbotMgr.BattlegroundData[queueTypeId][bracketId].skirmishArenaBotCount;
|
||||||
uint32 skirmishArenaPlayerCount =
|
uint32 skirmishArenaPlayerCount =
|
||||||
sRandomPlayerbotMgr->BattlegroundData[queueTypeId][bracketId].skirmishArenaPlayerCount;
|
sRandomPlayerbotMgr.BattlegroundData[queueTypeId][bracketId].skirmishArenaPlayerCount;
|
||||||
uint32 skirmishArenaInstanceCount =
|
uint32 skirmishArenaInstanceCount =
|
||||||
sRandomPlayerbotMgr->BattlegroundData[queueTypeId][bracketId].skirmishArenaInstanceCount;
|
sRandomPlayerbotMgr.BattlegroundData[queueTypeId][bracketId].skirmishArenaInstanceCount;
|
||||||
uint32 activeSkirmishArenaQueue =
|
uint32 activeSkirmishArenaQueue =
|
||||||
sRandomPlayerbotMgr->BattlegroundData[queueTypeId][bracketId].activeSkirmishArenaQueue;
|
sRandomPlayerbotMgr.BattlegroundData[queueTypeId][bracketId].activeSkirmishArenaQueue;
|
||||||
uint32 maxRequiredSkirmishBots = BracketSize * (activeSkirmishArenaQueue + skirmishArenaInstanceCount);
|
uint32 maxRequiredSkirmishBots = BracketSize * (activeSkirmishArenaQueue + skirmishArenaInstanceCount);
|
||||||
if (maxRequiredSkirmishBots != 0)
|
if (maxRequiredSkirmishBots != 0)
|
||||||
maxRequiredSkirmishBots = maxRequiredSkirmishBots + TeamSize;
|
maxRequiredSkirmishBots = maxRequiredSkirmishBots + TeamSize;
|
||||||
@@ -632,12 +632,12 @@ bool FreeBGJoinAction::shouldJoinBg(BattlegroundQueueTypeId queueTypeId, Battleg
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Check if bots should join Battleground
|
// Check if bots should join Battleground
|
||||||
uint32 bgAllianceBotCount = sRandomPlayerbotMgr->BattlegroundData[queueTypeId][bracketId].bgAllianceBotCount;
|
uint32 bgAllianceBotCount = sRandomPlayerbotMgr.BattlegroundData[queueTypeId][bracketId].bgAllianceBotCount;
|
||||||
uint32 bgAlliancePlayerCount = sRandomPlayerbotMgr->BattlegroundData[queueTypeId][bracketId].bgAlliancePlayerCount;
|
uint32 bgAlliancePlayerCount = sRandomPlayerbotMgr.BattlegroundData[queueTypeId][bracketId].bgAlliancePlayerCount;
|
||||||
uint32 bgHordeBotCount = sRandomPlayerbotMgr->BattlegroundData[queueTypeId][bracketId].bgHordeBotCount;
|
uint32 bgHordeBotCount = sRandomPlayerbotMgr.BattlegroundData[queueTypeId][bracketId].bgHordeBotCount;
|
||||||
uint32 bgHordePlayerCount = sRandomPlayerbotMgr->BattlegroundData[queueTypeId][bracketId].bgHordePlayerCount;
|
uint32 bgHordePlayerCount = sRandomPlayerbotMgr.BattlegroundData[queueTypeId][bracketId].bgHordePlayerCount;
|
||||||
uint32 activeBgQueue = sRandomPlayerbotMgr->BattlegroundData[queueTypeId][bracketId].activeBgQueue;
|
uint32 activeBgQueue = sRandomPlayerbotMgr.BattlegroundData[queueTypeId][bracketId].activeBgQueue;
|
||||||
uint32 bgInstanceCount = sRandomPlayerbotMgr->BattlegroundData[queueTypeId][bracketId].bgInstanceCount;
|
uint32 bgInstanceCount = sRandomPlayerbotMgr.BattlegroundData[queueTypeId][bracketId].bgInstanceCount;
|
||||||
|
|
||||||
if (teamId == TEAM_ALLIANCE)
|
if (teamId == TEAM_ALLIANCE)
|
||||||
{
|
{
|
||||||
@@ -670,7 +670,7 @@ bool BGLeaveAction::Execute(Event event)
|
|||||||
uint16 unk = 0x1F90;
|
uint16 unk = 0x1F90;
|
||||||
uint8 unk2 = 0x0;
|
uint8 unk2 = 0x0;
|
||||||
bool isArena = false;
|
bool isArena = false;
|
||||||
bool IsRandomBot = sRandomPlayerbotMgr->IsRandomBot(bot);
|
bool IsRandomBot = sRandomPlayerbotMgr.IsRandomBot(bot);
|
||||||
|
|
||||||
ArenaType arenaType = ArenaType(BattlegroundMgr::BGArenaType(queueTypeId));
|
ArenaType arenaType = ArenaType(BattlegroundMgr::BGArenaType(queueTypeId));
|
||||||
if (arenaType)
|
if (arenaType)
|
||||||
@@ -709,7 +709,7 @@ bool BGStatusAction::LeaveBG(PlayerbotAI* botAI)
|
|||||||
if (!bg)
|
if (!bg)
|
||||||
return false;
|
return false;
|
||||||
bool isArena = bg->isArena();
|
bool isArena = bg->isArena();
|
||||||
bool isRandomBot = sRandomPlayerbotMgr->IsRandomBot(bot);
|
bool isRandomBot = sRandomPlayerbotMgr.IsRandomBot(bot);
|
||||||
|
|
||||||
if (isRandomBot)
|
if (isRandomBot)
|
||||||
botAI->SetMaster(nullptr);
|
botAI->SetMaster(nullptr);
|
||||||
@@ -805,7 +805,7 @@ bool BGStatusAction::Execute(Event event)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool IsRandomBot = sRandomPlayerbotMgr->IsRandomBot(bot);
|
bool IsRandomBot = sRandomPlayerbotMgr.IsRandomBot(bot);
|
||||||
BattlegroundQueueTypeId queueTypeId = bot->GetBattlegroundQueueTypeId(QueueSlot);
|
BattlegroundQueueTypeId queueTypeId = bot->GetBattlegroundQueueTypeId(QueueSlot);
|
||||||
BattlegroundTypeId _bgTypeId = BattlegroundMgr::BGTemplateId(queueTypeId);
|
BattlegroundTypeId _bgTypeId = BattlegroundMgr::BGTemplateId(queueTypeId);
|
||||||
if (!queueTypeId)
|
if (!queueTypeId)
|
||||||
@@ -958,10 +958,10 @@ bool BGStatusAction::Execute(Event event)
|
|||||||
//TeamId teamId = bot->GetTeamId(); //not used, line marked for removal.
|
//TeamId teamId = bot->GetTeamId(); //not used, line marked for removal.
|
||||||
bool realPlayers = false;
|
bool realPlayers = false;
|
||||||
if (isRated)
|
if (isRated)
|
||||||
realPlayers = sRandomPlayerbotMgr->BattlegroundData[queueTypeId][bracketId].ratedArenaPlayerCount > 0;
|
realPlayers = sRandomPlayerbotMgr.BattlegroundData[queueTypeId][bracketId].ratedArenaPlayerCount > 0;
|
||||||
else
|
else
|
||||||
realPlayers =
|
realPlayers =
|
||||||
sRandomPlayerbotMgr->BattlegroundData[queueTypeId][bracketId].skirmishArenaPlayerCount > 0;
|
sRandomPlayerbotMgr.BattlegroundData[queueTypeId][bracketId].skirmishArenaPlayerCount > 0;
|
||||||
|
|
||||||
if (realPlayers)
|
if (realPlayers)
|
||||||
return false;
|
return false;
|
||||||
@@ -1276,7 +1276,7 @@ static std::pair<uint32, uint32> IC_AttackObjectives[] = {
|
|||||||
// useful commands for fixing BG bugs and checking waypoints/paths
|
// useful commands for fixing BG bugs and checking waypoints/paths
|
||||||
bool BGTactics::HandleConsoleCommand(ChatHandler* handler, char const* args)
|
bool BGTactics::HandleConsoleCommand(ChatHandler* handler, char const* args)
|
||||||
{
|
{
|
||||||
if (!sPlayerbotAIConfig->enabled)
|
if (!sPlayerbotAIConfig.enabled)
|
||||||
{
|
{
|
||||||
handler->PSendSysMessage("|cffff0000Playerbot system is currently disabled!");
|
handler->PSendSysMessage("|cffff0000Playerbot system is currently disabled!");
|
||||||
return true;
|
return true;
|
||||||
@@ -2219,7 +2219,7 @@ bool BGTactics::selectObjective(bool reset)
|
|||||||
if (urand(0, 99) < 20 && teamFC)
|
if (urand(0, 99) < 20 && teamFC)
|
||||||
{
|
{
|
||||||
target.Relocate(teamFC->GetPositionX(), teamFC->GetPositionY(), teamFC->GetPositionZ());
|
target.Relocate(teamFC->GetPositionX(), teamFC->GetPositionY(), teamFC->GetPositionZ());
|
||||||
if (sServerFacade->GetDistance2d(bot, teamFC) < 33.0f)
|
if (ServerFacade::instance().GetDistance2d(bot, teamFC) < 33.0f)
|
||||||
Follow(teamFC);
|
Follow(teamFC);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -2227,8 +2227,8 @@ bool BGTactics::selectObjective(bool reset)
|
|||||||
}
|
}
|
||||||
// Graveyard Camping if in lead
|
// Graveyard Camping if in lead
|
||||||
else if (!hasFlag && role < 8 &&
|
else if (!hasFlag && role < 8 &&
|
||||||
(team == TEAM_ALLIANCE && allianceScore == 2 && hordeScore == 0) ||
|
((team == TEAM_ALLIANCE && allianceScore == 2 && hordeScore == 0) ||
|
||||||
(team == TEAM_HORDE && hordeScore == 2 && allianceScore == 0))
|
(team == TEAM_HORDE && hordeScore == 2 && allianceScore == 0)))
|
||||||
{
|
{
|
||||||
if (team == TEAM_ALLIANCE)
|
if (team == TEAM_ALLIANCE)
|
||||||
SetSafePos(WS_GY_CAMPING_HORDE, 10.0f);
|
SetSafePos(WS_GY_CAMPING_HORDE, 10.0f);
|
||||||
@@ -2263,7 +2263,7 @@ bool BGTactics::selectObjective(bool reset)
|
|||||||
if (urand(0, 99) < 70)
|
if (urand(0, 99) < 70)
|
||||||
{
|
{
|
||||||
target.Relocate(teamFC->GetPositionX(), teamFC->GetPositionY(), teamFC->GetPositionZ());
|
target.Relocate(teamFC->GetPositionX(), teamFC->GetPositionY(), teamFC->GetPositionZ());
|
||||||
if (sServerFacade->GetDistance2d(bot, teamFC) < 33.0f)
|
if (ServerFacade::instance().GetDistance2d(bot, teamFC) < 33.0f)
|
||||||
Follow(teamFC);
|
Follow(teamFC);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2284,7 +2284,7 @@ bool BGTactics::selectObjective(bool reset)
|
|||||||
{
|
{
|
||||||
// Assist own FC if not pursuing enemy FC
|
// Assist own FC if not pursuing enemy FC
|
||||||
target.Relocate(teamFC->GetPositionX(), teamFC->GetPositionY(), teamFC->GetPositionZ());
|
target.Relocate(teamFC->GetPositionX(), teamFC->GetPositionY(), teamFC->GetPositionZ());
|
||||||
if (sServerFacade->GetDistance2d(bot, teamFC) < 33.0f)
|
if (ServerFacade::instance().GetDistance2d(bot, teamFC) < 33.0f)
|
||||||
Follow(teamFC);
|
Follow(teamFC);
|
||||||
}
|
}
|
||||||
else if (urand(0, 99) < 5)
|
else if (urand(0, 99) < 5)
|
||||||
@@ -3197,11 +3197,11 @@ bool BGTactics::moveToObjective(bool ignoreDist)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!ignoreDist && sServerFacade->IsDistanceGreaterThan(sServerFacade->GetDistance2d(bot, pos.x, pos.y), 100.0f))
|
if (!ignoreDist && ServerFacade::instance().IsDistanceGreaterThan(ServerFacade::instance().GetDistance2d(bot, pos.x, pos.y), 100.0f))
|
||||||
{
|
{
|
||||||
// std::ostringstream out;
|
// std::ostringstream out;
|
||||||
// out << "It is too far away! " << pos.x << ", " << pos.y << ", Distance: " <<
|
// out << "It is too far away! " << pos.x << ", " << pos.y << ", Distance: " <<
|
||||||
// sServerFacade->GetDistance2d(bot, pos.x, pos.y); bot->Say(out.str(), LANG_UNIVERSAL);
|
// ServerFacade::instance().GetDistance2d(bot, pos.x, pos.y); bot->Say(out.str(), LANG_UNIVERSAL);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -3213,7 +3213,7 @@ bool BGTactics::moveToObjective(bool ignoreDist)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// std::ostringstream out; out << "Moving to objective " << pos.x << ", " << pos.y << ", Distance: " <<
|
// std::ostringstream out; out << "Moving to objective " << pos.x << ", " << pos.y << ", Distance: " <<
|
||||||
// sServerFacade->GetDistance2d(bot, pos.x, pos.y); bot->Say(out.str(), LANG_UNIVERSAL);
|
// ServerFacade::instance().GetDistance2d(bot, pos.x, pos.y); bot->Say(out.str(), LANG_UNIVERSAL);
|
||||||
|
|
||||||
// dont increase from 1.5 will cause bugs with horde capping AV towers
|
// dont increase from 1.5 will cause bugs with horde capping AV towers
|
||||||
return MoveNear(bot->GetMapId(), pos.x, pos.y, pos.z, 1.5f);
|
return MoveNear(bot->GetMapId(), pos.x, pos.y, pos.z, 1.5f);
|
||||||
@@ -3433,7 +3433,7 @@ bool BGTactics::moveToObjectiveWp(BattleBotPath* const& currentPath, uint32 curr
|
|||||||
// out << "WP: ";
|
// out << "WP: ";
|
||||||
// reverse ? out << currPoint << " <<< -> " << nPoint : out << currPoint << ">>> ->" << nPoint;
|
// reverse ? out << currPoint << " <<< -> " << nPoint : out << currPoint << ">>> ->" << nPoint;
|
||||||
// out << ", " << nextPoint.x << ", " << nextPoint.y << " Path Size: " << currentPath->size() << ", Dist: " <<
|
// out << ", " << nextPoint.x << ", " << nextPoint.y << " Path Size: " << currentPath->size() << ", Dist: " <<
|
||||||
// sServerFacade->GetDistance2d(bot, nextPoint.x, nextPoint.y); bot->Say(out.str(), LANG_UNIVERSAL);
|
// ServerFacade::instance().GetDistance2d(bot, nextPoint.x, nextPoint.y); bot->Say(out.str(), LANG_UNIVERSAL);
|
||||||
|
|
||||||
return MoveTo(bot->GetMapId(), nextPoint.x + frand(-2, 2), nextPoint.y + frand(-2, 2), nextPoint.z);
|
return MoveTo(bot->GetMapId(), nextPoint.x + frand(-2, 2), nextPoint.y + frand(-2, 2), nextPoint.z);
|
||||||
}
|
}
|
||||||
@@ -4039,9 +4039,9 @@ bool BGTactics::useBuff()
|
|||||||
if (closeObjects.empty())
|
if (closeObjects.empty())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
bool needRegen = bot->GetHealthPct() < sPlayerbotAIConfig->mediumHealth ||
|
bool needRegen = bot->GetHealthPct() < sPlayerbotAIConfig.mediumHealth ||
|
||||||
(AI_VALUE2(bool, "has mana", "self target") &&
|
(AI_VALUE2(bool, "has mana", "self target") &&
|
||||||
AI_VALUE2(uint8, "mana", "self target") < sPlayerbotAIConfig->mediumMana);
|
AI_VALUE2(uint8, "mana", "self target") < sPlayerbotAIConfig.mediumMana);
|
||||||
bool needSpeed = (bgType != BATTLEGROUND_WS || bot->HasAura(BG_WS_SPELL_WARSONG_FLAG) ||
|
bool needSpeed = (bgType != BATTLEGROUND_WS || bot->HasAura(BG_WS_SPELL_WARSONG_FLAG) ||
|
||||||
bot->HasAura(BG_WS_SPELL_SILVERWING_FLAG) || bot->HasAura(BG_EY_NETHERSTORM_FLAG_SPELL)) ||
|
bot->HasAura(BG_WS_SPELL_SILVERWING_FLAG) || bot->HasAura(BG_EY_NETHERSTORM_FLAG_SPELL)) ||
|
||||||
!(teamFlagTaken() || flagTaken());
|
!(teamFlagTaken() || flagTaken());
|
||||||
@@ -4057,7 +4057,7 @@ bool BGTactics::useBuff()
|
|||||||
continue;
|
continue;
|
||||||
|
|
||||||
// use speed buff only if close
|
// use speed buff only if close
|
||||||
if (sServerFacade->IsDistanceGreaterThan(sServerFacade->GetDistance2d(bot, go),
|
if (ServerFacade::instance().IsDistanceGreaterThan(ServerFacade::instance().GetDistance2d(bot, go),
|
||||||
go->GetEntry() == Buff_Entries[0] ? 20.0f : 50.0f))
|
go->GetEntry() == Buff_Entries[0] ? 20.0f : 50.0f))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
@@ -4107,7 +4107,7 @@ uint32 BGTactics::getPlayersInArea(TeamId teamId, Position point, float range, b
|
|||||||
if (!combat && player->IsInCombat())
|
if (!combat && player->IsInCombat())
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (sServerFacade->GetDistance2d(player, point.GetPositionX(), point.GetPositionY()) < range)
|
if (ServerFacade::instance().GetDistance2d(player, point.GetPositionX(), point.GetPositionY()) < range)
|
||||||
++defCount;
|
++defCount;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -4191,9 +4191,9 @@ bool BGTactics::IsLockedInsideKeep()
|
|||||||
// get closest portal
|
// get closest portal
|
||||||
if (bot->GetTeamId() == TEAM_ALLIANCE && go->GetEntry() == GO_TELEPORTER_4)
|
if (bot->GetTeamId() == TEAM_ALLIANCE && go->GetEntry() == GO_TELEPORTER_4)
|
||||||
{
|
{
|
||||||
float tempDist = sServerFacade->GetDistance2d(bot, go->GetPositionX(), go->GetPositionY());
|
float tempDist = ServerFacade::instance().GetDistance2d(bot, go->GetPositionX(), go->GetPositionY());
|
||||||
|
|
||||||
if (sServerFacade->IsDistanceLessThan(tempDist, closestDistance))
|
if (ServerFacade::instance().IsDistanceLessThan(tempDist, closestDistance))
|
||||||
{
|
{
|
||||||
closestDistance = tempDist;
|
closestDistance = tempDist;
|
||||||
closestPortal = go;
|
closestPortal = go;
|
||||||
@@ -4204,9 +4204,9 @@ bool BGTactics::IsLockedInsideKeep()
|
|||||||
// get closest portal
|
// get closest portal
|
||||||
if (bot->GetTeamId() == TEAM_HORDE && go->GetEntry() == GO_TELEPORTER_2)
|
if (bot->GetTeamId() == TEAM_HORDE && go->GetEntry() == GO_TELEPORTER_2)
|
||||||
{
|
{
|
||||||
float tempDist = sServerFacade->GetDistance2d(bot, go->GetPositionX(), go->GetPositionY());
|
float tempDist = ServerFacade::instance().GetDistance2d(bot, go->GetPositionX(), go->GetPositionY());
|
||||||
|
|
||||||
if (sServerFacade->IsDistanceLessThan(tempDist, closestDistance))
|
if (ServerFacade::instance().IsDistanceLessThan(tempDist, closestDistance))
|
||||||
{
|
{
|
||||||
closestDistance = tempDist;
|
closestDistance = tempDist;
|
||||||
closestPortal = go;
|
closestPortal = go;
|
||||||
@@ -4253,7 +4253,7 @@ bool ArenaTactics::Execute(Event event)
|
|||||||
{
|
{
|
||||||
if (!bot->InBattleground())
|
if (!bot->InBattleground())
|
||||||
{
|
{
|
||||||
bool IsRandomBot = sRandomPlayerbotMgr->IsRandomBot(bot->GetGUID().GetCounter());
|
bool IsRandomBot = sRandomPlayerbotMgr.IsRandomBot(bot->GetGUID().GetCounter());
|
||||||
botAI->ChangeStrategy("-arena", BOT_STATE_COMBAT);
|
botAI->ChangeStrategy("-arena", BOT_STATE_COMBAT);
|
||||||
botAI->ChangeStrategy("-arena", BOT_STATE_NON_COMBAT);
|
botAI->ChangeStrategy("-arena", BOT_STATE_NON_COMBAT);
|
||||||
botAI->ResetStrategies(!IsRandomBot);
|
botAI->ResetStrategies(!IsRandomBot);
|
||||||
@@ -130,10 +130,10 @@ bool CastCustomSpellAction::Execute(Event event)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (target != bot && !bot->HasInArc(CAST_ANGLE_IN_FRONT, target, sPlayerbotAIConfig->sightDistance))
|
if (target != bot && !bot->HasInArc(CAST_ANGLE_IN_FRONT, target, sPlayerbotAIConfig.sightDistance))
|
||||||
{
|
{
|
||||||
sServerFacade->SetFacingTo(bot, target);
|
ServerFacade::instance().SetFacingTo(bot, target);
|
||||||
botAI->SetNextCheckDelay(sPlayerbotAIConfig->reactDelay);
|
botAI->SetNextCheckDelay(sPlayerbotAIConfig.reactDelay);
|
||||||
|
|
||||||
msg << "cast " << text;
|
msg << "cast " << text;
|
||||||
botAI->HandleCommand(CHAT_MSG_WHISPER, msg.str(), master);
|
botAI->HandleCommand(CHAT_MSG_WHISPER, msg.str(), master);
|
||||||
@@ -286,7 +286,7 @@ bool CastRandomSpellAction::Execute(Event event)
|
|||||||
|
|
||||||
if (isCast)
|
if (isCast)
|
||||||
{
|
{
|
||||||
if (MultiCast && ((wo && bot->HasInArc(CAST_ANGLE_IN_FRONT, wo, sPlayerbotAIConfig->sightDistance))))
|
if (MultiCast && ((wo && bot->HasInArc(CAST_ANGLE_IN_FRONT, wo, sPlayerbotAIConfig.sightDistance))))
|
||||||
{
|
{
|
||||||
std::ostringstream cmd;
|
std::ostringstream cmd;
|
||||||
cmd << "castnc " << chat->FormatWorldobject(wo) + " " << spellId << " " << 19;
|
cmd << "castnc " << chat->FormatWorldobject(wo) + " " << spellId << " " << 19;
|
||||||
@@ -6,7 +6,7 @@
|
|||||||
#include "ChangeStrategyAction.h"
|
#include "ChangeStrategyAction.h"
|
||||||
|
|
||||||
#include "Event.h"
|
#include "Event.h"
|
||||||
#include "PlayerbotDbStore.h"
|
#include "PlayerbotRepository.h"
|
||||||
#include "Playerbots.h"
|
#include "Playerbots.h"
|
||||||
|
|
||||||
bool ChangeCombatStrategyAction::Execute(Event event)
|
bool ChangeCombatStrategyAction::Execute(Event event)
|
||||||
@@ -24,7 +24,7 @@ bool ChangeCombatStrategyAction::Execute(Event event)
|
|||||||
case '+':
|
case '+':
|
||||||
case '-':
|
case '-':
|
||||||
case '~':
|
case '~':
|
||||||
sPlayerbotDbStore->Save(botAI);
|
PlayerbotRepository::instance().Save(botAI);
|
||||||
break;
|
break;
|
||||||
case '?':
|
case '?':
|
||||||
break;
|
break;
|
||||||
@@ -40,7 +40,7 @@ bool ChangeNonCombatStrategyAction::Execute(Event event)
|
|||||||
std::string const text = event.getParam();
|
std::string const text = event.getParam();
|
||||||
|
|
||||||
uint32 account = bot->GetSession()->GetAccountId();
|
uint32 account = bot->GetSession()->GetAccountId();
|
||||||
if (sPlayerbotAIConfig->IsInRandomAccountList(account) && botAI->GetMaster() &&
|
if (sPlayerbotAIConfig.IsInRandomAccountList(account) && botAI->GetMaster() &&
|
||||||
botAI->GetMaster()->GetSession()->GetSecurity() < SEC_GAMEMASTER)
|
botAI->GetMaster()->GetSession()->GetSecurity() < SEC_GAMEMASTER)
|
||||||
{
|
{
|
||||||
if (text.find("loot") != std::string::npos || text.find("gather") != std::string::npos)
|
if (text.find("loot") != std::string::npos || text.find("gather") != std::string::npos)
|
||||||
@@ -62,7 +62,7 @@ bool ChangeNonCombatStrategyAction::Execute(Event event)
|
|||||||
case '+':
|
case '+':
|
||||||
case '-':
|
case '-':
|
||||||
case '~':
|
case '~':
|
||||||
sPlayerbotDbStore->Save(botAI);
|
PlayerbotRepository::instance().Save(botAI);
|
||||||
break;
|
break;
|
||||||
case '?':
|
case '?':
|
||||||
break;
|
break;
|
||||||
@@ -110,20 +110,20 @@ std::string ChangeTalentsAction::SpecList()
|
|||||||
std::ostringstream out;
|
std::ostringstream out;
|
||||||
for (int specNo = 0; specNo < MAX_SPECNO; ++specNo)
|
for (int specNo = 0; specNo < MAX_SPECNO; ++specNo)
|
||||||
{
|
{
|
||||||
if (sPlayerbotAIConfig->premadeSpecName[cls][specNo].size() == 0)
|
if (sPlayerbotAIConfig.premadeSpecName[cls][specNo].size() == 0)
|
||||||
{
|
{
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
specFound++;
|
specFound++;
|
||||||
std::ostringstream out;
|
std::ostringstream out;
|
||||||
std::vector<std::vector<uint32>> parsed = sPlayerbotAIConfig->parsedSpecLinkOrder[cls][specNo][80];
|
std::vector<std::vector<uint32>> parsed = sPlayerbotAIConfig.parsedSpecLinkOrder[cls][specNo][80];
|
||||||
std::unordered_map<int, int> tabCount;
|
std::unordered_map<int, int> tabCount;
|
||||||
tabCount[0] = tabCount[1] = tabCount[2] = 0;
|
tabCount[0] = tabCount[1] = tabCount[2] = 0;
|
||||||
for (auto& item : parsed)
|
for (auto& item : parsed)
|
||||||
{
|
{
|
||||||
tabCount[item[0]] += item[3];
|
tabCount[item[0]] += item[3];
|
||||||
}
|
}
|
||||||
out << specFound << ". " << sPlayerbotAIConfig->premadeSpecName[cls][specNo] << " (";
|
out << specFound << ". " << sPlayerbotAIConfig.premadeSpecName[cls][specNo] << " (";
|
||||||
out << tabCount[0] << "-" << tabCount[1] << "-" << tabCount[2] << ")";
|
out << tabCount[0] << "-" << tabCount[1] << "-" << tabCount[2] << ")";
|
||||||
botAI->TellMasterNoFacing(out.str());
|
botAI->TellMasterNoFacing(out.str());
|
||||||
}
|
}
|
||||||
@@ -137,11 +137,11 @@ std::string ChangeTalentsAction::SpecPick(std::string param)
|
|||||||
// int specFound = 0; //not used, line marked for removal.
|
// int specFound = 0; //not used, line marked for removal.
|
||||||
for (int specNo = 0; specNo < MAX_SPECNO; ++specNo)
|
for (int specNo = 0; specNo < MAX_SPECNO; ++specNo)
|
||||||
{
|
{
|
||||||
if (sPlayerbotAIConfig->premadeSpecName[cls][specNo].size() == 0)
|
if (sPlayerbotAIConfig.premadeSpecName[cls][specNo].size() == 0)
|
||||||
{
|
{
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (sPlayerbotAIConfig->premadeSpecName[cls][specNo] == param)
|
if (sPlayerbotAIConfig.premadeSpecName[cls][specNo] == param)
|
||||||
{
|
{
|
||||||
PlayerbotFactory::InitTalentsBySpecNo(bot, specNo, true);
|
PlayerbotFactory::InitTalentsBySpecNo(bot, specNo, true);
|
||||||
|
|
||||||
@@ -149,7 +149,7 @@ std::string ChangeTalentsAction::SpecPick(std::string param)
|
|||||||
factory.InitGlyphs(false);
|
factory.InitGlyphs(false);
|
||||||
|
|
||||||
std::ostringstream out;
|
std::ostringstream out;
|
||||||
out << "Picking " << sPlayerbotAIConfig->premadeSpecName[cls][specNo];
|
out << "Picking " << sPlayerbotAIConfig.premadeSpecName[cls][specNo];
|
||||||
return out.str();
|
return out.str();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -176,7 +176,7 @@ std::string ChangeTalentsAction::SpecApply(std::string param)
|
|||||||
// std::vector<TalentPath*> ChangeTalentsAction::getPremadePaths(std::string const findName)
|
// std::vector<TalentPath*> ChangeTalentsAction::getPremadePaths(std::string const findName)
|
||||||
// {
|
// {
|
||||||
// std::vector<TalentPath*> ret;
|
// std::vector<TalentPath*> ret;
|
||||||
// // for (auto& path : sPlayerbotAIConfig->classSpecs[bot->getClass()].talentPath)
|
// // for (auto& path : sPlayerbotAIConfig.classSpecs[bot->getClass()].talentPath)
|
||||||
// // {
|
// // {
|
||||||
// // if (findName.empty() || path.name.find(findName) != std::string::npos)
|
// // if (findName.empty() || path.name.find(findName) != std::string::npos)
|
||||||
// // {
|
// // {
|
||||||
@@ -191,7 +191,7 @@ std::string ChangeTalentsAction::SpecApply(std::string param)
|
|||||||
// {
|
// {
|
||||||
// std::vector<TalentPath*> ret;
|
// std::vector<TalentPath*> ret;
|
||||||
|
|
||||||
// // for (auto& path : sPlayerbotAIConfig->classSpecs[bot->getClass()].talentPath)
|
// // for (auto& path : sPlayerbotAIConfig.classSpecs[bot->getClass()].talentPath)
|
||||||
// // {
|
// // {
|
||||||
// // TalentSpec newSpec = *GetBestPremadeSpec(path.id);
|
// // TalentSpec newSpec = *GetBestPremadeSpec(path.id);
|
||||||
// // newSpec.CropTalents(bot->GetLevel());
|
// // newSpec.CropTalents(bot->GetLevel());
|
||||||
@@ -206,7 +206,7 @@ std::string ChangeTalentsAction::SpecApply(std::string param)
|
|||||||
|
|
||||||
// TalentPath* ChangeTalentsAction::getPremadePath(uint32 id)
|
// TalentPath* ChangeTalentsAction::getPremadePath(uint32 id)
|
||||||
// {
|
// {
|
||||||
// // for (auto& path : sPlayerbotAIConfig->classSpecs[bot->getClass()].talentPath)
|
// // for (auto& path : sPlayerbotAIConfig.classSpecs[bot->getClass()].talentPath)
|
||||||
// // {
|
// // {
|
||||||
// // if (id == path.id)
|
// // if (id == path.id)
|
||||||
// // {
|
// // {
|
||||||
@@ -214,7 +214,7 @@ std::string ChangeTalentsAction::SpecApply(std::string param)
|
|||||||
// // }
|
// // }
|
||||||
// // }
|
// // }
|
||||||
|
|
||||||
// // return &sPlayerbotAIConfig->classSpecs[bot->getClass()].talentPath[0];
|
// // return &sPlayerbotAIConfig.classSpecs[bot->getClass()].talentPath[0];
|
||||||
// return nullptr;
|
// return nullptr;
|
||||||
// }
|
// }
|
||||||
|
|
||||||
@@ -270,9 +270,9 @@ std::string ChangeTalentsAction::SpecApply(std::string param)
|
|||||||
// return false;
|
// return false;
|
||||||
// }
|
// }
|
||||||
|
|
||||||
// uint32 specNo = sRandomPlayerbotMgr->GetValue(bot->GetGUID().GetCounter(), "specNo");
|
// uint32 specNo = sRandomPlayerbotMgr.GetValue(bot->GetGUID().GetCounter(), "specNo");
|
||||||
// uint32 specId = specNo - 1;
|
// uint32 specId = specNo - 1;
|
||||||
// std::string specLink = sRandomPlayerbotMgr->GetData(bot->GetGUID().GetCounter(), "specLink");
|
// std::string specLink = sRandomPlayerbotMgr.GetData(bot->GetGUID().GetCounter(), "specLink");
|
||||||
|
|
||||||
// //Continue the current spec
|
// //Continue the current spec
|
||||||
// if (specNo > 0)
|
// if (specNo > 0)
|
||||||
@@ -319,15 +319,15 @@ std::string ChangeTalentsAction::SpecApply(std::string param)
|
|||||||
// specId = -1;
|
// specId = -1;
|
||||||
// // specLink = "";
|
// // specLink = "";
|
||||||
// }
|
// }
|
||||||
// else if (paths.size() > 1 && false/*!sPlayerbotAIConfig->autoPickTalents*/ &&
|
// else if (paths.size() > 1 && false/*!sPlayerbotAIConfig.autoPickTalents*/ &&
|
||||||
// !sRandomPlayerbotMgr->IsRandomBot(bot))
|
// !sRandomPlayerbotMgr.IsRandomBot(bot))
|
||||||
// {
|
// {
|
||||||
// *out << "Found multiple specs: ";
|
// *out << "Found multiple specs: ";
|
||||||
// listPremadePaths(paths, out);
|
// listPremadePaths(paths, out);
|
||||||
// }
|
// }
|
||||||
// else
|
// else
|
||||||
// {
|
// {
|
||||||
// specId = PickPremadePath(paths, sRandomPlayerbotMgr->IsRandomBot(bot))->id;
|
// specId = PickPremadePath(paths, sRandomPlayerbotMgr.IsRandomBot(bot))->id;
|
||||||
// TalentSpec newSpec = *GetBestPremadeSpec(specId);
|
// TalentSpec newSpec = *GetBestPremadeSpec(specId);
|
||||||
// specLink = newSpec.GetTalentLink();
|
// specLink = newSpec.GetTalentLink();
|
||||||
// newSpec.CropTalents(bot->GetLevel());
|
// newSpec.CropTalents(bot->GetLevel());
|
||||||
@@ -341,12 +341,12 @@ std::string ChangeTalentsAction::SpecApply(std::string param)
|
|||||||
// }
|
// }
|
||||||
// }
|
// }
|
||||||
|
|
||||||
// sRandomPlayerbotMgr->SetValue(bot->GetGUID().GetCounter(), "specNo", specId + 1);
|
// sRandomPlayerbotMgr.SetValue(bot->GetGUID().GetCounter(), "specNo", specId + 1);
|
||||||
|
|
||||||
// if (!specLink.empty() && specId == -1)
|
// if (!specLink.empty() && specId == -1)
|
||||||
// sRandomPlayerbotMgr->SetValue(bot->GetGUID().GetCounter(), "specLink", 1, specLink);
|
// sRandomPlayerbotMgr.SetValue(bot->GetGUID().GetCounter(), "specLink", 1, specLink);
|
||||||
// else
|
// else
|
||||||
// sRandomPlayerbotMgr->SetValue(bot->GetGUID().GetCounter(), "specLink", 0);
|
// sRandomPlayerbotMgr.SetValue(bot->GetGUID().GetCounter(), "specLink", 0);
|
||||||
|
|
||||||
// return (specNo == 0) ? false : true;
|
// return (specNo == 0) ? false : true;
|
||||||
// }
|
// }
|
||||||
@@ -364,7 +364,7 @@ std::string ChangeTalentsAction::SpecApply(std::string param)
|
|||||||
// if (path->talentSpec.size())
|
// if (path->talentSpec.size())
|
||||||
// return &path->talentSpec.back();
|
// return &path->talentSpec.back();
|
||||||
|
|
||||||
// // return &sPlayerbotAIConfig->classSpecs[bot->getClassMask()].baseSpec;
|
// // return &sPlayerbotAIConfig.classSpecs[bot->getClassMask()].baseSpec;
|
||||||
// return nullptr;
|
// return nullptr;
|
||||||
// }
|
// }
|
||||||
|
|
||||||
@@ -372,7 +372,7 @@ bool AutoSetTalentsAction::Execute(Event event)
|
|||||||
{
|
{
|
||||||
std::ostringstream out;
|
std::ostringstream out;
|
||||||
|
|
||||||
if (!sPlayerbotAIConfig->autoPickTalents || !sRandomPlayerbotMgr->IsRandomBot(bot))
|
if (!sPlayerbotAIConfig.autoPickTalents || !sRandomPlayerbotMgr.IsRandomBot(bot))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (bot->GetFreeTalentPoints() <= 0)
|
if (bot->GetFreeTalentPoints() <= 0)
|
||||||
@@ -96,7 +96,7 @@ bool FollowChatShortcutAction::Execute(Event event)
|
|||||||
|
|
||||||
/* Default mechanics takes care of this now.
|
/* Default mechanics takes care of this now.
|
||||||
if (bot->GetMapId() != master->GetMapId() || (master && bot->GetDistance(master) >
|
if (bot->GetMapId() != master->GetMapId() || (master && bot->GetDistance(master) >
|
||||||
sPlayerbotAIConfig->sightDistance))
|
sPlayerbotAIConfig.sightDistance))
|
||||||
{
|
{
|
||||||
if (bot->isDead())
|
if (bot->isDead())
|
||||||
{
|
{
|
||||||
@@ -161,7 +161,7 @@ bool FleeChatShortcutAction::Execute(Event event)
|
|||||||
ResetReturnPosition();
|
ResetReturnPosition();
|
||||||
ResetStayPosition();
|
ResetStayPosition();
|
||||||
|
|
||||||
if (bot->GetMapId() != master->GetMapId() || bot->GetDistance(master) > sPlayerbotAIConfig->sightDistance)
|
if (bot->GetMapId() != master->GetMapId() || bot->GetDistance(master) > sPlayerbotAIConfig.sightDistance)
|
||||||
{
|
{
|
||||||
botAI->TellError("I will not flee with you - too far away");
|
botAI->TellError("I will not flee with you - too far away");
|
||||||
return true;
|
return true;
|
||||||
@@ -86,7 +86,7 @@ void CheatAction::ListCheats()
|
|||||||
for (int i = 0; i < log2((uint32)BotCheatMask::maxMask); i++)
|
for (int i = 0; i < log2((uint32)BotCheatMask::maxMask); i++)
|
||||||
{
|
{
|
||||||
BotCheatMask cheatMask = BotCheatMask(1 << i);
|
BotCheatMask cheatMask = BotCheatMask(1 << i);
|
||||||
if ((uint32)cheatMask & (uint32)sPlayerbotAIConfig->botCheatMask)
|
if ((uint32)cheatMask & (uint32)sPlayerbotAIConfig.botCheatMask)
|
||||||
out << "[conf:" << GetCheatName(BotCheatMask(cheatMask)) << "]";
|
out << "[conf:" << GetCheatName(BotCheatMask(cheatMask)) << "]";
|
||||||
else if (botAI->HasCheat(cheatMask))
|
else if (botAI->HasCheat(cheatMask))
|
||||||
out << "[" << GetCheatName(BotCheatMask(cheatMask)) << "]";
|
out << "[" << GetCheatName(BotCheatMask(cheatMask)) << "]";
|
||||||
@@ -28,7 +28,7 @@ bool CheckMailAction::Execute(Event event)
|
|||||||
continue;
|
continue;
|
||||||
|
|
||||||
uint32 account = owner->GetSession()->GetAccountId();
|
uint32 account = owner->GetSession()->GetAccountId();
|
||||||
if (sPlayerbotAIConfig->IsInRandomAccountList(account))
|
if (sPlayerbotAIConfig.IsInRandomAccountList(account))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
ProcessMail(mail, owner, trans);
|
ProcessMail(mail, owner, trans);
|
||||||
@@ -80,7 +80,7 @@ void CheckMailAction::ProcessMail(Mail* mail, Player* owner, CharacterDatabaseTr
|
|||||||
if (!item)
|
if (!item)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (!sGuildTaskMgr->CheckItemTask(i->item_template, item->GetCount(), owner, bot, true))
|
if (!GuildTaskMgr::instance().CheckItemTask(i->item_template, item->GetCount(), owner, bot, true))
|
||||||
{
|
{
|
||||||
std::ostringstream body;
|
std::ostringstream body;
|
||||||
body << "Hello, " << owner->GetName() << ",\n";
|
body << "Hello, " << owner->GetName() << ",\n";
|
||||||
@@ -89,7 +89,7 @@ bool CheckMountStateAction::isUseful()
|
|||||||
return false;
|
return false;
|
||||||
|
|
||||||
// Not useful when level lower than minimum required
|
// Not useful when level lower than minimum required
|
||||||
if (bot->GetLevel() < sPlayerbotAIConfig->useGroundMountAtMinLevel)
|
if (bot->GetLevel() < sPlayerbotAIConfig.useGroundMountAtMinLevel)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// Allow mounting while transformed only if the form allows it
|
// Allow mounting while transformed only if the form allows it
|
||||||
@@ -402,7 +402,7 @@ float CheckMountStateAction::CalculateDismountDistance() const
|
|||||||
// Warrior bots should dismount far enough to charge (because it's important for generating some initial rage),
|
// Warrior bots should dismount far enough to charge (because it's important for generating some initial rage),
|
||||||
// a real player would be riding toward enemy mashing the charge key but the bots won't cast charge while mounted.
|
// a real player would be riding toward enemy mashing the charge key but the bots won't cast charge while mounted.
|
||||||
bool isMelee = PlayerbotAI::IsMelee(bot);
|
bool isMelee = PlayerbotAI::IsMelee(bot);
|
||||||
float dismountDistance = isMelee ? sPlayerbotAIConfig->meleeDistance + 2.0f : sPlayerbotAIConfig->spellDistance + 2.0f;
|
float dismountDistance = isMelee ? sPlayerbotAIConfig.meleeDistance + 2.0f : sPlayerbotAIConfig.spellDistance + 2.0f;
|
||||||
return bot->getClass() == CLASS_WARRIOR ? std::max(18.0f, dismountDistance) : dismountDistance;
|
return bot->getClass() == CLASS_WARRIOR ? std::max(18.0f, dismountDistance) : dismountDistance;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -413,7 +413,7 @@ float CheckMountStateAction::CalculateMountDistance() const
|
|||||||
// seconds:
|
// seconds:
|
||||||
// 21 / 7 = 21 / 14 + 1.5 = 3 (7 = dismounted speed 14 = epic-mount speed 1.5 = mount-spell cast time)
|
// 21 / 7 = 21 / 14 + 1.5 = 3 (7 = dismounted speed 14 = epic-mount speed 1.5 = mount-spell cast time)
|
||||||
bool isMelee = PlayerbotAI::IsMelee(bot);
|
bool isMelee = PlayerbotAI::IsMelee(bot);
|
||||||
float baseDistance = isMelee ? sPlayerbotAIConfig->meleeDistance + 10.0f : sPlayerbotAIConfig->spellDistance + 10.0f;
|
float baseDistance = isMelee ? sPlayerbotAIConfig.meleeDistance + 10.0f : sPlayerbotAIConfig.spellDistance + 10.0f;
|
||||||
return std::max(21.0f, baseDistance);
|
return std::max(21.0f, baseDistance);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -440,7 +440,7 @@ int32 CheckMountStateAction::CalculateMasterMountSpeed(Player* master, const Mou
|
|||||||
int32 ridingSkill = bot->GetPureSkillValue(SKILL_RIDING);
|
int32 ridingSkill = bot->GetPureSkillValue(SKILL_RIDING);
|
||||||
int32 botLevel = bot->GetLevel();
|
int32 botLevel = bot->GetLevel();
|
||||||
|
|
||||||
if (ridingSkill <= 75 && botLevel < static_cast<int32>(sPlayerbotAIConfig->useFastGroundMountAtMinLevel))
|
if (ridingSkill <= 75 && botLevel < static_cast<int32>(sPlayerbotAIConfig.useFastGroundMountAtMinLevel))
|
||||||
return 59;
|
return 59;
|
||||||
|
|
||||||
// If there is a master and bot not in BG, use master's aura effects.
|
// If there is a master and bot not in BG, use master's aura effects.
|
||||||
@@ -20,7 +20,7 @@ bool CheckValuesAction::Execute(Event event)
|
|||||||
|
|
||||||
if (botAI->HasStrategy("map", BOT_STATE_NON_COMBAT) || botAI->HasStrategy("map full", BOT_STATE_NON_COMBAT))
|
if (botAI->HasStrategy("map", BOT_STATE_NON_COMBAT) || botAI->HasStrategy("map full", BOT_STATE_NON_COMBAT))
|
||||||
{
|
{
|
||||||
sTravelNodeMap->manageNodes(bot, botAI->HasStrategy("map full", BOT_STATE_NON_COMBAT));
|
TravelNodeMap::instance().manageNodes(bot, botAI->HasStrategy("map full", BOT_STATE_NON_COMBAT));
|
||||||
}
|
}
|
||||||
|
|
||||||
GuidVector possible_targets = *context->GetValue<GuidVector>("possible targets");
|
GuidVector possible_targets = *context->GetValue<GuidVector>("possible targets");
|
||||||
@@ -248,7 +248,7 @@ bool ChooseRpgTargetAction::Execute(Event event)
|
|||||||
}
|
}
|
||||||
|
|
||||||
std::mt19937 gen(time(0));
|
std::mt19937 gen(time(0));
|
||||||
sTravelMgr->weighted_shuffle(guidps.begin(), guidps.end(), relevances.begin(), relevances.end(), gen);
|
TravelMgr::instance().weighted_shuffle(guidps.begin(), guidps.end(), relevances.begin(), relevances.end(), gen);
|
||||||
|
|
||||||
GuidPosition guidP(guidps.front());
|
GuidPosition guidP(guidps.front());
|
||||||
if (!guidP)
|
if (!guidP)
|
||||||
@@ -279,7 +279,7 @@ bool ChooseRpgTargetAction::isUseful()
|
|||||||
|
|
||||||
GuidPosition guidP = AI_VALUE(GuidPosition, "rpg target");
|
GuidPosition guidP = AI_VALUE(GuidPosition, "rpg target");
|
||||||
|
|
||||||
if (guidP && guidP.distance(bot) < sPlayerbotAIConfig->reactDistance * 2)
|
if (guidP && guidP.distance(bot) < sPlayerbotAIConfig.reactDistance * 2)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// TravelTarget* travelTarget = AI_VALUE(TravelTarget*, "travel target"); //not used, line marked for removal.
|
// TravelTarget* travelTarget = AI_VALUE(TravelTarget*, "travel target"); //not used, line marked for removal.
|
||||||
@@ -330,7 +330,7 @@ bool ChooseRpgTargetAction::isFollowValid(Player* bot, WorldPosition pos)
|
|||||||
if (!botAI->HasStrategy("follow", BOT_STATE_NON_COMBAT))
|
if (!botAI->HasStrategy("follow", BOT_STATE_NON_COMBAT))
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
if (bot->GetDistance(groupLeader) > sPlayerbotAIConfig->rpgDistance * 2)
|
if (bot->GetDistance(groupLeader) > sPlayerbotAIConfig.rpgDistance * 2)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
Formation* formation = AI_VALUE(Formation*, "formation");
|
Formation* formation = AI_VALUE(Formation*, "formation");
|
||||||
@@ -340,7 +340,7 @@ bool ChooseRpgTargetAction::isFollowValid(Player* bot, WorldPosition pos)
|
|||||||
{
|
{
|
||||||
Player* player = groupLeader;
|
Player* player = groupLeader;
|
||||||
if (groupLeader && !groupLeader->isMoving() ||
|
if (groupLeader && !groupLeader->isMoving() ||
|
||||||
PAI_VALUE(WorldPosition, "last long move").distance(pos) < sPlayerbotAIConfig->reactDistance)
|
PAI_VALUE(WorldPosition, "last long move").distance(pos) < sPlayerbotAIConfig.reactDistance)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -20,13 +20,13 @@ bool AttackEnemyPlayerAction::isUseful()
|
|||||||
if (PlayerHasFlag::IsCapturingFlag(bot))
|
if (PlayerHasFlag::IsCapturingFlag(bot))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
return !sPlayerbotAIConfig->IsPvpProhibited(bot->GetZoneId(), bot->GetAreaId());
|
return !sPlayerbotAIConfig.IsPvpProhibited(bot->GetZoneId(), bot->GetAreaId());
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AttackEnemyFlagCarrierAction::isUseful()
|
bool AttackEnemyFlagCarrierAction::isUseful()
|
||||||
{
|
{
|
||||||
Unit* target = context->GetValue<Unit*>("enemy flag carrier")->Get();
|
Unit* target = context->GetValue<Unit*>("enemy flag carrier")->Get();
|
||||||
return target && sServerFacade->IsDistanceLessOrEqualThan(sServerFacade->GetDistance2d(bot, target), 100.0f) &&
|
return target && ServerFacade::instance().IsDistanceLessOrEqualThan(ServerFacade::instance().GetDistance2d(bot, target), 100.0f) &&
|
||||||
PlayerHasFlag::IsCapturingFlag(bot);
|
PlayerHasFlag::IsCapturingFlag(bot);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -366,7 +366,7 @@ bool ChooseTravelTargetAction::getBestDestination(std::vector<TravelDestination*
|
|||||||
|
|
||||||
WorldPosition botLocation(bot);
|
WorldPosition botLocation(bot);
|
||||||
std::vector<WorldPosition*> availablePoints =
|
std::vector<WorldPosition*> availablePoints =
|
||||||
sTravelMgr->getNextPoint(&botLocation, *activePoints); // Pick a good point.
|
TravelMgr::instance().getNextPoint(&botLocation, *activePoints); // Pick a good point.
|
||||||
|
|
||||||
if (availablePoints.empty()) // No points available.
|
if (availablePoints.empty()) // No points available.
|
||||||
return false;
|
return false;
|
||||||
@@ -488,7 +488,7 @@ bool ChooseTravelTargetAction::SetQuestTarget(TravelTarget* target, bool onlyCom
|
|||||||
if (newQuests)
|
if (newQuests)
|
||||||
{
|
{
|
||||||
// Prefer new quests near the player at lower levels.
|
// Prefer new quests near the player at lower levels.
|
||||||
activeDestinations = sTravelMgr->getQuestTravelDestinations(bot, -1, true, false, 400 + bot->GetLevel() * 10);
|
activeDestinations = TravelMgr::instance().getQuestTravelDestinations(bot, -1, true, false, 400 + bot->GetLevel() * 10);
|
||||||
}
|
}
|
||||||
if (activeQuests || completedQuests)
|
if (activeQuests || completedQuests)
|
||||||
{
|
{
|
||||||
@@ -510,7 +510,7 @@ bool ChooseTravelTargetAction::SetQuestTarget(TravelTarget* target, bool onlyCom
|
|||||||
continue;
|
continue;
|
||||||
|
|
||||||
//Find quest takers or objectives
|
//Find quest takers or objectives
|
||||||
std::vector<TravelDestination*> questDestinations = sTravelMgr->getQuestTravelDestinations(bot, questId, true, false, 0);
|
std::vector<TravelDestination*> questDestinations = TravelMgr::instance().getQuestTravelDestinations(bot, questId, true, false, 0);
|
||||||
|
|
||||||
if (onlyClassQuest && activeDestinations.size() && questDestinations.size()) //Only do class quests if we have any.
|
if (onlyClassQuest && activeDestinations.size() && questDestinations.size()) //Only do class quests if we have any.
|
||||||
{
|
{
|
||||||
@@ -525,7 +525,7 @@ bool ChooseTravelTargetAction::SetQuestTarget(TravelTarget* target, bool onlyCom
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (newQuests && activeDestinations.empty())
|
if (newQuests && activeDestinations.empty())
|
||||||
activeDestinations = sTravelMgr->getQuestTravelDestinations(bot, -1, true, false); //If we really don't find any new quests look futher away.
|
activeDestinations = TravelMgr::instance().getQuestTravelDestinations(bot, -1, true, false); //If we really don't find any new quests look futher away.
|
||||||
|
|
||||||
if (botAI->HasStrategy("debug travel", BotState::BOT_STATE_NON_COMBAT))
|
if (botAI->HasStrategy("debug travel", BotState::BOT_STATE_NON_COMBAT))
|
||||||
botAI->TellMasterNoFacing(std::to_string(activeDestinations.size()) + " quest destinations found.");
|
botAI->TellMasterNoFacing(std::to_string(activeDestinations.size()) + " quest destinations found.");
|
||||||
@@ -547,7 +547,7 @@ bool ChooseTravelTargetAction::SetNewQuestTarget(TravelTarget* target)
|
|||||||
|
|
||||||
// Find quest givers.
|
// Find quest givers.
|
||||||
std::vector<TravelDestination*> TravelDestinations =
|
std::vector<TravelDestination*> TravelDestinations =
|
||||||
sTravelMgr->getQuestTravelDestinations(bot, -1, botAI->HasRealPlayerMaster());
|
TravelMgr::instance().getQuestTravelDestinations(bot, -1, botAI->HasRealPlayerMaster());
|
||||||
|
|
||||||
activeDestinations.insert(activeDestinations.end(), TravelDestinations.begin(), TravelDestinations.end());
|
activeDestinations.insert(activeDestinations.end(), TravelDestinations.begin(), TravelDestinations.end());
|
||||||
|
|
||||||
@@ -576,7 +576,7 @@ bool ChooseTravelTargetAction::SetRpgTarget(TravelTarget* target)
|
|||||||
|
|
||||||
// Find rpg npcs
|
// Find rpg npcs
|
||||||
std::vector<TravelDestination*> TravelDestinations =
|
std::vector<TravelDestination*> TravelDestinations =
|
||||||
sTravelMgr->getRpgTravelDestinations(bot, botAI->HasRealPlayerMaster());
|
TravelMgr::instance().getRpgTravelDestinations(bot, botAI->HasRealPlayerMaster());
|
||||||
|
|
||||||
activeDestinations.insert(activeDestinations.end(), TravelDestinations.begin(), TravelDestinations.end());
|
activeDestinations.insert(activeDestinations.end(), TravelDestinations.begin(), TravelDestinations.end());
|
||||||
|
|
||||||
@@ -605,7 +605,7 @@ bool ChooseTravelTargetAction::SetGrindTarget(TravelTarget* target)
|
|||||||
|
|
||||||
// Find grind mobs.
|
// Find grind mobs.
|
||||||
std::vector<TravelDestination*> TravelDestinations =
|
std::vector<TravelDestination*> TravelDestinations =
|
||||||
sTravelMgr->getGrindTravelDestinations(bot, botAI->HasRealPlayerMaster());
|
TravelMgr::instance().getGrindTravelDestinations(bot, botAI->HasRealPlayerMaster());
|
||||||
|
|
||||||
activeDestinations.insert(activeDestinations.end(), TravelDestinations.begin(), TravelDestinations.end());
|
activeDestinations.insert(activeDestinations.end(), TravelDestinations.begin(), TravelDestinations.end());
|
||||||
|
|
||||||
@@ -634,7 +634,7 @@ bool ChooseTravelTargetAction::SetBossTarget(TravelTarget* target)
|
|||||||
|
|
||||||
// Find boss mobs.
|
// Find boss mobs.
|
||||||
std::vector<TravelDestination*> TravelDestinations =
|
std::vector<TravelDestination*> TravelDestinations =
|
||||||
sTravelMgr->getBossTravelDestinations(bot, botAI->HasRealPlayerMaster());
|
TravelMgr::instance().getBossTravelDestinations(bot, botAI->HasRealPlayerMaster());
|
||||||
|
|
||||||
activeDestinations.insert(activeDestinations.end(), TravelDestinations.begin(), TravelDestinations.end());
|
activeDestinations.insert(activeDestinations.end(), TravelDestinations.begin(), TravelDestinations.end());
|
||||||
|
|
||||||
@@ -662,7 +662,7 @@ bool ChooseTravelTargetAction::SetExploreTarget(TravelTarget* target)
|
|||||||
WorldPosition botLocation(bot);
|
WorldPosition botLocation(bot);
|
||||||
|
|
||||||
// Find quest givers.
|
// Find quest givers.
|
||||||
std::vector<TravelDestination*> TravelDestinations = sTravelMgr->getExploreTravelDestinations(bot, true, true);
|
std::vector<TravelDestination*> TravelDestinations = TravelMgr::instance().getExploreTravelDestinations(bot, true, true);
|
||||||
|
|
||||||
activeDestinations.insert(activeDestinations.end(), TravelDestinations.begin(), TravelDestinations.end());
|
activeDestinations.insert(activeDestinations.end(), TravelDestinations.begin(), TravelDestinations.end());
|
||||||
/*
|
/*
|
||||||
@@ -681,7 +681,7 @@ bool ChooseTravelTargetAction::SetExploreTarget(TravelTarget* target)
|
|||||||
|
|
||||||
if (activePoints.empty())
|
if (activePoints.empty())
|
||||||
{
|
{
|
||||||
TravelDestinations = sTravelMgr->getExploreTravelDestinations(bot, botAI->HasRealPlayerMaster());
|
TravelDestinations = TravelMgr::instance().getExploreTravelDestinations(bot, botAI->HasRealPlayerMaster());
|
||||||
|
|
||||||
for (auto& activeTarget : activeDestinations)
|
for (auto& activeTarget : activeDestinations)
|
||||||
{
|
{
|
||||||
@@ -710,7 +710,7 @@ bool ChooseTravelTargetAction::SetNpcFlagTarget(TravelTarget* target, std::vecto
|
|||||||
|
|
||||||
std::vector<TravelDestination*> dests;
|
std::vector<TravelDestination*> dests;
|
||||||
|
|
||||||
for (auto& d : sTravelMgr->getRpgTravelDestinations(bot, true, true))
|
for (auto& d : TravelMgr::instance().getRpgTravelDestinations(bot, true, true))
|
||||||
{
|
{
|
||||||
if (!d->getEntry())
|
if (!d->getEntry())
|
||||||
continue;
|
continue;
|
||||||
@@ -813,7 +813,7 @@ std::vector<TravelDestination*> TravelMgr::getBossTravelDestinations(Player* bot
|
|||||||
|
|
||||||
bool ChooseTravelTargetAction::SetNullTarget(TravelTarget* target)
|
bool ChooseTravelTargetAction::SetNullTarget(TravelTarget* target)
|
||||||
{
|
{
|
||||||
target->setTarget(sTravelMgr->nullTravelDestination, sTravelMgr->nullWorldPosition, true);
|
target->setTarget(TravelMgr::instance().nullTravelDestination, TravelMgr::instance().nullWorldPosition, true);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -832,7 +832,7 @@ TravelDestination* ChooseTravelTargetAction::FindDestination(Player* bot, std::s
|
|||||||
//Quests
|
//Quests
|
||||||
if (quests)
|
if (quests)
|
||||||
{
|
{
|
||||||
for (auto& d : sTravelMgr->getQuestTravelDestinations(bot, 0, true, true))
|
for (auto& d : TravelMgr::instance().getQuestTravelDestinations(bot, 0, true, true))
|
||||||
{
|
{
|
||||||
if (strstri(d->getTitle().c_str(), name.c_str()))
|
if (strstri(d->getTitle().c_str(), name.c_str()))
|
||||||
dests.push_back(d);
|
dests.push_back(d);
|
||||||
@@ -842,7 +842,7 @@ TravelDestination* ChooseTravelTargetAction::FindDestination(Player* bot, std::s
|
|||||||
//Zones
|
//Zones
|
||||||
if (zones)
|
if (zones)
|
||||||
{
|
{
|
||||||
for (auto& d : sTravelMgr->getExploreTravelDestinations(bot, true, true))
|
for (auto& d : TravelMgr::instance().getExploreTravelDestinations(bot, true, true))
|
||||||
{
|
{
|
||||||
if (strstri(d->getTitle().c_str(), name.c_str()))
|
if (strstri(d->getTitle().c_str(), name.c_str()))
|
||||||
dests.push_back(d);
|
dests.push_back(d);
|
||||||
@@ -852,7 +852,7 @@ TravelDestination* ChooseTravelTargetAction::FindDestination(Player* bot, std::s
|
|||||||
//Npcs
|
//Npcs
|
||||||
if (npcs)
|
if (npcs)
|
||||||
{
|
{
|
||||||
for (auto& d : sTravelMgr->getRpgTravelDestinations(bot, true, true))
|
for (auto& d : TravelMgr::instance().getRpgTravelDestinations(bot, true, true))
|
||||||
{
|
{
|
||||||
if (strstri(d->getTitle().c_str(), name.c_str()))
|
if (strstri(d->getTitle().c_str(), name.c_str()))
|
||||||
dests.push_back(d);
|
dests.push_back(d);
|
||||||
@@ -862,7 +862,7 @@ TravelDestination* ChooseTravelTargetAction::FindDestination(Player* bot, std::s
|
|||||||
//Mobs
|
//Mobs
|
||||||
if (mobs)
|
if (mobs)
|
||||||
{
|
{
|
||||||
for (auto& d : sTravelMgr->getGrindTravelDestinations(bot, true, true, 5000.0f))
|
for (auto& d : TravelMgr::instance().getGrindTravelDestinations(bot, true, true, 5000.0f))
|
||||||
{
|
{
|
||||||
if (strstri(d->getTitle().c_str(), name.c_str()))
|
if (strstri(d->getTitle().c_str(), name.c_str()))
|
||||||
dests.push_back(d);
|
dests.push_back(d);
|
||||||
@@ -872,7 +872,7 @@ TravelDestination* ChooseTravelTargetAction::FindDestination(Player* bot, std::s
|
|||||||
//Bosses
|
//Bosses
|
||||||
if (bosses)
|
if (bosses)
|
||||||
{
|
{
|
||||||
for (auto& d : sTravelMgr->getBossTravelDestinations(bot, true, true))
|
for (auto& d : TravelMgr::instance().getBossTravelDestinations(bot, true, true))
|
||||||
{
|
{
|
||||||
if (strstri(d->getTitle().c_str(), name.c_str()))
|
if (strstri(d->getTitle().c_str(), name.c_str()))
|
||||||
dests.push_back(d);
|
dests.push_back(d);
|
||||||
@@ -25,7 +25,7 @@ bool SwitchToMeleeAction::isUseful()
|
|||||||
return botAI->HasStrategy("ranged", BOT_STATE_COMBAT) &&
|
return botAI->HasStrategy("ranged", BOT_STATE_COMBAT) &&
|
||||||
((bot->IsInCombat() && target &&
|
((bot->IsInCombat() && target &&
|
||||||
(target->GetVictim() == bot && (!bot->GetGroup() || lastFlee) &&
|
(target->GetVictim() == bot && (!bot->GetGroup() || lastFlee) &&
|
||||||
sServerFacade->IsDistanceLessOrEqualThan(AI_VALUE2(float, "distance", "current target"), 8.0f))) ||
|
ServerFacade::instance().IsDistanceLessOrEqualThan(AI_VALUE2(float, "distance", "current target"), 8.0f))) ||
|
||||||
(!bot->IsInCombat()));
|
(!bot->IsInCombat()));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -47,7 +47,7 @@ bool SwitchToRangedAction::isUseful()
|
|||||||
return botAI->HasStrategy("close", BOT_STATE_COMBAT) && hasAmmo &&
|
return botAI->HasStrategy("close", BOT_STATE_COMBAT) && hasAmmo &&
|
||||||
((bot->IsInCombat() && target &&
|
((bot->IsInCombat() && target &&
|
||||||
((target->GetVictim() != bot || target->GetTarget() != bot->GetGUID()) ||
|
((target->GetVictim() != bot || target->GetTarget() != bot->GetGUID()) ||
|
||||||
sServerFacade->IsDistanceGreaterThan(AI_VALUE2(float, "distance", "current target"), 8.0f))) ||
|
ServerFacade::instance().IsDistanceGreaterThan(AI_VALUE2(float, "distance", "current target"), 8.0f))) ||
|
||||||
(!bot->IsInCombat()));
|
(!bot->IsInCombat()));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -19,7 +19,7 @@ bool DebugAction::Execute(Event event)
|
|||||||
|
|
||||||
if (text == "scan")
|
if (text == "scan")
|
||||||
{
|
{
|
||||||
sPlayerbotAIConfig->openLog("scan.csv", "w");
|
sPlayerbotAIConfig.openLog("scan.csv", "w");
|
||||||
|
|
||||||
uint32 i = 0;
|
uint32 i = 0;
|
||||||
for (auto p : WorldPosition().getCreaturesNear())
|
for (auto p : WorldPosition().getCreaturesNear())
|
||||||
@@ -36,15 +36,15 @@ bool DebugAction::Execute(Event event)
|
|||||||
|
|
||||||
pos.printWKT(out);
|
pos.printWKT(out);
|
||||||
|
|
||||||
sPlayerbotAIConfig->log("scan.csv", out.str().c_str());
|
sPlayerbotAIConfig.log("scan.csv", out.str().c_str());
|
||||||
|
|
||||||
if (zoneId == 0 && areaId == 0)
|
if (zoneId == 0 && areaId == 0)
|
||||||
{
|
{
|
||||||
sPlayerbotAIConfig->log("x", out.str().c_str());
|
sPlayerbotAIConfig.log("x", out.str().c_str());
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
sPlayerbotAIConfig->log("y", out.str().c_str());
|
sPlayerbotAIConfig.log("y", out.str().c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
i = zoneId;
|
i = zoneId;
|
||||||
@@ -53,8 +53,8 @@ bool DebugAction::Execute(Event event)
|
|||||||
}
|
}
|
||||||
else if (text.find("printmap") != std::string::npos)
|
else if (text.find("printmap") != std::string::npos)
|
||||||
{
|
{
|
||||||
sTravelNodeMap->printMap();
|
TravelNodeMap::instance().printMap();
|
||||||
sTravelNodeMap->printNodeStore();
|
TravelNodeMap::instance().printNodeStore();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
else if (text.find("travel ") != std::string::npos)
|
else if (text.find("travel ") != std::string::npos)
|
||||||
@@ -72,7 +72,7 @@ bool DebugAction::Execute(Event event)
|
|||||||
return false;
|
return false;
|
||||||
|
|
||||||
std::vector<WorldPosition> beginPath, endPath;
|
std::vector<WorldPosition> beginPath, endPath;
|
||||||
TravelNodeRoute route = sTravelNodeMap->getRoute(botPos, *points.front(), beginPath, bot);
|
TravelNodeRoute route = TravelNodeMap::instance().getRoute(botPos, *points.front(), beginPath, bot);
|
||||||
|
|
||||||
std::ostringstream out;
|
std::ostringstream out;
|
||||||
out << "Traveling to " << dest->getTitle() << ": ";
|
out << "Traveling to " << dest->getTitle() << ": ";
|
||||||
@@ -108,7 +108,7 @@ bool DebugAction::Execute(Event event)
|
|||||||
|
|
||||||
out << quest->GetTitle() << ": ";
|
out << quest->GetTitle() << ": ";
|
||||||
|
|
||||||
QuestContainer* cont = sTravelMgr->quests[questId];
|
QuestContainer* cont = TravelMgr::instance().quests[questId];
|
||||||
|
|
||||||
for (auto g : cont->questGivers)
|
for (auto g : cont->questGivers)
|
||||||
{
|
{
|
||||||
@@ -135,11 +135,11 @@ bool DebugAction::Execute(Event event)
|
|||||||
else if (text.find("quest") != std::string::npos)
|
else if (text.find("quest") != std::string::npos)
|
||||||
{
|
{
|
||||||
std::ostringstream out;
|
std::ostringstream out;
|
||||||
out << sTravelMgr->quests.size() << " quests ";
|
out << TravelMgr::instance().quests.size() << " quests ";
|
||||||
|
|
||||||
uint32 noT = 0, noG = 0, noO = 0;
|
uint32 noT = 0, noG = 0, noO = 0;
|
||||||
|
|
||||||
for (auto q : sTravelMgr->quests)
|
for (auto q : TravelMgr::instance().quests)
|
||||||
{
|
{
|
||||||
if (q.second->questGivers.empty())
|
if (q.second->questGivers.empty())
|
||||||
noG++;
|
noG++;
|
||||||
@@ -164,7 +164,7 @@ bool DebugAction::Execute(Event event)
|
|||||||
|
|
||||||
// uint32 noT = 0, noG = 0, noO = 0; //not used, line marked for removal.
|
// uint32 noT = 0, noG = 0, noO = 0; //not used, line marked for removal.
|
||||||
|
|
||||||
for (auto q : sTravelMgr->quests)
|
for (auto q : TravelMgr::instance().quests)
|
||||||
{
|
{
|
||||||
Quest const* quest = sObjectMgr->GetQuestTemplate(q.first);
|
Quest const* quest = sObjectMgr->GetQuestTemplate(q.first);
|
||||||
|
|
||||||
@@ -194,16 +194,16 @@ bool DebugAction::Execute(Event event)
|
|||||||
|
|
||||||
std::string const name = "USER:" + text.substr(9);
|
std::string const name = "USER:" + text.substr(9);
|
||||||
|
|
||||||
/* TravelNode* startNode = */ sTravelNodeMap->addNode(pos, name, false, false); // startNode not used, but addNode as side effect, fragment marked for removal.
|
/* TravelNode* startNode = */ TravelNodeMap::instance().addNode(pos, name, false, false); // startNode not used, but addNode as side effect, fragment marked for removal.
|
||||||
|
|
||||||
for (auto& endNode : sTravelNodeMap->getNodes(pos, 2000))
|
for (auto& endNode : TravelNodeMap::instance().getNodes(pos, 2000))
|
||||||
{
|
{
|
||||||
endNode->setLinked(false);
|
endNode->setLinked(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
botAI->TellMasterNoFacing("Node " + name + " created.");
|
botAI->TellMasterNoFacing("Node " + name + " created.");
|
||||||
|
|
||||||
sTravelNodeMap->setHasToGen();
|
TravelNodeMap::instance().setHasToGen();
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -211,7 +211,7 @@ bool DebugAction::Execute(Event event)
|
|||||||
{
|
{
|
||||||
WorldPosition pos(bot);
|
WorldPosition pos(bot);
|
||||||
|
|
||||||
TravelNode* startNode = sTravelNodeMap->getNode(pos, nullptr, 50);
|
TravelNode* startNode = TravelNodeMap::instance().getNode(pos, nullptr, 50);
|
||||||
|
|
||||||
if (!startNode)
|
if (!startNode)
|
||||||
return false;
|
return false;
|
||||||
@@ -221,24 +221,24 @@ bool DebugAction::Execute(Event event)
|
|||||||
botAI->TellMasterNoFacing("Node can not be removed.");
|
botAI->TellMasterNoFacing("Node can not be removed.");
|
||||||
}
|
}
|
||||||
|
|
||||||
sTravelNodeMap->m_nMapMtx.lock();
|
TravelNodeMap::instance().m_nMapMtx.lock();
|
||||||
sTravelNodeMap->removeNode(startNode);
|
TravelNodeMap::instance().removeNode(startNode);
|
||||||
botAI->TellMasterNoFacing("Node removed.");
|
botAI->TellMasterNoFacing("Node removed.");
|
||||||
sTravelNodeMap->m_nMapMtx.unlock();
|
TravelNodeMap::instance().m_nMapMtx.unlock();
|
||||||
|
|
||||||
sTravelNodeMap->setHasToGen();
|
TravelNodeMap::instance().setHasToGen();
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
else if (text.find("reset node") != std::string::npos)
|
else if (text.find("reset node") != std::string::npos)
|
||||||
{
|
{
|
||||||
for (auto& node : sTravelNodeMap->getNodes())
|
for (auto& node : TravelNodeMap::instance().getNodes())
|
||||||
node->setLinked(false);
|
node->setLinked(false);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
else if (text.find("reset path") != std::string::npos)
|
else if (text.find("reset path") != std::string::npos)
|
||||||
{
|
{
|
||||||
for (auto& node : sTravelNodeMap->getNodes())
|
for (auto& node : TravelNodeMap::instance().getNodes())
|
||||||
for (auto& path : *node->getLinks())
|
for (auto& path : *node->getLinks())
|
||||||
node->removeLinkTo(path.first, true);
|
node->removeLinkTo(path.first, true);
|
||||||
return true;
|
return true;
|
||||||
@@ -246,23 +246,23 @@ bool DebugAction::Execute(Event event)
|
|||||||
else if (text.find("gen node") != std::string::npos)
|
else if (text.find("gen node") != std::string::npos)
|
||||||
{
|
{
|
||||||
// Pathfinder
|
// Pathfinder
|
||||||
sTravelNodeMap->generateNodes();
|
TravelNodeMap::instance().generateNodes();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
else if (text.find("gen path") != std::string::npos)
|
else if (text.find("gen path") != std::string::npos)
|
||||||
{
|
{
|
||||||
sTravelNodeMap->generatePaths();
|
TravelNodeMap::instance().generatePaths();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
else if (text.find("crop path") != std::string::npos)
|
else if (text.find("crop path") != std::string::npos)
|
||||||
{
|
{
|
||||||
sTravelNodeMap->removeUselessPaths();
|
TravelNodeMap::instance().removeUselessPaths();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
else if (text.find("save node") != std::string::npos)
|
else if (text.find("save node") != std::string::npos)
|
||||||
{
|
{
|
||||||
sTravelNodeMap->printNodeStore();
|
TravelNodeMap::instance().printNodeStore();
|
||||||
sTravelNodeMap->saveNodeStore();
|
TravelNodeMap::instance().saveNodeStore();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
else if (text.find("load node") != std::string::npos)
|
else if (text.find("load node") != std::string::npos)
|
||||||
@@ -270,8 +270,8 @@ bool DebugAction::Execute(Event event)
|
|||||||
std::thread t(
|
std::thread t(
|
||||||
[]
|
[]
|
||||||
{
|
{
|
||||||
sTravelNodeMap->removeNodes();
|
TravelNodeMap::instance().removeNodes();
|
||||||
sTravelNodeMap->loadNodeStore();
|
TravelNodeMap::instance().loadNodeStore();
|
||||||
});
|
});
|
||||||
|
|
||||||
t.detach();
|
t.detach();
|
||||||
@@ -282,7 +282,7 @@ bool DebugAction::Execute(Event event)
|
|||||||
{
|
{
|
||||||
WorldPosition pos(bot);
|
WorldPosition pos(bot);
|
||||||
|
|
||||||
std::vector<TravelNode*> nodes = sTravelNodeMap->getNodes(pos, 500);
|
std::vector<TravelNode*> nodes = TravelNodeMap::instance().getNodes(pos, 500);
|
||||||
|
|
||||||
for (auto& node : nodes)
|
for (auto& node : nodes)
|
||||||
{
|
{
|
||||||
@@ -10,7 +10,7 @@
|
|||||||
|
|
||||||
bool DelayAction::Execute(Event event)
|
bool DelayAction::Execute(Event event)
|
||||||
{
|
{
|
||||||
uint32 delay = sPlayerbotAIConfig->passiveDelay + sPlayerbotAIConfig->globalCoolDown;
|
uint32 delay = sPlayerbotAIConfig.passiveDelay + sPlayerbotAIConfig.globalCoolDown;
|
||||||
|
|
||||||
botAI->SetNextCheckDelay(delay);
|
botAI->SetNextCheckDelay(delay);
|
||||||
|
|
||||||
@@ -67,7 +67,7 @@ bool CleanQuestLogAction::Execute(Event event)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!sPlayerbotAIConfig->dropObsoleteQuests)
|
if (!sPlayerbotAIConfig.dropObsoleteQuests)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -88,7 +88,7 @@ void EmoteActionBase::InitEmotes()
|
|||||||
|
|
||||||
bool EmoteActionBase::Emote(Unit* target, uint32 type, bool textEmote)
|
bool EmoteActionBase::Emote(Unit* target, uint32 type, bool textEmote)
|
||||||
{
|
{
|
||||||
if (target && !bot->HasInArc(static_cast<float>(M_PI), target, sPlayerbotAIConfig->sightDistance))
|
if (target && !bot->HasInArc(static_cast<float>(M_PI), target, sPlayerbotAIConfig.sightDistance))
|
||||||
bot->SetFacingToObject(target);
|
bot->SetFacingToObject(target);
|
||||||
|
|
||||||
ObjectGuid oldSelection = bot->GetTarget();
|
ObjectGuid oldSelection = bot->GetTarget();
|
||||||
@@ -100,7 +100,7 @@ bool EmoteActionBase::Emote(Unit* target, uint32 type, bool textEmote)
|
|||||||
if (player)
|
if (player)
|
||||||
{
|
{
|
||||||
PlayerbotAI* playerBotAI = GET_PLAYERBOT_AI(player);
|
PlayerbotAI* playerBotAI = GET_PLAYERBOT_AI(player);
|
||||||
if (playerBotAI && !player->HasInArc(static_cast<float>(M_PI), bot, sPlayerbotAIConfig->sightDistance))
|
if (playerBotAI && !player->HasInArc(static_cast<float>(M_PI), bot, sPlayerbotAIConfig.sightDistance))
|
||||||
{
|
{
|
||||||
player->SetFacingToObject(bot);
|
player->SetFacingToObject(bot);
|
||||||
}
|
}
|
||||||
@@ -133,7 +133,7 @@ Unit* EmoteActionBase::GetTarget()
|
|||||||
for (GuidVector::iterator i = nfp.begin(); i != nfp.end(); ++i)
|
for (GuidVector::iterator i = nfp.begin(); i != nfp.end(); ++i)
|
||||||
{
|
{
|
||||||
Unit* unit = botAI->GetUnit(*i);
|
Unit* unit = botAI->GetUnit(*i);
|
||||||
if (unit && sServerFacade->GetDistance2d(bot, unit) < sPlayerbotAIConfig->tooCloseDistance)
|
if (unit && ServerFacade::instance().GetDistance2d(bot, unit) < sPlayerbotAIConfig.tooCloseDistance)
|
||||||
targets.push_back(unit);
|
targets.push_back(unit);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -618,8 +618,8 @@ bool EmoteActionBase::ReceiveEmote(Player* source, uint32 emote, bool verbal)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (source && !bot->isMoving() && !bot->HasInArc(static_cast<float>(M_PI), source, sPlayerbotAIConfig->farDistance))
|
if (source && !bot->isMoving() && !bot->HasInArc(static_cast<float>(M_PI), source, sPlayerbotAIConfig.farDistance))
|
||||||
sServerFacade->SetFacingTo(bot, source);
|
ServerFacade::instance().SetFacingTo(bot, source);
|
||||||
|
|
||||||
if (verbal)
|
if (verbal)
|
||||||
{
|
{
|
||||||
@@ -689,7 +689,7 @@ bool EmoteAction::Execute(Event event)
|
|||||||
p >> emoteId >> source;
|
p >> emoteId >> source;
|
||||||
|
|
||||||
pSource = ObjectAccessor::FindPlayer(source);
|
pSource = ObjectAccessor::FindPlayer(source);
|
||||||
if (pSource && pSource != bot && sServerFacade->GetDistance2d(bot, pSource) < sPlayerbotAIConfig->farDistance &&
|
if (pSource && pSource != bot && ServerFacade::instance().GetDistance2d(bot, pSource) < sPlayerbotAIConfig.farDistance &&
|
||||||
emoteId != EMOTE_ONESHOT_NONE)
|
emoteId != EMOTE_ONESHOT_NONE)
|
||||||
{
|
{
|
||||||
if ((pSource->GetGUID() != bot->GetGUID()) &&
|
if ((pSource->GetGUID() != bot->GetGUID()) &&
|
||||||
@@ -737,7 +737,7 @@ bool EmoteAction::Execute(Event event)
|
|||||||
// time_t lastEmote = AI_VALUE2(time_t, "last emote", qualifier); //not used, line marked for removal.
|
// time_t lastEmote = AI_VALUE2(time_t, "last emote", qualifier); //not used, line marked for removal.
|
||||||
botAI->GetAiObjectContext()
|
botAI->GetAiObjectContext()
|
||||||
->GetValue<time_t>("last emote", qualifier)
|
->GetValue<time_t>("last emote", qualifier)
|
||||||
->Set(time(nullptr) + urand(1000, sPlayerbotAIConfig->repeatDelay) / 1000);
|
->Set(time(nullptr) + urand(1000, sPlayerbotAIConfig.repeatDelay) / 1000);
|
||||||
param = qualifier;
|
param = qualifier;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -330,7 +330,7 @@ void EquipAction::EquipItem(Item* item)
|
|||||||
|
|
||||||
bool EquipUpgradesAction::Execute(Event event)
|
bool EquipUpgradesAction::Execute(Event event)
|
||||||
{
|
{
|
||||||
if (!sPlayerbotAIConfig->autoEquipUpgradeLoot && !sRandomPlayerbotMgr->IsRandomBot(bot))
|
if (!sPlayerbotAIConfig.autoEquipUpgradeLoot && !sRandomPlayerbotMgr.IsRandomBot(bot))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (event.GetSource() == "trade status")
|
if (event.GetSource() == "trade status")
|
||||||
@@ -261,7 +261,9 @@ bool MoveNearWaterAction::isUseful()
|
|||||||
return false;
|
return false;
|
||||||
FishingSpotValue* fishingSpotValueObject = (FishingSpotValue*)context->GetValue<WorldPosition>("fishing spot");
|
FishingSpotValue* fishingSpotValueObject = (FishingSpotValue*)context->GetValue<WorldPosition>("fishing spot");
|
||||||
WorldPosition pos = fishingSpotValueObject->Get();
|
WorldPosition pos = fishingSpotValueObject->Get();
|
||||||
return !pos.IsValid() || fishingSpotValueObject->IsStale(FISHING_LOCATION_TIMEOUT) || pos != bot->GetPosition();
|
return !pos.IsValid() || fishingSpotValueObject->IsStale(FISHING_LOCATION_TIMEOUT) ||
|
||||||
|
bot->GetExactDist(&pos) < 0.1f;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool MoveNearWaterAction::isPossible()
|
bool MoveNearWaterAction::isPossible()
|
||||||
@@ -270,9 +272,9 @@ bool MoveNearWaterAction::isPossible()
|
|||||||
float fishingSearchWindow;
|
float fishingSearchWindow;
|
||||||
|
|
||||||
if (master)
|
if (master)
|
||||||
fishingSearchWindow = sPlayerbotAIConfig->fishingDistanceFromMaster;
|
fishingSearchWindow = sPlayerbotAIConfig.fishingDistanceFromMaster;
|
||||||
else
|
else
|
||||||
fishingSearchWindow = sPlayerbotAIConfig->fishingDistance;
|
fishingSearchWindow = sPlayerbotAIConfig.fishingDistance;
|
||||||
|
|
||||||
WorldPosition fishingHole = FindFishingHole(botAI);
|
WorldPosition fishingHole = FindFishingHole(botAI);
|
||||||
|
|
||||||
@@ -299,6 +301,17 @@ bool MoveNearWaterAction::isPossible()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// Can the bot fish from current position?
|
||||||
|
WorldPosition waterAtCurrentPos =
|
||||||
|
FindWaterRadial(bot, bot->GetPositionX(), bot->GetPositionY(), bot->GetPositionZ(), bot->GetMap(),
|
||||||
|
bot->GetPhaseMask(), MIN_DISTANCE_TO_WATER, MAX_DISTANCE_TO_WATER, SEARCH_INCREMENT, true);
|
||||||
|
if (waterAtCurrentPos.IsValid())
|
||||||
|
{
|
||||||
|
SET_AI_VALUE(WorldPosition, "fishing spot",
|
||||||
|
WorldPosition(WorldPosition(bot->GetMapId(), bot->GetPositionX(), bot->GetPositionY(),
|
||||||
|
bot->GetPositionZ())));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
// Lets find some water where we can fish.
|
// Lets find some water where we can fish.
|
||||||
WorldPosition water = FindWaterRadial(
|
WorldPosition water = FindWaterRadial(
|
||||||
bot, bot->GetPositionX(), bot->GetPositionY(), bot->GetPositionZ(),
|
bot, bot->GetPositionX(), bot->GetPositionY(), bot->GetPositionZ(),
|
||||||
@@ -372,7 +385,7 @@ bool EquipFishingPoleAction::isUseful()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sRandomPlayerbotMgr->IsRandomBot(bot))
|
if (sRandomPlayerbotMgr.IsRandomBot(bot))
|
||||||
{
|
{
|
||||||
bot->StoreNewItemInBestSlots(FISHING_POLE, 1); // Try to get a fishing pole
|
bot->StoreNewItemInBestSlots(FISHING_POLE, 1); // Try to get a fishing pole
|
||||||
return true;
|
return true;
|
||||||
@@ -383,7 +396,7 @@ bool EquipFishingPoleAction::isUseful()
|
|||||||
return false;
|
return false;
|
||||||
|
|
||||||
std::string masterName = master->GetName();
|
std::string masterName = master->GetName();
|
||||||
std::string text = sPlayerbotTextMgr->GetBotTextOrDefault(
|
std::string text = PlayerbotTextMgr::instance().GetBotTextOrDefault(
|
||||||
"no_fishing_pole_error", "I don't have a Fishing Pole",{});
|
"no_fishing_pole_error", "I don't have a Fishing Pole",{});
|
||||||
botAI->Whisper(text, masterName);
|
botAI->Whisper(text, masterName);
|
||||||
|
|
||||||
@@ -435,10 +448,14 @@ bool FishingAction::isUseful()
|
|||||||
{
|
{
|
||||||
if (!AI_VALUE(bool, "can fish"))
|
if (!AI_VALUE(bool, "can fish"))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
FishingSpotValue* fishingSpotValueObject = (FishingSpotValue*)context->GetValue<WorldPosition>("fishing spot");
|
FishingSpotValue* fishingSpotValueObject = (FishingSpotValue*)context->GetValue<WorldPosition>("fishing spot");
|
||||||
WorldPosition pos = fishingSpotValueObject->Get();
|
WorldPosition pos = fishingSpotValueObject->Get();
|
||||||
|
|
||||||
return pos.IsValid() && !fishingSpotValueObject->IsStale(FISHING_LOCATION_TIMEOUT) && pos == bot->GetPosition();
|
if (!pos.IsValid() || fishingSpotValueObject->IsStale(FISHING_LOCATION_TIMEOUT))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return bot->GetExactDist(&pos) < 0.1f;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool UseBobberAction::isUseful()
|
bool UseBobberAction::isUseful()
|
||||||
@@ -482,7 +499,7 @@ bool EndMasterFishingAction::isUseful()
|
|||||||
return false;
|
return false;
|
||||||
|
|
||||||
WorldPosition nearWater = FindWaterRadial(bot, bot->GetPositionX(), bot->GetPositionY(), bot->GetPositionZ(),
|
WorldPosition nearWater = FindWaterRadial(bot, bot->GetPositionX(), bot->GetPositionY(), bot->GetPositionZ(),
|
||||||
bot->GetMap(), bot->GetPhaseMask(), MIN_DISTANCE_TO_WATER, sPlayerbotAIConfig->endFishingWithMaster, 10.0f);
|
bot->GetMap(), bot->GetPhaseMask(), MIN_DISTANCE_TO_WATER, sPlayerbotAIConfig.endFishingWithMaster, 10.0f);
|
||||||
return !nearWater.IsValid();
|
return !nearWater.IsValid();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -44,7 +44,7 @@ bool FollowAction::Execute(Event event)
|
|||||||
// botAI->PetFollow();
|
// botAI->PetFollow();
|
||||||
// }
|
// }
|
||||||
// if (moved)
|
// if (moved)
|
||||||
// botAI->SetNextCheckDelay(sPlayerbotAIConfig->reactDelay);
|
// botAI->SetNextCheckDelay(sPlayerbotAIConfig.reactDelay);
|
||||||
|
|
||||||
return moved;
|
return moved;
|
||||||
}
|
}
|
||||||
@@ -98,9 +98,9 @@ bool FollowAction::isUseful()
|
|||||||
distance = bot->GetDistance(loc.GetPositionX(), loc.GetPositionY(), loc.GetPositionZ());
|
distance = bot->GetDistance(loc.GetPositionX(), loc.GetPositionY(), loc.GetPositionZ());
|
||||||
}
|
}
|
||||||
if (botAI->HasStrategy("master fishing", BOT_STATE_NON_COMBAT))
|
if (botAI->HasStrategy("master fishing", BOT_STATE_NON_COMBAT))
|
||||||
return sServerFacade->IsDistanceGreaterThan(distance, sPlayerbotAIConfig->fishingDistanceFromMaster);
|
return ServerFacade::instance().IsDistanceGreaterThan(distance, sPlayerbotAIConfig.fishingDistanceFromMaster);
|
||||||
|
|
||||||
return sServerFacade->IsDistanceGreaterThan(distance, formation->GetMaxDistance());
|
return ServerFacade::instance().IsDistanceGreaterThan(distance, formation->GetMaxDistance());
|
||||||
}
|
}
|
||||||
|
|
||||||
bool FollowAction::CanDeadFollow(Unit* target)
|
bool FollowAction::CanDeadFollow(Unit* target)
|
||||||
@@ -130,7 +130,7 @@ bool FleeToGroupLeaderAction::Execute(Event event)
|
|||||||
WorldPosition bosPos(bot);
|
WorldPosition bosPos(bot);
|
||||||
float distance = bosPos.fDist(targetPos);
|
float distance = bosPos.fDist(targetPos);
|
||||||
|
|
||||||
if (distance < sPlayerbotAIConfig->reactDistance * 3)
|
if (distance < sPlayerbotAIConfig.reactDistance * 3)
|
||||||
{
|
{
|
||||||
if (!urand(0, 3))
|
if (!urand(0, 3))
|
||||||
botAI->TellMaster("I am close, wait for me!");
|
botAI->TellMaster("I am close, wait for me!");
|
||||||
@@ -113,7 +113,7 @@ bool TogglePetSpellAutoCastAction::Execute(Event event)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Debug message if pet spells have been toggled and debug is enabled
|
// Debug message if pet spells have been toggled and debug is enabled
|
||||||
if (toggled && sPlayerbotAIConfig->petChatCommandDebug == 1)
|
if (toggled && sPlayerbotAIConfig.petChatCommandDebug == 1)
|
||||||
botAI->TellMaster("Pet autocast spells have been toggled.");
|
botAI->TellMaster("Pet autocast spells have been toggled.");
|
||||||
|
|
||||||
return toggled;
|
return toggled;
|
||||||
@@ -185,7 +185,7 @@ bool SetPetStanceAction::Execute(Event /*event*/)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Get the default pet stance from the configuration
|
// Get the default pet stance from the configuration
|
||||||
int32 stance = sPlayerbotAIConfig->defaultPetStance;
|
int32 stance = sPlayerbotAIConfig.defaultPetStance;
|
||||||
ReactStates react = REACT_DEFENSIVE;
|
ReactStates react = REACT_DEFENSIVE;
|
||||||
std::string stanceText = "defensive (from config, fallback)";
|
std::string stanceText = "defensive (from config, fallback)";
|
||||||
|
|
||||||
@@ -221,7 +221,7 @@ bool SetPetStanceAction::Execute(Event /*event*/)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// If debug is enabled in config, inform the master of the new stance
|
// If debug is enabled in config, inform the master of the new stance
|
||||||
if (sPlayerbotAIConfig->petChatCommandDebug == 1)
|
if (sPlayerbotAIConfig.petChatCommandDebug == 1)
|
||||||
botAI->TellMaster("Pet stance set to " + stanceText + " (applied to all pets/guardians).");
|
botAI->TellMaster("Pet stance set to " + stanceText + " (applied to all pets/guardians).");
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
@@ -87,7 +87,7 @@ namespace ai::buff
|
|||||||
{
|
{
|
||||||
std::string castName = baseName;
|
std::string castName = baseName;
|
||||||
Group* g = bot->GetGroup();
|
Group* g = bot->GetGroup();
|
||||||
if (!g || g->GetMembersCount() < static_cast<uint32>(sPlayerbotAIConfig->minBotsForGreaterBuff))
|
if (!g || g->GetMembersCount() < static_cast<uint32>(sPlayerbotAIConfig.minBotsForGreaterBuff))
|
||||||
return castName; // Group too small: stay in solo mode
|
return castName; // Group too small: stay in solo mode
|
||||||
|
|
||||||
if (std::string const groupName = GroupVariantFor(baseName); !groupName.empty())
|
if (std::string const groupName = GroupVariantFor(baseName); !groupName.empty())
|
||||||
@@ -114,7 +114,7 @@ namespace ai::buff
|
|||||||
time_t now = std::time(nullptr);
|
time_t now = std::time(nullptr);
|
||||||
uint32 botLow = static_cast<uint32>(bot->GetGUID().GetCounter());
|
uint32 botLow = static_cast<uint32>(bot->GetGUID().GetCounter());
|
||||||
time_t& last = s_lastWarn[ std::make_pair(botLow, groupName) ];
|
time_t& last = s_lastWarn[ std::make_pair(botLow, groupName) ];
|
||||||
if (!last || now - last >= sPlayerbotAIConfig->rpWarningCooldown) // Configurable anti-spam
|
if (!last || now - last >= sPlayerbotAIConfig.rpWarningCooldown) // Configurable anti-spam
|
||||||
{
|
{
|
||||||
// DB Key choice in regard of the buff
|
// DB Key choice in regard of the buff
|
||||||
std::string key;
|
std::string key;
|
||||||
@@ -132,7 +132,7 @@ namespace ai::buff
|
|||||||
placeholders["%group_spell"] = groupName;
|
placeholders["%group_spell"] = groupName;
|
||||||
placeholders["%base_spell"] = baseName;
|
placeholders["%base_spell"] = baseName;
|
||||||
|
|
||||||
std::string announceText = sPlayerbotTextMgr->GetBotTextOrDefault(key,
|
std::string announceText = PlayerbotTextMgr::instance().GetBotTextOrDefault(key,
|
||||||
"Out of components for %group_spell. Using %base_spell!", placeholders);
|
"Out of components for %group_spell. Using %base_spell!", placeholders);
|
||||||
|
|
||||||
announce(announceText);
|
announce(announceText);
|
||||||
@@ -82,7 +82,7 @@ bool CastSpellAction::isPossible()
|
|||||||
{
|
{
|
||||||
if (botAI->IsInVehicle() && !botAI->IsInVehicle(false, false, true))
|
if (botAI->IsInVehicle() && !botAI->IsInVehicle(false, false, true))
|
||||||
{
|
{
|
||||||
if (!sPlayerbotAIConfig->logInGroupOnly || (bot->GetGroup() && botAI->HasRealPlayerMaster()))
|
if (!sPlayerbotAIConfig.logInGroupOnly || (bot->GetGroup() && botAI->HasRealPlayerMaster()))
|
||||||
{
|
{
|
||||||
LOG_DEBUG("playerbots", "Can cast spell failed. Vehicle. - bot name: {}", bot->GetName());
|
LOG_DEBUG("playerbots", "Can cast spell failed. Vehicle. - bot name: {}", bot->GetName());
|
||||||
}
|
}
|
||||||
@@ -94,7 +94,7 @@ bool CastSpellAction::isPossible()
|
|||||||
|
|
||||||
if (spell == "mount" && bot->IsInCombat())
|
if (spell == "mount" && bot->IsInCombat())
|
||||||
{
|
{
|
||||||
if (!sPlayerbotAIConfig->logInGroupOnly || (bot->GetGroup() && botAI->HasRealPlayerMaster()))
|
if (!sPlayerbotAIConfig.logInGroupOnly || (bot->GetGroup() && botAI->HasRealPlayerMaster()))
|
||||||
{
|
{
|
||||||
LOG_DEBUG("playerbots", "Can cast spell failed. Mount. - bot name: {}", bot->GetName());
|
LOG_DEBUG("playerbots", "Can cast spell failed. Mount. - bot name: {}", bot->GetName());
|
||||||
}
|
}
|
||||||
@@ -133,7 +133,7 @@ bool CastSpellAction::isUseful()
|
|||||||
|
|
||||||
return spellTarget &&
|
return spellTarget &&
|
||||||
AI_VALUE2(bool, "spell cast useful",
|
AI_VALUE2(bool, "spell cast useful",
|
||||||
spell); // && sServerFacade->GetDistance2d(bot, spellTarget) <= (range + combatReach);
|
spell); // && ServerFacade::instance().GetDistance2d(bot, spellTarget) <= (range + combatReach);
|
||||||
}
|
}
|
||||||
|
|
||||||
CastMeleeSpellAction::CastMeleeSpellAction(PlayerbotAI* botAI, std::string const spell) : CastSpellAction(botAI, spell)
|
CastMeleeSpellAction::CastMeleeSpellAction(PlayerbotAI* botAI, std::string const spell) : CastSpellAction(botAI, spell)
|
||||||
@@ -64,7 +64,7 @@ Unit* GiveItemAction::GetTarget() { return AI_VALUE2(Unit*, "party member withou
|
|||||||
|
|
||||||
bool GiveItemAction::isUseful()
|
bool GiveItemAction::isUseful()
|
||||||
{
|
{
|
||||||
return GetTarget() && AI_VALUE2(uint8, "mana", "self target") > sPlayerbotAIConfig->lowMana;
|
return GetTarget() && AI_VALUE2(uint8, "mana", "self target") > sPlayerbotAIConfig.lowMana;
|
||||||
}
|
}
|
||||||
|
|
||||||
Unit* GiveFoodAction::GetTarget() { return AI_VALUE(Unit*, "party member without food"); }
|
Unit* GiveFoodAction::GetTarget() { return AI_VALUE(Unit*, "party member without food"); }
|
||||||
@@ -74,7 +74,7 @@ bool GiveFoodAction::isUseful()
|
|||||||
if (!GetTarget())
|
if (!GetTarget())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
bool isRandomBot = GetTarget()->IsPlayer() && sRandomPlayerbotMgr->IsRandomBot((Player*)GetTarget());
|
bool isRandomBot = GetTarget()->IsPlayer() && sRandomPlayerbotMgr.IsRandomBot((Player*)GetTarget());
|
||||||
|
|
||||||
return !isRandomBot || (isRandomBot && !botAI->HasCheat(BotCheatMask::food));
|
return !isRandomBot || (isRandomBot && !botAI->HasCheat(BotCheatMask::food));
|
||||||
}
|
}
|
||||||
@@ -86,7 +86,7 @@ bool GiveWaterAction::isUseful()
|
|||||||
if (!GetTarget())
|
if (!GetTarget())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
bool isRandomBot = GetTarget()->IsPlayer() && sRandomPlayerbotMgr->IsRandomBot((Player*)GetTarget());
|
bool isRandomBot = GetTarget()->IsPlayer() && sRandomPlayerbotMgr.IsRandomBot((Player*)GetTarget());
|
||||||
|
|
||||||
return !isRandomBot || (isRandomBot && !botAI->HasCheat(BotCheatMask::food));
|
return !isRandomBot || (isRandomBot && !botAI->HasCheat(BotCheatMask::food));
|
||||||
}
|
}
|
||||||
@@ -61,7 +61,7 @@ bool GoAction::Execute(Event event)
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
botAI->TellMasterNoFacing("Clearing travel target");
|
botAI->TellMasterNoFacing("Clearing travel target");
|
||||||
target->setTarget(sTravelMgr->nullTravelDestination, sTravelMgr->nullWorldPosition);
|
target->setTarget(TravelMgr::instance().nullTravelDestination, TravelMgr::instance().nullWorldPosition);
|
||||||
target->setForced(false);
|
target->setForced(false);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -75,8 +75,8 @@ bool GoAction::Execute(Event event)
|
|||||||
if (GameObject* go = botAI->GetGameObject(guid))
|
if (GameObject* go = botAI->GetGameObject(guid))
|
||||||
if (go->isSpawned())
|
if (go->isSpawned())
|
||||||
{
|
{
|
||||||
if (sServerFacade->IsDistanceGreaterThan(sServerFacade->GetDistance2d(bot, go),
|
if (ServerFacade::instance().IsDistanceGreaterThan(ServerFacade::instance().GetDistance2d(bot, go),
|
||||||
sPlayerbotAIConfig->reactDistance))
|
sPlayerbotAIConfig.reactDistance))
|
||||||
{
|
{
|
||||||
botAI->TellError("It is too far away");
|
botAI->TellError("It is too far away");
|
||||||
return false;
|
return false;
|
||||||
@@ -86,7 +86,7 @@ bool GoAction::Execute(Event event)
|
|||||||
out << "Moving to " << ChatHelper::FormatGameobject(go);
|
out << "Moving to " << ChatHelper::FormatGameobject(go);
|
||||||
botAI->TellMasterNoFacing(out.str());
|
botAI->TellMasterNoFacing(out.str());
|
||||||
return MoveNear(bot->GetMapId(), go->GetPositionX(), go->GetPositionY(), go->GetPositionZ() + 0.5f,
|
return MoveNear(bot->GetMapId(), go->GetPositionX(), go->GetPositionY(), go->GetPositionZ() + 0.5f,
|
||||||
sPlayerbotAIConfig->followDistance);
|
sPlayerbotAIConfig.followDistance);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
@@ -106,7 +106,7 @@ bool GoAction::Execute(Event event)
|
|||||||
out << "Moving to " << unit->GetName();
|
out << "Moving to " << unit->GetName();
|
||||||
botAI->TellMasterNoFacing(out.str());
|
botAI->TellMasterNoFacing(out.str());
|
||||||
return MoveNear(bot->GetMapId(), unit->GetPositionX(), unit->GetPositionY(),
|
return MoveNear(bot->GetMapId(), unit->GetPositionX(), unit->GetPositionY(),
|
||||||
unit->GetPositionZ() + 0.5f, sPlayerbotAIConfig->followDistance);
|
unit->GetPositionZ() + 0.5f, sPlayerbotAIConfig.followDistance);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -176,8 +176,8 @@ bool GoAction::Execute(Event event)
|
|||||||
float z = bot->GetPositionZ();
|
float z = bot->GetPositionZ();
|
||||||
bot->UpdateAllowedPositionZ(x, y, z);
|
bot->UpdateAllowedPositionZ(x, y, z);
|
||||||
|
|
||||||
if (sServerFacade->IsDistanceGreaterThan(sServerFacade->GetDistance2d(bot, x, y),
|
if (ServerFacade::instance().IsDistanceGreaterThan(ServerFacade::instance().GetDistance2d(bot, x, y),
|
||||||
sPlayerbotAIConfig->reactDistance))
|
sPlayerbotAIConfig.reactDistance))
|
||||||
{
|
{
|
||||||
botAI->TellMaster("It is too far away");
|
botAI->TellMaster("It is too far away");
|
||||||
return false;
|
return false;
|
||||||
@@ -203,14 +203,14 @@ bool GoAction::Execute(Event event)
|
|||||||
out << "Moving to " << x1 << "," << y1;
|
out << "Moving to " << x1 << "," << y1;
|
||||||
botAI->TellMasterNoFacing(out.str());
|
botAI->TellMasterNoFacing(out.str());
|
||||||
|
|
||||||
return MoveNear(bot->GetMapId(), x, y, z + 0.5f, sPlayerbotAIConfig->followDistance);
|
return MoveNear(bot->GetMapId(), x, y, z + 0.5f, sPlayerbotAIConfig.followDistance);
|
||||||
}
|
}
|
||||||
|
|
||||||
PositionInfo pos = context->GetValue<PositionMap&>("position")->Get()[param];
|
PositionInfo pos = context->GetValue<PositionMap&>("position")->Get()[param];
|
||||||
if (pos.isSet())
|
if (pos.isSet())
|
||||||
{
|
{
|
||||||
if (sServerFacade->IsDistanceGreaterThan(sServerFacade->GetDistance2d(bot, pos.x, pos.y),
|
if (ServerFacade::instance().IsDistanceGreaterThan(ServerFacade::instance().GetDistance2d(bot, pos.x, pos.y),
|
||||||
sPlayerbotAIConfig->reactDistance))
|
sPlayerbotAIConfig.reactDistance))
|
||||||
{
|
{
|
||||||
botAI->TellError("It is too far away");
|
botAI->TellError("It is too far away");
|
||||||
return false;
|
return false;
|
||||||
@@ -219,7 +219,7 @@ bool GoAction::Execute(Event event)
|
|||||||
std::ostringstream out;
|
std::ostringstream out;
|
||||||
out << "Moving to position " << param;
|
out << "Moving to position " << param;
|
||||||
botAI->TellMasterNoFacing(out.str());
|
botAI->TellMasterNoFacing(out.str());
|
||||||
return MoveNear(bot->GetMapId(), pos.x, pos.y, pos.z + 0.5f, sPlayerbotAIConfig->followDistance);
|
return MoveNear(bot->GetMapId(), pos.x, pos.y, pos.z + 0.5f, sPlayerbotAIConfig.followDistance);
|
||||||
}
|
}
|
||||||
|
|
||||||
botAI->TellMaster("Whisper 'go x,y', 'go [game object]', 'go unit' or 'go position' and I will go there");
|
botAI->TellMaster("Whisper 'go x,y', 'go [game object]', 'go unit' or 'go position' and I will go there");
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user