aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/server/game/Accounts/RBAC.h1
-rw-r--r--src/server/game/AuctionHouseBot/AuctionHouseBot.cpp6
-rw-r--r--src/server/game/AuctionHouseBot/AuctionHouseBot.h2
-rw-r--r--src/server/game/AuctionHouseBot/AuctionHouseBotBuyer.cpp42
-rw-r--r--src/server/game/AuctionHouseBot/AuctionHouseBotBuyer.h2
-rw-r--r--src/server/game/AuctionHouseBot/AuctionHouseBotSeller.cpp64
-rw-r--r--src/server/game/AuctionHouseBot/AuctionHouseBotSeller.h2
-rw-r--r--src/server/game/Entities/Player/Player.cpp15
-rw-r--r--src/server/game/Guilds/Guild.h3
-rw-r--r--src/server/game/Miscellaneous/Language.h9
-rw-r--r--src/server/game/Spells/SpellMgr.cpp10
-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.dist9
15 files changed, 1547 insertions, 67 deletions
diff --git a/src/server/game/Accounts/RBAC.h b/src/server/game/Accounts/RBAC.h
index 7aeceff87ae..fc22f76e949 100644
--- a/src/server/game/Accounts/RBAC.h
+++ b/src/server/game/Accounts/RBAC.h
@@ -697,6 +697,7 @@ enum RBACPermissions
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
index 707e143ac39..6bf5fa0aaa5 100644
--- a/src/server/game/AuctionHouseBot/AuctionHouseBot.cpp
+++ b/src/server/game/AuctionHouseBot/AuctionHouseBot.cpp
@@ -294,8 +294,7 @@ void AuctionHouseBot::InitializeAgents()
{
if (sAuctionBotConfig->GetConfig(CONFIG_AHBOT_SELLER_ENABLED))
{
- if (_seller)
- delete _seller;
+ delete _seller;
_seller = new AuctionBotSeller();
if (!_seller->Initialize())
@@ -307,8 +306,7 @@ void AuctionHouseBot::InitializeAgents()
if (sAuctionBotConfig->GetConfig(CONFIG_AHBOT_BUYER_ENABLED))
{
- if (_buyer)
- delete _buyer;
+ delete _buyer;
_buyer = new AuctionBotBuyer();
if (!_buyer->Initialize())
diff --git a/src/server/game/AuctionHouseBot/AuctionHouseBot.h b/src/server/game/AuctionHouseBot/AuctionHouseBot.h
index 8c1a2425f7c..04ca96dfdd9 100644
--- a/src/server/game/AuctionHouseBot/AuctionHouseBot.h
+++ b/src/server/game/AuctionHouseBot/AuctionHouseBot.h
@@ -168,7 +168,7 @@ enum AuctionBotConfigBoolValues
class AuctionBotConfig
{
private:
- AuctionBotConfig() {}
+ AuctionBotConfig(): _itemsPerCycleBoost(1000), _itemsPerCycleNormal(20) {}
~AuctionBotConfig() {}
AuctionBotConfig(const AuctionBotConfig&);
AuctionBotConfig& operator=(const AuctionBotConfig&);
diff --git a/src/server/game/AuctionHouseBot/AuctionHouseBotBuyer.cpp b/src/server/game/AuctionHouseBot/AuctionHouseBotBuyer.cpp
index f7c8003fc76..0043482c77f 100644
--- a/src/server/game/AuctionHouseBot/AuctionHouseBotBuyer.cpp
+++ b/src/server/game/AuctionHouseBot/AuctionHouseBotBuyer.cpp
@@ -20,7 +20,7 @@
#include "ItemPrototype.h"
#include "AuctionHouseBotBuyer.h"
-AuctionBotBuyer::AuctionBotBuyer()
+AuctionBotBuyer::AuctionBotBuyer(): _checkInterval(20)
{
// Define faction for our main data class.
for (int i = 0; i < MAX_AUCTION_HOUSE_TYPE; ++i)
@@ -50,7 +50,7 @@ bool AuctionBotBuyer::Initialize()
//load Check interval
_checkInterval = sAuctionBotConfig->GetConfig(CONFIG_AHBOT_BUYER_RECHECK_INTERVAL) * MINUTE;
- TC_LOG_INFO("ahbot", "AHBot buyer interval between 2 check = %u", _checkInterval);
+ TC_LOG_DEBUG("ahbot", "AHBot buyer interval between 2 check = %u", _checkInterval);
return true;
}
@@ -150,8 +150,8 @@ uint32 AuctionBotBuyer::GetBuyableEntry(BuyerConfiguration& config)
}
}
- TC_LOG_INFO("ahbot", "AHBot: %u items added to buyable vector for ah type: %u", count, config.GetHouseType());
- TC_LOG_INFO("ahbot", "AHBot: SameItemInfo size = %u", (uint32)config.SameItemInfo.size());
+ 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;
}
@@ -167,7 +167,7 @@ void AuctionBotBuyer::PrepareListOfEntry(BuyerConfiguration& config)
++itr;
}
- TC_LOG_INFO("ahbot", "AHBot: CheckedEntry size = %u", (uint32)config.CheckedEntry.size());
+ 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)
@@ -227,12 +227,12 @@ bool AuctionBotBuyer::IsBuyableEntry(uint32 buyoutPrice, double inGameBuyPrice,
if (urand(1, chanceRatio) <= chance)
{
- TC_LOG_INFO("ahbot", "AHBot: WIN BUY! Chance = %u, num = %u.", chance, chanceRatio);
+ TC_LOG_DEBUG("ahbot", "AHBot: WIN BUY! Chance = %u, num = %u.", chance, chanceRatio);
return true;
}
else
{
- TC_LOG_INFO("ahbot", "AHBot: LOOSE BUY! Chance = %u, num = %u.", chance, chanceRatio);
+ TC_LOG_DEBUG("ahbot", "AHBot: LOOSE BUY! Chance = %u, num = %u.", chance, chanceRatio);
return false;
}
}
@@ -274,25 +274,25 @@ bool AuctionBotBuyer::IsBidableEntry(uint32 bidPrice, double inGameBuyPrice, dou
if (urand(1, chanceRatio) <= chance)
{
- TC_LOG_INFO("ahbot", "AHBot: WIN BID! Chance = %u, num = %u.", chance, chanceRatio);
+ TC_LOG_DEBUG("ahbot", "AHBot: WIN BID! Chance = %u, num = %u.", chance, chanceRatio);
return true;
}
else
{
- TC_LOG_INFO("ahbot", "AHBot: LOOSE BID! Chance = %u, num = %u.", chance, chanceRatio);
+ TC_LOG_DEBUG("ahbot", "AHBot: LOOSE BID! Chance = %u, num = %u.", chance, chanceRatio);
return false;
}
}
void AuctionBotBuyer::PlaceBidToEntry(AuctionEntry* auction, uint32 bidPrice)
{
- TC_LOG_INFO("ahbot", "AHBot: Bid placed to entry %u, %.2fg", auction->Id, float(bidPrice) / 10000.0f);
+ 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_INFO("ahbot", "AHBot: Entry %u bought at %.2fg", auction->Id, float(auction->buyout) / 10000.0f);
+ TC_LOG_DEBUG("ahbot", "AHBot: Entry %u bought at %.2fg", auction->Id, float(auction->buyout) / 10000.0f);
auction->bid = auction->buyout;
}
@@ -307,7 +307,7 @@ void AuctionBotBuyer::AddNewAuctionBuyerBotBid(BuyerConfiguration& config)
if (config.CheckedEntry.size() > sAuctionBotConfig->GetItemPerCycleBoost())
{
buyCycles = sAuctionBotConfig->GetItemPerCycleBoost();
- TC_LOG_INFO("ahbot", "AHBot: Boost value used for Buyer! (if this happens often adjust both ItemsPerCycle in worldserver.conf)");
+ TC_LOG_DEBUG("ahbot", "AHBot: Boost value used for Buyer! (if this happens often adjust both ItemsPerCycle in worldserver.conf)");
}
else
buyCycles = sAuctionBotConfig->GetItemPerCycleNormal();
@@ -317,8 +317,8 @@ void AuctionBotBuyer::AddNewAuctionBuyerBotBid(BuyerConfiguration& config)
AuctionEntry* auction = auctionHouse->GetAuction(itr->second.AuctionId);
if (!auction) // is auction not active now
{
- TC_LOG_INFO("ahbot", "AHBot: Entry %u on ah %u doesn't exists, perhaps bought already?",
- itr->second.AuctionId, auction->GetHouseId());
+ TC_LOG_DEBUG("ahbot", "AHBot: Entry %u doesn't exists, perhaps bought already?",
+ itr->second.AuctionId);
config.CheckedEntry.erase(itr++);
continue;
@@ -326,7 +326,7 @@ void AuctionBotBuyer::AddNewAuctionBuyerBotBid(BuyerConfiguration& config)
if (itr->second.LastChecked != 0 && (now - itr->second.LastChecked) <= _checkInterval)
{
- TC_LOG_INFO("ahbot", "AHBot: In time interval wait for entry %u!", auction->Id);
+ TC_LOG_DEBUG("ahbot", "AHBot: In time interval wait for entry %u!", auction->Id);
++itr;
continue;
}
@@ -382,12 +382,12 @@ void AuctionBotBuyer::AddNewAuctionBuyerBotBid(BuyerConfiguration& config)
double maxBidablePrice = maxBuyablePrice - (maxBuyablePrice / 30); // Max Bidable price defined to 70% of max buyable price
- TC_LOG_INFO("ahbot", "AHBot: Auction added with data:");
- TC_LOG_INFO("ahbot", "AHBot: MaxPrice of Entry %u is %.1fg.", itr->second.AuctionId, maxBuyablePrice / 10000);
- TC_LOG_INFO("ahbot", "AHBot: GamePrice buy=%.1fg, bid=%.1fg.", inGameBuyPrice / 10000, inGameBidPrice / 10000);
- TC_LOG_INFO("ahbot", "AHBot: Minimal price see in AH Buy=%ug, Bid=%ug.",
+ 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_INFO("ahbot", "AHBot: Actual Entry price, Buy=%ug, Bid=%ug.", buyoutPrice / 10000, bidPrice / 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)
@@ -422,7 +422,7 @@ bool AuctionBotBuyer::Update(AuctionHouseType houseType)
{
if (sAuctionBotConfig->GetConfigBuyerEnabled(houseType))
{
- TC_LOG_INFO("ahbot", "AHBot: %s buying ...", AuctionBotConfig::GetHouseTypeName(houseType));
+ TC_LOG_DEBUG("ahbot", "AHBot: %s buying ...", AuctionBotConfig::GetHouseTypeName(houseType));
if (GetBuyableEntry(_houseConfig[houseType]) > 0)
AddNewAuctionBuyerBotBid(_houseConfig[houseType]);
return true;
diff --git a/src/server/game/AuctionHouseBot/AuctionHouseBotBuyer.h b/src/server/game/AuctionHouseBot/AuctionHouseBotBuyer.h
index 89be1b8b052..1148435f1c1 100644
--- a/src/server/game/AuctionHouseBot/AuctionHouseBotBuyer.h
+++ b/src/server/game/AuctionHouseBot/AuctionHouseBotBuyer.h
@@ -47,7 +47,7 @@ typedef std::map<uint32, BuyerAuctionEval> CheckEntryMap;
struct BuyerConfiguration
{
- BuyerConfiguration(): _houseType(AUCTION_HOUSE_NEUTRAL) {}
+ BuyerConfiguration(): FactionChance(3), BuyerEnabled(false), BuyerPriceRatio(100), _houseType(AUCTION_HOUSE_NEUTRAL) {}
void Initialize(AuctionHouseType houseType)
{
diff --git a/src/server/game/AuctionHouseBot/AuctionHouseBotSeller.cpp b/src/server/game/AuctionHouseBot/AuctionHouseBotSeller.cpp
index 0e6cfcaf22e..5d8da598299 100644
--- a/src/server/game/AuctionHouseBot/AuctionHouseBotSeller.cpp
+++ b/src/server/game/AuctionHouseBot/AuctionHouseBotSeller.cpp
@@ -39,7 +39,7 @@ bool AuctionBotSeller::Initialize()
std::vector<uint32> includeItems;
std::vector<uint32> excludeItems;
- TC_LOG_INFO("ahbot", "AHBot seller filters:");
+ TC_LOG_DEBUG("ahbot", "AHBot seller filters:");
{
std::stringstream includeStream(sAuctionBotConfig->GetAHBotIncludes());
@@ -55,10 +55,10 @@ bool AuctionBotSeller::Initialize()
excludeItems.push_back(atoi(temp.c_str()));
}
- TC_LOG_INFO("ahbot", "Forced Inclusion %u items", (uint32)includeItems.size());
- TC_LOG_INFO("ahbot", "Forced Exclusion %u items", (uint32)excludeItems.size());
+ TC_LOG_DEBUG("ahbot", "Forced Inclusion %u items", (uint32)includeItems.size());
+ TC_LOG_DEBUG("ahbot", "Forced Exclusion %u items", (uint32)excludeItems.size());
- TC_LOG_INFO("ahbot", "Loading npc vendor items for filter..");
+ 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)
@@ -72,9 +72,9 @@ bool AuctionBotSeller::Initialize()
for (std::set<uint32>::const_iterator it = tempItems.begin(); it != tempItems.end(); ++it)
npcItems.push_back(*it);
- TC_LOG_INFO("ahbot", "Npc vendor filter has %u items", (uint32)npcItems.size());
+ TC_LOG_DEBUG("ahbot", "Npc vendor filter has %u items", (uint32)npcItems.size());
- TC_LOG_INFO("ahbot", "Loading loot items for filter..");
+ 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 "
@@ -101,8 +101,8 @@ bool AuctionBotSeller::Initialize()
} while (result->NextRow());
}
- TC_LOG_INFO("ahbot", "Loot filter has %u items", (uint32)lootItems.size());
- TC_LOG_INFO("ahbot", "Sorting and cleaning items for AHBot seller...");
+ 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;
@@ -382,18 +382,18 @@ bool AuctionBotSeller::Initialize()
return false;
}
- TC_LOG_INFO("ahbot", "AuctionHouseBot seller will use %u items to fill auction house (according your config choices)", itemsAdded);
+ TC_LOG_DEBUG("ahbot", "AuctionHouseBot seller will use %u items to fill auction house (according your config choices)", itemsAdded);
LoadConfig();
- TC_LOG_INFO("ahbot", "Items loaded \tGray\tWhite\tGreen\tBlue\tPurple\tOrange\tYellow");
+ TC_LOG_DEBUG("ahbot", "Items loaded \tGray\tWhite\tGreen\tBlue\tPurple\tOrange\tYellow");
for (uint32 i = 0; i < MAX_ITEM_CLASS; ++i)
- TC_LOG_INFO("ahbot", "\t\t%u\t%u\t%u\t%u\t%u\t%u\t%u",
+ 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_INFO("ahbot", "AHBot seller configuration data loaded and initialized");
+ TC_LOG_DEBUG("ahbot", "AHBot seller configuration data loaded and initialized");
return true;
}
@@ -594,17 +594,17 @@ void AuctionBotSeller::LoadSellerValues(SellerConfiguration& config)
config.SetMinTime(sAuctionBotConfig->GetConfig(CONFIG_AHBOT_MINTIME));
config.SetMaxTime(sAuctionBotConfig->GetConfig(CONFIG_AHBOT_MAXTIME));
- TC_LOG_INFO("ahbot", "AHBot: minTime = %u", config.GetMinTime());
- TC_LOG_INFO("ahbot", "AHBot: maxTime = %u", config.GetMaxTime());
-
- TC_LOG_INFO("ahbot", "AHBot: For AH type %u", config.GetHouseType());
- TC_LOG_INFO("ahbot", "AHBot: GrayItems = %u", config.GetItemsAmountPerQuality(AUCTION_QUALITY_GRAY));
- TC_LOG_INFO("ahbot", "AHBot: WhiteItems = %u", config.GetItemsAmountPerQuality(AUCTION_QUALITY_WHITE));
- TC_LOG_INFO("ahbot", "AHBot: GreenItems = %u", config.GetItemsAmountPerQuality(AUCTION_QUALITY_GREEN));
- TC_LOG_INFO("ahbot", "AHBot: BlueItems = %u", config.GetItemsAmountPerQuality(AUCTION_QUALITY_BLUE));
- TC_LOG_INFO("ahbot", "AHBot: PurpleItems = %u", config.GetItemsAmountPerQuality(AUCTION_QUALITY_PURPLE));
- TC_LOG_INFO("ahbot", "AHBot: OrangeItems = %u", config.GetItemsAmountPerQuality(AUCTION_QUALITY_ORANGE));
- TC_LOG_INFO("ahbot", "AHBot: YellowItems = %u", config.GetItemsAmountPerQuality(AUCTION_QUALITY_YELLOW));
+ 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.
@@ -637,10 +637,10 @@ uint32 AuctionBotSeller::SetStat(SellerConfiguration& config)
}
}
- TC_LOG_INFO("ahbot", "AHBot: Missed Item \tGray\tWhite\tGreen\tBlue\tPurple\tOrange\tYellow");
+ 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_INFO("ahbot", "AHBot: \t\t%u\t%u\t%u\t%u\t%u\t%u\t%u",
+ 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),
@@ -899,13 +899,13 @@ void AuctionBotSeller::AddNewAuctions(SellerConfiguration& config)
if (config.LastMissedItem > sAuctionBotConfig->GetItemPerCycleBoost())
{
items = sAuctionBotConfig->GetItemPerCycleBoost();
- TC_LOG_INFO("ahbot", "AHBot: Boost value used to fill AH! (if this happens often adjust both ItemsPerCycle in worldserver.conf)");
+ 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;
- uint32 auctioneer;
+ uint32 houseid = 0;
+ uint32 auctioneer = 0;
switch (config.GetHouseType())
{
case AUCTION_HOUSE_ALLIANCE:
@@ -938,14 +938,14 @@ void AuctionBotSeller::AddNewAuctions(SellerConfiguration& config)
if (!itemId)
{
- TC_LOG_INFO("ahbot", "AHBot: Item entry 0 auction creating attempt.");
+ TC_LOG_DEBUG("ahbot", "AHBot: Item entry 0 auction creating attempt.");
continue;
}
ItemTemplate const* prototype = sObjectMgr->GetItemTemplate(itemId);
if (!prototype)
{
- TC_LOG_INFO("ahbot", "AHBot: Unknown item %u auction creating attempt.", itemId);
+ TC_LOG_DEBUG("ahbot", "AHBot: Unknown item %u auction creating attempt.", itemId);
continue;
}
@@ -1012,14 +1012,14 @@ void AuctionBotSeller::AddNewAuctions(SellerConfiguration& config)
}
CharacterDatabase.CommitTransaction(trans);
- TC_LOG_INFO("ahbot", "AHBot: Added %u items to auction", count);
+ TC_LOG_DEBUG("ahbot", "AHBot: Added %u items to auction", count);
}
bool AuctionBotSeller::Update(AuctionHouseType houseType)
{
if (sAuctionBotConfig->GetConfigItemAmountRatio(houseType) > 0)
{
- TC_LOG_INFO("ahbot", "AHBot: %s selling ...", AuctionBotConfig::GetHouseTypeName(houseType));
+ TC_LOG_DEBUG("ahbot", "AHBot: %s selling ...", AuctionBotConfig::GetHouseTypeName(houseType));
if (SetStat(_houseConfig[houseType]))
AddNewAuctions(_houseConfig[houseType]);
return true;
diff --git a/src/server/game/AuctionHouseBot/AuctionHouseBotSeller.h b/src/server/game/AuctionHouseBot/AuctionHouseBotSeller.h
index a1820196dc8..014fe23f71a 100644
--- a/src/server/game/AuctionHouseBot/AuctionHouseBotSeller.h
+++ b/src/server/game/AuctionHouseBot/AuctionHouseBotSeller.h
@@ -55,7 +55,7 @@ struct SellerItemInfo
class SellerConfiguration
{
public:
- SellerConfiguration(): _houseType(AUCTION_HOUSE_NEUTRAL)
+ SellerConfiguration(): LastMissedItem(0), _houseType(AUCTION_HOUSE_NEUTRAL), _minTime(1), _maxTime(72)
{
}
diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp
index d9c92d00a18..3cfe73e4d8c 100644
--- a/src/server/game/Entities/Player/Player.cpp
+++ b/src/server/game/Entities/Player/Player.cpp
@@ -15321,6 +15321,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);
+ }
}
}
}
@@ -15341,7 +15354,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);
diff --git a/src/server/game/Guilds/Guild.h b/src/server/game/Guilds/Guild.h
index da5f16d38c5..c8ee4d7b0a8 100644
--- a/src/server/game/Guilds/Guild.h
+++ b/src/server/game/Guilds/Guild.h
@@ -767,6 +767,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 d2d314fde31..9e4bd55671a 100644
--- a/src/server/game/Miscellaneous/Language.h
+++ b/src/server/game/Miscellaneous/Language.h
@@ -970,7 +970,14 @@ enum TrinityStrings
LANG_AHBOT_QUALITY_YELLOW = 1174,
LANG_AHBOT_ITEMS_AMOUNT = 1175,
LANG_AHBOT_ITEMS_RATIO = 1176,
- // Room for more level 3 1177-1199 not used
+ 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/Spells/SpellMgr.cpp b/src/server/game/Spells/SpellMgr.cpp
index 0e5264bf56a..18c529d0515 100644
--- a/src/server/game/Spells/SpellMgr.cpp
+++ b/src/server/game/Spells/SpellMgr.cpp
@@ -3360,6 +3360,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/scripts/Commands/cs_guild.cpp b/src/server/scripts/Commands/cs_guild.cpp
index dfc681a1d87..99d9e0a2a8a 100644
--- a/src/server/scripts/Commands/cs_guild.cpp
+++ b/src/server/scripts/Commands/cs_guild.cpp
@@ -45,6 +45,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[] =
@@ -244,6 +245,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 e93e3670864..14ac9a34cf5 100644
--- a/src/server/worldserver/worldserver.conf.dist
+++ b/src/server/worldserver/worldserver.conf.dist
@@ -2706,16 +2706,16 @@ AuctionHouseBot.LockBox.Enabled = 0
#
# AuctionHouseBot.ItemsPerCycle.Boost
-# Description: This value is used to fill DB faster than normal when there is more than this value on missed items (not auctioned items).
-# Normaly this value is only used once on server start with empty auction table.
+# 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 DB with way with less cpu/db using.
-# Normaly this value is used always when auction table is already initialised.
+# 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
@@ -2753,7 +2753,6 @@ AuctionHouseBot.Neutral.Price.Ratio = 100
# AuctionHouseBot.Items.ItemLevel.*
# Description: Prevent seller from listing items below/above this item level
# Default: 0 - (Disabled)
-# 1-80 (Levels)
AuctionHouseBot.Items.ItemLevel.Min = 0
AuctionHouseBot.Items.ItemLevel.Max = 0