aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sql/base/auth_database.sql10
-rw-r--r--sql/updates/auth/2014_08_28_00_auth_rbac_ahbot.sql40
-rw-r--r--sql/updates/auth/2014_08_28_01_auth_rbac_permissions.sql8
-rw-r--r--sql/updates/world/2014_08_28_01_world_ahbot.sql42
-rw-r--r--sql/updates/world/2014_08_28_02_world_sai.sql6
-rw-r--r--sql/updates/world/2014_08_28_03_world_ulduar.sql106
-rw-r--r--sql/updates/world/2014_08_28_04_world_creature_template.sql2
-rw-r--r--sql/updates/world/2014_08_28_04_world_misc.sql15
-rw-r--r--sql/updates/world/2014_08_28_05_world_sai.sql90
-rw-r--r--sql/updates/world/2014_08_28_06_world_command.sql1
-rw-r--r--sql/updates/world/2014_08_29_00_world_creature_template.sql4
-rw-r--r--sql/updates/world/2014_08_29_01_world_creature_template.sql2
-rw-r--r--sql/updates/world/2014_08_29_02_world_creature_template.sql3
-rw-r--r--sql/updates/world/2014_08_29_03_world_creature_template.sql5
-rw-r--r--src/server/game/Accounts/RBAC.h17
-rw-r--r--src/server/game/AuctionHouseBot/AuctionHouseBot.cpp426
-rw-r--r--src/server/game/AuctionHouseBot/AuctionHouseBot.h280
-rw-r--r--src/server/game/AuctionHouseBot/AuctionHouseBotBuyer.cpp432
-rw-r--r--src/server/game/AuctionHouseBot/AuctionHouseBotBuyer.h96
-rw-r--r--src/server/game/AuctionHouseBot/AuctionHouseBotSeller.cpp1029
-rw-r--r--src/server/game/AuctionHouseBot/AuctionHouseBotSeller.h147
-rw-r--r--src/server/game/CMakeLists.txt3
-rw-r--r--src/server/game/Entities/Item/Item.cpp10
-rw-r--r--src/server/game/Entities/Player/Player.cpp19
-rw-r--r--src/server/game/Guilds/Guild.h3
-rw-r--r--src/server/game/Miscellaneous/Language.h29
-rw-r--r--src/server/game/Scripting/ScriptLoader.cpp2
-rw-r--r--src/server/game/Spells/SpellMgr.cpp10
-rw-r--r--src/server/game/World/World.cpp17
-rw-r--r--src/server/game/World/World.h2
-rw-r--r--src/server/scripts/CMakeLists.txt1
-rw-r--r--src/server/scripts/Commands/cs_ahbot.cpp251
-rw-r--r--src/server/scripts/Commands/cs_guild.cpp58
-rw-r--r--src/server/scripts/Northrend/Ulduar/Ulduar/boss_hodir.cpp6
-rw-r--r--src/server/scripts/Northrend/Ulduar/Ulduar/boss_mimiron.cpp1385
-rw-r--r--src/server/worldserver/worldserver.conf.dist352
36 files changed, 4899 insertions, 10 deletions
diff --git a/sql/base/auth_database.sql b/sql/base/auth_database.sql
index 090a90597b5..d4f60771767 100644
--- a/sql/base/auth_database.sql
+++ b/sql/base/auth_database.sql
@@ -1,8 +1,8 @@
--- MySQL dump 10.15 Distrib 10.0.12-MariaDB, for Win64 (x86)
+-- MySQL dump 10.15 Distrib 10.0.13-MariaDB, for Win64 (x86)
--
-- Host: localhost Database: auth
-- ------------------------------------------------------
--- Server version 10.0.12-MariaDB
+-- Server version 10.0.13-MariaDB
/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
@@ -348,7 +348,7 @@ CREATE TABLE `rbac_linked_permissions` (
LOCK TABLES `rbac_linked_permissions` WRITE;
/*!40000 ALTER TABLE `rbac_linked_permissions` DISABLE KEYS */;
-INSERT INTO `rbac_linked_permissions` VALUES (192,21),(192,42),(192,43),(192,193),(192,196),(193,48),(193,194),(193,197),(194,1),(194,2),(194,11),(194,13),(194,14),(194,15),(194,16),(194,17),(194,18),(194,19),(194,20),(194,22),(194,23),(194,25),(194,26),(194,27),(194,28),(194,29),(194,30),(194,31),(194,32),(194,33),(194,34),(194,35),(194,36),(194,37),(194,38),(194,39),(194,40),(194,41),(194,44),(194,46),(194,47),(194,195),(194,198),(195,3),(195,4),(195,5),(195,6),(195,24),(195,49),(195,199),(196,200),(196,201),(196,226),(196,227),(196,230),(196,231),(196,233),(196,234),(196,235),(196,238),(196,239),(196,240),(196,241),(196,242),(196,243),(196,244),(196,245),(196,246),(196,247),(196,248),(196,249),(196,250),(196,251),(196,252),(196,253),(196,254),(196,255),(196,256),(196,257),(196,258),(196,259),(196,260),(196,261),(196,262),(196,264),(196,265),(196,266),(196,267),(196,268),(196,269),(196,270),(196,271),(196,272),(196,279),(196,280),(196,283),(196,287),(196,288),(196,289),(196,290),(196,291),(196,292),(196,293),(196,294),(196,295),(196,296),(196,297),(196,298),(196,299),(196,302),(196,303),(196,304),(196,305),(196,306),(196,307),(196,308),(196,309),(196,310),(196,313),(196,314),(196,319),(196,320),(196,321),(196,322),(196,323),(196,324),(196,325),(196,326),(196,327),(196,328),(196,329),(196,330),(196,331),(196,332),(196,333),(196,334),(196,335),(196,336),(196,337),(196,338),(196,339),(196,340),(196,341),(196,342),(196,343),(196,344),(196,345),(196,346),(196,347),(196,348),(196,349),(196,350),(196,351),(196,352),(196,353),(196,354),(196,355),(196,356),(196,357),(196,358),(196,359),(196,360),(196,361),(196,362),(196,363),(196,364),(196,365),(196,366),(196,373),(196,375),(196,400),(196,401),(196,402),(196,403),(196,404),(196,405),(196,406),(196,407),(196,417),(196,418),(196,419),(196,420),(196,421),(196,422),(196,423),(196,424),(196,425),(196,426),(196,427),(196,428),(196,429),(196,434),(196,435),(196,436),(196,437),(196,438),(196,439),(196,440),(196,441),(196,442),(196,443),(196,444),(196,445),(196,446),(196,447),(196,448),(196,449),(196,450),(196,451),(196,452),(196,453),(196,454),(196,455),(196,456),(196,457),(196,458),(196,459),(196,461),(196,463),(196,464),(196,465),(196,472),(196,473),(196,474),(196,475),(196,476),(196,477),(196,478),(196,488),(196,489),(196,491),(196,492),(196,493),(196,495),(196,497),(196,498),(196,499),(196,500),(196,502),(196,503),(196,505),(196,508),(196,511),(196,513),(196,514),(196,516),(196,519),(196,522),(196,523),(196,526),(196,527),(196,529),(196,530),(196,533),(196,535),(196,536),(196,537),(196,538),(196,539),(196,540),(196,541),(196,556),(196,581),(196,582),(196,592),(196,593),(196,596),(196,602),(196,603),(196,604),(196,605),(196,606),(196,607),(196,608),(196,609),(196,610),(196,611),(196,612),(196,613),(196,614),(196,615),(196,616),(196,617),(196,618),(196,619),(196,620),(196,621),(196,622),(196,623),(196,624),(196,625),(196,626),(196,627),(196,628),(196,629),(196,630),(196,631),(196,633),(196,634),(196,635),(196,636),(196,637),(196,638),(196,639),(196,640),(196,641),(196,642),(196,643),(196,644),(196,645),(196,646),(196,647),(196,648),(196,649),(196,650),(196,651),(196,652),(196,653),(196,654),(196,655),(196,656),(196,657),(196,658),(196,659),(196,660),(196,661),(196,662),(196,663),(196,664),(196,665),(196,666),(196,667),(196,668),(196,669),(196,670),(196,671),(196,672),(196,673),(196,674),(196,675),(196,676),(196,677),(196,678),(196,679),(196,680),(196,681),(196,682),(196,683),(196,684),(196,685),(196,686),(196,687),(196,688),(196,689),(196,690),(196,691),(196,692),(196,693),(196,694),(196,695),(196,696),(196,697),(196,698),(196,699),(196,700),(196,701),(196,702),(196,703),(196,704),(196,705),(196,706),(196,707),(196,708),(196,709),(196,710),(196,711),(196,712),(196,713),(196,714),(196,715),(196,716),(196,717),(196,718),(196,719),(196,721),(196,722),(196,723),(196,724),(196,725),(196,726),(196,727),(196,728),(196,729),(196,730),(196,733),(196,734),(196,735),(196,736),(196,738),(196,739),(196,748),(196,753),(196,757),(196,773),(196,777),(197,232),(197,236),(197,237),(197,273),(197,274),(197,275),(197,276),(197,277),(197,284),(197,285),(197,286),(197,301),(197,311),(197,387),(197,388),(197,389),(197,390),(197,391),(197,392),(197,393),(197,394),(197,395),(197,396),(197,397),(197,398),(197,399),(197,479),(197,480),(197,481),(197,482),(197,485),(197,486),(197,487),(197,494),(197,506),(197,509),(197,510),(197,517),(197,518),(197,521),(197,542),(197,543),(197,550),(197,558),(197,568),(197,571),(197,572),(197,573),(197,574),(197,575),(197,576),(197,577),(197,578),(197,579),(197,580),(197,583),(197,584),(197,585),(197,586),(197,587),(197,588),(197,589),(197,590),(197,591),(197,594),(197,595),(197,601),(197,743),(197,750),(197,758),(197,761),(197,762),(197,763),(197,764),(197,765),(197,766),(197,767),(197,768),(197,769),(197,770),(197,771),(197,772),(197,774),(198,218),(198,300),(198,312),(198,315),(198,316),(198,317),(198,318),(198,367),(198,368),(198,369),(198,370),(198,371),(198,372),(198,374),(198,376),(198,377),(198,378),(198,379),(198,380),(198,381),(198,382),(198,383),(198,384),(198,385),(198,386),(198,408),(198,409),(198,410),(198,411),(198,412),(198,413),(198,414),(198,415),(198,416),(198,430),(198,431),(198,432),(198,433),(198,462),(198,466),(198,467),(198,468),(198,469),(198,470),(198,471),(198,483),(198,484),(198,490),(198,504),(198,512),(198,515),(198,520),(198,524),(198,528),(198,531),(198,532),(198,544),(198,545),(198,546),(198,547),(198,548),(198,549),(198,551),(198,552),(198,553),(198,554),(198,555),(198,557),(198,559),(198,560),(198,561),(198,562),(198,563),(198,564),(198,565),(198,566),(198,567),(198,569),(198,570),(198,597),(198,598),(198,599),(198,600),(198,737),(198,740),(198,741),(198,742),(198,744),(198,745),(198,746),(198,747),(198,749),(198,751),(198,752),(198,754),(198,755),(198,756),(198,759),(198,760),(199,217),(199,221),(199,222),(199,223),(199,225),(199,263),(199,496),(199,501),(199,507),(199,525),(199,534);
+INSERT INTO `rbac_linked_permissions` VALUES (192,21),(192,42),(192,43),(192,193),(192,196),(192,778),(192,779),(192,780),(192,781),(192,782),(192,783),(192,784),(192,785),(192,786),(192,787),(192,788),(192,789),(192,790),(192,791),(192,792),(192,793),(192,794),(193,48),(193,194),(193,197),(194,1),(194,2),(194,11),(194,13),(194,14),(194,15),(194,16),(194,17),(194,18),(194,19),(194,20),(194,22),(194,23),(194,25),(194,26),(194,27),(194,28),(194,29),(194,30),(194,31),(194,32),(194,33),(194,34),(194,35),(194,36),(194,37),(194,38),(194,39),(194,40),(194,41),(194,44),(194,46),(194,47),(194,195),(194,198),(195,3),(195,4),(195,5),(195,6),(195,24),(195,49),(195,199),(196,200),(196,201),(196,226),(196,227),(196,230),(196,231),(196,233),(196,234),(196,235),(196,238),(196,239),(196,240),(196,241),(196,242),(196,243),(196,244),(196,245),(196,246),(196,247),(196,248),(196,249),(196,250),(196,251),(196,252),(196,253),(196,254),(196,255),(196,256),(196,257),(196,258),(196,259),(196,260),(196,261),(196,262),(196,264),(196,265),(196,266),(196,267),(196,268),(196,269),(196,270),(196,271),(196,272),(196,279),(196,280),(196,283),(196,287),(196,288),(196,289),(196,290),(196,291),(196,292),(196,293),(196,294),(196,295),(196,296),(196,297),(196,298),(196,299),(196,302),(196,303),(196,304),(196,305),(196,306),(196,307),(196,308),(196,309),(196,310),(196,313),(196,314),(196,319),(196,320),(196,321),(196,322),(196,323),(196,324),(196,325),(196,326),(196,327),(196,328),(196,329),(196,330),(196,331),(196,332),(196,333),(196,334),(196,335),(196,336),(196,337),(196,338),(196,339),(196,340),(196,341),(196,342),(196,343),(196,344),(196,345),(196,346),(196,347),(196,348),(196,349),(196,350),(196,351),(196,352),(196,353),(196,354),(196,355),(196,356),(196,357),(196,358),(196,359),(196,360),(196,361),(196,362),(196,363),(196,364),(196,365),(196,366),(196,373),(196,375),(196,400),(196,401),(196,402),(196,403),(196,404),(196,405),(196,406),(196,407),(196,417),(196,418),(196,419),(196,420),(196,421),(196,422),(196,423),(196,424),(196,425),(196,426),(196,427),(196,428),(196,429),(196,434),(196,435),(196,436),(196,437),(196,438),(196,439),(196,440),(196,441),(196,442),(196,443),(196,444),(196,445),(196,446),(196,447),(196,448),(196,449),(196,450),(196,451),(196,452),(196,453),(196,454),(196,455),(196,456),(196,457),(196,458),(196,459),(196,461),(196,463),(196,464),(196,465),(196,472),(196,473),(196,474),(196,475),(196,476),(196,477),(196,478),(196,488),(196,489),(196,491),(196,492),(196,493),(196,495),(196,497),(196,498),(196,499),(196,500),(196,502),(196,503),(196,505),(196,508),(196,511),(196,513),(196,514),(196,516),(196,519),(196,522),(196,523),(196,526),(196,527),(196,529),(196,530),(196,533),(196,535),(196,536),(196,537),(196,538),(196,539),(196,540),(196,541),(196,556),(196,581),(196,582),(196,592),(196,593),(196,596),(196,602),(196,603),(196,604),(196,605),(196,606),(196,607),(196,608),(196,609),(196,610),(196,611),(196,612),(196,613),(196,614),(196,615),(196,616),(196,617),(196,618),(196,619),(196,620),(196,621),(196,622),(196,623),(196,624),(196,625),(196,626),(196,627),(196,628),(196,629),(196,630),(196,631),(196,633),(196,634),(196,635),(196,636),(196,637),(196,638),(196,639),(196,640),(196,641),(196,642),(196,643),(196,644),(196,645),(196,646),(196,647),(196,648),(196,649),(196,650),(196,651),(196,652),(196,653),(196,654),(196,655),(196,656),(196,657),(196,658),(196,659),(196,660),(196,661),(196,662),(196,663),(196,664),(196,665),(196,666),(196,667),(196,668),(196,669),(196,670),(196,671),(196,672),(196,673),(196,674),(196,675),(196,676),(196,677),(196,678),(196,679),(196,680),(196,681),(196,682),(196,683),(196,684),(196,685),(196,686),(196,687),(196,688),(196,689),(196,690),(196,691),(196,692),(196,693),(196,694),(196,695),(196,696),(196,697),(196,698),(196,699),(196,700),(196,701),(196,702),(196,703),(196,704),(196,705),(196,706),(196,707),(196,708),(196,709),(196,710),(196,711),(196,712),(196,713),(196,714),(196,715),(196,716),(196,717),(196,718),(196,719),(196,721),(196,722),(196,723),(196,724),(196,725),(196,726),(196,727),(196,728),(196,729),(196,730),(196,733),(196,734),(196,735),(196,736),(196,738),(196,739),(196,748),(196,753),(196,757),(196,773),(196,777),(197,232),(197,236),(197,237),(197,273),(197,274),(197,275),(197,276),(197,277),(197,284),(197,285),(197,286),(197,301),(197,311),(197,387),(197,388),(197,389),(197,390),(197,391),(197,392),(197,393),(197,394),(197,395),(197,396),(197,397),(197,398),(197,399),(197,479),(197,480),(197,481),(197,482),(197,485),(197,486),(197,487),(197,494),(197,506),(197,509),(197,510),(197,517),(197,518),(197,521),(197,542),(197,543),(197,550),(197,558),(197,568),(197,571),(197,572),(197,573),(197,574),(197,575),(197,576),(197,577),(197,578),(197,579),(197,580),(197,583),(197,584),(197,585),(197,586),(197,587),(197,588),(197,589),(197,590),(197,591),(197,594),(197,595),(197,601),(197,743),(197,750),(197,758),(197,761),(197,762),(197,763),(197,764),(197,765),(197,766),(197,767),(197,768),(197,769),(197,770),(197,771),(197,772),(197,774),(198,218),(198,300),(198,312),(198,315),(198,316),(198,317),(198,318),(198,367),(198,368),(198,369),(198,370),(198,371),(198,372),(198,374),(198,376),(198,377),(198,378),(198,379),(198,380),(198,381),(198,382),(198,383),(198,384),(198,385),(198,386),(198,408),(198,409),(198,410),(198,411),(198,412),(198,413),(198,414),(198,415),(198,416),(198,430),(198,431),(198,432),(198,433),(198,462),(198,466),(198,467),(198,468),(198,469),(198,470),(198,471),(198,483),(198,484),(198,490),(198,504),(198,512),(198,515),(198,520),(198,524),(198,528),(198,531),(198,532),(198,544),(198,545),(198,546),(198,547),(198,548),(198,549),(198,551),(198,552),(198,553),(198,554),(198,555),(198,557),(198,559),(198,560),(198,561),(198,562),(198,563),(198,564),(198,565),(198,566),(198,567),(198,569),(198,570),(198,597),(198,598),(198,599),(198,600),(198,737),(198,740),(198,741),(198,742),(198,744),(198,745),(198,746),(198,747),(198,749),(198,751),(198,752),(198,754),(198,755),(198,756),(198,759),(198,760),(199,217),(199,221),(199,222),(199,223),(199,225),(199,263),(199,496),(199,501),(199,507),(199,525),(199,534);
/*!40000 ALTER TABLE `rbac_linked_permissions` ENABLE KEYS */;
UNLOCK TABLES;
@@ -372,7 +372,7 @@ CREATE TABLE `rbac_permissions` (
LOCK TABLES `rbac_permissions` WRITE;
/*!40000 ALTER TABLE `rbac_permissions` DISABLE KEYS */;
-INSERT INTO `rbac_permissions` VALUES (1,'Instant logout'),(2,'Skip Queue'),(3,'Join Normal Battleground'),(4,'Join Random Battleground'),(5,'Join Arenas'),(6,'Join Dungeon Finder'),(11,'Log GM trades'),(13,'Skip Instance required bosses check'),(14,'Skip character creation team mask check'),(15,'Skip character creation class mask check'),(16,'Skip character creation race mask check'),(17,'Skip character creation reserved name check'),(18,'Skip character creation heroic min level check'),(19,'Skip needed requirements to use channel check'),(20,'Skip disable map check'),(21,'Skip reset talents when used more than allowed check'),(22,'Skip spam chat check'),(23,'Skip over-speed ping check'),(24,'Two side faction characters on the same account'),(25,'Allow say chat between factions'),(26,'Allow channel chat between factions'),(27,'Two side mail interaction'),(28,'See two side who list'),(29,'Add friends of other faction'),(30,'Save character without delay with .save command'),(31,'Use params with .unstuck command'),(32,'Can be assigned tickets with .assign ticket command'),(33,'Notify if a command was not found'),(34,'Check if should appear in list using .gm ingame command'),(35,'See all security levels with who command'),(36,'Filter whispers'),(37,'Use staff badge in chat'),(38,'Resurrect with full Health Points'),(39,'Restore saved gm setting states'),(40,'Allows to add a gm to friend list'),(41,'Use Config option START_GM_LEVEL to assign new character level'),(42,'Allows to use CMSG_WORLD_TELEPORT opcode'),(43,'Allows to use CMSG_WHOIS opcode'),(44,'Receive global GM messages/texts'),(45,'Join channels without announce'),(46,'Change channel settings without being channel moderator'),(47,'Enables lower security than target check'),(48,'Enable IP, Last Login and EMail output in pinfo'),(49,'Forces to enter the email for confirmation on password change'),(50,'Allow user to check his own email with .account'),(192,'Role: Sec Level Administrator'),(193,'Role: Sec Level Gamemaster'),(194,'Role: Sec Level Moderator'),(195,'Role: Sec Level Player'),(196,'Role: Administrator Commands'),(197,'Role: Gamemaster Commands'),(198,'Role: Moderator Commands'),(199,'Role: Player Commands'),(200,'Command: rbac'),(201,'Command: rbac account'),(202,'Command: rbac account list'),(203,'Command: rbac account grant'),(204,'Command: rbac account deny'),(205,'Command: rbac account revoke'),(206,'Command: rbac list'),(217,'Command: account'),(218,'Command: account addon'),(219,'Command: account create'),(220,'Command: account delete'),(221,'Command: account lock'),(222,'Command: account lock country'),(223,'Command: account lock ip'),(224,'Command: account onlinelist'),(225,'Command: account password'),(226,'Command: account set'),(227,'Command: account set addon'),(228,'Command: account set gmlevel'),(229,'Command: account set password'),(230,'Command: achievement'),(231,'Command: achievement add'),(232,'Command: arena'),(233,'Command: arena captain'),(234,'Command: arena create'),(235,'Command: arena disband'),(236,'Command: arena info'),(237,'Command: arena lookup'),(238,'Command: arena rename'),(239,'Command: ban'),(240,'Command: ban account'),(241,'Command: ban character'),(242,'Command: ban ip'),(243,'Command: ban playeraccount'),(244,'Command: baninfo'),(245,'Command: baninfo account'),(246,'Command: baninfo character'),(247,'Command: baninfo ip'),(248,'Command: banlist'),(249,'Command: banlist account'),(250,'Command: banlist character'),(251,'Command: banlist ip'),(252,'Command: unban'),(253,'Command: unban account'),(254,'Command: unban character'),(255,'Command: unban ip'),(256,'Command: unban playeraccount'),(257,'Command: bf'),(258,'Command: bf start'),(259,'Command: bf stop'),(260,'Command: bf switch'),(261,'Command: bf timer'),(262,'Command: bf enable'),(263,'Command: account email'),(264,'Command: account set sec'),(265,'Command: account set sec email'),(266,'Command: account set sec regmail'),(267,'Command: cast'),(268,'Command: cast back'),(269,'Command: cast dist'),(270,'Command: cast self'),(271,'Command: cast target'),(272,'Command: cast dest'),(273,'Command: character'),(274,'Command: character customize'),(275,'Command: character changefaction'),(276,'Command: character changerace'),(277,'Command: character deleted'),(279,'Command: character deleted list'),(280,'Command: character deleted restore'),(283,'Command: character level'),(284,'Command: character rename'),(285,'Command: character reputation'),(286,'Command: character titles'),(287,'Command: levelup'),(288,'Command: pdump'),(289,'Command: pdump load'),(290,'Command: pdump write'),(291,'Command: cheat'),(292,'Command: cheat casttime'),(293,'Command: cheat cooldown'),(294,'Command: cheat explore'),(295,'Command: cheat god'),(296,'Command: cheat power'),(297,'Command: cheat status'),(298,'Command: cheat taxi'),(299,'Command: cheat waterwalk'),(300,'Command: debug'),(301,'Command: debug anim'),(302,'Command: debug areatriggers'),(303,'Command: debug arena'),(304,'Command: debug bg'),(305,'Command: debug entervehicle'),(306,'Command: debug getitemstate'),(307,'Command: debug getitemvalue'),(308,'Command: debug getvalue'),(309,'Command: debug hostil'),(310,'Command: debug itemexpire'),(311,'Command: debug lootrecipient'),(312,'Command: debug los'),(313,'Command: debug mod32value'),(314,'Command: debug moveflags'),(315,'Command: debug play'),(316,'Command: debug play cinematics'),(317,'Command: debug play movie'),(318,'Command: debug play sound'),(319,'Command: debug send'),(320,'Command: debug send buyerror'),(321,'Command: debug send channelnotify'),(322,'Command: debug send chatmessage'),(323,'Command: debug send equiperror'),(324,'Command: debug send largepacket'),(325,'Command: debug send opcode'),(326,'Command: debug send qinvalidmsg'),(327,'Command: debug send qpartymsg'),(328,'Command: debug send sellerror'),(329,'Command: debug send setphaseshift'),(330,'Command: debug send spellfail'),(331,'Command: debug setaurastate'),(332,'Command: debug setbit'),(333,'Command: debug setitemvalue'),(334,'Command: debug setvalue'),(335,'Command: debug setvid'),(336,'Command: debug spawnvehicle'),(337,'Command: debug threat'),(338,'Command: debug update'),(339,'Command: debug uws'),(340,'Command: wpgps'),(341,'Command: deserter'),(342,'Command: deserter bg'),(343,'Command: deserter bg add'),(344,'Command: deserter bg remove'),(345,'Command: deserter instance'),(346,'Command: deserter instance add'),(347,'Command: deserter instance remove'),(348,'Command: disable'),(349,'Command: disable add'),(350,'Command: disable add achievement_criteria'),(351,'Command: disable add battleground'),(352,'Command: disable add map'),(353,'Command: disable add mmap'),(354,'Command: disable add outdoorpvp'),(355,'Command: disable add quest'),(356,'Command: disable add spell'),(357,'Command: disable add vmap'),(358,'Command: disable remove'),(359,'Command: disable remove achievement_criteria'),(360,'Command: disable remove battleground'),(361,'Command: disable remove map'),(362,'Command: disable remove mmap'),(363,'Command: disable remove outdoorpvp'),(364,'Command: disable remove quest'),(365,'Command: disable remove spell'),(366,'Command: disable remove vmap'),(367,'Command: event'),(368,'Command: event activelist'),(369,'Command: event start'),(370,'Command: event stop'),(371,'Command: gm'),(372,'Command: gm chat'),(373,'Command: gm fly'),(374,'Command: gm ingame'),(375,'Command: gm list'),(376,'Command: gm visible'),(377,'Command: go'),(378,'Command: go creature'),(379,'Command: go graveyard'),(380,'Command: go grid'),(381,'Command: go object'),(382,'Command: go taxinode'),(383,'Command: go ticket'),(384,'Command: go trigger'),(385,'Command: go xyz'),(386,'Command: go zonexy'),(387,'Command: gobject'),(388,'Command: gobject activate'),(389,'Command: gobject add'),(390,'Command: gobject add temp'),(391,'Command: gobject delete'),(392,'Command: gobject info'),(393,'Command: gobject move'),(394,'Command: gobject near'),(395,'Command: gobject set'),(396,'Command: gobject set phase'),(397,'Command: gobject set state'),(398,'Command: gobject target'),(399,'Command: gobject turn'),(400,'debug transport'),(401,'Command: guild'),(402,'Command: guild create'),(403,'Command: guild delete'),(404,'Command: guild invite'),(405,'Command: guild uninvite'),(406,'Command: guild rank'),(407,'Command: guild rename'),(408,'Command: honor'),(409,'Command: honor add'),(410,'Command: honor add kill'),(411,'Command: honor update'),(412,'Command: instance'),(413,'Command: instance listbinds'),(414,'Command: instance unbind'),(415,'Command: instance stats'),(416,'Command: instance savedata'),(417,'Command: learn'),(418,'Command: learn all'),(419,'Command: learn all my'),(420,'Command: learn all my class'),(421,'Command: learn all my pettalents'),(422,'Command: learn all my spells'),(423,'Command: learn all my talents'),(424,'Command: learn all gm'),(425,'Command: learn all crafts'),(426,'Command: learn all default'),(427,'Command: learn all lang'),(428,'Command: learn all recipes'),(429,'Command: unlearn'),(430,'Command: lfg'),(431,'Command: lfg player'),(432,'Command: lfg group'),(433,'Command: lfg queue'),(434,'Command: lfg clean'),(435,'Command: lfg options'),(436,'Command: list'),(437,'Command: list creature'),(438,'Command: list item'),(439,'Command: list object'),(440,'Command: list auras'),(441,'Command: list mail'),(442,'Command: lookup'),(443,'Command: lookup area'),(444,'Command: lookup creature'),(445,'Command: lookup event'),(446,'Command: lookup faction'),(447,'Command: lookup item'),(448,'Command: lookup itemset'),(449,'Command: lookup object'),(450,'Command: lookup quest'),(451,'Command: lookup player'),(452,'Command: lookup player ip'),(453,'Command: lookup player account'),(454,'Command: lookup player email'),(455,'Command: lookup skill'),(456,'Command: lookup spell'),(457,'Command: lookup spell id'),(458,'Command: lookup taxinode'),(459,'Command: lookup tele'),(460,'Command: lookup title'),(461,'Command: lookup map'),(462,'Command: announce'),(463,'Command: channel'),(464,'Command: channel set'),(465,'Command: channel set ownership'),(466,'Command: gmannounce'),(467,'Command: gmnameannounce'),(468,'Command: gmnotify'),(469,'Command: nameannounce'),(470,'Command: notify'),(471,'Command: whispers'),(472,'Command: group'),(473,'Command: group leader'),(474,'Command: group disband'),(475,'Command: group remove'),(476,'Command: group join'),(477,'Command: group list'),(478,'Command: group summon'),(479,'Command: pet'),(480,'Command: pet create'),(481,'Command: pet learn'),(482,'Command: pet unlearn'),(483,'Command: send'),(484,'Command: send items'),(485,'Command: send mail'),(486,'Command: send message'),(487,'Command: send money'),(488,'Command: additem'),(489,'Command: additemset'),(490,'Command: appear'),(491,'Command: aura'),(492,'Command: bank'),(493,'Command: bindsight'),(494,'Command: combatstop'),(495,'Command: cometome'),(496,'Command: commands'),(497,'Command: cooldown'),(498,'Command: damage'),(499,'Command: dev'),(500,'Command: die'),(501,'Command: dismount'),(502,'Command: distance'),(503,'Command: flusharenapoints'),(504,'Command: freeze'),(505,'Command: gps'),(506,'Command: guid'),(507,'Command: help'),(508,'Command: hidearea'),(509,'Command: itemmove'),(510,'Command: kick'),(511,'Command: linkgrave'),(512,'Command: listfreeze'),(513,'Command: maxskill'),(514,'Command: movegens'),(515,'Command: mute'),(516,'Command: neargrave'),(517,'Command: pinfo'),(518,'Command: playall'),(519,'Command: possess'),(520,'Command: recall'),(521,'Command: repairitems'),(522,'Command: respawn'),(523,'Command: revive'),(524,'Command: saveall'),(525,'Command: save'),(526,'Command: setskill'),(527,'Command: showarea'),(528,'Command: summon'),(529,'Command: unaura'),(530,'Command: unbindsight'),(531,'Command: unfreeze'),(532,'Command: unmute'),(533,'Command: unpossess'),(534,'Command: unstuck'),(535,'Command: wchange'),(536,'Command: mmap'),(537,'Command: mmap loadedtiles'),(538,'Command: mmap loc'),(539,'Command: mmap path'),(540,'Command: mmap stats'),(541,'Command: mmap testarea'),(542,'Command: morph'),(543,'Command: demorph'),(544,'Command: modify'),(545,'Command: modify arenapoints'),(546,'Command: modify bit'),(547,'Command: modify drunk'),(548,'Command: modify energy'),(549,'Command: modify faction'),(550,'Command: modify gender'),(551,'Command: modify honor'),(552,'Command: modify hp'),(553,'Command: modify mana'),(554,'Command: modify money'),(555,'Command: modify mount'),(556,'Command: modify phase'),(557,'Command: modify rage'),(558,'Command: modify reputation'),(559,'Command: modify runicpower'),(560,'Command: modify scale'),(561,'Command: modify speed'),(562,'Command: modify speed all'),(563,'Command: modify speed backwalk'),(564,'Command: modify speed fly'),(565,'Command: modify speed walk'),(566,'Command: modify speed swim'),(567,'Command: modify spell'),(568,'Command: modify standstate'),(569,'Command: modify talentpoints'),(570,'Command: npc'),(571,'Command: npc add'),(572,'Command: npc add formation'),(573,'Command: npc add item'),(574,'Command: npc add move'),(575,'Command: npc add temp'),(576,'Command: npc add delete'),(577,'Command: npc add delete item'),(578,'Command: npc add follow'),(579,'Command: npc add follow stop'),(580,'Command: npc set'),(581,'Command: npc set allowmove'),(582,'Command: npc set entry'),(583,'Command: npc set factionid'),(584,'Command: npc set flag'),(585,'Command: npc set level'),(586,'Command: npc set link'),(587,'Command: npc set model'),(588,'Command: npc set movetype'),(589,'Command: npc set phase'),(590,'Command: npc set spawndist'),(591,'Command: npc set spawntime'),(592,'Command: npc set data'),(593,'Command: npc info'),(594,'Command: npc near'),(595,'Command: npc move'),(596,'Command: npc playemote'),(597,'Command: npc say'),(598,'Command: npc textemote'),(599,'Command: npc whisper'),(600,'Command: npc yell'),(601,'Command: npc tame'),(602,'Command: quest'),(603,'Command: quest add'),(604,'Command: quest complete'),(605,'Command: quest remove'),(606,'Command: quest reward'),(607,'Command: reload'),(608,'Command: reload access_requirement'),(609,'Command: reload achievement_criteria_data'),(610,'Command: reload achievement_reward'),(611,'Command: reload all'),(612,'Command: reload all achievement'),(613,'Command: reload all area'),(614,'Command: broadcast_text'),(615,'Command: reload all gossips'),(616,'Command: reload all item'),(617,'Command: reload all locales'),(618,'Command: reload all loot'),(619,'Command: reload all npc'),(620,'Command: reload all quest'),(621,'Command: reload all scripts'),(622,'Command: reload all spell'),(623,'Command: reload areatrigger_involvedrelation'),(624,'Command: reload areatrigger_tavern'),(625,'Command: reload areatrigger_teleport'),(626,'Command: reload auctions'),(627,'Command: reload autobroadcast'),(628,'Command: reload command'),(629,'Command: reload conditions'),(630,'Command: reload config'),(631,'Command: reload battleground_template'),(633,'Command: reload creature_linked_respawn'),(634,'Command: reload creature_loot_template'),(635,'Command: reload creature_onkill_reputation'),(636,'Command: reload creature_questender'),(637,'Command: reload creature_queststarter'),(638,'Command: reload creature_summon_groups'),(639,'Command: reload creature_template'),(640,'Command: reload creature_text'),(641,'Command: reload disables'),(642,'Command: reload disenchant_loot_template'),(643,'Command: reload event_scripts'),(644,'Command: reload fishing_loot_template'),(645,'Command: reload game_graveyard_zone'),(646,'Command: reload game_tele'),(647,'Command: reload gameobject_questender'),(648,'Command: reload gameobject_loot_template'),(649,'Command: reload gameobject_queststarter'),(650,'Command: reload gm_tickets'),(651,'Command: reload gossip_menu'),(652,'Command: reload gossip_menu_option'),(653,'Command: reload item_enchantment_template'),(654,'Command: reload item_loot_template'),(655,'Command: reload item_set_names'),(656,'Command: reload lfg_dungeon_rewards'),(657,'Command: reload locales_achievement_reward'),(658,'Command: reload locales_creature'),(659,'Command: reload locales_creature_text'),(660,'Command: reload locales_gameobject'),(661,'Command: reload locales_gossip_menu_option'),(662,'Command: reload locales_item'),(663,'Command: reload locales_item_set_name'),(664,'Command: reload locales_npc_text'),(665,'Command: reload locales_page_text'),(666,'Command: reload locales_points_of_interest'),(667,'Command: reload locales_quest'),(668,'Command: reload mail_level_reward'),(669,'Command: reload mail_loot_template'),(670,'Command: reload milling_loot_template'),(671,'Command: reload npc_spellclick_spells'),(672,'Command: reload npc_trainer'),(673,'Command: reload npc_vendor'),(674,'Command: reload page_text'),(675,'Command: reload pickpocketing_loot_template'),(676,'Command: reload points_of_interest'),(677,'Command: reload prospecting_loot_template'),(678,'Command: reload quest_poi'),(679,'Command: reload quest_template'),(680,'Command: reload rbac'),(681,'Command: reload reference_loot_template'),(682,'Command: reload reserved_name'),(683,'Command: reload reputation_reward_rate'),(684,'Command: reload reputation_spillover_template'),(685,'Command: reload skill_discovery_template'),(686,'Command: reload skill_extra_item_template'),(687,'Command: reload skill_fishing_base_level'),(688,'Command: reload skinning_loot_template'),(689,'Command: reload smart_scripts'),(690,'Command: reload spell_required'),(691,'Command: reload spell_area'),(692,'Command: reload spell_bonus_data'),(693,'Command: reload spell_group'),(694,'Command: reload spell_learn_spell'),(695,'Command: reload spell_loot_template'),(696,'Command: reload spell_linked_spell'),(697,'Command: reload spell_pet_auras'),(698,'Command: reload spell_proc_event'),(699,'Command: reload spell_proc'),(700,'Command: reload spell_scripts'),(701,'Command: reload spell_target_position'),(702,'Command: reload spell_threats'),(703,'Command: reload spell_group_stack_rules'),(704,'Command: reload trinity_string'),(705,'Command: reload warden_action'),(706,'Command: reload waypoint_scripts'),(707,'Command: reload waypoint_data'),(708,'Command: reload vehicle_accessory'),(709,'Command: reload vehicle_template_accessory'),(710,'Command: reset'),(711,'Command: reset achievements'),(712,'Command: reset honor'),(713,'Command: reset level'),(714,'Command: reset spells'),(715,'Command: reset stats'),(716,'Command: reset talents'),(717,'Command: reset all'),(718,'Command: server'),(719,'Command: server corpses'),(720,'Command: server exit'),(721,'Command: server idlerestart'),(722,'Command: server idlerestart cancel'),(723,'Command: server idleshutdown'),(724,'Command: server idleshutdown cancel'),(725,'Command: server info'),(726,'Command: server plimit'),(727,'Command: server restart'),(728,'Command: server restart cancel'),(729,'Command: server set'),(730,'Command: server set closed'),(731,'Command: server set difftime'),(732,'Command: server set loglevel'),(733,'Command: server set motd'),(734,'Command: server shutdown'),(735,'Command: server shutdown cancel'),(736,'Command: server motd'),(737,'Command: tele'),(738,'Command: tele add'),(739,'Command: tele del'),(740,'Command: tele name'),(741,'Command: tele group'),(742,'Command: ticket'),(743,'Command: ticket assign'),(744,'Command: ticket close'),(745,'Command: ticket closedlist'),(746,'Command: ticket comment'),(747,'Command: ticket complete'),(748,'Command: ticket delete'),(749,'Command: ticket escalate'),(750,'Command: ticket escalatedlist'),(751,'Command: ticket list'),(752,'Command: ticket onlinelist'),(753,'Command: ticket reset'),(754,'Command: ticket response'),(755,'Command: ticket response append'),(756,'Command: ticket response appendln'),(757,'Command: ticket togglesystem'),(758,'Command: ticket unassign'),(759,'Command: ticket viewid'),(760,'Command: ticket viewname'),(761,'Command: titles'),(762,'Command: titles add'),(763,'Command: titles current'),(764,'Command: titles remove'),(765,'Command: titles set'),(766,'Command: titles set mask'),(767,'Command: wp'),(768,'Command: wp add'),(769,'Command: wp event'),(770,'Command: wp load'),(771,'Command: wp modify'),(772,'Command: wp unload'),(773,'Command: wp reload'),(774,'Command: wp show'),(777,'Command: mailbox');
+INSERT INTO `rbac_permissions` VALUES (1,'Instant logout'),(2,'Skip Queue'),(3,'Join Normal Battleground'),(4,'Join Random Battleground'),(5,'Join Arenas'),(6,'Join Dungeon Finder'),(11,'Log GM trades'),(13,'Skip Instance required bosses check'),(14,'Skip character creation team mask check'),(15,'Skip character creation class mask check'),(16,'Skip character creation race mask check'),(17,'Skip character creation reserved name check'),(18,'Skip character creation heroic min level check'),(19,'Skip needed requirements to use channel check'),(20,'Skip disable map check'),(21,'Skip reset talents when used more than allowed check'),(22,'Skip spam chat check'),(23,'Skip over-speed ping check'),(24,'Two side faction characters on the same account'),(25,'Allow say chat between factions'),(26,'Allow channel chat between factions'),(27,'Two side mail interaction'),(28,'See two side who list'),(29,'Add friends of other faction'),(30,'Save character without delay with .save command'),(31,'Use params with .unstuck command'),(32,'Can be assigned tickets with .assign ticket command'),(33,'Notify if a command was not found'),(34,'Check if should appear in list using .gm ingame command'),(35,'See all security levels with who command'),(36,'Filter whispers'),(37,'Use staff badge in chat'),(38,'Resurrect with full Health Points'),(39,'Restore saved gm setting states'),(40,'Allows to add a gm to friend list'),(41,'Use Config option START_GM_LEVEL to assign new character level'),(42,'Allows to use CMSG_WORLD_TELEPORT opcode'),(43,'Allows to use CMSG_WHOIS opcode'),(44,'Receive global GM messages/texts'),(45,'Join channels without announce'),(46,'Change channel settings without being channel moderator'),(47,'Enables lower security than target check'),(48,'Enable IP, Last Login and EMail output in pinfo'),(49,'Forces to enter the email for confirmation on password change'),(50,'Allow user to check his own email with .account'),(192,'Role: Sec Level Administrator'),(193,'Role: Sec Level Gamemaster'),(194,'Role: Sec Level Moderator'),(195,'Role: Sec Level Player'),(196,'Role: Administrator Commands'),(197,'Role: Gamemaster Commands'),(198,'Role: Moderator Commands'),(199,'Role: Player Commands'),(200,'Command: rbac'),(201,'Command: rbac account'),(202,'Command: rbac account list'),(203,'Command: rbac account grant'),(204,'Command: rbac account deny'),(205,'Command: rbac account revoke'),(206,'Command: rbac list'),(217,'Command: account'),(218,'Command: account addon'),(219,'Command: account create'),(220,'Command: account delete'),(221,'Command: account lock'),(222,'Command: account lock country'),(223,'Command: account lock ip'),(224,'Command: account onlinelist'),(225,'Command: account password'),(226,'Command: account set'),(227,'Command: account set addon'),(228,'Command: account set gmlevel'),(229,'Command: account set password'),(230,'Command: achievement'),(231,'Command: achievement add'),(232,'Command: arena'),(233,'Command: arena captain'),(234,'Command: arena create'),(235,'Command: arena disband'),(236,'Command: arena info'),(237,'Command: arena lookup'),(238,'Command: arena rename'),(239,'Command: ban'),(240,'Command: ban account'),(241,'Command: ban character'),(242,'Command: ban ip'),(243,'Command: ban playeraccount'),(244,'Command: baninfo'),(245,'Command: baninfo account'),(246,'Command: baninfo character'),(247,'Command: baninfo ip'),(248,'Command: banlist'),(249,'Command: banlist account'),(250,'Command: banlist character'),(251,'Command: banlist ip'),(252,'Command: unban'),(253,'Command: unban account'),(254,'Command: unban character'),(255,'Command: unban ip'),(256,'Command: unban playeraccount'),(257,'Command: bf'),(258,'Command: bf start'),(259,'Command: bf stop'),(260,'Command: bf switch'),(261,'Command: bf timer'),(262,'Command: bf enable'),(263,'Command: account email'),(264,'Command: account set sec'),(265,'Command: account set sec email'),(266,'Command: account set sec regmail'),(267,'Command: cast'),(268,'Command: cast back'),(269,'Command: cast dist'),(270,'Command: cast self'),(271,'Command: cast target'),(272,'Command: cast dest'),(273,'Command: character'),(274,'Command: character customize'),(275,'Command: character changefaction'),(276,'Command: character changerace'),(277,'Command: character deleted'),(279,'Command: character deleted list'),(280,'Command: character deleted restore'),(283,'Command: character level'),(284,'Command: character rename'),(285,'Command: character reputation'),(286,'Command: character titles'),(287,'Command: levelup'),(288,'Command: pdump'),(289,'Command: pdump load'),(290,'Command: pdump write'),(291,'Command: cheat'),(292,'Command: cheat casttime'),(293,'Command: cheat cooldown'),(294,'Command: cheat explore'),(295,'Command: cheat god'),(296,'Command: cheat power'),(297,'Command: cheat status'),(298,'Command: cheat taxi'),(299,'Command: cheat waterwalk'),(300,'Command: debug'),(301,'Command: debug anim'),(302,'Command: debug areatriggers'),(303,'Command: debug arena'),(304,'Command: debug bg'),(305,'Command: debug entervehicle'),(306,'Command: debug getitemstate'),(307,'Command: debug getitemvalue'),(308,'Command: debug getvalue'),(309,'Command: debug hostil'),(310,'Command: debug itemexpire'),(311,'Command: debug lootrecipient'),(312,'Command: debug los'),(313,'Command: debug mod32value'),(314,'Command: debug moveflags'),(315,'Command: debug play'),(316,'Command: debug play cinematics'),(317,'Command: debug play movie'),(318,'Command: debug play sound'),(319,'Command: debug send'),(320,'Command: debug send buyerror'),(321,'Command: debug send channelnotify'),(322,'Command: debug send chatmessage'),(323,'Command: debug send equiperror'),(324,'Command: debug send largepacket'),(325,'Command: debug send opcode'),(326,'Command: debug send qinvalidmsg'),(327,'Command: debug send qpartymsg'),(328,'Command: debug send sellerror'),(329,'Command: debug send setphaseshift'),(330,'Command: debug send spellfail'),(331,'Command: debug setaurastate'),(332,'Command: debug setbit'),(333,'Command: debug setitemvalue'),(334,'Command: debug setvalue'),(335,'Command: debug setvid'),(336,'Command: debug spawnvehicle'),(337,'Command: debug threat'),(338,'Command: debug update'),(339,'Command: debug uws'),(340,'Command: wpgps'),(341,'Command: deserter'),(342,'Command: deserter bg'),(343,'Command: deserter bg add'),(344,'Command: deserter bg remove'),(345,'Command: deserter instance'),(346,'Command: deserter instance add'),(347,'Command: deserter instance remove'),(348,'Command: disable'),(349,'Command: disable add'),(350,'Command: disable add achievement_criteria'),(351,'Command: disable add battleground'),(352,'Command: disable add map'),(353,'Command: disable add mmap'),(354,'Command: disable add outdoorpvp'),(355,'Command: disable add quest'),(356,'Command: disable add spell'),(357,'Command: disable add vmap'),(358,'Command: disable remove'),(359,'Command: disable remove achievement_criteria'),(360,'Command: disable remove battleground'),(361,'Command: disable remove map'),(362,'Command: disable remove mmap'),(363,'Command: disable remove outdoorpvp'),(364,'Command: disable remove quest'),(365,'Command: disable remove spell'),(366,'Command: disable remove vmap'),(367,'Command: event'),(368,'Command: event activelist'),(369,'Command: event start'),(370,'Command: event stop'),(371,'Command: gm'),(372,'Command: gm chat'),(373,'Command: gm fly'),(374,'Command: gm ingame'),(375,'Command: gm list'),(376,'Command: gm visible'),(377,'Command: go'),(378,'Command: go creature'),(379,'Command: go graveyard'),(380,'Command: go grid'),(381,'Command: go object'),(382,'Command: go taxinode'),(383,'Command: go ticket'),(384,'Command: go trigger'),(385,'Command: go xyz'),(386,'Command: go zonexy'),(387,'Command: gobject'),(388,'Command: gobject activate'),(389,'Command: gobject add'),(390,'Command: gobject add temp'),(391,'Command: gobject delete'),(392,'Command: gobject info'),(393,'Command: gobject move'),(394,'Command: gobject near'),(395,'Command: gobject set'),(396,'Command: gobject set phase'),(397,'Command: gobject set state'),(398,'Command: gobject target'),(399,'Command: gobject turn'),(400,'debug transport'),(401,'Command: guild'),(402,'Command: guild create'),(403,'Command: guild delete'),(404,'Command: guild invite'),(405,'Command: guild uninvite'),(406,'Command: guild rank'),(407,'Command: guild rename'),(408,'Command: honor'),(409,'Command: honor add'),(410,'Command: honor add kill'),(411,'Command: honor update'),(412,'Command: instance'),(413,'Command: instance listbinds'),(414,'Command: instance unbind'),(415,'Command: instance stats'),(416,'Command: instance savedata'),(417,'Command: learn'),(418,'Command: learn all'),(419,'Command: learn all my'),(420,'Command: learn all my class'),(421,'Command: learn all my pettalents'),(422,'Command: learn all my spells'),(423,'Command: learn all my talents'),(424,'Command: learn all gm'),(425,'Command: learn all crafts'),(426,'Command: learn all default'),(427,'Command: learn all lang'),(428,'Command: learn all recipes'),(429,'Command: unlearn'),(430,'Command: lfg'),(431,'Command: lfg player'),(432,'Command: lfg group'),(433,'Command: lfg queue'),(434,'Command: lfg clean'),(435,'Command: lfg options'),(436,'Command: list'),(437,'Command: list creature'),(438,'Command: list item'),(439,'Command: list object'),(440,'Command: list auras'),(441,'Command: list mail'),(442,'Command: lookup'),(443,'Command: lookup area'),(444,'Command: lookup creature'),(445,'Command: lookup event'),(446,'Command: lookup faction'),(447,'Command: lookup item'),(448,'Command: lookup itemset'),(449,'Command: lookup object'),(450,'Command: lookup quest'),(451,'Command: lookup player'),(452,'Command: lookup player ip'),(453,'Command: lookup player account'),(454,'Command: lookup player email'),(455,'Command: lookup skill'),(456,'Command: lookup spell'),(457,'Command: lookup spell id'),(458,'Command: lookup taxinode'),(459,'Command: lookup tele'),(460,'Command: lookup title'),(461,'Command: lookup map'),(462,'Command: announce'),(463,'Command: channel'),(464,'Command: channel set'),(465,'Command: channel set ownership'),(466,'Command: gmannounce'),(467,'Command: gmnameannounce'),(468,'Command: gmnotify'),(469,'Command: nameannounce'),(470,'Command: notify'),(471,'Command: whispers'),(472,'Command: group'),(473,'Command: group leader'),(474,'Command: group disband'),(475,'Command: group remove'),(476,'Command: group join'),(477,'Command: group list'),(478,'Command: group summon'),(479,'Command: pet'),(480,'Command: pet create'),(481,'Command: pet learn'),(482,'Command: pet unlearn'),(483,'Command: send'),(484,'Command: send items'),(485,'Command: send mail'),(486,'Command: send message'),(487,'Command: send money'),(488,'Command: additem'),(489,'Command: additemset'),(490,'Command: appear'),(491,'Command: aura'),(492,'Command: bank'),(493,'Command: bindsight'),(494,'Command: combatstop'),(495,'Command: cometome'),(496,'Command: commands'),(497,'Command: cooldown'),(498,'Command: damage'),(499,'Command: dev'),(500,'Command: die'),(501,'Command: dismount'),(502,'Command: distance'),(503,'Command: flusharenapoints'),(504,'Command: freeze'),(505,'Command: gps'),(506,'Command: guid'),(507,'Command: help'),(508,'Command: hidearea'),(509,'Command: itemmove'),(510,'Command: kick'),(511,'Command: linkgrave'),(512,'Command: listfreeze'),(513,'Command: maxskill'),(514,'Command: movegens'),(515,'Command: mute'),(516,'Command: neargrave'),(517,'Command: pinfo'),(518,'Command: playall'),(519,'Command: possess'),(520,'Command: recall'),(521,'Command: repairitems'),(522,'Command: respawn'),(523,'Command: revive'),(524,'Command: saveall'),(525,'Command: save'),(526,'Command: setskill'),(527,'Command: showarea'),(528,'Command: summon'),(529,'Command: unaura'),(530,'Command: unbindsight'),(531,'Command: unfreeze'),(532,'Command: unmute'),(533,'Command: unpossess'),(534,'Command: unstuck'),(535,'Command: wchange'),(536,'Command: mmap'),(537,'Command: mmap loadedtiles'),(538,'Command: mmap loc'),(539,'Command: mmap path'),(540,'Command: mmap stats'),(541,'Command: mmap testarea'),(542,'Command: morph'),(543,'Command: demorph'),(544,'Command: modify'),(545,'Command: modify arenapoints'),(546,'Command: modify bit'),(547,'Command: modify drunk'),(548,'Command: modify energy'),(549,'Command: modify faction'),(550,'Command: modify gender'),(551,'Command: modify honor'),(552,'Command: modify hp'),(553,'Command: modify mana'),(554,'Command: modify money'),(555,'Command: modify mount'),(556,'Command: modify phase'),(557,'Command: modify rage'),(558,'Command: modify reputation'),(559,'Command: modify runicpower'),(560,'Command: modify scale'),(561,'Command: modify speed'),(562,'Command: modify speed all'),(563,'Command: modify speed backwalk'),(564,'Command: modify speed fly'),(565,'Command: modify speed walk'),(566,'Command: modify speed swim'),(567,'Command: modify spell'),(568,'Command: modify standstate'),(569,'Command: modify talentpoints'),(570,'Command: npc'),(571,'Command: npc add'),(572,'Command: npc add formation'),(573,'Command: npc add item'),(574,'Command: npc add move'),(575,'Command: npc add temp'),(576,'Command: npc add delete'),(577,'Command: npc add delete item'),(578,'Command: npc add follow'),(579,'Command: npc add follow stop'),(580,'Command: npc set'),(581,'Command: npc set allowmove'),(582,'Command: npc set entry'),(583,'Command: npc set factionid'),(584,'Command: npc set flag'),(585,'Command: npc set level'),(586,'Command: npc set link'),(587,'Command: npc set model'),(588,'Command: npc set movetype'),(589,'Command: npc set phase'),(590,'Command: npc set spawndist'),(591,'Command: npc set spawntime'),(592,'Command: npc set data'),(593,'Command: npc info'),(594,'Command: npc near'),(595,'Command: npc move'),(596,'Command: npc playemote'),(597,'Command: npc say'),(598,'Command: npc textemote'),(599,'Command: npc whisper'),(600,'Command: npc yell'),(601,'Command: npc tame'),(602,'Command: quest'),(603,'Command: quest add'),(604,'Command: quest complete'),(605,'Command: quest remove'),(606,'Command: quest reward'),(607,'Command: reload'),(608,'Command: reload access_requirement'),(609,'Command: reload achievement_criteria_data'),(610,'Command: reload achievement_reward'),(611,'Command: reload all'),(612,'Command: reload all achievement'),(613,'Command: reload all area'),(614,'Command: broadcast_text'),(615,'Command: reload all gossips'),(616,'Command: reload all item'),(617,'Command: reload all locales'),(618,'Command: reload all loot'),(619,'Command: reload all npc'),(620,'Command: reload all quest'),(621,'Command: reload all scripts'),(622,'Command: reload all spell'),(623,'Command: reload areatrigger_involvedrelation'),(624,'Command: reload areatrigger_tavern'),(625,'Command: reload areatrigger_teleport'),(626,'Command: reload auctions'),(627,'Command: reload autobroadcast'),(628,'Command: reload command'),(629,'Command: reload conditions'),(630,'Command: reload config'),(631,'Command: reload battleground_template'),(633,'Command: reload creature_linked_respawn'),(634,'Command: reload creature_loot_template'),(635,'Command: reload creature_onkill_reputation'),(636,'Command: reload creature_questender'),(637,'Command: reload creature_queststarter'),(638,'Command: reload creature_summon_groups'),(639,'Command: reload creature_template'),(640,'Command: reload creature_text'),(641,'Command: reload disables'),(642,'Command: reload disenchant_loot_template'),(643,'Command: reload event_scripts'),(644,'Command: reload fishing_loot_template'),(645,'Command: reload game_graveyard_zone'),(646,'Command: reload game_tele'),(647,'Command: reload gameobject_questender'),(648,'Command: reload gameobject_loot_template'),(649,'Command: reload gameobject_queststarter'),(650,'Command: reload gm_tickets'),(651,'Command: reload gossip_menu'),(652,'Command: reload gossip_menu_option'),(653,'Command: reload item_enchantment_template'),(654,'Command: reload item_loot_template'),(655,'Command: reload item_set_names'),(656,'Command: reload lfg_dungeon_rewards'),(657,'Command: reload locales_achievement_reward'),(658,'Command: reload locales_creature'),(659,'Command: reload locales_creature_text'),(660,'Command: reload locales_gameobject'),(661,'Command: reload locales_gossip_menu_option'),(662,'Command: reload locales_item'),(663,'Command: reload locales_item_set_name'),(664,'Command: reload locales_npc_text'),(665,'Command: reload locales_page_text'),(666,'Command: reload locales_points_of_interest'),(667,'Command: reload locales_quest'),(668,'Command: reload mail_level_reward'),(669,'Command: reload mail_loot_template'),(670,'Command: reload milling_loot_template'),(671,'Command: reload npc_spellclick_spells'),(672,'Command: reload npc_trainer'),(673,'Command: reload npc_vendor'),(674,'Command: reload page_text'),(675,'Command: reload pickpocketing_loot_template'),(676,'Command: reload points_of_interest'),(677,'Command: reload prospecting_loot_template'),(678,'Command: reload quest_poi'),(679,'Command: reload quest_template'),(680,'Command: reload rbac'),(681,'Command: reload reference_loot_template'),(682,'Command: reload reserved_name'),(683,'Command: reload reputation_reward_rate'),(684,'Command: reload reputation_spillover_template'),(685,'Command: reload skill_discovery_template'),(686,'Command: reload skill_extra_item_template'),(687,'Command: reload skill_fishing_base_level'),(688,'Command: reload skinning_loot_template'),(689,'Command: reload smart_scripts'),(690,'Command: reload spell_required'),(691,'Command: reload spell_area'),(692,'Command: reload spell_bonus_data'),(693,'Command: reload spell_group'),(694,'Command: reload spell_learn_spell'),(695,'Command: reload spell_loot_template'),(696,'Command: reload spell_linked_spell'),(697,'Command: reload spell_pet_auras'),(698,'Command: reload spell_proc_event'),(699,'Command: reload spell_proc'),(700,'Command: reload spell_scripts'),(701,'Command: reload spell_target_position'),(702,'Command: reload spell_threats'),(703,'Command: reload spell_group_stack_rules'),(704,'Command: reload trinity_string'),(705,'Command: reload warden_action'),(706,'Command: reload waypoint_scripts'),(707,'Command: reload waypoint_data'),(708,'Command: reload vehicle_accessory'),(709,'Command: reload vehicle_template_accessory'),(710,'Command: reset'),(711,'Command: reset achievements'),(712,'Command: reset honor'),(713,'Command: reset level'),(714,'Command: reset spells'),(715,'Command: reset stats'),(716,'Command: reset talents'),(717,'Command: reset all'),(718,'Command: server'),(719,'Command: server corpses'),(720,'Command: server exit'),(721,'Command: server idlerestart'),(722,'Command: server idlerestart cancel'),(723,'Command: server idleshutdown'),(724,'Command: server idleshutdown cancel'),(725,'Command: server info'),(726,'Command: server plimit'),(727,'Command: server restart'),(728,'Command: server restart cancel'),(729,'Command: server set'),(730,'Command: server set closed'),(731,'Command: server set difftime'),(732,'Command: server set loglevel'),(733,'Command: server set motd'),(734,'Command: server shutdown'),(735,'Command: server shutdown cancel'),(736,'Command: server motd'),(737,'Command: tele'),(738,'Command: tele add'),(739,'Command: tele del'),(740,'Command: tele name'),(741,'Command: tele group'),(742,'Command: ticket'),(743,'Command: ticket assign'),(744,'Command: ticket close'),(745,'Command: ticket closedlist'),(746,'Command: ticket comment'),(747,'Command: ticket complete'),(748,'Command: ticket delete'),(749,'Command: ticket escalate'),(750,'Command: ticket escalatedlist'),(751,'Command: ticket list'),(752,'Command: ticket onlinelist'),(753,'Command: ticket reset'),(754,'Command: ticket response'),(755,'Command: ticket response append'),(756,'Command: ticket response appendln'),(757,'Command: ticket togglesystem'),(758,'Command: ticket unassign'),(759,'Command: ticket viewid'),(760,'Command: ticket viewname'),(761,'Command: titles'),(762,'Command: titles add'),(763,'Command: titles current'),(764,'Command: titles remove'),(765,'Command: titles set'),(766,'Command: titles set mask'),(767,'Command: wp'),(768,'Command: wp add'),(769,'Command: wp event'),(770,'Command: wp load'),(771,'Command: wp modify'),(772,'Command: wp unload'),(773,'Command: wp reload'),(774,'Command: wp show'),(777,'Command: mailbox'),(778,'Command: ahbot'),(779,'Command: ahbot items'),(780,'Command: ahbot items gray'),(781,'Command: ahbot items white'),(782,'Command: ahbot items green'),(783,'Command: ahbot items blue'),(784,'Command: ahbot items purple'),(785,'Command: ahbot items orange'),(786,'Command: ahbot items yellow'),(787,'Command: ahbot ratio'),(788,'Command: ahbot ratio alliance'),(789,'Command: ahbot ratio horde'),(790,'Command: ahbot ratio neutral'),(791,'Command: ahbot rebuild'),(792,'Command: ahbot reload'),(793,'Command: ahbot status'),(794,'Command: .guild info');
/*!40000 ALTER TABLE `rbac_permissions` ENABLE KEYS */;
UNLOCK TABLES;
@@ -471,4 +471,4 @@ UNLOCK TABLES;
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;
--- Dump completed on 2014-07-08 11:39:12
+-- Dump completed on 2014-08-28 23:00:51
diff --git a/sql/updates/auth/2014_08_28_00_auth_rbac_ahbot.sql b/sql/updates/auth/2014_08_28_00_auth_rbac_ahbot.sql
new file mode 100644
index 00000000000..7de587dc19f
--- /dev/null
+++ b/sql/updates/auth/2014_08_28_00_auth_rbac_ahbot.sql
@@ -0,0 +1,40 @@
+SET @id = 778;
+
+-- Add new permissions
+DELETE FROM `rbac_permissions` WHERE `id` BETWEEN @id AND @id+15;
+INSERT INTO `rbac_permissions` (`id`, `name`) VALUES
+(@id, 'Command: ahbot'),
+(@id+1, 'Command: ahbot items'),
+(@id+2, 'Command: ahbot items gray'),
+(@id+3, 'Command: ahbot items white'),
+(@id+4, 'Command: ahbot items green'),
+(@id+5, 'Command: ahbot items blue'),
+(@id+6, 'Command: ahbot items purple'),
+(@id+7, 'Command: ahbot items orange'),
+(@id+8, 'Command: ahbot items yellow'),
+(@id+9, 'Command: ahbot ratio'),
+(@id+10, 'Command: ahbot ratio alliance'),
+(@id+11, 'Command: ahbot ratio horde'),
+(@id+12, 'Command: ahbot ratio neutral'),
+(@id+13, 'Command: ahbot rebuild'),
+(@id+14, 'Command: ahbot reload'),
+(@id+15, 'Command: ahbot status');
+
+DELETE FROM `rbac_linked_permissions` WHERE `linkedId` BETWEEN @id AND @id+15;
+INSERT INTO `rbac_linked_permissions` (`id`, `linkedId`) VALUES
+(192, @id),
+(192, @id+1),
+(192, @id+2),
+(192, @id+3),
+(192, @id+4),
+(192, @id+5),
+(192, @id+6),
+(192, @id+7),
+(192, @id+8),
+(192, @id+9),
+(192, @id+10),
+(192, @id+11),
+(192, @id+12),
+(192, @id+13),
+(192, @id+14),
+(192, @id+15);
diff --git a/sql/updates/auth/2014_08_28_01_auth_rbac_permissions.sql b/sql/updates/auth/2014_08_28_01_auth_rbac_permissions.sql
new file mode 100644
index 00000000000..4c885bfd92e
--- /dev/null
+++ b/sql/updates/auth/2014_08_28_01_auth_rbac_permissions.sql
@@ -0,0 +1,8 @@
+-- Permissions for .guild info command
+DELETE FROM `rbac_permissions` WHERE `id`=794;
+INSERT INTO `rbac_permissions` (`id`, `name`) VALUES
+(794, 'Command: .guild info');
+
+DELETE FROM `rbac_linked_permissions` WHERE `linkedId`=794;
+INSERT INTO `rbac_linked_permissions` (`id`, `linkedId`) VALUES
+(192, 794);
diff --git a/sql/updates/world/2014_08_28_01_world_ahbot.sql b/sql/updates/world/2014_08_28_01_world_ahbot.sql
new file mode 100644
index 00000000000..9a5eab9f393
--- /dev/null
+++ b/sql/updates/world/2014_08_28_01_world_ahbot.sql
@@ -0,0 +1,42 @@
+SET @id = 778;
+
+DELETE FROM `command` WHERE `name` LIKE 'ahbot%';
+INSERT INTO `command` (`name`, `permission`, `help`) VALUES
+('ahbot items', @id+1, 'Syntax: .ahbot items $GrayItems $WhiteItems $GreenItems $BlueItems $PurpleItems $OrangeItems $YellowItems\r\n\r\nSet amount of each items color be selled on auction.'),
+('ahbot items gray', @id+2, 'Syntax: .ahbot items gray $GrayItems\r\n\r\nSet amount of Gray color items be selled on auction.'),
+('ahbot items white', @id+3, 'Syntax: .ahbot items white $WhiteItems\r\n\r\nSet amount of White color items be selled on auction.'),
+('ahbot items green', @id+4, 'Syntax: .ahbot items green $GreenItems\r\n\r\nSet amount of Green color items be selled on auction.'),
+('ahbot items blue', @id+5, 'Syntax: .ahbot items blue $BlueItems\r\n\r\nSet amount of Blue color items be selled on auction.'),
+('ahbot items purple', @id+6, 'Syntax: .ahbot items purple $PurpleItems\r\n\r\nSet amount of Purple color items be selled on auction.'),
+('ahbot items orange', @id+7, 'Syntax: .ahbot items orange $OrangeItems\r\n\r\nSet amount of Orange color items be selled on auction.'),
+('ahbot items yellow', @id+8, 'Syntax: .ahbot items yellow $YellowItems\r\n\r\nSet amount of Yellow color items be selled on auction.'),
+('ahbot ratio', @id+9, 'Syntax: .ahbot ratio $allianceratio $horderatio $neutralratio\r\n\r\nSet ratio of items in 3 auctions house.'),
+('ahbot ratio alliance', @id+10, 'Syntax: .ahbot ratio alliance $allianceratio\r\n\r\nSet ratio of items in alliance auction house.'),
+('ahbot ratio horde', @id+11, 'Syntax: .ahbot ratio horde $horderatio\r\n\r\nSet ratio of items in horde auction house.'),
+('ahbot ratio neutral', @id+12, 'Syntax: .ahbot ratio neutral $neutralratio\r\n\r\nSet ratio of items in $neutral auction house.'),
+('ahbot rebuild', @id+13, 'Syntax: .ahbot rebuild [all]\r\n\r\nExpire all actual auction of ahbot except bided by player. Binded auctions included to expire if "all" option used. Ahbot re-fill auctions base at current settings then.'),
+('ahbot reload', @id+14, 'Syntax: .ahbot reload\r\n\r\nReload AHBot settings from configuration file.'),
+('ahbot status', @id+15, 'Syntax: .ahbot status [all]\r\n\r\nShow current ahbot state data in short form, and with "all" with details.');
+
+DELETE FROM `trinity_string` WHERE `entry` BETWEEN 1157 AND 1176;
+INSERT INTO `trinity_string` (`entry`, `content_default`) VALUES
+(1157, 'All config are reloaded from configuration file.'),
+(1158, '=========================================================='),
+(1159, '|--------------------------------------------------------|'),
+(1160, '| | Alliance | Horde | Neutral | Total |'),
+(1161, ' Alliance/Horde/Neutral/Total'),
+(1162, '| %-10s | %8u | %8u | %8u | %8u |'),
+(1163, '%-10s = %6u / %6u / %6u / %6u'),
+(1164, 'Count'),
+(1165, 'Item Ratio'),
+(1166, '| | Alliance | Horde | Neutral | Amount |'),
+(1167, ' Alliance/Horde/Neutral/Amount'),
+(1168, 'Gray'),
+(1169, 'White'),
+(1170, 'Green'),
+(1171, 'Blue'),
+(1172, 'Purple'),
+(1173, 'Orange'),
+(1174, 'Yellow'),
+(1175, 'Amount of %s items is set to %u.'),
+(1176, 'Items ratio for %s is set to %u.');
diff --git a/sql/updates/world/2014_08_28_02_world_sai.sql b/sql/updates/world/2014_08_28_02_world_sai.sql
new file mode 100644
index 00000000000..243d960b182
--- /dev/null
+++ b/sql/updates/world/2014_08_28_02_world_sai.sql
@@ -0,0 +1,6 @@
+--
+SET @ENTRY := 17589;
+UPDATE `creature_template` SET `AIName`='SmartAI' WHERE `entry`=@ENTRY;
+DELETE FROM `smart_scripts` WHERE `source_type`=0 AND `entryorguid`=@ENTRY;
+INSERT INTO `smart_scripts` (`entryorguid`,`source_type`,`id`,`link`,`event_type`,`event_phase_mask`,`event_chance`,`event_flags`,`event_param1`,`event_param2`,`event_param3`,`event_param4`,`action_type`,`action_param1`,`action_param2`,`action_param3`,`action_param4`,`action_param5`,`action_param6`,`target_type`,`target_param1`,`target_param2`,`target_param3`,`target_x`,`target_y`,`target_z`,`target_o`,`comment`) VALUES
+(@ENTRY,0,0,0,0,0,100,0,0,0,12000,14000,11,21067,64,0,0,0,0,2,0,0,0,0,0,0,0,'Veridian Broodling - In combat CMC - Spellcast Poison Bolt');
diff --git a/sql/updates/world/2014_08_28_03_world_ulduar.sql b/sql/updates/world/2014_08_28_03_world_ulduar.sql
new file mode 100644
index 00000000000..6405efd18f7
--- /dev/null
+++ b/sql/updates/world/2014_08_28_03_world_ulduar.sql
@@ -0,0 +1,106 @@
+--
+DELETE FROM `vehicle_template_accessory` WHERE `entry` IN (33651, 33432);
+INSERT INTO `vehicle_template_accessory` (`entry`, `accessory_entry`, `seat_id`, `minion`, `description`, `summontype`) VALUES
+(33651, 34050, 5, 1, 'VX-001 Rocket Seat 6', 8),
+(33651, 34050, 6, 1, 'VX-001 Rocket Seat 7', 8),
+(33432, 34071, 3, 1, 'MKII MKII turret Seat 1', 8);
+
+DELETE FROM `npc_spellclick_spells` WHERE `npc_entry` IN (33651, 33432);
+INSERT INTO `npc_spellclick_spells` (`npc_entry`, `spell_id`, `cast_flags`, `user_type`) VALUES
+(33651, 46598, 1, 1),
+(33432, 46598, 1, 1);
+
+UPDATE `creature_template` SET `HoverHeight` = 15, `ScriptName` = 'boss_aerial_command_unit', `InhabitType` = 4, `mechanic_immune_mask` = 646135679 WHERE `entry` = 33670;
+UPDATE `creature_template` SET `HoverHeight` = 15, `InhabitType` = 4, `mechanic_immune_mask` = 646135679 WHERE `entry` = 34109;
+UPDATE `creature_template` SET `unit_flags` = 33554438, `ScriptName` = 'boss_vx_001', `mechanic_immune_mask` = 646135679 WHERE `entry` = 33651;
+UPDATE `creature_template` SET `unit_flags` = 33554438, `mechanic_immune_mask` = 646135679 WHERE `entry` = 34108;
+UPDATE `creature_template` SET `ScriptName` = 'boss_leviathan_mk_ii', `mechanic_immune_mask` = 646135679 WHERE `entry` = 33432;
+UPDATE `creature_template` SET `mechanic_immune_mask` = 646135679 WHERE `entry` = 34106;
+UPDATE `creature_template` SET `InhabitType` = 4, `ScriptName` = 'boss_mimiron' WHERE `entry` = 33350;
+UPDATE `creature_template` SET `unit_flags` = 131078, `ScriptName` = 'npc_mimiron_proximity_mine' WHERE `entry` = 34362;
+UPDATE `creature_template` SET `unit_flags` = 33685510, `faction` = 14, `ScriptName` = 'npc_mimiron_frost_bomb' WHERE `entry` = 34149;
+UPDATE `creature_template` SET `unit_flags` = 33685510 WHERE `entry` IN( 34047, 34110, 34050, 34071);
+UPDATE `creature_template` SET `unit_flags` = 33685510, `ScriptName` = 'npc_magnetic_core' WHERE `entry` = 34068;
+UPDATE `creature_template` SET `unit_flags` = 33554436, `ScriptName` = 'npc_mimiron_flames' WHERE `entry` IN (34363, 34121);
+UPDATE `creature_template` SET `faction` = 14 , `ScriptName` = 'npc_mimiron_emergency_fire_bot' WHERE `entry` = 34147;
+UPDATE `creature_template` SET `faction` = 14 WHERE `entry` IN (34148, 34114, 33855);
+UPDATE `creature_template` SET `ScriptName` = 'npc_mimiron_assault_bot' WHERE `entry` = 34057;
+UPDATE `creature_template` SET `ScriptName` = 'npc_mimiron_computer' WHERE `entry` = 34143;
+UPDATE `creature_template` SET `speed_walk` = 2.5 , `speed_run` = 4.5 , `MovementType` = 2 , `InhabitType` = 7 WHERE `entry` = 33576;
+
+UPDATE `creature_model_info` SET `bounding_radius` = 0.31 , `combat_reach` = 5 WHERE `modelid` = 28979;
+UPDATE `creature_model_info` SET `bounding_radius` = 0.306 , `combat_reach` = 7 WHERE `modelid` = 28841;
+UPDATE `creature_model_info` SET `bounding_radius` = 0.31 , `combat_reach` = 7.7 WHERE `modelid` = 28831;
+
+UPDATE `gameobject_template` SET `flags` = 32, `ScriptName` = 'go_mimiron_hardmode_button' WHERE `entry` = 194739;
+
+UPDATE `creature_addon` SET `path_id` = 1376200 WHERE `guid` = 137620;
+
+UPDATE `creature` SET `position_x` = 2785.423 , `position_y` = 2673.119, `MovementType` = 2 WHERE `guid` = 137620;
+DELETE FROM `creature` WHERE `id` = 34071;
+
+
+DELETE FROM `creature_template_addon` WHERE `entry` IN (34047, 34148, 33836, 34149, 34147, 33670, 34363, 34121, 34109);
+INSERT INTO `creature_template_addon` (`entry`, `bytes1`, `bytes2`, `auras`) VALUES
+(33670, 50331648, 1, ''),
+(34109, 50331648, 1, ''),
+(34363, 0, 1, '64561'),
+(34121, 0, 1, '64561'),
+(34047, 0, 1, '64064'),
+(34148, 0, 1, '64616 64617'),
+(33836, 0, 1, '63767'),
+(34149, 0, 1, '64624'),
+(34147, 0, 1, '64617');
+
+DELETE FROM `creature_text` WHERE `entry` = 34143;
+INSERT INTO `creature_text` (`entry`, `groupid`, `text`, `type`, `probability`, `sound`, `BroadcastTextID`) VALUES
+(34143, 0, 'Self-destruct sequence initiated.', 14, 100, 15413, 34268),
+(34143, 1, 'Self-destruct sequence terminated. Override code A905..', 14, 100, 15414, 34284),
+(34143, 2, 'This area will self-destruct in ten minutes.', 14, 100, 15415, 34283),
+(34143, 3, 'This area will self-destruct in nine minutes.', 14, 100, 15416, 34282),
+(34143, 4, 'This area will self-destruct in eight minutes.', 14, 100, 15417, 34281),
+(34143, 5, 'This area will self-destruct in seven minutes.', 14, 100, 15418, 34280),
+(34143, 6, 'This area will self-destruct in six minutes.', 14, 100, 15419, 34273),
+(34143, 7, 'This area will self-destruct in five minutes.', 14, 100, 15420, 34274),
+(34143, 8, 'This area will self-destruct in four minutes.', 14, 100, 15421, 34275),
+(34143, 9, 'This area will self-destruct in three minutes.', 14, 100, 15422, 34276),
+(34143, 10, 'This area will self-destruct in two minutes.', 14, 100, 15423, 34277),
+(34143, 11, 'This area will self-destruct in one minute.', 14, 100, 15424, 34278),
+(34143, 12, 'Self-destruct sequence finalized. Have a nice day.', 14, 100, 15425, 34279);
+
+DELETE FROM `waypoint_data` WHERE `id` = 1376200;
+INSERT INTO `waypoint_data` (`id`, `point`, `position_x`, `position_y`, `position_z`, `orientation`, `delay`, `move_type`, `action`, `action_chance`, `wpguid`) VALUES
+(1376200, 0, 2785.423, 2673.119, 372.3605, 0, 0, 1, 0, 100, 0),
+(1376200, 1, 2823.024, 2649.059, 371.9791, 0, 0, 1, 0, 100, 0),
+(1376200, 2, 2854.097, 2590.826, 371.9791, 0, 0, 1, 0, 100, 0),
+(1376200, 3, 2852.951, 2547.112, 372.3605, 0, 0, 1, 0, 100, 0),
+(1376200, 4, 2822.796, 2489.515, 372.3605, 0, 0, 1, 0, 100, 0),
+(1376200, 5, 2784.964, 2465.247, 372.3605, 0, 0, 1, 0, 100, 0),
+(1376200, 6, 2741.24, 2456.771, 372.3605, 0, 0, 1, 0, 100, 0),
+(1376200, 7, 2701.036, 2464.319, 372.3605, 0, 0, 1, 0, 100, 0),
+(1376200, 8, 2660.476, 2489.578, 372.3605, 0, 0, 1, 0, 100, 0),
+(1376200, 9, 2636.893, 2525.687, 372.3605, 0, 0, 1, 0, 100, 0),
+(1376200, 10, 2631.294, 2547.831, 372.3605, 0, 0, 1, 0, 100, 0),
+(1376200, 11, 2631.437, 2591.752, 372.3605, 0, 0, 1, 0, 100, 0),
+(1376200, 12, 2637.362, 2613.7, 372.3605, 0, 0, 1, 0, 100, 0),
+(1376200, 13, 2650.221, 2636.163, 372.3605, 0, 0, 1, 0, 100, 0),
+(1376200, 14, 2661.572, 2649.715, 372.3605, 0, 0, 1, 0, 100, 0),
+(1376200, 15, 2696.595, 2672.664, 372.3605, 0, 0, 1, 0, 100, 0),
+(1376200, 16, 2711.099, 2677.791, 372.3605, 0, 0, 1, 0, 100, 0),
+(1376200, 17, 2740.676, 2683.12, 372.3605, 0, 0, 1, 0, 100, 0),
+(1376200, 18, 2771.834, 2677.767, 372.3605, 0, 0, 1, 0, 100, 0);
+
+DELETE FROM `disables` WHERE `sourceType` = 4 AND `entry` IN (10544, 10547, 10543, 10546, 10548, 10545, 10450, 10463, 10406, 10405);
+
+DELETE FROM `achievement_criteria_data` WHERE `criteria_id` IN (10406, 10405) AND `type` = 18;
+DELETE FROM `achievement_criteria_data` WHERE `criteria_id` IN (10545,10548,10546,10543,10547,10544, 10450, 10463) AND `type` = 11;
+INSERT INTO `achievement_criteria_data` (`criteria_id`, `type`, `value1`, `value2`, `ScriptName`) VALUES
+(10544, 11, 0, 0, 'achievement_setup_rocket'),
+(10547, 11, 0, 0, 'achievement_setup_rocket'),
+(10543, 11, 0, 0, 'achievement_setup_mine'),
+(10546, 11, 0, 0, 'achievement_setup_mine'),
+(10548, 11, 0, 0, 'achievement_setup_boom'),
+(10545, 11, 0, 0, 'achievement_setup_boom'),
+(10450, 11, 0, 0, 'achievement_firefighter'),
+(10463, 11, 0, 0, 'achievement_firefighter');
+--
diff --git a/sql/updates/world/2014_08_28_04_world_creature_template.sql b/sql/updates/world/2014_08_28_04_world_creature_template.sql
new file mode 100644
index 00000000000..ebd483850fb
--- /dev/null
+++ b/sql/updates/world/2014_08_28_04_world_creature_template.sql
@@ -0,0 +1,2 @@
+--
+UPDATE `creature_template` SET `faction`=14 WHERE `entry` IN (37672,38605,38786,38787);
diff --git a/sql/updates/world/2014_08_28_04_world_misc.sql b/sql/updates/world/2014_08_28_04_world_misc.sql
new file mode 100644
index 00000000000..3921b40998d
--- /dev/null
+++ b/sql/updates/world/2014_08_28_04_world_misc.sql
@@ -0,0 +1,15 @@
+-- .guild info command
+DELETE FROM `command` WHERE `name`='guild info';
+INSERT INTO `command` (`name`, `permission`, `help`) VALUES
+('guild info', 794, 'Shows information about target''''s guild or a given guild Id or Name.');
+
+-- .guild info command strings
+DELETE FROM `trinity_string` WHERE `entry` IN (1177,1178,1179,1180,1181,1182,1183);
+INSERT INTO `trinity_string` (`entry`, `content_default`) VALUES
+(1177, 'Displaying Guild Details for %s (Id: %u)'),
+(1178, '| Guild Master: %s (GUID: %u)'),
+(1179, '| Guild Creation Date: %s'),
+(1180, '| Guild Members: %u'),
+(1181, '| Guild Bank: %u gold'),
+(1182, '| Guild MOTD: %s'),
+(1183, '| Guild Information: %s');
diff --git a/sql/updates/world/2014_08_28_05_world_sai.sql b/sql/updates/world/2014_08_28_05_world_sai.sql
new file mode 100644
index 00000000000..acab7bfa4db
--- /dev/null
+++ b/sql/updates/world/2014_08_28_05_world_sai.sql
@@ -0,0 +1,90 @@
+DELETE FROM `creature_text` WHERE `entry` IN (26666,27221,27227);
+DELETE FROM `creature_text` WHERE `entry` =26484 and `groupid`>1;
+
+INSERT INTO `creature_text` (`entry`, `groupid`, `id`, `text`, `type`, `language`, `probability`, `emote`, `duration`, `sound`, `comment`, `BroadcastTextID`) VALUES
+(27227, 0, 0, 'Where... where am I?', 12, 0, 100, 0, 0, 0, 'Prospector Rokar',26240),
+(27227, 1, 0, 'Wait a minute here! You promised to spare me if I helped you. I held up my end o'' the bargain!', 12, 0, 100, 5, 0, 0, 'Prospector Rokar',26874),
+(27227, 2, 0, 'By the Light, Brann''s alive? I''d never help you capture him!', 12, 0, 100, 1, 0, 0, 'Prospector Rokar',26879),
+(26666, 0, 0, 'Stay your blade, Chieftain. He may yet have value to us.', 12, 0, 100, 1, 0, 0, 'Scout Vor''takh',26875),
+(26666, 1, 0, 'Remember the dwarven journal that was discovered? Well, this dwarf could be exactly what we need to track down Brann Bronzebeard and capture him.', 12, 0, 100, 1, 0, 0, 'Scout Vor''takh',26878),
+(26666, 2, 0, 'You will if you wish to keep your head attached to your shoulders.', 12, 0, 100, 1, 0, 0, 'Scout Vor''takh',26880),
+(26666, 3, 0, 'Does that satisfy you, Tormak?', 12, 0, 100, 6, 0, 0, 'Scout Vor''takh',26881),
+(27221, 0, 0, 'Let''s see if this works.', 12, 0, 100, 1, 0, 0, 'Tormak the Scarred',26239),
+(27221, 1, 0, 'You are among the Taunka of Camp Oneqwah, dwarf.', 12, 0, 100, 1, 0, 0, 'Tormak the Scarred',26251),
+(27221, 2, 0, 'If you agree to help us against our mutual enemy, you will come to no harm here.', 12, 0, 100, 1, 0, 0, 'Tormak the Scarred',26252),
+(27221, 3, 0, 'Think about it, prospector, but make up your mind swiftly. We must act soon.', 12, 0, 100, 25, 0, 0, 'Tormak the Scarred',26253),
+(27221, 4, 0, 'I''ll admit, dwarf, I was pleasantly surprised to see your plan succeed.', 12, 0, 100, 1, 0, 0, 'Tormak the Scarred',26871),
+(27221, 5, 0, 'We can''t just let you return to your companions and we can''t take you with us...', 12, 0, 100, 1, 0, 0, 'Tormak the Scarred',26873),
+(27221, 6, 0, 'He will live so long as he proves useful. I''d be careful if I was you, dwarf.', 12, 0, 100, 273, 0, 0, 'Tormak the Scarred',26882),
+(26484, 2, 0, 'By the Light, you killed Limpy Joe and took the meat! How did you know where to find us?', 12, 0, 100, 5, 0, 0, 'Hugh Glass',26639),
+(26484, 3, 0, 'Well, if you''ve come to kill me, too, can you at least wait until I''ve fed Griselda? Poor girl hasn''t eaten in days.', 12, 0, 100, 20, 0, 0, 'Hugh Glass',26642),
+(26484, 4, 0, 'Here, girl. I''ve got one last meal for you before Limpy Joe''s killer does us in!', 12, 0, 100, 22, 0, 0, 'Hugh Glass',26643),
+(26484, 5, 0, 'How could you kill poor, defenseless old Joe? And why did you bring the meat back?', 12, 0, 100, 6, 0, 0, 'Hugh Glass',26645),
+(26484, 6, 0, 'You''re an enigma, that''s what you are... And let me tell you, enigmas and I don''t get along....', 12, 0, 100, 1, 0, 0, 'Hugh Glass',26646),
+(26484, 7, 0, 'I think you''d best leave before Griselda decides she''s in the mood for dessert.', 12, 0, 100, 25, 0, 0, 'Hugh Glass',26647),
+(26484, 8, 0, 'Wake up, Griselda. Here, girl.', 12, 0, 100, 0, 0, 0, 'Hugh Glass',25700),
+(26484, 9, 0, 'They''ll never find us here, will they? We won''t let them get us like they got Limpy Joe and Flannel McGee!', 12, 0, 100, 5, 0, 0, 'Hugh Glass',25701),
+(26484, 9, 1, 'No, we escaped from those monsters! They''re nothing like us, Griselda.', 12, 0, 100, 1, 0, 0, 'Hugh Glass',25702),
+(26484, 9, 2, 'We''re hunters, you and I. No wolfmen here, no ma''am.', 12, 0, 100, 274, 0, 0, 'Hugh Glass',25703),
+(26484, 9, 3, 'Keep an eye out for them, girl! Don''t let them get us!', 12, 0, 100, 25, 0, 0, 'Hugh Glass',25704);
+
+UPDATE `creature_text` SET `emote`=396 WHERE `entry`=26604;
+
+UPDATE `creature_template` SET `AIName`='SmartAI' WHERE `entry` IN (26666,27221);
+DELETE FROM `smart_scripts` WHERE `entryorguid` IN (26666,27221) AND `source_type`=0;
+DELETE FROM `smart_scripts` WHERE `entryorguid` =26484 AND `source_type`=0 and `id`IN(1,2);
+
+DELETE FROM `smart_scripts` WHERE `entryorguid` IN (2722100,2722101,2648401) AND `source_type`=9;
+UPDATE `smart_scripts` SET `event_type`=20, `event_param1`=12484, `event_param2`=0, `event_param3`=0, `event_param4`=0, `comment`='Mack Fearsen - On Quest Complete (Scourgekabob) - Say Line 0' WHERE `entryorguid`=26604 AND `source_type`=0 AND `id`=2 AND `link`=0;
+
+INSERT INTO `smart_scripts` (`entryorguid`,`source_type`,`id`,`link`,`event_type`,`event_phase_mask`,`event_chance`,`event_flags`,`event_param1`,`event_param2`,`event_param3`,`event_param4`,`action_type`,`action_param1`,`action_param2`,`action_param3`,`action_param4`,`action_param5`,`action_param6`,`target_type`,`target_param1`,`target_param2`,`target_param3`,`target_x`,`target_y`,`target_z`,`target_o`,`comment`) VALUES
+(27221, 0, 0, 0, 20, 0, 100, 0, 12195, 0, 0, 0, 80, 2722100, 2, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Tormak the Scarred - On Quest Reward (The Unexpected Guest) - Run Script'),
+(27221, 0, 1, 0, 20, 0, 100, 0, 12199, 0, 0, 0, 80, 2722101, 2, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Tormak the Scarred - On Quest Reward (Bringing Down The Iron Thane) - Run Script 2'),
+(26666, 0, 0, 0, 38, 0, 100, 0, 1, 1, 0, 0, 53, 0, 26666, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Scout Vor''takh - On Data Set 1 1 - Start WP'),
+(26666, 0, 1, 0, 40, 0, 100, 0, 6, 26666, 0, 0, 54, 32000, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Scout Vor''takh - On On reached wp6 - Pause WP'),
+(26666, 0, 2, 0, 40, 0, 100, 0, 7, 26666, 0, 0, 66, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 4.55531, 'Scout Vor''takh - On On reached wp7 - Set Orientation'),
+(26484, 0, 1, 0, 20, 0, 100, 0, 12279, 0, 0, 0, 80, 2648401, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Hugh Glass - On Quest reward (A Bear of an Appetite) - Run Script'),
+(26484, 0, 2, 0, 1, 0, 100, 0, 15000, 60000, 90000, 120000, 1, 9, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Hugh Glass - OOC - Say'),
+(2722100, 9, 0, 0, 0, 0, 100, 0, 0, 0, 0, 0, 66, 0, 0, 0, 0, 0, 0, 19, 27227, 0, 0, 0, 0, 0, 0, 'Tormak the Scarred - Script - Set Orientation'),
+(2722100, 9, 1, 0, 0, 0, 100, 0, 0, 0, 0, 0, 81, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Tormak the Scarred - Script - Set NPC Flags'),
+(2722100, 9, 2, 0, 0, 0, 100, 0, 1000, 1000, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Tormak the Scarred - Script - Say Line 1'),
+(2722100, 9, 3, 0, 0, 0, 100, 0, 6000, 6000, 0, 0, 1, 0, 0, 0, 0, 0, 0, 19, 27227, 0, 0, 0, 0, 0, 0, 'Tormak the Scarred - Script - Say Line 1 on Prospector Rokar'),
+(2722100, 9, 4, 0, 0, 0, 100, 0, 6000, 6000, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Tormak the Scarred - Script - Say Line 2'),
+(2722100, 9, 5, 0, 0, 0, 100, 0, 6000, 6000, 0, 0, 1, 2, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Tormak the Scarred - Script - Say Line 3'),
+(2722100, 9, 6, 0, 0, 0, 100, 0, 6000, 6000, 0, 0, 1, 3, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Tormak the Scarred - Script - Say Line 4'),
+(2722100, 9, 7, 0, 0, 0, 100, 0, 2000, 2000, 0, 0, 81, 2, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Tormak the Scarred - Script - Set NPC Flags'),
+(2722100, 9, 8, 0, 0, 0, 100, 0, 0, 0, 0, 0, 66, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 2.80998, 'Tormak the Scarred - Script - Set Orientation'),
+(2722101, 9, 0, 0, 0, 0, 100, 0, 0, 0, 0, 0, 66, 0, 0, 0, 0, 0, 0, 19, 27227, 0, 0, 0, 0, 0, 0, 'Tormak the Scarred - Script 2 - Set Orientation'),
+(2722101, 9, 1, 0, 0, 0, 100, 0, 0, 0, 0, 0, 81, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Tormak the Scarred - Script 2 - Set NPC Flags'),
+(2722101, 9, 2, 0, 0, 0, 100, 0, 1000, 1000, 0, 0, 1, 4, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Tormak the Scarred - Script 2 - Say Line 5'),
+(2722101, 9, 3, 0, 0, 0, 100, 0, 6000, 6000, 0, 0, 1, 5, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Tormak the Scarred - Script 2 - Say Line 6'),
+(2722101, 9, 4, 0, 0, 0, 100, 0, 6000, 6000, 0, 0, 1, 1, 0, 0, 0, 0, 0, 19, 27227, 0, 0, 0, 0, 0, 0, 'Tormak the Scarred - Script 2 - Say Line 2 on Prospector Rokar'),
+(2722101, 9, 5, 0, 0, 0, 100, 0, 3000, 3000, 0, 0, 45, 1, 1, 0, 0, 0, 0, 19, 26666, 0, 0, 0, 0, 0, 0, 'Tormak the Scarred - Script 2 - Set Data 1 1 on Scout Vor''takh'),
+(2722101, 9, 6, 0, 0, 0, 100, 0, 3000, 3000, 0, 0, 1, 0, 0, 0, 0, 0, 0, 19, 26666, 0, 0, 0, 0, 0, 0, 'Tormak the Scarred - Script - Say Line 1 on Scout Vor''takh'),
+(2722101, 9, 7, 0, 0, 0, 100, 0, 6000, 6000, 0, 0, 1, 1, 0, 0, 0, 0, 0, 19, 26666, 0, 0, 0, 0, 0, 0, 'Tormak the Scarred - Script - Say Line 2 on Scout Vor''takh'),
+(2722101, 9, 8, 0, 0, 0, 100, 0, 6000, 6000, 0, 0, 1, 2, 0, 0, 0, 0, 0, 19, 27227, 0, 0, 0, 0, 0, 0, 'Tormak the Scarred - Script 2 - Say Line 3 on Prospector Rokar'),
+(2722101, 9, 9, 0, 0, 0, 100, 0, 6000, 6000, 0, 0, 1, 2, 0, 0, 0, 0, 0, 19, 26666, 0, 0, 0, 0, 0, 0, 'Tormak the Scarred - Script - Say Line 3 on Scout Vor''takh'),
+(2722101, 9, 10, 0, 0, 0, 100, 0, 6000, 6000, 0, 0, 1, 3, 0, 0, 0, 0, 0, 19, 26666, 0, 0, 0, 0, 0, 0, 'Tormak the Scarred - Script 2 - Say Line 3 on Scout Vor''takh'),
+(2722101, 9, 11, 0, 0, 0, 100, 0, 6000, 6000, 0, 0, 1, 6, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Tormak the Scarred - Script 2 - Say Line 7'),
+(2722101, 9, 12, 0, 0, 0, 100, 0, 2000, 2000, 0, 0, 81, 2, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Tormak the Scarred - Script 2 - Set NPC Flags'),
+(2722101, 9, 13, 0, 0, 0, 100, 0, 0, 0, 0, 0, 66, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 2.80998, 'Tormak the Scarred - Script 2 - Set Orientation'),
+(2648401, 9, 0, 0, 0, 0, 100, 0, 0, 0, 0, 0, 81, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Hugh Glass - Script 2 - Set NPC Flags'),
+(2648401, 9, 1, 0, 0, 0, 100, 0, 1000, 1000, 0, 0, 1, 2, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Hugh Glass - Script 2 - Say Line 3'),
+(2648401, 9, 2, 0, 0, 0, 100, 0, 6000, 6000, 0, 0, 1, 3, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Hugh Glass - Script 2 - Say Line 4'),
+(2648401, 9, 3, 0, 0, 0, 100, 0, 6000, 6000, 0, 0, 1, 4, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Hugh Glass - Script 2 - Say Line 4'),
+(2648401, 9, 4, 0, 0, 0, 100, 0, 6000, 6000, 0, 0, 1, 5, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Hugh Glass - Script 2 - Say Line 4'),
+(2648401, 9, 5, 0, 0, 0, 100, 0, 6000, 6000, 0, 0, 1, 6, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Hugh Glass - Script 2 - Say Line 4'),
+(2648401, 9, 6, 0, 0, 0, 100, 0, 6000, 6000, 0, 0, 1, 7, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Hugh Glass - Script 2 - Say Line 4'),
+(2648401, 9, 7, 0, 0, 0, 100, 0, 6000, 6000, 0, 0, 1, 8, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Hugh Glass - Script 2 - Say Line 4'),
+(2648401, 9, 8, 0, 0, 0, 100, 0, 2000, 2000, 0, 0, 81, 643, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Hugh Glass - Script 2 - Set NPC Flags');
+
+DELETE FROM `waypoints` WHERE `entry` =26666;
+INSERT INTO `waypoints` (`entry`, `pointid`, `position_x`, `position_y`, `position_z`, `point_comment`) VALUES
+(26666, 1,3849.295, -4532.052, 209.5975, 'Scout Vor''takh'),
+(26666, 2,3850.295, -4531.552, 209.5975, 'Scout Vor''takh'),
+(26666, 3,3851.545, -4530.302, 210.3475, 'Scout Vor''takh'),
+(26666, 4,3851.795, -4530.052, 210.3475, 'Scout Vor''takh'),
+(26666, 5,3853.545, -4529.802, 209.5975, 'Scout Vor''takh'),
+(26666, 6,3855.295, -4529.802, 209.5975, 'Scout Vor''takh'),
+(26666, 7,3848.19, -4531.66, 209.344, 'Scout Vor''takh');
+
diff --git a/sql/updates/world/2014_08_28_06_world_command.sql b/sql/updates/world/2014_08_28_06_world_command.sql
new file mode 100644
index 00000000000..963d7ca4269
--- /dev/null
+++ b/sql/updates/world/2014_08_28_06_world_command.sql
@@ -0,0 +1 @@
+UPDATE `command` SET `help`='Shows information about target''s guild or a given guild identifier or name.' WHERE `name`='guild info';
diff --git a/sql/updates/world/2014_08_29_00_world_creature_template.sql b/sql/updates/world/2014_08_29_00_world_creature_template.sql
new file mode 100644
index 00000000000..da298a0f6c5
--- /dev/null
+++ b/sql/updates/world/2014_08_29_00_world_creature_template.sql
@@ -0,0 +1,4 @@
+--
+UPDATE `creature_template` SET `faction`=834 WHERE `entry` IN (40681,40682,40683,40684);
+UPDATE `creature_template` SET `faction`=14 WHERE `entry` IN (38285,38788,38789,38790);
+UPDATE `creature_template` SET `faction`=21 WHERE `entry` IN (38184,38185);
diff --git a/sql/updates/world/2014_08_29_01_world_creature_template.sql b/sql/updates/world/2014_08_29_01_world_creature_template.sql
new file mode 100644
index 00000000000..4c4101d0c83
--- /dev/null
+++ b/sql/updates/world/2014_08_29_01_world_creature_template.sql
@@ -0,0 +1,2 @@
+-- Adds trigger and civilian flags_extra to Halion's Soul Consumption triggers
+UPDATE `creature_template` SET `flags_extra` = `flags_extra` |2|128 WHERE `entry` IN (40673, 40674, 40675);
diff --git a/sql/updates/world/2014_08_29_02_world_creature_template.sql b/sql/updates/world/2014_08_29_02_world_creature_template.sql
new file mode 100644
index 00000000000..2b151714e97
--- /dev/null
+++ b/sql/updates/world/2014_08_29_02_world_creature_template.sql
@@ -0,0 +1,3 @@
+--
+UPDATE `creature_template` SET `faction`=534 WHERE `entry` IN (37580,37614,37576,37615,37575,37617,37572,37616);
+UPDATE `creature_template` SET `faction`=35 WHERE `entry` IN (37813,38402,38582,38583);
diff --git a/sql/updates/world/2014_08_29_03_world_creature_template.sql b/sql/updates/world/2014_08_29_03_world_creature_template.sql
new file mode 100644
index 00000000000..7c057c8dc85
--- /dev/null
+++ b/sql/updates/world/2014_08_29_03_world_creature_template.sql
@@ -0,0 +1,5 @@
+--
+UPDATE `creature_template` SET `faction`=1692 WHERE `entry` IN (33139,34111);
+UPDATE `creature_template` SET `faction`=16 WHERE `entry` IN(32908,33151,32907,33150,32885,33153,32883,33152,32882,33154);
+UPDATE `creature_template` SET `faction`=1814 WHERE `entry` IN (29098,31602,29096,31590,29062,31589);
+UPDATE `creature_template` SET `faction`=14 WHERE `entry` IN (29153,31585);
diff --git a/src/server/game/Accounts/RBAC.h b/src/server/game/Accounts/RBAC.h
index 855ffd51bb8..020ed1a686a 100644
--- a/src/server/game/Accounts/RBAC.h
+++ b/src/server/game/Accounts/RBAC.h
@@ -681,6 +681,23 @@ enum RBACPermissions
RBAC_PERM_COMMAND_MODIFY_CURRENCY = 775, // only 4.3.4
RBAC_PERM_COMMAND_DEBUG_PHASE = 776, // only 4.3.4
RBAC_PERM_COMMAND_MAILBOX = 777,
+ RBAC_PERM_COMMAND_AHBOT = 778,
+ RBAC_PERM_COMMAND_AHBOT_ITEMS = 779,
+ RBAC_PERM_COMMAND_AHBOT_ITEMS_GRAY = 780,
+ RBAC_PERM_COMMAND_AHBOT_ITEMS_WHITE = 781,
+ RBAC_PERM_COMMAND_AHBOT_ITEMS_GREEN = 782,
+ RBAC_PERM_COMMAND_AHBOT_ITEMS_BLUE = 783,
+ RBAC_PERM_COMMAND_AHBOT_ITEMS_PURPLE = 784,
+ RBAC_PERM_COMMAND_AHBOT_ITEMS_ORANGE = 785,
+ RBAC_PERM_COMMAND_AHBOT_ITEMS_YELLOW = 786,
+ RBAC_PERM_COMMAND_AHBOT_RATIO = 787,
+ RBAC_PERM_COMMAND_AHBOT_RATIO_ALLIANCE = 788,
+ RBAC_PERM_COMMAND_AHBOT_RATIO_HORDE = 789,
+ RBAC_PERM_COMMAND_AHBOT_RATIO_NEUTRAL = 790,
+ RBAC_PERM_COMMAND_AHBOT_REBUILD = 791,
+ RBAC_PERM_COMMAND_AHBOT_RELOAD = 792,
+ RBAC_PERM_COMMAND_AHBOT_STATUS = 793,
+ RBAC_PERM_COMMAND_GUILD_INFO = 794,
// custom permissions 1000+
RBAC_PERM_MAX
diff --git a/src/server/game/AuctionHouseBot/AuctionHouseBot.cpp b/src/server/game/AuctionHouseBot/AuctionHouseBot.cpp
new file mode 100644
index 00000000000..6bf5fa0aaa5
--- /dev/null
+++ b/src/server/game/AuctionHouseBot/AuctionHouseBot.cpp
@@ -0,0 +1,426 @@
+/*
+ * Copyright (C) 2008-2014 TrinityCore <http://www.trinitycore.org/>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "Log.h"
+#include "Item.h"
+#include "World.h"
+#include "Config.h"
+#include "AuctionHouseMgr.h"
+#include "AuctionHouseBot.h"
+#include "AuctionHouseBotBuyer.h"
+#include "AuctionHouseBotSeller.h"
+
+bool AuctionBotConfig::Initialize()
+{
+ GetConfigFromFile();
+
+ if (!GetConfig(CONFIG_AHBOT_BUYER_ENABLED) && !GetConfig(CONFIG_AHBOT_SELLER_ENABLED))
+ {
+ TC_LOG_INFO("ahbot", "AHBOT is Disabled.");
+ return false;
+ }
+
+ if (GetConfig(CONFIG_AHBOT_ALLIANCE_ITEM_AMOUNT_RATIO) == 0 && GetConfig(CONFIG_AHBOT_HORDE_ITEM_AMOUNT_RATIO) == 0 && GetConfig(CONFIG_AHBOT_NEUTRAL_ITEM_AMOUNT_RATIO) == 0 &&
+ !GetConfig(CONFIG_AHBOT_BUYER_ALLIANCE_ENABLED) && !GetConfig(CONFIG_AHBOT_BUYER_HORDE_ENABLED) && !GetConfig(CONFIG_AHBOT_BUYER_NEUTRAL_ENABLED))
+ {
+ TC_LOG_INFO("ahbot", "All feature of AuctionHouseBot are disabled!");
+ return false;
+ }
+
+ if (GetConfig(CONFIG_AHBOT_ALLIANCE_ITEM_AMOUNT_RATIO) == 0 && GetConfig(CONFIG_AHBOT_HORDE_ITEM_AMOUNT_RATIO) == 0 && GetConfig(CONFIG_AHBOT_NEUTRAL_ITEM_AMOUNT_RATIO) == 0)
+ TC_LOG_INFO("ahbot", "AuctionHouseBot SELLER is disabled!");
+
+ if (!GetConfig(CONFIG_AHBOT_BUYER_ALLIANCE_ENABLED) && !GetConfig(CONFIG_AHBOT_BUYER_HORDE_ENABLED) && !GetConfig(CONFIG_AHBOT_BUYER_NEUTRAL_ENABLED))
+ TC_LOG_INFO("ahbot", "AuctionHouseBot BUYER is disabled!");
+
+ _itemsPerCycleBoost = GetConfig(CONFIG_AHBOT_ITEMS_PER_CYCLE_BOOST);
+ _itemsPerCycleNormal = GetConfig(CONFIG_AHBOT_ITEMS_PER_CYCLE_NORMAL);
+
+ return true;
+}
+
+void AuctionBotConfig::SetConfig(AuctionBotConfigUInt32Values index, char const* fieldname, uint32 defvalue)
+{
+ SetConfig(index, sConfigMgr->GetIntDefault(fieldname, defvalue));
+
+ if (int32(GetConfig(index)) < 0)
+ {
+ TC_LOG_ERROR("ahbot", "AHBot: %s (%i) can't be negative. Using %u instead.", fieldname, int32(GetConfig(index)), defvalue);
+ SetConfig(index, defvalue);
+ }
+}
+
+void AuctionBotConfig::SetConfigMax(AuctionBotConfigUInt32Values index, char const* fieldname, uint32 defvalue, uint32 maxvalue)
+{
+ SetConfig(index, sConfigMgr->GetIntDefault(fieldname, defvalue));
+
+ if (GetConfig(index) > maxvalue)
+ {
+ TC_LOG_ERROR("ahbot", "AHBot: %s (%u) must be in range 0...%u. Using %u instead.", fieldname, GetConfig(index), maxvalue, maxvalue);
+ SetConfig(index, maxvalue);
+ }
+}
+
+void AuctionBotConfig::SetConfigMinMax(AuctionBotConfigUInt32Values index, char const* fieldname, uint32 defvalue, uint32 minvalue, uint32 maxvalue)
+{
+ SetConfig(index, sConfigMgr->GetIntDefault(fieldname, defvalue));
+
+ if (GetConfig(index) > maxvalue)
+ {
+ TC_LOG_ERROR("ahbot", "AHBot: %s (%u) must be in range %u...%u. Using %u instead.", fieldname, GetConfig(index), minvalue, maxvalue, maxvalue);
+ SetConfig(index, maxvalue);
+ }
+
+ if (GetConfig(index) < minvalue)
+ {
+ TC_LOG_ERROR("ahbot", "AHBot: %s (%u) must be in range %u...%u. Using %u instead.", fieldname, GetConfig(index), minvalue, maxvalue, minvalue);
+ SetConfig(index, minvalue);
+ }
+}
+
+void AuctionBotConfig::SetConfig(AuctionBotConfigBoolValues index, char const* fieldname, bool defvalue)
+{
+ SetConfig(index, sConfigMgr->GetBoolDefault(fieldname, defvalue));
+}
+
+//Get AuctionHousebot configuration file
+void AuctionBotConfig::GetConfigFromFile()
+{
+ SetConfigMax(CONFIG_AHBOT_ALLIANCE_ITEM_AMOUNT_RATIO, "AuctionHouseBot.Alliance.Items.Amount.Ratio", 100, 10000);
+ SetConfigMax(CONFIG_AHBOT_HORDE_ITEM_AMOUNT_RATIO, "AuctionHouseBot.Horde.Items.Amount.Ratio", 100, 10000);
+ SetConfigMax(CONFIG_AHBOT_NEUTRAL_ITEM_AMOUNT_RATIO, "AuctionHouseBot.Neutral.Items.Amount.Ratio", 100, 10000);
+
+ SetAHBotIncludes(sConfigMgr->GetStringDefault("AuctionHouseBot.forceIncludeItems", ""));
+ SetAHBotExcludes(sConfigMgr->GetStringDefault("AuctionHouseBot.forceExcludeItems", ""));
+
+ SetConfig(CONFIG_AHBOT_BUYER_ALLIANCE_ENABLED, "AuctionHouseBot.Buyer.Alliance.Enabled", false);
+ SetConfig(CONFIG_AHBOT_BUYER_HORDE_ENABLED, "AuctionHouseBot.Buyer.Horde.Enabled", false);
+ SetConfig(CONFIG_AHBOT_BUYER_NEUTRAL_ENABLED, "AuctionHouseBot.Buyer.Neutral.Enabled", false);
+
+ SetConfig(CONFIG_AHBOT_ITEMS_VENDOR, "AuctionHouseBot.Items.Vendor", false);
+ SetConfig(CONFIG_AHBOT_ITEMS_LOOT, "AuctionHouseBot.Items.Loot", true);
+ SetConfig(CONFIG_AHBOT_ITEMS_MISC, "AuctionHouseBot.Items.Misc", false);
+
+ SetConfig(CONFIG_AHBOT_BIND_NO, "AuctionHouseBot.Bind.No", true);
+ SetConfig(CONFIG_AHBOT_BIND_PICKUP, "AuctionHouseBot.Bind.Pickup", false);
+ SetConfig(CONFIG_AHBOT_BIND_EQUIP, "AuctionHouseBot.Bind.Equip", true);
+ SetConfig(CONFIG_AHBOT_BIND_USE, "AuctionHouseBot.Bind.Use", true);
+ SetConfig(CONFIG_AHBOT_BIND_QUEST, "AuctionHouseBot.Bind.Quest", false);
+ SetConfig(CONFIG_AHBOT_LOCKBOX_ENABLED, "AuctionHouseBot.LockBox.Enabled", false);
+
+ SetConfig(CONFIG_AHBOT_BUYPRICE_SELLER, "AuctionHouseBot.BuyPrice.Seller", true);
+
+ SetConfig(CONFIG_AHBOT_ITEMS_PER_CYCLE_BOOST, "AuctionHouseBot.ItemsPerCycle.Boost", 1000);
+ SetConfig(CONFIG_AHBOT_ITEMS_PER_CYCLE_NORMAL, "AuctionHouseBot.ItemsPerCycle.Normal", 20);
+
+ SetConfig(CONFIG_AHBOT_ITEM_MIN_ITEM_LEVEL, "AuctionHouseBot.Items.ItemLevel.Min", 0);
+ SetConfig(CONFIG_AHBOT_ITEM_MAX_ITEM_LEVEL, "AuctionHouseBot.Items.ItemLevel.Max", 0);
+ SetConfig(CONFIG_AHBOT_ITEM_MIN_REQ_LEVEL, "AuctionHouseBot.Items.ReqLevel.Min", 0);
+ SetConfig(CONFIG_AHBOT_ITEM_MAX_REQ_LEVEL, "AuctionHouseBot.Items.ReqLevel.Max", 0);
+ SetConfig(CONFIG_AHBOT_ITEM_MIN_SKILL_RANK, "AuctionHouseBot.Items.ReqSkill.Min", 0);
+ SetConfig(CONFIG_AHBOT_ITEM_MAX_SKILL_RANK, "AuctionHouseBot.Items.ReqSkill.Max", 0);
+
+ SetConfig(CONFIG_AHBOT_ITEM_GRAY_AMOUNT, "AuctionHouseBot.Items.Amount.Gray", 0);
+ SetConfig(CONFIG_AHBOT_ITEM_WHITE_AMOUNT, "AuctionHouseBot.Items.Amount.White", 2000);
+ SetConfig(CONFIG_AHBOT_ITEM_GREEN_AMOUNT, "AuctionHouseBot.Items.Amount.Green", 2500);
+ SetConfig(CONFIG_AHBOT_ITEM_BLUE_AMOUNT, "AuctionHouseBot.Items.Amount.Blue", 1500);
+ SetConfig(CONFIG_AHBOT_ITEM_PURPLE_AMOUNT, "AuctionHouseBot.Items.Amount.Purple", 500);
+ SetConfig(CONFIG_AHBOT_ITEM_ORANGE_AMOUNT, "AuctionHouseBot.Items.Amount.Orange", 0);
+ SetConfig(CONFIG_AHBOT_ITEM_YELLOW_AMOUNT, "AuctionHouseBot.Items.Amount.Yellow", 0);
+
+ SetConfigMax(CONFIG_AHBOT_CLASS_CONSUMABLE_AMOUNT, "AuctionHouseBot.Class.Consumable", 6, 10);
+ SetConfigMax(CONFIG_AHBOT_CLASS_CONTAINER_AMOUNT, "AuctionHouseBot.Class.Container", 4, 10);
+ SetConfigMax(CONFIG_AHBOT_CLASS_WEAPON_AMOUNT, "AuctionHouseBot.Class.Weapon", 8, 10);
+ SetConfigMax(CONFIG_AHBOT_CLASS_GEM_AMOUNT, "AuctionHouseBot.Class.Gem", 3, 10);
+ SetConfigMax(CONFIG_AHBOT_CLASS_ARMOR_AMOUNT, "AuctionHouseBot.Class.Armor", 8, 10);
+ SetConfigMax(CONFIG_AHBOT_CLASS_REAGENT_AMOUNT, "AuctionHouseBot.Class.Reagent", 1, 10);
+ SetConfigMax(CONFIG_AHBOT_CLASS_PROJECTILE_AMOUNT, "AuctionHouseBot.Class.Projectile", 2, 10);
+ SetConfigMax(CONFIG_AHBOT_CLASS_TRADEGOOD_AMOUNT, "AuctionHouseBot.Class.TradeGood", 10, 10);
+ SetConfigMax(CONFIG_AHBOT_CLASS_GENERIC_AMOUNT, "AuctionHouseBot.Class.Generic", 1, 10);
+ SetConfigMax(CONFIG_AHBOT_CLASS_RECIPE_AMOUNT, "AuctionHouseBot.Class.Recipe", 6, 10);
+ SetConfigMax(CONFIG_AHBOT_CLASS_QUIVER_AMOUNT, "AuctionHouseBot.Class.Quiver", 1, 10);
+ SetConfigMax(CONFIG_AHBOT_CLASS_QUEST_AMOUNT, "AuctionHouseBot.Class.Quest", 1, 10);
+ SetConfigMax(CONFIG_AHBOT_CLASS_KEY_AMOUNT, "AuctionHouseBot.Class.Key", 1, 10);
+ SetConfigMax(CONFIG_AHBOT_CLASS_MISC_AMOUNT, "AuctionHouseBot.Class.Misc", 5, 10);
+ SetConfigMax(CONFIG_AHBOT_CLASS_GLYPH_AMOUNT, "AuctionHouseBot.Class.Glyph", 3, 10);
+
+ SetConfig(CONFIG_AHBOT_ALLIANCE_PRICE_RATIO, "AuctionHouseBot.Alliance.Price.Ratio", 100);
+ SetConfig(CONFIG_AHBOT_HORDE_PRICE_RATIO, "AuctionHouseBot.Horde.Price.Ratio", 100);
+ SetConfig(CONFIG_AHBOT_NEUTRAL_PRICE_RATIO, "AuctionHouseBot.Neutral.Price.Ratio", 100);
+
+ SetConfig(CONFIG_AHBOT_ITEM_GRAY_PRICE_RATIO, "AuctionHouseBot.Items.Gray.Price.Ratio", 100);
+ SetConfig(CONFIG_AHBOT_ITEM_WHITE_PRICE_RATIO, "AuctionHouseBot.Items.White.Price.Ratio", 100);
+ SetConfig(CONFIG_AHBOT_ITEM_GREEN_PRICE_RATIO, "AuctionHouseBot.Items.Green.Price.Ratio", 100);
+ SetConfig(CONFIG_AHBOT_ITEM_BLUE_PRICE_RATIO, "AuctionHouseBot.Items.Blue.Price.Ratio", 100);
+ SetConfig(CONFIG_AHBOT_ITEM_PURPLE_PRICE_RATIO, "AuctionHouseBot.Items.Purple.Price.Ratio", 100);
+ SetConfig(CONFIG_AHBOT_ITEM_ORANGE_PRICE_RATIO, "AuctionHouseBot.Items.Orange.Price.Ratio", 100);
+ SetConfig(CONFIG_AHBOT_ITEM_YELLOW_PRICE_RATIO, "AuctionHouseBot.Items.Yellow.Price.Ratio", 100);
+
+ SetConfig(CONFIG_AHBOT_CLASS_CONSUMABLE_PRICE_RATIO, "AuctionHouseBot.Class.Consumable.Price.Ratio", 100);
+ SetConfig(CONFIG_AHBOT_CLASS_CONTAINER_PRICE_RATIO, "AuctionHouseBot.Class.Container.Price.Ratio", 100);
+ SetConfig(CONFIG_AHBOT_CLASS_WEAPON_PRICE_RATIO, "AuctionHouseBot.Class.Weapon.Price.Ratio", 100);
+ SetConfig(CONFIG_AHBOT_CLASS_GEM_PRICE_RATIO, "AuctionHouseBot.Class.Gem.Price.Ratio", 100);
+ SetConfig(CONFIG_AHBOT_CLASS_ARMOR_PRICE_RATIO, "AuctionHouseBot.Class.Armor.Price.Ratio", 100);
+ SetConfig(CONFIG_AHBOT_CLASS_REAGENT_PRICE_RATIO, "AuctionHouseBot.Class.Reagent.Price.Ratio", 100);
+ SetConfig(CONFIG_AHBOT_CLASS_PROJECTILE_PRICE_RATIO, "AuctionHouseBot.Class.Projectile.Price.Ratio", 100);
+ SetConfig(CONFIG_AHBOT_CLASS_TRADEGOOD_PRICE_RATIO, "AuctionHouseBot.Class.TradeGood.Price.Ratio", 100);
+ SetConfig(CONFIG_AHBOT_CLASS_GENERIC_PRICE_RATIO, "AuctionHouseBot.Class.Generic.Price.Ratio", 100);
+ SetConfig(CONFIG_AHBOT_CLASS_RECIPE_PRICE_RATIO, "AuctionHouseBot.Class.Recipe.Price.Ratio", 100);
+ SetConfig(CONFIG_AHBOT_CLASS_QUIVER_PRICE_RATIO, "AuctionHouseBot.Class.Quiver.Price.Ratio", 100);
+ SetConfig(CONFIG_AHBOT_CLASS_QUEST_PRICE_RATIO, "AuctionHouseBot.Class.Quest.Price.Ratio", 100);
+ SetConfig(CONFIG_AHBOT_CLASS_KEY_PRICE_RATIO, "AuctionHouseBot.Class.Key.Price.Ratio", 100);
+ SetConfig(CONFIG_AHBOT_CLASS_MISC_PRICE_RATIO, "AuctionHouseBot.Class.Misc.Price.Ratio", 100);
+ SetConfig(CONFIG_AHBOT_CLASS_GLYPH_PRICE_RATIO, "AuctionHouseBot.Class.Glyph.Price.Ratio", 100);
+
+ SetConfig(CONFIG_AHBOT_CLASS_CONSUMABLE_ALLOW_ZERO, "AuctionHouseBot.Class.Consumable.Allow.Zero", false);
+ SetConfig(CONFIG_AHBOT_CLASS_CONTAINER_ALLOW_ZERO, "AuctionHouseBot.Class.Container.Allow.Zero", false);
+ SetConfig(CONFIG_AHBOT_CLASS_WEAPON_ALLOW_ZERO, "AuctionHouseBot.Class.Weapon.Allow.Zero", false);
+ SetConfig(CONFIG_AHBOT_CLASS_GEM_ALLOW_ZERO, "AuctionHouseBot.Class.Gem.Allow.Zero", false);
+ SetConfig(CONFIG_AHBOT_CLASS_ARMOR_ALLOW_ZERO, "AuctionHouseBot.Class.Armor.Allow.Zero", false);
+ SetConfig(CONFIG_AHBOT_CLASS_REAGENT_ALLOW_ZERO, "AuctionHouseBot.Class.Reagent.Allow.Zero", false);
+ SetConfig(CONFIG_AHBOT_CLASS_PROJECTILE_ALLOW_ZERO, "AuctionHouseBot.Class.Projectile.Allow.Zero", false);
+ SetConfig(CONFIG_AHBOT_CLASS_TRADEGOOD_ALLOW_ZERO, "AuctionHouseBot.Class.TradeGood.Allow.Zero", false);
+ SetConfig(CONFIG_AHBOT_CLASS_RECIPE_ALLOW_ZERO, "AuctionHouseBot.Class.Recipe.Allow.Zero", false);
+ SetConfig(CONFIG_AHBOT_CLASS_QUIVER_ALLOW_ZERO, "AuctionHouseBot.Class.Quiver.Allow.Zero", false);
+ SetConfig(CONFIG_AHBOT_CLASS_QUEST_ALLOW_ZERO, "AuctionHouseBot.Class.Quest.Allow.Zero", false);
+ SetConfig(CONFIG_AHBOT_CLASS_KEY_ALLOW_ZERO, "AuctionHouseBot.Class.Key.Allow.Zero", false);
+ SetConfig(CONFIG_AHBOT_CLASS_MISC_ALLOW_ZERO, "AuctionHouseBot.Class.Misc.Allow.Zero", false);
+ SetConfig(CONFIG_AHBOT_CLASS_GLYPH_ALLOW_ZERO, "AuctionHouseBot.Class.Glyph.Allow.Zero", false);
+
+ SetConfig(CONFIG_AHBOT_MINTIME, "AuctionHouseBot.MinTime", 1);
+ SetConfig(CONFIG_AHBOT_MAXTIME, "AuctionHouseBot.MaxTime", 72);
+
+ SetConfigMinMax(CONFIG_AHBOT_BUYER_CHANCE_RATIO_ALLIANCE, "AuctionHouseBot.Buyer.Alliance.Chance.Ratio", 3, 1, 100);
+ SetConfigMinMax(CONFIG_AHBOT_BUYER_CHANCE_RATIO_HORDE, "AuctionHouseBot.Buyer.Horde.Chance.Ratio", 3, 1, 100);
+ SetConfigMinMax(CONFIG_AHBOT_BUYER_CHANCE_RATIO_NEUTRAL, "AuctionHouseBot.Buyer.Neutral.Chance.Ratio", 3, 1, 100);
+ SetConfigMinMax(CONFIG_AHBOT_BUYER_RECHECK_INTERVAL, "AuctionHouseBot.Buyer.Recheck.Interval", 20, 1, DAY / MINUTE);
+
+ SetConfig(CONFIG_AHBOT_SELLER_ENABLED, "AuctionHouseBot.Seller.Enabled", false);
+ SetConfig(CONFIG_AHBOT_BUYER_ENABLED, "AuctionHouseBot.Buyer.Enabled", false);
+ SetConfig(CONFIG_AHBOT_BUYPRICE_BUYER, "AuctionHouseBot.Buyer.Buyprice", true);
+
+ SetConfig(CONFIG_AHBOT_CLASS_MISC_MOUNT_MIN_REQ_LEVEL, "AuctionHouseBot.Class.Misc.Mount.ReqLevel.Min", 0);
+ SetConfig(CONFIG_AHBOT_CLASS_MISC_MOUNT_MAX_REQ_LEVEL, "AuctionHouseBot.Class.Misc.Mount.ReqLevel.Max", 0);
+ SetConfig(CONFIG_AHBOT_CLASS_MISC_MOUNT_MIN_SKILL_RANK, "AuctionHouseBot.Class.Misc.Mount.ReqSkill.Min", 0);
+ SetConfig(CONFIG_AHBOT_CLASS_MISC_MOUNT_MAX_SKILL_RANK, "AuctionHouseBot.Class.Misc.Mount.ReqSkill.Max", 0);
+ SetConfig(CONFIG_AHBOT_CLASS_GLYPH_MIN_REQ_LEVEL, "AuctionHouseBot.Class.Glyph.ReqLevel.Min", 0);
+ SetConfig(CONFIG_AHBOT_CLASS_GLYPH_MAX_REQ_LEVEL, "AuctionHouseBot.Class.Glyph.ReqLevel.Max", 0);
+ SetConfig(CONFIG_AHBOT_CLASS_GLYPH_MIN_ITEM_LEVEL, "AuctionHouseBot.Class.Glyph.ItemLevel.Min", 0);
+ SetConfig(CONFIG_AHBOT_CLASS_GLYPH_MAX_ITEM_LEVEL, "AuctionHouseBot.Class.Glyph.ItemLevel.Max", 0);
+ SetConfig(CONFIG_AHBOT_CLASS_TRADEGOOD_MIN_ITEM_LEVEL, "AuctionHouseBot.Class.TradeGood.ItemLevel.Min", 0);
+ SetConfig(CONFIG_AHBOT_CLASS_TRADEGOOD_MAX_ITEM_LEVEL, "AuctionHouseBot.Class.TradeGood.ItemLevel.Max", 0);
+ SetConfig(CONFIG_AHBOT_CLASS_CONTAINER_MIN_ITEM_LEVEL, "AuctionHouseBot.Class.Container.ItemLevel.Min", 0);
+ SetConfig(CONFIG_AHBOT_CLASS_CONTAINER_MAX_ITEM_LEVEL, "AuctionHouseBot.Class.Container.ItemLevel.Max", 0);
+}
+
+char const* AuctionBotConfig::GetHouseTypeName(AuctionHouseType houseType)
+{
+ static char const* names[MAX_AUCTION_HOUSE_TYPE] = { "Alliance", "Horde", "Neutral" };
+ return names[houseType];
+}
+
+uint32 AuctionBotConfig::GetConfigItemAmountRatio(AuctionHouseType houseType) const
+{
+ switch (houseType)
+ {
+ case AUCTION_HOUSE_ALLIANCE:
+ return GetConfig(CONFIG_AHBOT_ALLIANCE_ITEM_AMOUNT_RATIO);
+ case AUCTION_HOUSE_HORDE:
+ return GetConfig(CONFIG_AHBOT_HORDE_ITEM_AMOUNT_RATIO);
+ default:
+ return GetConfig(CONFIG_AHBOT_NEUTRAL_ITEM_AMOUNT_RATIO);
+ }
+}
+
+bool AuctionBotConfig::GetConfigBuyerEnabled(AuctionHouseType houseType) const
+{
+ switch (houseType)
+ {
+ case AUCTION_HOUSE_ALLIANCE:
+ return GetConfig(CONFIG_AHBOT_BUYER_ALLIANCE_ENABLED);
+ case AUCTION_HOUSE_HORDE:
+ return GetConfig(CONFIG_AHBOT_BUYER_HORDE_ENABLED);
+ default:
+ return GetConfig(CONFIG_AHBOT_BUYER_NEUTRAL_ENABLED);
+ }
+}
+
+uint32 AuctionBotConfig::GetConfigItemQualityAmount(AuctionQuality quality) const
+{
+ switch (quality)
+ {
+ case AUCTION_QUALITY_GRAY:
+ return GetConfig(CONFIG_AHBOT_ITEM_GRAY_AMOUNT);
+ case AUCTION_QUALITY_WHITE:
+ return GetConfig(CONFIG_AHBOT_ITEM_WHITE_AMOUNT);
+ case AUCTION_QUALITY_GREEN:
+ return GetConfig(CONFIG_AHBOT_ITEM_GREEN_AMOUNT);
+ case AUCTION_QUALITY_BLUE:
+ return GetConfig(CONFIG_AHBOT_ITEM_BLUE_AMOUNT);
+ case AUCTION_QUALITY_PURPLE:
+ return GetConfig(CONFIG_AHBOT_ITEM_PURPLE_AMOUNT);
+ case AUCTION_QUALITY_ORANGE:
+ return GetConfig(CONFIG_AHBOT_ITEM_ORANGE_AMOUNT);
+ default:
+ return GetConfig(CONFIG_AHBOT_ITEM_YELLOW_AMOUNT);
+ }
+}
+
+AuctionHouseBot::AuctionHouseBot(): _buyer(nullptr), _seller(nullptr), _operationSelector(0)
+{
+}
+
+AuctionHouseBot::~AuctionHouseBot()
+{
+ delete _buyer;
+ delete _seller;
+}
+
+void AuctionHouseBot::InitializeAgents()
+{
+ if (sAuctionBotConfig->GetConfig(CONFIG_AHBOT_SELLER_ENABLED))
+ {
+ delete _seller;
+
+ _seller = new AuctionBotSeller();
+ if (!_seller->Initialize())
+ {
+ delete _seller;
+ _seller = nullptr;
+ }
+ }
+
+ if (sAuctionBotConfig->GetConfig(CONFIG_AHBOT_BUYER_ENABLED))
+ {
+ delete _buyer;
+
+ _buyer = new AuctionBotBuyer();
+ if (!_buyer->Initialize())
+ {
+ delete _buyer;
+ _buyer = nullptr;
+ }
+ }
+}
+
+void AuctionHouseBot::Initialize()
+{
+ if (sAuctionBotConfig->Initialize())
+ InitializeAgents();
+}
+
+void AuctionHouseBot::SetItemsRatio(uint32 al, uint32 ho, uint32 ne)
+{
+ if (_seller)
+ _seller->SetItemsRatio(al, ho, ne);
+}
+
+void AuctionHouseBot::SetItemsRatioForHouse(AuctionHouseType house, uint32 val)
+{
+ if (_seller)
+ _seller->SetItemsRatioForHouse(house, val);
+}
+
+void AuctionHouseBot::SetItemsAmount(uint32(&vals)[MAX_AUCTION_QUALITY])
+{
+ if (_seller)
+ _seller->SetItemsAmount(vals);
+}
+
+void AuctionHouseBot::SetItemsAmountForQuality(AuctionQuality quality, uint32 val)
+{
+ if (_seller)
+ _seller->SetItemsAmountForQuality(quality, val);
+}
+
+void AuctionHouseBot::ReloadAllConfig()
+{
+ sAuctionBotConfig->Reload();
+ InitializeAgents();
+}
+
+void AuctionHouseBot::PrepareStatusInfos(AuctionHouseBotStatusInfo& statusInfo)
+{
+ for (uint32 i = 0; i < MAX_AUCTION_HOUSE_TYPE; ++i)
+ {
+ statusInfo[i].ItemsCount = 0;
+
+ for (int j = 0; j < MAX_AUCTION_QUALITY; ++j)
+ statusInfo[i].QualityInfo[j] = 0;
+
+ AuctionHouseObject* auctionHouse = sAuctionMgr->GetAuctionsMap(AuctionHouseType(i));
+ for (AuctionHouseObject::AuctionEntryMap::const_iterator itr = auctionHouse->GetAuctionsBegin(); itr != auctionHouse->GetAuctionsEnd(); ++itr)
+ {
+ AuctionEntry* auctionEntry = itr->second;
+ if (Item* item = sAuctionMgr->GetAItem(auctionEntry->itemGUIDLow))
+ {
+ ItemTemplate const* prototype = item->GetTemplate();
+ if (!auctionEntry->owner) // Add only ahbot items
+ {
+ if (prototype->Quality < MAX_AUCTION_QUALITY)
+ ++statusInfo[i].QualityInfo[prototype->Quality];
+
+ ++statusInfo[i].ItemsCount;
+ }
+ }
+ }
+ }
+}
+
+void AuctionHouseBot::Rebuild(bool all)
+{
+ for (uint32 i = 0; i < MAX_AUCTION_HOUSE_TYPE; ++i)
+ {
+ AuctionHouseObject* auctionHouse = sAuctionMgr->GetAuctionsMap(AuctionHouseType(i));
+ for (AuctionHouseObject::AuctionEntryMap::const_iterator itr = auctionHouse->GetAuctionsBegin(); itr != auctionHouse->GetAuctionsEnd(); ++itr)
+ if (!itr->second->owner) // ahbot auction
+ if (all || itr->second->bid == 0) // expire now auction if no bid or forced
+ itr->second->expire_time = sWorld->GetGameTime();
+ }
+}
+
+void AuctionHouseBot::Update()
+{
+ // nothing do...
+ if (!_buyer && !_seller)
+ return;
+
+ // scan all possible update cases until first success
+ for (uint32 count = 0; count < 2 * MAX_AUCTION_HOUSE_TYPE; ++count)
+ {
+ bool successStep = false;
+
+ if (_operationSelector < MAX_AUCTION_HOUSE_TYPE)
+ {
+ if (_seller)
+ successStep = _seller->Update(AuctionHouseType(_operationSelector));
+ }
+ else
+ {
+ if (_buyer)
+ successStep = _buyer->Update(AuctionHouseType(_operationSelector - MAX_AUCTION_HOUSE_TYPE));
+ }
+
+ ++_operationSelector;
+ if (_operationSelector >= 2 * MAX_AUCTION_HOUSE_TYPE)
+ _operationSelector = 0;
+
+ // one success update per call
+ if (successStep)
+ break;
+ }
+}
diff --git a/src/server/game/AuctionHouseBot/AuctionHouseBot.h b/src/server/game/AuctionHouseBot/AuctionHouseBot.h
new file mode 100644
index 00000000000..04ca96dfdd9
--- /dev/null
+++ b/src/server/game/AuctionHouseBot/AuctionHouseBot.h
@@ -0,0 +1,280 @@
+/*
+ * Copyright (C) 2008-2014 TrinityCore <http://www.trinitycore.org/>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef AUCTION_HOUSE_BOT_H
+#define AUCTION_HOUSE_BOT_H
+
+#include "Define.h"
+
+class AuctionBotSeller;
+class AuctionBotBuyer;
+
+// shadow of ItemQualities with skipped ITEM_QUALITY_HEIRLOOM, anything after ITEM_QUALITY_ARTIFACT(6) in fact
+enum AuctionQuality
+{
+ AUCTION_QUALITY_GRAY = ITEM_QUALITY_POOR,
+ AUCTION_QUALITY_WHITE = ITEM_QUALITY_NORMAL,
+ AUCTION_QUALITY_GREEN = ITEM_QUALITY_UNCOMMON,
+ AUCTION_QUALITY_BLUE = ITEM_QUALITY_RARE,
+ AUCTION_QUALITY_PURPLE = ITEM_QUALITY_EPIC,
+ AUCTION_QUALITY_ORANGE = ITEM_QUALITY_LEGENDARY,
+ AUCTION_QUALITY_YELLOW = ITEM_QUALITY_ARTIFACT,
+};
+
+#define MAX_AUCTION_QUALITY 7
+
+enum AuctionHouseType
+{
+ AUCTION_HOUSE_ALLIANCE = 0,
+ AUCTION_HOUSE_HORDE = 1,
+ AUCTION_HOUSE_NEUTRAL = 2
+};
+
+#define MAX_AUCTION_HOUSE_TYPE 3
+
+enum AuctionBotConfigUInt32Values
+{
+ CONFIG_AHBOT_MAXTIME,
+ CONFIG_AHBOT_MINTIME,
+ CONFIG_AHBOT_ITEMS_PER_CYCLE_BOOST,
+ CONFIG_AHBOT_ITEMS_PER_CYCLE_NORMAL,
+ CONFIG_AHBOT_ALLIANCE_ITEM_AMOUNT_RATIO,
+ CONFIG_AHBOT_HORDE_ITEM_AMOUNT_RATIO,
+ CONFIG_AHBOT_NEUTRAL_ITEM_AMOUNT_RATIO,
+ CONFIG_AHBOT_ITEM_MIN_ITEM_LEVEL,
+ CONFIG_AHBOT_ITEM_MAX_ITEM_LEVEL,
+ CONFIG_AHBOT_ITEM_MIN_REQ_LEVEL,
+ CONFIG_AHBOT_ITEM_MAX_REQ_LEVEL,
+ CONFIG_AHBOT_ITEM_MIN_SKILL_RANK,
+ CONFIG_AHBOT_ITEM_MAX_SKILL_RANK,
+ CONFIG_AHBOT_ITEM_GRAY_AMOUNT,
+ CONFIG_AHBOT_ITEM_WHITE_AMOUNT,
+ CONFIG_AHBOT_ITEM_GREEN_AMOUNT,
+ CONFIG_AHBOT_ITEM_BLUE_AMOUNT,
+ CONFIG_AHBOT_ITEM_PURPLE_AMOUNT,
+ CONFIG_AHBOT_ITEM_ORANGE_AMOUNT,
+ CONFIG_AHBOT_ITEM_YELLOW_AMOUNT,
+ CONFIG_AHBOT_CLASS_CONSUMABLE_AMOUNT,
+ CONFIG_AHBOT_CLASS_CONTAINER_AMOUNT,
+ CONFIG_AHBOT_CLASS_WEAPON_AMOUNT,
+ CONFIG_AHBOT_CLASS_GEM_AMOUNT,
+ CONFIG_AHBOT_CLASS_ARMOR_AMOUNT,
+ CONFIG_AHBOT_CLASS_REAGENT_AMOUNT,
+ CONFIG_AHBOT_CLASS_PROJECTILE_AMOUNT,
+ CONFIG_AHBOT_CLASS_TRADEGOOD_AMOUNT,
+ CONFIG_AHBOT_CLASS_GENERIC_AMOUNT,
+ CONFIG_AHBOT_CLASS_RECIPE_AMOUNT,
+ CONFIG_AHBOT_CLASS_QUIVER_AMOUNT,
+ CONFIG_AHBOT_CLASS_QUEST_AMOUNT,
+ CONFIG_AHBOT_CLASS_KEY_AMOUNT,
+ CONFIG_AHBOT_CLASS_MISC_AMOUNT,
+ CONFIG_AHBOT_CLASS_GLYPH_AMOUNT,
+ CONFIG_AHBOT_ALLIANCE_PRICE_RATIO,
+ CONFIG_AHBOT_HORDE_PRICE_RATIO,
+ CONFIG_AHBOT_NEUTRAL_PRICE_RATIO,
+ CONFIG_AHBOT_ITEM_GRAY_PRICE_RATIO,
+ CONFIG_AHBOT_ITEM_WHITE_PRICE_RATIO,
+ CONFIG_AHBOT_ITEM_GREEN_PRICE_RATIO,
+ CONFIG_AHBOT_ITEM_BLUE_PRICE_RATIO,
+ CONFIG_AHBOT_ITEM_PURPLE_PRICE_RATIO,
+ CONFIG_AHBOT_ITEM_ORANGE_PRICE_RATIO,
+ CONFIG_AHBOT_ITEM_YELLOW_PRICE_RATIO,
+ CONFIG_AHBOT_CLASS_CONSUMABLE_PRICE_RATIO,
+ CONFIG_AHBOT_CLASS_CONTAINER_PRICE_RATIO,
+ CONFIG_AHBOT_CLASS_WEAPON_PRICE_RATIO,
+ CONFIG_AHBOT_CLASS_GEM_PRICE_RATIO,
+ CONFIG_AHBOT_CLASS_ARMOR_PRICE_RATIO,
+ CONFIG_AHBOT_CLASS_REAGENT_PRICE_RATIO,
+ CONFIG_AHBOT_CLASS_PROJECTILE_PRICE_RATIO,
+ CONFIG_AHBOT_CLASS_TRADEGOOD_PRICE_RATIO,
+ CONFIG_AHBOT_CLASS_GENERIC_PRICE_RATIO,
+ CONFIG_AHBOT_CLASS_RECIPE_PRICE_RATIO,
+ CONFIG_AHBOT_CLASS_MONEY_PRICE_RATIO,
+ CONFIG_AHBOT_CLASS_QUIVER_PRICE_RATIO,
+ CONFIG_AHBOT_CLASS_QUEST_PRICE_RATIO,
+ CONFIG_AHBOT_CLASS_KEY_PRICE_RATIO,
+ CONFIG_AHBOT_CLASS_PERMANENT_PRICE_RATIO,
+ CONFIG_AHBOT_CLASS_MISC_PRICE_RATIO,
+ CONFIG_AHBOT_CLASS_GLYPH_PRICE_RATIO,
+ CONFIG_AHBOT_BUYER_CHANCE_RATIO_ALLIANCE,
+ CONFIG_AHBOT_BUYER_CHANCE_RATIO_HORDE,
+ CONFIG_AHBOT_BUYER_CHANCE_RATIO_NEUTRAL,
+ CONFIG_AHBOT_BUYER_RECHECK_INTERVAL,
+ CONFIG_AHBOT_CLASS_MISC_MOUNT_MIN_REQ_LEVEL,
+ CONFIG_AHBOT_CLASS_MISC_MOUNT_MAX_REQ_LEVEL,
+ CONFIG_AHBOT_CLASS_MISC_MOUNT_MIN_SKILL_RANK,
+ CONFIG_AHBOT_CLASS_MISC_MOUNT_MAX_SKILL_RANK,
+ CONFIG_AHBOT_CLASS_GLYPH_MIN_REQ_LEVEL,
+ CONFIG_AHBOT_CLASS_GLYPH_MAX_REQ_LEVEL,
+ CONFIG_AHBOT_CLASS_GLYPH_MIN_ITEM_LEVEL,
+ CONFIG_AHBOT_CLASS_GLYPH_MAX_ITEM_LEVEL,
+ CONFIG_AHBOT_CLASS_TRADEGOOD_MIN_ITEM_LEVEL,
+ CONFIG_AHBOT_CLASS_TRADEGOOD_MAX_ITEM_LEVEL,
+ CONFIG_AHBOT_CLASS_CONTAINER_MIN_ITEM_LEVEL,
+ CONFIG_AHBOT_CLASS_CONTAINER_MAX_ITEM_LEVEL,
+ CONFIG_UINT32_AHBOT_UINT32_COUNT
+};
+
+enum AuctionBotConfigBoolValues
+{
+ CONFIG_AHBOT_BUYER_ALLIANCE_ENABLED,
+ CONFIG_AHBOT_BUYER_HORDE_ENABLED,
+ CONFIG_AHBOT_BUYER_NEUTRAL_ENABLED,
+ CONFIG_AHBOT_ITEMS_VENDOR,
+ CONFIG_AHBOT_ITEMS_LOOT,
+ CONFIG_AHBOT_ITEMS_MISC,
+ CONFIG_AHBOT_BIND_NO,
+ CONFIG_AHBOT_BIND_PICKUP,
+ CONFIG_AHBOT_BIND_EQUIP,
+ CONFIG_AHBOT_BIND_USE,
+ CONFIG_AHBOT_BIND_QUEST,
+ CONFIG_AHBOT_BUYPRICE_SELLER,
+ CONFIG_AHBOT_BUYPRICE_BUYER,
+ CONFIG_AHBOT_SELLER_ENABLED,
+ CONFIG_AHBOT_BUYER_ENABLED,
+ CONFIG_AHBOT_LOCKBOX_ENABLED,
+ CONFIG_AHBOT_CLASS_CONSUMABLE_ALLOW_ZERO,
+ CONFIG_AHBOT_CLASS_CONTAINER_ALLOW_ZERO,
+ CONFIG_AHBOT_CLASS_WEAPON_ALLOW_ZERO,
+ CONFIG_AHBOT_CLASS_GEM_ALLOW_ZERO,
+ CONFIG_AHBOT_CLASS_ARMOR_ALLOW_ZERO,
+ CONFIG_AHBOT_CLASS_REAGENT_ALLOW_ZERO,
+ CONFIG_AHBOT_CLASS_PROJECTILE_ALLOW_ZERO,
+ CONFIG_AHBOT_CLASS_TRADEGOOD_ALLOW_ZERO,
+ CONFIG_AHBOT_CLASS_RECIPE_ALLOW_ZERO,
+ CONFIG_AHBOT_CLASS_QUIVER_ALLOW_ZERO,
+ CONFIG_AHBOT_CLASS_QUEST_ALLOW_ZERO,
+ CONFIG_AHBOT_CLASS_KEY_ALLOW_ZERO,
+ CONFIG_AHBOT_CLASS_MISC_ALLOW_ZERO,
+ CONFIG_AHBOT_CLASS_GLYPH_ALLOW_ZERO,
+ CONFIG_UINT32_AHBOT_BOOL_COUNT
+};
+
+// All basic config data used by other AHBot classes for self-configure.
+class AuctionBotConfig
+{
+private:
+ AuctionBotConfig(): _itemsPerCycleBoost(1000), _itemsPerCycleNormal(20) {}
+ ~AuctionBotConfig() {}
+ AuctionBotConfig(const AuctionBotConfig&);
+ AuctionBotConfig& operator=(const AuctionBotConfig&);
+
+public:
+ static AuctionBotConfig* instance()
+ {
+ static AuctionBotConfig instance;
+ return &instance;
+ }
+
+ bool Initialize();
+ const std::string& GetAHBotIncludes() const { return _AHBotIncludes; }
+ const std::string& GetAHBotExcludes() const { return _AHBotExcludes; }
+
+ uint32 GetConfig(AuctionBotConfigUInt32Values index) const { return _configUint32Values[index]; }
+ bool GetConfig(AuctionBotConfigBoolValues index) const { return _configBoolValues[index]; }
+ void SetConfig(AuctionBotConfigBoolValues index, bool value) { _configBoolValues[index] = value; }
+ void SetConfig(AuctionBotConfigUInt32Values index, uint32 value) { _configUint32Values[index] = value; }
+
+ uint32 GetConfigItemAmountRatio(AuctionHouseType houseType) const;
+ bool GetConfigBuyerEnabled(AuctionHouseType houseType) const;
+ uint32 GetConfigItemQualityAmount(AuctionQuality quality) const;
+
+ uint32 GetItemPerCycleBoost() const { return _itemsPerCycleBoost; }
+ uint32 GetItemPerCycleNormal() const { return _itemsPerCycleNormal; }
+ void Reload() { GetConfigFromFile(); }
+
+ static char const* GetHouseTypeName(AuctionHouseType houseType);
+
+private:
+ std::string _AHBotIncludes;
+ std::string _AHBotExcludes;
+ uint32 _itemsPerCycleBoost;
+ uint32 _itemsPerCycleNormal;
+
+ uint32 _configUint32Values[CONFIG_UINT32_AHBOT_UINT32_COUNT];
+ bool _configBoolValues[CONFIG_UINT32_AHBOT_BOOL_COUNT];
+
+ void SetAHBotIncludes(const std::string& AHBotIncludes) { _AHBotIncludes = AHBotIncludes; }
+ void SetAHBotExcludes(const std::string& AHBotExcludes) { _AHBotExcludes = AHBotExcludes; }
+
+ void SetConfig(AuctionBotConfigUInt32Values index, char const* fieldname, uint32 defvalue);
+ void SetConfigMax(AuctionBotConfigUInt32Values index, char const* fieldname, uint32 defvalue, uint32 maxvalue);
+ void SetConfigMinMax(AuctionBotConfigUInt32Values index, char const* fieldname, uint32 defvalue, uint32 minvalue, uint32 maxvalue);
+ void SetConfig(AuctionBotConfigBoolValues index, char const* fieldname, bool defvalue);
+ void GetConfigFromFile();
+};
+
+#define sAuctionBotConfig AuctionBotConfig::instance()
+
+class AuctionBotAgent
+{
+public:
+ AuctionBotAgent() {}
+ virtual ~AuctionBotAgent() {}
+ virtual bool Initialize() = 0;
+ virtual bool Update(AuctionHouseType houseType) = 0;
+};
+
+struct AuctionHouseBotStatusInfoPerType
+{
+ uint32 ItemsCount;
+ uint32 QualityInfo[MAX_AUCTION_QUALITY];
+};
+
+typedef AuctionHouseBotStatusInfoPerType AuctionHouseBotStatusInfo[MAX_AUCTION_HOUSE_TYPE];
+
+// This class handle both Selling and Buying method
+// (holder of AuctionBotBuyer and AuctionBotSeller objects)
+class AuctionHouseBot
+{
+private:
+ AuctionHouseBot();
+ ~AuctionHouseBot();
+ AuctionHouseBot(const AuctionHouseBot&);
+ AuctionHouseBot& operator=(const AuctionHouseBot&);
+
+public:
+ static AuctionHouseBot* instance()
+ {
+ static AuctionHouseBot instance;
+ return &instance;
+ }
+
+ void Update();
+ void Initialize();
+
+ // Followed method is mainly used by cs_ahbot.cpp for in-game/console command
+ void SetItemsRatio(uint32 al, uint32 ho, uint32 ne);
+ void SetItemsRatioForHouse(AuctionHouseType house, uint32 val);
+ void SetItemsAmount(uint32(&vals)[MAX_AUCTION_QUALITY]);
+ void SetItemsAmountForQuality(AuctionQuality quality, uint32 val);
+ void ReloadAllConfig();
+ void Rebuild(bool all);
+
+ void PrepareStatusInfos(AuctionHouseBotStatusInfo& statusInfo);
+private:
+ void InitializeAgents();
+
+ AuctionBotBuyer* _buyer;
+ AuctionBotSeller* _seller;
+
+ uint32 _operationSelector; // 0..2*MAX_AUCTION_HOUSE_TYPE-1
+};
+
+#define sAuctionBot AuctionHouseBot::instance()
+
+#endif
diff --git a/src/server/game/AuctionHouseBot/AuctionHouseBotBuyer.cpp b/src/server/game/AuctionHouseBot/AuctionHouseBotBuyer.cpp
new file mode 100644
index 00000000000..0043482c77f
--- /dev/null
+++ b/src/server/game/AuctionHouseBot/AuctionHouseBotBuyer.cpp
@@ -0,0 +1,432 @@
+/*
+ * Copyright (C) 2008-2014 TrinityCore <http://www.trinitycore.org/>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "Log.h"
+#include "Item.h"
+#include "ItemPrototype.h"
+#include "AuctionHouseBotBuyer.h"
+
+AuctionBotBuyer::AuctionBotBuyer(): _checkInterval(20)
+{
+ // Define faction for our main data class.
+ for (int i = 0; i < MAX_AUCTION_HOUSE_TYPE; ++i)
+ _houseConfig[i].Initialize(AuctionHouseType(i));
+}
+
+AuctionBotBuyer::~AuctionBotBuyer()
+{
+}
+
+bool AuctionBotBuyer::Initialize()
+{
+ LoadConfig();
+
+ bool activeHouse = false;
+ for (int i = 0; i < MAX_AUCTION_HOUSE_TYPE; ++i)
+ {
+ if (_houseConfig[i].BuyerEnabled)
+ {
+ activeHouse = true;
+ break;
+ }
+ }
+
+ if (!activeHouse)
+ return false;
+
+ //load Check interval
+ _checkInterval = sAuctionBotConfig->GetConfig(CONFIG_AHBOT_BUYER_RECHECK_INTERVAL) * MINUTE;
+ TC_LOG_DEBUG("ahbot", "AHBot buyer interval between 2 check = %u", _checkInterval);
+ return true;
+}
+
+void AuctionBotBuyer::LoadBuyerValues(BuyerConfiguration& config)
+{
+ uint32 factionChance;
+
+ switch (config.GetHouseType())
+ {
+ case AUCTION_HOUSE_ALLIANCE:
+ config.BuyerPriceRatio = sAuctionBotConfig->GetConfig(CONFIG_AHBOT_ALLIANCE_PRICE_RATIO) + 50;
+ factionChance = sAuctionBotConfig->GetConfig(CONFIG_AHBOT_BUYER_CHANCE_RATIO_ALLIANCE);
+ break;
+ case AUCTION_HOUSE_HORDE:
+ config.BuyerPriceRatio = sAuctionBotConfig->GetConfig(CONFIG_AHBOT_HORDE_PRICE_RATIO) + 50;
+ factionChance = sAuctionBotConfig->GetConfig(CONFIG_AHBOT_BUYER_CHANCE_RATIO_HORDE);
+ break;
+ default:
+ config.BuyerPriceRatio = sAuctionBotConfig->GetConfig(CONFIG_AHBOT_NEUTRAL_PRICE_RATIO) + 50;
+ factionChance = sAuctionBotConfig->GetConfig(CONFIG_AHBOT_BUYER_CHANCE_RATIO_NEUTRAL);
+ break;
+ }
+
+ config.FactionChance = 5000 * factionChance;
+}
+
+void AuctionBotBuyer::LoadConfig()
+{
+ for (int i = 0; i < MAX_AUCTION_HOUSE_TYPE; ++i)
+ {
+ _houseConfig[i].BuyerEnabled = sAuctionBotConfig->GetConfigBuyerEnabled(AuctionHouseType(i));
+ if (_houseConfig[i].BuyerEnabled)
+ LoadBuyerValues(_houseConfig[i]);
+ }
+}
+
+uint32 AuctionBotBuyer::GetBuyableEntry(BuyerConfiguration& config)
+{
+ config.SameItemInfo.clear();
+ uint32 count = 0;
+ time_t now = time(nullptr);
+
+ AuctionHouseObject* house = sAuctionMgr->GetAuctionsMap(config.GetHouseType());
+ for (AuctionHouseObject::AuctionEntryMap::const_iterator itr = house->GetAuctionsBegin(); itr != house->GetAuctionsEnd(); ++itr)
+ {
+ AuctionEntry* entry = itr->second;
+ Item* item = sAuctionMgr->GetAItem(entry->itemGUIDLow);
+ if (item)
+ {
+ ItemTemplate const * prototype = item->GetTemplate();
+ if (prototype)
+ {
+ ++config.SameItemInfo[item->GetEntry()].ItemCount; // Structure constructor will make sure Element are correctly initialized if entry is created here.
+ config.SameItemInfo[item->GetEntry()].BuyPrice = config.SameItemInfo[item->GetEntry()].BuyPrice + (itr->second->buyout / item->GetCount());
+ config.SameItemInfo[item->GetEntry()].BidPrice = config.SameItemInfo[item->GetEntry()].BidPrice + (itr->second->startbid / item->GetCount());
+ if (itr->second->buyout != 0)
+ {
+ if (itr->second->buyout / item->GetCount() < config.SameItemInfo[item->GetEntry()].MinBuyPrice)
+ config.SameItemInfo[item->GetEntry()].MinBuyPrice = itr->second->buyout / item->GetCount();
+ else if (config.SameItemInfo[item->GetEntry()].MinBuyPrice == 0)
+ config.SameItemInfo[item->GetEntry()].MinBuyPrice = itr->second->buyout / item->GetCount();
+ }
+ if (itr->second->startbid / item->GetCount() < config.SameItemInfo[item->GetEntry()].MinBidPrice)
+ config.SameItemInfo[item->GetEntry()].MinBidPrice = itr->second->startbid / item->GetCount();
+ else if (config.SameItemInfo[item->GetEntry()].MinBidPrice == 0)
+ config.SameItemInfo[item->GetEntry()].MinBidPrice = itr->second->startbid / item->GetCount();
+
+ if (!entry->owner)
+ {
+
+ if (entry->bid != 0 && entry->bidder) // Add bid by player
+ {
+ config.CheckedEntry[entry->Id].LastExist = now;
+ config.CheckedEntry[entry->Id].AuctionId = entry->Id;
+ ++count;
+ }
+ }
+ else
+ {
+ if (entry->bid != 0)
+ {
+ if (entry->bidder)
+ {
+ config.CheckedEntry[entry->Id].LastExist = now;
+ config.CheckedEntry[entry->Id].AuctionId = entry->Id;
+ ++count;
+ }
+ }
+ else
+ {
+ config.CheckedEntry[entry->Id].LastExist = now;
+ config.CheckedEntry[entry->Id].AuctionId = entry->Id;
+ ++count;
+ }
+ }
+ }
+ }
+ }
+
+ TC_LOG_DEBUG("ahbot", "AHBot: %u items added to buyable vector for ah type: %u", count, config.GetHouseType());
+ TC_LOG_DEBUG("ahbot", "AHBot: SameItemInfo size = %u", (uint32)config.SameItemInfo.size());
+ return count;
+}
+
+void AuctionBotBuyer::PrepareListOfEntry(BuyerConfiguration& config)
+{
+ time_t now = time(nullptr) - 5;
+
+ for (CheckEntryMap::iterator itr = config.CheckedEntry.begin(); itr != config.CheckedEntry.end();)
+ {
+ if (itr->second.LastExist < (now - 5))
+ config.CheckedEntry.erase(itr++);
+ else
+ ++itr;
+ }
+
+ TC_LOG_DEBUG("ahbot", "AHBot: CheckedEntry size = %u", (uint32)config.CheckedEntry.size());
+}
+
+bool AuctionBotBuyer::IsBuyableEntry(uint32 buyoutPrice, double inGameBuyPrice, double maxBuyablePrice, uint32 minBuyPrice, uint32 maxChance, uint32 chanceRatio)
+{
+ double ratio = 0;
+ uint32 chance = 0;
+
+ if (buyoutPrice <= minBuyPrice)
+ {
+ if (buyoutPrice <= maxBuyablePrice)
+ chance = maxChance;
+ else
+ {
+
+ if (buyoutPrice > 0 && maxBuyablePrice > 0)
+ {
+ ratio = buyoutPrice / maxBuyablePrice;
+ if (ratio < 10)
+ chance = maxChance - (ratio * maxChance / 10);
+ else
+ chance = 1;
+ }
+ }
+ }
+ else if (buyoutPrice <= inGameBuyPrice)
+ {
+ if (buyoutPrice <= maxBuyablePrice)
+ chance = maxChance / 5;
+ else
+ {
+
+ if (buyoutPrice > 0 && maxBuyablePrice > 0)
+ {
+ ratio = buyoutPrice / maxBuyablePrice;
+ if (ratio < 10)
+ chance = (maxChance / 5) - (ratio * maxChance / 50);
+ else
+ chance = 1;
+ }
+ }
+ }
+ else if (buyoutPrice <= maxBuyablePrice)
+ chance = maxChance / 10;
+ else
+ {
+ if (buyoutPrice > 0 && maxBuyablePrice > 0)
+ {
+ ratio = buyoutPrice / maxBuyablePrice;
+ if (ratio < 10)
+ chance = (maxChance / 5) - (ratio* maxChance / 50);
+ else
+ chance = 0;
+ }
+ else
+ chance = 0;
+ }
+
+ if (urand(1, chanceRatio) <= chance)
+ {
+ TC_LOG_DEBUG("ahbot", "AHBot: WIN BUY! Chance = %u, num = %u.", chance, chanceRatio);
+ return true;
+ }
+ else
+ {
+ TC_LOG_DEBUG("ahbot", "AHBot: LOOSE BUY! Chance = %u, num = %u.", chance, chanceRatio);
+ return false;
+ }
+}
+
+bool AuctionBotBuyer::IsBidableEntry(uint32 bidPrice, double inGameBuyPrice, double maxBidablePrice, uint32 minBidPrice, uint32 maxChance, uint32 chanceRatio)
+{
+ double ratio = 0;
+ uint32 chance = 0;
+
+ if (bidPrice <= minBidPrice)
+ {
+ if (inGameBuyPrice != 0 && bidPrice < inGameBuyPrice - (inGameBuyPrice / 30))
+ chance = maxChance;
+ else
+ {
+ if (bidPrice < maxBidablePrice)
+ {
+ ratio = maxBidablePrice / bidPrice;
+ if (ratio < 3)
+ chance = maxChance / 500 * ratio;
+ else
+ chance = maxChance / 500;
+ }
+ }
+ }
+ else if (bidPrice < (inGameBuyPrice - (inGameBuyPrice / 30)))
+ chance = (maxChance / 10);
+ else
+ {
+ if (bidPrice < maxBidablePrice)
+ {
+ ratio = maxBidablePrice / bidPrice;
+ if (ratio < 4)
+ chance = maxChance / 1000 * ratio;
+ else
+ chance = maxChance / 1000;
+ }
+ }
+
+ if (urand(1, chanceRatio) <= chance)
+ {
+ TC_LOG_DEBUG("ahbot", "AHBot: WIN BID! Chance = %u, num = %u.", chance, chanceRatio);
+ return true;
+ }
+ else
+ {
+ TC_LOG_DEBUG("ahbot", "AHBot: LOOSE BID! Chance = %u, num = %u.", chance, chanceRatio);
+ return false;
+ }
+}
+
+void AuctionBotBuyer::PlaceBidToEntry(AuctionEntry* auction, uint32 bidPrice)
+{
+ TC_LOG_DEBUG("ahbot", "AHBot: Bid placed to entry %u, %.2fg", auction->Id, float(bidPrice) / 10000.0f);
+ auction->bid = bidPrice;
+}
+
+void AuctionBotBuyer::BuyEntry(AuctionEntry* auction)
+{
+ TC_LOG_DEBUG("ahbot", "AHBot: Entry %u bought at %.2fg", auction->Id, float(auction->buyout) / 10000.0f);
+ auction->bid = auction->buyout;
+}
+
+void AuctionBotBuyer::AddNewAuctionBuyerBotBid(BuyerConfiguration& config)
+{
+ AuctionHouseObject* auctionHouse = sAuctionMgr->GetAuctionsMap(config.GetHouseType());
+
+ PrepareListOfEntry(config);
+
+ time_t now = time(nullptr);
+ uint32 buyCycles;
+ if (config.CheckedEntry.size() > sAuctionBotConfig->GetItemPerCycleBoost())
+ {
+ buyCycles = sAuctionBotConfig->GetItemPerCycleBoost();
+ TC_LOG_DEBUG("ahbot", "AHBot: Boost value used for Buyer! (if this happens often adjust both ItemsPerCycle in worldserver.conf)");
+ }
+ else
+ buyCycles = sAuctionBotConfig->GetItemPerCycleNormal();
+
+ for (CheckEntryMap::iterator itr = config.CheckedEntry.begin(); itr != config.CheckedEntry.end();)
+ {
+ AuctionEntry* auction = auctionHouse->GetAuction(itr->second.AuctionId);
+ if (!auction) // is auction not active now
+ {
+ TC_LOG_DEBUG("ahbot", "AHBot: Entry %u doesn't exists, perhaps bought already?",
+ itr->second.AuctionId);
+
+ config.CheckedEntry.erase(itr++);
+ continue;
+ }
+
+ if (itr->second.LastChecked != 0 && (now - itr->second.LastChecked) <= _checkInterval)
+ {
+ TC_LOG_DEBUG("ahbot", "AHBot: In time interval wait for entry %u!", auction->Id);
+ ++itr;
+ continue;
+ }
+
+ if (buyCycles == 0)
+ break;
+
+ uint32 maxChance = 5000;
+
+ Item* item = sAuctionMgr->GetAItem(auction->itemGUIDLow);
+ if (!item) // auction item not accessible, possible auction in payment pending mode
+ {
+ config.CheckedEntry.erase(itr++);
+ continue;
+ }
+
+ ItemTemplate const* prototype = item->GetTemplate();
+
+ uint32 basePrice = sAuctionBotConfig->GetConfig(CONFIG_AHBOT_BUYPRICE_BUYER) ? prototype->BuyPrice : prototype->SellPrice;
+ basePrice *= item->GetCount();
+
+ double maxBuyablePrice = (basePrice * config.BuyerPriceRatio) / 100;
+ BuyerItemInfoMap::iterator sameItemItr = config.SameItemInfo.find(item->GetEntry());
+ uint32 buyoutPrice = auction->buyout / item->GetCount();
+
+ uint32 bidPrice;
+ uint32 bidPriceByItem;
+ if (auction->bid >= auction->startbid)
+ {
+ bidPrice = auction->GetAuctionOutBid();
+ bidPriceByItem = auction->bid / item->GetCount();
+ }
+ else
+ {
+ bidPrice = auction->startbid;
+ bidPriceByItem = auction->startbid / item->GetCount();
+ }
+
+ double inGameBuyPrice;
+ double inGameBidPrice;
+ if (sameItemItr == config.SameItemInfo.end())
+ {
+ inGameBuyPrice = 0;
+ inGameBidPrice = 0;
+ }
+ else
+ {
+ if (sameItemItr->second.ItemCount == 1)
+ maxBuyablePrice = maxBuyablePrice * 5; // if only one item exist can be bought if the price is high too.
+ inGameBuyPrice = sameItemItr->second.BuyPrice / sameItemItr->second.ItemCount;
+ inGameBidPrice = sameItemItr->second.BidPrice / sameItemItr->second.ItemCount;
+ }
+
+ double maxBidablePrice = maxBuyablePrice - (maxBuyablePrice / 30); // Max Bidable price defined to 70% of max buyable price
+
+ TC_LOG_DEBUG("ahbot", "AHBot: Auction added with data:");
+ TC_LOG_DEBUG("ahbot", "AHBot: MaxPrice of Entry %u is %.1fg.", itr->second.AuctionId, maxBuyablePrice / 10000);
+ TC_LOG_DEBUG("ahbot", "AHBot: GamePrice buy=%.1fg, bid=%.1fg.", inGameBuyPrice / 10000, inGameBidPrice / 10000);
+ TC_LOG_DEBUG("ahbot", "AHBot: Minimal price see in AH Buy=%ug, Bid=%ug.",
+ sameItemItr->second.MinBuyPrice / 10000, sameItemItr->second.MinBidPrice / 10000);
+ TC_LOG_DEBUG("ahbot", "AHBot: Actual Entry price, Buy=%ug, Bid=%ug.", buyoutPrice / 10000, bidPrice / 10000);
+
+ if (!auction->owner) // Original auction owner
+ maxChance = maxChance / 5; // if Owner is AHBot this mean player placed bid on this auction. We divide by 5 chance for AhBuyer to place bid on it. (This make more challenge than ignore entry)
+ if (auction->buyout != 0) // Is the item directly buyable?
+ {
+ if (IsBuyableEntry(buyoutPrice, inGameBuyPrice, maxBuyablePrice, sameItemItr->second.MinBuyPrice, maxChance, config.FactionChance))
+ {
+ if (IsBidableEntry(bidPriceByItem, inGameBuyPrice, maxBidablePrice, sameItemItr->second.MinBidPrice, maxChance / 2, config.FactionChance))
+ {
+ if (urand(0, 5) == 0)
+ PlaceBidToEntry(auction, bidPrice);
+ else
+ BuyEntry(auction);
+ }
+ else
+ BuyEntry(auction);
+ }
+ else if (IsBidableEntry(bidPriceByItem, inGameBuyPrice, maxBidablePrice, sameItemItr->second.MinBidPrice, maxChance / 2, config.FactionChance))
+ PlaceBidToEntry(auction, bidPrice);
+ }
+ else if (IsBidableEntry(bidPriceByItem, inGameBuyPrice, maxBidablePrice, sameItemItr->second.MinBidPrice, maxChance, config.FactionChance))
+ PlaceBidToEntry(auction, bidPrice);
+
+ itr->second.LastChecked = now;
+ --buyCycles;
+
+ ++itr;
+ }
+}
+
+bool AuctionBotBuyer::Update(AuctionHouseType houseType)
+{
+ if (sAuctionBotConfig->GetConfigBuyerEnabled(houseType))
+ {
+ TC_LOG_DEBUG("ahbot", "AHBot: %s buying ...", AuctionBotConfig::GetHouseTypeName(houseType));
+ if (GetBuyableEntry(_houseConfig[houseType]) > 0)
+ AddNewAuctionBuyerBotBid(_houseConfig[houseType]);
+ return true;
+ }
+
+ return false;
+}
diff --git a/src/server/game/AuctionHouseBot/AuctionHouseBotBuyer.h b/src/server/game/AuctionHouseBot/AuctionHouseBotBuyer.h
new file mode 100644
index 00000000000..1148435f1c1
--- /dev/null
+++ b/src/server/game/AuctionHouseBot/AuctionHouseBotBuyer.h
@@ -0,0 +1,96 @@
+/*
+ * Copyright (C) 2008-2014 TrinityCore <http://www.trinitycore.org/>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef AUCTION_HOUSE_BOT_BUYER_H
+#define AUCTION_HOUSE_BOT_BUYER_H
+
+#include "Define.h"
+#include "AuctionHouseMgr.h"
+#include "AuctionHouseBot.h"
+
+struct BuyerAuctionEval
+{
+ BuyerAuctionEval(): AuctionId(0), LastChecked(0), LastExist(0) {}
+
+ uint32 AuctionId;
+ time_t LastChecked;
+ time_t LastExist;
+};
+
+struct BuyerItemInfo
+{
+ BuyerItemInfo(): ItemCount(0), BuyPrice(0), BidPrice(0), MinBuyPrice(0), MinBidPrice(0) {}
+
+ uint32 ItemCount;
+ double BuyPrice;
+ double BidPrice;
+ uint32 MinBuyPrice;
+ uint32 MinBidPrice;
+};
+
+typedef std::map<uint32, BuyerItemInfo> BuyerItemInfoMap;
+typedef std::map<uint32, BuyerAuctionEval> CheckEntryMap;
+
+struct BuyerConfiguration
+{
+ BuyerConfiguration(): FactionChance(3), BuyerEnabled(false), BuyerPriceRatio(100), _houseType(AUCTION_HOUSE_NEUTRAL) {}
+
+ void Initialize(AuctionHouseType houseType)
+ {
+ _houseType = houseType;
+ }
+
+ AuctionHouseType GetHouseType() const { return _houseType; }
+
+ BuyerItemInfoMap SameItemInfo;
+ CheckEntryMap CheckedEntry;
+ uint32 FactionChance;
+ bool BuyerEnabled;
+ uint32 BuyerPriceRatio;
+
+private:
+ AuctionHouseType _houseType;
+};
+
+// This class handle all Buyer method
+// (holder of AuctionBotConfig for each auction house type)
+class AuctionBotBuyer : public AuctionBotAgent
+{
+public:
+ AuctionBotBuyer();
+ ~AuctionBotBuyer() override;
+
+ bool Initialize() override;
+ bool Update(AuctionHouseType houseType) override;
+
+ void LoadConfig();
+ void AddNewAuctionBuyerBotBid(BuyerConfiguration& config);
+
+private:
+ uint32 _checkInterval;
+ BuyerConfiguration _houseConfig[MAX_AUCTION_HOUSE_TYPE];
+
+ void LoadBuyerValues(BuyerConfiguration& config);
+ bool IsBuyableEntry(uint32 buyoutPrice, double inGameBuyPrice, double maxBuyablePrice, uint32 minBuyPrice, uint32 maxChance, uint32 chanceRatio);
+ bool IsBidableEntry(uint32 bidPrice, double inGameBuyPrice, double maxBidablePrice, uint32 minBidPrice, uint32 maxChance, uint32 chanceRatio);
+ void PlaceBidToEntry(AuctionEntry* auction, uint32 bidPrice);
+ void BuyEntry(AuctionEntry* auction);
+ void PrepareListOfEntry(BuyerConfiguration& config);
+ uint32 GetBuyableEntry(BuyerConfiguration& config);
+};
+
+#endif
diff --git a/src/server/game/AuctionHouseBot/AuctionHouseBotSeller.cpp b/src/server/game/AuctionHouseBot/AuctionHouseBotSeller.cpp
new file mode 100644
index 00000000000..13aa1f22fa3
--- /dev/null
+++ b/src/server/game/AuctionHouseBot/AuctionHouseBotSeller.cpp
@@ -0,0 +1,1029 @@
+/*
+ * Copyright (C) 2008-2014 TrinityCore <http://www.trinitycore.org/>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "Log.h"
+#include "DBCStores.h"
+#include "ObjectMgr.h"
+#include "AuctionHouseMgr.h"
+#include "AuctionHouseBotSeller.h"
+
+AuctionBotSeller::AuctionBotSeller()
+{
+ // Define faction for our main data class.
+ for (int i = 0; i < MAX_AUCTION_HOUSE_TYPE; ++i)
+ _houseConfig[i].Initialize(AuctionHouseType(i));
+}
+
+AuctionBotSeller::~AuctionBotSeller()
+{
+}
+
+bool AuctionBotSeller::Initialize()
+{
+ std::vector<uint32> npcItems;
+ std::vector<uint32> lootItems;
+ std::vector<uint32> includeItems;
+ std::vector<uint32> excludeItems;
+
+ TC_LOG_DEBUG("ahbot", "AHBot seller filters:");
+
+ {
+ std::stringstream includeStream(sAuctionBotConfig->GetAHBotIncludes());
+ std::string temp;
+ while (getline(includeStream, temp, ','))
+ includeItems.push_back(atoi(temp.c_str()));
+ }
+
+ {
+ std::stringstream excludeStream(sAuctionBotConfig->GetAHBotExcludes());
+ std::string temp;
+ while (getline(excludeStream, temp, ','))
+ excludeItems.push_back(atoi(temp.c_str()));
+ }
+
+ TC_LOG_DEBUG("ahbot", "Forced Inclusion %u items", (uint32)includeItems.size());
+ TC_LOG_DEBUG("ahbot", "Forced Exclusion %u items", (uint32)excludeItems.size());
+
+ TC_LOG_DEBUG("ahbot", "Loading npc vendor items for filter..");
+ const CreatureTemplateContainer* creatures = sObjectMgr->GetCreatureTemplates();
+ std::set<uint32> tempItems;
+ for (CreatureTemplateContainer::const_iterator it = creatures->begin(); it != creatures->end(); ++it)
+ {
+ if (const VendorItemData* data = sObjectMgr->GetNpcVendorItemList(it->first))
+ {
+ for (VendorItemList::const_iterator it2 = data->m_items.begin(); it2 != data->m_items.end(); ++it2)
+ tempItems.insert((*it2)->item);
+ }
+ }
+ for (std::set<uint32>::const_iterator it = tempItems.begin(); it != tempItems.end(); ++it)
+ npcItems.push_back(*it);
+
+ TC_LOG_DEBUG("ahbot", "Npc vendor filter has %u items", (uint32)npcItems.size());
+
+ TC_LOG_DEBUG("ahbot", "Loading loot items for filter..");
+ QueryResult result = WorldDatabase.PQuery(
+ "SELECT `item` FROM `creature_loot_template` UNION "
+ "SELECT `item` FROM `disenchant_loot_template` UNION "
+ "SELECT `item` FROM `fishing_loot_template` UNION "
+ "SELECT `item` FROM `gameobject_loot_template` UNION "
+ "SELECT `item` FROM `item_loot_template` UNION "
+ "SELECT `item` FROM `milling_loot_template` UNION "
+ "SELECT `item` FROM `pickpocketing_loot_template` UNION "
+ "SELECT `item` FROM `prospecting_loot_template` UNION "
+ "SELECT `item` FROM `skinning_loot_template` UNION "
+ "SELECT `item` FROM `spell_loot_template`");
+
+ if (result)
+ {
+ do
+ {
+ Field* fields = result->Fetch();
+
+ uint32 entry = fields[0].GetUInt32();
+ if (!entry)
+ continue;
+
+ lootItems.push_back(entry);
+ } while (result->NextRow());
+ }
+
+ TC_LOG_DEBUG("ahbot", "Loot filter has %u items", (uint32)lootItems.size());
+ TC_LOG_DEBUG("ahbot", "Sorting and cleaning items for AHBot seller...");
+
+ uint32 itemsAdded = 0;
+
+ for (uint32 itemId = 0; itemId < sItemStore.GetNumRows(); ++itemId)
+ {
+ ItemTemplate const* prototype = sObjectMgr->GetItemTemplate(itemId);
+
+ if (!prototype)
+ continue;
+
+ // skip items with too high quality (code can't properly work with its)
+ if (prototype->Quality >= MAX_AUCTION_QUALITY)
+ continue;
+
+ // forced exclude filter
+ bool isExcludeItem = false;
+ for (size_t i = 0; i < excludeItems.size() && !isExcludeItem; ++i)
+ if (itemId == excludeItems[i])
+ isExcludeItem = true;
+
+ if (isExcludeItem)
+ continue;
+
+ // forced include filter
+ bool isForcedIncludeItem = false;
+ for (size_t i = 0; i < includeItems.size() && !isForcedIncludeItem; ++i)
+ if (itemId == includeItems[i])
+ isForcedIncludeItem = true;
+
+ if (isForcedIncludeItem)
+ {
+ _itemPool[prototype->Quality][prototype->Class].push_back(itemId);
+ ++itemsAdded;
+ continue;
+ }
+
+ // bounding filters
+ switch (prototype->Bonding)
+ {
+ case NO_BIND:
+ if (!sAuctionBotConfig->GetConfig(CONFIG_AHBOT_BIND_NO))
+ continue;
+ break;
+ case BIND_WHEN_PICKED_UP:
+ if (!sAuctionBotConfig->GetConfig(CONFIG_AHBOT_BIND_PICKUP))
+ continue;
+ break;
+ case BIND_WHEN_EQUIPED:
+ if (!sAuctionBotConfig->GetConfig(CONFIG_AHBOT_BIND_EQUIP))
+ continue;
+ break;
+ case BIND_WHEN_USE:
+ if (!sAuctionBotConfig->GetConfig(CONFIG_AHBOT_BIND_USE))
+ continue;
+ break;
+ case BIND_QUEST_ITEM:
+ if (!sAuctionBotConfig->GetConfig(CONFIG_AHBOT_BIND_QUEST))
+ continue;
+ break;
+ default:
+ continue;
+ }
+
+ bool allowZero = false;
+ switch (prototype->Class)
+ {
+ case ITEM_CLASS_CONSUMABLE:
+ allowZero = sAuctionBotConfig->GetConfig(CONFIG_AHBOT_CLASS_CONSUMABLE_ALLOW_ZERO); break;
+ case ITEM_CLASS_CONTAINER:
+ allowZero = sAuctionBotConfig->GetConfig(CONFIG_AHBOT_CLASS_CONTAINER_ALLOW_ZERO); break;
+ case ITEM_CLASS_WEAPON:
+ allowZero = sAuctionBotConfig->GetConfig(CONFIG_AHBOT_CLASS_WEAPON_ALLOW_ZERO); break;
+ case ITEM_CLASS_GEM:
+ allowZero = sAuctionBotConfig->GetConfig(CONFIG_AHBOT_CLASS_GEM_ALLOW_ZERO); break;
+ case ITEM_CLASS_ARMOR:
+ allowZero = sAuctionBotConfig->GetConfig(CONFIG_AHBOT_CLASS_ARMOR_ALLOW_ZERO); break;
+ case ITEM_CLASS_REAGENT:
+ allowZero = sAuctionBotConfig->GetConfig(CONFIG_AHBOT_CLASS_REAGENT_ALLOW_ZERO); break;
+ case ITEM_CLASS_PROJECTILE:
+ allowZero = sAuctionBotConfig->GetConfig(CONFIG_AHBOT_CLASS_PROJECTILE_ALLOW_ZERO); break;
+ case ITEM_CLASS_TRADE_GOODS:
+ allowZero = sAuctionBotConfig->GetConfig(CONFIG_AHBOT_CLASS_TRADEGOOD_ALLOW_ZERO); break;
+ case ITEM_CLASS_RECIPE:
+ allowZero = sAuctionBotConfig->GetConfig(CONFIG_AHBOT_CLASS_RECIPE_ALLOW_ZERO); break;
+ case ITEM_CLASS_QUIVER:
+ allowZero = sAuctionBotConfig->GetConfig(CONFIG_AHBOT_CLASS_QUIVER_ALLOW_ZERO); break;
+ case ITEM_CLASS_QUEST:
+ allowZero = sAuctionBotConfig->GetConfig(CONFIG_AHBOT_CLASS_QUEST_ALLOW_ZERO); break;
+ case ITEM_CLASS_KEY:
+ allowZero = sAuctionBotConfig->GetConfig(CONFIG_AHBOT_CLASS_KEY_ALLOW_ZERO); break;
+ case ITEM_CLASS_MISC:
+ allowZero = sAuctionBotConfig->GetConfig(CONFIG_AHBOT_CLASS_MISC_ALLOW_ZERO); break;
+ case ITEM_CLASS_GLYPH:
+ allowZero = sAuctionBotConfig->GetConfig(CONFIG_AHBOT_CLASS_GLYPH_ALLOW_ZERO); break;
+ default:
+ allowZero = false;
+ }
+
+ // Filter out items with no buy/sell price unless otherwise flagged in the config.
+ if (!allowZero)
+ {
+ if (sAuctionBotConfig->GetConfig(CONFIG_AHBOT_BUYPRICE_SELLER))
+ {
+ if (prototype->BuyPrice == 0)
+ continue;
+ }
+ else
+ {
+ if (prototype->SellPrice == 0)
+ continue;
+ }
+ }
+
+ // vendor filter
+ if (!sAuctionBotConfig->GetConfig(CONFIG_AHBOT_ITEMS_VENDOR))
+ {
+ bool isVendorItem = false;
+ for (size_t i = 0; i < npcItems.size() && !isVendorItem; ++i)
+ if (itemId == npcItems[i])
+ isVendorItem = true;
+
+ if (isVendorItem)
+ continue;
+ }
+
+ // loot filter
+ if (!sAuctionBotConfig->GetConfig(CONFIG_AHBOT_ITEMS_LOOT))
+ {
+ bool isLootItem = false;
+ for (size_t i = 0; i < lootItems.size() && !isLootItem; ++i)
+ if (itemId == lootItems[i])
+ isLootItem = true;
+
+ if (isLootItem)
+ continue;
+ }
+
+ // not vendor/loot filter
+ if (!sAuctionBotConfig->GetConfig(CONFIG_AHBOT_ITEMS_MISC))
+ {
+ bool isVendorItem = false;
+ bool isLootItem = false;
+
+ for (size_t i = 0; i < npcItems.size() && !isVendorItem; ++i)
+ if (itemId == npcItems[i])
+ isVendorItem = true;
+
+ for (size_t i = 0; i < lootItems.size() && !isLootItem; ++i)
+ if (itemId == lootItems[i])
+ isLootItem = true;
+
+ if (!isLootItem && !isVendorItem)
+ continue;
+ }
+
+ // item class/subclass specific filters
+ switch (prototype->Class)
+ {
+ case ITEM_CLASS_ARMOR:
+ case ITEM_CLASS_WEAPON:
+ {
+ if (uint32 value = sAuctionBotConfig->GetConfig(CONFIG_AHBOT_ITEM_MIN_ITEM_LEVEL))
+ if (prototype->ItemLevel < value)
+ continue;
+ if (uint32 value = sAuctionBotConfig->GetConfig(CONFIG_AHBOT_ITEM_MAX_ITEM_LEVEL))
+ if (prototype->ItemLevel > value)
+ continue;
+ if (uint32 value = sAuctionBotConfig->GetConfig(CONFIG_AHBOT_ITEM_MIN_REQ_LEVEL))
+ if (prototype->RequiredLevel < value)
+ continue;
+ if (uint32 value = sAuctionBotConfig->GetConfig(CONFIG_AHBOT_ITEM_MAX_REQ_LEVEL))
+ if (prototype->RequiredLevel > value)
+ continue;
+ if (uint32 value = sAuctionBotConfig->GetConfig(CONFIG_AHBOT_ITEM_MIN_SKILL_RANK))
+ if (prototype->RequiredSkillRank < value)
+ continue;
+ if (uint32 value = sAuctionBotConfig->GetConfig(CONFIG_AHBOT_ITEM_MAX_SKILL_RANK))
+ if (prototype->RequiredSkillRank > value)
+ continue;
+ break;
+ }
+ case ITEM_CLASS_RECIPE:
+ case ITEM_CLASS_CONSUMABLE:
+ case ITEM_CLASS_PROJECTILE:
+ {
+ if (uint32 value = sAuctionBotConfig->GetConfig(CONFIG_AHBOT_ITEM_MIN_REQ_LEVEL))
+ if (prototype->RequiredLevel < value)
+ continue;
+ if (uint32 value = sAuctionBotConfig->GetConfig(CONFIG_AHBOT_ITEM_MAX_REQ_LEVEL))
+ if (prototype->RequiredLevel > value)
+ continue;
+ if (uint32 value = sAuctionBotConfig->GetConfig(CONFIG_AHBOT_ITEM_MIN_SKILL_RANK))
+ if (prototype->RequiredSkillRank < value)
+ continue;
+ if (uint32 value = sAuctionBotConfig->GetConfig(CONFIG_AHBOT_ITEM_MAX_SKILL_RANK))
+ if (prototype->RequiredSkillRank > value)
+ continue;
+ break;
+ }
+ case ITEM_CLASS_MISC:
+ if (prototype->SubClass == ITEM_SUBCLASS_JUNK_MOUNT)
+ {
+ if (uint32 value = sAuctionBotConfig->GetConfig(CONFIG_AHBOT_CLASS_MISC_MOUNT_MIN_REQ_LEVEL))
+ if (prototype->RequiredLevel < value)
+ continue;
+ if (uint32 value = sAuctionBotConfig->GetConfig(CONFIG_AHBOT_CLASS_MISC_MOUNT_MAX_REQ_LEVEL))
+ if (prototype->RequiredLevel > value)
+ continue;
+ if (uint32 value = sAuctionBotConfig->GetConfig(CONFIG_AHBOT_CLASS_MISC_MOUNT_MIN_SKILL_RANK))
+ if (prototype->RequiredSkillRank < value)
+ continue;
+ if (uint32 value = sAuctionBotConfig->GetConfig(CONFIG_AHBOT_CLASS_MISC_MOUNT_MAX_SKILL_RANK))
+ if (prototype->RequiredSkillRank > value)
+ continue;
+ }
+
+ if (prototype->Flags & ITEM_FLAG_UNLOCKED)
+ {
+ // skip any not locked lootable items (mostly quest specific or reward cases)
+ if (!prototype->LockID)
+ continue;
+
+ if (!sAuctionBotConfig->GetConfig(CONFIG_AHBOT_LOCKBOX_ENABLED))
+ continue;
+ }
+
+ break;
+ case ITEM_CLASS_GLYPH:
+ {
+ if (uint32 value = sAuctionBotConfig->GetConfig(CONFIG_AHBOT_CLASS_GLYPH_MIN_REQ_LEVEL))
+ if (prototype->RequiredLevel < value)
+ continue;
+ if (uint32 value = sAuctionBotConfig->GetConfig(CONFIG_AHBOT_CLASS_GLYPH_MAX_REQ_LEVEL))
+ if (prototype->RequiredLevel > value)
+ continue;
+ if (uint32 value = sAuctionBotConfig->GetConfig(CONFIG_AHBOT_CLASS_GLYPH_MIN_ITEM_LEVEL))
+ if (prototype->RequiredLevel < value)
+ continue;
+ if (uint32 value = sAuctionBotConfig->GetConfig(CONFIG_AHBOT_CLASS_GLYPH_MAX_ITEM_LEVEL))
+ if (prototype->RequiredLevel > value)
+ continue;
+ break;
+ }
+ case ITEM_CLASS_TRADE_GOODS:
+ {
+ if (uint32 value = sAuctionBotConfig->GetConfig(CONFIG_AHBOT_CLASS_TRADEGOOD_MIN_ITEM_LEVEL))
+ if (prototype->ItemLevel < value)
+ continue;
+ if (uint32 value = sAuctionBotConfig->GetConfig(CONFIG_AHBOT_CLASS_TRADEGOOD_MAX_ITEM_LEVEL))
+ if (prototype->ItemLevel > value)
+ continue;
+ break;
+ }
+ case ITEM_CLASS_CONTAINER:
+ case ITEM_CLASS_QUIVER:
+ {
+ if (uint32 value = sAuctionBotConfig->GetConfig(CONFIG_AHBOT_CLASS_CONTAINER_MIN_ITEM_LEVEL))
+ if (prototype->ItemLevel < value)
+ continue;
+ if (uint32 value = sAuctionBotConfig->GetConfig(CONFIG_AHBOT_CLASS_CONTAINER_MAX_ITEM_LEVEL))
+ if (prototype->ItemLevel > value)
+ continue;
+ break;
+ }
+ }
+
+ _itemPool[prototype->Quality][prototype->Class].push_back(itemId);
+ ++itemsAdded;
+ }
+
+ if (!itemsAdded)
+ {
+ TC_LOG_ERROR("ahbot", "AuctionHouseBot seller not have items, disabled.");
+ sAuctionBotConfig->SetConfig(CONFIG_AHBOT_ALLIANCE_ITEM_AMOUNT_RATIO, 0);
+ sAuctionBotConfig->SetConfig(CONFIG_AHBOT_HORDE_ITEM_AMOUNT_RATIO, 0);
+ sAuctionBotConfig->SetConfig(CONFIG_AHBOT_NEUTRAL_ITEM_AMOUNT_RATIO, 0);
+ return false;
+ }
+
+ TC_LOG_DEBUG("ahbot", "AuctionHouseBot seller will use %u items to fill auction house (according your config choices)", itemsAdded);
+
+ LoadConfig();
+
+ TC_LOG_DEBUG("ahbot", "Items loaded \tGray\tWhite\tGreen\tBlue\tPurple\tOrange\tYellow");
+ for (uint32 i = 0; i < MAX_ITEM_CLASS; ++i)
+ TC_LOG_DEBUG("ahbot", "\t\t%u\t%u\t%u\t%u\t%u\t%u\t%u",
+ (uint32)_itemPool[0][i].size(), (uint32)_itemPool[1][i].size(), (uint32)_itemPool[2][i].size(),
+ (uint32)_itemPool[3][i].size(), (uint32)_itemPool[4][i].size(), (uint32)_itemPool[5][i].size(),
+ (uint32)_itemPool[6][i].size());
+
+ TC_LOG_DEBUG("ahbot", "AHBot seller configuration data loaded and initialized");
+ return true;
+}
+
+void AuctionBotSeller::LoadConfig()
+{
+ for (int i = 0; i < MAX_AUCTION_HOUSE_TYPE; ++i)
+ if (sAuctionBotConfig->GetConfigItemAmountRatio(AuctionHouseType(i)))
+ LoadSellerValues(_houseConfig[i]);
+}
+
+void AuctionBotSeller::LoadItemsQuantity(SellerConfiguration& config)
+{
+ uint32 ratio = sAuctionBotConfig->GetConfigItemAmountRatio(config.GetHouseType());
+
+ config.SetItemsAmountPerQuality(AUCTION_QUALITY_GRAY, sAuctionBotConfig->GetConfig(CONFIG_AHBOT_ITEM_GRAY_AMOUNT) * ratio / 100);
+ config.SetItemsAmountPerQuality(AUCTION_QUALITY_WHITE, sAuctionBotConfig->GetConfig(CONFIG_AHBOT_ITEM_WHITE_AMOUNT) * ratio / 100);
+ config.SetItemsAmountPerQuality(AUCTION_QUALITY_GREEN, sAuctionBotConfig->GetConfig(CONFIG_AHBOT_ITEM_GREEN_AMOUNT) * ratio / 100);
+ config.SetItemsAmountPerQuality(AUCTION_QUALITY_BLUE, sAuctionBotConfig->GetConfig(CONFIG_AHBOT_ITEM_BLUE_AMOUNT) * ratio / 100);
+ config.SetItemsAmountPerQuality(AUCTION_QUALITY_PURPLE, sAuctionBotConfig->GetConfig(CONFIG_AHBOT_ITEM_PURPLE_AMOUNT) * ratio / 100);
+ config.SetItemsAmountPerQuality(AUCTION_QUALITY_ORANGE, sAuctionBotConfig->GetConfig(CONFIG_AHBOT_ITEM_ORANGE_AMOUNT) * ratio / 100);
+ config.SetItemsAmountPerQuality(AUCTION_QUALITY_YELLOW, sAuctionBotConfig->GetConfig(CONFIG_AHBOT_ITEM_YELLOW_AMOUNT) * ratio / 100);
+
+ // Set quantity wanted but only on possible item color
+ // This avoid any no-exist class-color items selection by random items create function
+ // ============================================================================================
+ config.SetItemsQuantityPerClass(AUCTION_QUALITY_GRAY, ITEM_CLASS_CONSUMABLE, 0);
+ config.SetItemsQuantityPerClass(AUCTION_QUALITY_GRAY, ITEM_CLASS_CONTAINER, 0);
+ config.SetItemsQuantityPerClass(AUCTION_QUALITY_GRAY, ITEM_CLASS_WEAPON, sAuctionBotConfig->GetConfig(CONFIG_AHBOT_CLASS_WEAPON_AMOUNT));
+ config.SetItemsQuantityPerClass(AUCTION_QUALITY_GRAY, ITEM_CLASS_GEM, 0);
+ config.SetItemsQuantityPerClass(AUCTION_QUALITY_GRAY, ITEM_CLASS_ARMOR, sAuctionBotConfig->GetConfig(CONFIG_AHBOT_CLASS_ARMOR_AMOUNT));
+ config.SetItemsQuantityPerClass(AUCTION_QUALITY_GRAY, ITEM_CLASS_REAGENT, 0);
+ config.SetItemsQuantityPerClass(AUCTION_QUALITY_GRAY, ITEM_CLASS_PROJECTILE, 0);
+ config.SetItemsQuantityPerClass(AUCTION_QUALITY_GRAY, ITEM_CLASS_TRADE_GOODS, sAuctionBotConfig->GetConfig(CONFIG_AHBOT_CLASS_TRADEGOOD_AMOUNT));
+ config.SetItemsQuantityPerClass(AUCTION_QUALITY_GRAY, ITEM_CLASS_GENERIC, 0);
+ config.SetItemsQuantityPerClass(AUCTION_QUALITY_GRAY, ITEM_CLASS_RECIPE, 0);
+ config.SetItemsQuantityPerClass(AUCTION_QUALITY_GRAY, ITEM_CLASS_QUIVER, 0);
+ config.SetItemsQuantityPerClass(AUCTION_QUALITY_GRAY, ITEM_CLASS_QUEST, sAuctionBotConfig->GetConfig(CONFIG_AHBOT_CLASS_QUEST_AMOUNT));
+ config.SetItemsQuantityPerClass(AUCTION_QUALITY_GRAY, ITEM_CLASS_KEY, 0);
+ config.SetItemsQuantityPerClass(AUCTION_QUALITY_GRAY, ITEM_CLASS_MISC, sAuctionBotConfig->GetConfig(CONFIG_AHBOT_CLASS_MISC_AMOUNT));
+ config.SetItemsQuantityPerClass(AUCTION_QUALITY_GRAY, ITEM_CLASS_GLYPH, 0);
+
+ config.SetItemsQuantityPerClass(AUCTION_QUALITY_WHITE, ITEM_CLASS_CONSUMABLE, sAuctionBotConfig->GetConfig(CONFIG_AHBOT_CLASS_CONSUMABLE_AMOUNT));
+ config.SetItemsQuantityPerClass(AUCTION_QUALITY_WHITE, ITEM_CLASS_CONTAINER, sAuctionBotConfig->GetConfig(CONFIG_AHBOT_CLASS_CONTAINER_AMOUNT));
+ config.SetItemsQuantityPerClass(AUCTION_QUALITY_WHITE, ITEM_CLASS_WEAPON, sAuctionBotConfig->GetConfig(CONFIG_AHBOT_CLASS_WEAPON_AMOUNT));
+ config.SetItemsQuantityPerClass(AUCTION_QUALITY_WHITE, ITEM_CLASS_GEM, sAuctionBotConfig->GetConfig(CONFIG_AHBOT_CLASS_GEM_AMOUNT));
+ config.SetItemsQuantityPerClass(AUCTION_QUALITY_WHITE, ITEM_CLASS_ARMOR, sAuctionBotConfig->GetConfig(CONFIG_AHBOT_CLASS_ARMOR_AMOUNT));
+ config.SetItemsQuantityPerClass(AUCTION_QUALITY_WHITE, ITEM_CLASS_REAGENT, sAuctionBotConfig->GetConfig(CONFIG_AHBOT_CLASS_REAGENT_AMOUNT));
+ config.SetItemsQuantityPerClass(AUCTION_QUALITY_WHITE, ITEM_CLASS_PROJECTILE, sAuctionBotConfig->GetConfig(CONFIG_AHBOT_CLASS_PROJECTILE_AMOUNT));
+ config.SetItemsQuantityPerClass(AUCTION_QUALITY_WHITE, ITEM_CLASS_TRADE_GOODS, sAuctionBotConfig->GetConfig(CONFIG_AHBOT_CLASS_TRADEGOOD_AMOUNT));
+ config.SetItemsQuantityPerClass(AUCTION_QUALITY_WHITE, ITEM_CLASS_GENERIC, sAuctionBotConfig->GetConfig(CONFIG_AHBOT_CLASS_GENERIC_AMOUNT));
+ config.SetItemsQuantityPerClass(AUCTION_QUALITY_WHITE, ITEM_CLASS_RECIPE, sAuctionBotConfig->GetConfig(CONFIG_AHBOT_CLASS_RECIPE_AMOUNT));
+ config.SetItemsQuantityPerClass(AUCTION_QUALITY_WHITE, ITEM_CLASS_QUIVER, sAuctionBotConfig->GetConfig(CONFIG_AHBOT_CLASS_QUIVER_AMOUNT));
+ config.SetItemsQuantityPerClass(AUCTION_QUALITY_WHITE, ITEM_CLASS_QUEST, sAuctionBotConfig->GetConfig(CONFIG_AHBOT_CLASS_QUEST_AMOUNT));
+ config.SetItemsQuantityPerClass(AUCTION_QUALITY_WHITE, ITEM_CLASS_KEY, sAuctionBotConfig->GetConfig(CONFIG_AHBOT_CLASS_KEY_AMOUNT));
+ config.SetItemsQuantityPerClass(AUCTION_QUALITY_WHITE, ITEM_CLASS_MISC, sAuctionBotConfig->GetConfig(CONFIG_AHBOT_CLASS_MISC_AMOUNT));
+ config.SetItemsQuantityPerClass(AUCTION_QUALITY_WHITE, ITEM_CLASS_GLYPH, sAuctionBotConfig->GetConfig(CONFIG_AHBOT_CLASS_GLYPH_AMOUNT));
+
+ config.SetItemsQuantityPerClass(AUCTION_QUALITY_GREEN, ITEM_CLASS_CONSUMABLE, sAuctionBotConfig->GetConfig(CONFIG_AHBOT_CLASS_CONSUMABLE_AMOUNT));
+ config.SetItemsQuantityPerClass(AUCTION_QUALITY_GREEN, ITEM_CLASS_CONTAINER, sAuctionBotConfig->GetConfig(CONFIG_AHBOT_CLASS_CONTAINER_AMOUNT));
+ config.SetItemsQuantityPerClass(AUCTION_QUALITY_GREEN, ITEM_CLASS_WEAPON, sAuctionBotConfig->GetConfig(CONFIG_AHBOT_CLASS_WEAPON_AMOUNT));
+ config.SetItemsQuantityPerClass(AUCTION_QUALITY_GREEN, ITEM_CLASS_GEM, sAuctionBotConfig->GetConfig(CONFIG_AHBOT_CLASS_GEM_AMOUNT));
+ config.SetItemsQuantityPerClass(AUCTION_QUALITY_GREEN, ITEM_CLASS_ARMOR, sAuctionBotConfig->GetConfig(CONFIG_AHBOT_CLASS_ARMOR_AMOUNT));
+ config.SetItemsQuantityPerClass(AUCTION_QUALITY_GREEN, ITEM_CLASS_REAGENT, 0);
+ config.SetItemsQuantityPerClass(AUCTION_QUALITY_GREEN, ITEM_CLASS_PROJECTILE, sAuctionBotConfig->GetConfig(CONFIG_AHBOT_CLASS_PROJECTILE_AMOUNT));
+ config.SetItemsQuantityPerClass(AUCTION_QUALITY_GREEN, ITEM_CLASS_TRADE_GOODS, sAuctionBotConfig->GetConfig(CONFIG_AHBOT_CLASS_TRADEGOOD_AMOUNT));
+ config.SetItemsQuantityPerClass(AUCTION_QUALITY_GREEN, ITEM_CLASS_GENERIC, 0);
+ config.SetItemsQuantityPerClass(AUCTION_QUALITY_GREEN, ITEM_CLASS_RECIPE, sAuctionBotConfig->GetConfig(CONFIG_AHBOT_CLASS_RECIPE_AMOUNT));
+ config.SetItemsQuantityPerClass(AUCTION_QUALITY_GREEN, ITEM_CLASS_QUIVER, sAuctionBotConfig->GetConfig(CONFIG_AHBOT_CLASS_QUIVER_AMOUNT));
+ config.SetItemsQuantityPerClass(AUCTION_QUALITY_GREEN, ITEM_CLASS_QUEST, sAuctionBotConfig->GetConfig(CONFIG_AHBOT_CLASS_QUEST_AMOUNT));
+ config.SetItemsQuantityPerClass(AUCTION_QUALITY_GREEN, ITEM_CLASS_KEY, sAuctionBotConfig->GetConfig(CONFIG_AHBOT_CLASS_KEY_AMOUNT));
+ config.SetItemsQuantityPerClass(AUCTION_QUALITY_GREEN, ITEM_CLASS_MISC, sAuctionBotConfig->GetConfig(CONFIG_AHBOT_CLASS_MISC_AMOUNT));
+ config.SetItemsQuantityPerClass(AUCTION_QUALITY_GREEN, ITEM_CLASS_GLYPH, 0);
+
+ config.SetItemsQuantityPerClass(AUCTION_QUALITY_BLUE, ITEM_CLASS_CONSUMABLE, sAuctionBotConfig->GetConfig(CONFIG_AHBOT_CLASS_CONSUMABLE_AMOUNT));
+ config.SetItemsQuantityPerClass(AUCTION_QUALITY_BLUE, ITEM_CLASS_CONTAINER, sAuctionBotConfig->GetConfig(CONFIG_AHBOT_CLASS_CONTAINER_AMOUNT));
+ config.SetItemsQuantityPerClass(AUCTION_QUALITY_BLUE, ITEM_CLASS_WEAPON, sAuctionBotConfig->GetConfig(CONFIG_AHBOT_CLASS_WEAPON_AMOUNT));
+ config.SetItemsQuantityPerClass(AUCTION_QUALITY_BLUE, ITEM_CLASS_GEM, sAuctionBotConfig->GetConfig(CONFIG_AHBOT_CLASS_GEM_AMOUNT));
+ config.SetItemsQuantityPerClass(AUCTION_QUALITY_BLUE, ITEM_CLASS_ARMOR, sAuctionBotConfig->GetConfig(CONFIG_AHBOT_CLASS_ARMOR_AMOUNT));
+ config.SetItemsQuantityPerClass(AUCTION_QUALITY_BLUE, ITEM_CLASS_REAGENT, 0);
+ config.SetItemsQuantityPerClass(AUCTION_QUALITY_BLUE, ITEM_CLASS_PROJECTILE, sAuctionBotConfig->GetConfig(CONFIG_AHBOT_CLASS_PROJECTILE_AMOUNT));
+ config.SetItemsQuantityPerClass(AUCTION_QUALITY_BLUE, ITEM_CLASS_TRADE_GOODS, sAuctionBotConfig->GetConfig(CONFIG_AHBOT_CLASS_TRADEGOOD_AMOUNT));
+ config.SetItemsQuantityPerClass(AUCTION_QUALITY_BLUE, ITEM_CLASS_GENERIC, 0);
+ config.SetItemsQuantityPerClass(AUCTION_QUALITY_BLUE, ITEM_CLASS_RECIPE, sAuctionBotConfig->GetConfig(CONFIG_AHBOT_CLASS_RECIPE_AMOUNT));
+ config.SetItemsQuantityPerClass(AUCTION_QUALITY_BLUE, ITEM_CLASS_QUIVER, sAuctionBotConfig->GetConfig(CONFIG_AHBOT_CLASS_QUIVER_AMOUNT));
+ config.SetItemsQuantityPerClass(AUCTION_QUALITY_BLUE, ITEM_CLASS_QUEST, sAuctionBotConfig->GetConfig(CONFIG_AHBOT_CLASS_QUEST_AMOUNT));
+ config.SetItemsQuantityPerClass(AUCTION_QUALITY_BLUE, ITEM_CLASS_KEY, 0);
+ config.SetItemsQuantityPerClass(AUCTION_QUALITY_BLUE, ITEM_CLASS_MISC, sAuctionBotConfig->GetConfig(CONFIG_AHBOT_CLASS_MISC_AMOUNT));
+ config.SetItemsQuantityPerClass(AUCTION_QUALITY_BLUE, ITEM_CLASS_GLYPH, 0);
+
+ config.SetItemsQuantityPerClass(AUCTION_QUALITY_PURPLE, ITEM_CLASS_CONSUMABLE, sAuctionBotConfig->GetConfig(CONFIG_AHBOT_CLASS_CONSUMABLE_AMOUNT));
+ config.SetItemsQuantityPerClass(AUCTION_QUALITY_PURPLE, ITEM_CLASS_CONTAINER, sAuctionBotConfig->GetConfig(CONFIG_AHBOT_CLASS_CONTAINER_AMOUNT));
+ config.SetItemsQuantityPerClass(AUCTION_QUALITY_PURPLE, ITEM_CLASS_WEAPON, sAuctionBotConfig->GetConfig(CONFIG_AHBOT_CLASS_WEAPON_AMOUNT));
+ config.SetItemsQuantityPerClass(AUCTION_QUALITY_PURPLE, ITEM_CLASS_GEM, sAuctionBotConfig->GetConfig(CONFIG_AHBOT_CLASS_GEM_AMOUNT));
+ config.SetItemsQuantityPerClass(AUCTION_QUALITY_PURPLE, ITEM_CLASS_ARMOR, sAuctionBotConfig->GetConfig(CONFIG_AHBOT_CLASS_ARMOR_AMOUNT));
+ config.SetItemsQuantityPerClass(AUCTION_QUALITY_PURPLE, ITEM_CLASS_REAGENT, 0);
+ config.SetItemsQuantityPerClass(AUCTION_QUALITY_PURPLE, ITEM_CLASS_PROJECTILE, sAuctionBotConfig->GetConfig(CONFIG_AHBOT_CLASS_PROJECTILE_AMOUNT));
+ config.SetItemsQuantityPerClass(AUCTION_QUALITY_PURPLE, ITEM_CLASS_TRADE_GOODS, sAuctionBotConfig->GetConfig(CONFIG_AHBOT_CLASS_TRADEGOOD_AMOUNT));
+ config.SetItemsQuantityPerClass(AUCTION_QUALITY_PURPLE, ITEM_CLASS_GENERIC, 0);
+ config.SetItemsQuantityPerClass(AUCTION_QUALITY_PURPLE, ITEM_CLASS_RECIPE, sAuctionBotConfig->GetConfig(CONFIG_AHBOT_CLASS_RECIPE_AMOUNT));
+ config.SetItemsQuantityPerClass(AUCTION_QUALITY_PURPLE, ITEM_CLASS_QUIVER, 0);
+ config.SetItemsQuantityPerClass(AUCTION_QUALITY_PURPLE, ITEM_CLASS_QUEST, sAuctionBotConfig->GetConfig(CONFIG_AHBOT_CLASS_QUEST_AMOUNT));
+ config.SetItemsQuantityPerClass(AUCTION_QUALITY_PURPLE, ITEM_CLASS_KEY, 0);
+ config.SetItemsQuantityPerClass(AUCTION_QUALITY_PURPLE, ITEM_CLASS_MISC, sAuctionBotConfig->GetConfig(CONFIG_AHBOT_CLASS_MISC_AMOUNT));
+ config.SetItemsQuantityPerClass(AUCTION_QUALITY_PURPLE, ITEM_CLASS_GLYPH, 0);
+
+ config.SetItemsQuantityPerClass(AUCTION_QUALITY_ORANGE, ITEM_CLASS_CONSUMABLE, 0);
+ config.SetItemsQuantityPerClass(AUCTION_QUALITY_ORANGE, ITEM_CLASS_CONTAINER, 0);
+ config.SetItemsQuantityPerClass(AUCTION_QUALITY_ORANGE, ITEM_CLASS_WEAPON, sAuctionBotConfig->GetConfig(CONFIG_AHBOT_CLASS_WEAPON_AMOUNT));
+ config.SetItemsQuantityPerClass(AUCTION_QUALITY_ORANGE, ITEM_CLASS_GEM, 0);
+ config.SetItemsQuantityPerClass(AUCTION_QUALITY_ORANGE, ITEM_CLASS_ARMOR, sAuctionBotConfig->GetConfig(CONFIG_AHBOT_CLASS_ARMOR_AMOUNT));
+ config.SetItemsQuantityPerClass(AUCTION_QUALITY_ORANGE, ITEM_CLASS_REAGENT, 0);
+ config.SetItemsQuantityPerClass(AUCTION_QUALITY_ORANGE, ITEM_CLASS_PROJECTILE, 0);
+ config.SetItemsQuantityPerClass(AUCTION_QUALITY_ORANGE, ITEM_CLASS_TRADE_GOODS, sAuctionBotConfig->GetConfig(CONFIG_AHBOT_CLASS_TRADEGOOD_AMOUNT));
+ config.SetItemsQuantityPerClass(AUCTION_QUALITY_ORANGE, ITEM_CLASS_GENERIC, 0);
+ config.SetItemsQuantityPerClass(AUCTION_QUALITY_ORANGE, ITEM_CLASS_RECIPE, 0);
+ config.SetItemsQuantityPerClass(AUCTION_QUALITY_ORANGE, ITEM_CLASS_QUIVER, 0);
+ config.SetItemsQuantityPerClass(AUCTION_QUALITY_ORANGE, ITEM_CLASS_QUEST, 0);
+ config.SetItemsQuantityPerClass(AUCTION_QUALITY_ORANGE, ITEM_CLASS_KEY, 0);
+ config.SetItemsQuantityPerClass(AUCTION_QUALITY_ORANGE, ITEM_CLASS_MISC, 0);
+ config.SetItemsQuantityPerClass(AUCTION_QUALITY_ORANGE, ITEM_CLASS_GLYPH, 0);
+
+ config.SetItemsQuantityPerClass(AUCTION_QUALITY_YELLOW, ITEM_CLASS_CONSUMABLE, 0);
+ config.SetItemsQuantityPerClass(AUCTION_QUALITY_YELLOW, ITEM_CLASS_CONTAINER, 0);
+ config.SetItemsQuantityPerClass(AUCTION_QUALITY_YELLOW, ITEM_CLASS_WEAPON, sAuctionBotConfig->GetConfig(CONFIG_AHBOT_CLASS_WEAPON_AMOUNT));
+ config.SetItemsQuantityPerClass(AUCTION_QUALITY_YELLOW, ITEM_CLASS_GEM, 0);
+ config.SetItemsQuantityPerClass(AUCTION_QUALITY_YELLOW, ITEM_CLASS_ARMOR, sAuctionBotConfig->GetConfig(CONFIG_AHBOT_CLASS_ARMOR_AMOUNT));
+ config.SetItemsQuantityPerClass(AUCTION_QUALITY_YELLOW, ITEM_CLASS_REAGENT, 0);
+ config.SetItemsQuantityPerClass(AUCTION_QUALITY_YELLOW, ITEM_CLASS_PROJECTILE, 0);
+ config.SetItemsQuantityPerClass(AUCTION_QUALITY_YELLOW, ITEM_CLASS_TRADE_GOODS, 0);
+ config.SetItemsQuantityPerClass(AUCTION_QUALITY_YELLOW, ITEM_CLASS_GENERIC, 0);
+ config.SetItemsQuantityPerClass(AUCTION_QUALITY_YELLOW, ITEM_CLASS_RECIPE, 0);
+ config.SetItemsQuantityPerClass(AUCTION_QUALITY_YELLOW, ITEM_CLASS_QUIVER, 0);
+ config.SetItemsQuantityPerClass(AUCTION_QUALITY_YELLOW, ITEM_CLASS_QUEST, 0);
+ config.SetItemsQuantityPerClass(AUCTION_QUALITY_YELLOW, ITEM_CLASS_KEY, 0);
+ config.SetItemsQuantityPerClass(AUCTION_QUALITY_YELLOW, ITEM_CLASS_MISC, 0);
+ config.SetItemsQuantityPerClass(AUCTION_QUALITY_YELLOW, ITEM_CLASS_GLYPH, 0);
+ // ============================================================================================
+
+ // Set the best value to get nearest amount of items wanted
+ for (uint32 j = 0; j < MAX_AUCTION_QUALITY; ++j)
+ {
+ uint32 index = config.GetItemsAmountPerQuality(AuctionQuality(j)) /
+ (sAuctionBotConfig->GetConfig(CONFIG_AHBOT_CLASS_CONSUMABLE_AMOUNT) + sAuctionBotConfig->GetConfig(CONFIG_AHBOT_CLASS_CONTAINER_AMOUNT) + sAuctionBotConfig->GetConfig(CONFIG_AHBOT_CLASS_WEAPON_AMOUNT) +
+ sAuctionBotConfig->GetConfig(CONFIG_AHBOT_CLASS_GEM_AMOUNT) + sAuctionBotConfig->GetConfig(CONFIG_AHBOT_CLASS_ARMOR_AMOUNT) + sAuctionBotConfig->GetConfig(CONFIG_AHBOT_CLASS_REAGENT_AMOUNT) +
+ sAuctionBotConfig->GetConfig(CONFIG_AHBOT_CLASS_PROJECTILE_AMOUNT) + sAuctionBotConfig->GetConfig(CONFIG_AHBOT_CLASS_TRADEGOOD_AMOUNT) + sAuctionBotConfig->GetConfig(CONFIG_AHBOT_CLASS_GENERIC_AMOUNT) +
+ sAuctionBotConfig->GetConfig(CONFIG_AHBOT_CLASS_RECIPE_AMOUNT) + sAuctionBotConfig->GetConfig(CONFIG_AHBOT_CLASS_QUIVER_AMOUNT) + sAuctionBotConfig->GetConfig(CONFIG_AHBOT_CLASS_QUEST_AMOUNT) +
+ sAuctionBotConfig->GetConfig(CONFIG_AHBOT_CLASS_KEY_AMOUNT) + sAuctionBotConfig->GetConfig(CONFIG_AHBOT_CLASS_MISC_AMOUNT) + sAuctionBotConfig->GetConfig(CONFIG_AHBOT_CLASS_GLYPH_AMOUNT));
+
+ for (uint32 i = 0; i < MAX_ITEM_CLASS; ++i)
+ config.SetItemsAmountPerClass(AuctionQuality(j), ItemClass(i), index);
+ }
+}
+
+void AuctionBotSeller::LoadSellerValues(SellerConfiguration& config)
+{
+ LoadItemsQuantity(config);
+ uint32 PriceRatio;
+ switch (config.GetHouseType())
+ {
+ case AUCTION_HOUSE_ALLIANCE:
+ PriceRatio = sAuctionBotConfig->GetConfig(CONFIG_AHBOT_ALLIANCE_PRICE_RATIO);
+ break;
+ case AUCTION_HOUSE_HORDE:
+ PriceRatio = sAuctionBotConfig->GetConfig(CONFIG_AHBOT_HORDE_PRICE_RATIO);
+ break;
+ default:
+ PriceRatio = sAuctionBotConfig->GetConfig(CONFIG_AHBOT_NEUTRAL_PRICE_RATIO);
+ break;
+ }
+
+ config.SetPriceRatioPerQuality(AUCTION_QUALITY_GRAY, PriceRatio * sAuctionBotConfig->GetConfig(CONFIG_AHBOT_ITEM_GRAY_PRICE_RATIO) / 100);
+ config.SetPriceRatioPerQuality(AUCTION_QUALITY_WHITE, PriceRatio * sAuctionBotConfig->GetConfig(CONFIG_AHBOT_ITEM_WHITE_PRICE_RATIO) / 100);
+ config.SetPriceRatioPerQuality(AUCTION_QUALITY_GREEN, PriceRatio * sAuctionBotConfig->GetConfig(CONFIG_AHBOT_ITEM_GREEN_PRICE_RATIO) / 100);
+ config.SetPriceRatioPerQuality(AUCTION_QUALITY_BLUE, PriceRatio * sAuctionBotConfig->GetConfig(CONFIG_AHBOT_ITEM_BLUE_PRICE_RATIO) / 100);
+ config.SetPriceRatioPerQuality(AUCTION_QUALITY_PURPLE, PriceRatio * sAuctionBotConfig->GetConfig(CONFIG_AHBOT_ITEM_PURPLE_PRICE_RATIO) / 100);
+ config.SetPriceRatioPerQuality(AUCTION_QUALITY_ORANGE, PriceRatio * sAuctionBotConfig->GetConfig(CONFIG_AHBOT_ITEM_ORANGE_PRICE_RATIO) / 100);
+ config.SetPriceRatioPerQuality(AUCTION_QUALITY_YELLOW, PriceRatio * sAuctionBotConfig->GetConfig(CONFIG_AHBOT_ITEM_YELLOW_PRICE_RATIO) / 100);
+
+ config.SetPriceRatioPerClass(ITEM_CLASS_CONSUMABLE, sAuctionBotConfig->GetConfig(CONFIG_AHBOT_CLASS_CONSUMABLE_PRICE_RATIO));
+ config.SetPriceRatioPerClass(ITEM_CLASS_CONTAINER, sAuctionBotConfig->GetConfig(CONFIG_AHBOT_CLASS_CONTAINER_PRICE_RATIO));
+ config.SetPriceRatioPerClass(ITEM_CLASS_WEAPON, sAuctionBotConfig->GetConfig(CONFIG_AHBOT_CLASS_WEAPON_PRICE_RATIO));
+ config.SetPriceRatioPerClass(ITEM_CLASS_GEM, sAuctionBotConfig->GetConfig(CONFIG_AHBOT_CLASS_GEM_PRICE_RATIO));
+ config.SetPriceRatioPerClass(ITEM_CLASS_ARMOR, sAuctionBotConfig->GetConfig(CONFIG_AHBOT_CLASS_ARMOR_PRICE_RATIO));
+ config.SetPriceRatioPerClass(ITEM_CLASS_REAGENT, sAuctionBotConfig->GetConfig(CONFIG_AHBOT_CLASS_REAGENT_PRICE_RATIO));
+ config.SetPriceRatioPerClass(ITEM_CLASS_PROJECTILE, sAuctionBotConfig->GetConfig(CONFIG_AHBOT_CLASS_PROJECTILE_PRICE_RATIO));
+ config.SetPriceRatioPerClass(ITEM_CLASS_TRADE_GOODS, sAuctionBotConfig->GetConfig(CONFIG_AHBOT_CLASS_TRADEGOOD_PRICE_RATIO));
+ config.SetPriceRatioPerClass(ITEM_CLASS_GENERIC, sAuctionBotConfig->GetConfig(CONFIG_AHBOT_CLASS_GENERIC_PRICE_RATIO));
+ config.SetPriceRatioPerClass(ITEM_CLASS_RECIPE, sAuctionBotConfig->GetConfig(CONFIG_AHBOT_CLASS_RECIPE_PRICE_RATIO));
+ config.SetPriceRatioPerClass(ITEM_CLASS_MONEY, sAuctionBotConfig->GetConfig(CONFIG_AHBOT_CLASS_MONEY_PRICE_RATIO));
+ config.SetPriceRatioPerClass(ITEM_CLASS_QUIVER, sAuctionBotConfig->GetConfig(CONFIG_AHBOT_CLASS_QUIVER_PRICE_RATIO));
+ config.SetPriceRatioPerClass(ITEM_CLASS_QUEST, sAuctionBotConfig->GetConfig(CONFIG_AHBOT_CLASS_QUEST_PRICE_RATIO));
+ config.SetPriceRatioPerClass(ITEM_CLASS_KEY, sAuctionBotConfig->GetConfig(CONFIG_AHBOT_CLASS_KEY_PRICE_RATIO));
+ config.SetPriceRatioPerClass(ITEM_CLASS_PERMANENT, sAuctionBotConfig->GetConfig(CONFIG_AHBOT_CLASS_PERMANENT_PRICE_RATIO));
+ config.SetPriceRatioPerClass(ITEM_CLASS_MISC, sAuctionBotConfig->GetConfig(CONFIG_AHBOT_CLASS_MISC_PRICE_RATIO));
+ config.SetPriceRatioPerClass(ITEM_CLASS_GLYPH, sAuctionBotConfig->GetConfig(CONFIG_AHBOT_CLASS_GLYPH_PRICE_RATIO));
+
+ //load min and max auction times
+ config.SetMinTime(sAuctionBotConfig->GetConfig(CONFIG_AHBOT_MINTIME));
+ config.SetMaxTime(sAuctionBotConfig->GetConfig(CONFIG_AHBOT_MAXTIME));
+
+ TC_LOG_DEBUG("ahbot", "AHBot: minTime = %u", config.GetMinTime());
+ TC_LOG_DEBUG("ahbot", "AHBot: maxTime = %u", config.GetMaxTime());
+
+ TC_LOG_DEBUG("ahbot", "AHBot: For AH type %u", config.GetHouseType());
+ TC_LOG_DEBUG("ahbot", "AHBot: GrayItems = %u", config.GetItemsAmountPerQuality(AUCTION_QUALITY_GRAY));
+ TC_LOG_DEBUG("ahbot", "AHBot: WhiteItems = %u", config.GetItemsAmountPerQuality(AUCTION_QUALITY_WHITE));
+ TC_LOG_DEBUG("ahbot", "AHBot: GreenItems = %u", config.GetItemsAmountPerQuality(AUCTION_QUALITY_GREEN));
+ TC_LOG_DEBUG("ahbot", "AHBot: BlueItems = %u", config.GetItemsAmountPerQuality(AUCTION_QUALITY_BLUE));
+ TC_LOG_DEBUG("ahbot", "AHBot: PurpleItems = %u", config.GetItemsAmountPerQuality(AUCTION_QUALITY_PURPLE));
+ TC_LOG_DEBUG("ahbot", "AHBot: OrangeItems = %u", config.GetItemsAmountPerQuality(AUCTION_QUALITY_ORANGE));
+ TC_LOG_DEBUG("ahbot", "AHBot: YellowItems = %u", config.GetItemsAmountPerQuality(AUCTION_QUALITY_YELLOW));
+}
+
+// Set static of items on one AH faction.
+// Fill ItemInfos object with real content of AH.
+uint32 AuctionBotSeller::SetStat(SellerConfiguration& config)
+{
+ AllItemsArray itemsSaved(MAX_AUCTION_QUALITY, std::vector<uint32>(MAX_ITEM_CLASS));
+
+ AuctionHouseObject* auctionHouse = sAuctionMgr->GetAuctionsMap(config.GetHouseType());
+ for (AuctionHouseObject::AuctionEntryMap::const_iterator itr = auctionHouse->GetAuctionsBegin(); itr != auctionHouse->GetAuctionsEnd(); ++itr)
+ {
+ AuctionEntry* auctionEntry = itr->second;
+ Item* item = sAuctionMgr->GetAItem(auctionEntry->itemGUIDLow);
+ if (item)
+ {
+ ItemTemplate const* prototype = item->GetTemplate();
+ if (prototype)
+ if (!auctionEntry->owner) // Add only ahbot items
+ ++itemsSaved[prototype->Quality][prototype->Class];
+ }
+ }
+
+ uint32 count = 0;
+ for (uint32 j = 0; j < MAX_AUCTION_QUALITY; ++j)
+ {
+ for (uint32 i = 0; i < MAX_ITEM_CLASS; ++i)
+ {
+ config.SetMissedItemsPerClass((AuctionQuality)j, (ItemClass)i, itemsSaved[j][i]);
+ count += config.GetMissedItemsPerClass((AuctionQuality)j, (ItemClass)i);
+ }
+ }
+
+ TC_LOG_DEBUG("ahbot", "AHBot: Missed Item \tGray\tWhite\tGreen\tBlue\tPurple\tOrange\tYellow");
+ for (uint32 i = 0; i < MAX_ITEM_CLASS; ++i)
+ {
+ TC_LOG_DEBUG("ahbot", "AHBot: \t\t%u\t%u\t%u\t%u\t%u\t%u\t%u",
+ config.GetMissedItemsPerClass(AUCTION_QUALITY_GRAY, (ItemClass)i),
+ config.GetMissedItemsPerClass(AUCTION_QUALITY_WHITE, (ItemClass)i),
+ config.GetMissedItemsPerClass(AUCTION_QUALITY_GREEN, (ItemClass)i),
+ config.GetMissedItemsPerClass(AUCTION_QUALITY_BLUE, (ItemClass)i),
+ config.GetMissedItemsPerClass(AUCTION_QUALITY_PURPLE, (ItemClass)i),
+ config.GetMissedItemsPerClass(AUCTION_QUALITY_ORANGE, (ItemClass)i),
+ config.GetMissedItemsPerClass(AUCTION_QUALITY_YELLOW, (ItemClass)i));
+ }
+ config.LastMissedItem = count;
+
+ return count;
+}
+
+// getRandomArray is used to make viable the possibility to add any of missed item in place of first one to last one.
+bool AuctionBotSeller::GetItemsToSell(SellerConfiguration& config, ItemsToSellArray& itemsToSellArray, AllItemsArray const& addedItem)
+{
+ itemsToSellArray.clear();
+ bool found = false;
+
+ for (uint32 j = 0; j < MAX_AUCTION_QUALITY; ++j)
+ {
+ for (uint32 i = 0; i < MAX_ITEM_CLASS; ++i)
+ {
+ if (config.GetMissedItemsPerClass(AuctionQuality(j), ItemClass(i)) > addedItem[j][i] && !_itemPool[j][i].empty())
+ {
+ ItemToSell miss_item;
+ miss_item.Color = j;
+ miss_item.Itemclass = i;
+ itemsToSellArray.push_back(miss_item);
+ found = true;
+ }
+ }
+ }
+
+ return found;
+}
+
+// Set items price. All important value are passed by address.
+void AuctionBotSeller::SetPricesOfItem(ItemTemplate const* itemProto, SellerConfiguration& config, uint32& buyp, uint32& bidp, uint32 stackCount)
+{
+ uint32 classRatio = config.GetPriceRatioPerClass(ItemClass(itemProto->Class));
+ uint32 qualityRatio = config.GetPriceRatioPerQuality(AuctionQuality(itemProto->Quality));
+ uint32 priceRatio = (classRatio * qualityRatio) / 100;
+
+ uint32 buyPrice = itemProto->BuyPrice;
+ uint32 sellPrice = itemProto->SellPrice;
+
+ if (buyPrice == 0)
+ {
+ if (sellPrice > 0)
+ buyPrice = sellPrice * GetSellModifier(itemProto);
+ else
+ {
+ uint32 divisor = ((itemProto->Class == 2 || itemProto->Class == 4) ? 284 : 80);
+ uint32 tempLevel = (itemProto->ItemLevel == 0 ? 1 : itemProto->ItemLevel);
+ uint32 tempQuality = (itemProto->Quality == 0 ? 1 : itemProto->Quality);
+
+ buyPrice = tempLevel * tempQuality * GetBuyModifier(itemProto)* tempLevel / divisor;
+ }
+ }
+
+ if (sellPrice == 0)
+ sellPrice = (buyPrice > 10 ? buyPrice / GetSellModifier(itemProto) : buyPrice);
+
+ if (!sAuctionBotConfig->GetConfig(CONFIG_AHBOT_BUYPRICE_SELLER))
+ buyPrice = sellPrice;
+
+ uint32 basePrice = (buyPrice * stackCount * priceRatio) / (itemProto->Class == 6 ? 200 : itemProto->BuyCount) / 100;
+ uint32 range = basePrice * 0.04;
+
+ buyp = urand(basePrice - range, basePrice + range) + 1;
+
+ basePrice = buyp * .5;
+ range = buyp * .4;
+ bidp = urand(basePrice - range, basePrice + range) + 1;
+}
+
+// Determine the multiplier for the sell price of any weapon without a buy price.
+uint32 AuctionBotSeller::GetSellModifier(ItemTemplate const* prototype)
+{
+ switch (prototype->Class)
+ {
+ case ITEM_CLASS_WEAPON:
+ case ITEM_CLASS_ARMOR:
+ case ITEM_CLASS_REAGENT:
+ case ITEM_CLASS_PROJECTILE:
+ return 5;
+ default:
+ return 4;
+ }
+}
+
+// Return the modifier by which the item's level and quality will be modified by to derive a relatively accurate price.
+uint32 AuctionBotSeller::GetBuyModifier(ItemTemplate const* prototype)
+{
+ switch (prototype->Class)
+ {
+ case ITEM_CLASS_CONSUMABLE:
+ {
+ switch (prototype->SubClass)
+ {
+ case ITEM_SUBCLASS_CONSUMABLE:
+ return 100;
+ case ITEM_SUBCLASS_FLASK:
+ return 400;
+ case ITEM_SUBCLASS_SCROLL:
+ return 15;
+ case ITEM_SUBCLASS_ITEM_ENHANCEMENT:
+ return 250;
+ case ITEM_SUBCLASS_BANDAGE:
+ return 125;
+ default:
+ return 300;
+ }
+ }
+ case ITEM_CLASS_WEAPON:
+ {
+ switch (prototype->SubClass)
+ {
+ case ITEM_SUBCLASS_WEAPON_AXE:
+ case ITEM_SUBCLASS_WEAPON_MACE:
+ case ITEM_SUBCLASS_WEAPON_SWORD:
+ case ITEM_SUBCLASS_WEAPON_FIST:
+ case ITEM_SUBCLASS_WEAPON_DAGGER:
+ return 1200;
+ case ITEM_SUBCLASS_WEAPON_AXE2:
+ case ITEM_SUBCLASS_WEAPON_MACE2:
+ case ITEM_SUBCLASS_WEAPON_POLEARM:
+ case ITEM_SUBCLASS_WEAPON_SWORD2:
+ case ITEM_SUBCLASS_WEAPON_STAFF:
+ return 1500;
+ case ITEM_SUBCLASS_WEAPON_THROWN:
+ return 350;
+ default:
+ return 1000;
+ }
+ }
+ case ITEM_CLASS_ARMOR:
+ {
+ switch (prototype->SubClass)
+ {
+ case ITEM_SUBCLASS_ARMOR_MISC:
+ case ITEM_SUBCLASS_ARMOR_CLOTH:
+ return 500;
+ case ITEM_SUBCLASS_ARMOR_LEATHER:
+ return 600;
+ case ITEM_SUBCLASS_ARMOR_MAIL:
+ return 700;
+ case ITEM_SUBCLASS_ARMOR_PLATE:
+ case ITEM_SUBCLASS_ARMOR_SHIELD:
+ return 800;
+ default:
+ return 400;
+ }
+ }
+ case ITEM_CLASS_REAGENT:
+ case ITEM_CLASS_PROJECTILE:
+ return 50;
+ case ITEM_CLASS_TRADE_GOODS:
+ {
+ switch (prototype->SubClass)
+ {
+ case ITEM_SUBCLASS_TRADE_GOODS:
+ case ITEM_SUBCLASS_PARTS:
+ case ITEM_SUBCLASS_MEAT:
+ return 50;
+ case ITEM_SUBCLASS_EXPLOSIVES:
+ return 250;
+ case ITEM_SUBCLASS_DEVICES:
+ return 500;
+ case ITEM_SUBCLASS_ELEMENTAL:
+ case ITEM_SUBCLASS_TRADE_GOODS_OTHER:
+ case ITEM_SUBCLASS_ENCHANTING:
+ return 300;
+ default:
+ return 100;
+ }
+ }
+ case ITEM_CLASS_QUEST: return 1000;
+ case ITEM_CLASS_KEY: return 3000;
+ default:
+ return 500;
+ }
+}
+
+void AuctionBotSeller::SetItemsRatio(uint32 al, uint32 ho, uint32 ne)
+{
+ sAuctionBotConfig->SetConfig(CONFIG_AHBOT_ALLIANCE_ITEM_AMOUNT_RATIO, std::max(al, 100000u));
+ sAuctionBotConfig->SetConfig(CONFIG_AHBOT_HORDE_ITEM_AMOUNT_RATIO, std::max(ho, 100000u));
+ sAuctionBotConfig->SetConfig(CONFIG_AHBOT_NEUTRAL_ITEM_AMOUNT_RATIO, std::max(ne, 100000u));
+
+ for (int i = 0; i < MAX_AUCTION_HOUSE_TYPE; ++i)
+ LoadItemsQuantity(_houseConfig[i]);
+}
+
+void AuctionBotSeller::SetItemsRatioForHouse(AuctionHouseType house, uint32 val)
+{
+ val = std::max(val, 10000u); // apply same upper limit as used for config load
+
+ switch (house)
+ {
+ case AUCTION_HOUSE_ALLIANCE: sAuctionBotConfig->SetConfig(CONFIG_AHBOT_ALLIANCE_ITEM_AMOUNT_RATIO, val); break;
+ case AUCTION_HOUSE_HORDE: sAuctionBotConfig->SetConfig(CONFIG_AHBOT_HORDE_ITEM_AMOUNT_RATIO, val); break;
+ default: sAuctionBotConfig->SetConfig(CONFIG_AHBOT_NEUTRAL_ITEM_AMOUNT_RATIO, val); break;
+ }
+
+ LoadItemsQuantity(_houseConfig[house]);
+}
+
+void AuctionBotSeller::SetItemsAmount(uint32(&vals)[MAX_AUCTION_QUALITY])
+{
+ sAuctionBotConfig->SetConfig(CONFIG_AHBOT_ITEM_GRAY_AMOUNT, vals[AUCTION_QUALITY_GRAY]);
+ sAuctionBotConfig->SetConfig(CONFIG_AHBOT_ITEM_WHITE_AMOUNT, vals[AUCTION_QUALITY_WHITE]);
+ sAuctionBotConfig->SetConfig(CONFIG_AHBOT_ITEM_GREEN_AMOUNT, vals[AUCTION_QUALITY_GREEN]);
+ sAuctionBotConfig->SetConfig(CONFIG_AHBOT_ITEM_BLUE_AMOUNT, vals[AUCTION_QUALITY_BLUE]);
+ sAuctionBotConfig->SetConfig(CONFIG_AHBOT_ITEM_PURPLE_AMOUNT, vals[AUCTION_QUALITY_PURPLE]);
+ sAuctionBotConfig->SetConfig(CONFIG_AHBOT_ITEM_ORANGE_AMOUNT, vals[AUCTION_QUALITY_ORANGE]);
+ sAuctionBotConfig->SetConfig(CONFIG_AHBOT_ITEM_YELLOW_AMOUNT, vals[AUCTION_QUALITY_YELLOW]);
+
+ for (int i = 0; i < MAX_AUCTION_HOUSE_TYPE; ++i)
+ LoadItemsQuantity(_houseConfig[i]);
+}
+
+void AuctionBotSeller::SetItemsAmountForQuality(AuctionQuality quality, uint32 val)
+{
+ switch (quality)
+ {
+ case AUCTION_QUALITY_GRAY:
+ sAuctionBotConfig->SetConfig(CONFIG_AHBOT_ITEM_GRAY_AMOUNT, val); break;
+ case AUCTION_QUALITY_WHITE:
+ sAuctionBotConfig->SetConfig(CONFIG_AHBOT_ITEM_WHITE_AMOUNT, val); break;
+ case AUCTION_QUALITY_GREEN:
+ sAuctionBotConfig->SetConfig(CONFIG_AHBOT_ITEM_GREEN_AMOUNT, val); break;
+ case AUCTION_QUALITY_BLUE:
+ sAuctionBotConfig->SetConfig(CONFIG_AHBOT_ITEM_BLUE_AMOUNT, val); break;
+ case AUCTION_QUALITY_PURPLE:
+ sAuctionBotConfig->SetConfig(CONFIG_AHBOT_ITEM_PURPLE_AMOUNT, val); break;
+ case AUCTION_QUALITY_ORANGE:
+ sAuctionBotConfig->SetConfig(CONFIG_AHBOT_ITEM_ORANGE_AMOUNT, val); break;
+ default:
+ sAuctionBotConfig->SetConfig(CONFIG_AHBOT_ITEM_YELLOW_AMOUNT, val); break;
+ }
+
+ for (int i = 0; i < MAX_AUCTION_HOUSE_TYPE; ++i)
+ LoadItemsQuantity(_houseConfig[i]);
+}
+
+// Add new auction to one of the factions.
+// Faction and setting associated is defined passed argument ( config )
+void AuctionBotSeller::AddNewAuctions(SellerConfiguration& config)
+{
+ uint32 count = 0;
+ uint32 items = 0;
+
+ // If there is large amount of items missed we can use boost value to get fast filled AH
+ if (config.LastMissedItem > sAuctionBotConfig->GetItemPerCycleBoost())
+ {
+ items = sAuctionBotConfig->GetItemPerCycleBoost();
+ TC_LOG_DEBUG("ahbot", "AHBot: Boost value used to fill AH! (if this happens often adjust both ItemsPerCycle in worldserver.conf)");
+ }
+ else
+ items = sAuctionBotConfig->GetItemPerCycleNormal();
+
+ uint32 houseid = 0;
+ uint32 auctioneer = 0;
+ switch (config.GetHouseType())
+ {
+ case AUCTION_HOUSE_ALLIANCE:
+ houseid = 1; auctioneer = 79707; break;
+ case AUCTION_HOUSE_HORDE:
+ houseid = 6; auctioneer = 4656; break;
+ default:
+ houseid = 7; auctioneer = 23442; break;
+ }
+
+ AuctionHouseEntry const* ahEntry = sAuctionHouseStore.LookupEntry(houseid);
+
+ AuctionHouseObject* auctionHouse = sAuctionMgr->GetAuctionsMap(config.GetHouseType());
+
+ ItemsToSellArray itemsToSell;
+ AllItemsArray allItems(MAX_AUCTION_QUALITY, std::vector<uint32>(MAX_ITEM_CLASS));
+ // Main loop
+ // getRandomArray will give what categories of items should be added (return true if there is at least 1 items missed)
+ SQLTransaction trans = CharacterDatabase.BeginTransaction();
+ while (GetItemsToSell(config, itemsToSell, allItems) && items > 0)
+ {
+ --items;
+
+ // Select random position from missed items table
+ uint32 pos = urand(0, itemsToSell.size() - 1);
+
+ // Set itemId with random item ID for selected categories and color, from _itemPool table
+ uint32 itemId = _itemPool[itemsToSell[pos].Color][itemsToSell[pos].Itemclass][urand(0, _itemPool[itemsToSell[pos].Color][itemsToSell[pos].Itemclass].size() - 1)];
+ ++allItems[itemsToSell[pos].Color][itemsToSell[pos].Itemclass]; // Helper table to avoid rescan from DB in this loop. (has we add item in random orders)
+
+ if (!itemId)
+ {
+ TC_LOG_DEBUG("ahbot", "AHBot: Item entry 0 auction creating attempt.");
+ continue;
+ }
+
+ ItemTemplate const* prototype = sObjectMgr->GetItemTemplate(itemId);
+ if (!prototype)
+ {
+ TC_LOG_DEBUG("ahbot", "AHBot: Unknown item %u auction creating attempt.", itemId);
+ continue;
+ }
+
+ uint32 stackCount = urand(1, prototype->GetMaxStackSize());
+
+ Item* item = Item::CreateItem(itemId, stackCount);
+ if (!item)
+ {
+ TC_LOG_ERROR("ahbot", "AHBot: Item::CreateItem() returned NULL for item %u (stack: %u)", itemId, stackCount);
+ return;
+ }
+
+ // Update the just created item so that if it needs random properties it has them.
+ // Ex: Notched Shortsword of Stamina will only generate as a Notched Shortsword without this.
+ if (int32 randomPropertyId = Item::GenerateItemRandomPropertyId(itemId))
+ item->SetItemRandomProperties(randomPropertyId);
+
+ uint32 buyoutPrice;
+ uint32 bidPrice = 0;
+
+ // Price of items are set here
+ SetPricesOfItem(prototype, config, buyoutPrice, bidPrice, stackCount);
+
+ // Deposit time
+ uint32 etime = urand(1, 3);
+ switch (etime)
+ {
+ case 1:
+ etime = 43200;
+ break;
+ case 2:
+ etime = 86400;
+ break;
+ case 3:
+ etime = 172800;
+ break;
+ default:
+ etime = 86400;
+ break;
+ }
+
+ AuctionEntry* auctionEntry = new AuctionEntry();
+ auctionEntry->Id = sObjectMgr->GenerateAuctionID();
+ auctionEntry->owner = 0;
+ auctionEntry->itemGUIDLow = item->GetGUIDLow();
+ auctionEntry->itemEntry = item->GetEntry();
+ auctionEntry->startbid = bidPrice;
+ auctionEntry->buyout = buyoutPrice;
+ auctionEntry->auctioneer = auctioneer;
+ auctionEntry->bidder = 0;
+ auctionEntry->bid = 0;
+ auctionEntry->deposit = sAuctionMgr->GetAuctionDeposit(ahEntry, etime, item, stackCount);
+ auctionEntry->auctionHouseEntry = ahEntry;
+ auctionEntry->expire_time = time(NULL) + urand(config.GetMinTime(), config.GetMaxTime()) * HOUR;
+
+ item->SaveToDB(trans);
+ sAuctionMgr->AddAItem(item);
+ auctionHouse->AddAuction(auctionEntry);
+ auctionEntry->SaveToDB(trans);
+
+ auctionHouse->AddAuction(auctionEntry);
+
+ ++count;
+ }
+ CharacterDatabase.CommitTransaction(trans);
+
+ TC_LOG_DEBUG("ahbot", "AHBot: Added %u items to auction", count);
+}
+
+bool AuctionBotSeller::Update(AuctionHouseType houseType)
+{
+ if (sAuctionBotConfig->GetConfigItemAmountRatio(houseType) > 0)
+ {
+ TC_LOG_DEBUG("ahbot", "AHBot: %s selling ...", AuctionBotConfig::GetHouseTypeName(houseType));
+ if (SetStat(_houseConfig[houseType]))
+ AddNewAuctions(_houseConfig[houseType]);
+ return true;
+ }
+ else
+ return false;
+}
diff --git a/src/server/game/AuctionHouseBot/AuctionHouseBotSeller.h b/src/server/game/AuctionHouseBot/AuctionHouseBotSeller.h
new file mode 100644
index 00000000000..014fe23f71a
--- /dev/null
+++ b/src/server/game/AuctionHouseBot/AuctionHouseBotSeller.h
@@ -0,0 +1,147 @@
+/*
+ * Copyright (C) 2008-2014 TrinityCore <http://www.trinitycore.org/>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef AUCTION_HOUSE_BOT_SELLER_H
+#define AUCTION_HOUSE_BOT_SELLER_H
+
+#include "Define.h"
+#include "ItemPrototype.h"
+#include "AuctionHouseBot.h"
+
+struct ItemToSell
+{
+ uint32 Color;
+ uint32 Itemclass;
+};
+
+typedef std::vector<ItemToSell> ItemsToSellArray;
+typedef std::vector<std::vector<uint32>> AllItemsArray;
+
+struct SellerItemClassInfo
+{
+ SellerItemClassInfo(): AmountOfItems(0), MissItems(0), Quantity(0), PriceRatio(0) {}
+
+ uint32 AmountOfItems;
+ uint32 MissItems;
+ uint32 Quantity;
+ uint32 PriceRatio;
+};
+
+struct SellerItemInfo
+{
+ SellerItemInfo(): AmountOfItems(0), MissItems(0), PriceRatio(0) {}
+
+ uint32 AmountOfItems;
+ uint32 MissItems;
+ uint32 PriceRatio;
+
+ SellerItemClassInfo ItemClassInfos[MAX_ITEM_CLASS];
+};
+
+class SellerConfiguration
+{
+public:
+ SellerConfiguration(): LastMissedItem(0), _houseType(AUCTION_HOUSE_NEUTRAL), _minTime(1), _maxTime(72)
+ {
+ }
+
+ ~SellerConfiguration() {}
+
+ void Initialize(AuctionHouseType houseType)
+ {
+ _houseType = houseType;
+ }
+
+ AuctionHouseType GetHouseType() const { return _houseType; }
+
+ uint32 LastMissedItem;
+
+ void SetMinTime(uint32 value)
+ {
+ _minTime = value;
+ }
+ uint32 GetMinTime() const
+ {
+ return std::min(1u, std::min(_minTime, _maxTime));
+ }
+
+ void SetMaxTime(uint32 value) { _maxTime = value; }
+ uint32 GetMaxTime() const { return _maxTime; }
+ // Data access classified by item class and item quality
+ void SetItemsAmountPerClass(AuctionQuality quality, ItemClass itemclass, uint32 amount) { _ItemInfo[quality].ItemClassInfos[itemclass].AmountOfItems = amount * _ItemInfo[quality].ItemClassInfos[itemclass].Quantity; }
+ uint32 GetItemsAmountPerClass(AuctionQuality quality, ItemClass itemclass) const { return _ItemInfo[quality].ItemClassInfos[itemclass].AmountOfItems; }
+ void SetItemsQuantityPerClass(AuctionQuality quality, ItemClass itemclass, uint32 qty) { _ItemInfo[quality].ItemClassInfos[itemclass].Quantity = qty; }
+ uint32 GetItemsQuantityPerClass(AuctionQuality quality, ItemClass itemclass) const { return _ItemInfo[quality].ItemClassInfos[itemclass].Quantity; }
+ void SetMissedItemsPerClass(AuctionQuality quality, ItemClass itemclass, uint32 found)
+ {
+ if (_ItemInfo[quality].ItemClassInfos[itemclass].AmountOfItems > found)
+ _ItemInfo[quality].ItemClassInfos[itemclass].MissItems = _ItemInfo[quality].ItemClassInfos[itemclass].AmountOfItems - found;
+ else
+ _ItemInfo[quality].ItemClassInfos[itemclass].MissItems = 0;
+ }
+ uint32 GetMissedItemsPerClass(AuctionQuality quality, ItemClass itemclass) const { return _ItemInfo[quality].ItemClassInfos[itemclass].MissItems; }
+
+ // Data for every quality of item
+ void SetItemsAmountPerQuality(AuctionQuality quality, uint32 cnt) { _ItemInfo[quality].AmountOfItems = cnt; }
+ uint32 GetItemsAmountPerQuality(AuctionQuality quality) const { return _ItemInfo[quality].AmountOfItems; }
+ void SetPriceRatioPerQuality(AuctionQuality quality, uint32 value) { _ItemInfo[quality].PriceRatio = value; }
+ uint32 GetPriceRatioPerQuality(AuctionQuality quality) const { return _ItemInfo[quality].PriceRatio; }
+ void SetPriceRatioPerClass(ItemClass item, uint32 value) { _ItemInfo[0].ItemClassInfos[item].PriceRatio = value; }
+ uint32 GetPriceRatioPerClass(ItemClass item) const { return _ItemInfo[0].ItemClassInfos[item].PriceRatio; }
+
+private:
+ AuctionHouseType _houseType;
+ uint32 _minTime;
+ uint32 _maxTime;
+ SellerItemInfo _ItemInfo[MAX_AUCTION_QUALITY];
+};
+
+// This class handle all Selling method
+// (holder of AHB_Seller_Config data for each auction house type)
+class AuctionBotSeller : public AuctionBotAgent
+{
+public:
+ typedef std::vector<uint32> ItemPool;
+
+ AuctionBotSeller();
+ ~AuctionBotSeller() override;
+
+ bool Initialize() override;
+ bool Update(AuctionHouseType houseType) override;
+
+ void AddNewAuctions(SellerConfiguration& config);
+ void SetItemsRatio(uint32 al, uint32 ho, uint32 ne);
+ void SetItemsRatioForHouse(AuctionHouseType house, uint32 val);
+ void SetItemsAmount(uint32(&vals)[MAX_AUCTION_QUALITY]);
+ void SetItemsAmountForQuality(AuctionQuality quality, uint32 val);
+ void LoadConfig();
+
+private:
+ SellerConfiguration _houseConfig[MAX_AUCTION_HOUSE_TYPE];
+
+ ItemPool _itemPool[MAX_AUCTION_QUALITY][MAX_ITEM_CLASS];
+
+ void LoadSellerValues(SellerConfiguration& config);
+ uint32 SetStat(SellerConfiguration& config);
+ bool GetItemsToSell(SellerConfiguration& config, ItemsToSellArray& itemsToSellArray, AllItemsArray const& addedItem);
+ void SetPricesOfItem(ItemTemplate const* itemProto, SellerConfiguration& config, uint32& buyp, uint32& bidp, uint32 stackcnt);
+ void LoadItemsQuantity(SellerConfiguration& config);
+ static uint32 GetBuyModifier(ItemTemplate const* prototype);
+ static uint32 GetSellModifier(ItemTemplate const* itemProto);
+};
+
+#endif
diff --git a/src/server/game/CMakeLists.txt b/src/server/game/CMakeLists.txt
index 532900c0438..d7d14e7bda4 100644
--- a/src/server/game/CMakeLists.txt
+++ b/src/server/game/CMakeLists.txt
@@ -13,6 +13,7 @@ file(GLOB_RECURSE sources_Achievements Achievements/*.cpp Achievements/*.h)
file(GLOB_RECURSE sources_Addons Addons/*.cpp Addons/*.h)
file(GLOB_RECURSE sources_AI AI/*.cpp AI/*.h)
file(GLOB_RECURSE sources_AuctionHouse AuctionHouse/*.cpp AuctionHouse/*.h)
+file(GLOB_RECURSE sources_AuctionHouseBot AuctionHouseBot/*.cpp AuctionHouseBot/*.h)
file(GLOB_RECURSE sources_Battlefield Battlefield/*.cpp Battlefield/*.h)
file(GLOB_RECURSE sources_Battlegrounds Battlegrounds/*.cpp Battlegrounds/*.h)
file(GLOB_RECURSE sources_Calendar Calendar/*.cpp Calendar/*.h)
@@ -63,6 +64,7 @@ set(game_STAT_SRCS
${sources_Addons}
${sources_AI}
${sources_AuctionHouse}
+ ${sources_AuctionHouseBot}
${sources_Battlefield}
${sources_Battlegrounds}
${sources_Calendar}
@@ -136,6 +138,7 @@ include_directories(
${CMAKE_CURRENT_SOURCE_DIR}/AI/ScriptedAI
${CMAKE_CURRENT_SOURCE_DIR}/AI/SmartScripts
${CMAKE_CURRENT_SOURCE_DIR}/AuctionHouse
+ ${CMAKE_CURRENT_SOURCE_DIR}/AuctionHouseBot
${CMAKE_CURRENT_SOURCE_DIR}/Battlefield
${CMAKE_CURRENT_SOURCE_DIR}/Battlefield/Zones
${CMAKE_CURRENT_SOURCE_DIR}/Battlegrounds
diff --git a/src/server/game/Entities/Item/Item.cpp b/src/server/game/Entities/Item/Item.cpp
index 6894dd86493..5a4ef765a6e 100644
--- a/src/server/game/Entities/Item/Item.cpp
+++ b/src/server/game/Entities/Item/Item.cpp
@@ -690,8 +690,11 @@ void Item::SetState(ItemUpdateState state, Player* forplayer)
if (uState == ITEM_NEW && state == ITEM_REMOVED)
{
// pretend the item never existed
- RemoveFromUpdateQueueOf(forplayer);
- forplayer->DeleteRefundReference(GetGUIDLow());
+ if (forplayer)
+ {
+ RemoveFromUpdateQueueOf(forplayer);
+ forplayer->DeleteRefundReference(GetGUIDLow());
+ }
delete this;
return;
}
@@ -701,7 +704,8 @@ void Item::SetState(ItemUpdateState state, Player* forplayer)
if (uState != ITEM_NEW)
uState = state;
- AddToUpdateQueueOf(forplayer);
+ if (forplayer)
+ AddToUpdateQueueOf(forplayer);
}
else
{
diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp
index 2876b4fc67d..71a7f4b160e 100644
--- a/src/server/game/Entities/Player/Player.cpp
+++ b/src/server/game/Entities/Player/Player.cpp
@@ -15296,6 +15296,19 @@ void Player::RewardQuest(Quest const* quest, uint32 reward, Object* questGiver,
Item* item = StoreNewItem(dest, itemId, true, Item::GenerateItemRandomPropertyId(itemId));
SendNewItem(item, quest->RewardItemIdCount[i], true, false);
}
+ else if (quest->IsDFQuest())
+ {
+ MailSender sender(MAIL_CREATURE, 34337 /* The Postmaster */ );
+ MailDraft draft("Recovered Item", "We recovered a lost item in the twisting nether and noted that it was yours.$B$BPlease find said object enclosed."); // This is the text used in Cataclysm, it probably wasn't changed.
+ SQLTransaction trans = CharacterDatabase.BeginTransaction();
+ if (Item* item = Item::CreateItem(quest->RewardItemId[i], quest->RewardItemIdCount[i], 0))
+ {
+ item->SaveToDB(trans);
+ draft.AddItem(item);
+ }
+ draft.SendMailTo(trans, MailReceiver(this, this->GetGUIDLow()), sender);
+ CharacterDatabase.CommitTransaction(trans);
+ }
}
}
}
@@ -15309,7 +15322,7 @@ void Player::RewardQuest(Quest const* quest, uint32 reward, Object* questGiver,
bool rewarded = (m_RewardedQuests.find(quest_id) != m_RewardedQuests.end());
// Not give XP in case already completed once repeatable quest
- uint32 XP = rewarded ? 0 : uint32(quest->XPValue(this)*sWorld->getRate(RATE_XP_QUEST));
+ uint32 XP = rewarded && !quest->IsDFQuest() ? 0 : uint32(quest->XPValue(this)*sWorld->getRate(RATE_XP_QUEST));
// handle SPELL_AURA_MOD_XP_QUEST_PCT auras
Unit::AuraEffectList const& ModXPPctAuras = GetAuraEffectsByType(SPELL_AURA_MOD_XP_QUEST_PCT);
@@ -15435,6 +15448,10 @@ void Player::RewardQuest(Quest const* quest, uint32 reward, Object* questGiver,
void Player::FailQuest(uint32 questId)
{
+ // Already complete quests shouldn't turn failed.
+ if (GetQuestStatus(questId) == QUEST_STATUS_COMPLETE)
+ return;
+
if (Quest const* quest = sObjectMgr->GetQuestTemplate(questId))
{
SetQuestStatus(questId, QUEST_STATUS_FAILED);
diff --git a/src/server/game/Guilds/Guild.h b/src/server/game/Guilds/Guild.h
index 8c7b926a700..375d39cf232 100644
--- a/src/server/game/Guilds/Guild.h
+++ b/src/server/game/Guilds/Guild.h
@@ -657,6 +657,9 @@ public:
std::string const& GetName() const { return m_name; }
std::string const& GetMOTD() const { return m_motd; }
std::string const& GetInfo() const { return m_info; }
+ uint32 GetMemberCount() const { return m_members.size(); }
+ time_t GetCreatedDate() const { return m_createdDate; }
+ uint64 GetBankMoney() const { return m_bankMoney; }
bool SetName(std::string const& name);
diff --git a/src/server/game/Miscellaneous/Language.h b/src/server/game/Miscellaneous/Language.h
index f4d1bc03144..cb868097ac6 100644
--- a/src/server/game/Miscellaneous/Language.h
+++ b/src/server/game/Miscellaneous/Language.h
@@ -941,7 +941,34 @@ enum TrinityStrings
LANG_LIST_MAIL_INFO_3 = 1154,
LANG_LIST_MAIL_INFO_ITEM = 1155,
LANG_LIST_MAIL_NOT_FOUND = 1156,
- // Room for more level 3 1157-1199 not used
+ LANG_AHBOT_RELOAD_OK = 1157,
+ LANG_AHBOT_STATUS_BAR_CONSOLE = 1158,
+ LANG_AHBOT_STATUS_MIDBAR_CONSOLE = 1159,
+ LANG_AHBOT_STATUS_TITLE1_CONSOLE = 1160,
+ LANG_AHBOT_STATUS_TITLE1_CHAT = 1161,
+ LANG_AHBOT_STATUS_FORMAT_CONSOLE = 1162,
+ LANG_AHBOT_STATUS_FORMAT_CHAT = 1163,
+ LANG_AHBOT_STATUS_ITEM_COUNT = 1164,
+ LANG_AHBOT_STATUS_ITEM_RATIO = 1165,
+ LANG_AHBOT_STATUS_TITLE2_CONSOLE = 1166,
+ LANG_AHBOT_STATUS_TITLE2_CHAT = 1167,
+ LANG_AHBOT_QUALITY_GRAY = 1168,
+ LANG_AHBOT_QUALITY_WHITE = 1169,
+ LANG_AHBOT_QUALITY_GREEN = 1170,
+ LANG_AHBOT_QUALITY_BLUE = 1171,
+ LANG_AHBOT_QUALITY_PURPLE = 1172,
+ LANG_AHBOT_QUALITY_ORANGE = 1173,
+ LANG_AHBOT_QUALITY_YELLOW = 1174,
+ LANG_AHBOT_ITEMS_AMOUNT = 1175,
+ LANG_AHBOT_ITEMS_RATIO = 1176,
+ LANG_GUILD_INFO_NAME = 1177,
+ LANG_GUILD_INFO_GUILD_MASTER = 1178,
+ LANG_GUILD_INFO_CREATION_DATE = 1179,
+ LANG_GUILD_INFO_MEMBER_COUNT = 1180,
+ LANG_GUILD_INFO_BANK_GOLD = 1181,
+ LANG_GUILD_INFO_MOTD = 1182,
+ LANG_GUILD_INFO_EXTRA_INFO = 1183,
+ // Room for more level 3 1184-1199 not used
// Debug commands
LANG_CINEMATIC_NOT_EXIST = 1200,
diff --git a/src/server/game/Scripting/ScriptLoader.cpp b/src/server/game/Scripting/ScriptLoader.cpp
index d036d438926..ed6c5430674 100644
--- a/src/server/game/Scripting/ScriptLoader.cpp
+++ b/src/server/game/Scripting/ScriptLoader.cpp
@@ -47,6 +47,7 @@ void AddSC_SmartScripts();
//Commands
void AddSC_account_commandscript();
void AddSC_achievement_commandscript();
+void AddSC_ahbot_commandscript();
void AddSC_arena_commandscript();
void AddSC_ban_commandscript();
void AddSC_bf_commandscript();
@@ -749,6 +750,7 @@ void AddCommandScripts()
{
AddSC_account_commandscript();
AddSC_achievement_commandscript();
+ AddSC_ahbot_commandscript();
AddSC_arena_commandscript();
AddSC_ban_commandscript();
AddSC_bf_commandscript();
diff --git a/src/server/game/Spells/SpellMgr.cpp b/src/server/game/Spells/SpellMgr.cpp
index bc97744fe32..8e0c8c8bd01 100644
--- a/src/server/game/Spells/SpellMgr.cpp
+++ b/src/server/game/Spells/SpellMgr.cpp
@@ -3350,6 +3350,16 @@ void SpellMgr::LoadSpellInfoCorrections()
// that will be clear if we get more spells with problem like this
spellInfo->AttributesEx |= SPELL_ATTR1_DISPEL_AURAS_ON_IMMUNITY;
break;
+ case 63414: // Spinning Up (Mimiron)
+ spellInfo->Effects[EFFECT_0].TargetB = SpellImplicitTargetInfo(TARGET_UNIT_CASTER);
+ spellInfo->ChannelInterruptFlags = 0;
+ break;
+ case 63036: // Rocket Strike (Mimiron)
+ spellInfo->Speed = 0;
+ break;
+ case 64668: // Magnetic Field (Mimiron)
+ spellInfo->Mechanic = MECHANIC_NONE;
+ break;
case 64468: // Empowering Shadows (Yogg-Saron)
case 64486: // Empowering Shadows (Yogg-Saron)
spellInfo->MaxAffectedTargets = 3; // same for both modes?
diff --git a/src/server/game/World/World.cpp b/src/server/game/World/World.cpp
index 184637b0a1d..f9c8c800ca5 100644
--- a/src/server/game/World/World.cpp
+++ b/src/server/game/World/World.cpp
@@ -23,6 +23,7 @@
#include "World.h"
#include "AchievementMgr.h"
#include "ArenaTeamMgr.h"
+#include "AuctionHouseBot.h"
#include "AuctionHouseMgr.h"
#include "BattlefieldMgr.h"
#include "BattlegroundMgr.h"
@@ -1255,6 +1256,9 @@ void World::LoadConfigSettings(bool reload)
m_bool_configs[CONFIG_IP_BASED_ACTION_LOGGING] = sConfigMgr->GetBoolDefault("Allow.IP.Based.Action.Logging", false);
+ // AHBot
+ m_int_configs[CONFIG_AHBOT_UPDATE_INTERVAL] = sConfigMgr->GetIntDefault("AuctionHouseBot.Update.Interval", 20);
+
// call ScriptMgr if we're reloading the configuration
if (reload)
sScriptMgr->OnConfigLoad(reload);
@@ -1740,6 +1744,9 @@ void World::SetInitialWorldSettings()
m_timers[WUPDATE_AUTOBROADCAST].SetInterval(getIntConfig(CONFIG_AUTOBROADCAST_INTERVAL));
m_timers[WUPDATE_DELETECHARS].SetInterval(DAY*IN_MILLISECONDS); // check for chars to delete every day
+ // for AhBot
+ m_timers[WUPDATE_AHBOT].SetInterval(getIntConfig(CONFIG_AHBOT_UPDATE_INTERVAL) * IN_MILLISECONDS); // every 20 sec
+
m_timers[WUPDATE_PINGDB].SetInterval(getIntConfig(CONFIG_DB_PING_INTERVAL)*MINUTE*IN_MILLISECONDS); // Mysql ping time in minutes
//to set mailtimer to return mails every day between 4 and 5 am
@@ -1767,6 +1774,9 @@ void World::SetInitialWorldSettings()
// Delete all characters which have been deleted X days before
Player::DeleteOldCharacters();
+ TC_LOG_INFO("server.loading", "Initialize AuctionHouseBot...");
+ sAuctionBot->Initialize();
+
// Delete all custom channels which haven't been used for PreserveCustomChannelDuration days.
Channel::CleanOldChannelsInDB();
@@ -1999,6 +2009,13 @@ void World::Update(uint32 diff)
sAuctionMgr->Update();
}
+ /// <li> Handle AHBot operations
+ if (m_timers[WUPDATE_AHBOT].Passed())
+ {
+ sAuctionBot->Update();
+ m_timers[WUPDATE_AHBOT].Reset();
+ }
+
/// <li> Handle session updates when the timer has passed
RecordTimeDiff(NULL);
UpdateSessions(diff);
diff --git a/src/server/game/World/World.h b/src/server/game/World/World.h
index fd31099a5ea..b77f8777bdc 100644
--- a/src/server/game/World/World.h
+++ b/src/server/game/World/World.h
@@ -76,6 +76,7 @@ enum WorldTimers
WUPDATE_AUTOBROADCAST,
WUPDATE_MAILBOXQUEUE,
WUPDATE_DELETECHARS,
+ WUPDATE_AHBOT,
WUPDATE_PINGDB,
WUPDATE_COUNT
};
@@ -333,6 +334,7 @@ enum WorldIntConfigs
CONFIG_BG_REWARD_LOSER_HONOR_LAST,
CONFIG_BIRTHDAY_TIME,
CONFIG_CREATURE_PICKPOCKET_REFILL,
+ CONFIG_AHBOT_UPDATE_INTERVAL,
INT_CONFIG_VALUE_COUNT
};
diff --git a/src/server/scripts/CMakeLists.txt b/src/server/scripts/CMakeLists.txt
index ba2709f0a23..f193cf4aa6a 100644
--- a/src/server/scripts/CMakeLists.txt
+++ b/src/server/scripts/CMakeLists.txt
@@ -78,6 +78,7 @@ include_directories(
${CMAKE_SOURCE_DIR}/src/server/game/AI/ScriptedAI
${CMAKE_SOURCE_DIR}/src/server/game/AI/SmartScripts
${CMAKE_SOURCE_DIR}/src/server/game/AuctionHouse
+ ${CMAKE_SOURCE_DIR}/src/server/game/AuctionHouseBot
${CMAKE_SOURCE_DIR}/src/server/game/Battlefield
${CMAKE_SOURCE_DIR}/src/server/game/Battlefield/Zones
${CMAKE_SOURCE_DIR}/src/server/game/Battlegrounds
diff --git a/src/server/scripts/Commands/cs_ahbot.cpp b/src/server/scripts/Commands/cs_ahbot.cpp
new file mode 100644
index 00000000000..04647d51ff0
--- /dev/null
+++ b/src/server/scripts/Commands/cs_ahbot.cpp
@@ -0,0 +1,251 @@
+/*
+ * Copyright (C) 2008-2014 TrinityCore <http://www.trinitycore.org/>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "ScriptMgr.h"
+#include "Chat.h"
+#include "Language.h"
+#include "AuctionHouseBot.h"
+
+static const uint32 ahbotQualityIds[MAX_AUCTION_QUALITY] =
+{
+ LANG_AHBOT_QUALITY_GRAY, LANG_AHBOT_QUALITY_WHITE,
+ LANG_AHBOT_QUALITY_GREEN, LANG_AHBOT_QUALITY_BLUE,
+ LANG_AHBOT_QUALITY_PURPLE, LANG_AHBOT_QUALITY_ORANGE,
+ LANG_AHBOT_QUALITY_YELLOW
+};
+
+class ahbot_commandscript : public CommandScript
+{
+public:
+ ahbot_commandscript(): CommandScript("ahbot_commandscript") {}
+
+ ChatCommand* GetCommands() const
+ {
+ static ChatCommand ahbotItemsAmountCommandTable[] =
+ {
+ { "gray", rbac::RBAC_PERM_COMMAND_AHBOT_ITEMS_GRAY, true, &HandleAHBotItemsAmountQualityCommand<AUCTION_QUALITY_GRAY>, "", NULL },
+ { "white", rbac::RBAC_PERM_COMMAND_AHBOT_ITEMS_WHITE, true, &HandleAHBotItemsAmountQualityCommand<AUCTION_QUALITY_WHITE>, "", NULL },
+ { "green", rbac::RBAC_PERM_COMMAND_AHBOT_ITEMS_GREEN, true, &HandleAHBotItemsAmountQualityCommand<AUCTION_QUALITY_GREEN>, "", NULL },
+ { "blue", rbac::RBAC_PERM_COMMAND_AHBOT_ITEMS_BLUE, true, &HandleAHBotItemsAmountQualityCommand<AUCTION_QUALITY_BLUE>, "", NULL },
+ { "purple", rbac::RBAC_PERM_COMMAND_AHBOT_ITEMS_PURPLE, true, &HandleAHBotItemsAmountQualityCommand<AUCTION_QUALITY_PURPLE>, "", NULL },
+ { "orange", rbac::RBAC_PERM_COMMAND_AHBOT_ITEMS_ORANGE, true, &HandleAHBotItemsAmountQualityCommand<AUCTION_QUALITY_ORANGE>, "", NULL },
+ { "yellow", rbac::RBAC_PERM_COMMAND_AHBOT_ITEMS_YELLOW, true, &HandleAHBotItemsAmountQualityCommand<AUCTION_QUALITY_YELLOW>, "", NULL },
+ { "", rbac::RBAC_PERM_COMMAND_AHBOT_ITEMS, true, &HandleAHBotItemsAmountCommand, "", NULL },
+ { NULL, 0, true, NULL, "", NULL }
+ };
+
+ static ChatCommand ahbotItemsRatioCommandTable[] =
+ {
+ { "alliance", rbac::RBAC_PERM_COMMAND_AHBOT_RATIO_ALLIANCE, true, &HandleAHBotItemsRatioHouseCommand<AUCTION_HOUSE_ALLIANCE>, "", NULL },
+ { "horde", rbac::RBAC_PERM_COMMAND_AHBOT_RATIO_HORDE, true, &HandleAHBotItemsRatioHouseCommand<AUCTION_HOUSE_HORDE>, "", NULL },
+ { "neutral", rbac::RBAC_PERM_COMMAND_AHBOT_RATIO_NEUTRAL, true, &HandleAHBotItemsRatioHouseCommand<AUCTION_HOUSE_NEUTRAL>, "", NULL },
+ { "", rbac::RBAC_PERM_COMMAND_AHBOT_RATIO, true, &HandleAHBotItemsRatioCommand, "", NULL },
+ { NULL, 0, true, NULL, "", NULL }
+ };
+
+ static ChatCommand ahbotCommandTable[] =
+ {
+ { "items", rbac::RBAC_PERM_COMMAND_AHBOT_ITEMS, true, NULL, "", ahbotItemsAmountCommandTable },
+ { "ratio", rbac::RBAC_PERM_COMMAND_AHBOT_RATIO, true, NULL, "", ahbotItemsRatioCommandTable },
+ { "rebuild", rbac::RBAC_PERM_COMMAND_AHBOT_REBUILD, true, &HandleAHBotRebuildCommand, "", NULL },
+ { "reload", rbac::RBAC_PERM_COMMAND_AHBOT_RELOAD, true, &HandleAHBotReloadCommand, "", NULL },
+ { "status", rbac::RBAC_PERM_COMMAND_AHBOT_STATUS, true, &HandleAHBotStatusCommand, "", NULL },
+ { NULL, 0, true, NULL, "", NULL }
+ };
+
+ static ChatCommand commandTable[] =
+ {
+ { "ahbot", rbac::RBAC_PERM_COMMAND_AHBOT, false, NULL, "", ahbotCommandTable },
+ { NULL, 0, false, NULL, "", NULL }
+ };
+
+ return commandTable;
+ }
+
+ static bool HandleAHBotItemsAmountCommand(ChatHandler* handler, const char* args)
+ {
+ uint32 qVals[MAX_AUCTION_QUALITY];
+ char* arg = strtok((char*)args, " ");
+ for (int i = 0; i < MAX_AUCTION_QUALITY; ++i)
+ {
+ if (!arg)
+ return false;
+ qVals[i] = atoi(arg);
+ arg = strtok(NULL, " ");
+ }
+
+ sAuctionBot->SetItemsAmount(qVals);
+
+ for (int i = 0; i < MAX_AUCTION_QUALITY; ++i)
+ handler->PSendSysMessage(LANG_AHBOT_ITEMS_AMOUNT, handler->GetTrinityString(ahbotQualityIds[i]), sAuctionBotConfig->GetConfigItemQualityAmount(AuctionQuality(i)));
+
+ return true;
+ }
+
+ template <AuctionQuality Q>
+ static bool HandleAHBotItemsAmountQualityCommand(ChatHandler* handler, const char* args)
+ {
+ char* arg = strtok((char*)args, " ");
+ if (!arg)
+ return false;
+ uint32 qualityVal = atoi(arg);
+
+ sAuctionBot->SetItemsAmountForQuality(Q, qualityVal);
+ handler->PSendSysMessage(LANG_AHBOT_ITEMS_AMOUNT, handler->GetTrinityString(ahbotQualityIds[Q]),
+ sAuctionBotConfig->GetConfigItemQualityAmount(Q));
+
+ return true;
+ }
+
+ static bool HandleAHBotItemsRatioCommand(ChatHandler* handler, const char* args)
+ {
+ uint32 rVal[MAX_AUCTION_QUALITY];
+ char* arg = strtok((char*)args, " ");
+ for (int i = 0; i < MAX_AUCTION_QUALITY; ++i)
+ {
+ if (!arg)
+ return false;
+ rVal[i] = atoi(arg);
+ arg = strtok(NULL, " ");
+ }
+
+ sAuctionBot->SetItemsRatio(rVal[0], rVal[1], rVal[2]);
+
+ for (int i = 0; i < MAX_AUCTION_HOUSE_TYPE; ++i)
+ handler->PSendSysMessage(LANG_AHBOT_ITEMS_RATIO, AuctionBotConfig::GetHouseTypeName(AuctionHouseType(i)), sAuctionBotConfig->GetConfigItemAmountRatio(AuctionHouseType(i)));
+ return true;
+ }
+
+ template<AuctionHouseType H>
+ static bool HandleAHBotItemsRatioHouseCommand(ChatHandler* handler, const char* args)
+ {
+ char* arg = strtok((char*)args, " ");
+ if (!arg)
+ return false;
+ uint32 ratioVal = atoi(arg);
+
+ sAuctionBot->SetItemsRatioForHouse(H, ratioVal);
+ handler->PSendSysMessage(LANG_AHBOT_ITEMS_RATIO, AuctionBotConfig::GetHouseTypeName(H), sAuctionBotConfig->GetConfigItemAmountRatio(H));
+ return true;
+ }
+
+ static bool HandleAHBotRebuildCommand(ChatHandler* /*handler*/, const char* args)
+ {
+ char* arg = strtok((char*)args, " ");
+ if (!arg)
+ return false;
+
+ bool all = false;
+ if (strcmp(arg, "all") == 0)
+ all = true;
+
+ sAuctionBot->Rebuild(all);
+ return true;
+ }
+
+ static bool HandleAHBotReloadCommand(ChatHandler* handler, const char* /*args*/)
+ {
+ sAuctionBot->ReloadAllConfig();
+ handler->SendSysMessage(LANG_AHBOT_RELOAD_OK);
+ return true;
+ }
+
+ static bool HandleAHBotStatusCommand(ChatHandler* handler, const char* args)
+ {
+ char* arg = strtok((char*)args, " ");
+ if (!arg)
+ return false;
+
+ bool all = false;
+ if (strcmp(arg, "all") == 0)
+ all = true;
+
+ AuctionHouseBotStatusInfo statusInfo;
+ sAuctionBot->PrepareStatusInfos(statusInfo);
+
+ WorldSession* session = handler->GetSession();
+
+ if (!session)
+ {
+ handler->SendSysMessage(LANG_AHBOT_STATUS_BAR_CONSOLE);
+ handler->SendSysMessage(LANG_AHBOT_STATUS_TITLE1_CONSOLE);
+ handler->SendSysMessage(LANG_AHBOT_STATUS_MIDBAR_CONSOLE);
+ }
+ else
+ handler->SendSysMessage(LANG_AHBOT_STATUS_TITLE1_CHAT);
+
+ uint32 fmtId = session ? LANG_AHBOT_STATUS_FORMAT_CHAT : LANG_AHBOT_STATUS_FORMAT_CONSOLE;
+
+ handler->PSendSysMessage(fmtId, handler->GetTrinityString(LANG_AHBOT_STATUS_ITEM_COUNT),
+ statusInfo[AUCTION_HOUSE_ALLIANCE].ItemsCount,
+ statusInfo[AUCTION_HOUSE_HORDE].ItemsCount,
+ statusInfo[AUCTION_HOUSE_NEUTRAL].ItemsCount,
+ statusInfo[AUCTION_HOUSE_ALLIANCE].ItemsCount +
+ statusInfo[AUCTION_HOUSE_HORDE].ItemsCount +
+ statusInfo[AUCTION_HOUSE_NEUTRAL].ItemsCount);
+
+ if (all)
+ {
+ handler->PSendSysMessage(fmtId, handler->GetTrinityString(LANG_AHBOT_STATUS_ITEM_RATIO),
+ sAuctionBotConfig->GetConfig(CONFIG_AHBOT_ALLIANCE_ITEM_AMOUNT_RATIO),
+ sAuctionBotConfig->GetConfig(CONFIG_AHBOT_HORDE_ITEM_AMOUNT_RATIO),
+ sAuctionBotConfig->GetConfig(CONFIG_AHBOT_NEUTRAL_ITEM_AMOUNT_RATIO),
+ sAuctionBotConfig->GetConfig(CONFIG_AHBOT_ALLIANCE_ITEM_AMOUNT_RATIO) +
+ sAuctionBotConfig->GetConfig(CONFIG_AHBOT_HORDE_ITEM_AMOUNT_RATIO) +
+ sAuctionBotConfig->GetConfig(CONFIG_AHBOT_NEUTRAL_ITEM_AMOUNT_RATIO));
+
+ if (!session)
+ {
+ handler->SendSysMessage(LANG_AHBOT_STATUS_BAR_CONSOLE);
+ handler->SendSysMessage(LANG_AHBOT_STATUS_TITLE2_CONSOLE);
+ handler->SendSysMessage(LANG_AHBOT_STATUS_MIDBAR_CONSOLE);
+ }
+ else
+ handler->SendSysMessage(LANG_AHBOT_STATUS_TITLE2_CHAT);
+
+ for (int i = 0; i < MAX_AUCTION_QUALITY; ++i)
+ handler->PSendSysMessage(fmtId, handler->GetTrinityString(ahbotQualityIds[i]),
+ statusInfo[AUCTION_HOUSE_ALLIANCE].QualityInfo[i],
+ statusInfo[AUCTION_HOUSE_HORDE].QualityInfo[i],
+ statusInfo[AUCTION_HOUSE_NEUTRAL].QualityInfo[i],
+ sAuctionBotConfig->GetConfigItemQualityAmount(AuctionQuality(i)));
+ }
+
+ if (!session)
+ handler->SendSysMessage(LANG_AHBOT_STATUS_BAR_CONSOLE);
+
+ return true;
+ }
+
+};
+
+template bool ahbot_commandscript::HandleAHBotItemsAmountQualityCommand<AUCTION_QUALITY_GRAY>(ChatHandler* handler, const char*);
+template bool ahbot_commandscript::HandleAHBotItemsAmountQualityCommand<AUCTION_QUALITY_WHITE>(ChatHandler* handler, const char*);
+template bool ahbot_commandscript::HandleAHBotItemsAmountQualityCommand<AUCTION_QUALITY_GREEN>(ChatHandler* handler, const char*);
+template bool ahbot_commandscript::HandleAHBotItemsAmountQualityCommand<AUCTION_QUALITY_BLUE>(ChatHandler* handler, const char*);
+template bool ahbot_commandscript::HandleAHBotItemsAmountQualityCommand<AUCTION_QUALITY_PURPLE>(ChatHandler* handler, const char*);
+template bool ahbot_commandscript::HandleAHBotItemsAmountQualityCommand<AUCTION_QUALITY_ORANGE>(ChatHandler* handler, const char*);
+template bool ahbot_commandscript::HandleAHBotItemsAmountQualityCommand<AUCTION_QUALITY_YELLOW>(ChatHandler* handler, const char*);
+
+template bool ahbot_commandscript::HandleAHBotItemsRatioHouseCommand<AUCTION_HOUSE_ALLIANCE>(ChatHandler* handler, const char*);
+template bool ahbot_commandscript::HandleAHBotItemsRatioHouseCommand<AUCTION_HOUSE_HORDE>(ChatHandler* handler, const char*);
+template bool ahbot_commandscript::HandleAHBotItemsRatioHouseCommand<AUCTION_HOUSE_NEUTRAL>(ChatHandler* handler, const char*);
+
+void AddSC_ahbot_commandscript()
+{
+ new ahbot_commandscript();
+}
diff --git a/src/server/scripts/Commands/cs_guild.cpp b/src/server/scripts/Commands/cs_guild.cpp
index 86213291367..0359cbbe379 100644
--- a/src/server/scripts/Commands/cs_guild.cpp
+++ b/src/server/scripts/Commands/cs_guild.cpp
@@ -44,6 +44,7 @@ public:
{ "uninvite", rbac::RBAC_PERM_COMMAND_GUILD_UNINVITE, true, &HandleGuildUninviteCommand, "", NULL },
{ "rank", rbac::RBAC_PERM_COMMAND_GUILD_RANK, true, &HandleGuildRankCommand, "", NULL },
{ "rename", rbac::RBAC_PERM_COMMAND_GUILD_RENAME, true, &HandleGuildRenameCommand, "", NULL },
+ { "info", rbac::RBAC_PERM_COMMAND_GUILD_INFO, true, &HandleGuildInfoCommand, "", NULL },
{ NULL, 0, false, NULL, "", NULL }
};
static ChatCommand commandTable[] =
@@ -243,6 +244,63 @@ public:
handler->PSendSysMessage(LANG_GUILD_RENAME_DONE, oldGuildStr, newGuildStr);
return true;
}
+
+ static bool HandleGuildInfoCommand(ChatHandler* handler, char const* args)
+ {
+ Player* target;
+ uint32 guildId;
+ std::string guildName;
+ std::string guildMasterName;
+ Guild* guild;
+
+ if (!*args)
+ {
+ // Look for the guild of the selected player or ourselves
+ if (target = handler->getSelectedPlayerOrSelf())
+ guild = target->GetGuild();
+ else
+ // getSelectedPlayerOrSelf will return null if there is no session
+ // so target becomes nullptr if the command is ran through console
+ // without specifying args.
+ return false;
+ }
+ else if (guildId = atoi(args)) // Try searching by Id
+ guild = sGuildMgr->GetGuildById(guildId);
+ else
+ {
+ // Try to extract a guild name
+ char* tailStr = *args != '"' ? strtok(NULL, "") : (char*)args;
+ if (!tailStr)
+ return false;
+
+ char* guildStr = handler->extractQuotedArg((char*)args);
+ if (!guildStr)
+ return false;
+
+ guildName = guildStr;
+ guild = sGuildMgr->GetGuildByName(guildName);
+ }
+
+ if (!guild)
+ return false;
+
+ // Display Guild Information
+ handler->PSendSysMessage(LANG_GUILD_INFO_NAME, guild->GetName().c_str(), guild->GetId()); // Guild Id + Name
+ if (sObjectMgr->GetPlayerNameByGUID(guild->GetLeaderGUID(), guildMasterName))
+ handler->PSendSysMessage(LANG_GUILD_INFO_GUILD_MASTER, guildMasterName.c_str(), guild->GetLeaderGUID()); // Guild Master
+
+ // Format creation date
+ char createdDateStr[20];
+ time_t createdDate = guild->GetCreatedDate();
+ strftime(createdDateStr, 20, "%Y-%m-%d %H:%M:%S", localtime(&createdDate));
+
+ handler->PSendSysMessage(LANG_GUILD_INFO_CREATION_DATE, createdDateStr); // Creation Date
+ handler->PSendSysMessage(LANG_GUILD_INFO_MEMBER_COUNT, guild->GetMemberCount()); // Number of Members
+ handler->PSendSysMessage(LANG_GUILD_INFO_BANK_GOLD, guild->GetBankMoney() / 100 / 100); // Bank Gold (in gold coins)
+ handler->PSendSysMessage(LANG_GUILD_INFO_MOTD, guild->GetMOTD().c_str()); // Message of the Day
+ handler->PSendSysMessage(LANG_GUILD_INFO_EXTRA_INFO, guild->GetInfo().c_str()); // Extra Information
+ return true;
+ }
};
void AddSC_guild_commandscript()
diff --git a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_hodir.cpp b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_hodir.cpp
index 7f4d585b0a4..a3d80beb546 100644
--- a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_hodir.cpp
+++ b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_hodir.cpp
@@ -324,6 +324,12 @@ class boss_hodir : public CreatureScript
void Reset() override
{
+ gettingColdInHereTimer = 0;
+ gettingColdInHere = false;
+ cheeseTheFreeze = false;
+ iHaveTheCoolestFriends = false;
+ iCouldSayThatThisCacheWasRare = false;
+
_Reset();
me->SetReactState(REACT_PASSIVE);
diff --git a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_mimiron.cpp b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_mimiron.cpp
index 69240866742..f1d44e72684 100644
--- a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_mimiron.cpp
+++ b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_mimiron.cpp
@@ -316,6 +316,17 @@ enum Phases
PHASE_AERIAL_ASSEMBLED
};
+enum Waypoints
+{
+ WP_MKII_P1_IDLE = 1,
+ WP_MKII_P4_POS_1,
+ WP_MKII_P4_POS_2,
+ WP_MKII_P4_POS_3,
+ WP_MKII_P4_POS_4,
+ WP_MKII_P4_POS_5,
+ WP_AERIAL_P4_POS
+};
+
uint32 const RepairSpells[4] =
{
SPELL_SEAT_1,
@@ -324,6 +335,1317 @@ uint32 const RepairSpells[4] =
SPELL_SEAT_5
};
+Position const VehicleRelocation[] =
+{
+ { 0.0f, 0.0f, 0.0f},
+ { 2792.070f, 2596.320f, 364.3136f }, // WP_MKII_P1_IDLE
+ { 2765.945f, 2571.095f, 364.0636f }, // WP_MKII_P4_POS_1
+ { 2768.195f, 2573.095f, 364.0636f }, // WP_MKII_P4_POS_2
+ { 2763.820f, 2568.870f, 364.3136f }, // WP_MKII_P4_POS_3
+ { 2761.215f, 2568.875f, 364.0636f }, // WP_MKII_P4_POS_4
+ { 2744.610f, 2569.380f, 364.3136f }, // WP_MKII_P4_POS_5
+ { 2748.513f, 2569.051f, 364.3136f } // WP_AERIAL_P4_POS
+};
+
+Position const VX001SummonPos = { 2744.431f, 2569.385f, 364.3968f, 3.141593f };
+Position const ACUSummonPos = { 2744.650f, 2569.460f, 380.0000f, 0.0f };
+
+static bool IsEncounterFinished(Unit* who)
+{
+ InstanceScript* instance = who->GetInstanceScript();
+
+ Creature* mkii = ObjectAccessor::GetCreature(*who, instance->GetData64(DATA_LEVIATHAN_MK_II));
+ Creature* vx001 = ObjectAccessor::GetCreature(*who, instance->GetData64(DATA_VX_001));
+ Creature* aerial = ObjectAccessor::GetCreature(*who, instance->GetData64(DATA_AERIAL_COMMAND_UNIT));
+ if (!mkii || !vx001 || !aerial)
+ return false;
+
+ if (mkii->getStandState() == UNIT_STAND_STATE_DEAD &&
+ vx001->getStandState() == UNIT_STAND_STATE_DEAD &&
+ aerial->getStandState() == UNIT_STAND_STATE_DEAD)
+ {
+ who->Kill(mkii);
+ who->Kill(vx001);
+ who->Kill(aerial);
+ mkii->DespawnOrUnsummon(120000);
+ vx001->DespawnOrUnsummon(120000);
+ aerial->DespawnOrUnsummon(120000);
+ if (Creature* mimiron = ObjectAccessor::GetCreature(*who, instance->GetData64(BOSS_MIMIRON)))
+ mimiron->AI()->JustDied(who);
+ return true;
+ }
+ return false;
+}
+
+class boss_mimiron : public CreatureScript
+{
+ public:
+ boss_mimiron() : CreatureScript("boss_mimiron") { }
+
+ struct boss_mimironAI : public BossAI
+ {
+ boss_mimironAI(Creature* creature) : BossAI(creature, BOSS_MIMIRON)
+ {
+ me->SetReactState(REACT_PASSIVE);
+ _fireFighter = false;
+ }
+
+ void DoAction(int32 action) override
+ {
+ switch (action)
+ {
+ case DO_ACTIVATE_VX001:
+ events.ScheduleEvent(EVENT_VX001_ACTIVATION_1, 1000);
+ break;
+ case DO_ACTIVATE_AERIAL:
+ events.ScheduleEvent(EVENT_AERIAL_ACTIVATION_1, 5000);
+ break;
+ case DO_ACTIVATE_V0L7R0N_1:
+ Talk(SAY_AERIAL_DEATH);
+ if (Creature* mkii = ObjectAccessor::GetCreature(*me, instance->GetData64(DATA_LEVIATHAN_MK_II)))
+ mkii->GetMotionMaster()->MovePoint(WP_MKII_P4_POS_1, VehicleRelocation[WP_MKII_P4_POS_1]);
+ break;
+ case DO_ACTIVATE_V0L7R0N_2:
+ events.ScheduleEvent(EVENT_VOL7RON_ACTIVATION_1, 1000);
+ break;
+ case DO_ACTIVATE_HARD_MODE:
+ _fireFighter = true;
+ DoZoneInCombat(me);
+ break;
+ default:
+ break;
+ }
+ }
+
+ void EnterCombat(Unit* /*who*/) override
+ {
+ if (!me->GetVehicleBase())
+ return;
+
+ _EnterCombat();
+ me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
+ me->RemoveAurasDueToSpell(SPELL_WELD);
+ DoCast(me->GetVehicleBase(), SPELL_SEAT_6);
+
+ if (GameObject* button = ObjectAccessor::GetGameObject(*me, instance->GetData64(DATA_MIMIRON_BUTTON)))
+ button->SetFlag(GAMEOBJECT_FLAGS, GO_FLAG_NOT_SELECTABLE);
+
+ if (_fireFighter)
+ events.ScheduleEvent(EVENT_SUMMON_FLAMES, 3000);
+ events.ScheduleEvent(EVENT_INTRO_1, 1500);
+ }
+
+ void JustDied(Unit* /*who*/) override
+ {
+ instance->SetBossState(BOSS_MIMIRON, DONE);
+ events.Reset();
+ me->CombatStop(true);
+ me->SetDisableGravity(false);
+ DoCast(me, SPELL_SLEEP_VISUAL_1);
+ DoCastAOE(SPELL_DESPAWN_ASSAULT_BOTS);
+ me->ExitVehicle();
+ // ExitVehicle() offset position is not implemented, so we make up for that with MoveJump()...
+ me->GetMotionMaster()->MoveJump(me->GetPositionX() + (10.f * std::cos(me->GetOrientation())), me->GetPositionY() + (10.f * std::sin(me->GetOrientation())), me->GetPositionZ(), 10.f, 5.f);
+ events.ScheduleEvent(EVENT_OUTTRO_1, 7000);
+ }
+
+ void Reset() override
+ {
+ if (instance->GetBossState(BOSS_MIMIRON) == DONE) // Mimiron will attempt to reset because he is not dead and will be set to friendly before despawning.
+ return;
+
+ _Reset();
+ me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
+ instance->SetData(DATA_MIMIRON_ELEVATOR, GO_STATE_ACTIVE);
+
+ if (_fireFighter)
+ if (Creature* computer = ObjectAccessor::GetCreature(*me, instance->GetData64(DATA_COMPUTER)))
+ computer->AI()->DoAction(DO_DEACTIVATE_COMPUTER);
+
+ if (GameObject* button = ObjectAccessor::GetGameObject(*me, instance->GetData64(DATA_MIMIRON_BUTTON)))
+ {
+ button->SetGoState(GO_STATE_READY);
+ button->RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_NOT_SELECTABLE);
+ }
+
+ _fireFighter = false;
+ DoCast(me, SPELL_WELD);
+
+ if (Unit* mkii = ObjectAccessor::GetUnit(*me, instance->GetData64(DATA_LEVIATHAN_MK_II)))
+ DoCast(mkii, SPELL_SEAT_3);
+ }
+
+ void UpdateAI(uint32 diff) override
+ {
+ if ((!UpdateVictim() || !CheckInRoom()) && instance->GetBossState(BOSS_MIMIRON) != DONE)
+ return;
+
+ events.Update(diff);
+
+ if (me->HasUnitState(UNIT_STATE_CASTING))
+ return;
+
+ while (uint32 eventId = events.ExecuteEvent())
+ {
+ switch (eventId)
+ {
+ case EVENT_SUMMON_FLAMES:
+ if (Unit* worldtrigger = ObjectAccessor::GetUnit(*me, instance->GetData64(DATA_MIMIRON_WORLD_TRIGGER)))
+ worldtrigger->CastCustomSpell(SPELL_SCRIPT_EFFECT_SUMMON_FLAMES_INITIAL, SPELLVALUE_MAX_TARGETS, 3, NULL, true, NULL, NULL, me->GetGUID());
+ events.RescheduleEvent(EVENT_SUMMON_FLAMES, 28000);
+ break;
+ case EVENT_INTRO_1:
+ Talk(_fireFighter ? SAY_HARDMODE_ON : SAY_MKII_ACTIVATE);
+ events.ScheduleEvent(EVENT_INTRO_2, 5000);
+ break;
+ case EVENT_INTRO_2:
+ if (Unit* mkii = me->GetVehicleBase())
+ {
+ DoCast(mkii, SPELL_SEAT_7);
+ mkii->RemoveAurasDueToSpell(SPELL_FREEZE_ANIM);
+ mkii->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_NOT_SELECTABLE);
+ }
+ events.ScheduleEvent(EVENT_INTRO_3, 2000);
+ break;
+ case EVENT_INTRO_3:
+ if (Creature* mkii = me->GetVehicleCreatureBase())
+ mkii->AI()->DoAction(_fireFighter ? DO_HARDMODE_MKII : DO_START_MKII);
+ break;
+ case EVENT_VX001_ACTIVATION_1:
+ if (Unit* mkii = me->GetVehicleBase())
+ mkii->SetFacingTo(3.686f); // fix magic number
+ events.ScheduleEvent(EVENT_VX001_ACTIVATION_2, 1000);
+ break;
+ case EVENT_VX001_ACTIVATION_2:
+ if (Unit* mkii = me->GetVehicleBase())
+ DoCast(mkii, SPELL_SEAT_6);
+ events.ScheduleEvent(EVENT_VX001_ACTIVATION_3, 1000);
+ break;
+ case EVENT_VX001_ACTIVATION_3:
+ Talk(SAY_MKII_DEATH);
+ events.ScheduleEvent(EVENT_VX001_ACTIVATION_4, 5000);
+ break;
+ case EVENT_VX001_ACTIVATION_4:
+ instance->SetData(DATA_MIMIRON_ELEVATOR, GO_STATE_READY);
+ if (Unit* worldtrigger = ObjectAccessor::GetUnit(*me, instance->GetData64(DATA_MIMIRON_WORLD_TRIGGER)))
+ worldtrigger->CastSpell(worldtrigger, SPELL_ELEVATOR_KNOCKBACK);
+ events.ScheduleEvent(EVENT_VX001_ACTIVATION_5, 6000);
+ break;
+ case EVENT_VX001_ACTIVATION_5:
+ if (Creature* vx001 = me->SummonCreature(NPC_VX_001, VX001SummonPos, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 120000))
+ vx001->CastSpell(vx001, SPELL_FREEZE_ANIM);
+ instance->SetData(DATA_MIMIRON_ELEVATOR, GO_STATE_ACTIVE_ALTERNATIVE);
+ events.ScheduleEvent(EVENT_VX001_ACTIVATION_6, 19000);
+ break;
+ case EVENT_VX001_ACTIVATION_6:
+ if (Unit* vx001 = ObjectAccessor::GetUnit(*me, instance->GetData64(DATA_VX_001)))
+ DoCast(vx001, SPELL_SEAT_1);
+ events.ScheduleEvent(EVENT_VX001_ACTIVATION_7, 3500);
+ break;
+ case EVENT_VX001_ACTIVATION_7:
+ Talk(SAY_VX001_ACTIVATE);
+ events.ScheduleEvent(EVENT_VX001_ACTIVATION_8, 4000);
+ break;
+ case EVENT_VX001_ACTIVATION_8:
+ if (Unit* vx001 = me->GetVehicleBase())
+ DoCast(vx001, SPELL_SEAT_2);
+ events.ScheduleEvent(EVENT_VX001_ACTIVATION_9, 3000);
+ break;
+ case EVENT_VX001_ACTIVATION_9:
+ if (Creature* vx001 = me->GetVehicleCreatureBase())
+ vx001->AI()->DoAction(_fireFighter ? DO_HARDMODE_VX001 : DO_START_VX001);
+ break;
+ case EVENT_AERIAL_ACTIVATION_1:
+ if (Unit* mkii = me->GetVehicleBase())
+ DoCast(mkii, SPELL_SEAT_5);
+ events.ScheduleEvent(EVENT_AERIAL_ACTIVATION_2, 2500);
+ break;
+ case EVENT_AERIAL_ACTIVATION_2:
+ Talk(SAY_VX001_DEATH);
+ events.ScheduleEvent(EVENT_AERIAL_ACTIVATION_3, 5000);
+ break;
+ case EVENT_AERIAL_ACTIVATION_3:
+ me->SummonCreature(NPC_AERIAL_COMMAND_UNIT, ACUSummonPos, TEMPSUMMON_MANUAL_DESPAWN);
+ events.ScheduleEvent(EVENT_AERIAL_ACTIVATION_4, 5000);
+ break;
+ case EVENT_AERIAL_ACTIVATION_4:
+ if (Unit* aerial = ObjectAccessor::GetUnit(*me, instance->GetData64(DATA_AERIAL_COMMAND_UNIT)))
+ me->CastSpell(aerial, SPELL_SEAT_1);
+ events.ScheduleEvent(EVENT_AERIAL_ACTIVATION_5, 2000);
+ break;
+ case EVENT_AERIAL_ACTIVATION_5:
+ Talk(SAY_AERIAL_ACTIVATE);
+ events.ScheduleEvent(EVENT_AERIAL_ACTIVATION_6, 8000);
+ break;
+ case EVENT_AERIAL_ACTIVATION_6:
+ if (Creature* acu = me->GetVehicleCreatureBase())
+ acu->GetAI()->DoAction(_fireFighter? DO_HARDMODE_AERIAL : DO_START_AERIAL);
+ break;
+ case EVENT_VOL7RON_ACTIVATION_1:
+ if (Creature* mkii = ObjectAccessor::GetCreature(*me, instance->GetData64(DATA_LEVIATHAN_MK_II)))
+ mkii->SetFacingTo(float(M_PI));
+ events.ScheduleEvent(EVENT_VOL7RON_ACTIVATION_2, 1000);
+ break;
+ case EVENT_VOL7RON_ACTIVATION_2:
+ if (Creature* mkii = ObjectAccessor::GetCreature(*me, instance->GetData64(DATA_LEVIATHAN_MK_II)))
+ {
+ if (Creature* vx001 = ObjectAccessor::GetCreature(*me, instance->GetData64(DATA_VX_001)))
+ {
+ vx001->RemoveAurasDueToSpell(SPELL_TORSO_DISABLED);
+ vx001->CastSpell(mkii, SPELL_MOUNT_MKII);
+ }
+ }
+ events.ScheduleEvent(EVENT_VOL7RON_ACTIVATION_3, 4500);
+ break;
+ case EVENT_VOL7RON_ACTIVATION_3:
+ if (Creature* mkii = ObjectAccessor::GetCreature(*me, instance->GetData64(DATA_LEVIATHAN_MK_II)))
+ mkii->GetMotionMaster()->MovePoint(WP_MKII_P4_POS_4, VehicleRelocation[WP_MKII_P4_POS_4]);
+ events.ScheduleEvent(EVENT_VOL7RON_ACTIVATION_4, 5000);
+ break;
+ case EVENT_VOL7RON_ACTIVATION_4:
+ if (Creature* vx001 = ObjectAccessor::GetCreature(*me, instance->GetData64(DATA_VX_001)))
+ {
+ if (Creature* aerial = ObjectAccessor::GetCreature(*me, instance->GetData64(DATA_AERIAL_COMMAND_UNIT)))
+ {
+ aerial->GetMotionMaster()->MoveLand(0, (aerial->GetPositionX(), aerial->GetPositionY(), aerial->GetPositionZMinusOffset()));
+ aerial->SetUInt32Value(UNIT_FIELD_BYTES_1, 0);
+ aerial->CastSpell(vx001, SPELL_MOUNT_VX_001);
+ aerial->CastSpell(aerial, SPELL_HALF_HEAL);
+ }
+ }
+ events.ScheduleEvent(EVENT_VOL7RON_ACTIVATION_5, 4000);
+ break;
+ case EVENT_VOL7RON_ACTIVATION_5:
+ Talk(SAY_V07TRON_ACTIVATE);
+ events.ScheduleEvent(EVENT_VOL7RON_ACTIVATION_6, 3000);
+ break;
+ case EVENT_VOL7RON_ACTIVATION_6:
+ if (Creature* vx001 = ObjectAccessor::GetCreature(*me, instance->GetData64(DATA_VX_001)))
+ DoCast(vx001, SPELL_SEAT_2);
+ events.ScheduleEvent(EVENT_VOL7RON_ACTIVATION_7, 5000);
+ break;
+ case EVENT_VOL7RON_ACTIVATION_7:
+ for (uint8 data = DATA_LEVIATHAN_MK_II; data <= DATA_AERIAL_COMMAND_UNIT; ++data)
+ if (Creature* mimironVehicle = ObjectAccessor::GetCreature(*me, instance->GetData64(data)))
+ mimironVehicle->AI()->DoAction(DO_ASSEMBLED_COMBAT);
+ break;
+ case EVENT_OUTTRO_1:
+ me->RemoveAurasDueToSpell(SPELL_SLEEP_VISUAL_1);
+ DoCast(me, SPELL_SLEEP_VISUAL_2);
+ me->setFaction(35);
+ events.ScheduleEvent(EVENT_OUTTRO_2, 3000);
+ break;
+ case EVENT_OUTTRO_2:
+ Talk(SAY_V07TRON_DEATH);
+ if (_fireFighter)
+ {
+ if (Creature* computer = ObjectAccessor::GetCreature(*me, instance->GetData64(DATA_COMPUTER)))
+ computer->AI()->DoAction(DO_DEACTIVATE_COMPUTER);
+ me->SummonGameObject(RAID_MODE(GO_CACHE_OF_INNOVATION_FIREFIGHTER, GO_CACHE_OF_INNOVATION_FIREFIGHTER_HERO), 2744.040f, 2569.352f, 364.3135f, 3.124123f, 0.f, 0.f, 0.9999619f, 0.008734641f, 604800);
+ }
+ else
+ me->SummonGameObject(RAID_MODE(GO_CACHE_OF_INNOVATION, GO_CACHE_OF_INNOVATION_HERO), 2744.040f, 2569.352f, 364.3135f, 3.124123f, 0.f, 0.f, 0.9999619f, 0.008734641f, 604800);
+ events.ScheduleEvent(EVENT_OUTTRO_3, 11000);
+ break;
+ case EVENT_OUTTRO_3:
+ DoCast(me, SPELL_TELEPORT_VISUAL);
+ me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
+ me->DespawnOrUnsummon(1000); // sniffs say 6 sec after, but it doesnt matter.
+ break;
+ default:
+ break;
+ }
+ }
+ }
+
+ private:
+ bool _fireFighter;
+ };
+
+ CreatureAI* GetAI(Creature* creature) const override
+ {
+ return GetUlduarAI<boss_mimironAI>(creature);
+ }
+};
+
+class boss_leviathan_mk_ii : public CreatureScript
+{
+ public:
+ boss_leviathan_mk_ii() : CreatureScript("boss_leviathan_mk_ii") { }
+
+ struct boss_leviathan_mk_iiAI : public BossAI
+ {
+ boss_leviathan_mk_iiAI(Creature* creature) : BossAI(creature, BOSS_MIMIRON)
+ {
+ _fireFighter = false;
+ _setupMine = true;
+ _setupBomb = true;
+ _setupRocket = true;
+ }
+
+ void DamageTaken(Unit* who, uint32 &damage) override
+ {
+ if (damage >= me->GetHealth())
+ {
+ damage = me->GetHealth() - 1; // Let creature fall to 1 hp, but do not let it die or damage itself with SetHealth().
+ me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
+ DoCast(me, SPELL_VEHICLE_DAMAGED, true);
+ me->AttackStop();
+ me->SetReactState(REACT_PASSIVE);
+ me->RemoveAllAurasExceptType(SPELL_AURA_CONTROL_VEHICLE, SPELL_AURA_MOD_INCREASE_HEALTH_PERCENT);
+
+ if (events.IsInPhase(PHASE_LEVIATHAN_SOLO))
+ {
+ me->CastStop();
+ if (Unit* turret = me->GetVehicleKit()->GetPassenger(3))
+ turret->Kill(turret);
+
+ me->SetSpeed(MOVE_RUN, 1.5f, true);
+ me->GetMotionMaster()->MovePoint(WP_MKII_P1_IDLE, VehicleRelocation[WP_MKII_P1_IDLE]);
+ }
+ else if (events.IsInPhase(PHASE_LEVIATHAN_ASSEMBLED))
+ {
+ me->SetStandState(UNIT_STAND_STATE_DEAD);
+
+ if (IsEncounterFinished(who))
+ return;
+
+ me->CastStop();
+ DoCast(me, SPELL_SELF_REPAIR);
+ }
+ events.Reset();
+ }
+ }
+
+ void DoAction(int32 action) override
+ {
+ switch (action)
+ {
+ case DO_HARDMODE_MKII:
+ _fireFighter = true;
+ DoCast(me, SPELL_EMERGENCY_MODE);
+ DoCastAOE(SPELL_EMERGENCY_MODE_TURRET);
+ events.ScheduleEvent(EVENT_FLAME_SUPPRESSANT_MK, 60000, 0, PHASE_LEVIATHAN_SOLO);
+ // Missing break intended.
+ case DO_START_MKII:
+ me->SetReactState(REACT_AGGRESSIVE);
+ events.SetPhase(PHASE_LEVIATHAN_SOLO);
+
+ events.ScheduleEvent(EVENT_NAPALM_SHELL, 3000, 0, PHASE_LEVIATHAN_SOLO);
+ events.ScheduleEvent(EVENT_PLASMA_BLAST, 15000, 0, PHASE_LEVIATHAN_SOLO);
+ events.ScheduleEvent(EVENT_PROXIMITY_MINE, 5000);
+ events.ScheduleEvent(EVENT_SHOCK_BLAST, 18000);
+ break;
+ case DO_ASSEMBLED_COMBAT:
+ me->SetStandState(UNIT_STAND_STATE_STAND);
+ me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_NOT_SELECTABLE);
+ me->SetReactState(REACT_AGGRESSIVE);
+
+ events.SetPhase(PHASE_LEVIATHAN_ASSEMBLED);
+ events.ScheduleEvent(EVENT_PROXIMITY_MINE, 15000);
+ events.ScheduleEvent(EVENT_SHOCK_BLAST, 45000);
+ break;
+ default:
+ break;
+ }
+ }
+
+ uint32 GetData(uint32 type) const override
+ {
+ switch (type)
+ {
+ case DATA_SETUP_MINE:
+ return _setupMine;
+ case DATA_SETUP_BOMB:
+ return _setupBomb;
+ case DATA_SETUP_ROCKET:
+ return _setupRocket;
+ case DATA_FIREFIGHTER:
+ return _fireFighter;
+ default:
+ return 0;
+ }
+ }
+
+ void JustSummoned(Creature* summon) override
+ {
+ summons.Summon(summon);
+ }
+
+ void KilledUnit(Unit* victim) override
+ {
+ if (victim->GetTypeId() == TYPEID_PLAYER)
+ if (Creature* mimiron = ObjectAccessor::GetCreature(*me, instance->GetData64(BOSS_MIMIRON)))
+ mimiron->AI()->Talk(events.IsInPhase(PHASE_LEVIATHAN_SOLO) ? SAY_MKII_SLAY : SAY_V07TRON_SLAY);
+ }
+
+ void MovementInform(uint32 type, uint32 point) override
+ {
+ if (type != POINT_MOTION_TYPE)
+ return;
+
+ switch (point)
+ {
+ case WP_MKII_P1_IDLE:
+ me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
+ DoCast(me, SPELL_HALF_HEAL);
+
+ if (Creature* mimiron = ObjectAccessor::GetCreature(*me, instance->GetData64(BOSS_MIMIRON)))
+ mimiron->AI()->DoAction(DO_ACTIVATE_VX001);
+ break;
+ case WP_MKII_P4_POS_1:
+ events.ScheduleEvent(EVENT_MOVE_POINT_2, 1);
+ break;
+ case WP_MKII_P4_POS_2:
+ events.ScheduleEvent(EVENT_MOVE_POINT_3, 1);
+ break;
+ case WP_MKII_P4_POS_3:
+ if (Creature* mimiron = ObjectAccessor::GetCreature(*me, instance->GetData64(BOSS_MIMIRON)))
+ mimiron->AI()->DoAction(DO_ACTIVATE_V0L7R0N_2);
+ break;
+ case WP_MKII_P4_POS_4:
+ events.ScheduleEvent(EVENT_MOVE_POINT_5, 1);
+ break;
+ default:
+ break;
+ }
+ }
+
+ void Reset() override
+ {
+ _Reset();
+ me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_NOT_SELECTABLE);
+ me->SetReactState(REACT_PASSIVE);
+ _fireFighter = false;
+ _setupMine = true;
+ _setupBomb = true;
+ _setupRocket = true;
+ DoCast(me, SPELL_FREEZE_ANIM);
+ }
+
+ void SetData(uint32 id, uint32 data) override
+ {
+ switch (id)
+ {
+ case DATA_SETUP_MINE:
+ _setupMine = data != 0;
+ break;
+ case DATA_SETUP_BOMB:
+ _setupBomb = data != 0;
+ break;
+ case DATA_SETUP_ROCKET:
+ _setupRocket = data != 0;
+ break;
+ default:
+ break;
+ }
+ }
+
+ void UpdateAI(uint32 diff) override
+ {
+ if (!UpdateVictim() || !CheckInRoom())
+ return;
+
+ events.Update(diff);
+
+ if (me->HasUnitState(UNIT_STATE_CASTING))
+ return;
+
+ while (uint32 eventId = events.ExecuteEvent())
+ {
+ switch (eventId)
+ {
+ case EVENT_PROXIMITY_MINE:
+ DoCastAOE(SPELL_PROXIMITY_MINES);
+ events.RescheduleEvent(EVENT_PROXIMITY_MINE, 35000);
+ break;
+ case EVENT_PLASMA_BLAST:
+ DoCastVictim(SPELL_SCRIPT_EFFECT_PLASMA_BLAST);
+ events.RescheduleEvent(EVENT_PLASMA_BLAST, urand(30000, 45000), 0, PHASE_LEVIATHAN_SOLO);
+
+ if (events.GetTimeUntilEvent(EVENT_NAPALM_SHELL) < 9000)
+ events.RescheduleEvent(EVENT_NAPALM_SHELL, 9000, 0, PHASE_LEVIATHAN_SOLO); // The actual spell is cast by the turret, we should not let it interrupt itself.
+ break;
+ case EVENT_SHOCK_BLAST:
+ DoCastAOE(SPELL_SHOCK_BLAST);
+ events.RescheduleEvent(EVENT_SHOCK_BLAST, urand(34000, 36000));
+ break;
+ case EVENT_FLAME_SUPPRESSANT_MK:
+ DoCastAOE(SPELL_FLAME_SUPPRESSANT_MK);
+ events.RescheduleEvent(EVENT_FLAME_SUPPRESSANT_MK, 60000, 0, PHASE_LEVIATHAN_SOLO);
+ break;
+ case EVENT_NAPALM_SHELL:
+ DoCastAOE(SPELL_FORCE_CAST_NAPALM_SHELL);
+ events.RescheduleEvent(EVENT_NAPALM_SHELL, urand(6000, 15000), 0, PHASE_LEVIATHAN_SOLO);
+
+ if (events.GetTimeUntilEvent(EVENT_PLASMA_BLAST) < 2000)
+ events.RescheduleEvent(EVENT_PLASMA_BLAST, 2000, 0, PHASE_LEVIATHAN_SOLO); // The actual spell is cast by the turret, we should not let it interrupt itself.
+ break;
+ case EVENT_MOVE_POINT_2:
+ me->GetMotionMaster()->MovePoint(WP_MKII_P4_POS_2, VehicleRelocation[WP_MKII_P4_POS_2]);
+ break;
+ case EVENT_MOVE_POINT_3:
+ me->GetMotionMaster()->MovePoint(WP_MKII_P4_POS_3, VehicleRelocation[WP_MKII_P4_POS_3]);
+ break;
+ case EVENT_MOVE_POINT_5:
+ me->GetMotionMaster()->MovePoint(WP_MKII_P4_POS_5, VehicleRelocation[WP_MKII_P4_POS_5]);
+ break;
+ default:
+ break;
+ }
+ }
+ DoMeleeAttackIfReady();
+ }
+
+ private:
+ bool _fireFighter;
+ bool _setupMine;
+ bool _setupBomb;
+ bool _setupRocket;
+ };
+
+ CreatureAI* GetAI(Creature* creature) const override
+ {
+ return GetUlduarAI<boss_leviathan_mk_iiAI>(creature);
+ }
+};
+
+class boss_vx_001 : public CreatureScript
+{
+ public:
+ boss_vx_001() : CreatureScript("boss_vx_001") { }
+
+ struct boss_vx_001AI : public BossAI
+ {
+ boss_vx_001AI(Creature* creature) : BossAI(creature, BOSS_MIMIRON)
+ {
+ me->SetDisableGravity(true); // This is the unfold visual state of VX-001, it has to be set on create as it requires an objectupdate if set later.
+ me->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_STATE_SPECIAL_UNARMED); // This is a hack to force the yet to be unfolded visual state.
+ me->SetReactState(REACT_PASSIVE);
+ _fireFighter = false;
+ }
+
+ void DamageTaken(Unit* who, uint32 &damage) override
+ {
+ if (damage >= me->GetHealth())
+ {
+ damage = me->GetHealth() - 1; // Let creature fall to 1 hp, but do not let it die or damage itself with SetHealth().
+ me->AttackStop();
+ DoCast(me, SPELL_VEHICLE_DAMAGED, true);
+ me->RemoveAllAurasExceptType(SPELL_AURA_CONTROL_VEHICLE, SPELL_AURA_MOD_INCREASE_HEALTH_PERCENT);
+
+ if (events.IsInPhase(PHASE_VX001_SOLO))
+ {
+ me->CastStop();
+ me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); // | UNIT_FLAG_NOT_SELECTABLE);
+ DoCast(me, SPELL_HALF_HEAL); // has no effect, wat
+ DoCast(me, SPELL_TORSO_DISABLED);
+ if (Creature* mimiron = ObjectAccessor::GetCreature(*me, instance->GetData64(BOSS_MIMIRON)))
+ mimiron->AI()->DoAction(DO_ACTIVATE_AERIAL);
+ }
+ else if (events.IsInPhase(PHASE_VX001_ASSEMBLED))
+ {
+ me->SetStandState(UNIT_STAND_STATE_DEAD);
+ me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
+
+ if (IsEncounterFinished(who))
+ return;
+
+ me->CastStop();
+ DoCast(me, SPELL_SELF_REPAIR);
+ }
+ events.Reset();
+ }
+ }
+
+ void DoAction(int32 action) override
+ {
+ switch (action)
+ {
+ case DO_HARDMODE_VX001:
+ _fireFighter = true;
+ DoCast(me, SPELL_EMERGENCY_MODE);
+ events.ScheduleEvent(EVENT_FROST_BOMB, 1000);
+ events.ScheduleEvent(EVENT_FLAME_SUPPRESSANT_VX, 6000);
+ // Missing break intended.
+ case DO_START_VX001:
+ me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_NOT_SELECTABLE);
+ me->RemoveAurasDueToSpell(SPELL_FREEZE_ANIM);
+ me->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_ONESHOT_NONE); // Remove emotestate.
+ //me->SetUInt32Value(UNIT_FIELD_BYTES_1, 33554432); Blizzard handles hover animation like this it seems.
+ DoCast(me, SPELL_HEAT_WAVE_AURA);
+
+ events.SetPhase(PHASE_VX001_SOLO);
+ events.ScheduleEvent(EVENT_ROCKET_STRIKE, 20000);
+ events.ScheduleEvent(EVENT_SPINNING_UP, urand(30000, 35000));
+ events.ScheduleEvent(EVENT_RAPID_BURST, 500, 0, PHASE_VX001_SOLO);
+ break;
+ case DO_ASSEMBLED_COMBAT:
+ me->SetStandState(UNIT_STAND_STATE_STAND);
+ me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_NOT_SELECTABLE);
+
+ events.SetPhase(PHASE_VX001_ASSEMBLED);
+ events.ScheduleEvent(EVENT_ROCKET_STRIKE, 20000);
+ events.ScheduleEvent(EVENT_SPINNING_UP, urand(30000, 35000));
+ events.ScheduleEvent(EVENT_HAND_PULSE, 500, 0, PHASE_VX001_ASSEMBLED);
+ if (_fireFighter)
+ events.ScheduleEvent(EVENT_FROST_BOMB, 1000);
+ break;
+ default:
+ break;
+ }
+ }
+
+ void EnterEvadeMode() override
+ {
+ summons.DespawnAll();
+ }
+
+ void JustSummoned(Creature* summon) override
+ {
+ summons.Summon(summon);
+ if (summon->GetEntry() == NPC_BURST_TARGET)
+ summon->CastSpell(me, SPELL_RAPID_BURST_TARGET_ME);
+ }
+
+ void KilledUnit(Unit* victim) override
+ {
+ if (victim->GetTypeId() == TYPEID_PLAYER)
+ if (Creature* mimiron = ObjectAccessor::GetCreature(*me, instance->GetData64(BOSS_MIMIRON)))
+ mimiron->AI()->Talk(events.IsInPhase(PHASE_VX001_SOLO) ? SAY_VX001_SLAY : SAY_V07TRON_SLAY);
+ }
+
+ void SpellHit(Unit* caster, SpellInfo const* /*spellProto*/) override
+ {
+ if (caster->GetEntry() == NPC_BURST_TARGET && !me->HasUnitState(UNIT_STATE_CASTING))
+ DoCast(caster, SPELL_RAPID_BURST);
+ }
+
+ void UpdateAI(uint32 diff) override
+ {
+ if (!UpdateVictim())
+ return;
+
+ events.Update(diff);
+
+ // Handle rotation during SPELL_SPINNING_UP, SPELL_P3WX2_LASER_BARRAGE, SPELL_RAPID_BURST, and SPELL_HAND_PULSE_LEFT/RIGHT
+ if (me->HasUnitState(UNIT_STATE_CASTING))
+ {
+ if (Creature* channelTarget = ObjectAccessor::GetCreature(*me, me->GetUInt64Value(UNIT_FIELD_CHANNEL_OBJECT)))
+ me->SetFacingToObject(channelTarget);
+ return;
+ }
+
+ while (uint32 eventId = events.ExecuteEvent())
+ {
+ switch (eventId)
+ {
+ case EVENT_RAPID_BURST:
+ if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 120, true))
+ DoCast(target, SPELL_SUMMON_BURST_TARGET);
+ events.RescheduleEvent(EVENT_RAPID_BURST, 3000, 0, PHASE_VX001_SOLO);
+ break;
+ case EVENT_ROCKET_STRIKE:
+ DoCastAOE(events.IsInPhase(PHASE_VX001_SOLO) ? SPELL_ROCKET_STRIKE_LEFT : SPELL_ROCKET_STRIKE_BOTH);
+ events.ScheduleEvent(EVENT_RELOAD, 10000);
+ events.RescheduleEvent(EVENT_ROCKET_STRIKE, urand(20000, 25000));
+ break;
+ case EVENT_RELOAD:
+ for (uint8 seat = 6; seat <= 7; seat++)
+ if (Unit* rocket = me->GetVehicleKit()->GetPassenger(seat))
+ rocket->SetDisplayId(rocket->GetNativeDisplayId());
+ break;
+ case EVENT_HAND_PULSE:
+ if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 120, true))
+ DoCast(target, urand(0, 1) == 0 ? SPELL_HAND_PULSE_LEFT : SPELL_HAND_PULSE_RIGHT);
+ events.RescheduleEvent(EVENT_HAND_PULSE, urand(1500, 3000), 0, PHASE_VX001_ASSEMBLED);
+ break;
+ case EVENT_FROST_BOMB:
+ DoCastAOE(SPELL_SCRIPT_EFFECT_FROST_BOMB);
+ events.RescheduleEvent(EVENT_FROST_BOMB, 45000);
+ break;
+ case EVENT_SPINNING_UP:
+ DoCastAOE(SPELL_SPINNING_UP);
+ events.DelayEvents(14000);
+ events.RescheduleEvent(EVENT_SPINNING_UP, urand(55000, 65000));
+ break;
+ case EVENT_FLAME_SUPPRESSANT_VX:
+ DoCastAOE(SPELL_FLAME_SUPPRESSANT_VX);
+ events.RescheduleEvent(EVENT_FLAME_SUPPRESSANT_VX, urand(10000, 12000), 0, PHASE_VX001_SOLO);
+ break;
+ default:
+ break;
+ }
+ }
+ }
+
+ private:
+ bool _fireFighter;
+ };
+
+ CreatureAI* GetAI(Creature* creature) const override
+ {
+ return GetUlduarAI<boss_vx_001AI>(creature);
+ }
+};
+
+class boss_aerial_command_unit : public CreatureScript
+{
+ public:
+ boss_aerial_command_unit() : CreatureScript("boss_aerial_command_unit") { }
+
+ struct boss_aerial_command_unitAI : public BossAI
+ {
+ boss_aerial_command_unitAI(Creature* creature) : BossAI(creature, BOSS_MIMIRON)
+ {
+ me->SetReactState(REACT_PASSIVE);
+ fireFigther = false;
+ }
+
+ void DamageTaken(Unit* who, uint32 &damage) override
+ {
+ if (damage >= me->GetHealth())
+ {
+ damage = me->GetHealth() - 1; // Let creature fall to 1 hp, but do not let it die or damage itself with SetHealth().
+ me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
+ me->AttackStop();
+ me->SetReactState(REACT_PASSIVE);
+ DoCast(me, SPELL_VEHICLE_DAMAGED, true);
+ me->RemoveAllAurasExceptType(SPELL_AURA_CONTROL_VEHICLE, SPELL_AURA_MOD_INCREASE_HEALTH_PERCENT);
+
+ if (events.IsInPhase(PHASE_AERIAL_SOLO))
+ {
+ me->GetMotionMaster()->Clear(true);
+ me->GetMotionMaster()->MovePoint(WP_AERIAL_P4_POS, VehicleRelocation[WP_AERIAL_P4_POS]);
+ }
+ else if (events.IsInPhase(PHASE_AERIAL_ASSEMBLED))
+ {
+ me->SetStandState(UNIT_STAND_STATE_DEAD);
+
+ if (IsEncounterFinished(who))
+ return;
+
+ me->CastStop();
+ DoCast(me, SPELL_SELF_REPAIR);
+ }
+ events.Reset();
+ }
+ }
+
+ void DoAction(int32 action) override
+ {
+ switch (action)
+ {
+ case DO_HARDMODE_AERIAL:
+ fireFigther = true;
+ DoCast(me, SPELL_EMERGENCY_MODE);
+ events.ScheduleEvent(EVENT_SUMMON_FIRE_BOTS, 1000, 0, PHASE_AERIAL_SOLO);
+ // Missing break intended.
+ case DO_START_AERIAL:
+ me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_NOT_SELECTABLE);
+ me->SetReactState(REACT_AGGRESSIVE);
+
+ events.SetPhase(PHASE_AERIAL_SOLO);
+ events.ScheduleEvent(EVENT_SUMMON_JUNK_BOT, 5000, 0, PHASE_AERIAL_SOLO);
+ events.ScheduleEvent(EVENT_SUMMON_ASSAULT_BOT, 9000, 0, PHASE_AERIAL_SOLO);
+ events.ScheduleEvent(EVENT_SUMMON_BOMB_BOT, 9000, 0, PHASE_AERIAL_SOLO);
+ break;
+ case DO_DISABLE_AERIAL:
+ me->CastStop();
+ me->AttackStop();
+ me->SetReactState(REACT_PASSIVE);
+ me->GetMotionMaster()->MoveFall();
+ events.DelayEvents(23000);
+ break;
+ case DO_ENABLE_AERIAL:
+ me->SetReactState(REACT_AGGRESSIVE);
+ break;
+ case DO_ASSEMBLED_COMBAT:
+ me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_NOT_SELECTABLE);
+ me->SetReactState(REACT_AGGRESSIVE);
+ me->SetStandState(UNIT_STAND_STATE_STAND);
+ events.SetPhase(PHASE_AERIAL_ASSEMBLED);
+ break;
+ default:
+ break;
+ }
+ }
+
+ void EnterEvadeMode() override
+ {
+ summons.DespawnAll();
+ }
+
+ void JustSummoned(Creature* summon) override
+ {
+ if (fireFigther && (summon->GetEntry() == NPC_ASSAULT_BOT || summon->GetEntry() == NPC_JUNK_BOT))
+ summon->CastSpell(summon, SPELL_EMERGENCY_MODE);
+ BossAI::JustSummoned(summon);
+ }
+
+ void KilledUnit(Unit* victim) override
+ {
+ if (victim->GetTypeId() == TYPEID_PLAYER)
+ if (Creature* mimiron = ObjectAccessor::GetCreature(*me, instance->GetData64(BOSS_MIMIRON)))
+ mimiron->AI()->Talk(events.IsInPhase(PHASE_AERIAL_SOLO) ? SAY_AERIAL_SLAY : SAY_V07TRON_SLAY);
+ }
+
+ void MovementInform(uint32 type, uint32 point) override
+ {
+ if (type == POINT_MOTION_TYPE && point == WP_AERIAL_P4_POS)
+ {
+ me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
+
+ if (Creature* mimiron = ObjectAccessor::GetCreature(*me, instance->GetData64(BOSS_MIMIRON)))
+ mimiron->AI()->DoAction(DO_ACTIVATE_V0L7R0N_1);
+ }
+ }
+
+ void UpdateAI(uint32 diff) override
+ {
+ if (!UpdateVictim())
+ return;
+
+ events.Update(diff);
+
+ if (me->HasUnitState(UNIT_STATE_CASTING))
+ return;
+
+ while (uint32 eventId = events.ExecuteEvent())
+ {
+ switch (eventId)
+ {
+ case EVENT_SUMMON_FIRE_BOTS:
+ me->CastCustomSpell(SPELL_SUMMON_FIRE_BOT_TRIGGER, SPELLVALUE_MAX_TARGETS, 3, NULL, true);
+ events.RescheduleEvent(EVENT_SUMMON_FIRE_BOTS, 45000, 0, PHASE_AERIAL_SOLO);
+ break;
+ case EVENT_SUMMON_JUNK_BOT:
+ me->CastCustomSpell(SPELL_SUMMON_JUNK_BOT_TRIGGER, SPELLVALUE_MAX_TARGETS, 1, NULL, true);
+ events.RescheduleEvent(EVENT_SUMMON_JUNK_BOT, urand(11000, 12000), 0, PHASE_AERIAL_SOLO);
+ break;
+ case EVENT_SUMMON_ASSAULT_BOT:
+ me->CastCustomSpell(SPELL_SUMMON_ASSAULT_BOT_TRIGGER, SPELLVALUE_MAX_TARGETS, 1, NULL, true);
+ events.RescheduleEvent(EVENT_SUMMON_ASSAULT_BOT, 30000, 0, PHASE_AERIAL_SOLO);
+ break;
+ case EVENT_SUMMON_BOMB_BOT:
+ DoCast(me, SPELL_SUMMON_BOMB_BOT);
+ events.RescheduleEvent(EVENT_SUMMON_BOMB_BOT, urand(15000, 20000), 0, PHASE_AERIAL_SOLO);
+ break;
+ default:
+ break;
+ }
+ }
+ DoSpellAttackIfReady(events.IsInPhase(PHASE_AERIAL_SOLO) ? SPELL_PLASMA_BALL_P1 : SPELL_PLASMA_BALL_P2);
+ }
+
+ private:
+ bool fireFigther;
+ };
+
+ CreatureAI* GetAI(Creature* creature) const override
+ {
+ return GetUlduarAI<boss_aerial_command_unitAI>(creature);
+ }
+};
+
+class npc_mimiron_assault_bot : public CreatureScript
+{
+ public:
+ npc_mimiron_assault_bot() : CreatureScript("npc_mimiron_assault_bot") { }
+
+ struct npc_mimiron_assault_botAI : public ScriptedAI
+ {
+ npc_mimiron_assault_botAI(Creature* creature) : ScriptedAI(creature)
+ {
+ }
+
+ void EnterCombat(Unit* /*who*/) override
+ {
+ events.ScheduleEvent(EVENT_MAGNETIC_FIELD, 14000);
+ }
+
+ void UpdateAI(uint32 diff) override
+ {
+ if (!UpdateVictim())
+ return;
+
+ events.Update(diff);
+
+ if (me->HasUnitState(UNIT_STATE_ROOT))
+ {
+ if (Unit* newTarget = SelectTarget(SELECT_TARGET_NEAREST, 0, 30.0f, true))
+ {
+ me->DeleteThreatList();
+ AttackStart(newTarget);
+ }
+ }
+
+ while (uint32 eventId = events.ExecuteEvent())
+ {
+ switch (eventId)
+ {
+ case EVENT_MAGNETIC_FIELD:
+ DoCastVictim(SPELL_MAGNETIC_FIELD);
+ me->ClearUnitState(UNIT_STATE_CASTING);
+ events.RescheduleEvent(EVENT_MAGNETIC_FIELD, 30000);
+ break;
+ default:
+ break;
+ }
+ }
+
+ DoMeleeAttackIfReady();
+ }
+
+ private:
+ EventMap events;
+ };
+
+ CreatureAI* GetAI(Creature* creature) const override
+ {
+ return GetUlduarAI<npc_mimiron_assault_botAI>(creature);
+ }
+};
+
+class npc_mimiron_emergency_fire_bot : public CreatureScript
+{
+ public:
+ npc_mimiron_emergency_fire_bot() : CreatureScript("npc_mimiron_emergency_fire_bot") { }
+
+ struct npc_mimiron_emergency_fire_botAI : public ScriptedAI
+ {
+ npc_mimiron_emergency_fire_botAI(Creature* creature) : ScriptedAI(creature)
+ {
+ me->SetReactState(REACT_PASSIVE);
+ isWaterSprayReady = true;
+ moveNew = true;
+ }
+
+ uint32 GetData(uint32 id) const override
+ {
+ if (id == DATA_WATERSPRAY)
+ return isWaterSprayReady;
+ if (id == DATA_MOVE_NEW)
+ return moveNew;
+ return 0;
+ }
+
+ void SetData(uint32 id, uint32 data) override
+ {
+ if (id == DATA_WATERSPRAY)
+ isWaterSprayReady = false;
+ else if (id == DATA_MOVE_NEW)
+ moveNew = data ? true : false;
+ }
+
+ void Reset() override
+ {
+ events.ScheduleEvent(EVENT_WATER_SPRAY, 7000);
+ isWaterSprayReady = true;
+ moveNew = true;
+ }
+
+ void UpdateAI(uint32 diff) override
+ {
+ if (!isWaterSprayReady)
+ events.Update(diff);
+
+ while (uint32 eventId = events.ExecuteEvent())
+ {
+ switch (eventId)
+ {
+ case EVENT_WATER_SPRAY:
+ isWaterSprayReady = true;
+ events.RescheduleEvent(EVENT_WATER_SPRAY, urand(7000, 9000));
+ break;
+ default:
+ break;
+ }
+ }
+ }
+
+ private:
+ EventMap events;
+ bool isWaterSprayReady;
+ bool moveNew;
+ };
+
+ CreatureAI* GetAI(Creature* creature) const override
+ {
+ return GetUlduarAI<npc_mimiron_emergency_fire_botAI>(creature);
+ }
+};
+
+class npc_mimiron_computer : public CreatureScript
+{
+ public:
+ npc_mimiron_computer() : CreatureScript("npc_mimiron_computer") { }
+
+ struct npc_mimiron_computerAI : public ScriptedAI
+ {
+ npc_mimiron_computerAI(Creature* creature) : ScriptedAI(creature)
+ {
+ instance = me->GetInstanceScript();
+ }
+
+ void DoAction(int32 action) override
+ {
+ switch (action)
+ {
+ case DO_ACTIVATE_COMPUTER:
+ Talk(SAY_SELF_DESTRUCT_INITIATED);
+ events.ScheduleEvent(EVENT_SELF_DESTRUCT_10, 3000);
+ break;
+ case DO_DEACTIVATE_COMPUTER:
+ Talk(SAY_SELF_DESTRUCT_TERMINATED);
+ me->RemoveAurasDueToSpell(SPELL_SELF_DESTRUCTION_AURA);
+ me->RemoveAurasDueToSpell(SPELL_SELF_DESTRUCTION_VISUAL);
+ events.Reset();
+ break;
+ default:
+ break;
+ }
+ }
+
+ void UpdateAI(uint32 diff) override
+ {
+ events.Update(diff);
+
+ while (uint32 eventId = events.ExecuteEvent())
+ {
+ switch (eventId)
+ {
+ case EVENT_SELF_DESTRUCT_10:
+ Talk(SAY_SELF_DESTRUCT_10);
+ if (Creature* mimiron = ObjectAccessor::GetCreature(*me, instance->GetData64(BOSS_MIMIRON)))
+ mimiron->AI()->DoAction(DO_ACTIVATE_HARD_MODE);
+ events.ScheduleEvent(EVENT_SELF_DESTRUCT_9, 60000);
+ break;
+ case EVENT_SELF_DESTRUCT_9:
+ Talk(SAY_SELF_DESTRUCT_9);
+ events.ScheduleEvent(EVENT_SELF_DESTRUCT_8, 60000);
+ break;
+ case EVENT_SELF_DESTRUCT_8:
+ Talk(SAY_SELF_DESTRUCT_8);
+ events.ScheduleEvent(EVENT_SELF_DESTRUCT_7, 60000);
+ break;
+ case EVENT_SELF_DESTRUCT_7:
+ Talk(SAY_SELF_DESTRUCT_7);
+ events.ScheduleEvent(EVENT_SELF_DESTRUCT_6, 60000);
+ break;
+ case EVENT_SELF_DESTRUCT_6:
+ Talk(SAY_SELF_DESTRUCT_6);
+ events.ScheduleEvent(EVENT_SELF_DESTRUCT_5, 60000);
+ break;
+ case EVENT_SELF_DESTRUCT_5:
+ Talk(SAY_SELF_DESTRUCT_5);
+ events.ScheduleEvent(EVENT_SELF_DESTRUCT_4, 60000);
+ break;
+ case EVENT_SELF_DESTRUCT_4:
+ Talk(SAY_SELF_DESTRUCT_4);
+ events.ScheduleEvent(EVENT_SELF_DESTRUCT_3, 60000);
+ break;
+ case EVENT_SELF_DESTRUCT_3:
+ Talk(SAY_SELF_DESTRUCT_3);
+ events.ScheduleEvent(EVENT_SELF_DESTRUCT_2, 60000);
+ break;
+ case EVENT_SELF_DESTRUCT_2:
+ Talk(SAY_SELF_DESTRUCT_2);
+ events.ScheduleEvent(EVENT_SELF_DESTRUCT_1, 60000);
+ break;
+ case EVENT_SELF_DESTRUCT_1:
+ Talk(SAY_SELF_DESTRUCT_1);
+ events.ScheduleEvent(EVENT_SELF_DESTRUCT_FINALIZED, 60000);
+ break;
+ case EVENT_SELF_DESTRUCT_FINALIZED:
+ Talk(SAY_SELF_DESTRUCT_FINALIZED);
+ if (Creature* mimiron = ObjectAccessor::GetCreature(*me, instance->GetData64(BOSS_MIMIRON)))
+ mimiron->AI()->DoAction(DO_ACTIVATE_SELF_DESTRUCT);
+ DoCast(me, SPELL_SELF_DESTRUCTION_AURA);
+ DoCast(me, SPELL_SELF_DESTRUCTION_VISUAL);
+ break;
+ default:
+ break;
+ }
+ }
+ }
+
+ private:
+ InstanceScript* instance;
+ EventMap events;
+ };
+
+ CreatureAI* GetAI(Creature* creature) const override
+ {
+ return GetUlduarAI<npc_mimiron_computerAI>(creature);
+ }
+};
+
+class npc_mimiron_flames : public CreatureScript
+{
+ public:
+ npc_mimiron_flames() : CreatureScript("npc_mimiron_flames") { }
+
+ struct npc_mimiron_flamesAI : public ScriptedAI
+ {
+ npc_mimiron_flamesAI(Creature* creature) : ScriptedAI(creature)
+ {
+ instance = me->GetInstanceScript();
+ }
+
+ void Reset() override // Reset is possibly more suitable for this case.
+ {
+ events.ScheduleEvent(EVENT_SPREAD_FLAMES, 4000);
+ }
+
+ void UpdateAI(uint32 diff) override
+ {
+ if (instance->GetBossState(BOSS_MIMIRON) != IN_PROGRESS)
+ me->DespawnOrUnsummon();
+
+ events.Update(diff);
+
+ while (uint32 eventId = events.ExecuteEvent())
+ {
+ switch (eventId)
+ {
+ case EVENT_SPREAD_FLAMES:
+ DoCastAOE(SPELL_SUMMON_FLAMES_SPREAD_TRIGGER);
+ break;
+ default:
+ break;
+ }
+ }
+ }
+
+ private:
+ InstanceScript* instance;
+ EventMap events;
+ };
+
+ CreatureAI* GetAI(Creature* creature) const override
+ {
+ return GetUlduarAI<npc_mimiron_flamesAI>(creature);
+ }
+};
+
+class npc_mimiron_frost_bomb : public CreatureScript
+{
+ public:
+ npc_mimiron_frost_bomb() : CreatureScript("npc_mimiron_frost_bomb") { }
+
+ struct npc_mimiron_frost_bombAI : public ScriptedAI
+ {
+ npc_mimiron_frost_bombAI(Creature* creature) : ScriptedAI(creature)
+ {
+ }
+
+ void Reset() override
+ {
+ events.ScheduleEvent(EVENT_FROST_BOMB_EXPLOSION, 10000);
+ }
+
+ void UpdateAI(uint32 diff) override
+ {
+ events.Update(diff);
+
+ while (uint32 eventId = events.ExecuteEvent())
+ {
+ switch (eventId)
+ {
+ case EVENT_FROST_BOMB_EXPLOSION:
+ DoCastAOE(SPELL_FROST_BOMB_EXPLOSION);
+ events.ScheduleEvent(EVENT_FROST_BOMB_CLEAR_FIRES, 3000);
+ break;
+ case EVENT_FROST_BOMB_CLEAR_FIRES:
+ DoCastAOE(SPELL_CLEAR_FIRES);
+ me->DespawnOrUnsummon(3000);
+ break;
+ default:
+ break;
+ }
+ }
+ }
+
+ private:
+ EventMap events;
+ };
+
+ CreatureAI* GetAI(Creature* creature) const override
+ {
+ return GetUlduarAI<npc_mimiron_frost_bombAI>(creature);
+ }
+};
+
+class npc_mimiron_proximity_mine : public CreatureScript
+{
+ public:
+ npc_mimiron_proximity_mine() : CreatureScript("npc_mimiron_proximity_mine") { }
+
+ struct npc_mimiron_proximity_mineAI : public ScriptedAI
+ {
+ npc_mimiron_proximity_mineAI(Creature* creature) : ScriptedAI(creature)
+ {
+ }
+
+ void Reset() override
+ {
+ events.ScheduleEvent(EVENT_PROXIMITY_MINE_ARM, 1500);
+ }
+
+ void UpdateAI(uint32 diff) override
+ {
+ events.Update(diff);
+
+ while (uint32 eventId = events.ExecuteEvent())
+ {
+ switch (eventId)
+ {
+ case EVENT_PROXIMITY_MINE_ARM:
+ DoCast(me, SPELL_PROXIMITY_MINE_PERIODIC_TRIGGER);
+ events.ScheduleEvent(EVENT_PROXIMITY_MINE_DETONATION, 33500);
+ break;
+ case EVENT_PROXIMITY_MINE_DETONATION:
+ if (me->HasAura(SPELL_PROXIMITY_MINE_PERIODIC_TRIGGER))
+ DoCastAOE(SPELL_PROXIMITY_MINE_EXPLOSION);
+ me->DespawnOrUnsummon(1000);
+ break;
+ default:
+ break;
+ }
+ }
+ }
+
+ private:
+ EventMap events;
+ };
+
+ CreatureAI* GetAI(Creature* creature) const override
+ {
+ return GetUlduarAI<npc_mimiron_proximity_mineAI>(creature);
+ }
+};
+
+class go_mimiron_hardmode_button : public GameObjectScript
+{
+ public:
+ go_mimiron_hardmode_button() : GameObjectScript("go_mimiron_hardmode_button") { }
+
+ bool OnGossipHello(Player* /*player*/, GameObject* go)
+ {
+ InstanceScript* instance = go->GetInstanceScript();
+
+ if (!instance)
+ return false;
+
+ if (Creature* computer = ObjectAccessor::GetCreature(*go, instance->GetData64(DATA_COMPUTER)))
+ computer->AI()->DoAction(DO_ACTIVATE_COMPUTER);
+ go->SetGoState(GO_STATE_ACTIVE);
+ go->SetFlag(GAMEOBJECT_FLAGS, GO_FLAG_NOT_SELECTABLE);
+ return true;
+ }
+};
+
// 63801 Bomb Bot
class spell_mimiron_bomb_bot : public SpellScriptLoader
{
@@ -1426,8 +2748,66 @@ class spell_mimiron_weld : public SpellScriptLoader
}
};
+class achievement_setup_boom : public AchievementCriteriaScript
+{
+ public:
+ achievement_setup_boom() : AchievementCriteriaScript("achievement_setup_boom") { }
+
+ bool OnCheck(Player* /*source*/, Unit* target)
+ {
+ return target && target->GetAI()->GetData(DATA_SETUP_BOMB);
+ }
+};
+
+class achievement_setup_mine : public AchievementCriteriaScript
+{
+ public:
+ achievement_setup_mine() : AchievementCriteriaScript("achievement_setup_mine") { }
+
+ bool OnCheck(Player* /*source*/, Unit* target)
+ {
+ return target && target->GetAI()->GetData(DATA_SETUP_MINE);
+ }
+};
+
+class achievement_setup_rocket : public AchievementCriteriaScript
+{
+ public:
+ achievement_setup_rocket() : AchievementCriteriaScript("achievement_setup_rocket") { }
+
+ bool OnCheck(Player* /*source*/, Unit* target)
+ {
+ return target && target->GetAI()->GetData(DATA_SETUP_ROCKET);
+ }
+};
+
+class achievement_firefighter : public AchievementCriteriaScript
+{
+ public:
+ achievement_firefighter() : AchievementCriteriaScript("achievement_firefighter") { }
+
+ bool OnCheck(Player* /*source*/, Unit* target)
+ {
+ return target && target->GetAI()->GetData(DATA_FIREFIGHTER);
+ }
+};
+
void AddSC_boss_mimiron()
{
+ new boss_aerial_command_unit();
+ new boss_leviathan_mk_ii();
+ new boss_mimiron();
+ new boss_vx_001();
+
+ new npc_mimiron_assault_bot();
+ new npc_mimiron_emergency_fire_bot();
+ new npc_mimiron_computer();
+ new npc_mimiron_flames();
+ new npc_mimiron_frost_bomb();
+ new npc_mimiron_proximity_mine();
+
+ new go_mimiron_hardmode_button();
+
new spell_mimiron_bomb_bot();
new spell_mimiron_clear_fires();
new spell_mimiron_despawn_assault_bots();
@@ -1454,4 +2834,9 @@ void AddSC_boss_mimiron()
new spell_mimiron_summon_junk_bot();
new spell_mimiron_summon_junk_bot_target();
new spell_mimiron_weld();
+
+ new achievement_setup_boom();
+ new achievement_setup_mine();
+ new achievement_setup_rocket();
+ new achievement_firefighter();
}
diff --git a/src/server/worldserver/worldserver.conf.dist b/src/server/worldserver/worldserver.conf.dist
index ee6def23c3e..9a78d74bb45 100644
--- a/src/server/worldserver/worldserver.conf.dist
+++ b/src/server/worldserver/worldserver.conf.dist
@@ -2630,6 +2630,357 @@ UI.ShowQuestLevelsInDialogs = 0
#
###################################################################################################
+###################################
+# Auction House Bot Configuration #
+###################################
+
+###################################################################################################################
+# AUCTION HOUSE BOT SETTINGS
+#
+# AuctionHouseBot.Update.Interval
+# Description: Interval in seconds for AHBot to get updated
+# Default: 20
+#
+
+AuctionHouseBot.Update.Interval = 20
+
+#
+# AuctionHouseBot.Seller.Enabled
+# Description: General enable or disable AuctionHouseBot Seller functionality
+# Default: 0 - (Disabled)
+# 1 - (Enabled)
+
+AuctionHouseBot.Seller.Enabled = 0
+
+#
+# AuctionHouseBot.Alliance.Items.Amount.Ratio
+# Description: Enable/Disable (disabled if 0) the part of AHBot that puts items up for auction on Alliance AH
+# Default: 100 - (Enabled with 100% of items specified in AuctionHouse.Items.Amount.color section)
+
+AuctionHouseBot.Alliance.Items.Amount.Ratio = 100
+
+#
+# AuctionHouseBot.Horde.Items.Amount.Ratio
+# Enable/Disable (disabled if 0) the part of AHBot that puts items up for auction on Horde AH
+# Default: 100 (Enabled with 100% of items specified in AuctionHouse.Items.Amount.color section)
+
+AuctionHouseBot.Horde.Items.Amount.Ratio = 100
+
+#
+# AuctionHouseBot.Neutral.Items.Amount.Ratio
+# Description: Enable/Disable (disabled if 0) the part of AHBot that puts items up for auction on Neutral AH
+# Default: 100 - (Enabled with 100% of items specified in AuctionHouse.Items.Amount.color section)
+
+AuctionHouseBot.Neutral.Items.Amount.Ratio = 100
+
+#
+# AuctionHouseBot.MinTime
+# Description: Minimum time for the new auction in hours
+# Default: 1 - (Hour)
+
+AuctionHouseBot.MinTime = 1
+
+#
+# AuctionHouseBot.MaxTime
+# Description: Maximum time for the new auction in hours
+# Default: 72 - (Hours)
+
+AuctionHouseBot.MaxTime = 72
+
+#
+# AuctionHouseBot.Items.Vendor
+# Description: Include items that can be bought from vendors.
+# Default: 0 - (Disabled)
+# 1 - (Enabled)
+
+AuctionHouseBot.Items.Vendor = 0
+
+#
+# AuctionHouseBot.Items.Loot
+# Description: Include items that can be looted or fished for.
+# Default: 1 - (Enabled)
+# 0 - (Disabled)
+
+AuctionHouseBot.Items.Loot = 1
+
+#
+# AuctionHouseBot.Items.Misc
+# Description: Include misc. items.
+# Default: 0 - (Disabled)
+# 1 - (Enabled)
+
+AuctionHouseBot.Items.Misc = 0
+
+#
+# AuctionHouseBot.Bind.*
+# Description: Indicates which bonding types to allow the bot to put up for auction
+# No - Items that don't bind Default 1 (Allowed)
+# Pickup - Items that bind on pickup Default 0 (Not Allowed)
+# Equip - Items that bind on equip Default 1 (Allowed)
+# Use - Items that bind on use Default 1 (Allowed)
+# Quest - Quest Items Default 0 (Not Allowed)
+# Values: 0 - (Disabled)
+# 1 - (Enabled)
+
+AuctionHouseBot.Bind.No = 1
+AuctionHouseBot.Bind.Pickup = 0
+AuctionHouseBot.Bind.Equip = 1
+AuctionHouseBot.Bind.Use = 1
+AuctionHouseBot.Bind.Quest = 0
+
+#
+# AuctionHouseBot.LockBox.Enabled
+# Description: Enable or not lockbox in auctionhouse
+# Default 0 - (Disabled)
+# 1 - (Enabled)
+
+AuctionHouseBot.LockBox.Enabled = 0
+
+#
+# AuctionHouseBot.ItemsPerCycle.Boost
+# Description: This value is used to fill AH faster than normal when there is more than this value on missed items (not auctioned items).
+# Usually this value is only used once on server start with empty auction table.
+# Default: 1000
+
+AuctionHouseBot.ItemsPerCycle.Boost = 1000
+
+#
+# AuctionHouseBot.ItemsPerCycle.Normal
+# Description: This value is used to fill AH for sold and expired items. A high value will be more resource intensive
+# Usually this value is used always when auction table is already initialised.
+# Default: 20
+
+AuctionHouseBot.ItemsPerCycle.Normal = 20
+
+#
+# AuctionHouseBot.BuyPrice.Seller
+# Description: Should the Seller use BuyPrice or SellPrice to determine Bid Prices
+# Default: 1 - (use SellPrice)
+# 0 - (use BuyPrice)
+
+AuctionHouseBot.BuyPrice.Seller = 1
+
+#
+# AuctionHouseBot.Alliance.Price.Ratio
+# Description: Percentage by which the price of items selled on Alliance Auction House is incremented / decreased
+# Default: 100 - (Not modify)
+
+AuctionHouseBot.Alliance.Price.Ratio = 100
+
+#
+# AuctionHouseBot.Horde.Price.Ratio
+# Description: Percentage by which the price of items selled on Horde Auction House is incremented / decreased
+# Default: 100 - (Not modify)
+
+AuctionHouseBot.Horde.Price.Ratio = 100
+
+#
+# AuctionHouseBot.Neutral.Price.Ratio
+# Description: Percentage by which the price of items selled on Neutral Auction House is incremented / decreased
+# Default: 100 - (Not modify)
+
+AuctionHouseBot.Neutral.Price.Ratio = 100
+
+#
+# AuctionHouseBot.Items.ItemLevel.*
+# Description: Prevent seller from listing items below/above this item level
+# Default: 0 - (Disabled)
+
+AuctionHouseBot.Items.ItemLevel.Min = 0
+AuctionHouseBot.Items.ItemLevel.Max = 0
+
+#
+# AuctionHouseBot.Items.ReqLevel.*
+# Prevent seller from listing items below/above this required level
+# Default: - 0 (Disabled)
+
+AuctionHouseBot.Items.ReqLevel.Min = 0
+AuctionHouseBot.Items.ReqLevel.Max = 0
+
+#
+# AuctionHouseBot.Items.ReqSkill.*
+# Description: Prevent seller from listing items below/above this skill level
+# Default: 0 - (Disabled)
+# 1 - (Enabled)
+
+AuctionHouseBot.Items.ReqSkill.Min = 0
+AuctionHouseBot.Items.ReqSkill.Max = 0
+
+#
+# AuctionHouseBot.Items.Amount.*
+# Description: Define here for every item qualities how many items you want to be shown in Auction House
+# This value will be adjusted by AuctionHouseBot.FACTION.Items.Amount.Ratio to define the exact amount of
+# items that will finally be shown on Auction House
+# Default: 0, 2000, 2500, 1500, 1000, 0, 0 (Gray, white, green, blue, purple, orange, yellow)
+
+AuctionHouseBot.Items.Amount.Gray = 0
+AuctionHouseBot.Items.Amount.White = 2000
+AuctionHouseBot.Items.Amount.Green = 2500
+AuctionHouseBot.Items.Amount.Blue = 1500
+AuctionHouseBot.Items.Amount.Purple = 1000
+AuctionHouseBot.Items.Amount.Orange = 0
+AuctionHouseBot.Items.Amount.Yellow = 0
+
+#
+# AustionHouseBot.Class.*
+# Description: Here you can set the class of items you prefer to be show on AH
+# These value are sorted by preference, from 0 (disabled) to 10 (max. preference)
+# Default: Consumable: 6
+# Container: 4
+# Weapon: 8
+# Gem: 3
+# Armor: 8
+# Reagent: 1
+# Projectile: 2
+# TradeGod: 10
+# Generic: 1
+# Recipe: 6
+# Quiver: 1
+# Quest: 1
+# Key: 1
+# Misc: 5
+# Glyph: 3
+
+AuctionHouseBot.Class.Consumable = 6
+AuctionHouseBot.Class.Container = 4
+AuctionHouseBot.Class.Weapon = 8
+AuctionHouseBot.Class.Gem = 3
+AuctionHouseBot.Class.Armor = 8
+AuctionHouseBot.Class.Reagent = 1
+AuctionHouseBot.Class.Projectile = 2
+AuctionHouseBot.Class.TradeGood = 10
+AuctionHouseBot.Class.Generic = 1
+AuctionHouseBot.Class.Recipe = 6
+AuctionHouseBot.Class.Quiver = 1
+AuctionHouseBot.Class.Quest = 1
+AuctionHouseBot.Class.Key = 1
+AuctionHouseBot.Class.Misc = 5
+AuctionHouseBot.Class.Glyph = 3
+
+###################################################################################################################
+#
+# AHBot ITEM FINE TUNING
+# The following are usefull for limiting what character levels can
+# benefit from the auction house
+#
+# AuctionHouseBot.Class.Misc.Mount.ReqLevel.*
+# Description: Prevent seller from listing mounts below/above this required level
+# Default: 0
+
+AuctionHouseBot.Class.Misc.Mount.ReqLevel.Min = 0
+AuctionHouseBot.Class.Misc.Mount.ReqLevel.Max = 0
+
+#
+# AuctionHouseBot.Class.Misc.Mount.ReqSkill.*
+# Description: Prevent seller from listing mounts below/above this skill level
+# Default: 0
+
+AuctionHouseBot.Class.Misc.Mount.ReqSkill.Min = 0
+AuctionHouseBot.Class.Misc.Mount.ReqSkill.Max = 0
+
+#
+# AuctionHouseBot.Class.Glyph.ReqLevel.*
+# Description: Prevent seller from listing glyphs below/above this required level
+# Default: 0
+
+AuctionHouseBot.Class.Glyph.ReqLevel.Min = 0
+AuctionHouseBot.Class.Glyph.ReqLevel.Max = 0
+
+#
+# AuctionHouseBot.Class.Glyph.ItemLevel.*
+# Description: Prevent seller from listing glyphs below/above this item level
+# Default: 0
+
+AuctionHouseBot.Class.Glyph.ItemLevel.Min = 0
+AuctionHouseBot.Class.Glyph.ItemLevel.Max = 0
+
+#
+# AuctionHouseBot.Class.TradeGood.ItemLevel.*
+# Description: Prevent seller from listing trade good items below/above this item level
+# Default: 0
+
+AuctionHouseBot.Class.TradeGood.ItemLevel.Min = 0
+AuctionHouseBot.Class.TradeGood.ItemLevel.Max = 0
+
+#
+# AuctionHouseBot.Class.Container.ItemLevel.*
+# Description: Prevent seller from listing contianers below/above this item level
+# Default: 0
+
+AuctionHouseBot.Class.Container.ItemLevel.Min = 0
+AuctionHouseBot.Class.Container.ItemLevel.Max = 0
+
+#
+# AuctionHouseBot.forceIncludeItems
+# Description: Include these items and ignore ALL filters
+# List of ids with delimiter ','
+# Default: ""
+
+AuctionHouseBot.forceIncludeItems = ""
+
+#
+# AuctionHouseBot.forceExcludeItems
+# Description: Exclude these items even if they would pass the filters
+# List of ids with delimiter ','
+# Example: "21878,27774,27811,28117,28122,43949" (this removes old items)
+# Default: ""
+#
+
+AuctionHouseBot.forceExcludeItems = ""
+
+#
+###################################################################################################################
+
+###################################################################################################################
+# AHBot Buyer config
+#
+# AuctionHouseBot.Buyer.Enabled
+# Description: General enable or disable AuctionHouseBot Buyer functionality
+# Default: 0 - (Disabled)
+# 1 - (Enabled)
+
+AuctionHouseBot.Buyer.Enabled = 0
+
+#
+# AuctionHouseBot.Buyer.FACTION.Enabled
+# Description: Enable or disable buyer independently by faction
+# Default: 0 - (Disabled)
+# 1 - (Enabled)
+
+AuctionHouseBot.Buyer.Alliance.Enabled = 0
+AuctionHouseBot.Buyer.Horde.Enabled = 0
+AuctionHouseBot.Buyer.Neutral.Enabled = 0
+
+#
+# AuctionHouseBot.BuyPrice.Buyer
+# Description: Should the Buyer use BuyPrice or SellPrice to determine Bid Prices
+# Default: 1 - (use BuyPrice)
+# 0 - (use SellPrice)
+
+AuctionHouseBot.Buyer.Buyprice = 1
+
+#
+# AuctionHouseBot.Buyer.Recheck.Interval
+# Description: This specifies the time interval (in minutes) between two evaluations of the same selled item.
+# The lesser this value is, the more chances you give for item to be bought by ahbot.
+# Default: 20 (20min.)
+
+AuctionHouseBot.Buyer.Recheck.Interval = 20
+
+#
+# AuctionHouseBot.Buyer.Alliance.Chance.Ratio
+# Description: Chance ratio for the buyer to buy an item. Higher the value, lesser the probability
+# Example: 3 (1 out of 3 change, that is, 33%).
+# Default: 3
+#
+
+AuctionHouseBot.Buyer.Alliance.Chance.Ratio = 3
+AuctionHouseBot.Buyer.Horde.Chance.Ratio = 3
+AuctionHouseBot.Buyer.Neutral.Chance.Ratio = 3
+
+#
+###################################################################################################################
+
###################################################################################################
# LOGGING SYSTEM SETTINGS
#
@@ -2726,6 +3077,7 @@ Logger.commands.gm=3,Console GM
Logger.sql.sql=5,Console DBErrors
#Logger.achievement=3,Console Server
+#Logger.ahbot=3,Console Server
#Logger.auctionHouse=3,Console Server
#Logger.bg.arena=3,Console Server
#Logger.bg.battlefield=3,Console Server