diff --git a/.github/workflows/codestyle_cpp.yml b/.github/workflows/codestyle_cpp.yml
new file mode 100644
index 0000000000..065732890f
--- /dev/null
+++ b/.github/workflows/codestyle_cpp.yml
@@ -0,0 +1,40 @@
+name: C++ Codestyle
+on:
+ pull_request:
+ types:
+ - opened
+ - reopened
+ - synchronize
+ - ready_for_review
+ paths:
+ - src/**
+ - "!README.md"
+ - "!docs/**"
+
+concurrency:
+ group: "codestyle-cppcheck-${{ github.event.pull_request.number }}"
+ cancel-in-progress: true
+
+jobs:
+ triage:
+ runs-on: ubuntu-latest
+ name: C++
+ if: github.event.pull_request.draft == false
+ steps:
+ - uses: actions/checkout@v4
+ - name: Setup python
+ uses: actions/setup-python@v5
+ with:
+ python-version: '3.10'
+ - name: AzerothCore codestyle
+ run: python ./apps/codestyle/codestyle-cpp.py
+ - name: C++ Advanced
+ run: |
+ sudo apt update -y
+ sudo apt install -y cppcheck
+ cppcheck --force --inline-suppr --suppressions-list=./.suppress.cppcheck src/ --output-file=report.txt
+
+ if [ -s report.txt ]; then # if file is not empty
+ cat report.txt
+ exit 1 # let github action fails
+ fi
diff --git a/.suppress.cppcheck b/.suppress.cppcheck
new file mode 100644
index 0000000000..07569fe086
--- /dev/null
+++ b/.suppress.cppcheck
@@ -0,0 +1 @@
+cppcheckError
\ No newline at end of file
diff --git a/README.md b/README.md
index 5007b49b82..3924765ab6 100644
--- a/README.md
+++ b/README.md
@@ -3,7 +3,7 @@
|
中文
|
- Español
+ Español
@@ -18,25 +18,27 @@
# Playerbots Module
-`mod-playerbots` is an [AzerothCore](https://www.azerothcore.org/) module that adds player-like bots to a server. The project is based off [IKE3's Playerbots](https://github.com/ike3/mangosbot) and requires a custom branch of AzerothCore to compile and run: [mod-playerbots/azerothcore-wotlk/tree/Playerbot](https://github.com/mod-playerbots/azerothcore-wotlk/tree/Playerbot).
+`mod-playerbots` is an [AzerothCore](https://www.azerothcore.org/) module that adds player-like bots to a server. The project is based off [IKE3's Playerbots](https://github.com/ike3/mangosbot).
Features include:
-- The ability to log in alt characters as bots, allowing players to interact with their other characters, form parties, level up, and more;
-- Random bots that wander through the world, complete quests, and otherwise behave like players, simulating the MMO experience;
-- Bots capable of running most raids and battlegrounds;
-- Highly configurable settings to define how bots behave;
-- Excellent performance, even when running thousands of bots.
+- The ability to log in alt characters as bots, allowing players to interact with their other characters, form parties, level up, and more
+- Random bots that wander through the world, complete quests, and otherwise behave like players, simulating the MMO experience
+- Bots capable of running most raids and battlegrounds
+- Highly configurable settings to define how bots behave
+- Excellent performance, even when running thousands of bots
-**This project is still under development**. If you encounter any errors or experience crashes, we kindly request that you [report them as GitHub issues](https://github.com/mod-playerbots/mod-playerbots/issues/new?template=bug_report.md). Your valuable feedback will help us improve this project collaboratively.
-
-`mod-playerbots` has a **[Discord server](https://discord.gg/NQm5QShwf9)** where you can discuss the project, ask questions, and get involved in the community!
+We also have a **[Discord server](https://discord.gg/NQm5QShwf9)** where you can discuss the project, ask questions, and get involved in the community!
## Installation
-### Classic Installation
+Supported platforms are Ubuntu, Windows, and macOS. Other Linux distributions may work, but may not receive support.
+
+**All `mod-playerbots` installations require a custom branch of AzerothCore: [mod-playerbots/azerothcore-wotlk/tree/Playerbot](https://github.com/mod-playerbots/azerothcore-wotlk/tree/Playerbot).** This branch allows the `mod-playerbots` module to build and function. Updates from the upstream are implemented regularly to this branch. Instructions for installing this required branch and this module are provided below.
+
+### Cloning the Repositories
-As noted above, `mod-playerbots` requires a custom branch of AzerothCore: [mod-playerbots/azerothcore-wotlk/tree/Playerbot](https://github.com/mod-playerbots/azerothcore-wotlk/tree/Playerbot). To install the module, simply run:
+To install both the required branch of AzerothCore and the `mod-playerbots` module from source, run the following:
```bash
git clone https://github.com/mod-playerbots/azerothcore-wotlk.git --branch=Playerbot
@@ -48,7 +50,7 @@ For more information, refer to the [AzerothCore Installation Guide](https://www.
### Docker Installation
-**Docker installation is considered experimental.** To install the module on a Docker installation, run:
+Docker installations are considered experimental (unofficial with limited support), and previous Docker experience is recommended. To install `mod-playerbots` on Docker, first clone the required branch of AzerothCore and this module:
```bash
git clone https://github.com/mod-playerbots/azerothcore-wotlk.git --branch=Playerbot
@@ -85,28 +87,23 @@ Use `docker compose up -d --build` to build and run the server. For more informa
## Documentation
-The [Playerbots Wiki](https://github.com/mod-playerbots/mod-playerbots/wiki) contains an extensive overview of addons, commands, raids with programmed bot strategies, and recommended performance configurations. Please note that documentation may be incomplete or out-of-date in some sections. Contributions are welcome.
+The [Playerbots Wiki](https://github.com/mod-playerbots/mod-playerbots/wiki) contains an extensive overview of AddOns, commands, raids with programmed bot strategies, and recommended performance configurations. Please note that documentation may be incomplete or out-of-date in some sections, and contributions are welcome.
-## Frequently Asked Questions
+Bots are controlled via chat commands. For larger bot groups, this can be cumbersome. Because of this, community members have developed client AddOns to allow controlling bots through the in-game UI. We recommend you check out their projects listed in the [AddOns and Submodules](https://github.com/mod-playerbots/mod-playerbots/wiki/Playerbot-Addons-and-Sub%E2%80%90Modules) page.
-- **Why aren't my bots casting spells?** Please make sure that the necessary English DBC file (enUS) is present.
-- **What platforms are supported?** We support Ubuntu, Windows, and macOS. Other Linux distros may work, but will not receive support.
-- **Why isn't my source compiling?** Please ensure that you are compiling with the required [custom branch of AzerothCore](https://github.com/mod-playerbots/azerothcore-wotlk/tree/Playerbot). Additionally, please [check the build status of our CI](https://github.com/mod-playerbots/mod-playerbots/actions). If the latest build is failing, rever to the last successful commit until we address the issue.
+## Contributing
-## Code standards
-- https://www.azerothcore.org/wiki/cpp-code-standards
+This project is still under development. We encourage anyone to make contributions, anything from pull requests to reporting issues. If you encounter any errors or experience crashes, we encourage you [report them as GitHub issues](https://github.com/mod-playerbots/mod-playerbots/issues/new?template=bug_report.md). Your valuable feedback will help us improve this project collaboratively.
-## Addons
+If you make coding contributions, `mod-playerbots` complies with the [C++ Code Standards](https://www.azerothcore.org/wiki/cpp-code-standards) established by AzerothCore. Each Pull Request must include all test scenarios the author performed, along with their results, to demonstrate that the changes were properly verified.
-Typically, bots are controlled via chat commands. For larger bot groups, this can be unwieldy. As an alternative, community members have developed client Add-Ons to allow controlling bots through the in-game UI. We recommend you check out their projects:
+We recommend joining the [Discord server](https://discord.gg/NQm5QShwf9) to make your contributions to the project easier, as a lot of active support is carried out through this server.
-- [Multibot](https://github.com/Macx-Lio/MultiBot) (by Macx-Lio), which includes English, Chinese, French, German, Korean, Russian, and Spanish support [note: active development is temporarily continuing on a fork in Macx-Lio's absence (https://github.com/Wishmaster117/MultiBot)]
-- [Unbot Addon (zh)](https://github.com/liyunfan1223/unbot-addon) (Chinese version by Liyunfan) [note: no longer under active development]
-- [Unbot Addon (en)](https://github.com/noisiver/unbot-addon/tree/english) (English version translated by @Revision) [note: no longer under active development]
+Please click on the "⭐" button to stay up to date and help us gain more visibility on GitHub!
## Acknowledgements
-`mod-playerbots` is is based off [ZhengPeiRu21/mod-playerbots](https://github.com/ZhengPeiRu21/mod-playerbots) and [celguar/mangosbot-bots](https://github.com/celguar/mangosbot-bots). We extend our gratitude to [@ZhengPeiRu21](https://github.com/ZhengPeiRu21) and [@celguar](https://github.com/celguar) for the continued efforts in maintaining the module.
+`mod-playerbots` is based on [ZhengPeiRu21/mod-playerbots](https://github.com/ZhengPeiRu21/mod-playerbots) and [celguar/mangosbot-bots](https://github.com/celguar/mangosbot-bots). We extend our gratitude to [@ZhengPeiRu21](https://github.com/ZhengPeiRu21) and [@celguar](https://github.com/celguar) for their continued efforts in maintaining the module.
Also, a thank you to the many contributors who've helped build this project:
diff --git a/apps/codestyle/codestyle-cpp.py b/apps/codestyle/codestyle-cpp.py
new file mode 100644
index 0000000000..72c2a88862
--- /dev/null
+++ b/apps/codestyle/codestyle-cpp.py
@@ -0,0 +1,263 @@
+import io
+import os
+import sys
+import re
+
+# Get the src directory of the project
+src_directory = os.path.join(os.getcwd(), 'src')
+
+# Global variables
+error_handler = False
+results = {
+ "Multiple blank lines check": "Passed",
+ "Trailing whitespace check": "Passed",
+ "GetCounter() check": "Passed",
+ "Misc codestyle check": "Passed",
+ "GetTypeId() check": "Passed",
+ "NpcFlagHelpers check": "Passed",
+ "ItemFlagHelpers check": "Passed",
+ "ItemTemplateFlagHelpers check": "Passed"
+}
+
+# Main function to parse all the files of the project
+def parsing_file(directory: str) -> None:
+ print("Starting AzerothCore CPP Codestyle check...")
+ print(" ")
+ print("Please read the C++ Code Standards for AzerothCore:")
+ print("https://www.azerothcore.org/wiki/cpp-code-standards")
+ print(" ")
+ for root, _, files in os.walk(directory):
+ for file in files:
+ if not file.endswith('.ico'): # Skip .ico files that cannot be read
+ file_path = os.path.join(root, file)
+ file_name = file
+ try:
+ with open(file_path, 'r', encoding='utf-8') as file:
+ multiple_blank_lines_check(file, file_path)
+ trailing_whitespace_check(file, file_path)
+ get_counter_check(file, file_path)
+ if not file_name.endswith('.cmake') and file_name != 'CMakeLists.txt':
+ misc_codestyle_check(file, file_path)
+ if file_name != 'Object.h':
+ get_typeid_check(file, file_path)
+ if file_name != 'Unit.h':
+ npcflags_helpers_check(file, file_path)
+ if file_name != 'Item.h':
+ itemflag_helpers_check(file, file_path)
+ if file_name != 'ItemTemplate.h':
+ itemtemplateflag_helpers_check(file, file_path)
+ except UnicodeDecodeError:
+ print(f"\nCould not decode file {file_path}")
+ sys.exit(1)
+ # Output the results
+ print("")
+ for check, result in results.items():
+ print(f"{check} : {result}")
+ if error_handler:
+ print("\nPlease fix the codestyle issues above.")
+ sys.exit(1)
+ else:
+ print(f"\nEverything looks good")
+
+# Codestyle patterns checking for multiple blank lines
+def multiple_blank_lines_check(file: io, file_path: str) -> None:
+ global error_handler, results
+ file.seek(0) # Reset file pointer to the beginning
+ check_failed = False
+ consecutive_blank_lines = 0
+ # Parse all the file
+ for line_number, line in enumerate(file, start = 1):
+ if line.strip() == '':
+ consecutive_blank_lines += 1
+ if consecutive_blank_lines > 1:
+ print(f"Multiple blank lines found in {file_path} at line {line_number - 1}")
+ check_failed = True
+ else:
+ consecutive_blank_lines = 0
+ # Additional check for the end of the file
+ if consecutive_blank_lines >= 1:
+ print(f"Multiple blank lines found at the end of: {file_path}")
+ check_failed = True
+ # Handle the script error and update the result output
+ if check_failed:
+ error_handler = True
+ results["Multiple blank lines check"] = "Failed"
+
+# Codestyle patterns checking for whitespace at the end of the lines
+def trailing_whitespace_check(file: io, file_path: str) -> None:
+ global error_handler, results
+ file.seek(0) # Reset file pointer to the beginning
+ # Parse all the file
+ for line_number, line in enumerate(file, start = 1):
+ if line.endswith(' \n'):
+ print(f"Trailing whitespace found: {file_path} at line {line_number}")
+ if not error_handler:
+ error_handler = True
+ results["Trailing whitespace check"] = "Failed"
+
+# Codestyle patterns checking for ObjectGuid::GetCounter()
+def get_counter_check(file: io, file_path: str) -> None:
+ global error_handler, results
+ file.seek(0) # Reset file pointer to the beginning
+ # Parse all the file
+ for line_number, line in enumerate(file, start = 1):
+ if 'ObjectGuid::GetCounter()' in line:
+ print(f"Please use ObjectGuid::ToString().c_str() instead ObjectGuid::GetCounter(): {file_path} at line {line_number}")
+ if not error_handler:
+ error_handler = True
+ results["GetCounter() check"] = "Failed"
+
+# Codestyle patterns checking for GetTypeId()
+def get_typeid_check(file: io, file_path: str) -> None:
+ global error_handler, results
+ file.seek(0) # Reset file pointer to the beginning
+ check_failed = False
+ # Parse all the file
+ for line_number, line in enumerate(file, start = 1):
+ if 'GetTypeId() == TYPEID_ITEM' in line or 'GetTypeId() != TYPEID_ITEM' in line:
+ print(f"Please use IsItem() instead of GetTypeId(): {file_path} at line {line_number}")
+ check_failed = True
+ if 'GetTypeId() == TYPEID_UNIT' in line or 'GetTypeId() != TYPEID_UNIT' in line:
+ print(f"Please use IsCreature() instead of GetTypeId(): {file_path} at line {line_number}")
+ check_failed = True
+ if 'GetTypeId() == TYPEID_PLAYER' in line or 'GetTypeId() != TYPEID_PLAYER' in line:
+ print(f"Please use IsPlayer() instead of GetTypeId(): {file_path} at line {line_number}")
+ check_failed = True
+ if 'GetTypeId() == TYPEID_GAMEOBJECT' in line or 'GetTypeId() != TYPEID_GAMEOBJECT' in line:
+ print(f"Please use IsGameObject() instead of GetTypeId(): {file_path} at line {line_number}")
+ check_failed = True
+ if 'GetTypeId() == TYPEID_DYNOBJECT' in line or 'GetTypeId() != TYPEID_DYNOBJECT' in line:
+ print(f"Please use IsDynamicObject() instead of GetTypeId(): {file_path} at line {line_number}")
+ check_failed = True
+ # Handle the script error and update the result output
+ if check_failed:
+ error_handler = True
+ results["GetTypeId() check"] = "Failed"
+
+# Codestyle patterns checking for NpcFlag helpers
+def npcflags_helpers_check(file: io, file_path: str) -> None:
+ global error_handler, results
+ file.seek(0) # Reset file pointer to the beginning
+ check_failed = False
+ # Parse all the file
+ for line_number, line in enumerate(file, start = 1):
+ if 'GetUInt32Value(UNIT_NPC_FLAGS)' in line:
+ print(
+ f"Please use GetNpcFlags() instead of GetUInt32Value(UNIT_NPC_FLAGS): {file_path} at line {line_number}")
+ check_failed = True
+ if 'HasFlag(UNIT_NPC_FLAGS,' in line:
+ print(
+ f"Please use HasNpcFlag() instead of HasFlag(UNIT_NPC_FLAGS, ...): {file_path} at line {line_number}")
+ check_failed = True
+ if 'SetUInt32Value(UNIT_NPC_FLAGS,' in line:
+ print(
+ f"Please use ReplaceAllNpcFlags() instead of SetUInt32Value(UNIT_NPC_FLAGS, ...): {file_path} at line {line_number}")
+ check_failed = True
+ if 'SetFlag(UNIT_NPC_FLAGS,' in line:
+ print(
+ f"Please use SetNpcFlag() instead of SetFlag(UNIT_NPC_FLAGS, ...): {file_path} at line {line_number}")
+ check_failed = True
+ if 'RemoveFlag(UNIT_NPC_FLAGS,' in line:
+ print(
+ f"Please use RemoveNpcFlag() instead of RemoveFlag(UNIT_NPC_FLAGS, ...): {file_path} at line {line_number}")
+ check_failed = True
+ # Handle the script error and update the result output
+ if check_failed:
+ error_handler = True
+ results["NpcFlagHelpers check"] = "Failed"
+
+# Codestyle patterns checking for ItemFlag helpers
+def itemflag_helpers_check(file: io, file_path: str) -> None:
+ global error_handler, results
+ file.seek(0) # Reset file pointer to the beginning
+ check_failed = False
+ # Parse all the file
+ for line_number, line in enumerate(file, start = 1):
+ if 'HasFlag(ITEM_FIELD_FLAGS, ITEM_FIELD_FLAG_REFUNDABLE)' in line:
+ print(
+ f"Please use IsRefundable() instead of HasFlag(ITEM_FIELD_FLAGS, ITEM_FIELD_FLAG_REFUNDABLE): {file_path} at line {line_number}")
+ check_failed = True
+ if 'HasFlag(ITEM_FIELD_FLAGS, ITEM_FIELD_FLAG_BOP_TRADEABLE)' in line:
+ print(
+ f"Please use IsBOPTradable() instead of HasFlag(ITEM_FIELD_FLAGS, ITEM_FIELD_FLAG_BOP_TRADEABLE): {file_path} at line {line_number}")
+ check_failed = True
+ if 'HasFlag(ITEM_FIELD_FLAGS, ITEM_FIELD_FLAG_WRAPPED)' in line:
+ print(
+ f"Please use IsWrapped() instead of HasFlag(ITEM_FIELD_FLAGS, ITEM_FIELD_FLAG_WRAPPED): {file_path} at line {line_number}")
+ check_failed = True
+ # Handle the script error and update the result output
+ if check_failed:
+ error_handler = True
+ results["ItemFlagHelpers check"] = "Failed"
+
+# Codestyle patterns checking for ItemTemplate helpers
+def itemtemplateflag_helpers_check(file: io, file_path: str) -> None:
+ global error_handler, results
+ file.seek(0) # Reset file pointer to the beginning
+ check_failed = False
+ # Parse all the file
+ for line_number, line in enumerate(file, start = 1):
+ if 'Flags & ITEM_FLAG' in line:
+ print(
+ f"Please use HasFlag(ItemFlag) instead of 'Flags & ITEM_FLAG_': {file_path} at line {line_number}")
+ check_failed = True
+ if 'Flags2 & ITEM_FLAG2' in line:
+ print(
+ f"Please use HasFlag2(ItemFlag2) instead of 'Flags2 & ITEM_FLAG2_': {file_path} at line {line_number}")
+ check_failed = True
+ if 'FlagsCu & ITEM_FLAGS_CU' in line:
+ print(
+ f"Please use HasFlagCu(ItemFlagsCustom) instead of 'FlagsCu & ITEM_FLAGS_CU_': {file_path} at line {line_number}")
+ check_failed = True
+ # Handle the script error and update the result output
+ if check_failed:
+ error_handler = True
+ results["ItemTemplateFlagHelpers check"] = "Failed"
+
+# Codestyle patterns checking for various codestyle issues
+def misc_codestyle_check(file: io, file_path: str) -> None:
+ global error_handler, results
+ file.seek(0) # Reset file pointer to the beginning
+ check_failed = False
+
+ # used to check for "if/else (...) {" "} else" ignores "if/else (...) {...}" "#define ... if/else (...) {"
+ ifelse_curlyregex = r"^[^#define].*\s+(if|else)(\s*\(.*\))?\s*{[^}]*$|}\s*else(\s*{[^}]*$)"
+ # used to catch double semicolons ";;" ignores "(;;)"
+ double_semiregex = r"(?.> aber es ist WoW!' WHERE `id`=899;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='wenn ich alles Essen im Spiel esse, werd ich dann unbesiegbar' WHERE `id`=900;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Also, ich werfe mein Pet einfach in jeden Bosskampf und drücke beim würfeln immer auf Gier, das sind die Hunter-Regeln.' WHERE `id`=901;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='kann man sterben, wenn man schon tot ist? Ich frage für nen Geist...' WHERE `id`=902;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='weiß jemand, wo das legendäre Schwert ist? hab schon 5 Minuten gesucht' WHERE `id`=903;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Man sagte mir, hier gibts 100.000 Gold, wo muss ich hin?' WHERE `id`=904;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='ich spiel das hier wie ich deine Mom letzte Nacht genommen hab - mit Geschrei und einem ruhmreichem Ende!' WHERE `id`=905;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='ab wann wirds Spaß, oder ist alles nur für immer Grind' WHERE `id`=906;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='ich frage ständig nach dem Weg, aber sie schicken mich immer irgendwo hin, ist das normal?' WHERE `id`=907;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='hab gehört, wenn du ALT+F4 drückst, kriegst du 100.000 Gold - Der Trick ist, vorher nen roten NPC anzugreifen' WHERE `id`=908;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='warum sieht mein Char immer so verwirrt aus, bin ich schuld?' WHERE `id`=909;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='hey, deine Mom meinte, du sollst jetzt ins Bett!' WHERE `id`=910;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Warcraft ist ein Grind - genau wie deine Mom neulich, hat sogar Abo!' WHERE `id`=911;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='stimmt es, dass Chuck Norris mal gelevelt hat, ohne nen Knopf zu drücken' WHERE `id`=912;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Chuck Norris braucht kein Mount, der Boden bewegt freiwillig sich unter ihm' WHERE `id`=913;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='wenn Chuck Norris nen Raid betritt, gibt der Boss einfach auf' WHERE `id`=914;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Chuck Norris nutzt keine Fähigkeiten, er guckt nur - und die Gegner sterben' WHERE `id`=915;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Chuck Norris braucht keine Heilung, seine Feinde heilen ihn aus Respekt' WHERE `id`=916;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Chuck Norris kann nen Raid solo... ohne Gear... und AFK' WHERE `id`=917;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Chuck Norris weicht nicht aus, das Spiel weicht ihm aus' WHERE `id`=918;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Chuck Norris nutzte mal ne Lowlevel-Waffe - das Spiel gab ihm den besten Loot' WHERE `id`=919;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='wenn Chuck Norris eine Ini betritt, landet der Loot automatisch in seinem Inventar' WHERE `id`=920;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='was ist Wilma' WHERE `id`=921;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Bist du aus Bayern?' WHERE `id`=922;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Wilma lecken' WHERE `id`=923;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Dann leck mir an den Eiern.' WHERE `id`=924;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='ICH FRESS NEN ARSCH' WHERE `id`=925;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='ich will mir %random_inventory_item_link in den Arsch schieben' WHERE `id`=926;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='ich will dir %random_inventory_item_link in den Arsch schieben' WHERE `id`=927;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Darnarschloch' WHERE `id`=928;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Du leidest an mehr Bugs als das Spiel selbst!' WHERE `id`=929;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Du hast Chefkochs salzige Schokobällchen im Mund!' WHERE `id`=930;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='cooler Ständer, Bro' WHERE `id`=931;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='hab alles probiert, am Ende hats ERP gerichtet' WHERE `id`=933;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='ich will in %zone_name bumsen' WHERE `id`=934;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='suche weiblichen Gnom mit Gorilla-Pet für ERP in %zone_name' WHERE `id`=935;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='ein Arschloch versteh ich, aber nen Perversen?' WHERE `id`=936;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Kein Gyat in %zone_name, nur Gesichtseintopf so weit das Auge reicht.' WHERE `id`=937;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='ich kill alle Tiere in %zone_name. Scheiß auf Tiere und die PETA!!!' WHERE `id`=938;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Nur gut, dass ich 3 Beine hab' WHERE `id`=939;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Chill, ich bin einfach grad komplett in meinem Film.' WHERE `id`=940;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Finger im Po Mexiko' WHERE `id`=941;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Das hast du irgendwie vergeigt, beeindruckend' WHERE `id`=942;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='das könnte ich blind machen, muss ich aber nicht' WHERE `id`=943;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='sicher, dass du weißt, wie man das Spiel spielt?' WHERE `id`=944;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='als würdest du absichtlich verlieren' WHERE `id`=945;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='hab schon bessere Plays von Level-1-Chars gesehen' WHERE `id`=946;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='du bist hier wie ein Speedbump' WHERE `id`=947;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='vielleicht suchst du dir lieber ein anderes Hobby' WHERE `id`=948;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='dein Gameplay ist wie Farbe beim Trocknen zusehen' WHERE `id`=949;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='mein Twink könnte dich da durch carrien' WHERE `id`=950;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='trollst du uns, oder bist du ernsthaft so?' WHERE `id`=951;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Ich glaub, das Gegnerteam läuft besser, wenn du bei uns bist' WHERE `id`=952;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='spiel vielleicht mal das Spiel statt nur die Landschaft zu bestaunen' WHERE `id`=953;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='ich glaube, du hast da jede einzelne Fähigkeit verfehlt' WHERE `id`=954;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='bist du lost oder stellst du dich nur dumm?' WHERE `id`=955;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Level-1-Chars nehmen weniger Schaden als das' WHERE `id`=956;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='das war für uns beide peinlich' WHERE `id`=957;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Hab schon besseres Teamplay in nem Solo-Game gesehen' WHERE `id`=958;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='ich stell mich mal hinten hin und schau dir beim Failen zu' WHERE `id`=959;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='dachtest du wirklich, das wäre ne gute Idee?' WHERE `id`=960;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='kaum zu glauben, dass du diese simple Aufgabe verkackt hast' WHERE `id`=961;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='bist du hier, um zu helfen, oder nur um Zeit zu verschwenden?' WHERE `id`=962;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='gut, dass ich da bin, um das Team zu schützen' WHERE `id`=963;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='ich schwöre, du machst es schwerer als nötig' WHERE `id`=964;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='wie schaffst du es, die simpelsten Sachen zu failen?' WHERE `id`=965;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='vielleicht mal lieber nur zuschauen, statt das zu tun was du spielen nennst' WHERE `id`=966;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='du könntest dich wenigstens bemühen, so zu tun, als wärst du gut' WHERE `id`=967;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='mach so weiter und wir sitzen hier den ganzen Tag' WHERE `id`=968;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='ehrlich, das war die schlechteste Entscheidung ever' WHERE `id`=969;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='ich glaub, dieses Spiel ist nix für dich' WHERE `id`=970;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='was sollte dieser Move?' WHERE `id`=971;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='du bist ne Last fürs Team' WHERE `id`=972;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='du denkst echt, du bist ein Pro, was?' WHERE `id`=973;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='vielleicht einfach quitten und uns allen den Stress sparen' WHERE `id`=974;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='%prefix %random_taken_quest_or_item_link' WHERE `id`=975;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='%prefix %random_inventory_item_link' WHERE `id`=976;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='%thunderfury_link' WHERE `id`=977;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='%thunderfury_link%thunderfury_link' WHERE `id`=978;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='%thunderfury_link%thunderfury_link%thunderfury_link' WHERE `id`=979;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='ich glaube, ich hab gerade %thunderfury_link gehört' WHERE `id`=980;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='ich glaub, ich habe %thunderfury_link gehört' WHERE `id`=981;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='ich hab definitiv %thunderfury_link gehört' WHERE `id`=982;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='kein Plan, aber ich bin ziemlich sicher, das ich %thunderfury_link gehört habe' WHERE `id`=983;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='hast du gerade %thunderfury_link gesagt' WHERE `id`=984;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='hat jemand %thunderfury_link gesagt' WHERE `id`=985;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='hat jemand %thunderfury_link gesagt?' WHERE `id`=986;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='jemand hat %thunderfury_link gesagt' WHERE `id`=987;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='%thunderfury_link kommt aus dem Schrank' WHERE `id`=988;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='ich schwöre, es war %thunderfury_link, könnte aber auch %thunderfury_link gewesen sein' WHERE `id`=989;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='warum %thunderfury_link nutzen, wenn %thunderfury_link offensichtlich viel stärker ist' WHERE `id`=990;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='hab ich gerade %thunderfury_link gehört?' WHERE `id`=991;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='niemals... hör ich da echt %thunderfury_link?' WHERE `id`=992;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='%thunderfury_link? klingt nach was, das nur Legenden führen!' WHERE `id`=993;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='ich spüre die Macht von %thunderfury_link in der Luft!' WHERE `id`=994;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='%thunderfury_link ist der *echte* MVP' WHERE `id`=995;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='kann mir jemand ne %thunderfury_link besorgen? frage für einen Freund... vielleicht zwei!' WHERE `id`=996;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='hat %thunderfury_link da gerade was *gesmitet*? ich schwöre, der Boden hat gewackelt' WHERE `id`=997;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='%thunderfury_link auf dem Schlachtfeld... Das ist purer Flex' WHERE `id`=998;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='ich *glaube*, ich hab %thunderfury_link gehört... oder war das nur ein Mythos?' WHERE `id`=999;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='hab ich gerade jemanden mit %thunderfury_link gesehen?!' WHERE `id`=1000;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Bin zu 99% sicher, das war %thunderfury_link. Zu 1% wars vielleicht nur ein random NPC.' WHERE `id`=1002;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='%thunderfury_link in Aktion! Wer braucht ne Armee, mit so einer Power?' WHERE `id`=1003;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Hab gehört, %thunderfury_link lockt alle Jungs an.' WHERE `id`=1004;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Warum überhaupt %thunderfury_link nutzen, wenn %thunderfury_link klar die bessere Option ist?' WHERE `id`=1005;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Bin das nur ich, oder hat %thunderfury_link nen passiven „Trash-Talk“-Effekt?' WHERE `id`=1006;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Dachte, ich hätte %thunderfury_link gehört, war aber nur der Klang reiner Awesomeness.' WHERE `id`=1007;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Oh, %thunderfury_link... Wo *warst* du mein ganzes Leben?' WHERE `id`=1008;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Hat jemand %thunderfury_link gesagt? Ich glaub, ich hol mir mal meine.' WHERE `id`=1009;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Das war definitiv der Sound von %thunderfury_link! Ich spür die Epicness.' WHERE `id`=1010;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Geht das nur mir so, oder lässt %thunderfury_link alle anderen *schwach aussehen*?' WHERE `id`=1011;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Wie man so sagt... je lauter %thunderfury_link, desto größer das Recht zu prahlen!' WHERE `id`=1012;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='VK: %item_formatted_link für %cost_gold.' WHERE `id`=1013;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Will wer %item_formatted_link? Nur %cost_gold.' WHERE `id`=1015;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Lächerlicher Preis: %cost_gold für %item_formatted_link!' WHERE `id`=1019;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Will %item_formatted_link für %cost_gold verkaufen.' WHERE `id`=1020;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='%item_formatted_link ist Wertvoll, aber ich würd es für %cost_gold verkaufen.' WHERE `id`=1024;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Billiger als %cost_gold kriegst du %item_formatted_link nicht!' WHERE `id`=1025;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Brauche mehr als %item_formatted_link!' WHERE `id`=1026;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Habe %item_formatted_link und brauche mehr.' WHERE `id`=1027;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Habe %item_formatted_link. Wer kauft für %cost_gold?' WHERE `id`=1028;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Wie wärs mit %item_formatted_link? Für %cost_gold.' WHERE `id`=1030;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Wer meinte, ich bin ein Bastard? %item_formatted_link für %cost_gold ist ein guter Preis!' WHERE `id`=1031;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Verkaufe %item_formatted_link? Nur %cost_gold.' WHERE `id`=1032;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='LFG zum Farmen. %item_formatted_link gibts von mir noch für %cost_gold.' WHERE `id`=1033;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Heute fast alles verkauft. %item_formatted_link hab ich noch für %cost_gold.' WHERE `id`=1034;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Wozu Handelschat? Klar, um %item_formatted_link für %cost_gold zu verkaufen.' WHERE `id`=1035;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Kann jemand den Preis %cost_gold für %item_formatted_link unterbieten?' WHERE `id`=1036;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Wollt ihr den Handelschat stoppen? Kauft einfach %item_formatted_link! Für %cost_gold!' WHERE `id`=1037;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Alle spammen im Handelschat. Ich auch - %cost_gold für %item_formatted_link!' WHERE `id`=1038;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Taugt %item_formatted_link was? Verkaufe es für %cost_gold.' WHERE `id`=1039;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Hab %item_formatted_link, verkaufe an dich für %cost_gold.' WHERE `id`=1040;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Gestern nix geschafft, aber %item_formatted_link bekommen. Verkaufe für %cost_gold.' WHERE `id`=1041;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Gestern gefarmt und %item_formatted_link gezogen. Will jemand für %cost_gold kaufen?' WHERE `id`=1042;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Gestern %item_formatted_link gekauft. Brauchts wer für %cost_gold?' WHERE `id`=1043;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Wer hatte %item_formatted_link gesucht? Preis bleibt - %cost_gold.' WHERE `id`=1044;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Hab immer noch %item_formatted_link. Kauft wer für %cost_gold?' WHERE `id`=1045;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Früher war ich besser bei Kasse. Jetzt verkauf ich %item_formatted_link für %cost_gold.' WHERE `id`=1046;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Ich Wünschte, ich hätte mehr als %item_formatted_link. Kaufen könnt ihrs trotzdem für %cost_gold.' WHERE `id`=1047;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Wozu ist euer Gold gut? Um mein %item_formatted_link für %cost_gold zu kaufen.' WHERE `id`=1048;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Gönnt mir etwas Gold. Kauft %item_formatted_link für %cost_gold.' WHERE `id`=1049;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Sind %cost_gold ein guter Preis für %item_formatted_link?' WHERE `id`=1050;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Hab gestern erst %item_formatted_link gekauft, brauch es aber nicht mehr. Will wer für %cost_gold?' WHERE `id`=1051;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Stell %item_formatted_link gleich ins AH, aber ihr könnts jetzt günstiger haben: nur %cost_gold.' WHERE `id`=1052;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Warum zum #!@ hab ich %item_formatted_link gekauft? Brauchts wer für %cost_gold?' WHERE `id`=1053;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='VK: %item_formatted_link für %cost_gold.' WHERE `id`=1054;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Will wer %item_formatted_link? Nur %cost_gold.' WHERE `id`=1056;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='VK: %item_formatted_link für %cost_gold. flüster mir bei Interesse.' WHERE `id`=1060;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Muss %item_formatted_link loswerden, %cost_gold oder bestes Angebot.' WHERE `id`=1061;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='%item_formatted_link für %cost_gold verfügbar. Schlagt zu!' WHERE `id`=1062;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Habe %item_formatted_link, will %cost_gold.' WHERE `id`=1063;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Verkaufe %item_formatted_link, nur %cost_gold.' WHERE `id`=1064;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Will jemand %item_formatted_link für %cost_gold? flüster mir!' WHERE `id`=1065;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Verkaufe %item_formatted_link für %cost_gold, greift zu solange es geht!' WHERE `id`=1066;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='%item_formatted_link für %cost_gold, schnell sein bevor es weg ist!' WHERE `id`=1067;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Verkaufe %item_formatted_link für %cost_gold, wer zuerst kommt wird auch zuerst bedient!' WHERE `id`=1069;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Nur %cost_gold für %item_formatted_link, nur für kurze Zeit!' WHERE `id`=1070;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='%item_formatted_link für %cost_gold verfügbar, meldet euch wenn ihrs braucht!' WHERE `id`=1071;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Interesse an %item_formatted_link für %cost_gold?' WHERE `id`=1072;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Verkaufe %item_formatted_link für %cost_gold, muss meine Taschen leeren.' WHERE `id`=1073;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Hol dir %item_formatted_link für %cost_gold, Top-Deal!' WHERE `id`=1074;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='%item_formatted_link für %cost_gold, greift zu solange der Vorrat reicht!' WHERE `id`=1075;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Verkaufe %item_formatted_link für %cost_gold, nicht verpassen!' WHERE `id`=1076;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Nur %cost_gold für %item_formatted_link, flüster mir für Details!' WHERE `id`=1077;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='%item_formatted_link gibts für %cost_gold, lasst uns handeln!' WHERE `id`=1078;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Verkaufe %item_formatted_link für %cost_gold, flüster mir für Infos.' WHERE `id`=1079;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Will %item_formatted_link verkaufen, für %cost_gold gehört es dir!' WHERE `id`=1080;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Verkaufe %item_formatted_link, nur %cost_gold.' WHERE `id`=1081;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Hab %item_formatted_link für %cost_gold, machen wir nen Deal!' WHERE `id`=1082;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Verkaufe %item_formatted_link, für %cost_gold nimmst du es mit!' WHERE `id`=1083;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='VK: %item_formatted_link für %cost_gold, Interesse?' WHERE `id`=1084;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Muss %item_formatted_link schnell loswerden, %cost_gold.' WHERE `id`=1085;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Verkaufe %item_formatted_link für %cost_gold, bester Preis weit und breit!' WHERE `id`=1086;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='%item_formatted_link für %cost_gold, machen wirs fix!' WHERE `id`=1088;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Verkaufe %item_formatted_link für %cost_gold, schnappt zu bevor alles weg ist!' WHERE `id`=1089;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Willst %item_formatted_link? Für %cost_gold kriegst du eins!' WHERE `id`=1090;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Ich habe auch %quest_links' WHERE `id`=1093;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Ich habe auch %quest_links, bin gerade in %zone_name' WHERE `id`=1094;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='%other_name, ich habe auch %quest_links' WHERE `id`=1095;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='%other_name, ich habe auch %quest_links, bin gerade in %zone_name' WHERE `id`=1096;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Bin bereit für %quest_links, bin gerade in %zone_name' WHERE `id`=1097;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Bin bereit für %quest_links, bin %my_role' WHERE `id`=1098;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='%other_name, bin bereit für %quest_links, bin gerade in %zone_name' WHERE `id`=1099;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='%other_name, bin bereit für %quest_links, bin %my_role' WHERE `id`=1100;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Braucht wer %quest_links? Bin in %zone_name.' WHERE `id`=1101;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Suche mehr %quest_links in %zone_name.' WHERE `id`=1102;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Will jemand %quest_links mit mir in %zone_name machen?' WHERE `id`=1104;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Habe %quest_links, suche Gruppe in %zone_name.' WHERE `id`=1105;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='%my_role sucht Gruppe, um %quest_links in %zone_name zu erledigen.' WHERE `id`=1108;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Ich brauche %quest_links, ist jemand in %zone_name frei?' WHERE `id`=1109;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Mach %quest_links in %zone_name, brauche mehr Hilfe.' WHERE `id`=1111;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Gibt’s %my_role mit Interesse an %quest_links in %zone_name?' WHERE `id`=1112;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Hilfe benötigt für %quest_links in %zone_name, mir ist langweilig.' WHERE `id`=1113;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Habe %quest_links, %my_role in %zone_name, wer ist dabei?' WHERE `id`=1114;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Macht grad jemand %quest_links? Bin in %zone_name.' WHERE `id`=1116;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='%quest_links offen in %zone_name, wer möchte?' WHERE `id`=1117;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Bereit für %quest_links in %zone_name, suche Gruppe.' WHERE `id`=1118;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Brauche %quest_links und Gesellschaft, jemand in %zone_name?' WHERE `id`=1119;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Wer kommt mit mir nach %zone_name für %quest_links?' WHERE `id`=1120;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Irgend ein %my_role frei für %quest_links in %zone_name?' WHERE `id`=1121;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Habe %quest_links und bin %my_role, brauche mehr Leute in %zone_name.' WHERE `id`=1122;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Bin %my_role und habe %quest_links, suche Gruppe in %zone_name.' WHERE `id`=1124;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Brauche Hilfe bei %quest_links in %zone_name, ist ein %my_role frei?' WHERE `id`=1125;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Hat ein %my_role Lust, %quest_links mit mir in %zone_name zu machen?' WHERE `id`=1126;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Lasst uns %quest_links zusammen in %zone_name abschließen.' WHERE `id`=1127;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Bin in %zone_name und habe %quest_links, wer will mit?' WHERE `id`=1128;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Suche mehr %my_role, um %quest_links in %zone_name abzuschließen.' WHERE `id`=1129;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Habe %quest_links und brauche %my_role in %zone_name.' WHERE `id`=1130;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Wer hat Bock auf %quest_links? Ich bin %my_role in %zone_name.' WHERE `id`=1131;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Suche Gruppe für %quest_links in %zone_name, %my_role gebraucht.' WHERE `id`=1132;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Braucht wer Hilfe bei %quest_links in %zone_name? Ich bin %my_role.' WHERE `id`=1133;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Habe %quest_links offen, brauche %my_role in %zone_name.' WHERE `id`=1134;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Bin in %zone_name und suche Hilfe für %quest_links, wer ist dabei?' WHERE `id`=1135;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Suche Gruppe, um %quest_links in %zone_name fertig zu machen.' WHERE `id`=1136;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Sucht jemand %quest_links in %zone_name? Ich bin %my_role.' WHERE `id`=1137;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Machen wir %quest_links zusammen! %zone_name wartet.' WHERE `id`=1138;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Brauche Gruppe für %quest_links, %zone_name - wer hat Interesse?' WHERE `id`=1139;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Wer will für %quest_links dazukommen? Bin in %zone_name.' WHERE `id`=1140;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Bin in %zone_name, suche Leute zum Abschließen von %quest_links.' WHERE `id`=1141;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Brauche Hilfe bei %quest_links in %zone_name, ein %my_role da?' WHERE `id`=1142;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Suche Gruppe, um %quest_links zu beenden, %zone_name da steppt der Bär.' WHERE `id`=1143;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Will jemand bei %quest_links in %zone_name helfen? Ich bin %my_role.' WHERE `id`=1144;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Suche %my_role, um %quest_links in %zone_name mitzumachen.' WHERE `id`=1145;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Hab %quest_links, %my_role für %zone_name gesucht.' WHERE `id`=1146;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Will %quest_links in %zone_name fertig bekommen, brauche mehr Leute.' WHERE `id`=1147;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Brauche Hilfe bei %quest_links, wer ist in %zone_name unterwegs?' WHERE `id`=1148;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Brauche mehr Leute für %quest_links, %zone_name.' WHERE `id`=1149;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Suche Gruppe in %zone_name, um %quest_links abzuschließen.' WHERE `id`=1150;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Wer will %quest_links in %zone_name machen? Bin startklar.' WHERE `id`=1151;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Will wer für %quest_links dazustoßen? Ich bin %my_role in %zone_name.' WHERE `id`=1152;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Suche %my_role für %quest_links in %zone_name.' WHERE `id`=1153;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Bin in %zone_name, braucht wer Hilfe bei %quest_links?' WHERE `id`=1154;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Brauche mehr für %quest_links in %zone_name, bin allein nicht stark genug?' WHERE `id`=1155;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Brauche Hilfe bei %quest_links in %zone_name, wer hat Bock?' WHERE `id`=1156;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Suche mehr Leute, um %quest_links zu beenden, %zone_name.' WHERE `id`=1157;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Hey, bin bei %quest_links dabei' WHERE `id`=1158;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Hey, ich habe auch %quest_links' WHERE `id`=1160;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Hey %other_name, bin bei %quest_links dabei' WHERE `id`=1161;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Hey %other_name, ich könnte %quest_links mit dir machen' WHERE `id`=1162;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Bock, für %quest_links eine Gruppe zu bilden?' WHERE `id`=1164;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Bin bereit für %quest_links, bin gerade in %zone_name' WHERE `id`=1165;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Bin bereit für %quest_links, bin %my_role' WHERE `id`=1166;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Hey, ich hab Bock auf %quest_links' WHERE `id`=1167;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Ich kann bei %quest_links helfen, wenn ihr wollt' WHERE `id`=1168;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Lasst uns %quest_links zusammen machen!' WHERE `id`=1169;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Ich hab auch %quest_links offen' WHERE `id`=1170;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Bin für %quest_links verfügbar, wenn ihr wollt' WHERE `id`=1171;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Bin bei %quest_links dabei, sagt Bescheid' WHERE `id`=1172;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Sucht wer %quest_links? Bin in %zone_name' WHERE `id`=1173;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Hey, ich brauche auch %quest_links, lets go' WHERE `id`=1174;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Hab %quest_links, will wer mit?' WHERE `id`=1175;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Könnte %quest_links brauchen, machen wirs' WHERE `id`=1176;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Hey, willst du für %quest_links dazukommen?' WHERE `id`=1177;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Ich kann bei %quest_links helfen, wenn ihr wollt' WHERE `id`=1178;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Hey %other_name, Bock auf %quest_links?' WHERE `id`=1179;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Willst du für %quest_links gruppen, %other_name?' WHERE `id`=1180;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Lass %quest_links zusammen machen, %other_name' WHERE `id`=1181;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Ich bin %my_role und ready für %quest_links' WHERE `id`=1182;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Kann für %quest_links joinen, %my_role hier' WHERE `id`=1183;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Bin bereit für %quest_links, %my_role!' WHERE `id`=1184;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Suche %my_role für %quest_links' WHERE `id`=1185;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Braucht wer Hilfe bei %quest_links?' WHERE `id`=1186;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Wer ist noch bei %quest_links dabei?' WHERE `id`=1187;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Jemand bereit für %quest_links in %zone_name?' WHERE `id`=1188;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Hab %quest_links, %my_role unterwegs' WHERE `id`=1189;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Ich brauch %quest_links auch, wer ist dabei?' WHERE `id`=1190;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Grinde %quest_links, wer hilft?' WHERE `id`=1191;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Bin bereit für %quest_links, noch wer?' WHERE `id`=1192;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Kann jemand für %quest_links dazukommen?' WHERE `id`=1193;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Suche Hilfe bei %quest_links, %my_role hier' WHERE `id`=1194;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Ich kann bei %quest_links aushelfen, braucht mich wer?' WHERE `id`=1195;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Macht noch wer %quest_links? Los gehts' WHERE `id`=1196;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Braucht wer Hilfe bei %quest_links? %my_role hier' WHERE `id`=1197;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Wer hat Bock auf %quest_links in %zone_name?' WHERE `id`=1198;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Kann für %quest_links joinen, wenn ihr wollt' WHERE `id`=1199;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Suche einen %my_role für %quest_links' WHERE `id`=1200;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Ist ein %my_role für %quest_links am Start?' WHERE `id`=1201;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Ich habe %quest_links, will wer mit?' WHERE `id`=1202;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Hey %other_name, Bock auf %quest_links?' WHERE `id`=1203;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Lass uns für %quest_links gruppen, %other_name' WHERE `id`=1204;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Ich brauche %quest_links, wer macht mit?' WHERE `id`=1205;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Ich brauche auch %quest_links, ist noch jemand da?' WHERE `id`=1206;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Suche %quest_links in %zone_name, wer ist dabei?' WHERE `id`=1207;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Ist jemand frei für %quest_links?' WHERE `id`=1208;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Hey, ich könnte bei %quest_links dazustoßen!' WHERE `id`=1209;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Ich habe auch %quest_links, lass uns gruppen' WHERE `id`=1210;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Ich habe %quest_links zu erledigen, willst du mit?' WHERE `id`=1211;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Ist ein %my_role für %quest_links in %zone_name frei?' WHERE `id`=1212;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Lass uns %quest_links zusammen abschließen, %other_name' WHERE `id`=1213;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Ich bin bei %quest_links dabei, will noch wer mit?' WHERE `id`=1214;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Wer macht noch %quest_links? Ich bin dabei' WHERE `id`=1215;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Ich habe %quest_links in %zone_name, braucht jemand Hilfe?' WHERE `id`=1216;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='%other_name, könnte dir %formatted_item_links verkaufen' WHERE `id`=1217;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Könnte eventuell %formatted_item_links verkaufen' WHERE `id`=1218;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Denke, ich könnte %formatted_item_links verkaufen' WHERE `id`=1219;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='%other_name, könnte eventuell %formatted_item_links verkaufen' WHERE `id`=1220;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='%other_name, ich denke, ich könnte %formatted_item_links verkaufen' WHERE `id`=1221;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Ich könnte dir %formatted_item_links verkaufen' WHERE `id`=1222;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Hey, habe %formatted_item_links zu verkaufen' WHERE `id`=1223;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Hey, könnte eventuell %formatted_item_links verkaufen' WHERE `id`=1224;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Ich könnte dir %formatted_item_links verkaufen' WHERE `id`=1225;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Hey, habe %formatted_item_links zu verkaufen' WHERE `id`=1226;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Hey, ich könnte eventuell %formatted_item_links verkaufen' WHERE `id`=1227;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Ich habe %formatted_item_links, Interesse?' WHERE `id`=1228;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Will %formatted_item_links verkaufen, was bietest du?' WHERE `id`=1229;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Ich kann dir %formatted_item_links zu einem fairem Preis verkaufen' WHERE `id`=1230;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Ich habe %formatted_item_links auf Lager, was zahlst du?' WHERE `id`=1231;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Verkaufe %formatted_item_links für %cost_gold, sag Bescheid bei Interesse' WHERE `id`=1232;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Habe %formatted_item_links zu verkaufen, was zahlst du?' WHERE `id`=1233;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Ich habe %formatted_item_links, wie klingt %cost_gold für dich?' WHERE `id`=1234;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Verkaufe %formatted_item_links für %cost_gold, flüster mir bei Interesse' WHERE `id`=1235;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Ich habe %formatted_item_links, meld dich bei Interesse' WHERE `id`=1236;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Gebe %formatted_item_links ab, wenn das Angebot passt' WHERE `id`=1237;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Will %formatted_item_links loswerden, flüster mir' WHERE `id`=1238;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Habe %formatted_item_links für %cost_gold, kaufst du?' WHERE `id`=1239;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Verkaufe %formatted_item_links, lass uns handeln' WHERE `id`=1240;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Hey, habe %formatted_item_links für %cost_gold' WHERE `id`=1241;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Kann dich mit %formatted_item_links versorgen, nenn deinen Preis' WHERE `id`=1242;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Ich habe %formatted_item_links verfügbar, sag Bescheid bei Interesse' WHERE `id`=1243;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Verkaufe %formatted_item_links, machen wir Business' WHERE `id`=1244;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Ich habe %formatted_item_links, macht mir ein Angebot' WHERE `id`=1245;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Ich habe %formatted_item_links, schreib mir, wenn du kaufen willst' WHERE `id`=1246;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Kann dir %formatted_item_links für %cost_gold anbieten' WHERE `id`=1247;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Ich habe %formatted_item_links zu verkaufen, schreib mir für den Preis' WHERE `id`=1248;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Verkaufe %formatted_item_links, greif zu solange es heiß ist' WHERE `id`=1249;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Verkaufe %formatted_item_links, nen besseren Deal findet ihr nicht' WHERE `id`=1250;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Ich habe %formatted_item_links zu verkaufen, was zahlst du?' WHERE `id`=1251;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Verkaufe %formatted_item_links, Preis auf Anfrage per flüstern' WHERE `id`=1252;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Interesse an %formatted_item_links? Ich verkaufe welche' WHERE `id`=1253;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Ich habe %formatted_item_links, PN für Preis' WHERE `id`=1254;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Verkaufe %formatted_item_links für %cost_gold, meldet euch' WHERE `id`=1255;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Verkaufe %formatted_item_links, macht mir ein Angebot' WHERE `id`=1256;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Habe %formatted_item_links, schreib mir für Details' WHERE `id`=1257;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Hey, habe %formatted_item_links, meldet euch bei Interesse' WHERE `id`=1258;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Verkaufe %formatted_item_links, machen wir nen Deal?' WHERE `id`=1259;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Verkaufe %formatted_item_links, sag Bescheid wenn du willst' WHERE `id`=1260;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Ich habe %formatted_item_links, ich mach dir nen guten Preis' WHERE `id`=1261;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Ich habe %formatted_item_links, mit gutem Angebot gehörts dir' WHERE `id`=1262;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Verkaufe %formatted_item_links, bin offen für Angebote' WHERE `id`=1263;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Ich habe %formatted_item_links, melde dich bei Interesse' WHERE `id`=1264;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Ich kann dir %formatted_item_links zu einem guten Preis verkaufen' WHERE `id`=1265;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Ich habe %formatted_item_links zu verkaufen, nehme alle Angebote an' WHERE `id`=1266;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Habe %formatted_item_links im Verkauf, flüster mir für Details' WHERE `id`=1267;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Habe %formatted_item_links im Verkauf, macht mir ein Angebot' WHERE `id`=1268;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Ich habe %formatted_item_links, was zahlt ihr?' WHERE `id`=1269;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Verkaufe %formatted_item_links, schreib mir für mehr Infos' WHERE `id`=1270;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Ich habe %formatted_item_links, sagt Bescheid bei Interesse' WHERE `id`=1271;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Verkaufe %formatted_item_links, lass uns über Zahlen reden' WHERE `id`=1272;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Ich kann dir %formatted_item_links verkaufen, was bietest du?' WHERE `id`=1273;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Hey, habe %formatted_item_links zu verkaufen, meldet euch bei Interesse' WHERE `id`=1274;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Ich habe %formatted_item_links, PN für den Preis' WHERE `id`=1275;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Verkaufe %formatted_item_links, bin offen für Angebote' WHERE `id`=1276;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Ich habe %formatted_item_links, schreibt mir einfach' WHERE `id`=1277;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Kann %formatted_item_links anbieten, sagt Bescheid bei Interesse' WHERE `id`=1278;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Verkaufe %formatted_item_links, bitte vernünftige Angebote' WHERE `id`=1279;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Ich habe %formatted_item_links, meldet euch für mehr Infos' WHERE `id`=1280;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Ich habe %formatted_item_links, macht mir ein Angebot' WHERE `id`=1281;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Verkaufe %formatted_item_links, schreibt mir bei Interesse' WHERE `id`=1282;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Habe %formatted_item_links zu verkaufen, lass uns handeln' WHERE `id`=1283;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Ich habe %formatted_item_links, sag Bescheid wenn du willst' WHERE `id`=1284;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Ich kann diese Quest nicht annehmen' WHERE `id`=1287;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Ich kann nicht mit dem Questgeber sprechen' WHERE `id`=1288;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Ich habe %quest bereits abgeschlossen' WHERE `id`=1289;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Ich habe %quest bereits' WHERE `id`=1290;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Ich kann %quest nicht annehmen' WHERE `id`=1291;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Ich kann %quest nicht annehmen, mein Questlog ist voll' WHERE `id`=1292;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Ich kann %quest nicht annehmen, meine Tasche ist voll' WHERE `id`=1293;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Ich habe %quest angenommen' WHERE `id`=1294;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Ich habe die Quest %quest nicht abgeschlossen' WHERE `id`=1295;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Quest %quest verfügbar' WHERE `id`=1296;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Ich habe die Quest %quest vergeigt' WHERE `id`=1297;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Ich kann die Quest %quest nicht abgeben' WHERE `id`=1298;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Ich habe die Quest %quest abgeschlossen' WHERE `id`=1299;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Ich habe die Quest %quest abgeschlossen und %item erhalten' WHERE `id`=1300;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Welche Belohnung soll ich für die Quest %quest nehmen? %rewards' WHERE `id`=1301;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Okay, ich nehme %item als Belohnung' WHERE `id`=1302;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Hi' WHERE `id`=1305;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Hallo zusammen!' WHERE `id`=1307;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Hallo, geh vor!' WHERE `id`=1309;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Hi, geh vor!' WHERE `id`=1310;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Hey %player, willst du in meine Gruppe?' WHERE `id`=1311;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Hey %player, kommst du in meine Gruppe?' WHERE `id`=1312;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Logout abgebrochen!' WHERE `id`=1313;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Ich logge mich aus!' WHERE `id`=1314;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Was war das, %s?' WHERE `id`=1318;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Bin nicht sicher, ob ich dich verstehe, %s?' WHERE `id`=1319;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='äh... keine Ahnung, wovon du redest' WHERE `id`=1320;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='whaaaa?' WHERE `id`=1322;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='hä?' WHERE `id`=1323;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='was?' WHERE `id`=1324;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='redest du grade?' WHERE `id`=1325;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='mir egal, Digga' WHERE `id`=1326;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='da bin ich raus' WHERE `id`=1327;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Konzentrier dich aufs Spiel, %s!' WHERE `id`=1330;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Mit dir zu chatten, %s, ist so großartig! Wollte dich immer schon treffen' WHERE `id`=1331;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Diese Chatnachrichten machen mich fertig! Fühlt sich an, als würde ich euch alle kennen!' WHERE `id`=1332;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='JA SICHER! HAHA KLAR!!!' WHERE `id`=1333;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Ich glaub dir!!!' WHERE `id`=1334;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Okay, ähm, lol' WHERE `id`=1335;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Hey %s... ach egal!' WHERE `id`=1337;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Wovon redest du, %s' WHERE `id`=1338;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Wer hat das gesagt? Ich fühl mich angesprochen' WHERE `id`=1339;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='wtf, worüber redet ihr alle' WHERE `id`=1340;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='ehrlich jetzt, kein Witz' WHERE `id`=1341;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='du bekommst gar nix' WHERE `id`=1342;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Plus Aura!!!' WHERE `id`=1343;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='thx!' WHERE `id`=1344;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='jup' WHERE `id`=1346;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='f' WHERE `id`=1347;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='%s, kein Scheiß xD' WHERE `id`=1348;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='warum ist das so' WHERE `id`=1349;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='ROFL' WHERE `id`=1350;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='dachte, ich halt besser die Klappe, der Chat hat mich wieder verwirrt' WHERE `id`=1351;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='ich kann richtig eifersüchtig werden' WHERE `id`=1352;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='%s, du hörst den triefenden Sarkasmus in meinem text_loc3 nicht' WHERE `id`=1353;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='er meinte „kein Ding“, passt schon' WHERE `id`=1354;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Ja, %s' WHERE `id`=1356;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='interessant...' WHERE `id`=1357;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='lol' WHERE `id`=1358;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='%s, fick dich, Mann :D' WHERE `id`=1359;
-UPDATE `ai_playerbot_texts` SET `text_loc3`=':^)' WHERE `id`=1360;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='thx' WHERE `id`=1361;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='%s, gut gesagt' WHERE `id`=1362;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='yay' WHERE `id`=1363;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='ja' WHERE `id`=1364;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='ooooooh' WHERE `id`=1365;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='hmm' WHERE `id`=1366;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='ja klar' WHERE `id`=1367;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='mir wird schlecht, wtf' WHERE `id`=1368;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='heiß' WHERE `id`=1369;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='die Weiber sind sauer' WHERE `id`=1370;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='was hast du gegessen, %s' WHERE `id`=1371;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='wtf' WHERE `id`=1372;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='ich versuche, diesen Kommentar zu verstehen' WHERE `id`=1373;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='*verwirrt*' WHERE `id`=1374;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='fuck ja' WHERE `id`=1375;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='0/10 würde ich nicht wieder lesen' WHERE `id`=1376;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='10/10 würde ich wieder lesen' WHERE `id`=1377;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='6/10 würde es lesen' WHERE `id`=1378;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='7/10 vielleicht' WHERE `id`=1379;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Respekt!' WHERE `id`=1380;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='oh ja, vielleicht' WHERE `id`=1381;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='ja und?' WHERE `id`=1382;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='hey %s, ich habe dich nicht vergessen' WHERE `id`=1383;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='du gehst mir hart auf den Sack, %s' WHERE `id`=1384;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='diesmal krieg ich dich, %s' WHERE `id`=1385;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Pass besser auf, %s' WHERE `id`=1386;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Die letzte Runde mochte ich nicht so' WHERE `id`=1387;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Letzte Runde war ich mies, danke, %s' WHERE `id`=1388;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Mach dich bereit zu sterben, %s' WHERE `id`=1389;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Fands nicht geil, dass du mich gekillt hast, %s' WHERE `id`=1390;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='%s, ich hasse dich' WHERE `id`=1391;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='grrrrrr, diesmal krieg ich dich, %s' WHERE `id`=1392;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='FICK DICH! NEIN, FICK MICH!' WHERE `id`=1393;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='%s, ich kotze dir in dein verficktes Maul' WHERE `id`=1394;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='verurteil mich nicht, verdammt nochmal' WHERE `id`=1395;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Deine Mom ist so fett, sie passt nicht mal durchs Dunkle Portal' WHERE `id`=1396;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='armselige Gestalt' WHERE `id`=1399;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='was zum Teufel' WHERE `id`=1400;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='das war scheiße' WHERE `id`=1401;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='REMATCH!!! Ich mach ihn platt' WHERE `id`=1402;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='peinlich, ich wurde von %s gekillt' WHERE `id`=1403;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='ok, ich bin raus' WHERE `id`=1404;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='hehe, hab %s weggeklatscht?' WHERE `id`=1405;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='viel zu easy, %s zu killen' WHERE `id`=1406;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='hab dich, du Bastard' WHERE `id`=1407;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='haha' WHERE `id`=1408;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Loser' WHERE `id`=1409;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='ich hab %s gekillt und ihr seid als nächste dran, Jungs' WHERE `id`=1410;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='oh ja, hab ihn geownt' WHERE `id`=1411;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='ich bin ne Killmaschine' WHERE `id`=1412;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='%s, erinnert mich an einen Slayer-Song... dieses ganze Gemetzel' WHERE `id`=1413;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='sorry, %s. Können wir die Szene nochmal machen?' WHERE `id`=1414;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='na, wie gefällt es dir Wurmfutter zu sein, %s???' WHERE `id`=1415;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='du solltest tot sein, %s, das gehört zum Spiel!!!!!' WHERE `id`=1416;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='sorry, %s. das sah so gut aus wie ein Kunstwerk von der Kirmes!' WHERE `id`=1417;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='%s, ich nehme nächstes Mal Gummigeschosse!' WHERE `id`=1418;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='was ist los, %s?? Kopf verloren? hahaha, ruhig bleiben!!' WHERE `id`=1419;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='musste das tun, %s. Du verstehst schon. Der Regisseur hat es so gesagt!!' WHERE `id`=1420;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='hey %s.......MUAHAHAHAHAHAHAHAHAHAHA' WHERE `id`=1421;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='%s, das hab ich genossen!! Wiederholung bitte!' WHERE `id`=1422;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='hey, %s! Kannst mich ab jetzt "Scarface" nennen.. du Stück SCHEI**!!!!' WHERE `id`=1423;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='redest du mit mir, %s??' WHERE `id`=1424;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='%s, mach es diesmal richtig, stell dich nicht vor meine Kugeln.' WHERE `id`=1425;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='%s, warum liegst du da rum??? hehe' WHERE `id`=1426;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='hab mich totgelacht' WHERE `id`=1427;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='hi %s' WHERE `id`=1428;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='oh, hi %s' WHERE `id`=1429;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='was geht, %s!!!' WHERE `id`=1430;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='hi' WHERE `id`=1431;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='was geht' WHERE `id`=1432;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='hallo %s' WHERE `id`=1433;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='hi %s, kennen wir uns?' WHERE `id`=1434;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='hey %s' WHERE `id`=1435;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='hai %s' WHERE `id`=1436;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='was zur Hölle' WHERE `id`=1437;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='WTF' WHERE `id`=1438;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='das ist Bullshit' WHERE `id`=1439;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='admin' WHERE `id`=1440;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='hey %s, hör auf, deine Admin-Rechte zu missbrauchen' WHERE `id`=1441;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='lass mich in Ruhe, Admin!' WHERE `id`=1442;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='du bist scheisse, Admin' WHERE `id`=1443;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='das ist mein Name, was willst du, %s' WHERE `id`=1444;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='ja???' WHERE `id`=1445;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='äh... was' WHERE `id`=1446;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='redest du mit mir, %s?' WHERE `id`=1447;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Hey ! Rate mal, was deine Mom letzte Nacht gesagt hat!' WHERE `id`=1450;
-UPDATE `ai_playerbot_texts` SET `text_loc3`=', du bist so hässlich, du würdest nicht mal im Affenbordell mit einem Sack Bananen landen!' WHERE `id`=1451;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Halt die Klappe, , du wirst so ein Mann sein, wie deine Mutter!!' WHERE `id`=1452;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Deine Mutter ist so fett, dass man eine Pokéflöte braucht, um sie aufzuwecken und dein Vater ist der Trainer!!!!' WHERE `id`=1453;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Dich als dumm zu bezeichnen, wäre eine Beleidigung für dumme Leute!' WHERE `id`=1454;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Ich furze in deine allgemeine Richtung!!!' WHERE `id`=1455;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Jeder Atemzug, den ich ohne deine Erlaubnis mache, steigert mein Selbstwertgefühl!' WHERE `id`=1456;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Was willst du tun , mich vollbluten? NIMM DAS!' WHERE `id`=1457;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='A-G-G-R-O! Das heißt Bosszeit!' WHERE `id`=1458;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Wir hatten grausame und hatten irre Begleiter, aber mit dir sind wir mit einem grausamen Irren gestraft!' WHERE `id`=1459;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Hey ! Hör auf, sie anzubaggern, sie ist nicht dein Typ. Die sind nicht aufblasbar.' WHERE `id`=1460;
-UPDATE `ai_playerbot_texts` SET `text_loc3`=', du bist so weit außerhalb deiner Liga, du spielst schon eine andere Sportart.' WHERE `id`=1461;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Großer Fehler heute Morgen, : Du bist aufgestanden!' WHERE `id`=1462;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Ich will mal versuchen, mich in ein Pferd zu verwandeln, brauche aber Hilfe. Ich mach die Vorderseite, du bleibst du.' WHERE `id`=1463;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Du kommst mir vor, als wäre das Beste von dir damals am Arsch deiner Mutter runtergelaufen und als braune Soße auf der Matratze geblieben!' WHERE `id`=1464;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Ich würd dir gern ein Abschiedsgeschenk machen... Aber zuerst machst du deinen Teil.' WHERE `id`=1465;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Bevor du kamst, waren wir motiviert, jetzt sind wir einfach nur noch genervt.' WHERE `id`=1466;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Ich mag dich. Man sagt, ich hätte keinen Geschmack, aber ich mag dich.' WHERE `id`=1467;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Ich glaube, du hast Minderwertigkeitskomplexe, aber ist okay, ist gerechtfertigt.' WHERE `id`=1468;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Verschwinde, sonst passiert was.' WHERE `id`=1469;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Kaum zu fassen, dass ich meine Zeit mit dir verschwende!' WHERE `id`=1470;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Ich liebe es, wenn mich jemand beleidigt, dann muss ich nicht mehr nett sein.' WHERE `id`=1471;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Ich werde dich auch auslöschen, du Mistkerl! Ich werde dir die Eingeweide rausreißen und dir ins Gesicht schmieren!' WHERE `id`=1472;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Du abscheuliche Bestie, nicht mal ein Hund würde dich fressen.' WHERE `id`=1473;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Du schlägst wie ein Vegetarier.' WHERE `id`=1474;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Wer hat dich ausgebuddelt, du wandelnde Seuche?' WHERE `id`=1475;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Ich schau dir nicht in die Augen, ich will heute noch schlafen können.' WHERE `id`=1476;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Boah, bei dir quillt ja noch das Mittagessen raus! Ich hab dich gerochen, bevor ich dich gesehen hab.' WHERE `id`=1477;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Oh du bist so hässlich, selbst der Respawn will dich nicht!' WHERE `id`=1478;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Ich muss mal einen riesigen machen. ist mein neues Wort für Scheiße.' WHERE `id`=1479;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Oh du nutzlose, moorsaufende Krebsgeschwulst!' WHERE `id`=1480;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Wäre ich wie du, würd ich mich selbst löschen!' WHERE `id`=1481;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Oh lehre mich, wie ich das Denken vergesse!' WHERE `id`=1482;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Ich hab schon Toiletten gesehen, die sauberer kämpfen als du.' WHERE `id`=1483;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Du verdammter Scheißkerl. Wo hast du dein Handwerk gelernt? Du dumme, verdammte Schlampe. Du Idiot. Wer hat dir gesagt, dass du mit Männern arbeiten kannst?' WHERE `id`=1484;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Wenn Unfähigkeit ’ne Klasse wäre, hättest du sie gemaxt.' WHERE `id`=1485;
-UPDATE `ai_playerbot_texts` SET `text_loc3`=' du dummes Arschfurz-Teppichladen-Arschloch' WHERE `id`=1486;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Ich lebe lang genug und dann nehm ich dir das Hirn raus!' WHERE `id`=1487;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Wenn einen intelligenten Gedanken im Kopf hätte, würde er an Einsamkeit sterben.' WHERE `id`=1488;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Hör auf zu weinen, du winselnder Arsch, hör auf mit deinem Unsinn. Du bist nur die Nachgeburt, .' WHERE `id`=1489;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='! Wenn Gehirn Vogelkacke wäre, hättest du einen sauberen Käfig' WHERE `id`=1490;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Hör mal zu, du Vokuhila... warum zündest du nicht einfach dein Tampon an und sprengst deine Box in die Luft? Denn das ist der einzige Knall, den du kriegen wirst.' WHERE `id`=1491;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Verschwinde aus meiner Sicht ! Du verseuchst meine Augen!' WHERE `id`=1492;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='SPIELZEIT!!!!' WHERE `id`=1493;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Niemand kommt vorbei!' WHERE `id`=1494;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Wir werden angegriffen! Klar zum Gefecht, ihr Deckschrubber! Wehrt die Eindringlinge ab!' WHERE `id`=1495;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Narren... Tötet den im Kleid!' WHERE `id`=1497;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Ich werde deine Seele Hakkar selbst zum Fraß vorwerfen!' WHERE `id`=1498;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Stolz kündigt das Ende eurer Welt an! Kommt, Sterbliche! Stellt euch dem Zorn der !' WHERE `id`=1499;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='All meine Pläne haben zu diesem Moment geführt!' WHERE `id`=1500;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Neuer Tag, neue glorreiche Schlacht!' WHERE `id`=1502;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Also, Geschäft... oder Vergnügen?' WHERE `id`=1503;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Ihr seid nicht vorbereitet!' WHERE `id`=1504;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Die letzte Eroberung der hat begonnen! Wieder liegt die Unterwerfung dieser Welt in unseren Händen. Lasst keinen überleben!' WHERE `id`=1505;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Euer Tod wird ein schmerzhafter sein.' WHERE `id`=1506;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Fleht um Gnade! Eure bedeutungslosen Leben sind bald verwirkt.' WHERE `id`=1507;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Gebt alle Hoffnung auf! Die ist zurückgekehrt, um zu beenden, was vor so vielen Jahren begann. Diesmal gibt es kein Entkommen!' WHERE `id`=1508;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Alarm! Ihr seid zur Auslöschung markiert!' WHERE `id`=1509;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Hahaha! Ihr seid hoffnungslos unterlegen!' WHERE `id`=1511;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Ich werde euren Größenwahn zerschmettern!' WHERE `id`=1512;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Verzeiht mir, denn ihr werdet gleich das Spiel verlieren.' WHERE `id`=1513;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Wehren macht es nur schlimmer.' WHERE `id`=1514;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Ungeziefer! Blutegel! Saugt mein Blut und erstickt daran!' WHERE `id`=1515;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Mein Blut wird euer Ende sein!' WHERE `id`=1517;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Macht hinne, Wachen! Es ist Zeit zum Töten!' WHERE `id`=1519;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Zögert euer Schicksal nicht hinaus. Kommt jetzt zu mir. Ich mache euer Opfer kurz.' WHERE `id`=1520;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Bald seid ihr tot!' WHERE `id`=1521;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Mu-ha-ha!' WHERE `id`=1522;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Ich bin der Jäger! Ihr seid die Beute...' WHERE `id`=1523;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Ihr werdet diesen Ort in Stücken verlassen!' WHERE `id`=1524;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Der Tod naht. Wird euer Gewissen rein sein?' WHERE `id`=1525;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Euer Verhalten wird nicht toleriert.' WHERE `id`=1526;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Hmm, unangekündigte Besucher. Vorbereitungen müssen getroffen werden...' WHERE `id`=1528;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Feindliche Einheiten entdeckt. Bedrohungsanalyse-Protokoll aktiv. Primärziel erfasst. Zeit minus dreißig Sekunden bis zur Neubewertung.' WHERE `id`=1529;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Neue Spielzeuge? Für mich? Ich verspreche, ich mach sie diesmal nicht kaputt!' WHERE `id`=1530;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Pssst... gleich ist alles vorbei.' WHERE `id`=1532;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Sag es mir... sag mir alles, Geheimnisse und Privatsachen! Ich reiße dir die Infos aus dem Fleisch!' WHERE `id`=1536;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Macht euch bereit, die Glocken haben geläutet! Bringt die Schwachen, die Jungen und die Alten in Sicherheit! Jeder von euch zahlt den letzten Preis! Fleht um Gnade, die Abrechnung ist gekommen!' WHERE `id`=1537;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Wo, bei Bonzos Messingknöpfen, bin ich?' WHERE `id`=1538;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Ich ertrage es nicht länger! Goblinkönig! Goblinkönig! Wo immer du bist! Nimm diesen weit weg von mir!' WHERE `id`=1539;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Ihr habt dreizehn Stunden, um das Labyrinth zu lösen, bevor euer kleiner Bruder einer von uns wird... für immer.' WHERE `id`=1540;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Also, die ist Kinderkram, ja? Dann sehen wir mal, wie ihr dieses kleine Stückchen verdaut...' WHERE `id`=1541;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Weiche! Ich stelle mich jedem Kampf. Du irrst dich, dies ist nicht dein Revier.' WHERE `id`=1542;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Zeig, was du drauf hast!' WHERE `id`=1543;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Zweiklingen-Action für eine glatte und saubere Rasur jedes mal.' WHERE `id`=1545;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Los, komm schon!' WHERE `id`=1546;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Du gehst drauf!' WHERE `id`=1547;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Stich, stich, stich!' WHERE `id`=1548;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Machen wir das schnell, Zeit ist Mana.' WHERE `id`=1549;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Ich glaube nicht, dass ihr die Schwere eurer Lage begreift.' WHERE `id`=1550;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Ich bringe meiner Familie und meinem Königreich Ehre!' WHERE `id`=1551;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Licht, gib mir Stärke!' WHERE `id`=1552;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Meine Kirche ist das Schlachtfeld, Zeit zum Gottesdienst...' WHERE `id`=1553;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Ich verachte euch...' WHERE `id`=1554;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Stellt euch dem Hammer der Gerechtigkeit!' WHERE `id`=1555;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Beweist euren Wert in der Prüfung der Waffen im Lichte!' WHERE `id`=1556;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Alles wird vor der Macht und der Gerechtigkeit meiner Sache fallen. Ihr werdet der Nächste sein!' WHERE `id`=1557;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Bereitet euch aufs Sterben vor!' WHERE `id`=1558;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Die Bestie an meiner Seite ist nichts gegen die Bestie in mir...' WHERE `id`=1559;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Erlebt die Feuerkraft dieses voll bewaffneten Jägers!' WHERE `id`=1560;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Heilt mich! Schnell!' WHERE `id`=1561;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Fast tot! Heilt mich!' WHERE `id`=1562;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Hilfe! Heilt mich!' WHERE `id`=1563;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Irgendwer! Heilt mich!' WHERE `id`=1564;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Heal! Heal! Heal!' WHERE `id`=1565;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Ich sterbe! Heal! Aaaaarhg!' WHERE `id`=1566;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Heal mich!' WHERE `id`=1567;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Ich sterbe. Ich sterbe. Ich sterbe. Heal!' WHERE `id`=1568;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Oh, der Schmerz. Heilt mich schnell!' WHERE `id`=1570;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Brauche Heal' WHERE `id`=1571;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='HP low' WHERE `id`=1572;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Gebt mal nen Heal. Bitte.' WHERE `id`=1573;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Kann mir jemand nen Heal geben?' WHERE `id`=1574;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Hey! Lieber jetzt heilen als später zu rezzen' WHERE `id`=1575;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Sorry. Brauche noch einen Heal' WHERE `id`=1576;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Verdammte Mobs. Heal mich bitte' WHERE `id`=1577;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Noch ein Treffer und ich bin hinüber. Heal bitte' WHERE `id`=1578;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Heiler da?' WHERE `id`=1579;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Warum hauen die mir immer ins Gesicht? Brauche Heal' WHERE `id`=1580;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Kann mich wer ein bisschen heilen?' WHERE `id`=1581;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='OOM' WHERE `id`=1582;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Kein Mana mehr' WHERE `id`=1583;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Verdammt, dafür hab ich mein ganzes Mana verballert' WHERE `id`=1584;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Wartet bis ich trinke oder mein Mana wieder da ist' WHERE `id`=1585;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Mana low' WHERE `id`=1586;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Mana low. Muss trinken' WHERE `id`=1588;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Haben wir nen Getränkeautomaten? Wieder OOM' WHERE `id`=1589;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Mein Mana ist Geschichte' WHERE `id`=1590;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Ich besorge mir nächstes mal Drinks. OOM' WHERE `id`=1591;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Noch 100 !' WHERE `id`=1595;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Das war es! Keine mehr!' WHERE `id`=1596;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Und ihr habt meinen Bogen... ups, keine !' WHERE `id`=1597;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Brauche !' WHERE `id`=1598;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Ich habe Angst' WHERE `id`=1600;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Wir sind am Arsch.' WHERE `id`=1601;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Das wars.' WHERE `id`=1602;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Hier ist jetzt Schluss.' WHERE `id`=1603;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Kann mal wer Blizzard anrufen?' WHERE `id`=1604;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Verdammt. Der Tank hat alle Mobs gepullt.' WHERE `id`=1605;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Wir sterben. Wir sterben. Wir sterben.' WHERE `id`=1606;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Whoa! So viel Spielzeug zum Austoben.' WHERE `id`=1607;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Ich kill sie alle!' WHERE `id`=1608;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Wenn der Tank stirbt, sind wir Geschichte.' WHERE `id`=1609;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='LEEEEERROOOYYYYYYYYYYYY JENNKINNNSSSSSS!!!!!!!' WHERE `id`=1611;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Okay. Was haben wir an AoE?' WHERE `id`=1612;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Jetzt wirds interessant.' WHERE `id`=1613;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Cool. Zieht sie zusammen für nen schönen Flammenstoß.' WHERE `id`=1614;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Kill! Kill! Kill!' WHERE `id`=1615;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Ich glaub, meine Hose ist nass.' WHERE `id`=1616;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Hoffentlich sind die Heiler ready. Leeeeroy!' WHERE `id`=1618;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Hoffentlich kommen die nicht zu mir.' WHERE `id`=1619;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Oh nein. Ich kann bei dem Gemetzel nicht hinsehen.' WHERE `id`=1620;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Hoffentlich gibts Gold.' WHERE `id`=1621;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Loot! Loot!' WHERE `id`=1622;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Mein Schatz.' WHERE `id`=1623;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Hoffentlich wartet da ein schickes episches Item auf mich.' WHERE `id`=1624;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Ich hab tiefe Taschen und Beutel.' WHERE `id`=1625;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Alles meins!' WHERE `id`=1626;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Hoffentlich heute kein grauer Müll.' WHERE `id`=1627;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Dieser Loot ist MEINER!' WHERE `id`=1628;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Looten ist eklig, aber ich brauch Gold.' WHERE `id`=1629;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Gold!' WHERE `id`=1630;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Okay. Mal sehen, was sie droppen.' WHERE `id`=1631;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Keine Sorge. Ich loote alles.' WHERE `id`=1632;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Ich bin ein Ninja-Looter.' WHERE `id`=1633;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Kann mir mal wer erklären, wo die das ganze Zeug versteckt haben?' WHERE `id`=1635;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Nein, ich loote keinen grauen Müll.' WHERE `id`=1636;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Ich bin zuerst. Ich bin zuerst. Ich bin zuerst.' WHERE `id`=1637;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Gebt mir euer Gold!' WHERE `id`=1638;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Meine Taschen sind leer, müssen aber voll werden.' WHERE `id`=1639;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Hab dafür ne neue Tasche.' WHERE `id`=1640;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Hoffentlich zieh ich beim Looten keine Aggro.' WHERE `id`=1641;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Ich kann nicht looten wenn jemand zusieht.' WHERE `id`=1642;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Ha! Ihr kriegt davon keinen Krümel!' WHERE `id`=1643;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Ich mag neues Gear.' WHERE `id`=1645;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Ich höre auf, wenn schon wieder nichts Wertvolles droppt.' WHERE `id`=1646;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Hoffentlich ist es ein hübscher Ring.' WHERE `id`=1647;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Ich reiß dir den Loot aus den Händen.' WHERE `id`=1648;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Alle weg da. Ich loote jetzt.' WHERE `id`=1649;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Geiler Loot.' WHERE `id`=1650;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Oh ihr RNG-Götter! Gewährt mir heute einen Epic beim würfeln.' WHERE `id`=1651;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Bitte gib mir neues Spielzeug.' WHERE `id`=1652;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Hoffe, die haben was Leckeres dabei.' WHERE `id`=1653;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Das Gold gehört mir. Ich lasse euch den Rest, versprochen.' WHERE `id`=1654;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Bin gleich da, wartet auf mich!' WHERE `id`=1657;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Bin nicht mehr weit, bitte wartet!' WHERE `id`=1658;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Bin auf dem Weg zu euch.' WHERE `id`=1659;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Ich reise zu euch.' WHERE `id`=1661;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Ich versuche zu euch zu kommen.' WHERE `id`=1662;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Rüste %item aus' WHERE `id`=1663;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Ich habe die Zauber gelernt: %spells' WHERE `id`=1665;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='%item hat Abklingzeit.' WHERE `id`=1666;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Ich habe %item nicht im Inventar.' WHERE `id`=1667;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Das Item mit der ID %item existiert nicht.' WHERE `id`=1668;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Folge.' WHERE `id`=1671;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Bleibe hier.' WHERE `id`=1672;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Fliehe.' WHERE `id`=1673;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Ich fliehe nicht mit dir, du bist zu weit weg.' WHERE `id`=1674;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Grinde.' WHERE `id`=1675;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Greife an.' WHERE `id`=1676;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Das ist zu weit weg.' WHERE `id`=1677;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Da kann ich nicht hin.' WHERE `id`=1679;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Ich bin nicht in deiner Gilde!' WHERE `id`=1680;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Keine Gildenbank in der Nähe gefunden.' WHERE `id`=1681;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Ich kann nicht ' WHERE `id`=1682;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Ich habe keine Rechte, Items in den ersten Gildenbank-Reiter zu legen.' WHERE `id`=1683;
-UPDATE `ai_playerbot_texts` SET `text_loc3`=' in die Gildenbank gelegt' WHERE `id`=1684;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Freies Bewegen.' WHERE `id`=1685;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Bewache.' WHERE `id`=1686;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='(das letzte)' WHERE `id`=1690;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='auf Handelsgegenstand' WHERE `id`=1692;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Loote %item' WHERE `id`=1696;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Ich habe nicht genug Gruppenmitglieder in der Nähe, um beschwören zu können.' WHERE `id`=1698;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Ich kenne den Zauber %spell nicht.' WHERE `id`=1701;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Stelle %spell her' WHERE `id`=1703;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Konnte %spell nicht wirken.' WHERE `id`=1705;
-UPDATE `ai_playerbot_texts` SET `text_loc3`=' |cffffff00(x%amount übrig)|r' WHERE `id`=1706;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Dummy' WHERE `id`=1707;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Beim Licht… Ich hab meine Königssymbole vergessen. Na gut, dann nehmen wir eben %base_spell!' WHERE `id`=1708;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Die Natur ist großzügig, meine Taschen nicht... keine Kräuter für %group_spell mehr. Nehmt fürs Erste %base_spell!' WHERE `id`=1709;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Arkanes Pulver alle... %group_spell muss warten. Wirke %base_spell!' WHERE `id`=1710;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='Ups, mir fehlen die Komponenten für %group_spell. Wir nehmen %base_spell!' WHERE `id`=1711;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='%player bewegt sich, um den roten Strahl zu blocken!' WHERE `id`=1712;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='%player bewegt sich, um den blauen Strahl zu blocken!' WHERE `id`=1713;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='%player bewegt sich, um den grünen Strahl zu blocken!' WHERE `id`=1714;
-UPDATE `ai_playerbot_texts` SET `text_loc3`='%player verlässt den blauen Strahl--nächster Blocker los!' WHERE `id`=1715;
-
-UPDATE `ai_playerbot_texts` SET `text_loc3`='%player verlässt den grünen Strahl--nächster Blocker los!' WHERE `id`=1716;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='am Arsch der Welt' WHERE `id`=1;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='an einem geheimen Ort' WHERE `id`=2;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='irgendwo' WHERE `id`=3;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='irgendwas' WHERE `id`=4;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='frag mich, wie %item_link wohl schmeckt' WHERE `id`=5;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='neeein, ich hab %item_link bekommen' WHERE `id`=6;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='ah nee, nicht schon wieder dieser Müll: %item_link' WHERE `id`=7;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='scheint so, als würde ich nur Müll looten: %item_link' WHERE `id`=8;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='naja, besser als nix, schätze ich: %item_link' WHERE `id`=9;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='keine Ahnung, was ich mit %item_link anfangen soll' WHERE `id`=10;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='naja, ich kann den ganzen Tag %item_link looten' WHERE `id`=11;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='neuer Tag, neuer %item_link' WHERE `id`=12;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='hab %item_link gelootet' WHERE `id`=13;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='ein %item_link ist okay' WHERE `id`=14;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='nicht schlecht, hab grad %item_link bekommen.' WHERE `id`=15;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='gerade %item_link in %zone_name gelootet' WHERE `id`=16;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='kann ich gut gebrauchen, %item_link' WHERE `id`=17;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Gold, Gold, Gold: %item_link' WHERE `id`=18;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='hab %item_link bekommen' WHERE `id`=19;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='%item_link ist BiS für Jäger' WHERE `id`=20;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='%item_link ist BiS für %my_class' WHERE `id`=21;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='RNG meint es heute gut: %item_link' WHERE `id`=22;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='nice, %item_link frisch gelootet' WHERE `id`=23;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='wow, hab gerade %item_link bekommen' WHERE `id`=24;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='%item_link ist BiS für Jäger' WHERE `id`=25;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='%item_link ist BiS für %my_class' WHERE `id`=26;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='RNG meint es heute gut: %item_link' WHERE `id`=27;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='nice, %item_link frisch gelootet' WHERE `id`=28;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='OMG, guckt mal, was ich gerade bekommen hab: %item_link!!!' WHERE `id`=29;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Keine @#$@% Chance! Ich hab %item_link bekommen, Wahnsinn.' WHERE `id`=30;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Keine @#$@% Chance! Das kann nicht sein - ich hab %item_link bekommen, völlig irre.' WHERE `id`=31;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Im Ernst? Noch ein %item_link? Mein Glück ist kaputt.' WHERE `id`=32;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Ich hab %item_link... ugh, schon wieder.' WHERE `id`=34;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Keine Ahnung, warum ich %item_link überhaupt aufhebe, es ist nutzlos.' WHERE `id`=35;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Schaut euch diesen glänzenden %item_link an... schade, ist trotzdem Müll.' WHERE `id`=36;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Dieser %item_link ist nicht mal das Papier wert, auf dem er stehen würde.' WHERE `id`=37;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Ich schätze, %item_link ist besser als gar nix? Gerade so.' WHERE `id`=38;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Kein Plan, was ich mit %item_link machen soll, vielleicht verkauf ich es für 1 Silber.' WHERE `id`=39;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Noch ein %item_link... naja, immerhin krieg ich was.' WHERE `id`=40;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Hoffentlich ist %item_link was wert, es sieht nämlich furchtbar aus.' WHERE `id`=41;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Warum krieg ich ständig %item_link... hab ich RNG verärgert?' WHERE `id`=43;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Als würde %item_link mir nachlaufen. Ich will das nicht!' WHERE `id`=44;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Da ist %item_link schon wieder. Was für eine Überraschung.' WHERE `id`=45;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Ich schätze, %item_link taugt als Händler-Müll?' WHERE `id`=46;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Neeeein, nicht schon wieder %item_link! RNG, bitte!' WHERE `id`=47;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Naja, ganz nutzlos ist %item_link immerhin nicht, oder?' WHERE `id`=48;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Noch ein %item_link? RNG, kümmert dich das überhaupt?' WHERE `id`=49;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Vielleicht ist %item_link in 10 Jahren was wert.' WHERE `id`=50;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Ich bewundere einfach mal, wie %item_link aussieht... und schmeiß es weg.' WHERE `id`=51;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Wer braucht %item_link? Ich sicher nicht.' WHERE `id`=52;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Vielleicht ist %item_link nützlich... haha, doch nur Müll.' WHERE `id`=53;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Das Universum schenkt mir %item_link. Toll.' WHERE `id`=54;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Gut, ich hab %item_link. Begeistert bin ich nicht.' WHERE `id`=55;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Was soll ich überhaupt mit %item_link anfangen? Nicht mal verkaufbar.' WHERE `id`=56;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Packen wir %item_link zu meinem wachsenden Enttäuschungsstapel.' WHERE `id`=57;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Danke für %item_link... genau das, was ich nicht gebraucht hab.' WHERE `id`=58;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Ich hab so viele %item_link gelootet, ich könnte damit einen Laden aufmachen.' WHERE `id`=60;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Ein glänzender %item_link... kommt wohl auf den Müllhaufen.' WHERE `id`=61;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Es ist %item_link, Leute. Nicht zu früh freuen.' WHERE `id`=62;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Naja, wenigstens ist es %item_link... könnte schlimmer sein.' WHERE `id`=63;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Lieber %item_link als gar nix.' WHERE `id`=64;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Noch ein %item_link. Nicht das Schlimmste.' WHERE `id`=65;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Hey, %item_link... ist schon okay, denk ich.' WHERE `id`=66;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Hey, %item_link. Nicht schlecht, nicht gut, aber ich nehme es.' WHERE `id`=67;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Könnte schlimmer sein... hab gerade %item_link gelootet.' WHERE `id`=68;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='%item_link wird für irgendwas nützlich sein, denke ich.' WHERE `id`=69;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Neuer Tag, neuer %item_link. Kann mich nicht beschweren.' WHERE `id`=70;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Naja, %item_link geht klar, würd ich sagen.' WHERE `id`=71;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Gerade %item_link bekommen. Nicht das Beste, aber etwas.' WHERE `id`=72;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='%item_link ist gut genug, ich bin nicht sauer.' WHERE `id`=74;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Kein Legendary, aber %item_link reicht.' WHERE `id`=75;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Kein schlechter Drop... %item_link ist okay.' WHERE `id`=76;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Lieber %item_link als gar nix.' WHERE `id`=77;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Schon wieder %item_link. Besser als nix, denke ich.' WHERE `id`=79;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='%item_link schon wieder, hm? Nicht begeistert, aber ich überlebe.' WHERE `id`=80;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Hätte schlimmer kommen können, %item_link ist gar nicht so schlecht.' WHERE `id`=82;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Ich nehm %item_link, könnte schlimmer sein.' WHERE `id`=84;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='%item_link gelootet, nix Besonderes, aber okay.' WHERE `id`=85;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Nicht das, was ich wollte, aber %item_link reicht fürs Erste.' WHERE `id`=86;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Noch ein %item_link. Nicht der Wahnsinn, aber geht klar.' WHERE `id`=87;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='%item_link gelootet, könnte schlimmer sein.' WHERE `id`=88;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Naja, %item_link ist besser als ein Stich ins Auge.' WHERE `id`=89;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Ich nehm %item_link und zieh weiter.' WHERE `id`=90;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Nice! Ein solider %item_link für die Sammlung.' WHERE `id`=91;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Nicht schlecht, %item_link könnte nützlich werden.' WHERE `id`=93;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Hab mir %item_link geholt, jetzt gehts los.' WHERE `id`=94;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Dieser %item_link ist besser als die meisten, nehm ich.' WHERE `id`=95;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Mit %item_link kann ich was Gutes anfangen.' WHERE `id`=96;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Mit %item_link lässt sich vielleicht gut verdienen.' WHERE `id`=99;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Ein solider %item_link, der Tag sieht gleich besser aus.' WHERE `id`=100;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Hab %item_link nicht erwartet, aber ich nehm es.' WHERE `id`=101;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Kein Plan, was ich mit %item_link machen soll aber ich freue mich drüber.' WHERE `id`=102;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Nicht meine erste Wahl, aber %item_link nehm ich gern.' WHERE `id`=103;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Genau das hab ich heute gebraucht: %item_link.' WHERE `id`=104;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Noch ein %item_link. Nehm ich, keine Beschwerden.' WHERE `id`=106;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Immerhin hat %item_link irgendeinen Nutzen. Nicht der schlimmste Loot.' WHERE `id`=107;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='%item_link ist vielleicht genau das, was ich heute brauche.' WHERE `id`=108;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Ich hab gerade %quest_link angenommen' WHERE `id`=109;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='gerade %quest_link angenommen' WHERE `id`=110;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='%quest_link - versuch das mal abzuschließen' WHERE `id`=111;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='%quest_link in %zone_name angenommen' WHERE `id`=112;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Gerade %quest_link abgeholt, Zeit ranzuklotzen!' WHERE `id`=113;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='%quest_link eingesackt, mal sehen, worum es geht.' WHERE `id`=114;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='%quest_link geschnappt, Los gehts!' WHERE `id`=115;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Neue Quest, %quest_link. Los!' WHERE `id`=116;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Sieht so aus, als wäre jetzt %quest_link dran, wünscht mir Glück.' WHERE `id`=117;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='%quest_link angenommen, mal sehen, wie hart die ist.' WHERE `id`=118;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='%quest_link mitgenommen, Zeit für Fortschritt.' WHERE `id`=119;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Gerade %quest_link genommen. Mal sehen, wie schwer die ist.' WHERE `id`=120;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='%quest_link angenommen, hoffentlich kein Überraschungsboss am Ende.' WHERE `id`=121;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Unterwegs, %quest_link abzuschließen. Auf gehts!' WHERE `id`=122;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Dann mach ich jetzt wohl %quest_link. Hoffentlich lohnt sichs.' WHERE `id`=123;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='%quest_link eingesackt. Weiter gehts!' WHERE `id`=124;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Hab gerade %quest_link angenommen. Sollte Kinderkram sein.' WHERE `id`=125;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='%quest_link angenommen, jetzt rock ich das.' WHERE `id`=126;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='%quest_link in %zone_name angenommen. Los gehts!' WHERE `id`=127;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Auf dem Weg, %quest_link zu beenden. Machen wirs schnell!' WHERE `id`=128;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='%quest_link angenommen. Mal sehen, was in %zone_name auf mich wartet.' WHERE `id`=129;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='%quest_link bekommen, hoffentlich dauert das nicht ewig.' WHERE `id`=130;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='%quest_link geschnappt. Schon wieder von vorn.' WHERE `id`=131;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Es sieht so aus, als ob %quest_link als nächstes dran ist.' WHERE `id`=132;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Unterwegs, %quest_link abzuschließen. Hoffe, die macht Spaß.' WHERE `id`=133;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Gerade %quest_link genommen. Zeit nachzuschauen, was mich erwartet.' WHERE `id`=136;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Nochmal %quest_link. Ziehen wirs schnell durch!' WHERE `id`=137;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Ich hab gerade %quest_link genommen. Das wird spaßig!' WHERE `id`=138;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='%quest_link in %zone_name angenommen. Los!' WHERE `id`=139;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='%quest_link geschnappt. Kann es kaum erwarten, was als Nächstes kommt.' WHERE `id`=140;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='%quest_link genommen. Abtauchen und durchziehen.' WHERE `id`=141;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Alles klar, %quest_link ist aktiv. An die Arbeit!' WHERE `id`=142;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Weiter zu %quest_link. Hoffentlich nicht zu hart.' WHERE `id`=143;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Gerade %quest_link geschnappt. Sollte easy sein!' WHERE `id`=144;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Ich hab %quest_link angenommen. Machen wirs fix!' WHERE `id`=145;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='%quest_link genommen, mal schauen, worum es geht.' WHERE `id`=146;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Gerade %quest_link angenommen, weiter gehts!' WHERE `id`=147;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Endlich fertig mit %quest_obj_name für %quest_link' WHERE `id`=148;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='endlich %quest_obj_available/%quest_obj_required von %quest_obj_name für %quest_link bekommen' WHERE `id`=149;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='%quest_obj_full_formatted für %quest_link, endlich' WHERE `id`=150;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Uff, %quest_obj_available/%quest_obj_required %quest_obj_name für %quest_link bekommen' WHERE `id`=151;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='brauche noch %quest_obj_missing von %quest_obj_name für %quest_link' WHERE `id`=152;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='%quest_obj_full_formatted, arbeite noch an %quest_link' WHERE `id`=153;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='%quest_obj_name für %quest_link fertig, was für ein Grind!' WHERE `id`=154;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Kurz vor Abschluss von %quest_obj_name für %quest_link, fehlen nur noch %quest_obj_missing.' WHERE `id`=155;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='%quest_obj_name fast durch, brauche nur noch %quest_obj_missing für %quest_link.' WHERE `id`=156;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Endlich %quest_obj_name für %quest_link fertig! Das hat gedauert!' WHERE `id`=158;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Läuft, hab %quest_obj_available/%quest_obj_required von %quest_obj_name für %quest_link.' WHERE `id`=159;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Yes! %quest_obj_name für %quest_link abgeschlossen. Weiter gehts!' WHERE `id`=160;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Fortschritt bei %quest_obj_name, %quest_obj_available/%quest_obj_required erledigt für %quest_link.' WHERE `id`=161;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='%quest_obj_full_formatted... fast geschafft für %quest_link!' WHERE `id`=162;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Brauche nur noch %quest_obj_missing %quest_obj_name für %quest_link, fast fertig!' WHERE `id`=163;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Endlich %quest_obj_name für %quest_link geschafft, was für eine Erleichterung!' WHERE `id`=164;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Hab %quest_obj_available/%quest_obj_required von %quest_obj_name für %quest_link, geht voran!' WHERE `id`=165;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='%quest_obj_name für %quest_link ist komplett! Weiter zur nächsten Aufgabe.' WHERE `id`=166;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='100% von %quest_obj_name für %quest_link erledigt, ab zu den Belohnungen!' WHERE `id`=167;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Es fehlen noch %quest_obj_missing von %quest_obj_name für %quest_link, fast fertig!' WHERE `id`=168;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Arbeite an %quest_obj_name für %quest_link, aktuell %quest_obj_available/%quest_obj_required erledigt.' WHERE `id`=169;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='%quest_obj_full_formatted für %quest_link. Das war ein langer Brocken!' WHERE `id`=170;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Brauche nur noch ein paar %quest_obj_name für %quest_link, dann bin ich durch!' WHERE `id`=171;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Noch ein Ziel erledigt! %quest_obj_full_formatted für %quest_link' WHERE `id`=172;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Grinde weiter %quest_obj_name für %quest_link, mit %quest_obj_available/%quest_obj_required fast da.' WHERE `id`=173;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Ziel erledigt! %quest_obj_full_formatted für %quest_link. Weiter zum nächsten!' WHERE `id`=174;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Endlich fertig mit %item_link für %quest_link' WHERE `id`=175;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='endlich %quest_obj_available/%quest_obj_required von %item_link für %quest_link bekommen' WHERE `id`=176;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='%quest_obj_full_formatted für %quest_link, endlich' WHERE `id`=177;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Uff, %quest_obj_available/%quest_obj_required %item_link für %quest_link bekommen' WHERE `id`=178;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='brauche noch %quest_obj_missing %item_link für %quest_link' WHERE `id`=179;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='%quest_obj_full_formatted, arbeite noch an %quest_link' WHERE `id`=180;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Es geht voran! %quest_obj_available/%quest_obj_required %item_link für %quest_link.' WHERE `id`=182;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='%quest_obj_name ist zur Hälfte durch, brauche noch %quest_obj_missing %item_link für %quest_link.' WHERE `id`=183;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Es fehlen noch %quest_obj_missing von %item_link für %quest_link, aber ich komme näher!' WHERE `id`=184;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Endlich %item_link für %quest_link fertig, weiter mit der nächsten Aufgabe!' WHERE `id`=185;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Fast da! %quest_obj_available/%quest_obj_required %item_link für %quest_link geholt.' WHERE `id`=186;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Yes! %item_link für %quest_link abgeschlossen. Weiter zum nächsten Ziel.' WHERE `id`=187;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Guter Fortschritt bei %item_link für %quest_link, brauche noch %quest_obj_missing.' WHERE `id`=189;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='100% von %item_link für %quest_link erledigt! Weiter gehts.' WHERE `id`=190;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Hab %quest_obj_available/%quest_obj_required %item_link für %quest_link. Das Ziel ist in Sicht!' WHERE `id`=191;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Geschafft, %item_link für %quest_link komplett. Was für eine Erleichterung!' WHERE `id`=192;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Arbeite hart an %item_link für %quest_link, brauche noch %quest_obj_missing.' WHERE `id`=193;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Fast fertig mit %item_link für %quest_link, es fehlen nur noch %quest_obj_missing.' WHERE `id`=194;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='%item_link für %quest_link abgeschlossen, der Grind ist real!' WHERE `id`=195;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Arbeite weiter an %item_link für %quest_link, bisher %quest_obj_available/%quest_obj_required erledigt.' WHERE `id`=196;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='%item_link für %quest_link kommt der Fertigstellung näher, %quest_obj_available/%quest_obj_required erledigt.' WHERE `id`=197;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Yes! %item_link für %quest_link fertig! Das hat etwas länger gedauert.' WHERE `id`=198;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Ich habe %quest_obj_available/%quest_obj_required %item_link für %quest_link, läuft!' WHERE `id`=199;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Durch mit %item_link für %quest_link. Weiter zum nächsten!' WHERE `id`=200;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Noch eins abgehakt! %item_link für %quest_link ist durch!' WHERE `id`=201;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Grinde weiter %item_link für %quest_link, habe %quest_obj_available/%quest_obj_required geschafft.' WHERE `id`=202;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Bin fast durch! Brauche noch %quest_obj_missing %item_link für %quest_link.' WHERE `id`=203;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Nicht rechtzeitig %quest_link geschafft...' WHERE `id`=204;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Zeit für %quest_link abgelaufen :(' WHERE `id`=205;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Alle Ziele für %quest_link abgeschlossen' WHERE `id`=206;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Alle Ziele für %quest_link erledigt' WHERE `id`=207;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Ich gebe %quest_link gleich ab, habe gerade alle Ziele erledigt' WHERE `id`=208;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Jaaa, endlich %quest_link abgegeben' WHERE `id`=209;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='hab %quest_link abgegeben' WHERE `id`=210;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Hab %quest_link geschafft, gerade abgegeben' WHERE `id`=211;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='gerade %quest_link abgegeben' WHERE `id`=212;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='gerade %quest_link in %zone_name abgegeben' WHERE `id`=213;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Noch eine Quest abgeschlossen! %quest_link abgegeben' WHERE `id`=214;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Mission erfüllt! %quest_link ist abgegeben' WHERE `id`=215;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Endlich, %quest_link abgegeben! Was für ein Ritt!' WHERE `id`=216;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Grade %quest_link abgeschlossen und abgegeben, fühlt sich gut an!' WHERE `id`=217;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='%quest_link in %zone_name abgegeben. Weiter zur nächsten Herausforderung!' WHERE `id`=218;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Hab %quest_link abgegeben. Wieder eine weniger!' WHERE `id`=219;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='%quest_link erfolgreich abgegeben, das hat gedauert!' WHERE `id`=220;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='%quest_link in %zone_name abgeschlossen und abgegeben. Fühlt sich gut an!' WHERE `id`=221;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Quest fertig! %quest_link abgegeben und bereit für die nächste!' WHERE `id`=222;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Endlich %quest_link in %zone_name abgegeben. Die war knackig!' WHERE `id`=223;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Das wars, %quest_link abgegeben! Jetzt Belohnung einsacken!' WHERE `id`=224;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='%quest_link fertig! Jetzt abgeben und weiter.' WHERE `id`=225;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='%quest_link eben abgeschlossen und abgegeben. Weiter gehts!' WHERE `id`=228;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Wieder eine im Kasten, %quest_link abgegeben' WHERE `id`=229;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='%quest_link abgegeben! Zeit, die Belohnung abzuholen.' WHERE `id`=230;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Das ging fix! %quest_link schon abgegeben!' WHERE `id`=232;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Gerade %quest_link in %zone_name abgegeben. Bereit fürs nächste Abenteuer!' WHERE `id`=233;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Mission komplett! %quest_link ist abgegeben!' WHERE `id`=235;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Hab gerade %quest_link beendet und abgegeben, weiter zur nächsten!' WHERE `id`=236;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='wieder %victim_name gelegt' WHERE `id`=237;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Ich leg ständig %victim_name um, nix Besonderes' WHERE `id`=238;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='noch ein %victim_name beißt ins Gras' WHERE `id`=239;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='ein %victim_name weniger in %zone_name' WHERE `id`=240;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Hab diesen Elite-Bastard %victim_name umgehauen!' WHERE `id`=241;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Elite %victim_name in %zone_name gekillt' WHERE `id`=242;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Puh, %victim_name doch noch gelegt!' WHERE `id`=243;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Gefällt dir das %victim_name?! Willst du, dass ich drei Wochen zurückspule, als du noch gelebt hast?!' WHERE `id`=244;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Yo, hab gerade %victim_name gekillt!' WHERE `id`=245;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Rare %victim_name in %zone_name gekillt' WHERE `id`=246;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='WTF hab ich da gerade umgehauen? %victim_name' WHERE `id`=247;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Gerade das Pet %victim_name gekillt' WHERE `id`=248;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Oh ja, hab gerade %victim_name gekillt' WHERE `id`=249;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='%victim_name in %zone_name gekillt' WHERE `id`=250;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Wieder %victim_name erlegt' WHERE `id`=251;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Ich leg ständig %victim_name um, nix Besonderes' WHERE `id`=252;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='noch ein %victim_name beißt ins Gras' WHERE `id`=253;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='ein %victim_name weniger in %zone_name' WHERE `id`=254;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='%victim_name so nebenbei umgehauen' WHERE `id`=255;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='%victim_name hatte keine Chance' WHERE `id`=256;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Schon wieder %victim_name aus dem Weg geräumt' WHERE `id`=257;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='%victim_name war zu easy, weiter gehts' WHERE `id`=258;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Und wieder %victim_name plattgemacht. Kinderkram' WHERE `id`=259;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='%victim_name war gar nicht so tough' WHERE `id`=260;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='%victim_name liegt, nix Besonderes' WHERE `id`=261;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Das war zu easy, %victim_name liegt' WHERE `id`=262;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='%victim_name ist so schnell umgekippt, einmal blinzeln und vorbei' WHERE `id`=263;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Diesen Elite %victim_name umgehauen!' WHERE `id`=264;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Elite %victim_name existiert nicht mehr' WHERE `id`=265;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Den Elite %victim_name weggemacht wie ein Boss' WHERE `id`=266;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Elite-Mob %victim_name, hat keine Chance gegen mich!' WHERE `id`=267;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Endlich den mächtigen %victim_name gelegt' WHERE `id`=268;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Elite %victim_name in %zone_name gekillt' WHERE `id`=269;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Hab gerade Elite %victim_name in %zone_name erwischt' WHERE `id`=270;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Elite %victim_name gekillt. Viel zu easy' WHERE `id`=271;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='%victim_name in %zone_name umgehauen, was ein Kampf' WHERE `id`=272;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Elite %victim_name gekillt. Ich scheine unaufhaltbar zu sein' WHERE `id`=273;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Puh, %victim_name doch noch gelegt!' WHERE `id`=274;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Seltener Elite %victim_name liegt' WHERE `id`=275;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='%victim_name gibt es nicht mehr. Noch ein seltener Elite gelegt' WHERE `id`=276;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Seltener Elite %victim_name down. Ich bin aus Feuer!' WHERE `id`=277;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Hab gerade den seltenen Elite %victim_name gekillt' WHERE `id`=278;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Das war geil! %victim_name gerade gekillt! Was ein Kampf' WHERE `id`=279;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Weltenboss %victim_name ist down! Das war episch' WHERE `id`=280;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Hab den Weltenboss %victim_name gelegt. Zeit zum Feiern!' WHERE `id`=281;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='%victim_name gekillt! Der Weltenboss war kein Spaß!' WHERE `id`=282;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Gerade %victim_name gekillt, das war legendär' WHERE `id`=283;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Yo, hab gerade %victim_name gekillt!' WHERE `id`=284;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Seltener %victim_name down. War ein geiler Fight' WHERE `id`=285;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Hab gerade den seltenen %victim_name gekillt' WHERE `id`=286;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Seltener %victim_name in %zone_name besiegt' WHERE `id`=287;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Gerade seltenen %victim_name in %zone_name gekillt. Das ging fix!' WHERE `id`=288;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Seltenen %victim_name in %zone_name gekillt' WHERE `id`=289;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Den seltenen %victim_name in %zone_name erwischt' WHERE `id`=290;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Hab %victim_name in %zone_name gekillt. Das tat gut' WHERE `id`=291;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='%victim_name in %zone_name umgehauen. Keine Chance gehabt' WHERE `id`=292;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Gerade %victim_name in %zone_name gekillt, easy' WHERE `id`=293;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Was hab ich da gerade gekillt? %victim_name' WHERE `id`=294;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Was ist das für ein %victim_name? Sowas hab ich noch nie gesehen' WHERE `id`=295;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Hab gerade was Seltsames gekillt, %victim_name' WHERE `id`=296;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='%victim_name war seltsam, aber liegt trotzdem' WHERE `id`=297;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Gerade %victim_name besiegt' WHERE `id`=298;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Machs gut, %victim_name. Warst nur ein Pet' WHERE `id`=299;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Hab gerade das Pet %victim_name umgehauen. Das kam unerwartet.' WHERE `id`=300;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='%victim_name liegt. Vielleicht nächstes Mal, Pet' WHERE `id`=301;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Ding! %my_level' WHERE `id`=302;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Jaaa, ich bin Level %my_level!' WHERE `id`=303;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Gerade aufgelevelt' WHERE `id`=304;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Stufe %my_level!!! Jetzt kann ich Endgame-Content machen' WHERE `id`=309;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Frisch auf Level %my_level, %my_class!!!' WHERE `id`=310;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Noch ein Level: %my_level, %my_race %my_class!' WHERE `id`=311;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Ding! Wieder ein Level up!' WHERE `id`=312;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Jetzt offiziell Level %my_level!' WHERE `id`=313;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Level %my_level, fühl mich jetzt schon stärker!' WHERE `id`=314;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Aufwärts! Level %my_level erreicht' WHERE `id`=315;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Das ging fix, schon Level %my_level!' WHERE `id`=316;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Gerade Level %my_level erreicht, auf gehts!' WHERE `id`=317;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Level %my_level, jetzt kommen die großen Sachen!' WHERE `id`=318;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Level %my_level, ich bin jetzt on fire!' WHERE `id`=319;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Level %my_level voll und weiter!' WHERE `id`=320;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Bin jetzt Level %my_level, was kommt als Nächstes?' WHERE `id`=321;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Level %my_level!!! Es passiert!' WHERE `id`=322;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Gerade Level %my_level erreicht, fühlt sich mega an!' WHERE `id`=323;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Level %my_level und ich fange erst an!' WHERE `id`=324;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Wow, schon Level %my_level, unaufhaltbar!' WHERE `id`=325;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Neue Höhen mit Level %my_level!!!' WHERE `id`=326;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Level %my_level und weiter Vollgas!' WHERE `id`=327;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Level %my_level erreicht, fühlt sich so gut an!' WHERE `id`=329;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Bin jetzt Level %my_level! Los gehts!' WHERE `id`=330;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Level %my_level, noch viel vor mir!' WHERE `id`=331;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Endlich Level %my_level erreicht, ich kann alles!' WHERE `id`=332;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Maxlevel %my_level, Endgame ich komme!' WHERE `id`=333;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Endgame freigeschaltet auf Level %my_level, her damit!' WHERE `id`=335;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Hab Level %my_level erreicht, Zeit zu glänzen!' WHERE `id`=336;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Level %my_level, lasst uns Endgame-Raids machen!' WHERE `id`=337;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Mit Level %my_level hält mich nix mehr auf!' WHERE `id`=338;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Level %my_level, bereit für High-Level-Content!' WHERE `id`=339;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Yes! Level %my_level, %my_class für alles bereit!' WHERE `id`=340;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Level %my_level, Zeit die Welt herauszufordern!' WHERE `id`=341;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Level %my_level erreicht, schnappen wir uns die Elitebosse!' WHERE `id`=342;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Jetzt bin ich Level %my_level, das echte Abenteuer beginnt!' WHERE `id`=343;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Level %my_level! Zeit für ernsthafte Action!' WHERE `id`=344;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Endlich auf Level %my_level! Jetzt zeige ich, was ich kann!' WHERE `id`=346;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Level %my_level ist da! Bereit für die große Liga!' WHERE `id`=347;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Gerade Level %my_level erreicht, macht euch bereit für echte Herausforderungen!' WHERE `id`=348;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Level %my_level voll, Zeit für epischen Content!' WHERE `id`=349;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Frisch auf Level %my_level! Bereit für Endgame-Inis!' WHERE `id`=350;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Jetzt, wo ich Level %my_level bin, ist nichts mehr außerhalb meiner Reichweite!' WHERE `id`=351;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Jetzt ist es offiziell! Level %my_level, Zeit zu dominieren!' WHERE `id`=352;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Level %my_level geschafft! Zeit, der Welt meinen Stempel aufzudrücken!' WHERE `id`=353;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Level %my_level freigeschaltet! Jetzt beginnt der echte Spaß!' WHERE `id`=354;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Level %my_level, und die Welt ist mein Spielplatz!' WHERE `id`=355;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Level %my_level, bereit, der Welt meine Power zu zeigen!' WHERE `id`=356;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Gerade %my_level erreicht, jetzt geh ich all in!' WHERE `id`=357;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Level %my_level, endlich kann ich alles angehen!' WHERE `id`=358;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Level %my_level, fühl mich unaufhaltbar!' WHERE `id`=359;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Gerade Level %my_level erreicht, kanns kaum erwarten ins Endgame zu springen!' WHERE `id`=360;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Gute Arbeit, %other_name. Das hast du dir verdient.' WHERE `id`=361;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Das war mies, %other_name. Ich mags nicht, aber...' WHERE `id`=362;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Glückwunsch, %other_name, du hast den Aufstieg verdient!' WHERE `id`=363;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Verdient, %other_name - willkommen im nächsten Level!' WHERE `id`=364;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Beförderungszeit! %other_name, die hast du dir verdient!' WHERE `id`=366;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Neue Rolle für %other_name! Gut gemacht, weiter so!' WHERE `id`=367;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Dickes Gratz an %other_name, wohlverdiente Beförderung!' WHERE `id`=368;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Applaus für %other_name zur Beförderung!' WHERE `id`=369;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Gratulation an %other_name zur Beförderung! Weiter so!' WHERE `id`=370;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Gratz, %other_name, du steigst auf! Gut gemacht!' WHERE `id`=371;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Noch ein Schritt nach oben für %other_name! Glückwunsch!' WHERE `id`=372;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Harte Entscheidung, aber %other_name, du wurdest degradiert. Zeit, dich zu beweisen!' WHERE `id`=373;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Sorry, %other_name, aber es gibt eine Degradierung. Komm stärker zurück!' WHERE `id`=374;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Leider, %other_name, diesmal eine Degradierung. Beim nächsten Mal packst du es!' WHERE `id`=375;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Schwere Entscheidung, aber %other_name, du wurdest degradiert. Zeit, dich wieder hochzugrinden!' WHERE `id`=376;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Unschön, aber %other_name, vorerst eine Degradierung.' WHERE `id`=377;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Sorry, %other_name, dein Rang wurde gesenkt. Lass uns zusammen härter arbeiten!' WHERE `id`=378;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Eine Degradierung für %other_name... Zeit, sich zu fokussieren und wieder hochzukommen!' WHERE `id`=379;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Nicht das, was wir wollten, aber %other_name, du wurdest degradiert. Lern draus und komm stärker zurück!' WHERE `id`=380;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Harter Moment für %other_name, aber wir wissen, du kommst von der Degradierung zurück!' WHERE `id`=381;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Sorry, %other_name, aber du wurdest degradiert. Zeit für Verbesserungen!' WHERE `id`=382;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Wir wollten das nicht für %other_name, aber es gab eine Degradierung. Zeit, besser zu werden!' WHERE `id`=383;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Frisches Blut gesucht! Tritt der Gilde bei, sei Teil von was Großem!' WHERE `id`=384;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Wir rekrutieren neue Mitglieder! Wenn du bereit bist, schließ dich an - die Gildentür steht offen!' WHERE `id`=385;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Die Gilde sucht fähige Abenteurer. Schließ dich an und geh mit uns ab!' WHERE `id`=386;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Bock auf eine starke Gilde? Wir suchen neue Member! Komm rein!' WHERE `id`=387;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Die Gilde wächst! Join uns für fette Abenteuer und Loot!' WHERE `id`=388;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Wer hat Bock auf %instance_name?' WHERE `id`=389;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Gibts Gruppen für %instance_name?' WHERE `id`=390;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Brauch jemand Hilfe für %instance_name?' WHERE `id`=391;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Suche Gruppe: %instance_name.' WHERE `id`=392;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Braucht wer %my_role für %instance_name?' WHERE `id`=393;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Fehlt %my_role für %instance_name?' WHERE `id`=394;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Ich kann %my_role für %instance_name sein.' WHERE `id`=395;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Braucht ihr %my_role für %instance_name?' WHERE `id`=397;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Braucht wer Gear aus %instance_name?' WHERE `id`=398;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Kleiner Grind in %instance_name?' WHERE `id`=399;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Lust auf %instance_name' WHERE `id`=400;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Bock auf %instance_name.' WHERE `id`=402;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='%my_role sucht Gruppe für %instance_name.' WHERE `id`=403;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Was ist mit %instance_name?' WHERE `id`=404;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Rein in %instance_name?' WHERE `id`=406;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Suche Gruppe für %instance_name.' WHERE `id`=407;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Braucht wer Hilfe bei Quests in %instance_name?' WHERE `id`=408;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Bock auf Quests in %instance_name.' WHERE `id`=409;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Wer hat Quests in %instance_name?' WHERE `id`=410;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='%my_role: Platz in Gruppe für %instance_name?' WHERE `id`=412;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Läuft überhaupt noch jemand %instance_name?' WHERE `id`=413;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='%instance_name: nimmt wer einen %my_role mit?' WHERE `id`=414;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Lohnt es sich als %my_role in %instance_name?' WHERE `id`=415;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Lohnt es sich echt, nach %instance_name zu gehen?' WHERE `id`=416;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Die Bosse in %instance_name droppen gutes Gear. Bock zu grinden?' WHERE `id`=418;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Was ist mit %instance_name?' WHERE `id`=419;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Braucht jemand %my_role?' WHERE `id`=420;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Braucht wer %my_role?' WHERE `id`=421;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Wer hat Bock auf %instance_name?' WHERE `id`=422;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Kann mich jemand bei %instance_name beschwören?' WHERE `id`=423;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Trefft mich in %instance_name' WHERE `id`=424;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Bock auf schnellen %instance_name Run' WHERE `id`=425;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Bock auf kompletten %instance_name Run' WHERE `id`=426;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Wie oft wart ihr schon in %instance_name?' WHERE `id`=427;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Noch ein %instance_name Run?' WHERE `id`=428;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='In %instance_name gewiped? Nehmt lieber mich!' WHERE `id`=429;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Nehmt mich bitte mit nach %instance_name.' WHERE `id`=430;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Wer nimmt %my_role mit nach %instance_name?' WHERE `id`=433;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='LFG %instance_name, bin %my_role' WHERE `id`=434;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='%my_role LFG %instance_name' WHERE `id`=435;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Brauche einen DD für %instance_name' WHERE `id`=437;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Suche einen Heiler für %instance_name' WHERE `id`=438;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Will %instance_name machen. Brauche eine Gruppe!' WHERE `id`=440;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Suche noch einen für %instance_name' WHERE `id`=442;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Will jemand mit nach %instance_name?' WHERE `id`=443;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Interesse an %instance_name?' WHERE `id`=444;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Suche einen schnellen Run durch %instance_name' WHERE `id`=445;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Wer ist dabei für %instance_name?' WHERE `id`=446;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Wollt ihr %instance_name farmen?' WHERE `id`=448;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Will %instance_name abschließen' WHERE `id`=449;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Suche Carry durch %instance_name' WHERE `id`=451;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Laufe %instance_name, suche andere' WHERE `id`=453;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Suche jemanden, der bei %instance_name hilft' WHERE `id`=455;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Brauche %my_role für %instance_name!' WHERE `id`=456;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Bock auf einen %instance_name Run?' WHERE `id`=457;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Brauche %my_role für %instance_name Run' WHERE `id`=458;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Will jemand Gear aus %instance_name farmen?' WHERE `id`=459;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Suche Gruppe für %instance_name Speedrun' WHERE `id`=460;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Brauche Gruppe, um %instance_name zu clearen' WHERE `id`=461;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Interesse, %instance_name zu farmen?' WHERE `id`=462;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Suche etwas Gear aus %instance_name' WHERE `id`=463;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Wer hat Lust auf einen schnellen %instance_name Run?' WHERE `id`=464;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Will jemand %instance_name zusammen angehen?' WHERE `id`=465;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Suche Leute, um %instance_name abzuschließen' WHERE `id`=466;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Kriegen wir eine Gruppe für %instance_name zusammen?' WHERE `id`=467;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Brauche einen schnellen Run für %instance_name' WHERE `id`=468;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Wer hat Lust, %instance_name zusammen zu farmen?' WHERE `id`=469;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Suche noch ein paar Leute für %instance_name' WHERE `id`=470;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Braucht jemand Hilfe bei den Mechaniken in %instance_name?' WHERE `id`=471;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Brauche schnell eine Gruppe für %instance_name' WHERE `id`=472;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Will jemand %instance_name als Speedrun laufen?' WHERE `id`=473;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Suche einen schnellen Abschluss von %instance_name' WHERE `id`=474;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Suche jemanden, der bei %instance_name mitkommt' WHERE `id`=475;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Wer hat Lust, %instance_name zu clearen?' WHERE `id`=476;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Brauche Hilfe beim Endboss von %instance_name' WHERE `id`=477;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Wer hat heute Lust, %instance_name zu laufen?' WHERE `id`=478;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Suche schnellen Run in %instance_name, um etwas Gear zu farmen' WHERE `id`=479;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Will jemand Mats aus %instance_name farmen?' WHERE `id`=480;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Lass uns eine Gruppe für %instance_name machen' WHERE `id`=481;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Braucht wer Hilfe bei %quest_link?' WHERE `id`=482;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Will jemand %quest_link teilen?' WHERE `id`=483;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Macht jemand %quest_link?' WHERE `id`=484;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Bock auf %quest_link.' WHERE `id`=485;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Wer hilft bei %quest_link?' WHERE `id`=487;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Braucht jemand Unterstützung bei %quest_link?' WHERE `id`=488;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Interesse an %quest_link?' WHERE `id`=489;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Will jemand %quest_link abschließen?' WHERE `id`=490;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Braucht wer ein Team für %quest_link?' WHERE `id`=491;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Wer hat Bock auf %quest_link?' WHERE `id`=492;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Will %quest_link machen. Wer ist dabei?' WHERE `id`=497;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Wer ist bereit für %quest_link?' WHERE `id`=499;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Wer will bei %quest_link mitmachen?' WHERE `id`=500;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Wer ist bei %quest_link dabei?' WHERE `id`=501;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Brauche hier etwas Hilfe bei %quest_link.' WHERE `id`=502;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Wer ist bereit, %quest_link zu machen?' WHERE `id`=504;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Suche etwas Hilfe für %quest_link.' WHERE `id`=505;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Braucht jemand Hilfe bei %quest_link?' WHERE `id`=506;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Wer hat Lust, %quest_link abzuschließen?' WHERE `id`=507;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Braucht jemand Unterstützung bei %quest_link?' WHERE `id`=508;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Wer kann bei %quest_link helfen?' WHERE `id`=509;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Suche eine helfende Hand bei %quest_link.' WHERE `id`=510;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Ist jemand bereit für %quest_link?' WHERE `id`=511;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Kann jemand bei %quest_link dazukommen?' WHERE `id`=512;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Suche ein paar Mitstreiter für %quest_link.' WHERE `id`=513;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Will jemand sich für %quest_link zusammentun?' WHERE `id`=514;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Wer muss %quest_link noch abschließen?' WHERE `id`=516;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Will %quest_link abschließen.' WHERE `id`=517;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Wer kann bei %quest_link mitkommen?' WHERE `id`=518;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Interesse, %quest_link abzuschließen?' WHERE `id`=519;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Bock, bei %quest_link zu helfen?' WHERE `id`=520;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Ist jemand bereit, bei %quest_link zu helfen?' WHERE `id`=521;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Brauche jemanden, um %quest_link zu beenden.' WHERE `id`=522;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Will jemand %quest_link beenden?' WHERE `id`=523;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Gibt’s Hilfe für %quest_link?' WHERE `id`=524;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Wer ist dabei für %quest_link?' WHERE `id`=525;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Suche Partner zum Abschließen von %quest_link.' WHERE `id`=526;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Wer hat Lust, %quest_link zu beenden?' WHERE `id`=527;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Heute jemand Interesse an %quest_link?' WHERE `id`=529;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Wer hat jetzt Bock auf %quest_link?' WHERE `id`=531;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Will jemand %quest_link starten?' WHERE `id`=532;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Bitte um Hilfe bei %quest_link.' WHERE `id`=533;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Wer kann mir bei %quest_link helfen?' WHERE `id`=534;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Suche Gruppe für %quest_link.' WHERE `id`=535;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Jemand bereit zum %category farmen?' WHERE `id`=536;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Suche Hilfe beim %category farmen.' WHERE `id`=537;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='%category sind verdammt teuer!' WHERE `id`=538;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Will %category.' WHERE `id`=539;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Kaufe: %category.' WHERE `id`=541;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Interesse an %category?' WHERE `id`=542;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Verkaufe: %category.' WHERE `id`=543;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Will %category farmen.' WHERE `id`=546;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Suche Gruppe fürs %category farmen.' WHERE `id`=547;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='%category sind willkommen.' WHERE `id`=548;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Kaufe alles von %category.' WHERE `id`=549;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Wow, alle farmen %category!' WHERE `id`=550;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='AH ist heiß auf %category.' WHERE `id`=552;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Will etwas %category tauschen.' WHERE `id`=554;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Etwas %category bitte?' WHERE `id`=558;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Hätte wohl den Skill für %category lernen sollen.' WHERE `id`=559;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Ich geiere auf %category.' WHERE `id`=560;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Für %category würden die Leute töten.' WHERE `id`=561;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='%category ist ein Top-Deal!' WHERE `id`=562;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Wo farmt man am besten %category?' WHERE `id`=564;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Bin ready für %category.' WHERE `id`=565;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Ich behalte meine ganzen %category wohl lieber.' WHERE `id`=567;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Brauchst du eine Gruppe? Vielleicht zum %category farmen?' WHERE `id`=568;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Denke immer noch über %category nach.' WHERE `id`=569;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Hab schon von %category gehört, aber meine Taschen sind leer.' WHERE `id`=570;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='LFG für %category' WHERE `id`=571;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Würde mich der Verkauf von %category reich machen?' WHERE `id`=572;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Okay. Ich farme %category morgen.' WHERE `id`=573;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Hab mindestens zehn Leute gesehen, die %category farmen.' WHERE `id`=575;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Hab gestern all meine %category verkauft. Bin komplett pleite!' WHERE `id`=576;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Will einer Gilde joinen, die %category farmt.' WHERE `id`=577;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Verkaufe %category, wer hat Interesse?' WHERE `id`=580;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Verkaufe %category, flüster mir.' WHERE `id`=582;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Brauche %category, verkauft das jemand?' WHERE `id`=584;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Hab %category zu verkaufen, meldet euch!' WHERE `id`=585;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Verkaufe %category, bester Preis am Markt.' WHERE `id`=588;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Suche %category im Tausch gegen %category.' WHERE `id`=589;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Wer braucht %category? Hab was zu verkaufen!' WHERE `id`=591;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Habe %category zu verkaufen, flüster mir für den Preis.' WHERE `id`=592;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Will %category verkaufen, flüster mir für Details.' WHERE `id`=593;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Kaufe: %category. Verkauft das jemand?' WHERE `id`=594;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Suche %category, bitte melden.' WHERE `id`=595;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Wer hat Interesse an %category?' WHERE `id`=596;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Kann jemand beim %category farmen helfen?' WHERE `id`=597;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Will %category kaufen, flüster mir einfach.' WHERE `id`=599;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Suche %category. Wer hat was?' WHERE `id`=600;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Kaufe: %category zum fairen Preis.' WHERE `id`=601;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Brauche dringend %category, hat wer was?' WHERE `id`=602;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Hab %category, verkaufe günstig.' WHERE `id`=603;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Verkaufe %category zum guten Kurs.' WHERE `id`=604;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Suche %category, verkauft wer günstig?' WHERE `id`=605;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Verkauft jemand %category? Hätte Interesse.' WHERE `id`=606;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Brauche %category, flüstert mir wenn ihr verkauft.' WHERE `id`=607;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Hat wer %category übrig zum Tauschen?' WHERE `id`=608;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Hat wer Interesse, %category zu tauschen?' WHERE `id`=610;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Verkaufe %category, meldet euch für Tausch.' WHERE `id`=611;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Kaufe: %category, suche guten Kurs.' WHERE `id`=612;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Wer braucht %category? Hab was übrig.' WHERE `id`=613;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Will wer %category? Verkaufe billig.' WHERE `id`=614;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Suche %category, verkauft wer was?' WHERE `id`=615;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Braucht jemand %category? Hab was zum Tauschen.' WHERE `id`=616;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Kaufe: %category. Ist jemand günstiger als AH?' WHERE `id`=617;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Verkaufe %category billig, flüster mir für Details.' WHERE `id`=618;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Braucht wer %category? Hab was zu verkaufen.' WHERE `id`=619;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Tausche %category gegen was anderes.' WHERE `id`=620;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Hab %category, tausche gegen %category.' WHERE `id`=621;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Kaufe: %category, hat wer was übrig?' WHERE `id`=622;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Farmt wer Ruf bei %faction?' WHERE `id`=623;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Kann wer bei %faction helfen?' WHERE `id`=624;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Hab Bock auf Quests für %faction.' WHERE `id`=625;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='%faction ist die beste Fraktion.' WHERE `id`=626;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Fehlt nur noch ein bisschen bis %rep_level bei %faction.' WHERE `id`=627;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Hat jemand %rep_level bei %faction?' WHERE `id`=628;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Wer will %rep_level bei %faction sein?' WHERE `id`=629;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Ich werde nie %rep_level bei %faction sein.' WHERE `id`=630;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Fehlt jemandem Ruf bei %faction?' WHERE `id`=631;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Kann beim Ruf farmen für %faction helfen.' WHERE `id`=632;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='%faction: brauche %rndK bis %rep_level.' WHERE `id`=634;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Wer kann Quests von %faction teilen?' WHERE `id`=635;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Gibts Inis für %faction?' WHERE `id`=636;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Hab Bock, Ruf bei %faction zu grinden.' WHERE `id`=637;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Lasst uns Ruf bei %faction farmen!' WHERE `id`=638;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Farme Ruf bei %faction.' WHERE `id`=639;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Bock, für %faction zu farmen.' WHERE `id`=640;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Brauche Hilfe bei %faction.' WHERE `id`=641;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Verkauft %faction was Nützliches?' WHERE `id`=642;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Wer farmt für %faction?' WHERE `id`=644;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Wie farmt man %faction am besten?' WHERE `id`=645;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Ich hasse den Rufgrind für %faction.' WHERE `id`=646;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Ich hab %faction so satt.' WHERE `id`=647;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Gehen wir %faction an?' WHERE `id`=648;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Scheint, als wenn alle %rep_level bei %faction sind. Nur ich hänge wie immer hinterher.' WHERE `id`=649;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='LFG für Rufgrind bei %faction?' WHERE `id`=650;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Kann jemand einen guten Spot für Rufgrind bei %faction empfehlen?' WHERE `id`=651;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Bringt mir Ruf bei %faction überhaupt was?' WHERE `id`=652;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Wer hätte gedacht, dass Ruf bei %faction doch noch nützlich ist...' WHERE `id`=653;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Lohnt es sich, meinen Ruf bei %faction zu pushen?' WHERE `id`=655;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Was ist besser für %faction? Quests oder Mobs grinden?' WHERE `id`=656;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Grinde euren Ruf bei %faction, gebt mir nur etwas Gold.' WHERE `id`=657;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Ich glaube, Ruf bei %faction zu grinden dauert ewig.' WHERE `id`=658;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Ich kill jeden Tag für %faction, bin aber noch weit weg von %rep_level.' WHERE `id`=659;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Sinken die AH-Gebühren auf %my_level?' WHERE `id`=660;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Wie viele Fraktionen hast du auf ehrfürchtig?' WHERE `id`=661;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Verdammt. Meine Gilde hat gestern ohne mich gut Ruf bei %faction gegrindet.' WHERE `id`=663;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Keiner will mir helfen, weil ich schon %rep_level bei %faction bin.' WHERE `id`=664;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Bleib bitte weg von %faction.' WHERE `id`=665;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Farmt heute jemand Ruf bei %faction?' WHERE `id`=666;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Helft mir, Ruf bei %faction zu grinden!' WHERE `id`=667;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Ich brauch so dringend %rep_level bei %faction!' WHERE `id`=668;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Lohnt sich der Grind für %faction?' WHERE `id`=669;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Kennt jemand gute Spots für Ruf bei %faction?' WHERE `id`=670;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Ich liebe es, Ruf bei %faction zu grinden!' WHERE `id`=671;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Brauche Hilfe, um den Rufgrind bei %faction abzuschließen!' WHERE `id`=672;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Nur noch ein paar Stufen bis %rep_level bei %faction!' WHERE `id`=673;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Wer hat heute Bock auf Grind für %faction?' WHERE `id`=674;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Suche Mitstreiter für Rufgrind bei %faction!' WHERE `id`=675;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Ich bin das Rufgrinden für %faction leid!' WHERE `id`=676;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Noch wer auf Rufgrind bei %faction?' WHERE `id`=677;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Zeit, den Rufgrind bei %faction richtig anzugehen!' WHERE `id`=678;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Helft mir, den Ruf bei %faction fertig zu machen!' WHERE `id`=679;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Mir fehlen nur noch %rndK für den %faction Ruf!' WHERE `id`=680;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Den ganzen Tag Ruf bei %faction am farmen!' WHERE `id`=681;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Rufgrind bei %faction endet nie!' WHERE `id`=683;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Hilfe bei den Daily-Quests von %faction?' WHERE `id`=684;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Wer ist grad beim Grind für %faction?' WHERE `id`=685;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Lasst uns Quests von %faction zusammen machen!' WHERE `id`=686;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Farmt heute jemand Ruf bei %faction?' WHERE `id`=687;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Brauche Hilfe beim Ruf bei %faction für %rep_level!' WHERE `id`=688;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Wer will mit mir Ruf bei %faction grinden?' WHERE `id`=689;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Kommt mit zum Rufgrind bei %faction!' WHERE `id`=690;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Läuft bei mir beim Rufgrind für %faction!' WHERE `id`=691;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Will jemand Boosts für den Rufgrind bei %faction?' WHERE `id`=692;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Bei %faction fehlt nicht mehr viel bis %rep_level, helft mir doch mal!' WHERE `id`=694;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Bock, mir beim Rufgrind für %faction zu helfen?' WHERE `id`=695;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Farme wieder Ruf bei %faction!' WHERE `id`=696;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Kennt jemand einen guten Spot für Ruf bei %faction?' WHERE `id`=697;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Wie viel fehlt noch beim Rufgrind für %faction?' WHERE `id`=698;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Macht jemand Quests von %faction mit mir?' WHERE `id`=699;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Suche jemand für Rufgrind bis %rep_level bei %faction!' WHERE `id`=700;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Mir fehlen nur noch %rndK Ruf bei %faction!' WHERE `id`=701;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Der Grind für %faction ist brutal!' WHERE `id`=702;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Farmt jemand Ruf bei %faction für %rep_level?' WHERE `id`=703;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Lasst uns den Rufgrind bei %faction zusammen machen!' WHERE `id`=704;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Mehr Ruf bei %faction, mehr Belohnungen!' WHERE `id`=705;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Farme Ruf bei %faction als %my_class' WHERE `id`=706;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Hängt noch jemand bei %faction auf %rep_level fest?' WHERE `id`=707;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Die ganze Nacht Rufgrind bei %faction!' WHERE `id`=708;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Wer will den Rufgrind bei %faction mit mir abschließen?' WHERE `id`=709;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Ich kann beim Rufgrind für %faction helfen!' WHERE `id`=710;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Bereit für mehr Rufgrind bei %faction!' WHERE `id`=711;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Bock zu helfen beim Ruf für %faction? Ich brauch das dringend!' WHERE `id`=712;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Ich brauche noch %rndK für den Ruf bei %faction!' WHERE `id`=713;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Farmt mit mir für Ruf bei %faction!' WHERE `id`=714;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Mir fehlen nur noch %rndK Ruf bei %faction!' WHERE `id`=715;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Der Rufgrind bei %faction nimmt kein Ende...' WHERE `id`=716;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Hat jemand Items für Rufboost bei %faction?' WHERE `id`=717;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Farmt jemand Ruf bei %faction für Mounts?' WHERE `id`=719;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Chance, mit mir Ruf bei %faction zu farmen?' WHERE `id`=720;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Ich bin so kurz vor %rep_level bei %faction!' WHERE `id`=721;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Helft mir, %rep_level bei %faction zu erreichen!' WHERE `id`=722;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Ich bin dabei, den %faction Rufgrind abzuschließen!' WHERE `id`=723;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Brauche Hilfe beim Rufgrind für %faction!' WHERE `id`=724;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Wer kann mit mir Ruf bei %faction farmen?' WHERE `id`=726;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Rufgrind bei %faction non-stop!' WHERE `id`=727;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Wer grindet gerade noch Ruf bei %faction?' WHERE `id`=728;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Will jemand zum Spaß Ruf bei %faction farmen?' WHERE `id`=729;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Ich muss noch Ruf bei %faction farmen, um neue Quests freizuschalten!' WHERE `id`=730;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Bock, Ruf bei %faction für Belohnungen zu grinden!' WHERE `id`=731;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Tag für Tag, Rufgrind bei %faction!' WHERE `id`=732;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Will jemand beim Rufgrind für %faction helfen?' WHERE `id`=733;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Helft mir, mit Ruf bei %faction Belohnungen freizuschalten!' WHERE `id`=734;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Ich grinde Ruf bei %faction für Mounts!' WHERE `id`=735;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Kommt mit, Ruf bei %faction farmen!' WHERE `id`=736;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Beim Rufgrind für %faction bin ich fast da!' WHERE `id`=737;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Grinde Ruf bei %faction mit meinen Leuten!' WHERE `id`=738;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Hab Bock auf Party in %zone_name.' WHERE `id`=739;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Sucht jemand %my_role?' WHERE `id`=740;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='%my_role sucht Gilde.' WHERE `id`=741;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='%my_role will einer guten Gilde beitreten.' WHERE `id`=743;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Fühlt sich noch wer einsam?' WHERE `id`=745;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Wer will was abhaben?' WHERE `id`=747;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Kommt her und holt mich!' WHERE `id`=748;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Macht hier grade jemand etwas?' WHERE `id`=750;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='%zone_name: ist hier jemand?' WHERE `id`=751;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='%zone_name: Wo sind alle?' WHERE `id`=752;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Scheint als wäre ich allein in %zone_name.' WHERE `id`=753;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Trefft mich in %zone_name.' WHERE `id`=754;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='%zone_name ist der beste Spot!' WHERE `id`=756;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Will nach %zone_name. Kommt wer mit?' WHERE `id`=757;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Ich mag %zone_name nicht, aber wohin sonst?' WHERE `id`=759;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Gibt’s gute Quests in %zone_name?' WHERE `id`=760;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='%zone_name ist der übelste Spot.' WHERE `id`=764;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Schnappt mich in %zone_name!' WHERE `id`=765;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Ab nach %zone_name!' WHERE `id`=766;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Bock zu questen in %zone_name' WHERE `id`=767;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Hat wer Quests in %zone_name?' WHERE `id`=768;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Kommt her nach %zone_name!' WHERE `id`=769;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Sieht so aus, als wär keine Horde in %zone_name' WHERE `id`=770;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Sieht so aus, als wär keine Allianz in %zone_name' WHERE `id`=771;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Ich bin echt müde von %zone_name. Vielleicht sollte ich woanders hin?' WHERE `id`=772;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Ich will nach Hause und dann in die Kiste.' WHERE `id`=774;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Weiß wer, was man fürs Beidhändig-Kämpfen braucht?' WHERE `id`=775;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='hi zusammen!' WHERE `id`=776;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='%zone_name ist gemütlich' WHERE `id`=777;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Ich fühl mich super' WHERE `id`=778;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Ich ignoriere Leute nicht, ich trolle sie, bis sie mich ignorieren' WHERE `id`=779;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='schön zu sehen, dass der Chat sich noch erinnert' WHERE `id`=781;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Wie jede Waffe ist es Jäger-BiS' WHERE `id`=782;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='für mich geht es im Spiel nur ums Solo-Spielen und darum, neue Wege zu finden, Dinge solo zu machen' WHERE `id`=783;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='ich habe NIEMANDEN jemals abgezockt' WHERE `id`=784;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Zeit, mir den Weg nach %zone_name freizukämpfen' WHERE `id`=787;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='ich muss kacken' WHERE `id`=789;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Wenn du deine häutbaren Kills nicht lootest, schrumpft dein Schniedel jedes mal dauerhaft um 1mm' WHERE `id`=790;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='NEEEEEEEEEEEEIN' WHERE `id`=791;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='ICH MAG ZÜGE' WHERE `id`=792;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='/w mir im chat' WHERE `id`=793;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='hi, wie geht es euch' WHERE `id`=794;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='hab mich grad ausgeloggt und wieder eingeloggt' WHERE `id`=795;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='könnt ihr mal leiser sein, ich hab mich in %zone_name verlaufen' WHERE `id`=796;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='wer will mit mir was trinken in %zone_name ...hicks!' WHERE `id`=797;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Früher war der Bait glaubwürdiger.' WHERE `id`=799;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='vielleicht hast du einfach deine Unschuld verloren' WHERE `id`=800;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Gibts hier Gilden, die %my_role mitziehen?' WHERE `id`=801;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Sobald man höher kommt, ist Gold easy zu machen' WHERE `id`=802;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='moin' WHERE `id`=803;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Warum tut mir der Arsch weh?' WHERE `id`=804;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Ich hab das Gefühl, Willenskraft ist BiS zum Leveln' WHERE `id`=805;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='bei Trollen erst recht' WHERE `id`=806;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='KANN MICH JEMAND INVITEN' WHERE `id`=807;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='brauche viele Drinks' WHERE `id`=808;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='verdammte Gnome' WHERE `id`=809;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='niemand mag Gnome' WHERE `id`=810;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Gnome taugen nur für eins' WHERE `id`=811;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='nun ja' WHERE `id`=812;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='selbstständige Gedanken sind schon gruselig' WHERE `id`=814;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='der Geist ist formbarer, als man glaubt' WHERE `id`=815;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='gibts hier Levelgilden?' WHERE `id`=816;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='brb' WHERE `id`=817;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='warum ist Schnee weiß, aber Eis klar? ist doch das Gleiche' WHERE `id`=818;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='warum ist Schlagsahne fluffig und normale nicht' WHERE `id`=819;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='warum riechen Füße, wenn sie keine Nase haben' WHERE `id`=820;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='scheint als hätte jemand ne Dose Neulinge aufgemacht' WHERE `id`=821;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='hört auf, Neulinge mit Bullshit-Antworten zu trollen' WHERE `id`=822;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='gibts hier auf dem Server PvP?' WHERE `id`=823;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='eh klar' WHERE `id`=824;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='puh... :)' WHERE `id`=825;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='wusstet ihr schon, dass...' WHERE `id`=826;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Ich stell mir lieber nicht vor, wie sich die Viecher fühlen, während ich sie umboxe.' WHERE `id`=827;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='ups, falscher Chat' WHERE `id`=828;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='bruh, ihr dreht heute völlig durch' WHERE `id`=829;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Nett hier. Aber waren Sie schon mal in Darnassus?' WHERE `id`=830;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='grrr wütend' WHERE `id`=831;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='der Grind macht Spaß' WHERE `id`=832;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='WoW hält mich wachsam' WHERE `id`=833;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='kurze Frage: wo krieg ich den Buff für mehr XP? bin in %zone_name' WHERE `id`=834;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='mögt ihr Würstchen?' WHERE `id`=835;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='inv mich. ich helfe' WHERE `id`=836;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='welche Klasse ist gut für PvP?' WHERE `id`=837;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='wo zum Teufel ist der Kochlehrer in %zone_name' WHERE `id`=838;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='wisst ihr, was in %zone_name abgeht?' WHERE `id`=839;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='muss was craften' WHERE `id`=840;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Bock auf Blödsinn in %zone_name?' WHERE `id`=841;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='machen wir %zone_name zu unserem Spielplatz' WHERE `id`=842;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='ich verirr mich gleich wieder in %zone_name' WHERE `id`=843;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='kaum zu glauben, dass ich immer noch in %zone_name hocke' WHERE `id`=844;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='lasst uns die Mailbox in %zone_name raiden!' WHERE `id`=846;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='ich schwöre, in %zone_name wimmelt es von Trollen' WHERE `id`=847;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='lasst uns zusammen Chaos in %zone_name anrichten' WHERE `id`=848;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='hab Bock, in %zone_name absolut gar nix zu machen' WHERE `id`=849;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='in %zone_name hört eh keiner zu' WHERE `id`=850;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='ist %zone_name überhaupt real oder wie Bielefeld?' WHERE `id`=851;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='schickt mal wer Hilfe nach %zone_name! ist wild hier!' WHERE `id`=852;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='ich bin sicher, in %zone_name spukt es' WHERE `id`=853;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='wenn %zone_name reden könnte, würde es wahrscheinlich schreien' WHERE `id`=854;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='irgendwas ist faul an %zone_name' WHERE `id`=855;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='gleich zerleg ich %zone_name mit meiner Awesomeness' WHERE `id`=856;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='sagt %zone_name, dass ich da bin' WHERE `id`=857;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='ich hab mich in %zone_name verlaufen, sendet Hilfe' WHERE `id`=858;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='ich starte ne Revolution in %zone_name' WHERE `id`=859;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='findet noch wer %zone_name verdächtig ruhig?' WHERE `id`=860;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='ich wette, %zone_name hat Geheimnisse, von denen wir nix wissen' WHERE `id`=861;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='%my_race kann man in %zone_name nie genug haben' WHERE `id`=862;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='langsam glaube ich, %zone_name ist nur ein Mythos' WHERE `id`=863;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='wer hätte gedacht, dass %zone_name so abgeht?' WHERE `id`=864;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='als wäre das Spiel in %zone_name kaputt' WHERE `id`=865;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='ist %zone_name eigentlich ne Wüste, oder bin ich einfach nur lost?' WHERE `id`=866;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='fühlt sich langsam an wie %zone_name im Mixer' WHERE `id`=867;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='hat jemand ne Karte für %zone_name?' WHERE `id`=868;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Noch wer, der denkt das %zone_name uns umbringen will?' WHERE `id`=869;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Ich bin auf wilder Fahrt durch %zone_name!' WHERE `id`=870;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Bin das nur ich, oder wird %zone_name immer weirder?' WHERE `id`=871;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Ich bin davon überzeugt, das %zone_name heimlich ein Freizeitpark ist.' WHERE `id`=872;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Tastatur kaputt... wahrscheinlich wieder zu wenig Freunde.' WHERE `id`=873;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Glaubt ihr, die Bäume in dem Spiel haben Gefühle?' WHERE `id`=874;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Ich drücke immer dieselbe Taste, aber ich gewinne trotzdem nicht' WHERE `id`=875;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='ich wette, ich könnte nen Raid gewinnen, in dem ich einfach nur LOOT schreie' WHERE `id`=876;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='versuche seit einer Stunde, auf mein Mount zu steigen, nix passiert' WHERE `id`=877;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='gibt es nen Weg, unverwundbar zu werden, ohne wirklich zu spielen?' WHERE `id`=878;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='kann ich einfach random Tasten smashen und trotzdem gewinnen? frage für nen Freund' WHERE `id`=879;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Wenn ich einfach stehen bleibe, dann bin ich immer noch besser als du!' WHERE `id`=880;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='warum heilt mich mein Pet nicht wenn ich im Feuer stehe' WHERE `id`=881;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='brauch ich Rüstung, um ein echter wahrer Held zu sein, oder ist das optional?' WHERE `id`=882;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Muss ich erst 10.000 Koboldkerzen klauen, um zu leveln, oder was?' WHERE `id`=883;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='meine Waffe ist kaputt, kann ich Gegner noch mit meinem riesigen Schw... äh, meiner Faust klatschen?' WHERE `id`=884;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='können wir das Spiel bitte in World of DieCraft umbenennen, ein Spieler killt mich dauernd' WHERE `id`=885;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Warum fliegt mein Pferd nicht? kann es nicht einfach nach oben gehen?' WHERE `id`=886;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Gibts ne Option, die Grafik auszumachen, damit es aussieht wie mein alter Taschenrechner?' WHERE `id`=887;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='ich sollte was killen, bin aber eingepennt, ist das normal?' WHERE `id`=888;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='killt noch wer random NPCs zum Spaß, oder bin das nur ich?' WHERE `id`=889;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='ich bin %my_level und kenn schon alle Geheimnisse des Spiels' WHERE `id`=890;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='kann ich einfach so lange mit NPCs reden, bis sie mir ihren ganzen Loot einfach geben?' WHERE `id`=891;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='warum verliere ich, ich spiel doch schon 15 Minuten' WHERE `id`=893;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Ich brauch keine Strategie, ich spam einfach diese Fähigkeit und hoffe aufs Beste' WHERE `id`=894;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='wenn ich haufenweise Glücksbringer anlege, krieg ich dann mehr Loot?' WHERE `id`=895;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Ist das Geheimnis dieses Spiels einfach, den Bildschirm anzuschreien?' WHERE `id`=896;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Kann ich einfach jedes Item anziehen, das ich finde, und aufs Beste hoffen?' WHERE `id`=897;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Muss ich echt Quests machen oder kann ich einfach erkunden und Leute anbrüllen?' WHERE `id`=898;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='ich zocke auf Arbeit, die sagen ich soll arbeiten >.> aber es ist WoW!' WHERE `id`=899;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='wenn ich alles Essen im Spiel esse, werd ich dann unbesiegbar' WHERE `id`=900;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Also, ich werfe mein Pet einfach in jeden Bosskampf und drücke beim würfeln immer auf Gier, das sind die Hunter-Regeln.' WHERE `id`=901;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='kann man sterben, wenn man schon tot ist? Ich frage für nen Geist...' WHERE `id`=902;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='weiß jemand, wo das legendäre Schwert ist? hab schon 5 Minuten gesucht' WHERE `id`=903;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Man sagte mir, hier gibts 100.000 Gold, wo muss ich hin?' WHERE `id`=904;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='ich spiel das hier wie ich deine Mom letzte Nacht genommen hab - mit Geschrei und einem ruhmreichem Ende!' WHERE `id`=905;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='ab wann wirds Spaß, oder ist alles nur für immer Grind' WHERE `id`=906;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='ich frage ständig nach dem Weg, aber sie schicken mich immer irgendwo hin, ist das normal?' WHERE `id`=907;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='hab gehört, wenn du ALT+F4 drückst, kriegst du 100.000 Gold - Der Trick ist, vorher nen roten NPC anzugreifen' WHERE `id`=908;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='warum sieht mein Char immer so verwirrt aus, bin ich schuld?' WHERE `id`=909;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='hey, deine Mom meinte, du sollst jetzt ins Bett!' WHERE `id`=910;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Warcraft ist ein Grind - genau wie deine Mom neulich, hat sogar Abo!' WHERE `id`=911;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='stimmt es, dass Chuck Norris mal gelevelt hat, ohne nen Knopf zu drücken' WHERE `id`=912;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Chuck Norris braucht kein Mount, der Boden bewegt freiwillig sich unter ihm' WHERE `id`=913;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='wenn Chuck Norris nen Raid betritt, gibt der Boss einfach auf' WHERE `id`=914;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Chuck Norris nutzt keine Fähigkeiten, er guckt nur - und die Gegner sterben' WHERE `id`=915;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Chuck Norris braucht keine Heilung, seine Feinde heilen ihn aus Respekt' WHERE `id`=916;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Chuck Norris kann nen Raid solo... ohne Gear... und AFK' WHERE `id`=917;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Chuck Norris weicht nicht aus, das Spiel weicht ihm aus' WHERE `id`=918;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Chuck Norris nutzte mal ne Lowlevel-Waffe - das Spiel gab ihm den besten Loot' WHERE `id`=919;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='wenn Chuck Norris eine Ini betritt, landet der Loot automatisch in seinem Inventar' WHERE `id`=920;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='was ist Wilma' WHERE `id`=921;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Bist du aus Bayern?' WHERE `id`=922;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Wilma lecken' WHERE `id`=923;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Dann leck mir an den Eiern.' WHERE `id`=924;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='ICH FRESS NEN ARSCH' WHERE `id`=925;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='ich will mir %random_inventory_item_link in den Arsch schieben' WHERE `id`=926;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='ich will dir %random_inventory_item_link in den Arsch schieben' WHERE `id`=927;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Darnarschloch' WHERE `id`=928;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Du leidest an mehr Bugs als das Spiel selbst!' WHERE `id`=929;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Du hast Chefkochs salzige Schokobällchen im Mund!' WHERE `id`=930;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='cooler Ständer, Bro' WHERE `id`=931;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='hab alles probiert, am Ende hats ERP gerichtet' WHERE `id`=933;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='ich will in %zone_name bumsen' WHERE `id`=934;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='suche weiblichen Gnom mit Gorilla-Pet für ERP in %zone_name' WHERE `id`=935;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='ein Arschloch versteh ich, aber nen Perversen?' WHERE `id`=936;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Kein Gyat in %zone_name, nur Gesichtseintopf so weit das Auge reicht.' WHERE `id`=937;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='ich kill alle Tiere in %zone_name. Scheiß auf Tiere und die PETA!!!' WHERE `id`=938;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Nur gut, dass ich 3 Beine hab' WHERE `id`=939;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Chill, ich bin einfach grad komplett in meinem Film.' WHERE `id`=940;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Finger im Po Mexiko' WHERE `id`=941;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Das hast du irgendwie vergeigt, beeindruckend' WHERE `id`=942;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='das könnte ich blind machen, muss ich aber nicht' WHERE `id`=943;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='sicher, dass du weißt, wie man das Spiel spielt?' WHERE `id`=944;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='als würdest du absichtlich verlieren' WHERE `id`=945;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='hab schon bessere Plays von Level-1-Chars gesehen' WHERE `id`=946;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='du bist hier wie ein Speedbump' WHERE `id`=947;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='vielleicht suchst du dir lieber ein anderes Hobby' WHERE `id`=948;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='dein Gameplay ist wie Farbe beim Trocknen zusehen' WHERE `id`=949;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='mein Twink könnte dich da durch carrien' WHERE `id`=950;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='trollst du uns, oder bist du ernsthaft so?' WHERE `id`=951;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Ich glaub, das Gegnerteam läuft besser, wenn du bei uns bist' WHERE `id`=952;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='spiel vielleicht mal das Spiel statt nur die Landschaft zu bestaunen' WHERE `id`=953;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='ich glaube, du hast da jede einzelne Fähigkeit verfehlt' WHERE `id`=954;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='bist du lost oder stellst du dich nur dumm?' WHERE `id`=955;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Level-1-Chars nehmen weniger Schaden als das' WHERE `id`=956;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='das war für uns beide peinlich' WHERE `id`=957;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Hab schon besseres Teamplay in nem Solo-Game gesehen' WHERE `id`=958;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='ich stell mich mal hinten hin und schau dir beim Failen zu' WHERE `id`=959;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='dachtest du wirklich, das wäre ne gute Idee?' WHERE `id`=960;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='kaum zu glauben, dass du diese simple Aufgabe verkackt hast' WHERE `id`=961;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='bist du hier, um zu helfen, oder nur um Zeit zu verschwenden?' WHERE `id`=962;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='gut, dass ich da bin, um das Team zu schützen' WHERE `id`=963;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='ich schwöre, du machst es schwerer als nötig' WHERE `id`=964;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='wie schaffst du es, die simpelsten Sachen zu failen?' WHERE `id`=965;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='vielleicht mal lieber nur zuschauen, statt das zu tun was du spielen nennst' WHERE `id`=966;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='du könntest dich wenigstens bemühen, so zu tun, als wärst du gut' WHERE `id`=967;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='mach so weiter und wir sitzen hier den ganzen Tag' WHERE `id`=968;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='ehrlich, das war die schlechteste Entscheidung ever' WHERE `id`=969;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='ich glaub, dieses Spiel ist nix für dich' WHERE `id`=970;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='was sollte dieser Move?' WHERE `id`=971;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='du bist ne Last fürs Team' WHERE `id`=972;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='du denkst echt, du bist ein Pro, was?' WHERE `id`=973;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='vielleicht einfach quitten und uns allen den Stress sparen' WHERE `id`=974;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='%prefix %random_taken_quest_or_item_link' WHERE `id`=975;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='%prefix %random_inventory_item_link' WHERE `id`=976;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='%thunderfury_link' WHERE `id`=977;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='%thunderfury_link%thunderfury_link' WHERE `id`=978;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='%thunderfury_link%thunderfury_link%thunderfury_link' WHERE `id`=979;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='ich glaube, ich hab gerade %thunderfury_link gehört' WHERE `id`=980;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='ich glaub, ich habe %thunderfury_link gehört' WHERE `id`=981;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='ich hab definitiv %thunderfury_link gehört' WHERE `id`=982;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='kein Plan, aber ich bin ziemlich sicher, das ich %thunderfury_link gehört habe' WHERE `id`=983;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='hast du gerade %thunderfury_link gesagt' WHERE `id`=984;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='hat jemand %thunderfury_link gesagt' WHERE `id`=985;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='hat jemand %thunderfury_link gesagt?' WHERE `id`=986;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='jemand hat %thunderfury_link gesagt' WHERE `id`=987;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='%thunderfury_link kommt aus dem Schrank' WHERE `id`=988;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='ich schwöre, es war %thunderfury_link, könnte aber auch %thunderfury_link gewesen sein' WHERE `id`=989;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='warum %thunderfury_link nutzen, wenn %thunderfury_link offensichtlich viel stärker ist' WHERE `id`=990;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='hab ich gerade %thunderfury_link gehört?' WHERE `id`=991;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='niemals... hör ich da echt %thunderfury_link?' WHERE `id`=992;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='%thunderfury_link? klingt nach was, das nur Legenden führen!' WHERE `id`=993;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='ich spüre die Macht von %thunderfury_link in der Luft!' WHERE `id`=994;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='%thunderfury_link ist der *echte* MVP' WHERE `id`=995;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='kann mir jemand ne %thunderfury_link besorgen? frage für einen Freund... vielleicht zwei!' WHERE `id`=996;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='hat %thunderfury_link da gerade was *gesmitet*? ich schwöre, der Boden hat gewackelt' WHERE `id`=997;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='%thunderfury_link auf dem Schlachtfeld... Das ist purer Flex' WHERE `id`=998;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='ich *glaube*, ich hab %thunderfury_link gehört... oder war das nur ein Mythos?' WHERE `id`=999;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='hab ich gerade jemanden mit %thunderfury_link gesehen?!' WHERE `id`=1000;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Bin zu 99% sicher, das war %thunderfury_link. Zu 1% wars vielleicht nur ein random NPC.' WHERE `id`=1002;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='%thunderfury_link in Aktion! Wer braucht ne Armee, mit so einer Power?' WHERE `id`=1003;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Hab gehört, %thunderfury_link lockt alle Jungs an.' WHERE `id`=1004;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Warum überhaupt %thunderfury_link nutzen, wenn %thunderfury_link klar die bessere Option ist?' WHERE `id`=1005;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Bin das nur ich, oder hat %thunderfury_link nen passiven „Trash-Talk“-Effekt?' WHERE `id`=1006;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Dachte, ich hätte %thunderfury_link gehört, war aber nur der Klang reiner Awesomeness.' WHERE `id`=1007;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Oh, %thunderfury_link... Wo *warst* du mein ganzes Leben?' WHERE `id`=1008;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Hat jemand %thunderfury_link gesagt? Ich glaub, ich hol mir mal meine.' WHERE `id`=1009;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Das war definitiv der Sound von %thunderfury_link! Ich spür die Epicness.' WHERE `id`=1010;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Geht das nur mir so, oder lässt %thunderfury_link alle anderen *schwach aussehen*?' WHERE `id`=1011;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Wie man so sagt... je lauter %thunderfury_link, desto größer das Recht zu prahlen!' WHERE `id`=1012;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='VK: %item_formatted_link für %cost_gold.' WHERE `id`=1013;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Will wer %item_formatted_link? Nur %cost_gold.' WHERE `id`=1015;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Lächerlicher Preis: %cost_gold für %item_formatted_link!' WHERE `id`=1019;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Will %item_formatted_link für %cost_gold verkaufen.' WHERE `id`=1020;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='%item_formatted_link ist Wertvoll, aber ich würd es für %cost_gold verkaufen.' WHERE `id`=1024;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Billiger als %cost_gold kriegst du %item_formatted_link nicht!' WHERE `id`=1025;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Brauche mehr als %item_formatted_link!' WHERE `id`=1026;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Habe %item_formatted_link und brauche mehr.' WHERE `id`=1027;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Habe %item_formatted_link. Wer kauft für %cost_gold?' WHERE `id`=1028;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Wie wärs mit %item_formatted_link? Für %cost_gold.' WHERE `id`=1030;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Wer meinte, ich bin ein Bastard? %item_formatted_link für %cost_gold ist ein guter Preis!' WHERE `id`=1031;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Verkaufe %item_formatted_link? Nur %cost_gold.' WHERE `id`=1032;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='LFG zum Farmen. %item_formatted_link gibts von mir noch für %cost_gold.' WHERE `id`=1033;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Heute fast alles verkauft. %item_formatted_link hab ich noch für %cost_gold.' WHERE `id`=1034;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Wozu Handelschat? Klar, um %item_formatted_link für %cost_gold zu verkaufen.' WHERE `id`=1035;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Kann jemand den Preis %cost_gold für %item_formatted_link unterbieten?' WHERE `id`=1036;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Wollt ihr den Handelschat stoppen? Kauft einfach %item_formatted_link! Für %cost_gold!' WHERE `id`=1037;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Alle spammen im Handelschat. Ich auch - %cost_gold für %item_formatted_link!' WHERE `id`=1038;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Taugt %item_formatted_link was? Verkaufe es für %cost_gold.' WHERE `id`=1039;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Hab %item_formatted_link, verkaufe an dich für %cost_gold.' WHERE `id`=1040;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Gestern nix geschafft, aber %item_formatted_link bekommen. Verkaufe für %cost_gold.' WHERE `id`=1041;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Gestern gefarmt und %item_formatted_link gezogen. Will jemand für %cost_gold kaufen?' WHERE `id`=1042;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Gestern %item_formatted_link gekauft. Brauchts wer für %cost_gold?' WHERE `id`=1043;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Wer hatte %item_formatted_link gesucht? Preis bleibt - %cost_gold.' WHERE `id`=1044;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Hab immer noch %item_formatted_link. Kauft wer für %cost_gold?' WHERE `id`=1045;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Früher war ich besser bei Kasse. Jetzt verkauf ich %item_formatted_link für %cost_gold.' WHERE `id`=1046;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Ich Wünschte, ich hätte mehr als %item_formatted_link. Kaufen könnt ihrs trotzdem für %cost_gold.' WHERE `id`=1047;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Wozu ist euer Gold gut? Um mein %item_formatted_link für %cost_gold zu kaufen.' WHERE `id`=1048;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Gönnt mir etwas Gold. Kauft %item_formatted_link für %cost_gold.' WHERE `id`=1049;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Sind %cost_gold ein guter Preis für %item_formatted_link?' WHERE `id`=1050;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Hab gestern erst %item_formatted_link gekauft, brauch es aber nicht mehr. Will wer für %cost_gold?' WHERE `id`=1051;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Stell %item_formatted_link gleich ins AH, aber ihr könnts jetzt günstiger haben: nur %cost_gold.' WHERE `id`=1052;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Warum zum #!@ hab ich %item_formatted_link gekauft? Brauchts wer für %cost_gold?' WHERE `id`=1053;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='VK: %item_formatted_link für %cost_gold.' WHERE `id`=1054;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Will wer %item_formatted_link? Nur %cost_gold.' WHERE `id`=1056;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='VK: %item_formatted_link für %cost_gold. flüster mir bei Interesse.' WHERE `id`=1060;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Muss %item_formatted_link loswerden, %cost_gold oder bestes Angebot.' WHERE `id`=1061;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='%item_formatted_link für %cost_gold verfügbar. Schlagt zu!' WHERE `id`=1062;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Habe %item_formatted_link, will %cost_gold.' WHERE `id`=1063;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Verkaufe %item_formatted_link, nur %cost_gold.' WHERE `id`=1064;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Will jemand %item_formatted_link für %cost_gold? flüster mir!' WHERE `id`=1065;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Verkaufe %item_formatted_link für %cost_gold, greift zu solange es geht!' WHERE `id`=1066;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='%item_formatted_link für %cost_gold, schnell sein bevor es weg ist!' WHERE `id`=1067;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Verkaufe %item_formatted_link für %cost_gold, wer zuerst kommt wird auch zuerst bedient!' WHERE `id`=1069;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Nur %cost_gold für %item_formatted_link, nur für kurze Zeit!' WHERE `id`=1070;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='%item_formatted_link für %cost_gold verfügbar, meldet euch wenn ihrs braucht!' WHERE `id`=1071;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Interesse an %item_formatted_link für %cost_gold?' WHERE `id`=1072;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Verkaufe %item_formatted_link für %cost_gold, muss meine Taschen leeren.' WHERE `id`=1073;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Hol dir %item_formatted_link für %cost_gold, Top-Deal!' WHERE `id`=1074;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='%item_formatted_link für %cost_gold, greift zu solange der Vorrat reicht!' WHERE `id`=1075;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Verkaufe %item_formatted_link für %cost_gold, nicht verpassen!' WHERE `id`=1076;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Nur %cost_gold für %item_formatted_link, flüster mir für Details!' WHERE `id`=1077;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='%item_formatted_link gibts für %cost_gold, lasst uns handeln!' WHERE `id`=1078;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Verkaufe %item_formatted_link für %cost_gold, flüster mir für Infos.' WHERE `id`=1079;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Will %item_formatted_link verkaufen, für %cost_gold gehört es dir!' WHERE `id`=1080;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Verkaufe %item_formatted_link, nur %cost_gold.' WHERE `id`=1081;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Hab %item_formatted_link für %cost_gold, machen wir nen Deal!' WHERE `id`=1082;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Verkaufe %item_formatted_link, für %cost_gold nimmst du es mit!' WHERE `id`=1083;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='VK: %item_formatted_link für %cost_gold, Interesse?' WHERE `id`=1084;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Muss %item_formatted_link schnell loswerden, %cost_gold.' WHERE `id`=1085;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Verkaufe %item_formatted_link für %cost_gold, bester Preis weit und breit!' WHERE `id`=1086;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='%item_formatted_link für %cost_gold, machen wirs fix!' WHERE `id`=1088;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Verkaufe %item_formatted_link für %cost_gold, schnappt zu bevor alles weg ist!' WHERE `id`=1089;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Willst %item_formatted_link? Für %cost_gold kriegst du eins!' WHERE `id`=1090;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Ich habe auch %quest_links' WHERE `id`=1093;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Ich habe auch %quest_links, bin gerade in %zone_name' WHERE `id`=1094;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='%other_name, ich habe auch %quest_links' WHERE `id`=1095;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='%other_name, ich habe auch %quest_links, bin gerade in %zone_name' WHERE `id`=1096;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Bin bereit für %quest_links, bin gerade in %zone_name' WHERE `id`=1097;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Bin bereit für %quest_links, bin %my_role' WHERE `id`=1098;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='%other_name, bin bereit für %quest_links, bin gerade in %zone_name' WHERE `id`=1099;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='%other_name, bin bereit für %quest_links, bin %my_role' WHERE `id`=1100;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Braucht wer %quest_links? Bin in %zone_name.' WHERE `id`=1101;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Suche mehr %quest_links in %zone_name.' WHERE `id`=1102;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Will jemand %quest_links mit mir in %zone_name machen?' WHERE `id`=1104;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Habe %quest_links, suche Gruppe in %zone_name.' WHERE `id`=1105;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='%my_role sucht Gruppe, um %quest_links in %zone_name zu erledigen.' WHERE `id`=1108;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Ich brauche %quest_links, ist jemand in %zone_name frei?' WHERE `id`=1109;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Mach %quest_links in %zone_name, brauche mehr Hilfe.' WHERE `id`=1111;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Gibt’s %my_role mit Interesse an %quest_links in %zone_name?' WHERE `id`=1112;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Hilfe benötigt für %quest_links in %zone_name, mir ist langweilig.' WHERE `id`=1113;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Habe %quest_links, %my_role in %zone_name, wer ist dabei?' WHERE `id`=1114;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Macht grad jemand %quest_links? Bin in %zone_name.' WHERE `id`=1116;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='%quest_links offen in %zone_name, wer möchte?' WHERE `id`=1117;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Bereit für %quest_links in %zone_name, suche Gruppe.' WHERE `id`=1118;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Brauche %quest_links und Gesellschaft, jemand in %zone_name?' WHERE `id`=1119;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Wer kommt mit mir nach %zone_name für %quest_links?' WHERE `id`=1120;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Irgend ein %my_role frei für %quest_links in %zone_name?' WHERE `id`=1121;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Habe %quest_links und bin %my_role, brauche mehr Leute in %zone_name.' WHERE `id`=1122;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Bin %my_role und habe %quest_links, suche Gruppe in %zone_name.' WHERE `id`=1124;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Brauche Hilfe bei %quest_links in %zone_name, ist ein %my_role frei?' WHERE `id`=1125;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Hat ein %my_role Lust, %quest_links mit mir in %zone_name zu machen?' WHERE `id`=1126;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Lasst uns %quest_links zusammen in %zone_name abschließen.' WHERE `id`=1127;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Bin in %zone_name und habe %quest_links, wer will mit?' WHERE `id`=1128;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Suche mehr %my_role, um %quest_links in %zone_name abzuschließen.' WHERE `id`=1129;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Habe %quest_links und brauche %my_role in %zone_name.' WHERE `id`=1130;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Wer hat Bock auf %quest_links? Ich bin %my_role in %zone_name.' WHERE `id`=1131;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Suche Gruppe für %quest_links in %zone_name, %my_role gebraucht.' WHERE `id`=1132;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Braucht wer Hilfe bei %quest_links in %zone_name? Ich bin %my_role.' WHERE `id`=1133;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Habe %quest_links offen, brauche %my_role in %zone_name.' WHERE `id`=1134;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Bin in %zone_name und suche Hilfe für %quest_links, wer ist dabei?' WHERE `id`=1135;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Suche Gruppe, um %quest_links in %zone_name fertig zu machen.' WHERE `id`=1136;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Sucht jemand %quest_links in %zone_name? Ich bin %my_role.' WHERE `id`=1137;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Machen wir %quest_links zusammen! %zone_name wartet.' WHERE `id`=1138;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Brauche Gruppe für %quest_links, %zone_name - wer hat Interesse?' WHERE `id`=1139;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Wer will für %quest_links dazukommen? Bin in %zone_name.' WHERE `id`=1140;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Bin in %zone_name, suche Leute zum Abschließen von %quest_links.' WHERE `id`=1141;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Brauche Hilfe bei %quest_links in %zone_name, ein %my_role da?' WHERE `id`=1142;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Suche Gruppe, um %quest_links zu beenden, %zone_name da steppt der Bär.' WHERE `id`=1143;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Will jemand bei %quest_links in %zone_name helfen? Ich bin %my_role.' WHERE `id`=1144;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Suche %my_role, um %quest_links in %zone_name mitzumachen.' WHERE `id`=1145;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Hab %quest_links, %my_role für %zone_name gesucht.' WHERE `id`=1146;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Will %quest_links in %zone_name fertig bekommen, brauche mehr Leute.' WHERE `id`=1147;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Brauche Hilfe bei %quest_links, wer ist in %zone_name unterwegs?' WHERE `id`=1148;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Brauche mehr Leute für %quest_links, %zone_name.' WHERE `id`=1149;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Suche Gruppe in %zone_name, um %quest_links abzuschließen.' WHERE `id`=1150;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Wer will %quest_links in %zone_name machen? Bin startklar.' WHERE `id`=1151;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Will wer für %quest_links dazustoßen? Ich bin %my_role in %zone_name.' WHERE `id`=1152;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Suche %my_role für %quest_links in %zone_name.' WHERE `id`=1153;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Bin in %zone_name, braucht wer Hilfe bei %quest_links?' WHERE `id`=1154;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Brauche mehr für %quest_links in %zone_name, bin allein nicht stark genug?' WHERE `id`=1155;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Brauche Hilfe bei %quest_links in %zone_name, wer hat Bock?' WHERE `id`=1156;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Suche mehr Leute, um %quest_links zu beenden, %zone_name.' WHERE `id`=1157;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Hey, bin bei %quest_links dabei' WHERE `id`=1158;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Hey, ich habe auch %quest_links' WHERE `id`=1160;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Hey %other_name, bin bei %quest_links dabei' WHERE `id`=1161;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Hey %other_name, ich könnte %quest_links mit dir machen' WHERE `id`=1162;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Bock, für %quest_links eine Gruppe zu bilden?' WHERE `id`=1164;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Bin bereit für %quest_links, bin gerade in %zone_name' WHERE `id`=1165;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Bin bereit für %quest_links, bin %my_role' WHERE `id`=1166;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Hey, ich hab Bock auf %quest_links' WHERE `id`=1167;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Ich kann bei %quest_links helfen, wenn ihr wollt' WHERE `id`=1168;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Lasst uns %quest_links zusammen machen!' WHERE `id`=1169;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Ich hab auch %quest_links offen' WHERE `id`=1170;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Bin für %quest_links verfügbar, wenn ihr wollt' WHERE `id`=1171;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Bin bei %quest_links dabei, sagt Bescheid' WHERE `id`=1172;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Sucht wer %quest_links? Bin in %zone_name' WHERE `id`=1173;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Hey, ich brauche auch %quest_links, lets go' WHERE `id`=1174;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Hab %quest_links, will wer mit?' WHERE `id`=1175;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Könnte %quest_links brauchen, machen wirs' WHERE `id`=1176;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Hey, willst du für %quest_links dazukommen?' WHERE `id`=1177;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Ich kann bei %quest_links helfen, wenn ihr wollt' WHERE `id`=1178;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Hey %other_name, Bock auf %quest_links?' WHERE `id`=1179;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Willst du für %quest_links gruppen, %other_name?' WHERE `id`=1180;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Lass %quest_links zusammen machen, %other_name' WHERE `id`=1181;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Ich bin %my_role und ready für %quest_links' WHERE `id`=1182;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Kann für %quest_links joinen, %my_role hier' WHERE `id`=1183;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Bin bereit für %quest_links, %my_role!' WHERE `id`=1184;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Suche %my_role für %quest_links' WHERE `id`=1185;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Braucht wer Hilfe bei %quest_links?' WHERE `id`=1186;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Wer ist noch bei %quest_links dabei?' WHERE `id`=1187;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Jemand bereit für %quest_links in %zone_name?' WHERE `id`=1188;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Hab %quest_links, %my_role unterwegs' WHERE `id`=1189;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Ich brauch %quest_links auch, wer ist dabei?' WHERE `id`=1190;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Grinde %quest_links, wer hilft?' WHERE `id`=1191;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Bin bereit für %quest_links, noch wer?' WHERE `id`=1192;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Kann jemand für %quest_links dazukommen?' WHERE `id`=1193;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Suche Hilfe bei %quest_links, %my_role hier' WHERE `id`=1194;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Ich kann bei %quest_links aushelfen, braucht mich wer?' WHERE `id`=1195;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Macht noch wer %quest_links? Los gehts' WHERE `id`=1196;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Braucht wer Hilfe bei %quest_links? %my_role hier' WHERE `id`=1197;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Wer hat Bock auf %quest_links in %zone_name?' WHERE `id`=1198;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Kann für %quest_links joinen, wenn ihr wollt' WHERE `id`=1199;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Suche einen %my_role für %quest_links' WHERE `id`=1200;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Ist ein %my_role für %quest_links am Start?' WHERE `id`=1201;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Ich habe %quest_links, will wer mit?' WHERE `id`=1202;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Hey %other_name, Bock auf %quest_links?' WHERE `id`=1203;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Lass uns für %quest_links gruppen, %other_name' WHERE `id`=1204;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Ich brauche %quest_links, wer macht mit?' WHERE `id`=1205;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Ich brauche auch %quest_links, ist noch jemand da?' WHERE `id`=1206;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Suche %quest_links in %zone_name, wer ist dabei?' WHERE `id`=1207;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Ist jemand frei für %quest_links?' WHERE `id`=1208;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Hey, ich könnte bei %quest_links dazustoßen!' WHERE `id`=1209;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Ich habe auch %quest_links, lass uns gruppen' WHERE `id`=1210;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Ich habe %quest_links zu erledigen, willst du mit?' WHERE `id`=1211;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Ist ein %my_role für %quest_links in %zone_name frei?' WHERE `id`=1212;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Lass uns %quest_links zusammen abschließen, %other_name' WHERE `id`=1213;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Ich bin bei %quest_links dabei, will noch wer mit?' WHERE `id`=1214;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Wer macht noch %quest_links? Ich bin dabei' WHERE `id`=1215;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Ich habe %quest_links in %zone_name, braucht jemand Hilfe?' WHERE `id`=1216;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='%other_name, könnte dir %formatted_item_links verkaufen' WHERE `id`=1217;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Könnte eventuell %formatted_item_links verkaufen' WHERE `id`=1218;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Denke, ich könnte %formatted_item_links verkaufen' WHERE `id`=1219;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='%other_name, könnte eventuell %formatted_item_links verkaufen' WHERE `id`=1220;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='%other_name, ich denke, ich könnte %formatted_item_links verkaufen' WHERE `id`=1221;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Ich könnte dir %formatted_item_links verkaufen' WHERE `id`=1222;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Hey, habe %formatted_item_links zu verkaufen' WHERE `id`=1223;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Hey, könnte eventuell %formatted_item_links verkaufen' WHERE `id`=1224;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Ich könnte dir %formatted_item_links verkaufen' WHERE `id`=1225;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Hey, habe %formatted_item_links zu verkaufen' WHERE `id`=1226;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Hey, ich könnte eventuell %formatted_item_links verkaufen' WHERE `id`=1227;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Ich habe %formatted_item_links, Interesse?' WHERE `id`=1228;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Will %formatted_item_links verkaufen, was bietest du?' WHERE `id`=1229;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Ich kann dir %formatted_item_links zu einem fairem Preis verkaufen' WHERE `id`=1230;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Ich habe %formatted_item_links auf Lager, was zahlst du?' WHERE `id`=1231;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Verkaufe %formatted_item_links für %cost_gold, sag Bescheid bei Interesse' WHERE `id`=1232;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Habe %formatted_item_links zu verkaufen, was zahlst du?' WHERE `id`=1233;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Ich habe %formatted_item_links, wie klingt %cost_gold für dich?' WHERE `id`=1234;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Verkaufe %formatted_item_links für %cost_gold, flüster mir bei Interesse' WHERE `id`=1235;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Ich habe %formatted_item_links, meld dich bei Interesse' WHERE `id`=1236;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Gebe %formatted_item_links ab, wenn das Angebot passt' WHERE `id`=1237;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Will %formatted_item_links loswerden, flüster mir' WHERE `id`=1238;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Habe %formatted_item_links für %cost_gold, kaufst du?' WHERE `id`=1239;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Verkaufe %formatted_item_links, lass uns handeln' WHERE `id`=1240;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Hey, habe %formatted_item_links für %cost_gold' WHERE `id`=1241;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Kann dich mit %formatted_item_links versorgen, nenn deinen Preis' WHERE `id`=1242;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Ich habe %formatted_item_links verfügbar, sag Bescheid bei Interesse' WHERE `id`=1243;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Verkaufe %formatted_item_links, machen wir Business' WHERE `id`=1244;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Ich habe %formatted_item_links, macht mir ein Angebot' WHERE `id`=1245;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Ich habe %formatted_item_links, schreib mir, wenn du kaufen willst' WHERE `id`=1246;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Kann dir %formatted_item_links für %cost_gold anbieten' WHERE `id`=1247;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Ich habe %formatted_item_links zu verkaufen, schreib mir für den Preis' WHERE `id`=1248;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Verkaufe %formatted_item_links, greif zu solange es heiß ist' WHERE `id`=1249;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Verkaufe %formatted_item_links, nen besseren Deal findet ihr nicht' WHERE `id`=1250;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Ich habe %formatted_item_links zu verkaufen, was zahlst du?' WHERE `id`=1251;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Verkaufe %formatted_item_links, Preis auf Anfrage per flüstern' WHERE `id`=1252;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Interesse an %formatted_item_links? Ich verkaufe welche' WHERE `id`=1253;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Ich habe %formatted_item_links, PN für Preis' WHERE `id`=1254;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Verkaufe %formatted_item_links für %cost_gold, meldet euch' WHERE `id`=1255;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Verkaufe %formatted_item_links, macht mir ein Angebot' WHERE `id`=1256;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Habe %formatted_item_links, schreib mir für Details' WHERE `id`=1257;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Hey, habe %formatted_item_links, meldet euch bei Interesse' WHERE `id`=1258;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Verkaufe %formatted_item_links, machen wir nen Deal?' WHERE `id`=1259;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Verkaufe %formatted_item_links, sag Bescheid wenn du willst' WHERE `id`=1260;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Ich habe %formatted_item_links, ich mach dir nen guten Preis' WHERE `id`=1261;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Ich habe %formatted_item_links, mit gutem Angebot gehörts dir' WHERE `id`=1262;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Verkaufe %formatted_item_links, bin offen für Angebote' WHERE `id`=1263;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Ich habe %formatted_item_links, melde dich bei Interesse' WHERE `id`=1264;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Ich kann dir %formatted_item_links zu einem guten Preis verkaufen' WHERE `id`=1265;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Ich habe %formatted_item_links zu verkaufen, nehme alle Angebote an' WHERE `id`=1266;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Habe %formatted_item_links im Verkauf, flüster mir für Details' WHERE `id`=1267;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Habe %formatted_item_links im Verkauf, macht mir ein Angebot' WHERE `id`=1268;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Ich habe %formatted_item_links, was zahlt ihr?' WHERE `id`=1269;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Verkaufe %formatted_item_links, schreib mir für mehr Infos' WHERE `id`=1270;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Ich habe %formatted_item_links, sagt Bescheid bei Interesse' WHERE `id`=1271;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Verkaufe %formatted_item_links, lass uns über Zahlen reden' WHERE `id`=1272;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Ich kann dir %formatted_item_links verkaufen, was bietest du?' WHERE `id`=1273;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Hey, habe %formatted_item_links zu verkaufen, meldet euch bei Interesse' WHERE `id`=1274;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Ich habe %formatted_item_links, PN für den Preis' WHERE `id`=1275;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Verkaufe %formatted_item_links, bin offen für Angebote' WHERE `id`=1276;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Ich habe %formatted_item_links, schreibt mir einfach' WHERE `id`=1277;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Kann %formatted_item_links anbieten, sagt Bescheid bei Interesse' WHERE `id`=1278;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Verkaufe %formatted_item_links, bitte vernünftige Angebote' WHERE `id`=1279;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Ich habe %formatted_item_links, meldet euch für mehr Infos' WHERE `id`=1280;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Ich habe %formatted_item_links, macht mir ein Angebot' WHERE `id`=1281;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Verkaufe %formatted_item_links, schreibt mir bei Interesse' WHERE `id`=1282;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Habe %formatted_item_links zu verkaufen, lass uns handeln' WHERE `id`=1283;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Ich habe %formatted_item_links, sag Bescheid wenn du willst' WHERE `id`=1284;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Ich kann diese Quest nicht annehmen' WHERE `id`=1287;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Ich kann nicht mit dem Questgeber sprechen' WHERE `id`=1288;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Ich habe %quest bereits abgeschlossen' WHERE `id`=1289;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Ich habe %quest bereits' WHERE `id`=1290;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Ich kann %quest nicht annehmen' WHERE `id`=1291;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Ich kann %quest nicht annehmen, mein Questlog ist voll' WHERE `id`=1292;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Ich kann %quest nicht annehmen, meine Tasche ist voll' WHERE `id`=1293;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Ich habe %quest angenommen' WHERE `id`=1294;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Ich habe die Quest %quest nicht abgeschlossen' WHERE `id`=1295;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Quest %quest verfügbar' WHERE `id`=1296;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Ich habe die Quest %quest vergeigt' WHERE `id`=1297;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Ich kann die Quest %quest nicht abgeben' WHERE `id`=1298;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Ich habe die Quest %quest abgeschlossen' WHERE `id`=1299;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Ich habe die Quest %quest abgeschlossen und %item erhalten' WHERE `id`=1300;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Welche Belohnung soll ich für die Quest %quest nehmen? %rewards' WHERE `id`=1301;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Okay, ich nehme %item als Belohnung' WHERE `id`=1302;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Hi' WHERE `id`=1305;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Hallo zusammen!' WHERE `id`=1307;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Hallo, geh vor!' WHERE `id`=1309;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Hi, geh vor!' WHERE `id`=1310;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Hey %player, willst du in meine Gruppe?' WHERE `id`=1311;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Hey %player, kommst du in meine Gruppe?' WHERE `id`=1312;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Logout abgebrochen!' WHERE `id`=1313;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Ich logge mich aus!' WHERE `id`=1314;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Was war das, %s?' WHERE `id`=1318;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Bin nicht sicher, ob ich dich verstehe, %s?' WHERE `id`=1319;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='äh... keine Ahnung, wovon du redest' WHERE `id`=1320;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='whaaaa?' WHERE `id`=1322;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='hä?' WHERE `id`=1323;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='was?' WHERE `id`=1324;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='redest du grade?' WHERE `id`=1325;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='mir egal, Digga' WHERE `id`=1326;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='da bin ich raus' WHERE `id`=1327;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Konzentrier dich aufs Spiel, %s!' WHERE `id`=1330;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Mit dir zu chatten, %s, ist so großartig! Wollte dich immer schon treffen' WHERE `id`=1331;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Diese Chatnachrichten machen mich fertig! Fühlt sich an, als würde ich euch alle kennen!' WHERE `id`=1332;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='JA SICHER! HAHA KLAR!!!' WHERE `id`=1333;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Ich glaub dir!!!' WHERE `id`=1334;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Okay, ähm, lol' WHERE `id`=1335;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Hey %s... ach egal!' WHERE `id`=1337;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Wovon redest du, %s' WHERE `id`=1338;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Wer hat das gesagt? Ich fühl mich angesprochen' WHERE `id`=1339;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='wtf, worüber redet ihr alle' WHERE `id`=1340;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='ehrlich jetzt, kein Witz' WHERE `id`=1341;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='du bekommst gar nix' WHERE `id`=1342;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Plus Aura!!!' WHERE `id`=1343;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='thx!' WHERE `id`=1344;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='jup' WHERE `id`=1346;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='f' WHERE `id`=1347;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='%s, kein Scheiß xD' WHERE `id`=1348;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='warum ist das so' WHERE `id`=1349;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='ROFL' WHERE `id`=1350;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='dachte, ich halt besser die Klappe, der Chat hat mich wieder verwirrt' WHERE `id`=1351;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='ich kann richtig eifersüchtig werden' WHERE `id`=1352;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='%s, du hörst den triefenden Sarkasmus in meinem text_loc3 nicht' WHERE `id`=1353;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='er meinte „kein Ding“, passt schon' WHERE `id`=1354;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Ja, %s' WHERE `id`=1356;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='interessant...' WHERE `id`=1357;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='lol' WHERE `id`=1358;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='%s, fick dich, Mann :D' WHERE `id`=1359;
+UPDATE `ai_playerbot_texts` SET `text_loc3`=':^)' WHERE `id`=1360;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='thx' WHERE `id`=1361;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='%s, gut gesagt' WHERE `id`=1362;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='yay' WHERE `id`=1363;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='ja' WHERE `id`=1364;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='ooooooh' WHERE `id`=1365;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='hmm' WHERE `id`=1366;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='ja klar' WHERE `id`=1367;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='mir wird schlecht, wtf' WHERE `id`=1368;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='heiß' WHERE `id`=1369;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='die Weiber sind sauer' WHERE `id`=1370;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='was hast du gegessen, %s' WHERE `id`=1371;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='wtf' WHERE `id`=1372;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='ich versuche, diesen Kommentar zu verstehen' WHERE `id`=1373;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='*verwirrt*' WHERE `id`=1374;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='fuck ja' WHERE `id`=1375;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='0/10 würde ich nicht wieder lesen' WHERE `id`=1376;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='10/10 würde ich wieder lesen' WHERE `id`=1377;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='6/10 würde es lesen' WHERE `id`=1378;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='7/10 vielleicht' WHERE `id`=1379;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Respekt!' WHERE `id`=1380;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='oh ja, vielleicht' WHERE `id`=1381;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='ja und?' WHERE `id`=1382;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='hey %s, ich habe dich nicht vergessen' WHERE `id`=1383;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='du gehst mir hart auf den Sack, %s' WHERE `id`=1384;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='diesmal krieg ich dich, %s' WHERE `id`=1385;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Pass besser auf, %s' WHERE `id`=1386;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Die letzte Runde mochte ich nicht so' WHERE `id`=1387;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Letzte Runde war ich mies, danke, %s' WHERE `id`=1388;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Mach dich bereit zu sterben, %s' WHERE `id`=1389;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Fands nicht geil, dass du mich gekillt hast, %s' WHERE `id`=1390;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='%s, ich hasse dich' WHERE `id`=1391;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='grrrrrr, diesmal krieg ich dich, %s' WHERE `id`=1392;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='FICK DICH! NEIN, FICK MICH!' WHERE `id`=1393;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='%s, ich kotze dir in dein verficktes Maul' WHERE `id`=1394;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='verurteil mich nicht, verdammt nochmal' WHERE `id`=1395;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Deine Mom ist so fett, sie passt nicht mal durchs Dunkle Portal' WHERE `id`=1396;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='armselige Gestalt' WHERE `id`=1399;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='was zum Teufel' WHERE `id`=1400;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='das war scheiße' WHERE `id`=1401;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='REMATCH!!! Ich mach ihn platt' WHERE `id`=1402;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='peinlich, ich wurde von %s gekillt' WHERE `id`=1403;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='ok, ich bin raus' WHERE `id`=1404;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='hehe, hab %s weggeklatscht?' WHERE `id`=1405;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='viel zu easy, %s zu killen' WHERE `id`=1406;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='hab dich, du Bastard' WHERE `id`=1407;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='haha' WHERE `id`=1408;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Loser' WHERE `id`=1409;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='ich hab %s gekillt und ihr seid als nächste dran, Jungs' WHERE `id`=1410;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='oh ja, hab ihn geownt' WHERE `id`=1411;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='ich bin ne Killmaschine' WHERE `id`=1412;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='%s, erinnert mich an einen Slayer-Song... dieses ganze Gemetzel' WHERE `id`=1413;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='sorry, %s. Können wir die Szene nochmal machen?' WHERE `id`=1414;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='na, wie gefällt es dir Wurmfutter zu sein, %s???' WHERE `id`=1415;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='du solltest tot sein, %s, das gehört zum Spiel!!!!!' WHERE `id`=1416;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='sorry, %s. das sah so gut aus wie ein Kunstwerk von der Kirmes!' WHERE `id`=1417;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='%s, ich nehme nächstes Mal Gummigeschosse!' WHERE `id`=1418;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='was ist los, %s?? Kopf verloren? hahaha, ruhig bleiben!!' WHERE `id`=1419;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='musste das tun, %s. Du verstehst schon. Der Regisseur hat es so gesagt!!' WHERE `id`=1420;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='hey %s.......MUAHAHAHAHAHAHAHAHAHAHA' WHERE `id`=1421;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='%s, das hab ich genossen!! Wiederholung bitte!' WHERE `id`=1422;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='hey, %s! Kannst mich ab jetzt "Scarface" nennen.. du Stück SCHEI**!!!!' WHERE `id`=1423;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='redest du mit mir, %s??' WHERE `id`=1424;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='%s, mach es diesmal richtig, stell dich nicht vor meine Kugeln.' WHERE `id`=1425;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='%s, warum liegst du da rum??? hehe' WHERE `id`=1426;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='hab mich totgelacht' WHERE `id`=1427;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='hi %s' WHERE `id`=1428;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='oh, hi %s' WHERE `id`=1429;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='was geht, %s!!!' WHERE `id`=1430;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='hi' WHERE `id`=1431;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='was geht' WHERE `id`=1432;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='hallo %s' WHERE `id`=1433;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='hi %s, kennen wir uns?' WHERE `id`=1434;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='hey %s' WHERE `id`=1435;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='hai %s' WHERE `id`=1436;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='was zur Hölle' WHERE `id`=1437;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='WTF' WHERE `id`=1438;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='das ist Bullshit' WHERE `id`=1439;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='admin' WHERE `id`=1440;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='hey %s, hör auf, deine Admin-Rechte zu missbrauchen' WHERE `id`=1441;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='lass mich in Ruhe, Admin!' WHERE `id`=1442;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='du bist scheisse, Admin' WHERE `id`=1443;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='das ist mein Name, was willst du, %s' WHERE `id`=1444;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='ja???' WHERE `id`=1445;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='äh... was' WHERE `id`=1446;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='redest du mit mir, %s?' WHERE `id`=1447;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Hey ! Rate mal, was deine Mom letzte Nacht gesagt hat!' WHERE `id`=1450;
+UPDATE `ai_playerbot_texts` SET `text_loc3`=', du bist so hässlich, du würdest nicht mal im Affenbordell mit einem Sack Bananen landen!' WHERE `id`=1451;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Halt die Klappe, , du wirst so ein Mann sein, wie deine Mutter!!' WHERE `id`=1452;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Deine Mutter ist so fett, dass man eine Pokéflöte braucht, um sie aufzuwecken und dein Vater ist der Trainer!!!!' WHERE `id`=1453;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Dich als dumm zu bezeichnen, wäre eine Beleidigung für dumme Leute!' WHERE `id`=1454;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Ich furze in deine allgemeine Richtung!!!' WHERE `id`=1455;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Jeder Atemzug, den ich ohne deine Erlaubnis mache, steigert mein Selbstwertgefühl!' WHERE `id`=1456;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Was willst du tun , mich vollbluten? NIMM DAS!' WHERE `id`=1457;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='A-G-G-R-O! Das heißt Bosszeit!' WHERE `id`=1458;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Wir hatten grausame und hatten irre Begleiter, aber mit dir sind wir mit einem grausamen Irren gestraft!' WHERE `id`=1459;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Hey ! Hör auf, sie anzubaggern, sie ist nicht dein Typ. Die sind nicht aufblasbar.' WHERE `id`=1460;
+UPDATE `ai_playerbot_texts` SET `text_loc3`=', du bist so weit außerhalb deiner Liga, du spielst schon eine andere Sportart.' WHERE `id`=1461;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Großer Fehler heute Morgen, : Du bist aufgestanden!' WHERE `id`=1462;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Ich will mal versuchen, mich in ein Pferd zu verwandeln, brauche aber Hilfe. Ich mach die Vorderseite, du bleibst du.' WHERE `id`=1463;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Du kommst mir vor, als wäre das Beste von dir damals am Arsch deiner Mutter runtergelaufen und als braune Soße auf der Matratze geblieben!' WHERE `id`=1464;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Ich würd dir gern ein Abschiedsgeschenk machen... Aber zuerst machst du deinen Teil.' WHERE `id`=1465;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Bevor du kamst, waren wir motiviert, jetzt sind wir einfach nur noch genervt.' WHERE `id`=1466;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Ich mag dich. Man sagt, ich hätte keinen Geschmack, aber ich mag dich.' WHERE `id`=1467;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Ich glaube, du hast Minderwertigkeitskomplexe, aber ist okay, ist gerechtfertigt.' WHERE `id`=1468;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Verschwinde, sonst passiert was.' WHERE `id`=1469;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Kaum zu fassen, dass ich meine Zeit mit dir verschwende!' WHERE `id`=1470;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Ich liebe es, wenn mich jemand beleidigt, dann muss ich nicht mehr nett sein.' WHERE `id`=1471;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Ich werde dich auch auslöschen, du Mistkerl! Ich werde dir die Eingeweide rausreißen und dir ins Gesicht schmieren!' WHERE `id`=1472;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Du abscheuliche Bestie, nicht mal ein Hund würde dich fressen.' WHERE `id`=1473;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Du schlägst wie ein Vegetarier.' WHERE `id`=1474;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Wer hat dich ausgebuddelt, du wandelnde Seuche?' WHERE `id`=1475;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Ich schau dir nicht in die Augen, ich will heute noch schlafen können.' WHERE `id`=1476;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Boah, bei dir quillt ja noch das Mittagessen raus! Ich hab dich gerochen, bevor ich dich gesehen hab.' WHERE `id`=1477;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Oh du bist so hässlich, selbst der Respawn will dich nicht!' WHERE `id`=1478;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Ich muss mal einen riesigen machen. ist mein neues Wort für Scheiße.' WHERE `id`=1479;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Oh du nutzlose, moorsaufende Krebsgeschwulst!' WHERE `id`=1480;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Wäre ich wie du, würd ich mich selbst löschen!' WHERE `id`=1481;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Oh lehre mich, wie ich das Denken vergesse!' WHERE `id`=1482;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Ich hab schon Toiletten gesehen, die sauberer kämpfen als du.' WHERE `id`=1483;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Du verdammter Scheißkerl. Wo hast du dein Handwerk gelernt? Du dumme, verdammte Schlampe. Du Idiot. Wer hat dir gesagt, dass du mit Männern arbeiten kannst?' WHERE `id`=1484;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Wenn Unfähigkeit ’ne Klasse wäre, hättest du sie gemaxt.' WHERE `id`=1485;
+UPDATE `ai_playerbot_texts` SET `text_loc3`=' du dummes Arschfurz-Teppichladen-Arschloch' WHERE `id`=1486;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Ich lebe lang genug und dann nehm ich dir das Hirn raus!' WHERE `id`=1487;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Wenn einen intelligenten Gedanken im Kopf hätte, würde er an Einsamkeit sterben.' WHERE `id`=1488;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Hör auf zu weinen, du winselnder Arsch, hör auf mit deinem Unsinn. Du bist nur die Nachgeburt, .' WHERE `id`=1489;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='! Wenn Gehirn Vogelkacke wäre, hättest du einen sauberen Käfig' WHERE `id`=1490;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Hör mal zu, du Vokuhila... warum zündest du nicht einfach dein Tampon an und sprengst deine Box in die Luft? Denn das ist der einzige Knall, den du kriegen wirst.' WHERE `id`=1491;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Verschwinde aus meiner Sicht ! Du verseuchst meine Augen!' WHERE `id`=1492;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='SPIELZEIT!!!!' WHERE `id`=1493;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Niemand kommt vorbei!' WHERE `id`=1494;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Wir werden angegriffen! Klar zum Gefecht, ihr Deckschrubber! Wehrt die Eindringlinge ab!' WHERE `id`=1495;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Narren... Tötet den im Kleid!' WHERE `id`=1497;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Ich werde deine Seele Hakkar selbst zum Fraß vorwerfen!' WHERE `id`=1498;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Stolz kündigt das Ende eurer Welt an! Kommt, Sterbliche! Stellt euch dem Zorn der !' WHERE `id`=1499;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='All meine Pläne haben zu diesem Moment geführt!' WHERE `id`=1500;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Neuer Tag, neue glorreiche Schlacht!' WHERE `id`=1502;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Also, Geschäft... oder Vergnügen?' WHERE `id`=1503;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Ihr seid nicht vorbereitet!' WHERE `id`=1504;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Die letzte Eroberung der hat begonnen! Wieder liegt die Unterwerfung dieser Welt in unseren Händen. Lasst keinen überleben!' WHERE `id`=1505;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Euer Tod wird ein schmerzhafter sein.' WHERE `id`=1506;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Fleht um Gnade! Eure bedeutungslosen Leben sind bald verwirkt.' WHERE `id`=1507;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Gebt alle Hoffnung auf! Die ist zurückgekehrt, um zu beenden, was vor so vielen Jahren begann. Diesmal gibt es kein Entkommen!' WHERE `id`=1508;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Alarm! Ihr seid zur Auslöschung markiert!' WHERE `id`=1509;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Hahaha! Ihr seid hoffnungslos unterlegen!' WHERE `id`=1511;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Ich werde euren Größenwahn zerschmettern!' WHERE `id`=1512;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Verzeiht mir, denn ihr werdet gleich das Spiel verlieren.' WHERE `id`=1513;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Wehren macht es nur schlimmer.' WHERE `id`=1514;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Ungeziefer! Blutegel! Saugt mein Blut und erstickt daran!' WHERE `id`=1515;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Mein Blut wird euer Ende sein!' WHERE `id`=1517;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Macht hinne, Wachen! Es ist Zeit zum Töten!' WHERE `id`=1519;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Zögert euer Schicksal nicht hinaus. Kommt jetzt zu mir. Ich mache euer Opfer kurz.' WHERE `id`=1520;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Bald seid ihr tot!' WHERE `id`=1521;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Mu-ha-ha!' WHERE `id`=1522;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Ich bin der Jäger! Ihr seid die Beute...' WHERE `id`=1523;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Ihr werdet diesen Ort in Stücken verlassen!' WHERE `id`=1524;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Der Tod naht. Wird euer Gewissen rein sein?' WHERE `id`=1525;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Euer Verhalten wird nicht toleriert.' WHERE `id`=1526;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Hmm, unangekündigte Besucher. Vorbereitungen müssen getroffen werden...' WHERE `id`=1528;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Feindliche Einheiten entdeckt. Bedrohungsanalyse-Protokoll aktiv. Primärziel erfasst. Zeit minus dreißig Sekunden bis zur Neubewertung.' WHERE `id`=1529;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Neue Spielzeuge? Für mich? Ich verspreche, ich mach sie diesmal nicht kaputt!' WHERE `id`=1530;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Pssst... gleich ist alles vorbei.' WHERE `id`=1532;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Sag es mir... sag mir alles, Geheimnisse und Privatsachen! Ich reiße dir die Infos aus dem Fleisch!' WHERE `id`=1536;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Macht euch bereit, die Glocken haben geläutet! Bringt die Schwachen, die Jungen und die Alten in Sicherheit! Jeder von euch zahlt den letzten Preis! Fleht um Gnade, die Abrechnung ist gekommen!' WHERE `id`=1537;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Wo, bei Bonzos Messingknöpfen, bin ich?' WHERE `id`=1538;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Ich ertrage es nicht länger! Goblinkönig! Goblinkönig! Wo immer du bist! Nimm diesen weit weg von mir!' WHERE `id`=1539;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Ihr habt dreizehn Stunden, um das Labyrinth zu lösen, bevor euer kleiner Bruder einer von uns wird... für immer.' WHERE `id`=1540;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Also, die ist Kinderkram, ja? Dann sehen wir mal, wie ihr dieses kleine Stückchen verdaut...' WHERE `id`=1541;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Weiche! Ich stelle mich jedem Kampf. Du irrst dich, dies ist nicht dein Revier.' WHERE `id`=1542;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Zeig, was du drauf hast!' WHERE `id`=1543;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Zweiklingen-Action für eine glatte und saubere Rasur jedes mal.' WHERE `id`=1545;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Los, komm schon!' WHERE `id`=1546;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Du gehst drauf!' WHERE `id`=1547;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Stich, stich, stich!' WHERE `id`=1548;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Machen wir das schnell, Zeit ist Mana.' WHERE `id`=1549;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Ich glaube nicht, dass ihr die Schwere eurer Lage begreift.' WHERE `id`=1550;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Ich bringe meiner Familie und meinem Königreich Ehre!' WHERE `id`=1551;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Licht, gib mir Stärke!' WHERE `id`=1552;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Meine Kirche ist das Schlachtfeld, Zeit zum Gottesdienst...' WHERE `id`=1553;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Ich verachte euch...' WHERE `id`=1554;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Stellt euch dem Hammer der Gerechtigkeit!' WHERE `id`=1555;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Beweist euren Wert in der Prüfung der Waffen im Lichte!' WHERE `id`=1556;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Alles wird vor der Macht und der Gerechtigkeit meiner Sache fallen. Ihr werdet der Nächste sein!' WHERE `id`=1557;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Bereitet euch aufs Sterben vor!' WHERE `id`=1558;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Die Bestie an meiner Seite ist nichts gegen die Bestie in mir...' WHERE `id`=1559;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Erlebt die Feuerkraft dieses voll bewaffneten Jägers!' WHERE `id`=1560;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Heilt mich! Schnell!' WHERE `id`=1561;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Fast tot! Heilt mich!' WHERE `id`=1562;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Hilfe! Heilt mich!' WHERE `id`=1563;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Irgendwer! Heilt mich!' WHERE `id`=1564;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Heal! Heal! Heal!' WHERE `id`=1565;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Ich sterbe! Heal! Aaaaarhg!' WHERE `id`=1566;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Heal mich!' WHERE `id`=1567;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Ich sterbe. Ich sterbe. Ich sterbe. Heal!' WHERE `id`=1568;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Oh, der Schmerz. Heilt mich schnell!' WHERE `id`=1570;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Brauche Heal' WHERE `id`=1571;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='HP low' WHERE `id`=1572;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Gebt mal nen Heal. Bitte.' WHERE `id`=1573;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Kann mir jemand nen Heal geben?' WHERE `id`=1574;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Hey! Lieber jetzt heilen als später zu rezzen' WHERE `id`=1575;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Sorry. Brauche noch einen Heal' WHERE `id`=1576;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Verdammte Mobs. Heal mich bitte' WHERE `id`=1577;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Noch ein Treffer und ich bin hinüber. Heal bitte' WHERE `id`=1578;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Heiler da?' WHERE `id`=1579;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Warum hauen die mir immer ins Gesicht? Brauche Heal' WHERE `id`=1580;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Kann mich wer ein bisschen heilen?' WHERE `id`=1581;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='OOM' WHERE `id`=1582;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Kein Mana mehr' WHERE `id`=1583;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Verdammt, dafür hab ich mein ganzes Mana verballert' WHERE `id`=1584;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Wartet bis ich trinke oder mein Mana wieder da ist' WHERE `id`=1585;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Mana low' WHERE `id`=1586;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Mana low. Muss trinken' WHERE `id`=1588;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Haben wir nen Getränkeautomaten? Wieder OOM' WHERE `id`=1589;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Mein Mana ist Geschichte' WHERE `id`=1590;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Ich besorge mir nächstes mal Drinks. OOM' WHERE `id`=1591;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Noch 100 !' WHERE `id`=1595;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Das war es! Keine mehr!' WHERE `id`=1596;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Und ihr habt meinen Bogen... ups, keine !' WHERE `id`=1597;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Brauche !' WHERE `id`=1598;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Ich habe Angst' WHERE `id`=1600;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Wir sind am Arsch.' WHERE `id`=1601;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Das wars.' WHERE `id`=1602;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Hier ist jetzt Schluss.' WHERE `id`=1603;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Kann mal wer Blizzard anrufen?' WHERE `id`=1604;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Verdammt. Der Tank hat alle Mobs gepullt.' WHERE `id`=1605;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Wir sterben. Wir sterben. Wir sterben.' WHERE `id`=1606;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Whoa! So viel Spielzeug zum Austoben.' WHERE `id`=1607;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Ich kill sie alle!' WHERE `id`=1608;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Wenn der Tank stirbt, sind wir Geschichte.' WHERE `id`=1609;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='LEEEEERROOOYYYYYYYYYYYY JENNKINNNSSSSSS!!!!!!!' WHERE `id`=1611;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Okay. Was haben wir an AoE?' WHERE `id`=1612;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Jetzt wirds interessant.' WHERE `id`=1613;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Cool. Zieht sie zusammen für nen schönen Flammenstoß.' WHERE `id`=1614;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Kill! Kill! Kill!' WHERE `id`=1615;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Ich glaub, meine Hose ist nass.' WHERE `id`=1616;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Hoffentlich sind die Heiler ready. Leeeeroy!' WHERE `id`=1618;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Hoffentlich kommen die nicht zu mir.' WHERE `id`=1619;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Oh nein. Ich kann bei dem Gemetzel nicht hinsehen.' WHERE `id`=1620;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Hoffentlich gibts Gold.' WHERE `id`=1621;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Loot! Loot!' WHERE `id`=1622;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Mein Schatz.' WHERE `id`=1623;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Hoffentlich wartet da ein schickes episches Item auf mich.' WHERE `id`=1624;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Ich hab tiefe Taschen und Beutel.' WHERE `id`=1625;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Alles meins!' WHERE `id`=1626;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Hoffentlich heute kein grauer Müll.' WHERE `id`=1627;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Dieser Loot ist MEINER!' WHERE `id`=1628;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Looten ist eklig, aber ich brauch Gold.' WHERE `id`=1629;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Gold!' WHERE `id`=1630;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Okay. Mal sehen, was sie droppen.' WHERE `id`=1631;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Keine Sorge. Ich loote alles.' WHERE `id`=1632;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Ich bin ein Ninja-Looter.' WHERE `id`=1633;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Kann mir mal wer erklären, wo die das ganze Zeug versteckt haben?' WHERE `id`=1635;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Nein, ich loote keinen grauen Müll.' WHERE `id`=1636;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Ich bin zuerst. Ich bin zuerst. Ich bin zuerst.' WHERE `id`=1637;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Gebt mir euer Gold!' WHERE `id`=1638;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Meine Taschen sind leer, müssen aber voll werden.' WHERE `id`=1639;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Hab dafür ne neue Tasche.' WHERE `id`=1640;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Hoffentlich zieh ich beim Looten keine Aggro.' WHERE `id`=1641;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Ich kann nicht looten wenn jemand zusieht.' WHERE `id`=1642;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Ha! Ihr kriegt davon keinen Krümel!' WHERE `id`=1643;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Ich mag neues Gear.' WHERE `id`=1645;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Ich höre auf, wenn schon wieder nichts Wertvolles droppt.' WHERE `id`=1646;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Hoffentlich ist es ein hübscher Ring.' WHERE `id`=1647;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Ich reiß dir den Loot aus den Händen.' WHERE `id`=1648;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Alle weg da. Ich loote jetzt.' WHERE `id`=1649;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Geiler Loot.' WHERE `id`=1650;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Oh ihr RNG-Götter! Gewährt mir heute einen Epic beim würfeln.' WHERE `id`=1651;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Bitte gib mir neues Spielzeug.' WHERE `id`=1652;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Hoffe, die haben was Leckeres dabei.' WHERE `id`=1653;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Das Gold gehört mir. Ich lasse euch den Rest, versprochen.' WHERE `id`=1654;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Bin gleich da, wartet auf mich!' WHERE `id`=1657;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Bin nicht mehr weit, bitte wartet!' WHERE `id`=1658;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Bin auf dem Weg zu euch.' WHERE `id`=1659;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Ich reise zu euch.' WHERE `id`=1661;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Ich versuche zu euch zu kommen.' WHERE `id`=1662;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Rüste %item aus' WHERE `id`=1663;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Ich habe die Zauber gelernt: %spells' WHERE `id`=1665;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='%item hat Abklingzeit.' WHERE `id`=1666;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Ich habe %item nicht im Inventar.' WHERE `id`=1667;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Das Item mit der ID %item existiert nicht.' WHERE `id`=1668;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Folge.' WHERE `id`=1671;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Bleibe hier.' WHERE `id`=1672;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Fliehe.' WHERE `id`=1673;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Ich fliehe nicht mit dir, du bist zu weit weg.' WHERE `id`=1674;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Grinde.' WHERE `id`=1675;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Greife an.' WHERE `id`=1676;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Das ist zu weit weg.' WHERE `id`=1677;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Da kann ich nicht hin.' WHERE `id`=1679;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Ich bin nicht in deiner Gilde!' WHERE `id`=1680;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Keine Gildenbank in der Nähe gefunden.' WHERE `id`=1681;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Ich kann nicht ' WHERE `id`=1682;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Ich habe keine Rechte, Items in den ersten Gildenbank-Reiter zu legen.' WHERE `id`=1683;
+UPDATE `ai_playerbot_texts` SET `text_loc3`=' in die Gildenbank gelegt' WHERE `id`=1684;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Freies Bewegen.' WHERE `id`=1685;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Bewache.' WHERE `id`=1686;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='(das letzte)' WHERE `id`=1690;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='auf Handelsgegenstand' WHERE `id`=1692;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Loote %item' WHERE `id`=1696;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Ich habe nicht genug Gruppenmitglieder in der Nähe, um beschwören zu können.' WHERE `id`=1698;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Ich kenne den Zauber %spell nicht.' WHERE `id`=1701;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Stelle %spell her' WHERE `id`=1703;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Konnte %spell nicht wirken.' WHERE `id`=1705;
+UPDATE `ai_playerbot_texts` SET `text_loc3`=' |cffffff00(x%amount übrig)|r' WHERE `id`=1706;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Dummy' WHERE `id`=1707;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Beim Licht… Ich hab meine Königssymbole vergessen. Na gut, dann nehmen wir eben %base_spell!' WHERE `id`=1708;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Die Natur ist großzügig, meine Taschen nicht... keine Kräuter für %group_spell mehr. Nehmt fürs Erste %base_spell!' WHERE `id`=1709;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Arkanes Pulver alle... %group_spell muss warten. Wirke %base_spell!' WHERE `id`=1710;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='Ups, mir fehlen die Komponenten für %group_spell. Wir nehmen %base_spell!' WHERE `id`=1711;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='%player bewegt sich, um den roten Strahl zu blocken!' WHERE `id`=1712;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='%player bewegt sich, um den blauen Strahl zu blocken!' WHERE `id`=1713;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='%player bewegt sich, um den grünen Strahl zu blocken!' WHERE `id`=1714;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='%player verlässt den blauen Strahl--nächster Blocker los!' WHERE `id`=1715;
+UPDATE `ai_playerbot_texts` SET `text_loc3`='%player verlässt den grünen Strahl--nächster Blocker los!' WHERE `id`=1716;
diff --git a/data/sql/playerbots/updates/2025_11_25_00_ai_playerbot_pet_action_texts.sql b/data/sql/playerbots/updates/2025_11_25_00_ai_playerbot_pet_action_texts.sql
new file mode 100644
index 0000000000..b7c6c96826
--- /dev/null
+++ b/data/sql/playerbots/updates/2025_11_25_00_ai_playerbot_pet_action_texts.sql
@@ -0,0 +1,255 @@
+DELETE FROM ai_playerbot_texts WHERE name IN (
+ 'pet_usage_error',
+ 'pet_no_pet_error',
+ 'pet_stance_report',
+ 'pet_no_target_error',
+ 'pet_target_dead_error',
+ 'pet_invalid_target_error',
+ 'pet_pvp_prohibited_error',
+ 'pet_attack_success',
+ 'pet_attack_failed',
+ 'pet_follow_success',
+ 'pet_stay_success',
+ 'pet_unknown_command_error',
+ 'pet_stance_set_success',
+ 'pet_type_pet',
+ 'pet_type_guardian',
+ 'pet_stance_aggressive',
+ 'pet_stance_defensive',
+ 'pet_stance_passive',
+ 'pet_stance_unknown'
+);
+
+DELETE FROM ai_playerbot_texts_chance WHERE name IN (
+ 'pet_usage_error',
+ 'pet_no_pet_error',
+ 'pet_stance_report',
+ 'pet_no_target_error',
+ 'pet_target_dead_error',
+ 'pet_invalid_target_error',
+ 'pet_pvp_prohibited_error',
+ 'pet_attack_success',
+ 'pet_attack_failed',
+ 'pet_follow_success',
+ 'pet_stay_success',
+ 'pet_unknown_command_error',
+ 'pet_stance_set_success',
+ 'pet_type_pet',
+ 'pet_type_guardian',
+ 'pet_stance_aggressive',
+ 'pet_stance_defensive',
+ 'pet_stance_passive',
+ 'pet_stance_unknown'
+);
+
+INSERT INTO ai_playerbot_texts (id, name, text, say_type, reply_type, text_loc1, text_loc2, text_loc3, text_loc4, text_loc5, text_loc6, text_loc7, text_loc8) VALUES
+(1717, 'pet_usage_error', "Usage: pet ", 0, 0,
+"사용법: pet ",
+"Utilisation: pet ",
+"Verwendung: pet ",
+"用法: pet ",
+"用法: pet ",
+"Uso: pet ",
+"Uso: pet ",
+"Использование: pet "),
+
+(1718, 'pet_no_pet_error', "You have no pet or guardian pet.", 0, 0,
+"펫이나 수호자 펫이 없습니다.",
+"Vous n'avez pas de familier ou gardien.",
+"Du hast kein Tier oder Wächter.",
+"你没有宠物或守护者宠物。",
+"你沒有寵物或守護者寵物。",
+"No tienes mascota o mascota guardián.",
+"No tienes mascota o mascota guardián.",
+"У вас нет питомца или защитника."),
+
+(1719, 'pet_stance_report', "Current stance of %type \"%name\": %stance.", 0, 0,
+"%type \"%name\"의 현재 태세: %stance.",
+"Position actuelle du %type \"%name\": %stance.",
+"Aktuelle Haltung des %type \"%name\": %stance.",
+"%type \"%name\" 的当前姿态: %stance。",
+"%type \"%name\" 的當前姿態: %stance。",
+"Postura actual del %type \"%name\": %stance.",
+"Postura actual del %type \"%name\": %stance.",
+"Текущая позиция %type \"%name\": %stance."),
+
+(1720, 'pet_no_target_error', "No valid target selected by master.", 0, 0,
+"주인이 유효한 대상을 선택하지 않았습니다.",
+"Aucune cible valide sélectionnée par le maître.",
+"Kein gültiges Ziel vom Meister ausgewählt.",
+"主人未选择有效目标。",
+"主人未選擇有效目標。",
+"No hay objetivo válido seleccionado por el maestro.",
+"No hay objetivo válido seleccionado por el maestro.",
+"Хозяин не выбрал действительную цель."),
+
+(1721, 'pet_target_dead_error', "Target is not alive.", 0, 0,
+"대상이 살아있지 않습니다.",
+"La cible n'est pas vivante.",
+"Das Ziel ist nicht am Leben.",
+"目标未存活。",
+"目標未存活。",
+"El objetivo no está vivo.",
+"El objetivo no está vivo.",
+"Цель не жива."),
+
+(1722, 'pet_invalid_target_error', "Target is not a valid attack target for the bot.", 0, 0,
+"대상이 봇에게 유효한 공격 대상이 아닙니다.",
+"La cible n'est pas une cible d'attaque valide pour le bot.",
+"Das Ziel ist kein gültiges Angriffsziel für den Bot.",
+"目标不是机器人的有效攻击目标。",
+"目標不是機器人的有效攻擊目標。",
+"El objetivo no es un objetivo de ataque válido para el bot.",
+"El objetivo no es un objetivo de ataque válido para el bot.",
+"Цель не является допустимой целью атаки для бота."),
+
+(1723, 'pet_pvp_prohibited_error', "I cannot command my pet to attack players in PvP prohibited areas.", 0, 0,
+"PvP 금지 지역에서는 펫에게 플레이어 공격 명령을 내릴 수 없습니다.",
+"Je ne peux pas commander à mon familier d'attaquer des joueurs dans les zones où le PvP est interdit.",
+"Ich kann meinem Tier nicht befehlen, Spieler in PvP-verbotenen Gebieten anzugreifen.",
+"我不能命令我的宠物在禁止PvP的区域攻击玩家。",
+"我不能命令我的寵物在禁止PvP的區域攻擊玩家。",
+"No puedo ordenar a mi mascota atacar jugadores en áreas donde el PvP está prohibido.",
+"No puedo ordenar a mi mascota atacar jugadores en áreas donde el PvP está prohibido.",
+"Я не могу приказать своему питомцу атаковать игроков в зонах, где PvP запрещено."),
+
+(1724, 'pet_attack_success', "Pet commanded to attack your target.", 0, 0,
+"펫이 당신의 대상을 공격하도록 명령했습니다.",
+"Le familier a reçu l'ordre d'attaquer votre cible.",
+"Tier wurde befohlen, dein Ziel anzugreifen.",
+"宠物已命令攻击你的目标。",
+"寵物已命令攻擊你的目標。",
+"Mascota ordenada a atacar tu objetivo.",
+"Mascota ordenada a atacar tu objetivo.",
+"Питомцу приказано атаковать вашу цель."),
+
+(1725, 'pet_attack_failed', "Pet did not attack. (Already attacking or unable to attack target)", 0, 0,
+"펫이 공격하지 않았습니다. (이미 공격 중이거나 대상 공격 불가)",
+"Le familier n'a pas attaqué. (Attaque déjà en cours ou impossible d'attaquer la cible)",
+"Tier hat nicht angegriffen. (Greift bereits an oder kann Ziel nicht angreifen)",
+"宠物未攻击。(已在攻击或无法攻击目标)",
+"寵物未攻擊。(已在攻擊或無法攻擊目標)",
+"La mascota no atacó. (Ya está atacando o no puede atacar al objetivo)",
+"La mascota no atacó. (Ya está atacando o no puede atacar al objetivo)",
+"Питомец не атаковал. (Уже атакует или не может атаковать цель)"),
+
+(1726, 'pet_follow_success', "Pet commanded to follow.", 0, 0,
+"펫이 따라오도록 명령했습니다.",
+"Le familier a reçu l'ordre de suivre.",
+"Tier wurde befohlen zu folgen.",
+"宠物已命令跟随。",
+"寵物已命令跟隨。",
+"Mascota ordenada a seguir.",
+"Mascota ordenada a seguir.",
+"Питомцу приказано следовать."),
+
+(1727, 'pet_stay_success', "Pet commanded to stay.", 0, 0,
+"펫이 머물도록 명령했습니다.",
+"Le familier a reçu l'ordre de rester.",
+"Tier wurde befohlen zu bleiben.",
+"宠物已命令停留。",
+"寵物已命令停留。",
+"Mascota ordenada a quedarse.",
+"Mascota ordenada a quedarse.",
+"Питомцу приказано остаться."),
+
+(1728, 'pet_unknown_command_error', "Unknown pet command: %param. Use: pet ", 0, 0,
+"알 수 없는 펫 명령: %param. 사용법: pet ",
+"Commande de familier inconnue: %param. Utilisation: pet ",
+"Unbekannter Tierbefehl: %param. Verwendung: pet ",
+"未知宠物命令: %param。用法: pet ",
+"未知寵物命令: %param。用法: pet ",
+"Comando de mascota desconocido: %param. Uso: pet ",
+"Comando de mascota desconocido: %param. Uso: pet ",
+"Неизвестная команда питомца: %param. Использование: pet "),
+
+(1729, 'pet_stance_set_success', "Pet stance set to %stance.", 0, 0,
+"펫 태세가 %stance(으)로 설정되었습니다.",
+"Position du familier définie sur %stance.",
+"Tierhaltung auf %stance gesetzt.",
+"宠物姿态设置为 %stance。",
+"寵物姿態設置為 %stance。",
+"Postura de mascota establecida en %stance.",
+"Postura de mascota establecida en %stance.",
+"Позиция питомца установлена на %stance."),
+
+(1730, 'pet_type_pet', "pet", 0, 0,
+"펫",
+"familier",
+"Tier",
+"宠物",
+"寵物",
+"mascota",
+"mascota",
+"питомец"),
+
+(1731, 'pet_type_guardian', "guardian", 0, 0,
+"수호자",
+"gardien",
+"Wächter",
+"守护者",
+"守護者",
+"guardián",
+"guardián",
+"защитник"),
+
+(1732, 'pet_stance_aggressive', "aggressive", 0, 0,
+"공격적",
+"agressif",
+"aggressiv",
+"进攻",
+"進攻",
+"agresivo",
+"agresivo",
+"агрессивная"),
+
+(1733, 'pet_stance_defensive', "defensive", 0, 0,
+"방어적",
+"défensif",
+"defensiv",
+"防御",
+"防禦",
+"defensivo",
+"defensivo",
+"защитная"),
+
+(1734, 'pet_stance_passive', "passive", 0, 0,
+"수동적",
+"passif",
+"passiv",
+"被动",
+"被動",
+"pasivo",
+"pasivo",
+"пассивная"),
+
+(1735, 'pet_stance_unknown', "unknown", 0, 0,
+"알 수 없음",
+"inconnu",
+"unbekannt",
+"未知",
+"未知",
+"desconocido",
+"desconocido",
+"неизвестная");
+
+INSERT INTO ai_playerbot_texts_chance (name, probability) VALUES
+('pet_usage_error', 100),
+('pet_no_pet_error', 100),
+('pet_stance_report', 100),
+('pet_no_target_error', 100),
+('pet_target_dead_error', 100),
+('pet_invalid_target_error', 100),
+('pet_pvp_prohibited_error', 100),
+('pet_attack_success', 100),
+('pet_attack_failed', 100),
+('pet_follow_success', 100),
+('pet_stay_success', 100),
+('pet_unknown_command_error', 100),
+('pet_stance_set_success', 100),
+('pet_type_pet', 100),
+('pet_type_guardian', 100),
+('pet_stance_aggressive', 100),
+('pet_stance_defensive', 100),
+('pet_stance_passive', 100),
+('pet_stance_unknown', 100);
\ No newline at end of file
diff --git a/src/AiFactory.cpp b/src/AiFactory.cpp
index 3ec1418aab..5d6377f466 100644
--- a/src/AiFactory.cpp
+++ b/src/AiFactory.cpp
@@ -413,10 +413,12 @@ void AiFactory::AddDefaultCombatStrategies(Player* player, PlayerbotAI* const fa
break;
}
- if (PlayerbotAI::IsTank(player, true)) {
+ if (PlayerbotAI::IsTank(player, true))
+ {
engine->addStrategy("tank face", false);
}
- if (PlayerbotAI::IsMelee(player, true) && PlayerbotAI::IsDps(player, true)) {
+ if (PlayerbotAI::IsMelee(player, true) && PlayerbotAI::IsDps(player, true))
+ {
engine->addStrategy("behind", false);
}
if (PlayerbotAI::IsHeal(player, true))
@@ -706,7 +708,9 @@ void AiFactory::AddDefaultNonCombatStrategies(Player* player, PlayerbotAI* const
// {
// // nonCombatEngine->addStrategy("travel");
// nonCombatEngine->addStrategy("rpg");
- // } else {
+ // }
+ // else
+ // {
// nonCombatEngine->addStrategy("move random");
// }
diff --git a/src/BroadcastHelper.cpp b/src/BroadcastHelper.cpp
index 85bc52218c..19979d3d9f 100644
--- a/src/BroadcastHelper.cpp
+++ b/src/BroadcastHelper.cpp
@@ -70,7 +70,7 @@ bool BroadcastHelper::BroadcastToChannelWithGlobalChance(PlayerbotAI* ai, std::s
return false;
}
- for (const auto& pair : toChannels)
+ for (auto const& pair : toChannels)
{
uint32 roll = urand(1, 100);
uint32 chance = pair.second;
@@ -166,7 +166,7 @@ bool BroadcastHelper::BroadcastToChannelWithGlobalChance(PlayerbotAI* ai, std::s
return false;
}
-bool BroadcastHelper::BroadcastLootingItem(PlayerbotAI* ai, Player* bot, const ItemTemplate *proto)
+bool BroadcastHelper::BroadcastLootingItem(PlayerbotAI* ai, Player* bot, ItemTemplate const* proto)
{
if (!sPlayerbotAIConfig->enableBroadcasts)
return false;
@@ -410,7 +410,6 @@ bool BroadcastHelper::BroadcastQuestUpdateComplete(PlayerbotAI* ai, Player* bot,
placeholders["%my_race"] = ai->GetChatHelper()->FormatRace(bot->getRace());
placeholders["%my_level"] = std::to_string(bot->GetLevel());
-
return BroadcastToChannelWithGlobalChance(
ai,
BOT_TEXT2("broadcast_quest_update_complete", placeholders),
diff --git a/src/ChatFilter.cpp b/src/ChatFilter.cpp
index 9a6b67002b..6025a56274 100644
--- a/src/ChatFilter.cpp
+++ b/src/ChatFilter.cpp
@@ -373,7 +373,7 @@ class SpecChatFilter : public ChatFilter
bool ParseSpecPrefix(const std::string& message, std::string& specPrefix, std::string& rest)
{
std::string msgLower = ToLower(message);
- for (const auto& entry : specTabNames)
+ for (auto const& entry : specTabNames)
{
std::string prefix = "@" + entry.second;
if (msgLower.find(ToLower(prefix)) == 0)
@@ -555,7 +555,7 @@ class AggroByChatFilter : public ChatFilter
const float radius = 100.0f;
GuidVector npcs = botAI->GetAiObjectContext()->GetValue("nearest npcs")->Get();
bool match = false;
- for (const auto& guid : npcs)
+ for (auto const& guid : npcs)
{
Creature* c = botAI->GetCreature(guid);
if (!c)
diff --git a/src/ChatHelper.cpp b/src/ChatHelper.cpp
index d1a5050960..bf28874700 100644
--- a/src/ChatHelper.cpp
+++ b/src/ChatHelper.cpp
@@ -329,9 +329,11 @@ ItemWithRandomProperty ChatHelper::parseItemWithRandomProperty(std::string const
while (currentPos < text.length()) {
size_t nextColon = text.find(':', currentPos);
- if (nextColon == std::string::npos) {
+ if (nextColon == std::string::npos)
+ {
size_t hTag = text.find("|h", currentPos);
- if (hTag != std::string::npos) {
+ if (hTag != std::string::npos)
+ {
params.push_back(text.substr(currentPos, hTag - currentPos));
}
break;
@@ -341,7 +343,8 @@ ItemWithRandomProperty ChatHelper::parseItemWithRandomProperty(std::string const
currentPos = nextColon + 1;
}
- if (params.size() >= 6) {
+ if (params.size() >= 6)
+ {
res.randomPropertyId = atoi(params[5].c_str());
}
diff --git a/src/GuildTaskMgr.cpp b/src/GuildTaskMgr.cpp
index a689abdb86..8fb4711dd7 100644
--- a/src/GuildTaskMgr.cpp
+++ b/src/GuildTaskMgr.cpp
@@ -1067,7 +1067,7 @@ void GuildTaskMgr::SendCompletionMessage(Player* player, std::string const verb)
void GuildTaskMgr::CheckKillTaskInternal(Player* player, Unit* victim)
{
ObjectGuid::LowType owner = player->GetGUID().GetCounter();
- if (victim->GetTypeId() != TYPEID_UNIT)
+ if (!victim->IsCreature())
return;
Creature* creature = reinterpret_cast(victim);
diff --git a/src/PlayerbotAI.cpp b/src/PlayerbotAI.cpp
index 9a670961e1..c1878632c6 100644
--- a/src/PlayerbotAI.cpp
+++ b/src/PlayerbotAI.cpp
@@ -14,6 +14,7 @@
#include "BudgetValues.h"
#include "ChannelMgr.h"
#include "CharacterPackets.h"
+#include "ChatHelper.h"
#include "Common.h"
#include "CreatureAIImpl.h"
#include "CreatureData.h"
@@ -106,14 +107,14 @@ void PacketHandlingHelper::AddPacket(WorldPacket const& packet)
PlayerbotAI::PlayerbotAI()
: PlayerbotAIBase(true),
bot(nullptr),
+ master(nullptr),
+ accountId(0),
aiObjectContext(nullptr),
currentEngine(nullptr),
+ currentState(BOT_STATE_NON_COMBAT),
chatHelper(this),
chatFilter(this),
- accountId(0),
- security(nullptr),
- master(nullptr),
- currentState(BOT_STATE_NON_COMBAT)
+ security(nullptr)
{
for (uint8 i = 0; i < BOT_STATE_MAX; i++)
engines[i] = nullptr;
@@ -128,9 +129,9 @@ PlayerbotAI::PlayerbotAI()
PlayerbotAI::PlayerbotAI(Player* bot)
: PlayerbotAIBase(true),
bot(bot),
+ master(nullptr),
chatHelper(this),
chatFilter(this),
- master(nullptr),
security(bot) // reorder args - whipowill
{
if (!bot->isTaxiCheater() && HasCheat((BotCheatMask::taxi)))
@@ -283,6 +284,15 @@ void PlayerbotAI::UpdateAI(uint32 elapsed, bool minimal)
return;
}
+ GameObject* goSpellTarget = currentSpell->m_targets.GetGOTarget();
+
+ if (goSpellTarget && !goSpellTarget->isSpawned())
+ {
+ InterruptSpell();
+ YieldThread(GetReactDelay());
+ return;
+ }
+
bool isHeal = false;
bool isSingleTarget = true;
@@ -355,7 +365,7 @@ void PlayerbotAI::UpdateAI(uint32 elapsed, bool minimal)
}
// Update the bot's group status (moved to helper function)
- UpdateAIGroupMembership();
+ UpdateAIGroupMaster();
// Update internal AI
UpdateAIInternal(elapsed, minimal);
@@ -363,46 +373,63 @@ void PlayerbotAI::UpdateAI(uint32 elapsed, bool minimal)
}
// Helper function for UpdateAI to check group membership and handle removal if necessary
-void PlayerbotAI::UpdateAIGroupMembership()
+void PlayerbotAI::UpdateAIGroupMaster()
{
- if (!bot || !bot->GetGroup())
+ if (!bot)
+ return;
+
+ PlayerbotAI* botAI = GET_PLAYERBOT_AI(bot);
+ if (!botAI)
return;
Group* group = bot->GetGroup();
- if (!bot->InBattleground() && !bot->inRandomLfgDungeon() && !group->isLFGGroup())
+ bool IsRandomBot = sRandomPlayerbotMgr->IsRandomBot(bot);
+
+ // If bot is not in group verify that for is RandomBot before clearing master and resetting.
+ if (!group)
{
- Player* leader = group->GetLeader();
- if (leader && leader != bot) // Ensure the leader is valid and not the bot itself
+ if (master && IsRandomBot)
{
- PlayerbotAI* leaderAI = GET_PLAYERBOT_AI(leader);
- if (leaderAI && !leaderAI->IsRealPlayer())
- {
- LeaveOrDisbandGroup();
- }
+ SetMaster(nullptr);
+ Reset(true);
+ ResetStrategies();
}
+ return;
}
- else if (group->isLFGGroup())
- {
- bool hasRealPlayer = false;
- // Iterate over all group members to check if at least one is a real player
- for (GroupReference* ref = group->GetFirstMember(); ref; ref = ref->next())
- {
- Player* member = ref->GetSource();
- if (!member)
- continue;
+ // Bot in BG, but master no longer part of a group: release master
+ // Exclude alt and addclass bots as they rely on current (real player) master, security-wise.
+ if (bot->InBattleground() && IsRandomBot && master && !master->GetGroup())
+ SetMaster(nullptr);
- PlayerbotAI* memberAI = GET_PLAYERBOT_AI(member);
- if (memberAI && !memberAI->IsRealPlayer())
- continue;
+ PlayerbotAI* masterBotAI = nullptr;
+ if (master)
+ masterBotAI = GET_PLAYERBOT_AI(master);
- hasRealPlayer = true;
- break;
- }
- if (!hasRealPlayer)
+ if (!master || (masterBotAI && !masterBotAI->IsRealPlayer()))
+ {
+ Player* newMaster = FindNewMaster();
+ if (newMaster)
{
- LeaveOrDisbandGroup();
+ master = newMaster;
+ botAI->SetMaster(newMaster);
+ botAI->ResetStrategies();
+
+ if (!bot->InBattleground())
+ {
+ botAI->ChangeStrategy("+follow", BOT_STATE_NON_COMBAT);
+
+ if (botAI->GetMaster() == botAI->GetGroupLeader())
+ botAI->TellMaster("Hello, I follow you!");
+ else
+ botAI->TellMaster(!urand(0, 2) ? "Hello!" : "Hi!");
+ }
+ else
+ {
+ // we're in a battleground, stay with the pack and focus on objective
+ botAI->ChangeStrategy("-follow", BOT_STATE_NON_COMBAT);
+ }
}
}
}
@@ -792,7 +819,6 @@ void PlayerbotAI::LeaveOrDisbandGroup()
WorldPacket* packet = new WorldPacket(CMSG_GROUP_DISBAND);
bot->GetSession()->QueuePacket(packet);
- ResetStrategies();
}
bool PlayerbotAI::IsAllowedCommand(std::string const text)
@@ -1301,7 +1327,6 @@ void PlayerbotAI::DoNextAction(bool min)
return;
}
-
// Change engine if just died
bool isBotAlive = bot->IsAlive();
if (currentEngine != engines[BOT_STATE_DEAD] && !isBotAlive)
@@ -1359,95 +1384,6 @@ void PlayerbotAI::DoNextAction(bool min)
else if (bot->isAFK())
bot->ToggleAFK();
- Group* group = bot->GetGroup();
- PlayerbotAI* masterBotAI = nullptr;
- if (master)
- masterBotAI = GET_PLAYERBOT_AI(master);
-
- // Test BG master set
- if ((!master || (masterBotAI && !masterBotAI->IsRealPlayer())) && group)
- {
- PlayerbotAI* botAI = GET_PLAYERBOT_AI(bot);
- if (!botAI)
- {
- return;
- }
-
- // Ideally we want to have the leader as master.
- Player* newMaster = botAI->GetGroupMaster();
- Player* playerMaster = nullptr;
-
- // Are there any non-bot players in the group?
- if (!newMaster || GET_PLAYERBOT_AI(newMaster))
- {
- for (GroupReference* gref = group->GetFirstMember(); gref; gref = gref->next())
- {
- Player* member = gref->GetSource();
- if (!member || member == bot || member == newMaster || !member->IsInWorld() ||
- !member->IsInSameRaidWith(bot))
- continue;
-
- PlayerbotAI* memberBotAI = GET_PLAYERBOT_AI(member);
- if (memberBotAI)
- {
- if (memberBotAI->IsRealPlayer() && !bot->InBattleground())
- playerMaster = member;
-
- continue;
- }
-
- // Same BG checks (optimize checking conditions here)
- if (bot->InBattleground() && bot->GetBattleground() &&
- bot->GetBattleground()->GetBgTypeID() == BATTLEGROUND_AV && !GET_PLAYERBOT_AI(member) &&
- member->InBattleground() && bot->GetMapId() == member->GetMapId())
- {
- // Skip if same BG but same subgroup or lower level
- if (!group->SameSubGroup(bot, member) || member->GetLevel() < bot->GetLevel())
- continue;
-
- // Follow real player only if higher honor points
- uint32 honorpts = member->GetHonorPoints();
- if (bot->GetHonorPoints() && honorpts < bot->GetHonorPoints())
- continue;
-
- playerMaster = member;
- continue;
- }
-
- if (bot->InBattleground())
- continue;
-
- newMaster = member;
- break;
- }
- }
-
- if (!newMaster && playerMaster)
- newMaster = playerMaster;
-
- if (newMaster && (!master || master != newMaster) && bot != newMaster)
- {
- master = newMaster;
- botAI->SetMaster(newMaster);
- botAI->ResetStrategies();
-
- if (!bot->InBattleground())
- {
- botAI->ChangeStrategy("+follow", BOT_STATE_NON_COMBAT);
-
- if (botAI->GetMaster() == botAI->GetGroupMaster())
- botAI->TellMaster("Hello, I follow you!");
- else
- botAI->TellMaster(!urand(0, 2) ? "Hello!" : "Hi!");
- }
- else
- {
- // we're in a battleground, stay with the pack and focus on objective
- botAI->ChangeStrategy("-follow", BOT_STATE_NON_COMBAT);
- }
- }
- }
-
if (master && master->IsInWorld())
{
float distance = sServerFacade->GetDistance2d(bot, master);
@@ -1517,22 +1453,28 @@ void PlayerbotAI::ApplyInstanceStrategies(uint32 mapId, bool tellMaster)
switch (mapId)
{
case 249:
- strategyName = "onyxia"; // Onyxia's Lair
+ strategyName = "onyxia"; // Onyxia's Lair
break;
case 409:
- strategyName = "mc"; // Molten Core
+ strategyName = "moltencore"; // Molten Core
break;
case 469:
- strategyName = "bwl"; // Blackwing Lair
+ strategyName = "bwl"; // Blackwing Lair
break;
case 509:
- strategyName = "aq20"; // Ruins of Ahn'Qiraj
+ strategyName = "aq20"; // Ruins of Ahn'Qiraj
break;
case 532:
strategyName = "karazhan"; // Karazhan
break;
case 533:
- strategyName = "naxx"; // Naxxramas
+ strategyName = "naxx"; // Naxxramas
+ break;
+ case 544:
+ strategyName = "magtheridon"; // Magtheridon's Lair
+ break;
+ case 565:
+ strategyName = "gruulslair"; // Gruul's Lair
break;
case 574:
strategyName = "wotlk-uk"; // Utgarde Keep
@@ -1865,11 +1807,11 @@ int32 PlayerbotAI::GetAssistTankIndex(Player* player)
{
return -1;
}
+
int counter = 0;
for (GroupReference* ref = group->GetFirstMember(); ref; ref = ref->next())
{
Player* member = ref->GetSource();
-
if (!member)
{
continue;
@@ -1879,11 +1821,13 @@ int32 PlayerbotAI::GetAssistTankIndex(Player* player)
{
return counter;
}
+
if (IsTank(member, true) && group->IsAssistant(member->GetGUID()))
{
counter++;
}
}
+
return 0;
}
@@ -2196,14 +2140,15 @@ bool PlayerbotAI::IsMainTank(Player* player)
break;
}
}
+
if (mainTank != ObjectGuid::Empty)
{
return player->GetGUID() == mainTank;
}
+
for (GroupReference* ref = group->GetFirstMember(); ref; ref = ref->next())
{
Player* member = ref->GetSource();
-
if (!member)
{
continue;
@@ -2214,6 +2159,7 @@ bool PlayerbotAI::IsMainTank(Player* player)
return player->GetGUID() == member->GetGUID();
}
}
+
return false;
}
@@ -2235,8 +2181,7 @@ bool PlayerbotAI::IsBotMainTank(Player* player)
return true; // If no group, consider the bot as main tank
}
- uint32 botAssistTankIndex = GetAssistTankIndex(player);
-
+ int32 botAssistTankIndex = GetAssistTankIndex(player);
if (botAssistTankIndex == -1)
{
return false;
@@ -2250,8 +2195,7 @@ bool PlayerbotAI::IsBotMainTank(Player* player)
continue;
}
- uint32 memberAssistTankIndex = GetAssistTankIndex(member);
-
+ int32 memberAssistTankIndex = GetAssistTankIndex(member);
if (memberAssistTankIndex == -1)
{
continue;
@@ -2300,7 +2244,7 @@ uint32 PlayerbotAI::GetGroupTankNum(Player* player)
bool PlayerbotAI::IsAssistTank(Player* player) { return IsTank(player) && !IsMainTank(player); }
-bool PlayerbotAI::IsAssistTankOfIndex(Player* player, int index)
+bool PlayerbotAI::IsAssistTankOfIndex(Player* player, int index, bool ignoreDeadPlayers)
{
Group* group = player->GetGroup();
if (!group)
@@ -2317,6 +2261,9 @@ bool PlayerbotAI::IsAssistTankOfIndex(Player* player, int index)
continue;
}
+ if (ignoreDeadPlayers && !member->IsAlive())
+ continue;
+
if (group->IsAssistant(member->GetGUID()) && IsAssistTank(member))
{
if (index == counter)
@@ -2336,6 +2283,9 @@ bool PlayerbotAI::IsAssistTankOfIndex(Player* player, int index)
continue;
}
+ if (ignoreDeadPlayers && !member->IsAlive())
+ continue;
+
if (!group->IsAssistant(member->GetGUID()) && IsAssistTank(member))
{
if (index == counter)
@@ -3167,8 +3117,10 @@ bool PlayerbotAI::CanCastSpell(uint32 spellid, Unit* target, bool checkHasSpell,
SpellCastResult result = spell->CheckCast(true);
delete spell;
- // if (!sPlayerbotAIConfig->logInGroupOnly || (bot->GetGroup() && HasRealPlayerMaster())) {
- // if (result != SPELL_FAILED_NOT_READY && result != SPELL_CAST_OK) {
+ // if (!sPlayerbotAIConfig->logInGroupOnly || (bot->GetGroup() && HasRealPlayerMaster()))
+ // {
+ // if (result != SPELL_FAILED_NOT_READY && result != SPELL_CAST_OK)
+ // {
// LOG_DEBUG("playerbots", "CanCastSpell - target name: {}, spellid: {}, bot name: {}, result: {}",
// target->GetName(), spellid, bot->GetName(), result);
// }
@@ -3191,7 +3143,6 @@ bool PlayerbotAI::CanCastSpell(uint32 spellid, Unit* target, bool checkHasSpell,
default:
if (!sPlayerbotAIConfig->logInGroupOnly || (bot->GetGroup() && HasRealPlayerMaster()))
{
- // if (result != SPELL_FAILED_NOT_READY && result != SPELL_CAST_OK) {
LOG_DEBUG("playerbots",
"CanCastSpell Check Failed. - target name: {}, spellid: {}, bot name: {}, result: {}",
target->GetName(), spellid, bot->GetName(), result);
@@ -3374,7 +3325,8 @@ bool PlayerbotAI::CastSpell(uint32 spellId, Unit* target, Item* itemTarget)
if (bot->IsFlying() || bot->HasUnitState(UNIT_STATE_IN_FLIGHT))
{
- // if (!sPlayerbotAIConfig->logInGroupOnly || (bot->GetGroup() && HasRealPlayerMaster())) {
+ // if (!sPlayerbotAIConfig->logInGroupOnly || (bot->GetGroup() && HasRealPlayerMaster()))
+ // {
// LOG_DEBUG("playerbots", "Spell cast is flying - target name: {}, spellid: {}, bot name: {}}",
// target->GetName(), spellId, bot->GetName());
// }
@@ -3419,7 +3371,8 @@ bool PlayerbotAI::CastSpell(uint32 spellId, Unit* target, Item* itemTarget)
{
bot->GetTradeData()->SetSpell(spellId);
delete spell;
- // if (!sPlayerbotAIConfig->logInGroupOnly || (bot->GetGroup() && HasRealPlayerMaster())) {
+ // if (!sPlayerbotAIConfig->logInGroupOnly || (bot->GetGroup() && HasRealPlayerMaster()))
+ // {
// LOG_DEBUG("playerbots", "Spell cast no item - target name: {}, spellid: {}, bot name: {}",
// target->GetName(), spellId, bot->GetName());
// }
@@ -3488,7 +3441,8 @@ bool PlayerbotAI::CastSpell(uint32 spellId, Unit* target, Item* itemTarget)
// spell->m_targets.SetUnitTarget(target);
// SpellCastResult spellSuccess = spell->CheckCast(true);
- // if (!sPlayerbotAIConfig->logInGroupOnly || (bot->GetGroup() && HasRealPlayerMaster())) {
+ // if (!sPlayerbotAIConfig->logInGroupOnly || (bot->GetGroup() && HasRealPlayerMaster()))
+ // {
// LOG_DEBUG("playerbots", "Spell cast result - target name: {}, spellid: {}, bot name: {}, result: {}",
// target->GetName(), spellId, bot->GetName(), spellSuccess);
// }
@@ -3499,7 +3453,8 @@ bool PlayerbotAI::CastSpell(uint32 spellId, Unit* target, Item* itemTarget)
if (result != SPELL_CAST_OK)
{
- // if (!sPlayerbotAIConfig->logInGroupOnly || (bot->GetGroup() && HasRealPlayerMaster())) {
+ // if (!sPlayerbotAIConfig->logInGroupOnly || (bot->GetGroup() && HasRealPlayerMaster()))
+ // {
// LOG_DEBUG("playerbots", "Spell cast failed. - target name: {}, spellid: {}, bot name: {}, result: {}",
// target->GetName(), spellId, bot->GetName(), result);
// }
@@ -3566,7 +3521,8 @@ bool PlayerbotAI::CastSpell(uint32 spellId, Unit* target, Item* itemTarget)
// {
// spell->cancel();
// delete spell;
- // if (!sPlayerbotAIConfig->logInGroupOnly || (bot->GetGroup() && HasRealPlayerMaster())) {
+ // if (!sPlayerbotAIConfig->logInGroupOnly || (bot->GetGroup() && HasRealPlayerMaster()))
+ // {
// LOG_DEBUG("playerbots", "Spell cast loot - target name: {}, spellid: {}, bot name: {}",
// target->GetName(), spellId, bot->GetName());
// }
@@ -4130,6 +4086,50 @@ bool IsAlliance(uint8 race)
race == RACE_DRAENEI;
}
+Player* PlayerbotAI::FindNewMaster()
+{
+ // Ideally we want to have the leader as master.
+ Group* group = bot->GetGroup();
+ // Only allow real players as masters unless in battleground.
+ if (!group)
+ return nullptr;
+
+ Player* groupLeader = GetGroupLeader();
+ PlayerbotAI* leaderBotAI = GET_PLAYERBOT_AI(groupLeader);
+ if (!leaderBotAI || leaderBotAI->IsRealPlayer())
+ return groupLeader;
+
+ // Find the real player in group
+ for (GroupReference* gref = group->GetFirstMember(); gref; gref = gref->next())
+ {
+ Player* member = gref->GetSource();
+ if (!member || member == bot || !member->IsInWorld() ||
+ !member->IsInSameRaidWith(bot))
+ continue;
+
+ PlayerbotAI* memberBotAI = GET_PLAYERBOT_AI(member);
+ if ((!memberBotAI || memberBotAI->IsRealPlayer()) && !bot->InBattleground())
+ return member;
+
+ if (bot->InBattleground() && bot->GetBattleground() &&
+ bot->GetBattleground()->GetBgTypeID() == BATTLEGROUND_AV && !GET_PLAYERBOT_AI(member) &&
+ member->InBattleground() && bot->GetMapId() == member->GetMapId())
+ {
+ // Skip if same BG but same subgroup or lower level
+ if (!group->SameSubGroup(bot, member) || member->GetLevel() < bot->GetLevel())
+ continue;
+
+ // Follow real player only if higher honor points
+ uint32 honorpts = member->GetHonorPoints();
+ if (bot->GetHonorPoints() && honorpts < bot->GetHonorPoints())
+ continue;
+
+ return member;
+ }
+ }
+ return nullptr;
+}
+
bool PlayerbotAI::HasRealPlayerMaster()
{
if (master)
@@ -4145,7 +4145,7 @@ bool PlayerbotAI::HasActivePlayerMaster() { return master && !GET_PLAYERBOT_AI(m
bool PlayerbotAI::IsAlt() { return HasRealPlayerMaster() && !sRandomPlayerbotMgr->IsRandomBot(bot); }
-Player* PlayerbotAI::GetGroupMaster()
+Player* PlayerbotAI::GetGroupLeader()
{
if (!bot->InBattleground())
if (Group* group = bot->GetGroup())
@@ -4753,7 +4753,6 @@ uint32 PlayerbotAI::GetEquipGearScore(Player* player)
sum += gearScore[i];
}
-
if (count)
{
uint32 res = uint32(sum / count);
@@ -5290,7 +5289,7 @@ Item* PlayerbotAI::FindOpenableItem() const
return FindItemInInventory(
[this](ItemTemplate const* itemTemplate) -> bool
{
- return (itemTemplate->Flags & ITEM_FLAG_HAS_LOOT) &&
+ return itemTemplate->HasFlag(ITEM_FLAG_HAS_LOOT) &&
(itemTemplate->LockID == 0 || !this->bot->GetItemByEntry(itemTemplate->ItemId)->IsLocked());
});
}
@@ -5441,7 +5440,7 @@ Item* PlayerbotAI::FindOilFor(Item* weapon) const
if (prioritizedOils)
{
- for (const auto& id : *prioritizedOils)
+ for (auto const& id : *prioritizedOils)
{
oil = FindConsumable(id);
if (oil)
diff --git a/src/PlayerbotAI.h b/src/PlayerbotAI.h
index a6600845fe..3b9eaab1ea 100644
--- a/src/PlayerbotAI.h
+++ b/src/PlayerbotAI.h
@@ -428,7 +428,7 @@ class PlayerbotAI : public PlayerbotAIBase
static bool IsMainTank(Player* player);
static uint32 GetGroupTankNum(Player* player);
static bool IsAssistTank(Player* player);
- static bool IsAssistTankOfIndex(Player* player, int index);
+ static bool IsAssistTankOfIndex(Player* player, int index, bool ignoreDeadPlayers = false);
static bool IsHealAssistantOfIndex(Player* player, int index);
static bool IsRangedDpsAssistantOfIndex(Player* player, int index);
bool HasAggro(Unit* unit);
@@ -529,6 +529,7 @@ class PlayerbotAI : public PlayerbotAIBase
Player* GetBot() { return bot; }
Player* GetMaster() { return master; }
+ Player* FindNewMaster();
// Checks if the bot is really a player. Players always have themselves as master.
bool IsRealPlayer() { return master ? (master == bot) : false; }
@@ -539,7 +540,7 @@ class PlayerbotAI : public PlayerbotAIBase
// Get the group leader or the master of the bot.
// Checks if the bot is summoned as alt of a player
bool IsAlt();
- Player* GetGroupMaster();
+ Player* GetGroupLeader();
// Returns a semi-random (cycling) number that is fixed for each bot.
uint32 GetFixedBotNumer(uint32 maxNum = 100, float cyclePerMin = 1);
GrouperType GetGrouperType();
@@ -611,7 +612,7 @@ class PlayerbotAI : public PlayerbotAIBase
static void _fillGearScoreData(Player* player, Item* item, std::vector* gearScore, uint32& twoHandScore,
bool mixed = false);
bool IsTellAllowed(PlayerbotSecurityLevel securityLevel = PLAYERBOT_SECURITY_ALLOW_ALL);
- void UpdateAIGroupMembership();
+ void UpdateAIGroupMaster();
Item* FindItemInInventory(std::function checkItem) const;
void HandleCommands();
void HandleCommand(uint32 type, const std::string& text, Player& fromPlayer, const uint32 lang = LANG_UNIVERSAL);
diff --git a/src/PlayerbotAIConfig.cpp b/src/PlayerbotAIConfig.cpp
index e6bc1baf7d..64065d8795 100644
--- a/src/PlayerbotAIConfig.cpp
+++ b/src/PlayerbotAIConfig.cpp
@@ -201,8 +201,8 @@ bool PlayerbotAIConfig::Initialize()
maxRandomBotReviveTime = sConfigMgr->GetOption("AiPlayerbot.MaxRandomBotReviveTime", 5 * MINUTE);
minRandomBotTeleportInterval = sConfigMgr->GetOption("AiPlayerbot.MinRandomBotTeleportInterval", 1 * HOUR);
maxRandomBotTeleportInterval = sConfigMgr->GetOption("AiPlayerbot.MaxRandomBotTeleportInterval", 5 * HOUR);
- permanantlyInWorldTime =
- sConfigMgr->GetOption("AiPlayerbot.PermanantlyInWorldTime", 1 * YEAR);
+ permanentlyInWorldTime =
+ sConfigMgr->GetOption("AiPlayerbot.PermanentlyInWorldTime", 1 * YEAR);
randomBotTeleportDistance = sConfigMgr->GetOption("AiPlayerbot.RandomBotTeleportDistance", 100);
randomBotsPerInterval = sConfigMgr->GetOption("AiPlayerbot.RandomBotsPerInterval", 60);
minRandomBotsPriceChangeInterval =
@@ -773,8 +773,8 @@ std::string const PlayerbotAIConfig::GetTimestampStr()
// HH hour (2 digits 00-23)
// MM minutes (2 digits 00-59)
// SS seconds (2 digits 00-59)
- char buf[20];
- snprintf(buf, 20, "%04d-%02d-%02d %02d-%02d-%02d", aTm->tm_year + 1900, aTm->tm_mon + 1, aTm->tm_mday, aTm->tm_hour,
+ char buf[32];
+ snprintf(buf, sizeof(buf), "%04d-%02d-%02d %02d-%02d-%02d", aTm->tm_year + 1900, aTm->tm_mon + 1, aTm->tm_mday, aTm->tm_hour,
aTm->tm_min, aTm->tm_sec);
return std::string(buf);
}
diff --git a/src/PlayerbotAIConfig.h b/src/PlayerbotAIConfig.h
index 01ad4b48e1..857a0270f0 100644
--- a/src/PlayerbotAIConfig.h
+++ b/src/PlayerbotAIConfig.h
@@ -133,7 +133,7 @@ class PlayerbotAIConfig
uint32 minRandomBotChangeStrategyTime, maxRandomBotChangeStrategyTime;
uint32 minRandomBotReviveTime, maxRandomBotReviveTime;
uint32 minRandomBotTeleportInterval, maxRandomBotTeleportInterval;
- uint32 permanantlyInWorldTime;
+ uint32 permanentlyInWorldTime;
uint32 minRandomBotPvpTime, maxRandomBotPvpTime;
uint32 randomBotsPerInterval;
uint32 minRandomBotsPriceChangeInterval, maxRandomBotsPriceChangeInterval;
diff --git a/src/PlayerbotMgr.cpp b/src/PlayerbotMgr.cpp
index b2b1a0f3c9..d96851dafc 100644
--- a/src/PlayerbotMgr.cpp
+++ b/src/PlayerbotMgr.cpp
@@ -27,7 +27,9 @@
#include "PlayerbotAIConfig.h"
#include "PlayerbotDbStore.h"
#include "PlayerbotFactory.h"
+#include "PlayerbotOperations.h"
#include "PlayerbotSecurity.h"
+#include "PlayerbotWorldThreadProcessor.h"
#include "Playerbots.h"
#include "RandomPlayerbotMgr.h"
#include "SharedDefines.h"
@@ -85,7 +87,6 @@ class PlayerbotLoginQueryHolder : public LoginQueryHolder
void PlayerbotHolder::AddPlayerBot(ObjectGuid playerGuid, uint32 masterAccountId)
{
- // bot is loading
if (botLoading.find(playerGuid) != botLoading.end())
return;
@@ -195,7 +196,9 @@ void PlayerbotHolder::HandlePlayerBotLoginCallback(PlayerbotLoginQueryHolder con
}
sRandomPlayerbotMgr->OnPlayerLogin(bot);
- OnBotLogin(bot);
+
+ auto op = std::make_unique(bot->GetGUID(), this);
+ sPlayerbotWorldProcessor->QueueOperation(std::move(op));
botLoading.erase(holder.GetGuid());
}
@@ -316,11 +319,9 @@ void PlayerbotHolder::LogoutPlayerBot(ObjectGuid guid)
if (!botAI)
return;
- Group* group = bot->GetGroup();
- if (group && !bot->InBattleground() && !bot->InBattlegroundQueue() && botAI->HasActivePlayerMaster())
- {
- sPlayerbotDbStore->Save(botAI);
- }
+ // Queue group cleanup operation for world thread
+ auto cleanupOp = std::make_unique(guid);
+ sPlayerbotWorldProcessor->QueueOperation(std::move(cleanupOp));
LOG_DEBUG("playerbots", "Bot {} logging out", bot->GetName().c_str());
bot->SaveToDB(false, false);
@@ -549,6 +550,7 @@ void PlayerbotHolder::OnBotLogin(Player* const bot)
botAI->TellMaster("Hello!", PLAYERBOT_SECURITY_TALK);
+ // Queue group operations for world thread
if (master && master->GetGroup() && !group)
{
Group* mgroup = master->GetGroup();
@@ -556,24 +558,29 @@ void PlayerbotHolder::OnBotLogin(Player* const bot)
{
if (!mgroup->isRaidGroup() && !mgroup->isLFGGroup() && !mgroup->isBGGroup() && !mgroup->isBFGroup())
{
- mgroup->ConvertToRaid();
+ // Queue ConvertToRaid operation
+ auto convertOp = std::make_unique(master->GetGUID());
+ sPlayerbotWorldProcessor->QueueOperation(std::move(convertOp));
}
if (mgroup->isRaidGroup())
{
- mgroup->AddMember(bot);
+ // Queue AddMember operation
+ auto addOp = std::make_unique(master->GetGUID(), bot->GetGUID());
+ sPlayerbotWorldProcessor->QueueOperation(std::move(addOp));
}
}
else
{
- mgroup->AddMember(bot);
+ // Queue AddMember operation
+ auto addOp = std::make_unique(master->GetGUID(), bot->GetGUID());
+ sPlayerbotWorldProcessor->QueueOperation(std::move(addOp));
}
}
else if (master && !group)
{
- Group* newGroup = new Group();
- newGroup->Create(master);
- sGroupMgr->AddGroup(newGroup);
- newGroup->AddMember(bot);
+ // Queue group creation and AddMember operation
+ auto inviteOp = std::make_unique(master->GetGUID(), bot->GetGUID());
+ sPlayerbotWorldProcessor->QueueOperation(std::move(inviteOp));
}
// if (master)
// {
@@ -1602,8 +1609,26 @@ void PlayerbotMgr::OnBotLoginInternal(Player* const bot)
void PlayerbotMgr::OnPlayerLogin(Player* player)
{
+ if (!player)
+ return;
+
+ WorldSession* session = player->GetSession();
+ if (!session)
+ {
+ LOG_WARN("playerbots", "Unable to register locale priority for player {} because the session is missing", player->GetName());
+ return;
+ }
+
+ // DB locale (source of bot text translation)
+ LocaleConstant const databaseLocale = session->GetSessionDbLocaleIndex();
+
+ // For bot texts (DB-driven), prefer the database locale with a safe fallback.
+ LocaleConstant usedLocale = databaseLocale;
+ if (usedLocale >= MAX_LOCALES)
+ usedLocale = LOCALE_enUS; // fallback
+
// set locale priority for bot texts
- sPlayerbotTextMgr->AddLocalePriority(player->GetSession()->GetSessionDbcLocale());
+ sPlayerbotTextMgr->AddLocalePriority(usedLocale);
if (sPlayerbotAIConfig->selfBotLevel > 2)
HandlePlayerbotCommand("self", player);
@@ -1611,7 +1636,7 @@ void PlayerbotMgr::OnPlayerLogin(Player* player)
if (!sPlayerbotAIConfig->botAutologin)
return;
- uint32 accountId = player->GetSession()->GetAccountId();
+ uint32 accountId = session->GetAccountId();
QueryResult results = CharacterDatabase.Query("SELECT name FROM characters WHERE account = {}", accountId);
if (results)
{
@@ -1736,7 +1761,8 @@ PlayerbotAI* PlayerbotsMgr::GetPlayerbotAI(Player* player)
{
return nullptr;
}
- // if (player->GetSession()->isLogingOut() || player->IsDuringRemoveFromWorld()) {
+ // if (player->GetSession()->isLogingOut() || player->IsDuringRemoveFromWorld())
+ // {
// return nullptr;
// }
auto itr = _playerbotsAIMap.find(player->GetGUID());
diff --git a/src/PlayerbotOperation.h b/src/PlayerbotOperation.h
new file mode 100644
index 0000000000..6ac303d323
--- /dev/null
+++ b/src/PlayerbotOperation.h
@@ -0,0 +1,93 @@
+/*
+ * Copyright (C) 2016+ AzerothCore , released under GNU AGPL v3 license, you may redistribute it
+ * and/or modify it under version 3 of the License, or (at your option), any later version.
+ */
+
+#ifndef _PLAYERBOT_OPERATION_H
+#define _PLAYERBOT_OPERATION_H
+
+#include "Common.h"
+#include "ObjectGuid.h"
+#include
+
+/**
+ * @brief Base class for thread-unsafe operations that must be executed in the world thread
+ *
+ * PlayerbotOperation represents an operation that needs to be deferred from a map thread
+ * to the world thread for safe execution. Examples include group modifications, LFG operations,
+ * guild operations, etc.
+ *
+ * Thread Safety:
+ * - The constructor and data members must be thread-safe (use copies, not pointers)
+ * - Execute() is called in the world thread and can safely perform thread-unsafe operations
+ * - Subclasses must not store raw pointers to (core/world thread) game object (use ObjectGuid instead)
+ */
+class PlayerbotOperation
+{
+public:
+ virtual ~PlayerbotOperation() = default;
+
+ /**
+ * @brief Execute this operation in the world thread
+ *
+ * This method is called by PlayerbotWorldThreadProcessor::Update() which runs in the world thread.
+ * It's safe to perform any thread-unsafe operation here (Group, LFG, Guild, etc.)
+ *
+ * @return true if operation succeeded, false if it failed
+ */
+ virtual bool Execute() = 0;
+
+ /**
+ * @brief Get the bot GUID this operation is for (optional)
+ *
+ * Used for logging and debugging purposes.
+ *
+ * @return ObjectGuid of the bot, or ObjectGuid::Empty if not applicable
+ */
+ virtual ObjectGuid GetBotGuid() const { return ObjectGuid::Empty; }
+
+ /**
+ * @brief Get the operation priority (higher = more urgent)
+ *
+ * Priority levels:
+ * - 100: Critical (crash prevention, cleanup operations)
+ * - 50: High (player-facing operations like group invites)
+ * - 10: Normal (background operations)
+ * - 0: Low (statistics, logging)
+ *
+ * @return Priority value (0-100)
+ */
+ virtual uint32 GetPriority() const { return 10; }
+
+ /**
+ * @brief Get a human-readable name for this operation
+ *
+ * Used for logging and debugging.
+ *
+ * @return Operation name
+ */
+ virtual std::string GetName() const { return "Unknown Operation"; }
+
+ /**
+ * @brief Check if this operation is still valid
+ *
+ * Called before Execute() to check if the operation should still be executed.
+ * For example, if a bot logged out, group invite operations for that bot can be skipped.
+ *
+ * @return true if operation should be executed, false to skip
+ */
+ virtual bool IsValid() const { return true; }
+};
+
+/**
+ * @brief Comparison operator for priority queue (higher priority first)
+ */
+struct PlayerbotOperationComparator
+{
+ bool operator()(const std::unique_ptr& a, const std::unique_ptr& b) const
+ {
+ return a->GetPriority() < b->GetPriority(); // Lower priority goes to back of queue
+ }
+};
+
+#endif
diff --git a/src/PlayerbotOperations.h b/src/PlayerbotOperations.h
new file mode 100644
index 0000000000..d7c2b47bb8
--- /dev/null
+++ b/src/PlayerbotOperations.h
@@ -0,0 +1,500 @@
+/*
+ * Copyright (C) 2016+ AzerothCore , released under GNU AGPL v3 license, you may redistribute it
+ * and/or modify it under version 3 of the License, or (at your option), any later version.
+ */
+
+#ifndef _PLAYERBOT_OPERATIONS_H
+#define _PLAYERBOT_OPERATIONS_H
+
+#include "Group.h"
+#include "GroupMgr.h"
+#include "GuildMgr.h"
+#include "ObjectAccessor.h"
+#include "PlayerbotOperation.h"
+#include "Player.h"
+#include "PlayerbotAI.h"
+#include "PlayerbotMgr.h"
+#include "PlayerbotDbStore.h"
+#include "RandomPlayerbotMgr.h"
+
+// Group invite operation
+class GroupInviteOperation : public PlayerbotOperation
+{
+public:
+ GroupInviteOperation(ObjectGuid botGuid, ObjectGuid targetGuid)
+ : m_botGuid(botGuid), m_targetGuid(targetGuid)
+ {
+ }
+
+ bool Execute() override
+ {
+ Player* bot = ObjectAccessor::FindPlayer(m_botGuid);
+ Player* target = ObjectAccessor::FindPlayer(m_targetGuid);
+
+ if (!bot || !target)
+ {
+ LOG_DEBUG("playerbots", "GroupInviteOperation: Bot or target not found");
+ return false;
+ }
+
+ // Check if target is already in a group
+ if (target->GetGroup())
+ {
+ LOG_DEBUG("playerbots", "GroupInviteOperation: Target {} is already in a group", target->GetName());
+ return false;
+ }
+
+ Group* group = bot->GetGroup();
+
+ // Create group if bot doesn't have one
+ if (!group)
+ {
+ group = new Group;
+ if (!group->Create(bot))
+ {
+ delete group;
+ LOG_ERROR("playerbots", "GroupInviteOperation: Failed to create group for bot {}", bot->GetName());
+ return false;
+ }
+ sGroupMgr->AddGroup(group);
+ LOG_DEBUG("playerbots", "GroupInviteOperation: Created new group for bot {}", bot->GetName());
+ }
+
+ // Convert to raid if needed (more than 5 members)
+ if (!group->isRaidGroup() && group->GetMembersCount() >= 5)
+ {
+ group->ConvertToRaid();
+ LOG_DEBUG("playerbots", "GroupInviteOperation: Converted group to raid");
+ }
+
+ // Add member to group
+ if (group->AddMember(target))
+ {
+ LOG_DEBUG("playerbots", "GroupInviteOperation: Successfully added {} to group", target->GetName());
+ return true;
+ }
+ else
+ {
+ LOG_ERROR("playerbots", "GroupInviteOperation: Failed to add {} to group", target->GetName());
+ return false;
+ }
+ }
+
+ ObjectGuid GetBotGuid() const override { return m_botGuid; }
+
+ uint32 GetPriority() const override { return 50; } // High priority (player-facing)
+
+ std::string GetName() const override { return "GroupInvite"; }
+
+ bool IsValid() const override
+ {
+ // Check if bot still exists and is online
+ Player* bot = ObjectAccessor::FindPlayer(m_botGuid);
+ Player* target = ObjectAccessor::FindPlayer(m_targetGuid);
+ return bot && target;
+ }
+
+private:
+ ObjectGuid m_botGuid;
+ ObjectGuid m_targetGuid;
+};
+
+// Remove member from group
+class GroupRemoveMemberOperation : public PlayerbotOperation
+{
+public:
+ GroupRemoveMemberOperation(ObjectGuid botGuid, ObjectGuid targetGuid)
+ : m_botGuid(botGuid), m_targetGuid(targetGuid)
+ {
+ }
+
+ bool Execute() override
+ {
+ Player* bot = ObjectAccessor::FindPlayer(m_botGuid);
+ Player* target = ObjectAccessor::FindPlayer(m_targetGuid);
+
+ if (!bot || !target)
+ return false;
+
+ Group* group = bot->GetGroup();
+ if (!group)
+ {
+ LOG_DEBUG("playerbots", "GroupRemoveMemberOperation: Bot is not in a group");
+ return false;
+ }
+
+ if (!group->IsMember(target->GetGUID()))
+ {
+ LOG_DEBUG("playerbots", "GroupRemoveMemberOperation: Target is not in bot's group");
+ return false;
+ }
+
+ group->RemoveMember(target->GetGUID());
+ LOG_DEBUG("playerbots", "GroupRemoveMemberOperation: Removed {} from group", target->GetName());
+ return true;
+ }
+
+ ObjectGuid GetBotGuid() const override { return m_botGuid; }
+
+ uint32 GetPriority() const override { return 50; }
+
+ std::string GetName() const override { return "GroupRemoveMember"; }
+
+ bool IsValid() const override
+ {
+ Player* bot = ObjectAccessor::FindPlayer(m_botGuid);
+ return bot != nullptr;
+ }
+
+private:
+ ObjectGuid m_botGuid;
+ ObjectGuid m_targetGuid;
+};
+
+// Convert group to raid
+class GroupConvertToRaidOperation : public PlayerbotOperation
+{
+public:
+ GroupConvertToRaidOperation(ObjectGuid botGuid) : m_botGuid(botGuid) {}
+
+ bool Execute() override
+ {
+ Player* bot = ObjectAccessor::FindPlayer(m_botGuid);
+ if (!bot)
+ return false;
+
+ Group* group = bot->GetGroup();
+ if (!group)
+ {
+ LOG_DEBUG("playerbots", "GroupConvertToRaidOperation: Bot is not in a group");
+ return false;
+ }
+
+ if (group->isRaidGroup())
+ {
+ LOG_DEBUG("playerbots", "GroupConvertToRaidOperation: Group is already a raid");
+ return true; // Success - already in desired state
+ }
+
+ group->ConvertToRaid();
+ LOG_DEBUG("playerbots", "GroupConvertToRaidOperation: Converted group to raid");
+ return true;
+ }
+
+ ObjectGuid GetBotGuid() const override { return m_botGuid; }
+
+ uint32 GetPriority() const override { return 50; }
+
+ std::string GetName() const override { return "GroupConvertToRaid"; }
+
+ bool IsValid() const override
+ {
+ Player* bot = ObjectAccessor::FindPlayer(m_botGuid);
+ return bot != nullptr;
+ }
+
+private:
+ ObjectGuid m_botGuid;
+};
+
+// Set group leader
+class GroupSetLeaderOperation : public PlayerbotOperation
+{
+public:
+ GroupSetLeaderOperation(ObjectGuid botGuid, ObjectGuid newLeaderGuid)
+ : m_botGuid(botGuid), m_newLeaderGuid(newLeaderGuid)
+ {
+ }
+
+ bool Execute() override
+ {
+ Player* bot = ObjectAccessor::FindPlayer(m_botGuid);
+ Player* newLeader = ObjectAccessor::FindPlayer(m_newLeaderGuid);
+
+ if (!bot || !newLeader)
+ return false;
+
+ Group* group = bot->GetGroup();
+ if (!group)
+ {
+ LOG_DEBUG("playerbots", "GroupSetLeaderOperation: Bot is not in a group");
+ return false;
+ }
+
+ if (!group->IsMember(newLeader->GetGUID()))
+ {
+ LOG_DEBUG("playerbots", "GroupSetLeaderOperation: New leader is not in the group");
+ return false;
+ }
+
+ group->ChangeLeader(newLeader->GetGUID());
+ LOG_DEBUG("playerbots", "GroupSetLeaderOperation: Changed leader to {}", newLeader->GetName());
+ return true;
+ }
+
+ ObjectGuid GetBotGuid() const override { return m_botGuid; }
+
+ uint32 GetPriority() const override { return 50; }
+
+ std::string GetName() const override { return "GroupSetLeader"; }
+
+ bool IsValid() const override
+ {
+ Player* bot = ObjectAccessor::FindPlayer(m_botGuid);
+ Player* newLeader = ObjectAccessor::FindPlayer(m_newLeaderGuid);
+ return bot && newLeader;
+ }
+
+private:
+ ObjectGuid m_botGuid;
+ ObjectGuid m_newLeaderGuid;
+};
+
+// Form arena group
+class ArenaGroupFormationOperation : public PlayerbotOperation
+{
+public:
+ ArenaGroupFormationOperation(ObjectGuid leaderGuid, std::vector memberGuids,
+ uint32 requiredSize, uint32 arenaTeamId, std::string arenaTeamName)
+ : m_leaderGuid(leaderGuid), m_memberGuids(memberGuids),
+ m_requiredSize(requiredSize), m_arenaTeamId(arenaTeamId), m_arenaTeamName(arenaTeamName)
+ {
+ }
+
+ bool Execute() override
+ {
+ Player* leader = ObjectAccessor::FindPlayer(m_leaderGuid);
+ if (!leader)
+ {
+ LOG_ERROR("playerbots", "ArenaGroupFormationOperation: Leader not found");
+ return false;
+ }
+
+ // Step 1: Remove all members from their existing groups
+ for (const ObjectGuid& memberGuid : m_memberGuids)
+ {
+ Player* member = ObjectAccessor::FindPlayer(memberGuid);
+ if (!member)
+ continue;
+
+ Group* memberGroup = member->GetGroup();
+ if (memberGroup)
+ {
+ memberGroup->RemoveMember(memberGuid);
+ LOG_DEBUG("playerbots", "ArenaGroupFormationOperation: Removed {} from their existing group",
+ member->GetName());
+ }
+ }
+
+ // Step 2: Disband leader's existing group
+ Group* leaderGroup = leader->GetGroup();
+ if (leaderGroup)
+ {
+ leaderGroup->Disband(true);
+ LOG_DEBUG("playerbots", "ArenaGroupFormationOperation: Disbanded leader's existing group");
+ }
+
+ // Step 3: Create new group with leader
+ Group* newGroup = new Group();
+ if (!newGroup->Create(leader))
+ {
+ delete newGroup;
+ LOG_ERROR("playerbots", "ArenaGroupFormationOperation: Failed to create arena group for leader {}",
+ leader->GetName());
+ return false;
+ }
+
+ sGroupMgr->AddGroup(newGroup);
+ LOG_DEBUG("playerbots", "ArenaGroupFormationOperation: Created new arena group with leader {}",
+ leader->GetName());
+
+ // Step 4: Add members to the new group
+ uint32 addedMembers = 0;
+ for (const ObjectGuid& memberGuid : m_memberGuids)
+ {
+ Player* member = ObjectAccessor::FindPlayer(memberGuid);
+ if (!member)
+ {
+ LOG_DEBUG("playerbots", "ArenaGroupFormationOperation: Member {} not found, skipping",
+ memberGuid.ToString());
+ continue;
+ }
+
+ if (member->GetLevel() < 70)
+ {
+ LOG_DEBUG("playerbots", "ArenaGroupFormationOperation: Member {} is below level 70, skipping",
+ member->GetName());
+ continue;
+ }
+
+ if (newGroup->AddMember(member))
+ {
+ addedMembers++;
+ LOG_DEBUG("playerbots", "ArenaGroupFormationOperation: Added {} to arena group",
+ member->GetName());
+ }
+ else
+ LOG_ERROR("playerbots", "ArenaGroupFormationOperation: Failed to add {} to arena group",
+ member->GetName());
+ }
+
+ if (addedMembers == 0)
+ {
+ LOG_ERROR("playerbots", "ArenaGroupFormationOperation: No members were added to the arena group");
+ newGroup->Disband();
+ return false;
+ }
+
+ // Step 5: Teleport members to leader and reset AI
+ for (const ObjectGuid& memberGuid : m_memberGuids)
+ {
+ Player* member = ObjectAccessor::FindPlayer(memberGuid);
+ if (!member || !newGroup->IsMember(memberGuid))
+ continue;
+
+ PlayerbotAI* memberBotAI = sPlayerbotsMgr->GetPlayerbotAI(member);
+ if (memberBotAI)
+ memberBotAI->Reset();
+
+ member->RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_TELEPORTED | AURA_INTERRUPT_FLAG_CHANGE_MAP);
+ member->TeleportTo(leader->GetMapId(), leader->GetPositionX(), leader->GetPositionY(),
+ leader->GetPositionZ(), 0);
+
+ LOG_DEBUG("playerbots", "ArenaGroupFormationOperation: Teleported {} to leader", member->GetName());
+ }
+
+ // Check if we have enough members
+ if (newGroup->GetMembersCount() < m_requiredSize)
+ {
+ LOG_INFO("playerbots", "Team #{} <{}> Group is not ready for match (not enough members: {}/{})",
+ m_arenaTeamId, m_arenaTeamName, newGroup->GetMembersCount(), m_requiredSize);
+ newGroup->Disband();
+ return false;
+ }
+
+ LOG_INFO("playerbots", "Team #{} <{}> Group is ready for match with {} members",
+ m_arenaTeamId, m_arenaTeamName, newGroup->GetMembersCount());
+ return true;
+ }
+
+ ObjectGuid GetBotGuid() const override { return m_leaderGuid; }
+
+ uint32 GetPriority() const override { return 60; } // Very high priority (arena/BG operations)
+
+ std::string GetName() const override { return "ArenaGroupFormation"; }
+
+ bool IsValid() const override
+ {
+ Player* leader = ObjectAccessor::FindPlayer(m_leaderGuid);
+ return leader != nullptr;
+ }
+
+private:
+ ObjectGuid m_leaderGuid;
+ std::vector m_memberGuids;
+ uint32 m_requiredSize;
+ uint32 m_arenaTeamId;
+ std::string m_arenaTeamName;
+};
+
+// Bot logout group cleanup operation
+class BotLogoutGroupCleanupOperation : public PlayerbotOperation
+{
+public:
+ BotLogoutGroupCleanupOperation(ObjectGuid botGuid) : m_botGuid(botGuid) {}
+
+ bool Execute() override
+ {
+ Player* bot = ObjectAccessor::FindPlayer(m_botGuid);
+ if (!bot)
+ return false;
+
+ PlayerbotAI* botAI = sPlayerbotsMgr->GetPlayerbotAI(bot);
+ if (!botAI)
+ return false;
+
+ Group* group = bot->GetGroup();
+ if (group && !bot->InBattleground() && !bot->InBattlegroundQueue() && botAI->HasActivePlayerMaster())
+ sPlayerbotDbStore->Save(botAI);
+
+ return true;
+ }
+
+ ObjectGuid GetBotGuid() const override { return m_botGuid; }
+ uint32 GetPriority() const override { return 70; }
+ std::string GetName() const override { return "BotLogoutGroupCleanup"; }
+
+ bool IsValid() const override
+ {
+ Player* bot = ObjectAccessor::FindPlayer(m_botGuid);
+ return bot != nullptr;
+ }
+
+private:
+ ObjectGuid m_botGuid;
+};
+
+// Add player bot operation (for logging in bots from map threads)
+class AddPlayerBotOperation : public PlayerbotOperation
+{
+public:
+ AddPlayerBotOperation(ObjectGuid botGuid, uint32 masterAccountId)
+ : m_botGuid(botGuid), m_masterAccountId(masterAccountId)
+ {
+ }
+
+ bool Execute() override
+ {
+ sRandomPlayerbotMgr->AddPlayerBot(m_botGuid, m_masterAccountId);
+ return true;
+ }
+
+ ObjectGuid GetBotGuid() const override { return m_botGuid; }
+
+ uint32 GetPriority() const override { return 50; } // High priority
+
+ std::string GetName() const override { return "AddPlayerBot"; }
+
+ bool IsValid() const override
+ {
+ return !ObjectAccessor::FindConnectedPlayer(m_botGuid);
+ }
+
+private:
+ ObjectGuid m_botGuid;
+ uint32 m_masterAccountId;
+};
+
+class OnBotLoginOperation : public PlayerbotOperation
+{
+public:
+ OnBotLoginOperation(ObjectGuid botGuid, PlayerbotHolder* holder)
+ : m_botGuid(botGuid), m_holder(holder)
+ {
+ }
+
+ bool Execute() override
+ {
+ Player* bot = ObjectAccessor::FindConnectedPlayer(m_botGuid);
+ if (!bot || !m_holder)
+ return false;
+
+ m_holder->OnBotLogin(bot);
+ return true;
+ }
+
+ ObjectGuid GetBotGuid() const override { return m_botGuid; }
+ uint32 GetPriority() const override { return 100; }
+ std::string GetName() const override { return "OnBotLogin"; }
+
+ bool IsValid() const override
+ {
+ return ObjectAccessor::FindConnectedPlayer(m_botGuid) != nullptr;
+ }
+
+private:
+ ObjectGuid m_botGuid;
+ PlayerbotHolder* m_holder;
+};
+
+#endif
diff --git a/src/PlayerbotSecurity.cpp b/src/PlayerbotSecurity.cpp
index 45e8598989..822f40e6d4 100644
--- a/src/PlayerbotSecurity.cpp
+++ b/src/PlayerbotSecurity.cpp
@@ -251,9 +251,9 @@ bool PlayerbotSecurity::CheckLevelFor(PlayerbotSecurityLevel level, bool silent,
out << "I am currently leading a group. I can invite you if you want.";
break;
case PLAYERBOT_DENY_NOT_LEADER:
- if (botAI->GetGroupMaster())
+ if (botAI->GetGroupLeader())
{
- out << "I am in a group with " << botAI->GetGroupMaster()->GetName()
+ out << "I am in a group with " << botAI->GetGroupLeader()->GetName()
<< ". You can ask him for invite.";
}
else
diff --git a/src/PlayerbotTextMgr.cpp b/src/PlayerbotTextMgr.cpp
index 3caa96a738..1dce9a29a5 100644
--- a/src/PlayerbotTextMgr.cpp
+++ b/src/PlayerbotTextMgr.cpp
@@ -190,26 +190,29 @@ bool PlayerbotTextMgr::GetBotText(std::string name, std::string& text, std::map<
void PlayerbotTextMgr::AddLocalePriority(uint32 locale)
{
- if (!locale)
+ if (locale >= MAX_LOCALES)
+ {
+ LOG_WARN("playerbots", "Ignoring locale {} for bot texts because it exceeds MAX_LOCALES ({})", locale, MAX_LOCALES - 1);
return;
+ }
botTextLocalePriority[locale]++;
}
uint32 PlayerbotTextMgr::GetLocalePriority()
{
- uint32 topLocale = 0;
-
// if no real players online, reset top locale
- if (!sWorldSessionMgr->GetActiveSessionCount())
+ uint32 const activeSessions = sWorldSessionMgr->GetActiveSessionCount();
+ if (!activeSessions)
{
ResetLocalePriority();
return 0;
}
+ uint32 topLocale = 0;
for (uint8 i = 0; i < MAX_LOCALES; ++i)
{
- if (botTextLocalePriority[i] > topLocale)
+ if (botTextLocalePriority[i] > botTextLocalePriority[topLocale])
topLocale = i;
}
diff --git a/src/PlayerbotWorldThreadProcessor.cpp b/src/PlayerbotWorldThreadProcessor.cpp
new file mode 100644
index 0000000000..c776eb1207
--- /dev/null
+++ b/src/PlayerbotWorldThreadProcessor.cpp
@@ -0,0 +1,217 @@
+/*
+ * Copyright (C) 2016+ AzerothCore , released under GNU AGPL v3 license, you may redistribute it
+ * and/or modify it under version 3 of the License, or (at your option), any later version.
+ */
+
+#include "PlayerbotWorldThreadProcessor.h"
+
+#include "Log.h"
+#include "PlayerbotAIConfig.h"
+
+#include
+
+PlayerbotWorldThreadProcessor::PlayerbotWorldThreadProcessor()
+ : m_enabled(true), m_maxQueueSize(10000), m_batchSize(100), m_queueWarningThreshold(80),
+ m_timeSinceLastUpdate(0), m_updateInterval(50) // Process at least every 50ms
+{
+ LOG_INFO("playerbots", "PlayerbotWorldThreadProcessor initialized");
+}
+
+PlayerbotWorldThreadProcessor::~PlayerbotWorldThreadProcessor() { ClearQueue(); }
+
+PlayerbotWorldThreadProcessor* PlayerbotWorldThreadProcessor::instance()
+{
+ static PlayerbotWorldThreadProcessor instance;
+ return &instance;
+}
+
+void PlayerbotWorldThreadProcessor::Update(uint32 diff)
+{
+ if (!m_enabled)
+ return;
+
+ // Accumulate time
+ m_timeSinceLastUpdate += diff;
+
+ // Don't process too frequently to reduce overhead
+ if (m_timeSinceLastUpdate < m_updateInterval)
+ return;
+
+ m_timeSinceLastUpdate = 0;
+
+ // Check queue health (warn if getting full)
+ CheckQueueHealth();
+
+ // Process a batch of operations
+ ProcessBatch();
+}
+
+bool PlayerbotWorldThreadProcessor::QueueOperation(std::unique_ptr operation)
+{
+ if (!operation)
+ {
+ LOG_ERROR("playerbots", "Attempted to queue null operation");
+ return false;
+ }
+
+ std::lock_guard lock(m_queueMutex);
+
+ // Check if queue is full
+ if (m_operationQueue.size() >= m_maxQueueSize)
+ {
+ LOG_ERROR("playerbots",
+ "PlayerbotWorldThreadProcessor queue is full ({} operations). Dropping operation: {}",
+ m_maxQueueSize, operation->GetName());
+
+ std::lock_guard statsLock(m_statsMutex);
+ m_stats.totalOperationsSkipped++;
+ return false;
+ }
+
+ // Queue the operation
+ m_operationQueue.push(std::move(operation));
+
+ // Update statistics
+ {
+ std::lock_guard statsLock(m_statsMutex);
+ m_stats.currentQueueSize = static_cast(m_operationQueue.size());
+ m_stats.maxQueueSize = std::max(m_stats.maxQueueSize, m_stats.currentQueueSize);
+ }
+
+ return true;
+}
+
+void PlayerbotWorldThreadProcessor::ProcessBatch()
+{
+ // Extract a batch of operations from the queue
+ std::vector> batch;
+ batch.reserve(m_batchSize);
+
+ {
+ std::lock_guard lock(m_queueMutex);
+
+ // Extract up to batchSize operations
+ while (!m_operationQueue.empty() && batch.size() < m_batchSize)
+ {
+ batch.push_back(std::move(m_operationQueue.front()));
+ m_operationQueue.pop();
+ }
+
+ // Update current queue size stat
+ std::lock_guard statsLock(m_statsMutex);
+ m_stats.currentQueueSize = static_cast(m_operationQueue.size());
+ }
+
+ // Execute operations outside of lock to avoid blocking queue
+ uint32 totalExecutionTime = 0;
+ for (auto& operation : batch)
+ {
+ if (!operation)
+ continue;
+
+ try
+ {
+ // Check if operation is still valid
+ if (!operation->IsValid())
+ {
+ LOG_DEBUG("playerbots", "Skipping invalid operation: {}", operation->GetName());
+
+ std::lock_guard statsLock(m_statsMutex);
+ m_stats.totalOperationsSkipped++;
+ continue;
+ }
+
+ // Time the execution
+ uint32 startTime = getMSTime();
+
+ // Execute the operation
+ bool success = operation->Execute();
+
+ uint32 executionTime = GetMSTimeDiffToNow(startTime);
+ totalExecutionTime += executionTime;
+
+ // Log slow operations
+ if (executionTime > 100)
+ LOG_WARN("playerbots", "Slow operation: {} took {}ms", operation->GetName(), executionTime);
+
+ // Update statistics
+ std::lock_guard statsLock(m_statsMutex);
+ if (success)
+ m_stats.totalOperationsProcessed++;
+ else
+ {
+ m_stats.totalOperationsFailed++;
+ LOG_DEBUG("playerbots", "Operation failed: {}", operation->GetName());
+ }
+ }
+ catch (std::exception const& e)
+ {
+ LOG_ERROR("playerbots", "Exception in operation {}: {}", operation->GetName(), e.what());
+
+ std::lock_guard statsLock(m_statsMutex);
+ m_stats.totalOperationsFailed++;
+ }
+ catch (...)
+ {
+ LOG_ERROR("playerbots", "Unknown exception in operation {}", operation->GetName());
+
+ std::lock_guard statsLock(m_statsMutex);
+ m_stats.totalOperationsFailed++;
+ }
+ }
+
+ // Update average execution time
+ if (!batch.empty())
+ {
+ std::lock_guard statsLock(m_statsMutex);
+ uint32 avgTime = totalExecutionTime / static_cast(batch.size());
+ // Exponential moving average
+ m_stats.averageExecutionTimeMs =
+ (m_stats.averageExecutionTimeMs * 9 + avgTime) / 10; // 90% old, 10% new
+ }
+}
+
+void PlayerbotWorldThreadProcessor::CheckQueueHealth()
+{
+ uint32 queueSize = GetQueueSize();
+ uint32 threshold = (m_maxQueueSize * m_queueWarningThreshold) / 100;
+
+ if (queueSize >= threshold)
+ {
+ LOG_WARN("playerbots",
+ "PlayerbotWorldThreadProcessor queue is {}% full ({}/{}). "
+ "Consider increasing update frequency or batch size.",
+ (queueSize * 100) / m_maxQueueSize, queueSize, m_maxQueueSize);
+ }
+}
+
+uint32 PlayerbotWorldThreadProcessor::GetQueueSize() const
+{
+ std::lock_guard lock(m_queueMutex);
+ return static_cast(m_operationQueue.size());
+}
+
+void PlayerbotWorldThreadProcessor::ClearQueue()
+{
+ std::lock_guard lock(m_queueMutex);
+
+ uint32 cleared = static_cast(m_operationQueue.size());
+ if (cleared > 0)
+ LOG_INFO("playerbots", "Clearing {} queued operations", cleared);
+
+ // Clear the queue
+ while (!m_operationQueue.empty())
+ {
+ m_operationQueue.pop();
+ }
+
+ // Reset queue size stat
+ std::lock_guard statsLock(m_statsMutex);
+ m_stats.currentQueueSize = 0;
+}
+
+PlayerbotWorldThreadProcessor::Statistics PlayerbotWorldThreadProcessor::GetStatistics() const
+{
+ std::lock_guard statsLock(m_statsMutex);
+ return m_stats; // Return a copy
+}
diff --git a/src/PlayerbotWorldThreadProcessor.h b/src/PlayerbotWorldThreadProcessor.h
new file mode 100644
index 0000000000..e37d2b5ba5
--- /dev/null
+++ b/src/PlayerbotWorldThreadProcessor.h
@@ -0,0 +1,142 @@
+/*
+ * Copyright (C) 2016+ AzerothCore , released under GNU AGPL v3 license, you may redistribute it
+ * and/or modify it under version 3 of the License, or (at your option), any later version.
+ */
+
+#ifndef _PLAYERBOT_WORLD_THREAD_PROCESSOR_H
+#define _PLAYERBOT_WORLD_THREAD_PROCESSOR_H
+
+#include "Common.h"
+#include "PlayerbotOperation.h"
+
+#include
+#include
+#include
+
+/**
+ * @brief Processes thread-unsafe bot operations in the world thread
+ *
+ * The PlayerbotWorldThreadProcessor manages a queue of operations that must be executed
+ * in the world thread rather than map threads. This ensures thread safety for operations
+ * like group modifications, LFG, guilds, battlegrounds, etc.
+ *
+ * Architecture:
+ * - Map threads queue operations via QueueOperation()
+ * - World thread processes operations via Update() (called from WorldScript::OnUpdate)
+ * - Operations are processed in priority order
+ * - Thread-safe queue protected by mutex
+ *
+ * Usage:
+ * auto op = std::make_unique(botGuid, params);
+ * sPlayerbotWorldProcessor->QueueOperation(std::move(op));
+ */
+class PlayerbotWorldThreadProcessor
+{
+public:
+ PlayerbotWorldThreadProcessor();
+ ~PlayerbotWorldThreadProcessor();
+
+ static PlayerbotWorldThreadProcessor* instance();
+
+ /**
+ * @brief Update and process queued operations (called from world thread)
+ *
+ * This method should be called from WorldScript::OnUpdate hook, which runs in the world thread.
+ * It processes a batch of queued operations.
+ *
+ * @param diff Time since last update in milliseconds
+ */
+ void Update(uint32 diff);
+
+ /**
+ * @brief Queue an operation for execution in the world thread
+ *
+ * Thread-safe method that can be called from any thread (typically map threads).
+ * The operation will be executed later during Update().
+ *
+ * @param operation Unique pointer to the operation (ownership is transferred)
+ * @return true if operation was queued, false if queue is full
+ */
+ bool QueueOperation(std::unique_ptr operation);
+
+ /**
+ * @brief Get current queue size
+ *
+ * Thread-safe method for monitoring queue size.
+ *
+ * @return Number of operations waiting to be processed
+ */
+ uint32 GetQueueSize() const;
+
+ /**
+ * @brief Clear all queued operations
+ *
+ * Used during shutdown or emergency situations.
+ */
+ void ClearQueue();
+
+ /**
+ * @brief Get statistics about operation processing
+ */
+ struct Statistics
+ {
+ uint64 totalOperationsProcessed = 0;
+ uint64 totalOperationsFailed = 0;
+ uint64 totalOperationsSkipped = 0;
+ uint32 currentQueueSize = 0;
+ uint32 maxQueueSize = 0;
+ uint32 averageExecutionTimeMs = 0;
+ };
+
+ Statistics GetStatistics() const;
+
+ /**
+ * @brief Enable/disable operation processing
+ *
+ * When disabled, operations are still queued but not processed.
+ * Useful for testing or temporary suspension.
+ *
+ * @param enabled true to enable processing, false to disable
+ */
+ void SetEnabled(bool enabled) { m_enabled = enabled; }
+
+ bool IsEnabled() const { return m_enabled; }
+
+private:
+ /**
+ * @brief Process a single batch of operations
+ *
+ * Extracts operations from queue and executes them.
+ * Called internally by Update().
+ */
+ void ProcessBatch();
+
+ /**
+ * @brief Check if queue is approaching capacity
+ *
+ * Logs warning if queue is getting full.
+ */
+ void CheckQueueHealth();
+
+ // Thread-safe queue
+ mutable std::mutex m_queueMutex;
+ std::queue> m_operationQueue;
+
+ // Configuration
+ bool m_enabled;
+ uint32 m_maxQueueSize; // Maximum operations in queue
+ uint32 m_batchSize; // Operations to process per Update()
+ uint32 m_queueWarningThreshold; // Warn when queue reaches this percentage
+
+ // Statistics
+ mutable std::mutex m_statsMutex;
+ Statistics m_stats;
+
+ // Timing
+ uint32 m_timeSinceLastUpdate;
+ uint32 m_updateInterval; // Minimum ms between updates
+};
+
+#define sPlayerbotWorldProcessor PlayerbotWorldThreadProcessor::instance()
+
+#endif
diff --git a/src/Playerbots.cpp b/src/Playerbots.cpp
index a7217d7bc4..ed4e482636 100644
--- a/src/Playerbots.cpp
+++ b/src/Playerbots.cpp
@@ -25,6 +25,7 @@
#include "Metric.h"
#include "PlayerScript.h"
#include "PlayerbotAIConfig.h"
+#include "PlayerbotWorldThreadProcessor.h"
#include "RandomPlayerbotMgr.h"
#include "ScriptMgr.h"
#include "cs_playerbots.h"
@@ -81,12 +82,12 @@ class PlayerbotsPlayerScript : public PlayerScript
PlayerbotsPlayerScript() : PlayerScript("PlayerbotsPlayerScript", {
PLAYERHOOK_ON_LOGIN,
PLAYERHOOK_ON_AFTER_UPDATE,
- PLAYERHOOK_ON_CHAT,
- PLAYERHOOK_ON_CHAT_WITH_CHANNEL,
- PLAYERHOOK_ON_CHAT_WITH_GROUP,
PLAYERHOOK_ON_BEFORE_CRITERIA_PROGRESS,
PLAYERHOOK_ON_BEFORE_ACHI_COMPLETE,
PLAYERHOOK_CAN_PLAYER_USE_PRIVATE_CHAT,
+ PLAYERHOOK_CAN_PLAYER_USE_GROUP_CHAT,
+ PLAYERHOOK_CAN_PLAYER_USE_GUILD_CHAT,
+ PLAYERHOOK_CAN_PLAYER_USE_CHANNEL_CHAT,
PLAYERHOOK_ON_GIVE_EXP,
PLAYERHOOK_ON_BEFORE_TELEPORT
}) {}
@@ -163,14 +164,17 @@ class PlayerbotsPlayerScript : public PlayerScript
{
botAI->HandleCommand(type, msg, player);
- return false;
+ // hotfix; otherwise the server will crash when whispering logout
+ // https://github.com/mod-playerbots/mod-playerbots/pull/1838
+ // TODO: find the root cause and solve it. (does not happen in party chat)
+ if (msg == "logout")
+ return false;
}
}
-
return true;
}
- void OnPlayerChat(Player* player, uint32 type, uint32 /*lang*/, std::string& msg, Group* group) override
+ bool OnPlayerCanUseChat(Player* player, uint32 type, uint32 /*lang*/, std::string& msg, Group* group) override
{
for (GroupReference* itr = group->GetFirstMember(); itr != nullptr; itr = itr->next())
{
@@ -182,9 +186,10 @@ class PlayerbotsPlayerScript : public PlayerScript
}
}
}
+ return true;
}
- void OnPlayerChat(Player* player, uint32 type, uint32 /*lang*/, std::string& msg) override
+ bool OnPlayerCanUseChat(Player* player, uint32 type, uint32 /*lang*/, std::string& msg, Guild* guild) override
{
if (type == CHAT_MSG_GUILD)
{
@@ -203,9 +208,10 @@ class PlayerbotsPlayerScript : public PlayerScript
}
}
}
+ return true;
}
- void OnPlayerChat(Player* player, uint32 type, uint32 /*lang*/, std::string& msg, Channel* channel) override
+ bool OnPlayerCanUseChat(Player* player, uint32 type, uint32 /*lang*/, std::string& msg, Channel* channel) override
{
if (PlayerbotMgr* playerbotMgr = GET_PLAYERBOT_MGR(player))
{
@@ -216,6 +222,7 @@ class PlayerbotsPlayerScript : public PlayerScript
}
sRandomPlayerbotMgr->HandleCommand(type, msg, player);
+ return true;
}
bool OnPlayerBeforeAchievementComplete(Player* player, AchievementEntry const* achievement) override
@@ -300,7 +307,8 @@ class PlayerbotsWorldScript : public WorldScript
{
public:
PlayerbotsWorldScript() : WorldScript("PlayerbotsWorldScript", {
- WORLDHOOK_ON_BEFORE_WORLD_INITIALIZED
+ WORLDHOOK_ON_BEFORE_WORLD_INITIALIZED,
+ WORLDHOOK_ON_UPDATE
}) {}
void OnBeforeWorldInitialized() override
@@ -329,6 +337,13 @@ class PlayerbotsWorldScript : public WorldScript
LOG_INFO("server.loading", ">> Loaded playerbots config in {} ms", GetMSTimeDiffToNow(oldMSTime));
LOG_INFO("server.loading", " ");
+ LOG_INFO("server.loading", "Playerbots World Thread Processor initialized");
+ }
+
+ void OnUpdate(uint32 diff) override
+ {
+ sPlayerbotWorldProcessor->Update(diff);
+ sRandomPlayerbotMgr->UpdateAI(diff); // World thread only
}
};
@@ -390,8 +405,7 @@ class PlayerbotsScript : public PlayerbotScript
void OnPlayerbotUpdate(uint32 diff) override
{
- sRandomPlayerbotMgr->UpdateAI(diff);
- sRandomPlayerbotMgr->UpdateSessions();
+ sRandomPlayerbotMgr->UpdateSessions(); // Per-bot updates only
}
void OnPlayerbotUpdateSessions(Player* player) override
diff --git a/src/RandomItemMgr.cpp b/src/RandomItemMgr.cpp
index f99c49590b..a6e143ae14 100644
--- a/src/RandomItemMgr.cpp
+++ b/src/RandomItemMgr.cpp
@@ -982,7 +982,7 @@ void RandomItemMgr::BuildItemInfoCache()
continue;
}
- if (proto->Flags & ITEM_FLAG_DEPRECATED)
+ if (proto->HasFlag(ITEM_FLAG_DEPRECATED))
{
itemForTest.insert(proto->ItemId);
continue;
@@ -1072,10 +1072,10 @@ void RandomItemMgr::BuildItemInfoCache()
// cacheInfo.team = TEAM_NEUTRAL;
// // check faction
- // if (proto->Flags2 & ITEM_FLAG2_FACTION_HORDE)
+ // if (proto->HasFlag2(ITEM_FLAG2_FACTION_HORDE))
// cacheInfo.team = TEAM_HORDE;
- // if (proto->Flags2 & ITEM_FLAG2_FACTION_ALLIANCE)
+ // if (proto->HasFlag2(ITEM_FLAG2_FACTION_ALLIANCE))
// cacheInfo.team = TEAM_ALLIANCE;
// if (cacheInfo.team == TEAM_NEUTRAL && proto->AllowableRace > 1 && proto->AllowableRace < 8388607)
@@ -1099,7 +1099,7 @@ void RandomItemMgr::BuildItemInfoCache()
// // check item source
- // if (proto->Flags & ITEM_FLAG_NO_DISENCHANT)
+ // if (proto->HasFlag(ITEM_FLAG_NO_DISENCHANT))
// {
// cacheInfo.source = ITEM_SOURCE_PVP;
// LOG_DEBUG("playerbots", "Item: {}, source: PvP Reward", proto->ItemId);
@@ -1367,7 +1367,7 @@ uint32 RandomItemMgr::CalculateStatWeight(uint8 playerclass, uint8 spec, ItemTem
}
// check item spells
- for (const auto& spellData : proto->Spells)
+ for (auto const& spellData : proto->Spells)
{
// no spell
if (!spellData.SpellId)
@@ -2374,7 +2374,6 @@ void RandomItemMgr::BuildPotionCache()
if (proto->Duration & 0x80000000)
continue;
-
if (proto->AllowableClass != -1)
continue;
diff --git a/src/RandomPlayerbotFactory.cpp b/src/RandomPlayerbotFactory.cpp
index cf5fdc915e..4be2d0edfc 100644
--- a/src/RandomPlayerbotFactory.cpp
+++ b/src/RandomPlayerbotFactory.cpp
@@ -19,188 +19,99 @@
#include "Log.h"
#include "GuildMgr.h"
-std::map> RandomPlayerbotFactory::availableRaces;
-
-constexpr RandomPlayerbotFactory::NameRaceAndGender RandomPlayerbotFactory::CombineRaceAndGender(uint8 gender,
- uint8 race)
+constexpr RandomPlayerbotFactory::NameRaceAndGender RandomPlayerbotFactory::CombineRaceAndGender(uint8 race,
+ uint8 gender)
{
+ NameRaceAndGender baseIndex;
switch (race)
{
+ case RACE_ORC: baseIndex = NameRaceAndGender::OrcMale; break;
+ case RACE_DWARF: baseIndex = NameRaceAndGender::DwarfMale; break;
+ case RACE_NIGHTELF: baseIndex = NameRaceAndGender::NightelfMale; break;
+ case RACE_TAUREN: baseIndex = NameRaceAndGender::TaurenMale; break;
+ case RACE_GNOME: baseIndex = NameRaceAndGender::GnomeMale; break;
+ case RACE_TROLL: baseIndex = NameRaceAndGender::TrollMale; break;
+ case RACE_BLOODELF: baseIndex = NameRaceAndGender::BloodelfMale; break;
+ case RACE_DRAENEI: baseIndex = NameRaceAndGender::DraeneiMale; break;
case RACE_HUMAN:
- return static_cast(static_cast(NameRaceAndGender::GenericMale) + gender);
- case RACE_ORC:
- return static_cast(static_cast(NameRaceAndGender::OrcMale) + gender);
- case RACE_DWARF:
- return static_cast(static_cast(NameRaceAndGender::DwarfMale) + gender);
- case RACE_NIGHTELF:
- return static_cast(static_cast(NameRaceAndGender::NightelfMale) + gender);
case RACE_UNDEAD_PLAYER:
- return static_cast(static_cast(NameRaceAndGender::GenericMale) + gender);
- case RACE_TAUREN:
- return static_cast(static_cast(NameRaceAndGender::TaurenMale) + gender);
- case RACE_GNOME:
- return static_cast(static_cast(NameRaceAndGender::GnomeMale) + gender);
- case RACE_TROLL:
- return static_cast(static_cast(NameRaceAndGender::TrollMale) + gender);
- case RACE_DRAENEI:
- return static_cast(static_cast(NameRaceAndGender::DraeneiMale) + gender);
- case RACE_BLOODELF:
- return static_cast(static_cast(NameRaceAndGender::BloodelfMale) + gender);
default:
- LOG_ERROR("playerbots", "The race with ID %d does not have a naming category", race);
- return static_cast(static_cast(NameRaceAndGender::GenericMale) + gender);
+ baseIndex = NameRaceAndGender::GenericMale;
+ break;
}
+
+ return static_cast(static_cast(baseIndex) + ((gender >= GENDER_NONE) ? GENDER_MALE : gender));
}
-RandomPlayerbotFactory::RandomPlayerbotFactory(uint32 accountId) : accountId(accountId)
+bool RandomPlayerbotFactory::IsValidRaceClassCombination(uint8 race, uint8 cls, uint32 expansion)
{
- uint32 const expansion = sWorld->getIntConfig(CONFIG_EXPANSION);
-
- availableRaces[CLASS_WARRIOR].push_back(RACE_HUMAN);
- availableRaces[CLASS_WARRIOR].push_back(RACE_NIGHTELF);
- availableRaces[CLASS_WARRIOR].push_back(RACE_GNOME);
- availableRaces[CLASS_WARRIOR].push_back(RACE_DWARF);
- availableRaces[CLASS_WARRIOR].push_back(RACE_ORC);
- availableRaces[CLASS_WARRIOR].push_back(RACE_UNDEAD_PLAYER);
- availableRaces[CLASS_WARRIOR].push_back(RACE_TAUREN);
- availableRaces[CLASS_WARRIOR].push_back(RACE_TROLL);
- if (expansion >= EXPANSION_THE_BURNING_CRUSADE)
- {
- availableRaces[CLASS_WARRIOR].push_back(RACE_DRAENEI);
- }
+ // skip expansion races if not playing with expansion
+ if (expansion < EXPANSION_THE_BURNING_CRUSADE && (race == RACE_BLOODELF || race == RACE_DRAENEI))
+ return false;
- availableRaces[CLASS_PALADIN].push_back(RACE_HUMAN);
- availableRaces[CLASS_PALADIN].push_back(RACE_DWARF);
- if (expansion >= EXPANSION_THE_BURNING_CRUSADE)
- {
- availableRaces[CLASS_PALADIN].push_back(RACE_DRAENEI);
- availableRaces[CLASS_PALADIN].push_back(RACE_BLOODELF);
- }
-
- availableRaces[CLASS_ROGUE].push_back(RACE_HUMAN);
- availableRaces[CLASS_ROGUE].push_back(RACE_DWARF);
- availableRaces[CLASS_ROGUE].push_back(RACE_NIGHTELF);
- availableRaces[CLASS_ROGUE].push_back(RACE_GNOME);
- availableRaces[CLASS_ROGUE].push_back(RACE_ORC);
- availableRaces[CLASS_ROGUE].push_back(RACE_UNDEAD_PLAYER);
- availableRaces[CLASS_ROGUE].push_back(RACE_TROLL);
- if (expansion >= EXPANSION_THE_BURNING_CRUSADE)
- {
- availableRaces[CLASS_ROGUE].push_back(RACE_BLOODELF);
- }
-
- availableRaces[CLASS_PRIEST].push_back(RACE_HUMAN);
- availableRaces[CLASS_PRIEST].push_back(RACE_DWARF);
- availableRaces[CLASS_PRIEST].push_back(RACE_NIGHTELF);
- availableRaces[CLASS_PRIEST].push_back(RACE_TROLL);
- availableRaces[CLASS_PRIEST].push_back(RACE_UNDEAD_PLAYER);
- if (expansion >= EXPANSION_THE_BURNING_CRUSADE)
- {
- availableRaces[CLASS_PRIEST].push_back(RACE_DRAENEI);
- availableRaces[CLASS_PRIEST].push_back(RACE_BLOODELF);
- }
-
- availableRaces[CLASS_MAGE].push_back(RACE_HUMAN);
- availableRaces[CLASS_MAGE].push_back(RACE_GNOME);
- availableRaces[CLASS_MAGE].push_back(RACE_UNDEAD_PLAYER);
- availableRaces[CLASS_MAGE].push_back(RACE_TROLL);
- if (expansion >= EXPANSION_THE_BURNING_CRUSADE)
- {
- availableRaces[CLASS_MAGE].push_back(RACE_DRAENEI);
- availableRaces[CLASS_MAGE].push_back(RACE_BLOODELF);
- }
-
- availableRaces[CLASS_WARLOCK].push_back(RACE_HUMAN);
- availableRaces[CLASS_WARLOCK].push_back(RACE_GNOME);
- availableRaces[CLASS_WARLOCK].push_back(RACE_UNDEAD_PLAYER);
- availableRaces[CLASS_WARLOCK].push_back(RACE_ORC);
- if (expansion >= EXPANSION_THE_BURNING_CRUSADE)
- {
- availableRaces[CLASS_WARLOCK].push_back(RACE_BLOODELF);
- }
+ // skip expansion classes if not playing with expansion
+ if (expansion < EXPANSION_WRATH_OF_THE_LICH_KING && cls == CLASS_DEATH_KNIGHT)
+ return false;
- availableRaces[CLASS_SHAMAN].push_back(RACE_ORC);
- availableRaces[CLASS_SHAMAN].push_back(RACE_TAUREN);
- availableRaces[CLASS_SHAMAN].push_back(RACE_TROLL);
- if (expansion >= EXPANSION_THE_BURNING_CRUSADE)
- {
- availableRaces[CLASS_SHAMAN].push_back(RACE_DRAENEI);
- }
-
- availableRaces[CLASS_HUNTER].push_back(RACE_DWARF);
- availableRaces[CLASS_HUNTER].push_back(RACE_NIGHTELF);
- availableRaces[CLASS_HUNTER].push_back(RACE_ORC);
- availableRaces[CLASS_HUNTER].push_back(RACE_TAUREN);
- availableRaces[CLASS_HUNTER].push_back(RACE_TROLL);
- if (expansion >= EXPANSION_THE_BURNING_CRUSADE)
- {
- availableRaces[CLASS_HUNTER].push_back(RACE_DRAENEI);
- availableRaces[CLASS_HUNTER].push_back(RACE_BLOODELF);
- }
-
- availableRaces[CLASS_DRUID].push_back(RACE_NIGHTELF);
- availableRaces[CLASS_DRUID].push_back(RACE_TAUREN);
-
- if (expansion == EXPANSION_WRATH_OF_THE_LICH_KING)
- {
- availableRaces[CLASS_DEATH_KNIGHT].push_back(RACE_NIGHTELF);
- availableRaces[CLASS_DEATH_KNIGHT].push_back(RACE_TAUREN);
- availableRaces[CLASS_DEATH_KNIGHT].push_back(RACE_HUMAN);
- availableRaces[CLASS_DEATH_KNIGHT].push_back(RACE_ORC);
- availableRaces[CLASS_DEATH_KNIGHT].push_back(RACE_UNDEAD_PLAYER);
- availableRaces[CLASS_DEATH_KNIGHT].push_back(RACE_TROLL);
- availableRaces[CLASS_DEATH_KNIGHT].push_back(RACE_BLOODELF);
- availableRaces[CLASS_DEATH_KNIGHT].push_back(RACE_DRAENEI);
- availableRaces[CLASS_DEATH_KNIGHT].push_back(RACE_GNOME);
- availableRaces[CLASS_DEATH_KNIGHT].push_back(RACE_DWARF);
- }
+ PlayerInfo const* info = sObjectMgr->GetPlayerInfo(race, cls);
+ return info != nullptr;
}
Player* RandomPlayerbotFactory::CreateRandomBot(WorldSession* session, uint8 cls, std::unordered_map>& nameCache)
{
- LOG_DEBUG("playerbots", "Creating new random bot for class {}", cls);
+ LOG_DEBUG("playerbots", "Creating a new random bot for class: {}", cls);
+
+ const bool alliance = static_cast(urand(0, 1));
- uint8 gender = rand() % 2 ? GENDER_MALE : GENDER_FEMALE;
- bool alliance = rand() % 2 ? true : false;
std::vector raceOptions;
- for (const auto& race : availableRaces[cls])
+ for (uint8 race = RACE_HUMAN; race < MAX_RACES; ++race)
{
+ // skip disabled with config races
+ if ((1 << (race - 1)) & sWorld->getIntConfig(CONFIG_CHARACTER_CREATING_DISABLED_RACEMASK))
+ continue;
+
+ // Try to get 50/50 faction distribution for random bot population balance.
+ // Without this check, races from the faction with more class options would dominate.
if (alliance == IsAlliance(race))
{
- raceOptions.push_back(race);
+ if (IsValidRaceClassCombination(race, cls, sWorld->getIntConfig(CONFIG_EXPANSION)))
+ raceOptions.push_back(race);
}
}
if (raceOptions.empty())
{
- LOG_ERROR("playerbots", "No races available for class: {}", cls);
+ LOG_ERROR("playerbots", "No races are available for class: {}", cls);
return nullptr;
}
- uint8 race = raceOptions[urand(0, raceOptions.size() - 1)];
-
- const auto raceAndGender = CombineRaceAndGender(gender, race);
+ const uint8 race = raceOptions[urand(0, raceOptions.size() - 1)];
+ const uint8 gender = urand(0, 1) ? GENDER_MALE : GENDER_FEMALE;
+ const auto raceAndGender = CombineRaceAndGender(race, gender);
std::string name;
- if (nameCache.empty())
- {
- name = CreateRandomBotName(raceAndGender);
- }
- else
+ if (!nameCache.empty())
{
if (nameCache[raceAndGender].empty())
{
- LOG_ERROR("playerbots", "No name found for race and gender: {}", raceAndGender);
+ LOG_ERROR("playerbots", "No names found for the specified race: {} and gender: {}",
+ race, gender);
return nullptr;
}
+
uint32 i = urand(0, nameCache[raceAndGender].size() - 1);
name = nameCache[raceAndGender][i];
swap(nameCache[raceAndGender][i], nameCache[raceAndGender].back());
nameCache[raceAndGender].pop_back();
}
+ else
+ {
+ name = CreateRandomBotName(raceAndGender);
+ }
+
if (name.empty())
{
- LOG_ERROR("playerbots", "Unable to get random bot name!");
+ LOG_ERROR("playerbots", "Failed to get a valid random bot name");
return nullptr;
}
@@ -246,19 +157,20 @@ Player* RandomPlayerbotFactory::CreateRandomBot(WorldSession* session, uint8 cls
player->CleanupsBeforeDelete();
delete player;
- LOG_ERROR("playerbots", "Unable to create random bot for account {} - name: \"{}\"; race: {}; class: {}",
- accountId, name.c_str(), race, cls);
+ LOG_ERROR("playerbots", "Unable to create random bot - name: \"{}\", race: {}, class: {}",
+ name.c_str(), race, cls);
return nullptr;
}
player->setCinematic(2);
player->SetAtLoginFlag(AT_LOGIN_NONE);
- if (player->getClass() == CLASS_DEATH_KNIGHT)
+ if (cls == CLASS_DEATH_KNIGHT)
{
player->learnSpell(50977, false);
}
- LOG_DEBUG("playerbots", "Random bot created for account {} - name: \"{}\"; race: {}; class: {}", accountId,
+
+ LOG_DEBUG("playerbots", "Random bot created - name: \"{}\", race: {}, class: {}",
name.c_str(), race, cls);
return player;
@@ -786,7 +698,7 @@ void RandomPlayerbotFactory::CreateRandomBots()
}
LOG_DEBUG("playerbots", "Creating random bot characters for account: [{}/{}]", accountNumber + 1, totalAccountCount);
- RandomPlayerbotFactory factory(accountId);
+ RandomPlayerbotFactory factory;
WorldSession* session = new WorldSession(accountId, "", 0x0, nullptr, SEC_PLAYER, EXPANSION_WRATH_OF_THE_LICH_KING,
time_t(0), LOCALE_enUS, 0, false, false, 0, true);
@@ -798,29 +710,24 @@ void RandomPlayerbotFactory::CreateRandomBots()
if (!((1 << (cls - 1)) & CLASSMASK_ALL_PLAYABLE) || !sChrClassesStore.LookupEntry(cls))
continue;
- if (bool const isClassDeathKnight = cls == CLASS_DEATH_KNIGHT;
- isClassDeathKnight && sWorld->getIntConfig(CONFIG_EXPANSION) != EXPANSION_WRATH_OF_THE_LICH_KING)
- {
+ // skip disabled with config classes
+ if ((1 << (cls - 1)) & sWorld->getIntConfig(CONFIG_CHARACTER_CREATING_DISABLED_CLASSMASK))
continue;
- }
- if (cls != 10)
+ Player* playerBot = factory.CreateRandomBot(session, cls, nameCache);
+ if (!playerBot)
{
- if (Player* playerBot = factory.CreateRandomBot(session, cls, nameCache))
- {
- playerBot->SaveToDB(true, false);
- sCharacterCache->AddCharacterCacheEntry(playerBot->GetGUID(), accountId, playerBot->GetName(),
- playerBot->getGender(), playerBot->getRace(),
- playerBot->getClass(), playerBot->GetLevel());
- playerBot->CleanupsBeforeDelete();
- delete playerBot;
- bot_creation++;
- }
- else
- {
- LOG_ERROR("playerbots", "Fail to create character for account {}", accountId);
- }
+ LOG_ERROR("playerbots", "Fail to create character for account {}", accountId);
+ continue;
}
+
+ playerBot->SaveToDB(true, false);
+ sCharacterCache->AddCharacterCacheEntry(playerBot->GetGUID(), accountId, playerBot->GetName(),
+ playerBot->getGender(), playerBot->getRace(),
+ playerBot->getClass(), playerBot->GetLevel());
+ playerBot->CleanupsBeforeDelete();
+ delete playerBot;
+ bot_creation++;
}
}
@@ -875,23 +782,67 @@ void RandomPlayerbotFactory::CreateRandomGuilds()
LOG_INFO("playerbots", "Random bot guilds deleted");
}
+ std::unordered_set botAccounts;
+ botAccounts.reserve(sPlayerbotAIConfig->randomBotAccounts.size());
+ for (uint32 acc : sPlayerbotAIConfig->randomBotAccounts)
+ botAccounts.insert(acc);
+
+ // Recount bot guilds directly from the database (does not depend on connected bots)
uint32 guildNumber = 0;
+ sPlayerbotAIConfig->randomBotGuilds.clear();
+ sPlayerbotAIConfig->randomBotGuilds.shrink_to_fit(); // avoids accumulating old capacity
+
+ if (!botAccounts.empty())
+ {
+ if (QueryResult res = CharacterDatabase.Query(
+ // We only retrieve what is necessary (guildid, leader account)
+ "SELECT g.guildid, c.account "
+ "FROM guild g JOIN characters c ON g.leaderguid = c.guid"))
+ {
+ do
+ {
+ Field* f = res->Fetch();
+ const uint32 guildId = f[0].Get();
+ const uint32 accountId = f[1].Get();
+
+ // Determine if guild leader's account is a bot account.
+ if (botAccounts.find(accountId) != botAccounts.end())
+ {
+ ++guildNumber;
+ sPlayerbotAIConfig->randomBotGuilds.push_back(guildId);
+ }
+ } while (res->NextRow());
+ }
+ }
+
+ LOG_INFO("playerbots", "{}/{} random bot guilds exist in guild table",guildNumber, sPlayerbotAIConfig->randomBotGuildCount);
+ if (guildNumber >= sPlayerbotAIConfig->randomBotGuildCount)
+ {
+ LOG_DEBUG("playerbots", "No new random guilds required");
+ return;
+ }
+
+ // We list the available leaders (online bots, not in guilds)
GuidVector availableLeaders;
- for (std::vector::iterator i = randomBots.begin(); i != randomBots.end(); ++i)
+ availableLeaders.reserve(randomBots.size()); // limit reallocs
+ for (const uint32 botLowGuid : randomBots)
{
- ObjectGuid leader = ObjectGuid::Create(*i);
- if (Guild* guild = sGuildMgr->GetGuildByLeader(leader))
+ ObjectGuid leader = ObjectGuid::Create(botLowGuid);
+ if (sGuildMgr->GetGuildByLeader(leader))
{
- ++guildNumber;
- sPlayerbotAIConfig->randomBotGuilds.push_back(guild->GetId());
+ // already GuildLeader -> ignored
+ continue;
}
else
{
- Player* player = ObjectAccessor::FindPlayer(leader);
- if (player && !player->GetGuildId())
- availableLeaders.push_back(leader);
+ if (Player* player = ObjectAccessor::FindPlayer(leader))
+ {
+ if (!player->GetGuildId())
+ availableLeaders.push_back(leader);
+ }
}
}
+ LOG_DEBUG("playerbots", "{} available leaders for new guilds found", availableLeaders.size());
// Create up to randomBotGuildCount by counting only EFFECTIVE creations
uint32 createdThisRun = 0;
@@ -899,10 +850,10 @@ void RandomPlayerbotFactory::CreateRandomGuilds()
{
std::string const guildName = CreateRandomGuildName();
if (guildName.empty())
- continue;
+ break; // no more names available in playerbots_guild_names
if (sGuildMgr->GetGuildByName(guildName))
- continue;
+ continue; // name already taken, skip
if (availableLeaders.empty())
{
@@ -981,8 +932,7 @@ void RandomPlayerbotFactory::CreateRandomGuilds()
}
// Shows the true total and how many were created during this run
- LOG_INFO("playerbots", "{} random bot guilds available (created this run: {})",
- uint32(sPlayerbotAIConfig->randomBotGuilds.size()), createdThisRun);
+ LOG_INFO("playerbots", "{} random bot guilds created this run)", createdThisRun);
}
std::string const RandomPlayerbotFactory::CreateRandomGuildName()
diff --git a/src/RandomPlayerbotFactory.h b/src/RandomPlayerbotFactory.h
index e74926a20e..d6c19e454b 100644
--- a/src/RandomPlayerbotFactory.h
+++ b/src/RandomPlayerbotFactory.h
@@ -44,9 +44,9 @@ class RandomPlayerbotFactory
BloodelfFemale
};
- static constexpr NameRaceAndGender CombineRaceAndGender(uint8 gender, uint8 race);
+ static constexpr NameRaceAndGender CombineRaceAndGender(uint8 race, uint8 gender);
- RandomPlayerbotFactory(uint32 accountId);
+ RandomPlayerbotFactory() {};
virtual ~RandomPlayerbotFactory() {}
Player* CreateRandomBot(WorldSession* session, uint8 cls, std::unordered_map>& names);
@@ -58,11 +58,9 @@ class RandomPlayerbotFactory
static uint32 CalculateAvailableCharsPerAccount();
private:
+ static bool IsValidRaceClassCombination(uint8 race, uint8 class_, uint32 expansion);
std::string const CreateRandomBotName(NameRaceAndGender raceAndGender);
static std::string const CreateRandomArenaTeamName();
-
- uint32 accountId;
- static std::map> availableRaces;
};
#endif
diff --git a/src/RandomPlayerbotMgr.cpp b/src/RandomPlayerbotMgr.cpp
index 05f4c8eff8..222990ca20 100644
--- a/src/RandomPlayerbotMgr.cpp
+++ b/src/RandomPlayerbotMgr.cpp
@@ -633,7 +633,7 @@ void RandomPlayerbotMgr::AssignAccountTypes()
uint32 existingRndBotAccounts = 0;
uint32 existingAddClassAccounts = 0;
- for (const auto& [accountId, accountType] : currentAssignments)
+ for (auto const& [accountId, accountType] : currentAssignments)
{
if (accountType == 1) existingRndBotAccounts++;
else if (accountType == 2) existingAddClassAccounts++;
@@ -688,7 +688,7 @@ void RandomPlayerbotMgr::AssignAccountTypes()
}
// Populate filtered account lists with ALL accounts of each type
- for (const auto& [accountId, accountType] : currentAssignments)
+ for (auto const& [accountId, accountType] : currentAssignments)
{
if (accountType == 1) rndBotTypeAccounts.push_back(accountId);
else if (accountType == 2) addClassTypeAccounts.push_back(accountId);
@@ -798,7 +798,7 @@ uint32 RandomPlayerbotMgr::AddRandomBots()
std::vector allianceChars;
std::vector hordeChars;
- for (const auto& charInfo : allCharacters)
+ for (auto const& charInfo : allCharacters)
{
if (IsAlliance(charInfo.rRace))
allianceChars.push_back(charInfo);
@@ -822,7 +822,7 @@ uint32 RandomPlayerbotMgr::AddRandomBots()
uint32 add_time = sPlayerbotAIConfig->enablePeriodicOnlineOffline
? urand(sPlayerbotAIConfig->minRandomBotInWorldTime,
sPlayerbotAIConfig->maxRandomBotInWorldTime)
- : sPlayerbotAIConfig->permanantlyInWorldTime;
+ : sPlayerbotAIConfig->permanentlyInWorldTime;
SetEventValue(charInfo.guid, "add", 1, add_time);
SetEventValue(charInfo.guid, "logout", 0, 0);
@@ -832,7 +832,7 @@ uint32 RandomPlayerbotMgr::AddRandomBots()
};
// PHASE 1: Log-in Alliance bots up to allowedAllianceCount
- for (const auto& charInfo : allianceChars)
+ for (auto const& charInfo : allianceChars)
{
if (!allowedAllianceCount)
break;
@@ -845,7 +845,7 @@ uint32 RandomPlayerbotMgr::AddRandomBots()
}
// PHASE 2: Log-in Horde bots up to maxAllowedBotCount
- for (const auto& charInfo : hordeChars)
+ for (auto const& charInfo : hordeChars)
{
if (!maxAllowedBotCount)
break;
@@ -855,7 +855,7 @@ uint32 RandomPlayerbotMgr::AddRandomBots()
}
// PHASE 3: If maxAllowedBotCount wasn't reached, log-in more Alliance bots
- for (const auto& charInfo : allianceChars)
+ for (auto const& charInfo : allianceChars)
{
if (!maxAllowedBotCount)
break;
@@ -1248,7 +1248,7 @@ void RandomPlayerbotMgr::CheckBgQueue()
void RandomPlayerbotMgr::LogBattlegroundInfo()
{
- for (const auto& queueTypePair : BattlegroundData)
+ for (auto const& queueTypePair : BattlegroundData)
{
uint8 queueType = queueTypePair.first;
@@ -1256,7 +1256,7 @@ void RandomPlayerbotMgr::LogBattlegroundInfo()
if (uint8 type = BattlegroundMgr::BGArenaType(queueTypeId))
{
- for (const auto& bracketIdPair : queueTypePair.second)
+ for (auto const& bracketIdPair : queueTypePair.second)
{
auto& bgInfo = bracketIdPair.second;
if (bgInfo.minLevel == 0)
@@ -1306,7 +1306,7 @@ void RandomPlayerbotMgr::LogBattlegroundInfo()
break;
}
- for (const auto& bracketIdPair : queueTypePair.second)
+ for (auto const& bracketIdPair : queueTypePair.second)
{
auto& bgInfo = bracketIdPair.second;
if (bgInfo.minLevel == 0)
@@ -1480,10 +1480,10 @@ bool RandomPlayerbotMgr::ProcessBot(uint32 bot)
if (!sRandomPlayerbotMgr->IsRandomBot(player))
update = false;
- if (player->GetGroup() && botAI->GetGroupMaster())
+ if (player->GetGroup() && botAI->GetGroupLeader())
{
- PlayerbotAI* groupMasterBotAI = GET_PLAYERBOT_AI(botAI->GetGroupMaster());
- if (!groupMasterBotAI || groupMasterBotAI->IsRealPlayer())
+ PlayerbotAI* groupLeaderBotAI = GET_PLAYERBOT_AI(botAI->GetGroupLeader());
+ if (!groupLeaderBotAI || groupLeaderBotAI->IsRealPlayer())
{
update = false;
}
@@ -1704,7 +1704,6 @@ void RandomPlayerbotMgr::RandomTeleport(Player* bot, std::vector&
return;
}
-
PerformanceMonitorOperation* pmo = sPerformanceMonitor->start(PERF_MON_RNDBOT, "RandomTeleportByLocations");
std::shuffle(std::begin(tlocs), std::end(tlocs), RandomEngine::Instance());
@@ -2261,7 +2260,7 @@ void RandomPlayerbotMgr::RandomTeleportForLevel(Player* bot)
// Pick a weighted city randomly, then a random banker in that city
// then teleport to that banker
CityId selectedCity = weightedCities[urand(0, weightedCities.size() - 1)];
- const auto& bankers = cityToBankers.at(selectedCity);
+ auto const& bankers = cityToBankers.at(selectedCity);
uint32 selectedBankerEntry = bankers[urand(0, bankers.size() - 1)];
auto locIt = bankerEntryToLocation.find(selectedBankerEntry);
if (locIt != bankerEntryToLocation.end())
diff --git a/src/ServerFacade.cpp b/src/ServerFacade.cpp
index 61b9b0d43f..f85525bc31 100644
--- a/src/ServerFacade.cpp
+++ b/src/ServerFacade.cpp
@@ -56,7 +56,7 @@ Unit* ServerFacade::GetChaseTarget(Unit* target)
MovementGenerator* movementGen = target->GetMotionMaster()->top();
if (movementGen && movementGen->GetMovementGeneratorType() == CHASE_MOTION_TYPE)
{
- if (target->GetTypeId() == TYPEID_PLAYER)
+ if (target->IsPlayer())
{
return static_cast const*>(movementGen)->GetTarget();
}
diff --git a/src/TravelMgr.cpp b/src/TravelMgr.cpp
index f8df8bfea9..8dfbbe4526 100644
--- a/src/TravelMgr.cpp
+++ b/src/TravelMgr.cpp
@@ -480,7 +480,7 @@ std::string const WorldPosition::getAreaName(bool fullName, bool zoneName)
std::set WorldPosition::getTransports(uint32 entry)
{
/*
- if(!entry)
+ if (!entry)
return getMap()->m_transports;
else
{
@@ -488,7 +488,7 @@ std::set WorldPosition::getTransports(uint32 entry)
std::set transports;
/*
for (auto transport : getMap()->m_transports)
- if(transport->GetEntry() == entry)
+ if (transport->GetEntry() == entry)
transports.insert(transport);
return transports;
@@ -1272,7 +1272,7 @@ std::string const RpgTravelDestination::getTitle()
{
std::ostringstream out;
- if(entry > 0)
+ if (entry > 0)
out << "rpg npc ";
out << " " << ChatHelper::FormatWorldEntry(entry);
@@ -2076,7 +2076,6 @@ void TravelMgr::LoadQuestTravelTable()
continue;
}
-
if (r.role == 0)
{
container->questGivers.push_back(loc);
@@ -2591,7 +2590,7 @@ void TravelMgr::LoadQuestTravelTable()
//if (data->displayId == 3015)
// pos.setZ(pos.getZ() + 6.0f);
- //else if(data->displayId == 3031)
+ //else if (data->displayId == 3031)
// pos.setZ(pos.getZ() - 17.0f);
if (prevNode)
diff --git a/src/TravelNode.cpp b/src/TravelNode.cpp
index 8e88006700..d3c03ed97e 100644
--- a/src/TravelNode.cpp
+++ b/src/TravelNode.cpp
@@ -180,7 +180,7 @@ uint32 TravelNodePath::getPrice()
if (!taxiPath)
return 0;
-
+
return taxiPath->price;
}
@@ -470,7 +470,6 @@ bool TravelNode::cropUselessLinks()
for (auto& firstLink : getLinks())
{
-
TravelNode* firstNode = firstLink.first;
float firstLength = firstLink.second.getDistance();
for (auto& secondLink : getLinks())
@@ -1302,7 +1301,7 @@ TravelNodeRoute TravelNodeMap::getRoute(TravelNode* start, TravelNode* goal, Pla
return TravelNodeRoute(path);
}
- for (const auto& link : *currentNode->dataNode->getLinks()) // for each successor n' of n
+ for (auto const& link : *currentNode->dataNode->getLinks()) // for each successor n' of n
{
TravelNode* linkNode = link.first;
float linkCost = link.second->getCost(bot, currentNode->currentGold);
@@ -1351,7 +1350,7 @@ TravelNodeRoute TravelNodeMap::getRoute(WorldPosition startPos, WorldPosition en
std::vector newStartPath;
std::vector startNodes = m_nodes, endNodes = m_nodes;
- if(!startNodes.size() || !endNodes.size())
+ if (!startNodes.size() || !endNodes.size())
return TravelNodeRoute();
// Partial sort to get the closest 5 nodes at the begin of the array.
@@ -1902,7 +1901,7 @@ void TravelNodeMap::generateTransportNodes()
// if (data->displayId == 3015)
// pos.setZ(pos.getZ() + 6.0f);
- // else if(data->displayId == 3031)
+ // else if (data->displayId == 3031)
// pos.setZ(pos.getZ() - 17.0f);
if (prevNode)
diff --git a/src/factory/PlayerbotFactory.cpp b/src/factory/PlayerbotFactory.cpp
index af1552a3f9..50a216c970 100644
--- a/src/factory/PlayerbotFactory.cpp
+++ b/src/factory/PlayerbotFactory.cpp
@@ -180,7 +180,7 @@ void PlayerbotFactory::Init()
continue;
}
- if (proto->Flags & ITEM_FLAG_UNIQUE_EQUIPPABLE)
+ if (proto->HasFlag(ITEM_FLAG_UNIQUE_EQUIPPABLE))
{
continue;
}
@@ -1391,7 +1391,7 @@ bool PlayerbotFactory::CanEquipArmor(ItemTemplate const* proto)
// for (uint8 j = 0; j < MAX_ITEM_PROTO_STATS; ++j)
// {
// // for ItemStatValue != 0
- // if(!proto->ItemStat[j].ItemStatValue)
+ // if (!proto->ItemStat[j].ItemStatValue)
// continue;
// AddItemStats(proto->ItemStat[j].ItemStatType, sp, ap, tank);
@@ -1600,7 +1600,8 @@ void Shuffle(std::vector& items)
// bool noItem = false;
// uint32 quality = urand(ITEM_QUALITY_UNCOMMON, ITEM_QUALITY_EPIC);
// uint32 attempts = 10;
-// if (urand(0, 100) < 100 * sPlayerbotAIConfig->randomGearLoweringChance && quality > ITEM_QUALITY_NORMAL) {
+// if (urand(0, 100) < 100 * sPlayerbotAIConfig->randomGearLoweringChance && quality > ITEM_QUALITY_NORMAL)
+// {
// quality--;
// }
// // current item;
@@ -1705,7 +1706,8 @@ void PlayerbotFactory::InitEquipment(bool incremental, bool second_chance)
if (incremental && !sPlayerbotAIConfig->incrementalGearInit)
return;
- if (level < 5) {
+ if (level < 5)
+ {
// original items
if (CharStartOutfitEntry const* oEntry = GetCharStartOutfitEntry(bot->getRace(), bot->getClass(), bot->getGender()))
{
@@ -1734,7 +1736,8 @@ void PlayerbotFactory::InitEquipment(bool incremental, bool second_chance)
continue;
}
- if (bot->HasItemCount(itemId, count)) {
+ if (bot->HasItemCount(itemId, count))
+ {
continue;
}
@@ -2771,7 +2774,8 @@ void PlayerbotFactory::InitTalents(uint32 specNo)
void PlayerbotFactory::InitTalentsByTemplate(uint32 specTab)
{
- // if (sPlayerbotAIConfig->parsedSpecLinkOrder[bot->getClass()][specNo][80].size() == 0) {
+ // if (sPlayerbotAIConfig->parsedSpecLinkOrder[bot->getClass()][specNo][80].size() == 0)
+ // {
// return;
// }
uint32 cls = bot->getClass();
@@ -4095,6 +4099,7 @@ void PlayerbotFactory::InitImmersive()
void PlayerbotFactory::InitArenaTeam()
{
+
if (!sPlayerbotAIConfig->IsInRandomAccountList(bot->GetSession()->GetAccountId()))
return;
@@ -4181,10 +4186,34 @@ void PlayerbotFactory::InitArenaTeam()
if (botcaptain && botcaptain->GetTeamId() == bot->GetTeamId()) // need?
{
+ // Add bot to arena team
arenateam->AddMember(bot->GetGUID());
- arenateam->SaveToDB();
+
+ // Only synchronize ratings once the team is full (avoid redundant work)
+ // The captain was added with incorrect ratings when the team was created,
+ // so we fix everyone's ratings once the roster is complete
+ if (arenateam->GetMembersSize() >= (uint32)arenateam->GetType())
+ {
+ uint32 teamRating = arenateam->GetRating();
+
+ // Use SetRatingForAll to align all members with team rating
+ arenateam->SetRatingForAll(teamRating);
+
+ // For bot-only teams, keep MMR synchronized with team rating
+ // This ensures matchmaking reflects the artificial team strength (1000-2000 range)
+ // instead of being influenced by the global CONFIG_ARENA_START_MATCHMAKER_RATING
+ for (auto& member : arenateam->GetMembers())
+ {
+ // Set MMR to match personal rating (which already matches team rating)
+ member.MatchMakerRating = member.PersonalRating;
+ member.MaxMMR = std::max(member.MaxMMR, member.PersonalRating);
+ }
+ // Force save all member data to database
+ arenateam->SaveToDB(true);
+ }
}
}
+
arenateams.erase(arenateams.begin() + index);
}
diff --git a/src/factory/StatsWeightCalculator.cpp b/src/factory/StatsWeightCalculator.cpp
index fa9e8a83b8..8a3048914e 100644
--- a/src/factory/StatsWeightCalculator.cpp
+++ b/src/factory/StatsWeightCalculator.cpp
@@ -97,7 +97,7 @@ float StatsWeightCalculator::CalculateItem(uint32 itemId, int32 randomPropertyId
// Use player level as effective item level for heirlooms - Quality EPIC
// Else - Blend with item quality and level for normal items
if (proto->Quality == ITEM_QUALITY_HEIRLOOM)
- weight_ *= PlayerbotFactory::CalcMixedGearScore(lvl, ITEM_QUALITY_EPIC);
+ weight_ *= PlayerbotFactory::CalcMixedGearScore(lvl, ITEM_QUALITY_EPIC);
else
weight_ *= PlayerbotFactory::CalcMixedGearScore(proto->ItemLevel, proto->Quality);
diff --git a/src/strategy/AiObjectContext.cpp b/src/strategy/AiObjectContext.cpp
index f0e93fd393..7a1da0f8a6 100644
--- a/src/strategy/AiObjectContext.cpp
+++ b/src/strategy/AiObjectContext.cpp
@@ -39,6 +39,10 @@
#include "raids/blackwinglair/RaidBwlTriggerContext.h"
#include "raids/karazhan/RaidKarazhanActionContext.h"
#include "raids/karazhan/RaidKarazhanTriggerContext.h"
+#include "raids/magtheridon/RaidMagtheridonActionContext.h"
+#include "raids/magtheridon/RaidMagtheridonTriggerContext.h"
+#include "raids/gruulslair/RaidGruulsLairActionContext.h"
+#include "raids/gruulslair/RaidGruulsLairTriggerContext.h"
#include "raids/naxxramas/RaidNaxxActionContext.h"
#include "raids/naxxramas/RaidNaxxTriggerContext.h"
#include "raids/eyeofeternity/RaidEoEActionContext.h"
@@ -111,6 +115,8 @@ void AiObjectContext::BuildSharedActionContexts(SharedNamedObjectContextList::iterator i = strategies.begin(); i != strategies.end(); i++)
// {
// Strategy* strategy = i->second;
- // if (strategy) {
+ // if (strategy)
+ // {
// delete strategy;
// }
// }
@@ -402,7 +403,6 @@ void Engine::addStrategiesNoInit(std::string first, ...)
va_end(vl);
}
-
bool Engine::removeStrategy(std::string const name, bool init)
{
std::map::iterator i = strategies.find(name);
diff --git a/src/strategy/NamedObjectContext.h b/src/strategy/NamedObjectContext.h
index af8c4ecec6..b60232a5c3 100644
--- a/src/strategy/NamedObjectContext.h
+++ b/src/strategy/NamedObjectContext.h
@@ -148,7 +148,7 @@ class SharedNamedObjectContextList
void Add(NamedObjectContext* context)
{
contexts.push_back(context);
- for (const auto& iter : context->creators)
+ for (auto const& iter : context->creators)
creators[iter.first] = iter.second;
}
};
@@ -294,7 +294,7 @@ class NamedObjectFactoryList
void Add(NamedObjectFactory* context)
{
factories.push_back(context);
- for (const auto& iter : context->creators)
+ for (auto const& iter : context->creators)
creators[iter.first] = iter.second;
}
diff --git a/src/strategy/actions/ActionContext.h b/src/strategy/actions/ActionContext.h
index cebd7615a7..09c9145f93 100644
--- a/src/strategy/actions/ActionContext.h
+++ b/src/strategy/actions/ActionContext.h
@@ -121,7 +121,7 @@ class ActionContext : public NamedObjectContext
creators["shoot"] = &ActionContext::shoot;
creators["follow"] = &ActionContext::follow;
creators["move from group"] = &ActionContext::move_from_group;
- creators["flee to master"] = &ActionContext::flee_to_master;
+ creators["flee to group leader"] = &ActionContext::flee_to_group_leader;
creators["runaway"] = &ActionContext::runaway;
creators["stay"] = &ActionContext::stay;
creators["sit"] = &ActionContext::sit;
@@ -318,7 +318,7 @@ class ActionContext : public NamedObjectContext
static Action* runaway(PlayerbotAI* botAI) { return new RunAwayAction(botAI); }
static Action* follow(PlayerbotAI* botAI) { return new FollowAction(botAI); }
static Action* move_from_group(PlayerbotAI* botAI) { return new MoveFromGroupAction(botAI); }
- static Action* flee_to_master(PlayerbotAI* botAI) { return new FleeToMasterAction(botAI); }
+ static Action* flee_to_group_leader(PlayerbotAI* botAI) { return new FleeToGroupLeaderAction(botAI); }
static Action* add_gathering_loot(PlayerbotAI* botAI) { return new AddGatheringLootAction(botAI); }
static Action* add_loot(PlayerbotAI* botAI) { return new AddLootAction(botAI); }
static Action* add_all_loot(PlayerbotAI* botAI) { return new AddAllLootAction(botAI); }
diff --git a/src/strategy/actions/AreaTriggerAction.cpp b/src/strategy/actions/AreaTriggerAction.cpp
index 298bc686a4..f480277825 100644
--- a/src/strategy/actions/AreaTriggerAction.cpp
+++ b/src/strategy/actions/AreaTriggerAction.cpp
@@ -40,7 +40,14 @@ bool ReachAreaTriggerAction::Execute(Event event)
return true;
}
- bot->GetMotionMaster()->MovePoint(at->map, at->x, at->y, at->z);
+ bot->GetMotionMaster()->MovePoint(
+ /*id*/ at->map,
+ /*coords*/ at->x, at->y, at->z,
+ /*forcedMovement*/ FORCED_MOVEMENT_NONE,
+ /*speed*/ 0.0f, // default speed (not handled here)
+ /*orientation*/ 0.0f, // keep current orientation of bot
+ /*generatePath*/ true, // true => terrain path (2d mmap); false => straight spline (3d vmap)
+ /*forceDestination*/ false);
float distance = bot->GetDistance(at->x, at->y, at->z);
float delay = 1000.0f * distance / bot->GetSpeed(MOVE_RUN) + sPlayerbotAIConfig->reactDelay;
diff --git a/src/strategy/actions/AttackAction.cpp b/src/strategy/actions/AttackAction.cpp
index 6e8ed60712..df7a06ec4f 100644
--- a/src/strategy/actions/AttackAction.cpp
+++ b/src/strategy/actions/AttackAction.cpp
@@ -188,17 +188,21 @@ bool AttackAction::Attack(Unit* target, bool with_pet /*true*/)
bot->Attack(target, shouldMelee);
/* prevent pet dead immediately in group */
- // if (bot->GetMap()->IsDungeon() && bot->GetGroup() && !target->IsInCombat()) {
+ // if (bot->GetMap()->IsDungeon() && bot->GetGroup() && !target->IsInCombat())
+ // {
// with_pet = false;
// }
// if (Pet* pet = bot->GetPet())
// {
- // if (with_pet) {
+ // if (with_pet)
+ // {
// pet->SetReactState(REACT_DEFENSIVE);
// pet->SetTarget(target->GetGUID());
// pet->GetCharmInfo()->SetIsCommandAttack(true);
// pet->AI()->AttackStart(target);
- // } else {
+ // }
+ // else
+ // {
// pet->SetReactState(REACT_PASSIVE);
// pet->GetCharmInfo()->SetIsCommandFollow(true);
// pet->GetCharmInfo()->IsReturning();
diff --git a/src/strategy/actions/AutoMaintenanceOnLevelupAction.cpp b/src/strategy/actions/AutoMaintenanceOnLevelupAction.cpp
index b83936daeb..ad6a00c6d6 100644
--- a/src/strategy/actions/AutoMaintenanceOnLevelupAction.cpp
+++ b/src/strategy/actions/AutoMaintenanceOnLevelupAction.cpp
@@ -176,4 +176,3 @@ void AutoMaintenanceOnLevelupAction::AutoUpgradeEquip()
factory.InitEquipment(true);
}
}
-
diff --git a/src/strategy/actions/BankAction.cpp b/src/strategy/actions/BankAction.cpp
index 19804da874..4d8d6c4d8c 100644
--- a/src/strategy/actions/BankAction.cpp
+++ b/src/strategy/actions/BankAction.cpp
@@ -17,7 +17,7 @@ bool BankAction::Execute(Event event)
for (GuidVector::iterator i = npcs.begin(); i != npcs.end(); i++)
{
Unit* npc = botAI->GetUnit(*i);
- if (!npc || !npc->HasFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_BANKER))
+ if (!npc || !npc->HasNpcFlag(UNIT_NPC_FLAG_BANKER))
continue;
return ExecuteBank(text, npc);
diff --git a/src/strategy/actions/BattleGroundTactics.cpp b/src/strategy/actions/BattleGroundTactics.cpp
index 5e9e7daf0c..827ab01970 100644
--- a/src/strategy/actions/BattleGroundTactics.cpp
+++ b/src/strategy/actions/BattleGroundTactics.cpp
@@ -4,10 +4,12 @@
*/
#include "BattleGroundTactics.h"
-#include "BattleGroundJoinAction.h"
+
+#include
#include "ArenaTeam.h"
#include "ArenaTeamMgr.h"
+#include "BattleGroundJoinAction.h"
#include "Battleground.h"
#include "BattlegroundAB.h"
#include "BattlegroundAV.h"
@@ -22,11 +24,12 @@
#include "BattlegroundSA.h"
#include "BattlegroundWS.h"
#include "Event.h"
+#include "GameObject.h"
#include "IVMapMgr.h"
+#include "PathGenerator.h"
#include "Playerbots.h"
#include "PositionValue.h"
#include "PvpTriggers.h"
-#include "PathGenerator.h"
#include "ServerFacade.h"
#include "Vehicle.h"
@@ -1754,7 +1757,7 @@ bool BGTactics::moveToStart(bool force)
WS_WAITING_POS_ALLIANCE_2.GetPositionY() + frand(-4.0f, 4.0f),
WS_WAITING_POS_ALLIANCE_2.GetPositionZ());
}
- else // BB_WSG_WAIT_SPOT_SPAWN
+ else // BB_WSG_WAIT_SPOT_SPAWN
{
if (bot->GetTeamId() == TEAM_HORDE)
MoveTo(bg->GetMapId(), WS_WAITING_POS_HORDE_3.GetPositionX() + frand(-10.0f, 10.0f),
@@ -1894,13 +1897,13 @@ bool BGTactics::selectObjective(bool reset)
bool isDefender = role < defendersProhab;
bool isAdvanced = !isDefender && role > 8;
- const auto& attackObjectives =
+ auto const& attackObjectives =
(team == TEAM_HORDE) ? AV_AttackObjectives_Horde : AV_AttackObjectives_Alliance;
- const auto& defendObjectives =
+ auto const& defendObjectives =
(team == TEAM_HORDE) ? AV_DefendObjectives_Horde : AV_DefendObjectives_Alliance;
uint32 destroyedNodes = 0;
- for (const auto& [nodeId, _] : defendObjectives)
+ for (auto const& [nodeId, _] : defendObjectives)
if (av->GetAVNodeInfo(nodeId).State == POINT_DESTROYED)
destroyedNodes++;
@@ -2000,7 +2003,7 @@ bool BGTactics::selectObjective(bool reset)
std::vector contestedObjectives;
std::vector availableObjectives;
- for (const auto& [nodeId, goId] : defendObjectives)
+ for (auto const& [nodeId, goId] : defendObjectives)
{
const BG_AV_NodeInfo& node = av->GetAVNodeInfo(nodeId);
if (node.State == POINT_DESTROYED)
@@ -2026,7 +2029,7 @@ bool BGTactics::selectObjective(bool reset)
if (!BgObjective)
{
uint32 towersDown = 0;
- for (const auto& [nodeId, _] : attackObjectives)
+ for (auto const& [nodeId, _] : attackObjectives)
if (av->GetAVNodeInfo(nodeId).State == POINT_DESTROYED)
towersDown++;
@@ -2053,7 +2056,7 @@ bool BGTactics::selectObjective(bool reset)
{
std::vector candidates;
- for (const auto& [nodeId, goId] : attackObjectives)
+ for (auto const& [nodeId, goId] : attackObjectives)
{
const BG_AV_NodeInfo& node = av->GetAVNodeInfo(nodeId);
GameObject* go = bg->GetBGObject(goId);
@@ -2105,13 +2108,13 @@ bool BGTactics::selectObjective(bool reset)
Position objPos = BgObjective->GetPosition();
Optional linkedNodeId;
- for (const auto& [nodeId, goId] : attackObjectives)
+ for (auto const& [nodeId, goId] : attackObjectives)
if (bg->GetBGObject(goId) == BgObjective)
linkedNodeId = nodeId;
if (!linkedNodeId)
{
- for (const auto& [nodeId, goId] : defendObjectives)
+ for (auto const& [nodeId, goId] : defendObjectives)
if (bg->GetBGObject(goId) == BgObjective)
linkedNodeId = nodeId;
}
@@ -2543,7 +2546,7 @@ bool BGTactics::selectObjective(bool reset)
float bestDist = FLT_MAX;
uint32 bestTrigger = 0;
- for (const auto& [nodeId, _, areaTrigger] : EY_AttackObjectives)
+ for (auto const& [nodeId, _, areaTrigger] : EY_AttackObjectives)
{
if (!IsOwned(nodeId))
continue;
@@ -2610,7 +2613,7 @@ bool BGTactics::selectObjective(bool reset)
// --- PRIORITY 2: Nearby unowned contested node ---
if (!foundObjective)
{
- for (const auto& [nodeId, _, __] : EY_AttackObjectives)
+ for (auto const& [nodeId, _, __] : EY_AttackObjectives)
{
if (IsOwned(nodeId))
continue;
@@ -2711,7 +2714,7 @@ bool BGTactics::selectObjective(bool reset)
if (!foundObjective && strategy == EY_STRATEGY_FLAG_FOCUS)
{
bool ownsAny = false;
- for (const auto& [nodeId, _, __] : EY_AttackObjectives)
+ for (auto const& [nodeId, _, __] : EY_AttackObjectives)
{
if (IsOwned(nodeId))
{
@@ -2739,7 +2742,7 @@ bool BGTactics::selectObjective(bool reset)
float bestDist = FLT_MAX;
Optional bestNode;
- for (const auto& [nodeId, _, __] : EY_AttackObjectives)
+ for (auto const& [nodeId, _, __] : EY_AttackObjectives)
{
if (IsOwned(nodeId))
continue;
@@ -2974,7 +2977,7 @@ bool BGTactics::selectObjective(bool reset)
uint32 len = end(IC_AttackObjectives) - begin(IC_AttackObjectives);
for (uint32 i = 0; i < len; i++)
{
- const auto& objective =
+ auto const& objective =
IC_AttackObjectives[(i + role) %
len]; // use role to determine which objective checked first
if (isleOfConquestBG->GetICNodePoint(objective.first).nodeState != NODE_STATE_CONTROLLED_H)
@@ -3126,7 +3129,7 @@ bool BGTactics::selectObjective(bool reset)
uint32 len = end(IC_AttackObjectives) - begin(IC_AttackObjectives);
for (uint32 i = 0; i < len; i++)
{
- const auto& objective =
+ auto const& objective =
IC_AttackObjectives[(i + role) %
len]; // use role to determine which objective checked first
if (isleOfConquestBG->GetICNodePoint(objective.first).nodeState != NODE_STATE_CONTROLLED_H)
@@ -3365,12 +3368,12 @@ bool BGTactics::resetObjective()
return false;
// Adjust role-change chance based on battleground type
- uint32 oddsToChangeRole = 1; // default low
+ uint32 oddsToChangeRole = 1; // default low
BattlegroundTypeId bgType = bg->GetBgTypeID();
if (bgType == BATTLEGROUND_WS)
oddsToChangeRole = 2;
- else if (bgType == BATTLEGROUND_EY || bgType == BATTLEGROUND_IC || bgType == BATTLEGROUND_AB)
+ else if (bgType == BATTLEGROUND_EY || bgType == BATTLEGROUND_IC || bgType == BATTLEGROUND_AB)
oddsToChangeRole = 1;
else if (bgType == BATTLEGROUND_AV)
oddsToChangeRole = 0;
@@ -3578,6 +3581,16 @@ bool BGTactics::atFlag(std::vector const& vPaths, std::vector(bg);
+ if (eyeBg)
+ eyCenterFlag = eyeBg->GetBGObject(BG_EY_OBJECT_FLAG_NETHERSTORM);
+ }
+
// Set up appropriate search ranges and object lists based on BG type
switch (bgType)
{
@@ -3607,27 +3620,82 @@ bool BGTactics::atFlag(std::vector const& vPaths, std::vectorGetCurrentSpell(spellType);
+ if (!currentSpell || !currentSpell->m_spellInfo || currentSpell->m_spellInfo->Id != SPELL_CAPTURE_BANNER)
+ return false;
+
+ // If the capture target is no longer available (another bot already captured it), stop channeling
+ if (GameObject* targetFlag = currentSpell->m_targets.GetGOTarget())
+ {
+ if (!targetFlag->isSpawned() || targetFlag->GetGoState() != GO_STATE_READY)
+ {
+ bot->InterruptNonMeleeSpells(true);
+ resetObjective();
+ return false;
+ }
+ }
+ else
+ {
+ bot->InterruptNonMeleeSpells(true);
+ resetObjective();
+ return false;
+ }
+
+ if (bot->IsMounted())
+ {
+ bot->RemoveAurasByType(SPELL_AURA_MOUNTED);
+ }
+
+ if (bot->IsInDisallowedMountForm())
+ {
+ bot->RemoveAurasByType(SPELL_AURA_MOD_SHAPESHIFT);
+ }
+
+ if (bot->isMoving())
+ {
+ bot->StopMoving();
+ }
+
+ return true;
+ };
+
+ // If we are already channeling the capture spell, keep the bot stationary and dismounted
+ if (keepStationaryWhileCapturing(CURRENT_CHANNELED_SPELL) || keepStationaryWhileCapturing(CURRENT_GENERIC_SPELL))
+ return true;
+
// First identify which flag/base we're trying to interact with
GameObject* targetFlag = nullptr;
for (ObjectGuid const guid : closeObjects)
{
GameObject* go = botAI->GetGameObject(guid);
if (!go)
+ {
continue;
+ }
+
+ bool const isEyCenterFlag = eyeBg && eyCenterFlag && eyCenterFlag->GetGUID() == go->GetGUID();
// Check if this object is a valid capture target
- std::vector::const_iterator f = find(vFlagIds.begin(), vFlagIds.end(), go->GetEntry());
- if (f == vFlagIds.end())
+ std::vector::const_iterator f = std::find(vFlagIds.begin(), vFlagIds.end(), go->GetEntry());
+ if (f == vFlagIds.end() && !isEyCenterFlag)
+ {
continue;
+ }
// Verify the object is active and ready
if (!go->isSpawned() || go->GetGoState() != GO_STATE_READY)
+ {
continue;
+ }
// Check if we're in range (using double range for enemy detection)
float const dist = bot->GetDistance(go);
if (flagRange && dist > flagRange * 2.0f)
+ {
continue;
+ }
targetFlag = go;
break;
@@ -3655,7 +3723,7 @@ bool BGTactics::atFlag(std::vector const& vPaths, std::vector const& vPaths, std::vectorGetUnit(guid))
{
- // Check if they're casting the capture spell
- if (Spell* spell = pFriend->GetCurrentSpell(CURRENT_GENERIC_SPELL))
+ // Check if they're casting or channeling the capture spell
+ Spell* spell = pFriend->GetCurrentSpell(CURRENT_GENERIC_SPELL);
+ if (!spell)
{
- if (spell->m_spellInfo->Id == SPELL_CAPTURE_BANNER)
- {
- numCapturing++;
- capturingPlayer = pFriend;
- }
+ spell = pFriend->GetCurrentSpell(CURRENT_CHANNELED_SPELL);
+ }
+
+ if (spell && spell->m_spellInfo && spell->m_spellInfo->Id == SPELL_CAPTURE_BANNER)
+ {
+ numCapturing++;
+ capturingPlayer = pFriend;
}
}
}
@@ -3704,9 +3775,11 @@ bool BGTactics::atFlag(std::vector const& vPaths, std::vectorGetGUID() == go->GetGUID();
+
// Validate this is a capture target
- std::vector::const_iterator f = find(vFlagIds.begin(), vFlagIds.end(), go->GetEntry());
- if (f == vFlagIds.end())
+ std::vector::const_iterator f = std::find(vFlagIds.begin(), vFlagIds.end(), go->GetEntry());
+ if (f == vFlagIds.end() && !isEyCenterFlag)
continue;
// Check object is active
@@ -3722,12 +3795,40 @@ bool BGTactics::atFlag(std::vector const& vPaths, std::vectorGetEntry() == vFlagsWS[bot->GetTeamId()]
- : bgType == BATTLEGROUND_EY ? go->GetEntry() == vFlagsEY[0]
- : false;
+ bool isWsBaseFlag = bgType == BATTLEGROUND_WS && go->GetEntry() == vFlagsWS[bot->GetTeamId()];
+ bool isEyBaseFlag = bgType == BATTLEGROUND_EY && go->GetEntry() == vFlagsEY[0];
+
+ // Ensure bots are inside the Eye of the Storm capture circle before casting
+ if (bgType == BATTLEGROUND_EY)
+ {
+ GameObject* captureFlag = (isEyBaseFlag && eyCenterFlag) ? eyCenterFlag : go;
+ float const requiredRange = 2.5f;
+ if (!bot->IsWithinDistInMap(captureFlag, requiredRange))
+ {
+ // Stay mounted while relocating to avoid mount/dismount loops
+ return MoveTo(bot->GetMapId(), captureFlag->GetPositionX(), captureFlag->GetPositionY(),
+ captureFlag->GetPositionZ());
+ }
+
+ // Once inside the circle, dismount and stop before starting the channel
+ if (bot->IsMounted())
+ {
+ bot->RemoveAurasByType(SPELL_AURA_MOUNTED);
+ }
+
+ if (bot->IsInDisallowedMountForm())
+ {
+ bot->RemoveAurasByType(SPELL_AURA_MOD_SHAPESHIFT);
+ }
+
+ if (bot->isMoving())
+ {
+ bot->StopMoving();
+ }
+ }
// Don't capture own flag in WSG unless carrying enemy flag
- if (atBase && bgType == BATTLEGROUND_WS &&
+ if (isWsBaseFlag && bgType == BATTLEGROUND_WS &&
!(bot->HasAura(BG_WS_SPELL_WARSONG_FLAG) || bot->HasAura(BG_WS_SPELL_SILVERWING_FLAG)))
continue;
@@ -3743,7 +3844,7 @@ bool BGTactics::atFlag(std::vector const& vPaths, std::vectorGetObjectSize() + go->GetObjectSize() + 0.1f;
return MoveTo(bot->GetMapId(), go->GetPositionX() + (urand(0, 1) ? -moveDist : moveDist),
- go->GetPositionY() + (urand(0, 1) ? -moveDist : moveDist), go->GetPositionZ());
+ go->GetPositionY() + (urand(0, 1) ? -moveDist : moveDist), go->GetPositionZ());
}
// Dismount before capturing
@@ -3772,7 +3873,7 @@ bool BGTactics::atFlag(std::vector const& vPaths, std::vectorGetTeamId() == TEAM_HORDE)
{
@@ -3811,28 +3912,50 @@ bool BGTactics::atFlag(std::vector const& vPaths, std::vectorIsMounted())
+ {
bot->RemoveAurasByType(SPELL_AURA_MOUNTED);
+ }
if (bot->IsInDisallowedMountForm())
+ {
bot->RemoveAurasByType(SPELL_AURA_MOD_SHAPESHIFT);
+ }
// Handle center flag differently (requires spell cast)
- if (atBase)
+ if (isEyCenterFlag)
{
+ for (uint8 type = CURRENT_MELEE_SPELL; type <= CURRENT_CHANNELED_SPELL; ++type)
+ {
+ if (Spell* currentSpell = bot->GetCurrentSpell(static_cast(type)))
+ {
+ // m_spellInfo may be null in some states: protect access
+ if (currentSpell->m_spellInfo && currentSpell->m_spellInfo->Id == SPELL_CAPTURE_BANNER)
+ {
+ bot->StopMoving();
+ botAI->SetNextCheckDelay(500);
+ return true;
+ }
+ }
+ }
+
SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(SPELL_CAPTURE_BANNER);
if (!spellInfo)
return false;
Spell* spell = new Spell(bot, spellInfo, TRIGGERED_NONE);
spell->m_targets.SetGOTarget(go);
+
+ bot->StopMoving();
spell->prepare(&spell->m_targets);
+
botAI->WaitForSpellCast(spell);
- //return true; Intended to make a bot cast SPELL_CAPTURE_BANNER and wait for spell finish, but doesn't work and causes infinite loop
+ resetObjective();
+ return true;
}
// Pick up dropped flag
@@ -3849,8 +3972,8 @@ bool BGTactics::atFlag(std::vector const& vPaths, std::vectorGetMapId(), go->GetPositionX(), go->GetPositionY(), go->GetPositionZ());
}
}
- default:
- break;
+ default:
+ break;
}
}
diff --git a/src/strategy/actions/CheckMountStateAction.cpp b/src/strategy/actions/CheckMountStateAction.cpp
index 7bbcd58efb..bf7a3a169a 100644
--- a/src/strategy/actions/CheckMountStateAction.cpp
+++ b/src/strategy/actions/CheckMountStateAction.cpp
@@ -81,7 +81,7 @@ bool CheckMountStateAction::isUseful()
// to mostly be an issue in tunnels of WSG and AV)
float posZ = bot->GetPositionZ();
float groundLevel = bot->GetMapWaterOrGroundLevel(bot->GetPositionX(), bot->GetPositionY(), posZ);
- if (!bot->IsMounted() && posZ < groundLevel)
+ if (!bot->IsMounted() && !bot->HasWaterWalkAura() && posZ < groundLevel)
return false;
// Not useful when bot does not have mount strat and is not currently mounted
@@ -370,7 +370,7 @@ bool CheckMountStateAction::TryPreferredMount(Player* master) const
bool CheckMountStateAction::TryRandomMountFiltered(const std::map>& spells, int32 masterSpeed) const
{
- for (const auto& pair : spells)
+ for (auto const& pair : spells)
{
int32 currentSpeed = pair.first;
@@ -378,7 +378,7 @@ bool CheckMountStateAction::TryRandomMountFiltered(const std::mapGetGroupMaster();
+ Player* groupLeader = botAI->GetGroupLeader();
Player* realMaster = botAI->GetMaster();
AiObjectContext* context = botAI->GetAiObjectContext();
@@ -327,30 +327,30 @@ bool ChooseRpgTargetAction::isFollowValid(Player* bot, WorldPosition pos)
return false;
}
- if (!gmaster || bot == gmaster)
+ if (!groupLeader || bot == groupLeader)
return true;
if (!botAI->HasStrategy("follow", BOT_STATE_NON_COMBAT))
return true;
- if (bot->GetDistance(gmaster) > sPlayerbotAIConfig->rpgDistance * 2)
+ if (bot->GetDistance(groupLeader) > sPlayerbotAIConfig->rpgDistance * 2)
return false;
Formation* formation = AI_VALUE(Formation*, "formation");
- float distance = gmaster->GetDistance2d(pos.getX(), pos.getY());
+ float distance = groupLeader->GetDistance2d(pos.getX(), pos.getY());
if (!botAI->HasActivePlayerMaster() && distance < 50.0f)
{
- Player* player = gmaster;
- if (gmaster && !gmaster->isMoving() ||
+ Player* player = groupLeader;
+ if (groupLeader && !groupLeader->isMoving() ||
PAI_VALUE(WorldPosition, "last long move").distance(pos) < sPlayerbotAIConfig->reactDistance)
return true;
}
- if ((inDungeon || !gmaster->HasPlayerFlag(PLAYER_FLAGS_RESTING)) && realMaster == gmaster && distance > 5.0f)
+ if ((inDungeon || !groupLeader->HasPlayerFlag(PLAYER_FLAGS_RESTING)) && realMaster == groupLeader && distance > 5.0f)
return false;
- if (!gmaster->isMoving() && distance < 25.0f)
+ if (!groupLeader->isMoving() && distance < 25.0f)
return true;
if (distance < formation->GetMaxDistance())
diff --git a/src/strategy/actions/ChooseTravelTargetAction.cpp b/src/strategy/actions/ChooseTravelTargetAction.cpp
index 709307f406..cf6dddd40c 100644
--- a/src/strategy/actions/ChooseTravelTargetAction.cpp
+++ b/src/strategy/actions/ChooseTravelTargetAction.cpp
@@ -120,7 +120,6 @@ void ChooseTravelTargetAction::getNewTarget(TravelTarget* newTarget, TravelTarge
}
}
-
//Continue current target. 90% chance
if (!foundTarget && urand(1, 100) > 10)
{
@@ -181,7 +180,7 @@ void ChooseTravelTargetAction::getNewTarget(TravelTarget* newTarget, TravelTarge
void ChooseTravelTargetAction::setNewTarget(TravelTarget* newTarget, TravelTarget* oldTarget)
{
// Tell the master where we are going.
- if (!bot->GetGroup() || (botAI->GetGroupMaster() == bot))
+ if (!bot->GetGroup() || (botAI->GetGroupLeader() == bot))
ReportTravelTarget(newTarget, oldTarget);
// If we are heading to a creature/npc clear it from the ignore list.
@@ -673,7 +672,7 @@ bool ChooseTravelTargetAction::SetExploreTarget(TravelTarget* target)
//271 south shore
//35 booty bay
//380 The Barrens The Crossroads
- if(((ExploreTravelDestination * )activeTarget)->getAreaId() == 380)
+ if (((ExploreTravelDestination * )activeTarget)->getAreaId() == 380)
{
activePoints.push_back(activeTarget->getPoints(true)[0]);
}
diff --git a/src/strategy/actions/DropQuestAction.cpp b/src/strategy/actions/DropQuestAction.cpp
index ddcdaef52b..48e571eb3e 100644
--- a/src/strategy/actions/DropQuestAction.cpp
+++ b/src/strategy/actions/DropQuestAction.cpp
@@ -58,7 +58,6 @@ bool DropQuestAction::Execute(Event event)
return true;
}
-
bool CleanQuestLogAction::Execute(Event event)
{
Player* requester = event.getOwner() ? event.getOwner() : GetMaster();
@@ -165,7 +164,6 @@ bool CleanQuestLogAction::Execute(Event event)
return true;
}
-
void CleanQuestLogAction::DropQuestType(uint8& numQuest, uint8 wantNum, bool isGreen, bool hasProgress, bool isComplete)
{
std::vector slots;
diff --git a/src/strategy/actions/EmoteAction.cpp b/src/strategy/actions/EmoteAction.cpp
index 72952e66cc..1770ca2b75 100644
--- a/src/strategy/actions/EmoteAction.cpp
+++ b/src/strategy/actions/EmoteAction.cpp
@@ -837,8 +837,8 @@ uint32 TalkAction::GetRandomEmote(Unit* unit, bool textEmote)
types.push_back(TEXT_EMOTE_TALKEX);
types.push_back(TEXT_EMOTE_TALKQ);
- if (unit && (unit->HasFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_TRAINER) ||
- unit->HasFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_QUESTGIVER)))
+ if (unit && (unit->HasNpcFlag(UNIT_NPC_FLAG_TRAINER) ||
+ unit->HasNpcFlag(UNIT_NPC_FLAG_QUESTGIVER)))
{
types.push_back(TEXT_EMOTE_SALUTE);
}
@@ -864,8 +864,8 @@ uint32 TalkAction::GetRandomEmote(Unit* unit, bool textEmote)
types.push_back(EMOTE_ONESHOT_EXCLAMATION);
types.push_back(EMOTE_ONESHOT_QUESTION);
- if (unit && (unit->HasFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_TRAINER) ||
- unit->HasFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_QUESTGIVER)))
+ if (unit && (unit->HasNpcFlag(UNIT_NPC_FLAG_TRAINER) ||
+ unit->HasNpcFlag(UNIT_NPC_FLAG_QUESTGIVER)))
{
types.push_back(EMOTE_ONESHOT_SALUTE);
}
diff --git a/src/strategy/actions/EquipAction.cpp b/src/strategy/actions/EquipAction.cpp
index 946af5b2f6..71a2df01e6 100644
--- a/src/strategy/actions/EquipAction.cpp
+++ b/src/strategy/actions/EquipAction.cpp
@@ -271,19 +271,38 @@ void EquipAction::EquipItem(Item* item)
{
if (equippedItems[1])
{
- // Both slots are full - pick the worst item to replace
+ // Both slots are full - pick the worst item to replace, but only if new item is better
StatsWeightCalculator calc(bot);
calc.SetItemSetBonus(false);
calc.SetOverflowPenalty(false);
- float firstItemScore = calc.CalculateItem(equippedItems[0]->GetTemplate()->ItemId);
- float secondItemScore = calc.CalculateItem(equippedItems[1]->GetTemplate()->ItemId);
+ // Calculate new item score with random properties
+ int32 newItemRandomProp = item->GetItemRandomPropertyId();
+ float newItemScore = calc.CalculateItem(itemId, newItemRandomProp);
- // If the second slot is worse, place the new item there
- if (firstItemScore > secondItemScore)
+ // Calculate equipped items scores with random properties
+ int32 firstRandomProp = equippedItems[0]->GetItemRandomPropertyId();
+ int32 secondRandomProp = equippedItems[1]->GetItemRandomPropertyId();
+ float firstItemScore = calc.CalculateItem(equippedItems[0]->GetTemplate()->ItemId, firstRandomProp);
+ float secondItemScore = calc.CalculateItem(equippedItems[1]->GetTemplate()->ItemId, secondRandomProp);
+
+ // Determine which slot (if any) should be replaced
+ bool betterThanFirst = newItemScore > firstItemScore;
+ bool betterThanSecond = newItemScore > secondItemScore;
+
+ // Early return if new item is not better than either equipped item
+ if (!betterThanFirst && !betterThanSecond)
+ return;
+
+ if (betterThanFirst && betterThanSecond)
{
- dstSlot++;
+ // New item is better than both - replace the worse of the two equipped items
+ if (firstItemScore > secondItemScore)
+ dstSlot++; // Replace second slot (worse)
+ // else: keep dstSlot as-is (replace first slot)
}
+ else if (betterThanSecond)
+ dstSlot++; // Only better than second slot - replace it
}
else
{
@@ -309,7 +328,6 @@ void EquipAction::EquipItem(Item* item)
botAI->TellMaster(out);
}
-
bool EquipUpgradesAction::Execute(Event event)
{
if (!sPlayerbotAIConfig->autoEquipUpgradeLoot && !sRandomPlayerbotMgr->IsRandomBot(bot))
@@ -338,9 +356,12 @@ bool EquipUpgradesAction::Execute(Event event)
int32 randomProperty = item->GetItemRandomPropertyId();
uint32 itemId = item->GetTemplate()->ItemId;
std::string itemUsageParam;
- if (randomProperty != 0) {
+ if (randomProperty != 0)
+ {
itemUsageParam = std::to_string(itemId) + "," + std::to_string(randomProperty);
- } else {
+ }
+ else
+ {
itemUsageParam = std::to_string(itemId);
}
ItemUsage usage = AI_VALUE2(ItemUsage, "item usage", itemUsageParam);
@@ -369,9 +390,12 @@ bool EquipUpgradeAction::Execute(Event event)
int32 randomProperty = item->GetItemRandomPropertyId();
uint32 itemId = item->GetTemplate()->ItemId;
std::string itemUsageParam;
- if (randomProperty != 0) {
+ if (randomProperty != 0)
+ {
itemUsageParam = std::to_string(itemId) + "," + std::to_string(randomProperty);
- } else {
+ }
+ else
+ {
itemUsageParam = std::to_string(itemId);
}
ItemUsage usage = AI_VALUE2(ItemUsage, "item usage", itemUsageParam);
diff --git a/src/strategy/actions/FollowActions.cpp b/src/strategy/actions/FollowActions.cpp
index f4a66bf9e7..d168e8cc93 100644
--- a/src/strategy/actions/FollowActions.cpp
+++ b/src/strategy/actions/FollowActions.cpp
@@ -70,7 +70,7 @@ bool FollowAction::isUseful()
if (!target.empty())
fTarget = AI_VALUE(Unit*, target);
else
- fTarget = AI_VALUE(Unit*, "master target");
+ fTarget = AI_VALUE(Unit*, "group leader");
if (fTarget)
{
@@ -114,9 +114,9 @@ bool FollowAction::CanDeadFollow(Unit* target)
return true;
}
-bool FleeToMasterAction::Execute(Event event)
+bool FleeToGroupLeaderAction::Execute(Event event)
{
- Unit* fTarget = AI_VALUE(Unit*, "master target");
+ Unit* fTarget = AI_VALUE(Unit*, "group leader");
bool canFollow = Follow(fTarget);
if (!canFollow)
{
@@ -146,22 +146,22 @@ bool FleeToMasterAction::Execute(Event event)
return true;
}
-bool FleeToMasterAction::isUseful()
+bool FleeToGroupLeaderAction::isUseful()
{
- if (!botAI->GetGroupMaster())
+ if (!botAI->GetGroupLeader())
return false;
- if (botAI->GetGroupMaster() == bot)
+ if (botAI->GetGroupLeader() == bot)
return false;
Unit* target = AI_VALUE(Unit*, "current target");
- if (target && botAI->GetGroupMaster()->GetTarget() == target->GetGUID())
+ if (target && botAI->GetGroupLeader()->GetTarget() == target->GetGUID())
return false;
if (!botAI->HasStrategy("follow", BOT_STATE_NON_COMBAT))
return false;
- Unit* fTarget = AI_VALUE(Unit*, "master target");
+ Unit* fTarget = AI_VALUE(Unit*, "group leader");
if (!CanDeadFollow(fTarget))
return false;
diff --git a/src/strategy/actions/FollowActions.h b/src/strategy/actions/FollowActions.h
index 5468e34131..9331bbf556 100644
--- a/src/strategy/actions/FollowActions.h
+++ b/src/strategy/actions/FollowActions.h
@@ -20,10 +20,10 @@ class FollowAction : public MovementAction
bool CanDeadFollow(Unit* target);
};
-class FleeToMasterAction : public FollowAction
+class FleeToGroupLeaderAction : public FollowAction
{
public:
- FleeToMasterAction(PlayerbotAI* botAI) : FollowAction(botAI, "flee to master") {}
+ FleeToGroupLeaderAction(PlayerbotAI* botAI) : FollowAction(botAI, "flee to group leader") {}
bool Execute(Event event) override;
bool isUseful() override;
diff --git a/src/strategy/actions/GenericBuffUtils.cpp b/src/strategy/actions/GenericBuffUtils.cpp
index 9e227caf15..1ac71bad4e 100644
--- a/src/strategy/actions/GenericBuffUtils.cpp
+++ b/src/strategy/actions/GenericBuffUtils.cpp
@@ -61,7 +61,7 @@ namespace ai::buff
return false;
if (SpellInfo const* info = sSpellMgr->GetSpellInfo(spellId))
- {
+ {
for (int i = 0; i < MAX_SPELL_REAGENTS; ++i)
{
if (info->Reagent[i] > 0)
diff --git a/src/strategy/actions/GenericBuffUtils.h b/src/strategy/actions/GenericBuffUtils.h
index d9cfc84213..c893de5976 100644
--- a/src/strategy/actions/GenericBuffUtils.h
+++ b/src/strategy/actions/GenericBuffUtils.h
@@ -29,7 +29,6 @@ namespace ai::buff
// Returns false if the spellId is invalid.
bool HasRequiredReagents(Player* bot, uint32 spellId);
-
// Applies the "switch to group buff" policy if: the bot is in a group of size x+,
// the group variant is known/useful, and reagents are available. Otherwise, returns baseName.
// If announceOnMissing == true and reagents are missing, calls the 'announce' callback
diff --git a/src/strategy/actions/GenericSpellActions.cpp b/src/strategy/actions/GenericSpellActions.cpp
index 3a36d9ccd0..b30975ad14 100644
--- a/src/strategy/actions/GenericSpellActions.cpp
+++ b/src/strategy/actions/GenericSpellActions.cpp
@@ -190,8 +190,8 @@ CastEnchantItemAction::CastEnchantItemAction(PlayerbotAI* botAI, std::string con
bool CastEnchantItemAction::isPossible()
{
- // if (!CastSpellAction::isPossible()) {
-
+ // if (!CastSpellAction::isPossible())
+ // {
// botAI->TellMasterNoFacing("Impossible: " + spell);
// return false;
// }
@@ -364,7 +364,8 @@ bool UseTrinketAction::UseTrinket(Item* item)
for (int i = 0; i < MAX_SPELL_EFFECTS; i++)
{
const SpellEffectInfo& effectInfo = spellInfo->Effects[i];
- if (effectInfo.Effect == SPELL_EFFECT_APPLY_AURA) {
+ if (effectInfo.Effect == SPELL_EFFECT_APPLY_AURA)
+ {
applyAura = true;
break;
}
diff --git a/src/strategy/actions/GuildManagementActions.cpp b/src/strategy/actions/GuildManagementActions.cpp
index af5a1f0172..f00a955e7c 100644
--- a/src/strategy/actions/GuildManagementActions.cpp
+++ b/src/strategy/actions/GuildManagementActions.cpp
@@ -58,6 +58,14 @@ Player* GuidManageAction::GetPlayer(Event event)
return nullptr;
}
+void GuidManageAction::SendPacket(WorldPacket const& packet)
+{
+ // make a heap copy because QueuePacket takes ownership
+ WorldPacket* data = new WorldPacket(packet);
+
+ bot->GetSession()->QueuePacket(data);
+}
+
bool GuidManageAction::Execute(Event event)
{
Player* player = GetPlayer(event);
@@ -84,12 +92,6 @@ bool GuildInviteAction::isUseful()
return bot->GetGuildId() && sGuildMgr->GetGuildById(bot->GetGuildId())->HasRankRight(bot, GR_RIGHT_INVITE);
}
-void GuildInviteAction::SendPacket(WorldPacket packet)
-{
- WorldPackets::Guild::GuildInviteByName data = WorldPacket(packet);
- bot->GetSession()->HandleGuildInviteOpcode(data);
-}
-
bool GuildInviteAction::PlayerIsValid(Player* member)
{
return !member->GetGuildId() && (sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_GUILD) ||
@@ -101,12 +103,6 @@ bool GuildPromoteAction::isUseful()
return bot->GetGuildId() && sGuildMgr->GetGuildById(bot->GetGuildId())->HasRankRight(bot, GR_RIGHT_PROMOTE);
}
-void GuildPromoteAction::SendPacket(WorldPacket packet)
-{
- WorldPackets::Guild::GuildPromoteMember data = WorldPacket(packet);
- bot->GetSession()->HandleGuildPromoteOpcode(data);
-}
-
bool GuildPromoteAction::PlayerIsValid(Player* member)
{
return member->GetGuildId() == bot->GetGuildId() && GetRankId(bot) < GetRankId(member) - 1;
@@ -117,12 +113,6 @@ bool GuildDemoteAction::isUseful()
return bot->GetGuildId() && sGuildMgr->GetGuildById(bot->GetGuildId())->HasRankRight(bot, GR_RIGHT_DEMOTE);
}
-void GuildDemoteAction::SendPacket(WorldPacket packet)
-{
- WorldPackets::Guild::GuildDemoteMember data = WorldPacket(packet);
- bot->GetSession()->HandleGuildDemoteOpcode(data);
-}
-
bool GuildDemoteAction::PlayerIsValid(Player* member)
{
return member->GetGuildId() == bot->GetGuildId() && GetRankId(bot) < GetRankId(member);
@@ -133,12 +123,6 @@ bool GuildRemoveAction::isUseful()
return bot->GetGuildId() && sGuildMgr->GetGuildById(bot->GetGuildId())->HasRankRight(bot, GR_RIGHT_REMOVE);
}
-void GuildRemoveAction::SendPacket(WorldPacket packet)
-{
- WorldPackets::Guild::GuildOfficerRemoveMember data = WorldPacket(packet);
- bot->GetSession()->HandleGuildRemoveOpcode(data);
-}
-
bool GuildRemoveAction::PlayerIsValid(Player* member)
{
return member->GetGuildId() == bot->GetGuildId() && GetRankId(bot) < GetRankId(member);
@@ -193,7 +177,7 @@ bool GuildManageNearbyAction::Execute(Event event)
if (guild->GetMemberSize() > 1000)
return false;
- if ( (guild->GetRankRights(botMember->GetRankId()) & GR_RIGHT_INVITE) == 0)
+ if ((guild->GetRankRights(botMember->GetRankId()) & GR_RIGHT_INVITE) == 0)
continue;
if (player->GetGuildIdInvited())
diff --git a/src/strategy/actions/GuildManagementActions.h b/src/strategy/actions/GuildManagementActions.h
index bf46d1b741..b1d363e89a 100644
--- a/src/strategy/actions/GuildManagementActions.h
+++ b/src/strategy/actions/GuildManagementActions.h
@@ -25,7 +25,7 @@ class GuidManageAction : public Action
bool isUseful() override { return false; }
protected:
- virtual void SendPacket(WorldPacket data){};
+ virtual void SendPacket(WorldPacket const& packet);
virtual Player* GetPlayer(Event event);
virtual bool PlayerIsValid(Player* member);
virtual uint8 GetRankId(Player* member);
@@ -44,7 +44,6 @@ class GuildInviteAction : public GuidManageAction
bool isUseful() override;
protected:
- void SendPacket(WorldPacket data) override;
bool PlayerIsValid(Player* member) override;
};
@@ -59,7 +58,6 @@ class GuildPromoteAction : public GuidManageAction
bool isUseful() override;
protected:
- void SendPacket(WorldPacket data) override;
bool PlayerIsValid(Player* member) override;
};
@@ -74,7 +72,6 @@ class GuildDemoteAction : public GuidManageAction
bool isUseful() override;
protected:
- void SendPacket(WorldPacket data) override;
bool PlayerIsValid(Player* member) override;
};
@@ -89,7 +86,6 @@ class GuildRemoveAction : public GuidManageAction
bool isUseful() override;
protected:
- void SendPacket(WorldPacket data) override;
bool PlayerIsValid(Player* member) override;
};
diff --git a/src/strategy/actions/InviteToGroupAction.cpp b/src/strategy/actions/InviteToGroupAction.cpp
index 7af26210c6..bec515fefb 100644
--- a/src/strategy/actions/InviteToGroupAction.cpp
+++ b/src/strategy/actions/InviteToGroupAction.cpp
@@ -9,7 +9,9 @@
#include "Event.h"
#include "GuildMgr.h"
#include "Log.h"
+#include "PlayerbotOperations.h"
#include "Playerbots.h"
+#include "PlayerbotWorldThreadProcessor.h"
#include "ServerFacade.h"
bool InviteToGroupAction::Invite(Player* inviter, Player* player)
@@ -27,7 +29,10 @@ bool InviteToGroupAction::Invite(Player* inviter, Player* player)
{
if (GET_PLAYERBOT_AI(player) && !GET_PLAYERBOT_AI(player)->IsRealPlayer())
if (!group->isRaidGroup() && group->GetMembersCount() > 4)
- group->ConvertToRaid();
+ {
+ auto convertOp = std::make_unique(inviter->GetGUID());
+ sPlayerbotWorldProcessor->QueueOperation(std::move(convertOp));
+ }
}
WorldPacket p;
@@ -89,7 +94,10 @@ bool InviteNearbyToGroupAction::Execute(Event event)
// When inviting the 5th member of the group convert to raid for future invites.
if (group && botAI->GetGrouperType() > GrouperType::LEADER_5 && !group->isRaidGroup() &&
bot->GetGroup()->GetMembersCount() > 3)
- group->ConvertToRaid();
+ {
+ auto convertOp = std::make_unique(bot->GetGUID());
+ sPlayerbotWorldProcessor->QueueOperation(std::move(convertOp));
+ }
if (sPlayerbotAIConfig->inviteChat && sRandomPlayerbotMgr->IsRandomBot(bot))
{
@@ -133,7 +141,7 @@ bool InviteNearbyToGroupAction::isUseful()
if (group->isRaidGroup() && group->IsFull())
return false;
- if (botAI->GetGroupMaster() != bot)
+ if (botAI->GetGroupLeader() != bot)
return false;
uint32 memberCount = group->GetMembersCount();
@@ -221,7 +229,8 @@ bool InviteGuildToGroupAction::Execute(Event event)
if (group && botAI->GetGrouperType() > GrouperType::LEADER_5 && !group->isRaidGroup() &&
bot->GetGroup()->GetMembersCount() > 3)
{
- group->ConvertToRaid();
+ auto convertOp = std::make_unique(bot->GetGUID());
+ sPlayerbotWorldProcessor->QueueOperation(std::move(convertOp));
}
if (sPlayerbotAIConfig->inviteChat &&
@@ -362,7 +371,10 @@ bool LfgAction::Execute(Event event)
if (param.empty() || param == "5" || group->isRaidGroup())
return false; // Group or raid is full so stop trying.
else
- group->ConvertToRaid(); // We want a raid but are in a group so convert and continue.
+ {
+ auto convertOp = std::make_unique(requester->GetGUID());
+ sPlayerbotWorldProcessor->QueueOperation(std::move(convertOp));
+ }
}
Group::MemberSlotList const& groupSlot = group->GetMemberSlots();
diff --git a/src/strategy/actions/LeaveGroupAction.cpp b/src/strategy/actions/LeaveGroupAction.cpp
index 88567b1ddd..a279c9426c 100644
--- a/src/strategy/actions/LeaveGroupAction.cpp
+++ b/src/strategy/actions/LeaveGroupAction.cpp
@@ -11,8 +11,11 @@
bool LeaveGroupAction::Execute(Event event)
{
- Player* master = event.getOwner();
- return Leave(master);
+ Player* player = event.getOwner();
+ if (player == botAI->GetMaster())
+ return Leave();
+
+ return false;
}
bool PartyCommandAction::Execute(Event event)
@@ -26,13 +29,21 @@ bool PartyCommandAction::Execute(Event event)
if (operation != PARTY_OP_LEAVE)
return false;
-
+ // Only leave if master has left the party, and randombot cannot set new master.
Player* master = GetMaster();
if (master && member == master->GetName())
- return Leave(bot);
-
- botAI->Reset();
-
+ {
+ if (sRandomPlayerbotMgr->IsRandomBot(bot))
+ {
+ Player* newMaster = botAI->FindNewMaster();
+ if (newMaster || bot->InBattleground())
+ {
+ botAI->SetMaster(newMaster);
+ return false;
+ }
+ }
+ return Leave();
+ }
return false;
}
@@ -42,17 +53,17 @@ bool UninviteAction::Execute(Event event)
if (p.GetOpcode() == CMSG_GROUP_UNINVITE)
{
p.rpos(0);
- std::string membername;
- p >> membername;
+ std::string memberName;
+ p >> memberName;
// player not found
- if (!normalizePlayerName(membername))
+ if (!normalizePlayerName(memberName))
{
return false;
}
- if (bot->GetName() == membername)
- return Leave(bot);
+ if (bot->GetName() == memberName)
+ return Leave();
}
if (p.GetOpcode() == CMSG_GROUP_UNINVITE_GUID)
@@ -62,50 +73,29 @@ bool UninviteAction::Execute(Event event)
p >> guid;
if (bot->GetGUID() == guid)
- return Leave(bot);
+ return Leave();
}
- botAI->Reset();
-
return false;
}
-bool LeaveGroupAction::Leave(Player* player)
+bool LeaveGroupAction::Leave()
{
- if (player &&
- !botAI &&
- !botAI->GetSecurity()->CheckLevelFor(PLAYERBOT_SECURITY_INVITE, false, player))
-
+ if (!botAI)
return false;
- bool aiMaster = GET_PLAYERBOT_AI(botAI->GetMaster()) != nullptr;
-
- botAI->TellMaster("Goodbye!", PLAYERBOT_SECURITY_TALK);
-
- bool randomBot = sRandomPlayerbotMgr->IsRandomBot(bot);
- bool shouldStay = randomBot && bot->GetGroup() && player == bot;
- if (!shouldStay)
- {
- botAI->LeaveOrDisbandGroup();
- }
-
- if (randomBot)
- {
- GET_PLAYERBOT_AI(bot)->SetMaster(nullptr);
- }
-
- if (!aiMaster)
- botAI->ResetStrategies(!randomBot);
-
- botAI->Reset();
+ Player* master = botAI -> GetMaster();
+ if (master)
+ botAI->TellMaster("Goodbye!", PLAYERBOT_SECURITY_TALK);
+ botAI->LeaveOrDisbandGroup();
return true;
}
bool LeaveFarAwayAction::Execute(Event event)
{
// allow bot to leave party when they want
- return Leave(botAI->GetGroupMaster());
+ return Leave();
}
bool LeaveFarAwayAction::isUseful()
@@ -119,22 +109,22 @@ bool LeaveFarAwayAction::isUseful()
if (!bot->GetGroup())
return false;
- Player* master = botAI->GetGroupMaster();
+ Player* groupLeader = botAI->GetGroupLeader();
Player* trueMaster = botAI->GetMaster();
- if (!master || (bot == master && !botAI->IsRealPlayer()))
+ if (!groupLeader || (bot == groupLeader && !botAI->IsRealPlayer()))
return false;
- PlayerbotAI* masterBotAI = nullptr;
- if (master)
- masterBotAI = GET_PLAYERBOT_AI(master);
- if (master && !masterBotAI)
+ PlayerbotAI* groupLeaderBotAI = nullptr;
+ if (groupLeader)
+ groupLeaderBotAI = GET_PLAYERBOT_AI(groupLeader);
+ if (groupLeader && !groupLeaderBotAI)
return false;
if (trueMaster && !GET_PLAYERBOT_AI(trueMaster))
return false;
if (botAI->IsAlt() &&
- (!masterBotAI || masterBotAI->IsRealPlayer())) // Don't leave group when alt grouped with player master.
+ (!groupLeaderBotAI || groupLeaderBotAI->IsRealPlayer())) // Don't leave group when alt grouped with player groupLeader.
return false;
if (botAI->GetGrouperType() == GrouperType::SOLO)
@@ -148,24 +138,22 @@ bool LeaveFarAwayAction::isUseful()
if (dCount > 4 && !botAI->HasRealPlayerMaster())
return true;
- if (bot->GetGuildId() == master->GetGuildId())
+ if (bot->GetGuildId() == groupLeader->GetGuildId())
{
- if (bot->GetLevel() > master->GetLevel() + 5)
+ if (bot->GetLevel() > groupLeader->GetLevel() + 5)
{
if (AI_VALUE(bool, "should get money"))
return false;
}
}
- if (abs(int32(master->GetLevel() - bot->GetLevel())) > 4)
+ if (abs(int32(groupLeader->GetLevel() - bot->GetLevel())) > 4)
return true;
- if (bot->GetMapId() != master->GetMapId() || bot->GetDistance2d(master) >= 2 * sPlayerbotAIConfig->rpgDistance)
+ if (bot->GetMapId() != groupLeader->GetMapId() || bot->GetDistance2d(groupLeader) >= 2 * sPlayerbotAIConfig->rpgDistance)
{
return true;
}
- botAI->Reset();
-
return false;
}
diff --git a/src/strategy/actions/LeaveGroupAction.h b/src/strategy/actions/LeaveGroupAction.h
index dcb4e96ce5..83baea3c1b 100644
--- a/src/strategy/actions/LeaveGroupAction.h
+++ b/src/strategy/actions/LeaveGroupAction.h
@@ -18,7 +18,7 @@ class LeaveGroupAction : public Action
bool Execute(Event event) override;
- virtual bool Leave(Player* player);
+ virtual bool Leave();
};
class PartyCommandAction : public LeaveGroupAction
diff --git a/src/strategy/actions/LfgActions.cpp b/src/strategy/actions/LfgActions.cpp
index 406a0ec05e..15f8b92f25 100644
--- a/src/strategy/actions/LfgActions.cpp
+++ b/src/strategy/actions/LfgActions.cpp
@@ -16,7 +16,6 @@
using namespace lfg;
-
bool LfgJoinAction::Execute(Event event) { return JoinLFG(); }
uint32 LfgJoinAction::GetRoles()
@@ -113,7 +112,7 @@ bool LfgJoinAction::JoinLFG()
dungeon->TypeID != LFG_TYPE_HEROIC && dungeon->TypeID != LFG_TYPE_RAID))
continue;
- const auto& botLevel = bot->GetLevel();
+ auto const& botLevel = bot->GetLevel();
/*LFG_TYPE_RANDOM on classic is 15-58 so bot over level 25 will never queue*/
if (dungeon->MinLevel && (botLevel < dungeon->MinLevel || botLevel > dungeon->MaxLevel) ||
@@ -180,7 +179,6 @@ bool LfgRoleCheckAction::Execute(Event event)
// if (currentRoles == newRoles)
// return false;
-
WorldPacket* packet = new WorldPacket(CMSG_LFG_SET_ROLES);
*packet << (uint8)newRoles;
bot->GetSession()->QueuePacket(packet);
@@ -267,7 +265,6 @@ bool LfgAcceptAction::Execute(Event event)
return false;
}
-
bool LfgLeaveAction::Execute(Event event)
{
// Don't leave if lfg strategy enabled
diff --git a/src/strategy/actions/LootRollAction.cpp b/src/strategy/actions/LootRollAction.cpp
index 3b3a4240ec..912f75fddf 100644
--- a/src/strategy/actions/LootRollAction.cpp
+++ b/src/strategy/actions/LootRollAction.cpp
@@ -41,9 +41,12 @@ bool LootRollAction::Execute(Event event)
continue;
std::string itemUsageParam;
- if (randomProperty != 0) {
+ if (randomProperty != 0)
+ {
itemUsageParam = std::to_string(itemId) + "," + std::to_string(randomProperty);
- } else {
+ }
+ else
+ {
itemUsageParam = std::to_string(itemId);
}
ItemUsage usage = AI_VALUE2(ItemUsage, "item usage", itemUsageParam);
@@ -120,7 +123,6 @@ bool LootRollAction::Execute(Event event)
return false;
}
-
RollVote LootRollAction::CalculateRollVote(ItemTemplate const* proto)
{
std::ostringstream out;
diff --git a/src/strategy/actions/MoveToTravelTargetAction.cpp b/src/strategy/actions/MoveToTravelTargetAction.cpp
index a4dec2caac..ed60339b82 100644
--- a/src/strategy/actions/MoveToTravelTargetAction.cpp
+++ b/src/strategy/actions/MoveToTravelTargetAction.cpp
@@ -18,7 +18,7 @@ bool MoveToTravelTargetAction::Execute(Event event)
WorldLocation location = *target->getPosition();
Group* group = bot->GetGroup();
- if (group && !urand(0, 1) && bot == botAI->GetGroupMaster() && !bot->IsInCombat())
+ if (group && !urand(0, 1) && bot == botAI->GetGroupLeader() && !bot->IsInCombat())
{
for (GroupReference* ref = group->GetFirstMember(); ref; ref = ref->next())
{
diff --git a/src/strategy/actions/MovementActions.cpp b/src/strategy/actions/MovementActions.cpp
index 0598a39d19..f66638a7a1 100644
--- a/src/strategy/actions/MovementActions.cpp
+++ b/src/strategy/actions/MovementActions.cpp
@@ -10,6 +10,7 @@
#include
#include
+#include "Corpse.h"
#include "Event.h"
#include "FleeManager.h"
#include "G3D/Vector3.h"
@@ -41,7 +42,6 @@
#include "Unit.h"
#include "Vehicle.h"
#include "WaypointMovementGenerator.h"
-#include "Corpse.h"
MovementAction::MovementAction(PlayerbotAI* botAI, std::string const name) : Action(botAI, name)
{
@@ -192,14 +192,15 @@ bool MovementAction::MoveTo(uint32 mapId, float x, float y, float z, bool idle,
{
return false;
}
+
bool generatePath = !bot->IsFlying() && !bot->isSwimming();
- bool disableMoveSplinePath = sPlayerbotAIConfig->disableMoveSplinePath >= 2 ||
- (sPlayerbotAIConfig->disableMoveSplinePath == 1 && bot->InBattleground());
+ bool disableMoveSplinePath =
+ sPlayerbotAIConfig->disableMoveSplinePath >= 2 ||
+ (sPlayerbotAIConfig->disableMoveSplinePath == 1 && bot->InBattleground());
if (Vehicle* vehicle = bot->GetVehicle())
{
VehicleSeatEntry const* seat = vehicle->GetSeatForPassenger(bot);
Unit* vehicleBase = vehicle->GetBase();
- // If the mover (vehicle) can fly, we DO NOT want an mmaps path (2D ground) => disable pathfinding
generatePath = !vehicleBase || !vehicleBase->CanFly();
if (!vehicleBase || !seat || !seat->CanControl()) // is passenger and cant move anyway
return false;
@@ -207,22 +208,7 @@ bool MovementAction::MoveTo(uint32 mapId, float x, float y, float z, bool idle,
float distance = vehicleBase->GetExactDist(x, y, z); // use vehicle distance, not bot
if (distance > 0.01f)
{
- MotionMaster& mm = *vehicleBase->GetMotionMaster(); // need to move vehicle, not bot
- // Disable ground pathing if the bot/master/vehicle are flying
- auto isFlying = [](Unit* u){ return u && (u->HasUnitMovementFlag(MOVEMENTFLAG_FLYING) || u->IsInFlight()); };
- bool allowPathVeh = generatePath;
- Unit* masterVeh = botAI ? botAI->GetMaster() : nullptr;
- if (isFlying(vehicleBase) || isFlying(bot) || isFlying(masterVeh))
- allowPathVeh = false;
- mm.Clear();
- if (!backwards)
- {
- mm.MovePoint(0, x, y, z, FORCED_MOVEMENT_NONE, 0.0f, 0.0f, allowPathVeh);
- }
- else
- {
- mm.MovePointBackwards(0, x, y, z, allowPathVeh);
- }
+ DoMovePoint(vehicleBase, x, y, z, generatePath, backwards);
float speed = backwards ? vehicleBase->GetSpeed(MOVE_RUN_BACK) : vehicleBase->GetSpeed(MOVE_RUN);
float delay = 1000.0f * (distance / speed);
if (lessDelay)
@@ -248,23 +234,7 @@ bool MovementAction::MoveTo(uint32 mapId, float x, float y, float z, bool idle,
// bot->CastStop();
// botAI->InterruptSpell();
// }
-
- MotionMaster& mm = *bot->GetMotionMaster();
- // No ground pathfinding if the bot/master are flying => allow true 3D (Z) movement
- auto isFlying = [](Unit* u){ return u && (u->HasUnitMovementFlag(MOVEMENTFLAG_FLYING) || u->IsInFlight()); };
- bool allowPath = generatePath;
- Unit* master = botAI ? botAI->GetMaster() : nullptr;
- if (isFlying(bot) || isFlying(master))
- allowPath = false;
- mm.Clear();
- if (!backwards)
- {
- mm.MovePoint(0, x, y, z, FORCED_MOVEMENT_NONE, 0.0f, 0.0f, allowPath);
- }
- else
- {
- mm.MovePointBackwards(0, x, y, z, allowPath);
- }
+ DoMovePoint(bot, x, y, z, generatePath, backwards);
float delay = 1000.0f * MoveDelay(distance, backwards);
if (lessDelay)
{
@@ -282,9 +252,7 @@ bool MovementAction::MoveTo(uint32 mapId, float x, float y, float z, bool idle,
Movement::PointsArray path =
SearchForBestPath(x, y, z, modifiedZ, sPlayerbotAIConfig->maxMovementSearchTime, normal_only);
if (modifiedZ == INVALID_HEIGHT)
- {
return false;
- }
float distance = bot->GetExactDist(x, y, modifiedZ);
if (distance > 0.01f)
{
@@ -296,24 +264,8 @@ bool MovementAction::MoveTo(uint32 mapId, float x, float y, float z, bool idle,
// bot->CastStop();
// botAI->InterruptSpell();
// }
-
- MotionMaster& mm = *bot->GetMotionMaster();
G3D::Vector3 endP = path.back();
- // No ground pathfinding if the bot/master are flying => allow true 3D (Z) movement
- auto isFlying = [](Unit* u){ return u && (u->HasUnitMovementFlag(MOVEMENTFLAG_FLYING) || u->IsInFlight()); };
- bool allowPath = generatePath;
- Unit* master = botAI ? botAI->GetMaster() : nullptr;
- if (isFlying(bot) || isFlying(master))
- allowPath = false;
- mm.Clear();
- if (!backwards)
- {
- mm.MovePoint(0, x, y, z, FORCED_MOVEMENT_NONE, 0.0f, 0.0f, allowPath);
- }
- else
- {
- mm.MovePointBackwards(0, x, y, z, allowPath);
- }
+ DoMovePoint(bot, x, y, z, generatePath, backwards);
float delay = 1000.0f * MoveDelay(distance, backwards);
if (lessDelay)
{
@@ -530,7 +482,8 @@ bool MovementAction::MoveTo(uint32 mapId, float x, float y, float z, bool idle,
// {
// AI_VALUE(LastMovement&, "last area trigger").lastAreaTrigger = entry;
// }
- // else {
+ // else
+ // {
// LOG_DEBUG("playerbots", "!entry");
// return bot->TeleportTo(movePosition.getMapId(), movePosition.getX(), movePosition.getY(),
// movePosition.getZ(), movePosition.getO(), 0);
@@ -580,9 +533,7 @@ bool MovementAction::MoveTo(uint32 mapId, float x, float y, float z, bool idle,
// bool goTaxi = bot->ActivateTaxiPathTo({ tEntry->from, tEntry->to }, unit, 1);
// if (botAI->HasCheat(BotCheatMask::gold))
- // {
// bot->SetMoney(botMoney);
- // }
// LOG_DEBUG("playerbots", "goTaxi");
// return goTaxi;
// }
@@ -873,15 +824,16 @@ bool MovementAction::ReachCombatTo(Unit* target, float distance)
float deltaAngle = Position::NormalizeOrientation(targetOrientation - target->GetAngle(bot));
if (deltaAngle > M_PI)
- deltaAngle -= 2.0f * M_PI; // -PI..PI
+ deltaAngle -= 2.0f * M_PI; // -PI..PI
// if target is moving forward and moving far away, predict the position
bool behind = fabs(deltaAngle) > M_PI_2;
- if (target->HasUnitMovementFlag(MOVEMENTFLAG_FORWARD) && behind) {
+ if (target->HasUnitMovementFlag(MOVEMENTFLAG_FORWARD) && behind)
+ {
float predictDis = std::min(3.0f, target->GetObjectSize() * 2);
tx += cos(target->GetOrientation()) * predictDis;
ty += sin(target->GetOrientation()) * predictDis;
- if (!target->GetMap()->CheckCollisionAndGetValidCoords(target, target->GetPositionX(), target->GetPositionY(), target->GetPositionZ(),
- tx, ty, tz))
+ if (!target->GetMap()->CheckCollisionAndGetValidCoords(target, target->GetPositionX(), target->GetPositionY(),
+ target->GetPositionZ(), tx, ty, tz))
{
tx = target->GetPositionX();
ty = target->GetPositionY();
@@ -999,9 +951,8 @@ bool MovementAction::IsMovingAllowed()
return false;
if (bot->isFrozen() || bot->IsPolymorphed() || (bot->isDead() && !bot->HasPlayerFlag(PLAYER_FLAGS_GHOST)) ||
- bot->IsBeingTeleported() || bot->HasRootAura() || bot->HasSpiritOfRedemptionAura() ||
- bot->HasConfuseAura() || bot->IsCharmed() || bot->HasStunAura() ||
- bot->IsInFlight() || bot->HasUnitState(UNIT_STATE_LOST_CONTROL))
+ bot->IsBeingTeleported() || bot->HasRootAura() || bot->HasSpiritOfRedemptionAura() || bot->HasConfuseAura() ||
+ bot->IsCharmed() || bot->HasStunAura() || bot->IsInFlight() || bot->HasUnitState(UNIT_STATE_LOST_CONTROL))
return false;
if (bot->GetMotionMaster()->GetMotionSlotType(MOTION_SLOT_CONTROLLED) != NULL_MOTION_TYPE)
@@ -1009,7 +960,8 @@ bool MovementAction::IsMovingAllowed()
return false;
}
- // if (bot->HasUnitMovementFlag(MOVEMENTFLAG_FALLING)) {
+ // if (bot->HasUnitMovementFlag(MOVEMENTFLAG_FALLING))
+ // {
// return false;
// }
return bot->GetMotionMaster()->GetCurrentMovementGeneratorType() != FLIGHT_MOTION_TYPE;
@@ -1019,84 +971,95 @@ bool MovementAction::Follow(Unit* target, float distance) { return Follow(target
void MovementAction::UpdateMovementState()
{
- int8 botInLiquidState = bot->GetLiquidData().Status;
-
- if (botInLiquidState == LIQUID_MAP_IN_WATER || botInLiquidState == LIQUID_MAP_UNDER_WATER)
- {
- bot->SetSwim(true);
- }
- else
- {
- bot->SetSwim(false);
- }
-
- bool onGround = bot->GetPositionZ() <
- bot->GetMapWaterOrGroundLevel(bot->GetPositionX(), bot->GetPositionY(), bot->GetPositionZ()) + 1.0f;
-
- // Keep bot->SendMovementFlagUpdate() withing the if statements to not intefere with bot behavior on ground/(shallow) waters
-
- bool hasFlightAura = bot->HasAuraType(SPELL_AURA_MOD_INCREASE_MOUNTED_FLIGHT_SPEED) || bot->HasAuraType(SPELL_AURA_FLY);
- if (hasFlightAura)
- {
- bool changed = false;
- if (!bot->HasUnitMovementFlag(MOVEMENTFLAG_CAN_FLY))
- {
- bot->AddUnitMovementFlag(MOVEMENTFLAG_CAN_FLY);
- changed = true;
+ const bool isCurrentlyRestricted = // see if the bot is currently slowed, rooted, or otherwise unable to move
+ bot->isFrozen() ||
+ bot->IsPolymorphed() ||
+ bot->HasRootAura() ||
+ bot->HasStunAura() ||
+ bot->HasConfuseAura() ||
+ bot->HasUnitState(UNIT_STATE_LOST_CONTROL);
+
+ // no update movement flags while movement is current restricted.
+ if (!isCurrentlyRestricted && bot->IsAlive())
+ {
+ // state flags
+ const auto master = botAI ? botAI->GetMaster() : nullptr; // real player or not
+ const bool masterIsFlying = master ? master->HasUnitMovementFlag(MOVEMENTFLAG_FLYING) : true;
+ const bool masterIsSwimming = master ? master->HasUnitMovementFlag(MOVEMENTFLAG_SWIMMING) : true;
+ const auto liquidState = bot->GetLiquidData().Status; // default LIQUID_MAP_NO_WATER
+ const float gZ = bot->GetMapWaterOrGroundLevel(bot->GetPositionX(), bot->GetPositionY(), bot->GetPositionZ());
+ const bool wantsToFly = bot->HasIncreaseMountedFlightSpeedAura() || bot->HasFlyAura();
+ const bool isFlying = bot->HasUnitMovementFlag(MOVEMENTFLAG_FLYING);
+ const bool isWaterArea = liquidState != LIQUID_MAP_NO_WATER;
+ const bool isUnderWater = liquidState == LIQUID_MAP_UNDER_WATER;
+ const bool isInWater = liquidState == LIQUID_MAP_IN_WATER;
+ const bool isWaterWalking = bot->HasUnitMovementFlag(MOVEMENTFLAG_WATERWALKING);
+ const bool isSwimming = bot->HasUnitMovementFlag(MOVEMENTFLAG_SWIMMING);
+ const bool wantsToWaterWalk = bot->HasWaterWalkAura();
+ const bool wantsToSwim = isInWater || isUnderWater;
+ const bool onGroundZ = (bot->GetPositionZ() < gZ + 1.f) && !isWaterArea;
+ bool movementFlagsUpdated = false;
+
+ // handle water state
+ if (isWaterArea && !isFlying)
+ {
+ // water walking
+ if (wantsToWaterWalk && !isWaterWalking && !masterIsSwimming)
+ {
+ bot->RemoveUnitMovementFlag(MOVEMENTFLAG_SWIMMING);
+ bot->AddUnitMovementFlag(MOVEMENTFLAG_WATERWALKING);
+ movementFlagsUpdated = true;
+ }
+ // swimming
+ else if (wantsToSwim && !isSwimming && masterIsSwimming)
+ {
+ bot->RemoveUnitMovementFlag(MOVEMENTFLAG_WATERWALKING);
+ bot->AddUnitMovementFlag(MOVEMENTFLAG_SWIMMING);
+ movementFlagsUpdated = true;
+ }
}
- if (!bot->HasUnitMovementFlag(MOVEMENTFLAG_DISABLE_GRAVITY))
+ else if (isSwimming || isWaterWalking)
{
- bot->AddUnitMovementFlag(MOVEMENTFLAG_DISABLE_GRAVITY);
- changed = true;
+ // reset water flags
+ bot->RemoveUnitMovementFlag(MOVEMENTFLAG_SWIMMING);
+ bot->RemoveUnitMovementFlag(MOVEMENTFLAG_WATERWALKING);
+ movementFlagsUpdated = true;
}
- if (!bot->HasUnitMovementFlag(MOVEMENTFLAG_FLYING))
+
+ // handle flying state
+ if (wantsToFly && !isFlying && masterIsFlying)
{
+ bot->AddUnitMovementFlag(MOVEMENTFLAG_CAN_FLY);
+ bot->AddUnitMovementFlag(MOVEMENTFLAG_DISABLE_GRAVITY);
bot->AddUnitMovementFlag(MOVEMENTFLAG_FLYING);
- changed = true;
- }
- if (changed)
- bot->SendMovementFlagUpdate();
- }
- else if (!hasFlightAura)
- {
- bool changed = false;
- if (bot->HasUnitMovementFlag(MOVEMENTFLAG_FLYING))
- {
- bot->RemoveUnitMovementFlag(MOVEMENTFLAG_FLYING);
- changed = true;
+ movementFlagsUpdated = true;
}
- if (bot->HasUnitMovementFlag(MOVEMENTFLAG_DISABLE_GRAVITY))
- {
- bot->RemoveUnitMovementFlag(MOVEMENTFLAG_DISABLE_GRAVITY);
- changed = true;
- }
- if (bot->HasUnitMovementFlag(MOVEMENTFLAG_CAN_FLY))
+ else if ((!wantsToFly || onGroundZ) && isFlying)
{
bot->RemoveUnitMovementFlag(MOVEMENTFLAG_CAN_FLY);
- changed = true;
+ bot->RemoveUnitMovementFlag(MOVEMENTFLAG_DISABLE_GRAVITY);
+ bot->RemoveUnitMovementFlag(MOVEMENTFLAG_FLYING);
+ movementFlagsUpdated = true;
}
- if (changed)
- bot->SendMovementFlagUpdate();
- }
- // See if the bot is currently slowed, rooted, or otherwise unable to move
- bool isCurrentlyRestricted = bot->isFrozen() || bot->IsPolymorphed() || bot->HasRootAura() || bot->HasStunAura() ||
- bot->HasConfuseAura() || bot->HasUnitState(UNIT_STATE_LOST_CONTROL);
+ // detect if movement restrictions have been lifted, CC just ended.
+ if (wasMovementRestricted)
+ movementFlagsUpdated = true; // refresh movement state to ensure animations play correctly
- // Detect if movement restrictions have been lifted
- if (wasMovementRestricted && !isCurrentlyRestricted && bot->IsAlive())
- {
- // CC just ended - refresh movement state to ensure animations play correctly
- bot->SendMovementFlagUpdate();
+ if (movementFlagsUpdated)
+ bot->SendMovementFlagUpdate();
}
- // Save current state for the next check
+ // Save current state for the next check
wasMovementRestricted = isCurrentlyRestricted;
// Temporary speed increase in group
- // if (botAI->HasRealPlayerMaster()) {
+ // if (botAI->HasRealPlayerMaster())
+ // {
// bot->SetSpeedRate(MOVE_RUN, 1.1f);
- // } else {
+ // }
+ // else
+ // {
// bot->SetSpeedRate(MOVE_RUN, 1.0f);
// }
// check if target is not reachable (from Vmangos)
@@ -1105,7 +1068,7 @@ void MovementAction::UpdateMovementState()
// {
// if (Unit* pTarget = sServerFacade->GetChaseTarget(bot))
// {
- // if (!bot->IsWithinMeleeRange(pTarget) && pTarget->GetTypeId() == TYPEID_UNIT)
+ // if (!bot->IsWithinMeleeRange(pTarget) && pTarget->IsCreature())
// {
// float angle = bot->GetAngle(pTarget);
// float distance = 5.0f;
@@ -1139,7 +1102,7 @@ void MovementAction::UpdateMovementState()
// {
// if (Unit* pTarget = sServerFacade->GetChaseTarget(bot))
// {
- // if (pTarget != botAI->GetGroupMaster())
+ // if (pTarget != botAI->GetGroupLeader())
// return;
// if (!bot->IsWithinMeleeRange(pTarget))
@@ -1174,6 +1137,13 @@ bool MovementAction::Follow(Unit* target, float distance, float angle)
if (!target)
return false;
+ if (!bot->InBattleground() && sServerFacade->IsDistanceLessOrEqualThan(sServerFacade->GetDistance2d(bot, target),
+ sPlayerbotAIConfig->followDistance))
+ {
+ // botAI->TellError("No need to follow");
+ return false;
+ }
+
/*
if (!bot->InBattleground()
&& sServerFacade->IsDistanceLessOrEqualThan(sServerFacade->GetDistance2d(bot, target->GetPositionX(),
@@ -1291,17 +1261,21 @@ bool MovementAction::Follow(Unit* target, float distance, float angle)
return MoveTo(target, sPlayerbotAIConfig->followDistance);
}
+ if (sServerFacade->IsDistanceLessOrEqualThan(sServerFacade->GetDistance2d(bot, target),
+ sPlayerbotAIConfig->followDistance))
+ {
+ // botAI->TellError("No need to follow");
+ return false;
+ }
+
if (target->IsFriendlyTo(bot) && bot->IsMounted() && AI_VALUE(GuidVector, "all targets").empty())
distance += angle;
- // Do not cancel follow if the 2D distance is short but the Z still differs (e.g., master above).
- float dz1 = fabs(bot->GetPositionZ() - target->GetPositionZ());
- if (!bot->InBattleground()
- && sServerFacade->IsDistanceLessOrEqualThan(sServerFacade->GetDistance2d(bot, target), sPlayerbotAIConfig->followDistance)
- && dz1 < sPlayerbotAIConfig->contactDistance)
+ if (!bot->InBattleground() && sServerFacade->IsDistanceLessOrEqualThan(sServerFacade->GetDistance2d(bot, target),
+ sPlayerbotAIConfig->followDistance))
{
// botAI->TellError("No need to follow");
- return false; // truly in range (2D and Z) => no need to move
+ return false;
}
bot->HandleEmoteCommand(0);
@@ -1382,7 +1356,7 @@ float MovementAction::MoveDelay(float distance, bool backwards)
}
else
{
- speed = backwards ? bot->GetSpeed(MOVE_RUN_BACK) :bot->GetSpeed(MOVE_RUN);
+ speed = backwards ? bot->GetSpeed(MOVE_RUN_BACK) : bot->GetSpeed(MOVE_RUN);
}
float delay = distance / speed;
return delay;
@@ -1412,8 +1386,7 @@ void MovementAction::SetNextMovementDelay(float delayMillis)
{
AI_VALUE(LastMovement&, "last movement")
.Set(bot->GetMapId(), bot->GetPositionX(), bot->GetPositionY(), bot->GetPositionZ(), bot->GetOrientation(),
- delayMillis,
- MovementPriority::MOVEMENT_FORCED);
+ delayMillis, MovementPriority::MOVEMENT_FORCED);
}
bool MovementAction::Flee(Unit* target)
@@ -1627,7 +1600,8 @@ bool MovementAction::MoveAway(Unit* target, float distance, bool backwards)
dz = bot->GetPositionZ();
exact = false;
}
- if (MoveTo(target->GetMapId(), dx, dy, dz, false, false, true, exact, MovementPriority::MOVEMENT_COMBAT, false, backwards))
+ if (MoveTo(target->GetMapId(), dx, dy, dz, false, false, true, exact, MovementPriority::MOVEMENT_COMBAT, false,
+ backwards))
{
return true;
}
@@ -1649,7 +1623,8 @@ bool MovementAction::MoveAway(Unit* target, float distance, bool backwards)
dz = bot->GetPositionZ();
exact = false;
}
- if (MoveTo(target->GetMapId(), dx, dy, dz, false, false, true, exact, MovementPriority::MOVEMENT_COMBAT, false, backwards))
+ if (MoveTo(target->GetMapId(), dx, dy, dz, false, false, true, exact, MovementPriority::MOVEMENT_COMBAT, false,
+ backwards))
{
return true;
}
@@ -1698,7 +1673,7 @@ bool MovementAction::Move(float angle, float distance)
float x = bot->GetPositionX() + cos(angle) * distance;
float y = bot->GetPositionY() + sin(angle) * distance;
- //TODO do we need GetMapWaterOrGroundLevel() if we're using CheckCollisionAndGetValidCoords() ?
+ // TODO do we need GetMapWaterOrGroundLevel() if we're using CheckCollisionAndGetValidCoords() ?
float z = bot->GetMapWaterOrGroundLevel(x, y, bot->GetPositionZ());
if (z == -100000.0f || z == -200000.0f)
z = bot->GetPositionZ();
@@ -1721,7 +1696,8 @@ bool MovementAction::MoveInside(uint32 mapId, float x, float y, float z, float d
// float MovementAction::SearchBestGroundZForPath(float x, float y, float z, bool generatePath, float range, bool
// normal_only, float step)
// {
-// if (!generatePath) {
+// if (!generatePath)
+// {
// return z;
// }
// float min_length = 100000.0f;
@@ -1732,10 +1708,12 @@ bool MovementAction::MoveInside(uint32 mapId, float x, float y, float z, float d
// modified_z = bot->GetMapWaterOrGroundLevel(x, y, z + delta);
// PathGenerator gen(bot);
// gen.CalculatePath(x, y, modified_z);
-// if (gen.GetPathType() == PATHFIND_NORMAL && gen.getPathLength() < min_length) {
+// if (gen.GetPathType() == PATHFIND_NORMAL && gen.getPathLength() < min_length)
+// {
// min_length = gen.getPathLength();
// current_z = modified_z;
-// if (abs(current_z - z) < 0.5f) {
+// if (abs(current_z - z) < 0.5f)
+// {
// return current_z;
// }
// }
@@ -1744,30 +1722,34 @@ bool MovementAction::MoveInside(uint32 mapId, float x, float y, float z, float d
// modified_z = bot->GetMapWaterOrGroundLevel(x, y, z + delta);
// PathGenerator gen(bot);
// gen.CalculatePath(x, y, modified_z);
-// if (gen.GetPathType() == PATHFIND_NORMAL && gen.getPathLength() < min_length) {
+// if (gen.GetPathType() == PATHFIND_NORMAL && gen.getPathLength() < min_length)
+// {
// min_length = gen.getPathLength();
// current_z = modified_z;
-// if (abs(current_z - z) < 0.5f) {
+// if (abs(current_z - z) < 0.5f)
// return current_z;
-// }
// }
// }
// for (delta = range / 2 + step; delta <= range; delta += 2) {
// modified_z = bot->GetMapWaterOrGroundLevel(x, y, z + delta);
// PathGenerator gen(bot);
// gen.CalculatePath(x, y, modified_z);
-// if (gen.GetPathType() == PATHFIND_NORMAL && gen.getPathLength() < min_length) {
+// if (gen.GetPathType() == PATHFIND_NORMAL && gen.getPathLength() < min_length)
+// {
// min_length = gen.getPathLength();
// current_z = modified_z;
-// if (abs(current_z - z) < 0.5f) {
+// if (abs(current_z - z) < 0.5f)
+// {
// return current_z;
// }
// }
// }
-// if (current_z == INVALID_HEIGHT && normal_only) {
+// if (current_z == INVALID_HEIGHT && normal_only)
+// {
// return INVALID_HEIGHT;
// }
-// if (current_z == INVALID_HEIGHT && !normal_only) {
+// if (current_z == INVALID_HEIGHT && !normal_only)
+// {
// return z;
// }
// return current_z;
@@ -1842,6 +1824,46 @@ const Movement::PointsArray MovementAction::SearchForBestPath(float x, float y,
return result;
}
+void MovementAction::DoMovePoint(Unit* unit, float x, float y, float z, bool generatePath, bool backwards)
+{
+ if (!unit)
+ return;
+
+ MotionMaster* mm = unit->GetMotionMaster();
+ if (!mm)
+ return;
+
+ // enable water walking
+ if (unit->HasUnitMovementFlag(MOVEMENTFLAG_WATERWALKING))
+ {
+ float gZ = unit->GetMapWaterOrGroundLevel(unit->GetPositionX(), unit->GetPositionY(), unit->GetPositionZ());
+ unit->UpdatePosition(unit->GetPositionX(), unit->GetPositionY(), gZ, false);
+ // z = gZ; no overwrite Z axe otherwise you cant steer the bots into swimming when water walking.
+ }
+
+ mm->Clear();
+ if (backwards)
+ {
+ mm->MovePointBackwards(
+ /*id*/ 0,
+ /*coords*/ x, y, z,
+ /*generatePath*/ generatePath,
+ /*forceDestination*/ false);
+ return;
+ }
+ else
+ {
+ mm->MovePoint(
+ /*id*/ 0,
+ /*coords*/ x, y, z,
+ /*forcedMovement*/ FORCED_MOVEMENT_NONE,
+ /*speed*/ 0.f,
+ /*orientation*/ 0.f,
+ /*generatePath*/ generatePath, // true => terrain path (2d mmap); false => straight spline (3d vmap)
+ /*forceDestination*/ false);
+ }
+}
+
bool FleeAction::Execute(Event event)
{
return MoveAway(AI_VALUE(Unit*, "current target"), sPlayerbotAIConfig->fleeDistance, true);
@@ -1922,7 +1944,8 @@ bool AvoidAoeAction::AvoidAuraWithDynamicObj()
{
return false;
}
- if (sPlayerbotAIConfig->aoeAvoidSpellWhitelist.find(spellInfo->Id) != sPlayerbotAIConfig->aoeAvoidSpellWhitelist.end())
+ if (sPlayerbotAIConfig->aoeAvoidSpellWhitelist.find(spellInfo->Id) !=
+ sPlayerbotAIConfig->aoeAvoidSpellWhitelist.end())
return false;
DynamicObject* dynOwner = aura->GetDynobjOwner();
@@ -1987,7 +2010,8 @@ bool AvoidAoeAction::AvoidGameObjectWithDamage()
continue;
}
- if (sPlayerbotAIConfig->aoeAvoidSpellWhitelist.find(spellId) != sPlayerbotAIConfig->aoeAvoidSpellWhitelist.end())
+ if (sPlayerbotAIConfig->aoeAvoidSpellWhitelist.find(spellId) !=
+ sPlayerbotAIConfig->aoeAvoidSpellWhitelist.end())
continue;
const SpellInfo* spellInfo = sSpellMgr->GetSpellInfo(spellId);
@@ -2013,7 +2037,8 @@ bool AvoidAoeAction::AvoidGameObjectWithDamage()
lastTellTimer = time(NULL);
lastMoveTimer = getMSTime();
std::ostringstream out;
- out << "I'm avoiding " << name.str() << " (" << spellInfo->Id << ")" << " Radius " << radius << " - [Trap]";
+ out << "I'm avoiding " << name.str() << " (" << spellInfo->Id << ")" << " Radius " << radius
+ << " - [Trap]";
bot->Say(out.str(), LANG_UNIVERSAL);
}
return true;
@@ -2056,7 +2081,8 @@ bool AvoidAoeAction::AvoidUnitWithDamageAura()
sSpellMgr->GetSpellInfo(spellInfo->Effects[aurEff->GetEffIndex()].TriggerSpell);
if (!triggerSpellInfo)
continue;
- if (sPlayerbotAIConfig->aoeAvoidSpellWhitelist.find(triggerSpellInfo->Id) != sPlayerbotAIConfig->aoeAvoidSpellWhitelist.end())
+ if (sPlayerbotAIConfig->aoeAvoidSpellWhitelist.find(triggerSpellInfo->Id) !=
+ sPlayerbotAIConfig->aoeAvoidSpellWhitelist.end())
return false;
for (int j = 0; j < MAX_SPELL_EFFECTS; j++)
{
@@ -2078,7 +2104,8 @@ bool AvoidAoeAction::AvoidUnitWithDamageAura()
lastTellTimer = time(NULL);
lastMoveTimer = getMSTime();
std::ostringstream out;
- out << "I'm avoiding " << name.str() << " (" << triggerSpellInfo->Id << ")" << " Radius " << radius << " - [Unit Trigger]";
+ out << "I'm avoiding " << name.str() << " (" << triggerSpellInfo->Id << ")"
+ << " Radius " << radius << " - [Unit Trigger]";
bot->Say(out.str(), LANG_UNIVERSAL);
}
}
@@ -2097,7 +2124,8 @@ Position MovementAction::BestPositionForMeleeToFlee(Position pos, float radius)
if (currentTarget)
{
// Normally, move to left or right is the best position
- bool isTanking = (!currentTarget->isFrozen() && !currentTarget->HasRootAura()) && (currentTarget->GetVictim() == bot);
+ bool isTanking = (!currentTarget->isFrozen()
+ && !currentTarget->HasRootAura()) && (currentTarget->GetVictim() == bot);
float angle = bot->GetAngle(currentTarget);
float angleLeft = angle + (float)M_PI / 2;
float angleRight = angle - (float)M_PI / 2;
@@ -2312,8 +2340,7 @@ bool CombatFormationMoveAction::isUseful()
bool CombatFormationMoveAction::Execute(Event event)
{
float dis = AI_VALUE(float, "disperse distance");
- if (dis <= 0.0f ||
- (!bot->IsInCombat() && botAI->HasStrategy("stay", BotState::BOT_STATE_NON_COMBAT)) ||
+ if (dis <= 0.0f || (!bot->IsInCombat() && botAI->HasStrategy("stay", BotState::BOT_STATE_NON_COMBAT)) ||
(bot->IsInCombat() && botAI->HasStrategy("stay", BotState::BOT_STATE_COMBAT)))
return false;
Player* playerToLeave = NearestGroupMember(dis);
@@ -2463,7 +2490,7 @@ bool TankFaceAction::Execute(Event event)
float deltaAngle = Position::NormalizeOrientation(averageAngle - target->GetAngle(bot));
if (deltaAngle > M_PI)
- deltaAngle -= 2.0f * M_PI; // -PI..PI
+ deltaAngle -= 2.0f * M_PI; // -PI..PI
float tolerable = M_PI_2;
@@ -2474,12 +2501,13 @@ bool TankFaceAction::Execute(Event event)
float goodAngle2 = Position::NormalizeOrientation(averageAngle - M_PI * 3 / 5);
// if dist < bot->GetMeleeRange(target) / 2, target will move backward
- float dist = std::max(bot->GetExactDist(target), bot->GetMeleeRange(target) / 2) - bot->GetCombatReach() - target->GetCombatReach();
+ float dist = std::max(bot->GetExactDist(target), bot->GetMeleeRange(target) / 2) - bot->GetCombatReach() -
+ target->GetCombatReach();
std::vector availablePos;
float x, y, z;
target->GetNearPoint(bot, x, y, z, 0.0f, dist, goodAngle1);
- if (bot->GetMap()->CheckCollisionAndGetValidCoords(bot, bot->GetPositionX(), bot->GetPositionY(), bot->GetPositionZ(),
- x, y, z))
+ if (bot->GetMap()->CheckCollisionAndGetValidCoords(bot, bot->GetPositionX(), bot->GetPositionY(),
+ bot->GetPositionZ(), x, y, z))
{
/// @todo: movement control now is a mess, prepare to rewrite
std::list& infoList = AI_VALUE(std::list&, "recently flee info");
@@ -2491,8 +2519,8 @@ bool TankFaceAction::Execute(Event event)
}
}
target->GetNearPoint(bot, x, y, z, 0.0f, dist, goodAngle2);
- if (bot->GetMap()->CheckCollisionAndGetValidCoords(bot, bot->GetPositionX(), bot->GetPositionY(), bot->GetPositionZ(),
- x, y, z))
+ if (bot->GetMap()->CheckCollisionAndGetValidCoords(bot, bot->GetPositionX(), bot->GetPositionY(),
+ bot->GetPositionZ(), x, y, z))
{
std::list& infoList = AI_VALUE(std::list&, "recently flee info");
Position pos(x, y, z);
@@ -2505,13 +2533,15 @@ bool TankFaceAction::Execute(Event event)
if (availablePos.empty())
return false;
Position nearest = GetNearestPosition(availablePos);
- return MoveTo(bot->GetMapId(), nearest.GetPositionX(), nearest.GetPositionY(), nearest.GetPositionZ(), false, false, false, true, MovementPriority::MOVEMENT_COMBAT);
+ return MoveTo(bot->GetMapId(), nearest.GetPositionX(), nearest.GetPositionY(), nearest.GetPositionZ(), false, false,
+ false, true, MovementPriority::MOVEMENT_COMBAT);
}
bool RearFlankAction::isUseful()
{
Unit* target = AI_VALUE(Unit*, "current target");
- if (!target) { return false; }
+ if (!target)
+ return false;
// Need to double the front angle check to account for mirrored angle.
bool inFront = target->HasInArc(2.f * minAngle, bot);
@@ -2525,7 +2555,8 @@ bool RearFlankAction::isUseful()
bool RearFlankAction::Execute(Event event)
{
Unit* target = AI_VALUE(Unit*, "current target");
- if (!target) { return false; }
+ if (!target)
+ return false;
float angle = frand(minAngle, maxAngle);
float baseDistance = bot->GetMeleeRange(target) * 0.5f;
@@ -2544,8 +2575,8 @@ bool RearFlankAction::Execute(Event event)
destination = &rightFlank;
}
- return MoveTo(bot->GetMapId(), destination->GetPositionX(), destination->GetPositionY(), destination->GetPositionZ(),
- false, false, false, true, MovementPriority::MOVEMENT_COMBAT);
+ return MoveTo(bot->GetMapId(), destination->GetPositionX(), destination->GetPositionY(),
+ destination->GetPositionZ(), false, false, false, true, MovementPriority::MOVEMENT_COMBAT);
}
bool DisperseSetAction::Execute(Event event)
@@ -2632,7 +2663,7 @@ bool DisperseSetAction::Execute(Event event)
return true;
}
-bool RunAwayAction::Execute(Event event) { return Flee(AI_VALUE(Unit*, "master target")); }
+bool RunAwayAction::Execute(Event event) { return Flee(AI_VALUE(Unit*, "group leader")); }
bool MoveToLootAction::Execute(Event event)
{
@@ -2673,9 +2704,8 @@ bool SetFacingTargetAction::isUseful() { return !AI_VALUE2(bool, "facing", "curr
bool SetFacingTargetAction::isPossible()
{
if (bot->isFrozen() || bot->IsPolymorphed() || (bot->isDead() && !bot->HasPlayerFlag(PLAYER_FLAGS_GHOST)) ||
- bot->IsBeingTeleported() || bot->HasConfuseAura() || bot->IsCharmed() ||
- bot->HasStunAura() || bot->IsInFlight() ||
- bot->HasUnitState(UNIT_STATE_LOST_CONTROL))
+ bot->IsBeingTeleported() || bot->HasConfuseAura() || bot->IsCharmed() || bot->HasStunAura() ||
+ bot->IsInFlight() || bot->HasUnitState(UNIT_STATE_LOST_CONTROL))
return false;
return true;
@@ -2695,7 +2725,7 @@ bool SetBehindTargetAction::Execute(Event event)
float deltaAngle = Position::NormalizeOrientation(target->GetOrientation() - target->GetAngle(bot));
if (deltaAngle > M_PI)
- deltaAngle -= 2.0f * M_PI; // -PI..PI
+ deltaAngle -= 2.0f * M_PI; // -PI..PI
float tolerable = M_PI_2;
@@ -2705,12 +2735,13 @@ bool SetBehindTargetAction::Execute(Event event)
float goodAngle1 = Position::NormalizeOrientation(target->GetOrientation() + M_PI * 3 / 5);
float goodAngle2 = Position::NormalizeOrientation(target->GetOrientation() - M_PI * 3 / 5);
- float dist = std::max(bot->GetExactDist(target), bot->GetMeleeRange(target) / 2) - bot->GetCombatReach() - target->GetCombatReach();
+ float dist = std::max(bot->GetExactDist(target), bot->GetMeleeRange(target) / 2) - bot->GetCombatReach() -
+ target->GetCombatReach();
std::vector availablePos;
float x, y, z;
target->GetNearPoint(bot, x, y, z, 0.0f, dist, goodAngle1);
- if (bot->GetMap()->CheckCollisionAndGetValidCoords(bot, bot->GetPositionX(), bot->GetPositionY(), bot->GetPositionZ(),
- x, y, z))
+ if (bot->GetMap()->CheckCollisionAndGetValidCoords(bot, bot->GetPositionX(), bot->GetPositionY(),
+ bot->GetPositionZ(), x, y, z))
{
/// @todo: movement control now is a mess, prepare to rewrite
std::list& infoList = AI_VALUE(std::list&, "recently flee info");
@@ -2722,8 +2753,8 @@ bool SetBehindTargetAction::Execute(Event event)
}
}
target->GetNearPoint(bot, x, y, z, 0.0f, dist, goodAngle2);
- if (bot->GetMap()->CheckCollisionAndGetValidCoords(bot, bot->GetPositionX(), bot->GetPositionY(), bot->GetPositionZ(),
- x, y, z))
+ if (bot->GetMap()->CheckCollisionAndGetValidCoords(bot, bot->GetPositionX(), bot->GetPositionY(),
+ bot->GetPositionZ(), x, y, z))
{
std::list& infoList = AI_VALUE(std::list&, "recently flee info");
Position pos(x, y, z);
@@ -2736,7 +2767,8 @@ bool SetBehindTargetAction::Execute(Event event)
if (availablePos.empty())
return false;
Position nearest = GetNearestPosition(availablePos);
- return MoveTo(bot->GetMapId(), nearest.GetPositionX(), nearest.GetPositionY(), nearest.GetPositionZ(), false, false, false, true, MovementPriority::MOVEMENT_COMBAT);
+ return MoveTo(bot->GetMapId(), nearest.GetPositionX(), nearest.GetPositionY(), nearest.GetPositionZ(), false, false,
+ false, true, MovementPriority::MOVEMENT_COMBAT);
}
bool MoveOutOfCollisionAction::Execute(Event event)
@@ -2807,7 +2839,7 @@ bool MoveFromGroupAction::Execute(Event event)
{
float distance = atoi(event.getParam().c_str());
if (!distance)
- distance = 20.0f; // flee distance from config is too small for this
+ distance = 20.0f; // flee distance from config is too small for this
return MoveFromGroup(distance);
}
@@ -2818,7 +2850,7 @@ bool MoveAwayFromCreatureAction::Execute(Event event)
// Find all creatures with the specified Id
std::vector creatures;
- for (const auto& guid : targets)
+ for (auto const& guid : targets)
{
Unit* unit = botAI->GetUnit(guid);
if (unit && (alive && unit->IsAlive()) && unit->GetEntry() == creatureId)
@@ -2890,10 +2922,7 @@ bool MoveAwayFromCreatureAction::Execute(Event event)
return false;
}
-bool MoveAwayFromCreatureAction::isPossible()
-{
- return bot->CanFreeMove();
-}
+bool MoveAwayFromCreatureAction::isPossible() { return bot->CanFreeMove(); }
bool MoveAwayFromPlayerWithDebuffAction::Execute(Event event)
{
@@ -2980,7 +3009,4 @@ bool MoveAwayFromPlayerWithDebuffAction::Execute(Event event)
return false;
}
-bool MoveAwayFromPlayerWithDebuffAction::isPossible()
-{
- return bot->CanFreeMove();
-}
+bool MoveAwayFromPlayerWithDebuffAction::isPossible() { return bot->CanFreeMove(); }
diff --git a/src/strategy/actions/MovementActions.h b/src/strategy/actions/MovementActions.h
index b5f7a38912..d12bcd555c 100644
--- a/src/strategy/actions/MovementActions.h
+++ b/src/strategy/actions/MovementActions.h
@@ -29,12 +29,17 @@ class MovementAction : public Action
protected:
bool JumpTo(uint32 mapId, float x, float y, float z, MovementPriority priority = MovementPriority::MOVEMENT_NORMAL);
- bool MoveNear(uint32 mapId, float x, float y, float z, float distance = sPlayerbotAIConfig->contactDistance, MovementPriority priority = MovementPriority::MOVEMENT_NORMAL);
+ bool MoveNear(uint32 mapId, float x, float y, float z, float distance = sPlayerbotAIConfig->contactDistance,
+ MovementPriority priority = MovementPriority::MOVEMENT_NORMAL);
bool MoveToLOS(WorldObject* target, bool ranged = false);
bool MoveTo(uint32 mapId, float x, float y, float z, bool idle = false, bool react = false,
- bool normal_only = false, bool exact_waypoint = false, MovementPriority priority = MovementPriority::MOVEMENT_NORMAL, bool lessDelay = false, bool backwards = false);
- bool MoveTo(WorldObject* target, float distance = 0.0f, MovementPriority priority = MovementPriority::MOVEMENT_NORMAL);
- bool MoveNear(WorldObject* target, float distance = sPlayerbotAIConfig->contactDistance, MovementPriority priority = MovementPriority::MOVEMENT_NORMAL);
+ bool normal_only = false, bool exact_waypoint = false,
+ MovementPriority priority = MovementPriority::MOVEMENT_NORMAL, bool lessDelay = false,
+ bool backwards = false);
+ bool MoveTo(WorldObject* target, float distance = 0.0f,
+ MovementPriority priority = MovementPriority::MOVEMENT_NORMAL);
+ bool MoveNear(WorldObject* target, float distance = sPlayerbotAIConfig->contactDistance,
+ MovementPriority priority = MovementPriority::MOVEMENT_NORMAL);
float GetFollowAngle();
bool Follow(Unit* target, float distance = sPlayerbotAIConfig->followDistance);
bool Follow(Unit* target, float distance, float angle);
@@ -51,10 +56,11 @@ class MovementAction : public Action
bool Flee(Unit* target);
void ClearIdleState();
void UpdateMovementState();
- bool MoveAway(Unit* target, float distance = sPlayerbotAIConfig -> fleeDistance, bool backwards = false);
+ bool MoveAway(Unit* target, float distance = sPlayerbotAIConfig->fleeDistance, bool backwards = false);
bool MoveFromGroup(float distance);
bool Move(float angle, float distance);
- bool MoveInside(uint32 mapId, float x, float y, float z, float distance = sPlayerbotAIConfig->followDistance, MovementPriority priority = MovementPriority::MOVEMENT_NORMAL);
+ bool MoveInside(uint32 mapId, float x, float y, float z, float distance = sPlayerbotAIConfig->followDistance,
+ MovementPriority priority = MovementPriority::MOVEMENT_NORMAL);
void CreateWp(Player* wpOwner, float x, float y, float z, float o, uint32 entry, bool important = false);
Position BestPositionForMeleeToFlee(Position pos, float radius);
Position BestPositionForRangedToFlee(Position pos, float radius);
@@ -74,6 +80,7 @@ class MovementAction : public Action
const Movement::PointsArray SearchForBestPath(float x, float y, float z, float& modified_z, int maxSearchCount = 5,
bool normal_only = false, float step = 8.0f);
bool wasMovementRestricted = false;
+ void DoMovePoint(Unit* unit, float x, float y, float z, bool generatePath, bool backwards);
};
class FleeAction : public MovementAction
@@ -119,7 +126,6 @@ class AvoidAoeAction : public MovementAction
int moveInterval;
};
-
class CombatFormationMoveAction : public MovementAction
{
public:
@@ -150,17 +156,18 @@ class TankFaceAction : public CombatFormationMoveAction
class RearFlankAction : public MovementAction
{
-// 90 degree minimum angle prevents any frontal cleaves/breaths and avoids parry-hasting the boss.
-// 120 degree maximum angle leaves a 120 degree symmetrical cone at the tail end which is usually enough to avoid tail swipes.
-// Some dragons or mobs may have different danger zone angles, override if needed.
+ // 90 degree minimum angle prevents any frontal cleaves/breaths and avoids parry-hasting the boss.
+ // 120 degree maximum angle leaves a 120 degree symmetrical cone at the tail end which is usually enough to avoid
+ // tail swipes. Some dragons or mobs may have different danger zone angles, override if needed.
public:
- RearFlankAction(PlayerbotAI* botAI, float distance = 0.0f, float minAngle = ANGLE_90_DEG, float maxAngle = ANGLE_120_DEG)
+ RearFlankAction(PlayerbotAI* botAI, float distance = 0.0f, float minAngle = ANGLE_90_DEG,
+ float maxAngle = ANGLE_120_DEG)
: MovementAction(botAI, "rear flank")
- {
- this->distance = distance;
- this->minAngle = minAngle;
- this->maxAngle = maxAngle;
- }
+ {
+ this->distance = distance;
+ this->minAngle = minAngle;
+ this->maxAngle = maxAngle;
+ }
bool Execute(Event event) override;
bool isUseful() override;
@@ -298,7 +305,9 @@ class MoveAwayFromCreatureAction : public MovementAction
{
public:
MoveAwayFromCreatureAction(PlayerbotAI* botAI, std::string name, uint32 creatureId, float range, bool alive = true)
- : MovementAction(botAI, name), creatureId(creatureId), range(range), alive(alive) {}
+ : MovementAction(botAI, name), creatureId(creatureId), range(range), alive(alive)
+ {
+ }
bool Execute(Event event) override;
bool isPossible() override;
@@ -313,7 +322,9 @@ class MoveAwayFromPlayerWithDebuffAction : public MovementAction
{
public:
MoveAwayFromPlayerWithDebuffAction(PlayerbotAI* botAI, std::string name, uint32 spellId, float range)
- : MovementAction(botAI, name), spellId(spellId), range(range) {}
+ : MovementAction(botAI, name), spellId(spellId), range(range)
+ {
+ }
bool Execute(Event event) override;
bool isPossible() override;
diff --git a/src/strategy/actions/NonCombatActions.cpp b/src/strategy/actions/NonCombatActions.cpp
index e810ad27cd..f87aa891dd 100644
--- a/src/strategy/actions/NonCombatActions.cpp
+++ b/src/strategy/actions/NonCombatActions.cpp
@@ -47,16 +47,16 @@ bool DrinkAction::Execute(Event event)
return UseItemAction::Execute(event);
}
-bool DrinkAction::isUseful()
-{
- return UseItemAction::isUseful() &&
+bool DrinkAction::isUseful()
+{
+ return UseItemAction::isUseful() &&
AI_VALUE2(bool, "has mana", "self target") &&
AI_VALUE2(uint8, "mana", "self target") < 100;
}
bool DrinkAction::isPossible()
{
- return !bot->IsInCombat() &&
+ return !bot->IsInCombat() &&
!bot->IsMounted() &&
!botAI->HasAnyAuraOf(GetTarget(), "dire bear form", "bear form", "cat form", "travel form",
"aquatic form","flight form", "swift flight form", nullptr) &&
@@ -102,15 +102,15 @@ bool EatAction::Execute(Event event)
return UseItemAction::Execute(event);
}
-bool EatAction::isUseful()
-{
- return UseItemAction::isUseful() &&
+bool EatAction::isUseful()
+{
+ return UseItemAction::isUseful() &&
AI_VALUE2(uint8, "health", "self target") < 100;
}
bool EatAction::isPossible()
{
- return !bot->IsInCombat() &&
+ return !bot->IsInCombat() &&
!bot->IsMounted() &&
!botAI->HasAnyAuraOf(GetTarget(), "dire bear form", "bear form", "cat form", "travel form",
"aquatic form","flight form", "swift flight form", nullptr) &&
diff --git a/src/strategy/actions/PassLeadershipToMasterAction.cpp b/src/strategy/actions/PassLeadershipToMasterAction.cpp
index ceb1fbbcf2..87890c1c57 100644
--- a/src/strategy/actions/PassLeadershipToMasterAction.cpp
+++ b/src/strategy/actions/PassLeadershipToMasterAction.cpp
@@ -6,16 +6,17 @@
#include "PassLeadershipToMasterAction.h"
#include "Event.h"
+#include "PlayerbotOperations.h"
#include "Playerbots.h"
+#include "PlayerbotWorldThreadProcessor.h"
bool PassLeadershipToMasterAction::Execute(Event event)
{
if (Player* master = GetMaster())
if (master && master != bot && bot->GetGroup() && bot->GetGroup()->IsMember(master->GetGUID()))
{
- WorldPacket p(SMSG_GROUP_SET_LEADER, 8);
- p << master->GetGUID();
- bot->GetSession()->HandleGroupSetLeaderOpcode(p);
+ auto setLeaderOp = std::make_unique(bot->GetGUID(), master->GetGUID());
+ sPlayerbotWorldProcessor->QueueOperation(std::move(setLeaderOp));
if (!message.empty())
botAI->TellMasterNoFacing(message);
diff --git a/src/strategy/actions/PetsAction.cpp b/src/strategy/actions/PetsAction.cpp
index 8d78ba85ed..0785b5eabe 100644
--- a/src/strategy/actions/PetsAction.cpp
+++ b/src/strategy/actions/PetsAction.cpp
@@ -25,7 +25,9 @@ bool PetsAction::Execute(Event event)
if (param.empty())
{
// If no parameter is provided, show usage instructions and return.
- botAI->TellError("Usage: pet ");
+ std::string text = sPlayerbotTextMgr->GetBotTextOrDefault(
+ "pet_usage_error", "Usage: pet ", {});
+ botAI->TellError(text);
return false;
}
@@ -52,7 +54,9 @@ bool PetsAction::Execute(Event event)
// If no pets or guardians are found, notify and return.
if (targets.empty())
{
- botAI->TellError("You have no pet or guardian pet.");
+ std::string text = sPlayerbotTextMgr->GetBotTextOrDefault(
+ "pet_no_pet_error", "You have no pet or guardian pet.", {});
+ botAI->TellError(text);
return false;
}
@@ -63,42 +67,54 @@ bool PetsAction::Execute(Event event)
if (param == "aggressive")
{
react = REACT_AGGRESSIVE;
- stanceText = "aggressive";
+ stanceText = sPlayerbotTextMgr->GetBotTextOrDefault(
+ "pet_stance_aggressive", "aggressive", {});
}
else if (param == "defensive")
{
react = REACT_DEFENSIVE;
- stanceText = "defensive";
+ stanceText = sPlayerbotTextMgr->GetBotTextOrDefault(
+ "pet_stance_defensive", "defensive", {});
}
else if (param == "passive")
{
react = REACT_PASSIVE;
- stanceText = "passive";
+ stanceText = sPlayerbotTextMgr->GetBotTextOrDefault(
+ "pet_stance_passive", "passive", {});
}
// The "stance" command simply reports the current stance of each pet/guardian.
else if (param == "stance")
{
for (Creature* target : targets)
{
- std::string type = target->IsPet() ? "pet" : "guardian";
+ std::string type = target->IsPet() ?
+ sPlayerbotTextMgr->GetBotTextOrDefault("pet_type_pet", "pet", {}) :
+ sPlayerbotTextMgr->GetBotTextOrDefault("pet_type_guardian", "guardian", {});
std::string name = target->GetName();
std::string stance;
switch (target->GetReactState())
{
case REACT_AGGRESSIVE:
- stance = "aggressive";
+ stance = sPlayerbotTextMgr->GetBotTextOrDefault(
+ "pet_stance_aggressive", "aggressive", {});
break;
case REACT_DEFENSIVE:
- stance = "defensive";
+ stance = sPlayerbotTextMgr->GetBotTextOrDefault(
+ "pet_stance_defensive", "defensive", {});
break;
case REACT_PASSIVE:
- stance = "passive";
+ stance = sPlayerbotTextMgr->GetBotTextOrDefault(
+ "pet_stance_passive", "passive", {});
break;
default:
- stance = "unknown";
+ stance = sPlayerbotTextMgr->GetBotTextOrDefault(
+ "pet_stance_unknown", "unknown", {});
break;
}
- botAI->TellMaster("Current stance of " + type + " \"" + name + "\": " + stance + ".");
+ std::string text = sPlayerbotTextMgr->GetBotTextOrDefault(
+ "pet_stance_report", "Current stance of %type \"%name\": %stance.",
+ {{"type", type}, {"name", name}, {"stance", stance}});
+ botAI->TellMaster(text);
}
return true;
}
@@ -121,17 +137,31 @@ bool PetsAction::Execute(Event event)
// If no valid target is selected, show an error and return.
if (!targetUnit)
{
- botAI->TellError("No valid target selected by master.");
+ std::string text = sPlayerbotTextMgr->GetBotTextOrDefault(
+ "pet_no_target_error", "No valid target selected by master.", {});
+ botAI->TellError(text);
return false;
}
if (!targetUnit->IsAlive())
{
- botAI->TellError("Target is not alive.");
+ std::string text = sPlayerbotTextMgr->GetBotTextOrDefault(
+ "pet_target_dead_error", "Target is not alive.", {});
+ botAI->TellError(text);
return false;
}
if (!bot->IsValidAttackTarget(targetUnit))
{
- botAI->TellError("Target is not a valid attack target for the bot.");
+ std::string text = sPlayerbotTextMgr->GetBotTextOrDefault(
+ "pet_invalid_target_error", "Target is not a valid attack target for the bot.", {});
+ botAI->TellError(text);
+ return false;
+ }
+ if (sPlayerbotAIConfig->IsPvpProhibited(bot->GetZoneId(), bot->GetAreaId())
+ && (targetUnit->IsPlayer() || targetUnit->IsPet()))
+ {
+ std::string text = sPlayerbotTextMgr->GetBotTextOrDefault(
+ "pet_pvp_prohibited_error", "I cannot command my pet to attack players in PvP prohibited areas.", {});
+ botAI->TellError(text);
return false;
}
if (sPlayerbotAIConfig->IsPvpProhibited(bot->GetZoneId(), bot->GetAreaId(), bot)
@@ -188,9 +218,17 @@ bool PetsAction::Execute(Event event)
}
// Inform the master if the command succeeded or failed.
if (didAttack && sPlayerbotAIConfig->petChatCommandDebug == 1)
- botAI->TellMaster("Pet commanded to attack your target.");
+ {
+ std::string text = sPlayerbotTextMgr->GetBotTextOrDefault(
+ "pet_attack_success", "Pet commanded to attack your target.", {});
+ botAI->TellMaster(text);
+ }
else if (!didAttack)
- botAI->TellError("Pet did not attack. (Already attacking or unable to attack target)");
+ {
+ std::string text = sPlayerbotTextMgr->GetBotTextOrDefault(
+ "pet_attack_failed", "Pet did not attack. (Already attacking or unable to attack target)", {});
+ botAI->TellError(text);
+ }
return didAttack;
}
// The "follow" command makes all pets/guardians follow the bot.
@@ -198,7 +236,11 @@ bool PetsAction::Execute(Event event)
{
botAI->PetFollow();
if (sPlayerbotAIConfig->petChatCommandDebug == 1)
- botAI->TellMaster("Pet commanded to follow.");
+ {
+ std::string text = sPlayerbotTextMgr->GetBotTextOrDefault(
+ "pet_follow_success", "Pet commanded to follow.", {});
+ botAI->TellMaster(text);
+ }
return true;
}
// The "stay" command causes all pets/guardians to stop and stay in place.
@@ -235,14 +277,20 @@ bool PetsAction::Execute(Event event)
}
}
if (sPlayerbotAIConfig->petChatCommandDebug == 1)
- botAI->TellMaster("Pet commanded to stay.");
+ {
+ std::string text = sPlayerbotTextMgr->GetBotTextOrDefault(
+ "pet_stay_success", "Pet commanded to stay.", {});
+ botAI->TellMaster(text);
+ }
return true;
}
// Unknown command: show usage instructions and return.
else
{
- botAI->TellError("Unknown pet command: " + param +
- ". Use: pet ");
+ std::string text = sPlayerbotTextMgr->GetBotTextOrDefault(
+ "pet_unknown_command_error", "Unknown pet command: %param. Use: pet ",
+ {{"param", param}});
+ botAI->TellError(text);
return false;
}
@@ -257,7 +305,12 @@ bool PetsAction::Execute(Event event)
// Inform the master of the new stance if debug is enabled.
if (sPlayerbotAIConfig->petChatCommandDebug == 1)
- botAI->TellMaster("Pet stance set to " + stanceText + ".");
+ {
+ std::string text = sPlayerbotTextMgr->GetBotTextOrDefault(
+ "pet_stance_set_success", "Pet stance set to %stance.",
+ {{"stance", stanceText}});
+ botAI->TellMaster(text);
+ }
return true;
-}
+}
\ No newline at end of file
diff --git a/src/strategy/actions/QuestAction.cpp b/src/strategy/actions/QuestAction.cpp
index 39e8e1ba68..b96c539475 100644
--- a/src/strategy/actions/QuestAction.cpp
+++ b/src/strategy/actions/QuestAction.cpp
@@ -48,7 +48,7 @@ bool QuestAction::Execute(Event event)
// Check the nearest NPCs
GuidVector npcs = AI_VALUE(GuidVector, "nearest npcs");
- for (const auto& npc : npcs)
+ for (auto const& npc : npcs)
{
Unit* unit = botAI->GetUnit(npc);
if (unit && bot->GetDistance(unit) <= INTERACTION_DISTANCE)
@@ -59,7 +59,7 @@ bool QuestAction::Execute(Event event)
// Checks the nearest game objects
GuidVector gos = AI_VALUE(GuidVector, "nearest game objects");
- for (const auto& go : gos)
+ for (auto const& go : gos)
{
GameObject* gameobj = botAI->GetGameObject(go);
if (gameobj && bot->GetDistance(gameobj) <= INTERACTION_DISTANCE)
@@ -359,7 +359,7 @@ bool QuestUpdateAddItemAction::Execute(Event event)
uint32 availableItemsCount = botAI->GetInventoryItemsCountWithId(itemId);
placeholders["%quest_obj_available"] = std::to_string(availableItemsCount);
- for (const auto& pair : botAI->GetCurrentQuestsRequiringItemId(itemId))
+ for (auto const& pair : botAI->GetCurrentQuestsRequiringItemId(itemId))
{
placeholders["%quest_link"] = chat->FormatQuest(pair.first);
uint32 requiredItemsCount = pair.second;
diff --git a/src/strategy/actions/QuestAction.h b/src/strategy/actions/QuestAction.h
index b9ca10e54b..c19faf9ece 100644
--- a/src/strategy/actions/QuestAction.h
+++ b/src/strategy/actions/QuestAction.h
@@ -49,7 +49,7 @@ class QuestUpdateAddItemAction : public Action
{
public:
QuestUpdateAddItemAction(PlayerbotAI* ai) : Action(ai, "quest update add item") {}
- bool Execute(Event event) override;;
+ bool Execute(Event event) override;
};
class QuestUpdateFailedAction : public Action
@@ -70,7 +70,7 @@ class QuestItemPushResultAction : public Action
{
public:
QuestItemPushResultAction(PlayerbotAI* ai) : Action(ai, "quest item push result") {}
- bool Execute(Event event) override;;
+ bool Execute(Event event) override;
};
#endif
diff --git a/src/strategy/actions/RandomBotUpdateAction.cpp b/src/strategy/actions/RandomBotUpdateAction.cpp
index 1536cd6b92..61a8360e59 100644
--- a/src/strategy/actions/RandomBotUpdateAction.cpp
+++ b/src/strategy/actions/RandomBotUpdateAction.cpp
@@ -13,10 +13,10 @@ bool RandomBotUpdateAction::Execute(Event event)
if (!sRandomPlayerbotMgr->IsRandomBot(bot))
return false;
- if (bot->GetGroup() && botAI->GetGroupMaster())
+ if (bot->GetGroup() && botAI->GetGroupLeader())
{
- PlayerbotAI* groupMasterBotAI = GET_PLAYERBOT_AI(botAI->GetGroupMaster());
- if (!groupMasterBotAI || groupMasterBotAI->IsRealPlayer())
+ PlayerbotAI* groupLeaderBotAI = GET_PLAYERBOT_AI(botAI->GetGroupLeader());
+ if (!groupLeaderBotAI || groupLeaderBotAI->IsRealPlayer())
return true;
}
diff --git a/src/strategy/actions/ReleaseSpiritAction.cpp b/src/strategy/actions/ReleaseSpiritAction.cpp
index 666e42aba3..17fcc42a0b 100644
--- a/src/strategy/actions/ReleaseSpiritAction.cpp
+++ b/src/strategy/actions/ReleaseSpiritAction.cpp
@@ -128,7 +128,7 @@ bool AutoReleaseSpiritAction::HandleBattlegroundSpiritHealer()
GuidVector npcs = NearestNpcsValue(botAI, bgRange);
Unit* spiritHealer = nullptr;
- for (const auto& guid : npcs)
+ for (auto const& guid : npcs)
{
Unit* unit = botAI->GetUnit(guid);
if (unit && unit->IsFriendlyTo(bot) && unit->IsSpiritService())
@@ -168,15 +168,15 @@ bool AutoReleaseSpiritAction::ShouldAutoRelease() const
if (!bot->GetGroup())
return true;
- Player* groupMaster = botAI->GetGroupMaster();
- if (!groupMaster || groupMaster == bot)
+ Player* groupLeader = botAI->GetGroupLeader();
+ if (!groupLeader || groupLeader == bot)
return true;
if (!botAI->HasActivePlayerMaster())
return true;
if (botAI->HasActivePlayerMaster() &&
- groupMaster->GetMapId() == bot->GetMapId() &&
+ groupLeader->GetMapId() == bot->GetMapId() &&
bot->GetMap() &&
(bot->GetMap()->IsRaid() || bot->GetMap()->IsDungeon()))
{
@@ -184,7 +184,7 @@ bool AutoReleaseSpiritAction::ShouldAutoRelease() const
}
return sServerFacade->IsDistanceGreaterThan(
- AI_VALUE2(float, "distance", "master target"),
+ AI_VALUE2(float, "distance", "group leader"),
sPlayerbotAIConfig->sightDistance);
}
diff --git a/src/strategy/actions/ResetInstancesAction.cpp b/src/strategy/actions/ResetInstancesAction.cpp
index 1c0a6f2480..cce5eef1e3 100644
--- a/src/strategy/actions/ResetInstancesAction.cpp
+++ b/src/strategy/actions/ResetInstancesAction.cpp
@@ -16,4 +16,4 @@ bool ResetInstancesAction::Execute(Event event)
return true;
}
-bool ResetInstancesAction::isUseful() { return botAI->GetGroupMaster() == bot; };
+bool ResetInstancesAction::isUseful() { return botAI->GetGroupLeader() == bot; };
diff --git a/src/strategy/actions/RevealGatheringItemAction.cpp b/src/strategy/actions/RevealGatheringItemAction.cpp
index 00f1cc1db4..9725dce5ce 100644
--- a/src/strategy/actions/RevealGatheringItemAction.cpp
+++ b/src/strategy/actions/RevealGatheringItemAction.cpp
@@ -12,24 +12,7 @@
#include "GridNotifiersImpl.h"
#include "Playerbots.h"
#include "ServerFacade.h"
-
-class AnyGameObjectInObjectRangeCheck
-{
-public:
- AnyGameObjectInObjectRangeCheck(WorldObject const* obj, float range) : i_obj(obj), i_range(range) {}
- WorldObject const& GetFocusObject() const { return *i_obj; }
- bool operator()(GameObject* go)
- {
- if (go && i_obj->IsWithinDistInMap(go, i_range) && go->isSpawned() && go->GetGOInfo())
- return true;
-
- return false;
- }
-
-private:
- WorldObject const* i_obj;
- float i_range;
-};
+#include "NearestGameObjects.h"
bool RevealGatheringItemAction::Execute(Event event)
{
diff --git a/src/strategy/actions/ReviveFromCorpseAction.cpp b/src/strategy/actions/ReviveFromCorpseAction.cpp
index 83897dc2ab..ce0b1fa05d 100644
--- a/src/strategy/actions/ReviveFromCorpseAction.cpp
+++ b/src/strategy/actions/ReviveFromCorpseAction.cpp
@@ -17,14 +17,14 @@
bool ReviveFromCorpseAction::Execute(Event event)
{
- Player* master = botAI->GetGroupMaster();
+ Player* groupLeader = botAI->GetGroupLeader();
Corpse* corpse = bot->GetCorpse();
- // follow master when master revives
+ // follow group Leader when group Leader revives
WorldPacket& p = event.getPacket();
- if (!p.empty() && p.GetOpcode() == CMSG_RECLAIM_CORPSE && master && !corpse && bot->IsAlive())
+ if (!p.empty() && p.GetOpcode() == CMSG_RECLAIM_CORPSE && groupLeader && !corpse && bot->IsAlive())
{
- if (sServerFacade->IsDistanceLessThan(AI_VALUE2(float, "distance", "master target"),
+ if (sServerFacade->IsDistanceLessThan(AI_VALUE2(float, "distance", "group leader"),
sPlayerbotAIConfig->farDistance))
{
if (!botAI->HasStrategy("follow", BOT_STATE_NON_COMBAT))
@@ -43,10 +43,10 @@ bool ReviveFromCorpseAction::Execute(Event event)
// time(nullptr))
// return false;
- if (master)
+ if (groupLeader)
{
- if (!GET_PLAYERBOT_AI(master) && master->isDead() && master->GetCorpse() &&
- sServerFacade->IsDistanceLessThan(AI_VALUE2(float, "distance", "master target"),
+ if (!GET_PLAYERBOT_AI(groupLeader) && groupLeader->isDead() && groupLeader->GetCorpse() &&
+ sServerFacade->IsDistanceLessThan(AI_VALUE2(float, "distance", "group leader"),
sPlayerbotAIConfig->farDistance))
return false;
}
@@ -79,15 +79,15 @@ bool FindCorpseAction::Execute(Event event)
if (bot->InBattleground())
return false;
- Player* master = botAI->GetGroupMaster();
+ Player* groupLeader = botAI->GetGroupLeader();
Corpse* corpse = bot->GetCorpse();
if (!corpse)
return false;
- // if (master)
+ // if (groupLeader)
// {
- // if (!GET_PLAYERBOT_AI(master) &&
- // sServerFacade->IsDistanceLessThan(AI_VALUE2(float, "distance", "master target"),
+ // if (!GET_PLAYERBOT_AI(groupLeader) &&
+ // sServerFacade->IsDistanceLessThan(AI_VALUE2(float, "distance", "group leader"),
// sPlayerbotAIConfig->farDistance)) return false;
// }
@@ -110,20 +110,20 @@ bool FindCorpseAction::Execute(Event event)
WorldPosition botPos(bot);
WorldPosition corpsePos(corpse);
WorldPosition moveToPos = corpsePos;
- WorldPosition masterPos(master);
+ WorldPosition leaderPos(groupLeader);
float reclaimDist = CORPSE_RECLAIM_RADIUS - 5.0f;
float corpseDist = botPos.distance(corpsePos);
int64 deadTime = time(nullptr) - corpse->GetGhostTime();
- bool moveToMaster = master && master != bot && masterPos.fDist(corpsePos) < reclaimDist;
+ bool moveToLeader = groupLeader && groupLeader != bot && leaderPos.fDist(corpsePos) < reclaimDist;
// Should we ressurect? If so, return false.
if (corpseDist < reclaimDist)
{
- if (moveToMaster) // We are near master.
+ if (moveToLeader) // We are near group leader.
{
- if (botPos.fDist(masterPos) < sPlayerbotAIConfig->spellDistance)
+ if (botPos.fDist(leaderPos) < sPlayerbotAIConfig->spellDistance)
return false;
}
else if (deadTime > 8 * MINUTE) // We have walked too long already.
@@ -140,8 +140,8 @@ bool FindCorpseAction::Execute(Event event)
// If we are getting close move to a save ressurrection spot instead of just the corpse.
if (corpseDist < sPlayerbotAIConfig->reactDistance)
{
- if (moveToMaster)
- moveToPos = masterPos;
+ if (moveToLeader)
+ moveToPos = leaderPos;
else
{
FleeManager manager(bot, reclaimDist, 0.0, urand(0, 1), moveToPos);
@@ -215,12 +215,12 @@ GraveyardStruct const* SpiritHealerAction::GetGrave(bool startZone)
if (!startZone && ClosestGrave)
return ClosestGrave;
- if (botAI->HasStrategy("follow", BOT_STATE_NON_COMBAT) && botAI->GetGroupMaster() && botAI->GetGroupMaster() != bot)
+ if (botAI->HasStrategy("follow", BOT_STATE_NON_COMBAT) && botAI->GetGroupLeader() && botAI->GetGroupLeader() != bot)
{
- Player* master = botAI->GetGroupMaster();
- if (master && master != bot)
+ Player* groupLeader = botAI->GetGroupLeader();
+ if (groupLeader && groupLeader != bot)
{
- ClosestGrave = sGraveyard->GetClosestGraveyard(master, bot->GetTeamId());
+ ClosestGrave = sGraveyard->GetClosestGraveyard(groupLeader, bot->GetTeamId());
if (ClosestGrave)
return ClosestGrave;
@@ -314,7 +314,7 @@ bool SpiritHealerAction::Execute(Event event)
for (GuidVector::iterator i = npcs.begin(); i != npcs.end(); i++)
{
Unit* unit = botAI->GetUnit(*i);
- if (unit && unit->HasFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_SPIRITHEALER))
+ if (unit && unit->HasNpcFlag(UNIT_NPC_FLAG_SPIRITHEALER))
{
LOG_DEBUG("playerbots", "Bot {} {}:{} <{}> revives at spirit healer", bot->GetGUID().ToString().c_str(),
bot->GetTeamId() == TEAM_ALLIANCE ? "A" : "H", bot->GetLevel(), bot->GetName());
diff --git a/src/strategy/actions/RewardAction.cpp b/src/strategy/actions/RewardAction.cpp
index 1022166d0f..8fe1c6ff72 100644
--- a/src/strategy/actions/RewardAction.cpp
+++ b/src/strategy/actions/RewardAction.cpp
@@ -35,8 +35,8 @@ bool RewardAction::Execute(Event event)
return true;
}
- Unit* mtar = AI_VALUE(Unit*, "master target");
- if (mtar && Reward(itemId, mtar))
+ Unit* groupLeaderUnit = AI_VALUE(Unit*, "group leader");
+ if (groupLeaderUnit && Reward(itemId, groupLeaderUnit))
return true;
botAI->TellError("Cannot talk to quest giver");
diff --git a/src/strategy/actions/RpgAction.cpp b/src/strategy/actions/RpgAction.cpp
index 21b68d6bf8..ae6a50fddb 100644
--- a/src/strategy/actions/RpgAction.cpp
+++ b/src/strategy/actions/RpgAction.cpp
@@ -50,7 +50,6 @@ bool RpgAction::SetNextRpgAction()
std::vector relevances;
std::vector triggerNodes;
-
for (auto& strategy : botAI->GetAiObjectContext()->GetSupportedStrategies())
{
if (strategy.find("rpg") == std::string::npos)
diff --git a/src/strategy/actions/RpgSubActions.cpp b/src/strategy/actions/RpgSubActions.cpp
index 784f6bbb20..aa4269fa92 100644
--- a/src/strategy/actions/RpgSubActions.cpp
+++ b/src/strategy/actions/RpgSubActions.cpp
@@ -76,7 +76,7 @@ void RpgHelper::setFacing(GuidPosition guidPosition)
void RpgHelper::setDelay(bool waitForGroup)
{
- if (!botAI->HasRealPlayerMaster() || (waitForGroup && botAI->GetGroupMaster() == bot && bot->GetGroup()))
+ if (!botAI->HasRealPlayerMaster() || (waitForGroup && botAI->GetGroupLeader() == bot && bot->GetGroup()))
botAI->SetNextCheckDelay(sPlayerbotAIConfig->rpgDelay);
else
botAI->SetNextCheckDelay(sPlayerbotAIConfig->rpgDelay / 5);
diff --git a/src/strategy/actions/SayAction.cpp b/src/strategy/actions/SayAction.cpp
index 474f37e4ce..00fae65293 100644
--- a/src/strategy/actions/SayAction.cpp
+++ b/src/strategy/actions/SayAction.cpp
@@ -195,7 +195,7 @@ void ChatReplyAction::ChatReplyDo(Player* bot, uint32& type, uint32& guid1, uint
}
ChatChannelSource chatChannelSource = GET_PLAYERBOT_AI(bot)->GetChatChannelSource(bot, type, chanName);
- if ( (msg.starts_with("LFG") || msg.starts_with("LFM")) && HandleLFGQuestsReply(bot, chatChannelSource, msg, name))
+ if ((msg.starts_with("LFG") || msg.starts_with("LFM")) && HandleLFGQuestsReply(bot, chatChannelSource, msg, name))
{
return;
}
diff --git a/src/strategy/actions/SecurityCheckAction.cpp b/src/strategy/actions/SecurityCheckAction.cpp
index 1320eb04a6..c47a6e52cb 100644
--- a/src/strategy/actions/SecurityCheckAction.cpp
+++ b/src/strategy/actions/SecurityCheckAction.cpp
@@ -22,8 +22,8 @@ bool SecurityCheckAction::Execute(Event event)
ItemQualities threshold = group->GetLootThreshold();
if (method == MASTER_LOOT || method == FREE_FOR_ALL || threshold > ITEM_QUALITY_UNCOMMON)
{
- if ((botAI->GetGroupMaster()->GetSession()->GetSecurity() == SEC_PLAYER) &&
- (!bot->GetGuildId() || bot->GetGuildId() != botAI->GetGroupMaster()->GetGuildId()))
+ if ((botAI->GetGroupLeader()->GetSession()->GetSecurity() == SEC_PLAYER) &&
+ (!bot->GetGuildId() || bot->GetGuildId() != botAI->GetGroupLeader()->GetGuildId()))
{
botAI->TellError("I will play with this loot type only if I'm in your guild :/");
botAI->ChangeStrategy("+passive,+stay", BOT_STATE_NON_COMBAT);
diff --git a/src/strategy/actions/SeeSpellAction.cpp b/src/strategy/actions/SeeSpellAction.cpp
index 8b90adece0..f42dcade64 100644
--- a/src/strategy/actions/SeeSpellAction.cpp
+++ b/src/strategy/actions/SeeSpellAction.cpp
@@ -12,6 +12,7 @@
#include "RTSCValues.h"
#include "RtscAction.h"
#include "PositionValue.h"
+#include "ByteBuffer.h"
Creature* SeeSpellAction::CreateWps(Player* wpOwner, float x, float y, float z, float o, uint32 entry, Creature* lastWp,
bool important)
@@ -31,27 +32,52 @@ Creature* SeeSpellAction::CreateWps(Player* wpOwner, float x, float y, float z,
bool SeeSpellAction::Execute(Event event)
{
- WorldPacket p(event.getPacket()); //
+ // RTSC packet data
+ WorldPacket p(event.getPacket());
+ uint8 castCount;
uint32 spellId;
- uint8 castCount, castFlags;
- Player* master = botAI->GetMaster();
+ uint8 castFlags;
- p.rpos(0);
- p >> castCount >> spellId >> castFlags;
+ // check RTSC header size = castCount (uint8) + spellId (uint32) + castFlags (uint8)
+ uint32 const rtscHeaderSize = sizeof(uint8) + sizeof(uint32) + sizeof(uint8);
+ if (p.size() < rtscHeaderSize)
+ {
+ LOG_WARN("playerbots", "SeeSpellAction: Corrupt RTSC packet size={}, expected>={}", p.size(), rtscHeaderSize);
+ return false;
+ }
+ Player* master = botAI->GetMaster();
if (!master)
return false;
+ // read RTSC packet data
+ p.rpos(0); // set read position to start
+ p >> castCount >> spellId >> castFlags;
+
// if (!botAI->HasStrategy("RTSC", botAI->GetState()))
// return false;
if (spellId != RTSC_MOVE_SPELL)
return false;
- SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spellId);
-
+ // should not throw exception,just defensive measure to prevent any crashes when core function breaks.
SpellCastTargets targets;
- targets.Read(p, botAI->GetMaster());
+ try
+ {
+ targets.Read(p, master);
+ if (!targets.GetDst())
+ {
+ // do not dereference a null destination; ignore malformed RTSC packets instead of crashing
+ LOG_WARN("playerbots", "SeeSpellAction: (malformed) RTSC payload does not contain full targets data");
+ return false;
+ }
+ }
+ catch (ByteBufferException const&)
+ {
+ // ignore malformed RTSC packets instead of crashing
+ LOG_WARN("playerbots", "SeeSpellAction: Failed deserialization (malformed) RTSC payload");
+ return false;
+ }
WorldPosition spellPosition(master->GetMapId(), targets.GetDst()->_position);
SET_AI_VALUE(WorldPosition, "see spell location", spellPosition);
diff --git a/src/strategy/actions/SetHomeAction.cpp b/src/strategy/actions/SetHomeAction.cpp
index 36893f4a8c..44f3c7b49f 100644
--- a/src/strategy/actions/SetHomeAction.cpp
+++ b/src/strategy/actions/SetHomeAction.cpp
@@ -24,7 +24,7 @@ bool SetHomeAction::Execute(Event event)
}
if (Unit* unit = botAI->GetUnit(selection))
- if (unit->HasFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_INNKEEPER))
+ if (unit->HasNpcFlag(UNIT_NPC_FLAG_INNKEEPER))
{
if (isRpgAction)
{
diff --git a/src/strategy/actions/SuggestWhatToDoAction.cpp b/src/strategy/actions/SuggestWhatToDoAction.cpp
index 468b1f5077..96cc7f52ac 100644
--- a/src/strategy/actions/SuggestWhatToDoAction.cpp
+++ b/src/strategy/actions/SuggestWhatToDoAction.cpp
@@ -120,7 +120,8 @@ void SuggestWhatToDoAction::grindMaterials()
for (std::map::iterator i = categories.begin(); i != categories.end(); ++i)
{
- if (urand(0, 10) < 3) {
+ if (urand(0, 10) < 3)
+ {
std::string name = i->first;
double multiplier = i->second;
diff --git a/src/strategy/actions/TameAction.cpp b/src/strategy/actions/TameAction.cpp
index b414b47806..5b3eda1034 100644
--- a/src/strategy/actions/TameAction.cpp
+++ b/src/strategy/actions/TameAction.cpp
@@ -81,7 +81,7 @@ bool TameAction::Execute(Event event)
std::ostringstream oss;
oss << "Available pet families: ";
size_t count = 0;
- for (const auto& name : normalFamilies)
+ for (auto const& name : normalFamilies)
{
if (count++ != 0)
oss << ", ";
@@ -93,7 +93,7 @@ bool TameAction::Execute(Event event)
oss << " | ";
oss << "Exotic: ";
count = 0;
- for (const auto& name : exoticFamilies)
+ for (auto const& name : exoticFamilies)
{
if (count++ != 0)
oss << ", ";
diff --git a/src/strategy/actions/TellGlyphsAction.h b/src/strategy/actions/TellGlyphsAction.h
index 6f3e0dace3..77bb5b1ca5 100644
--- a/src/strategy/actions/TellGlyphsAction.h
+++ b/src/strategy/actions/TellGlyphsAction.h
@@ -18,4 +18,3 @@ class TellGlyphsAction : public Action
};
#endif
-
diff --git a/src/strategy/actions/TellMasterAction.cpp b/src/strategy/actions/TellMasterAction.cpp
index 701f93d773..4b8d96d561 100644
--- a/src/strategy/actions/TellMasterAction.cpp
+++ b/src/strategy/actions/TellMasterAction.cpp
@@ -22,7 +22,7 @@ bool OutOfReactRangeAction::Execute(Event event)
bool OutOfReactRangeAction::isUseful()
{
- bool canFollow = Follow(AI_VALUE(Unit*, "master target"));
+ bool canFollow = Follow(AI_VALUE(Unit*, "group leader"));
if (!canFollow)
{
return false;
diff --git a/src/strategy/actions/TradeAction.cpp b/src/strategy/actions/TradeAction.cpp
index 9ac7aca2be..ad81d9f93b 100644
--- a/src/strategy/actions/TradeAction.cpp
+++ b/src/strategy/actions/TradeAction.cpp
@@ -15,7 +15,7 @@ bool TradeAction::Execute(Event event)
std::string const text = event.getParam();
// If text starts with any excluded prefix, don't process it further.
- for (const auto& prefix : sPlayerbotAIConfig->tradeActionExcludedPrefixes)
+ for (auto const& prefix : sPlayerbotAIConfig->tradeActionExcludedPrefixes)
{
if (text.find(prefix) == 0)
return false;
diff --git a/src/strategy/actions/TrainerAction.cpp b/src/strategy/actions/TrainerAction.cpp
index c5509cf8b8..e2e89115b9 100644
--- a/src/strategy/actions/TrainerAction.cpp
+++ b/src/strategy/actions/TrainerAction.cpp
@@ -172,7 +172,7 @@ bool MaintenanceAction::Execute(Event event)
PlayerbotFactory factory(bot, bot->GetLevel());
if (!botAI->IsAlt())
- {
+ {
factory.InitAttunementQuests();
factory.InitBags(false);
factory.InitAmmo();
@@ -194,7 +194,7 @@ bool MaintenanceAction::Execute(Event event)
if (bot->GetLevel() >= sPlayerbotAIConfig->minEnchantingBotLevel)
factory.ApplyEnchantAndGemsNew();
}
- else
+ else
{
if (sPlayerbotAIConfig->altMaintenanceAttunementQs)
factory.InitAttunementQuests();
diff --git a/src/strategy/actions/TravelAction.cpp b/src/strategy/actions/TravelAction.cpp
index 5804fd7d24..f99f8b29d3 100644
--- a/src/strategy/actions/TravelAction.cpp
+++ b/src/strategy/actions/TravelAction.cpp
@@ -64,7 +64,7 @@ bool MoveToDarkPortalAction::Execute(Event event)
{
if (bot->GetGroup())
if (bot->GetGroup()->GetLeaderGUID() != bot->GetGUID() &&
- !GET_PLAYERBOT_AI(GET_PLAYERBOT_AI(bot)->GetGroupMaster()))
+ !GET_PLAYERBOT_AI(GET_PLAYERBOT_AI(bot)->GetGroupLeader()))
return false;
if (bot->GetLevel() > 57)
diff --git a/src/strategy/actions/UseMeetingStoneAction.cpp b/src/strategy/actions/UseMeetingStoneAction.cpp
index 24d58aff30..6e902730b8 100644
--- a/src/strategy/actions/UseMeetingStoneAction.cpp
+++ b/src/strategy/actions/UseMeetingStoneAction.cpp
@@ -9,6 +9,7 @@
#include "Event.h"
#include "GridNotifiers.h"
#include "GridNotifiersImpl.h"
+#include "NearestGameObjects.h"
#include "PlayerbotAIConfig.h"
#include "Playerbots.h"
#include "PositionValue.h"
@@ -54,24 +55,6 @@ bool UseMeetingStoneAction::Execute(Event event)
return Teleport(master, bot);
}
-class AnyGameObjectInObjectRangeCheck
-{
-public:
- AnyGameObjectInObjectRangeCheck(WorldObject const* obj, float range) : i_obj(obj), i_range(range) {}
- WorldObject const& GetFocusObject() const { return *i_obj; }
- bool operator()(GameObject* go)
- {
- if (go && i_obj->IsWithinDistInMap(go, i_range) && go->isSpawned() && go->GetGOInfo())
- return true;
-
- return false;
- }
-
-private:
- WorldObject const* i_obj;
- float i_range;
-};
-
bool SummonAction::Execute(Event event)
{
Player* master = GetMaster();
@@ -134,7 +117,7 @@ bool SummonAction::SummonUsingNpcs(Player* summoner, Player* player)
for (Unit* unit : targets)
{
- if (unit && unit->HasFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_INNKEEPER))
+ if (unit && unit->HasNpcFlag(UNIT_NPC_FLAG_INNKEEPER))
{
if (!player->HasItemCount(6948, 1, false))
{
@@ -242,7 +225,7 @@ bool SummonAction::Teleport(Player* summoner, Player* player)
}
}
- if(summoner != player)
+ if (summoner != player)
botAI->TellError("Not enough place to summon");
return false;
}
diff --git a/src/strategy/actions/WorldBuffAction.cpp b/src/strategy/actions/WorldBuffAction.cpp
index b47083850a..3cd770e4d0 100644
--- a/src/strategy/actions/WorldBuffAction.cpp
+++ b/src/strategy/actions/WorldBuffAction.cpp
@@ -97,4 +97,3 @@ std::vector WorldBuffAction::NeedWorldBuffs(Unit* unit)
return retVec;
}
-
diff --git a/src/strategy/actions/XpGainAction.cpp b/src/strategy/actions/XpGainAction.cpp
index 446be3bb6d..4048ce3af8 100644
--- a/src/strategy/actions/XpGainAction.cpp
+++ b/src/strategy/actions/XpGainAction.cpp
@@ -15,7 +15,6 @@ bool XpGainAction::Execute(Event event)
{
context->GetValue("death count")->Set(0);
-
WorldPacket p(event.getPacket()); // (8+4+1+4+8)
ObjectGuid guid;
// uint32 xpgain;
diff --git a/src/strategy/deathknight/DKActions.cpp b/src/strategy/deathknight/DKActions.cpp
index 5206103617..2b5ce97706 100644
--- a/src/strategy/deathknight/DKActions.cpp
+++ b/src/strategy/deathknight/DKActions.cpp
@@ -43,7 +43,7 @@ bool CastRaiseDeadAction::Execute(Event event)
return false;
}
uint32 spellId = AI_VALUE2(uint32, "spell id", spell);
- // const SpellInfo *spellInfo = sSpellMgr->GetSpellInfo(spellId);
+ // SpellInfo const *spellInfo = sSpellMgr->GetSpellInfo(spellId);
bot->AddSpellCooldown(spellId, 0, 3 * 60 * 1000);
return true;
-}
\ No newline at end of file
+}
diff --git a/src/strategy/druid/DruidActions.cpp b/src/strategy/druid/DruidActions.cpp
index b5a493dbb5..217db82508 100644
--- a/src/strategy/druid/DruidActions.cpp
+++ b/src/strategy/druid/DruidActions.cpp
@@ -7,6 +7,9 @@
#include "Event.h"
#include "Playerbots.h"
+#include "ServerFacade.h"
+#include "AoeValues.h"
+#include "TargetValue.h"
NextAction** CastAbolishPoisonAction::getAlternatives()
{
@@ -30,6 +33,32 @@ bool CastEntanglingRootsCcAction::Execute(Event event) { return botAI->CastSpell
Value* CastHibernateCcAction::GetTargetValue() { return context->GetValue("cc target", "hibernate"); }
bool CastHibernateCcAction::Execute(Event event) { return botAI->CastSpell("hibernate", GetTarget()); }
+bool CastStarfallAction::isUseful()
+{
+ if (!CastSpellAction::isUseful())
+ return false;
+
+ // Avoid breaking CC
+ WorldLocation aoePos = *context->GetValue("aoe position");
+ Unit* ccTarget = context->GetValue("current cc target")->Get();
+ if (ccTarget && ccTarget->IsAlive())
+ {
+ float dist2d = sServerFacade->GetDistance2d(ccTarget, aoePos.GetPositionX(), aoePos.GetPositionY());
+ if (sServerFacade->IsDistanceLessOrEqualThan(dist2d, sPlayerbotAIConfig->aoeRadius))
+ return false;
+ }
+
+ // Avoid single-target usage on initial pull
+ uint8 aoeCount = *context->GetValue("aoe count");
+ if (aoeCount < 2)
+ {
+ Unit* target = context->GetValue("current target")->Get();
+ if (!target || (!botAI->HasAura("moonfire", target) && !botAI->HasAura("insect swarm", target)))
+ return false;
+ }
+
+ return true;
+}
NextAction** CastReviveAction::getPrerequisites()
{
diff --git a/src/strategy/druid/DruidActions.h b/src/strategy/druid/DruidActions.h
index f7a4ef32ce..d0af6e5a49 100644
--- a/src/strategy/druid/DruidActions.h
+++ b/src/strategy/druid/DruidActions.h
@@ -144,6 +144,8 @@ class CastStarfallAction : public CastSpellAction
{
public:
CastStarfallAction(PlayerbotAI* botAI) : CastSpellAction(botAI, "starfall") {}
+
+ bool isUseful() override;
};
class CastHurricaneAction : public CastSpellAction
@@ -311,7 +313,6 @@ class CastEnrageAction : public CastBuffSpellAction
CastEnrageAction(PlayerbotAI* ai) : CastBuffSpellAction(ai, "enrage") {}
};
-
class CastRejuvenationOnNotFullAction : public HealPartyMemberAction
{
public:
diff --git a/src/strategy/dungeons/DungeonStrategyContext.h b/src/strategy/dungeons/DungeonStrategyContext.h
index ce982b148f..cc606afef8 100644
--- a/src/strategy/dungeons/DungeonStrategyContext.h
+++ b/src/strategy/dungeons/DungeonStrategyContext.h
@@ -35,8 +35,6 @@ Bronjahm, Devourer of Souls
*/
-
-
class DungeonStrategyContext : public NamedObjectContext
{
public:
@@ -84,8 +82,6 @@ class DungeonStrategyContext : public NamedObjectContext
static Strategy* wotlk_toc(PlayerbotAI* botAI) { return new WotlkDungeonToCStrategy(botAI); }
// NYI from here down
static Strategy* wotlk_hor(PlayerbotAI* botAI) { return new WotlkDungeonUKStrategy(botAI); }
-
-
};
#endif
diff --git a/src/strategy/dungeons/wotlk/WotlkDungeonTriggerContext.h b/src/strategy/dungeons/wotlk/WotlkDungeonTriggerContext.h
index 057d25e020..1a3d7a94a3 100644
--- a/src/strategy/dungeons/wotlk/WotlkDungeonTriggerContext.h
+++ b/src/strategy/dungeons/wotlk/WotlkDungeonTriggerContext.h
@@ -18,5 +18,4 @@
#include "trialofthechampion/TrialOfTheChampionTriggerContext.h"
// #include "hallsofreflection/HallsOfReflectionTriggerContext.h"
-
#endif
diff --git a/src/strategy/dungeons/wotlk/azjolnerub/AzjolNerubActions.cpp b/src/strategy/dungeons/wotlk/azjolnerub/AzjolNerubActions.cpp
index 2b7e7c9f13..e31ffd00f5 100644
--- a/src/strategy/dungeons/wotlk/azjolnerub/AzjolNerubActions.cpp
+++ b/src/strategy/dungeons/wotlk/azjolnerub/AzjolNerubActions.cpp
@@ -2,7 +2,6 @@
#include "AzjolNerubActions.h"
#include "AzjolNerubStrategy.h"
-
bool AttackWebWrapAction::isUseful() { return !botAI->IsHeal(bot); }
bool AttackWebWrapAction::Execute(Event event)
{
diff --git a/src/strategy/dungeons/wotlk/azjolnerub/AzjolNerubStrategy.cpp b/src/strategy/dungeons/wotlk/azjolnerub/AzjolNerubStrategy.cpp
index dcefbae507..1a30e98ce8 100644
--- a/src/strategy/dungeons/wotlk/azjolnerub/AzjolNerubStrategy.cpp
+++ b/src/strategy/dungeons/wotlk/azjolnerub/AzjolNerubStrategy.cpp
@@ -1,7 +1,6 @@
#include "AzjolNerubStrategy.h"
#include "AzjolNerubMultipliers.h"
-
void WotlkDungeonANStrategy::InitTriggers(std::vector &triggers)
{
// Krik'thir the Gatewatcher
diff --git a/src/strategy/dungeons/wotlk/azjolnerub/AzjolNerubStrategy.h b/src/strategy/dungeons/wotlk/azjolnerub/AzjolNerubStrategy.h
index bf5a7917a2..70196e6e41 100644
--- a/src/strategy/dungeons/wotlk/azjolnerub/AzjolNerubStrategy.h
+++ b/src/strategy/dungeons/wotlk/azjolnerub/AzjolNerubStrategy.h
@@ -5,7 +5,6 @@
#include "AiObjectContext.h"
#include "Strategy.h"
-
class WotlkDungeonANStrategy : public Strategy
{
public:
diff --git a/src/strategy/dungeons/wotlk/azjolnerub/AzjolNerubTriggers.cpp b/src/strategy/dungeons/wotlk/azjolnerub/AzjolNerubTriggers.cpp
index df52374c4d..f9ef4ff953 100644
--- a/src/strategy/dungeons/wotlk/azjolnerub/AzjolNerubTriggers.cpp
+++ b/src/strategy/dungeons/wotlk/azjolnerub/AzjolNerubTriggers.cpp
@@ -3,7 +3,6 @@
#include "AiObject.h"
#include "AiObjectContext.h"
-
bool KrikthirWebWrapTrigger::IsActive()
{
if (!botAI->IsDps(bot)) { return false; }
diff --git a/src/strategy/dungeons/wotlk/cullingofstratholme/CullingOfStratholmeActions.cpp b/src/strategy/dungeons/wotlk/cullingofstratholme/CullingOfStratholmeActions.cpp
index dd857569a0..15121f4a2e 100644
--- a/src/strategy/dungeons/wotlk/cullingofstratholme/CullingOfStratholmeActions.cpp
+++ b/src/strategy/dungeons/wotlk/cullingofstratholme/CullingOfStratholmeActions.cpp
@@ -2,7 +2,6 @@
#include "CullingOfStratholmeActions.h"
#include "CullingOfStratholmeStrategy.h"
-
bool ExplodeGhoulSpreadAction::Execute(Event event)
{
Unit* boss = AI_VALUE2(Unit*, "find target", "salramm the fleshcrafter");
@@ -32,7 +31,7 @@ bool EpochStackAction::isUseful()
// Hunter bots will try and melee in between ranged attacks, or just melee entirely at 5 as they are in range.
// 7.5 or 8.0 solves this for this boss.
// Unfortunately at this range the boss will charge. So I guess just don't stack as a hunter..
- // if(bot->getClass() == CLASS_HUNTER)
+ // if (bot->getClass() == CLASS_HUNTER)
// {
// return AI_VALUE2(float, "distance", "current target") > 7.5f;
// }
@@ -45,7 +44,7 @@ bool EpochStackAction::Execute(Event event)
if (!boss) { return false; }
float maxMovement = 10.0f;
- // if(bot->getClass() == CLASS_HUNTER)
+ // if (bot->getClass() == CLASS_HUNTER)
// {
// return Move(bot->GetAngle(boss), fmin(bot->GetExactDist2d(boss) - 6.5f, maxMovement));
// }
diff --git a/src/strategy/dungeons/wotlk/cullingofstratholme/CullingOfStratholmeStrategy.cpp b/src/strategy/dungeons/wotlk/cullingofstratholme/CullingOfStratholmeStrategy.cpp
index b9081ba82c..e9011ee7ff 100644
--- a/src/strategy/dungeons/wotlk/cullingofstratholme/CullingOfStratholmeStrategy.cpp
+++ b/src/strategy/dungeons/wotlk/cullingofstratholme/CullingOfStratholmeStrategy.cpp
@@ -1,7 +1,6 @@
#include "CullingOfStratholmeStrategy.h"
#include "CullingOfStratholmeMultipliers.h"
-
void WotlkDungeonCoSStrategy::InitTriggers(std::vector &triggers)
{
// Meathook
diff --git a/src/strategy/dungeons/wotlk/cullingofstratholme/CullingOfStratholmeStrategy.h b/src/strategy/dungeons/wotlk/cullingofstratholme/CullingOfStratholmeStrategy.h
index 9c687da9c5..bff1267435 100644
--- a/src/strategy/dungeons/wotlk/cullingofstratholme/CullingOfStratholmeStrategy.h
+++ b/src/strategy/dungeons/wotlk/cullingofstratholme/CullingOfStratholmeStrategy.h
@@ -5,7 +5,6 @@
#include "AiObjectContext.h"
#include "Strategy.h"
-
class WotlkDungeonCoSStrategy : public Strategy
{
public:
diff --git a/src/strategy/dungeons/wotlk/cullingofstratholme/CullingOfStratholmeTriggers.cpp b/src/strategy/dungeons/wotlk/cullingofstratholme/CullingOfStratholmeTriggers.cpp
index a2b7dc11cc..cb67ad077f 100644
--- a/src/strategy/dungeons/wotlk/cullingofstratholme/CullingOfStratholmeTriggers.cpp
+++ b/src/strategy/dungeons/wotlk/cullingofstratholme/CullingOfStratholmeTriggers.cpp
@@ -3,7 +3,6 @@
#include "AiObject.h"
#include "AiObjectContext.h"
-
bool ExplodeGhoulTrigger::IsActive()
{
Unit* boss = AI_VALUE2(Unit*, "find target", "salramm the fleshcrafter");
diff --git a/src/strategy/dungeons/wotlk/draktharonkeep/DrakTharonKeepActions.cpp b/src/strategy/dungeons/wotlk/draktharonkeep/DrakTharonKeepActions.cpp
index 0ab72c1bb0..8cbbe49c2a 100644
--- a/src/strategy/dungeons/wotlk/draktharonkeep/DrakTharonKeepActions.cpp
+++ b/src/strategy/dungeons/wotlk/draktharonkeep/DrakTharonKeepActions.cpp
@@ -2,7 +2,6 @@
#include "DrakTharonKeepActions.h"
#include "DrakTharonKeepStrategy.h"
-
bool CorpseExplodeSpreadAction::Execute(Event event)
{
Unit* boss = AI_VALUE2(Unit*, "find target", "trollgore");
diff --git a/src/strategy/dungeons/wotlk/draktharonkeep/DrakTharonKeepStrategy.cpp b/src/strategy/dungeons/wotlk/draktharonkeep/DrakTharonKeepStrategy.cpp
index 4166f2f5b3..a32d523135 100644
--- a/src/strategy/dungeons/wotlk/draktharonkeep/DrakTharonKeepStrategy.cpp
+++ b/src/strategy/dungeons/wotlk/draktharonkeep/DrakTharonKeepStrategy.cpp
@@ -1,7 +1,6 @@
#include "DrakTharonKeepStrategy.h"
#include "DrakTharonKeepMultipliers.h"
-
void WotlkDungeonDTKStrategy::InitTriggers(std::vector &triggers)
{
// Trollgore
diff --git a/src/strategy/dungeons/wotlk/draktharonkeep/DrakTharonKeepStrategy.h b/src/strategy/dungeons/wotlk/draktharonkeep/DrakTharonKeepStrategy.h
index b819ad3809..41ef0ced6f 100644
--- a/src/strategy/dungeons/wotlk/draktharonkeep/DrakTharonKeepStrategy.h
+++ b/src/strategy/dungeons/wotlk/draktharonkeep/DrakTharonKeepStrategy.h
@@ -5,7 +5,6 @@
#include "AiObjectContext.h"
#include "Strategy.h"
-
class WotlkDungeonDTKStrategy : public Strategy
{
public:
diff --git a/src/strategy/dungeons/wotlk/draktharonkeep/DrakTharonKeepTriggers.cpp b/src/strategy/dungeons/wotlk/draktharonkeep/DrakTharonKeepTriggers.cpp
index 9ed4b19121..406f4d4333 100644
--- a/src/strategy/dungeons/wotlk/draktharonkeep/DrakTharonKeepTriggers.cpp
+++ b/src/strategy/dungeons/wotlk/draktharonkeep/DrakTharonKeepTriggers.cpp
@@ -3,7 +3,6 @@
#include "AiObject.h"
#include "AiObjectContext.h"
-
bool CorpseExplodeTrigger::IsActive()
{
Unit* boss = AI_VALUE2(Unit*, "find target", "trollgore");
diff --git a/src/strategy/dungeons/wotlk/forgeofsouls/ForgeOfSoulsActions.cpp b/src/strategy/dungeons/wotlk/forgeofsouls/ForgeOfSoulsActions.cpp
index 3bd21f34d1..e72fe98d5f 100644
--- a/src/strategy/dungeons/wotlk/forgeofsouls/ForgeOfSoulsActions.cpp
+++ b/src/strategy/dungeons/wotlk/forgeofsouls/ForgeOfSoulsActions.cpp
@@ -17,7 +17,6 @@ bool MoveFromBronjahmAction::Execute(Event event)
return false;
}
-
bool AttackCorruptedSoulFragmentAction::Execute(Event event)
{
Unit* currentTarget = AI_VALUE(Unit*, "current target");
@@ -52,7 +51,6 @@ bool AttackCorruptedSoulFragmentAction::Execute(Event event)
return false;
}
-
bool BronjahmGroupPositionAction::Execute(Event event)
{
Unit* boss = AI_VALUE2(Unit*, "find target", "bronjahm");
@@ -165,5 +163,3 @@ bool DevourerOfSoulsAction::Execute(Event event)
return false;
}
-
-
diff --git a/src/strategy/dungeons/wotlk/forgeofsouls/ForgeOfSoulsMultipliers.cpp b/src/strategy/dungeons/wotlk/forgeofsouls/ForgeOfSoulsMultipliers.cpp
index 7ddcffb86d..7873e7c1d1 100644
--- a/src/strategy/dungeons/wotlk/forgeofsouls/ForgeOfSoulsMultipliers.cpp
+++ b/src/strategy/dungeons/wotlk/forgeofsouls/ForgeOfSoulsMultipliers.cpp
@@ -6,7 +6,6 @@
#include "ForgeOfSoulsTriggers.h"
#include "ForgeOfSoulsActions.h"
-
float BronjahmMultiplier::GetValue(Action* action) {
Unit* boss = AI_VALUE2(Unit *, "find target", "bronjahm");
if (!boss)
diff --git a/src/strategy/dungeons/wotlk/forgeofsouls/ForgeOfSoulsMultipliers.h b/src/strategy/dungeons/wotlk/forgeofsouls/ForgeOfSoulsMultipliers.h
index 99d7e47b64..1c89bb096b 100644
--- a/src/strategy/dungeons/wotlk/forgeofsouls/ForgeOfSoulsMultipliers.h
+++ b/src/strategy/dungeons/wotlk/forgeofsouls/ForgeOfSoulsMultipliers.h
@@ -20,5 +20,4 @@ class AttackFragmentMultiplier : public Multiplier
float GetValue(Action* action) override;
};
-
#endif
diff --git a/src/strategy/dungeons/wotlk/gundrak/GundrakStrategy.cpp b/src/strategy/dungeons/wotlk/gundrak/GundrakStrategy.cpp
index ac7b909d2d..8c5612dc65 100644
--- a/src/strategy/dungeons/wotlk/gundrak/GundrakStrategy.cpp
+++ b/src/strategy/dungeons/wotlk/gundrak/GundrakStrategy.cpp
@@ -1,7 +1,6 @@
#include "GundrakStrategy.h"
#include "GundrakMultipliers.h"
-
void WotlkDungeonGDStrategy::InitTriggers(std::vector &triggers)
{
// Moorabi
diff --git a/src/strategy/dungeons/wotlk/gundrak/GundrakStrategy.h b/src/strategy/dungeons/wotlk/gundrak/GundrakStrategy.h
index c7910c1ca1..47f8617f17 100644
--- a/src/strategy/dungeons/wotlk/gundrak/GundrakStrategy.h
+++ b/src/strategy/dungeons/wotlk/gundrak/GundrakStrategy.h
@@ -5,7 +5,6 @@
#include "AiObjectContext.h"
#include "Strategy.h"
-
class WotlkDungeonGDStrategy : public Strategy
{
public:
diff --git a/src/strategy/dungeons/wotlk/hallsoflightning/HallsOfLightningActions.cpp b/src/strategy/dungeons/wotlk/hallsoflightning/HallsOfLightningActions.cpp
index a31699f806..047e0aee13 100644
--- a/src/strategy/dungeons/wotlk/hallsoflightning/HallsOfLightningActions.cpp
+++ b/src/strategy/dungeons/wotlk/hallsoflightning/HallsOfLightningActions.cpp
@@ -126,7 +126,7 @@ bool LokenStackAction::isUseful()
// Minimum hunter range is 5, but values too close to this seem to cause issues..
// Hunter bots will try and melee in between ranged attacks, or just melee entirely at 5 as they are in range.
// 6.5 or 7.0 solves this for this boss.
- if(bot->getClass() == CLASS_HUNTER)
+ if (bot->getClass() == CLASS_HUNTER)
{
return AI_VALUE2(float, "distance", "current target") > 6.5f;
}
@@ -141,7 +141,7 @@ bool LokenStackAction::Execute(Event event)
float maxMovement = 10.0f;
if (!boss->HasUnitState(UNIT_STATE_CASTING))
{
- if(bot->getClass() == CLASS_HUNTER)
+ if (bot->getClass() == CLASS_HUNTER)
{
return Move(bot->GetAngle(boss), fmin(bot->GetExactDist2d(boss) - 6.5f, maxMovement));
}
@@ -152,7 +152,6 @@ bool LokenStackAction::Execute(Event event)
return false;
}
-
bool AvoidLightningNovaAction::Execute(Event event)
{
Unit* boss = AI_VALUE2(Unit*, "find target", "loken");
diff --git a/src/strategy/dungeons/wotlk/hallsoflightning/HallsOfLightningMultipliers.cpp b/src/strategy/dungeons/wotlk/hallsoflightning/HallsOfLightningMultipliers.cpp
index fa67682237..3bf9fcfd63 100644
--- a/src/strategy/dungeons/wotlk/hallsoflightning/HallsOfLightningMultipliers.cpp
+++ b/src/strategy/dungeons/wotlk/hallsoflightning/HallsOfLightningMultipliers.cpp
@@ -123,4 +123,3 @@ float LokenMultiplier::GetValue(Action* action)
return 1.0f; // Default multiplier value for other cases.
}
-
diff --git a/src/strategy/dungeons/wotlk/hallsoflightning/HallsOfLightningStrategy.cpp b/src/strategy/dungeons/wotlk/hallsoflightning/HallsOfLightningStrategy.cpp
index dc17c3d8f7..42d30d96d9 100644
--- a/src/strategy/dungeons/wotlk/hallsoflightning/HallsOfLightningStrategy.cpp
+++ b/src/strategy/dungeons/wotlk/hallsoflightning/HallsOfLightningStrategy.cpp
@@ -1,7 +1,6 @@
#include "HallsOfLightningStrategy.h"
#include "HallsOfLightningMultipliers.h"
-
void WotlkDungeonHoLStrategy::InitTriggers(std::vector &triggers)
{
// General Bjarngrim
diff --git a/src/strategy/dungeons/wotlk/hallsoflightning/HallsOfLightningStrategy.h b/src/strategy/dungeons/wotlk/hallsoflightning/HallsOfLightningStrategy.h
index 8ee265dd47..6463033b3a 100644
--- a/src/strategy/dungeons/wotlk/hallsoflightning/HallsOfLightningStrategy.h
+++ b/src/strategy/dungeons/wotlk/hallsoflightning/HallsOfLightningStrategy.h
@@ -5,7 +5,6 @@
#include "AiObjectContext.h"
#include "Strategy.h"
-
class WotlkDungeonHoLStrategy : public Strategy
{
public:
diff --git a/src/strategy/dungeons/wotlk/hallsofstone/HallsOfStoneStrategy.cpp b/src/strategy/dungeons/wotlk/hallsofstone/HallsOfStoneStrategy.cpp
index 78d73f4de8..b13d4d6353 100644
--- a/src/strategy/dungeons/wotlk/hallsofstone/HallsOfStoneStrategy.cpp
+++ b/src/strategy/dungeons/wotlk/hallsofstone/HallsOfStoneStrategy.cpp
@@ -1,7 +1,6 @@
#include "HallsOfStoneStrategy.h"
#include "HallsOfStoneMultipliers.h"
-
void WotlkDungeonHoSStrategy::InitTriggers(std::vector &triggers)
{
// Maiden of Grief
diff --git a/src/strategy/dungeons/wotlk/hallsofstone/HallsOfStoneStrategy.h b/src/strategy/dungeons/wotlk/hallsofstone/HallsOfStoneStrategy.h
index 6208483816..ee26aa2cd2 100644
--- a/src/strategy/dungeons/wotlk/hallsofstone/HallsOfStoneStrategy.h
+++ b/src/strategy/dungeons/wotlk/hallsofstone/HallsOfStoneStrategy.h
@@ -5,7 +5,6 @@
#include "AiObjectContext.h"
#include "Strategy.h"
-
class WotlkDungeonHoSStrategy : public Strategy
{
public:
diff --git a/src/strategy/dungeons/wotlk/nexus/NexusMultipliers.cpp b/src/strategy/dungeons/wotlk/nexus/NexusMultipliers.cpp
index 764c9f346c..7adc79b455 100644
--- a/src/strategy/dungeons/wotlk/nexus/NexusMultipliers.cpp
+++ b/src/strategy/dungeons/wotlk/nexus/NexusMultipliers.cpp
@@ -94,4 +94,3 @@ float OrmorokMultiplier::GetValue(Action* action)
}
return 1.0f;
}
-
diff --git a/src/strategy/dungeons/wotlk/nexus/NexusStrategy.cpp b/src/strategy/dungeons/wotlk/nexus/NexusStrategy.cpp
index e471d3b804..22a85f5027 100644
--- a/src/strategy/dungeons/wotlk/nexus/NexusStrategy.cpp
+++ b/src/strategy/dungeons/wotlk/nexus/NexusStrategy.cpp
@@ -1,7 +1,6 @@
#include "NexusStrategy.h"
#include "NexusMultipliers.h"
-
void WotlkDungeonNexStrategy::InitTriggers(std::vector &triggers)
{
// Horde Commander (Alliance N)/Commander Kolurg (Alliance H)
diff --git a/src/strategy/dungeons/wotlk/nexus/NexusStrategy.h b/src/strategy/dungeons/wotlk/nexus/NexusStrategy.h
index f9ecf42643..c78225b93b 100644
--- a/src/strategy/dungeons/wotlk/nexus/NexusStrategy.h
+++ b/src/strategy/dungeons/wotlk/nexus/NexusStrategy.h
@@ -5,7 +5,6 @@
#include "AiObjectContext.h"
#include "Strategy.h"
-
class WotlkDungeonNexStrategy : public Strategy
{
public:
diff --git a/src/strategy/dungeons/wotlk/oculus/OculusMultipliers.cpp b/src/strategy/dungeons/wotlk/oculus/OculusMultipliers.cpp
index 5789d69649..7be543ee70 100644
--- a/src/strategy/dungeons/wotlk/oculus/OculusMultipliers.cpp
+++ b/src/strategy/dungeons/wotlk/oculus/OculusMultipliers.cpp
@@ -40,7 +40,7 @@ float OccFlyingMultiplier::GetValue(Action* action)
float UromMultiplier::GetValue(Action* action)
{
- if(GetPhaseByCurrentPosition(bot) < 3)
+ if (GetPhaseByCurrentPosition(bot) < 3)
{
Unit* target = action->GetTarget();
if (target && target->GetEntry() == NPC_MAGE_LORD_UROM)
diff --git a/src/strategy/dungeons/wotlk/oculus/OculusStrategy.cpp b/src/strategy/dungeons/wotlk/oculus/OculusStrategy.cpp
index 1220e56f49..3e98dfa6a4 100644
--- a/src/strategy/dungeons/wotlk/oculus/OculusStrategy.cpp
+++ b/src/strategy/dungeons/wotlk/oculus/OculusStrategy.cpp
@@ -1,7 +1,6 @@
#include "OculusStrategy.h"
#include "OculusMultipliers.h"
-
void WotlkDungeonOccStrategy::InitTriggers(std::vector &triggers)
{
// Drakos the Interrogator
diff --git a/src/strategy/dungeons/wotlk/oculus/OculusStrategy.h b/src/strategy/dungeons/wotlk/oculus/OculusStrategy.h
index a734f2f450..2accfd8f4d 100644
--- a/src/strategy/dungeons/wotlk/oculus/OculusStrategy.h
+++ b/src/strategy/dungeons/wotlk/oculus/OculusStrategy.h
@@ -5,7 +5,6 @@
#include "AiObjectContext.h"
#include "Strategy.h"
-
class WotlkDungeonOccStrategy : public Strategy
{
public:
diff --git a/src/strategy/dungeons/wotlk/oldkingdom/OldKingdomActions.cpp b/src/strategy/dungeons/wotlk/oldkingdom/OldKingdomActions.cpp
index 703c7454a5..916bf29200 100644
--- a/src/strategy/dungeons/wotlk/oldkingdom/OldKingdomActions.cpp
+++ b/src/strategy/dungeons/wotlk/oldkingdom/OldKingdomActions.cpp
@@ -2,7 +2,6 @@
#include "OldKingdomActions.h"
#include "OldKingdomStrategy.h"
-
bool AttackNadoxGuardianAction::Execute(Event event)
{
Unit* target = AI_VALUE2(Unit*, "find target", "ahn'kahar guardian");
diff --git a/src/strategy/dungeons/wotlk/oldkingdom/OldKingdomStrategy.cpp b/src/strategy/dungeons/wotlk/oldkingdom/OldKingdomStrategy.cpp
index 850fcfcb85..50a38412f7 100644
--- a/src/strategy/dungeons/wotlk/oldkingdom/OldKingdomStrategy.cpp
+++ b/src/strategy/dungeons/wotlk/oldkingdom/OldKingdomStrategy.cpp
@@ -1,7 +1,6 @@
#include "OldKingdomStrategy.h"
#include "OldKingdomMultipliers.h"
-
void WotlkDungeonOKStrategy::InitTriggers(std::vector &triggers)
{
// Elder Nadox
diff --git a/src/strategy/dungeons/wotlk/oldkingdom/OldKingdomStrategy.h b/src/strategy/dungeons/wotlk/oldkingdom/OldKingdomStrategy.h
index 03c5085ee9..75c475559e 100644
--- a/src/strategy/dungeons/wotlk/oldkingdom/OldKingdomStrategy.h
+++ b/src/strategy/dungeons/wotlk/oldkingdom/OldKingdomStrategy.h
@@ -5,7 +5,6 @@
#include "AiObjectContext.h"
#include "Strategy.h"
-
class WotlkDungeonOKStrategy : public Strategy
{
public:
diff --git a/src/strategy/dungeons/wotlk/oldkingdom/OldKingdomTriggers.cpp b/src/strategy/dungeons/wotlk/oldkingdom/OldKingdomTriggers.cpp
index 2de9190ce9..6b72f656a9 100644
--- a/src/strategy/dungeons/wotlk/oldkingdom/OldKingdomTriggers.cpp
+++ b/src/strategy/dungeons/wotlk/oldkingdom/OldKingdomTriggers.cpp
@@ -3,7 +3,6 @@
#include "AiObject.h"
#include "AiObjectContext.h"
-
bool NadoxGuardianTrigger::IsActive()
{
if (botAI->IsHeal(bot)) { return false; }
diff --git a/src/strategy/dungeons/wotlk/pitofsaron/PitOfSaronActions.cpp b/src/strategy/dungeons/wotlk/pitofsaron/PitOfSaronActions.cpp
index fee0ed6078..f34b98462e 100644
--- a/src/strategy/dungeons/wotlk/pitofsaron/PitOfSaronActions.cpp
+++ b/src/strategy/dungeons/wotlk/pitofsaron/PitOfSaronActions.cpp
@@ -136,7 +136,6 @@ bool IckAndKrickAction::PoisonNova(bool poisonNova, Unit* boss)
return false;
}
-
bool IckAndKrickAction::ExplosiveBarrage(bool explosiveBarrage, Unit* boss)
{
std::vector orbs;
diff --git a/src/strategy/dungeons/wotlk/pitofsaron/PitOfSaronMultipliers.cpp b/src/strategy/dungeons/wotlk/pitofsaron/PitOfSaronMultipliers.cpp
index cbe1877800..be36e480f2 100644
--- a/src/strategy/dungeons/wotlk/pitofsaron/PitOfSaronMultipliers.cpp
+++ b/src/strategy/dungeons/wotlk/pitofsaron/PitOfSaronMultipliers.cpp
@@ -5,8 +5,6 @@
#include "MovementActions.h"
#include "PitOfSaronTriggers.h"
-
-
float IckAndKrickMultiplier::GetValue(Action* action)
{
Unit* boss = AI_VALUE2(Unit*, "find target", "ick");
diff --git a/src/strategy/dungeons/wotlk/pitofsaron/PitOfSaronMultipliers.h b/src/strategy/dungeons/wotlk/pitofsaron/PitOfSaronMultipliers.h
index fabf6319a3..bcafc01a43 100644
--- a/src/strategy/dungeons/wotlk/pitofsaron/PitOfSaronMultipliers.h
+++ b/src/strategy/dungeons/wotlk/pitofsaron/PitOfSaronMultipliers.h
@@ -20,5 +20,4 @@ class GarfrostMultiplier : public Multiplier
float GetValue(Action* action) override;
};
-
#endif
diff --git a/src/strategy/dungeons/wotlk/trialofthechampion/TrialOfTheChampionActions.cpp b/src/strategy/dungeons/wotlk/trialofthechampion/TrialOfTheChampionActions.cpp
index 0cb1ee0e7b..5dd1ef8bcc 100644
--- a/src/strategy/dungeons/wotlk/trialofthechampion/TrialOfTheChampionActions.cpp
+++ b/src/strategy/dungeons/wotlk/trialofthechampion/TrialOfTheChampionActions.cpp
@@ -9,7 +9,6 @@
#include "GenericActions.h"
#include
-
bool ToCLanceAction::Execute(Event event)
{
// If already has lance equipped, do nothing
diff --git a/src/strategy/dungeons/wotlk/trialofthechampion/TrialOfTheChampionStrategy.cpp b/src/strategy/dungeons/wotlk/trialofthechampion/TrialOfTheChampionStrategy.cpp
index 4c439e18a5..e1f97000c6 100644
--- a/src/strategy/dungeons/wotlk/trialofthechampion/TrialOfTheChampionStrategy.cpp
+++ b/src/strategy/dungeons/wotlk/trialofthechampion/TrialOfTheChampionStrategy.cpp
@@ -1,7 +1,6 @@
#include "TrialOfTheChampionStrategy.h"
#include "TrialOfTheChampionMultipliers.h"
-
void WotlkDungeonToCStrategy::InitTriggers(std::vector