Merge remote-tracking branch 'upstream/master' into karazhan

This commit is contained in:
crow
2025-09-27 03:22:50 -05:00
238 changed files with 106653 additions and 102603 deletions

View File

@@ -21,6 +21,7 @@
# THRESHOLDS # THRESHOLDS
# QUESTS # QUESTS
# COMBAT # COMBAT
# PALADIN BUFFS STRATEGIES
# CHEATS # CHEATS
# SPELLS # SPELLS
# FLIGHTPATH # FLIGHTPATH
@@ -457,6 +458,24 @@ AiPlayerbot.FleeingEnabled = 1
# #
#################################################################################################### ####################################################################################################
####################################################################################################
# PALADIN BUFFS STRATEGIES
#
#
# Min group size to use Greater buffs (Paladin, Mage, Druid)
# Default: 3
AiPlayerbot.MinBotsForGreaterBuff = 3
# Cooldown (seconds) between reagent-missing RP warnings, per bot & per buff
# Default: 30
AiPlayerbot.RPWarningCooldown = 30
#
#
#
####################################################################################################
#################################################################################################### ####################################################################################################
# CHEATS # CHEATS
# #
@@ -494,7 +513,7 @@ AiPlayerbot.AutoGearScoreLimit = 0
# Enable/Disable cheats for bots # Enable/Disable cheats for bots
# "food" (bots eat or drink without using food or drinks from their inventory) # "food" (bots eat or drink without using food or drinks from their inventory)
# "gold" (bots have infinite gold) # "gold" (bots have infinite gold)
# "health" (bots have infinite health) # "health" (bots immediately regenerate lost health)
# "mana" (bots have infinite mana) # "mana" (bots have infinite mana)
# "power" (bots have infinite energy, rage, and runic power) # "power" (bots have infinite energy, rage, and runic power)
# "taxi" (bots may use all flight paths, though they will not actually learn them) # "taxi" (bots may use all flight paths, though they will not actually learn them)
@@ -760,7 +779,7 @@ AiPlayerbot.botActiveAloneSmartScaleWhenMaxLevel = 80
# #
# Quest that will be completed and rewarded for all randombots # Quest that will be completed and rewarded for all randombots
AiPlayerbot.RandomBotQuestIds = "7848,3802,5505,6502,7761,10277,10285,11492,24499,24511,24710,24712" AiPlayerbot.RandomBotQuestIds = "7848,3802,5505,6502,7761,10277,10285,11492,13188,13189,24499,24511,24710,24712"
# Randombots will group with nearby randombots to do shared quests # Randombots will group with nearby randombots to do shared quests
AiPlayerbot.RandomBotGroupNearby = 0 AiPlayerbot.RandomBotGroupNearby = 0
@@ -1429,11 +1448,11 @@ AiPlayerbot.PremadeSpecGlyph.7.0 = 41536,43385,41532,43386,44923,45776
AiPlayerbot.PremadeSpecLink.7.0.60 = 4530001520213351102301351 AiPlayerbot.PremadeSpecLink.7.0.60 = 4530001520213351102301351
AiPlayerbot.PremadeSpecLink.7.0.80 = 3530001523213351322301351-005050031 AiPlayerbot.PremadeSpecLink.7.0.80 = 3530001523213351322301351-005050031
AiPlayerbot.PremadeSpecName.7.1 = enh pve AiPlayerbot.PremadeSpecName.7.1 = enh pve
AiPlayerbot.PremadeSpecGlyph.7.1 = 41542,43385,41539,43386,44923,45771 AiPlayerbot.PremadeSpecGlyph.7.1 = 41530,43385,41539,43386,44923,45771
AiPlayerbot.PremadeSpecLink.7.1.60 = -30205033005001333031131131051 AiPlayerbot.PremadeSpecLink.7.1.60 = -30305003105021333031121131051
AiPlayerbot.PremadeSpecLink.7.1.80 = 053030052-30205033005021333031131131051 AiPlayerbot.PremadeSpecLink.7.1.80 = 053030152-30305003105021333031131131051
AiPlayerbot.PremadeSpecName.7.2 = resto pve AiPlayerbot.PremadeSpecName.7.2 = resto pve
AiPlayerbot.PremadeSpecGlyph.7.2 = 41517,43385,41527,43386,44923,45775 AiPlayerbot.PremadeSpecGlyph.7.2 = 41527,43385,41517,43386,44923,45775
AiPlayerbot.PremadeSpecLink.7.2.60 = --50005301235310501102321251 AiPlayerbot.PremadeSpecLink.7.2.60 = --50005301235310501102321251
AiPlayerbot.PremadeSpecLink.7.2.80 = -00502033-50005331335310501122331251 AiPlayerbot.PremadeSpecLink.7.2.80 = -00502033-50005331335310501122331251
AiPlayerbot.PremadeSpecName.7.3 = ele pvp AiPlayerbot.PremadeSpecName.7.3 = ele pvp
@@ -1997,11 +2016,11 @@ AiPlayerbot.AllowedLogFiles = ""
#################################################################################################### ####################################################################################################
# A list of gameObject GUID's that are not allowed for bots to interact with. # A list of gameObject GUID's that are not allowed for bots to interact with.
# #
AiPlayerbot.DisallowedGameObjects = 176213,17155,2656,74448,19020,3719,3658,3705,3706,105579,75293,2857,179490,141596,160836,160845,179516,176224,181085,176112,128308,128403,165739,165738,175245,175970,176325,176327,123329 AiPlayerbot.DisallowedGameObjects = 176213,17155,2656,74448,19020,3719,3658,3705,3706,105579,75293,2857,179490,141596,160836,160845,179516,176224,181085,176112,128308,128403,165739,165738,175245,175970,176325,176327,123329,2560
# #
# List of GUID's: # List of GUID's:
# QuestItems: # QuestItems:
# 176213 = Blood of Heroes, 17155 = Defias Gunpowder, 2656 = Waterlogged Envelope, 123329 = Baelogs Chest # 176213 = Blood of Heroes, 17155 = Defias Gunpowder, 2656 = Waterlogged Envelope, 123329 = Baelogs Chest, 2560 = Half-Buried Bottle
# Chests: # Chests:
# Large Solid Chest = 74448, Box of Assorted Parts = 19020, Food Crate = 3719, Water Barrel = 3658, Barrel of Milk = 3705, Barrel of sweet Nectar = 3706, Tattered Chest = 105579, Large bettered Chest = 75293, Solid Chest = 2857, Battered Foodlocker = 179490, Witch Doctor's Chest = 141596, Relic Coffer = 160836, Dark Coffer = 160845, Fengus's Chest = 179516, Supply Crate = 176224/181085, Malor's Strongbox = 176112 # Large Solid Chest = 74448, Box of Assorted Parts = 19020, Food Crate = 3719, Water Barrel = 3658, Barrel of Milk = 3705, Barrel of sweet Nectar = 3706, Tattered Chest = 105579, Large bettered Chest = 75293, Solid Chest = 2857, Battered Foodlocker = 179490, Witch Doctor's Chest = 141596, Relic Coffer = 160836, Dark Coffer = 160845, Fengus's Chest = 179516, Supply Crate = 176224/181085, Malor's Strongbox = 176112
# Other: # Other:

View File

@@ -0,0 +1,8 @@
UPDATE guild
SET
EmblemStyle = FLOOR(RAND() * 181),
EmblemColor = FLOOR(RAND() * 18),
BorderStyle = FLOOR(RAND() * 8),
BorderColor = FLOOR(RAND() * 18),
BackgroundColor = FLOOR(RAND() * 52)
WHERE EmblemStyle=0 AND EmblemColor=0 AND BorderStyle=0 AND BorderColor=0 AND BackgroundColor=0;

View File

@@ -8,7 +8,7 @@ CREATE TABLE IF NOT EXISTS `ai_playerbot_texts_chance` (
/*!40000 ALTER TABLE `ai_playerbot_texts_chance` DISABLE KEYS */; /*!40000 ALTER TABLE `ai_playerbot_texts_chance` DISABLE KEYS */;
INSERT INTO `ai_playerbot_texts_chance` (`id`, `name`, `probability`) VALUES INSERT INTO `ai_playerbot_texts_chance` (`id`, `name`, `probability`) VALUES
(1, 'taunt', 30), (1, 'taunt', 30),
(2, 'aoe', 75), (2, 'aoe', 75),
(3, 'loot', 20); (3, 'loot', 20);
/*!40000 ALTER TABLE `ai_playerbot_texts_chance` ENABLE KEYS */; /*!40000 ALTER TABLE `ai_playerbot_texts_chance` ENABLE KEYS */;

View File

@@ -53,16 +53,16 @@ INSERT INTO `playerbots_dungeon_suggestion_definition` VALUES
(NULL, 'ub' , 'The Underbog' , 1, 0, 62, 70, NULL), (NULL, 'ub' , 'The Underbog' , 1, 0, 62, 70, NULL),
(NULL, 'mt' , 'Mana-Tombs' , 1, 0, 63, 70, NULL), (NULL, 'mt' , 'Mana-Tombs' , 1, 0, 63, 70, NULL),
(NULL, 'ac' , 'Auchenai Crypts' , 1, 0, 64, 70, NULL), (NULL, 'ac' , 'Auchenai Crypts' , 1, 0, 64, 70, NULL),
(NULL, 'seth', 'Sethekk Halls' , 1, 0, 66, 70, NULL), (NULL, 'seth', 'Sethekk Halls' , 1, 0, 66, 70, NULL),
(NULL, 'oh' , 'Old Hillsbrad Foothills', 1, 0, 66, 70, NULL), (NULL, 'oh' , 'Old Hillsbrad Foothills', 1, 0, 66, 70, NULL),
(NULL, 'bm' , 'The Black Morass' , 1, 0, 68, 70, NULL), (NULL, 'bm' , 'The Black Morass' , 1, 0, 68, 70, NULL),
(NULL, 'mech', 'The Mechanar' , 1, 0, 68, 70, NULL), (NULL, 'mech', 'The Mechanar' , 1, 0, 68, 70, NULL),
(NULL, 'bot' , 'The Botanica' , 1, 0, 69, 70, NULL), (NULL, 'bot' , 'The Botanica' , 1, 0, 69, 70, NULL),
(NULL, 'arc' , 'The Arcatraz' , 1, 0, 69, 70, NULL), (NULL, 'arc' , 'The Arcatraz' , 1, 0, 69, 70, NULL),
(NULL, 'sh' , 'The Shattered Halls' , 1, 0, 69, 70, NULL), (NULL, 'sh' , 'The Shattered Halls' , 1, 0, 69, 70, NULL),
(NULL, 'sv' , 'The Steamvault' , 1, 0, 69, 70, NULL), (NULL, 'sv' , 'The Steamvault' , 1, 0, 69, 70, NULL),
(NULL, 'sl' , 'Shadow Labyrinth' , 1, 0, 69, 70, NULL), (NULL, 'sl' , 'Shadow Labyrinth' , 1, 0, 69, 70, NULL),
(NULL, 'mgt' , 'Magister''s Terrace' , 1, 0, 70, 70, NULL), (NULL, 'mgt' , 'Magister''s Terrace' , 1, 0, 70, 70, NULL),
-- == The Burning Crusade (Heroic) == -- == The Burning Crusade (Heroic) ==
@@ -72,51 +72,51 @@ INSERT INTO `playerbots_dungeon_suggestion_definition` VALUES
(NULL, 'ub' , 'The Underbog' , 1, 1, 70, 70, NULL), (NULL, 'ub' , 'The Underbog' , 1, 1, 70, 70, NULL),
(NULL, 'mt' , 'Mana-Tombs' , 1, 1, 70, 70, NULL), (NULL, 'mt' , 'Mana-Tombs' , 1, 1, 70, 70, NULL),
(NULL, 'ac' , 'Auchenai Crypts' , 1, 1, 70, 70, NULL), (NULL, 'ac' , 'Auchenai Crypts' , 1, 1, 70, 70, NULL),
(NULL, 'seth', 'Sethekk Halls' , 1, 1, 70, 70, NULL), (NULL, 'seth', 'Sethekk Halls' , 1, 1, 70, 70, NULL),
(NULL, 'oh' , 'Old Hillsbrad Foothills', 1, 1, 70, 70, NULL), (NULL, 'oh' , 'Old Hillsbrad Foothills', 1, 1, 70, 70, NULL),
(NULL, 'bm' , 'The Black Morass' , 1, 1, 70, 70, NULL), (NULL, 'bm' , 'The Black Morass' , 1, 1, 70, 70, NULL),
(NULL, 'mech', 'The Mechanar' , 1, 1, 70, 70, NULL), (NULL, 'mech', 'The Mechanar' , 1, 1, 70, 70, NULL),
(NULL, 'bot' , 'The Botanica' , 1, 1, 70, 70, NULL), (NULL, 'bot' , 'The Botanica' , 1, 1, 70, 70, NULL),
(NULL, 'arc' , 'The Arcatraz' , 1, 1, 70, 70, NULL), (NULL, 'arc' , 'The Arcatraz' , 1, 1, 70, 70, NULL),
(NULL, 'sh' , 'The Shattered Halls' , 1, 1, 70, 70, NULL), (NULL, 'sh' , 'The Shattered Halls' , 1, 1, 70, 70, NULL),
(NULL, 'sv' , 'The Steamvault' , 1, 1, 70, 70, NULL), (NULL, 'sv' , 'The Steamvault' , 1, 1, 70, 70, NULL),
(NULL, 'sl' , 'Shadow Labyrinth' , 1, 1, 70, 70, NULL), (NULL, 'sl' , 'Shadow Labyrinth' , 1, 1, 70, 70, NULL),
(NULL, 'mgt' , 'Magister''s Terrace' , 1, 1, 70, 70, NULL), (NULL, 'mgt' , 'Magister''s Terrace' , 1, 1, 70, 70, NULL),
-- == Wrath of the Lich King == -- == Wrath of the Lich King ==
(NULL, 'uk' , 'Utgarde Keep' , 2, 0, 70, 72, NULL), (NULL, 'uk' , 'Utgarde Keep' , 2, 0, 70, 72, NULL),
(NULL, 'nexus' , 'The Nexus' , 2, 0, 71, 73, NULL), (NULL, 'nexus' , 'The Nexus' , 2, 0, 71, 73, NULL),
(NULL, 'an' , 'Azjol-Nerub' , 2, 0, 72, 74, NULL), (NULL, 'an' , 'Azjol-Nerub' , 2, 0, 72, 74, NULL),
(NULL, 'ak' , 'Ahn''kahet: The Old Kingdom', 2, 0, 73, 75, NULL), (NULL, 'ak' , 'Ahn''kahet: The Old Kingdom', 2, 0, 73, 75, NULL),
(NULL, 'dtk' , 'Drak''Tharon Keep' , 2, 0, 74, 76, NULL), (NULL, 'dtk' , 'Drak''Tharon Keep' , 2, 0, 74, 76, NULL),
(NULL, 'vh' , 'Violet Hold' , 2, 0, 75, 77, NULL), (NULL, 'vh' , 'Violet Hold' , 2, 0, 75, 77, NULL),
(NULL, 'gd' , 'Gundrak' , 2, 0, 76, 78, NULL), (NULL, 'gd' , 'Gundrak' , 2, 0, 76, 78, NULL),
(NULL, 'hos' , 'Halls of Stone' , 2, 0, 77, 79, NULL), (NULL, 'hos' , 'Halls of Stone' , 2, 0, 77, 79, NULL),
(NULL, 'hol' , 'Halls of Lightning' , 2, 0, 80, 80, NULL), (NULL, 'hol' , 'Halls of Lightning' , 2, 0, 80, 80, NULL),
(NULL, 'cos' , 'The Culling of Stratholme' , 2, 0, 80, 80, NULL), (NULL, 'cos' , 'The Culling of Stratholme' , 2, 0, 80, 80, NULL),
(NULL, 'oculus', 'The Oculus' , 2, 0, 80, 80, NULL), (NULL, 'oculus', 'The Oculus' , 2, 0, 80, 80, NULL),
(NULL, 'up' , 'Utgarde Pinnacle' , 2, 0, 80, 80, NULL), (NULL, 'up' , 'Utgarde Pinnacle' , 2, 0, 80, 80, NULL),
(NULL, 'toc' , 'Trial of the Champion' , 2, 0, 80, 80, NULL), (NULL, 'toc' , 'Trial of the Champion' , 2, 0, 80, 80, NULL),
(NULL, 'fos' , 'Forge of Souls' , 2, 0, 80, 80, NULL), (NULL, 'fos' , 'Forge of Souls' , 2, 0, 80, 80, NULL),
(NULL, 'pos' , 'Pit of Saron' , 2, 0, 80, 80, NULL), (NULL, 'pos' , 'Pit of Saron' , 2, 0, 80, 80, NULL),
(NULL, 'hor' , 'Halls of Reflection' , 2, 0, 80, 80, NULL), (NULL, 'hor' , 'Halls of Reflection' , 2, 0, 80, 80, NULL),
-- == Wrath of the Lich King (Heroic) == -- == Wrath of the Lich King (Heroic) ==
(NULL, 'uk' , 'Utgarde Keep' , 2, 1, 80, 80, NULL), (NULL, 'uk' , 'Utgarde Keep' , 2, 1, 80, 80, NULL),
(NULL, 'nexus' , 'The Nexus' , 2, 1, 80, 80, NULL), (NULL, 'nexus' , 'The Nexus' , 2, 1, 80, 80, NULL),
(NULL, 'an' , 'Azjol-Nerub' , 2, 1, 80, 80, NULL), (NULL, 'an' , 'Azjol-Nerub' , 2, 1, 80, 80, NULL),
(NULL, 'ak' , 'Ahn''kahet: The Old Kingdom', 2, 1, 80, 80, NULL), (NULL, 'ak' , 'Ahn''kahet: The Old Kingdom', 2, 1, 80, 80, NULL),
(NULL, 'dtk' , 'Drak''Tharon Keep' , 2, 1, 80, 80, NULL), (NULL, 'dtk' , 'Drak''Tharon Keep' , 2, 1, 80, 80, NULL),
(NULL, 'vh' , 'Violet Hold' , 2, 1, 80, 80, NULL), (NULL, 'vh' , 'Violet Hold' , 2, 1, 80, 80, NULL),
(NULL, 'gd' , 'Gundrak' , 2, 1, 80, 80, NULL), (NULL, 'gd' , 'Gundrak' , 2, 1, 80, 80, NULL),
(NULL, 'hos' , 'Halls of Stone' , 2, 1, 80, 80, NULL), (NULL, 'hos' , 'Halls of Stone' , 2, 1, 80, 80, NULL),
(NULL, 'hol' , 'Halls of Lightning' , 2, 1, 80, 80, NULL), (NULL, 'hol' , 'Halls of Lightning' , 2, 1, 80, 80, NULL),
(NULL, 'cos' , 'The Culling of Stratholme' , 2, 1, 80, 80, NULL), (NULL, 'cos' , 'The Culling of Stratholme' , 2, 1, 80, 80, NULL),
(NULL, 'oculus', 'The Oculus' , 2, 1, 80, 80, NULL), (NULL, 'oculus', 'The Oculus' , 2, 1, 80, 80, NULL),
(NULL, 'up' , 'Utgarde Pinnacle' , 2, 1, 80, 80, NULL), (NULL, 'up' , 'Utgarde Pinnacle' , 2, 1, 80, 80, NULL),
(NULL, 'toc' , 'Trial of the Champion' , 2, 1, 80, 80, NULL), (NULL, 'toc' , 'Trial of the Champion' , 2, 1, 80, 80, NULL),
(NULL, 'fos' , 'Forge of Souls' , 2, 1, 80, 80, NULL), (NULL, 'fos' , 'Forge of Souls' , 2, 1, 80, 80, NULL),
(NULL, 'pos' , 'Pit of Saron' , 2, 1, 80, 80, NULL), (NULL, 'pos' , 'Pit of Saron' , 2, 1, 80, 80, NULL),
(NULL, 'hor' , 'Halls of Reflection' , 2, 1, 80, 80, NULL); (NULL, 'hor' , 'Halls of Reflection' , 2, 1, 80, 80, NULL);

View File

@@ -25,226 +25,226 @@ CREATE TABLE `playerbots_enchants` (
/*!40000 ALTER TABLE `playerbots_enchants` DISABLE KEYS */; /*!40000 ALTER TABLE `playerbots_enchants` DISABLE KEYS */;
DELETE FROM `playerbots_enchants`; DELETE FROM `playerbots_enchants`;
INSERT INTO `playerbots_enchants` (`class`, `spec`, `spellid`, `slotid`, `name`) VALUES INSERT INTO `playerbots_enchants` (`class`, `spec`, `spellid`, `slotid`, `name`) VALUES
(1, 10, 20034, 15, 'Crusader '), (1, 10, 20034, 15, 'Crusader '),
(1, 10, 22779, 17, '30 Hit '), (1, 10, 22779, 17, '30 Hit '),
(1, 10, 27927, 10, '4 All Stats '), (1, 10, 27927, 10, '4 All Stats '),
(1, 10, 27927, 11, '4 All Stats '), (1, 10, 27927, 11, '4 All Stats '),
(1, 10, 27960, 4, '6 All Stats '), (1, 10, 27960, 4, '6 All Stats '),
(1, 10, 27984, 16, 'Mongoose '), (1, 10, 27984, 16, 'Mongoose '),
(1, 10, 29483, 2, '26 Attackpower 14 Crit '), (1, 10, 29483, 2, '26 Attackpower 14 Crit '),
(1, 10, 33996, 9, '26 Attackpower '), (1, 10, 33996, 9, '26 Attackpower '),
(1, 10, 34002, 8, '24 Attackpower '), (1, 10, 34002, 8, '24 Attackpower '),
(1, 10, 34004, 14, '12 Agility '), (1, 10, 34004, 14, '12 Agility '),
(1, 10, 34007, 7, 'Minor Speed 6 Agility'), (1, 10, 34007, 7, 'Minor Speed 6 Agility'),
(1, 10, 35452, 0, '34 Attackpower 16 Hit '), (1, 10, 35452, 0, '34 Attackpower 16 Hit '),
(1, 10, 35490, 6, '50 Attackpower 12 Crit '), (1, 10, 35490, 6, '50 Attackpower 12 Crit '),
(1, 11, 20034, 15, 'Crusader '), (1, 11, 20034, 15, 'Crusader '),
(1, 11, 20034, 16, 'Crusader '), (1, 11, 20034, 16, 'Crusader '),
(1, 11, 22779, 17, '30 Hit '), (1, 11, 22779, 17, '30 Hit '),
(1, 11, 27927, 10, '4 All Stats '), (1, 11, 27927, 10, '4 All Stats '),
(1, 11, 27927, 11, '4 All Stats '), (1, 11, 27927, 11, '4 All Stats '),
(1, 11, 27960, 4, '6 All Stats '), (1, 11, 27960, 4, '6 All Stats '),
(1, 11, 29483, 2, '26 Attackpower 14 Crit '), (1, 11, 29483, 2, '26 Attackpower 14 Crit '),
(1, 11, 33996, 9, '26 Attackpower '), (1, 11, 33996, 9, '26 Attackpower '),
(1, 11, 34002, 8, '24 Attackpower '), (1, 11, 34002, 8, '24 Attackpower '),
(1, 11, 34004, 14, '12 Agility '), (1, 11, 34004, 14, '12 Agility '),
(1, 11, 34007, 7, 'Minor Speed 6 Agility'), (1, 11, 34007, 7, 'Minor Speed 6 Agility'),
(1, 11, 35452, 0, '34 Attackpower 16 Hit '), (1, 11, 35452, 0, '34 Attackpower 16 Hit '),
(1, 11, 35490, 6, '50 Attackpower 12 Crit '), (1, 11, 35490, 6, '50 Attackpower 12 Crit '),
(1, 12, 22779, 17, '30 Hit '), (1, 12, 22779, 17, '30 Hit '),
(1, 12, 25072, 9, '2% Threat '), (1, 12, 25072, 9, '2% Threat '),
(1, 12, 27906, 8, '12 Defense '), (1, 12, 27906, 8, '12 Defense '),
(1, 12, 27927, 10, '4 All Stats '), (1, 12, 27927, 10, '4 All Stats '),
(1, 12, 27927, 11, '4 All Stats '), (1, 12, 27927, 11, '4 All Stats '),
(1, 12, 27954, 7, '5% Root/Snare Resist 10 Hit'), (1, 12, 27954, 7, '5% Root/Snare Resist 10 Hit'),
(1, 12, 27960, 4, '6 All Stats '), (1, 12, 27960, 4, '6 All Stats '),
(1, 12, 28004, 15, 'Battlemaster '), (1, 12, 28004, 15, 'Battlemaster '),
(1, 12, 34009, 16, '18 Stamina '), (1, 12, 34009, 16, '18 Stamina '),
(1, 12, 35433, 2, '10 Dodge 15 Defense '), (1, 12, 35433, 2, '10 Dodge 15 Defense '),
(1, 12, 35443, 0, '16 Defense 17 Dodge '), (1, 12, 35443, 0, '16 Defense 17 Dodge '),
(1, 12, 35495, 6, '40 Stamina 12 Agility '), (1, 12, 35495, 6, '40 Stamina 12 Agility '),
(1, 12, 47051, 14, '12 Defense '), (1, 12, 47051, 14, '12 Defense '),
(2, 20, 22779, 17, '30 Hit '), (2, 20, 22779, 17, '30 Hit '),
(2, 20, 27926, 10, '20 Healing 7 Spelldamage '), (2, 20, 27926, 10, '20 Healing 7 Spelldamage '),
(2, 20, 27926, 11, '20 Healing 7 Spelldamage '), (2, 20, 27926, 11, '20 Healing 7 Spelldamage '),
(2, 20, 27945, 16, '12 Intellect '), (2, 20, 27945, 16, '12 Intellect '),
(2, 20, 27954, 7, '5% Root/Snare Resist 10 Hit'), (2, 20, 27954, 7, '5% Root/Snare Resist 10 Hit'),
(2, 20, 27960, 4, '6 All Stats '), (2, 20, 27960, 4, '6 All Stats '),
(2, 20, 29475, 2, '31 Healing 11 Spelldamage 5 mp5 '), (2, 20, 29475, 2, '31 Healing 11 Spelldamage 5 mp5 '),
(2, 20, 31370, 6, '66 Healing 22 Spelldamage 20 Stamina '), (2, 20, 31370, 6, '66 Healing 22 Spelldamage 20 Stamina '),
(2, 20, 33999, 9, '35 Healing 12 Spelldamage '), (2, 20, 33999, 9, '35 Healing 12 Spelldamage '),
(2, 20, 34001, 8, '12 Intellect '), (2, 20, 34001, 8, '12 Intellect '),
(2, 20, 34003, 14, '20 Spell Penetration '), (2, 20, 34003, 14, '20 Spell Penetration '),
(2, 20, 34010, 15, '81 Healing 27 Spelldamage '), (2, 20, 34010, 15, '81 Healing 27 Spelldamage '),
(2, 20, 35445, 0, '35 Healing 12 Spelldamage 7 mp5 '), (2, 20, 35445, 0, '35 Healing 12 Spelldamage 7 mp5 '),
(2, 21, 22779, 17, '30 Hit '), (2, 21, 22779, 17, '30 Hit '),
(2, 21, 25072, 9, '2% Threat '), (2, 21, 25072, 9, '2% Threat '),
(2, 21, 27906, 8, '12 Defense '), (2, 21, 27906, 8, '12 Defense '),
(2, 21, 27927, 10, '4 All Stats '), (2, 21, 27927, 10, '4 All Stats '),
(2, 21, 27927, 11, '4 All Stats '), (2, 21, 27927, 11, '4 All Stats '),
(2, 21, 27954, 7, '5% Root/Snare Resist 10 Hit'), (2, 21, 27954, 7, '5% Root/Snare Resist 10 Hit'),
(2, 21, 27960, 4, '6 All Stats '), (2, 21, 27960, 4, '6 All Stats '),
(2, 21, 28004, 15, 'Battlemaster '), (2, 21, 28004, 15, 'Battlemaster '),
(2, 21, 34009, 16, '18 Stamina '), (2, 21, 34009, 16, '18 Stamina '),
(2, 21, 35433, 2, '10 Dodge 15 Defense '), (2, 21, 35433, 2, '10 Dodge 15 Defense '),
(2, 21, 35443, 0, '16 Defense 17 Dodge '), (2, 21, 35443, 0, '16 Defense 17 Dodge '),
(2, 21, 35495, 6, '40 Stamina 12 Agility '), (2, 21, 35495, 6, '40 Stamina 12 Agility '),
(2, 21, 47051, 14, '12 Defense '), (2, 21, 47051, 14, '12 Defense '),
(2, 22, 20034, 15, 'Crusader '), (2, 22, 20034, 15, 'Crusader '),
(2, 22, 22779, 17, '30 Hit '), (2, 22, 22779, 17, '30 Hit '),
(2, 22, 27899, 8, '12 Strength '), (2, 22, 27899, 8, '12 Strength '),
(2, 22, 27927, 10, '4 All Stats '), (2, 22, 27927, 10, '4 All Stats '),
(2, 22, 27927, 11, '4 All Stats '), (2, 22, 27927, 11, '4 All Stats '),
(2, 22, 27960, 4, '6 All Stats '), (2, 22, 27960, 4, '6 All Stats '),
(2, 22, 29483, 2, '26 Attackpower 14 Crit '), (2, 22, 29483, 2, '26 Attackpower 14 Crit '),
(2, 22, 33995, 6, '50 Attackpower 12 Crit '), (2, 22, 33995, 6, '50 Attackpower 12 Crit '),
(2, 22, 33996, 9, '15 Strength '), (2, 22, 33996, 9, '15 Strength '),
(2, 22, 34004, 14, '12 Agility '), (2, 22, 34004, 14, '12 Agility '),
(2, 22, 34007, 7, 'Minor Speed 6 Agility'), (2, 22, 34007, 7, 'Minor Speed 6 Agility'),
(2, 22, 37891, 0, '17 Strength16 Intellect '), (2, 22, 37891, 0, '17 Strength16 Intellect '),
(3, 30, 22779, 17, '30 Hit '), (3, 30, 22779, 17, '30 Hit '),
(3, 30, 25080, 9, '15 Agility '), (3, 30, 25080, 9, '15 Agility '),
(3, 30, 27927, 10, '4 All Stats '), (3, 30, 27927, 10, '4 All Stats '),
(3, 30, 27927, 11, '4 All Stats '), (3, 30, 27927, 11, '4 All Stats '),
(3, 30, 27951, 7, '12 Agility'), (3, 30, 27951, 7, '12 Agility'),
(3, 30, 27960, 4, '6 All Stats '), (3, 30, 27960, 4, '6 All Stats '),
(3, 30, 29483, 2, '26 Attackpower 14 Crit '), (3, 30, 29483, 2, '26 Attackpower 14 Crit '),
(3, 30, 34002, 8, '24 Attackpower '), (3, 30, 34002, 8, '24 Attackpower '),
(3, 30, 34004, 14, '12 Agility '), (3, 30, 34004, 14, '12 Agility '),
(3, 30, 35452, 0, '34 Attackpower 16 Hit '), (3, 30, 35452, 0, '34 Attackpower 16 Hit '),
(3, 30, 35495, 6, '40 Stamina 12 Agility '), (3, 30, 35495, 6, '40 Stamina 12 Agility '),
(3, 30, 42620, 15, 'Greater Agility '), (3, 30, 42620, 15, 'Greater Agility '),
(3, 30, 42620, 16, 'Greater Agility '), (3, 30, 42620, 16, 'Greater Agility '),
(4, 40, 22779, 17, '30 Hit '), (4, 40, 22779, 17, '30 Hit '),
(4, 40, 25080, 9, '15 Agility '), (4, 40, 25080, 9, '15 Agility '),
(4, 40, 27927, 10, '4 All Stats '), (4, 40, 27927, 10, '4 All Stats '),
(4, 40, 27927, 11, '4 All Stats '), (4, 40, 27927, 11, '4 All Stats '),
(4, 40, 27951, 7, '12 Agility'), (4, 40, 27951, 7, '12 Agility'),
(4, 40, 27960, 4, '6 All Stats '), (4, 40, 27960, 4, '6 All Stats '),
(4, 40, 27984, 15, 'Mongoose '), (4, 40, 27984, 15, 'Mongoose '),
(4, 40, 27984, 16, 'Mongoose '), (4, 40, 27984, 16, 'Mongoose '),
(4, 40, 29483, 2, '26 Attackpower 14 Crit '), (4, 40, 29483, 2, '26 Attackpower 14 Crit '),
(4, 40, 34002, 8, '24 Attackpower '), (4, 40, 34002, 8, '24 Attackpower '),
(4, 40, 34004, 14, '12 Agility '), (4, 40, 34004, 14, '12 Agility '),
(4, 40, 35452, 0, '34 Attackpower 16 Hit '), (4, 40, 35452, 0, '34 Attackpower 16 Hit '),
(4, 40, 35495, 6, '40 Stamina 12 Agility '), (4, 40, 35495, 6, '40 Stamina 12 Agility '),
(5, 50, 22779, 17, '30 Hit '), (5, 50, 22779, 17, '30 Hit '),
(5, 50, 27926, 10, '20 Healing 7 Spelldamage '), (5, 50, 27926, 10, '20 Healing 7 Spelldamage '),
(5, 50, 27926, 11, '20 Healing 7 Spelldamage '), (5, 50, 27926, 11, '20 Healing 7 Spelldamage '),
(5, 50, 27945, 16, '12 Intellect '), (5, 50, 27945, 16, '12 Intellect '),
(5, 50, 27954, 7, '5% Root/Snare Resist 10 Hit'), (5, 50, 27954, 7, '5% Root/Snare Resist 10 Hit'),
(5, 50, 27960, 4, '6 All Stats '), (5, 50, 27960, 4, '6 All Stats '),
(5, 50, 29475, 2, '31 Healing 11 Spelldamage 5 mp5 '), (5, 50, 29475, 2, '31 Healing 11 Spelldamage 5 mp5 '),
(5, 50, 31370, 6, '66 Healing 22 Spelldamage 20 Stamina '), (5, 50, 31370, 6, '66 Healing 22 Spelldamage 20 Stamina '),
(5, 50, 33999, 9, '35 Healing 12 Spelldamage '), (5, 50, 33999, 9, '35 Healing 12 Spelldamage '),
(5, 50, 34001, 8, '12 Intellect '), (5, 50, 34001, 8, '12 Intellect '),
(5, 50, 34003, 14, '20 Spell Penetration '), (5, 50, 34003, 14, '20 Spell Penetration '),
(5, 50, 34010, 15, '81 Healing 27 Spelldamage '), (5, 50, 34010, 15, '81 Healing 27 Spelldamage '),
(5, 50, 35445, 0, '35 Healing 12 Spelldamage 7 mp5 '), (5, 50, 35445, 0, '35 Healing 12 Spelldamage 7 mp5 '),
(7, 70, 22779, 17, '30 Hit '), (7, 70, 22779, 17, '30 Hit '),
(7, 70, 27926, 10, '20 Healing 7 Spelldamage '), (7, 70, 27926, 10, '20 Healing 7 Spelldamage '),
(7, 70, 27926, 11, '20 Healing 7 Spelldamage '), (7, 70, 27926, 11, '20 Healing 7 Spelldamage '),
(7, 70, 27945, 16, '12 Intellect '), (7, 70, 27945, 16, '12 Intellect '),
(7, 70, 27954, 7, '5% Root/Snare Resist 10 Hit'), (7, 70, 27954, 7, '5% Root/Snare Resist 10 Hit'),
(7, 70, 27960, 4, '6 All Stats '), (7, 70, 27960, 4, '6 All Stats '),
(7, 70, 31370, 6, '66 Healing 22 Spelldamage 20 Stamina '), (7, 70, 31370, 6, '66 Healing 22 Spelldamage 20 Stamina '),
(7, 70, 33994, 9, '15 Spell Hit '), (7, 70, 33994, 9, '15 Spell Hit '),
(7, 70, 34001, 8, '12 Intellect '), (7, 70, 34001, 8, '12 Intellect '),
(7, 70, 34003, 14, '20 Spell Penetration '), (7, 70, 34003, 14, '20 Spell Penetration '),
(7, 70, 34010, 15, '81 Healing 27 Spelldamage '), (7, 70, 34010, 15, '81 Healing 27 Spelldamage '),
(7, 70, 35406, 2, '18 Spelldamage 10 Crit '), (7, 70, 35406, 2, '18 Spelldamage 10 Crit '),
(7, 70, 35447, 0, '22 Spelldamage 14 Hit '), (7, 70, 35447, 0, '22 Spelldamage 14 Hit '),
(7, 71, 22779, 17, '30 Hit '), (7, 71, 22779, 17, '30 Hit '),
(7, 71, 25080, 9, '15 Agility '), (7, 71, 25080, 9, '15 Agility '),
(7, 71, 27927, 10, '4 All Stats '), (7, 71, 27927, 10, '4 All Stats '),
(7, 71, 27927, 11, '4 All Stats '), (7, 71, 27927, 11, '4 All Stats '),
(7, 71, 27951, 7, '12 Agility'), (7, 71, 27951, 7, '12 Agility'),
(7, 71, 27960, 4, '6 All Stats '), (7, 71, 27960, 4, '6 All Stats '),
(7, 71, 27977, 15, '35 Agility '), (7, 71, 27977, 15, '35 Agility '),
(7, 71, 27984, 16, 'Mongoose '), (7, 71, 27984, 16, 'Mongoose '),
(7, 71, 29483, 2, '26 Attackpower 14 Crit '), (7, 71, 29483, 2, '26 Attackpower 14 Crit '),
(7, 71, 34002, 8, '24 Attackpower '), (7, 71, 34002, 8, '24 Attackpower '),
(7, 71, 34004, 14, '12 Agility '), (7, 71, 34004, 14, '12 Agility '),
(7, 71, 35452, 0, '34 Attackpower 16 Hit '), (7, 71, 35452, 0, '34 Attackpower 16 Hit '),
(7, 71, 35495, 6, '40 Stamina 12 Agility '), (7, 71, 35495, 6, '40 Stamina 12 Agility '),
(7, 72, 22779, 17, '30 Hit '), (7, 72, 22779, 17, '30 Hit '),
(7, 72, 27926, 10, '20 Healing 7 Spelldamage '), (7, 72, 27926, 10, '20 Healing 7 Spelldamage '),
(7, 72, 27926, 11, '20 Healing 7 Spelldamage '), (7, 72, 27926, 11, '20 Healing 7 Spelldamage '),
(7, 72, 27945, 16, '12 Intellect '), (7, 72, 27945, 16, '12 Intellect '),
(7, 72, 27954, 7, '5% Root/Snare Resist 10 Hit'), (7, 72, 27954, 7, '5% Root/Snare Resist 10 Hit'),
(7, 72, 27960, 4, '6 All Stats '), (7, 72, 27960, 4, '6 All Stats '),
(7, 72, 29475, 2, '31 Healing 11 Spelldamage 5 mp5 '), (7, 72, 29475, 2, '31 Healing 11 Spelldamage 5 mp5 '),
(7, 72, 31370, 6, '66 Healing 22 Spelldamage 20 Stamina '), (7, 72, 31370, 6, '66 Healing 22 Spelldamage 20 Stamina '),
(7, 72, 33999, 9, '35 Healing 12 Spelldamage '), (7, 72, 33999, 9, '35 Healing 12 Spelldamage '),
(7, 72, 34001, 8, '12 Intellect '), (7, 72, 34001, 8, '12 Intellect '),
(7, 72, 34003, 14, '20 Spell Penetration '), (7, 72, 34003, 14, '20 Spell Penetration '),
(7, 72, 34010, 15, '81 Healing 27 Spelldamage '), (7, 72, 34010, 15, '81 Healing 27 Spelldamage '),
(7, 72, 35445, 0, '35 Healing 12 Spelldamage 7 mp5 '), (7, 72, 35445, 0, '35 Healing 12 Spelldamage 7 mp5 '),
(8, 80, 22779, 17, '30 Hit '), (8, 80, 22779, 17, '30 Hit '),
(8, 80, 27927, 10, '4 All Stats '), (8, 80, 27927, 10, '4 All Stats '),
(8, 80, 27927, 11, '4 All Stats '), (8, 80, 27927, 11, '4 All Stats '),
(8, 80, 27945, 16, '12 Intellect '), (8, 80, 27945, 16, '12 Intellect '),
(8, 80, 27954, 7, '5% Root/Snare Resist 10 Hit'), (8, 80, 27954, 7, '5% Root/Snare Resist 10 Hit'),
(8, 80, 27960, 4, '6 All Stats '), (8, 80, 27960, 4, '6 All Stats '),
(8, 80, 27975, 15, '40 Spelldamage '), (8, 80, 27975, 15, '40 Spelldamage '),
(8, 80, 31372, 6, '35 Spelldamage 20 Stamina '), (8, 80, 31372, 6, '35 Spelldamage 20 Stamina '),
(8, 80, 33994, 9, '15 Spell Hit '), (8, 80, 33994, 9, '15 Spell Hit '),
(8, 80, 34001, 8, '12 Intellect '), (8, 80, 34001, 8, '12 Intellect '),
(8, 80, 34003, 14, '20 Spell Penetration '), (8, 80, 34003, 14, '20 Spell Penetration '),
(8, 80, 35406, 2, '18 Spelldamage 10 Crit '), (8, 80, 35406, 2, '18 Spelldamage 10 Crit '),
(8, 80, 35447, 0, '22 Spelldamage 14 Hit '), (8, 80, 35447, 0, '22 Spelldamage 14 Hit '),
(9, 90, 22779, 17, '30 Hit '), (9, 90, 22779, 17, '30 Hit '),
(9, 90, 27924, 11, '12 Spelldamage '), (9, 90, 27924, 11, '12 Spelldamage '),
(9, 90, 27927, 10, '4 All Stats '), (9, 90, 27927, 10, '4 All Stats '),
(9, 90, 27945, 16, '12 Intellect '), (9, 90, 27945, 16, '12 Intellect '),
(9, 90, 27954, 7, '5% Root/Snare Resist 10 Hit'), (9, 90, 27954, 7, '5% Root/Snare Resist 10 Hit'),
(9, 90, 27960, 4, '6 All Stats '), (9, 90, 27960, 4, '6 All Stats '),
(9, 90, 27975, 15, '40 Spelldamage '), (9, 90, 27975, 15, '40 Spelldamage '),
(9, 90, 31372, 6, '35 Spelldamage 20 Stamina '), (9, 90, 31372, 6, '35 Spelldamage 20 Stamina '),
(9, 90, 33994, 9, '15 Spell Hit '), (9, 90, 33994, 9, '15 Spell Hit '),
(9, 90, 34001, 8, '12 Intellect '), (9, 90, 34001, 8, '12 Intellect '),
(9, 90, 34003, 14, '20 Spell Penetration '), (9, 90, 34003, 14, '20 Spell Penetration '),
(9, 90, 35406, 2, '18 Spelldamage 10 Crit '), (9, 90, 35406, 2, '18 Spelldamage 10 Crit '),
(9, 90, 35447, 0, '22 Spelldamage 14 Hit '), (9, 90, 35447, 0, '22 Spelldamage 14 Hit '),
(11, 110, 22779, 17, '30 Hit '), (11, 110, 22779, 17, '30 Hit '),
(11, 110, 27926, 10, '20 Healing 7 Spelldamage '), (11, 110, 27926, 10, '20 Healing 7 Spelldamage '),
(11, 110, 27926, 11, '20 Healing 7 Spelldamage '), (11, 110, 27926, 11, '20 Healing 7 Spelldamage '),
(11, 110, 27945, 16, '12 Intellect '), (11, 110, 27945, 16, '12 Intellect '),
(11, 110, 27954, 7, '5% Root/Snare Resist 10 Hit'), (11, 110, 27954, 7, '5% Root/Snare Resist 10 Hit'),
(11, 110, 27960, 4, '6 All Stats '), (11, 110, 27960, 4, '6 All Stats '),
(11, 110, 31370, 6, '66 Healing 22 Spelldamage 20 Stamina '), (11, 110, 31370, 6, '66 Healing 22 Spelldamage 20 Stamina '),
(11, 110, 33994, 9, '15 Spell Hit '), (11, 110, 33994, 9, '15 Spell Hit '),
(11, 110, 34001, 8, '12 Intellect '), (11, 110, 34001, 8, '12 Intellect '),
(11, 110, 34003, 14, '20 Spell Penetration '), (11, 110, 34003, 14, '20 Spell Penetration '),
(11, 110, 34010, 15, '81 Healing 27 Spelldamage '), (11, 110, 34010, 15, '81 Healing 27 Spelldamage '),
(11, 110, 35406, 2, '18 Spelldamage 10 Crit '), (11, 110, 35406, 2, '18 Spelldamage 10 Crit '),
(11, 110, 35447, 0, '22 Spelldamage 14 Hit '), (11, 110, 35447, 0, '22 Spelldamage 14 Hit '),
(11, 111, 22779, 17, '30 Hit '), (11, 111, 22779, 17, '30 Hit '),
(11, 111, 25080, 9, '15 Agility '), (11, 111, 25080, 9, '15 Agility '),
(11, 111, 27927, 10, '4 All Stats '), (11, 111, 27927, 10, '4 All Stats '),
(11, 111, 27927, 11, '4 All Stats '), (11, 111, 27927, 11, '4 All Stats '),
(11, 111, 27951, 7, '12 Agility'), (11, 111, 27951, 7, '12 Agility'),
(11, 111, 27960, 4, '6 All Stats '), (11, 111, 27960, 4, '6 All Stats '),
(11, 111, 29483, 2, '26 Attackpower 14 Crit '), (11, 111, 29483, 2, '26 Attackpower 14 Crit '),
(11, 111, 34002, 8, '24 Attackpower '), (11, 111, 34002, 8, '24 Attackpower '),
(11, 111, 34004, 14, '12 Agility '), (11, 111, 34004, 14, '12 Agility '),
(11, 111, 35452, 0, '34 Attackpower 16 Hit '), (11, 111, 35452, 0, '34 Attackpower 16 Hit '),
(11, 111, 35495, 6, '40 Stamina 12 Agility '), (11, 111, 35495, 6, '40 Stamina 12 Agility '),
(11, 111, 42620, 15, 'Greater Agility '), (11, 111, 42620, 15, 'Greater Agility '),
(11, 111, 42620, 16, 'Greater Agility '), (11, 111, 42620, 16, 'Greater Agility '),
(11, 112, 22779, 17, '30 Hit '), (11, 112, 22779, 17, '30 Hit '),
(11, 112, 27926, 10, '20 Healing 7 Spelldamage '), (11, 112, 27926, 10, '20 Healing 7 Spelldamage '),
(11, 112, 27926, 11, '20 Healing 7 Spelldamage '), (11, 112, 27926, 11, '20 Healing 7 Spelldamage '),
(11, 112, 27945, 16, '12 Intellect '), (11, 112, 27945, 16, '12 Intellect '),
(11, 112, 27954, 7, '5% Root/Snare Resist 10 Hit'), (11, 112, 27954, 7, '5% Root/Snare Resist 10 Hit'),
(11, 112, 27960, 4, '6 All Stats '), (11, 112, 27960, 4, '6 All Stats '),
(11, 112, 29475, 2, '31 Healing 11 Spelldamage 5 mp5 '), (11, 112, 29475, 2, '31 Healing 11 Spelldamage 5 mp5 '),
(11, 112, 31370, 6, '66 Healing 22 Spelldamage 20 Stamina '), (11, 112, 31370, 6, '66 Healing 22 Spelldamage 20 Stamina '),
(11, 112, 33999, 9, '35 Healing 12 Spelldamage '), (11, 112, 33999, 9, '35 Healing 12 Spelldamage '),
(11, 112, 34001, 8, '12 Intellect '), (11, 112, 34001, 8, '12 Intellect '),
(11, 112, 34003, 14, '20 Spell Penetration '), (11, 112, 34003, 14, '20 Spell Penetration '),
(11, 112, 34010, 15, '81 Healing 27 Spelldamage '), (11, 112, 34010, 15, '81 Healing 27 Spelldamage '),
(11, 112, 35445, 0, '35 Healing 12 Spelldamage 7 mp5 '); (11, 112, 35445, 0, '35 Healing 12 Spelldamage 7 mp5 ');
/*!40000 ALTER TABLE `playerbots_enchants` ENABLE KEYS */; /*!40000 ALTER TABLE `playerbots_enchants` ENABLE KEYS */;
/*!40101 SET SQL_MODE=IFNULL(@OLD_SQL_MODE, '') */; /*!40101 SET SQL_MODE=IFNULL(@OLD_SQL_MODE, '') */;

View File

@@ -7,278 +7,278 @@ CREATE TABLE IF NOT EXISTS `playerbots_weightscale_data` (
) ENGINE=InnoDB DEFAULT CHARSET=utf8; ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
INSERT INTO `playerbots_weightscale_data` (`id`, `field`, `val`) VALUES INSERT INTO `playerbots_weightscale_data` (`id`, `field`, `val`) VALUES
(1, 'exprtng', 100), (1, 'exprtng', 100),
(1, 'str', 82), (1, 'str', 82),
(1, 'critstrkrtng', 66), (1, 'critstrkrtng', 66),
(1, 'agi', 53), (1, 'agi', 53),
(1, 'armorpenrtng', 52), (1, 'armorpenrtng', 52),
(1, 'hitrtng', 48), (1, 'hitrtng', 48),
(1, 'hastertng', 36), (1, 'hastertng', 36),
(1, 'atkpwr', 31), (1, 'atkpwr', 31),
(1, 'armor', 5), (1, 'armor', 5),
(2, 'exprtng', 100), (2, 'exprtng', 100),
(2, 'str', 82), (2, 'str', 82),
(2, 'critstrkrtng', 66), (2, 'critstrkrtng', 66),
(2, 'agi', 53), (2, 'agi', 53),
(2, 'armorpenrtng', 52), (2, 'armorpenrtng', 52),
(2, 'hitrtng', 48), (2, 'hitrtng', 48),
(2, 'hastertng', 36), (2, 'hastertng', 36),
(2, 'atkpwr', 31), (2, 'atkpwr', 31),
(2, 'armor', 5), (2, 'armor', 5),
(3, 'sta', 100), (3, 'sta', 100),
(3, 'dodgertng', 90), (3, 'dodgertng', 90),
(3, 'defrtng', 86), (3, 'defrtng', 86),
(3, 'block', 81), (3, 'block', 81),
(3, 'agi', 67), (3, 'agi', 67),
(3, 'parryrtng', 67), (3, 'parryrtng', 67),
(3, 'blockrtng', 48), (3, 'blockrtng', 48),
(3, 'str', 48), (3, 'str', 48),
(3, 'exprtng', 19), (3, 'exprtng', 19),
(3, 'hitrtng', 10), (3, 'hitrtng', 10),
(3, 'armorpenrtng', 10), (3, 'armorpenrtng', 10),
(3, 'critstrkrtng', 7), (3, 'critstrkrtng', 7),
(3, 'armor', 6), (3, 'armor', 6),
(3, 'hastertng', 1), (3, 'hastertng', 1),
(3, 'atkpwr', 1), (3, 'atkpwr', 1),
(4, 'int', 100), (4, 'int', 100),
(4, 'manargn', 88), (4, 'manargn', 88),
(4, 'splpwr', 58), (4, 'splpwr', 58),
(4, 'critstrkrtng', 46), (4, 'critstrkrtng', 46),
(4, 'hastertng', 35), (4, 'hastertng', 35),
(5, 'sta', 100), (5, 'sta', 100),
(5, 'dodgertng', 94), (5, 'dodgertng', 94),
(5, 'block', 86), (5, 'block', 86),
(5, 'defrtng', 86), (5, 'defrtng', 86),
(5, 'exprtng', 79), (5, 'exprtng', 79),
(5, 'agi', 76), (5, 'agi', 76),
(5, 'parryrtng', 76), (5, 'parryrtng', 76),
(5, 'hitrtng', 58), (5, 'hitrtng', 58),
(5, 'blockrtng', 52), (5, 'blockrtng', 52),
(5, 'str', 50), (5, 'str', 50),
(5, 'armor', 6), (5, 'armor', 6),
(5, 'atkpwr', 6), (5, 'atkpwr', 6),
(5, 'splpwr', 4), (5, 'splpwr', 4),
(5, 'critstrkrtng', 3), (5, 'critstrkrtng', 3),
(6, 'mledps', 470), (6, 'mledps', 470),
(6, 'hitrtng', 100), (6, 'hitrtng', 100),
(6, 'str', 80), (6, 'str', 80),
(6, 'exprtng', 66), (6, 'exprtng', 66),
(6, 'critstrkrtng', 40), (6, 'critstrkrtng', 40),
(6, 'atkpwr', 34), (6, 'atkpwr', 34),
(6, 'agi', 32), (6, 'agi', 32),
(6, 'hastertng', 30), (6, 'hastertng', 30),
(6, 'armorpenrtng', 22), (6, 'armorpenrtng', 22),
(6, 'splpwr', 9), (6, 'splpwr', 9),
(7, 'rgddps', 213), (7, 'rgddps', 213),
(7, 'hitrtng', 100), (7, 'hitrtng', 100),
(7, 'agi', 58), (7, 'agi', 58),
(7, 'critstrkrtng', 40), (7, 'critstrkrtng', 40),
(7, 'int', 37), (7, 'int', 37),
(7, 'atkpwr', 30), (7, 'atkpwr', 30),
(7, 'armorpenrtng', 28), (7, 'armorpenrtng', 28),
(7, 'hastertng', 21), (7, 'hastertng', 21),
(8, 'rgddps', 379), (8, 'rgddps', 379),
(8, 'hitrtng', 100), (8, 'hitrtng', 100),
(8, 'agi', 74), (8, 'agi', 74),
(8, 'critstrkrtng', 57), (8, 'critstrkrtng', 57),
(8, 'armorpenrtng', 40), (8, 'armorpenrtng', 40),
(8, 'int', 39), (8, 'int', 39),
(8, 'atkpwr', 32), (8, 'atkpwr', 32),
(8, 'hastertng', 24), (8, 'hastertng', 24),
(9, 'rgddps', 181), (9, 'rgddps', 181),
(9, 'hitrtng', 100), (9, 'hitrtng', 100),
(9, 'agi', 76), (9, 'agi', 76),
(9, 'critstrkrtng', 42), (9, 'critstrkrtng', 42),
(9, 'int', 35), (9, 'int', 35),
(9, 'hastertng', 31), (9, 'hastertng', 31),
(9, 'atkpwr', 29), (9, 'atkpwr', 29),
(9, 'armorpenrtng', 26), (9, 'armorpenrtng', 26),
(10, 'mledps', 170), (10, 'mledps', 170),
(10, 'agi', 100), (10, 'agi', 100),
(10, 'exprtng', 87), (10, 'exprtng', 87),
(10, 'hitrtng', 83), (10, 'hitrtng', 83),
(10, 'critstrkrtng', 81), (10, 'critstrkrtng', 81),
(10, 'atkpwr', 65), (10, 'atkpwr', 65),
(10, 'armorpenrtng', 65), (10, 'armorpenrtng', 65),
(10, 'hastertng', 64), (10, 'hastertng', 64),
(10, 'str', 55), (10, 'str', 55),
(11, 'mledps', 220), (11, 'mledps', 220),
(11, 'armorpenrtng', 100), (11, 'armorpenrtng', 100),
(11, 'agi', 100), (11, 'agi', 100),
(11, 'exprtng', 82), (11, 'exprtng', 82),
(11, 'hitrtng', 80), (11, 'hitrtng', 80),
(11, 'critstrkrtng', 75), (11, 'critstrkrtng', 75),
(11, 'hastertng', 73), (11, 'hastertng', 73),
(11, 'str', 55), (11, 'str', 55),
(11, 'atkpwr', 50), (11, 'atkpwr', 50),
(12, 'mledps', 228), (12, 'mledps', 228),
(12, 'exprtng', 100), (12, 'exprtng', 100),
(12, 'agi', 100), (12, 'agi', 100),
(12, 'hitrtng', 80), (12, 'hitrtng', 80),
(12, 'armorpenrtng', 75), (12, 'armorpenrtng', 75),
(12, 'critstrkrtng', 75), (12, 'critstrkrtng', 75),
(12, 'hastertng', 75), (12, 'hastertng', 75),
(12, 'str', 55), (12, 'str', 55),
(12, 'atkpwr', 50), (12, 'atkpwr', 50),
(13, 'splpwr', 100), (13, 'splpwr', 100),
(13, 'manargn', 67), (13, 'manargn', 67),
(13, 'int', 65), (13, 'int', 65),
(13, 'hastertng', 59), (13, 'hastertng', 59),
(13, 'critstrkrtng', 48), (13, 'critstrkrtng', 48),
(13, 'spi', 22), (13, 'spi', 22),
(14, 'manargn', 100), (14, 'manargn', 100),
(14, 'int', 69), (14, 'int', 69),
(14, 'splpwr', 60), (14, 'splpwr', 60),
(14, 'spi', 52), (14, 'spi', 52),
(14, 'critstrkrtng', 38), (14, 'critstrkrtng', 38),
(14, 'hastertng', 31), (14, 'hastertng', 31),
(15, 'hitrtng', 100), (15, 'hitrtng', 100),
(15, 'shasplpwr', 76), (15, 'shasplpwr', 76),
(15, 'splpwr', 76), (15, 'splpwr', 76),
(15, 'critstrkrtng', 54), (15, 'critstrkrtng', 54),
(15, 'hastertng', 50), (15, 'hastertng', 50),
(15, 'spi', 16), (15, 'spi', 16),
(15, 'int', 16), (15, 'int', 16),
(16, 'mledps', 360), (16, 'mledps', 360),
(16, 'armorpenrtng', 100), (16, 'armorpenrtng', 100),
(16, 'str', 99), (16, 'str', 99),
(16, 'hitrtng', 91), (16, 'hitrtng', 91),
(16, 'exprtng', 90), (16, 'exprtng', 90),
(16, 'critstrkrtng', 57), (16, 'critstrkrtng', 57),
(16, 'hastertng', 55), (16, 'hastertng', 55),
(16, 'atkpwr', 36), (16, 'atkpwr', 36),
(16, 'armor', 1), (16, 'armor', 1),
(17, 'mledps', 337), (17, 'mledps', 337),
(17, 'hitrtng', 100), (17, 'hitrtng', 100),
(17, 'str', 97), (17, 'str', 97),
(17, 'exprtng', 81), (17, 'exprtng', 81),
(17, 'armorpenrtng', 61), (17, 'armorpenrtng', 61),
(17, 'critstrkrtng', 45), (17, 'critstrkrtng', 45),
(17, 'atkpwr', 35), (17, 'atkpwr', 35),
(17, 'hastertng', 28), (17, 'hastertng', 28),
(17, 'armor', 1), (17, 'armor', 1),
(18, 'mledps', 419), (18, 'mledps', 419),
(18, 'parryrtng', 100), (18, 'parryrtng', 100),
(18, 'hitrtng', 97), (18, 'hitrtng', 97),
(18, 'str', 96), (18, 'str', 96),
(18, 'defrtng', 85), (18, 'defrtng', 85),
(18, 'exprtng', 69), (18, 'exprtng', 69),
(18, 'dodgertng', 61), (18, 'dodgertng', 61),
(18, 'agi', 61), (18, 'agi', 61),
(18, 'sta', 61), (18, 'sta', 61),
(18, 'critstrkrtng', 49), (18, 'critstrkrtng', 49),
(18, 'atkpwr', 41), (18, 'atkpwr', 41),
(18, 'armorpenrtng', 31), (18, 'armorpenrtng', 31),
(18, 'armor', 5), (18, 'armor', 5),
(19, 'mledps', 209), (19, 'mledps', 209),
(19, 'str', 100), (19, 'str', 100),
(19, 'hitrtng', 66), (19, 'hitrtng', 66),
(19, 'exprtng', 51), (19, 'exprtng', 51),
(19, 'hastertng', 48), (19, 'hastertng', 48),
(19, 'critstrkrtng', 45), (19, 'critstrkrtng', 45),
(19, 'atkpwr', 34), (19, 'atkpwr', 34),
(19, 'armorpenrtng', 32), (19, 'armorpenrtng', 32),
(19, 'armor', 1), (19, 'armor', 1),
(20, 'hitrtng', 100), (20, 'hitrtng', 100),
(20, 'splpwr', 60), (20, 'splpwr', 60),
(20, 'hastertng', 56), (20, 'hastertng', 56),
(20, 'critstrkrtng', 40), (20, 'critstrkrtng', 40),
(20, 'int', 11), (20, 'int', 11),
(21, 'mledps', 135), (21, 'mledps', 135),
(21, 'hitrtng', 100), (21, 'hitrtng', 100),
(21, 'exprtng', 84), (21, 'exprtng', 84),
(21, 'agi', 55), (21, 'agi', 55),
(21, 'int', 55), (21, 'int', 55),
(21, 'critstrkrtng', 55), (21, 'critstrkrtng', 55),
(21, 'hastertng', 42), (21, 'hastertng', 42),
(21, 'str', 35), (21, 'str', 35),
(21, 'atkpwr', 32), (21, 'atkpwr', 32),
(21, 'splpwr', 29), (21, 'splpwr', 29),
(21, 'armorpenrtng', 26), (21, 'armorpenrtng', 26),
(22, 'manargn', 100), (22, 'manargn', 100),
(22, 'int', 85), (22, 'int', 85),
(22, 'splpwr', 77), (22, 'splpwr', 77),
(22, 'critstrkrtng', 62), (22, 'critstrkrtng', 62),
(22, 'hastertng', 35), (22, 'hastertng', 35),
(23, 'hitrtng', 100), (23, 'hitrtng', 100),
(23, 'hastertng', 54), (23, 'hastertng', 54),
(23, 'arcsplpwr', 49), (23, 'arcsplpwr', 49),
(23, 'splpwr', 49), (23, 'splpwr', 49),
(23, 'critstrkrtng', 37), (23, 'critstrkrtng', 37),
(23, 'int', 34), (23, 'int', 34),
(23, 'frosplpwr', 24), (23, 'frosplpwr', 24),
(23, 'firsplpwr', 24), (23, 'firsplpwr', 24),
(23, 'spi', 14), (23, 'spi', 14),
(24, 'hitrtng', 100), (24, 'hitrtng', 100),
(24, 'hastertng', 53), (24, 'hastertng', 53),
(24, 'firsplpwr', 46), (24, 'firsplpwr', 46),
(24, 'splpwr', 46), (24, 'splpwr', 46),
(24, 'critstrkrtng', 43), (24, 'critstrkrtng', 43),
(24, 'frosplpwr', 23), (24, 'frosplpwr', 23),
(24, 'arcsplpwr', 23), (24, 'arcsplpwr', 23),
(24, 'int', 13), (24, 'int', 13),
(25, 'hitrtng', 100), (25, 'hitrtng', 100),
(25, 'hastertng', 42), (25, 'hastertng', 42),
(25, 'frosplpwr', 39), (25, 'frosplpwr', 39),
(25, 'splpwr', 39), (25, 'splpwr', 39),
(25, 'arcsplpwr', 19), (25, 'arcsplpwr', 19),
(25, 'firsplpwr', 19), (25, 'firsplpwr', 19),
(25, 'critstrkrtng', 19), (25, 'critstrkrtng', 19),
(25, 'int', 6), (25, 'int', 6),
(26, 'hitrtng', 100), (26, 'hitrtng', 100),
(26, 'shasplpwr', 72), (26, 'shasplpwr', 72),
(26, 'splpwr', 72), (26, 'splpwr', 72),
(26, 'hastertng', 61), (26, 'hastertng', 61),
(26, 'critstrkrtng', 38), (26, 'critstrkrtng', 38),
(26, 'firsplpwr', 36), (26, 'firsplpwr', 36),
(26, 'spi', 34), (26, 'spi', 34),
(26, 'int', 15), (26, 'int', 15),
(27, 'hitrtng', 100), (27, 'hitrtng', 100),
(27, 'hastertng', 50), (27, 'hastertng', 50),
(27, 'firsplpwr', 45), (27, 'firsplpwr', 45),
(27, 'shasplpwr', 45), (27, 'shasplpwr', 45),
(27, 'splpwr', 45), (27, 'splpwr', 45),
(27, 'critstrkrtng', 31), (27, 'critstrkrtng', 31),
(27, 'spi', 29), (27, 'spi', 29),
(27, 'int', 13), (27, 'int', 13),
(28, 'hitrtng', 100), (28, 'hitrtng', 100),
(28, 'firsplpwr', 47), (28, 'firsplpwr', 47),
(28, 'splpwr', 47), (28, 'splpwr', 47),
(28, 'hastertng', 46), (28, 'hastertng', 46),
(28, 'spi', 26), (28, 'spi', 26),
(28, 'shasplpwr', 23), (28, 'shasplpwr', 23),
(28, 'critstrkrtng', 16), (28, 'critstrkrtng', 16),
(28, 'int', 13), (28, 'int', 13),
(29, 'hitrtng', 100), (29, 'hitrtng', 100),
(29, 'splpwr', 66), (29, 'splpwr', 66),
(29, 'hastertng', 54), (29, 'hastertng', 54),
(29, 'critstrkrtng', 43), (29, 'critstrkrtng', 43),
(29, 'spi', 22), (29, 'spi', 22),
(29, 'int', 22), (29, 'int', 22),
(30, 'agi', 100), (30, 'agi', 100),
(30, 'sta', 75), (30, 'sta', 75),
(30, 'dodgertng', 65), (30, 'dodgertng', 65),
(30, 'defrtng', 60), (30, 'defrtng', 60),
(30, 'exprtng', 16), (30, 'exprtng', 16),
(30, 'str', 10), (30, 'str', 10),
(30, 'armor', 10), (30, 'armor', 10),
(30, 'hitrtng', 8), (30, 'hitrtng', 8),
(30, 'hastertng', 5), (30, 'hastertng', 5),
(30, 'atkpwr', 4), (30, 'atkpwr', 4),
(30, 'feratkpwr', 4), (30, 'feratkpwr', 4),
(30, 'critstrkrtng', 3), (30, 'critstrkrtng', 3),
(31, 'splpwr', 100), (31, 'splpwr', 100),
(31, 'manargn', 73), (31, 'manargn', 73),
(31, 'hastertng', 57), (31, 'hastertng', 57),
(31, 'int', 51), (31, 'int', 51),
(31, 'spi', 32), (31, 'spi', 32),
(31, 'critstrkrtng', 11), (31, 'critstrkrtng', 11),
(32, 'agi', 100), (32, 'agi', 100),
(32, 'armorpenrtng', 90), (32, 'armorpenrtng', 90),
(32, 'str', 80), (32, 'str', 80),
(32, 'critstrkrtng', 55), (32, 'critstrkrtng', 55),
(32, 'exprtng', 50), (32, 'exprtng', 50),
(32, 'hitrtng', 50), (32, 'hitrtng', 50),
(32, 'feratkpwr', 40), (32, 'feratkpwr', 40),
(32, 'atkpwr', 40), (32, 'atkpwr', 40),
(32, 'hastertng', 35); (32, 'hastertng', 35);

View File

@@ -7,35 +7,35 @@ CREATE TABLE IF NOT EXISTS `playerbots_weightscales` (
) ENGINE=InnoDB AUTO_INCREMENT=33 DEFAULT CHARSET=utf8 ROW_FORMAT=COMPACT; ) ENGINE=InnoDB AUTO_INCREMENT=33 DEFAULT CHARSET=utf8 ROW_FORMAT=COMPACT;
INSERT INTO `playerbots_weightscales` (`id`, `name`, `class`) VALUES INSERT INTO `playerbots_weightscales` (`id`, `name`, `class`) VALUES
(1, 'arms', 1), (1, 'arms', 1),
(2, 'fury', 1), (2, 'fury', 1),
(3, 'prot', 1), (3, 'prot', 1),
(4, 'holy', 2), (4, 'holy', 2),
(5, 'prot', 2), (5, 'prot', 2),
(6, 'retrib', 2), (6, 'retrib', 2),
(7, 'beast', 3), (7, 'beast', 3),
(8, 'marks', 3), (8, 'marks', 3),
(9, 'surv', 3), (9, 'surv', 3),
(10, 'assas', 4), (10, 'assas', 4),
(11, 'combat', 4), (11, 'combat', 4),
(12, 'subtle', 4), (12, 'subtle', 4),
(13, 'disc', 5), (13, 'disc', 5),
(14, 'holy', 5), (14, 'holy', 5),
(15, 'shadow', 5), (15, 'shadow', 5),
(16, 'blooddps', 6), (16, 'blooddps', 6),
(17, 'frostdps', 6), (17, 'frostdps', 6),
(18, 'frosttank', 6), (18, 'frosttank', 6),
(19, 'unholydps', 6), (19, 'unholydps', 6),
(20, 'elem', 7), (20, 'elem', 7),
(21, 'enhance', 7), (21, 'enhance', 7),
(22, 'resto', 7), (22, 'resto', 7),
(23, 'arcane', 8), (23, 'arcane', 8),
(24, 'fire', 8), (24, 'fire', 8),
(25, 'frost', 8), (25, 'frost', 8),
(26, 'afflic', 9), (26, 'afflic', 9),
(27, 'demo', 9), (27, 'demo', 9),
(28, 'destro', 9), (28, 'destro', 9),
(29, 'balance', 11), (29, 'balance', 11),
(30, 'feraltank', 11), (30, 'feraltank', 11),
(31, 'resto', 11), (31, 'resto', 11),
(32, 'feraldps', 11); (32, 'feraldps', 11);

View File

@@ -24,9 +24,9 @@ CREATE TABLE IF NOT EXISTS `updates_include` (
DELETE FROM `updates_include`; DELETE FROM `updates_include`;
/*!40000 ALTER TABLE `updates_include` DISABLE KEYS */; /*!40000 ALTER TABLE `updates_include` DISABLE KEYS */;
INSERT INTO `updates_include` (`path`, `state`) VALUES INSERT INTO `updates_include` (`path`, `state`) VALUES
('$/data/sql/playerbots/updates', 'RELEASED'), ('$/data/sql/playerbots/updates', 'RELEASED'),
('$/data/sql/playerbots/custom', 'CUSTOM'), ('$/data/sql/playerbots/custom', 'CUSTOM'),
('$/data/sql/playerbots/archive', 'ARCHIVED'); ('$/data/sql/playerbots/archive', 'ARCHIVED');
/*!40000 ALTER TABLE `updates_include` ENABLE KEYS */; /*!40000 ALTER TABLE `updates_include` ENABLE KEYS */;
/*!40101 SET SQL_MODE=IFNULL(@OLD_SQL_MODE, '') */; /*!40101 SET SQL_MODE=IFNULL(@OLD_SQL_MODE, '') */;

View File

@@ -1285,7 +1285,7 @@ CREATE TABLE IF NOT EXISTS `ai_playerbot_texts_chance` (
/*!40000 ALTER TABLE `ai_playerbot_texts_chance` DISABLE KEYS */; /*!40000 ALTER TABLE `ai_playerbot_texts_chance` DISABLE KEYS */;
INSERT INTO `ai_playerbot_texts_chance` (`id`, `name`, `probability`) VALUES INSERT INTO `ai_playerbot_texts_chance` (`id`, `name`, `probability`) VALUES
(1, 'taunt', 30), (1, 'taunt', 30),
(2, 'aoe', 75), (2, 'aoe', 75),
(3, 'loot', 20); (3, 'loot', 20);
/*!40000 ALTER TABLE `ai_playerbot_texts_chance` ENABLE KEYS */; /*!40000 ALTER TABLE `ai_playerbot_texts_chance` ENABLE KEYS */;

View File

@@ -0,0 +1,849 @@
UPDATE `ai_playerbot_texts` SET `text_loc8` = "посреди нигде" WHERE `id` = 1;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "в неопределенном месте" WHERE `id` = 2;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "где-то" WHERE `id` = 3;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "что-то" WHERE `id` = 4;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "интересно, какой на вкус %item_link" WHERE `id` = 5;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "нет, мне выпал %item_link" WHERE `id` = 6;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "опять этот хлам %item_link" WHERE `id` = 7;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "похоже, я лутаю мусор %item_link" WHERE `id` = 8;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "ну, лучше чем ничего, наверное %item_link" WHERE `id` = 9;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "не знаю, что делать с %item_link" WHERE `id` = 10;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "интересно, какой на вкус %item_link" WHERE `id` = 11;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "могу лутать %item_link весь день" WHERE `id` = 12;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "еще один день, еще один %item_link" WHERE `id` = 13;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "получил немного %item_link" WHERE `id` = 14;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "немного %item_link — это нормально" WHERE `id` = 15;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "неплохо, только что получил %item_link" WHERE `id` = 16;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "только что залутал %item_link в %zone_name" WHERE `id` = 17;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "могу найти применение %item_link" WHERE `id` = 18;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "деньги, деньги, деньги %item_link" WHERE `id` = 19;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "получил %item_link" WHERE `id` = 20;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "%item_link — лучший для охотника" WHERE `id` = 21;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "%item_link — лучший для %my_class" WHERE `id` = 22;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "сегодня удача на моей стороне %item_link" WHERE `id` = 23;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "классный %item_link, только что залутал" WHERE `id` = 24;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "вау, только что получил %item_link" WHERE `id` = 25;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "%item_link — лучший для охотника" WHERE `id` = 26;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "%item_link — лучший для %my_class" WHERE `id` = 27;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "сегодня удача на моей стороне %item_link" WHERE `id` = 28;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "классный %item_link, только что залутал" WHERE `id` = 29;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "ОГО, посмотрите, что я только что получил %item_link!!!" WHERE `id` = 30;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Нет @#$@%! Не может быть, я получил %item_link, это безумие" WHERE `id` = 31;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Нет @#$@%! Не может быть, я получил %item_link, это безумие" WHERE `id` = 32;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Я только что взял %quest_link" WHERE `id` = 33;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "только что принял %quest_link" WHERE `id` = 34;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "%quest_link попробую выполнить это задание" WHERE `id` = 35;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "взял %quest_link в %zone_name" WHERE `id` = 36;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Наконец-то закончил %quest_obj_name для %quest_link" WHERE `id` = 37;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "наконец-то получил %quest_obj_available/%quest_obj_required %quest_obj_name для %quest_link" WHERE `id` = 38;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "%quest_obj_full_formatted для %quest_link, наконец-то" WHERE `id` = 39;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Ох, получил %quest_obj_available/%quest_obj_required %quest_obj_name для %quest_link" WHERE `id` = 40;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "еще нужно %quest_obj_missing %quest_obj_name для %quest_link" WHERE `id` = 41;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "%quest_obj_full_formatted, все еще работаю над %quest_link" WHERE `id` = 42;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Наконец-то закончил с %item_link для %quest_link" WHERE `id` = 43;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "наконец-то получил %quest_obj_available/%quest_obj_required %item_link для %quest_link" WHERE `id` = 44;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "%quest_obj_full_formatted для %quest_link, наконец-то" WHERE `id` = 45;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Ох, получил %quest_obj_available/%quest_obj_required %item_link для %quest_link" WHERE `id` = 46;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "еще нужно %quest_obj_missing %item_link для %quest_link" WHERE `id` = 47;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "%quest_obj_full_formatted, все еще работаю над %quest_link" WHERE `id` = 48;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Не успел завершить %quest_link вовремя..." WHERE `id` = 49;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Время для %quest_link вышло :(" WHERE `id` = 50;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Я выполнил все задачи для %quest_link" WHERE `id` = 51;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Выполнил все задачи для %quest_link" WHERE `id` = 52;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Скоро сдам %quest_link, только что закончил все задачи" WHERE `id` = 53;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Да, наконец-то сдал %quest_link" WHERE `id` = 54;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "сдал %quest_link" WHERE `id` = 55;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "смог завершить %quest_link, только что сдал" WHERE `id` = 56;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "только что сдал %quest_link" WHERE `id` = 57;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "только что сдал %quest_link в %zone_name" WHERE `id` = 58;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "еще одна жертва — %victim_name" WHERE `id` = 59;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Я продолжаю убивать %victim_name, нечего рассказывать" WHERE `id` = 60;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "еще один %victim_name пал" WHERE `id` = 61;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "минус один %victim_name в %zone_name" WHERE `id` = 62;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Убил этого элитного ублюдка %victim_name!" WHERE `id` = 63;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "убил элиту %victim_name в %zone_name" WHERE `id` = 64;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Фух, удалось завалить %victim_name!" WHERE `id` = 65;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Это было круто! Только что убил %victim_name! Теперь есть что рассказать" WHERE `id` = 66;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Йо, я только что убил %victim_name!" WHERE `id` = 67;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "убил редкого %victim_name в %zone_name" WHERE `id` = 68;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Что я только что убил? %victim_name" WHERE `id` = 69;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Только что убил этого пета %victim_name" WHERE `id` = 70;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "О да, только что убил %victim_name" WHERE `id` = 71;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "убил %victim_name в %zone_name" WHERE `id` = 72;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Динг!" WHERE `id` = 73;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Да, я теперь %my_level уровень!" WHERE `id` = 74;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Я только что повысил уровень" WHERE `id` = 75;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Я %my_level уровень!!!" WHERE `id` = 76;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Становлюсь сильнее, уже %my_level уровень!!!" WHERE `id` = 77;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Только что достиг %my_level уровня!!!" WHERE `id` = 78;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "ОГО, наконец-то %my_level уровень!!!" WHERE `id` = 79;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "%my_level!!! теперь могу заниматься эндгейм-контентом" WHERE `id` = 80;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "свежий новый уровень %my_level %my_class!!!" WHERE `id` = 81;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "еще один уровень %my_level %my_race %my_class!" WHERE `id` = 82;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Молодец %other_name. Ты это заслужил." WHERE `id` = 83;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Это было ужасно %other_name. Не хотел этого делать, но..." WHERE `id` = 84;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Кому нужен %instance_name?" WHERE `id` = 85;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Есть группы в %instance_name?" WHERE `id` = 86;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Нужна помощь в %instance_name?" WHERE `id` = 87;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "ЛФД: %instance_name." WHERE `id` = 88;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Кому нужен %my_role для %instance_name?" WHERE `id` = 89;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Не хватает %my_role для %instance_name?" WHERE `id` = 90;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Могу быть %my_role для %instance_name." WHERE `id` = 91;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Нужна помощь с %instance_name?" WHERE `id` = 92;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Нужна помощь %my_role с %instance_name?" WHERE `id` = 93;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Кому нужен шмот из %instance_name?" WHERE `id` = 94;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Немного пофармить в %instance_name?" WHERE `id` = 95;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Ищу %instance_name" WHERE `id` = 96;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Нужна помощь в %instance_name." WHERE `id` = 97;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Хочу пройти %instance_name." WHERE `id` = 98;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "%my_role ищет %instance_name." WHERE `id` = 99;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Как насчет %instance_name?" WHERE `id` = 100;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Кто хочет пофармить %instance_name?" WHERE `id` = 101;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Пойдем в %instance_name?" WHERE `id` = 102;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Ищу %instance_name." WHERE `id` = 103;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Нужна помощь с квестами в %instance_name?" WHERE `id` = 104;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Хочу квестить в %instance_name." WHERE `id` = 105;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Кто-то с квестами в %instance_name?" WHERE `id` = 106;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Могу помочь с квестами в %instance_name." WHERE `id` = 107;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "%my_role: есть место в группе для %instance_name?" WHERE `id` = 108;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Кто-нибудь еще ходит в %instance_name в наши дни?" WHERE `id` = 109;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "%instance_name: кто хочет взять %my_role?" WHERE `id` = 110;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Есть ли смысл быть %my_role в %instance_name?" WHERE `id` = 111;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Стоит ли идти в %instance_name?" WHERE `id` = 112;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Кому нужны еще люди для %instance_name?" WHERE `id` = 113;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "В %instance_name боссы дропают хороший шмот. Пойдем?" WHERE `id` = 114;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Как насчет %instance_name?" WHERE `id` = 115;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Кому нужен %my_role?" WHERE `id` = 116;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Кому нужен %my_role?" WHERE `id` = 117;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Кто хочет %instance_name?" WHERE `id` = 118;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Кто может призвать меня в %instance_name?" WHERE `id` = 119;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Встретимся в %instance_name" WHERE `id` = 120;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Хочу быструю пробежку %instance_name" WHERE `id` = 121;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Хочу полный забег %instance_name" WHERE `id` = 122;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Сколько раз ты был в %instance_name?" WHERE `id` = 123;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Еще один забег в %instance_name?" WHERE `id` = 124;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Вайпнулись в %instance_name? Возьмите меня!" WHERE `id` = 125;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Возьмите меня в %instance_name, пожалуйста." WHERE `id` = 126;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Быстрый забег в %instance_name?" WHERE `id` = 127;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Полный забег в %instance_name?" WHERE `id` = 128;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Кто может взять %my_role в %instance_name?" WHERE `id` = 129;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "ЛФГ %instance_name, я %my_role" WHERE `id` = 130;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "%my_role ЛФГ %instance_name" WHERE `id` = 131;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Нужна помощь с %quest_link?" WHERE `id` = 132;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Кто хочет поделиться %quest_link?" WHERE `id` = 133;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Кто делает %quest_link?" WHERE `id` = 134;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Хочу сделать %quest_link." WHERE `id` = 135;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Кто хочет пофармить %category?" WHERE `id` = 136;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Ищу помощь для фарма %category." WHERE `id` = 137;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Черт, %category такие дорогие!" WHERE `id` = 138;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Хочу %category." WHERE `id` = 139;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Нужна помощь с %category." WHERE `id` = 140;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Куплю %category." WHERE `id` = 141;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Кому интересно %category?" WHERE `id` = 142;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Продам %category." WHERE `id` = 143;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Продаю %category дешевле, чем на Аукционе." WHERE `id` = 144;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Кто хочет пофармить %category?" WHERE `id` = 145;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Хочу пофармить %category." WHERE `id` = 146;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Ищу пати после %category." WHERE `id` = 147;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Любые %category приветствуются." WHERE `id` = 148;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Куплю что угодно из %category." WHERE `id` = 149;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Вау, кто-то фармит %category!" WHERE `id` = 150;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "%category отлично продаются на аукционе." WHERE `id` = 151;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Аукцион горячий по %category." WHERE `id` = 152;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "%category на рынке." WHERE `id` = 153;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Хочу обменять немного %category." WHERE `id` = 154;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Нужно больше %category." WHERE `id` = 155;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Кто-нибудь может поделиться %category?" WHERE `id` = 156;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Кто хочет %category?" WHERE `id` = 157;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Немного %category, пожалуйста?" WHERE `id` = 158;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Надо было прокачать навык для %category." WHERE `id` = 159;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Очень хочу %category." WHERE `id` = 160;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Люди убивают ради %category." WHERE `id` = 161;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "%category — отличная сделка!" WHERE `id` = 162;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Все сходят с ума по %category!" WHERE `id` = 163;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Где лучше всего фармить %category?" WHERE `id` = 164;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Я полностью готов к %category." WHERE `id` = 165;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Выгодно ли продавать %category?" WHERE `id` = 166;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Наверное, я бы оставил все свои %category себе." WHERE `id` = 167;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Нужна группа? Может, пофармить %category?" WHERE `id` = 168;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Все еще думаю о %category." WHERE `id` = 169;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Я уже слышал о %category, но карманы пусты." WHERE `id` = 170;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "ЛФГ для %category" WHERE `id` = 171;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Сделает ли продажа %category меня богатым?" WHERE `id` = 172;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "ОК. Завтра фармлю %category." WHERE `id` = 173;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Все говорят о %category." WHERE `id` = 174;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Видел как минимум десять человек, фармящих %category." WHERE `id` = 175;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Вчера продал все свои %category. Теперь я полностью на мели!" WHERE `id` = 176;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Хочу вступить в гильдию, фармящую %category." WHERE `id` = 177;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Кто фармит репутацию %faction?" WHERE `id` = 178;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Кто поможет с %faction?" WHERE `id` = 179;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Хочу квестить ради %faction." WHERE `id` = 180;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "%faction — лучшая." WHERE `id` = 181;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Нужно чуть-чуть, чтобы стать %rep_level у %faction." WHERE `id` = 182;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Кто-нибудь уже %rep_level у %faction?" WHERE `id` = 183;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Кто хочет стать %rep_level у %faction?" WHERE `id` = 184;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Я никогда не стану %rep_level у %faction." WHERE `id` = 185;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Кто-то не хватает репы у %faction?" WHERE `id` = 186;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Могу помочь с фармом репы %faction." WHERE `id` = 187;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Чем больше репы, тем лучше. Особенно у %faction." WHERE `id` = 188;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "%faction: нужно %rndK для %rep_level." WHERE `id` = 189;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Кто может поделиться квестами %faction?" WHERE `id` = 190;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Есть подземелья для %faction?" WHERE `id` = 191;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Хочу фармить репу %faction." WHERE `id` = 192;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Давайте фармить репу %faction!" WHERE `id` = 193;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Фармлю репу %faction." WHERE `id` = 194;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Хочу пофармить %faction." WHERE `id` = 195;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Нужна помощь с %faction." WHERE `id` = 196;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "%faction что-то полезное продает?" WHERE `id` = 197;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Есть ли у %faction торговцы?" WHERE `id` = 198;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Кто фармит %faction?" WHERE `id` = 199;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Как лучше всего фармить %faction?" WHERE `id` = 200;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Ненавижу фарм репы %faction." WHERE `id` = 201;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Я так устал от %faction." WHERE `id` = 202;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Пойдем за %faction?" WHERE `id` = 203;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Кажется, все уже %rep_level у %faction. Только я, как обычно, опаздываю." WHERE `id` = 204;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "ЛФГ для фарма репы %faction?" WHERE `id` = 205;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Кто-нибудь подскажет хорошее место для фарма репы %faction?" WHERE `id` = 206;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Будет ли польза от репы %faction?" WHERE `id` = 207;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Кто бы мог подумать, что репа %faction окажется полезной..." WHERE `id` = 208;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Хочу быть превознесенным у всех фракций, начну с %faction." WHERE `id` = 209;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Есть ли смысл повышать репу с %faction?" WHERE `id` = 210;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Что лучше для %faction? Квесты или фарм мобов?" WHERE `id` = 211;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Пофармлю репу %faction для тебя. Только дай немного золота." WHERE `id` = 212;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Думаю, фармить репу %faction — это навсегда." WHERE `id` = 213;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Я убиваю ради %faction каждый день, но все еще далеко до %rep_level." WHERE `id` = 214;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "На %my_level депозиты на аукционе уменьшатся, да?" WHERE `id` = 215;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Сколько у тебя превознесенных реп?" WHERE `id` = 216;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Кто хочет быть %my_level у %faction?" WHERE `id` = 217;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Черт. Моя гильдия вчера хорошо пофармила %faction без меня." WHERE `id` = 218;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Никто не хочет мне помогать, потому что я %rep_level у %faction." WHERE `id` = 219;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Пожалуйста, держись подальше от %faction." WHERE `id` = 220;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Хочу в пати в %zone_name." WHERE `id` = 221;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Кто ищет %my_role?" WHERE `id` = 222;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "%my_role ищет гильдию." WHERE `id` = 223;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Ищу золото." WHERE `id` = 224;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "%my_role хочет вступить в хорошую гильдию." WHERE `id` = 225;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Нужен друг." WHERE `id` = 226;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Кто-нибудь чувствует себя одиноко?" WHERE `id` = 227;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Скучно..." WHERE `id` = 228;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Кто хочет немного?" WHERE `id` = 229;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Давай, поймай меня!" WHERE `id` = 230;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Может, дуэль в %zone_name?" WHERE `id` = 231;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Кто-нибудь что-то делает?" WHERE `id` = 232;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "%zone_name: кто-нибудь здесь есть?" WHERE `id` = 233;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "%zone_name: где все?" WHERE `id` = 234;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Похоже, я один в %zone_name." WHERE `id` = 235;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Встретимся в %zone_name." WHERE `id` = 236;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Давайте квестить в %zone_name!" WHERE `id` = 237;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "%zone_name — лучшее место!" WHERE `id` = 238;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Хочу в %zone_name. Кто со мной?" WHERE `id` = 239;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Кто хочет пойти в %zone_name?" WHERE `id` = 240;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Мне не нравится %zone_name. Куда пойти?" WHERE `id` = 241;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Есть хорошие квесты в %zone_name?" WHERE `id` = 242;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Куда идти после %zone_name?" WHERE `id` = 243;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Кто в %zone_name?" WHERE `id` = 244;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "ЛФГ в %zone_name." WHERE `id` = 245;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "%zone_name — худшее место." WHERE `id` = 246;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Лови меня в %zone_name!" WHERE `id` = 247;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Пойдем в %zone_name!" WHERE `id` = 248;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Хочу квестить в %zone_name" WHERE `id` = 249;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "У кого есть квесты в %zone_name?" WHERE `id` = 250;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Приходите сюда, в %zone_name!" WHERE `id` = 251;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Похоже, в %zone_name нет Орды" WHERE `id` = 252;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Похоже, в %zone_name нет Альянса" WHERE `id` = 253;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Я очень устал от %zone_name. Может, пойти куда-нибудь еще?" WHERE `id` = 254;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Удачи" WHERE `id` = 255;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Хочу домой, а потом на край" WHERE `id` = 256;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Кто-нибудь знает, что нужно для двуручного боя?" WHERE `id` = 257;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Всем привет!" WHERE `id` = 258;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "%zone_name уютно" WHERE `id` = 259;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Я отлично себя чувствую" WHERE `id` = 260;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Я не игнорирую людей, я троллю их, пока они не проигнорируют меня" WHERE `id` = 261;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Что думаете о моей сборке? %my_role" WHERE `id` = 262;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Рад видеть, что чат еще помнит" WHERE `id` = 263;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Как и все оружие — это лучший для охотника" WHERE `id` = 264;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Вся суть игры для меня — соло и поиск новых способов соло" WHERE `id` = 265;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Я НИКОГДА никого не обманывал" WHERE `id` = 266;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Ах да, мир варкрафта, где я ищу жизненные советы" WHERE `id` = 267;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "АЛЛО?" WHERE `id` = 268;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Пора пробиваться в %zone_name" WHERE `id` = 269;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "%zone_name" WHERE `id` = 270;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "надо в туалет" WHERE `id` = 271;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Если не лутать скинируемых мобов, твой пп уменьшится на 1мм навсегда" WHERE `id` = 272;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "НЕТТТТТТТТТТ" WHERE `id` = 273;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Я ЛЮБЛЮ КАРТОШКУ" WHERE `id` = 274;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "w чат" WHERE `id` = 275;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "привет, как дела" WHERE `id` = 276;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "только что вышел и снова зашел" WHERE `id` = 277;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "можете потише, я заблудился в %zone_name" WHERE `id` = 278;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "кто хочет выпить со мной в %zone_name ... ик!" WHERE `id` = 279;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "хахахахахииииииии дирин диринг инггггг хахахахахииииииииииииии" WHERE `id` = 280;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "раньше приманка была правдоподобной" WHERE `id` = 281;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "может, ты просто потерял невинность" WHERE `id` = 282;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "есть гильдии, готовые тащить %my_role?" WHERE `id` = 283;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "чем выше уровень, тем легче золото" WHERE `id` = 284;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "утро" WHERE `id` = 285;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "почему у меня болит задница?" WHERE `id` = 286;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Мне кажется, дух — лучший для прокачки" WHERE `id` = 287;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Особенно для тролля" WHERE `id` = 288;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "КТО-НИБУДЬ ПРИГЛАСИТЕ МЕНЯ" WHERE `id` = 289;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "нужно много выпивки" WHERE `id` = 290;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "чертовы гномы" WHERE `id` = 291;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "никто не любит гномов" WHERE `id` = 292;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "гномы годятся только для одного" WHERE `id` = 293;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Ну" WHERE `id` = 294;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "грибы" WHERE `id` = 295;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "автоматические мысли — страшная вещь" WHERE `id` = 296;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "ум более гибок, чем нам кажется" WHERE `id` = 297;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "есть гильдии для прокачки?" WHERE `id` = 298;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "брб" WHERE `id` = 299;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Почему снег белый, а лед прозрачный? Ведь это одно и то же" WHERE `id` = 300;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "почему взбитые сливки пышные, а обычные нет" WHERE `id` = 301;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "почему ноги пахнут, если у них нет носа" WHERE `id` = 302;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "похоже, прибыла банка новичков" WHERE `id` = 303;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "хватит троллить новичков бредовыми ответами" WHERE `id` = 304;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "На этом сервере есть PvP?" WHERE `id` = 305;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "угу" WHERE `id` = 306;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "фух... :)" WHERE `id` = 307;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "вы знали что" WHERE `id` = 308;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "я не пытаюсь представить, что чувствуют другие существа" WHERE `id` = 309;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "ой, не тот чат" WHERE `id` = 310;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "бро, вы сегодня отжигаете" WHERE `id` = 311;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "пусть все знают, что мой текст был здесь" WHERE `id` = 312;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "гррр злой" WHERE `id` = 313;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "гринд — это весело" WHERE `id` = 314;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Wow держит меня в тонусе" WHERE `id` = 315;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "у меня вопрос: где можно взять бросок на больше опыта? я в %zone_name" WHERE `id` = 316;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "вы любите сосиски?" WHERE `id` = 317;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Пригласите меня. Я помогу" WHERE `id` = 318;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "какой класс лучше для пвп?" WHERE `id` = 319;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "где, черт возьми, тренер кулинарии в %zone_name" WHERE `id` = 320;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "знаете, что происходит в %zone_name?" WHERE `id` = 321;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Мне нужно что-то скрафтить" WHERE `id` = 322;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "что такое лигма" WHERE `id` = 323;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "что такое сугма" WHERE `id` = 324;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "лима болс" WHERE `id` = 325;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "сугма болс" WHERE `id` = 326;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Я ЕМ ЗАДНИЦУ" WHERE `id` = 327;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Я хочу засунуть %random_inventory_item_link себе в задницу" WHERE `id` = 328;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Я хочу засунуть %random_inventory_item_link тебе в задницу" WHERE `id` = 329;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Дарнасс" WHERE `id` = 330;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "похоже, у тебя сугма" WHERE `id` = 331;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "дииз натс в твой рот" WHERE `id` = 332;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "крутой стояк, бро" WHERE `id` = 333;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "ERP?" WHERE `id` = 334;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "я перепробовал все, но в итоге ERP помог" WHERE `id` = 335;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Хочу заняться этим в %zone_name" WHERE `id` = 336;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "ищу гнома-девушку с гориллой для ERP в %zone_name" WHERE `id` = 337;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "я могу понять засранца, но извращенца?" WHERE `id` = 338;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "в %zone_name нет гят" WHERE `id` = 339;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Я убиваю всех животных в %zone_name. К черту животных!!!" WHERE `id` = 340;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "хорошо, что у меня три ноги" WHERE `id` = 341;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "не злись, я гоиню как сигма" WHERE `id` = 342;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "попробуй палец, но дырку" WHERE `id` = 343;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "%prefix %random_taken_quest_or_item_link" WHERE `id` = 344;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "%prefix %random_inventory_item_link" WHERE `id` = 345;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "%thunderfury_link" WHERE `id` = 346;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "%thunderfury_link%thunderfury_link" WHERE `id` = 347;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "%thunderfury_link%thunderfury_link%thunderfury_link" WHERE `id` = 348;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Кажется, я только что услышал %thunderfury_link" WHERE `id` = 349;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Кажется, я слышал %thunderfury_link" WHERE `id` = 350;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Я точно слышал %thunderfury_link" WHERE `id` = 351;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Не знаю, но уверен, что слышал %thunderfury_link" WHERE `id` = 352;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Ты только что сказал %thunderfury_link" WHERE `id` = 353;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "кто-то сказал %thunderfury_link" WHERE `id` = 354;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Кто-то сказал %thunderfury_link?" WHERE `id` = 355;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Кто-то сказал %thunderfury_link" WHERE `id` = 356;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "%thunderfury_link выходит из шкафа" WHERE `id` = 357;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "мог бы поклясться, что это был %thunderfury_link, хотя, может, и %thunderfury_link" WHERE `id` = 358;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Зачем использовать %thunderfury_link, если %thunderfury_link явно круче" WHERE `id` = 359;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Продаю %item_formatted_link за %cost_gold." WHERE `id` = 360;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Кто хочет %item_formatted_link за %cost_gold?" WHERE `id` = 361;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Кому нужен %item_formatted_link? Всего %cost_gold." WHERE `id` = 362;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Всего %cost_gold за %item_formatted_link!" WHERE `id` = 363;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Продаю %item_formatted_link за %cost_gold." WHERE `id` = 364;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "%item_formatted_link твой всего за %cost_gold!" WHERE `id` = 365;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Смешная цена %cost_gold за %item_formatted_link!" WHERE `id` = 366;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Хочу продать %item_formatted_link за %cost_gold." WHERE `id` = 367;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Кому нужен %item_formatted_link? Всего %cost_gold." WHERE `id` = 368;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Кому нужен %item_formatted_link за %cost_gold?" WHERE `id` = 369;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "%cost_gold за %item_formatted_link. Дешевле, чем на аукционе!" WHERE `id` = 370;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "%item_formatted_link дорогой, но я бы продал за %cost_gold." WHERE `id` = 371;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Ты нигде не найдешь %item_formatted_link дешевле, чем за %cost_gold!" WHERE `id` = 372;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Нужно больше, чем %item_formatted_link!" WHERE `id` = 373;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "У меня есть %item_formatted_link и нужно еще." WHERE `id` = 374;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Есть %item_formatted_link. Кто хочет купить за %cost_gold?" WHERE `id` = 375;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Кто хочет купить %item_formatted_link за %cost_gold?" WHERE `id` = 376;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Как насчет %item_formatted_link? За %cost_gold." WHERE `id` = 377;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Кто сказал, что я ублюдок? %item_formatted_link за %cost_gold — хорошая цена." WHERE `id` = 378;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Продаю %item_formatted_link? Всего %cost_gold." WHERE `id` = 379;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "ЛФГ для фарма. Все еще можешь купить %item_formatted_link у меня за %cost_gold." WHERE `id` = 380;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Сегодня почти все продал. Еще есть %item_formatted_link за %cost_gold." WHERE `id` = 381;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Для чего нужен торговый чат? Конечно, чтобы продавать %item_formatted_link за %cost_gold." WHERE `id` = 382;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Кто перебьет цену %cost_gold за %item_formatted_link?" WHERE `id` = 383;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Хочешь прекратить торговый чат? Просто купи %item_formatted_link за %cost_gold!" WHERE `id` = 384;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Все спамят в торговом чате. Я тоже — %cost_gold за %item_formatted_link!" WHERE `id` = 385;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Есть ли польза от %item_formatted_link? Просто продаю за %cost_gold." WHERE `id` = 386;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "У меня есть %item_formatted_link, готов продать за %cost_gold." WHERE `id` = 387;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Вчера ничего не делал, но получил %item_formatted_link. Продаю за %cost_gold." WHERE `id` = 388;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Вчера фармил и получил %item_formatted_link. Кто купит за %cost_gold?" WHERE `id` = 389;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Вчера купил %item_formatted_link. Кому нужно за %cost_gold?" WHERE `id` = 390;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Кто спрашивал про %item_formatted_link? Цена та же — %cost_gold." WHERE `id` = 391;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "У меня еще есть %item_formatted_link. Купишь за %cost_gold?" WHERE `id` = 392;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Раньше было больше, чем %item_formatted_link. Теперь нужно продать за %cost_gold." WHERE `id` = 393;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Хотел бы иметь больше, чем %item_formatted_link. Но можешь купить за %cost_gold." WHERE `id` = 394;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Для чего твое золото? Чтобы купить мой %item_formatted_link за %cost_gold." WHERE `id` = 395;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Пожалуйста, подкинь немного золота. Можешь купить %item_formatted_link за %cost_gold." WHERE `id` = 396;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "%cost_gold — хорошая цена за %item_formatted_link?" WHERE `id` = 397;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Вчера купил %item_formatted_links, но больше не нужно. Кому за %cost_gold?" WHERE `id` = 398;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Собирался выставить %item_formatted_link на аукцион, но можешь купить дешевле сейчас за %cost_gold." WHERE `id` = 399;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Зачем, черт возьми, я купил %item_formatted_link? Кому нужно за %cost_gold?" WHERE `id` = 400;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "У меня есть %quest_links" WHERE `id` = 401;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "У меня тоже есть %quest_links" WHERE `id` = 402;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "У меня тоже есть %quest_links, сейчас я в %zone_name" WHERE `id` = 403;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "%other_name, у меня тоже есть %quest_links" WHERE `id` = 404;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "%other_name, у меня тоже есть %quest_links, сейчас я в %zone_name" WHERE `id` = 405;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Я готов к %quest_links, сейчас я в %zone_name" WHERE `id` = 406;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Я готов к %quest_links, я %my_role" WHERE `id` = 407;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "%other_name, я готов к %quest_links, сейчас я в %zone_name" WHERE `id` = 408;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "%other_name, я готов к %quest_links, я %my_role" WHERE `id` = 409;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Привет, я готов к %quest_links" WHERE `id` = 410;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Привет, могу сделать %quest_links с тобой" WHERE `id` = 411;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Привет, у меня тоже есть %quest_links" WHERE `id` = 412;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Привет %other_name, я готов к %quest_links" WHERE `id` = 413;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Привет %other_name, могу сделать %quest_links с тобой" WHERE `id` = 414;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Привет %other_name, у меня тоже есть %quest_links" WHERE `id` = 415;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Хочешь сгруппироваться для %quest_links?" WHERE `id` = 416;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Я готов к %quest_links, сейчас я в %zone_name" WHERE `id` = 417;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Я готов к %quest_links, я %my_role" WHERE `id` = 418;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "%other_name, могу продать тебе %formatted_item_links" WHERE `id` = 419;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Могу, возможно, продать %formatted_item_links" WHERE `id` = 420;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Думаю, могу продать %formatted_item_links" WHERE `id` = 421;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "%other_name, возможно, могу продать %formatted_item_links" WHERE `id` = 422;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "%other_name, думаю, могу продать %formatted_item_links" WHERE `id` = 423;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Могу продать тебе %formatted_item_links" WHERE `id` = 424;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Привет, у меня есть %formatted_item_links на продажу" WHERE `id` = 425;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Привет, возможно, могу продать %formatted_item_links" WHERE `id` = 426;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Квест принят" WHERE `id` = 427;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Квест удален" WHERE `id` = 428;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Я не могу взять этот квест" WHERE `id` = 429;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Я не могу поговорить с дающим квест" WHERE `id` = 430;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Я уже выполнил %quest" WHERE `id` = 431;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "У меня уже есть %quest" WHERE `id` = 432;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Я не могу взять %quest" WHERE `id` = 433;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Я не могу взять %quest, потому что мой журнал квестов заполнен" WHERE `id` = 434;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Я не могу взять %quest, потому что моя сумка заполнена" WHERE `id` = 435;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Я принял %quest" WHERE `id` = 436;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Я не выполнил квест %quest" WHERE `id` = 437;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Квест %quest доступен" WHERE `id` = 438;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Я провалил квест %quest" WHERE `id` = 439;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Я не могу сдать квест %quest" WHERE `id` = 440;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Я выполнил квест %quest" WHERE `id` = 441;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Я выполнил квест %quest и получил %item" WHERE `id` = 442;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Какую награду выбрать за выполнение квеста %quest?%rewards" WHERE `id` = 443;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Хорошо, выберу %item в качестве награды" WHERE `id` = 444;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Привет" WHERE `id` = 445;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Привет!" WHERE `id` = 446;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Здравствуй" WHERE `id` = 447;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Здравствуй!" WHERE `id` = 448;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Приветствую!" WHERE `id` = 449;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Привет, я следую за тобой!" WHERE `id` = 450;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Привет, веди меня!" WHERE `id` = 451;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Привет, веди меня!" WHERE `id` = 452;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Эй %player, хочешь в мою группу?" WHERE `id` = 453;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Эй %player, хочешь в мою группу?" WHERE `id` = 454;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Выход отменен!" WHERE `id` = 455;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Я выхожу из игры!" WHERE `id` = 456;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "До свидания!" WHERE `id` = 457;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Пока!" WHERE `id` = 458;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Увидимся!" WHERE `id` = 459;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "что это было, %s?" WHERE `id` = 460;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "не уверен, что понял %s?" WHERE `id` = 461;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "эээ... не понимаю, о чем ты" WHERE `id` = 462;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "ты ко мне обращаешься, %s?" WHERE `id` = 463;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "чт-что?" WHERE `id` = 464;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "а?" WHERE `id` = 465;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "что?" WHERE `id` = 466;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "ты говоришь?" WHERE `id` = 467;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "как хочешь" WHERE `id` = 468;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "ты меня запутал" WHERE `id` = 469;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Бла бла бла..." WHERE `id` = 470;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Что ты сказал, %s?" WHERE `id` = 471;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Сконцентрируйся на игре, %s!" WHERE `id` = 472;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Общаться с тобой, %s, так здорово! Всегда хотел встретиться" WHERE `id` = 473;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Эти сообщения в чате сводят меня с ума! Такое чувство, что я всех вас знаю!" WHERE `id` = 474;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "ДА ЛАДНО! ХАХА КОНЕЧНО!!!" WHERE `id` = 475;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Я тебе верю!!!" WHERE `id` = 476;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "ОК, ага, ЛОЛ" WHERE `id` = 477;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Почему все всегда говорят одно и то же???" WHERE `id` = 478;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Эй %s... а, неважно!" WHERE `id` = 479;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "О чем ты, %s" WHERE `id` = 480;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Кто это сказал? Я похож на это замечание" WHERE `id` = 481;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "чего вы все несете" WHERE `id` = 482;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "фр фр, без шуток" WHERE `id` = 483;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "ты ничего не получишь" WHERE `id` = 484;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "сваг" WHERE `id` = 485;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "спасибо!" WHERE `id` = 486;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "нет" WHERE `id` = 487;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Да" WHERE `id` = 488;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "ф" WHERE `id` = 489;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "%s, без шуток xD" WHERE `id` = 490;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "почему так" WHERE `id` = 491;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "лмао" WHERE `id` = 492;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "решил помолчать, снова запутался в чате" WHERE `id` = 493;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "я могу по-настоящему завидовать" WHERE `id` = 494;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "%s, ты не слышишь капающую иронию в моем тексте" WHERE `id` = 495;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "он сказал без обид, все нормально" WHERE `id` = 496;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "момент дворфа" WHERE `id` = 497;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Да, %s" WHERE `id` = 498;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "интересно..." WHERE `id` = 499;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "лол" WHERE `id` = 500;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "%s, иди ты :D" WHERE `id` = 501;
UPDATE `ai_playerbot_texts` SET `text_loc8` = ":^)" WHERE `id` = 502;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "спс" WHERE `id` = 503;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "%s, хорошо сказано" WHERE `id` = 504;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "ура" WHERE `id` = 505;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "да" WHERE `id` = 506;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "ооооо" WHERE `id` = 507;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "хмм" WHERE `id` = 508;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "ага, конечно" WHERE `id` = 509;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "ты заставил меня блевануть, что за" WHERE `id` = 510;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "жарко" WHERE `id` = 511;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "злятся" WHERE `id` = 512;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "что ты ел, %s" WHERE `id` = 513;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "что за" WHERE `id` = 514;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "попробую понять этот комментарий" WHERE `id` = 515;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "*в замешательстве*" WHERE `id` = 516;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "да, черт возьми" WHERE `id` = 517;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "0/10 не стал бы читать снова" WHERE `id` = 518;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "10/10 прочитал бы снова" WHERE `id` = 519;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "6/10 прочитал бы" WHERE `id` = 520;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "7/10 прочитал бы" WHERE `id` = 521;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "бейсд" WHERE `id` = 522;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "о да, может быть" WHERE `id` = 523;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "да, и что" WHERE `id` = 524;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "эй %s, я тебя не забыл" WHERE `id` = 525;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "ты меня бесишь, %s" WHERE `id` = 526;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "я достану тебя в этот раз, %s" WHERE `id` = 527;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "лучше берегись, %s" WHERE `id` = 528;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "мне не понравился прошлый раунд" WHERE `id` = 529;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "я был плох в прошлом раунде из-за %s" WHERE `id` = 530;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "готовься умереть, %s" WHERE `id` = 531;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "не нравится, что ты меня убил, %s" WHERE `id` = 532;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "%s, я тебя ненавижу" WHERE `id` = 533;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "грррр, в этот раз я тебя достану, %s" WHERE `id` = 534;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "ну и пошел ты" WHERE `id` = 535;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "%s, я тебе в рот блевану" WHERE `id` = 536;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "не суди меня" WHERE `id` = 537;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Твоя мама такая толстая, что не может пройти через Темный Портал" WHERE `id` = 538;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "что за" WHERE `id` = 539;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "что за??" WHERE `id` = 540;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "ничтожество" WHERE `id` = 541;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "что за" WHERE `id` = 542;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "отстой" WHERE `id` = 543;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "РЕВАНШ!!! я его уделаю" WHERE `id` = 544;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "жалко, меня убил %s" WHERE `id` = 545;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "ладно, я закончил" WHERE `id` = 546;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "хе-хе, я уделал %s?" WHERE `id` = 547;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "это было слишком просто, убил %s" WHERE `id` = 548;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "попался, дружок" WHERE `id` = 549;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "ха-ха" WHERE `id` = 550;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "лузер" WHERE `id` = 551;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "я убил %s, вы все следующие" WHERE `id` = 552;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "о да, я его уделал" WHERE `id` = 553;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "я машина для убийств" WHERE `id` = 554;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "%s, это напоминает мне песню Slayer... столько крови" WHERE `id` = 555;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "извини, %s. можем повторить сцену?" WHERE `id` = 556;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "ну как тебе быть кормом для червей, %s???" WHERE `id` = 557;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "ты должен быть мёртв, %s, это часть игры!!!!!" WHERE `id` = 558;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "извини, %s. выглядело так же хорошо, как картина Энди Уорхола!" WHERE `id` = 559;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "%s, в следующий раз использую резиновые пули!" WHERE `id` = 560;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "что случилось, %s?? голову потерял? хахаха, надо сохранять хладнокровие!!" WHERE `id` = 561;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "я должен был это сделать, %s. Ты понимаешь. Режиссёр так сказал!!" WHERE `id` = 562;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "эй, %s.......МУАХАХАХАХАХАХА" WHERE `id` = 563;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "%s, мне это понравилось!! Давай сыграем ещё раз, Сэм" WHERE `id` = 564;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "эй, %s! можешь звать меня ликом... ты кусок ЧЕРТА!!!!" WHERE `id` = 565;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "ты со мной разговариваешь, %s??" WHERE `id` = 566;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "%s, в этот раз не стой перед моими пулями." WHERE `id` = 567;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "%s, чего ты валяешься??? хехе" WHERE `id` = 568;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "сильно смеялся" WHERE `id` = 569;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "привет %s" WHERE `id` = 570;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "о, привет %s" WHERE `id` = 571;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "как дела, %s!!!" WHERE `id` = 572;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "привет" WHERE `id` = 573;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "как дела" WHERE `id` = 574;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "здравствуй %s" WHERE `id` = 575;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "привет %s, мы знакомы?" WHERE `id` = 576;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "эй %s" WHERE `id` = 577;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "хай %s" WHERE `id` = 578;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "что за фигня" WHERE `id` = 579;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "что за черт" WHERE `id` = 580;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "это бред" WHERE `id` = 581;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "админ" WHERE `id` = 582;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "эй %s, хватит злоупотреблять своими правами админа" WHERE `id` = 583;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "оставь меня в покое, админ!" WHERE `id` = 584;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "ты отстой, админ" WHERE `id` = 585;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "это моё имя, что тебе нужно %s" WHERE `id` = 586;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "да???" WHERE `id` = 587;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "эээ... что" WHERE `id` = 588;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "ты со мной разговариваешь, %s?" WHERE `id` = 589;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "У меня под бронёй щенки!" WHERE `id` = 590;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Укуси меня, <target>!" WHERE `id` = 591;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Эй, <target>! Угадай, что твоя мама сказала прошлой ночью!" WHERE `id` = 592;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "<target>, ты такой урод, что даже в обезьяньем борделе с бананами не добился бы успеха!" WHERE `id` = 593;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Заткнись, <target>, тебе никогда не стать таким мужчиной, как твоя мать!!" WHERE `id` = 594;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Твоя мать была хомяком, а отец пах одуванчиками!!!!" WHERE `id` = 595;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Я больше не хочу с тобой разговаривать, ты пустоголовый кормовой корытоочиститель!!!" WHERE `id` = 596;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Я пускаю в твою сторону газы!!!" WHERE `id` = 597;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Иди и вскипяти свою задницу, сын смешного человека!!!" WHERE `id` = 598;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Что ты собираешься делать, <target>, заставить меня кровоточить? ВПЕРЁД!" WHERE `id` = 599;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "М-О-О-Н! Это значит агр!" WHERE `id` = 600;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Ты так же полезен, как одноногий на конкурсе пинков." WHERE `id` = 601;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Эй, <target>! Перестань клеиться к ним, они не твой тип. Они не надувные." WHERE `id` = 602;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "<target>, ты настолько не в своей лиге, что играешь в другой вид спорта." WHERE `id` = 603;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Ты сегодня совершил большую ошибку, <target>, ты встал с кровати." WHERE `id` = 604;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Я хочу попробовать превратиться в лошадь, но мне нужна помощь. Я буду спереди, а ты будь собой." WHERE `id` = 605;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Можно я одолжу твоё лицо на пару дней? Моя задница уходит в отпуск...." WHERE `id` = 606;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Я бы хотел сделать тебе прощальный подарок... Сначала ты сделай свою часть." WHERE `id` = 607;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "До тебя мы были голодны, теперь мы просто сыты по горло." WHERE `id` = 608;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Ты мне нравишься. Говорят, у меня нет вкуса, но ты мне нравишься." WHERE `id` = 609;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Думаю, у тебя комплекс неполноценности, но это нормально, он оправдан." WHERE `id` = 610;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Прочь, гнилое создание! Или я вытрясу твои кости из одежды." WHERE `id` = 611;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Не могу поверить, что трачу на тебя своё время!" WHERE `id` = 612;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Мне нравится, когда меня оскорбляют, значит, можно больше не быть вежливым." WHERE `id` = 613;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Ты кожаный-жилет, хрустальная пуговица, узловатый, агатовый, рвотный чулок, ленточный подвязочник, гладкоязычный, испанский кошелёк!" WHERE `id` = 614;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Ты дрожащий ловец летучих мышей, пивной червь!" WHERE `id` = 615;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Ты действительно идол поклонников идиотов!" WHERE `id` = 616;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Ты ублюдочный узловатый хвостун!" WHERE `id` = 617;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Ты, ублюдочный мандрагор, тебе больше подходит быть у меня на шапке, чем ждать у моих пяток!" WHERE `id` = 618;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Ты! Ты кухарка! Ты бродяга! Ты мерзавец! Я пощекочу твою катастрофу!" WHERE `id` = 619;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "О, <target>! Ты заразная, плохо воспитанная льняная девка!" WHERE `id` = 620;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Мы протекаем в твоей трубе, <target>!" WHERE `id` = 621;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "О, ты бесполезный болотный цветок!" WHERE `id` = 622;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Если бы я был как ты, я бы выбросил себя!" WHERE `id` = 623;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Научи меня, <target>, как забыть думать!" WHERE `id` = 624;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Истинно, ты проклят, как плохо прожаренное яйцо, с одной стороны!" WHERE `id` = 625;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Ты голодающий, ты кожа-угря, ты сушёный бычий язык, ты бычий член, ты треска — о, чтобы хватило дыхания сказать, что ты такое!! — ты портновский ярд, ты ножны, ты футляр для лука, ты мерзкий стоячий клинок!" WHERE `id` = 626;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Фу! Брось себя в гнилую пасть Смерти!" WHERE `id` = 627;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "<target>, ты торговец рыбой!" WHERE `id` = 628;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Я доживу, чтобы выбить тебе мозги!" WHERE `id` = 629;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Ты очень поверхностен, <target>!! Ты корм для червей по сравнению с хорошим куском мяса!!" WHERE `id` = 630;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Подлый негодяй! О, <target>, ты зловонный, ненавистный к свиньям орех!" WHERE `id` = 631;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "<target>! Твой поцелуй так же утешителен, как замёрзшая вода для голодной змеи!" WHERE `id` = 632;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Я презираю тебя, паршивый спутник. Что, ты бедный, низкий, мошеннический, безрубашечный приятель! Прочь, ты плесневелый негодяй, прочь!" WHERE `id` = 633;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Прочь с глаз моих! Ты заражаешь мои глаза, <target>!" WHERE `id` = 634;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "ВРЕМЯ ИГРЫ!!!!" WHERE `id` = 635;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Никто не пройдёт!" WHERE `id` = 636;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "На нас напали! Вперёд, вы негодяи! Отразите захватчиков!" WHERE `id` = 637;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Никто не может бросить вызов Братству!" WHERE `id` = 638;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Дураки... Убейте того, кто в платье!" WHERE `id` = 639;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Я отдам твою душу самому Хаккару!" WHERE `id` = 640;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Гордость предвещает конец вашего мира! Идите, смертные! Столкнитесь с гневом !" WHERE `id` = 641;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Все мои планы привели к этому!" WHERE `id` = 642;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Ах! Еще ягнята на заклание!" WHERE `id` = 643;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Еще один день, еще одна славная битва!" WHERE `id` = 644;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Итак, дело... или удовольствие?" WHERE `id` = 645;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Вы не готовы!" WHERE `id` = 646;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Финальное завоевание началось! Снова подчинение этого мира в наших руках. Пусть никто не выживет!" WHERE `id` = 647;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Ваша смерть будет болезненной." WHERE `id` = 648;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Просите о милости! Ваши бессмысленные жизни скоро будут потеряны." WHERE `id` = 649;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Оставьте все надежды! вернулся, чтобы завершить то, что было начато много лет назад. На этот раз не будет побега!" WHERE `id` = 650;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Внимание! Вы помечены для уничтожения!" WHERE `id` = 651;
UPDATE `ai_playerbot_texts` SET `text_loc8` = " предназначена только для гостей..." WHERE `id` = 652;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Ха-ха-ха! Вы безнадежно не на уровне!" WHERE `id` = 653;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Я сокрушу ваши иллюзии величия!" WHERE `id` = 654;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Простите меня, ведь вы собираетесь проиграть игру." WHERE `id` = 655;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Борьба только усугубляет ситуацию." WHERE `id` = 656;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Паразиты! Пиявки! Берите мою кровь и подавитесь ею!" WHERE `id` = 657;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Опять... ЕЩЕ РАЗ!" WHERE `id` = 658;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Моя кровь станет вашим концом!" WHERE `id` = 659;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Хорошо, теперь ты сразишься со мной!" WHERE `id` = 660;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Давайте, охранники! Время убивать!" WHERE `id` = 661;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Не задерживайте свою судьбу. Идите ко мне сейчас. Я сделаю вашу жертву быстрой." WHERE `id` = 662;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Ты скоро будешь мертв!" WHERE `id` = 663;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Муа-ха-ха!" WHERE `id` = 664;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Я хищник! Ты жертва..." WHERE `id` = 665;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Ты уйдешь в кусках!" WHERE `id` = 666;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Смерть приходит. Будет ли твоя совесть чиста?" WHERE `id` = 667;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Ваше поведение не будет терпимо." WHERE `id` = 668;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Менажерия предназначена только для гостей." WHERE `id` = 669;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Хмм, незваные гости, нужно подготовиться..." WHERE `id` = 670;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Обнаружены враждебные сущности. Протокол оценки угрозы активирован. Основная цель захвачена. Время до повторной оценки - тридцать секунд." WHERE `id` = 671;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Новые игрушки? Для меня? Обещаю, что на этот раз не сломаю их!" WHERE `id` = 672;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Я готов играть!" WHERE `id` = 673;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Шшш... скоро все закончится." WHERE `id` = 674;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Ааааагхиббргубугбугрубгл!" WHERE `id` = 675;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "РвлРвлРвлРвл!" WHERE `id` = 676;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Ты тоже будешь служить!" WHERE `id` = 677;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Скажи мне... скажи мне все! Непослушные секреты! Я вырву секреты из твоей плоти!" WHERE `id` = 678;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Приготовьтесь, колокола прозвучали! Укройте своих слабых, молодых и старых! Каждый из вас заплатит окончательную цену! Просите о милости, расплата пришла!" WHERE `id` = 679;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Где я, в латунных пуговицах Бонзо?" WHERE `id` = 680;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Я больше не могу это терпеть! Король гоблинов! Король гоблинов! Где бы ты ни был! Унеси этого далеко от меня!" WHERE `id` = 681;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "У вас есть тринадцать часов, чтобы решить лабиринт, прежде чем ваш младший брат станет одним из нас... навсегда." WHERE `id` = 682;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Итак, - это кусок торта, да? Ну, давайте посмотрим, как вы справитесь с этим маленьким куском..." WHERE `id` = 683;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Отступи, я приму тебя, упрямый, готовый сразиться с кем угодно, я знаю, что ты не прав, и это не то место, где ты должен быть." WHERE `id` = 684;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Покажи, что у тебя есть!" WHERE `id` = 685;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "До смерти!" WHERE `id` = 686;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Двойное лезвие, для чистого бритья каждый раз." WHERE `id` = 687;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Давай!" WHERE `id` = 688;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Ты падешь!" WHERE `id` = 689;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Ударь, ударь, ударь!" WHERE `id` = 690;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Давайте сделаем это быстро, время - это мана." WHERE `id` = 691;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Я не думаю, что вы осознаете серьезность вашей ситуации." WHERE `id` = 692;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Я принесу честь своей семье и своему королевству!" WHERE `id` = 693;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Свет, дай мне силу!" WHERE `id` = 694;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Моя церковь - это поле битвы - время поклоняться..." WHERE `id` = 695;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Я держу тебя в презрении..." WHERE `id` = 696;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Столкнись с молотом справедливости!" WHERE `id` = 697;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Докажи свою ценность в испытании оружием под Светом!" WHERE `id` = 698;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Все должны пасть перед могуществом и правом моего дела, ты будешь следующим!" WHERE `id` = 699;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Приготовься умереть!" WHERE `id` = 700;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Зверь со мной ничто по сравнению с зверем внутри..." WHERE `id` = 701;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Стань свидетелем огневой мощи этого полностью вооруженного охотника!" WHERE `id` = 702;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Исцели меня! Быстро!" WHERE `id` = 703;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Почти мертв! Исцели меня!" WHERE `id` = 704;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Помогите! Исцели меня!" WHERE `id` = 705;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Кто-нибудь! Исцели меня!" WHERE `id` = 706;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Исцели! Исцели! Исцели!" WHERE `id` = 707;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Я умираю! Исцели! Ааааргх!" WHERE `id` = 708;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Исцели меня!" WHERE `id` = 709;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Я умру. Я умру. Я умру. Исцели!" WHERE `id` = 710;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Целители, где вы? Я умираю!" WHERE `id` = 711;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "О, боль. Исцели меня быстро!" WHERE `id` = 712;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Нужна исцеление" WHERE `id` = 713;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Низкое здоровье" WHERE `id` = 714;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Сделай исцеление. Пожалуйста." WHERE `id` = 715;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Может кто-нибудь исцелить меня?" WHERE `id` = 716;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Эй! Лучше исцели меня сейчас, чем воскрешать позже." WHERE `id` = 717;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Извини. Нужна еще одна исцеление." WHERE `id` = 718;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Черт возьми, мобы. Исцели меня, пожалуйста." WHERE `id` = 719;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Еще один удар, и я пропал. Исцели, пожалуйста." WHERE `id` = 720;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Есть ли целители?" WHERE `id` = 721;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Почему они всегда бьют меня в лицо? Нужна исцеление." WHERE `id` = 722;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Может кто-нибудь немного исцелить меня?" WHERE `id` = 723;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "OOM" WHERE `id` = 724;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "У меня закончилась мана" WHERE `id` = 725;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Черт, я потратил всю свою ману на это" WHERE `id` = 726;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Тебе стоит подождать, пока я выпью или восстановлю свою ману" WHERE `id` = 727;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Низкая мана" WHERE `id` = 728;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Нет маны. Снова?" WHERE `id` = 729;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Низкая мана. Хочу выпить." WHERE `id` = 730;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "У нас есть торговый автомат? Снова нет маны." WHERE `id` = 731;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Моя мана в истории." WHERE `id` = 732;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "В следующий раз я возьму напитки. Нет маны." WHERE `id` = 733;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Где моя мана?" WHERE `id` = 734;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "У меня осталось немного !" WHERE `id` = 735;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Мне нужно больше !" WHERE `id` = 736;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "100 осталось!" WHERE `id` = 737;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Вот и все! Нет !" WHERE `id` = 738;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "И у тебя есть мой лук... Ой, нет !" WHERE `id` = 739;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Нужна патроны!" WHERE `id` = 740;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "О боже!" WHERE `id` = 741;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Мне страшно" WHERE `id` = 742;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Мы пропали" WHERE `id` = 743;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Это закончено" WHERE `id` = 744;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Это заканчивается сейчас" WHERE `id` = 745;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Может кто-нибудь вызвать метель или что-то подобное?" WHERE `id` = 746;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Черт. Танку агрировал всех мобов вокруг." WHERE `id` = 747;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Мы умрем. Мы умрем. Мы умрем." WHERE `id` = 748;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Ух ты! Так много игрушек, с которыми можно играть." WHERE `id` = 749;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Я убью их всех!" WHERE `id` = 750;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Если танк умрет, мы в истории." WHERE `id` = 751;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Аааааргх!" WHERE `id` = 752;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "ЛЕЕЕЕЕЕЕЕЕЕЕЕЕЕЕЕЕЕЕЕЙ ДЖЕНКИНС!!!!!!!" WHERE `id` = 753;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Правильно. Что у нас есть в AOE?" WHERE `id` = 754;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Это становится интересным." WHERE `id` = 755;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Круто. Соберите их в одном месте для хорошего огненного удара." WHERE `id` = 756;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Убей! Убей! Убей!" WHERE `id` = 757;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Я думаю, что мои штаны мокрые." WHERE `id` = 758;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Мы в истории." WHERE `id` = 759;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Надеюсь, целители готовы. Лееерой!" WHERE `id` = 760;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Надеюсь, они не придут за мной." WHERE `id` = 761;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "О нет. Я не вижу в этом резне." WHERE `id` = 762;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Надеюсь, там будет немного денег." WHERE `id` = 763;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Лут! Лут!" WHERE `id` = 764;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Мое драгоценное." WHERE `id` = 765;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Надеюсь, там ждет меня блестящий эпический предмет." WHERE `id` = 766;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "У меня глубокие карманы и сумки." WHERE `id` = 767;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Все мое!" WHERE `id` = 768;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Надеюсь, сегодня не будет серой ерунды." WHERE `id` = 769;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Этот лут - МОЙ!" WHERE `id` = 770;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Лутать отвратительно, но мне нужны деньги." WHERE `id` = 771;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Золото!" WHERE `id` = 772;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Хорошо. Давайте посмотрим, что у них есть." WHERE `id` = 773;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Не волнуйтесь. Я все залутаю." WHERE `id` = 774;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Я ниндзя лута." WHERE `id` = 775;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Мне нужно бросить кубик?" WHERE `id` = 776;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Кто-нибудь объясните мне, куда они положили все эти вещи?" WHERE `id` = 777;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Нет, я не буду лутать серую ерунду." WHERE `id` = 778;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Я первый. Я первый. Я первый." WHERE `id` = 779;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Отдай мне свои деньги!" WHERE `id` = 780;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Мои карманы пусты, мне нужно их заполнить." WHERE `id` = 781;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "У меня есть новая сумка для этого." WHERE `id` = 782;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Надеюсь, я не агрирую никого, пока лутаю." WHERE `id` = 783;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Пожалуйста, не смотрите. Я лутаю." WHERE `id` = 784;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Ха! Ты не получишь ни кусочка этого!" WHERE `id` = 785;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Лутать круто." WHERE `id` = 786;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Мне нравится новая экипировка." WHERE `id` = 787;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Я уйду, если снова не будет ничего ценного." WHERE `id` = 788;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Надеюсь, это будет красивое кольцо." WHERE `id` = 789;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Я вырву лут у тебя." WHERE `id` = 790;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Все держитесь подальше. Я собираюсь лутать." WHERE `id` = 791;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Сладкий лут." WHERE `id` = 792;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Бог Ролла! Дай мне эпик сегодня." WHERE `id` = 793;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Пожалуйста, дай мне новые игрушки." WHERE `id` = 794;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Надеюсь, они принесут вкусняшки." WHERE `id` = 795;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Золото - мое. Я оставлю все, обещаю." WHERE `id` = 796;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Нет, я не могу устоять." WHERE `id` = 797;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Я хочу больше!" WHERE `id` = 798;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Я близко, подожди меня!" WHERE `id` = 799;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Я не далеко, пожалуйста, подожди!" WHERE `id` = 800;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Я направляюсь к вашему местоположению." WHERE `id` = 801;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Я иду к тебе." WHERE `id` = 802;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Я путешествую к вашему местоположению." WHERE `id` = 803;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Я пытаюсь добраться до тебя." WHERE `id` = 804;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Экипирую %item." WHERE `id` = 805;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "%item снят." WHERE `id` = 806;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Я выучил заклинания: %spells." WHERE `id` = 807;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "%item в перезарядке." WHERE `id` = 808;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "У меня нет %item в инвентаре." WHERE `id` = 809;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Предмет с ID %item не существует." WHERE `id` = 810;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Вставляю %gem в %item." WHERE `id` = 811;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Я не могу использовать %item." WHERE `id` = 812;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Следую." WHERE `id` = 813;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Остаюсь." WHERE `id` = 814;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Убегаю." WHERE `id` = 815;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Я не буду убегать с тобой, ты слишком далеко." WHERE `id` = 816;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Фармлю." WHERE `id` = 817;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Атакую." WHERE `id` = 818;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Это слишком далеко." WHERE `id` = 819;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Это под водой." WHERE `id` = 820;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Я не могу туда пойти." WHERE `id` = 821;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Я не в твоем гильдии!" WHERE `id` = 822;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Не могу найти гильдейский банк поблизости." WHERE `id` = 823;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Я не могу положить " WHERE `id` = 824;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "У меня нет прав на размещение предметов в первой вкладке гильдейского банка." WHERE `id` = 825;
UPDATE `ai_playerbot_texts` SET `text_loc8` = " положено в гильдейский банк." WHERE `id` = 826;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Свободное движение." WHERE `id` = 827;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Охраняю." WHERE `id` = 828;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Использую %target." WHERE `id` = 829;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "на %unit." WHERE `id` = 830;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "(%amount доступно)" WHERE `id` = 831;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "(последний)" WHERE `id` = 832;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Сокет не подходит." WHERE `id` = 833;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "на торговом предмете." WHERE `id` = 834;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "на себе." WHERE `id` = 835;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "на %item." WHERE `id` = 836;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "на %gameobject." WHERE `id` = 837;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Лутаю %item." WHERE `id` = 838;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Призываю %target." WHERE `id` = 839;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "У меня недостаточно членов группы, чтобы вызвать." WHERE `id` = 840;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Не удалось найти цель для призыва." WHERE `id` = 841;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Я не могу призывать, пока я в бою." WHERE `id` = 842;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Я не знаю заклинание %spell." WHERE `id` = 843;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Кастую %spell." WHERE `id` = 844;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Создаю %spell." WHERE `id` = 845;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Не могу кастовать %spell." WHERE `id` = 846;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "Не удалось кастовать %spell." WHERE `id` = 847;
UPDATE `ai_playerbot_texts` SET `text_loc8` = " |cffffff00(x%amount осталось)|r" WHERE `id` = 848;
UPDATE `ai_playerbot_texts` SET `text_loc8` = "dummy" WHERE `id` = 849;

View File

@@ -0,0 +1,35 @@
DELETE FROM ai_playerbot_texts
WHERE name IN (
'rp_missing_reagent_greater_blessing',
'rp_missing_reagent_gift_of_the_wild',
'rp_missing_reagent_arcane_brilliance',
'rp_missing_reagent_generic'
);
DELETE FROM ai_playerbot_texts_chance
WHERE name IN (
'rp_missing_reagent_greater_blessing',
'rp_missing_reagent_gift_of_the_wild',
'rp_missing_reagent_arcane_brilliance',
'rp_missing_reagent_generic'
);
INSERT INTO ai_playerbot_texts (name, text, say_type, reply_type, text_loc1, text_loc2, `text_loc3`, `text_loc4`, `text_loc5`, `text_loc6`, `text_loc7`, `text_loc8`) VALUES
('rp_missing_reagent_greater_blessing',
'By the Light... I forgot my Symbols of Kings. Well make do with %base_spell!', 0, 0,
'', 'Par la Lumière... J''ai oublié mes Symboles du roi. On se contentera de %base_spell !', '', '', '', '', '', ''),
('rp_missing_reagent_gift_of_the_wild',
'Nature is generous, my bags are not... out of herbs for %group_spell. Take %base_spell for now!', 0, 0,
'', 'La nature est généreuse, pas mes sacs... plus d''herbes pour %group_spell. Prenez %base_spell pour l''instant !', '', '', '', '', '', ''),
('rp_missing_reagent_arcane_brilliance',
'Out of Arcane Powder... %group_spell will have to wait. Casting %base_spell!', 0, 0,
'', 'Plus de poudre des arcanes... %group_spell attendra. Je lance %base_spell !', '', '', '', '', '', ''),
('rp_missing_reagent_generic',
'Oops, Im out of components for %group_spell. Well go with %base_spell!', 0, 0,
'', 'Oups, je n''ai plus de composants pour %group_spell. On fera avec %base_spell !', '', '', '', '', '', '');
INSERT INTO ai_playerbot_texts_chance (name, probability) VALUES
('rp_missing_reagent_greater_blessing', 100),
('rp_missing_reagent_gift_of_the_wild', 100),
('rp_missing_reagent_arcane_brilliance', 100),
('rp_missing_reagent_generic', 100);

View File

@@ -0,0 +1,856 @@
UPDATE ai_playerbot_texts SET text_loc2 = '';
UPDATE `ai_playerbot_texts` SET `text_loc2`='au milieu de nulle part' WHERE `id`=1;
UPDATE `ai_playerbot_texts` SET `text_loc2`='un endroit non divulgué' WHERE `id`=2;
UPDATE `ai_playerbot_texts` SET `text_loc2`='quelque part' WHERE `id`=3;
UPDATE `ai_playerbot_texts` SET `text_loc2`='un truc' WHERE `id`=4;
UPDATE `ai_playerbot_texts` SET `text_loc2`='je me demande quel goût a %item_link' WHERE `id`=5;
UPDATE `ai_playerbot_texts` SET `text_loc2`='noooon, jai eu %item_link' WHERE `id`=6;
UPDATE `ai_playerbot_texts` SET `text_loc2`='oh non, encore cette camelote %item_link' WHERE `id`=7;
UPDATE `ai_playerbot_texts` SET `text_loc2`='on dirait que je ramasse des ordures %item_link' WHERE `id`=8;
UPDATE `ai_playerbot_texts` SET `text_loc2`='bon, cest mieux que rien je suppose %item_link' WHERE `id`=9;
UPDATE `ai_playerbot_texts` SET `text_loc2`='je ne sais pas quoi faire de %item_link' WHERE `id`=10;
UPDATE `ai_playerbot_texts` SET `text_loc2`='je me demande quel goût a %item_link' WHERE `id`=11;
UPDATE `ai_playerbot_texts` SET `text_loc2`='je pourrais ramasser du %item_link toute la journée' WHERE `id`=12;
UPDATE `ai_playerbot_texts` SET `text_loc2`='un jour de plus, un %item_link de plus' WHERE `id`=13;
UPDATE `ai_playerbot_texts` SET `text_loc2`='jai ramassé un peu de %item_link' WHERE `id`=14;
UPDATE `ai_playerbot_texts` SET `text_loc2`='un peu de %item_link, cest toujours ça' WHERE `id`=15;
UPDATE `ai_playerbot_texts` SET `text_loc2`='pas mal, je viens de choper %item_link' WHERE `id`=16;
UPDATE `ai_playerbot_texts` SET `text_loc2`='je viens de ramasser %item_link à %zone_name' WHERE `id`=17;
UPDATE `ai_playerbot_texts` SET `text_loc2`='je pourrais bien lutiliser ça %item_link' WHERE `id`=18;
UPDATE `ai_playerbot_texts` SET `text_loc2`='argent, argent, argent %item_link' WHERE `id`=19;
UPDATE `ai_playerbot_texts` SET `text_loc2`='jai eu %item_link' WHERE `id`=20;
UPDATE `ai_playerbot_texts` SET `text_loc2`='%item_link est BiS pour les chasseurs' WHERE `id`=21;
UPDATE `ai_playerbot_texts` SET `text_loc2`='%item_link est BiS pour les %my_class' WHERE `id`=22;
UPDATE `ai_playerbot_texts` SET `text_loc2`='la chance est avec moi aujourdhui %item_link' WHERE `id`=23;
UPDATE `ai_playerbot_texts` SET `text_loc2`='trop bon %item_link, fraîchement looté' WHERE `id`=24;
UPDATE `ai_playerbot_texts` SET `text_loc2`='wow, je viens de choper %item_link' WHERE `id`=25;
UPDATE `ai_playerbot_texts` SET `text_loc2`='%item_link est BiS pour les chasseurs' WHERE `id`=26;
UPDATE `ai_playerbot_texts` SET `text_loc2`='%item_link est BiS pour les %my_class' WHERE `id`=27;
UPDATE `ai_playerbot_texts` SET `text_loc2`='la chance est avec moi aujourdhui %item_link' WHERE `id`=28;
UPDATE `ai_playerbot_texts` SET `text_loc2`='trop bon %item_link, fraîchement looté' WHERE `id`=29;
UPDATE `ai_playerbot_texts` SET `text_loc2`='OMG, regardez ce que je viens de looter %item_link !!!' WHERE `id`=30;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Noooon ! Cest pas possible, jai eu %item_link, cest de la folie' WHERE `id`=31;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Noooon ! Cest pas possible, jai eu %item_link, cest de la folie' WHERE `id`=32;
UPDATE `ai_playerbot_texts` SET `text_loc2`='je viens juste de prendre la quête %quest_link' WHERE `id`=33;
UPDATE `ai_playerbot_texts` SET `text_loc2`='je viens daccepter %quest_link' WHERE `id`=34;
UPDATE `ai_playerbot_texts` SET `text_loc2`='%quest_link je vais essayer de la finir' WHERE `id`=35;
UPDATE `ai_playerbot_texts` SET `text_loc2`='jai pris %quest_link à %zone_name' WHERE `id`=36;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Enfin fini lobjectif %quest_obj_name pour %quest_link' WHERE `id`=37;
UPDATE `ai_playerbot_texts` SET `text_loc2`='jai enfin %quest_obj_available/%quest_obj_required de %quest_obj_name pour %quest_link' WHERE `id`=38;
UPDATE `ai_playerbot_texts` SET `text_loc2`='%quest_obj_full_formatted pour %quest_link, enfin !' WHERE `id`=39;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Oof, jai %quest_obj_available/%quest_obj_required %quest_obj_name pour %quest_link' WHERE `id`=40;
UPDATE `ai_playerbot_texts` SET `text_loc2`='il me manque encore %quest_obj_missing de %quest_obj_name pour %quest_link' WHERE `id`=41;
UPDATE `ai_playerbot_texts` SET `text_loc2`='%quest_obj_full_formatted, je bosse toujours sur %quest_link' WHERE `id`=42;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Enfin fini avec %item_link pour %quest_link' WHERE `id`=43;
UPDATE `ai_playerbot_texts` SET `text_loc2`='jai enfin %quest_obj_available/%quest_obj_required de %item_link pour %quest_link' WHERE `id`=44;
UPDATE `ai_playerbot_texts` SET `text_loc2`='%quest_obj_full_formatted pour %quest_link, enfin !' WHERE `id`=45;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Oof, jai %quest_obj_available/%quest_obj_required %item_link pour %quest_link' WHERE `id`=46;
UPDATE `ai_playerbot_texts` SET `text_loc2`='il me manque encore %quest_obj_missing de %item_link pour %quest_link' WHERE `id`=47;
UPDATE `ai_playerbot_texts` SET `text_loc2`='%quest_obj_full_formatted, je suis encore sur %quest_link' WHERE `id`=48;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Échec : je nai pas fini %quest_link à temps...' WHERE `id`=49;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Plus de temps pour %quest_link :(' WHERE `id`=50;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Jai terminé tous les objectifs de %quest_link' WHERE `id`=51;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Objectifs terminés pour %quest_link' WHERE `id`=52;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Je vais rendre %quest_link bientôt, tout est fait' WHERE `id`=53;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Ouiii, jai enfin rendu %quest_link' WHERE `id`=54;
UPDATE `ai_playerbot_texts` SET `text_loc2`='%quest_link rendu' WHERE `id`=55;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Mission %quest_link terminée, rendu !' WHERE `id`=56;
UPDATE `ai_playerbot_texts` SET `text_loc2`='%quest_link rendu' WHERE `id`=57;
UPDATE `ai_playerbot_texts` SET `text_loc2`='%quest_link rendu à %zone_name' WHERE `id`=58;
UPDATE `ai_playerbot_texts` SET `text_loc2`='encore un %victim_name à terre' WHERE `id`=59;
UPDATE `ai_playerbot_texts` SET `text_loc2`='je continue à tuer %victim_name, la routine quoi' WHERE `id`=60;
UPDATE `ai_playerbot_texts` SET `text_loc2`='un autre %victim_name qui mord la poussière' WHERE `id`=61;
UPDATE `ai_playerbot_texts` SET `text_loc2`='un %victim_name en moins à %zone_name' WHERE `id`=62;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Jai descendu ce sale élite %victim_name !' WHERE `id`=63;
UPDATE `ai_playerbot_texts` SET `text_loc2`='élite %victim_name éliminé à %zone_name' WHERE `id`=64;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Ouf, jai réussi à abattre %victim_name !' WHERE `id`=65;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Cétait épique ! %victim_name est tombé, maintenant jai une histoire à raconter' WHERE `id`=66;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Yoo, je viens de tuer %victim_name !' WHERE `id`=67;
UPDATE `ai_playerbot_texts` SET `text_loc2`='rare %victim_name éliminé à %zone_name' WHERE `id`=68;
UPDATE `ai_playerbot_texts` SET `text_loc2`='WTF ais-je bien tué? %victim_name' WHERE `id`=69;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Jai tué cette bestiole %victim_name' WHERE `id`=70;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Oh ouiii, jai tué %victim_name' WHERE `id`=71;
UPDATE `ai_playerbot_texts` SET `text_loc2`='%victim_name éliminé à %zone_name' WHERE `id`=72;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Ding !' WHERE `id`=73;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Ouiii, je suis niveau %my_level !' WHERE `id`=74;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Je viens de passer un niveau' WHERE `id`=75;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Je suis niveau %my_level !!!' WHERE `id`=76;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Je deviens plus fort, déjà %my_level !!!' WHERE `id`=77;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Je viens datteindre le niveau %my_level !!!' WHERE `id`=78;
UPDATE `ai_playerbot_texts` SET `text_loc2`='OMG, enfin niveau %my_level !!!' WHERE `id`=79;
UPDATE `ai_playerbot_texts` SET `text_loc2`='%my_level !!! prêt pour le contenu endgame' WHERE `id`=80;
UPDATE `ai_playerbot_texts` SET `text_loc2`='tout frais, nouveau %my_level %my_class !!!' WHERE `id`=81;
UPDATE `ai_playerbot_texts` SET `text_loc2`='encore un niveau %my_level %my_race %my_class !' WHERE `id`=82;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Bien joué %other_name. Tu las mérité.' WHERE `id`=83;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Cétait affreux %other_name. Jai détesté faire ça mais...' WHERE `id`=84;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Quelquun veut faire %instance_name ?' WHERE `id`=85;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Des groupes pour %instance_name ?' WHERE `id`=86;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Besoin daide pour %instance_name ?' WHERE `id`=87;
UPDATE `ai_playerbot_texts` SET `text_loc2`='LFD : %instance_name.' WHERE `id`=88;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Quelquun a besoin dun %my_role pour %instance_name ?' WHERE `id`=89;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Il manque un %my_role pour %instance_name ?' WHERE `id`=90;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Je peux être %my_role pour %instance_name.' WHERE `id`=91;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Besoin dun coup de main à %instance_name ?' WHERE `id`=92;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Besoin dun %my_role pour %instance_name ?' WHERE `id`=93;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Quelquun a besoin de loot à %instance_name ?' WHERE `id`=94;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Un petit farm à %instance_name ?' WHERE `id`=95;
UPDATE `ai_playerbot_texts` SET `text_loc2`='WTR %instance_name' WHERE `id`=96;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Besoin daide pour %instance_name.' WHERE `id`=97;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Envie de faire %instance_name.' WHERE `id`=98;
UPDATE `ai_playerbot_texts` SET `text_loc2`='%my_role cherche un groupe pour %instance_name.' WHERE `id`=99;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Et %instance_name, on y va ?' WHERE `id`=100;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Qui veut farmer %instance_name ?' WHERE `id`=101;
UPDATE `ai_playerbot_texts` SET `text_loc2`='On entre dans %instance_name ?' WHERE `id`=102;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Je cherche groupe pour %instance_name.' WHERE `id`=103;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Des quêtes à %instance_name ?' WHERE `id`=104;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Envie de faire des quêtes à %instance_name.' WHERE `id`=105;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Quelquun avec des quêtes à %instance_name ?' WHERE `id`=106;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Je peux aider pour les quêtes à %instance_name.' WHERE `id`=107;
UPDATE `ai_playerbot_texts` SET `text_loc2`='%my_role : une place dispo pour %instance_name ?' WHERE `id`=108;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Est-ce que quelquun fait encore %instance_name de nos jours ?' WHERE `id`=109;
UPDATE `ai_playerbot_texts` SET `text_loc2`='%instance_name : quelquun cherche un %my_role ?' WHERE `id`=110;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Ça sert encore à quelque chose dêtre %my_role à %instance_name ?' WHERE `id`=111;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Ça vaut vraiment le coup daller à %instance_name ?' WHERE `id`=112;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Quelquun a besoin de plus de joueurs pour %instance_name ?' WHERE `id`=113;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Les boss de %instance_name lootent du bon matos. On y va ?' WHERE `id`=114;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Alors, %instance_name ?' WHERE `id`=115;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Quelquun a besoin dun %my_role ?' WHERE `id`=116;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Quelquun a besoin dun %my_role ?' WHERE `id`=117;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Qui veut aller à %instance_name ?' WHERE `id`=118;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Quelquun peut me TP à %instance_name ?' WHERE `id`=119;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Retrouve-moi à %instance_name' WHERE `id`=120;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Envie dun petit run rapide à %instance_name ?' WHERE `id`=121;
UPDATE `ai_playerbot_texts` SET `text_loc2`='On se fait un run complet à %instance_name ?' WHERE `id`=122;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Tas été combien de fois à %instance_name ?' WHERE `id`=123;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Encore un run à %instance_name ?' WHERE `id`=124;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Wipe à %instance_name ? Prends-moi, je suis un porte-bonheur !' WHERE `id`=125;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Emmène-moi à %instance_name sil te plaît.' WHERE `id`=126;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Un petit %instance_name vite fait bien fait ?' WHERE `id`=127;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Full %instance_name jusquà la fin ?' WHERE `id`=128;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Qui peut prendre un %my_role à %instance_name ?' WHERE `id`=129;
UPDATE `ai_playerbot_texts` SET `text_loc2`='LFG %instance_name, je suis %my_role' WHERE `id`=130;
UPDATE `ai_playerbot_texts` SET `text_loc2`='%my_role cherche groupe pour %instance_name' WHERE `id`=131;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Besoin daide pour %quest_link ?' WHERE `id`=132;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Quelquun veut partager %quest_link ?' WHERE `id`=133;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Quelquun fait %quest_link ?' WHERE `id`=134;
UPDATE `ai_playerbot_texts` SET `text_loc2`='On fait %quest_link ?' WHERE `id`=135;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Quelquun pour farmer du %category ?' WHERE `id`=136;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Cherche aide pour farmer %category.' WHERE `id`=137;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Ces %category coûtent un bras !' WHERE `id`=138;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Jai besoin de %category.' WHERE `id`=139;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Besoin daide pour %category.' WHERE `id`=140;
UPDATE `ai_playerbot_texts` SET `text_loc2`='WTB %category.' WHERE `id`=141;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Quelquun est intéressé par %category ?' WHERE `id`=142;
UPDATE `ai_playerbot_texts` SET `text_loc2`='WTS %category.' WHERE `id`=143;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Je vends %category moins cher que lHV.' WHERE `id`=144;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Qui veut farmer du %category ?' WHERE `id`=145;
UPDATE `ai_playerbot_texts` SET `text_loc2`='On farme du %category ?' WHERE `id`=146;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Je cherche un groupe, après ça on fait du %category ?' WHERE `id`=147;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Tous les %category sont les bienvenus.' WHERE `id`=148;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Jachète tout ce qui ressemble à du %category.' WHERE `id`=149;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Wow, ya des gens qui farment encore du %category ?' WHERE `id`=150;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Les %category partent comme des petits pains à lHV !' WHERE `id`=151;
UPDATE `ai_playerbot_texts` SET `text_loc2`='LHV brûle à cause des %category !' WHERE `id`=152;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Ya des %category sur le marché.' WHERE `id`=153;
UPDATE `ai_playerbot_texts` SET `text_loc2`='J\'échange des %category ?' WHERE `id`=154;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Il me faut plus de %category.' WHERE `id`=155;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Quelquun a un peu de %category à donner ?' WHERE `id`=156;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Qui veut du %category ?' WHERE `id`=157;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Un peu de %category sil vous plaît ?' WHERE `id`=158;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Jaurais monter une compétence pour les %category.' WHERE `id`=159;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Je meurs denvie davoir des %category.' WHERE `id`=160;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Les gens se tuent pour les %category.' WHERE `id`=161;
UPDATE `ai_playerbot_texts` SET `text_loc2`='%category, cest une affaire en or !' WHERE `id`=162;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Tout le monde devient fou pour les %category !' WHERE `id`=163;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Cest le meilleur spot pour farmer des %category ?' WHERE `id`=164;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Je suis prêt pour le farm de %category.' WHERE `id`=165;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Ça se vend bien les %category ?' WHERE `id`=166;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Je vais garder tous mes %category. Pour moi.' WHERE `id`=167;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Besoin dun groupe ? On pourrait farm des %category ensemble.' WHERE `id`=168;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Je pense encore aux %category.' WHERE `id`=169;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Jai entendu parler des %category... mais mon porte-monnaie ne veut pas.' WHERE `id`=170;
UPDATE `ai_playerbot_texts` SET `text_loc2`='LFG pour %category' WHERE `id`=171;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Vendre %category rend riche ?' WHERE `id`=172;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Ok. Demain je farm les %category.' WHERE `id`=173;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Tout le monde parle des %category.' WHERE `id`=174;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Jai vu au moins dix gars farmer du %category.' WHERE `id`=175;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Jai tout vendu mes %category hier. Maintenant je mange du pain sec!' WHERE `id`=176;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Envie de rejoindre une guilde qui farme du %category.' WHERE `id`=177;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Quelquun farm la réputation %faction ?' WHERE `id`=178;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Quelquun peut maider pour %faction ?' WHERE `id`=179;
UPDATE `ai_playerbot_texts` SET `text_loc2`='On fait des quêtes pour %faction ?' WHERE `id`=180;
UPDATE `ai_playerbot_texts` SET `text_loc2`='%faction est la meilleur' WHERE `id`=181;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Il me manque juste un tout petit peu pour être %rep_level avec %faction.' WHERE `id`=182;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Quelquun est %rep_level avec %faction ?' WHERE `id`=183;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Qui veut devenir %rep_level avec %faction ?' WHERE `id`=184;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Je serai jamais %rep_level avec %faction.' WHERE `id`=185;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Quelquun a oublié de monter la réputation %faction ?' WHERE `id`=186;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Je peux aider à farmer la réputation %faction.' WHERE `id`=187;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Plus on a de réputation, mieux cest. Surtout avec %faction.' WHERE `id`=188;
UPDATE `ai_playerbot_texts` SET `text_loc2`='%faction : il me faut encore %rndK pour être %rep_level.' WHERE `id`=189;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Qui peut partager des quêtes %faction ?' WHERE `id`=190;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Des donjons pour la réputation %faction ?' WHERE `id`=191;
UPDATE `ai_playerbot_texts` SET `text_loc2`='On farm la réput %faction ?' WHERE `id`=192;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Allons-y pour %faction !' WHERE `id`=193;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Je farm la réputation %faction.' WHERE `id`=194;
UPDATE `ai_playerbot_texts` SET `text_loc2`='On farme pour %faction ?' WHERE `id`=195;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Besoin daide pour %faction.' WHERE `id`=196;
UPDATE `ai_playerbot_texts` SET `text_loc2`='%faction vend quelque chose dutile ?' WHERE `id`=197;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Il existe des vendeurs %faction ?' WHERE `id`=198;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Qui farme %faction ?' WHERE `id`=199;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Quelle est la meilleure façon de farmer %faction ?' WHERE `id`=200;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Je déteste farmer la réputation %faction.' WHERE `id`=201;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Jen ai marre de %faction.' WHERE `id`=202;
UPDATE `ai_playerbot_texts` SET `text_loc2`='On y va pour %faction ?' WHERE `id`=203;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Tout le monde est %rep_level avec %faction. Et moi, je galère encore.' WHERE `id`=204;
UPDATE `ai_playerbot_texts` SET `text_loc2`='LFG pour farm de réputation %faction ?' WHERE `id`=205;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Quelquun a un bon spot pour la réputation %faction ?' WHERE `id`=206;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Améliorer ma réput %faction, ça sert ?' WHERE `id`=207;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Qui aurait cru que la réputation %faction finirait par servir...' WHERE `id`=208;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Je veux être exalté avec toutes les factions. En commençant par %faction.' WHERE `id`=209;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Est-ce que ça vaut le coup de monter %faction ?' WHERE `id`=210;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Quest-ce qui marche le mieux pour %faction ? Les quêtes ou tuer des mobs ?' WHERE `id`=211;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Je farm %faction pour toi, si tu me paies.' WHERE `id`=212;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Farmer la réputation %faction ? Ça prendra 3 vies au moins.' WHERE `id`=213;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Je tue pour %faction tous les jours, mais je suis toujours pas %rep_level.' WHERE `id`=214;
UPDATE `ai_playerbot_texts` SET `text_loc2`='À %my_level, les dépôts à lHV vont baisser, non ?' WHERE `id`=215;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Combien de réputations exaltées tu as ?' WHERE `id`=216;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Qui veut être %my_level avec %faction ?' WHERE `id`=217;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Ma guilde a farmé la réputation %faction hier. Sans moi...' WHERE `id`=218;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Personne ne veut maider, tout ça parce que je suis %rep_level avec %faction.' WHERE `id`=219;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Évitez la %faction.' WHERE `id`=220;
UPDATE `ai_playerbot_texts` SET `text_loc2`='On se fait une soirée à %zone_name ?' WHERE `id`=221;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Quelquun cherche un %my_role ?' WHERE `id`=222;
UPDATE `ai_playerbot_texts` SET `text_loc2`='%my_role cherche une guilde.' WHERE `id`=223;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Je cherche de lor.' WHERE `id`=224;
UPDATE `ai_playerbot_texts` SET `text_loc2`='%my_role cherche une bonne guilde.' WHERE `id`=225;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Jai besoin dun ami.' WHERE `id`=226;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Quelquun dautre se sent seul ?' WHERE `id`=227;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Je mennuie...' WHERE `id`=228;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Qui en veut ?' WHERE `id`=229;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Allez viens te battre !' WHERE `id`=230;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Un petit duel à %zone_name ?' WHERE `id`=231;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Quelquun fait quelque chose ici ?' WHERE `id`=232;
UPDATE `ai_playerbot_texts` SET `text_loc2`='%zone_name : ya une âme qui vive ici ?' WHERE `id`=233;
UPDATE `ai_playerbot_texts` SET `text_loc2`='%zone_name : tout le monde est en furtif ou quoi ?' WHERE `id`=234;
UPDATE `ai_playerbot_texts` SET `text_loc2`='On dirait que je suis seul à %zone_name.' WHERE `id`=235;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Rejoins-moi à %zone_name .' WHERE `id`=236;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Allez, on fait des quêtes à %zone_name !' WHERE `id`=237;
UPDATE `ai_playerbot_texts` SET `text_loc2`='%zone_name cest LE coin sympa du momment.' WHERE `id`=238;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Jveux aller à %zone_name. Quelquun me suit ?' WHERE `id`=239;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Qui veut aller à %zone_name ?' WHERE `id`=240;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Jaime pas %zone_name. doi-je aller ?' WHERE `id`=241;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Ya de bonnes quêtes à %zone_name ?' WHERE `id`=242;
UPDATE `ai_playerbot_texts` SET `text_loc2`='On va après %zone_name ?' WHERE `id`=243;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Qui traîne à %zone_name ?' WHERE `id`=244;
UPDATE `ai_playerbot_texts` SET `text_loc2`='LFG pour %zone_name.' WHERE `id`=245;
UPDATE `ai_playerbot_texts` SET `text_loc2`='%zone_name est lendroit le plus naze du monde.' WHERE `id`=246;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Attrape-moi à %zone_name si tu peux !' WHERE `id`=247;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Direction %zone_name !' WHERE `id`=248;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Envie de quêtes à %zone_name' WHERE `id`=249;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Quelquun a des quêtes à %zone_name ?' WHERE `id`=250;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Venez à %zone_name !' WHERE `id`=251;
UPDATE `ai_playerbot_texts` SET `text_loc2`='On dirait que la Horde a déserté %zone_name...' WHERE `id`=252;
UPDATE `ai_playerbot_texts` SET `text_loc2`='On dirait que lAlliance a déserté %zone_name...' WHERE `id`=253;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Jen peux plus de %zone_name. Quelquun me sort de ?' WHERE `id`=254;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Bonne chance !' WHERE `id`=255;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Je veux rentrer chez moi puis pleurer au bord du vide' WHERE `id`=256;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Quelquun sait ce quil faut pour jouer double arme ?' WHERE `id`=257;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Salut tout le monde !' WHERE `id`=258;
UPDATE `ai_playerbot_texts` SET `text_loc2`='%zone_name est cosy' WHERE `id`=259;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Je me sens bien' WHERE `id`=260;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Je nignore pas les gens. Je les trolle jusquà ce quils mignorent.' WHERE `id`=261;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Que pensez-vous de mon build ? %my_role' WHERE `id`=262;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Heureux de voir que le chat ne ma pas oublié' WHERE `id`=263;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Comme toutes les armes, cest BiS pour chasseur' WHERE `id`=264;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Le but du jeu pour moi ? Solo tout ce qui bouge.' WHERE `id`=265;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Jai JAMAIS arnaqué personne.' WHERE `id`=266;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Ah, World of Warcraft. je viens chercher des conseils de vie.' WHERE `id`=267;
UPDATE `ai_playerbot_texts` SET `text_loc2`='YA QUELQUUN ?!' WHERE `id`=268;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Il est temps de me frayer un chemin dans %zone_name.' WHERE `id`=269;
UPDATE `ai_playerbot_texts` SET `text_loc2`='%zone_name' WHERE `id`=270;
UPDATE `ai_playerbot_texts` SET `text_loc2`=' faut que jaille aux toilettes.' WHERE `id`=271;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Si tu loot pas tes mobs skinables, ton zizi perd 1mm. Cest la règle.' WHERE `id`=272;
UPDATE `ai_playerbot_texts` SET `text_loc2`='NOOOOOOOOOOOOO' WHERE `id`=273;
UPDATE `ai_playerbot_texts` SET `text_loc2`='JAIME LA PATATE' WHERE `id`=274;
UPDATE `ai_playerbot_texts` SET `text_loc2`='La discussion est animée.' WHERE `id`=275;
UPDATE `ai_playerbot_texts` SET `text_loc2`='salut, comment ça va les gens ?' WHERE `id`=276;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Je viens de me déco / reco.' WHERE `id`=277;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Faites moins de bruit, jsuis perdu dans %zone_name' WHERE `id`=278;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Quelquun veut boire un verre à %zone_name ? hic' WHERE `id`=279;
UPDATE `ai_playerbot_texts` SET `text_loc2`='hahahahaheeeee dirin diring inggggg hahahahaheeeeeeeeeeeeee' WHERE `id`=280;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Avant, les appâts étaient crédibles.' WHERE `id`=281;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Peut-être que tas juste perdu ton innocence.' WHERE `id`=282;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Ya une guilde qui veut carry un %my_role fragile ?' WHERE `id`=283;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Plus on monte en niveau, plus lor coule à flots' WHERE `id`=284;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Bonjour !' WHERE `id`=285;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Pourquoi jai mal au cul ?' WHERE `id`=286;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Je pense que lesprit est BiS pour monter de niveau.' WHERE `id`=287;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Encore plus si tes troll.' WHERE `id`=288;
UPDATE `ai_playerbot_texts` SET `text_loc2`='QUELQUUN PEUT MINVITER ?' WHERE `id`=289;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Jai besoin de beaucouuuup de boissons.' WHERE `id`=290;
UPDATE `ai_playerbot_texts` SET `text_loc2`='P*utain de gnomes' WHERE `id`=291;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Personne naime les gnomes.' WHERE `id`=292;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Les gnomes ne servent quà une chose' WHERE `id`=293;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Bah' WHERE `id`=294;
UPDATE `ai_playerbot_texts` SET `text_loc2`=' des champignons.' WHERE `id`=295;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Les pensées automatiques, cest flippant.' WHERE `id`=296;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Lesprit est plus malléable quon aimerait le croire.' WHERE `id`=297;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Ya des guildes pour leveling ?' WHERE `id`=298;
UPDATE `ai_playerbot_texts` SET `text_loc2`='brb' WHERE `id`=299;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Pourquoi la neige est-elle blanche alors que la glace est transparente, alors quelles sont faites de la même chose ?' WHERE `id`=300;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Pourquoi la crème fouettée est fluffy, mais pas la normale ?' WHERE `id`=301;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Pourquoi les pieds sentent alors quils nont pas de nez ?' WHERE `id`=302;
UPDATE `ai_playerbot_texts` SET `text_loc2`='On dirait que la boîte à noobs vient de souvrir.' WHERE `id`=303;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Arrêtez de troller les nouveaux avec vos réponses à la con.' WHERE `id`=304;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Ya du PvP sur ce serveur ?' WHERE `id`=305;
UPDATE `ai_playerbot_texts` SET `text_loc2`='évidemment...' WHERE `id`=306;
UPDATE `ai_playerbot_texts` SET `text_loc2`='ouf :)' WHERE `id`=307;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Vous saviez que' WHERE `id`=308;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Je ne tente pas dimaginer ce que ressentent les autres créatures' WHERE `id`=309;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Oups, mauvais canal.' WHERE `id`=310;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Bruh, vous êtes déchaînés aujourdhui' WHERE `id`=311;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Juste pour que tout le monde sache : mon message est passé ici' WHERE `id`=312;
UPDATE `ai_playerbot_texts` SET `text_loc2`='grrr énervéééééé' WHERE `id`=313;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Le farm, cest marrant' WHERE `id`=314;
UPDATE `ai_playerbot_texts` SET `text_loc2`='WoW me garde vif' WHERE `id`=315;
UPDATE `ai_playerbot_texts` SET `text_loc2`=', question : on prend le rôle pour plus dXP ? Je suis à %zone_name.' WHERE `id`=316;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Vous aimez les saucisses ?' WHERE `id`=317;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Invitez-moi. Je peux aider.' WHERE `id`=318;
UPDATE `ai_playerbot_texts` SET `text_loc2`='À votre avis, quelle classe est la meilleure en PvP ?' WHERE `id`=319;
UPDATE `ai_playerbot_texts` SET `text_loc2`=' est ce foutu maître de cuisine à %zone_name ?!' WHERE `id`=320;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Vous savez ce quil se passe à %zone_name ?' WHERE `id`=321;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Jai besoin de crafter quelque chose' WHERE `id`=322;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Cest quoi lèchemes' WHERE `id`=323;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Cest quoi sucemes ' WHERE `id`=324;
UPDATE `ai_playerbot_texts` SET `text_loc2`='lèchemes couilles' WHERE `id`=325;
UPDATE `ai_playerbot_texts` SET `text_loc2`='sucemes couilles' WHERE `id`=326;
UPDATE `ai_playerbot_texts` SET `text_loc2`='JE MANGE DES FESSES' WHERE `id`=327;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Jai envie de me fourrer %random_inventory_item_link le soleil ne brille pas' WHERE `id`=328;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Jai envie de te fourrer %random_inventory_item_link tu penses' WHERE `id`=329;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Darnasses' WHERE `id`=330;
UPDATE `ai_playerbot_texts` SET `text_loc2`='On dirait que tas chopé le syndrôme de sucemes' WHERE `id`=331;
UPDATE `ai_playerbot_texts` SET `text_loc2`='cesnoix dans ta bouche' WHERE `id`=332;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Sympa ton os, frérot' WHERE `id`=333;
UPDATE `ai_playerbot_texts` SET `text_loc2`='ERP ?' WHERE `id`=334;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Jai tout essayé, mais au final cest lERP qui a marché' WHERE `id`=335;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Jai envie de batifoler à %zone_name' WHERE `id`=336;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Recherche gnome femelle avec gorille pour ERP sauvage à %zone_name' WHERE `id`=337;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Je peux comprendre un idiot, mais un gros pervers ?' WHERE `id`=338;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Aucun GYAT en vue à %zone_name' WHERE `id`=339;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Je tue tous les animaux de %zone_name. Désolé WWF !' WHERE `id`=340;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Heureusement que jai trois jambes' WHERE `id`=341;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Sois pas vénère, je goon comme un sigma' WHERE `id`=342;
UPDATE `ai_playerbot_texts` SET `text_loc2`='essaye doigt, mais trou' WHERE `id`=343;
UPDATE `ai_playerbot_texts` SET `text_loc2`='%prefix %random_taken_quest_or_item_link' WHERE `id`=344;
UPDATE `ai_playerbot_texts` SET `text_loc2`='%prefix %random_inventory_item_link' WHERE `id`=345;
UPDATE `ai_playerbot_texts` SET `text_loc2`='%thunderfury_link' WHERE `id`=346;
UPDATE `ai_playerbot_texts` SET `text_loc2`='%thunderfury_link%thunderfury_link' WHERE `id`=347;
UPDATE `ai_playerbot_texts` SET `text_loc2`='%thunderfury_link%thunderfury_link%thunderfury_link' WHERE `id`=348;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Je crois que je viens dentendre %thunderfury_link' WHERE `id`=349;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Jai entendu %thunderfury_link' WHERE `id`=350;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Jai clairement entendu %thunderfury_link' WHERE `id`=351;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Jsuis pas sûr, mais jcrois avoir entendu %thunderfury_link' WHERE `id`=352;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Tas dit %thunderfury_link' WHERE `id`=353;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Quelquun a dit %thunderfury_link' WHERE `id`=354;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Quelquun a VRAIMENT dit %thunderfury_link' WHERE `id`=355;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Quelquun a parlé de %thunderfury_link' WHERE `id`=356;
UPDATE `ai_playerbot_texts` SET `text_loc2`='%thunderfury_link sort du placard, les gars' WHERE `id`=357;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Jaurais juré que cétait un %thunderfury_link ou peut-être un %thunderfury_link' WHERE `id`=358;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Pourquoi utiliser %thunderfury_link alors que %thunderfury_link est bien plus OP' WHERE `id`=359;
UPDATE `ai_playerbot_texts` SET `text_loc2`='WTS %item_formatted_link pour %cost_gold.' WHERE `id`=360;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Qui veut %item_formatted_link pour %cost_gold ?' WHERE `id`=361;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Quelquun veut %item_formatted_link ? Seulement %cost_gold' WHERE `id`=362;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Juste %cost_gold pour %item_formatted_link!' WHERE `id`=363;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Je vends %item_formatted_link pour %cost_gold' WHERE `id`=364;
UPDATE `ai_playerbot_texts` SET `text_loc2`='%item_formatted_link est à toi pour seulement %cost_gold !' WHERE `id`=365;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Prix ridicule : %cost_gold pour %item_formatted_link !' WHERE `id`=366;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Je cherche à vendre %item_formatted_link pour %cost_gold' WHERE `id`=367;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Qui a besoin de %item_formatted_link ? Seulement %cost_gold' WHERE `id`=368;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Quelquun veut %item_formatted_link pour %cost_gold ?' WHERE `id`=369;
UPDATE `ai_playerbot_texts` SET `text_loc2`='%cost_gold pour %item_formatted_link. Moins cher quà lHV !' WHERE `id`=370;
UPDATE `ai_playerbot_texts` SET `text_loc2`='%item_formatted_link est cher, mais je te le fais à %cost_gold' WHERE `id`=371;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Tu trouveras jamais %item_formatted_link moins cher que %cost_gold!' WHERE `id`=372;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Jai besoin de plus que %item_formatted_link, !' WHERE `id`=373;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Jai %item_formatted_link et jen veux encore' WHERE `id`=374;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Jai %item_formatted_link. Qui lachète pour %cost_gold ?' WHERE `id`=375;
UPDATE `ai_playerbot_texts` SET `text_loc2`='WTB %item_formatted_link pour %cost_gold, quelquun ?' WHERE `id`=376;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Et %item_formatted_link ? Pour %cost_gold.' WHERE `id`=377;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Qui ma traité d\'arnaqueur ? %item_formatted_link pour %cost_gold cest honnête !' WHERE `id`=378;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Je vends %item_formatted_link. Juste %cost_gold' WHERE `id`=379;
UPDATE `ai_playerbot_texts` SET `text_loc2`='LFG pour du farm, et au passage %item_formatted_link à vendre %cost_gold' WHERE `id`=380;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Presque tout vendu aujourdhui. Me reste %item_formatted_link pour %cost_gold' WHERE `id`=381;
UPDATE `ai_playerbot_texts` SET `text_loc2`='À quoi sert le canal commerce ? A vendre %item_formatted_link pour %cost_gold, évidemment' WHERE `id`=382;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Quelquun peut battre %cost_gold pour %item_formatted_link ?' WHERE `id`=383;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Envie darrêter le spam commerce ? Achetez %item_formatted_link à %cost_gold !' WHERE `id`=384;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Tout le monde spam, moi aussi : %cost_gold pour %item_formatted_link !' WHERE `id`=385;
UPDATE `ai_playerbot_texts` SET `text_loc2`='%item_formatted_link est utile ? Je sais pas, mais je le vends %cost_gold' WHERE `id`=386;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Jai %item_formatted_link prêt à vendre %cost_gold' WHERE `id`=387;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Hier jai rien foutu, mais jai loot %item_formatted_link. À vendre %cost_gold' WHERE `id`=388;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Jai farmé hier, jai eu %item_formatted_link. WTB ? %cost_gold' WHERE `id`=389;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Jai acheté %item_formatted_link hier. Quelquun le veut ? %cost_gold' WHERE `id`=390;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Quelquun cherchait %item_formatted_link ? Cest %cost_gold toujours' WHERE `id`=391;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Jai encore %item_formatted_link. Achetez-le %cost_gold' WHERE `id`=392;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Avant jen avais plein %item_formatted_link, maintenant je dois vendre à %cost_gold' WHERE `id`=393;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Jaimerais en avoir plus que %item_formatted_link. Mais achetez celui-là %cost_gold' WHERE `id`=394;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Ton or te sert à quoi ? À acheter %item_formatted_link pour %cost_gold' WHERE `id`=395;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Ayez pitié, donnez-moi de lor... ou achetez %item_formatted_link %cost_gold' WHERE `id`=396;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Est-ce que %cost_gold est un bon prix pour %item_formatted_link ?' WHERE `id`=397;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Jai acheté %item_formatted_links hier, mais jen veux plus. Quelqu\'un vends pour %cost_gold' WHERE `id`=398;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Je vais le mettre à lHV %item_formatted_link, mais tu peux lavoir moins cher : %cost_gold' WHERE `id`=399;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Pourquoi jai acheté %item_formatted_link bordel ? Quelquun le veut ? %cost_gold' WHERE `id`=400;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Jai %quest_links' WHERE `id`=401;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Moi aussi jai %quest_links' WHERE `id`=402;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Moi aussi jai %quest_links, je suis à %zone_name' WHERE `id`=403;
UPDATE `ai_playerbot_texts` SET `text_loc2`='%other_name, moi aussi jai %quest_links' WHERE `id`=404;
UPDATE `ai_playerbot_texts` SET `text_loc2`='%other_name, moi aussi jai %quest_links, et je suis à %zone_name' WHERE `id`=405;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Je suis dispo pour %quest_links, je suis à %zone_name' WHERE `id`=406;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Je suis dispo pour %quest_links, je suis %my_role' WHERE `id`=407;
UPDATE `ai_playerbot_texts` SET `text_loc2`='%other_name, je suis dispo pour %quest_links à %zone_name' WHERE `id`=408;
UPDATE `ai_playerbot_texts` SET `text_loc2`='%other_name, je suis dispo pour %quest_links, je suis %my_role' WHERE `id`=409;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Hey, je suis partant pour %quest_links' WHERE `id`=410;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Hey, je pourrais faire %quest_links avec toi' WHERE `id`=411;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Hey, moi aussi jai %quest_links' WHERE `id`=412;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Hey %other_name, partant pour %quest_links' WHERE `id`=413;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Hey %other_name, je peux faire %quest_links avec toi' WHERE `id`=414;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Hey %other_name, moi aussi jai %quest_links' WHERE `id`=415;
UPDATE `ai_playerbot_texts` SET `text_loc2`='On se groupe pour %quest_links ?' WHERE `id`=416;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Je suis partant pour %quest_links, je suis à %zone_name' WHERE `id`=417;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Je suis dispo pour %quest_links, je suis %my_role' WHERE `id`=418;
UPDATE `ai_playerbot_texts` SET `text_loc2`='%other_name, je peux te vendre %formatted_item_links' WHERE `id`=419;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Je peux peut-être vendre %formatted_item_links' WHERE `id`=420;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Je pense pouvoir vendre %formatted_item_links' WHERE `id`=421;
UPDATE `ai_playerbot_texts` SET `text_loc2`='%other_name, je peux peut-être te vendre %formatted_item_links' WHERE `id`=422;
UPDATE `ai_playerbot_texts` SET `text_loc2`='%other_name, tu penses que je peux vendre %formatted_item_links ?' WHERE `id`=423;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Je peux te vendre %formatted_item_links' WHERE `id`=424;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Hey, jai %formatted_item_links à vendre' WHERE `id`=425;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Hey, je pourrais peut-être vendre %formatted_item_links' WHERE `id`=426;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Quête acceptée' WHERE `id`=427;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Quête abandonnée' WHERE `id`=428;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Je ne peux pas prendre cette quête' WHERE `id`=429;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Je ne peux pas parler au donneur de quête' WHERE `id`=430;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Jai déjà terminé %quest' WHERE `id`=431;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Jai déjà la quête %quest' WHERE `id`=432;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Je ne peux pas prendre %quest' WHERE `id`=433;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Je ne peux pas prendre %quest, mon journal de quêtes est plein' WHERE `id`=434;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Je ne peux pas prendre %quest, mes sacs sont pleins' WHERE `id`=435;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Jai accepté la quête %quest' WHERE `id`=436;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Je nai pas encore terminé la quête %quest' WHERE `id`=437;
UPDATE `ai_playerbot_texts` SET `text_loc2`='La quête %quest est dispo' WHERE `id`=438;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Jai échoué à la quête %quest' WHERE `id`=439;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Je ne peux pas rendre la quête %quest' WHERE `id`=440;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Jai terminé la quête %quest' WHERE `id`=441;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Jai terminé la quête %quest et reçu %item' WHERE `id`=442;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Quelle récompense devrais-je choisir pour la quête %quest ? %rewards' WHERE `id`=443;
UPDATE `ai_playerbot_texts` SET `text_loc2`='OK, je vais prendre %item comme récompense' WHERE `id`=444;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Bonjour' WHERE `id`=445;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Bonjour !' WHERE `id`=446;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Salut' WHERE `id`=447;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Salut !' WHERE `id`=448;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Salut à toi !' WHERE `id`=449;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Bonjour, je vous suis !' WHERE `id`=450;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Bonjour, montrez-moi le chemin !' WHERE `id`=451;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Salut, montre-moi le chemin !' WHERE `id`=452;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Hey %player, tu veux rejoindre mon groupe ?' WHERE `id`=453;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Hey %player, tu veux rejoindre mon groupe ?' WHERE `id`=454;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Déconnexion annulée !' WHERE `id`=455;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Je me déconnecte !' WHERE `id`=456;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Au revoir !' WHERE `id`=457;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Bye bye !' WHERE `id`=458;
UPDATE `ai_playerbot_texts` SET `text_loc2`='À plus tard !' WHERE `id`=459;
UPDATE `ai_playerbot_texts` SET `text_loc2`='cétait quoi ce truc %s ?' WHERE `id`=460;
UPDATE `ai_playerbot_texts` SET `text_loc2`='pas sûr davoir compris %s ?' WHERE `id`=461;
UPDATE `ai_playerbot_texts` SET `text_loc2`='euh jai aucune idée de ce que tu racontes' WHERE `id`=462;
UPDATE `ai_playerbot_texts` SET `text_loc2`='tu parles à moi, %s ?' WHERE `id`=463;
UPDATE `ai_playerbot_texts` SET `text_loc2`='whaaaa ?' WHERE `id`=464;
UPDATE `ai_playerbot_texts` SET `text_loc2`='hein ?' WHERE `id`=465;
UPDATE `ai_playerbot_texts` SET `text_loc2`='quoi ?' WHERE `id`=466;
UPDATE `ai_playerbot_texts` SET `text_loc2`='tu parles ou tu râles ?' WHERE `id`=467;
UPDATE `ai_playerbot_texts` SET `text_loc2`='comme tu veux, mec' WHERE `id`=468;
UPDATE `ai_playerbot_texts` SET `text_loc2`='tu mas perdu ' WHERE `id`=469;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Bla bla bla' WHERE `id`=470;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Tas dit quoi, %s ?' WHERE `id`=471;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Concentre-toi sur le jeu, %s !' WHERE `id`=472;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Parler avec toi %s, cest génial ! Jai toujours rêvé de te rencontrer' WHERE `id`=473;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Ces messages me font flipper ! Jai limpression de tous vous connaître !' WHERE `id`=474;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Ouais bien sûr ! HAHA ! Cest ça, allez !' WHERE `id`=475;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Je te crois !!!' WHERE `id`=476;
UPDATE `ai_playerbot_texts` SET `text_loc2`='OK, uhuh LOL' WHERE `id`=477;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Pourquoi tout le monde dit toujours les mêmes trucs ???' WHERE `id`=478;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Hey %s euh, laisse tomber !' WHERE `id`=479;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Tu parles de quoi %s ? Sérieux ?' WHERE `id`=480;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Qui a dit ça ? Je me sens visé ' WHERE `id`=481;
UPDATE `ai_playerbot_texts` SET `text_loc2`='wtf vous racontez tous ?' WHERE `id`=482;
UPDATE `ai_playerbot_texts` SET `text_loc2`='fr fr no cap on a stack' WHERE `id`=483;
UPDATE `ai_playerbot_texts` SET `text_loc2`='tauras que dalle' WHERE `id`=484;
UPDATE `ai_playerbot_texts` SET `text_loc2`='swag' WHERE `id`=485;
UPDATE `ai_playerbot_texts` SET `text_loc2`='merci !' WHERE `id`=486;
UPDATE `ai_playerbot_texts` SET `text_loc2`='non' WHERE `id`=487;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Yep' WHERE `id`=488;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Paix à son ame.' WHERE `id`=489;
UPDATE `ai_playerbot_texts` SET `text_loc2`='%s sans déconner xD' WHERE `id`=490;
UPDATE `ai_playerbot_texts` SET `text_loc2`='pourquoi ça ?' WHERE `id`=491;
UPDATE `ai_playerbot_texts` SET `text_loc2`='mdr' WHERE `id`=492;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Je pensais fermer ma gueule, jai encore rien compris au chat' WHERE `id`=493;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Je peux devenir vraiment jaloux... comme un elfe sans loot' WHERE `id`=494;
UPDATE `ai_playerbot_texts` SET `text_loc2`='%s tu captes pas le sarcasme qui dégouline de mon message ?' WHERE `id`=495;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Il a dit "no homo", donc cest bon apparemment' WHERE `id`=496;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Instant nain' WHERE `id`=497;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Oui %s' WHERE `id`=498;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Intéressant' WHERE `id`=499;
UPDATE `ai_playerbot_texts` SET `text_loc2`='lol' WHERE `id`=500;
UPDATE `ai_playerbot_texts` SET `text_loc2`='%s va te faire voir mec :D' WHERE `id`=501;
UPDATE `ai_playerbot_texts` SET `text_loc2`=':^)' WHERE `id`=502;
UPDATE `ai_playerbot_texts` SET `text_loc2`='merci' WHERE `id`=503;
UPDATE `ai_playerbot_texts` SET `text_loc2`='%s bien dit !' WHERE `id`=504;
UPDATE `ai_playerbot_texts` SET `text_loc2`='ouiiiii' WHERE `id`=505;
UPDATE `ai_playerbot_texts` SET `text_loc2`='ouais' WHERE `id`=506;
UPDATE `ai_playerbot_texts` SET `text_loc2`='ooooooh' WHERE `id`=507;
UPDATE `ai_playerbot_texts` SET `text_loc2`='hmm' WHERE `id`=508;
UPDATE `ai_playerbot_texts` SET `text_loc2`='ouais cest ça' WHERE `id`=509;
UPDATE `ai_playerbot_texts` SET `text_loc2`='tas failli me faire vomir, wtf' WHERE `id`=510;
UPDATE `ai_playerbot_texts` SET `text_loc2`='chaud !' WHERE `id`=511;
UPDATE `ai_playerbot_texts` SET `text_loc2`='les rageux pleurent' WHERE `id`=512;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Tas mangé quoi %s ?' WHERE `id`=513;
UPDATE `ai_playerbot_texts` SET `text_loc2`='wtf' WHERE `id`=514;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Je vais essayer de comprendre ce que tas dit' WHERE `id`=515;
UPDATE `ai_playerbot_texts` SET `text_loc2`='*confus*' WHERE `id`=516;
UPDATE `ai_playerbot_texts` SET `text_loc2`='putain ouais' WHERE `id`=517;
UPDATE `ai_playerbot_texts` SET `text_loc2`='0/10 ne lirait pas ça une deuxième fois' WHERE `id`=518;
UPDATE `ai_playerbot_texts` SET `text_loc2`='10/10 je relis direct' WHERE `id`=519;
UPDATE `ai_playerbot_texts` SET `text_loc2`='6/10 ouais, pourquoi pas' WHERE `id`=520;
UPDATE `ai_playerbot_texts` SET `text_loc2`='7/10 ça passe' WHERE `id`=521;
UPDATE `ai_playerbot_texts` SET `text_loc2`='basé' WHERE `id`=522;
UPDATE `ai_playerbot_texts` SET `text_loc2`='ah ouais peut-être' WHERE `id`=523;
UPDATE `ai_playerbot_texts` SET `text_loc2`='ouais, et alors ?' WHERE `id`=524;
UPDATE `ai_playerbot_texts` SET `text_loc2`='hey %s je tai pas oublié' WHERE `id`=525;
UPDATE `ai_playerbot_texts` SET `text_loc2`='tu ménerves %s' WHERE `id`=526;
UPDATE `ai_playerbot_texts` SET `text_loc2`='je vais tavoir cette fois %s' WHERE `id`=527;
UPDATE `ai_playerbot_texts` SET `text_loc2`='garde un œil derrière toi %s' WHERE `id`=528;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Jai pas trop aimé la manche davant' WHERE `id`=529;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Jai é nul au dernier round à cause de %s' WHERE `id`=530;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Prépare-toi à mourir %s' WHERE `id`=531;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Jai pas trop kiffé que tu me tues %s' WHERE `id`=532;
UPDATE `ai_playerbot_texts` SET `text_loc2`='%s, je te hais' WHERE `id`=533;
UPDATE `ai_playerbot_texts` SET `text_loc2`='grrrrr je vais tavoir cette fois %s' WHERE `id`=534;
UPDATE `ai_playerbot_texts` SET `text_loc2`='eh bien va te faire foutre' WHERE `id`=535;
UPDATE `ai_playerbot_texts` SET `text_loc2`='%s je vais vomir dans ta putain de bouche' WHERE `id`=536;
UPDATE `ai_playerbot_texts` SET `text_loc2`='me juge pas bordel' WHERE `id`=537;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Ta mère est tellement grosse quelle passe même pas le Portail des Ténèbres' WHERE `id`=538;
UPDATE `ai_playerbot_texts` SET `text_loc2`='wtf' WHERE `id`=539;
UPDATE `ai_playerbot_texts` SET `text_loc2`='wtf ??' WHERE `id`=540;
UPDATE `ai_playerbot_texts` SET `text_loc2`='vie misérable' WHERE `id`=541;
UPDATE `ai_playerbot_texts` SET `text_loc2`='quest-ce qui se passe ?' WHERE `id`=542;
UPDATE `ai_playerbot_texts` SET `text_loc2`='nul à chier' WHERE `id`=543;
UPDATE `ai_playerbot_texts` SET `text_loc2`='REVANCHE !!! Je vais léclater' WHERE `id`=544;
UPDATE `ai_playerbot_texts` SET `text_loc2`='pathétique, je me suis fait tuer par %s' WHERE `id`=545;
UPDATE `ai_playerbot_texts` SET `text_loc2`='ok jen ai fini' WHERE `id`=546;
UPDATE `ai_playerbot_texts` SET `text_loc2`=' , jai explosé %s ?' WHERE `id`=547;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Cétait trop facile, d\'exploser %s' WHERE `id`=548;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Tes grillé, clochard' WHERE `id`=549;
UPDATE `ai_playerbot_texts` SET `text_loc2`='ha ha' WHERE `id`=550;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Loser' WHERE `id`=551;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Jai tué %s et vous êtes tous les prochains, les gars' WHERE `id`=552;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Oh ouais, je lai éclaté' WHERE `id`=553;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Je suis une machine à tuer' WHERE `id`=554;
UPDATE `ai_playerbot_texts` SET `text_loc2`='%s, ça me rappelle un morceau de Slayer… tout ce sang, cest beau' WHERE `id`=555;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Désolé %s. On peut refaire la scène ?' WHERE `id`=556;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Alors %s… ça fait quoi de nourrir les vers ???' WHERE `id`=557;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Tétais censé être mort %s ! Cest dans le script bon sang !' WHERE `id`=558;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Désolé %s. Franchement, cétait aussi beau quun Warhol !' WHERE `id`=559;
UPDATE `ai_playerbot_texts` SET `text_loc2`='%s, je prendrai les balles en caoutchouc la prochaine fois, promis !' WHERE `id`=560;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Quest-ce quil y a %s ?? Tas perdu la tête ? Hahaha, faut rester cool !' WHERE `id`=561;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Fallait que je le fasse %s… Le Réalisateur me la dit !' WHERE `id`=562;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Hey %s… MUAHAHAHAHAHAHAHAHAHAHA' WHERE `id`=563;
UPDATE `ai_playerbot_texts` SET `text_loc2`='%s, celle-là, je lai savourée !! Allez, on recommence Sam !' WHERE `id`=564;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Hey %s ! Tu peux commencer à mappeler Scarface… espèce de M…erde !' WHERE `id`=565;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Tu me parles à moi %s ?? Tu me parles à MOI ?!' WHERE `id`=566;
UPDATE `ai_playerbot_texts` SET `text_loc2`='%s, fais-le bien cette fois, évite MES balles.' WHERE `id`=567;
UPDATE `ai_playerbot_texts` SET `text_loc2`='%s, pourquoi tu traînes par terre ? Allez bouge !' WHERE `id`=568;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Jai rigolé comme jamais' WHERE `id`=569;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Salut %s' WHERE `id`=570;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Oh, salut %s' WHERE `id`=571;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Wazzup %s !!!' WHERE `id`=572;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Salut' WHERE `id`=573;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Wazzup' WHERE `id`=574;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Bonjour %s' WHERE `id`=575;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Salut %s, je te connais ?' WHERE `id`=576;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Hey %s' WHERE `id`=577;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Hai %s' WHERE `id`=578;
UPDATE `ai_playerbot_texts` SET `text_loc2`='cest quoi ce délire' WHERE `id`=579;
UPDATE `ai_playerbot_texts` SET `text_loc2`='wtf' WHERE `id`=580;
UPDATE `ai_playerbot_texts` SET `text_loc2`='cest du foutage de gueule' WHERE `id`=581;
UPDATE `ai_playerbot_texts` SET `text_loc2`='admin' WHERE `id`=582;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Hey %s, arrête dabuser de ton admin là' WHERE `id`=583;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Lâche-moi admin !' WHERE `id`=584;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Tes nul admin' WHERE `id`=585;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Cest mon nom ça, tu veux quoi %s ?' WHERE `id`=586;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Oui ???' WHERE `id`=587;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Euh… quoi ?' WHERE `id`=588;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Tu me parles à moi %s ?' WHERE `id`=589;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Jai des chiots sous mon armure !' WHERE `id`=590;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Mords-moi, <target> !' WHERE `id`=591;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Hey <target> ! Devine ce que ta mère a dit hier soir !' WHERE `id`=592;
UPDATE `ai_playerbot_texts` SET `text_loc2`='<target>, tes tellement moche que tu pourrais même pas scorer dans un bordel de singes avec un sac de bananes !' WHERE `id`=593;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Tais-toi <target>, tu seras jamais lhomme que ta mère est !!' WHERE `id`=594;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Ta mère était un hamster et ton père sentait la surette !' WHERE `id`=595;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Je ne veux plus te parler, espèce de vide-écuelle à bestiaux débiles !!!' WHERE `id`=596;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Je pète dans ta direction générale !!!' WHERE `id`=597;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Va faire bouillir ton postérieur, fils dun imbécile cosmique !!!' WHERE `id`=598;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Tu comptes faire quoi <target>, saigner sur moi ? ALLEZ, VIENS !' WHERE `id`=599;
UPDATE `ai_playerbot_texts` SET `text_loc2`='M-O-O-N ! Ça veut dire aggro !' WHERE `id`=600;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Tes aussi utile quun unijambiste dans un concours de coups de pied au cul' WHERE `id`=601;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Hey <target> ! Arrête de draguer, cest pas ton genre. Cest pas gonflable.' WHERE `id`=602;
UPDATE `ai_playerbot_texts` SET `text_loc2`='<target>, tes tellement hors catégorie que tu joues carrément à un autre sport' WHERE `id`=603;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Tu as fait une grosse erreur aujourdhui <target>… tes sorti du lit.' WHERE `id`=604;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Je veux essayer de me transformer en cheval. Je prends lavant, et toi… tu restes toi.' WHERE `id`=605;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Je peux emprunter ton visage ? Mon cul part en vacances.' WHERE `id`=606;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Jaimerais toffrir un cadeau de départ… dabord, fais ta part.' WHERE `id`=607;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Avant que tarrives, on avait faim. Maintenant on en a juste marre.' WHERE `id`=608;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Je taime bien. Les gens disent que jai mauvais goût, mais je taime bien.' WHERE `id`=609;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Je pense que tas un complexe dinfériorité… mais tinquiète, il est mérité.' WHERE `id`=610;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Arrière, créature pourrie ! Ou je secoue tes os hors de ta tunique !' WHERE `id`=611;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Je crois pas que je perds mon temps avec toi… et pourtant !' WHERE `id`=612;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Jadore quand on minsulte : jai plus besoin dêtre poli.' WHERE `id`=613;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Espèce de veston de cuir, boutons en cristal, tête nouée, braillard à gerbe, jarretière de puce, langue mielleuse, bourse espagnole !' WHERE `id`=614;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Espèce de pleurnichard, chasseur de chauve-souris, ivrogne de malte !' WHERE `id`=615;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Tes vraiment une idole pour les adorateurs de lidiotie !' WHERE `id`=616;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Misérable piaf mal dégrossi !' WHERE `id`=617;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Fils de mandragore ! Tes plus utile en plumeau quen laquais !' WHERE `id`=618;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Toi ! Gueux ! Cloporte ! Tarlouze ! Je vais chatouiller ta catastrophe !' WHERE `id`=619;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Oh <target> ! Infâme fille de lin mal élevé !' WHERE `id`=620;
UPDATE `ai_playerbot_texts` SET `text_loc2`='On fuit par ta cheminée, <target> !' WHERE `id`=621;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Oh toi, misérable fleur de cancre gorgée de marais !' WHERE `id`=622;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Si jétais comme toi, je me jetterais à la poubelle.' WHERE `id`=623;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Apprends-moi <target>… à ne plus penser du tout.' WHERE `id`=624;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Tes maudit comme un œuf mal rôti… tout cramé dun côté.' WHERE `id`=625;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Espèce de gringalet, de peau de hareng, de langue de bœuf séchée, de… souffle… taureau démembré, morceau de corde ! Queue dépée, boîte à rien, tige de tailleur !' WHERE `id`=626;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Fi ! Quon te jette dans la bouche pourrie de la Mort !' WHERE `id`=627;
UPDATE `ai_playerbot_texts` SET `text_loc2`='<target>, tes poissonnier, avoue !' WHERE `id`=628;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Je vivrai assez pour te défoncer le crâne !' WHERE `id`=629;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Tes aussi profond quune flaque ! <target>, tes bonne pour les vers, pas pour la viande !' WHERE `id`=630;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Vermine ! Ô <target>, espèce de noisette infernale puante !' WHERE `id`=631;
UPDATE `ai_playerbot_texts` SET `text_loc2`='<target> ! Ton baiser est aussi réconfortant quun glaçon pour un serpent affamé !' WHERE `id`=632;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Je te méprise, compagnon galeux. Quoi, pauvre arnaqueur sans chemise ! Dégage, raclure moisie !' WHERE `id`=633;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Hors de ma vue ! Tu infectes mes yeux <target> !' WHERE `id`=634;
UPDATE `ai_playerbot_texts` SET `text_loc2`='HEURE DE JEU !!!!' WHERE `id`=635;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Personne ne passera !' WHERE `id`=636;
UPDATE `ai_playerbot_texts` SET `text_loc2`='On est attaqués ! Hissez les voiles ! Repoussez les intrus !' WHERE `id`=637;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Personne ne défie la Confrérie !' WHERE `id`=638;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Imbéciles… tuez celui en robe !' WHERE `id`=639;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Je vais offrir ton âme à Hakkar lui-même !' WHERE `id`=640;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Lorgueil annonce la fin de ton monde ! Venez, mortels ! Affrontez la colère de la %randomfaction !' WHERE `id`=641;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Tous mes plans menaient à CE moment !' WHERE `id`=642;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Ahh ! Encore des agneaux pour labattoir !' WHERE `id`=643;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Encore une journée, encore une glorieuse bataille !' WHERE `id`=644;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Alors, affaires… ou plaisir ?' WHERE `id`=645;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Vous nêtes pas préparés !' WHERE `id`=646;
UPDATE `ai_playerbot_texts` SET `text_loc2`='La conquête finale de la %randomfaction a commencé ! Cette fois, aucun ne survivra !' WHERE `id`=647;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Ta mort sera douloureuse.' WHERE `id`=648;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Implore pitié ! Tes vies inutiles vont être sacrifiées.' WHERE `id`=649;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Abandonne tout espoir ! La %randomfaction est revenue pour finir ce qui a commencé… et cette fois, pas déchappatoire !' WHERE `id`=650;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Alerte ! Tu es marqué pour lEXTERMINATION !' WHERE `id`=651;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Le %subzone est réservé aux invités seulement…' WHERE `id`=652;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Ha ha ha ! Tu es totalement dépassé !' WHERE `id`=653;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Je vais écraser tes illusions de grandeur !' WHERE `id`=654;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Pardonne-moi, mais tu vas perdre cette partie.' WHERE `id`=655;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Résister ne fait quempirer les choses.' WHERE `id`=656;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Vermine ! Sangsues ! Prends mon sang et étouffe-toi avec !' WHERE `id`=657;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Pas encore… PAS ENCORE !' WHERE `id`=658;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Mon sang sera ta perte !' WHERE `id`=659;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Parfait. Maintenant bats-toi contre moi !' WHERE `id`=660;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Allez les gardes ! Cest lheure de tuer !' WHERE `id`=661;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Nattends pas la mort, viens à moi. Je rendrai ton sacrifice rapide.' WHERE `id`=662;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Tu seras mort très bientôt !' WHERE `id`=663;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Mouahaha !' WHERE `id`=664;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Cest moi le prédateur ! Toi, la proie...' WHERE `id`=665;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Tu vas repartir en morceaux !' WHERE `id`=666;
UPDATE `ai_playerbot_texts` SET `text_loc2`='La mort approche... As-tu la conscience tranquille ?' WHERE `id`=667;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Ton comportement ne sera pas toléré.' WHERE `id`=668;
UPDATE `ai_playerbot_texts` SET `text_loc2`='La Ménagerie est réservée aux invités.' WHERE `id`=669;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Hmm, des visiteurs non annoncés… Il faut se préparer…' WHERE `id`=670;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Entités hostiles détectées. Évaluation de menace en cours. Cible principale verrouillée. Réévaluation dans trente secondes.' WHERE `id`=671;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Des nouveaux jouets ? Pour moi ? Promis, je les casse pas… cette fois !' WHERE `id`=672;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Je suis prêt à jouer !' WHERE `id`=673;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Chut… tout sera fini bientôt.' WHERE `id`=674;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Aaaaaughibbrgubugbugrguburgle !' WHERE `id`=675;
UPDATE `ai_playerbot_texts` SET `text_loc2`='RwlRwlRwlRwl !' WHERE `id`=676;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Toi aussi, tu serviras !' WHERE `id`=677;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Dis-moi... dis-moi tout ! Tes vilains petits secrets ! Je vais les arracher de ta chair !' WHERE `id`=678;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Préparez-vous, les cloches ont sonné ! Protégez vos faibles, vos jeunes et vos vieux ! Chacun paiera le prix final ! Implorerez-vous pitié ? Le Jugement est arrivé !' WHERE `id`=679;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Mais où suis-je, par les boutons en laiton de Bonzo ?' WHERE `id`=680;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Je nen peux plus ! Roi Gobelin ! Roi Gobelin ! Où que tu sois ! Emporte ce <target> loin de moi !' WHERE `id`=681;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Tu as treize heures pour résoudre le labyrinthe... sinon ton petit frère deviendra lun des nôtres... pour toujours.' WHERE `id`=682;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Alors, le <subzone> cest du gâteau, hein ? Voyons comment tu gères ce petit bout-là…' WHERE `id`=683;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Recule, jvais taffronter. Déterminé, prêt à affronter nimporte qui. Jsais que tas tort, tas rien à faire ici !' WHERE `id`=684;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Montre-moi cque tas dans le ventre !' WHERE `id`=685;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Jusquà la mort !' WHERE `id`=686;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Double lame, pour un rasage net à chaque fois !' WHERE `id`=687;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Allez, viens !' WHERE `id`=688;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Tu vas tomber !' WHERE `id`=689;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Piou piou, coup de couteau !' WHERE `id`=690;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Finissons-en vite, le temps cest du mana.' WHERE `id`=691;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Je ne crois pas que tu réalises dans quelle merde tu es.' WHERE `id`=692;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Je vais faire honneur à ma famille et à mon royaume !' WHERE `id`=693;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Lumière, donne-moi la force !' WHERE `id`=694;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Mon église, cest le champ de bataille lheure de la messe a sonné !' WHERE `id`=695;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Je te tiens en mépris total…' WHERE `id`=696;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Affronte le marteau de la justice !' WHERE `id`=697;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Prouve ta valeur dans lépreuve des armes, sous la Lumière !' WHERE `id`=698;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Tous doivent tomber devant la puissance de ma cause tu es le prochain !' WHERE `id`=699;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Prépare-toi à mourir !' WHERE `id`=700;
UPDATE `ai_playerbot_texts` SET `text_loc2`='La bête en moi est bien pire que celle à mes côtés…' WHERE `id`=701;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Admire la puissance de feu dun chasseur totalement équipé !' WHERE `id`=702;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Soigne-moi ! Vite !' WHERE `id`=703;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Je suis presque mort ! Soignez-moi !' WHERE `id`=704;
UPDATE `ai_playerbot_texts` SET `text_loc2`='À laide ! Soignez-moi !' WHERE `id`=705;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Quelquun ! Un soin vite !' WHERE `id`=706;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Heal ! Heal ! Heal !' WHERE `id`=707;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Je meurs ! Soin ! Aaaaarhg !' WHERE `id`=708;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Soignez-moi !' WHERE `id`=709;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Je vais mourir. Je vais mourir. Je vais mourir. Soignez-moi !' WHERE `id`=710;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Healers, vous êtes où ? Je crève !' WHERE `id`=711;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Ouille, la douleur ! Soignez vite !' WHERE `id`=712;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Besoin de soin' WHERE `id`=713;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Vie basse !' WHERE `id`=714;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Lâche un heal. Sil te plaît.' WHERE `id`=715;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Quelquun peut me balancer un soin ?' WHERE `id`=716;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Hey ! Mieux vaut me soigner maintenant que me rez plus tard !' WHERE `id`=717;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Désolé… mais encore un heal, please.' WHERE `id`=718;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Saletés de mobs… heal moi vite !' WHERE `id`=719;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Encore un coup et je suis mort. Un petit heal ?' WHERE `id`=720;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Ya des soigneurs dans cette galère ?' WHERE `id`=721;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Pourquoi cest toujours ma tête quils frappent ? Jai besoin dun soin !' WHERE `id`=722;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Quelquun pour me soigner un chouïa ?' WHERE `id`=723;
UPDATE `ai_playerbot_texts` SET `text_loc2`='OOM' WHERE `id`=724;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Plus de mana !' WHERE `id`=725;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Jai cramé tout mon mana pour ça, sérieux...' WHERE `id`=726;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Faudrait attendre que je boive ou que je régène, là…' WHERE `id`=727;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Mana faible… très faible…' WHERE `id`=728;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Encore à sec ? Pas de mana, encore.' WHERE `id`=729;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Mana bas. Je veux une boisson !' WHERE `id`=730;
UPDATE `ai_playerbot_texts` SET `text_loc2`='On a une machine à boissons ? Jai encore plus rien !' WHERE `id`=731;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Mon mana ? Parti dans les limbes.' WHERE `id`=732;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Jachèterai des boissons la prochaine fois. Là jai que dalle.' WHERE `id`=733;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Où est passé mon mana ?' WHERE `id`=734;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Il me reste quelques <ammo> !' WHERE `id`=735;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Besoin de plus de <ammo> !' WHERE `id`=736;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Plus que 100 <ammo> !' WHERE `id`=737;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Cest fini ! Plus un seul <ammo> !' WHERE `id`=738;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Et tu as mon arc… oups, plus de <ammo> !' WHERE `id`=739;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Jai besoin de munitions !' WHERE `id`=740;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Oh mon dieu !' WHERE `id`=741;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Jai peur… là… vraiment.' WHERE `id`=742;
UPDATE `ai_playerbot_texts` SET `text_loc2`='On est foutus !' WHERE `id`=743;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Cest fini. F.I.N.I.' WHERE `id`=744;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Ça se termine maintenant.' WHERE `id`=745;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Quelquun peut balancer un blizzard ou un truc ?!' WHERE `id`=746;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Mince. Le tank a aggro TOUT le monde…' WHERE `id`=747;
UPDATE `ai_playerbot_texts` SET `text_loc2`='On va mourir. On va mourir. On VA MOURIR !' WHERE `id`=748;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Wow ! Tant de jouets à casser !' WHERE `id`=749;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Je vais tous les buter ! TOUS !' WHERE `id`=750;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Si le tank meurt, cest foutu pour nous tous…' WHERE `id`=751;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Aaaaaargh !' WHERE `id`=752;
UPDATE `ai_playerbot_texts` SET `text_loc2`='LEEEEERROOOYYYYYYYYYYYY JENNKINNNSSSSSS !!!!!!!!' WHERE `id`=753;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Bon. Quest-ce quon a en AOE là ?' WHERE `id`=754;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Ça devient intéressant…' WHERE `id`=755;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Cool. Regroupez-les bien pour une jolie boule de feu !' WHERE `id`=756;
UPDATE `ai_playerbot_texts` SET `text_loc2`='TUEZ ! TUEZ ! TUEZ !' WHERE `id`=757;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Je crois que jai mouillé mon pantalon…' WHERE `id`=758;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Cest notre fin. Cétait sympa.' WHERE `id`=759;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Jespère que les healers sont prêts… LEEEEROYYYY !' WHERE `id`=760;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Pourvu quils ne me ciblent pas moi…' WHERE `id`=761;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Oh non. Je peux pas regarder ce massacre…' WHERE `id`=762;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Jespère quil y aura de la thune.' WHERE `id`=763;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Loot ! LOOT !' WHERE `id`=764;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Mon précieux…' WHERE `id`=765;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Jespère quun bel objet épique mattend là-dedans' WHERE `id`=766;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Jai des poches profondes et des sacs encore vides.' WHERE `id`=767;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Tout est à moi !' WHERE `id`=768;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Pas de gris moisi aujourdhui, pitié…' WHERE `id`=769;
UPDATE `ai_playerbot_texts` SET `text_loc2`='CE loot est À MOI !' WHERE `id`=770;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Looter cest sale… mais jai besoin de thunes.' WHERE `id`=771;
UPDATE `ai_playerbot_texts` SET `text_loc2`='De lor !' WHERE `id`=772;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Ok. Voyons ce quils ont laissé…' WHERE `id`=773;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Tinquiète, je vais tout looter. Tout.' WHERE `id`=774;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Je suis un ninja du loot.' WHERE `id`=775;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Je dois lancer les dés ?' WHERE `id`=776;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Quelquun peut mexpliquer où ils ont rangé tout ça ?' WHERE `id`=777;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Non, je loot pas cette merde grise.' WHERE `id`=778;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Cest moi dabord ! Cest moi ! MOI !' WHERE `id`=779;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Donne-moi ton fric !' WHERE `id`=780;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Mes poches sont vides, il faut les remplir.' WHERE `id`=781;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Jai un nouveau sac, il est fait pour ça.' WHERE `id`=782;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Jespère que je vais pas aggro en lootant…' WHERE `id`=783;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Ne regardez pas… je loot discret…' WHERE `id`=784;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Ha ! Vous naurez rien de tout ça !' WHERE `id`=785;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Le loot, cest stylé.' WHERE `id`=786;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Jadore les nouveaux équipements.' WHERE `id`=787;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Je me casse si ya encore rien de valeur…' WHERE `id`=788;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Jespère que ce sera une jolie bague !' WHERE `id`=789;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Je vais tarracher le loot des mains !' WHERE `id`=790;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Personne ne touche à rien. Cest MOI qui loot.' WHERE `id`=791;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Loot sucré :D' WHERE `id`=792;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Dieu du lancer, donne-moi un épique aujourdhui…' WHERE `id`=793;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Allez, de nouveaux jouets sil vous plaît !' WHERE `id`=794;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Jespère quils ont des trucs savoureux…' WHERE `id`=795;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Lor est à moi. Je laisse tout le reste… promis…' WHERE `id`=796;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Non, je peux pas résister.' WHERE `id`=797;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Jen veux ENCORE !' WHERE `id`=798;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Je suis presque là, attendez-moi !' WHERE `id`=799;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Je suis pas loin, attendez-moi !' WHERE `id`=800;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Jarrive vers ta position' WHERE `id`=801;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Jarrive vers toi' WHERE `id`=802;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Je me dirige vers ta position' WHERE `id`=803;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Jessaie de te rejoindre' WHERE `id`=804;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Équipement de %item' WHERE `id`=805;
UPDATE `ai_playerbot_texts` SET `text_loc2`='%item retiré' WHERE `id`=806;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Jai appris les sorts : %spells' WHERE `id`=807;
UPDATE `ai_playerbot_texts` SET `text_loc2`='%item est en recharge' WHERE `id`=808;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Je nai pas %item dans mon inventaire' WHERE `id`=809;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Lobjet avec lID %item nexiste pas' WHERE `id`=810;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Insertion de %gem dans %item' WHERE `id`=811;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Je ne peux pas utiliser %item' WHERE `id`=812;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Suivi' WHERE `id`=813;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Je reste ici' WHERE `id`=814;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Je fuis' WHERE `id`=815;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Je fuis pas avec toi, tes trop loin !' WHERE `id`=816;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Farm en cours' WHERE `id`=817;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Attaque en cours' WHERE `id`=818;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Cest trop loin' WHERE `id`=819;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Cest sous leau' WHERE `id`=820;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Je ne peux pas y aller' WHERE `id`=821;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Je ne suis pas dans ta guilde !' WHERE `id`=822;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Impossible de trouver une banque de guilde à proximité' WHERE `id`=823;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Je ne peux pas déposer' WHERE `id`=824;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Je nai pas les droits pour déposer dans le premier onglet de la banque de guilde' WHERE `id`=825;
UPDATE `ai_playerbot_texts` SET `text_loc2`='déposé dans la banque de guilde' WHERE `id`=826;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Déplacement libre' WHERE `id`=827;
UPDATE `ai_playerbot_texts` SET `text_loc2`='En garde' WHERE `id`=828;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Utilisation de %target' WHERE `id`=829;
UPDATE `ai_playerbot_texts` SET `text_loc2`='sur %unit' WHERE `id`=830;
UPDATE `ai_playerbot_texts` SET `text_loc2`='(%amount disponible)' WHERE `id`=831;
UPDATE `ai_playerbot_texts` SET `text_loc2`='(le dernier)' WHERE `id`=832;
UPDATE `ai_playerbot_texts` SET `text_loc2`='La châsse ne correspond pas' WHERE `id`=833;
UPDATE `ai_playerbot_texts` SET `text_loc2`='sur objet déchange' WHERE `id`=834;
UPDATE `ai_playerbot_texts` SET `text_loc2`='sur moi-même' WHERE `id`=835;
UPDATE `ai_playerbot_texts` SET `text_loc2`='sur %item' WHERE `id`=836;
UPDATE `ai_playerbot_texts` SET `text_loc2`='sur %gameobject' WHERE `id`=837;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Loot de %item' WHERE `id`=838;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Invocation de %target' WHERE `id`=839;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Je nai pas assez de membres du groupe à proximité pour invoquer' WHERE `id`=840;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Impossible de trouver la cible dinvocation' WHERE `id`=841;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Je ne peux pas invoquer en combat' WHERE `id`=842;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Je ne connais pas le sort %spell' WHERE `id`=843;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Lancement du sort %spell' WHERE `id`=844;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Fabrication de %spell' WHERE `id`=845;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Impossible de lancer %spell' WHERE `id`=846;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Échec du lancement de %spell' WHERE `id`=847;
UPDATE `ai_playerbot_texts` SET `text_loc2`='|cffffff00(x%amount restant)|r' WHERE `id`=848;
UPDATE `ai_playerbot_texts` SET `text_loc2`='dummy' WHERE `id`=849;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Par la Lumière... J\'ai oublié mes Symboles du roi. On se contentera de %base_spell !' WHERE `id`=934;
UPDATE `ai_playerbot_texts` SET `text_loc2`='La nature est généreuse, pas mes sacs... plus d\'herbes pour %group_spell. Prenez %base_spell pour l\'instant !' WHERE `id`=935;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Plus de poudre des arcanes... %group_spell attendra. Je lance %base_spell !' WHERE `id`=936;
UPDATE `ai_playerbot_texts` SET `text_loc2`='Oups, je n\'ai plus de composants pour %group_spell. On fera avec %base_spell !' WHERE `id`=937;

View File

@@ -91,6 +91,9 @@ uint8 AiFactory::GetPlayerSpecTab(Player* bot)
case CLASS_WARLOCK: case CLASS_WARLOCK:
tab = WARLOCK_TAB_DEMONOLOGY; tab = WARLOCK_TAB_DEMONOLOGY;
break; break;
case CLASS_SHAMAN:
tab = SHAMAN_TAB_ELEMENTAL;
break;
} }
return tab; return tab;
@@ -304,9 +307,9 @@ void AiFactory::AddDefaultCombatStrategies(Player* player, PlayerbotAI* const fa
engine->addStrategiesNoInit("dps assist", "cure", nullptr); engine->addStrategiesNoInit("dps assist", "cure", nullptr);
break; break;
case CLASS_MAGE: case CLASS_MAGE:
if (tab == 0) if (tab == 0) // Arcane
engine->addStrategiesNoInit("arcane", nullptr); engine->addStrategiesNoInit("arcane", nullptr);
else if (tab == 1) else if (tab == 1) // Fire
{ {
if (player->HasSpell(44614) /*Frostfire Bolt*/ && player->HasAura(15047) /*Ice Shards*/) if (player->HasSpell(44614) /*Frostfire Bolt*/ && player->HasAura(15047) /*Ice Shards*/)
{ {
@@ -317,7 +320,7 @@ void AiFactory::AddDefaultCombatStrategies(Player* player, PlayerbotAI* const fa
engine->addStrategiesNoInit("fire", nullptr); engine->addStrategiesNoInit("fire", nullptr);
} }
} }
else else // Frost
engine->addStrategiesNoInit("frost", nullptr); engine->addStrategiesNoInit("frost", nullptr);
engine->addStrategiesNoInit("dps", "dps assist", "cure", "aoe", nullptr); engine->addStrategiesNoInit("dps", "dps assist", "cure", "aoe", nullptr);
@@ -331,14 +334,14 @@ void AiFactory::AddDefaultCombatStrategies(Player* player, PlayerbotAI* const fa
engine->addStrategiesNoInit("fury", "aoe", "dps assist", /*"behind",*/ nullptr); engine->addStrategiesNoInit("fury", "aoe", "dps assist", /*"behind",*/ nullptr);
break; break;
case CLASS_SHAMAN: case CLASS_SHAMAN:
if (tab == 0) if (tab == 0) // Elemental
engine->addStrategiesNoInit("caster", "caster aoe", "bmana", nullptr); engine->addStrategiesNoInit("ele", "stoneskin", "wrath", "mana spring", "wrath of air", nullptr);
else if (tab == 2) else if (tab == 2) // Restoration
engine->addStrategiesNoInit("heal", "bmana", nullptr); engine->addStrategiesNoInit("resto", "stoneskin", "flametongue", "mana spring", "wrath of air", nullptr);
else else // Enhancement
engine->addStrategiesNoInit("melee", "melee aoe", "bdps", nullptr); engine->addStrategiesNoInit("enh", "strength of earth", "magma", "healing stream", "windfury", nullptr);
engine->addStrategiesNoInit("dps assist", "cure", "totems", nullptr); engine->addStrategiesNoInit("dps assist", "cure", "aoe", nullptr);
break; break;
case CLASS_PALADIN: case CLASS_PALADIN:
if (tab == 1) if (tab == 1)

View File

@@ -8,6 +8,18 @@
#include "Group.h" #include "Group.h"
#include "Playerbots.h" #include "Playerbots.h"
#include "RtiTargetValue.h" #include "RtiTargetValue.h"
#include "AiFactory.h"
#include <algorithm>
#include <cctype>
#include <string>
static std::string ToLower(const std::string& str)
{
std::string out = str;
std::transform(out.begin(), out.end(), out.begin(), [](unsigned char c){ return std::tolower(c); });
return out;
}
std::string const ChatFilter::Filter(std::string& message) std::string const ChatFilter::Filter(std::string& message)
{ {
@@ -25,32 +37,33 @@ public:
std::string const Filter(std::string& message) override std::string const Filter(std::string& message) override
{ {
Player* bot = botAI->GetBot(); Player* bot = botAI->GetBot();
std::string msgLower = ToLower(message);
bool tank = message.find("@tank") == 0; bool tank = msgLower.find("@tank") == 0;
if (tank && !botAI->IsTank(bot)) if (tank && !botAI->IsTank(bot))
return ""; return "";
bool dps = message.find("@dps") == 0; bool dps = msgLower.find("@dps") == 0;
if (dps && (botAI->IsTank(bot) || botAI->IsHeal(bot))) if (dps && (botAI->IsTank(bot) || botAI->IsHeal(bot)))
return ""; return "";
bool heal = message.find("@heal") == 0; bool heal = msgLower.find("@heal") == 0;
if (heal && !botAI->IsHeal(bot)) if (heal && !botAI->IsHeal(bot))
return ""; return "";
bool ranged = message.find("@ranged") == 0; bool ranged = msgLower.find("@ranged") == 0;
if (ranged && !botAI->IsRanged(bot)) if (ranged && !botAI->IsRanged(bot))
return ""; return "";
bool melee = message.find("@melee") == 0; bool melee = msgLower.find("@melee") == 0;
if (melee && botAI->IsRanged(bot)) if (melee && botAI->IsRanged(bot))
return ""; return "";
bool rangeddps = message.find("@rangeddps") == 0; bool rangeddps = msgLower.find("@rangeddps") == 0;
if (rangeddps && (!botAI->IsRanged(bot) || botAI->IsTank(bot) || botAI->IsHeal(bot))) if (rangeddps && (!botAI->IsRanged(bot) || botAI->IsTank(bot) || botAI->IsHeal(bot)))
return ""; return "";
bool meleedps = message.find("@meleedps") == 0; bool meleedps = msgLower.find("@meleedps") == 0;
if (meleedps && (!botAI->IsMelee(bot) || botAI->IsTank(bot) || botAI->IsHeal(bot))) if (meleedps && (!botAI->IsMelee(bot) || botAI->IsTank(bot) || botAI->IsHeal(bot)))
return ""; return "";
@@ -69,11 +82,11 @@ public:
std::string const Filter(std::string& message) override std::string const Filter(std::string& message) override
{ {
Player* bot = botAI->GetBot(); Player* bot = botAI->GetBot();
std::string msgLower = ToLower(message);
if (message[0] != '@') if (msgLower[0] != '@')
return message; return message;
if (message.find("-") != std::string::npos) if (msgLower.find("-") != std::string::npos)
{ {
uint32 fromLevel = atoi(message.substr(message.find("@") + 1, message.find("-")).c_str()); uint32 fromLevel = atoi(message.substr(message.find("@") + 1, message.find("-")).c_str());
uint32 toLevel = atoi(message.substr(message.find("-") + 1, message.find(" ")).c_str()); uint32 toLevel = atoi(message.substr(message.find("-") + 1, message.find(" ")).c_str());
@@ -100,9 +113,10 @@ public:
std::string const Filter(std::string& message) override std::string const Filter(std::string& message) override
{ {
Player* bot = botAI->GetBot(); Player* bot = botAI->GetBot();
std::string msgLower = ToLower(message);
bool melee = message.find("@melee") == 0; bool melee = msgLower.find("@melee") == 0;
bool ranged = message.find("@ranged") == 0; bool ranged = msgLower.find("@ranged") == 0;
if (!melee && !ranged) if (!melee && !ranged)
return message; return message;
@@ -159,17 +173,17 @@ public:
std::string const Filter(std::string& message) override std::string const Filter(std::string& message) override
{ {
Player* bot = botAI->GetBot(); Player* bot = botAI->GetBot();
std::string msgLower = ToLower(message);
Group* group = bot->GetGroup(); Group* group = bot->GetGroup();
if (!group) if (!group)
return message; return message;
bool found = false; bool found = false;
//bool isRti = false; //not used, shadowed by the next declaration, line marked for removal.
for (std::vector<std::string>::iterator i = rtis.begin(); i != rtis.end(); i++) for (std::vector<std::string>::iterator i = rtis.begin(); i != rtis.end(); i++)
{ {
std::string const rti = *i; std::string const rti = *i;
std::string rtiLower = ToLower(rti);
bool isRti = message.find(rti) == 0; bool isRti = msgLower.find(rtiLower) == 0;
if (!isRti) if (!isRti)
continue; continue;
@@ -204,7 +218,7 @@ class ClassChatFilter : public ChatFilter
public: public:
ClassChatFilter(PlayerbotAI* botAI) : ChatFilter(botAI) ClassChatFilter(PlayerbotAI* botAI) : ChatFilter(botAI)
{ {
classNames["@death_knight"] = CLASS_DEATH_KNIGHT; classNames["@dk"] = CLASS_DEATH_KNIGHT;
classNames["@druid"] = CLASS_DRUID; classNames["@druid"] = CLASS_DRUID;
classNames["@hunter"] = CLASS_HUNTER; classNames["@hunter"] = CLASS_HUNTER;
classNames["@mage"] = CLASS_MAGE; classNames["@mage"] = CLASS_MAGE;
@@ -219,12 +233,12 @@ public:
std::string const Filter(std::string& message) override std::string const Filter(std::string& message) override
{ {
Player* bot = botAI->GetBot(); Player* bot = botAI->GetBot();
std::string msgLower = ToLower(message);
bool found = false; bool found = false;
//bool isClass = false; //not used, shadowed by the next declaration, line marked for removal.
for (std::map<std::string, uint8>::iterator i = classNames.begin(); i != classNames.end(); i++) for (std::map<std::string, uint8>::iterator i = classNames.begin(); i != classNames.end(); i++)
{ {
bool isClass = message.find(i->first) == 0; bool isClass = msgLower.find(ToLower(i->first)) == 0;
if (isClass && bot->getClass() != i->second) if (isClass && bot->getClass() != i->second)
return ""; return "";
@@ -251,8 +265,8 @@ public:
std::string const Filter(std::string& message) override std::string const Filter(std::string& message) override
{ {
Player* bot = botAI->GetBot(); Player* bot = botAI->GetBot();
std::string msgLower = ToLower(message);
if (message.find("@group") == 0) if (msgLower.find("@group") == 0)
{ {
size_t spacePos = message.find(" "); size_t spacePos = message.find(" ");
if (spacePos == std::string::npos) if (spacePos == std::string::npos)
@@ -295,6 +309,277 @@ public:
} }
}; };
class SpecChatFilter : public ChatFilter
{
public:
SpecChatFilter(PlayerbotAI* botAI) : ChatFilter(botAI)
{
// Map (class, specTab) to spec+class string
specTabNames[{CLASS_PALADIN, 0}] = "hpal";
specTabNames[{CLASS_PALADIN, 1}] = "ppal";
specTabNames[{CLASS_PALADIN, 2}] = "rpal";
specTabNames[{CLASS_PRIEST, 0}] = "disc";
specTabNames[{CLASS_PRIEST, 1}] = "hpr";
specTabNames[{CLASS_PRIEST, 2}] = "spr";
specTabNames[{CLASS_MAGE, 0}] = "arc";
specTabNames[{CLASS_MAGE, 1}] = "frost";
specTabNames[{CLASS_MAGE, 2}] = "fire";
specTabNames[{CLASS_WARRIOR, 0}] = "arms";
specTabNames[{CLASS_WARRIOR, 1}] = "fury";
specTabNames[{CLASS_WARRIOR, 2}] = "pwar";
specTabNames[{CLASS_WARLOCK, 0}] = "affl";
specTabNames[{CLASS_WARLOCK, 1}] = "demo";
specTabNames[{CLASS_WARLOCK, 2}] = "dest";
specTabNames[{CLASS_SHAMAN, 0}] = "ele";
specTabNames[{CLASS_SHAMAN, 1}] = "enh";
specTabNames[{CLASS_SHAMAN, 2}] = "rsha";
specTabNames[{CLASS_DRUID, 0}] = "bal";
// See below for feral druid
specTabNames[{CLASS_DRUID, 2}] = "rdru";
specTabNames[{CLASS_HUNTER, 0}] = "bmh";
specTabNames[{CLASS_HUNTER, 1}] = "mmh";
specTabNames[{CLASS_HUNTER, 2}] = "svh";
specTabNames[{CLASS_ROGUE, 0}] = "mut";
specTabNames[{CLASS_ROGUE, 1}] = "comb";
specTabNames[{CLASS_ROGUE, 2}] = "sub";
// See below for blood death knight
specTabNames[{CLASS_DEATH_KNIGHT, 1}] = "fdk";
specTabNames[{CLASS_DEATH_KNIGHT, 2}] = "udk";
}
std::string const Filter(std::string& message) override
{
std::string msgLower = ToLower(message);
std::string specPrefix;
std::string rest;
if (!ParseSpecPrefix(message, specPrefix, rest))
{
return message;
}
Player* bot = botAI->GetBot();
if (!MatchesSpec(bot, specPrefix))
{
return "";
}
std::string result = ChatFilter::Filter(rest);
return result;
}
private:
std::map<std::pair<uint8, int>, std::string> specTabNames;
bool ParseSpecPrefix(const std::string& message, std::string& specPrefix, std::string& rest)
{
std::string msgLower = ToLower(message);
for (const auto& entry : specTabNames)
{
std::string prefix = "@" + entry.second;
if (msgLower.find(ToLower(prefix)) == 0)
{
specPrefix = entry.second;
size_t spacePos = message.find(' ');
rest = (spacePos != std::string::npos) ? message.substr(spacePos + 1) : "";
return true;
}
}
return false;
}
bool MatchesSpec(Player* bot, const std::string& specPrefix)
{
uint8 cls = bot->getClass();
int specTab = AiFactory::GetPlayerSpecTab(bot);
std::string botSpecClass;
// For druids, specTab==1 is always feral; distinguish bear/cat at runtime by role
if (cls == CLASS_DRUID && specTab == 1)
{
botSpecClass = botAI->IsTank(bot) ? "bear" : "cat";
}
// For death knights, specTab==0 is always blood; distinguish tank/dps at runtime by role
else if (cls == CLASS_DEATH_KNIGHT && specTab == 0)
{
botSpecClass = botAI->IsTank(bot) ? "bdkt" : "bdkd";
}
else
{
auto it = specTabNames.find({cls, specTab});
if (it != specTabNames.end())
botSpecClass = it->second;
}
return ToLower(botSpecClass) == ToLower(specPrefix);
}
};
class AuraChatFilter : public ChatFilter
{
public:
AuraChatFilter(PlayerbotAI* botAI) : ChatFilter(botAI) {}
std::string const Filter(std::string& message) override
{
Player* bot = botAI->GetBot();
std::string msgLower = ToLower(message);
const std::string auraPrefix = "@aura";
const std::string noAuraPrefix = "@noaura";
size_t prefixLen = 0;
bool isNoAura = false;
if (msgLower.find(auraPrefix) == 0)
{
prefixLen = auraPrefix.length();
isNoAura = false;
}
else if (msgLower.find(noAuraPrefix) == 0)
{
prefixLen = noAuraPrefix.length();
isNoAura = true;
}
else
{
return message;
}
// Trim any leading spaces after @aura or @noaura (can use space between prefix and spell ID if desired, but not required)
std::string auraIdOrName = message.substr(prefixLen);
auraIdOrName.erase(0, auraIdOrName.find_first_not_of(' '));
if (auraIdOrName.empty())
{
return message;
}
uint32 auraId = 0;
size_t spacePos = auraIdOrName.find(' ');
std::string idStr = (spacePos != std::string::npos) ? auraIdOrName.substr(0, spacePos) : auraIdOrName;
std::string rest = (spacePos != std::string::npos) ? auraIdOrName.substr(spacePos + 1) : "";
if (!idStr.empty())
{
bool isNumeric = std::all_of(idStr.begin(), idStr.end(), ::isdigit);
if (isNumeric)
{
auraId = atoi(idStr.c_str());
}
}
if (auraId == 0)
return message;
bool hasAura = bot->HasAura(auraId);
bool match = isNoAura ? !hasAura : hasAura;
std::string result = match ? ChatFilter::Filter(rest) : "";
return result;
}
};
class AggroByChatFilter : public ChatFilter
{
public:
AggroByChatFilter(PlayerbotAI* botAI) : ChatFilter(botAI) {}
std::string const Filter(std::string& message) override
{
Player* bot = botAI->GetBot();
std::string msgLower = ToLower(message);
const std::string prefix = "@aggroby";
size_t prefixLen = prefix.length();
if (msgLower.find(prefix) != 0)
{
return message;
}
// Trim any leading spaces after @aggroby (can use space between prefix and entry ID/creature name if desired, but not required)
std::string enemyStr = message.substr(prefixLen);
enemyStr.erase(0, enemyStr.find_first_not_of(' '));
if (enemyStr.empty())
{
return message;
}
// If creature name is more than one word, it must be enclosed in quotes, e.g. @aggroby "Scarlet Commander Mograine" flee
std::string rest = "";
std::string enemyName = "";
bool isName = false;
uint32 entryId = 0;
if (enemyStr[0] == '"')
{
size_t endQuote = enemyStr.find('"', 1);
if (endQuote != std::string::npos)
{
enemyName = enemyStr.substr(1, endQuote - 1);
isName = true;
size_t spacePos = enemyStr.find(' ', endQuote + 1);
if (spacePos != std::string::npos)
{
rest = enemyStr.substr(spacePos + 1);
}
else
{
rest = "";
}
}
else
{
enemyName = enemyStr.substr(1);
isName = true;
rest = "";
}
}
else
{
size_t splitPos = enemyStr.find_first_of(" ");
std::string idOrName = (splitPos != std::string::npos) ? enemyStr.substr(0, splitPos) : enemyStr;
if (splitPos != std::string::npos)
{
rest = enemyStr.substr(splitPos + 1);
}
else
{
rest = "";
}
if (!idOrName.empty())
{
bool isNumeric = std::all_of(idOrName.begin(), idOrName.end(), ::isdigit);
if (isNumeric)
{
entryId = atoi(idOrName.c_str());
}
else
{
enemyName = idOrName;
isName = true;
}
}
}
const float radius = 100.0f;
GuidVector npcs = botAI->GetAiObjectContext()->GetValue<GuidVector>("nearest npcs")->Get();
bool match = false;
for (const auto& guid : npcs)
{
Creature* c = botAI->GetCreature(guid);
if (!c)
{
continue;
}
bool nameMatch = isName && ToLower(c->GetName()) == ToLower(enemyName);
bool idMatch = (entryId != 0) && c->GetEntry() == entryId;
if ((nameMatch || idMatch) && c->GetDistance2d(bot) <= radius)
{
Unit* victim = c->GetVictim();
if (victim && victim->GetGUID() == bot->GetGUID())
{
match = true;
break;
}
}
}
std::string result = match ? ChatFilter::Filter(rest) : "";
return result;
}
};
CompositeChatFilter::CompositeChatFilter(PlayerbotAI* botAI) : ChatFilter(botAI) CompositeChatFilter::CompositeChatFilter(PlayerbotAI* botAI) : ChatFilter(botAI)
{ {
filters.push_back(new StrategyChatFilter(botAI)); filters.push_back(new StrategyChatFilter(botAI));
@@ -303,6 +588,9 @@ CompositeChatFilter::CompositeChatFilter(PlayerbotAI* botAI) : ChatFilter(botAI)
filters.push_back(new CombatTypeChatFilter(botAI)); filters.push_back(new CombatTypeChatFilter(botAI));
filters.push_back(new LevelChatFilter(botAI)); filters.push_back(new LevelChatFilter(botAI));
filters.push_back(new SubGroupChatFilter(botAI)); filters.push_back(new SubGroupChatFilter(botAI));
filters.push_back(new SpecChatFilter(botAI));
filters.push_back(new AuraChatFilter(botAI));
filters.push_back(new AggroByChatFilter(botAI));
} }
CompositeChatFilter::~CompositeChatFilter() CompositeChatFilter::~CompositeChatFilter()
@@ -313,14 +601,11 @@ CompositeChatFilter::~CompositeChatFilter()
std::string const CompositeChatFilter::Filter(std::string& message) std::string const CompositeChatFilter::Filter(std::string& message)
{ {
for (uint32 j = 0; j < filters.size(); ++j) for (auto* filter : filters)
{ {
for (std::vector<ChatFilter*>::iterator i = filters.begin(); i != filters.end(); i++) message = filter->Filter(message);
{ if (message.empty())
message = (*i)->Filter(message); break;
if (message.empty())
break;
}
} }
return message; return message;

View File

@@ -2937,9 +2937,9 @@ bool PlayerbotAI::HasAura(uint32 spellId, Unit const* unit)
return unit->HasAura(spellId); return unit->HasAura(spellId);
// for (uint8 effect = EFFECT_0; effect <= EFFECT_2; effect++) // for (uint8 effect = EFFECT_0; effect <= EFFECT_2; effect++)
// { // {
// AuraEffect const* aurEff = unit->GetAuraEffect(spellId, effect); // AuraEffect const* aurEff = unit->GetAuraEffect(spellId, effect);
// if (IsRealAura(bot, aurEff, unit)) // if (IsRealAura(bot, aurEff, unit))
// return true; // return true;
// } // }
// return false; // return false;

View File

@@ -81,6 +81,9 @@ bool PlayerbotAIConfig::Initialize()
sitDelay = sConfigMgr->GetOption<int32>("AiPlayerbot.SitDelay", 30000); sitDelay = sConfigMgr->GetOption<int32>("AiPlayerbot.SitDelay", 30000);
returnDelay = sConfigMgr->GetOption<int32>("AiPlayerbot.ReturnDelay", 7000); returnDelay = sConfigMgr->GetOption<int32>("AiPlayerbot.ReturnDelay", 7000);
lootDelay = sConfigMgr->GetOption<int32>("AiPlayerbot.LootDelay", 1000); lootDelay = sConfigMgr->GetOption<int32>("AiPlayerbot.LootDelay", 1000);
// Buff system
minBotsForGreaterBuff = sConfigMgr->GetOption<int32>("AiPlayerbot.MinBotsForGreaterBuff", 3);
rpWarningCooldown = sConfigMgr->GetOption<int32>("AiPlayerbot.RPWarningCooldown", 30);
disabledWithoutRealPlayerLoginDelay = sConfigMgr->GetOption<int32>("AiPlayerbot.DisabledWithoutRealPlayerLoginDelay", 30); disabledWithoutRealPlayerLoginDelay = sConfigMgr->GetOption<int32>("AiPlayerbot.DisabledWithoutRealPlayerLoginDelay", 30);
disabledWithoutRealPlayerLogoutDelay = sConfigMgr->GetOption<int32>("AiPlayerbot.DisabledWithoutRealPlayerLogoutDelay", 300); disabledWithoutRealPlayerLogoutDelay = sConfigMgr->GetOption<int32>("AiPlayerbot.DisabledWithoutRealPlayerLogoutDelay", 300);
@@ -167,14 +170,14 @@ bool PlayerbotAIConfig::Initialize()
pvpProhibitedAreaIds); pvpProhibitedAreaIds);
fastReactInBG = sConfigMgr->GetOption<bool>("AiPlayerbot.FastReactInBG", true); fastReactInBG = sConfigMgr->GetOption<bool>("AiPlayerbot.FastReactInBG", true);
LoadList<std::vector<uint32>>( LoadList<std::vector<uint32>>(
sConfigMgr->GetOption<std::string>("AiPlayerbot.RandomBotQuestIds", "7848,3802,5505,6502,7761"), sConfigMgr->GetOption<std::string>("AiPlayerbot.RandomBotQuestIds", "7848,3802,5505,6502,7761,10277,10285,11492,13188,13189,24499,24511,24710,24712"),
randomBotQuestIds); randomBotQuestIds);
LoadSet<std::set<uint32>>( LoadSet<std::set<uint32>>(
sConfigMgr->GetOption<std::string>("AiPlayerbot.DisallowedGameObjects", sConfigMgr->GetOption<std::string>("AiPlayerbot.DisallowedGameObjects",
"176213,17155,2656,74448,19020,3719,3658,3705,3706,105579,75293,2857," "176213,17155,2656,74448,19020,3719,3658,3705,3706,105579,75293,2857,"
"179490,141596,160836,160845,179516,176224,181085,176112,128308,128403," "179490,141596,160836,160845,179516,176224,181085,176112,128308,128403,"
"165739,165738,175245,175970,176325,176327,123329"), "165739,165738,175245,175970,176325,176327,123329,2560"),
disallowedGameObjects); disallowedGameObjects);
botAutologin = sConfigMgr->GetOption<bool>("AiPlayerbot.BotAutologin", false); botAutologin = sConfigMgr->GetOption<bool>("AiPlayerbot.BotAutologin", false);
randomBotAutologin = sConfigMgr->GetOption<bool>("AiPlayerbot.RandomBotAutologin", true); randomBotAutologin = sConfigMgr->GetOption<bool>("AiPlayerbot.RandomBotAutologin", true);
@@ -216,9 +219,9 @@ bool PlayerbotAIConfig::Initialize()
"531,532,534,544,548,550,564,565,580,249,533,603,615,616,624,631,649,724"), "531,532,534,544,548,550,564,565,580,249,533,603,615,616,624,631,649,724"),
restrictedHealerDPSMaps); restrictedHealerDPSMaps);
//////////////////////////// ICC //////////////////////////// ICC
EnableICCBuffs = sConfigMgr->GetOption<bool>("AiPlayerbot.EnableICCBuffs", true); EnableICCBuffs = sConfigMgr->GetOption<bool>("AiPlayerbot.EnableICCBuffs", true);
//////////////////////////// CHAT //////////////////////////// CHAT
enableBroadcasts = sConfigMgr->GetOption<bool>("AiPlayerbot.EnableBroadcasts", true); enableBroadcasts = sConfigMgr->GetOption<bool>("AiPlayerbot.EnableBroadcasts", true);

View File

@@ -139,6 +139,12 @@ public:
uint32 disabledWithoutRealPlayerLoginDelay, disabledWithoutRealPlayerLogoutDelay; uint32 disabledWithoutRealPlayerLoginDelay, disabledWithoutRealPlayerLogoutDelay;
bool randomBotJoinLfg; bool randomBotJoinLfg;
// Buff system
// Min group size to use Greater buffs (Paladin, Mage, Druid). Default: 3
int32 minBotsForGreaterBuff;
// Cooldown (seconds) between reagent-missing RP warnings, per bot & per buff. Default: 30
int32 rpWarningCooldown;
// chat // chat
bool randomBotTalk; bool randomBotTalk;
bool randomBotEmote; bool randomBotEmote;

View File

@@ -475,7 +475,7 @@ void PlayerbotHolder::OnBotLogin(Player* const bot)
} }
Player* master = botAI->GetMaster(); Player* master = botAI->GetMaster();
if (master) if (master)
{ {
ObjectGuid masterGuid = master->GetGUID(); ObjectGuid masterGuid = master->GetGUID();
if (master->GetGroup() && !master->GetGroup()->IsLeader(masterGuid)) if (master->GetGroup() && !master->GetGroup()->IsLeader(masterGuid))
@@ -499,7 +499,7 @@ void PlayerbotHolder::OnBotLogin(Player* const bot)
} }
} }
// Don't disband alt groups when master goes away // Don't disband alt groups when master goes away
// Controlled by config // Controlled by config
if (sPlayerbotAIConfig->KeepAltsInGroup()) if (sPlayerbotAIConfig->KeepAltsInGroup())
{ {
@@ -1130,18 +1130,18 @@ std::vector<std::string> PlayerbotHolder::HandlePlayerbotCommand(char const* arg
int8 gender = -1; // -1 = gender will be random int8 gender = -1; // -1 = gender will be random
if (genderArg) if (genderArg)
{ {
std::string g = genderArg; std::string g = genderArg;
std::transform(g.begin(), g.end(), g.begin(), ::tolower); std::transform(g.begin(), g.end(), g.begin(), ::tolower);
if (g == "male" || g == "0") if (g == "male" || g == "0")
gender = GENDER_MALE; // 0 gender = GENDER_MALE; // 0
else if (g == "female" || g == "1") else if (g == "female" || g == "1")
gender = GENDER_FEMALE; // 1 gender = GENDER_FEMALE; // 1
else else
{ {
messages.push_back("Unknown gender : " + g + " (male/female/0/1)"); messages.push_back("Unknown gender : " + g + " (male/female/0/1)");
return messages; return messages;
} }
} //end } //end
if (claz == 6 && master->GetLevel() < sWorld->getIntConfig(CONFIG_START_HEROIC_PLAYER_LEVEL)) if (claz == 6 && master->GetLevel() < sWorld->getIntConfig(CONFIG_START_HEROIC_PLAYER_LEVEL))

View File

@@ -217,16 +217,20 @@ public:
if (!player->GetSession()->IsBot() || !sRandomPlayerbotMgr->IsRandomBot(player)) if (!player->GetSession()->IsBot() || !sRandomPlayerbotMgr->IsRandomBot(player))
return; return;
// no XP multiplier, when bot has group where leader is a real player. // no XP multiplier, when bot is in a group with a real player.
if (Group* group = player->GetGroup()) if (Group* group = player->GetGroup())
{ {
Player* leader = group->GetLeader(); for (GroupReference* gref = group->GetFirstMember(); gref; gref = gref->next())
if (leader && leader != player)
{ {
if (PlayerbotAI* leaderBotAI = GET_PLAYERBOT_AI(leader)) Player* member = gref->GetSource();
if (!member)
{ {
if (leaderBotAI->HasRealPlayerMaster()) continue;
return; }
if (!member->GetSession()->IsBot())
{
return;
} }
} }
} }

View File

@@ -15,6 +15,9 @@
#include "SharedDefines.h" #include "SharedDefines.h"
#include "SocialMgr.h" #include "SocialMgr.h"
#include "Timer.h" #include "Timer.h"
#include "Guild.h" // EmblemInfo::SaveToDB
#include "Log.h"
#include "GuildMgr.h"
std::map<uint8, std::vector<uint8>> RandomPlayerbotFactory::availableRaces; std::map<uint8, std::vector<uint8>> RandomPlayerbotFactory::availableRaces;
@@ -890,7 +893,9 @@ void RandomPlayerbotFactory::CreateRandomGuilds()
} }
} }
for (; guildNumber < sPlayerbotAIConfig->randomBotGuildCount; ++guildNumber) // Create up to randomBotGuildCount by counting only EFFECTIVE creations
uint32 createdThisRun = 0;
for (; guildNumber < sPlayerbotAIConfig->randomBotGuildCount; /* ++guildNumber -> done only if creation */)
{ {
std::string const guildName = CreateRandomGuildName(); std::string const guildName = CreateRandomGuildName();
if (guildName.empty()) if (guildName.empty())
@@ -902,21 +907,29 @@ void RandomPlayerbotFactory::CreateRandomGuilds()
if (availableLeaders.empty()) if (availableLeaders.empty())
{ {
LOG_ERROR("playerbots", "No leaders for random guilds available"); LOG_ERROR("playerbots", "No leaders for random guilds available");
continue; break; // no more leaders: we can no longer progress without distorting the counter
} }
uint32 index = urand(0, availableLeaders.size() - 1); uint32 index = urand(0, availableLeaders.size() - 1);
ObjectGuid leader = availableLeaders[index]; ObjectGuid leader = availableLeaders[index];
availableLeaders.erase(availableLeaders.begin() + index); // Removes the chosen leader to avoid re-selecting it repeatedly
Player* player = ObjectAccessor::FindPlayer(leader); Player* player = ObjectAccessor::FindPlayer(leader);
if (!player) if (!player)
{ {
LOG_ERROR("playerbots", "ObjectAccessor Cannot find player to set leader for guild {} . Skipped...", LOG_ERROR("playerbots", "ObjectAccessor Cannot find player to set leader for guild {} . Skipped...",
guildName.c_str()); guildName.c_str());
// we will try with other leaders in the next round (guildNumber is not incremented)
continue; continue;
} }
if (player->GetGuildId()) if (player->GetGuildId())
{
// leader already in guild -> we don't advance the counter, we move on to the next one
continue; continue;
}
LOG_DEBUG("playerbots", "Creating guild name='{}' leader='{}'...", guildName.c_str(), player->GetName().c_str());
Guild* guild = new Guild(); Guild* guild = new Guild();
if (!guild->Create(player, guildName)) if (!guild->Create(player, guildName))
@@ -929,6 +942,8 @@ void RandomPlayerbotFactory::CreateRandomGuilds()
sGuildMgr->AddGuild(guild); sGuildMgr->AddGuild(guild);
LOG_DEBUG("playerbots", "Guild created: id={} name='{}'", guild->GetId(), guildName.c_str());
// create random emblem // create random emblem
uint32 st, cl, br, bc, bg; uint32 st, cl, br, bc, bg;
bg = urand(0, 51); bg = urand(0, 51);
@@ -936,13 +951,38 @@ void RandomPlayerbotFactory::CreateRandomGuilds()
cl = urand(0, 17); cl = urand(0, 17);
br = urand(0, 7); br = urand(0, 7);
st = urand(0, 180); st = urand(0, 180);
EmblemInfo emblemInfo(st, cl, br, bc, bg);
guild->HandleSetEmblem(emblemInfo); LOG_DEBUG("playerbots",
"[TABARD] new guild id={} random -> style={}, color={}, borderStyle={}, borderColor={}, bgColor={}",
guild->GetId(), st, cl, br, bc, bg);
// populate guild table with a random tabard design
CharacterDatabase.Execute(
"UPDATE guild SET EmblemStyle={}, EmblemColor={}, BorderStyle={}, BorderColor={}, BackgroundColor={} "
"WHERE guildid={}",
st, cl, br, bc, bg, guild->GetId());
LOG_DEBUG("playerbots", "[TABARD] UPDATE done for guild id={}", guild->GetId());
// Immediate reading for log
if (QueryResult qr = CharacterDatabase.Query(
"SELECT EmblemStyle,EmblemColor,BorderStyle,BorderColor,BackgroundColor FROM guild WHERE guildid={}",
guild->GetId()))
{
Field* f = qr->Fetch();
LOG_DEBUG("playerbots",
"[TABARD] DB check guild id={} => style={}, color={}, borderStyle={}, borderColor={}, bgColor={}",
guild->GetId(), f[0].Get<uint8>(), f[1].Get<uint8>(), f[2].Get<uint8>(), f[3].Get<uint8>(), f[4].Get<uint8>());
}
sPlayerbotAIConfig->randomBotGuilds.push_back(guild->GetId()); sPlayerbotAIConfig->randomBotGuilds.push_back(guild->GetId());
// The guild is only counted if it is actually created
++guildNumber;
++createdThisRun;
} }
LOG_INFO("playerbots", "{} random bot guilds available", guildNumber); // 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);
} }
std::string const RandomPlayerbotFactory::CreateRandomGuildName() std::string const RandomPlayerbotFactory::CreateRandomGuildName()

View File

@@ -717,14 +717,14 @@ uint32 RandomPlayerbotMgr::AddRandomBots()
if (currentBots.size() < maxAllowedBotCount) if (currentBots.size() < maxAllowedBotCount)
{ {
// Calculate how many bots to add // Calculate how many bots to add
maxAllowedBotCount -= currentBots.size(); maxAllowedBotCount -= currentBots.size();
maxAllowedBotCount = std::min(sPlayerbotAIConfig->randomBotsPerInterval, maxAllowedBotCount); maxAllowedBotCount = std::min(sPlayerbotAIConfig->randomBotsPerInterval, maxAllowedBotCount);
// Single RNG instance for all shuffling // Single RNG instance for all shuffling
std::mt19937 rng(std::chrono::steady_clock::now().time_since_epoch().count()); std::mt19937 rng(std::chrono::steady_clock::now().time_since_epoch().count());
// Only need to track the Alliance count, as it's in Phase 1 // Only need to track the Alliance count, as it's in Phase 1
uint32 totalRatio = sPlayerbotAIConfig->randomBotAllianceRatio + sPlayerbotAIConfig->randomBotHordeRatio; uint32 totalRatio = sPlayerbotAIConfig->randomBotAllianceRatio + sPlayerbotAIConfig->randomBotHordeRatio;
uint32 allowedAllianceCount = maxAllowedBotCount * (sPlayerbotAIConfig->randomBotAllianceRatio) / totalRatio; uint32 allowedAllianceCount = maxAllowedBotCount * (sPlayerbotAIConfig->randomBotAllianceRatio) / totalRatio;
@@ -877,17 +877,17 @@ uint32 RandomPlayerbotMgr::AddRandomBots()
LOG_ERROR("playerbots", LOG_ERROR("playerbots",
"Can't log-in all the requested bots. Try increasing RandomBotAccountCount in your conf file.\n" "Can't log-in all the requested bots. Try increasing RandomBotAccountCount in your conf file.\n"
"{} more accounts needed.", moreAccountsNeeded); "{} more accounts needed.", moreAccountsNeeded);
missingBotsTimer = 0; // Reset timer so error is not spammed every tick missingBotsTimer = 0; // Reset timer so error is not spammed every tick
} }
} }
else else
{ {
missingBotsTimer = 0; // Reset timer if logins for this interval were successful missingBotsTimer = 0; // Reset timer if logins for this interval were successful
} }
} }
else else
{ {
missingBotsTimer = 0; // Reset timer if there's enough bots missingBotsTimer = 0; // Reset timer if there's enough bots
} }
return currentBots.size(); return currentBots.size();
@@ -897,7 +897,7 @@ void RandomPlayerbotMgr::LoadBattleMastersCache()
{ {
BattleMastersCache.clear(); BattleMastersCache.clear();
LOG_INFO("playerbots", "Loading BattleMasters Cache..."); LOG_INFO("playerbots", "Loading Battlemasters Cache...");
QueryResult result = WorldDatabase.Query("SELECT `entry`,`bg_template` FROM `battlemaster_entry`"); QueryResult result = WorldDatabase.Query("SELECT `entry`,`bg_template` FROM `battlemaster_entry`");
@@ -940,7 +940,7 @@ void RandomPlayerbotMgr::LoadBattleMastersCache()
BattleMastersCache[bmTeam][BattlegroundTypeId(bgTypeId)].insert( BattleMastersCache[bmTeam][BattlegroundTypeId(bgTypeId)].insert(
BattleMastersCache[bmTeam][BattlegroundTypeId(bgTypeId)].end(), entry); BattleMastersCache[bmTeam][BattlegroundTypeId(bgTypeId)].end(), entry);
LOG_DEBUG("playerbots", "Cached Battmemaster #{} for BG Type {} ({})", entry, bgTypeId, LOG_DEBUG("playerbots", "Cached Battlemaster #{} for BG Type {} ({})", entry, bgTypeId,
bmTeam == TEAM_ALLIANCE ? "Alliance" bmTeam == TEAM_ALLIANCE ? "Alliance"
: bmTeam == TEAM_HORDE ? "Horde" : bmTeam == TEAM_HORDE ? "Horde"
: "Neutral"); : "Neutral");

View File

@@ -2299,7 +2299,7 @@ void TravelNodeMap::printNodeStore()
} }
} }
sPlayerbotAIConfig->log(nodeStore, " }"); sPlayerbotAIConfig->log(nodeStore, " }");
sPlayerbotAIConfig->log(nodeStore, "};"); sPlayerbotAIConfig->log(nodeStore, "};");
printf("\r [Done] \r\x3D"); printf("\r [Done] \r\x3D");

View File

@@ -26,18 +26,18 @@ enum StrategyType : uint32
// enum ActionPriority // enum ActionPriority
// { // {
// ACTION_IDLE = 0, // ACTION_IDLE = 0,
// ACTION_DEFAULT = 5, // ACTION_DEFAULT = 5,
// ACTION_NORMAL = 10, // ACTION_NORMAL = 10,
// ACTION_HIGH = 20, // ACTION_HIGH = 20,
// ACTION_MOVE = 30, // ACTION_MOVE = 30,
// ACTION_INTERRUPT = 40, // ACTION_INTERRUPT = 40,
// ACTION_DISPEL = 50, // ACTION_DISPEL = 50,
// ACTION_RAID = 60, // ACTION_RAID = 60,
// ACTION_LIGHT_HEAL = 10, // ACTION_LIGHT_HEAL = 10,
// ACTION_MEDIUM_HEAL = 20, // ACTION_MEDIUM_HEAL = 20,
// ACTION_CRITICAL_HEAL = 30, // ACTION_CRITICAL_HEAL = 30,
// ACTION_EMERGENCY = 90 // ACTION_EMERGENCY = 90
// }; // };
static float ACTION_IDLE = 0.0f; static float ACTION_IDLE = 0.0f;

View File

@@ -193,8 +193,8 @@ public:
creators["calc"] = &ChatActionContext::calc; creators["calc"] = &ChatActionContext::calc;
creators["wipe"] = &ChatActionContext::wipe; creators["wipe"] = &ChatActionContext::wipe;
creators["tame"] = &ChatActionContext::tame; creators["tame"] = &ChatActionContext::tame;
creators["glyphs"] = &ChatActionContext::glyphs; // Added for custom Glyphs creators["glyphs"] = &ChatActionContext::glyphs; // Added for custom Glyphs
creators["glyph equip"] = &ChatActionContext::glyph_equip; // Added for custom Glyphs creators["glyph equip"] = &ChatActionContext::glyph_equip; // Added for custom Glyphs
creators["pet"] = &ChatActionContext::pet; creators["pet"] = &ChatActionContext::pet;
creators["pet attack"] = &ChatActionContext::pet_attack; creators["pet attack"] = &ChatActionContext::pet_attack;
creators["roll"] = &ChatActionContext::roll_action; creators["roll"] = &ChatActionContext::roll_action;
@@ -305,8 +305,8 @@ private:
static Action* calc(PlayerbotAI* ai) { return new TellCalculateItemAction(ai); } static Action* calc(PlayerbotAI* ai) { return new TellCalculateItemAction(ai); }
static Action* wipe(PlayerbotAI* ai) { return new WipeAction(ai); } static Action* wipe(PlayerbotAI* ai) { return new WipeAction(ai); }
static Action* tame(PlayerbotAI* botAI) { return new TameAction(botAI); } static Action* tame(PlayerbotAI* botAI) { return new TameAction(botAI); }
static Action* glyphs(PlayerbotAI* botAI) { return new TellGlyphsAction(botAI); } // Added for custom Glyphs static Action* glyphs(PlayerbotAI* botAI) { return new TellGlyphsAction(botAI); } // Added for custom Glyphs
static Action* glyph_equip(PlayerbotAI* ai) { return new EquipGlyphsAction(ai); } // Added for custom Glyphs static Action* glyph_equip(PlayerbotAI* ai) { return new EquipGlyphsAction(ai); } // Added for custom Glyphs
static Action* pet(PlayerbotAI* botAI) { return new PetAction(botAI); } static Action* pet(PlayerbotAI* botAI) { return new PetAction(botAI); }
static Action* pet_attack(PlayerbotAI* botAI) { return new PetAction(botAI, "attack"); } static Action* pet_attack(PlayerbotAI* botAI) { return new PetAction(botAI, "attack"); }
static Action* roll_action(PlayerbotAI* botAI) { return new RollAction(botAI); } static Action* roll_action(PlayerbotAI* botAI) { return new RollAction(botAI); }

View File

@@ -151,9 +151,9 @@ bool EquipGlyphsAction::Execute(Event event)
botAI->TellMaster("Glyphs updated."); botAI->TellMaster("Glyphs updated.");
// Flag for custom glyphs // Flag for custom glyphs
botAI->GetAiObjectContext()->GetValue<bool>("custom_glyphs")->Set(true); botAI->GetAiObjectContext()->GetValue<bool>("custom_glyphs")->Set(true);
LOG_INFO("playerbots", "Custom Glyph Flag set to ON"); LOG_INFO("playerbots", "Custom Glyph Flag set to ON");
return true; return true;
} }

View File

@@ -0,0 +1,153 @@
/*
* Copyright (C) 2016+ AzerothCore <www.azerothcore.org>, released under GNU GPL v2 license, you may redistribute it
* and/or modify it under version 2 of the License, or (at your option), any later version.
*/
#include "GenericBuffUtils.h"
#include "PlayerbotAIConfig.h"
#include <map>
#include "Player.h"
#include "Group.h"
#include "SpellMgr.h"
#include "Chat.h"
#include "PlayerbotAI.h"
#include "ServerFacade.h"
#include "AiObjectContext.h"
#include "Value.h"
#include "Config.h"
#include "PlayerbotTextMgr.h"
namespace ai::buff
{
std::string MakeAuraQualifierForBuff(std::string const& name)
{
// Paladin
if (name == "blessing of kings") return "blessing of kings,greater blessing of kings";
if (name == "blessing of might") return "blessing of might,greater blessing of might";
if (name == "blessing of wisdom") return "blessing of wisdom,greater blessing of wisdom";
if (name == "blessing of sanctuary") return "blessing of sanctuary,greater blessing of sanctuary";
// Druid
if (name == "mark of the wild") return "mark of the wild,gift of the wild";
// Mage
if (name == "arcane intellect") return "arcane intellect,arcane brilliance";
// Priest
if (name == "power word: fortitude") return "power word: fortitude,prayer of fortitude";
return name;
}
std::string GroupVariantFor(std::string const& name)
{
// Paladin
if (name == "blessing of kings") return "greater blessing of kings";
if (name == "blessing of might") return "greater blessing of might";
if (name == "blessing of wisdom") return "greater blessing of wisdom";
if (name == "blessing of sanctuary") return "greater blessing of sanctuary";
// Druid
if (name == "mark of the wild") return "gift of the wild";
// Mage
if (name == "arcane intellect") return "arcane brilliance";
// Priest
if (name == "power word: fortitude") return "prayer of fortitude";
return std::string();
}
bool HasRequiredReagents(Player* bot, uint32 spellId)
{
if (!spellId)
return false;
if (SpellInfo const* info = sSpellMgr->GetSpellInfo(spellId))
{ for (int i = 0; i < MAX_SPELL_REAGENTS; ++i)
{
if (info->Reagent[i] > 0)
{
uint32 const itemId = info->Reagent[i];
int32 const need = info->ReagentCount[i];
if ((int32)bot->GetItemCount(itemId, false) < need)
return false;
}
}
// No reagent required
return true;
}
return false;
}
std::string UpgradeToGroupIfAppropriate(
Player* bot,
PlayerbotAI* botAI,
std::string const& baseName,
bool announceOnMissing,
std::function<void(std::string const&)> announce)
{
std::string castName = baseName; Group* g = bot->GetGroup();
if (!g || g->GetMembersCount() < static_cast<uint32>(sPlayerbotAIConfig->minBotsForGreaterBuff))
return castName; // Group too small: stay in solo mode
if (std::string const groupName = GroupVariantFor(baseName); !groupName.empty())
{
uint32 const groupVariantSpellId = botAI->GetAiObjectContext()
->GetValue<uint32>("spell id", groupName)->Get();
// We check usefulness on the **basic** buff (not the greater version),
// because "spell cast useful" may return false for the greater variant.
bool const usefulBase = botAI->GetAiObjectContext()
->GetValue<bool>("spell cast useful", baseName)->Get();
if (groupVariantSpellId && HasRequiredReagents(bot, groupVariantSpellId))
{
// Learned + reagents OK -> switch to greater
return groupName;
}
// Missing reagents -> announce if (a) greater is known, (b) base buff is useful,
// (c) announce was requested, (d) a callback is provided.
if (announceOnMissing && groupVariantSpellId && usefulBase && announce)
{
static std::map<std::pair<uint32, std::string>, time_t> s_lastWarn; // par bot & par buff
time_t now = std::time(nullptr);
uint32 botLow = static_cast<uint32>(bot->GetGUID().GetCounter());
time_t& last = s_lastWarn[ std::make_pair(botLow, groupName) ];
if (!last || now - last >= sPlayerbotAIConfig->rpWarningCooldown) // Configurable anti-spam
{
// DB Key choice in regard of the buff
std::string key;
if (groupName.find("greater blessing") != std::string::npos)
key = "rp_missing_reagent_greater_blessing";
else if (groupName == "gift of the wild")
key = "rp_missing_reagent_gift_of_the_wild";
else if (groupName == "arcane brilliance")
key = "rp_missing_reagent_arcane_brilliance";
else
key = "rp_missing_reagent_generic";
// Placeholders
std::map<std::string, std::string> ph;
ph["%group_spell"] = groupName;
ph["%base_spell"] = baseName;
// Respecte ai_playerbot_texts_chance if present
std::string rp;
bool got = sPlayerbotTextMgr->GetBotText(key, rp, ph);
if (got && !rp.empty())
{
announce(rp);
last = now;
}
else
{
// Minimal Fallback
std::ostringstream oss;
oss << "Out of components for " << groupName << ". Using " << baseName << "!";
announce(oss.str());
last = now;
}
}
}
}
return castName;
}
}

View File

@@ -0,0 +1,64 @@
/*
* Copyright (C) 2016+ AzerothCore <www.azerothcore.org>, released under GNU GPL v2 license, you may redistribute it
* and/or modify it under version 2 of the License, or (at your option), any later version.
*/
#pragma once
#include <string>
#include <functional>
#include "Common.h"
#include "Group.h"
#include "Chat.h"
#include "Language.h"
class Player;
class PlayerbotAI;
namespace ai::buff
{
// Build an aura qualifier "single + greater" to avoid double-buffing
std::string MakeAuraQualifierForBuff(std::string const& name);
// Returns the group spell name for a given single-target buff.
// If no group equivalent exists, returns "".
std::string GroupVariantFor(std::string const& name);
// Checks if the bot has the required reagents to cast a spell (by its spellId).
// 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
// (if provided) to notify the party/raid.
std::string UpgradeToGroupIfAppropriate(
Player* bot,
PlayerbotAI* botAI,
std::string const& baseName,
bool announceOnMissing = false,
std::function<void(std::string const&)> announce = {}
);
}
namespace ai::chat {
inline std::function<void(std::string const&)> MakeGroupAnnouncer(Player* me)
{
return [me](std::string const& msg)
{
if (Group* g = me->GetGroup())
{
WorldPacket data;
ChatMsg type = g->isRaidGroup() ? CHAT_MSG_RAID : CHAT_MSG_PARTY;
ChatHandler::BuildChatPacket(data, type, LANG_UNIVERSAL, me, /*receiver=*/nullptr, msg.c_str());
g->BroadcastPacket(&data, true, -1, me->GetGUID());
}
else
{
me->Say(msg, LANG_UNIVERSAL);
}
};
}
}

View File

@@ -5,6 +5,8 @@
#include "GenericSpellActions.h" #include "GenericSpellActions.h"
#include <ctime>
#include "Event.h" #include "Event.h"
#include "ItemTemplate.h" #include "ItemTemplate.h"
#include "ObjectDefines.h" #include "ObjectDefines.h"
@@ -13,6 +15,14 @@
#include "Playerbots.h" #include "Playerbots.h"
#include "ServerFacade.h" #include "ServerFacade.h"
#include "WorldPacket.h" #include "WorldPacket.h"
#include "Group.h"
#include "Chat.h"
#include "Language.h"
#include "GenericBuffUtils.h"
#include "PlayerbotAI.h"
using ai::buff::MakeAuraQualifierForBuff;
using ai::buff::UpgradeToGroupIfAppropriate;
CastSpellAction::CastSpellAction(PlayerbotAI* botAI, std::string const spell) CastSpellAction::CastSpellAction(PlayerbotAI* botAI, std::string const spell)
: Action(botAI, spell), range(botAI->GetRange("spell")), spell(spell) : Action(botAI, spell), range(botAI->GetRange("spell")), spell(spell)
@@ -216,11 +226,24 @@ Value<Unit*>* CurePartyMemberAction::GetTargetValue()
return context->GetValue<Unit*>("party member to dispel", dispelType); return context->GetValue<Unit*>("party member to dispel", dispelType);
} }
// Make Bots Paladin, druid, mage use the greater buff rank spell
// TODO Priest doen't verify il he have components
Value<Unit*>* BuffOnPartyAction::GetTargetValue() Value<Unit*>* BuffOnPartyAction::GetTargetValue()
{ {
return context->GetValue<Unit*>("party member without aura", spell); return context->GetValue<Unit*>("party member without aura", MakeAuraQualifierForBuff(spell));
} }
bool BuffOnPartyAction::Execute(Event event)
{
std::string castName = spell; // default = mono
auto SendGroupRP = ai::chat::MakeGroupAnnouncer(bot);
castName = ai::buff::UpgradeToGroupIfAppropriate(bot, botAI, castName, /*announceOnMissing=*/true, SendGroupRP);
return botAI->CastSpell(castName, GetTarget());
}
// End greater buff fix
CastShootAction::CastShootAction(PlayerbotAI* botAI) : CastSpellAction(botAI, "shoot") CastShootAction::CastShootAction(PlayerbotAI* botAI) : CastSpellAction(botAI, "shoot")
{ {
if (Item* const pItem = bot->GetItemByPos(INVENTORY_SLOT_BAG_0, EQUIPMENT_SLOT_RANGED)) if (Item* const pItem = bot->GetItemByPos(INVENTORY_SLOT_BAG_0, EQUIPMENT_SLOT_RANGED))

View File

@@ -215,17 +215,18 @@ protected:
uint32 dispelType; uint32 dispelType;
}; };
// Make Bots Paladin, druid, mage use the greater buff rank spell
class BuffOnPartyAction : public CastBuffSpellAction, public PartyMemberActionNameSupport class BuffOnPartyAction : public CastBuffSpellAction, public PartyMemberActionNameSupport
{ {
public: public:
BuffOnPartyAction(PlayerbotAI* botAI, std::string const spell) BuffOnPartyAction(PlayerbotAI* botAI, std::string const spell)
: CastBuffSpellAction(botAI, spell), PartyMemberActionNameSupport(spell) : CastBuffSpellAction(botAI, spell), PartyMemberActionNameSupport(spell) { }
{
}
Value<Unit*>* GetTargetValue() override; Value<Unit*>* GetTargetValue() override;
bool Execute(Event event) override;
std::string const getName() override { return PartyMemberActionNameSupport::getName(); } std::string const getName() override { return PartyMemberActionNameSupport::getName(); }
}; };
// End Fix
class CastShootAction : public CastSpellAction class CastShootAction : public CastSpellAction
{ {

View File

@@ -26,55 +26,12 @@ bool GossipHelloAction::Execute(Event event)
p >> guid; p >> guid;
} }
if (!guid)
return false;
Creature* pCreature = bot->GetNPCIfCanInteractWith(guid, UNIT_NPC_FLAG_NONE);
if (!pCreature)
{
LOG_DEBUG("playerbots",
"[PlayerbotMgr]: HandleMasterIncomingPacket - Received CMSG_GOSSIP_HELLO {} not found or you can't "
"interact with him.",
guid.ToString().c_str());
return false;
}
GossipMenuItemsMapBounds pMenuItemBounds =
sObjectMgr->GetGossipMenuItemsMapBounds(pCreature->GetCreatureTemplate()->GossipMenuId);
if (pMenuItemBounds.first == pMenuItemBounds.second)
return false;
std::string const text = event.getParam(); std::string const text = event.getParam();
int32 menuToSelect = -1; int32 menuToSelect = -1;
if (text.empty()) if (!text.empty())
{
WorldPacket p1;
p1 << guid;
bot->GetSession()->HandleGossipHelloOpcode(p1);
bot->SetFacingToObject(pCreature);
std::ostringstream out;
out << "--- " << pCreature->GetName() << " ---";
botAI->TellMasterNoFacing(out.str());
TellGossipMenus();
}
else if (!bot->PlayerTalkClass)
{
botAI->TellError("I need to talk first");
return false;
}
else
{
menuToSelect = atoi(text.c_str()); menuToSelect = atoi(text.c_str());
// if (menuToSelect > 0)
// menuToSelect--;
ProcessGossip(menuToSelect); return Execute(guid, menuToSelect, false);
}
bot->TalkedToCreature(pCreature->GetEntry(), pCreature->GetGUID());
return true;
} }
void GossipHelloAction::TellGossipText(uint32 textId) void GossipHelloAction::TellGossipText(uint32 textId)
@@ -120,16 +77,16 @@ void GossipHelloAction::TellGossipMenus()
} }
} }
bool GossipHelloAction::ProcessGossip(int32 menuToSelect) bool GossipHelloAction::ProcessGossip(int32 menuToSelect, bool silent)
{ {
GossipMenu& menu = bot->PlayerTalkClass->GetGossipMenu(); GossipMenu& menu = bot->PlayerTalkClass->GetGossipMenu();
if (menuToSelect != -1 && !menu.GetItem(menuToSelect)) if (menuToSelect != -1 && !menu.GetItem(menuToSelect))
{ {
botAI->TellError("Unknown gossip option"); if (!silent)
botAI->TellError("Unknown gossip option");
return false; return false;
} }
// GossipMenuItem const* item = menu.GetItem(menuToSelect); //not used, line marked for removal.
WorldPacket p; WorldPacket p;
std::string code; std::string code;
p << GetMaster()->GetTarget(); p << GetMaster()->GetTarget();
@@ -137,7 +94,59 @@ bool GossipHelloAction::ProcessGossip(int32 menuToSelect)
p << code; p << code;
bot->GetSession()->HandleGossipSelectOptionOpcode(p); bot->GetSession()->HandleGossipSelectOptionOpcode(p);
TellGossipMenus(); if (!silent)
TellGossipMenus();
return true; return true;
} }
bool GossipHelloAction::Execute(ObjectGuid guid, int32 menuToSelect, bool silent)
{
if (!guid)
return false;
Creature* pCreature = bot->GetNPCIfCanInteractWith(guid, UNIT_NPC_FLAG_NONE);
if (!pCreature)
{
LOG_DEBUG("playerbots",
"[PlayerbotMgr]: HandleMasterIncomingPacket - Received CMSG_GOSSIP_HELLO {} not found or you can't "
"interact with him.",
guid.ToString().c_str());
return false;
}
GossipMenuItemsMapBounds pMenuItemBounds =
sObjectMgr->GetGossipMenuItemsMapBounds(pCreature->GetCreatureTemplate()->GossipMenuId);
if (pMenuItemBounds.first == pMenuItemBounds.second)
return false;
if (menuToSelect == -1)
{
WorldPacket p1;
p1 << guid;
bot->GetSession()->HandleGossipHelloOpcode(p1);
bot->SetFacingToObject(pCreature);
if (!silent)
{
std::ostringstream out;
out << "--- " << pCreature->GetName() << " ---";
botAI->TellMasterNoFacing(out.str());
TellGossipMenus();
}
}
else if (!bot->PlayerTalkClass)
{
if (!silent)
botAI->TellError("I need to talk first");
return false;
}
else
{
if (!ProcessGossip(menuToSelect, silent))
return false;
}
bot->TalkedToCreature(pCreature->GetEntry(), pCreature->GetGUID());
return true;
}

View File

@@ -16,10 +16,12 @@ public:
GossipHelloAction(PlayerbotAI* botAI) : Action(botAI, "gossip hello") {} GossipHelloAction(PlayerbotAI* botAI) : Action(botAI, "gossip hello") {}
bool Execute(Event event) override; bool Execute(Event event) override;
// Overload for direct usage
bool Execute(ObjectGuid guid, int32 menuToSelect, bool silent = false);
private: private:
void TellGossipMenus(); void TellGossipMenus();
bool ProcessGossip(int32 menuToSelect); bool ProcessGossip(int32 menuToSelect, bool silent);
void TellGossipText(uint32 textId); void TellGossipText(uint32 textId);
}; };

View File

@@ -12,6 +12,7 @@
#include "Playerbots.h" #include "Playerbots.h"
#include "RandomPlayerbotFactory.h" #include "RandomPlayerbotFactory.h"
#include "ServerFacade.h" #include "ServerFacade.h"
#include "SharedDefines.h" // GOLD
bool BuyPetitionAction::Execute(Event event) bool BuyPetitionAction::Execute(Event event)
{ {
@@ -237,6 +238,15 @@ bool PetitionTurnInAction::Execute(Event event)
if (bot->GetGuildId()) if (bot->GetGuildId())
{ {
// Ensure that bot has at least 10g for HandleSetEmblem can be managed core side
// (EMBLEM_PRICE = 10 * GOLD in core)
static constexpr uint32 REQUIRED = 10 * GOLD;
uint32 have = bot->GetMoney(); // actual money earned by bot in copper
if (have < REQUIRED)
{
bot->ModifyMoney(int32(REQUIRED - have)); // add only the missing amount to bot to reach 10g
}
Guild* guild = sGuildMgr->GetGuildById(bot->GetGuildId()); Guild* guild = sGuildMgr->GetGuildById(bot->GetGuildId());
uint32 st, cl, br, bc, bg; uint32 st, cl, br, bc, bg;
@@ -247,7 +257,7 @@ bool PetitionTurnInAction::Execute(Event event)
st = urand(0, 180); st = urand(0, 180);
EmblemInfo emblemInfo(st, cl, br, bc, bg); EmblemInfo emblemInfo(st, cl, br, bc, bg);
guild->HandleSetEmblem(emblemInfo); guild->HandleSetEmblem(emblemInfo); // official core handling
// LANG_GUILD_VETERAN -> can invite // LANG_GUILD_VETERAN -> can invite
guild->HandleSetRankInfo(2, GR_RIGHT_GCHATLISTEN | GR_RIGHT_GCHATSPEAK | GR_RIGHT_INVITE); guild->HandleSetRankInfo(2, GR_RIGHT_GCHATLISTEN | GR_RIGHT_GCHATSPEAK | GR_RIGHT_INVITE);

View File

@@ -90,7 +90,11 @@ void GuildInviteAction::SendPacket(WorldPacket packet)
bot->GetSession()->HandleGuildInviteOpcode(data); bot->GetSession()->HandleGuildInviteOpcode(data);
} }
bool GuildInviteAction::PlayerIsValid(Player* member) { return !member->GetGuildId(); } bool GuildInviteAction::PlayerIsValid(Player* member)
{
return !member->GetGuildId() && (sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_GUILD) ||
(bot->GetTeamId() == member->GetTeamId()));
}
bool GuildPromoteAction::isUseful() bool GuildPromoteAction::isUseful()
{ {

View File

@@ -31,7 +31,7 @@ bool PartyCommandAction::Execute(Event event)
if (master && member == master->GetName()) if (master && member == master->GetName())
return Leave(bot); return Leave(bot);
botAI->Reset(); botAI->Reset();
return false; return false;
} }
@@ -65,7 +65,7 @@ bool UninviteAction::Execute(Event event)
return Leave(bot); return Leave(bot);
} }
botAI->Reset(); botAI->Reset();
return false; return false;
} }
@@ -163,7 +163,7 @@ bool LeaveFarAwayAction::isUseful()
return true; return true;
} }
botAI->Reset(); botAI->Reset();
return false; return false;
} }

View File

@@ -77,7 +77,7 @@ uint32 LfgJoinAction::GetRoles()
default: default:
return PLAYER_ROLE_DAMAGE; return PLAYER_ROLE_DAMAGE;
break; break;
} }
return PLAYER_ROLE_DAMAGE; return PLAYER_ROLE_DAMAGE;
@@ -318,7 +318,7 @@ bool LfgJoinAction::isUseful()
if (bot->GetLevel() < 15) if (bot->GetLevel() < 15)
return false; return false;
// don't use if active player master // don't use if active player master
if (GET_PLAYERBOT_AI(bot)->IsRealPlayer()) if (GET_PLAYERBOT_AI(bot)->IsRealPlayer())
return false; return false;

View File

@@ -49,7 +49,7 @@ bool UseMeetingStoneAction::Execute(Event event)
GameObjectTemplate const* goInfo = gameObject->GetGOInfo(); GameObjectTemplate const* goInfo = gameObject->GetGOInfo();
if (!goInfo || goInfo->entry != 179944) if (!goInfo || goInfo->entry != 179944)
return false; return false;
return Teleport(master, bot); return Teleport(master, bot);
} }

View File

@@ -25,7 +25,7 @@ public:
// creators["icy clutch"] = &icy_clutch; // creators["icy clutch"] = &icy_clutch;
creators["horn of winter"] = &horn_of_winter; creators["horn of winter"] = &horn_of_winter;
creators["killing machine"] = &killing_machine; // buff creators["killing machine"] = &killing_machine; // buff
// creators["deathchill"] = &deathchill; //boost // creators["deathchill"] = &deathchill; //boost
creators["icebound fortitude"] = &icebound_fortitude; creators["icebound fortitude"] = &icebound_fortitude;
// creators["mind freeze"] = &mind_freeze; interrupt // creators["mind freeze"] = &mind_freeze; interrupt
// creators["empower rune weapon"] = &empower_rune_weapon; boost // creators["empower rune weapon"] = &empower_rune_weapon; boost
@@ -193,8 +193,8 @@ void GenericDKStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
new NextAction("pestilence", ACTION_NORMAL + 4), new NextAction("pestilence", ACTION_NORMAL + 4),
new NextAction("blood boil", ACTION_NORMAL + 3), nullptr))); new NextAction("blood boil", ACTION_NORMAL + 3), nullptr)));
// triggers.push_back(new TriggerNode("light aoe", NextAction::array(0, // triggers.push_back(new TriggerNode("light aoe", NextAction::array(0,
// new NextAction("pestilence", ACTION_NORMAL + 4), // new NextAction("pestilence", ACTION_NORMAL + 4),
// nullptr))); // nullptr)));
triggers.push_back( triggers.push_back(
new TriggerNode("pestilence glyph", NextAction::array(0, new NextAction("pestilence", ACTION_HIGH + 9), NULL))); new TriggerNode("pestilence glyph", NextAction::array(0, new NextAction("pestilence", ACTION_HIGH + 9), NULL)));
} }

View File

@@ -93,13 +93,13 @@ void ChatCommandHandlerStrategy::InitTriggers(std::vector<TriggerNode*>& trigger
triggers.push_back( triggers.push_back(
new TriggerNode("disperse", NextAction::array(0, new NextAction("disperse set", relevance), NULL))); new TriggerNode("disperse", NextAction::array(0, new NextAction("disperse set", relevance), NULL)));
triggers.push_back( triggers.push_back(
new TriggerNode("open items", NextAction::array(0, new NextAction("open items", relevance), nullptr))); new TriggerNode("open items", NextAction::array(0, new NextAction("open items", relevance), nullptr)));
triggers.push_back( triggers.push_back(
new TriggerNode("qi", NextAction::array(0, new NextAction("query item usage", relevance), nullptr))); new TriggerNode("qi", NextAction::array(0, new NextAction("query item usage", relevance), nullptr)));
triggers.push_back( triggers.push_back(
new TriggerNode("unlock items", NextAction::array(0, new NextAction("unlock items", relevance), nullptr))); new TriggerNode("unlock items", NextAction::array(0, new NextAction("unlock items", relevance), nullptr)));
triggers.push_back( triggers.push_back(
new TriggerNode("unlock traded item", NextAction::array(0, new NextAction("unlock traded item", relevance), nullptr))); new TriggerNode("unlock traded item", NextAction::array(0, new NextAction("unlock traded item", relevance), nullptr)));
triggers.push_back( triggers.push_back(
new TriggerNode("wipe", NextAction::array(0, new NextAction("wipe", relevance), nullptr))); new TriggerNode("wipe", NextAction::array(0, new NextAction("wipe", relevance), nullptr)));
triggers.push_back(new TriggerNode("tame", NextAction::array(0, new NextAction("tame", relevance), nullptr))); triggers.push_back(new TriggerNode("tame", NextAction::array(0, new NextAction("tame", relevance), nullptr)));

View File

@@ -13,6 +13,53 @@
#include "Playerbots.h" #include "Playerbots.h"
#include "SharedDefines.h" #include "SharedDefines.h"
#include "../../../../../src/server/scripts/Spells/spell_generic.cpp" #include "../../../../../src/server/scripts/Spells/spell_generic.cpp"
#include "GenericBuffUtils.h"
#include "Config.h"
#include "Group.h"
#include "ObjectAccessor.h"
using ai::buff::MakeAuraQualifierForBuff;
using ai::buff::UpgradeToGroupIfAppropriate;
// Helper : detect tank role on the target (player bot or not) return true if spec is tank or if the bot have tank strategies (bear/tank/tank face).
static inline bool IsTankRole(Player* p)
{
if (!p) return false;
if (p->HasTankSpec())
return true;
if (PlayerbotAI* otherAI = GET_PLAYERBOT_AI(p))
{
if (otherAI->HasStrategy("tank", BOT_STATE_NON_COMBAT) ||
otherAI->HasStrategy("tank", BOT_STATE_COMBAT) ||
otherAI->HasStrategy("tank face", BOT_STATE_NON_COMBAT) ||
otherAI->HasStrategy("tank face", BOT_STATE_COMBAT) ||
otherAI->HasStrategy("bear", BOT_STATE_NON_COMBAT) ||
otherAI->HasStrategy("bear", BOT_STATE_COMBAT))
return true;
}
return false;
}
// Added for solo paladin patch : determine if he's the only paladin on party
static inline bool IsOnlyPaladinInGroup(Player* bot)
{
if (!bot) return false;
Group* g = bot->GetGroup();
if (!g) return true; // solo
uint32 pals = 0u;
for (GroupReference* r = g->GetFirstMember(); r; r = r->next())
{
Player* p = r->GetSource();
if (!p || !p->IsInWorld()) continue;
if (p->getClass() == CLASS_PALADIN) ++pals;
}
return pals == 1u;
}
static inline bool GroupHasTankOfClass(Group* g, uint8 classId)
{
return GroupHasTankOfClass(g, static_cast<Classes>(classId));
}
inline std::string const GetActualBlessingOfMight(Unit* target) inline std::string const GetActualBlessingOfMight(Unit* target)
{ {
@@ -92,24 +139,32 @@ inline std::string const GetActualBlessingOfWisdom(Unit* target)
inline std::string const GetActualBlessingOfSanctuary(Unit* target, Player* bot) inline std::string const GetActualBlessingOfSanctuary(Unit* target, Player* bot)
{ {
Player* targetPlayer = target->ToPlayer(); if (!bot->HasSpell(SPELL_BLESSING_OF_SANCTUARY))
return "";
if (!targetPlayer) Player* tp = target->ToPlayer();
if (!tp)
return "";
if (auto* ai = GET_PLAYERBOT_AI(bot))
{ {
return "blessing of sanctuary"; if (Unit* mt = ai->GetAiObjectContext()->GetValue<Unit*>("main tank")->Get())
{
if (mt == target)
return "blessing of sanctuary";
}
} }
if (targetPlayer->HasTankSpec() && bot->HasSpell(SPELL_BLESSING_OF_SANCTUARY)) if (tp->HasTankSpec())
{
return "blessing of sanctuary"; return "blessing of sanctuary";
}
return "blessing of kings"; return "";
} }
Value<Unit*>* CastBlessingOnPartyAction::GetTargetValue() Value<Unit*>* CastBlessingOnPartyAction::GetTargetValue()
{ {
return context->GetValue<Unit*>("party member without aura", name);
return context->GetValue<Unit*>("party member without aura", MakeAuraQualifierForBuff(spell));
} }
bool CastBlessingOfMightAction::Execute(Event event) bool CastBlessingOfMightAction::Execute(Event event)
@@ -118,12 +173,19 @@ bool CastBlessingOfMightAction::Execute(Event event)
if (!target) if (!target)
return false; return false;
return botAI->CastSpell(GetActualBlessingOfMight(target), target); std::string castName = GetActualBlessingOfMight(target);
auto RP = ai::chat::MakeGroupAnnouncer(bot);
castName = ai::buff::UpgradeToGroupIfAppropriate(bot, botAI, castName, /*announceOnMissing=*/true, RP);
return botAI->CastSpell(castName, target);
} }
Value<Unit*>* CastBlessingOfMightOnPartyAction::GetTargetValue() Value<Unit*>* CastBlessingOfMightOnPartyAction::GetTargetValue()
{ {
return context->GetValue<Unit*>("party member without aura", "blessing of might,blessing of wisdom"); return context->GetValue<Unit*>(
"party member without aura",
"blessing of might,greater blessing of might,blessing of wisdom,greater blessing of wisdom,blessing of sanctuary,greater blessing of sanctuary"
);
} }
bool CastBlessingOfMightOnPartyAction::Execute(Event event) bool CastBlessingOfMightOnPartyAction::Execute(Event event)
@@ -132,7 +194,11 @@ bool CastBlessingOfMightOnPartyAction::Execute(Event event)
if (!target) if (!target)
return false; return false;
return botAI->CastSpell(GetActualBlessingOfMight(target), target); std::string castName = GetActualBlessingOfMight(target);
auto RP = ai::chat::MakeGroupAnnouncer(bot);
castName = ai::buff::UpgradeToGroupIfAppropriate(bot, botAI, castName, /*announceOnMissing=*/true, RP);
return botAI->CastSpell(castName, target);
} }
bool CastBlessingOfWisdomAction::Execute(Event event) bool CastBlessingOfWisdomAction::Execute(Event event)
@@ -141,12 +207,19 @@ bool CastBlessingOfWisdomAction::Execute(Event event)
if (!target) if (!target)
return false; return false;
return botAI->CastSpell(GetActualBlessingOfWisdom(target), target); std::string castName = GetActualBlessingOfWisdom(target);
auto RP = ai::chat::MakeGroupAnnouncer(bot);
castName = ai::buff::UpgradeToGroupIfAppropriate(bot, botAI, castName, /*announceOnMissing=*/true, RP);
return botAI->CastSpell(castName, target);
} }
Value<Unit*>* CastBlessingOfWisdomOnPartyAction::GetTargetValue() Value<Unit*>* CastBlessingOfWisdomOnPartyAction::GetTargetValue()
{ {
return context->GetValue<Unit*>("party member without aura", "blessing of might,blessing of wisdom"); return context->GetValue<Unit*>(
"party member without aura",
"blessing of wisdom,greater blessing of wisdom,blessing of might,greater blessing of might,blessing of sanctuary,greater blessing of sanctuary"
);
} }
bool CastBlessingOfWisdomOnPartyAction::Execute(Event event) bool CastBlessingOfWisdomOnPartyAction::Execute(Event event)
@@ -155,21 +228,250 @@ bool CastBlessingOfWisdomOnPartyAction::Execute(Event event)
if (!target) if (!target)
return false; return false;
return botAI->CastSpell(GetActualBlessingOfWisdom(target), target); Player* targetPlayer = target->ToPlayer();
if (Group* g = bot->GetGroup())
if (targetPlayer && !g->IsMember(targetPlayer->GetGUID()))
return false;
if (botAI->HasStrategy("bmana", BOT_STATE_NON_COMBAT) &&
targetPlayer && IsTankRole(targetPlayer))
{
LOG_DEBUG("playerbots", "[Wisdom/bmana] Skip tank {} (Kings only)", target->GetName());
return false;
}
std::string castName = GetActualBlessingOfWisdom(target);
if (castName.empty())
return false;
auto RP = ai::chat::MakeGroupAnnouncer(bot);
castName = ai::buff::UpgradeToGroupIfAppropriate(bot, botAI, castName, /*announceOnMissing=*/true, RP);
return botAI->CastSpell(castName, target);
} }
Value<Unit*>* CastBlessingOfSanctuaryOnPartyAction::GetTargetValue() Value<Unit*>* CastBlessingOfSanctuaryOnPartyAction::GetTargetValue()
{ {
return context->GetValue<Unit*>("party member without aura", "blessing of sanctuary,blessing of kings"); return context->GetValue<Unit*>(
"party member without aura",
"blessing of sanctuary,greater blessing of sanctuary"
);
} }
bool CastBlessingOfSanctuaryOnPartyAction::Execute(Event event) bool CastBlessingOfSanctuaryOnPartyAction::Execute(Event event)
{
if (!bot->HasSpell(SPELL_BLESSING_OF_SANCTUARY))
return false;
Unit* target = GetTarget();
if (!target)
{
// Fallback: GetTarget() can be null if no one needs a buff.
// Keep a valid pointer for the checks/logs that follow.
target = bot;
}
Player* targetPlayer = target ? target->ToPlayer() : nullptr;
// Small helpers to check relevant auras
const auto HasKingsAura = [&](Unit* u) -> bool {
return botAI->HasAura("blessing of kings", u) || botAI->HasAura("greater blessing of kings", u);
};
const auto HasSanctAura = [&](Unit* u) -> bool {
return botAI->HasAura("blessing of sanctuary", u) || botAI->HasAura("greater blessing of sanctuary", u);
};
if (Group* g = bot->GetGroup())
{
if (targetPlayer && !g->IsMember(targetPlayer->GetGUID()))
{
LOG_DEBUG("playerbots", "[Sanct] Initial target not in group, ignoring");
target = bot;
targetPlayer = bot->ToPlayer();
}
}
if (Player* self = bot->ToPlayer())
{
bool selfHasSanct = HasSanctAura(self);
bool needSelf = IsTankRole(self) && !selfHasSanct;
LOG_DEBUG("playerbots", "[Sanct] {} isTank={} selfHasSanct={} needSelf={}",
bot->GetName(), IsTankRole(self), selfHasSanct, needSelf);
if (needSelf)
{
target = self;
targetPlayer = self;
}
}
// Try to re-target a valid tank in group if needed
bool targetOk = false;
if (targetPlayer)
{
bool hasSanct = HasSanctAura(targetPlayer);
targetOk = IsTankRole(targetPlayer) && !hasSanct;
}
if (!targetOk)
{
if (Group* g = bot->GetGroup())
{
for (GroupReference* gref = g->GetFirstMember(); gref; gref = gref->next())
{
Player* p = gref->GetSource();
if (!p) continue;
if (!p->IsInWorld() || !p->IsAlive()) continue;
if (!IsTankRole(p)) continue;
bool hasSanct = HasSanctAura(p);
if (!hasSanct)
{
target = p; // prioritize this tank
targetPlayer = p;
targetOk = true;
break;
}
}
}
}
{
bool hasKings = HasKingsAura(target);
bool hasSanct = HasSanctAura(target);
bool knowSanct = bot->HasSpell(SPELL_BLESSING_OF_SANCTUARY);
LOG_DEBUG("playerbots", "[Sanct] Final target={} hasKings={} hasSanct={} knowSanct={}",
target->GetName(), hasKings, hasSanct, knowSanct);
}
std::string castName = GetActualBlessingOfSanctuary(target, bot);
// If internal logic didn't recognize the tank (e.g., bear druid), force single-target Sanctuary
if (castName.empty())
{
if (targetPlayer)
{
if (IsTankRole(targetPlayer))
castName = "blessing of sanctuary"; // force single-target
else
return false;
}
else
return false;
}
if (targetPlayer && !IsTankRole(targetPlayer))
{
auto RP = ai::chat::MakeGroupAnnouncer(bot);
castName = ai::buff::UpgradeToGroupIfAppropriate(bot, botAI, castName, /*announceOnMissing=*/true, RP);
}
else
{
castName = "blessing of sanctuary";
}
bool ok = botAI->CastSpell(castName, target);
LOG_DEBUG("playerbots", "[Sanct] Cast {} on {} result={}", castName, target->GetName(), ok);
return ok;
}
Value<Unit*>* CastBlessingOfKingsOnPartyAction::GetTargetValue()
{
return context->GetValue<Unit*>(
"party member without aura",
"blessing of kings,greater blessing of kings,blessing of sanctuary,greater blessing of sanctuary"
);
}
bool CastBlessingOfKingsOnPartyAction::Execute(Event event)
{ {
Unit* target = GetTarget(); Unit* target = GetTarget();
if (!target) if (!target)
return false; return false;
return botAI->CastSpell(GetActualBlessingOfSanctuary(target, bot), target); Group* g = bot->GetGroup();
if (!g)
return false;
// Added for patch solo paladin, never buff itself to not remove his sanctuary buff
if (botAI->HasStrategy("bstats", BOT_STATE_NON_COMBAT) && IsOnlyPaladinInGroup(bot))
{
if (target->GetGUID() == bot->GetGUID())
{
LOG_DEBUG("playerbots", "[Kings/bstats-solo] Skip self to keep Sanctuary on {}", bot->GetName());
return false;
}
}
// End solo paladin patch
Player* targetPlayer = target->ToPlayer();
if (targetPlayer && !g->IsMember(targetPlayer->GetGUID()))
return false;
const bool hasBmana = botAI->HasStrategy("bmana", BOT_STATE_NON_COMBAT);
const bool hasBstats = botAI->HasStrategy("bstats", BOT_STATE_NON_COMBAT);
if (hasBmana)
{
if (!targetPlayer || !IsTankRole(targetPlayer))
{
LOG_DEBUG("playerbots", "[Kings/bmana] Skip non-tank {}", target->GetName());
return false;
}
}
if (targetPlayer)
{
const bool isTank = IsTankRole(targetPlayer);
const bool hasSanctFromMe =
target->HasAura(SPELL_BLESSING_OF_SANCTUARY, bot->GetGUID()) ||
target->HasAura(SPELL_GREATER_BLESSING_OF_SANCTUARY, bot->GetGUID());
const bool hasSanctAny =
botAI->HasAura("blessing of sanctuary", target) ||
botAI->HasAura("greater blessing of sanctuary", target);
if (isTank && hasSanctFromMe)
{
LOG_DEBUG("playerbots", "[Kings] Skip: {} has my Sanctuary and is a tank", target->GetName());
return false;
}
if (hasBstats && isTank && hasSanctAny)
{
LOG_DEBUG("playerbots", "[Kings] Skip (bstats): {} already has Sanctuary and is a tank", target->GetName());
return false;
}
}
std::string castName = "blessing of kings";
bool allowGreater = true;
if (hasBmana)
allowGreater = false;
if (allowGreater && hasBstats && targetPlayer)
{
switch (targetPlayer->getClass())
{
case CLASS_WARRIOR:
case CLASS_PALADIN:
case CLASS_DRUID:
case CLASS_DEATH_KNIGHT:
allowGreater = false;
break;
default:
break;
}
}
if (allowGreater)
{
auto RP = ai::chat::MakeGroupAnnouncer(bot);
castName = ai::buff::UpgradeToGroupIfAppropriate(bot, botAI, castName, /*announceOnMissing=*/true, RP);
}
return botAI->CastSpell(castName, target);
} }
bool CastSealSpellAction::isUseful() { return AI_VALUE2(bool, "combat", "self target"); } bool CastSealSpellAction::isUseful() { return AI_VALUE2(bool, "combat", "self target"); }

View File

@@ -141,6 +141,8 @@ public:
CastBlessingOfKingsOnPartyAction(PlayerbotAI* botAI) : CastBlessingOnPartyAction(botAI, "blessing of kings") {} CastBlessingOfKingsOnPartyAction(PlayerbotAI* botAI) : CastBlessingOnPartyAction(botAI, "blessing of kings") {}
std::string const getName() override { return "blessing of kings on party"; } std::string const getName() override { return "blessing of kings on party"; }
Value<Unit*>* GetTargetValue() override; // added for Sanctuary priority
bool Execute(Event event) override; // added for 2 paladins logic
}; };
class CastBlessingOfSanctuaryAction : public CastBuffSpellAction class CastBlessingOfSanctuaryAction : public CastBuffSpellAction

View File

@@ -9,11 +9,11 @@
void PaladinBuffManaStrategy::InitTriggers(std::vector<TriggerNode*>& triggers) void PaladinBuffManaStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
{ {
triggers.push_back( triggers.push_back(new TriggerNode("blessing of wisdom on party",
new TriggerNode("blessing of wisdom on party", NextAction::array(0, new NextAction("blessing of wisdom on party", 11.0f), NULL)));
NextAction::array(0, new NextAction("blessing of wisdom on party", 11.0f), nullptr)));
// triggers.push_back(new TriggerNode("blessing", NextAction::array(0, new NextAction("blessing of wisdom", triggers.push_back(new TriggerNode("blessing of kings on party",
// ACTION_HIGH + 8), nullptr))); NextAction::array(0, new NextAction("blessing of kings on party", 10.5f), NULL)));
} }
void PaladinBuffHealthStrategy::InitTriggers(std::vector<TriggerNode*>& triggers) void PaladinBuffHealthStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
@@ -86,9 +86,13 @@ void PaladinBuffThreatStrategy::InitTriggers(std::vector<TriggerNode*>& triggers
void PaladinBuffStatsStrategy::InitTriggers(std::vector<TriggerNode*>& triggers) void PaladinBuffStatsStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
{ {
// First Sanctuary (prio > Kings)
triggers.push_back(
new TriggerNode("blessing of sanctuary on party",
NextAction::array(0, new NextAction("blessing of sanctuary on party", 12.0f), nullptr)));
// After Kings
triggers.push_back( triggers.push_back(
new TriggerNode("blessing of kings on party", new TriggerNode("blessing of kings on party",
NextAction::array(0, new NextAction("blessing of kings on party", 11.0f), nullptr))); NextAction::array(0, new NextAction("blessing of kings on party", 11.0f), nullptr)));
// triggers.push_back(new TriggerNode("blessing", NextAction::array(0, new NextAction("blessing of kings",
// ACTION_HIGH + 8), nullptr)));
} }

View File

@@ -238,7 +238,7 @@ class BlessingOfSanctuaryOnPartyTrigger : public BuffOnPartyTrigger
{ {
public: public:
BlessingOfSanctuaryOnPartyTrigger(PlayerbotAI* botAI) BlessingOfSanctuaryOnPartyTrigger(PlayerbotAI* botAI)
: BuffOnPartyTrigger(botAI, "blessing of sanctuary,blessing of kings", 2 * 2000) : BuffOnPartyTrigger(botAI, "blessing of sanctuary", 2 * 2000)
{ {
} }
}; };

View File

@@ -27,8 +27,8 @@ void HealPriestStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
// NextAction::array(0, new NextAction("reach spell", ACTION_NORMAL + 9), NULL))); // NextAction::array(0, new NextAction("reach spell", ACTION_NORMAL + 9), NULL)));
// triggers.push_back(new TriggerNode( // triggers.push_back(new TriggerNode(
// "medium aoe heal", // "medium aoe heal",
// NextAction::array(0, // NextAction::array(0,
// new NextAction("circle of healing on party", ACTION_MEDIUM_HEAL + 8), // new NextAction("circle of healing on party", ACTION_MEDIUM_HEAL + 8),
// // new NextAction("power word: shield on almost full health below", ACTION_MEDIUM_HEAL + 7), // // new NextAction("power word: shield on almost full health below", ACTION_MEDIUM_HEAL + 7),
// NULL))); // NULL)));

View File

@@ -143,13 +143,13 @@ float ThaddiusGenericMultiplier::GetValue(Action* action)
// // if (curr_phase == 2 && bot->GetPositionZ() > 312.5f && dynamic_cast<MovementAction*>(action)) { // // if (curr_phase == 2 && bot->GetPositionZ() > 312.5f && dynamic_cast<MovementAction*>(action)) {
// if (curr_phase == 2 && (curr_timer % 20000 >= 18000 || curr_timer % 20000 <= 2000) && // if (curr_phase == 2 && (curr_timer % 20000 >= 18000 || curr_timer % 20000 <= 2000) &&
// dynamic_cast<MovementAction*>(action)) { // dynamic_cast<MovementAction*>(action)) {
// // MotionMaster *mm = bot->GetMotionMaster(); // // MotionMaster *mm = bot->GetMotionMaster();
// // mm->Clear(); // // mm->Clear();
// return 0.0f; // return 0.0f;
// } // }
// thaddius phase // thaddius phase
// if (curr_phase == 8 && dynamic_cast<FleeAction*>(action)) { // if (curr_phase == 8 && dynamic_cast<FleeAction*>(action)) {
// return 0.0f; // return 0.0f;
// } // }
return 1.0f; return 1.0f;
} }
@@ -262,23 +262,23 @@ float FourhorsemanGenericMultiplier::GetValue(Action* action)
// float GothikGenericMultiplier::GetValue(Action* action) // float GothikGenericMultiplier::GetValue(Action* action)
// { // {
// Unit* boss = AI_VALUE2(Unit*, "find target", "gothik the harvester"); // Unit* boss = AI_VALUE2(Unit*, "find target", "gothik the harvester");
// if (!boss) { // if (!boss) {
// return 1.0f; // return 1.0f;
// } // }
// BossAI* boss_ai = dynamic_cast<BossAI*>(boss->GetAI()); // BossAI* boss_ai = dynamic_cast<BossAI*>(boss->GetAI());
// EventMap* eventMap = boss_botAI->GetEvents(); // EventMap* eventMap = boss_botAI->GetEvents();
// uint32 curr_phase = eventMap->GetPhaseMask(); // uint32 curr_phase = eventMap->GetPhaseMask();
// if (curr_phase == 1 && (dynamic_cast<FollowAction*>(action))) { // if (curr_phase == 1 && (dynamic_cast<FollowAction*>(action))) {
// return 0.0f; // return 0.0f;
// } // }
// if (curr_phase == 1 && (dynamic_cast<AttackAction*>(action))) { // if (curr_phase == 1 && (dynamic_cast<AttackAction*>(action))) {
// Unit* target = action->GetTarget(); // Unit* target = action->GetTarget();
// if (target == boss) { // if (target == boss) {
// return 0.0f; // return 0.0f;
// } // }
// } // }
// return 1.0f; // return 1.0f;
// } // }
float GluthGenericMultiplier::GetValue(Action* action) float GluthGenericMultiplier::GetValue(Action* action)

View File

@@ -51,8 +51,8 @@ void GenericRogueNonCombatStrategy::InitTriggers(std::vector<TriggerNode*>& trig
NextAction::array(0, new NextAction("use deadly poison on off hand", 19.0f), NULL))); NextAction::array(0, new NextAction("use deadly poison on off hand", 19.0f), NULL)));
// triggers.push_back(new TriggerNode( // triggers.push_back(new TriggerNode(
// "off hand weapon no enchant", // "off hand weapon no enchant",
// NextAction::array(0, new NextAction("use instant poison", 18.0f), NULL))); // NextAction::array(0, new NextAction("use instant poison", 18.0f), NULL)));
triggers.push_back(new TriggerNode("often", NextAction::array(0, new NextAction("unstealth", 30.0f), NULL))); triggers.push_back(new TriggerNode("often", NextAction::array(0, new NextAction("unstealth", 30.0f), NULL)));
} }

View File

@@ -1,96 +0,0 @@
/*
* Copyright (C) 2016+ AzerothCore <www.azerothcore.org>, released under GNU GPL v2 license, you may redistribute it
* and/or modify it under version 2 of the License, or (at your option), any later version.
*/
#include "CasterShamanStrategy.h"
#include "Playerbots.h"
class CasterShamanStrategyActionNodeFactory : public NamedObjectFactory<ActionNode>
{
public:
CasterShamanStrategyActionNodeFactory()
{
creators["magma totem"] = &magma_totem;
creators["totem of wrath"] = &totem_of_wrath;
}
private:
static ActionNode* magma_totem([[maybe_unused]] PlayerbotAI* botAI)
{
return new ActionNode("magma totem",
/*P*/ nullptr,
/*A*/ nullptr,
/*C*/ NextAction::array(0, new NextAction("fire nova"), nullptr));
}
static ActionNode* totem_of_wrath([[maybe_unused]] PlayerbotAI* botAI)
{
return new ActionNode("totem of wrath",
/*P*/ nullptr,
/*A*/ NextAction::array(0, new NextAction("flametongue totem"), nullptr),
/*C*/ nullptr);
}
};
CasterShamanStrategy::CasterShamanStrategy(PlayerbotAI* botAI) : GenericShamanStrategy(botAI)
{
actionNodeFactories.Add(new CasterShamanStrategyActionNodeFactory());
}
NextAction** CasterShamanStrategy::getDefaultActions()
{
return NextAction::array(0, new NextAction("lava burst", ACTION_DEFAULT + 0.2f),
new NextAction("lightning bolt", ACTION_DEFAULT + 0.1f),
// new NextAction("earth shock", ACTION_DEFAULT), // cast during movement
nullptr);
}
void CasterShamanStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
{
GenericShamanStrategy::InitTriggers(triggers);
// triggers.push_back(new TriggerNode("enemy out of spell", NextAction::array(0, new NextAction("reach spell",
// ACTION_NORMAL + 9), nullptr))); triggers.push_back(new TriggerNode("shaman weapon", NextAction::array(0, new
// NextAction("flametongue weapon", 23.0f), nullptr)));
triggers.push_back(new TriggerNode(
"enough mana", NextAction::array(0, new NextAction("chain lightning", ACTION_DEFAULT + 0.1f), nullptr)));
triggers.push_back(new TriggerNode("main hand weapon no imbue",
NextAction::array(0, new NextAction("flametongue weapon", 22.0f), nullptr)));
// triggers.push_back(new TriggerNode("searing totem", NextAction::array(0, new NextAction("searing totem", 19.0f),
// nullptr)));
triggers.push_back(
new TriggerNode("flame shock", NextAction::array(0, new NextAction("flame shock", 20.0f), nullptr)));
triggers.push_back(new TriggerNode("elemental mastery",
NextAction::array(0, new NextAction("elemental mastery", 27.0f), nullptr)));
// triggers.push_back(new TriggerNode("frost shock snare", NextAction::array(0, new NextAction("frost
// shock", 21.0f), nullptr)));
triggers.push_back(
new TriggerNode("no fire totem", NextAction::array(0,
new NextAction("totem of wrath", 15.0f),
new NextAction("searing totem", 6.0f),
nullptr)));
triggers.push_back(new TriggerNode("fire elemental totem",
NextAction::array(0, new NextAction("fire elemental totem", 32.0f), nullptr)));
triggers.push_back(
new TriggerNode("medium mana", NextAction::array(0, new NextAction("thunderstorm", ACTION_HIGH + 1), nullptr)));
triggers.push_back(new TriggerNode("enemy is close",
NextAction::array(0, new NextAction("thunderstorm", ACTION_HIGH + 1), nullptr)));
triggers.push_back(new TriggerNode("enemy too close for spell",
NextAction::array(0, new NextAction("flee", ACTION_MOVE + 9), nullptr)));
}
void CasterAoeShamanStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
{
triggers.push_back(
new TriggerNode("light aoe", NextAction::array(0, new NextAction("chain lightning", 25.0f), nullptr)));
triggers.push_back(
new TriggerNode("medium aoe", NextAction::array(0, new NextAction("fire nova", 24.0f), nullptr)));
}

View File

@@ -1,33 +0,0 @@
/*
* Copyright (C) 2016+ AzerothCore <www.azerothcore.org>, released under GNU GPL v2 license, you may redistribute it
* and/or modify it under version 2 of the License, or (at your option), any later version.
*/
#ifndef _PLAYERBOT_CASTSHAMANSTRATEGY_H
#define _PLAYERBOT_CASTSHAMANSTRATEGY_H
#include "GenericShamanStrategy.h"
class PlayerbotAI;
class CasterShamanStrategy : public GenericShamanStrategy
{
public:
CasterShamanStrategy(PlayerbotAI* botAI);
void InitTriggers(std::vector<TriggerNode*>& triggers) override;
NextAction** getDefaultActions() override;
std::string const getName() override { return "caster"; }
uint32 GetType() const override { return STRATEGY_TYPE_COMBAT | STRATEGY_TYPE_DPS | STRATEGY_TYPE_RANGED; }
};
class CasterAoeShamanStrategy : public CombatStrategy
{
public:
CasterAoeShamanStrategy(PlayerbotAI* botAI) : CombatStrategy(botAI) {}
void InitTriggers(std::vector<TriggerNode*>& triggers) override;
std::string const getName() override { return "caster aoe"; }
};
#endif

View File

@@ -0,0 +1,76 @@
/*
* Copyright (C) 2016+ AzerothCore <www.azerothcore.org>, released under GNU GPL v2 license, you may redistribute it
* and/or modify it under version 2 of the License, or (at your option), any later version.
*/
#include "ElementalShamanStrategy.h"
#include "Playerbots.h"
// ===== Action Node Factory =====
class ElementalShamanStrategyActionNodeFactory : public NamedObjectFactory<ActionNode>
{
public:
ElementalShamanStrategyActionNodeFactory()
{
creators["flame shock"] = &flame_shock;
creators["earth shock"] = &earth_shock;
creators["lava burst"] = &lava_burst;
creators["lightning bolt"] = &lightning_bolt;
creators["call of the elements"] = &call_of_the_elements;
creators["elemental mastery"] = &elemental_mastery;
creators["stoneclaw totem"] = &stoneclaw_totem;
creators["water shield"] = &water_shield;
creators["thunderstorm"] = &thunderstorm;
}
private:
static ActionNode* flame_shock(PlayerbotAI*) { return new ActionNode("flame shock", nullptr, nullptr, nullptr); }
static ActionNode* earth_shock(PlayerbotAI*) { return new ActionNode("earth shock", nullptr, nullptr, nullptr); }
static ActionNode* lava_burst(PlayerbotAI*) { return new ActionNode("lava burst", nullptr, nullptr, nullptr); }
static ActionNode* lightning_bolt(PlayerbotAI*) { return new ActionNode("lightning bolt", nullptr, nullptr, nullptr); }
static ActionNode* call_of_the_elements(PlayerbotAI*) { return new ActionNode("call of the elements", nullptr, nullptr, nullptr); }
static ActionNode* elemental_mastery(PlayerbotAI*) { return new ActionNode("elemental mastery", nullptr, nullptr, nullptr); }
static ActionNode* stoneclaw_totem(PlayerbotAI*) { return new ActionNode("stoneclaw totem", nullptr, nullptr, nullptr); }
static ActionNode* water_shield(PlayerbotAI*) { return new ActionNode("water shield", nullptr, nullptr, nullptr); }
static ActionNode* thunderstorm(PlayerbotAI*) { return new ActionNode("thunderstorm", nullptr, nullptr, nullptr); }
};
// ===== Single Target Strategy =====
ElementalShamanStrategy::ElementalShamanStrategy(PlayerbotAI* botAI) : GenericShamanStrategy(botAI)
{
actionNodeFactories.Add(new ElementalShamanStrategyActionNodeFactory());
}
// ===== Default Actions =====
NextAction** ElementalShamanStrategy::getDefaultActions()
{
return NextAction::array(0, new NextAction("lava burst", 5.2f),
new NextAction("lightning bolt", 5.0f),
nullptr);
}
// ===== Trigger Initialization ===
void ElementalShamanStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
{
GenericShamanStrategy::InitTriggers(triggers);
// Totem Triggers
triggers.push_back(new TriggerNode("call of the elements", NextAction::array(0, new NextAction("call of the elements", 60.0f), nullptr)));
triggers.push_back(new TriggerNode("low health", NextAction::array(0, new NextAction("stoneclaw totem", 40.0f), nullptr)));
// Cooldown Trigger
triggers.push_back(new TriggerNode("elemental mastery", NextAction::array(0, new NextAction("elemental mastery", 29.0f), nullptr)));
// Damage Triggers
triggers.push_back(new TriggerNode("earth shock execute", NextAction::array(0, new NextAction("earth shock", 5.5f), nullptr)));
triggers.push_back(new TriggerNode("flame shock", NextAction::array(0, new NextAction("flame shock", 5.3f), nullptr)));
// Mana Triggers
triggers.push_back(new TriggerNode("water shield", NextAction::array(0, new NextAction("water shield", 19.5f), nullptr)));
triggers.push_back(new TriggerNode("high mana", NextAction::array(0, new NextAction("thunderstorm", 19.0f), nullptr)));
// Range Triggers
triggers.push_back(new TriggerNode("enemy is close", NextAction::array(0, new NextAction("thunderstorm", 19.0f), nullptr)));
}

View File

@@ -0,0 +1,24 @@
/*
* Copyright (C) 2016+ AzerothCore <www.azerothcore.org>, released under GNU GPL v2 license, you may redistribute it
* and/or modify it under version 2 of the License, or (at your option), any later version.
*/
#ifndef _PLAYERBOT_ELEMENTALSHAMANSTRATEGY_H
#define _PLAYERBOT_ELEMENTALSHAMANSTRATEGY_H
#include "GenericShamanStrategy.h"
class PlayerbotAI;
class ElementalShamanStrategy : public GenericShamanStrategy
{
public:
ElementalShamanStrategy(PlayerbotAI* botAI);
void InitTriggers(std::vector<TriggerNode*>& triggers) override;
NextAction** getDefaultActions() override;
std::string const getName() override { return "ele"; }
uint32 GetType() const override { return STRATEGY_TYPE_COMBAT | STRATEGY_TYPE_DPS | STRATEGY_TYPE_RANGED; }
};
#endif

View File

@@ -0,0 +1,83 @@
/*
* Copyright (C) 2016+ AzerothCore <www.azerothcore.org>, released under GNU GPL v2 license, you may redistribute it
* and/or modify it under version 2 of the License, or (at your option), any later version.
*/
#include "EnhancementShamanStrategy.h"
#include "Playerbots.h"
// ===== Action Node Factory =====
class EnhancementShamanStrategyActionNodeFactory : public NamedObjectFactory<ActionNode>
{
public:
EnhancementShamanStrategyActionNodeFactory()
{
creators["stormstrike"] = &stormstrike;
creators["lava lash"] = &lava_lash;
creators["feral spirit"] = &feral_spirit;
creators["lightning bolt"] = &lightning_bolt;
creators["earth shock"] = &earth_shock;
creators["flame shock"] = &flame_shock;
creators["shamanistic rage"] = &shamanistic_rage;
creators["call of the elements"] = &call_of_the_elements;
creators["lightning shield"] = &lightning_shield;
}
private:
static ActionNode* stormstrike(PlayerbotAI*) { return new ActionNode("stormstrike", nullptr, nullptr, nullptr); }
static ActionNode* lava_lash([[maybe_unused]] PlayerbotAI* botAI)
{
return new ActionNode("lava lash",
/*P*/ nullptr,
/*A*/ NextAction::array(0, new NextAction("melee"), nullptr),
/*C*/ nullptr);
}
static ActionNode* feral_spirit(PlayerbotAI*) { return new ActionNode("feral spirit", nullptr, nullptr, nullptr); }
static ActionNode* lightning_bolt(PlayerbotAI*) { return new ActionNode("lightning bolt", nullptr, nullptr, nullptr); }
static ActionNode* earth_shock(PlayerbotAI*) { return new ActionNode("earth shock", nullptr, nullptr, nullptr); }
static ActionNode* flame_shock(PlayerbotAI*) { return new ActionNode("flame shock", nullptr, nullptr, nullptr); }
static ActionNode* shamanistic_rage(PlayerbotAI*) { return new ActionNode("shamanistic rage", nullptr, nullptr, nullptr); }
static ActionNode* call_of_the_elements(PlayerbotAI*) { return new ActionNode("call of the elements", nullptr, nullptr, nullptr); }
static ActionNode* lightning_shield(PlayerbotAI*) { return new ActionNode("lightning shield", nullptr, nullptr, nullptr); }
};
// ===== Single Target Strategy =====
EnhancementShamanStrategy::EnhancementShamanStrategy(PlayerbotAI* botAI) : GenericShamanStrategy(botAI)
{
actionNodeFactories.Add(new EnhancementShamanStrategyActionNodeFactory());
}
// ===== Default Actions =====
NextAction** EnhancementShamanStrategy::getDefaultActions()
{
return NextAction::array(0,
new NextAction("stormstrike", 5.5f),
new NextAction("feral spirit", 5.4f),
new NextAction("earth shock", 5.3f),
new NextAction("lava lash", 5.2f),
new NextAction("melee", 5.0f), NULL);
}
// ===== Trigger Initialization ===
void EnhancementShamanStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
{
GenericShamanStrategy::InitTriggers(triggers);
// Totem Trigger
triggers.push_back(new TriggerNode("call of the elements and enemy within melee", NextAction::array(0, new NextAction("call of the elements", 60.0f), nullptr)));
// Spirit Walk Trigger
triggers.push_back(new TriggerNode("spirit walk ready", NextAction::array(0, new NextAction("spirit walk", 50.0f), nullptr)));
// Damage Triggers
triggers.push_back(new TriggerNode("enemy out of melee", NextAction::array(0, new NextAction("reach melee", 40.0f), nullptr)));
triggers.push_back(new TriggerNode("maelstrom weapon 5", NextAction::array(0, new NextAction("lightning bolt", 20.0f), nullptr)));
triggers.push_back(new TriggerNode("maelstrom weapon 4", NextAction::array(0, new NextAction("lightning bolt", 19.5f), nullptr)));
triggers.push_back(new TriggerNode("flame shock", NextAction::array(0, new NextAction("flame shock", 19.0f), nullptr)));
triggers.push_back(new TriggerNode("lightning shield", NextAction::array(0, new NextAction("lightning shield", 18.5f), nullptr)));
// Health/Mana Triggers
triggers.push_back(new TriggerNode("medium mana", NextAction::array(0, new NextAction("shamanistic rage", 23.0f), nullptr)));
triggers.push_back(new TriggerNode("low health", NextAction::array(0, new NextAction("shamanistic rage", 23.0f), nullptr)));
}

View File

@@ -3,31 +3,22 @@
* and/or modify it under version 2 of the License, or (at your option), any later version. * and/or modify it under version 2 of the License, or (at your option), any later version.
*/ */
#ifndef _PLAYERBOT_MELEESHAMANSTRATEGY_H #ifndef _PLAYERBOT_ENHANCEMENTSHAMANSTRATEGY_H
#define _PLAYERBOT_MELEESHAMANSTRATEGY_H #define _PLAYERBOT_ENHANCEMENTSHAMANSTRATEGY_H
#include "GenericShamanStrategy.h" #include "GenericShamanStrategy.h"
class PlayerbotAI; class PlayerbotAI;
class MeleeShamanStrategy : public GenericShamanStrategy class EnhancementShamanStrategy : public GenericShamanStrategy
{ {
public: public:
MeleeShamanStrategy(PlayerbotAI* botAI); EnhancementShamanStrategy(PlayerbotAI* botAI);
void InitTriggers(std::vector<TriggerNode*>& triggers) override; void InitTriggers(std::vector<TriggerNode*>& triggers) override;
NextAction** getDefaultActions() override; NextAction** getDefaultActions() override;
std::string const getName() override { return "melee"; } std::string const getName() override { return "enh"; }
uint32 GetType() const override { return STRATEGY_TYPE_COMBAT | STRATEGY_TYPE_DPS | STRATEGY_TYPE_MELEE; } uint32 GetType() const override { return STRATEGY_TYPE_COMBAT | STRATEGY_TYPE_DPS | STRATEGY_TYPE_MELEE; }
}; };
class MeleeAoeShamanStrategy : public CombatStrategy
{
public:
MeleeAoeShamanStrategy(PlayerbotAI* botAI) : CombatStrategy(botAI) {}
void InitTriggers(std::vector<TriggerNode*>& triggers) override;
std::string const getName() override { return "melee aoe"; }
};
#endif #endif

View File

@@ -4,109 +4,95 @@
*/ */
#include "GenericShamanStrategy.h" #include "GenericShamanStrategy.h"
#include "HealShamanStrategy.h"
#include "Playerbots.h" #include "Playerbots.h"
#include "Strategy.h" #include "Strategy.h"
#include "AiFactory.h"
class GenericShamanStrategyActionNodeFactory : public NamedObjectFactory<ActionNode> class GenericShamanStrategyActionNodeFactory : public NamedObjectFactory<ActionNode>
{ {
public: public:
GenericShamanStrategyActionNodeFactory() GenericShamanStrategyActionNodeFactory()
{ {
creators["flametongue weapon"] = &flametongue_weapon; creators["totem of wrath"] = &totem_of_wrath;
creators["frostbrand weapon"] = &frostbrand_weapon; creators["flametongue totem"] = &flametongue_totem;
creators["windfury weapon"] = &windfury_weapon; creators["magma totem"] = &magma_totem;
creators["lesser healing wave"] = &lesser_healing_wave; creators["searing totem"] = &searing_totem;
creators["lesser healing wave on party"] = &lesser_healing_wave_on_party; creators["strength of earth totem"] = &strength_of_earth_totem;
creators["chain heal on party"] = &chain_heal; creators["stoneskin totem"] = &stoneskin_totem;
creators["riptide"] = &riptide; creators["cleansing totem"] = &cleansing_totem;
creators["riptide on party"] = &riptide_on_party; creators["mana spring totem"] = &mana_spring_totem;
creators["earth shock"] = &earth_shock; creators["healing stream totem"] = &healing_stream_totem;
creators["water shield"] = &water_shield; creators["wrath of air totem"] = &wrath_of_air_totem;
creators["windfury totem"] = &windfury_totem;
creators["grounding totem"] = &grounding_totem;
creators["wind shear"] = &wind_shear;
creators["purge"] = &purge;
} }
private: private:
static ActionNode* earth_shock([[maybe_unused]] PlayerbotAI* botAI) // Passthrough totems are set up so lower level shamans will still cast totems.
// Totem of Wrath -> Flametongue Totem -> Searing Totem
// Magma Totem -> Searing Totem
// Strength of Earth Totem -> Stoneskin Totem
// Cleansing Totem -> Mana Spring Totem
// Wrath of Air Totem -> Windfury Totem -> Grounding Totem
static ActionNode* totem_of_wrath([[maybe_unused]] PlayerbotAI* botAI)
{ {
return new ActionNode("earth shock", return new ActionNode("totem of wrath",
/*P*/ nullptr, /*P*/ nullptr,
/*A*/ NextAction::array(0, new NextAction("flame shock"), nullptr), /*A*/ NextAction::array(0, new NextAction("flametongue totem"), nullptr),
/*C*/ nullptr); /*C*/ nullptr);
} }
static ActionNode* flametongue_totem([[maybe_unused]] PlayerbotAI* botAI)
static ActionNode* flametongue_weapon([[maybe_unused]] PlayerbotAI* botAI)
{ {
return new ActionNode("flametongue weapon", return new ActionNode("flametongue totem",
/*P*/ nullptr, /*P*/ nullptr,
/*A*/ NextAction::array(0, new NextAction("rockbiter weapon"), nullptr), /*A*/ NextAction::array(0, new NextAction("searing totem"), nullptr),
/*C*/ nullptr); /*C*/ nullptr);
} }
static ActionNode* magma_totem([[maybe_unused]] PlayerbotAI* botAI)
static ActionNode* frostbrand_weapon([[maybe_unused]] PlayerbotAI* botAI)
{ {
return new ActionNode("frostbrand weapon", return new ActionNode("magma totem",
/*P*/ nullptr, /*P*/ nullptr,
/*A*/ NextAction::array(0, new NextAction("flametongue weapon"), nullptr), /*A*/ NextAction::array(0, new NextAction("searing totem"), nullptr),
/*C*/ nullptr); /*C*/ nullptr);
} }
static ActionNode* searing_totem(PlayerbotAI*) { return new ActionNode("searing totem", nullptr, nullptr, nullptr); }
static ActionNode* windfury_weapon([[maybe_unused]] PlayerbotAI* botAI) static ActionNode* strength_of_earth_totem([[maybe_unused]] PlayerbotAI* botAI)
{ {
return new ActionNode("windfury weapon", return new ActionNode("strength of earth totem",
/*P*/ nullptr, /*P*/ nullptr,
/*A*/ NextAction::array(0, new NextAction("flametongue weapon"), nullptr), /*A*/ NextAction::array(0, new NextAction("stoneskin totem"), nullptr),
/*C*/ nullptr); /*C*/ nullptr);
} }
static ActionNode* stoneskin_totem(PlayerbotAI*) { return new ActionNode("stoneskin totem", nullptr, nullptr, nullptr); }
static ActionNode* lesser_healing_wave([[maybe_unused]] PlayerbotAI* botAI) static ActionNode* cleansing_totem([[maybe_unused]] PlayerbotAI* botAI)
{ {
return new ActionNode("lesser healing wave", return new ActionNode("cleansing totem",
/*P*/ nullptr, /*P*/ nullptr,
/*A*/ NextAction::array(0, new NextAction("healing wave"), nullptr), /*A*/ NextAction::array(0, new NextAction("mana spring totem"), nullptr),
/*C*/ nullptr); /*C*/ nullptr);
} }
static ActionNode* mana_spring_totem(PlayerbotAI*) { return new ActionNode("mana spring totem", nullptr, nullptr, nullptr); }
static ActionNode* lesser_healing_wave_on_party([[maybe_unused]] PlayerbotAI* botAI) static ActionNode* healing_stream_totem(PlayerbotAI*) { return new ActionNode("healing stream totem", nullptr, nullptr, nullptr); }
static ActionNode* wrath_of_air_totem([[maybe_unused]] PlayerbotAI* botAI)
{ {
return new ActionNode("lesser healing wave on party", return new ActionNode("wrath of air totem",
/*P*/ nullptr, /*P*/ nullptr,
/*A*/ NextAction::array(0, new NextAction("healing wave on party"), nullptr), /*A*/ NextAction::array(0, new NextAction("windfury totem"), nullptr),
/*C*/ nullptr); /*C*/ nullptr);
} }
static ActionNode* windfury_totem([[maybe_unused]] PlayerbotAI* botAI)
static ActionNode* chain_heal([[maybe_unused]] PlayerbotAI* botAI)
{ {
return new ActionNode("chain heal on party", return new ActionNode("windfury totem",
/*P*/ nullptr, /*P*/ nullptr,
/*A*/ NextAction::array(0, new NextAction("lesser healing wave on party"), nullptr), /*A*/ NextAction::array(0, new NextAction("grounding totem"), nullptr),
/*C*/ nullptr); /*C*/ nullptr);
} }
static ActionNode* grounding_totem(PlayerbotAI*) { return new ActionNode("grounding totem", nullptr, nullptr, nullptr); }
static ActionNode* riptide([[maybe_unused]] PlayerbotAI* botAI) static ActionNode* wind_shear(PlayerbotAI*) { return new ActionNode("wind shear", nullptr, nullptr, nullptr); }
{ static ActionNode* purge(PlayerbotAI*) { return new ActionNode("purge", nullptr, nullptr, nullptr); }
return new ActionNode("riptide",
/*P*/ nullptr,
/*A*/ NextAction::array(0, new NextAction("healing wave"), nullptr),
/*C*/ nullptr);
}
static ActionNode* riptide_on_party([[maybe_unused]] PlayerbotAI* botAI)
{
return new ActionNode("riptide on party",
/*P*/ nullptr,
// /*A*/ NextAction::array(0, new NextAction("healing wave on party"), nullptr),
/*A*/ nullptr,
/*C*/ nullptr);
}
static ActionNode* water_shield([[maybe_unused]] PlayerbotAI* botAI)
{
return new ActionNode("water shield",
/*P*/ nullptr,
/*A*/ NextAction::array(0, new NextAction("lightning shield"), nullptr),
/*C*/ nullptr);
}
}; };
GenericShamanStrategy::GenericShamanStrategy(PlayerbotAI* botAI) : CombatStrategy(botAI) GenericShamanStrategy::GenericShamanStrategy(PlayerbotAI* botAI) : CombatStrategy(botAI)
@@ -118,75 +104,68 @@ void GenericShamanStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
{ {
CombatStrategy::InitTriggers(triggers); CombatStrategy::InitTriggers(triggers);
triggers.push_back( triggers.push_back(new TriggerNode("wind shear", NextAction::array(0, new NextAction("wind shear", 23.0f), nullptr)));
new TriggerNode("wind shear", NextAction::array(0, new NextAction("wind shear", 23.0f), nullptr))); triggers.push_back(new TriggerNode("wind shear on enemy healer", NextAction::array(0, new NextAction("wind shear on enemy healer", 23.0f), nullptr)));
triggers.push_back(
new TriggerNode("wind shear on enemy healer",
NextAction::array(0, new NextAction("wind shear on enemy healer", 23.0f), nullptr)));
triggers.push_back(new TriggerNode("purge", NextAction::array(0, new NextAction("purge", ACTION_DISPEL), nullptr))); triggers.push_back(new TriggerNode("purge", NextAction::array(0, new NextAction("purge", ACTION_DISPEL), nullptr)));
// triggers.push_back(new TriggerNode("party member medium health", NextAction::array(0, new NextAction("lesser triggers.push_back(new TriggerNode("medium mana", NextAction::array(0, new NextAction("mana potion", ACTION_DISPEL), nullptr)));
// healing wave on party", 25.0f), nullptr))); triggers.push_back(new TriggerNode("party member low health",
// NextAction::array(0, new NextAction("riptide on party", 25.0f), nullptr))); triggers.push_back(new
// TriggerNode("medium aoe heal", NextAction::array(0, new NextAction("chain heal on party", 27.0f), nullptr)));
// triggers.push_back(new TriggerNode("medium health", NextAction::array(0, new NextAction("lesser healing
// wave", 26.0f), nullptr))); triggers.push_back(new TriggerNode("low health", NextAction::array(0, new
// NextAction("riptide", 26.0f), nullptr)));
triggers.push_back(new TriggerNode("heroism", NextAction::array(0, new NextAction("heroism", 31.0f), nullptr)));
triggers.push_back(new TriggerNode("bloodlust", NextAction::array(0, new NextAction("bloodlust", 30.0f), nullptr)));
triggers.push_back(new TriggerNode("has pet", NextAction::array(0, new NextAction("toggle pet spell", 60.0f), nullptr)));
triggers.push_back(new TriggerNode("new pet", NextAction::array(0, new NextAction("set pet stance", 65.0f), nullptr))); triggers.push_back(new TriggerNode("new pet", NextAction::array(0, new NextAction("set pet stance", 65.0f), nullptr)));
} }
void ShamanBuffDpsStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
{
triggers.push_back(
new TriggerNode("lightning shield", NextAction::array(0, new NextAction("lightning shield", 22.0f), nullptr)));
}
void ShamanBuffManaStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
{
triggers.push_back(
new TriggerNode("water shield", NextAction::array(0, new NextAction("water shield", 22.0f), nullptr)));
}
void ShamanCureStrategy::InitTriggers(std::vector<TriggerNode*>& triggers) void ShamanCureStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
{ {
triggers.push_back( triggers.push_back(new TriggerNode("cure poison", NextAction::array(0, new NextAction("cure poison", 21.0f), nullptr)));
new TriggerNode("cure poison", NextAction::array(0, new NextAction("cure poison", 21.0f), nullptr))); triggers.push_back(new TriggerNode("party member cure poison", NextAction::array(0, new NextAction("cure poison on party", 21.0f), nullptr)));
triggers.push_back(new TriggerNode("party member cure poison", triggers.push_back(new TriggerNode("cleanse spirit poison", NextAction::array(0, new NextAction("cleanse spirit", 24.0f), nullptr)));
NextAction::array(0, new NextAction("cure poison on party", 21.0f), nullptr))); triggers.push_back(new TriggerNode("party member cleanse spirit poison", NextAction::array(0, new NextAction("cleanse spirit poison on party", 23.0f), nullptr)));
triggers.push_back(new TriggerNode("cleanse spirit poison", triggers.push_back(new TriggerNode("cure disease", NextAction::array(0, new NextAction("cure disease", 31.0f), nullptr)));
NextAction::array(0, new NextAction("cleanse spirit", 24.0f), nullptr))); triggers.push_back(new TriggerNode("party member cure disease", NextAction::array(0, new NextAction("cure disease on party", 30.0f), nullptr)));
triggers.push_back( triggers.push_back(new TriggerNode("cleanse spirit disease", NextAction::array(0, new NextAction("cleanse spirit", 24.0f), nullptr)));
new TriggerNode("party member cleanse spirit poison", triggers.push_back(new TriggerNode("party member cleanse spirit disease", NextAction::array(0, new NextAction("cleanse spirit disease on party", 23.0f), nullptr)));
NextAction::array(0, new NextAction("cleanse spirit poison on party", 23.0f), nullptr))); triggers.push_back(new TriggerNode("cleanse spirit curse", NextAction::array(0, new NextAction("cleanse spirit", 24.0f), nullptr)));
triggers.push_back( triggers.push_back(new TriggerNode("party member cleanse spirit curse", NextAction::array(0, new NextAction("cleanse spirit curse on party", 23.0f), nullptr)));
new TriggerNode("cure disease", NextAction::array(0, new NextAction("cure disease", 31.0f), nullptr)));
triggers.push_back(new TriggerNode("party member cure disease",
NextAction::array(0, new NextAction("cure disease on party", 30.0f), nullptr)));
triggers.push_back(new TriggerNode("cleanse spirit disease",
NextAction::array(0, new NextAction("cleanse spirit", 24.0f), nullptr)));
triggers.push_back(
new TriggerNode("party member cleanse spirit disease",
NextAction::array(0, new NextAction("cleanse spirit disease on party", 23.0f), nullptr)));
triggers.push_back(new TriggerNode("cleanse spirit curse",
NextAction::array(0, new NextAction("cleanse spirit", 24.0f), nullptr)));
triggers.push_back(
new TriggerNode("party member cleanse spirit curse",
NextAction::array(0, new NextAction("cleanse spirit curse on party", 23.0f), nullptr)));
} }
void ShamanHealerDpsStrategy::InitTriggers(std::vector<TriggerNode*>& triggers) void ShamanBoostStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
{ {
triggers.push_back( triggers.push_back(new TriggerNode("heroism", NextAction::array(0, new NextAction("heroism", 30.0f), nullptr)));
new TriggerNode("healer should attack", triggers.push_back(new TriggerNode("bloodlust", NextAction::array(0, new NextAction("bloodlust", 30.0f), nullptr)));
NextAction::array(0,
new NextAction("flame shock", ACTION_DEFAULT + 0.2f),
new NextAction("lava burst", ACTION_DEFAULT + 0.1f),
new NextAction("lightning bolt", ACTION_DEFAULT), nullptr)));
triggers.push_back( Player* bot = botAI->GetBot();
new TriggerNode("medium aoe and healer should attack", int tab = AiFactory::GetPlayerSpecTab(bot);
NextAction::array(0,
new NextAction("chain lightning", ACTION_DEFAULT + 0.3f), nullptr))); if (tab == 0) // Elemental
{
triggers.push_back(new TriggerNode("fire elemental totem", NextAction::array(0, new NextAction("fire elemental totem", 23.0f), nullptr)));
}
else if (tab == 1) // Enhancement
{
triggers.push_back(new TriggerNode("fire elemental totem", NextAction::array(0, new NextAction("fire elemental totem melee", 24.0f), nullptr)));
}
}
void ShamanAoeStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
{
Player* bot = botAI->GetBot();
int tab = AiFactory::GetPlayerSpecTab(bot);
if (tab == 0) // Elemental
{
triggers.push_back(new TriggerNode("medium aoe",NextAction::array(0, new NextAction("fire nova", 23.0f), nullptr)));
triggers.push_back(new TriggerNode("chain lightning no cd", NextAction::array(0, new NextAction("chain lightning", 5.6f), nullptr)));
}
else if (tab == 1) // Enhancement
{
triggers.push_back(new TriggerNode("medium aoe",NextAction::array(0,
new NextAction("magma totem", 24.0f),
new NextAction("fire nova", 23.0f), nullptr)));
triggers.push_back(new TriggerNode("maelstrom weapon 5 and medium aoe", NextAction::array(0, new NextAction("chain lightning", 22.0f), nullptr)));
triggers.push_back(new TriggerNode("maelstrom weapon 4 and medium aoe", NextAction::array(0, new NextAction("chain lightning", 21.0f), nullptr)));
triggers.push_back(new TriggerNode("enemy within melee", NextAction::array(0, new NextAction("fire nova", 5.1f), nullptr)));
}
else if (tab == 2) // Restoration
{
// Handled by "Healer DPS" Strategy
}
} }

View File

@@ -18,24 +18,6 @@ public:
void InitTriggers(std::vector<TriggerNode*>& triggers) override; void InitTriggers(std::vector<TriggerNode*>& triggers) override;
}; };
class ShamanBuffDpsStrategy : public Strategy
{
public:
ShamanBuffDpsStrategy(PlayerbotAI* botAI) : Strategy(botAI) {}
void InitTriggers(std::vector<TriggerNode*>& triggers) override;
std::string const getName() override { return "bdps"; }
};
class ShamanBuffManaStrategy : public Strategy
{
public:
ShamanBuffManaStrategy(PlayerbotAI* botAI) : Strategy(botAI) {}
void InitTriggers(std::vector<TriggerNode*>& triggers) override;
std::string const getName() override { return "bmana"; }
};
class ShamanCureStrategy : public Strategy class ShamanCureStrategy : public Strategy
{ {
public: public:
@@ -45,13 +27,22 @@ public:
std::string const getName() override { return "cure"; } std::string const getName() override { return "cure"; }
}; };
class ShamanHealerDpsStrategy : public Strategy class ShamanBoostStrategy : public Strategy
{ {
public: public:
ShamanHealerDpsStrategy(PlayerbotAI* botAI) : Strategy(botAI) {} ShamanBoostStrategy(PlayerbotAI* botAI) : Strategy(botAI) {}
void InitTriggers(std::vector<TriggerNode*>& triggers) override; void InitTriggers(std::vector<TriggerNode*>& triggers) override;
std::string const getName() override { return "healer dps"; } std::string const getName() override { return "boost"; }
};
class ShamanAoeStrategy : public CombatStrategy
{
public:
ShamanAoeStrategy(PlayerbotAI* botAI) : CombatStrategy(botAI) {}
void InitTriggers(std::vector<TriggerNode*>& triggers) override;
std::string const getName() override { return "aoe"; }
}; };
#endif #endif

View File

@@ -1,115 +0,0 @@
/*
* Copyright (C) 2016+ AzerothCore <www.azerothcore.org>, released under GNU GPL v2 license, you may redistribute it
* and/or modify it under version 2 of the License, or (at your option), any later version.
*/
#include "HealShamanStrategy.h"
#include "Playerbots.h"
class HealShamanStrategyActionNodeFactory : public NamedObjectFactory<ActionNode>
{
public:
HealShamanStrategyActionNodeFactory()
{
creators["earthliving weapon"] = &earthliving_weapon;
creators["mana tide totem"] = &mana_tide_totem;
}
private:
static ActionNode* earthliving_weapon([[maybe_unused]] PlayerbotAI* botAI)
{
return new ActionNode("earthliving weapon",
/*P*/ nullptr,
/*A*/ NextAction::array(0, new NextAction("flametongue weapon"), nullptr),
/*C*/ nullptr);
}
static ActionNode* mana_tide_totem([[maybe_unused]] PlayerbotAI* botAI)
{
return new ActionNode("mana tide totem",
/*P*/ nullptr,
/*A*/ NextAction::array(0, new NextAction("mana potion"), nullptr),
/*C*/ nullptr);
}
};
HealShamanStrategy::HealShamanStrategy(PlayerbotAI* botAI) : GenericShamanStrategy(botAI)
{
actionNodeFactories.Add(new HealShamanStrategyActionNodeFactory());
}
void HealShamanStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
{
GenericShamanStrategy::InitTriggers(triggers);
// triggers.push_back(new TriggerNode("enemy out of spell", NextAction::array(0, new NextAction("reach spell",
// ACTION_NORMAL + 9), nullptr))); triggers.push_back(new TriggerNode("shaman weapon", NextAction::array(0, new
// NextAction("earthliving weapon", 22.0f), nullptr)));
triggers.push_back(new TriggerNode("main hand weapon no imbue",
NextAction::array(0, new NextAction("earthliving weapon", 22.0f), nullptr)));
triggers.push_back(new TriggerNode(
"group heal setting",
NextAction::array(0, new NextAction("riptide on party", 27.0f), new NextAction("chain heal on party", 26.0f), NULL)));
triggers.push_back(new TriggerNode(
"party member critical health",
NextAction::array(0, new NextAction("riptide on party", 25.0f), new NextAction("healing wave on party", 24.0f),
new NextAction("lesser healing wave on party", 23.0f), nullptr)));
triggers.push_back(new TriggerNode(
"party member low health",
NextAction::array(0, new NextAction("riptide on party", 19.0f), new NextAction("healing wave on party", 18.0f),
new NextAction("lesser healing wave on party", 17.0f), nullptr)));
triggers.push_back(new TriggerNode(
"party member medium health",
NextAction::array(0, new NextAction("riptide on party", 16.0f), new NextAction("healing wave on party", 15.0f),
new NextAction("lesser healing wave on party", 14.0f), nullptr)));
triggers.push_back(
new TriggerNode("party member almost full health",
NextAction::array(0, new NextAction("riptide on party", 12.0f),
new NextAction("lesser healing wave on party", 11.0f), nullptr)));
triggers.push_back(
new TriggerNode("party member cleanse spirit poison",
NextAction::array(0, new NextAction("cleanse spirit poison on party", ACTION_DISPEL + 2),
new NextAction("cleansing totem", ACTION_DISPEL + 2), NULL)));
triggers.push_back(
new TriggerNode("party member cleanse spirit disease",
NextAction::array(0, new NextAction("cleanse spirit disease on party", ACTION_DISPEL + 2),
new NextAction("cleansing totem", ACTION_DISPEL + 1), NULL)));
triggers.push_back(new TriggerNode(
"party member cleanse spirit curse",
NextAction::array(0, new NextAction("cleanse spirit curse on party", ACTION_DISPEL + 2), NULL)));
// triggers.push_back(new TriggerNode(
// "no fire totem",
// NextAction::array(0, new NextAction("flametongue totem", 10.0f), NULL)));
// triggers.push_back(new TriggerNode(
// "no water totem",
// NextAction::array(0, new NextAction("healing stream totem", 13.0f), NULL)));
triggers.push_back(
new TriggerNode("earth shield on main tank",
NextAction::array(0, new NextAction("earth shield on main tank", ACTION_HIGH + 7), NULL)));
triggers.push_back(new TriggerNode("enemy too close for spell",
NextAction::array(0, new NextAction("flee", ACTION_MOVE + 9), nullptr)));
triggers.push_back(
new TriggerNode("medium mana", NextAction::array(0, new NextAction("mana tide totem", ACTION_HIGH + 5), NULL)));
triggers.push_back(
new TriggerNode("no fire totem", NextAction::array(0, new NextAction("flametongue totem", 7.0f),
new NextAction("searing totem", 6.0f), nullptr)));
triggers.push_back(new TriggerNode("fire elemental totem",
NextAction::array(0, new NextAction("fire elemental totem", 32.0f), nullptr)));
triggers.push_back(new TriggerNode(
"party member to heal out of spell range",
NextAction::array(0, new NextAction("reach party member to heal", ACTION_CRITICAL_HEAL + 1), nullptr)));
}

View File

@@ -1,24 +0,0 @@
/*
* Copyright (C) 2016+ AzerothCore <www.azerothcore.org>, released under GNU GPL v2 license, you may redistribute it
* and/or modify it under version 2 of the License, or (at your option), any later version.
*/
#ifndef _PLAYERBOT_HEALSHAMANSTRATEGY_H
#define _PLAYERBOT_HEALSHAMANSTRATEGY_H
#include "GenericShamanStrategy.h"
#include "Strategy.h"
class PlayerbotAI;
class HealShamanStrategy : public GenericShamanStrategy
{
public:
HealShamanStrategy(PlayerbotAI* botAI);
void InitTriggers(std::vector<TriggerNode*>& triggers) override;
std::string const getName() override { return "heal"; }
uint32 GetType() const override { return STRATEGY_TYPE_RANGED | STRATEGY_TYPE_HEAL; }
};
#endif

View File

@@ -1,105 +0,0 @@
/*
* Copyright (C) 2016+ AzerothCore <www.azerothcore.org>, released under GNU GPL v2 license, you may redistribute it
* and/or modify it under version 2 of the License, or (at your option), any later version.
*/
#include "MeleeShamanStrategy.h"
#include "Playerbots.h"
class MeleeShamanStrategyActionNodeFactory : public NamedObjectFactory<ActionNode>
{
public:
MeleeShamanStrategyActionNodeFactory()
{
creators["stormstrike"] = &stormstrike;
creators["lava lash"] = &lava_lash;
creators["magma totem"] = &magma_totem;
}
private:
static ActionNode* stormstrike([[maybe_unused]] PlayerbotAI* botAI)
{
return new ActionNode("stormstrike",
/*P*/ nullptr,
// /*A*/ NextAction::array(0, new NextAction("lava lash"), nullptr),
nullptr,
/*C*/ nullptr);
}
static ActionNode* lava_lash([[maybe_unused]] PlayerbotAI* botAI)
{
return new ActionNode("lava lash",
/*P*/ nullptr,
/*A*/ NextAction::array(0, new NextAction("melee"), nullptr),
/*C*/ nullptr);
}
static ActionNode* magma_totem([[maybe_unused]] PlayerbotAI* botAI)
{
return new ActionNode("magma totem",
/*P*/ NULL,
/*A*/ NextAction::array(0, new NextAction("searing totem"), NULL),
/*C*/ NULL);
}
};
MeleeShamanStrategy::MeleeShamanStrategy(PlayerbotAI* botAI) : GenericShamanStrategy(botAI)
{
actionNodeFactories.Add(new MeleeShamanStrategyActionNodeFactory());
}
NextAction** MeleeShamanStrategy::getDefaultActions()
{
return NextAction::array(
0, new NextAction("stormstrike", ACTION_DEFAULT + 0.5f), new NextAction("earth shock", ACTION_DEFAULT + 0.4f),
new NextAction("feral spirit", ACTION_DEFAULT + 0.3f), new NextAction("fire nova", ACTION_DEFAULT + 0.2f),
new NextAction("lava lash", ACTION_DEFAULT + 0.1f), new NextAction("melee", ACTION_DEFAULT), NULL);
}
void MeleeShamanStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
{
GenericShamanStrategy::InitTriggers(triggers);
// triggers.push_back(new TriggerNode("shaman weapon", NextAction::array(0, new NextAction("flametongue
// weapon", 22.0f), nullptr)));
triggers.push_back(new TriggerNode("main hand weapon no imbue",
NextAction::array(0, new NextAction("windfury weapon", 22.0f), nullptr)));
triggers.push_back(new TriggerNode("off hand weapon no imbue",
NextAction::array(0, new NextAction("flametongue weapon", 21.0f), nullptr)));
// triggers.push_back(new TriggerNode("searing totem", NextAction::array(0, new NextAction("reach melee", 22.0f),
// new NextAction("searing totem", 22.0f), nullptr)));
triggers.push_back(
new TriggerNode("flame shock", NextAction::array(0, new NextAction("flame shock", 20.0f), nullptr)));
triggers.push_back(
new TriggerNode("maelstrom weapon 4", NextAction::array(0, new NextAction("lightning bolt", 25.0f), nullptr)));
triggers.push_back(new TriggerNode(
"medium aoe", NextAction::array(0, new NextAction("strength of earth totem", ACTION_LIGHT_HEAL), nullptr)));
triggers.push_back(new TriggerNode(
"enemy out of melee", NextAction::array(0, new NextAction("reach melee", ACTION_HIGH + 1), nullptr)));
triggers.push_back(new TriggerNode(
"no fire totem",
NextAction::array(0, new NextAction("reach melee", 23.0f), new NextAction("magma totem", 22.0f), nullptr)));
triggers.push_back(new TriggerNode(
"fire elemental totem", NextAction::array(0, new NextAction("fire elemental totem melee", 32.0f), nullptr)));
triggers.push_back(
new TriggerNode("no air totem", NextAction::array(0, new NextAction("windfury totem", 20.0f), nullptr)));
triggers.push_back(
new TriggerNode("medium mana", NextAction::array(0, new NextAction("shamanistic rage", 23.0f), nullptr)));
triggers.push_back(
new TriggerNode("low health", NextAction::array(0, new NextAction("shamanistic rage", 23.0f), nullptr)));
}
void MeleeAoeShamanStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
{
// triggers.push_back(new TriggerNode("magma totem", NextAction::array(0, new NextAction("magma totem", 26.0f),
// nullptr)));
triggers.push_back(
new TriggerNode("medium aoe", NextAction::array(0, new NextAction("fire nova", 25.0f), nullptr)));
}

View File

@@ -0,0 +1,124 @@
/*
* Copyright (C) 2016+ AzerothCore <www.azerothcore.org>, released under GNU GPL v2 license, you may redistribute it
* and/or modify it under version 2 of the License, or (at your option), any later version.
*/
#include "RestoShamanStrategy.h"
#include "Playerbots.h"
// ===== Action Node Factory =====
class RestoShamanStrategyActionNodeFactory : public NamedObjectFactory<ActionNode>
{
public:
RestoShamanStrategyActionNodeFactory()
{
creators["mana tide totem"] = &mana_tide_totem;
creators["call of the elements"] = &call_of_the_elements;
creators["stoneclaw totem"] = &stoneclaw_totem;
creators["riptide on party"] = &riptide_on_party;
creators["chain heal on party"] = &chain_heal_on_party;
creators["healing wave on party"] = &healing_wave_on_party;
creators["lesser healing wave on party"] = &lesser_healing_wave_on_party;
creators["earth shield on main tank"] = &earth_shield_on_main_tank;
creators["cleanse spirit poison on party"] = &cleanse_spirit_poison_on_party;
creators["cleanse spirit disease on party"] = &cleanse_spirit_disease_on_party;
creators["cleanse spirit curse on party"] = &cleanse_spirit_curse_on_party;
creators["cleansing totem"] = &cleansing_totem;
creators["water shield"] = &water_shield;
creators["flame shock"] = &flame_shock;
creators["lava burst"] = &lava_burst;
creators["lightning bolt"] = &lightning_bolt;
creators["chain lightning"] = &chain_lightning;
}
private:
static ActionNode* mana_tide_totem([[maybe_unused]] PlayerbotAI* botAI)
{
return new ActionNode("mana tide totem",
/*P*/ nullptr,
/*A*/ NextAction::array(0, new NextAction("mana potion"), nullptr),
/*C*/ nullptr);
}
static ActionNode* call_of_the_elements(PlayerbotAI*) { return new ActionNode("call of the elements", nullptr, nullptr, nullptr); }
static ActionNode* stoneclaw_totem(PlayerbotAI*) { return new ActionNode("stoneclaw totem", nullptr, nullptr, nullptr); }
static ActionNode* riptide_on_party(PlayerbotAI*) { return new ActionNode("riptide on party", nullptr, nullptr, nullptr); }
static ActionNode* chain_heal_on_party(PlayerbotAI*) { return new ActionNode("chain heal on party", nullptr, nullptr, nullptr); }
static ActionNode* healing_wave_on_party(PlayerbotAI*) { return new ActionNode("healing wave on party", nullptr, nullptr, nullptr); }
static ActionNode* lesser_healing_wave_on_party(PlayerbotAI*) { return new ActionNode("lesser healing wave on party", nullptr, nullptr, nullptr); }
static ActionNode* earth_shield_on_main_tank(PlayerbotAI*) { return new ActionNode("earth shield on main tank", nullptr, nullptr, nullptr); }
static ActionNode* cleanse_spirit_poison_on_party(PlayerbotAI*) { return new ActionNode("cleanse spirit poison on party", nullptr, nullptr, nullptr); }
static ActionNode* cleanse_spirit_disease_on_party(PlayerbotAI*) { return new ActionNode("cleanse spirit disease on party", nullptr, nullptr, nullptr); }
static ActionNode* cleanse_spirit_curse_on_party(PlayerbotAI*) { return new ActionNode("cleanse spirit curse on party", nullptr, nullptr, nullptr); }
static ActionNode* cleansing_totem(PlayerbotAI*) { return new ActionNode("cleansing totem", nullptr, nullptr, nullptr); }
static ActionNode* water_shield(PlayerbotAI*) { return new ActionNode("water shield", nullptr, nullptr, nullptr); }
static ActionNode* flame_shock(PlayerbotAI*) { return new ActionNode("flame shock", nullptr, nullptr, nullptr); }
static ActionNode* lava_burst(PlayerbotAI*) { return new ActionNode("lava burst", nullptr, nullptr, nullptr); }
static ActionNode* lightning_bolt(PlayerbotAI*) { return new ActionNode("lightning bolt", nullptr, nullptr, nullptr); }
static ActionNode* chain_lightning(PlayerbotAI*) { return new ActionNode("chain lightning", nullptr, nullptr, nullptr); }
};
// ===== Single Target Strategy =====
RestoShamanStrategy::RestoShamanStrategy(PlayerbotAI* botAI) : GenericShamanStrategy(botAI)
{
actionNodeFactories.Add(new RestoShamanStrategyActionNodeFactory());
}
// ===== Trigger Initialization ===
void RestoShamanStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
{
GenericShamanStrategy::InitTriggers(triggers);
// Totem Triggers
triggers.push_back(new TriggerNode("call of the elements", NextAction::array(0, new NextAction("call of the elements", 60.0f), nullptr)));
triggers.push_back(new TriggerNode("low health", NextAction::array(0, new NextAction("stoneclaw totem", 40.0f), nullptr)));
triggers.push_back(new TriggerNode("medium mana", NextAction::array(0, new NextAction("mana tide totem", ACTION_HIGH + 5), NULL)));
// Healing Triggers
triggers.push_back(new TriggerNode("group heal setting", NextAction::array(0,
new NextAction("riptide on party", 27.0f),
new NextAction("chain heal on party", 26.0f), NULL)));
triggers.push_back(new TriggerNode("party member critical health", NextAction::array(0,
new NextAction("riptide on party", 25.0f),
new NextAction("healing wave on party", 24.0f),
new NextAction("lesser healing wave on party", 23.0f), nullptr)));
triggers.push_back(new TriggerNode("party member low health", NextAction::array(0,
new NextAction("riptide on party", 19.0f),
new NextAction("healing wave on party", 18.0f),
new NextAction("lesser healing wave on party", 17.0f), nullptr)));
triggers.push_back(new TriggerNode("party member medium health", NextAction::array(0,
new NextAction("riptide on party", 16.0f),
new NextAction("healing wave on party", 15.0f),
new NextAction("lesser healing wave on party", 14.0f), nullptr)));
triggers.push_back(new TriggerNode("party member almost full health", NextAction::array(0,
new NextAction("riptide on party", 12.0f),
new NextAction("lesser healing wave on party", 11.0f), nullptr)));
triggers.push_back(new TriggerNode("earth shield on main tank", NextAction::array(0, new NextAction("earth shield on main tank", ACTION_HIGH + 7), NULL)));
// Dispel Triggers
triggers.push_back(new TriggerNode("party member cleanse spirit poison", NextAction::array(0, new NextAction("cleanse spirit poison on party", ACTION_DISPEL + 2), nullptr)));
triggers.push_back(new TriggerNode("party member cleanse spirit disease", NextAction::array(0, new NextAction("cleanse spirit disease on party", ACTION_DISPEL + 2), nullptr)));
triggers.push_back(new TriggerNode("party member cleanse spirit curse",NextAction::array(0, new NextAction("cleanse spirit curse on party", ACTION_DISPEL + 2), NULL)));
// Range/Mana Triggers
triggers.push_back(new TriggerNode("enemy too close for spell", NextAction::array(0, new NextAction("flee", ACTION_MOVE + 9), nullptr)));
triggers.push_back(new TriggerNode("party member to heal out of spell range", NextAction::array(0, new NextAction("reach party member to heal", ACTION_CRITICAL_HEAL + 1), nullptr)));
triggers.push_back(new TriggerNode("water shield", NextAction::array(0, new NextAction("water shield", 19.5f), nullptr)));
}
void ShamanHealerDpsStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
{
triggers.push_back(new TriggerNode("healer should attack",
NextAction::array(0, new NextAction("flame shock", ACTION_DEFAULT + 0.2f),
new NextAction("lava burst", ACTION_DEFAULT + 0.1f),
new NextAction("lightning bolt", ACTION_DEFAULT), nullptr)));
triggers.push_back(
new TriggerNode("medium aoe and healer should attack",
NextAction::array(0, new NextAction("chain lightning", ACTION_DEFAULT + 0.3f), nullptr)));
}

View File

@@ -0,0 +1,33 @@
/*
* Copyright (C) 2016+ AzerothCore <www.azerothcore.org>, released under GNU GPL v2 license, you may redistribute it
* and/or modify it under version 2 of the License, or (at your option), any later version.
*/
#ifndef _PLAYERBOT_RESTOSHAMANSTRATEGY_H
#define _PLAYERBOT_RESTOSHAMANSTRATEGY_H
#include "GenericShamanStrategy.h"
#include "Strategy.h"
class PlayerbotAI;
class RestoShamanStrategy : public GenericShamanStrategy
{
public:
RestoShamanStrategy(PlayerbotAI* botAI);
void InitTriggers(std::vector<TriggerNode*>& triggers) override;
std::string const getName() override { return "resto"; }
uint32 GetType() const override { return STRATEGY_TYPE_RANGED | STRATEGY_TYPE_HEAL; }
};
class ShamanHealerDpsStrategy : public Strategy
{
public:
ShamanHealerDpsStrategy(PlayerbotAI* botAI) : Strategy(botAI) {}
void InitTriggers(std::vector<TriggerNode*>& triggers) override;
std::string const getName() override { return "healer dps"; }
};
#endif

View File

@@ -4,42 +4,17 @@
*/ */
#include "ShamanActions.h" #include "ShamanActions.h"
#include "TotemsShamanStrategy.h"
#include "Playerbots.h" #include "Playerbots.h"
#include "Totem.h" #include "Totem.h"
#include "PlayerbotAI.h"
#include "Action.h"
bool CastTotemAction::isUseful() bool CastTotemAction::isUseful()
{ {
if (needLifeTime > 0.1f && AI_VALUE(uint8, "attacker count") < 3) return CastBuffSpellAction::isUseful()
{ && !AI_VALUE2(bool, "has totem", name)
Unit* target = AI_VALUE(Unit*, "current target"); && !botAI->HasAura(buff, bot);
if (!target)
{
return false;
}
float dps = AI_VALUE(float, "estimated group dps");
if (target->GetHealth() / dps < needLifeTime)
{
return false;
}
}
return CastBuffSpellAction::isUseful() && !AI_VALUE2(bool, "has totem", name) && !botAI->HasAura(buff, bot);
}
bool CastManaSpringTotemAction::isUseful()
{
return CastTotemAction::isUseful() && !AI_VALUE2(bool, "has totem", "healing stream totem");
}
bool CastFlametongueTotemAction::isUseful()
{
return CastTotemAction::isUseful() && !AI_VALUE2(bool, "has totem", "magma totem") &&
!botAI->HasAura("totem of wrath", bot);
}
bool CastSearingTotemAction::isUseful()
{
return CastTotemAction::isUseful() && !AI_VALUE2(bool, "has totem", "flametongue totem");
} }
bool CastMagmaTotemAction::isUseful() { bool CastMagmaTotemAction::isUseful() {
@@ -68,3 +43,69 @@ bool CastCleansingTotemAction::isUseful()
{ {
return CastTotemAction::isUseful() && !AI_VALUE2(bool, "has totem", "mana tide totem"); return CastTotemAction::isUseful() && !AI_VALUE2(bool, "has totem", "mana tide totem");
} }
// Will only cast Stoneclaw Totem if low on health and not in a group
bool CastStoneclawTotemAction::isUseful() { return !botAI->GetBot()->GetGroup(); }
// Will only cast Lava Burst if Flame Shock is on the target
bool CastLavaBurstAction::isUseful()
{
Unit* target = GetTarget();
if (!target)
return false;
static const uint32 FLAME_SHOCK_IDS[] = {8050, 8052, 8053, 10447, 10448, 29228, 25457, 49232, 49233};
ObjectGuid botGuid = botAI->GetBot()->GetGUID();
for (uint32 spellId : FLAME_SHOCK_IDS)
{
if (target->HasAura(spellId, botGuid))
return true;
}
return false;
}
// Logic for making a guardian (spirit wolf) use a spell (spirit walk)
// There is no existing code for guardians casting spells in the AC/Playerbots repo.
bool CastSpiritWalkAction::Execute(Event event)
{
Player* bot = botAI->GetBot();
constexpr uint32 SPIRIT_WOLF = 29264;
constexpr uint32 SPIRIT_WALK_SPELL = 58875;
for (Unit* unit : bot->m_Controlled)
{
if (unit->GetEntry() == SPIRIT_WOLF)
{
if (unit->HasSpell(SPIRIT_WALK_SPELL))
{
unit->CastSpell(unit, SPIRIT_WALK_SPELL, false);
return true;
}
}
}
return false;
}
// Set Strategy Assigned Totems (Actions) - First, it checks
// the highest-rank spell the bot knows for each totem type,
// then adds it to the Call of the Elements bar.
bool SetTotemAction::Execute(Event event)
{
size_t spellIdsCount = sizeof(totemSpellIds) / sizeof(uint32);
uint32 totemSpell = 0;
for (int i = spellIdsCount - 1; i >= 0; --i)
{
if (bot->HasSpell(totemSpellIds[i]))
{
totemSpell = totemSpellIds[i];
break;
}
}
if (!totemSpell)
return false;
bot->addActionButton(actionButtonId, totemSpell, ACTION_BUTTON_SPELL);
return true;
}

View File

@@ -9,9 +9,286 @@
#include "GenericSpellActions.h" #include "GenericSpellActions.h"
#include "Playerbots.h" #include "Playerbots.h"
#include "SharedDefines.h" #include "SharedDefines.h"
#include "TotemsShamanStrategy.h"
class PlayerbotAI; class PlayerbotAI;
// Buff and Out of Combat Actions
class CastWaterShieldAction : public CastBuffSpellAction
{
public:
CastWaterShieldAction(PlayerbotAI* botAI) : CastBuffSpellAction(botAI, "water shield") {}
};
class CastLightningShieldAction : public CastBuffSpellAction
{
public:
CastLightningShieldAction(PlayerbotAI* botAI) : CastBuffSpellAction(botAI, "lightning shield") {}
};
class CastEarthlivingWeaponAction : public CastEnchantItemAction
{
public:
CastEarthlivingWeaponAction(PlayerbotAI* botAI) : CastEnchantItemAction(botAI, "earthliving weapon") {}
};
class CastRockbiterWeaponAction : public CastEnchantItemAction
{
public:
CastRockbiterWeaponAction(PlayerbotAI* botAI) : CastEnchantItemAction(botAI, "rockbiter weapon") {}
};
class CastFlametongueWeaponAction : public CastEnchantItemAction
{
public:
CastFlametongueWeaponAction(PlayerbotAI* botAI) : CastEnchantItemAction(botAI, "flametongue weapon") {}
};
class CastFrostbrandWeaponAction : public CastEnchantItemAction
{
public:
CastFrostbrandWeaponAction(PlayerbotAI* botAI) : CastEnchantItemAction(botAI, "frostbrand weapon") {}
};
class CastWindfuryWeaponAction : public CastEnchantItemAction
{
public:
CastWindfuryWeaponAction(PlayerbotAI* botAI) : CastEnchantItemAction(botAI, "windfury weapon") {}
};
class CastAncestralSpiritAction : public ResurrectPartyMemberAction
{
public:
CastAncestralSpiritAction(PlayerbotAI* botAI) : ResurrectPartyMemberAction(botAI, "ancestral spirit") {}
};
class CastWaterBreathingAction : public CastBuffSpellAction
{
public:
CastWaterBreathingAction(PlayerbotAI* botAI) : CastBuffSpellAction(botAI, "water breathing") {}
};
class CastWaterWalkingAction : public CastBuffSpellAction
{
public:
CastWaterWalkingAction(PlayerbotAI* botAI) : CastBuffSpellAction(botAI, "water walking") {}
};
class CastWaterBreathingOnPartyAction : public BuffOnPartyAction
{
public:
CastWaterBreathingOnPartyAction(PlayerbotAI* botAI) : BuffOnPartyAction(botAI, "water breathing") {}
};
class CastWaterWalkingOnPartyAction : public BuffOnPartyAction
{
public:
CastWaterWalkingOnPartyAction(PlayerbotAI* botAI) : BuffOnPartyAction(botAI, "water walking") {}
};
// Boost Actions
class CastHeroismAction : public CastBuffSpellAction
{
public:
CastHeroismAction(PlayerbotAI* botAI) : CastBuffSpellAction(botAI, "heroism") {}
};
class CastBloodlustAction : public CastBuffSpellAction
{
public:
CastBloodlustAction(PlayerbotAI* botAI) : CastBuffSpellAction(botAI, "bloodlust") {}
};
class CastElementalMasteryAction : public CastBuffSpellAction
{
public:
CastElementalMasteryAction(PlayerbotAI* botAI) : CastBuffSpellAction(botAI, "elemental mastery") {}
};
class CastShamanisticRageAction : public CastBuffSpellAction
{
public:
CastShamanisticRageAction(PlayerbotAI* ai) : CastBuffSpellAction(ai, "shamanistic rage") {}
};
class CastFeralSpiritAction : public CastSpellAction
{
public:
CastFeralSpiritAction(PlayerbotAI* ai) : CastSpellAction(ai, "feral spirit") {}
};
class CastSpiritWalkAction : public Action
{
public:
CastSpiritWalkAction(PlayerbotAI* botAI) : Action(botAI, "spirit walk") {}
bool Execute(Event event) override;
};
// CC, Interrupt, and Dispel Actions
class CastWindShearAction : public CastSpellAction
{
public:
CastWindShearAction(PlayerbotAI* botAI) : CastSpellAction(botAI, "wind shear") {}
};
class CastWindShearOnEnemyHealerAction : public CastSpellOnEnemyHealerAction
{
public:
CastWindShearOnEnemyHealerAction(PlayerbotAI* botAI) : CastSpellOnEnemyHealerAction(botAI, "wind shear") {}
};
class CastPurgeAction : public CastSpellAction
{
public:
CastPurgeAction(PlayerbotAI* botAI) : CastSpellAction(botAI, "purge") {}
};
class CastCleanseSpiritAction : public CastCureSpellAction
{
public:
CastCleanseSpiritAction(PlayerbotAI* botAI) : CastCureSpellAction(botAI, "cleanse spirit") {}
};
class CastCleanseSpiritPoisonOnPartyAction : public CurePartyMemberAction
{
public:
CastCleanseSpiritPoisonOnPartyAction(PlayerbotAI* botAI)
: CurePartyMemberAction(botAI, "cleanse spirit", DISPEL_POISON)
{
}
std::string const getName() override { return "cleanse spirit poison on party"; }
};
class CastCleanseSpiritCurseOnPartyAction : public CurePartyMemberAction
{
public:
CastCleanseSpiritCurseOnPartyAction(PlayerbotAI* botAI)
: CurePartyMemberAction(botAI, "cleanse spirit", DISPEL_CURSE)
{
}
std::string const getName() override { return "cleanse spirit curse on party"; }
};
class CastCleanseSpiritDiseaseOnPartyAction : public CurePartyMemberAction
{
public:
CastCleanseSpiritDiseaseOnPartyAction(PlayerbotAI* botAI)
: CurePartyMemberAction(botAI, "cleanse spirit", DISPEL_DISEASE)
{
}
std::string const getName() override { return "cleanse spirit disease on party"; }
};
class CastCurePoisonActionSham : public CastCureSpellAction
{
public:
CastCurePoisonActionSham(PlayerbotAI* botAI) : CastCureSpellAction(botAI, "cure poison") {}
};
class CastCurePoisonOnPartyActionSham : public CurePartyMemberAction
{
public:
CastCurePoisonOnPartyActionSham(PlayerbotAI* botAI) : CurePartyMemberAction(botAI, "cure poison", DISPEL_POISON) {}
std::string const getName() override { return "cure poison on party"; }
};
class CastCureDiseaseActionSham : public CastCureSpellAction
{
public:
CastCureDiseaseActionSham(PlayerbotAI* botAI) : CastCureSpellAction(botAI, "cure disease") {}
};
class CastCureDiseaseOnPartyActionSham : public CurePartyMemberAction
{
public:
CastCureDiseaseOnPartyActionSham(PlayerbotAI* botAI) : CurePartyMemberAction(botAI, "cure disease", DISPEL_DISEASE)
{
}
std::string const getName() override { return "cure disease on party"; }
};
// Damage and Debuff Actions
class CastFireNovaAction : public CastMeleeSpellAction
{
public:
CastFireNovaAction(PlayerbotAI* botAI) : CastMeleeSpellAction(botAI, "fire nova") {}
bool isUseful() override;
};
class CastStormstrikeAction : public CastMeleeSpellAction
{
public:
CastStormstrikeAction(PlayerbotAI* botAI) : CastMeleeSpellAction(botAI, "stormstrike") {}
};
class CastLavaLashAction : public CastMeleeSpellAction
{
public:
CastLavaLashAction(PlayerbotAI* botAI) : CastMeleeSpellAction(botAI, "lava lash") {}
};
class CastFlameShockAction : public CastDebuffSpellAction
{
public:
CastFlameShockAction(PlayerbotAI* botAI) : CastDebuffSpellAction(botAI, "flame shock", true, 6.0f) {}
bool isUseful() override
{
// Bypass TTL check
return CastAuraSpellAction::isUseful();
}
};
class CastEarthShockAction : public CastSpellAction
{
public:
CastEarthShockAction(PlayerbotAI* botAI) : CastSpellAction(botAI, "earth shock") {}
};
class CastFrostShockAction : public CastSnareSpellAction
{
public:
CastFrostShockAction(PlayerbotAI* botAI) : CastSnareSpellAction(botAI, "frost shock") {}
};
class CastChainLightningAction : public CastSpellAction
{
public:
CastChainLightningAction(PlayerbotAI* botAI) : CastSpellAction(botAI, "chain lightning") {}
ActionThreatType getThreatType() override { return ActionThreatType::Aoe; }
};
class CastLightningBoltAction : public CastSpellAction
{
public:
CastLightningBoltAction(PlayerbotAI* botAI) : CastSpellAction(botAI, "lightning bolt") {}
};
class CastThunderstormAction : public CastSpellAction
{
public:
CastThunderstormAction(PlayerbotAI* botAI) : CastSpellAction(botAI, "thunderstorm") {}
};
class CastLavaBurstAction : public CastSpellAction
{
public:
CastLavaBurstAction(PlayerbotAI* ai) : CastSpellAction(ai, "lava burst") {}
bool isUseful() override;
};
// Healing Actions
class CastLesserHealingWaveAction : public CastHealingSpellAction class CastLesserHealingWaveAction : public CastHealingSpellAction
{ {
public: public:
@@ -78,351 +355,109 @@ public:
CastEarthShieldOnPartyAction(PlayerbotAI* botAI) : BuffOnPartyAction(botAI, "earth shield") {} CastEarthShieldOnPartyAction(PlayerbotAI* botAI) : BuffOnPartyAction(botAI, "earth shield") {}
}; };
class CastWaterShieldAction : public CastBuffSpellAction
{
public:
CastWaterShieldAction(PlayerbotAI* botAI) : CastBuffSpellAction(botAI, "water shield") {}
};
class CastLightningShieldAction : public CastBuffSpellAction
{
public:
CastLightningShieldAction(PlayerbotAI* botAI) : CastBuffSpellAction(botAI, "lightning shield") {}
};
class CastEarthlivingWeaponAction : public CastEnchantItemAction
{
public:
CastEarthlivingWeaponAction(PlayerbotAI* botAI) : CastEnchantItemAction(botAI, "earthliving weapon") {}
};
class CastRockbiterWeaponAction : public CastEnchantItemAction
{
public:
CastRockbiterWeaponAction(PlayerbotAI* botAI) : CastEnchantItemAction(botAI, "rockbiter weapon") {}
};
class CastFlametongueWeaponAction : public CastEnchantItemAction
{
public:
CastFlametongueWeaponAction(PlayerbotAI* botAI) : CastEnchantItemAction(botAI, "flametongue weapon") {}
};
class CastFrostbrandWeaponAction : public CastEnchantItemAction
{
public:
CastFrostbrandWeaponAction(PlayerbotAI* botAI) : CastEnchantItemAction(botAI, "frostbrand weapon") {}
};
class CastWindfuryWeaponAction : public CastEnchantItemAction
{
public:
CastWindfuryWeaponAction(PlayerbotAI* botAI) : CastEnchantItemAction(botAI, "windfury weapon") {}
};
class CastTotemAction : public CastBuffSpellAction
{
public:
CastTotemAction(PlayerbotAI* botAI, std::string const spell, std::string const buffName = "",
float needLifeTime = 8.0f)
: CastBuffSpellAction(botAI, spell), needLifeTime(needLifeTime)
{
if (buffName == "")
{
buff = spell;
}
else
{
buff = buffName;
}
}
bool isUseful() override;
protected:
float needLifeTime;
std::string buff;
};
class CastStoneskinTotemAction : public CastTotemAction
{
public:
CastStoneskinTotemAction(PlayerbotAI* botAI) : CastTotemAction(botAI, "stoneskin totem") {}
};
class CastEarthbindTotemAction : public CastTotemAction
{
public:
CastEarthbindTotemAction(PlayerbotAI* botAI) : CastTotemAction(botAI, "earthbind totem") {}
};
class CastStrengthOfEarthTotemAction : public CastTotemAction
{
public:
CastStrengthOfEarthTotemAction(PlayerbotAI* botAI)
: CastTotemAction(botAI, "strength of earth totem", "strength of earth", 20.0f)
{
}
};
class CastManaSpringTotemAction : public CastTotemAction
{
public:
CastManaSpringTotemAction(PlayerbotAI* botAI) : CastTotemAction(botAI, "mana spring totem", "mana spring", 0.0f) {}
bool isUseful() override;
};
class CastManaTideTotemAction : public CastTotemAction
{
public:
CastManaTideTotemAction(PlayerbotAI* botAI) : CastTotemAction(botAI, "mana tide totem") {}
std::string const GetTargetName() override { return "self target"; }
};
class CastHealingStreamTotemAction : public CastTotemAction
{
public:
CastHealingStreamTotemAction(PlayerbotAI* botAI) : CastTotemAction(botAI, "healing stream totem") {}
};
class CastCleansingTotemAction : public CastTotemAction
{
public:
CastCleansingTotemAction(PlayerbotAI* botAI) : CastTotemAction(botAI, "cleansing totem") {}
virtual bool isUseful();
};
class CastFlametongueTotemAction : public CastTotemAction
{
public:
CastFlametongueTotemAction(PlayerbotAI* botAI) : CastTotemAction(botAI, "flametongue totem", "", 20.0f) {}
bool isUseful() override;
};
class CastWindfuryTotemAction : public CastTotemAction
{
public:
CastWindfuryTotemAction(PlayerbotAI* botAI) : CastTotemAction(botAI, "windfury totem") {}
};
class CastGraceOfAirTotemAction : public CastTotemAction
{
public:
CastGraceOfAirTotemAction(PlayerbotAI* botAI) : CastTotemAction(botAI, "grace of air totem") {}
};
class CastSearingTotemAction : public CastTotemAction
{
public:
CastSearingTotemAction(PlayerbotAI* botAI) : CastTotemAction(botAI, "searing totem", "", 0.0f) {}
std::string const GetTargetName() override { return "self target"; }
bool isUseful() override;
};
class CastMagmaTotemAction : public CastTotemAction
{
public:
CastMagmaTotemAction(PlayerbotAI* botAI) : CastTotemAction(botAI, "magma totem", "", 0.0f) {}
std::string const GetTargetName() override { return "self target"; }
bool isUseful() override;
};
class CastFireNovaAction : public CastMeleeSpellAction
{
public:
CastFireNovaAction(PlayerbotAI* botAI) : CastMeleeSpellAction(botAI, "fire nova") {}
bool isUseful() override;
};
class CastWindShearAction : public CastSpellAction
{
public:
CastWindShearAction(PlayerbotAI* botAI) : CastSpellAction(botAI, "wind shear") {}
};
class CastAncestralSpiritAction : public ResurrectPartyMemberAction
{
public:
CastAncestralSpiritAction(PlayerbotAI* botAI) : ResurrectPartyMemberAction(botAI, "ancestral spirit") {}
};
class CastPurgeAction : public CastSpellAction
{
public:
CastPurgeAction(PlayerbotAI* botAI) : CastSpellAction(botAI, "purge") {}
};
class CastStormstrikeAction : public CastMeleeSpellAction
{
public:
CastStormstrikeAction(PlayerbotAI* botAI) : CastMeleeSpellAction(botAI, "stormstrike") {}
};
class CastLavaLashAction : public CastMeleeSpellAction
{
public:
CastLavaLashAction(PlayerbotAI* botAI) : CastMeleeSpellAction(botAI, "lava lash") {}
};
class CastWaterBreathingAction : public CastBuffSpellAction
{
public:
CastWaterBreathingAction(PlayerbotAI* botAI) : CastBuffSpellAction(botAI, "water breathing") {}
};
class CastWaterWalkingAction : public CastBuffSpellAction
{
public:
CastWaterWalkingAction(PlayerbotAI* botAI) : CastBuffSpellAction(botAI, "water walking") {}
};
class CastWaterBreathingOnPartyAction : public BuffOnPartyAction
{
public:
CastWaterBreathingOnPartyAction(PlayerbotAI* botAI) : BuffOnPartyAction(botAI, "water breathing") {}
};
class CastWaterWalkingOnPartyAction : public BuffOnPartyAction
{
public:
CastWaterWalkingOnPartyAction(PlayerbotAI* botAI) : BuffOnPartyAction(botAI, "water walking") {}
};
class CastCleanseSpiritAction : public CastCureSpellAction
{
public:
CastCleanseSpiritAction(PlayerbotAI* botAI) : CastCureSpellAction(botAI, "cleanse spirit") {}
};
class CastCleanseSpiritPoisonOnPartyAction : public CurePartyMemberAction
{
public:
CastCleanseSpiritPoisonOnPartyAction(PlayerbotAI* botAI)
: CurePartyMemberAction(botAI, "cleanse spirit", DISPEL_POISON)
{
}
std::string const getName() override { return "cleanse spirit poison on party"; }
};
class CastCleanseSpiritCurseOnPartyAction : public CurePartyMemberAction
{
public:
CastCleanseSpiritCurseOnPartyAction(PlayerbotAI* botAI)
: CurePartyMemberAction(botAI, "cleanse spirit", DISPEL_CURSE)
{
}
std::string const getName() override { return "cleanse spirit curse on party"; }
};
class CastCleanseSpiritDiseaseOnPartyAction : public CurePartyMemberAction
{
public:
CastCleanseSpiritDiseaseOnPartyAction(PlayerbotAI* botAI)
: CurePartyMemberAction(botAI, "cleanse spirit", DISPEL_DISEASE)
{
}
std::string const getName() override { return "cleanse spirit disease on party"; }
};
class CastFlameShockAction : public CastDebuffSpellAction
{
public:
CastFlameShockAction(PlayerbotAI* botAI) : CastDebuffSpellAction(botAI, "flame shock", true, 6.0f) {}
};
class CastEarthShockAction : public CastSpellAction
{
public:
CastEarthShockAction(PlayerbotAI* botAI) : CastSpellAction(botAI, "earth shock") {}
};
class CastFrostShockAction : public CastSnareSpellAction
{
public:
CastFrostShockAction(PlayerbotAI* botAI) : CastSnareSpellAction(botAI, "frost shock") {}
};
class CastChainLightningAction : public CastSpellAction
{
public:
CastChainLightningAction(PlayerbotAI* botAI) : CastSpellAction(botAI, "chain lightning") {}
ActionThreatType getThreatType() override { return ActionThreatType::Aoe; }
};
class CastLightningBoltAction : public CastSpellAction
{
public:
CastLightningBoltAction(PlayerbotAI* botAI) : CastSpellAction(botAI, "lightning bolt") {}
};
class CastThunderstormAction : public CastSpellAction
{
public:
CastThunderstormAction(PlayerbotAI* botAI) : CastSpellAction(botAI, "thunderstorm") {}
};
class CastHeroismAction : public CastBuffSpellAction
{
public:
CastHeroismAction(PlayerbotAI* botAI) : CastBuffSpellAction(botAI, "heroism") {}
};
class CastBloodlustAction : public CastBuffSpellAction
{
public:
CastBloodlustAction(PlayerbotAI* botAI) : CastBuffSpellAction(botAI, "bloodlust") {}
};
class CastElementalMasteryAction : public CastBuffSpellAction
{
public:
CastElementalMasteryAction(PlayerbotAI* botAI) : CastBuffSpellAction(botAI, "elemental mastery") {}
};
class CastWindShearOnEnemyHealerAction : public CastSpellOnEnemyHealerAction
{
public:
CastWindShearOnEnemyHealerAction(PlayerbotAI* botAI) : CastSpellOnEnemyHealerAction(botAI, "wind shear") {}
};
CURE_ACTION(CastCurePoisonActionSham, "cure disease");
CURE_PARTY_ACTION(CastCurePoisonOnPartyActionSham, "cure poison", DISPEL_POISON);
CURE_ACTION(CastCureDiseaseActionSham, "cure disease");
CURE_PARTY_ACTION(CastCureDiseaseOnPartyActionSham, "cure disease", DISPEL_DISEASE);
class CastLavaBurstAction : public CastSpellAction
{
public:
CastLavaBurstAction(PlayerbotAI* ai) : CastSpellAction(ai, "lava burst") {}
};
class CastEarthShieldOnMainTankAction : public BuffOnMainTankAction class CastEarthShieldOnMainTankAction : public BuffOnMainTankAction
{ {
public: public:
CastEarthShieldOnMainTankAction(PlayerbotAI* ai) : BuffOnMainTankAction(ai, "earth shield", false) {} CastEarthShieldOnMainTankAction(PlayerbotAI* ai) : BuffOnMainTankAction(ai, "earth shield", false) {}
}; };
// Totem Spells
class CastTotemAction : public CastBuffSpellAction
{
public:
CastTotemAction(PlayerbotAI* botAI, std::string const spell, std::string const buffName = "")
: CastBuffSpellAction(botAI, spell)
{
buff = (buffName == "") ? spell : buffName;
}
bool isUseful() override;
protected:
std::string buff;
};
class CastCallOfTheElementsAction : public CastSpellAction
{
public:
CastCallOfTheElementsAction(PlayerbotAI* ai) : CastSpellAction(ai, "call of the elements") {}
};
class CastTotemicRecallAction : public CastSpellAction
{
public:
CastTotemicRecallAction(PlayerbotAI* ai) : CastSpellAction(ai, "totemic recall") {}
};
class CastStrengthOfEarthTotemAction : public CastTotemAction
{
public:
CastStrengthOfEarthTotemAction(PlayerbotAI* botAI) : CastTotemAction(botAI, "strength of earth totem", "strength of earth") {}
};
class CastStoneskinTotemAction : public CastTotemAction
{
public:
CastStoneskinTotemAction(PlayerbotAI* botAI) : CastTotemAction(botAI, "stoneskin totem", "stoneskin") {}
};
class CastTremorTotemAction : public CastTotemAction
{
public:
CastTremorTotemAction(PlayerbotAI* botAI) : CastTotemAction(botAI, "tremor totem", "") {}
};
class CastEarthbindTotemAction : public CastTotemAction
{
public:
CastEarthbindTotemAction(PlayerbotAI* botAI) : CastTotemAction(botAI, "earthbind totem", "") {}
};
class CastStoneclawTotemAction : public CastTotemAction
{
public:
CastStoneclawTotemAction(PlayerbotAI* botAI) : CastTotemAction(botAI, "stoneclaw totem", "") {}
bool isUseful() override;
};
class CastSearingTotemAction : public CastTotemAction
{
public:
CastSearingTotemAction(PlayerbotAI* botAI) : CastTotemAction(botAI, "searing totem", "") {}
};
class CastMagmaTotemAction : public CastTotemAction
{
public:
CastMagmaTotemAction(PlayerbotAI* botAI) : CastTotemAction(botAI, "magma totem", "") {}
std::string const GetTargetName() override { return "self target"; }
bool isUseful() override;
};
class CastFlametongueTotemAction : public CastTotemAction
{
public:
CastFlametongueTotemAction(PlayerbotAI* botAI) : CastTotemAction(botAI, "flametongue totem", "flametongue totem") {}
};
class CastTotemOfWrathAction : public CastTotemAction class CastTotemOfWrathAction : public CastTotemAction
{ {
public: public:
CastTotemOfWrathAction(PlayerbotAI* ai) : CastTotemAction(ai, "totem of wrath") {} CastTotemOfWrathAction(PlayerbotAI* botAI) : CastTotemAction(botAI, "totem of wrath", "totem of wrath") {}
virtual std::string const GetTargetName() override { return "self target"; } };
virtual bool isUseful() override { return CastTotemAction::isUseful(); }
class CastFrostResistanceTotemAction : public CastTotemAction
{
public:
CastFrostResistanceTotemAction(PlayerbotAI* botAI)
: CastTotemAction(botAI, "frost resistance totem", "frost resistance") {}
}; };
class CastFireElementalTotemAction : public CastTotemAction class CastFireElementalTotemAction : public CastTotemAction
{ {
public: public:
CastFireElementalTotemAction(PlayerbotAI* ai) : CastTotemAction(ai, "fire elemental totem", "", 0.0f) {} CastFireElementalTotemAction(PlayerbotAI* ai) : CastTotemAction(ai, "fire elemental totem", "") {}
virtual std::string const GetTargetName() override { return "self target"; } virtual std::string const GetTargetName() override { return "self target"; }
virtual bool isUseful() override { return CastTotemAction::isUseful(); } virtual bool isUseful() override { return CastTotemAction::isUseful(); }
}; };
@@ -430,7 +465,7 @@ public:
class CastFireElementalTotemMeleeAction : public CastTotemAction class CastFireElementalTotemMeleeAction : public CastTotemAction
{ {
public: public:
CastFireElementalTotemMeleeAction(PlayerbotAI* ai) : CastTotemAction(ai, "fire elemental totem", "", 0.0f) {} CastFireElementalTotemMeleeAction(PlayerbotAI* ai) : CastTotemAction(ai, "fire elemental totem", "") {}
virtual std::string const GetTargetName() override { return "self target"; } virtual std::string const GetTargetName() override { return "self target"; }
virtual bool isUseful() override virtual bool isUseful() override
{ {
@@ -441,21 +476,187 @@ public:
} }
}; };
class CastHealingStreamTotemAction : public CastTotemAction
{
public:
CastHealingStreamTotemAction(PlayerbotAI* botAI) : CastTotemAction(botAI, "healing stream totem", "") {}
};
class CastManaSpringTotemAction : public CastTotemAction
{
public:
CastManaSpringTotemAction(PlayerbotAI* botAI) : CastTotemAction(botAI, "mana spring totem", "mana spring") {}
};
class CastCleansingTotemAction : public CastTotemAction
{
public:
CastCleansingTotemAction(PlayerbotAI* botAI) : CastTotemAction(botAI, "cleansing totem", "") {}
virtual bool isUseful();
};
class CastManaTideTotemAction : public CastTotemAction
{
public:
CastManaTideTotemAction(PlayerbotAI* botAI) : CastTotemAction(botAI, "mana tide totem", "") {}
std::string const GetTargetName() override { return "self target"; }
};
class CastFireResistanceTotemAction : public CastTotemAction
{
public:
CastFireResistanceTotemAction(PlayerbotAI* botAI) : CastTotemAction(botAI, "fire resistance totem", "fire resistance") {}
};
class CastWrathOfAirTotemAction : public CastTotemAction class CastWrathOfAirTotemAction : public CastTotemAction
{ {
public: public:
CastWrathOfAirTotemAction(PlayerbotAI* ai) : CastTotemAction(ai, "wrath of air totem", "wrath of air totem") {} CastWrathOfAirTotemAction(PlayerbotAI* ai) : CastTotemAction(ai, "wrath of air totem", "wrath of air totem") {}
}; };
class CastShamanisticRageAction : public CastBuffSpellAction class CastWindfuryTotemAction : public CastTotemAction
{ {
public: public:
CastShamanisticRageAction(PlayerbotAI* ai) : CastBuffSpellAction(ai, "shamanistic rage") {} CastWindfuryTotemAction(PlayerbotAI* botAI) : CastTotemAction(botAI, "windfury totem", "windfury totem") {}
}; };
class CastFeralSpiritAction : public CastSpellAction class CastNatureResistanceTotemAction : public CastTotemAction
{ {
public: public:
CastFeralSpiritAction(PlayerbotAI* ai) : CastSpellAction(ai, "feral spirit") {} CastNatureResistanceTotemAction(PlayerbotAI* botAI) : CastTotemAction(botAI, "nature resistance totem", "nature resistance") {}
}; };
// Set Strategy Assigned Totems
class SetTotemAction : public Action
{
public:
SetTotemAction(PlayerbotAI* botAI, std::string const totemName, const uint32 totemSpellIds[], int actionButtonId)
: Action(botAI, "set " + totemName), totemSpellIds(totemSpellIds), actionButtonId(actionButtonId)
{
}
bool Execute(Event event) override;
uint32 const* totemSpellIds;
int actionButtonId;
};
class SetStrengthOfEarthTotemAction : public SetTotemAction
{
public:
SetStrengthOfEarthTotemAction(PlayerbotAI* ai)
: SetTotemAction(ai, "strength of earth totem", STRENGTH_OF_EARTH_TOTEM, TOTEM_BAR_SLOT_EARTH) {}
};
class SetStoneskinTotemAction : public SetTotemAction
{
public:
SetStoneskinTotemAction(PlayerbotAI* ai)
: SetTotemAction(ai, "stoneskin totem", STONESKIN_TOTEM, TOTEM_BAR_SLOT_EARTH) {}
};
class SetTremorTotemAction : public SetTotemAction
{
public:
SetTremorTotemAction(PlayerbotAI* ai)
: SetTotemAction(ai, "tremor totem", TREMOR_TOTEM, TOTEM_BAR_SLOT_EARTH) {}
};
class SetEarthbindTotemAction : public SetTotemAction
{
public:
SetEarthbindTotemAction(PlayerbotAI* ai)
: SetTotemAction(ai, "earthbind totem", EARTHBIND_TOTEM, TOTEM_BAR_SLOT_EARTH) {}
};
class SetSearingTotemAction : public SetTotemAction
{
public:
SetSearingTotemAction(PlayerbotAI* ai)
: SetTotemAction(ai, "searing totem", SEARING_TOTEM, TOTEM_BAR_SLOT_FIRE) {}
};
class SetMagmaTotemAction : public SetTotemAction
{
public:
SetMagmaTotemAction(PlayerbotAI* ai)
: SetTotemAction(ai, "magma totem", MAGMA_TOTEM, TOTEM_BAR_SLOT_FIRE) {}
};
class SetFlametongueTotemAction : public SetTotemAction
{
public:
SetFlametongueTotemAction(PlayerbotAI* ai)
: SetTotemAction(ai, "flametongue totem", FLAMETONGUE_TOTEM, TOTEM_BAR_SLOT_FIRE) {}
};
class SetTotemOfWrathAction : public SetTotemAction
{
public:
SetTotemOfWrathAction(PlayerbotAI* ai)
: SetTotemAction(ai, "totem of wrath", TOTEM_OF_WRATH, TOTEM_BAR_SLOT_FIRE) {}
};
class SetFrostResistanceTotemAction : public SetTotemAction
{
public:
SetFrostResistanceTotemAction(PlayerbotAI* ai)
: SetTotemAction(ai, "frost resistance totem", FROST_RESISTANCE_TOTEM, TOTEM_BAR_SLOT_FIRE) {}
};
class SetHealingStreamTotemAction : public SetTotemAction
{
public:
SetHealingStreamTotemAction(PlayerbotAI* ai)
: SetTotemAction(ai, "healing stream totem", HEALING_STREAM_TOTEM, TOTEM_BAR_SLOT_WATER) {}
};
class SetManaSpringTotemAction : public SetTotemAction
{
public:
SetManaSpringTotemAction(PlayerbotAI* ai)
: SetTotemAction(ai, "mana spring totem", MANA_SPRING_TOTEM, TOTEM_BAR_SLOT_WATER) {}
};
class SetCleansingTotemAction : public SetTotemAction
{
public:
SetCleansingTotemAction(PlayerbotAI* ai)
: SetTotemAction(ai, "cleansing totem", CLEANSING_TOTEM, TOTEM_BAR_SLOT_WATER) {}
};
class SetFireResistanceTotemAction : public SetTotemAction
{
public:
SetFireResistanceTotemAction(PlayerbotAI* ai)
: SetTotemAction(ai, "fire resistance totem", FIRE_RESISTANCE_TOTEM, TOTEM_BAR_SLOT_WATER) {}
};
class SetWrathOfAirTotemAction : public SetTotemAction
{
public:
SetWrathOfAirTotemAction(PlayerbotAI* ai)
: SetTotemAction(ai, "wrath of air totem", WRATH_OF_AIR_TOTEM, TOTEM_BAR_SLOT_AIR) {}
};
class SetWindfuryTotemAction : public SetTotemAction
{
public:
SetWindfuryTotemAction(PlayerbotAI* ai)
: SetTotemAction(ai, "windfury totem", WINDFURY_TOTEM, TOTEM_BAR_SLOT_AIR) {}
};
class SetNatureResistanceTotemAction : public SetTotemAction
{
public:
SetNatureResistanceTotemAction(PlayerbotAI* ai)
: SetTotemAction(ai, "nature resistance totem", NATURE_RESISTANCE_TOTEM, TOTEM_BAR_SLOT_AIR) {}
};
class SetGroundingTotemAction : public SetTotemAction
{
public:
SetGroundingTotemAction(PlayerbotAI* ai)
: SetTotemAction(ai, "grounding totem", GROUNDING_TOTEM, TOTEM_BAR_SLOT_AIR) {}
};
#endif #endif

View File

@@ -5,10 +5,10 @@
#include "ShamanAiObjectContext.h" #include "ShamanAiObjectContext.h"
#include "CasterShamanStrategy.h" #include "ElementalShamanStrategy.h"
#include "GenericShamanStrategy.h" #include "GenericShamanStrategy.h"
#include "HealShamanStrategy.h" #include "RestoShamanStrategy.h"
#include "MeleeShamanStrategy.h" #include "EnhancementShamanStrategy.h"
#include "NamedObjectContext.h" #include "NamedObjectContext.h"
#include "Playerbots.h" #include "Playerbots.h"
#include "ShamanActions.h" #include "ShamanActions.h"
@@ -22,34 +22,18 @@ public:
ShamanStrategyFactoryInternal() ShamanStrategyFactoryInternal()
{ {
creators["nc"] = &ShamanStrategyFactoryInternal::nc; creators["nc"] = &ShamanStrategyFactoryInternal::nc;
creators["totems"] = &ShamanStrategyFactoryInternal::totems; creators["aoe"] = &ShamanStrategyFactoryInternal::aoe;
creators["melee aoe"] = &ShamanStrategyFactoryInternal::melee_aoe;
creators["caster aoe"] = &ShamanStrategyFactoryInternal::caster_aoe;
creators["cure"] = &ShamanStrategyFactoryInternal::cure; creators["cure"] = &ShamanStrategyFactoryInternal::cure;
creators["healer dps"] = &ShamanStrategyFactoryInternal::healer_dps; creators["healer dps"] = &ShamanStrategyFactoryInternal::healer_dps;
creators["boost"] = &ShamanStrategyFactoryInternal::boost;
} }
private: private:
static Strategy* nc(PlayerbotAI* botAI) { return new ShamanNonCombatStrategy(botAI); } static Strategy* nc(PlayerbotAI* botAI) { return new ShamanNonCombatStrategy(botAI); }
static Strategy* totems(PlayerbotAI* botAI) { return new TotemsShamanStrategy(botAI); } static Strategy* aoe(PlayerbotAI* botAI) { return new ShamanAoeStrategy(botAI); }
static Strategy* melee_aoe(PlayerbotAI* botAI) { return new MeleeAoeShamanStrategy(botAI); }
static Strategy* caster_aoe(PlayerbotAI* botAI) { return new CasterAoeShamanStrategy(botAI); }
static Strategy* cure(PlayerbotAI* botAI) { return new ShamanCureStrategy(botAI); } static Strategy* cure(PlayerbotAI* botAI) { return new ShamanCureStrategy(botAI); }
static Strategy* healer_dps(PlayerbotAI* botAI) { return new ShamanHealerDpsStrategy(botAI); } static Strategy* healer_dps(PlayerbotAI* botAI) { return new ShamanHealerDpsStrategy(botAI); }
}; static Strategy* boost(PlayerbotAI* botAI) { return new ShamanBoostStrategy(botAI); }
class ShamanBuffStrategyFactoryInternal : public NamedObjectContext<Strategy>
{
public:
ShamanBuffStrategyFactoryInternal() : NamedObjectContext<Strategy>(false, true)
{
creators["bmana"] = &ShamanBuffStrategyFactoryInternal::bmana;
creators["bdps"] = &ShamanBuffStrategyFactoryInternal::bdps;
}
private:
static Strategy* bmana(PlayerbotAI* botAI) { return new ShamanBuffManaStrategy(botAI); }
static Strategy* bdps(PlayerbotAI* botAI) { return new ShamanBuffDpsStrategy(botAI); }
}; };
class ShamanCombatStrategyFactoryInternal : public NamedObjectContext<Strategy> class ShamanCombatStrategyFactoryInternal : public NamedObjectContext<Strategy>
@@ -57,16 +41,89 @@ class ShamanCombatStrategyFactoryInternal : public NamedObjectContext<Strategy>
public: public:
ShamanCombatStrategyFactoryInternal() : NamedObjectContext<Strategy>(false, true) ShamanCombatStrategyFactoryInternal() : NamedObjectContext<Strategy>(false, true)
{ {
creators["heal"] = &ShamanCombatStrategyFactoryInternal::heal; creators["resto"] = &ShamanCombatStrategyFactoryInternal::resto;
creators["melee"] = &ShamanCombatStrategyFactoryInternal::dps; creators["enh"] = &ShamanCombatStrategyFactoryInternal::enh;
creators["dps"] = &ShamanCombatStrategyFactoryInternal::dps; creators["ele"] = &ShamanCombatStrategyFactoryInternal::ele;
creators["caster"] = &ShamanCombatStrategyFactoryInternal::caster;
} }
private: private:
static Strategy* heal(PlayerbotAI* botAI) { return new HealShamanStrategy(botAI); } static Strategy* resto(PlayerbotAI* botAI) { return new RestoShamanStrategy(botAI); }
static Strategy* dps(PlayerbotAI* botAI) { return new MeleeShamanStrategy(botAI); } static Strategy* enh(PlayerbotAI* botAI) { return new EnhancementShamanStrategy(botAI); }
static Strategy* caster(PlayerbotAI* botAI) { return new CasterShamanStrategy(botAI); } static Strategy* ele(PlayerbotAI* botAI) { return new ElementalShamanStrategy(botAI); }
};
class ShamanEarthTotemStrategyFactoryInternal : public NamedObjectContext<Strategy>
{
public:
ShamanEarthTotemStrategyFactoryInternal() : NamedObjectContext<Strategy>(false, true)
{
creators["strength of earth"] = &ShamanEarthTotemStrategyFactoryInternal::strength_of_earth_totem;
creators["stoneskin"] = &ShamanEarthTotemStrategyFactoryInternal::stoneclaw_totem;
creators["tremor"] = &ShamanEarthTotemStrategyFactoryInternal::earth_totem;
creators["earthbind"] = &ShamanEarthTotemStrategyFactoryInternal::earthbind_totem;
}
private:
static Strategy* strength_of_earth_totem(PlayerbotAI* botAI) { return new StrengthOfEarthTotemStrategy(botAI); }
static Strategy* stoneclaw_totem(PlayerbotAI* botAI) { return new StoneclawTotemStrategy(botAI); }
static Strategy* earth_totem(PlayerbotAI* botAI) { return new EarthTotemStrategy(botAI); }
static Strategy* earthbind_totem(PlayerbotAI* botAI) { return new EarthbindTotemStrategy(botAI); }
};
class ShamanFireTotemStrategyFactoryInternal : public NamedObjectContext<Strategy>
{
public:
ShamanFireTotemStrategyFactoryInternal() : NamedObjectContext<Strategy>(false, true)
{
creators["searing"] = &ShamanFireTotemStrategyFactoryInternal::searing_totem;
creators["magma"] = &ShamanFireTotemStrategyFactoryInternal::magma_totem;
creators["flametongue"] = &ShamanFireTotemStrategyFactoryInternal::flametongue_totem;
creators["wrath"] = &ShamanFireTotemStrategyFactoryInternal::totem_of_wrath;
creators["frost resistance"] = &ShamanFireTotemStrategyFactoryInternal::frost_resistance_totem;
}
private:
static Strategy* searing_totem(PlayerbotAI* botAI) { return new SearingTotemStrategy(botAI); }
static Strategy* magma_totem(PlayerbotAI* botAI) { return new MagmaTotemStrategy(botAI); }
static Strategy* flametongue_totem(PlayerbotAI* botAI) { return new FlametongueTotemStrategy(botAI); }
static Strategy* totem_of_wrath(PlayerbotAI* botAI) { return new TotemOfWrathStrategy(botAI); }
static Strategy* frost_resistance_totem(PlayerbotAI* botAI) { return new FrostResistanceTotemStrategy(botAI); }
};
class ShamanWaterTotemStrategyFactoryInternal : public NamedObjectContext<Strategy>
{
public:
ShamanWaterTotemStrategyFactoryInternal() : NamedObjectContext<Strategy>(false, true)
{
creators["healing stream"] = &ShamanWaterTotemStrategyFactoryInternal::healing_stream_totem;
creators["mana spring"] = &ShamanWaterTotemStrategyFactoryInternal::mana_spring_totem;
creators["cleansing"] = &ShamanWaterTotemStrategyFactoryInternal::cleansing_totem;
creators["fire resistance"] = &ShamanWaterTotemStrategyFactoryInternal::fire_resistance_totem;
}
private:
static Strategy* healing_stream_totem(PlayerbotAI* botAI) { return new HealingStreamTotemStrategy(botAI); }
static Strategy* mana_spring_totem(PlayerbotAI* botAI) { return new ManaSpringTotemStrategy(botAI); }
static Strategy* cleansing_totem(PlayerbotAI* botAI) { return new CleansingTotemStrategy(botAI); }
static Strategy* fire_resistance_totem(PlayerbotAI* botAI) { return new FireResistanceTotemStrategy(botAI); }
};
class ShamanAirTotemStrategyFactoryInternal : public NamedObjectContext<Strategy>
{
public:
ShamanAirTotemStrategyFactoryInternal() : NamedObjectContext<Strategy>(false, true)
{
creators["wrath of air"] = &ShamanAirTotemStrategyFactoryInternal::wrath_of_air_totem;
creators["windfury"] = &ShamanAirTotemStrategyFactoryInternal::windfury_totem;
creators["nature resistance"] = &ShamanAirTotemStrategyFactoryInternal::nature_resistance_totem;
creators["grounding"] = &ShamanAirTotemStrategyFactoryInternal::grounding_totem;
}
private:
static Strategy* wrath_of_air_totem(PlayerbotAI* botAI) { return new WrathOfAirTotemStrategy(botAI); }
static Strategy* windfury_totem(PlayerbotAI* botAI) { return new WindfuryTotemStrategy(botAI); }
static Strategy* nature_resistance_totem(PlayerbotAI* botAI) { return new NatureResistanceTotemStrategy(botAI); }
static Strategy* grounding_totem(PlayerbotAI* botAI) { return new GroundingTotemStrategy(botAI); }
}; };
class ShamanATriggerFactoryInternal : public NamedObjectContext<Trigger> class ShamanATriggerFactoryInternal : public NamedObjectContext<Trigger>
@@ -74,17 +131,8 @@ class ShamanATriggerFactoryInternal : public NamedObjectContext<Trigger>
public: public:
ShamanATriggerFactoryInternal() ShamanATriggerFactoryInternal()
{ {
creators["grace of air totem"] = &ShamanATriggerFactoryInternal::grace_of_air_totem;
creators["windfury totem"] = &ShamanATriggerFactoryInternal::windfury_totem;
creators["mana spring totem"] = &ShamanATriggerFactoryInternal::mana_spring_totem;
creators["flametongue totem"] = &ShamanATriggerFactoryInternal::flametongue_totem;
creators["strength of earth totem"] = &ShamanATriggerFactoryInternal::strength_of_earth_totem;
creators["fire elemental totem"] = &ShamanATriggerFactoryInternal::fire_elemental_totem;
creators["magma totem"] = &ShamanATriggerFactoryInternal::magma_totem;
creators["searing totem"] = &ShamanATriggerFactoryInternal::searing_totem;
creators["wind shear"] = &ShamanATriggerFactoryInternal::wind_shear; creators["wind shear"] = &ShamanATriggerFactoryInternal::wind_shear;
creators["purge"] = &ShamanATriggerFactoryInternal::purge; creators["purge"] = &ShamanATriggerFactoryInternal::purge;
// creators["shaman weapon"] = &ShamanATriggerFactoryInternal::shaman_weapon;
creators["main hand weapon no imbue"] = &ShamanATriggerFactoryInternal::main_hand_weapon_no_imbue; creators["main hand weapon no imbue"] = &ShamanATriggerFactoryInternal::main_hand_weapon_no_imbue;
creators["off hand weapon no imbue"] = &ShamanATriggerFactoryInternal::off_hand_weapon_no_imbue; creators["off hand weapon no imbue"] = &ShamanATriggerFactoryInternal::off_hand_weapon_no_imbue;
creators["water shield"] = &ShamanATriggerFactoryInternal::water_shield; creators["water shield"] = &ShamanATriggerFactoryInternal::water_shield;
@@ -109,15 +157,41 @@ public:
creators["party member cure poison"] = &ShamanATriggerFactoryInternal::party_member_cure_poison; creators["party member cure poison"] = &ShamanATriggerFactoryInternal::party_member_cure_poison;
creators["cure disease"] = &ShamanATriggerFactoryInternal::cure_disease; creators["cure disease"] = &ShamanATriggerFactoryInternal::cure_disease;
creators["party member cure disease"] = &ShamanATriggerFactoryInternal::party_member_cure_disease; creators["party member cure disease"] = &ShamanATriggerFactoryInternal::party_member_cure_disease;
creators["no fire totem"] = &ShamanATriggerFactoryInternal::no_fire_totem;
creators["no water totem"] = &ShamanATriggerFactoryInternal::no_water_totem;
creators["no air totem"] = &ShamanATriggerFactoryInternal::no_air_totem;
creators["earth shield on main tank"] = &ShamanATriggerFactoryInternal::earth_shield_on_main_tank; creators["earth shield on main tank"] = &ShamanATriggerFactoryInternal::earth_shield_on_main_tank;
creators["maelstrom weapon 3"] = &ShamanATriggerFactoryInternal::maelstrom_weapon_3; creators["maelstrom weapon 3"] = &ShamanATriggerFactoryInternal::maelstrom_weapon_3;
creators["maelstrom weapon 4"] = &ShamanATriggerFactoryInternal::maelstrom_weapon_4; creators["maelstrom weapon 4"] = &ShamanATriggerFactoryInternal::maelstrom_weapon_4;
creators["maelstrom weapon 5"] = &ShamanATriggerFactoryInternal::maelstrom_weapon_5; creators["maelstrom weapon 5"] = &ShamanATriggerFactoryInternal::maelstrom_weapon_5;
creators["flame shock"] = &ShamanATriggerFactoryInternal::flame_shock; creators["flame shock"] = &ShamanATriggerFactoryInternal::flame_shock;
creators["wrath of air totem"] = &ShamanATriggerFactoryInternal::wrath_of_air_totem; creators["fire elemental totem"] = &ShamanATriggerFactoryInternal::fire_elemental_totem;
creators["earth shock execute"] = &ShamanATriggerFactoryInternal::earth_shock_execute;
creators["spirit walk ready"] = &ShamanATriggerFactoryInternal::spirit_walk_ready;
creators["chain lightning no cd"] = &ShamanATriggerFactoryInternal::chain_lightning_no_cd;
creators["call of the elements and enemy within melee"] = &ShamanATriggerFactoryInternal::call_of_the_elements_and_enemy_within_melee;
creators["maelstrom weapon 5 and medium aoe"] = &ShamanATriggerFactoryInternal::maelstrom_weapon_5_and_medium_aoe;
creators["maelstrom weapon 4 and medium aoe"] = &ShamanATriggerFactoryInternal::maelstrom_weapon_4_and_medium_aoe;
creators["call of the elements"] = &ShamanATriggerFactoryInternal::call_of_the_elements;
creators["totemic recall"] = &ShamanATriggerFactoryInternal::totemic_recall;
creators["no earth totem"] = &ShamanATriggerFactoryInternal::no_earth_totem;
creators["no fire totem"] = &ShamanATriggerFactoryInternal::no_fire_totem;
creators["no water totem"] = &ShamanATriggerFactoryInternal::no_water_totem;
creators["no air totem"] = &ShamanATriggerFactoryInternal::no_air_totem;
creators["set strength of earth totem"] = &ShamanATriggerFactoryInternal::set_strength_of_earth_totem;
creators["set stoneskin totem"] = &ShamanATriggerFactoryInternal::set_stoneskin_totem;
creators["set tremor totem"] = &ShamanATriggerFactoryInternal::set_tremor_totem;
creators["set earthbind totem"] = &ShamanATriggerFactoryInternal::set_earthbind_totem;
creators["set searing totem"] = &ShamanATriggerFactoryInternal::set_searing_totem;
creators["set magma totem"] = &ShamanATriggerFactoryInternal::set_magma_totem;
creators["set flametongue totem"] = &ShamanATriggerFactoryInternal::set_flametongue_totem;
creators["set totem of wrath"] = &ShamanATriggerFactoryInternal::set_totem_of_wrath;
creators["set frost resistance totem"] = &ShamanATriggerFactoryInternal::set_frost_resistance_totem;
creators["set healing stream totem"] = &ShamanATriggerFactoryInternal::set_healing_stream_totem;
creators["set mana spring totem"] = &ShamanATriggerFactoryInternal::set_mana_spring_totem;
creators["set cleansing totem"] = &ShamanATriggerFactoryInternal::set_cleansing_totem;
creators["set fire resistance totem"] = &ShamanATriggerFactoryInternal::set_fire_resistance_totem;
creators["set wrath of air totem"] = &ShamanATriggerFactoryInternal::set_wrath_of_air_totem;
creators["set windfury totem"] = &ShamanATriggerFactoryInternal::set_windfury_totem;
creators["set nature resistance totem"] = &ShamanATriggerFactoryInternal::set_nature_resistance_totem;
creators["set grounding totem"] = &ShamanATriggerFactoryInternal::set_grounding_totem;
} }
private: private:
@@ -127,18 +201,9 @@ private:
static Trigger* heroism(PlayerbotAI* botAI) { return new HeroismTrigger(botAI); } static Trigger* heroism(PlayerbotAI* botAI) { return new HeroismTrigger(botAI); }
static Trigger* bloodlust(PlayerbotAI* botAI) { return new BloodlustTrigger(botAI); } static Trigger* bloodlust(PlayerbotAI* botAI) { return new BloodlustTrigger(botAI); }
static Trigger* elemental_mastery(PlayerbotAI* botAI) { return new ElementalMasteryTrigger(botAI); } static Trigger* elemental_mastery(PlayerbotAI* botAI) { return new ElementalMasteryTrigger(botAI); }
static Trigger* party_member_cleanse_disease(PlayerbotAI* botAI) static Trigger* party_member_cleanse_disease(PlayerbotAI* botAI) { return new PartyMemberCleanseSpiritDiseaseTrigger(botAI); }
{ static Trigger* party_member_cleanse_curse(PlayerbotAI* botAI) { return new PartyMemberCleanseSpiritCurseTrigger(botAI); }
return new PartyMemberCleanseSpiritDiseaseTrigger(botAI); static Trigger* party_member_cleanse_poison(PlayerbotAI* botAI) { return new PartyMemberCleanseSpiritPoisonTrigger(botAI); }
}
static Trigger* party_member_cleanse_curse(PlayerbotAI* botAI)
{
return new PartyMemberCleanseSpiritCurseTrigger(botAI);
}
static Trigger* party_member_cleanse_poison(PlayerbotAI* botAI)
{
return new PartyMemberCleanseSpiritPoisonTrigger(botAI);
}
static Trigger* cleanse_disease(PlayerbotAI* botAI) { return new CleanseSpiritDiseaseTrigger(botAI); } static Trigger* cleanse_disease(PlayerbotAI* botAI) { return new CleanseSpiritDiseaseTrigger(botAI); }
static Trigger* cleanse_curse(PlayerbotAI* botAI) { return new CleanseSpiritCurseTrigger(botAI); } static Trigger* cleanse_curse(PlayerbotAI* botAI) { return new CleanseSpiritCurseTrigger(botAI); }
static Trigger* cleanse_poison(PlayerbotAI* botAI) { return new CleanseSpiritPoisonTrigger(botAI); } static Trigger* cleanse_poison(PlayerbotAI* botAI) { return new CleanseSpiritPoisonTrigger(botAI); }
@@ -146,37 +211,51 @@ private:
static Trigger* water_walking(PlayerbotAI* botAI) { return new WaterWalkingTrigger(botAI); } static Trigger* water_walking(PlayerbotAI* botAI) { return new WaterWalkingTrigger(botAI); }
static Trigger* water_breathing_on_party(PlayerbotAI* botAI) { return new WaterBreathingOnPartyTrigger(botAI); } static Trigger* water_breathing_on_party(PlayerbotAI* botAI) { return new WaterBreathingOnPartyTrigger(botAI); }
static Trigger* water_walking_on_party(PlayerbotAI* botAI) { return new WaterWalkingOnPartyTrigger(botAI); } static Trigger* water_walking_on_party(PlayerbotAI* botAI) { return new WaterWalkingOnPartyTrigger(botAI); }
static Trigger* windfury_totem(PlayerbotAI* botAI) { return new WindfuryTotemTrigger(botAI); }
static Trigger* grace_of_air_totem(PlayerbotAI* botAI) { return new GraceOfAirTotemTrigger(botAI); }
static Trigger* mana_spring_totem(PlayerbotAI* botAI) { return new ManaSpringTotemTrigger(botAI); }
static Trigger* flametongue_totem(PlayerbotAI* botAI) { return new FlametongueTotemTrigger(botAI); }
static Trigger* strength_of_earth_totem(PlayerbotAI* botAI) { return new StrengthOfEarthTotemTrigger(botAI); }
static Trigger* fire_elemental_totem(PlayerbotAI* botAI) { return new FireElementalTotemTrigger(botAI); }
static Trigger* magma_totem(PlayerbotAI* botAI) { return new MagmaTotemTrigger(botAI); }
static Trigger* searing_totem(PlayerbotAI* botAI) { return new SearingTotemTrigger(botAI); }
static Trigger* wind_shear(PlayerbotAI* botAI) { return new WindShearInterruptSpellTrigger(botAI); } static Trigger* wind_shear(PlayerbotAI* botAI) { return new WindShearInterruptSpellTrigger(botAI); }
static Trigger* purge(PlayerbotAI* botAI) { return new PurgeTrigger(botAI); } static Trigger* purge(PlayerbotAI* botAI) { return new PurgeTrigger(botAI); }
// static Trigger* shaman_weapon(PlayerbotAI* botAI) { return new ShamanWeaponTrigger(botAI); }
static Trigger* main_hand_weapon_no_imbue(PlayerbotAI* botAI) { return new MainHandWeaponNoImbueTrigger(botAI); } static Trigger* main_hand_weapon_no_imbue(PlayerbotAI* botAI) { return new MainHandWeaponNoImbueTrigger(botAI); }
static Trigger* off_hand_weapon_no_imbue(PlayerbotAI* botAI) { return new OffHandWeaponNoImbueTrigger(botAI); } static Trigger* off_hand_weapon_no_imbue(PlayerbotAI* botAI) { return new OffHandWeaponNoImbueTrigger(botAI); }
static Trigger* water_shield(PlayerbotAI* botAI) { return new WaterShieldTrigger(botAI); } static Trigger* water_shield(PlayerbotAI* botAI) { return new WaterShieldTrigger(botAI); }
static Trigger* lightning_shield(PlayerbotAI* botAI) { return new LightningShieldTrigger(botAI); } static Trigger* lightning_shield(PlayerbotAI* botAI) { return new LightningShieldTrigger(botAI); }
static Trigger* shock(PlayerbotAI* botAI) { return new ShockTrigger(botAI); } static Trigger* shock(PlayerbotAI* botAI) { return new ShockTrigger(botAI); }
static Trigger* frost_shock_snare(PlayerbotAI* botAI) { return new FrostShockSnareTrigger(botAI); } static Trigger* frost_shock_snare(PlayerbotAI* botAI) { return new FrostShockSnareTrigger(botAI); }
static Trigger* wind_shear_on_enemy_healer(PlayerbotAI* botAI) static Trigger* wind_shear_on_enemy_healer(PlayerbotAI* botAI) { return new WindShearInterruptEnemyHealerSpellTrigger(botAI); }
{
return new WindShearInterruptEnemyHealerSpellTrigger(botAI);
}
static Trigger* cure_poison(PlayerbotAI* botAI) { return new CurePoisonTrigger(botAI); } static Trigger* cure_poison(PlayerbotAI* botAI) { return new CurePoisonTrigger(botAI); }
static Trigger* party_member_cure_poison(PlayerbotAI* botAI) { return new PartyMemberCurePoisonTrigger(botAI); } static Trigger* party_member_cure_poison(PlayerbotAI* botAI) { return new PartyMemberCurePoisonTrigger(botAI); }
static Trigger* cure_disease(PlayerbotAI* botAI) { return new CureDiseaseTrigger(botAI); } static Trigger* cure_disease(PlayerbotAI* botAI) { return new CureDiseaseTrigger(botAI); }
static Trigger* party_member_cure_disease(PlayerbotAI* botAI) { return new PartyMemberCureDiseaseTrigger(botAI); } static Trigger* party_member_cure_disease(PlayerbotAI* botAI) { return new PartyMemberCureDiseaseTrigger(botAI); }
static Trigger* earth_shield_on_main_tank(PlayerbotAI* ai) { return new EarthShieldOnMainTankTrigger(ai); }
static Trigger* flame_shock(PlayerbotAI* ai) { return new FlameShockTrigger(ai); }
static Trigger* fire_elemental_totem(PlayerbotAI* botAI) { return new FireElementalTotemTrigger(botAI); }
static Trigger* earth_shock_execute(PlayerbotAI* botAI) { return new EarthShockExecuteTrigger(botAI); }
static Trigger* spirit_walk_ready(PlayerbotAI* ai) { return new SpiritWalkTrigger(ai); }
static Trigger* chain_lightning_no_cd(PlayerbotAI* ai) { return new ChainLightningNoCdTrigger(ai); }
static Trigger* call_of_the_elements_and_enemy_within_melee(PlayerbotAI* ai) { return new CallOfTheElementsAndEnemyWithinMeleeTrigger(ai); }
static Trigger* maelstrom_weapon_5_and_medium_aoe(PlayerbotAI* ai) { return new MaelstromWeapon5AndMediumAoeTrigger(ai); }
static Trigger* maelstrom_weapon_4_and_medium_aoe(PlayerbotAI* ai) { return new MaelstromWeapon4AndMediumAoeTrigger(ai); }
static Trigger* call_of_the_elements(PlayerbotAI* ai) { return new CallOfTheElementsTrigger(ai); }
static Trigger* totemic_recall(PlayerbotAI* ai) { return new TotemicRecallTrigger(ai); }
static Trigger* no_earth_totem(PlayerbotAI* ai) { return new NoEarthTotemTrigger(ai); }
static Trigger* no_fire_totem(PlayerbotAI* ai) { return new NoFireTotemTrigger(ai); } static Trigger* no_fire_totem(PlayerbotAI* ai) { return new NoFireTotemTrigger(ai); }
static Trigger* no_water_totem(PlayerbotAI* ai) { return new NoWaterTotemTrigger(ai); } static Trigger* no_water_totem(PlayerbotAI* ai) { return new NoWaterTotemTrigger(ai); }
static Trigger* no_air_totem(PlayerbotAI* ai) { return new NoAirTotemTrigger(ai); } static Trigger* no_air_totem(PlayerbotAI* ai) { return new NoAirTotemTrigger(ai); }
static Trigger* earth_shield_on_main_tank(PlayerbotAI* ai) { return new EarthShieldOnMainTankTrigger(ai); } static Trigger* set_strength_of_earth_totem(PlayerbotAI* ai) { return new SetStrengthOfEarthTotemTrigger(ai); }
static Trigger* flame_shock(PlayerbotAI* ai) { return new FlameShockTrigger(ai); } static Trigger* set_stoneskin_totem(PlayerbotAI* ai) { return new SetStoneskinTotemTrigger(ai); }
static Trigger* wrath_of_air_totem(PlayerbotAI* ai) { return new WrathOfAirTotemTrigger(ai); } static Trigger* set_tremor_totem(PlayerbotAI* ai) { return new SetTremorTotemTrigger(ai); }
static Trigger* set_earthbind_totem(PlayerbotAI* ai) { return new SetEarthbindTotemTrigger(ai); }
static Trigger* set_searing_totem(PlayerbotAI* ai) { return new SetSearingTotemTrigger(ai); }
static Trigger* set_magma_totem(PlayerbotAI* ai) { return new SetMagmaTotemTrigger(ai); }
static Trigger* set_flametongue_totem(PlayerbotAI* ai) { return new SetFlametongueTotemTrigger(ai); }
static Trigger* set_totem_of_wrath(PlayerbotAI* ai) { return new SetTotemOfWrathTrigger(ai); }
static Trigger* set_frost_resistance_totem(PlayerbotAI* ai) { return new SetFrostResistanceTotemTrigger(ai); }
static Trigger* set_healing_stream_totem(PlayerbotAI* ai) { return new SetHealingStreamTotemTrigger(ai); }
static Trigger* set_mana_spring_totem(PlayerbotAI* ai) { return new SetManaSpringTotemTrigger(ai); }
static Trigger* set_cleansing_totem(PlayerbotAI* ai) { return new SetCleansingTotemTrigger(ai); }
static Trigger* set_fire_resistance_totem(PlayerbotAI* ai) { return new SetFireResistanceTotemTrigger(ai); }
static Trigger* set_wrath_of_air_totem(PlayerbotAI* ai) { return new SetWrathOfAirTotemTrigger(ai); }
static Trigger* set_windfury_totem(PlayerbotAI* ai) { return new SetWindfuryTotemTrigger(ai); }
static Trigger* set_nature_resistance_totem(PlayerbotAI* ai) { return new SetNatureResistanceTotemTrigger(ai); }
static Trigger* set_grounding_totem(PlayerbotAI* ai) { return new SetGroundingTotemTrigger(ai); }
}; };
class ShamanAiObjectContextInternal : public NamedObjectContext<Action> class ShamanAiObjectContextInternal : public NamedObjectContext<Action>
@@ -186,16 +265,6 @@ public:
{ {
creators["water shield"] = &ShamanAiObjectContextInternal::water_shield; creators["water shield"] = &ShamanAiObjectContextInternal::water_shield;
creators["lightning shield"] = &ShamanAiObjectContextInternal::lightning_shield; creators["lightning shield"] = &ShamanAiObjectContextInternal::lightning_shield;
creators["strength of earth totem"] = &ShamanAiObjectContextInternal::strength_of_earth_totem;
creators["flametongue totem"] = &ShamanAiObjectContextInternal::flametongue_totem;
creators["searing totem"] = &ShamanAiObjectContextInternal::searing_totem;
creators["magma totem"] = &ShamanAiObjectContextInternal::magma_totem;
creators["windfury totem"] = &ShamanAiObjectContextInternal::windfury_totem;
creators["grace of air totem"] = &ShamanAiObjectContextInternal::grace_of_air_totem;
creators["mana spring totem"] = &ShamanAiObjectContextInternal::mana_spring_totem;
creators["mana tide totem"] = &ShamanAiObjectContextInternal::mana_tide_totem;
creators["earthbind totem"] = &ShamanAiObjectContextInternal::earthbind_totem;
creators["healing stream totem"] = &ShamanAiObjectContextInternal::healing_stream_totem;
creators["wind shear"] = &ShamanAiObjectContextInternal::wind_shear; creators["wind shear"] = &ShamanAiObjectContextInternal::wind_shear;
creators["wind shear on enemy healer"] = &ShamanAiObjectContextInternal::wind_shear_on_enemy_healer; creators["wind shear on enemy healer"] = &ShamanAiObjectContextInternal::wind_shear_on_enemy_healer;
creators["rockbiter weapon"] = &ShamanAiObjectContextInternal::rockbiter_weapon; creators["rockbiter weapon"] = &ShamanAiObjectContextInternal::rockbiter_weapon;
@@ -240,12 +309,48 @@ public:
creators["cure poison on party"] = &ShamanAiObjectContextInternal::cure_poison_on_party; creators["cure poison on party"] = &ShamanAiObjectContextInternal::cure_poison_on_party;
creators["lava burst"] = &ShamanAiObjectContextInternal::lava_burst; creators["lava burst"] = &ShamanAiObjectContextInternal::lava_burst;
creators["earth shield on main tank"] = &ShamanAiObjectContextInternal::earth_shield_on_main_tank; creators["earth shield on main tank"] = &ShamanAiObjectContextInternal::earth_shield_on_main_tank;
creators["fire elemental totem"] = &ShamanAiObjectContextInternal::fire_elemental_totem;
creators["fire elemental totem melee"] = &ShamanAiObjectContextInternal::fire_elemental_totem_melee;
creators["totem of wrath"] = &ShamanAiObjectContextInternal::totem_of_wrath;
creators["wrath of air totem"] = &ShamanAiObjectContextInternal::wrath_of_air_totem;
creators["shamanistic rage"] = &ShamanAiObjectContextInternal::shamanistic_rage; creators["shamanistic rage"] = &ShamanAiObjectContextInternal::shamanistic_rage;
creators["feral spirit"] = &ShamanAiObjectContextInternal::feral_spirit; creators["feral spirit"] = &ShamanAiObjectContextInternal::feral_spirit;
creators["spirit walk"] = &ShamanAiObjectContextInternal::spirit_walk;
creators["call of the elements"] = &ShamanAiObjectContextInternal::call_of_the_elements;
creators["totemic recall"] = &ShamanAiObjectContextInternal::totemic_recall;
creators["strength of earth totem"] = &ShamanAiObjectContextInternal::strength_of_earth_totem;
creators["stoneskin totem"] = &ShamanAiObjectContextInternal::stoneskin_totem;
creators["tremor totem"] = &ShamanAiObjectContextInternal::tremor_totem;
creators["earthbind totem"] = &ShamanAiObjectContextInternal::earthbind_totem;
creators["stoneclaw totem"] = &ShamanAiObjectContextInternal::stoneclaw_totem;
creators["searing totem"] = &ShamanAiObjectContextInternal::searing_totem;
creators["magma totem"] = &ShamanAiObjectContextInternal::magma_totem;
creators["flametongue totem"] = &ShamanAiObjectContextInternal::flametongue_totem;
creators["totem of wrath"] = &ShamanAiObjectContextInternal::totem_of_wrath;
creators["frost resistance totem"] = &ShamanAiObjectContextInternal::frost_resistance_totem;
creators["fire elemental totem"] = &ShamanAiObjectContextInternal::fire_elemental_totem;
creators["fire elemental totem melee"] = &ShamanAiObjectContextInternal::fire_elemental_totem_melee;
creators["healing stream totem"] = &ShamanAiObjectContextInternal::healing_stream_totem;
creators["mana spring totem"] = &ShamanAiObjectContextInternal::mana_spring_totem;
creators["cleansing totem"] = &ShamanAiObjectContextInternal::cleansing_totem;
creators["mana tide totem"] = &ShamanAiObjectContextInternal::mana_tide_totem;
creators["fire resistance totem"] = &ShamanAiObjectContextInternal::fire_resistance_totem;
creators["wrath of air totem"] = &ShamanAiObjectContextInternal::wrath_of_air_totem;
creators["windfury totem"] = &ShamanAiObjectContextInternal::windfury_totem;
creators["nature resistance totem"] = &ShamanAiObjectContextInternal::nature_resistance_totem;
creators["set strength of earth totem"] = &ShamanAiObjectContextInternal::set_strength_of_earth_totem;
creators["set stoneskin totem"] = &ShamanAiObjectContextInternal::set_stoneskin_totem;
creators["set tremor totem"] = &ShamanAiObjectContextInternal::set_tremor_totem;
creators["set earthbind totem"] = &ShamanAiObjectContextInternal::set_earthbind_totem;
creators["set searing totem"] = &ShamanAiObjectContextInternal::set_searing_totem;
creators["set magma totem"] = &ShamanAiObjectContextInternal::set_magma_totem;
creators["set flametongue totem"] = &ShamanAiObjectContextInternal::set_flametongue_totem;
creators["set totem of wrath"] = &ShamanAiObjectContextInternal::set_totem_of_wrath;
creators["set frost resistance totem"] = &ShamanAiObjectContextInternal::set_frost_resistance_totem;
creators["set healing stream totem"] = &ShamanAiObjectContextInternal::set_healing_stream_totem;
creators["set mana spring totem"] = &ShamanAiObjectContextInternal::set_mana_spring_totem;
creators["set cleansing totem"] = &ShamanAiObjectContextInternal::set_cleansing_totem;
creators["set fire resistance totem"] = &ShamanAiObjectContextInternal::set_fire_resistance_totem;
creators["set wrath of air totem"] = &ShamanAiObjectContextInternal::set_wrath_of_air_totem;
creators["set windfury totem"] = &ShamanAiObjectContextInternal::set_windfury_totem;
creators["set nature resistance totem"] = &ShamanAiObjectContextInternal::set_nature_resistance_totem;
creators["set grounding totem"] = &ShamanAiObjectContextInternal::set_grounding_totem;
} }
private: private:
@@ -258,18 +363,9 @@ private:
static Action* frost_shock(PlayerbotAI* botAI) { return new CastFrostShockAction(botAI); } static Action* frost_shock(PlayerbotAI* botAI) { return new CastFrostShockAction(botAI); }
static Action* earth_shock(PlayerbotAI* botAI) { return new CastEarthShockAction(botAI); } static Action* earth_shock(PlayerbotAI* botAI) { return new CastEarthShockAction(botAI); }
static Action* flame_shock(PlayerbotAI* botAI) { return new CastFlameShockAction(botAI); } static Action* flame_shock(PlayerbotAI* botAI) { return new CastFlameShockAction(botAI); }
static Action* cleanse_spirit_poison_on_party(PlayerbotAI* botAI) static Action* cleanse_spirit_poison_on_party(PlayerbotAI* botAI) { return new CastCleanseSpiritPoisonOnPartyAction(botAI); }
{ static Action* cleanse_spirit_disease_on_party(PlayerbotAI* botAI) { return new CastCleanseSpiritDiseaseOnPartyAction(botAI); }
return new CastCleanseSpiritPoisonOnPartyAction(botAI); static Action* cleanse_spirit_curse_on_party(PlayerbotAI* botAI) { return new CastCleanseSpiritCurseOnPartyAction(botAI); }
}
static Action* cleanse_spirit_disease_on_party(PlayerbotAI* botAI)
{
return new CastCleanseSpiritDiseaseOnPartyAction(botAI);
}
static Action* cleanse_spirit_curse_on_party(PlayerbotAI* botAI)
{
return new CastCleanseSpiritCurseOnPartyAction(botAI);
}
static Action* cleanse_spirit(PlayerbotAI* botAI) { return new CastCleanseSpiritAction(botAI); } static Action* cleanse_spirit(PlayerbotAI* botAI) { return new CastCleanseSpiritAction(botAI); }
static Action* water_walking(PlayerbotAI* botAI) { return new CastWaterWalkingAction(botAI); } static Action* water_walking(PlayerbotAI* botAI) { return new CastWaterWalkingAction(botAI); }
static Action* water_breathing(PlayerbotAI* botAI) { return new CastWaterBreathingAction(botAI); } static Action* water_breathing(PlayerbotAI* botAI) { return new CastWaterBreathingAction(botAI); }
@@ -277,17 +373,7 @@ private:
static Action* water_breathing_on_party(PlayerbotAI* botAI) { return new CastWaterBreathingOnPartyAction(botAI); } static Action* water_breathing_on_party(PlayerbotAI* botAI) { return new CastWaterBreathingOnPartyAction(botAI); }
static Action* water_shield(PlayerbotAI* botAI) { return new CastWaterShieldAction(botAI); } static Action* water_shield(PlayerbotAI* botAI) { return new CastWaterShieldAction(botAI); }
static Action* lightning_shield(PlayerbotAI* botAI) { return new CastLightningShieldAction(botAI); } static Action* lightning_shield(PlayerbotAI* botAI) { return new CastLightningShieldAction(botAI); }
static Action* strength_of_earth_totem(PlayerbotAI* botAI) { return new CastStrengthOfEarthTotemAction(botAI); }
static Action* flametongue_totem(PlayerbotAI* botAI) { return new CastFlametongueTotemAction(botAI); }
static Action* magma_totem(PlayerbotAI* botAI) { return new CastMagmaTotemAction(botAI); }
static Action* searing_totem(PlayerbotAI* botAI) { return new CastSearingTotemAction(botAI); }
static Action* fire_nova(PlayerbotAI* botAI) { return new CastFireNovaAction(botAI); } static Action* fire_nova(PlayerbotAI* botAI) { return new CastFireNovaAction(botAI); }
static Action* windfury_totem(PlayerbotAI* botAI) { return new CastWindfuryTotemAction(botAI); }
static Action* grace_of_air_totem(PlayerbotAI* botAI) { return new CastGraceOfAirTotemAction(botAI); }
static Action* mana_spring_totem(PlayerbotAI* botAI) { return new CastManaSpringTotemAction(botAI); }
static Action* mana_tide_totem(PlayerbotAI* botAI) { return new CastManaTideTotemAction(botAI); }
static Action* earthbind_totem(PlayerbotAI* botAI) { return new CastEarthbindTotemAction(botAI); }
static Action* healing_stream_totem(PlayerbotAI* botAI) { return new CastHealingStreamTotemAction(botAI); }
static Action* wind_shear(PlayerbotAI* botAI) { return new CastWindShearAction(botAI); } static Action* wind_shear(PlayerbotAI* botAI) { return new CastWindShearAction(botAI); }
static Action* rockbiter_weapon(PlayerbotAI* botAI) { return new CastRockbiterWeaponAction(botAI); } static Action* rockbiter_weapon(PlayerbotAI* botAI) { return new CastRockbiterWeaponAction(botAI); }
static Action* flametongue_weapon(PlayerbotAI* botAI) { return new CastFlametongueWeaponAction(botAI); } static Action* flametongue_weapon(PlayerbotAI* botAI) { return new CastFlametongueWeaponAction(botAI); }
@@ -298,10 +384,7 @@ private:
static Action* healing_wave(PlayerbotAI* botAI) { return new CastHealingWaveAction(botAI); } static Action* healing_wave(PlayerbotAI* botAI) { return new CastHealingWaveAction(botAI); }
static Action* lesser_healing_wave(PlayerbotAI* botAI) { return new CastLesserHealingWaveAction(botAI); } static Action* lesser_healing_wave(PlayerbotAI* botAI) { return new CastLesserHealingWaveAction(botAI); }
static Action* healing_wave_on_party(PlayerbotAI* botAI) { return new CastHealingWaveOnPartyAction(botAI); } static Action* healing_wave_on_party(PlayerbotAI* botAI) { return new CastHealingWaveOnPartyAction(botAI); }
static Action* lesser_healing_wave_on_party(PlayerbotAI* botAI) static Action* lesser_healing_wave_on_party(PlayerbotAI* botAI) { return new CastLesserHealingWaveOnPartyAction(botAI); }
{
return new CastLesserHealingWaveOnPartyAction(botAI);
}
static Action* earth_shield(PlayerbotAI* botAI) { return new CastEarthShieldAction(botAI); } static Action* earth_shield(PlayerbotAI* botAI) { return new CastEarthShieldAction(botAI); }
static Action* earth_shield_on_party(PlayerbotAI* botAI) { return new CastEarthShieldOnPartyAction(botAI); } static Action* earth_shield_on_party(PlayerbotAI* botAI) { return new CastEarthShieldOnPartyAction(botAI); }
static Action* chain_heal(PlayerbotAI* botAI) { return new CastChainHealAction(botAI); } static Action* chain_heal(PlayerbotAI* botAI) { return new CastChainHealAction(botAI); }
@@ -310,22 +393,55 @@ private:
static Action* stormstrike(PlayerbotAI* botAI) { return new CastStormstrikeAction(botAI); } static Action* stormstrike(PlayerbotAI* botAI) { return new CastStormstrikeAction(botAI); }
static Action* lava_lash(PlayerbotAI* botAI) { return new CastLavaLashAction(botAI); } static Action* lava_lash(PlayerbotAI* botAI) { return new CastLavaLashAction(botAI); }
static Action* ancestral_spirit(PlayerbotAI* botAI) { return new CastAncestralSpiritAction(botAI); } static Action* ancestral_spirit(PlayerbotAI* botAI) { return new CastAncestralSpiritAction(botAI); }
static Action* wind_shear_on_enemy_healer(PlayerbotAI* botAI) static Action* wind_shear_on_enemy_healer(PlayerbotAI* botAI) { return new CastWindShearOnEnemyHealerAction(botAI); }
{
return new CastWindShearOnEnemyHealerAction(botAI);
}
static Action* cure_poison(PlayerbotAI* botAI) { return new CastCurePoisonActionSham(botAI); } static Action* cure_poison(PlayerbotAI* botAI) { return new CastCurePoisonActionSham(botAI); }
static Action* cure_poison_on_party(PlayerbotAI* botAI) { return new CastCurePoisonOnPartyActionSham(botAI); } static Action* cure_poison_on_party(PlayerbotAI* botAI) { return new CastCurePoisonOnPartyActionSham(botAI); }
static Action* cure_disease(PlayerbotAI* botAI) { return new CastCureDiseaseActionSham(botAI); } static Action* cure_disease(PlayerbotAI* botAI) { return new CastCureDiseaseActionSham(botAI); }
static Action* cure_disease_on_party(PlayerbotAI* botAI) { return new CastCureDiseaseOnPartyActionSham(botAI); } static Action* cure_disease_on_party(PlayerbotAI* botAI) { return new CastCureDiseaseOnPartyActionSham(botAI); }
static Action* lava_burst(PlayerbotAI* ai) { return new CastLavaBurstAction(ai); } static Action* lava_burst(PlayerbotAI* ai) { return new CastLavaBurstAction(ai); }
static Action* earth_shield_on_main_tank(PlayerbotAI* ai) { return new CastEarthShieldOnMainTankAction(ai); } static Action* earth_shield_on_main_tank(PlayerbotAI* ai) { return new CastEarthShieldOnMainTankAction(ai); }
static Action* totem_of_wrath(PlayerbotAI* ai) { return new CastTotemOfWrathAction(ai); }
static Action* fire_elemental_totem(PlayerbotAI* ai) { return new CastFireElementalTotemAction(ai); }
static Action* fire_elemental_totem_melee(PlayerbotAI* ai) { return new CastFireElementalTotemMeleeAction(ai); }
static Action* wrath_of_air_totem(PlayerbotAI* ai) { return new CastWrathOfAirTotemAction(ai); }
static Action* shamanistic_rage(PlayerbotAI* ai) { return new CastShamanisticRageAction(ai); } static Action* shamanistic_rage(PlayerbotAI* ai) { return new CastShamanisticRageAction(ai); }
static Action* feral_spirit(PlayerbotAI* ai) { return new CastFeralSpiritAction(ai); } static Action* feral_spirit(PlayerbotAI* ai) { return new CastFeralSpiritAction(ai); }
static Action* spirit_walk(PlayerbotAI* ai) { return new CastSpiritWalkAction(ai); }
static Action* call_of_the_elements(PlayerbotAI* ai) { return new CastCallOfTheElementsAction(ai); }
static Action* totemic_recall(PlayerbotAI* ai) { return new CastTotemicRecallAction(ai); }
static Action* strength_of_earth_totem(PlayerbotAI* ai) { return new CastStrengthOfEarthTotemAction(ai); }
static Action* stoneskin_totem(PlayerbotAI* ai) { return new CastStoneskinTotemAction(ai); }
static Action* tremor_totem(PlayerbotAI* ai) { return new CastTremorTotemAction(ai); }
static Action* earthbind_totem(PlayerbotAI* ai) { return new CastEarthbindTotemAction(ai); }
static Action* stoneclaw_totem(PlayerbotAI* ai) { return new CastStoneclawTotemAction(ai); }
static Action* searing_totem(PlayerbotAI* ai) { return new CastSearingTotemAction(ai); }
static Action* magma_totem(PlayerbotAI* ai) { return new CastMagmaTotemAction(ai); }
static Action* flametongue_totem(PlayerbotAI* ai) { return new CastFlametongueTotemAction(ai); }
static Action* totem_of_wrath(PlayerbotAI* ai) { return new CastTotemOfWrathAction(ai); }
static Action* frost_resistance_totem(PlayerbotAI* ai) { return new CastFrostResistanceTotemAction(ai); }
static Action* fire_elemental_totem(PlayerbotAI* ai) { return new CastFireElementalTotemAction(ai); }
static Action* fire_elemental_totem_melee(PlayerbotAI* ai) { return new CastFireElementalTotemMeleeAction(ai); }
static Action* healing_stream_totem(PlayerbotAI* ai) { return new CastHealingStreamTotemAction(ai); }
static Action* mana_spring_totem(PlayerbotAI* ai) { return new CastManaSpringTotemAction(ai); }
static Action* cleansing_totem(PlayerbotAI* ai) { return new CastCleansingTotemAction(ai); }
static Action* mana_tide_totem(PlayerbotAI* ai) { return new CastManaTideTotemAction(ai); }
static Action* fire_resistance_totem(PlayerbotAI* ai) { return new CastFireResistanceTotemAction(ai); }
static Action* wrath_of_air_totem(PlayerbotAI* ai) { return new CastWrathOfAirTotemAction(ai); }
static Action* windfury_totem(PlayerbotAI* ai) { return new CastWindfuryTotemAction(ai); }
static Action* nature_resistance_totem(PlayerbotAI* ai) { return new CastNatureResistanceTotemAction(ai); }
static Action* set_strength_of_earth_totem(PlayerbotAI* ai) { return new SetStrengthOfEarthTotemAction(ai); }
static Action* set_stoneskin_totem(PlayerbotAI* ai) { return new SetStoneskinTotemAction(ai); }
static Action* set_tremor_totem(PlayerbotAI* ai) { return new SetTremorTotemAction(ai); }
static Action* set_earthbind_totem(PlayerbotAI* ai) { return new SetEarthbindTotemAction(ai); }
static Action* set_searing_totem(PlayerbotAI* ai) { return new SetSearingTotemAction(ai); }
static Action* set_magma_totem(PlayerbotAI* ai) { return new SetMagmaTotemAction(ai); }
static Action* set_flametongue_totem(PlayerbotAI* ai) { return new SetFlametongueTotemAction(ai); }
static Action* set_totem_of_wrath(PlayerbotAI* ai) { return new SetTotemOfWrathAction(ai); }
static Action* set_frost_resistance_totem(PlayerbotAI* ai) { return new SetFrostResistanceTotemAction(ai); }
static Action* set_healing_stream_totem(PlayerbotAI* ai) { return new SetHealingStreamTotemAction(ai); }
static Action* set_mana_spring_totem(PlayerbotAI* ai) { return new SetManaSpringTotemAction(ai); }
static Action* set_cleansing_totem(PlayerbotAI* ai) { return new SetCleansingTotemAction(ai); }
static Action* set_fire_resistance_totem(PlayerbotAI* ai) { return new SetFireResistanceTotemAction(ai); }
static Action* set_wrath_of_air_totem(PlayerbotAI* ai) { return new SetWrathOfAirTotemAction(ai); }
static Action* set_windfury_totem(PlayerbotAI* ai) { return new SetWindfuryTotemAction(ai); }
static Action* set_nature_resistance_totem(PlayerbotAI* ai) { return new SetNatureResistanceTotemAction(ai); }
static Action* set_grounding_totem(PlayerbotAI* ai) { return new SetGroundingTotemAction(ai); }
}; };
SharedNamedObjectContextList<Strategy> ShamanAiObjectContext::sharedStrategyContexts; SharedNamedObjectContextList<Strategy> ShamanAiObjectContext::sharedStrategyContexts;
@@ -351,7 +467,10 @@ void ShamanAiObjectContext::BuildSharedStrategyContexts(SharedNamedObjectContext
AiObjectContext::BuildSharedStrategyContexts(strategyContexts); AiObjectContext::BuildSharedStrategyContexts(strategyContexts);
strategyContexts.Add(new ShamanStrategyFactoryInternal()); strategyContexts.Add(new ShamanStrategyFactoryInternal());
strategyContexts.Add(new ShamanCombatStrategyFactoryInternal()); strategyContexts.Add(new ShamanCombatStrategyFactoryInternal());
strategyContexts.Add(new ShamanBuffStrategyFactoryInternal()); strategyContexts.Add(new ShamanEarthTotemStrategyFactoryInternal());
strategyContexts.Add(new ShamanFireTotemStrategyFactoryInternal());
strategyContexts.Add(new ShamanWaterTotemStrategyFactoryInternal());
strategyContexts.Add(new ShamanAirTotemStrategyFactoryInternal());
} }
void ShamanAiObjectContext::BuildSharedActionContexts(SharedNamedObjectContextList<Action>& actionContexts) void ShamanAiObjectContext::BuildSharedActionContexts(SharedNamedObjectContextList<Action>& actionContexts)

View File

@@ -4,55 +4,120 @@
*/ */
#include "ShamanNonCombatStrategy.h" #include "ShamanNonCombatStrategy.h"
#include "AiFactory.h"
#include "Strategy.h"
#include "Playerbots.h" #include "Playerbots.h"
class ShamanNonCombatStrategyActionNodeFactory : public NamedObjectFactory<ActionNode>
{
public:
ShamanNonCombatStrategyActionNodeFactory()
{
creators["flametongue weapon"] = &flametongue_weapon;
creators["frostbrand weapon"] = &frostbrand_weapon;
creators["windfury weapon"] = &windfury_weapon;
creators["earthliving weapon"] = &earthliving_weapon;
creators["wind shear"] = &wind_shear;
creators["purge"] = &purge;
}
private:
static ActionNode* flametongue_weapon([[maybe_unused]] PlayerbotAI* botAI)
{
return new ActionNode("flametongue weapon",
/*P*/ nullptr,
/*A*/ NextAction::array(0, new NextAction("rockbiter weapon"), nullptr),
/*C*/ nullptr);
}
static ActionNode* frostbrand_weapon([[maybe_unused]] PlayerbotAI* botAI)
{
return new ActionNode("frostbrand weapon",
/*P*/ nullptr,
/*A*/ NextAction::array(0, new NextAction("flametongue weapon"), nullptr),
/*C*/ nullptr);
}
static ActionNode* windfury_weapon([[maybe_unused]] PlayerbotAI* botAI)
{
return new ActionNode("windfury weapon",
/*P*/ nullptr,
/*A*/ NextAction::array(0, new NextAction("flametongue weapon"), nullptr),
/*C*/ nullptr);
}
static ActionNode* earthliving_weapon([[maybe_unused]] PlayerbotAI* botAI)
{
return new ActionNode("earthliving weapon",
/*P*/ nullptr,
/*A*/ NextAction::array(0, new NextAction("flametongue weapon"), nullptr),
/*C*/ nullptr);
}
static ActionNode* wind_shear(PlayerbotAI*) { return new ActionNode("wind shear", nullptr, nullptr, nullptr); }
static ActionNode* purge(PlayerbotAI*) { return new ActionNode("purge", nullptr, nullptr, nullptr); }
};
ShamanNonCombatStrategy::ShamanNonCombatStrategy(PlayerbotAI* botAI) : NonCombatStrategy(botAI)
{
actionNodeFactories.Add(new ShamanNonCombatStrategyActionNodeFactory());
}
void ShamanNonCombatStrategy::InitTriggers(std::vector<TriggerNode*>& triggers) void ShamanNonCombatStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
{ {
NonCombatStrategy::InitTriggers(triggers); NonCombatStrategy::InitTriggers(triggers);
triggers.push_back( // Totemic Recall
new TriggerNode("party member dead", triggers.push_back(new TriggerNode("totemic recall", NextAction::array(0, new NextAction("totemic recall", 60.0f), nullptr)));
NextAction::array(0, new NextAction("ancestral spirit", ACTION_CRITICAL_HEAL + 10), nullptr)));
triggers.push_back(
new TriggerNode("water breathing", NextAction::array(0, new NextAction("water breathing", 12.0f), nullptr)));
triggers.push_back(
new TriggerNode("water walking", NextAction::array(0, new NextAction("water walking", 12.0f), nullptr)));
triggers.push_back(new TriggerNode(
"water breathing on party", NextAction::array(0, new NextAction("water breathing on party", 11.0f), nullptr)));
triggers.push_back(new TriggerNode("water walking on party",
NextAction::array(0, new NextAction("water walking on party", 11.0f), nullptr)));
triggers.push_back(new TriggerNode("party member critical health",
NextAction::array(0, new NextAction("riptide on party", 31.0f),
new NextAction("healing wave on party", 30.0f), NULL)));
triggers.push_back(new TriggerNode("party member low health", // Healing/Resurrect Triggers
NextAction::array(0, new NextAction("riptide on party", 29.0f), triggers.push_back(new TriggerNode("party member dead", NextAction::array(0, new NextAction("ancestral spirit", ACTION_CRITICAL_HEAL + 10), nullptr)));
new NextAction("healing wave on party", 28.0f), NULL))); triggers.push_back(new TriggerNode("party member critical health", NextAction::array(0,
new NextAction("riptide on party", 31.0f),
new NextAction("healing wave on party", 30.0f), NULL)));
triggers.push_back(new TriggerNode("party member low health",NextAction::array(0,
new NextAction("riptide on party", 29.0f),
new NextAction("healing wave on party", 28.0f), NULL)));
triggers.push_back(new TriggerNode("party member medium health",NextAction::array(0,
new NextAction("riptide on party", 27.0f),
new NextAction("healing wave on party", 26.0f), NULL)));
triggers.push_back(new TriggerNode("party member almost full health",NextAction::array(0,
new NextAction("riptide on party", 25.0f),
new NextAction("lesser healing wave on party", 24.0f), NULL)));
triggers.push_back(new TriggerNode("group heal setting",NextAction::array(0, new NextAction("chain heal on party", 27.0f), NULL)));
triggers.push_back(new TriggerNode("party member medium health", // Cure Triggers
NextAction::array(0, new NextAction("riptide on party", 27.0f), triggers.push_back(new TriggerNode("cure poison", NextAction::array(0, new NextAction("cure poison", 21.0f), nullptr)));
new NextAction("healing wave on party", 26.0f), NULL))); triggers.push_back(new TriggerNode("party member cure poison", NextAction::array(0, new NextAction("cure poison on party", 21.0f), nullptr)));
triggers.push_back(new TriggerNode("cure disease", NextAction::array(0, new NextAction("cure disease", 31.0f), nullptr)));
triggers.push_back(new TriggerNode("party member cure disease", NextAction::array(0, new NextAction("cure disease on party", 30.0f), nullptr)));
triggers.push_back(new TriggerNode("party member almost full health", // Out of Combat Buff Triggers
NextAction::array(0, new NextAction("riptide on party", 25.0f), Player* bot = botAI->GetBot();
new NextAction("lesser healing wave on party", 24.0f), NULL))); int tab = AiFactory::GetPlayerSpecTab(bot);
triggers.push_back( if (tab == 0) // Elemental
new TriggerNode("group heal setting", NextAction::array(0, new NextAction("chain heal on party", 27.0f), NULL))); {
triggers.push_back(new TriggerNode("main hand weapon no imbue", NextAction::array(0, new NextAction("flametongue weapon", 22.0f), nullptr)));
triggers.push_back(new TriggerNode("water shield", NextAction::array(0, new NextAction("water shield", 21.0f), nullptr)));
}
else if (tab == 1) // Enhancement
{
triggers.push_back(new TriggerNode("main hand weapon no imbue", NextAction::array(0, new NextAction("windfury weapon", 22.0f), nullptr)));
triggers.push_back(new TriggerNode("off hand weapon no imbue", NextAction::array(0, new NextAction("flametongue weapon", 21.0f), nullptr)));
triggers.push_back(new TriggerNode("lightning shield", NextAction::array(0, new NextAction("lightning shield", 20.0f), nullptr)));
}
else if (tab == 2) // Restoration
{
triggers.push_back(new TriggerNode("main hand weapon no imbue",NextAction::array(0, new NextAction("earthliving weapon", 22.0f), nullptr)));
triggers.push_back(new TriggerNode("water shield", NextAction::array(0, new NextAction("water shield", 20.0f), nullptr)));
}
triggers.push_back( // Buff Triggers while swimming
new TriggerNode("cure poison", NextAction::array(0, new NextAction("cure poison", 21.0f), nullptr))); triggers.push_back(new TriggerNode("water breathing", NextAction::array(0, new NextAction("water breathing", 12.0f), nullptr)));
triggers.push_back(new TriggerNode("party member cure poison", triggers.push_back(new TriggerNode("water walking", NextAction::array(0, new NextAction("water walking", 12.0f), nullptr)));
NextAction::array(0, new NextAction("cure poison on party", 21.0f), nullptr))); triggers.push_back(new TriggerNode("water breathing on party", NextAction::array(0, new NextAction("water breathing on party", 11.0f), nullptr)));
triggers.push_back( triggers.push_back(new TriggerNode("water walking on party", NextAction::array(0, new NextAction("water walking on party", 11.0f), nullptr)));
new TriggerNode("cure disease", NextAction::array(0, new NextAction("cure disease", 31.0f), nullptr)));
triggers.push_back(new TriggerNode("party member cure disease", // Pet Triggers
NextAction::array(0, new NextAction("cure disease on party", 30.0f), nullptr))); triggers.push_back(new TriggerNode("has pet", NextAction::array(0, new NextAction("toggle pet spell", 60.0f), nullptr)));
triggers.push_back( triggers.push_back(new TriggerNode("new pet", NextAction::array(0, new NextAction("set pet stance", 65.0f), nullptr)));
new TriggerNode("has pet", NextAction::array(0, new NextAction("toggle pet spell", 60.0f), nullptr)));
triggers.push_back(
new TriggerNode("new pet", NextAction::array(0, new NextAction("set pet stance", 65.0f), nullptr)));
} }
void ShamanNonCombatStrategy::InitMultipliers(std::vector<Multiplier*>& multipliers) void ShamanNonCombatStrategy::InitMultipliers(std::vector<Multiplier*>& multipliers)

View File

@@ -13,7 +13,7 @@ class PlayerbotAI;
class ShamanNonCombatStrategy : public NonCombatStrategy class ShamanNonCombatStrategy : public NonCombatStrategy
{ {
public: public:
ShamanNonCombatStrategy(PlayerbotAI* botAI) : NonCombatStrategy(botAI) {} ShamanNonCombatStrategy(PlayerbotAI* botAI);
void InitTriggers(std::vector<TriggerNode*>& triggers) override; void InitTriggers(std::vector<TriggerNode*>& triggers) override;
void InitMultipliers(std::vector<Multiplier*>& multipliers) override; void InitMultipliers(std::vector<Multiplier*>& multipliers) override;

View File

@@ -4,37 +4,15 @@
*/ */
#include "ShamanTriggers.h" #include "ShamanTriggers.h"
#include "Player.h"
#include "PlayerbotAI.h"
#include "ItemTemplate.h" #include "ItemTemplate.h"
#include "Playerbots.h" #include "Playerbots.h"
#include "TotemsShamanStrategy.h"
/* #include "InstanceScript.h"
std::vector<std::string> ShamanWeaponTrigger::spells; #include "Creature.h"
#include "Unit.h"
bool ShamanWeaponTrigger::IsActive() #include <ctime>
{
if (spells.empty())
{
spells.push_back("frostbrand weapon");
spells.push_back("rockbiter weapon");
spells.push_back("flametongue weapon");
spells.push_back("earthliving weapon");
spells.push_back("windfury weapon");
}
for (std::vector<std::string>::iterator i = spells.begin(); i != spells.end(); ++i)
{
uint32 spellId = AI_VALUE2(uint32, "spell id", spell);
if (!spellId)
continue;
if (AI_VALUE2(Item*, "item for spell", spellId))
return true;
}
return false;
}
*/
bool MainHandWeaponNoImbueTrigger::IsActive() bool MainHandWeaponNoImbueTrigger::IsActive()
{ {
@@ -63,18 +41,30 @@ bool ShockTrigger::IsActive()
!botAI->HasAura("frost shock", GetTarget(), false, true); !botAI->HasAura("frost shock", GetTarget(), false, true);
} }
// Checks if the target's health is above 25%/1500 hp. Returns false if either are true.
// This logic exists to prevent the use of Earth Shock on bosses as an Elemental Shaman.
bool EarthShockExecuteTrigger::IsActive()
{
Unit* target = AI_VALUE(Unit*, "current target");
if (!target)
return false;
float percent = 100.0f * target->GetHealth() / target->GetMaxHealth();
if (percent >= 25.0f)
return false;
if (target->GetHealth() >= 1500)
return false;
return true;
}
bool TotemTrigger::IsActive() bool TotemTrigger::IsActive()
{ {
return AI_VALUE(uint8, "attacker count") >= attackerCount && !AI_VALUE2(bool, "has totem", name) && return AI_VALUE(uint8, "attacker count") >= attackerCount && !AI_VALUE2(bool, "has totem", name) &&
!botAI->HasAura(name, bot); !botAI->HasAura(name, bot);
} }
bool ManaSpringTotemTrigger::IsActive()
{
return AI_VALUE(uint8, "attacker count") >= attackerCount && !AI_VALUE2(bool, "has totem", "mana tide totem") &&
!AI_VALUE2(bool, "has totem", name);
}
bool WaterWalkingTrigger::IsActive() { return BuffTrigger::IsActive() && AI_VALUE2(bool, "swimming", "self target"); } bool WaterWalkingTrigger::IsActive() { return BuffTrigger::IsActive() && AI_VALUE2(bool, "swimming", "self target"); }
bool WaterBreathingTrigger::IsActive() { return BuffTrigger::IsActive() && AI_VALUE2(bool, "swimming", "self target"); } bool WaterBreathingTrigger::IsActive() { return BuffTrigger::IsActive() && AI_VALUE2(bool, "swimming", "self target"); }
@@ -89,21 +79,365 @@ bool WaterBreathingOnPartyTrigger::IsActive()
return BuffOnPartyTrigger::IsActive() && AI_VALUE2(bool, "swimming", "self target"); return BuffOnPartyTrigger::IsActive() && AI_VALUE2(bool, "swimming", "self target");
} }
// Checks if Chain Lightning is on Cooldown, and prevents activation if it is.
// This is to ensure that Elemental Mastery is used on Lava Burst (2.0 second cast),
// and not on Chain Lightning (1.5 second cast with talents).
bool ElementalMasteryTrigger::IsActive()
{
return bot->HasSpellCooldown(421);
}
// Checks if Sprit Wolves are out/if Spirit Walk buff is not on the bot/if the cooldown for Spirit Walk is ready.
// There is custom code for the Spirit Walk cooldown (32 seconds), since no working
// code exists in the AC/Playerbots repo for checking if a guardian's spell is on cooldown.
bool SpiritWalkTrigger::IsActive()
{
Player* bot = botAI->GetBot();
constexpr uint32 SPIRIT_WOLF = 29264;
constexpr uint32 SPIRIT_WALK = 58875;
constexpr int COOLDOWN_SECONDS = 32;
time_t now = time(nullptr);
if ((now - lastSpiritWalkTime) < COOLDOWN_SECONDS)
return false;
for (Unit* unit : bot->m_Controlled)
{
Creature* wolf = dynamic_cast<Creature*>(unit);
if (wolf && wolf->GetEntry() == SPIRIT_WOLF && wolf->IsAlive())
{
if (!bot->HasAura(SPIRIT_WALK))
{
lastSpiritWalkTime = now;
return true;
}
}
}
return false;
}
// Checks if the bot knows Call of the Elements, and prevents the trigger firing if it doesn't.
// Fires the trigger if at least 2 of the totem slots are empty or out of range.
bool CallOfTheElementsTrigger::IsActive()
{
if (!botAI->CanCastSpell(SPELL_CALL_OF_THE_ELEMENTS, bot, true))
{
return false;
}
int emptyCount = 0;
static const uint8 slots[] = {SUMMON_SLOT_TOTEM_EARTH, SUMMON_SLOT_TOTEM_FIRE, SUMMON_SLOT_TOTEM_WATER,
SUMMON_SLOT_TOTEM_AIR};
for (uint8 slot : slots)
{
ObjectGuid guid = bot->m_SummonSlot[slot];
bool possibleEmpty = false;
if (guid.IsEmpty())
{
possibleEmpty = true;
}
else
{
Creature* totem = bot->GetMap()->GetCreature(guid);
if (!totem || totem->GetDistance(bot) > 30.0f)
{
possibleEmpty = true;
}
}
if (!possibleEmpty)
{
continue;
}
if ((slot == SUMMON_SLOT_TOTEM_EARTH && bot->HasSpell(SPELL_STONESKIN_TOTEM_RANK_1)) ||
(slot == SUMMON_SLOT_TOTEM_FIRE && bot->HasSpell(SPELL_SEARING_TOTEM_RANK_1)) ||
(slot == SUMMON_SLOT_TOTEM_WATER && bot->HasSpell(SPELL_HEALING_STREAM_TOTEM_RANK_1)) ||
(slot == SUMMON_SLOT_TOTEM_AIR && bot->HasSpell(SPELL_NATURE_RESISTANCE_TOTEM_RANK_1)))
{
emptyCount++;
}
}
return emptyCount >= 2;
}
// Totemic Recall - Prevents the trigger firing under the following circumstances:
// 1. The bot does not have Totemic Recall (level 30).
// 2. The bot is in an instance and any boss encounter is in progress.
// 3. Any group member or their pet is in combat.
// 4. If Mana Tide Totem or Fire Elemental Totem is active and within 30 yards of the bot.
// 5. Finally, if any totem summon slot is not empty, the trigger will fire.
bool TotemicRecallTrigger::IsActive()
{
Player* bot = botAI->GetBot();
if (!bot->HasSpell(SPELL_TOTEMIC_RECALL))
return false;
Map* map = bot->GetMap();
if (map->IsDungeon())
{
InstanceScript* instance = ((InstanceMap*)map)->GetInstanceScript();
if (instance)
{
for (uint32 i = 0; i < instance->GetEncounterCount(); ++i)
{
if (instance->GetBossState(i) == IN_PROGRESS)
return false;
}
}
}
Group* group = bot->GetGroup();
if (group)
{
for (GroupReference* ref = group->GetFirstMember(); ref; ref = ref->next())
{
Player* member = ref->GetSource();
if (!member)
continue;
if (member->IsInCombat())
return false;
Pet* pet = member->GetPet();
if (pet && pet->IsInCombat())
return false;
}
}
ObjectGuid guid = bot->m_SummonSlot[SUMMON_SLOT_TOTEM_WATER];
if (!guid.IsEmpty())
{
Creature* totem = bot->GetMap()->GetCreature(guid);
uint32 currentSpell = 0;
if (totem)
currentSpell = totem->GetUInt32Value(UNIT_CREATED_BY_SPELL);
for (size_t i = 0; i < MANA_TIDE_TOTEM_COUNT; ++i)
{
if (currentSpell == MANA_TIDE_TOTEM[i] && totem && totem->GetDistance(bot) <= 30.0f)
return false;
}
}
guid = bot->m_SummonSlot[SUMMON_SLOT_TOTEM_FIRE];
if (!guid.IsEmpty())
{
Creature* totem = bot->GetMap()->GetCreature(guid);
uint32 currentSpell = 0;
if (totem)
currentSpell = totem->GetUInt32Value(UNIT_CREATED_BY_SPELL);
for (size_t i = 0; i < FIRE_ELEMENTAL_TOTEM_COUNT; ++i)
{
if (currentSpell == FIRE_ELEMENTAL_TOTEM[i] && totem && totem->GetDistance(bot) <= 30.0f)
return false;
}
}
return !bot->m_SummonSlot[SUMMON_SLOT_TOTEM_EARTH].IsEmpty() ||
!bot->m_SummonSlot[SUMMON_SLOT_TOTEM_FIRE].IsEmpty() ||
!bot->m_SummonSlot[SUMMON_SLOT_TOTEM_WATER].IsEmpty() ||
!bot->m_SummonSlot[SUMMON_SLOT_TOTEM_AIR].IsEmpty();
}
// Find the active totem strategy for this slot, and return the highest-rank spellId the bot knows for it
static uint32 GetRequiredTotemSpellId(PlayerbotAI* ai, const char* strategies[], const uint32* spellList[],
const size_t spellCounts[], size_t numStrategies)
{
Player* bot = ai->GetBot();
for (size_t i = 0; i < numStrategies; ++i)
{
if (ai->HasStrategy(strategies[i], BOT_STATE_COMBAT))
{
// Find the highest-rank spell the bot knows
for (size_t j = 0; j < spellCounts[i]; ++j)
{
if (bot->HasSpell(spellList[i][j]))
return spellList[i][j];
}
}
}
return 0; // No relevant strategy active, or bot doesn't know any rank
}
// Get the spellId of the currently summoned totem in the slot
static uint32 GetSummonedTotemSpellId(Player* bot, uint8 slot)
{
ObjectGuid guid = bot->m_SummonSlot[slot];
if (guid.IsEmpty())
return 0;
Creature* totem = bot->GetMap()->GetCreature(guid);
if (!totem)
return 0;
return totem->GetUInt32Value(UNIT_CREATED_BY_SPELL);
}
bool NoEarthTotemTrigger::IsActive()
{
// Check if the bot has Stoneskin Totem (required level 4) and prevents the trigger firing if it doesn't
if (!bot->HasSpell(SPELL_STONESKIN_TOTEM_RANK_1))
return false;
ObjectGuid guid = bot->m_SummonSlot[SUMMON_SLOT_TOTEM_EARTH];
Creature* totem = nullptr;
uint32 currentSpell = 0;
if (!guid.IsEmpty())
{
totem = bot->GetMap()->GetCreature(guid);
if (totem)
currentSpell = totem->GetUInt32Value(UNIT_CREATED_BY_SPELL);
}
// Define supported earth totem strategies for this slot:
static const char* names[] = {"strength of earth", "stoneskin", "tremor", "earthbind"};
static const uint32* spells[] = {STRENGTH_OF_EARTH_TOTEM, STONESKIN_TOTEM, TREMOR_TOTEM, EARTHBIND_TOTEM};
static const size_t counts[] = {STRENGTH_OF_EARTH_TOTEM_COUNT, STONESKIN_TOTEM_COUNT, TREMOR_TOTEM_COUNT,
EARTHBIND_TOTEM_COUNT};
uint32 requiredSpell = GetRequiredTotemSpellId(botAI, names, spells, counts, 4);
// EXCEPTION: If Stoneclaw Totem is out and in range, consider the slot "occupied" (do not fire the trigger)
for (size_t i = 0; i < STONECLAW_TOTEM_COUNT; ++i)
if (currentSpell == STONECLAW_TOTEM[i] && totem && totem->GetDistance(bot) <= 30.0f)
return false;
// If no relevant strategy, only care if the slot is empty or totem is too far away
if (!requiredSpell)
return guid.IsEmpty() || !totem || totem->GetDistance(bot) > 30.0f;
// Fire if slot is empty or wrong totem or totem is too far away
return !currentSpell || currentSpell != requiredSpell || !totem || totem->GetDistance(bot) > 30.0f;
}
bool NoFireTotemTrigger::IsActive() bool NoFireTotemTrigger::IsActive()
{ {
return !AI_VALUE2(bool, "has totem", "magma totem") && !AI_VALUE2(bool, "has totem", "flametongue totem") && // Check if the bot has Searing Totem (required level 10) and prevents the trigger firing if it doesn't
!AI_VALUE2(bool, "has totem", "searing totem") && !AI_VALUE2(bool, "has totem", "fire elemental totem") && if (!bot->HasSpell(SPELL_SEARING_TOTEM_RANK_1))
!AI_VALUE2(bool, "has totem", "frost resistance totem") && !AI_VALUE2(bool, "has totem", "totem of wrath"); return false;
ObjectGuid guid = bot->m_SummonSlot[SUMMON_SLOT_TOTEM_FIRE];
Creature* totem = nullptr;
uint32 currentSpell = 0;
if (!guid.IsEmpty())
{
totem = bot->GetMap()->GetCreature(guid);
if (totem)
currentSpell = totem->GetUInt32Value(UNIT_CREATED_BY_SPELL);
}
// Define supported fire totem strategies for this slot:
static const char* names[] = {"searing", "magma", "flametongue", "wrath", "frost resistance"};
static const uint32* spells[] = {SEARING_TOTEM, MAGMA_TOTEM, FLAMETONGUE_TOTEM, TOTEM_OF_WRATH,
FROST_RESISTANCE_TOTEM};
static const size_t counts[] = {SEARING_TOTEM_COUNT, MAGMA_TOTEM_COUNT, FLAMETONGUE_TOTEM_COUNT, TOTEM_OF_WRATH_COUNT,
FROST_RESISTANCE_TOTEM_COUNT};
uint32 requiredSpell = GetRequiredTotemSpellId(botAI, names, spells, counts, 5);
// EXCEPTION: If Fire Elemental is out and in range, consider the slot "occupied" (do not fire the trigger)
for (size_t i = 0; i < FIRE_ELEMENTAL_TOTEM_COUNT; ++i)
if (currentSpell == FIRE_ELEMENTAL_TOTEM[i] && totem && totem->GetDistance(bot) <= 30.0f)
return false;
// If no relevant strategy, only care if the slot is empty or totem is too far away
if (!requiredSpell)
return guid.IsEmpty() || !totem || totem->GetDistance(bot) > 30.0f;
// Fire if slot is empty or wrong totem or totem is too far away
return !currentSpell || currentSpell != requiredSpell || !totem || totem->GetDistance(bot) > 30.0f;
} }
bool NoWaterTotemTrigger::IsActive() bool NoWaterTotemTrigger::IsActive()
{ {
return !AI_VALUE2(bool, "has totem", "fire resistance totem") && !AI_VALUE2(bool, "has totem", "mana tide totem") && // Check if the bot has Healing Stream Totem (required level 20) and prevents the trigger firing if it doesn't
!AI_VALUE2(bool, "has totem", "cleansing totem") && !AI_VALUE2(bool, "has totem", "mana spring totem") && if (!bot->HasSpell(SPELL_HEALING_STREAM_TOTEM_RANK_1))
!AI_VALUE2(bool, "has totem", "healing stream totem"); return false;
ObjectGuid guid = bot->m_SummonSlot[SUMMON_SLOT_TOTEM_WATER];
Creature* totem = nullptr;
uint32 currentSpell = 0;
if (!guid.IsEmpty())
{
totem = bot->GetMap()->GetCreature(guid);
if (totem)
currentSpell = totem->GetUInt32Value(UNIT_CREATED_BY_SPELL);
}
// Define supported water totem strategies for this slot:
static const char* names[] = {"healing stream", "mana spring", "cleansing", "fire resistance"};
static const uint32* spells[] = {HEALING_STREAM_TOTEM, MANA_SPRING_TOTEM, CLEANSING_TOTEM, FIRE_RESISTANCE_TOTEM};
static const size_t counts[] = {HEALING_STREAM_TOTEM_COUNT, MANA_SPRING_TOTEM_COUNT, CLEANSING_TOTEM_COUNT,
FIRE_RESISTANCE_TOTEM_COUNT};
uint32 requiredSpell = GetRequiredTotemSpellId(botAI, names, spells, counts, 4);
// EXCEPTION: If Mana Tide is out and in range, consider the slot "occupied" (do not fire the trigger)
for (size_t i = 0; i < MANA_TIDE_TOTEM_COUNT; ++i)
if (currentSpell == MANA_TIDE_TOTEM[i] && totem && totem->GetDistance(bot) <= 30.0f)
return false;
// If no relevant strategy, only care if the slot is empty or totem is too far away
if (!requiredSpell)
return guid.IsEmpty() || !totem || totem->GetDistance(bot) > 30.0f;
// Fire if slot is empty or wrong totem or totem is too far away
return !currentSpell || currentSpell != requiredSpell || !totem || totem->GetDistance(bot) > 30.0f;
} }
bool NoAirTotemTrigger::IsActive() bool NoAirTotemTrigger::IsActive()
{ {
return !AI_VALUE2(bool, "has totem", "wrath of air totem") && !AI_VALUE2(bool, "has totem", "windfury totem"); // Check if the bot has Nature Resistance Totem (required level 30) and prevents the trigger firing if it doesn't
if (!bot->HasSpell(SPELL_NATURE_RESISTANCE_TOTEM_RANK_1))
return false;
ObjectGuid guid = bot->m_SummonSlot[SUMMON_SLOT_TOTEM_AIR];
Creature* totem = nullptr;
uint32 currentSpell = 0;
if (!guid.IsEmpty())
{
totem = bot->GetMap()->GetCreature(guid);
if (totem)
currentSpell = totem->GetUInt32Value(UNIT_CREATED_BY_SPELL);
}
// Define supported air totem strategies for this slot:
static const char* names[] = {"wrath of air", "windfury", "nature resistance", "grounding totem"};
static const uint32* spells[] = {WRATH_OF_AIR_TOTEM, WINDFURY_TOTEM, NATURE_RESISTANCE_TOTEM, GROUNDING_TOTEM};
static const size_t counts[] = {WRATH_OF_AIR_TOTEM_COUNT, WINDFURY_TOTEM_COUNT, NATURE_RESISTANCE_TOTEM_COUNT,
GROUNDING_TOTEM_COUNT};
uint32 requiredSpell = GetRequiredTotemSpellId(botAI, names, spells, counts, 3);
// If no relevant strategy, only care if the slot is empty or totem is too far away
if (!requiredSpell)
return guid.IsEmpty() || !totem || totem->GetDistance(bot) > 30.0f;
// Fire if slot is empty or wrong totem or totem is too far away
return !currentSpell || currentSpell != requiredSpell || !totem || totem->GetDistance(bot) > 30.0f;
}
bool SetTotemTrigger::IsActive()
{
if (!bot->HasSpell(SPELL_CALL_OF_THE_ELEMENTS))
return false;
if (!bot->HasSpell(requiredSpellId))
return false;
ActionButton const* button = bot->GetActionButton(actionButtonId);
if (!button || button->GetType() != ACTION_BUTTON_SPELL || button->GetAction() == 0)
return true;
size_t totemSpellIdsCount = sizeof(totemSpellIds) / sizeof(uint32);
for (size_t i = 0; i < totemSpellIdsCount; ++i)
{
if (button->GetAction() == totemSpellIds[i])
{
return false;
}
}
return true;
} }

View File

@@ -9,21 +9,36 @@
#include "CureTriggers.h" #include "CureTriggers.h"
#include "GenericTriggers.h" #include "GenericTriggers.h"
#include "SharedDefines.h" #include "SharedDefines.h"
#include "Trigger.h"
#include <set>
#include "TotemsShamanStrategy.h"
#include "Player.h"
#include "PlayerbotAI.h"
#include <ctime>
class PlayerbotAI; class PlayerbotAI;
/* // Buff and Out of Combat Triggers
class ShamanWeaponTrigger : public BuffTrigger
{
public:
ShamanWeaponTrigger(PlayerbotAI* botAI) : BuffTrigger(botAI, "rockbiter weapon", 2 * 2000) { }
bool IsActive() override; const uint32 SPELL_EARTHBIND_TOTEM_RANK_1 = 2484;
const uint32 SPELL_SEARING_TOTEM_RANK_1 = 3599;
private: const uint32 SPELL_WRATH_OF_AIR_TOTEM_RANK_1 = 3738;
static std::vector<std::string> spells; const uint32 SPELL_HEALING_STREAM_TOTEM_RANK_1 = 5394;
}; const uint32 SPELL_MANA_SPRING_TOTEM_RANK_1 = 5675;
*/ const uint32 SPELL_STONESKIN_TOTEM_RANK_1 = 8071;
const uint32 SPELL_STRENGTH_OF_EARTH_TOTEM_RANK_1 = 8075;
const uint32 SPELL_TREMOR_TOTEM_RANK_1 = 8143;
const uint32 SPELL_CLEANSING_TOTEM_RANK_1 = 8170;
const uint32 SPELL_GROUNDING_TOTEM_RANK_1 = 8177;
const uint32 SPELL_FROST_RESISTANCE_TOTEM_RANK_1 = 8181;
const uint32 SPELL_FIRE_RESISTANCE_TOTEM_RANK_1 = 8184;
const uint32 SPELL_MAGMA_TOTEM_RANK_1 = 8190;
const uint32 SPELL_FLAMETONGUE_TOTEM_RANK_1 = 8227;
const uint32 SPELL_WINDFURY_TOTEM_RANK_1 = 8512;
const uint32 SPELL_NATURE_RESISTANCE_TOTEM_RANK_1 = 10595;
const uint32 SPELL_TOTEM_OF_WRATH_RANK_1 = 30706;
const uint32 SPELL_TOTEMIC_RECALL = 36936;
const uint32 SPELL_CALL_OF_THE_ELEMENTS = 66842;
class MainHandWeaponNoImbueTrigger : public BuffTrigger class MainHandWeaponNoImbueTrigger : public BuffTrigger
{ {
@@ -39,76 +54,6 @@ public:
virtual bool IsActive(); virtual bool IsActive();
}; };
class TotemTrigger : public Trigger
{
public:
TotemTrigger(PlayerbotAI* botAI, std::string const spell, uint32 attackerCount = 0)
: Trigger(botAI, spell), attackerCount(attackerCount)
{
}
bool IsActive() override;
protected:
uint32 attackerCount;
};
class WindfuryTotemTrigger : public TotemTrigger
{
public:
WindfuryTotemTrigger(PlayerbotAI* botAI) : TotemTrigger(botAI, "windfury totem") {}
};
class GraceOfAirTotemTrigger : public TotemTrigger
{
public:
GraceOfAirTotemTrigger(PlayerbotAI* botAI) : TotemTrigger(botAI, "grace of air totem") {}
};
class ManaSpringTotemTrigger : public TotemTrigger
{
public:
ManaSpringTotemTrigger(PlayerbotAI* botAI) : TotemTrigger(botAI, "mana spring totem") {}
bool IsActive() override;
};
class FlametongueTotemTrigger : public TotemTrigger
{
public:
FlametongueTotemTrigger(PlayerbotAI* botAI) : TotemTrigger(botAI, "flametongue totem") {}
};
class StrengthOfEarthTotemTrigger : public TotemTrigger
{
public:
StrengthOfEarthTotemTrigger(PlayerbotAI* botAI) : TotemTrigger(botAI, "strength of earth totem") {}
};
class FireElementalTotemTrigger : public BoostTrigger
{
public:
FireElementalTotemTrigger(PlayerbotAI* botAI) : BoostTrigger(botAI, "fire elemental totem") {}
};
class MagmaTotemTrigger : public TotemTrigger
{
public:
MagmaTotemTrigger(PlayerbotAI* botAI) : TotemTrigger(botAI, "magma totem", 3) {}
};
class SearingTotemTrigger : public TotemTrigger
{
public:
SearingTotemTrigger(PlayerbotAI* botAI) : TotemTrigger(botAI, "searing totem", 1) {}
};
class WindShearInterruptSpellTrigger : public InterruptSpellTrigger
{
public:
WindShearInterruptSpellTrigger(PlayerbotAI* botAI) : InterruptSpellTrigger(botAI, "wind shear") {}
};
class WaterShieldTrigger : public BuffTrigger class WaterShieldTrigger : public BuffTrigger
{ {
public: public:
@@ -121,12 +66,6 @@ public:
LightningShieldTrigger(PlayerbotAI* botAI) : BuffTrigger(botAI, "lightning shield") {} LightningShieldTrigger(PlayerbotAI* botAI) : BuffTrigger(botAI, "lightning shield") {}
}; };
class PurgeTrigger : public TargetAuraDispelTrigger
{
public:
PurgeTrigger(PlayerbotAI* botAI) : TargetAuraDispelTrigger(botAI, "purge", DISPEL_MAGIC) {}
};
class WaterWalkingTrigger : public BuffTrigger class WaterWalkingTrigger : public BuffTrigger
{ {
public: public:
@@ -154,13 +93,70 @@ public:
class WaterBreathingOnPartyTrigger : public BuffOnPartyTrigger class WaterBreathingOnPartyTrigger : public BuffOnPartyTrigger
{ {
public: public:
WaterBreathingOnPartyTrigger(PlayerbotAI* botAI) : BuffOnPartyTrigger(botAI, "water breathing on party", 2 * 2000) WaterBreathingOnPartyTrigger(PlayerbotAI* botAI) : BuffOnPartyTrigger(botAI, "water breathing on party", 2 * 2000) {}
{
}
bool IsActive() override; bool IsActive() override;
}; };
// Boost Triggers
class HeroismTrigger : public BoostTrigger
{
public:
HeroismTrigger(PlayerbotAI* botAI) : BoostTrigger(botAI, "heroism") {}
};
class BloodlustTrigger : public BoostTrigger
{
public:
BloodlustTrigger(PlayerbotAI* botAI) : BoostTrigger(botAI, "bloodlust") {}
};
class ElementalMasteryTrigger : public BuffTrigger
{
public:
ElementalMasteryTrigger(PlayerbotAI* botAI) : BuffTrigger(botAI, "elemental mastery") {}
bool IsActive() override;
};
class SpiritWalkTrigger : public Trigger
{
public:
SpiritWalkTrigger(PlayerbotAI* ai) : Trigger(ai, "spirit walk ready") {}
bool IsActive() override;
private:
time_t lastSpiritWalkTime = 0;
};
class FireElementalTotemTrigger : public BoostTrigger
{
public:
FireElementalTotemTrigger(PlayerbotAI* botAI) : BoostTrigger(botAI, "fire elemental totem") {}
};
// CC, Interrupt, and Dispel Triggers
class WindShearInterruptSpellTrigger : public InterruptSpellTrigger
{
public:
WindShearInterruptSpellTrigger(PlayerbotAI* botAI) : InterruptSpellTrigger(botAI, "wind shear") {}
};
class WindShearInterruptEnemyHealerSpellTrigger : public InterruptEnemyHealerTrigger
{
public:
WindShearInterruptEnemyHealerSpellTrigger(PlayerbotAI* botAI) : InterruptEnemyHealerTrigger(botAI, "wind shear") {}
};
class PurgeTrigger : public TargetAuraDispelTrigger
{
public:
PurgeTrigger(PlayerbotAI* botAI) : TargetAuraDispelTrigger(botAI, "purge", DISPEL_MAGIC) {}
};
class CleanseSpiritPoisonTrigger : public NeedCureTrigger class CleanseSpiritPoisonTrigger : public NeedCureTrigger
{ {
public: public:
@@ -206,6 +202,33 @@ public:
} }
}; };
class CurePoisonTrigger : public NeedCureTrigger
{
public:
CurePoisonTrigger(PlayerbotAI* botAI) : NeedCureTrigger(botAI, "cure poison", DISPEL_POISON) {}
};
class PartyMemberCurePoisonTrigger : public PartyMemberNeedCureTrigger
{
public:
PartyMemberCurePoisonTrigger(PlayerbotAI* botAI) : PartyMemberNeedCureTrigger(botAI, "cure poison", DISPEL_POISON) {}
};
class CureDiseaseTrigger : public NeedCureTrigger
{
public:
CureDiseaseTrigger(PlayerbotAI* botAI) : NeedCureTrigger(botAI, "cure disease", DISPEL_DISEASE) {}
};
class PartyMemberCureDiseaseTrigger : public PartyMemberNeedCureTrigger
{
public:
PartyMemberCureDiseaseTrigger(PlayerbotAI* botAI)
: PartyMemberNeedCureTrigger(botAI, "cure disease", DISPEL_DISEASE) {}
};
// Damage and Debuff Triggers
class ShockTrigger : public DebuffTrigger class ShockTrigger : public DebuffTrigger
{ {
public: public:
@@ -220,63 +243,88 @@ public:
FrostShockSnareTrigger(PlayerbotAI* botAI) : SnareTargetTrigger(botAI, "frost shock") {} FrostShockSnareTrigger(PlayerbotAI* botAI) : SnareTargetTrigger(botAI, "frost shock") {}
}; };
class HeroismTrigger : public BoostTrigger
{
public:
HeroismTrigger(PlayerbotAI* botAI) : BoostTrigger(botAI, "heroism") {}
};
class BloodlustTrigger : public BoostTrigger
{
public:
BloodlustTrigger(PlayerbotAI* botAI) : BoostTrigger(botAI, "bloodlust") {}
};
class ElementalMasteryTrigger : public BoostTrigger
{
public:
ElementalMasteryTrigger(PlayerbotAI* botAI) : BoostTrigger(botAI, "elemental mastery") {}
};
class MaelstromWeaponTrigger : public HasAuraStackTrigger class MaelstromWeaponTrigger : public HasAuraStackTrigger
{ {
public: public:
MaelstromWeaponTrigger(PlayerbotAI* botAI, int stack = 5) : HasAuraStackTrigger(botAI, "maelstrom weapon", stack) {} MaelstromWeaponTrigger(PlayerbotAI* botAI, int stack = 5) : HasAuraStackTrigger(botAI, "maelstrom weapon", stack) {}
}; };
class WindShearInterruptEnemyHealerSpellTrigger : public InterruptEnemyHealerTrigger class FlameShockTrigger : public DebuffTrigger
{ {
public: public:
WindShearInterruptEnemyHealerSpellTrigger(PlayerbotAI* botAI) : InterruptEnemyHealerTrigger(botAI, "wind shear") {} FlameShockTrigger(PlayerbotAI* ai) : DebuffTrigger(ai, "flame shock", 1, true, 6.0f) {}
bool IsActive() override { return BuffTrigger::IsActive(); }
}; };
class CurePoisonTrigger : public NeedCureTrigger class EarthShockExecuteTrigger : public Trigger
{ {
public: public:
CurePoisonTrigger(PlayerbotAI* botAI) : NeedCureTrigger(botAI, "cure poison", DISPEL_POISON) {} EarthShockExecuteTrigger(PlayerbotAI* botAI) : Trigger(botAI, "earth shock execute") {}
bool IsActive() override;
}; };
class PartyMemberCurePoisonTrigger : public PartyMemberNeedCureTrigger class MaelstromWeapon5AndMediumAoeTrigger : public TwoTriggers
{ {
public: public:
PartyMemberCurePoisonTrigger(PlayerbotAI* botAI) : PartyMemberNeedCureTrigger(botAI, "cure poison", DISPEL_POISON) MaelstromWeapon5AndMediumAoeTrigger(PlayerbotAI* ai) : TwoTriggers(ai, "maelstrom weapon 5", "medium aoe") {}
};
class MaelstromWeapon4AndMediumAoeTrigger : public TwoTriggers
{
public:
MaelstromWeapon4AndMediumAoeTrigger(PlayerbotAI* ai) : TwoTriggers(ai, "maelstrom weapon 4", "medium aoe") {}
};
class ChainLightningNoCdTrigger : public SpellNoCooldownTrigger
{
public:
ChainLightningNoCdTrigger(PlayerbotAI* ai) : SpellNoCooldownTrigger(ai, "chain lightning") {}
};
// Healing Triggers
class EarthShieldOnMainTankTrigger : public BuffOnMainTankTrigger
{
public:
EarthShieldOnMainTankTrigger(PlayerbotAI* botAI) : BuffOnMainTankTrigger(botAI, "earth shield", false) {}
};
// Totem Triggers
class TotemTrigger : public Trigger
{
public:
TotemTrigger(PlayerbotAI* botAI, std::string const spell, uint32 attackerCount = 0)
: Trigger(botAI, spell), attackerCount(attackerCount)
{ {
} }
bool IsActive() override;
protected:
uint32 attackerCount;
}; };
class CureDiseaseTrigger : public NeedCureTrigger class CallOfTheElementsTrigger : public Trigger
{ {
public: public:
CureDiseaseTrigger(PlayerbotAI* botAI) : NeedCureTrigger(botAI, "cure disease", DISPEL_DISEASE) {} CallOfTheElementsTrigger(PlayerbotAI* ai) : Trigger(ai, "call of the elements") {}
bool IsActive() override;
}; };
class PartyMemberCureDiseaseTrigger : public PartyMemberNeedCureTrigger class TotemicRecallTrigger : public Trigger
{ {
public: public:
PartyMemberCureDiseaseTrigger(PlayerbotAI* botAI) TotemicRecallTrigger(PlayerbotAI* ai) : Trigger(ai, "totemic recall") {}
: PartyMemberNeedCureTrigger(botAI, "cure disease", DISPEL_DISEASE) bool IsActive() override;
{ };
}
class NoEarthTotemTrigger : public Trigger
{
public:
NoEarthTotemTrigger(PlayerbotAI* ai) : Trigger(ai, "no earth totem") {}
bool IsActive() override;
}; };
class NoFireTotemTrigger : public Trigger class NoFireTotemTrigger : public Trigger
@@ -293,28 +341,155 @@ public:
bool IsActive() override; bool IsActive() override;
}; };
class EarthShieldOnMainTankTrigger : public BuffOnMainTankTrigger class NoAirTotemTrigger : public Trigger
{ {
public: public:
EarthShieldOnMainTankTrigger(PlayerbotAI* botAI) : BuffOnMainTankTrigger(botAI, "earth shield", false) {} NoAirTotemTrigger(PlayerbotAI* ai) : Trigger(ai, "no air totem") {}
};
class FlameShockTrigger : public DebuffTrigger
{
public:
FlameShockTrigger(PlayerbotAI* ai) : DebuffTrigger(ai, "flame shock", 1, true, 6.0f) {}
};
class WrathOfAirTotemTrigger : public TotemTrigger
{
public:
WrathOfAirTotemTrigger(PlayerbotAI* ai) : TotemTrigger(ai, "wrath of air totem") {}
};
class NoAirTotemTrigger : public TotemTrigger
{
public:
NoAirTotemTrigger(PlayerbotAI* ai) : TotemTrigger(ai, "no air totem") {}
bool IsActive() override; bool IsActive() override;
}; };
class CallOfTheElementsAndEnemyWithinMeleeTrigger : public TwoTriggers
{
public:
CallOfTheElementsAndEnemyWithinMeleeTrigger(PlayerbotAI* ai) : TwoTriggers(ai, "call of the elements", "enemy within melee") {}
};
// Set Strategy Assigned Totems
class SetTotemTrigger : public Trigger
{
public:
SetTotemTrigger(PlayerbotAI* ai, std::string const spellName, const uint32 requiredSpellId,
const uint32 totemSpellIds[], int actionButtonId)
: Trigger(ai, "set " + spellName),
requiredSpellId(requiredSpellId),
totemSpellIds(totemSpellIds),
actionButtonId(actionButtonId) {}
bool IsActive() override;
private:
uint32 requiredSpellId;
uint32 const* totemSpellIds;
int actionButtonId;
};
class SetStrengthOfEarthTotemTrigger : public SetTotemTrigger
{
public:
SetStrengthOfEarthTotemTrigger(PlayerbotAI* ai)
: SetTotemTrigger(ai, "strength of earth totem", SPELL_STRENGTH_OF_EARTH_TOTEM_RANK_1, STRENGTH_OF_EARTH_TOTEM, TOTEM_BAR_SLOT_EARTH) {}
};
class SetStoneskinTotemTrigger : public SetTotemTrigger
{
public:
SetStoneskinTotemTrigger(PlayerbotAI* ai)
: SetTotemTrigger(ai, "stoneskin totem", SPELL_STONESKIN_TOTEM_RANK_1, STONESKIN_TOTEM, TOTEM_BAR_SLOT_EARTH) {}
};
class SetTremorTotemTrigger : public SetTotemTrigger
{
public:
SetTremorTotemTrigger(PlayerbotAI* ai)
: SetTotemTrigger(ai, "tremor totem", SPELL_TREMOR_TOTEM_RANK_1, TREMOR_TOTEM, TOTEM_BAR_SLOT_EARTH) {}
};
class SetEarthbindTotemTrigger : public SetTotemTrigger
{
public:
SetEarthbindTotemTrigger(PlayerbotAI* ai)
: SetTotemTrigger(ai, "earthbind totem", SPELL_EARTHBIND_TOTEM_RANK_1, EARTHBIND_TOTEM, TOTEM_BAR_SLOT_EARTH) {}
};
class SetSearingTotemTrigger : public SetTotemTrigger
{
public:
SetSearingTotemTrigger(PlayerbotAI* ai)
: SetTotemTrigger(ai, "searing totem", SPELL_SEARING_TOTEM_RANK_1, SEARING_TOTEM, TOTEM_BAR_SLOT_FIRE) {}
};
class SetMagmaTotemTrigger : public SetTotemTrigger
{
public:
SetMagmaTotemTrigger(PlayerbotAI* ai)
: SetTotemTrigger(ai, "magma totem", SPELL_MAGMA_TOTEM_RANK_1, MAGMA_TOTEM, TOTEM_BAR_SLOT_FIRE) {}
};
class SetFlametongueTotemTrigger : public SetTotemTrigger
{
public:
SetFlametongueTotemTrigger(PlayerbotAI* ai)
: SetTotemTrigger(ai, "flametongue totem", SPELL_FLAMETONGUE_TOTEM_RANK_1, FLAMETONGUE_TOTEM, TOTEM_BAR_SLOT_FIRE) {}
};
class SetTotemOfWrathTrigger : public SetTotemTrigger
{
public:
SetTotemOfWrathTrigger(PlayerbotAI* ai)
: SetTotemTrigger(ai, "totem of wrath", SPELL_TOTEM_OF_WRATH_RANK_1, TOTEM_OF_WRATH, TOTEM_BAR_SLOT_FIRE) {}
};
class SetFrostResistanceTotemTrigger : public SetTotemTrigger
{
public:
SetFrostResistanceTotemTrigger(PlayerbotAI* ai)
: SetTotemTrigger(ai, "frost resistance totem", SPELL_FROST_RESISTANCE_TOTEM_RANK_1, FROST_RESISTANCE_TOTEM, TOTEM_BAR_SLOT_FIRE) {}
};
class SetHealingStreamTotemTrigger : public SetTotemTrigger
{
public:
SetHealingStreamTotemTrigger(PlayerbotAI* ai)
: SetTotemTrigger(ai, "healing stream totem", SPELL_HEALING_STREAM_TOTEM_RANK_1, HEALING_STREAM_TOTEM, TOTEM_BAR_SLOT_WATER) {}
};
class SetManaSpringTotemTrigger : public SetTotemTrigger
{
public:
SetManaSpringTotemTrigger(PlayerbotAI* ai)
: SetTotemTrigger(ai, "mana spring totem", SPELL_MANA_SPRING_TOTEM_RANK_1, MANA_SPRING_TOTEM, TOTEM_BAR_SLOT_WATER) {}
};
class SetCleansingTotemTrigger : public SetTotemTrigger
{
public:
SetCleansingTotemTrigger(PlayerbotAI* ai)
: SetTotemTrigger(ai, "cleansing totem", SPELL_CLEANSING_TOTEM_RANK_1, CLEANSING_TOTEM, TOTEM_BAR_SLOT_WATER) {}
};
class SetFireResistanceTotemTrigger : public SetTotemTrigger
{
public:
SetFireResistanceTotemTrigger(PlayerbotAI* ai)
: SetTotemTrigger(ai, "fire resistance totem", SPELL_FIRE_RESISTANCE_TOTEM_RANK_1, FIRE_RESISTANCE_TOTEM, TOTEM_BAR_SLOT_WATER) {}
};
class SetWrathOfAirTotemTrigger : public SetTotemTrigger
{
public:
SetWrathOfAirTotemTrigger(PlayerbotAI* ai)
: SetTotemTrigger(ai, "wrath of air totem", SPELL_WRATH_OF_AIR_TOTEM_RANK_1, WRATH_OF_AIR_TOTEM, TOTEM_BAR_SLOT_AIR) {}
};
class SetWindfuryTotemTrigger : public SetTotemTrigger
{
public:
SetWindfuryTotemTrigger(PlayerbotAI* ai)
: SetTotemTrigger(ai, "windfury totem", SPELL_WINDFURY_TOTEM_RANK_1, WINDFURY_TOTEM, TOTEM_BAR_SLOT_AIR) {}
};
class SetNatureResistanceTotemTrigger : public SetTotemTrigger
{
public:
SetNatureResistanceTotemTrigger(PlayerbotAI* ai)
: SetTotemTrigger(ai, "nature resistance totem", SPELL_NATURE_RESISTANCE_TOTEM_RANK_1, NATURE_RESISTANCE_TOTEM, TOTEM_BAR_SLOT_AIR) {}
};
class SetGroundingTotemTrigger : public SetTotemTrigger
{
public:
SetGroundingTotemTrigger(PlayerbotAI* ai)
: SetTotemTrigger(ai, "grounding totem", SPELL_GROUNDING_TOTEM_RANK_1, GROUNDING_TOTEM, TOTEM_BAR_SLOT_AIR) {}
};
#endif #endif

View File

@@ -4,22 +4,185 @@
*/ */
#include "TotemsShamanStrategy.h" #include "TotemsShamanStrategy.h"
#include "Playerbots.h" #include "Playerbots.h"
TotemsShamanStrategy::TotemsShamanStrategy(PlayerbotAI* botAI) : GenericShamanStrategy(botAI) {} // These combat strategies are used to set the corresponding totems on the bar, and cast the totem when it's missing.
// There are special cases for Totem of Wrath, Windfury Totem, Wrath of Air totem, and Cleansing totem - these totems
// aren't learned at level 30, and have fallbacks in order to prevent the trigger from continuously firing.
void TotemsShamanStrategy::InitTriggers(std::vector<TriggerNode*>& triggers) // Earth Totems
StrengthOfEarthTotemStrategy::StrengthOfEarthTotemStrategy(PlayerbotAI* botAI) : GenericShamanStrategy(botAI) {}
void StrengthOfEarthTotemStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
{ {
GenericShamanStrategy::InitTriggers(triggers); GenericShamanStrategy::InitTriggers(triggers);
triggers.push_back(new TriggerNode("set strength of earth totem", NextAction::array(0, new NextAction("set strength of earth totem", 60.0f), nullptr)));
triggers.push_back( triggers.push_back(new TriggerNode("no earth totem", NextAction::array(0, new NextAction("strength of earth totem", 55.0f), nullptr)));
new TriggerNode("no air totem", NextAction::array(0, new NextAction("wrath of air totem", 8.0f), nullptr))); }
triggers.push_back( StoneclawTotemStrategy::StoneclawTotemStrategy(PlayerbotAI* botAI) : GenericShamanStrategy(botAI) {}
new TriggerNode("no water totem", NextAction::array(0, new NextAction("mana spring totem", 7.0f), void StoneclawTotemStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
new NextAction("healing stream totem", 6.0f), nullptr))); {
GenericShamanStrategy::InitTriggers(triggers);
triggers.push_back(new TriggerNode("strength of earth totem", triggers.push_back(new TriggerNode("set stoneskin totem", NextAction::array(0, new NextAction("set stoneskin totem", 60.0f), nullptr)));
NextAction::array(0, new NextAction("strength of earth totem", 6.0f), nullptr))); triggers.push_back(new TriggerNode("no earth totem", NextAction::array(0, new NextAction("stoneskin totem", 55.0f), nullptr)));
}
EarthTotemStrategy::EarthTotemStrategy(PlayerbotAI* botAI) : GenericShamanStrategy(botAI) {}
void EarthTotemStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
{
GenericShamanStrategy::InitTriggers(triggers);
triggers.push_back(new TriggerNode("set tremor totem", NextAction::array(0, new NextAction("set tremor totem", 60.0f), nullptr)));
triggers.push_back(new TriggerNode("no earth totem", NextAction::array(0, new NextAction("tremor totem", 55.0f), nullptr)));
}
EarthbindTotemStrategy::EarthbindTotemStrategy(PlayerbotAI* botAI) : GenericShamanStrategy(botAI) {}
void EarthbindTotemStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
{
GenericShamanStrategy::InitTriggers(triggers);
triggers.push_back(new TriggerNode("set earthbind totem", NextAction::array(0, new NextAction("set earthbind totem", 60.0f), nullptr)));
triggers.push_back(new TriggerNode("no earth totem", NextAction::array(0, new NextAction("earthbind totem", 55.0f), nullptr)));
}
// Fire Totems
SearingTotemStrategy::SearingTotemStrategy(PlayerbotAI* botAI) : GenericShamanStrategy(botAI) {}
void SearingTotemStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
{
GenericShamanStrategy::InitTriggers(triggers);
triggers.push_back(new TriggerNode("set searing totem", NextAction::array(0, new NextAction("set searing totem", 60.0f), nullptr)));
triggers.push_back(new TriggerNode("no fire totem", NextAction::array(0, new NextAction("searing totem", 55.0f), nullptr)));
}
MagmaTotemStrategy::MagmaTotemStrategy(PlayerbotAI* botAI) : GenericShamanStrategy(botAI) {}
void MagmaTotemStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
{
GenericShamanStrategy::InitTriggers(triggers);
triggers.push_back(new TriggerNode("set magma totem", NextAction::array(0, new NextAction("set magma totem", 60.0f), nullptr)));
triggers.push_back(new TriggerNode("no fire totem", NextAction::array(0, new NextAction("magma totem", 55.0f), nullptr)));
}
FlametongueTotemStrategy::FlametongueTotemStrategy(PlayerbotAI* botAI) : GenericShamanStrategy(botAI) {}
void FlametongueTotemStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
{
GenericShamanStrategy::InitTriggers(triggers);
triggers.push_back(new TriggerNode("set flametongue totem", NextAction::array(0, new NextAction("set flametongue totem", 60.0f), nullptr)));
triggers.push_back(new TriggerNode("no fire totem", NextAction::array(0, new NextAction("flametongue totem", 55.0f), nullptr)));
}
TotemOfWrathStrategy::TotemOfWrathStrategy(PlayerbotAI* botAI) : GenericShamanStrategy(botAI) {}
void TotemOfWrathStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
{
GenericShamanStrategy::InitTriggers(triggers);
// If the bot hasn't learned Totem of Wrath yet, set Flametongue Totem instead.
Player* bot = botAI->GetBot();
if (bot->HasSpell(30706))
{
triggers.push_back(new TriggerNode("set totem of wrath", NextAction::array(0, new NextAction("set totem of wrath", 60.0f), nullptr)));
}
else if (bot->HasSpell(8227))
{
triggers.push_back(new TriggerNode("set flametongue totem", NextAction::array(0, new NextAction("set flametongue totem", 60.0f), nullptr)));
}
triggers.push_back(new TriggerNode("no fire totem", NextAction::array(0, new NextAction("totem of wrath", 55.0f), nullptr)));
}
FrostResistanceTotemStrategy::FrostResistanceTotemStrategy(PlayerbotAI* botAI) : GenericShamanStrategy(botAI) {}
void FrostResistanceTotemStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
{
GenericShamanStrategy::InitTriggers(triggers);
triggers.push_back(new TriggerNode("set frost resistance totem", NextAction::array(0, new NextAction("set frost resistance totem", 60.0f), nullptr)));
triggers.push_back(new TriggerNode("no fire totem", NextAction::array(0, new NextAction("frost resistance totem", 55.0f), nullptr)));
}
// Water Totems
HealingStreamTotemStrategy::HealingStreamTotemStrategy(PlayerbotAI* botAI) : GenericShamanStrategy(botAI) {}
void HealingStreamTotemStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
{
GenericShamanStrategy::InitTriggers(triggers);
triggers.push_back(new TriggerNode("set healing stream totem", NextAction::array(0, new NextAction("set healing stream totem", 60.0f), nullptr)));
triggers.push_back(new TriggerNode("no water totem", NextAction::array(0, new NextAction("healing stream totem", 55.0f), nullptr)));
}
ManaSpringTotemStrategy::ManaSpringTotemStrategy(PlayerbotAI* botAI) : GenericShamanStrategy(botAI) {}
void ManaSpringTotemStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
{
GenericShamanStrategy::InitTriggers(triggers);
triggers.push_back(new TriggerNode("set mana spring totem", NextAction::array(0, new NextAction("set mana spring totem", 60.0f), nullptr)));
triggers.push_back(new TriggerNode("no water totem", NextAction::array(0, new NextAction("mana spring totem", 55.0f), nullptr)));
}
CleansingTotemStrategy::CleansingTotemStrategy(PlayerbotAI* botAI) : GenericShamanStrategy(botAI) {}
void CleansingTotemStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
{
GenericShamanStrategy::InitTriggers(triggers);
// If the bot hasn't learned Cleansing Totem yet, set Mana Spring Totem instead.
Player* bot = botAI->GetBot();
if (bot->HasSpell(8170))
{
triggers.push_back(new TriggerNode("set cleansing totem", NextAction::array(0, new NextAction("set cleansing totem", 60.0f), nullptr)));
}
else if (bot->HasSpell(5675))
{
triggers.push_back(new TriggerNode("set mana spring totem", NextAction::array(0, new NextAction("set mana spring totem", 60.0f), nullptr)));
}
triggers.push_back(new TriggerNode("no water totem", NextAction::array(0, new NextAction("cleansing totem", 55.0f), nullptr)));
}
FireResistanceTotemStrategy::FireResistanceTotemStrategy(PlayerbotAI* botAI) : GenericShamanStrategy(botAI) {}
void FireResistanceTotemStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
{
GenericShamanStrategy::InitTriggers(triggers);
triggers.push_back(new TriggerNode("set fire resistance totem", NextAction::array(0, new NextAction("set fire resistance totem", 60.0f), nullptr)));
triggers.push_back(new TriggerNode("no water totem", NextAction::array(0, new NextAction("fire resistance totem", 55.0f), nullptr)));
}
// Air Totems
WrathOfAirTotemStrategy::WrathOfAirTotemStrategy(PlayerbotAI* botAI) : GenericShamanStrategy(botAI) {}
void WrathOfAirTotemStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
{
GenericShamanStrategy::InitTriggers(triggers);
// If the bot hasn't learned Wrath of Air Totem yet, set Grounding Totem instead.
Player* bot = botAI->GetBot();
if (bot->HasSpell(3738))
{
triggers.push_back(new TriggerNode("set wrath of air totem", NextAction::array(0, new NextAction("set wrath of air totem", 60.0f), nullptr)));
}
else if (bot->HasSpell(8177))
{
triggers.push_back(new TriggerNode("set grounding totem", NextAction::array(0, new NextAction("set grounding totem", 60.0f), nullptr)));
}
triggers.push_back(
new TriggerNode("no air totem", NextAction::array(0, new NextAction("wrath of air totem", 55.0f), nullptr)));
}
WindfuryTotemStrategy::WindfuryTotemStrategy(PlayerbotAI* botAI) : GenericShamanStrategy(botAI) {}
void WindfuryTotemStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
{
GenericShamanStrategy::InitTriggers(triggers);
// If the bot hasn't learned Windfury Totem yet, set Grounding Totem instead.
Player* bot = botAI->GetBot();
if (bot->HasSpell(8512))
{
triggers.push_back(new TriggerNode("set windfury totem", NextAction::array(0, new NextAction("set windfury totem", 60.0f), nullptr)));
}
else if (bot->HasSpell(8177))
{
triggers.push_back(new TriggerNode("set grounding totem", NextAction::array(0, new NextAction("set grounding totem", 60.0f), nullptr)));
}
triggers.push_back(new TriggerNode("no air totem", NextAction::array(0, new NextAction("windfury totem", 55.0f), nullptr)));
}
NatureResistanceTotemStrategy::NatureResistanceTotemStrategy(PlayerbotAI* botAI) : GenericShamanStrategy(botAI) {}
void NatureResistanceTotemStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
{
GenericShamanStrategy::InitTriggers(triggers);
triggers.push_back(new TriggerNode("set nature resistance totem", NextAction::array(0, new NextAction("set nature resistance totem", 60.0f), nullptr)));
triggers.push_back(new TriggerNode("no air totem", NextAction::array(0, new NextAction("nature resistance totem", 55.0f), nullptr)));
}
GroundingTotemStrategy::GroundingTotemStrategy(PlayerbotAI* botAI) : GenericShamanStrategy(botAI) {}
void GroundingTotemStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
{
GenericShamanStrategy::InitTriggers(triggers);
triggers.push_back(new TriggerNode("set grounding totem", NextAction::array(0, new NextAction("set grounding totem", 60.0f), nullptr)));
triggers.push_back(new TriggerNode("no air totem", NextAction::array(0, new NextAction("grounding totem", 55.0f), nullptr)));
} }

View File

@@ -7,16 +7,358 @@
#define _PLAYERBOT_TOTEMSSHAMANSTRATEGY_H #define _PLAYERBOT_TOTEMSSHAMANSTRATEGY_H
#include "GenericShamanStrategy.h" #include "GenericShamanStrategy.h"
#include <set>
#include <vector>
#include <string>
// This is the header with all of the totem-related constants and arrays used in the Shaman strategies.
// Totem Bar Slot Constants
#define TOTEM_BAR_SLOT_FIRE 132
#define TOTEM_BAR_SLOT_EARTH 133
#define TOTEM_BAR_SLOT_WATER 134
#define TOTEM_BAR_SLOT_AIR 135
// Strength of Earth Totem
static const uint32 STRENGTH_OF_EARTH_TOTEM[] = {
58643, // Rank 8
57622, // Rank 7
25528, // Rank 6
25361, // Rank 5
10442, // Rank 4
8161, // Rank 3
8160, // Rank 2
8075 // Rank 1
};
static const size_t STRENGTH_OF_EARTH_TOTEM_COUNT = sizeof(STRENGTH_OF_EARTH_TOTEM) / sizeof(uint32);
// Stoneskin Totem
static const uint32 STONESKIN_TOTEM[] = {
58753, // Rank 10
58751, // Rank 9
25509, // Rank 8
25508, // Rank 7
10408, // Rank 6
10407, // Rank 5
10406, // Rank 4
8155, // Rank 3
8154, // Rank 2
8071 // Rank 1
};
static const size_t STONESKIN_TOTEM_COUNT = sizeof(STONESKIN_TOTEM) / sizeof(uint32);
// Tremor Totem
static const uint32 TREMOR_TOTEM[] = {
8143 // Rank 1
};
static const size_t TREMOR_TOTEM_COUNT = sizeof(TREMOR_TOTEM) / sizeof(uint32);
// Earthbind Totem
static const uint32 EARTHBIND_TOTEM[] = {
2484 // Rank 1
};
static const size_t EARTHBIND_TOTEM_COUNT = sizeof(EARTHBIND_TOTEM) / sizeof(uint32);
// Stoneclaw Totem
static const uint32 STONECLAW_TOTEM[] = {
58582, // Rank 10
58581, // Rank 9
58580, // Rank 8
25525, // Rank 7
10428, // Rank 6
10427, // Rank 5
6392, // Rank 4
6391, // Rank 3
6390, // Rank 2
5730 // Rank 1
};
static const size_t STONECLAW_TOTEM_COUNT = sizeof(STONECLAW_TOTEM) / sizeof(uint32);
// Searing Totem
static const uint32 SEARING_TOTEM[] = {
58704, // Rank 10
58703, // Rank 9
58699, // Rank 8
25533, // Rank 7
10438, // Rank 6
10437, // Rank 5
6365, // Rank 4
6364, // Rank 3
6363, // Rank 2
3599 // Rank 1
};
static const size_t SEARING_TOTEM_COUNT = sizeof(SEARING_TOTEM) / sizeof(uint32);
// Magma Totem
static const uint32 MAGMA_TOTEM[] = {
58734, // Rank 7
58731, // Rank 6
25552, // Rank 5
10587, // Rank 4
10586, // Rank 3
10585, // Rank 2
8190 // Rank 1
};
static const size_t MAGMA_TOTEM_COUNT = sizeof(MAGMA_TOTEM) / sizeof(uint32);
// Flametongue Totem
static const uint32 FLAMETONGUE_TOTEM[] = {
58656, // Rank 8
58652, // Rank 7
58649, // Rank 6
25557, // Rank 5
16387, // Rank 4
10526, // Rank 3
8249, // Rank 2
8227 // Rank 1
};
static const size_t FLAMETONGUE_TOTEM_COUNT = sizeof(FLAMETONGUE_TOTEM) / sizeof(uint32);
// Totem of Wrath
static const uint32 TOTEM_OF_WRATH[] = {
57722, // Rank 4
57721, // Rank 3
57720, // Rank 2
30706 // Rank 1
};
static const size_t TOTEM_OF_WRATH_COUNT = sizeof(TOTEM_OF_WRATH) / sizeof(uint32);
// Frost Resistance Totem
static const uint32 FROST_RESISTANCE_TOTEM[] = {
58745, // Rank 6
58741, // Rank 5
25560, // Rank 4
10479, // Rank 3
10478, // Rank 2
8181 // Rank 1
};
static const size_t FROST_RESISTANCE_TOTEM_COUNT = sizeof(FROST_RESISTANCE_TOTEM) / sizeof(uint32);
// Fire Elemental Totem
static const uint32 FIRE_ELEMENTAL_TOTEM[] = {
2894 // Rank 1
};
static const size_t FIRE_ELEMENTAL_TOTEM_COUNT = sizeof(FIRE_ELEMENTAL_TOTEM) / sizeof(uint32);
// Healing Stream Totem
static const uint32 HEALING_STREAM_TOTEM[] = {
58757, // Rank 9
58756, // Rank 8
58755, // Rank 7
25567, // Rank 6
10463, // Rank 5
10462, // Rank 4
6377, // Rank 3
6375, // Rank 2
5394 // Rank 1
};
static const size_t HEALING_STREAM_TOTEM_COUNT = sizeof(HEALING_STREAM_TOTEM) / sizeof(uint32);
// Mana Spring Totem
static const uint32 MANA_SPRING_TOTEM[] = {
58774, // Rank 8
58773, // Rank 7
58771, // Rank 6
25570, // Rank 5
10497, // Rank 4
10496, // Rank 3
10495, // Rank 2
5675 // Rank 1
};
static const size_t MANA_SPRING_TOTEM_COUNT = sizeof(MANA_SPRING_TOTEM) / sizeof(uint32);
// Cleansing Totem
static const uint32 CLEANSING_TOTEM[] = {
8170 // Rank 1
};
static const size_t CLEANSING_TOTEM_COUNT = sizeof(CLEANSING_TOTEM) / sizeof(uint32);
// Fire Resistance Totem
static const uint32 FIRE_RESISTANCE_TOTEM[] = {
58739, // Rank 6
58737, // Rank 5
25563, // Rank 4
10538, // Rank 3
10537, // Rank 2
8184 // Rank 1
};
static const size_t FIRE_RESISTANCE_TOTEM_COUNT = sizeof(FIRE_RESISTANCE_TOTEM) / sizeof(uint32);
// Mana Tide Totem
static const uint32 MANA_TIDE_TOTEM[] = {
16190 // Rank 1
};
static const size_t MANA_TIDE_TOTEM_COUNT = sizeof(MANA_TIDE_TOTEM) / sizeof(uint32);
// Wrath of Air Totem
static const uint32 WRATH_OF_AIR_TOTEM[] = {
3738 // Rank 1
};
static const size_t WRATH_OF_AIR_TOTEM_COUNT = sizeof(WRATH_OF_AIR_TOTEM) / sizeof(uint32);
// Windfury Totem
static const uint32 WINDFURY_TOTEM[] = {
8512 // Rank 1
};
static const size_t WINDFURY_TOTEM_COUNT = sizeof(WINDFURY_TOTEM) / sizeof(uint32);
// Nature Resistance Totem
static const uint32 NATURE_RESISTANCE_TOTEM[] = {
58749, // Rank 6
58746, // Rank 5
25574, // Rank 4
10601, // Rank 3
10600, // Rank 2
10595 // Rank 1
};
static const size_t NATURE_RESISTANCE_TOTEM_COUNT = sizeof(NATURE_RESISTANCE_TOTEM) / sizeof(uint32);
// Grounding Totem
static const uint32 GROUNDING_TOTEM[] = {
8177 // Rank 1
};
static const size_t GROUNDING_TOTEM_COUNT = sizeof(GROUNDING_TOTEM) / sizeof(uint32);
class PlayerbotAI; class PlayerbotAI;
class TotemsShamanStrategy : public GenericShamanStrategy // Earth Totem Strategies
class StrengthOfEarthTotemStrategy : public GenericShamanStrategy
{ {
public: public:
TotemsShamanStrategy(PlayerbotAI* botAI); StrengthOfEarthTotemStrategy(PlayerbotAI* botAI);
void InitTriggers(std::vector<TriggerNode*>& triggers) override; void InitTriggers(std::vector<TriggerNode*>& triggers) override;
std::string const getName() override { return "totems"; } std::string const getName() override { return "strength of earth"; }
};
class StoneclawTotemStrategy : public GenericShamanStrategy
{
public:
StoneclawTotemStrategy(PlayerbotAI* botAI);
void InitTriggers(std::vector<TriggerNode*>& triggers) override;
std::string const getName() override { return "stoneskin"; }
};
class EarthTotemStrategy : public GenericShamanStrategy
{
public:
EarthTotemStrategy(PlayerbotAI* botAI);
void InitTriggers(std::vector<TriggerNode*>& triggers) override;
std::string const getName() override { return "tremor"; }
};
class EarthbindTotemStrategy : public GenericShamanStrategy
{
public:
EarthbindTotemStrategy(PlayerbotAI* botAI);
void InitTriggers(std::vector<TriggerNode*>& triggers) override;
std::string const getName() override { return "earthbind"; }
};
// Fire Totem Strategies
class SearingTotemStrategy : public GenericShamanStrategy
{
public:
SearingTotemStrategy(PlayerbotAI* botAI);
void InitTriggers(std::vector<TriggerNode*>& triggers) override;
std::string const getName() override { return "searing"; }
};
class MagmaTotemStrategy : public GenericShamanStrategy
{
public:
MagmaTotemStrategy(PlayerbotAI* botAI);
void InitTriggers(std::vector<TriggerNode*>& triggers) override;
std::string const getName() override { return "magma"; }
};
class FlametongueTotemStrategy : public GenericShamanStrategy
{
public:
FlametongueTotemStrategy(PlayerbotAI* botAI);
void InitTriggers(std::vector<TriggerNode*>& triggers) override;
std::string const getName() override { return "flametongue"; }
};
class TotemOfWrathStrategy : public GenericShamanStrategy
{
public:
TotemOfWrathStrategy(PlayerbotAI* botAI);
void InitTriggers(std::vector<TriggerNode*>& triggers) override;
std::string const getName() override { return "wrath"; }
};
class FrostResistanceTotemStrategy : public GenericShamanStrategy
{
public:
FrostResistanceTotemStrategy(PlayerbotAI* botAI);
void InitTriggers(std::vector<TriggerNode*>& triggers) override;
std::string const getName() override { return "frost resistance"; }
};
// Water Totem Strategies
class HealingStreamTotemStrategy : public GenericShamanStrategy
{
public:
HealingStreamTotemStrategy(PlayerbotAI* botAI);
void InitTriggers(std::vector<TriggerNode*>& triggers) override;
std::string const getName() override { return "healing stream"; }
};
class ManaSpringTotemStrategy : public GenericShamanStrategy
{
public:
ManaSpringTotemStrategy(PlayerbotAI* botAI);
void InitTriggers(std::vector<TriggerNode*>& triggers) override;
std::string const getName() override { return "mana spring"; }
};
class CleansingTotemStrategy : public GenericShamanStrategy
{
public:
CleansingTotemStrategy(PlayerbotAI* botAI);
void InitTriggers(std::vector<TriggerNode*>& triggers) override;
std::string const getName() override { return "cleansing"; }
};
class FireResistanceTotemStrategy : public GenericShamanStrategy
{
public:
FireResistanceTotemStrategy(PlayerbotAI* botAI);
void InitTriggers(std::vector<TriggerNode*>& triggers) override;
std::string const getName() override { return "fire resistance"; }
};
// Air Totem Strategies
class WrathOfAirTotemStrategy : public GenericShamanStrategy
{
public:
WrathOfAirTotemStrategy(PlayerbotAI* botAI);
void InitTriggers(std::vector<TriggerNode*>& triggers) override;
std::string const getName() override { return "wrath of air"; }
};
class WindfuryTotemStrategy : public GenericShamanStrategy
{
public:
WindfuryTotemStrategy(PlayerbotAI* botAI);
void InitTriggers(std::vector<TriggerNode*>& triggers) override;
std::string const getName() override { return "windfury"; }
};
class NatureResistanceTotemStrategy : public GenericShamanStrategy
{
public:
NatureResistanceTotemStrategy(PlayerbotAI* botAI);
void InitTriggers(std::vector<TriggerNode*>& triggers) override;
std::string const getName() override { return "nature resistance"; }
};
class GroundingTotemStrategy : public GenericShamanStrategy
{
public:
GroundingTotemStrategy(PlayerbotAI* botAI);
void InitTriggers(std::vector<TriggerNode*>& triggers) override;
std::string const getName() override { return "grounding"; }
}; };
#endif #endif

View File

@@ -98,7 +98,7 @@ void ArrowFormation::FillSlotsExceptMaster()
else if (member != botAI->GetMaster()) else if (member != botAI->GetMaster())
FindSlot(member)->AddLast(new FormationUnit(index, false)); FindSlot(member)->AddLast(new FormationUnit(index, false));
++index; ++index;
} }
gref = gref->next(); gref = gref->next();
} }
} }

View File

@@ -160,7 +160,7 @@ public:
creators["my attacker count"] = &ValueContext::my_attacker_count; creators["my attacker count"] = &ValueContext::my_attacker_count;
creators["has aggro"] = &ValueContext::has_aggro; creators["has aggro"] = &ValueContext::has_aggro;
creators["mounted"] = &ValueContext::mounted; creators["mounted"] = &ValueContext::mounted;
creators["custom_glyphs"] = &ValueContext::custom_glyphs; // Added for custom glyphs creators["custom_glyphs"] = &ValueContext::custom_glyphs; // Added for custom glyphs
creators["can loot"] = &ValueContext::can_loot; creators["can loot"] = &ValueContext::can_loot;
creators["loot target"] = &ValueContext::loot_target; creators["loot target"] = &ValueContext::loot_target;
@@ -555,7 +555,7 @@ private:
static UntypedValue* last_flee_angle(PlayerbotAI* ai) { return new LastFleeAngleValue(ai); } static UntypedValue* last_flee_angle(PlayerbotAI* ai) { return new LastFleeAngleValue(ai); }
static UntypedValue* last_flee_timestamp(PlayerbotAI* ai) { return new LastFleeTimestampValue(ai); } static UntypedValue* last_flee_timestamp(PlayerbotAI* ai) { return new LastFleeTimestampValue(ai); }
static UntypedValue* recently_flee_info(PlayerbotAI* ai) { return new RecentlyFleeInfo(ai); } static UntypedValue* recently_flee_info(PlayerbotAI* ai) { return new RecentlyFleeInfo(ai); }
// ------------------------------------------------------- // -------------------------------------------------------
// Flag for cutom glyphs : true when /w bot glyph equip // Flag for cutom glyphs : true when /w bot glyph equip
// ------------------------------------------------------- // -------------------------------------------------------
static UntypedValue* custom_glyphs(PlayerbotAI* ai) static UntypedValue* custom_glyphs(PlayerbotAI* ai)