diff options
Diffstat (limited to 'src')
42 files changed, 635 insertions, 671 deletions
diff --git a/src/server/bnetserver/Realms/WorldListener.cpp b/src/server/bnetserver/Realms/WorldListener.cpp index 9c9f1029e87..d84425496c7 100644 --- a/src/server/bnetserver/Realms/WorldListener.cpp +++ b/src/server/bnetserver/Realms/WorldListener.cpp @@ -97,15 +97,19 @@ void WorldListener::HandleToonOnlineStatusChange(Battlenet::RealmHandle const& r { if (online) { - Battlenet::WoWRealm::ToonReady* toonReady = new Battlenet::WoWRealm::ToonReady(); - toonReady->Realm.Battlegroup = realm.Battlegroup; - toonReady->Realm.Index = realm.Index; - toonReady->Realm.Region = realm.Region; - toonReady->Guid = toonHandle.Guid; - toonReady->Name = toonHandle.Name; - session->AsyncWrite(toonReady); + if (!session->IsToonOnline()) + { + Battlenet::WoWRealm::ToonReady* toonReady = new Battlenet::WoWRealm::ToonReady(); + toonReady->Realm.Battlegroup = realm.Battlegroup; + toonReady->Realm.Index = realm.Index; + toonReady->Realm.Region = realm.Region; + toonReady->Guid = toonHandle.Guid; + toonReady->Name = toonHandle.Name; + session->SetToonOnline(true); + session->AsyncWrite(toonReady); + } } - else + else if (session->IsToonOnline()) session->AsyncWrite(new Battlenet::WoWRealm::ToonLoggedOut()); } } diff --git a/src/server/bnetserver/Server/Session.cpp b/src/server/bnetserver/Server/Session.cpp index fd6784152e8..f0940aa6947 100644 --- a/src/server/bnetserver/Server/Session.cpp +++ b/src/server/bnetserver/Server/Session.cpp @@ -38,7 +38,7 @@ Battlenet::Session::ModuleHandler const Battlenet::Session::ModuleHandlers[MODUL Battlenet::Session::Session(tcp::socket&& socket) : Socket(std::move(socket)), _accountId(0), _accountName(), _locale(), _os(), _build(0), _gameAccountId(0), _gameAccountName(), _accountSecurityLevel(SEC_PLAYER), I(), s(), v(), b(), B(), K(), - _reconnectProof(), _crypt(), _authed(false), _subscribedToRealmListUpdates(false) + _reconnectProof(), _crypt(), _authed(false), _subscribedToRealmListUpdates(false), _toonOnline(false) { static uint8 const N_Bytes[] = { diff --git a/src/server/bnetserver/Server/Session.h b/src/server/bnetserver/Server/Session.h index 4a1feb7c8a8..ab373ebe6cc 100644 --- a/src/server/bnetserver/Server/Session.h +++ b/src/server/bnetserver/Server/Session.h @@ -91,6 +91,9 @@ namespace Battlenet uint32 GetAccountId() const { return _accountId; } uint32 GetGameAccountId() const { return _gameAccountId; } + bool IsToonOnline() const { return _toonOnline; } + void SetToonOnline(bool online) { _toonOnline = online; } + bool IsSubscribedToRealmListUpdates() const { return _subscribedToRealmListUpdates; } void AsyncWrite(ServerPacket* packet); @@ -141,6 +144,7 @@ namespace Battlenet PacketCrypt _crypt; bool _authed; bool _subscribedToRealmListUpdates; + bool _toonOnline; }; } diff --git a/src/server/bnetserver/Server/SessionManager.cpp b/src/server/bnetserver/Server/SessionManager.cpp index 9e5836dab8d..6c52ee477f1 100644 --- a/src/server/bnetserver/Server/SessionManager.cpp +++ b/src/server/bnetserver/Server/SessionManager.cpp @@ -46,7 +46,11 @@ void Battlenet::SessionManager::AddSession(Session* session) void Battlenet::SessionManager::RemoveSession(Session* session) { std::unique_lock<boost::shared_mutex> lock(_sessionMutex); - _sessions.erase({ session->GetAccountId(), session->GetGameAccountId() }); + auto itr = _sessions.find({ session->GetAccountId(), session->GetGameAccountId() }); + // Remove old session only if it was not overwritten by reconnecting + if (itr != _sessions.end() && itr->second == session) + _sessions.erase(itr); + _sessionsByAccountId[session->GetAccountId()].remove(session); } diff --git a/src/server/game/AuctionHouseBot/AuctionHouseBotSeller.cpp b/src/server/game/AuctionHouseBot/AuctionHouseBotSeller.cpp index 36d78ba389c..dc23c0157eb 100644 --- a/src/server/game/AuctionHouseBot/AuctionHouseBotSeller.cpp +++ b/src/server/game/AuctionHouseBot/AuctionHouseBotSeller.cpp @@ -272,10 +272,10 @@ bool AuctionBotSeller::Initialize() if (prototype->GetBaseItemLevel() > value) continue; if (uint32 value = sAuctionBotConfig->GetConfig(CONFIG_AHBOT_ITEM_MIN_REQ_LEVEL)) - if (prototype->GetBaseRequiredLevel() < value) + if (prototype->GetBaseRequiredLevel() < static_cast<int32>(value)) continue; if (uint32 value = sAuctionBotConfig->GetConfig(CONFIG_AHBOT_ITEM_MAX_REQ_LEVEL)) - if (prototype->GetBaseRequiredLevel() > value) + if (prototype->GetBaseRequiredLevel() > static_cast<int32>(value)) continue; if (uint32 value = sAuctionBotConfig->GetConfig(CONFIG_AHBOT_ITEM_MIN_SKILL_RANK)) if (prototype->GetRequiredSkillRank() < value) @@ -290,10 +290,10 @@ bool AuctionBotSeller::Initialize() case ITEM_CLASS_PROJECTILE: { if (uint32 value = sAuctionBotConfig->GetConfig(CONFIG_AHBOT_ITEM_MIN_REQ_LEVEL)) - if (prototype->GetBaseRequiredLevel() < value) + if (prototype->GetBaseRequiredLevel() < static_cast<int32>(value)) continue; if (uint32 value = sAuctionBotConfig->GetConfig(CONFIG_AHBOT_ITEM_MAX_REQ_LEVEL)) - if (prototype->GetBaseRequiredLevel() > value) + if (prototype->GetBaseRequiredLevel() > static_cast<int32>(value)) continue; if (uint32 value = sAuctionBotConfig->GetConfig(CONFIG_AHBOT_ITEM_MIN_SKILL_RANK)) if (prototype->GetRequiredSkillRank() < value) @@ -307,10 +307,10 @@ bool AuctionBotSeller::Initialize() if (prototype->GetSubClass() == ITEM_SUBCLASS_JUNK_MOUNT) { if (uint32 value = sAuctionBotConfig->GetConfig(CONFIG_AHBOT_CLASS_MISC_MOUNT_MIN_REQ_LEVEL)) - if (prototype->GetBaseRequiredLevel() < value) + if (prototype->GetBaseRequiredLevel() < static_cast<int32>(value)) continue; if (uint32 value = sAuctionBotConfig->GetConfig(CONFIG_AHBOT_CLASS_MISC_MOUNT_MAX_REQ_LEVEL)) - if (prototype->GetBaseRequiredLevel() > value) + if (prototype->GetBaseRequiredLevel() > static_cast<int32>(value)) continue; if (uint32 value = sAuctionBotConfig->GetConfig(CONFIG_AHBOT_CLASS_MISC_MOUNT_MIN_SKILL_RANK)) if (prototype->GetRequiredSkillRank() < value) @@ -334,16 +334,16 @@ bool AuctionBotSeller::Initialize() case ITEM_CLASS_GLYPH: { if (uint32 value = sAuctionBotConfig->GetConfig(CONFIG_AHBOT_CLASS_GLYPH_MIN_REQ_LEVEL)) - if (prototype->GetBaseRequiredLevel() < value) + if (prototype->GetBaseRequiredLevel() < static_cast<int32>(value)) continue; if (uint32 value = sAuctionBotConfig->GetConfig(CONFIG_AHBOT_CLASS_GLYPH_MAX_REQ_LEVEL)) - if (prototype->GetBaseRequiredLevel() > value) + if (prototype->GetBaseRequiredLevel() > static_cast<int32>(value)) continue; if (uint32 value = sAuctionBotConfig->GetConfig(CONFIG_AHBOT_CLASS_GLYPH_MIN_ITEM_LEVEL)) - if (prototype->GetBaseRequiredLevel() < value) + if (prototype->GetBaseRequiredLevel() < static_cast<int32>(value)) continue; if (uint32 value = sAuctionBotConfig->GetConfig(CONFIG_AHBOT_CLASS_GLYPH_MAX_ITEM_LEVEL)) - if (prototype->GetBaseRequiredLevel() > value) + if (prototype->GetBaseRequiredLevel() > static_cast<int32>(value)) continue; break; } diff --git a/src/server/game/DataStores/DB2Stores.cpp b/src/server/game/DataStores/DB2Stores.cpp index 39e5d443871..f2148b6a24e 100644 --- a/src/server/game/DataStores/DB2Stores.cpp +++ b/src/server/game/DataStores/DB2Stores.cpp @@ -23,6 +23,7 @@ #include "World.h" #include <functional> +DB2Storage<BroadcastTextEntry> sBroadcastTextStore(BroadcastTextEntryfmt, HOTFIX_SEL_BROADCAST_TEXT); std::map<uint32 /*curveID*/, std::map<uint32/*index*/, CurvePointEntry const*, std::greater<uint32>>> HeirloomCurvePoints; DB2Storage<CurvePointEntry> sCurvePointStore(CurvePointEntryfmt); DB2Storage<HolidaysEntry> sHolidaysStore(HolidaysEntryfmt); @@ -50,7 +51,7 @@ DB2Storage<SpellRuneCostEntry> sSpellRuneCostStore(SpellRuneCostEnt DB2Storage<SpellTotemsEntry> sSpellTotemsStore(SpellTotemsEntryfmt); DB2Storage<TaxiNodesEntry> sTaxiNodesStore(TaxiNodesEntryfmt); DB2Storage<TaxiPathEntry> sTaxiPathStore(TaxiPathEntryfmt); -DB2Storage<TaxiPathNodeEntry> sTaxiPathNodeStore(TaxiPathNodeEntryfmt); +DB2Storage<TaxiPathNodeEntry> sTaxiPathNodeStore(TaxiPathNodeEntryfmt, HOTFIX_SEL_TAXI_PATH_NODE); TaxiMask sTaxiNodesMask; TaxiMask sOldContinentsNodesMask; TaxiMask sHordeTaxiNodesMask; @@ -86,6 +87,8 @@ inline void LoadDB2(uint32& availableDb2Locales, DB2StoreProblemList& errlist, D std::string db2_filename = db2_path + filename; if (storage.Load(db2_filename.c_str(), uint32(sWorld->GetDefaultDbcLocale()))) { + storage.LoadSQLData(); + for (uint32 i = 0; i < TOTAL_LOCALES; ++i) { if (!(availableDb2Locales & (1 << i))) @@ -128,6 +131,7 @@ void LoadDB2Stores(std::string const& dataPath) DB2StoreProblemList bad_db2_files; uint32 availableDb2Locales = 0xFF; + LoadDB2(availableDb2Locales, bad_db2_files, sBroadcastTextStore, db2Path, "BroadcastText.db2"); LoadDB2(availableDb2Locales, bad_db2_files, sCurvePointStore, db2Path, "CurvePoint.db2"); LoadDB2(availableDb2Locales, bad_db2_files, sHolidaysStore, db2Path, "Holidays.db2"); LoadDB2(availableDb2Locales, bad_db2_files, sItemStore, db2Path, "Item.db2"); @@ -306,6 +310,22 @@ DB2StorageBase const* GetDB2Storage(uint32 type) return NULL; } +char const* GetBroadcastTextValue(BroadcastTextEntry const* broadcastText, LocaleConstant locale /*= DEFAULT_LOCALE*/, uint8 gender /*= GENDER_MALE*/, bool forceGender /*= false*/) +{ + if (gender == GENDER_FEMALE && (forceGender || broadcastText->FemaleText->Str[DEFAULT_LOCALE][0] != '\0')) + { + if (broadcastText->FemaleText->Str[locale][0] != '\0') + return broadcastText->FemaleText->Str[locale]; + + return broadcastText->FemaleText->Str[DEFAULT_LOCALE]; + } + + if (broadcastText->MaleText->Str[locale][0] != '\0') + return broadcastText->MaleText->Str[locale]; + + return broadcastText->MaleText->Str[DEFAULT_LOCALE]; +} + uint32 GetHeirloomItemLevel(uint32 curveId, uint32 level) { // Assuming linear item level scaling for heirlooms diff --git a/src/server/game/DataStores/DB2Stores.h b/src/server/game/DataStores/DB2Stores.h index 20ff43a9bd4..d68c27987e1 100644 --- a/src/server/game/DataStores/DB2Stores.h +++ b/src/server/game/DataStores/DB2Stores.h @@ -23,6 +23,7 @@ #include <string> #include <map> +extern DB2Storage<BroadcastTextEntry> sBroadcastTextStore; extern DB2Storage<HolidaysEntry> sHolidaysStore; extern DB2Storage<ItemEntry> sItemStore; extern DB2Storage<ItemCurrencyCostEntry> sItemCurrencyCostStore; @@ -56,6 +57,7 @@ void LoadDB2Stores(std::string const& dataPath); DB2StorageBase const* GetDB2Storage(uint32 type); +char const* GetBroadcastTextValue(BroadcastTextEntry const* broadcastText, LocaleConstant locale = DEFAULT_LOCALE, uint8 gender = GENDER_MALE, bool forceGender = false); uint32 GetHeirloomItemLevel(uint32 curveId, uint32 level); uint32 GetItemDisplayId(uint32 itemId, uint32 appearanceModId); std::vector<ItemBonusEntry const*> GetItemBonuses(uint32 bonusListId); diff --git a/src/server/game/DataStores/DB2Structure.h b/src/server/game/DataStores/DB2Structure.h index 5942f8a425a..3416e562ad3 100644 --- a/src/server/game/DataStores/DB2Structure.h +++ b/src/server/game/DataStores/DB2Structure.h @@ -24,6 +24,7 @@ #pragma pack(push, 1) +#define MAX_BROADCAST_TEXT_EMOTES 3 #define MAX_HOLIDAY_DURATIONS 10 #define MAX_HOLIDAY_DATES 16 #define MAX_HOLIDAY_FLAGS 10 @@ -31,6 +32,19 @@ #define MAX_ITEM_PROTO_SOCKETS 3 #define MAX_ITEM_PROTO_STATS 10 +struct BroadcastTextEntry +{ + uint32 ID; + int32 Language; + LocalizedString* MaleText; + LocalizedString* FemaleText; + uint32 EmoteID[MAX_BROADCAST_TEXT_EMOTES]; + uint32 EmoteDelay[MAX_BROADCAST_TEXT_EMOTES]; + uint32 SoundID; + uint32 UnkEmoteID; + uint32 Type; +}; + struct CurvePointEntry { uint32 ID; // 0 diff --git a/src/server/game/DataStores/DB2fmt.h b/src/server/game/DataStores/DB2fmt.h index 087c1dfd588..d789f4a6622 100644 --- a/src/server/game/DataStores/DB2fmt.h +++ b/src/server/game/DataStores/DB2fmt.h @@ -18,6 +18,7 @@ #ifndef TRINITY_DB2SFRM_H #define TRINITY_DB2SFRM_H +char const BroadcastTextEntryfmt[] = "nissiiiiiiiii"; char const CurvePointEntryfmt[] = "niiff"; char const HolidaysEntryfmt[] = "niiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiixxsiix"; char const Itemfmt[] = "niiiiiiii"; diff --git a/src/server/game/Entities/Creature/GossipDef.cpp b/src/server/game/Entities/Creature/GossipDef.cpp index 68e1ebb3ab5..9a6dc5879fd 100644 --- a/src/server/game/Entities/Creature/GossipDef.cpp +++ b/src/server/game/Entities/Creature/GossipDef.cpp @@ -94,18 +94,18 @@ void GossipMenu::AddMenuItem(uint32 menuId, uint32 menuItemId, uint32 sender, ui /// Store texts for localization. std::string strOptionText, strBoxText; - BroadcastText const* optionBroadcastText = sObjectMgr->GetBroadcastText(itr->second.OptionBroadcastTextId); - BroadcastText const* boxBroadcastText = sObjectMgr->GetBroadcastText(itr->second.BoxBroadcastTextId); + BroadcastTextEntry const* optionBroadcastText = sBroadcastTextStore.LookupEntry(itr->second.OptionBroadcastTextId); + BroadcastTextEntry const* boxBroadcastText = sBroadcastTextStore.LookupEntry(itr->second.BoxBroadcastTextId); /// OptionText if (optionBroadcastText) - strOptionText = optionBroadcastText->GetText(GetLocale()); + strOptionText = GetBroadcastTextValue(optionBroadcastText, GetLocale()); else strOptionText = itr->second.OptionText; /// BoxText if (boxBroadcastText) - strBoxText = boxBroadcastText->GetText(GetLocale()); + strBoxText = GetBroadcastTextValue(boxBroadcastText, GetLocale()); else strBoxText = itr->second.BoxText; diff --git a/src/server/game/Entities/Item/Item.cpp b/src/server/game/Entities/Item/Item.cpp index 7fa8e9e5e6e..92d66d6808b 100644 --- a/src/server/game/Entities/Item/Item.cpp +++ b/src/server/game/Entities/Item/Item.cpp @@ -1838,8 +1838,8 @@ void BonusData::AddBonus(uint32 type, int32 const (&values)[2]) break; } case ITEM_BONUS_QUALITY: - if (Quality < values[0]) - Quality = values[0]; + if (Quality < static_cast<uint32>(values[0])) + Quality = static_cast<uint32>(values[0]); break; case ITEM_BONUS_SOCKET: { @@ -1855,8 +1855,8 @@ void BonusData::AddBonus(uint32 type, int32 const (&values)[2]) break; } case ITEM_BONUS_APPEARANCE: - if (AppearanceModID < values[0]) - AppearanceModID = values[0]; + if (AppearanceModID < static_cast<uint32>(values[0])) + AppearanceModID = static_cast<uint32>(values[0]); break; case ITEM_BONUS_REQUIRED_LEVEL: RequiredLevel += values[0]; diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp index 1487e934f24..ad95e908840 100644 --- a/src/server/game/Entities/Player/Player.cpp +++ b/src/server/game/Entities/Player/Player.cpp @@ -13852,17 +13852,17 @@ void Player::PrepareGossipMenu(WorldObject* source, uint32 menuId /*= 0*/, bool if (canTalk) { std::string strOptionText, strBoxText; - BroadcastText const* optionBroadcastText = sObjectMgr->GetBroadcastText(itr->second.OptionBroadcastTextId); - BroadcastText const* boxBroadcastText = sObjectMgr->GetBroadcastText(itr->second.BoxBroadcastTextId); + BroadcastTextEntry const* optionBroadcastText = sBroadcastTextStore.LookupEntry(itr->second.OptionBroadcastTextId); + BroadcastTextEntry const* boxBroadcastText = sBroadcastTextStore.LookupEntry(itr->second.BoxBroadcastTextId); LocaleConstant locale = GetSession()->GetSessionDbLocaleIndex(); if (optionBroadcastText) - strOptionText = optionBroadcastText->GetText(locale, getGender()); + strOptionText = GetBroadcastTextValue(optionBroadcastText, locale, getGender()); else strOptionText = itr->second.OptionText; if (boxBroadcastText) - strBoxText = boxBroadcastText->GetText(locale, getGender()); + strBoxText = GetBroadcastTextValue(boxBroadcastText, locale, getGender()); else strBoxText = itr->second.BoxText; diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp index ede8c959594..ed696517be9 100644 --- a/src/server/game/Entities/Unit/Unit.cpp +++ b/src/server/game/Entities/Unit/Unit.cpp @@ -16462,7 +16462,7 @@ void Unit::Whisper(std::string const& text, Language language, Player* target, b void Unit::Talk(uint32 textId, ChatMsg msgType, float textRange, WorldObject const* target) { - if (!sObjectMgr->GetBroadcastText(textId)) + if (!sBroadcastTextStore.LookupEntry(textId)) { TC_LOG_ERROR("entities.unit", "WorldObject::MonsterText: `broadcast_text` was not %u found", textId); return; @@ -16494,7 +16494,7 @@ void Unit::Whisper(uint32 textId, Player* target, bool isBossWhisper /*= false*/ if (!target) return; - BroadcastText const* bct = sObjectMgr->GetBroadcastText(textId); + BroadcastTextEntry const* bct = sBroadcastTextStore.LookupEntry(textId); if (!bct) { TC_LOG_ERROR("entities.unit", "WorldObject::MonsterWhisper: `broadcast_text` was not %u found", textId); @@ -16503,6 +16503,6 @@ void Unit::Whisper(uint32 textId, Player* target, bool isBossWhisper /*= false*/ LocaleConstant locale = target->GetSession()->GetSessionDbLocaleIndex(); WorldPackets::Chat::Chat packet; - packet.Initalize(isBossWhisper ? CHAT_MSG_RAID_BOSS_WHISPER : CHAT_MSG_MONSTER_WHISPER, LANG_UNIVERSAL, this, target, bct->GetText(locale, getGender()), 0, "", locale); + packet.Initalize(isBossWhisper ? CHAT_MSG_RAID_BOSS_WHISPER : CHAT_MSG_MONSTER_WHISPER, LANG_UNIVERSAL, this, target, GetBroadcastTextValue(bct, locale, getGender()), 0, "", locale); target->SendDirectMessage(packet.Write()); } diff --git a/src/server/game/Globals/ObjectMgr.cpp b/src/server/game/Globals/ObjectMgr.cpp index f9c532d23dd..16958a2dde8 100644 --- a/src/server/game/Globals/ObjectMgr.cpp +++ b/src/server/game/Globals/ObjectMgr.cpp @@ -4323,7 +4323,7 @@ void ObjectMgr::LoadScripts(ScriptsType type) tableName.c_str(), tmp.Talk.ChatType, tmp.id); continue; } - if (!sObjectMgr->GetBroadcastText(uint32(tmp.Talk.TextID))) + if (!sBroadcastTextStore.LookupEntry(uint32(tmp.Talk.TextID))) { TC_LOG_ERROR("sql.sql", "Table `%s` has invalid talk text id (dataint = %i) in SCRIPT_COMMAND_TALK for script id %u", tableName.c_str(), tmp.Talk.TextID, tmp.id); @@ -5087,7 +5087,7 @@ void ObjectMgr::LoadGossipText() { if (gText.Options[i].BroadcastTextID) { - if (!sObjectMgr->GetBroadcastText(gText.Options[i].BroadcastTextID)) + if (!sBroadcastTextStore.LookupEntry(gText.Options[i].BroadcastTextID)) { TC_LOG_ERROR("sql.sql", "GossipText (Id: %u) in table `npc_text` has non-existing or incompatible BroadcastTextID%u %u.", id, i, gText.Options[i].BroadcastTextID); gText.Options[i].BroadcastTextID = 0; @@ -8042,7 +8042,7 @@ void ObjectMgr::LoadGossipMenuItems() if (gMenuItem.OptionBroadcastTextId) { - if (!GetBroadcastText(gMenuItem.OptionBroadcastTextId)) + if (!sBroadcastTextStore.LookupEntry(gMenuItem.OptionBroadcastTextId)) { TC_LOG_ERROR("sql.sql", "Table `gossip_menu_option` for menu %u, id %u has non-existing or incompatible OptionBroadcastTextId %u, ignoring.", gMenuItem.MenuId, gMenuItem.OptionIndex, gMenuItem.OptionBroadcastTextId); gMenuItem.OptionBroadcastTextId = 0; @@ -8060,7 +8060,7 @@ void ObjectMgr::LoadGossipMenuItems() if (gMenuItem.BoxBroadcastTextId) { - if (!GetBroadcastText(gMenuItem.BoxBroadcastTextId)) + if (!sBroadcastTextStore.LookupEntry(gMenuItem.BoxBroadcastTextId)) { TC_LOG_ERROR("sql.sql", "Table `gossip_menu_option` for menu %u, id %u has non-existing or incompatible BoxBroadcastTextId %u, ignoring.", gMenuItem.MenuId, gMenuItem.OptionIndex, gMenuItem.BoxBroadcastTextId); gMenuItem.BoxBroadcastTextId = 0; @@ -8273,141 +8273,6 @@ uint32 ObjectMgr::GetScriptId(char const* name) return uint32(itr - _scriptNamesStore.begin()); } -void ObjectMgr::LoadBroadcastTexts() -{ - uint32 oldMSTime = getMSTime(); - - _broadcastTextStore.clear(); // for reload case - - // 0 1 2 3 4 5 6 7 8 9 10 11 12 - QueryResult result = WorldDatabase.Query("SELECT ID, Language, MaleText, FemaleText, EmoteID0, EmoteID1, EmoteID2, EmoteDelay0, EmoteDelay1, EmoteDelay2, SoundId, Unk1, Unk2 FROM broadcast_text"); - if (!result) - { - TC_LOG_INFO("server.loading", ">> Loaded 0 broadcast texts. DB table `broadcast_text` is empty."); - return; - } - - _broadcastTextStore.rehash(result->GetRowCount()); - uint32 count = 0; - - do - { - Field* fields = result->Fetch(); - - BroadcastText bct; - - bct.Id = fields[0].GetUInt32(); - bct.Language = fields[1].GetUInt32(); - bct.MaleText[DEFAULT_LOCALE] = fields[2].GetString(); - bct.FemaleText[DEFAULT_LOCALE] = fields[3].GetString(); - bct.EmoteId0 = fields[4].GetUInt32(); - bct.EmoteId1 = fields[5].GetUInt32(); - bct.EmoteId2 = fields[6].GetUInt32(); - bct.EmoteDelay0 = fields[7].GetUInt32(); - bct.EmoteDelay1 = fields[8].GetUInt32(); - bct.EmoteDelay2 = fields[9].GetUInt32(); - bct.SoundId = fields[10].GetUInt32(); - bct.Unk1 = fields[11].GetUInt32(); - bct.Unk2 = fields[12].GetUInt32(); - - if (bct.SoundId) - { - if (!sSoundEntriesStore.LookupEntry(bct.SoundId)) - { - TC_LOG_INFO("sql.sql", "BroadcastText (Id: %u) in table `broadcast_text` has SoundId %u but sound does not exist. Skipped.", bct.Id, bct.SoundId); - // don't load bct of higher expansions - continue; - } - } - - if (!GetLanguageDescByID(bct.Language)) - { - TC_LOG_INFO("sql.sql", "BroadcastText (Id: %u) in table `broadcast_text` using Language %u but Language does not exist. Skipped.", bct.Id, bct.Language); - // don't load bct of higher expansions - continue; - } - - if (bct.EmoteId0) - { - if (!sEmotesStore.LookupEntry(bct.EmoteId0)) - { - TC_LOG_INFO("sql.sql", "BroadcastText (Id: %u) in table `broadcast_text` has EmoteId0 %u but emote does not exist. Skipped.", bct.Id, bct.EmoteId0); - // don't load bct of higher expansions - continue; - } - } - - if (bct.EmoteId1) - { - if (!sEmotesStore.LookupEntry(bct.EmoteId1)) - { - TC_LOG_INFO("sql.sql", "BroadcastText (Id: %u) in table `broadcast_text` has EmoteId1 %u but emote does not exist. Skipped.", bct.Id, bct.EmoteId1); - // don't load bct of higher expansions - continue; - } - } - - if (bct.EmoteId2) - { - if (!sEmotesStore.LookupEntry(bct.EmoteId2)) - { - TC_LOG_INFO("sql.sql", "BroadcastText (Id: %u) in table `broadcast_text` has EmoteId2 %u but emote does not exist. Skipped.", bct.Id, bct.EmoteId2); - // don't load bct of higher expansions - continue; - } - } - - _broadcastTextStore[bct.Id] = bct; - - ++count; - } - while (result->NextRow()); - - TC_LOG_INFO("server.loading", ">> Loaded %u broadcast texts in %u ms", count, GetMSTimeDiffToNow(oldMSTime)); -} - -void ObjectMgr::LoadBroadcastTextLocales() -{ - uint32 oldMSTime = getMSTime(); - - // 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 - QueryResult result = WorldDatabase.Query("SELECT Id, MaleText_loc1, MaleText_loc2, MaleText_loc3, MaleText_loc4, MaleText_loc5, MaleText_loc6, MaleText_loc7, MaleText_loc8, FemaleText_loc1, FemaleText_loc2, FemaleText_loc3, FemaleText_loc4, FemaleText_loc5, FemaleText_loc6, FemaleText_loc7, FemaleText_loc8 FROM locales_broadcast_text"); - - if (!result) - { - TC_LOG_INFO("server.loading", ">> Loaded 0 broadcast text locales. DB table `locales_broadcast_text` is empty."); - return; - } - - uint32 count = 0; - - do - { - Field* fields = result->Fetch(); - - uint32 id = fields[0].GetUInt32(); - BroadcastTextContainer::iterator bct = _broadcastTextStore.find(id); - if (bct == _broadcastTextStore.end()) - { - TC_LOG_INFO("sql.sql", "BroadcastText (Id: %u) in table `locales_broadcast_text` does not exist or is incompatible. Skipped!", id); - // don't load bct of higher expansions - continue; - } - - for (uint8 i = TOTAL_LOCALES - 1; i > 0; --i) - { - LocaleConstant locale = LocaleConstant(i); - AddLocaleString(fields[1 + (i - 1)].GetString(), locale, bct->second.MaleText); - AddLocaleString(fields[9 + (i - 1)].GetString(), locale, bct->second.FemaleText); - } - - ++count; - } - while (result->NextRow()); - - TC_LOG_INFO("server.loading", ">> Loaded %u broadcast text locales in %u ms", count, GetMSTimeDiffToNow(oldMSTime)); -} - CreatureBaseStats const* ObjectMgr::GetCreatureBaseStats(uint8 level, uint8 unitClass) { CreatureBaseStatsContainer::const_iterator it = _creatureBaseStatsStore.find(MAKE_PAIR16(level, unitClass)); @@ -8675,47 +8540,6 @@ void ObjectMgr::LoadHotfixData() TC_LOG_INFO("server.loading", ">> Loaded %u hotfix info entries in %u ms", count, GetMSTimeDiffToNow(oldMSTime)); } -void ObjectMgr::LoadMissingKeyChains() -{ - uint32 oldMSTime = getMSTime(); - - QueryResult result = WorldDatabase.Query("SELECT keyId, k1, k2, k3, k4, k5, k6, k7, k8, " - "k9, k10, k11, k12, k13, k14, k15, k16, " - "k17, k18, k19, k20, k21, k22, k23, k24, " - "k25, k26, k27, k28, k29, k30, k31, k32 " - "FROM keychain_db2 ORDER BY keyId DESC"); - - if (!result) - { - TC_LOG_INFO("server.loading", ">> Loaded 0 KeyChain entries. DB table `keychain_db2` is empty."); - return; - } - - uint32 count = 0; - - do - { - Field* fields = result->Fetch(); - uint32 id = fields[0].GetUInt32(); - - KeyChainEntry* kce = sKeyChainStore.CreateEntry(id, true); - if (!kce) - { - TC_LOG_ERROR("sql.sql", "Could not create KeyChainEntry %u, skipped.", id); - continue; - } - - kce->Id = id; - for (uint32 i = 0; i < KEYCHAIN_SIZE; ++i) - kce->Key[i] = fields[1 + i].GetUInt8(); - - ++count; - } - while (result->NextRow()); - - TC_LOG_INFO("server.loading", ">> Loaded %u KeyChain entries in %u ms", count, GetMSTimeDiffToNow(oldMSTime)); -} - void ObjectMgr::LoadFactionChangeSpells() { uint32 oldMSTime = getMSTime(); diff --git a/src/server/game/Globals/ObjectMgr.h b/src/server/game/Globals/ObjectMgr.h index 9b83ce27392..17873be4252 100644 --- a/src/server/game/Globals/ObjectMgr.h +++ b/src/server/game/Globals/ObjectMgr.h @@ -436,49 +436,6 @@ struct AreaTriggerStruct float target_Orientation; }; -struct BroadcastText -{ - BroadcastText() : Id(0), Language(0), EmoteId0(0), EmoteId1(0), EmoteId2(0), - EmoteDelay0(0), EmoteDelay1(0), EmoteDelay2(0), SoundId(0), Unk1(0), Unk2(0) - { - MaleText.resize(DEFAULT_LOCALE + 1); - FemaleText.resize(DEFAULT_LOCALE + 1); - } - - uint32 Id; - uint32 Language; - StringVector MaleText; - StringVector FemaleText; - uint32 EmoteId0; - uint32 EmoteId1; - uint32 EmoteId2; - uint32 EmoteDelay0; - uint32 EmoteDelay1; - uint32 EmoteDelay2; - uint32 SoundId; - uint32 Unk1; - uint32 Unk2; - // uint32 VerifiedBuild; - - std::string const& GetText(LocaleConstant locale = DEFAULT_LOCALE, uint8 gender = GENDER_MALE, bool forceGender = false) const - { - if (gender == GENDER_FEMALE && (forceGender || !FemaleText[DEFAULT_LOCALE].empty())) - { - if (FemaleText.size() > size_t(locale) && !FemaleText[locale].empty()) - return FemaleText[locale]; - return FemaleText[DEFAULT_LOCALE]; - } - // else if (gender == GENDER_MALE) - { - if (MaleText.size() > size_t(locale) && !MaleText[locale].empty()) - return MaleText[locale]; - return MaleText[DEFAULT_LOCALE]; - } - } -}; - -typedef std::unordered_map<uint32, BroadcastText> BroadcastTextContainer; - typedef std::set<ObjectGuid::LowType> CellGuidSet; typedef std::map<ObjectGuid/*player guid*/, uint32/*instance*/> CellCorpseSet; struct CellObjectGuids @@ -994,8 +951,6 @@ class ObjectMgr void LoadSpellScriptNames(); void ValidateSpellScripts(); - void LoadBroadcastTexts(); - void LoadBroadcastTextLocales(); void LoadCreatureClassLevelStats(); void LoadCreatureLocales(); void LoadCreatureTemplates(); @@ -1136,14 +1091,6 @@ class ObjectMgr return NULL; } - BroadcastText const* GetBroadcastText(uint32 id) const - { - BroadcastTextContainer::const_iterator itr = _broadcastTextStore.find(id); - if (itr != _broadcastTextStore.end()) - return &itr->second; - return NULL; - } - CreatureData const* GetCreatureData(ObjectGuid::LowType guid) const { CreatureDataContainer::const_iterator itr = _creatureDataStore.find(guid); @@ -1354,9 +1301,6 @@ class ObjectMgr return ret ? ret : time(NULL); } - void LoadMissingKeyChains(); - - void LoadRaceAndClassExpansionRequirements(); void LoadRealmNames(); @@ -1502,7 +1446,6 @@ class ObjectMgr /// Stores temp summon data grouped by summoner's entry, summoner's type and group id TempSummonDataContainer _tempSummonDataStore; - BroadcastTextContainer _broadcastTextStore; ItemTemplateContainer _itemTemplateStore; ItemLocaleContainer _itemLocaleStore; QuestLocaleContainer _questLocaleStore; diff --git a/src/server/game/Handlers/PetitionsHandler.cpp b/src/server/game/Handlers/PetitionsHandler.cpp index 819075a54c5..67c29c32c7d 100644 --- a/src/server/game/Handlers/PetitionsHandler.cpp +++ b/src/server/game/Handlers/PetitionsHandler.cpp @@ -42,14 +42,6 @@ enum CharterItemIDs ARENA_TEAM_CHARTER_5v5 = 23562 }; -enum CharterCosts -{ - GUILD_CHARTER_COST = 1000, - ARENA_TEAM_CHARTER_2v2_COST = 800000, - ARENA_TEAM_CHARTER_3v3_COST = 1200000, - ARENA_TEAM_CHARTER_5v5_COST = 2000000 -}; - void WorldSession::HandlePetitionBuyOpcode(WorldPacket& recvData) { TC_LOG_DEBUG("network", "Received opcode CMSG_PETITION_BUY"); @@ -106,7 +98,7 @@ void WorldSession::HandlePetitionBuyOpcode(WorldPacket& recvData) return; charterid = GUILD_CHARTER; - cost = GUILD_CHARTER_COST; + cost = sWorld->getIntConfig(CONFIG_CHARTER_COST_GUILD); type = GUILD_CHARTER_TYPE; } else @@ -122,17 +114,17 @@ void WorldSession::HandlePetitionBuyOpcode(WorldPacket& recvData) { case 1: charterid = ARENA_TEAM_CHARTER_2v2; - cost = ARENA_TEAM_CHARTER_2v2_COST; + cost = sWorld->getIntConfig(CONFIG_CHARTER_COST_ARENA_2v2); type = ARENA_TEAM_CHARTER_2v2_TYPE; break; case 2: charterid = ARENA_TEAM_CHARTER_3v3; - cost = ARENA_TEAM_CHARTER_3v3_COST; + cost = sWorld->getIntConfig(CONFIG_CHARTER_COST_ARENA_3v3); type = ARENA_TEAM_CHARTER_3v3_TYPE; break; case 3: charterid = ARENA_TEAM_CHARTER_5v5; - cost = ARENA_TEAM_CHARTER_5v5_COST; + cost = sWorld->getIntConfig(CONFIG_CHARTER_COST_ARENA_5v5); type = ARENA_TEAM_CHARTER_5v5_TYPE; break; default: @@ -936,7 +928,7 @@ void WorldSession::SendPetitionShowList(ObjectGuid guid) data << uint32(1); // index data << uint32(GUILD_CHARTER); // charter entry data << uint32(CHARTER_DISPLAY_ID); // charter display id - data << uint32(GUILD_CHARTER_COST); // charter cost + data << uint32(sWorld->getIntConfig(CONFIG_CHARTER_COST_GUILD)); // charter cost data << uint32(0); // unknown data << uint32(sWorld->getIntConfig(CONFIG_MIN_PETITION_SIGNS)); // required signs } @@ -947,21 +939,21 @@ void WorldSession::SendPetitionShowList(ObjectGuid guid) data << uint32(1); // index data << uint32(ARENA_TEAM_CHARTER_2v2); // charter entry data << uint32(CHARTER_DISPLAY_ID); // charter display id - data << uint32(ARENA_TEAM_CHARTER_2v2_COST); // charter cost + data << uint32(sWorld->getIntConfig(CONFIG_CHARTER_COST_ARENA_2v2)); // charter cost data << uint32(2); // unknown data << uint32(2); // required signs? // 3v3 data << uint32(2); // index data << uint32(ARENA_TEAM_CHARTER_3v3); // charter entry data << uint32(CHARTER_DISPLAY_ID); // charter display id - data << uint32(ARENA_TEAM_CHARTER_3v3_COST); // charter cost + data << uint32(sWorld->getIntConfig(CONFIG_CHARTER_COST_ARENA_3v3)); // charter cost data << uint32(3); // unknown data << uint32(3); // required signs? // 5v5 data << uint32(3); // index data << uint32(ARENA_TEAM_CHARTER_5v5); // charter entry data << uint32(CHARTER_DISPLAY_ID); // charter display id - data << uint32(ARENA_TEAM_CHARTER_5v5_COST); // charter cost + data << uint32(sWorld->getIntConfig(CONFIG_CHARTER_COST_ARENA_5v5)); // charter cost data << uint32(5); // unknown data << uint32(5); // required signs? } diff --git a/src/server/game/OutdoorPvP/OutdoorPvPMgr.cpp b/src/server/game/OutdoorPvP/OutdoorPvPMgr.cpp index b4d77e9d0fb..cc34132b142 100644 --- a/src/server/game/OutdoorPvP/OutdoorPvPMgr.cpp +++ b/src/server/game/OutdoorPvP/OutdoorPvPMgr.cpp @@ -231,8 +231,8 @@ void OutdoorPvPMgr::HandlePlayerResurrects(Player* player, uint32 zoneid) std::string OutdoorPvPMgr::GetDefenseMessage(uint32 zoneId, uint32 id, LocaleConstant locale) const { - if (BroadcastText const* bct = sObjectMgr->GetBroadcastText(id)) - return bct->GetText(locale); + if (BroadcastTextEntry const* bct = sBroadcastTextStore.LookupEntry(id)) + return GetBroadcastTextValue(bct, locale); TC_LOG_ERROR("outdoorpvp", "Can not find DefenseMessage (Zone: %u, Id: %u). BroadcastText (Id: %u) does not exist.", zoneId, id, id); return ""; diff --git a/src/server/game/Spells/Spell.cpp b/src/server/game/Spells/Spell.cpp index eae52b77cff..66e67d0f09e 100644 --- a/src/server/game/Spells/Spell.cpp +++ b/src/server/game/Spells/Spell.cpp @@ -7299,6 +7299,19 @@ bool Spell::CallScriptEffectHandlers(SpellEffIndex effIndex, SpellEffectHandleMo return preventDefault; } +void Spell::CallScriptSuccessfulDispel(SpellEffIndex effIndex) +{ + for (std::list<SpellScript*>::iterator scritr = m_loadedScripts.begin(); scritr != m_loadedScripts.end(); ++scritr) + { + (*scritr)->_PrepareScriptCall(SPELL_SCRIPT_HOOK_EFFECT_SUCCESSFUL_DISPEL); + std::list<SpellScript::EffectHandler>::iterator hookItrEnd = (*scritr)->OnEffectSuccessfulDispel.end(), hookItr = (*scritr)->OnEffectSuccessfulDispel.begin(); + for (; hookItr != hookItrEnd; ++hookItr) + hookItr->Call(*scritr, effIndex); + + (*scritr)->_FinishScriptCall(); + } +} + void Spell::CallScriptBeforeHitHandlers() { for (std::list<SpellScript*>::iterator scritr = m_loadedScripts.begin(); scritr != m_loadedScripts.end(); ++scritr) diff --git a/src/server/game/Spells/Spell.h b/src/server/game/Spells/Spell.h index 57302c4f32e..66eb4ae6ded 100644 --- a/src/server/game/Spells/Spell.h +++ b/src/server/game/Spells/Spell.h @@ -676,6 +676,7 @@ class Spell SpellCastResult CallScriptCheckCastHandlers(); void PrepareScriptHitHandlers(); bool CallScriptEffectHandlers(SpellEffIndex effIndex, SpellEffectHandleMode mode); + void CallScriptSuccessfulDispel(SpellEffIndex effIndex); void CallScriptBeforeHitHandlers(); void CallScriptOnHitHandlers(); void CallScriptAfterHitHandlers(); diff --git a/src/server/game/Spells/SpellEffects.cpp b/src/server/game/Spells/SpellEffects.cpp index 1a710eb6df9..7f445791d4e 100644 --- a/src/server/game/Spells/SpellEffects.cpp +++ b/src/server/game/Spells/SpellEffects.cpp @@ -2259,7 +2259,7 @@ void Spell::EffectLearnSpell(SpellEffIndex effIndex) TC_LOG_DEBUG("spells", "Spell: %s has learned spell %u from %s", player->GetGUID().ToString().c_str(), spellToLearn, m_caster->GetGUID().ToString().c_str()); } -void Spell::EffectDispel(SpellEffIndex /*effIndex*/) +void Spell::EffectDispel(SpellEffIndex effIndex) { if (effectHandleMode != SPELL_EFFECT_HANDLE_HIT_TARGET) return; @@ -2351,20 +2351,7 @@ void Spell::EffectDispel(SpellEffIndex /*effIndex*/) } m_caster->SendMessageToSet(&dataSuccess, true); - // On success dispel - // Devour Magic - if (m_spellInfo->SpellFamilyName == SPELLFAMILY_WARLOCK && m_spellInfo->GetCategory() == SPELLCATEGORY_DEVOUR_MAGIC) - { - if (SpellEffectInfo const* effect = GetEffect(EFFECT_1)) - { - int32 heal_amount = effect->CalcValue(m_caster); - m_caster->CastCustomSpell(m_caster, 19658, &heal_amount, NULL, NULL, true); - // Glyph of Felhunter - if (Unit* owner = m_caster->GetOwner()) - if (owner->GetAura(56249)) - owner->CastCustomSpell(owner, 19658, &heal_amount, NULL, NULL, true); - } - } + CallScriptSuccessfulDispel(effIndex); } void Spell::EffectDualWield(SpellEffIndex /*effIndex*/) diff --git a/src/server/game/Spells/SpellScript.cpp b/src/server/game/Spells/SpellScript.cpp index 1d5eab259aa..1bd4d3be5d6 100644 --- a/src/server/game/Spells/SpellScript.cpp +++ b/src/server/game/Spells/SpellScript.cpp @@ -320,6 +320,10 @@ bool SpellScript::_Validate(SpellInfo const* entry) if (!(*itr).GetAffectedEffectsMask(entry)) TC_LOG_ERROR("scripts", "Spell `%u` Effect `%s` of script `%s` did not match dbc effect data - handler bound to hook `OnEffectHitTarget` of SpellScript won't be executed", entry->Id, (*itr).ToString().c_str(), m_scriptName->c_str()); + for (std::list<EffectHandler>::iterator itr = OnEffectSuccessfulDispel.begin(); itr != OnEffectSuccessfulDispel.end(); ++itr) + if (!(*itr).GetAffectedEffectsMask(entry)) + TC_LOG_ERROR("scripts", "Spell `%u` Effect `%s` of script `%s` did not match dbc effect data - handler bound to hook `OnEffectSuccessfulDispel` of SpellScript won't be executed", entry->Id, (*itr).ToString().c_str(), m_scriptName->c_str()); + for (std::list<ObjectAreaTargetSelectHandler>::iterator itr = OnObjectAreaTargetSelect.begin(); itr != OnObjectAreaTargetSelect.end(); ++itr) if (!(*itr).GetAffectedEffectsMask(entry)) TC_LOG_ERROR("scripts", "Spell `%u` Effect `%s` of script `%s` did not match dbc effect data - handler bound to hook `OnObjectAreaTargetSelect` of SpellScript won't be executed", entry->Id, (*itr).ToString().c_str(), m_scriptName->c_str()); diff --git a/src/server/game/Spells/SpellScript.h b/src/server/game/Spells/SpellScript.h index ba25a056ee8..0e4c78283bd 100644 --- a/src/server/game/Spells/SpellScript.h +++ b/src/server/game/Spells/SpellScript.h @@ -130,6 +130,7 @@ enum SpellScriptHookType SPELL_SCRIPT_HOOK_EFFECT_LAUNCH_TARGET, SPELL_SCRIPT_HOOK_EFFECT_HIT, SPELL_SCRIPT_HOOK_EFFECT_HIT_TARGET, + SPELL_SCRIPT_HOOK_EFFECT_SUCCESSFUL_DISPEL, SPELL_SCRIPT_HOOK_BEFORE_HIT, SPELL_SCRIPT_HOOK_HIT, SPELL_SCRIPT_HOOK_AFTER_HIT, @@ -292,6 +293,7 @@ class SpellScript : public _SpellScript HookList<EffectHandler> OnEffectLaunchTarget; HookList<EffectHandler> OnEffectHit; HookList<EffectHandler> OnEffectHitTarget; + HookList<EffectHandler> OnEffectSuccessfulDispel; #define SpellEffectFn(F, I, N) EffectHandlerFunction(&F, I, N) // example: BeforeHit += SpellHitFn(class::function); @@ -334,6 +336,9 @@ class SpellScript : public _SpellScript // 11. OnHit - executed just before spell deals damage and procs auras - when spell hits target - called for each target from spell target map // 12. AfterHit - executed just after spell finishes all it's jobs for target - called for each target from spell target map + // this hook is only executed after a successful dispel of any aura + // OnEffectSuccessfulDispel - executed just after effect successfully dispelled aura(s) + // // methods allowing interaction with Spell object // diff --git a/src/server/game/Texts/ChatTextBuilder.h b/src/server/game/Texts/ChatTextBuilder.h index 1cab1f3576c..6e7a5738394 100644 --- a/src/server/game/Texts/ChatTextBuilder.h +++ b/src/server/game/Texts/ChatTextBuilder.h @@ -32,9 +32,9 @@ namespace Trinity void operator()(WorldPacket& data, LocaleConstant locale) { - BroadcastText const* bct = sObjectMgr->GetBroadcastText(_textId); + BroadcastTextEntry const* bct = sBroadcastTextStore.LookupEntry(_textId); WorldPackets::Chat::Chat packet; - packet.Initalize(_msgType, bct ? Language(bct->Language) : LANG_UNIVERSAL, _source, _target, bct ? bct->GetText(locale, _source->getGender()) : "", _achievementId, "", locale); + packet.Initalize(_msgType, bct ? Language(bct->Language) : LANG_UNIVERSAL, _source, _target, bct ? GetBroadcastTextValue(bct, locale, _source->getGender()) : "", _achievementId, "", locale); packet.Write(); data = packet.Move(); } diff --git a/src/server/game/Texts/CreatureTextMgr.cpp b/src/server/game/Texts/CreatureTextMgr.cpp index 7f299c57c21..16a1bde5a96 100644 --- a/src/server/game/Texts/CreatureTextMgr.cpp +++ b/src/server/game/Texts/CreatureTextMgr.cpp @@ -146,7 +146,7 @@ void CreatureTextMgr::LoadCreatureTexts() if (temp.BroadcastTextId) { - if (!sObjectMgr->GetBroadcastText(temp.BroadcastTextId)) + if (!sBroadcastTextStore.LookupEntry(temp.BroadcastTextId)) { TC_LOG_ERROR("sql.sql", "CreatureTextMgr: Entry %u, Group %u, Id %u in table `creature_text` has non-existing or incompatible BroadcastTextId %u.", temp.entry, temp.group, temp.id, temp.BroadcastTextId); temp.BroadcastTextId = 0; @@ -499,10 +499,10 @@ std::string CreatureTextMgr::GetLocalizedChatString(uint32 entry, uint8 gender, locale = DEFAULT_LOCALE; std::string baseText = ""; - BroadcastText const* bct = sObjectMgr->GetBroadcastText(groupItr->BroadcastTextId); + BroadcastTextEntry const* bct = sBroadcastTextStore.LookupEntry(groupItr->BroadcastTextId); if (bct) - baseText = bct->GetText(locale, gender); + baseText = GetBroadcastTextValue(bct, locale, gender); else baseText = groupItr->text; diff --git a/src/server/game/World/World.cpp b/src/server/game/World/World.cpp index a3ee2fa1265..7f0ea4cd583 100644 --- a/src/server/game/World/World.cpp +++ b/src/server/game/World/World.cpp @@ -722,6 +722,11 @@ void World::LoadConfigSettings(bool reload) m_int_configs[CONFIG_MIN_PET_NAME] = 2; } + m_int_configs[CONFIG_CHARTER_COST_GUILD] = sConfigMgr->GetIntDefault("Guild.CharterCost", 1000); + m_int_configs[CONFIG_CHARTER_COST_ARENA_2v2] = sConfigMgr->GetIntDefault("ArenaTeam.CharterCost.2v2", 800000); + m_int_configs[CONFIG_CHARTER_COST_ARENA_3v3] = sConfigMgr->GetIntDefault("ArenaTeam.CharterCost.3v3", 1200000); + m_int_configs[CONFIG_CHARTER_COST_ARENA_5v5] = sConfigMgr->GetIntDefault("ArenaTeam.CharterCost.5v5", 2000000); + m_int_configs[CONFIG_CHARACTER_CREATING_DISABLED] = sConfigMgr->GetIntDefault("CharacterCreating.Disabled", 0); m_int_configs[CONFIG_CHARACTER_CREATING_DISABLED_RACEMASK] = sConfigMgr->GetIntDefault("CharacterCreating.Disabled.RaceMask", 0); m_int_configs[CONFIG_CHARACTER_CREATING_DISABLED_CLASSMASK] = sConfigMgr->GetIntDefault("CharacterCreating.Disabled.ClassMask", 0); @@ -1440,10 +1445,6 @@ void World::SetInitialWorldSettings() TC_LOG_INFO("server.loading", "Loading instances..."); sInstanceSaveMgr->LoadInstances(); - TC_LOG_INFO("server.loading", "Loading Broadcast texts..."); - sObjectMgr->LoadBroadcastTexts(); - sObjectMgr->LoadBroadcastTextLocales(); - TC_LOG_INFO("server.loading", "Loading Localization strings..."); uint32 oldMSTime = getMSTime(); sObjectMgr->LoadCreatureLocales(); @@ -1923,9 +1924,6 @@ void World::SetInitialWorldSettings() TC_LOG_INFO("misc", "Loading hotfix info..."); sObjectMgr->LoadHotfixData(); - TC_LOG_INFO("server.loading", "Loading missing KeyChains..."); - sObjectMgr->LoadMissingKeyChains(); - TC_LOG_INFO("server.loading", "Loading race and class expansion requirements..."); sObjectMgr->LoadRaceAndClassExpansionRequirements(); diff --git a/src/server/game/World/World.h b/src/server/game/World/World.h index 79723c540ab..7f583da894b 100644 --- a/src/server/game/World/World.h +++ b/src/server/game/World/World.h @@ -363,6 +363,10 @@ enum WorldIntConfigs CONFIG_CREATURE_PICKPOCKET_REFILL, CONFIG_AHBOT_UPDATE_INTERVAL, CONFIG_FEATURE_SYSTEM_CHARACTER_UNDELETE_COOLDOWN, + CONFIG_CHARTER_COST_GUILD, + CONFIG_CHARTER_COST_ARENA_2v2, + CONFIG_CHARTER_COST_ARENA_3v3, + CONFIG_CHARTER_COST_ARENA_5v5, INT_CONFIG_VALUE_COUNT }; diff --git a/src/server/scripts/Commands/cs_reload.cpp b/src/server/scripts/Commands/cs_reload.cpp index a25c6bbcb59..5ade8708703 100644 --- a/src/server/scripts/Commands/cs_reload.cpp +++ b/src/server/scripts/Commands/cs_reload.cpp @@ -76,7 +76,6 @@ public: { "areatrigger_teleport", rbac::RBAC_PERM_COMMAND_RELOAD_AREATRIGGER_TELEPORT, true, &HandleReloadAreaTriggerTeleportCommand, "", NULL }, { "autobroadcast", rbac::RBAC_PERM_COMMAND_RELOAD_AUTOBROADCAST, true, &HandleReloadAutobroadcastCommand, "", NULL }, { "battleground_template", rbac::RBAC_PERM_COMMAND_RELOAD_BATTLEGROUND_TEMPLATE, true, &HandleReloadBattlegroundTemplate, "", NULL }, - { "broadcast_text", rbac::RBAC_PERM_COMMAND_RELOAD_BROADCAST_TEXT, true, &HandleReloadBroadcastTextCommand, "", NULL }, { "command", rbac::RBAC_PERM_COMMAND_RELOAD_COMMAND, true, &HandleReloadCommandCommand, "", NULL }, { "conditions", rbac::RBAC_PERM_COMMAND_RELOAD_CONDITIONS, true, &HandleReloadConditions, "", NULL }, { "config", rbac::RBAC_PERM_COMMAND_RELOAD_CONFIG, true, &HandleReloadConfigCommand, "", NULL }, @@ -381,15 +380,6 @@ public: return true; } - static bool HandleReloadBroadcastTextCommand(ChatHandler* handler, const char* /*args*/) - { - TC_LOG_INFO("misc", "Re-Loading Broadcast texts..."); - sObjectMgr->LoadBroadcastTexts(); - sObjectMgr->LoadBroadcastTextLocales(); - handler->SendGlobalGMSysMessage("DB table `broadcast_text` reloaded."); - return true; - } - static bool HandleReloadCommandCommand(ChatHandler* handler, const char* /*args*/) { handler->SetLoadCommandTable(true); diff --git a/src/server/scripts/Northrend/Nexus/Nexus/boss_anomalus.cpp b/src/server/scripts/Northrend/Nexus/Nexus/boss_anomalus.cpp index e61cfdae328..627f6d33622 100644 --- a/src/server/scripts/Northrend/Nexus/Nexus/boss_anomalus.cpp +++ b/src/server/scripts/Northrend/Nexus/Nexus/boss_anomalus.cpp @@ -100,21 +100,21 @@ class boss_anomalus : public CreatureScript { Initialize(); - instance->SetData(DATA_ANOMALUS_EVENT, NOT_STARTED); + instance->SetBossState(DATA_ANOMALUS, NOT_STARTED); } void EnterCombat(Unit* /*who*/) override { Talk(SAY_AGGRO); - instance->SetData(DATA_ANOMALUS_EVENT, IN_PROGRESS); + instance->SetBossState(DATA_ANOMALUS, IN_PROGRESS); } void JustDied(Unit* /*killer*/) override { Talk(SAY_DEATH); - instance->SetData(DATA_ANOMALUS_EVENT, DONE); + instance->SetBossState(DATA_ANOMALUS, DONE); } uint32 GetData(uint32 type) const override diff --git a/src/server/scripts/Northrend/Nexus/Nexus/boss_keristrasza.cpp b/src/server/scripts/Northrend/Nexus/Nexus/boss_keristrasza.cpp index 6b3df5ef665..a8ffb1d542e 100644 --- a/src/server/scripts/Northrend/Nexus/Nexus/boss_keristrasza.cpp +++ b/src/server/scripts/Northrend/Nexus/Nexus/boss_keristrasza.cpp @@ -101,7 +101,7 @@ public: RemovePrison(CheckContainmentSpheres()); - instance->SetData(DATA_KERISTRASZA_EVENT, NOT_STARTED); + instance->SetBossState(DATA_KERISTRASZA, NOT_STARTED); } void EnterCombat(Unit* /*who*/) override @@ -109,14 +109,14 @@ public: Talk(SAY_AGGRO); DoCastAOE(SPELL_INTENSE_COLD); - instance->SetData(DATA_KERISTRASZA_EVENT, IN_PROGRESS); + instance->SetBossState(DATA_KERISTRASZA, IN_PROGRESS); } void JustDied(Unit* /*killer*/) override { Talk(SAY_DEATH); - instance->SetData(DATA_KERISTRASZA_EVENT, DONE); + instance->SetBossState(DATA_KERISTRASZA, DONE); } void KilledUnit(Unit* who) override diff --git a/src/server/scripts/Northrend/Nexus/Nexus/boss_magus_telestra.cpp b/src/server/scripts/Northrend/Nexus/Nexus/boss_magus_telestra.cpp index 8c58a65cdbe..1df5f5eac8f 100644 --- a/src/server/scripts/Northrend/Nexus/Nexus/boss_magus_telestra.cpp +++ b/src/server/scripts/Northrend/Nexus/Nexus/boss_magus_telestra.cpp @@ -31,7 +31,9 @@ enum Spells SPELL_FIRE_MAGUS_VISUAL = 47705, SPELL_FROST_MAGUS_VISUAL = 47706, - SPELL_ARCANE_MAGUS_VISUAL = 47704 + SPELL_ARCANE_MAGUS_VISUAL = 47704, + + SPELL_WEAR_CHRISTMAS_HAT = 61400 }; enum Creatures @@ -53,7 +55,9 @@ enum Yells enum Misc { ACTION_MAGUS_DEAD = 1, - DATA_SPLIT_PERSONALITY = 2 + DATA_SPLIT_PERSONALITY = 2, + + GAME_EVENT_WINTER_VEIL = 2, }; const Position CenterOfRoom = {504.80f, 89.07f, -16.12f, 6.27f}; @@ -128,21 +132,24 @@ public: me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); me->SetVisible(true); - instance->SetData(DATA_MAGUS_TELESTRA_EVENT, NOT_STARTED); + instance->SetBossState(DATA_MAGUS_TELESTRA, NOT_STARTED); + + if (IsHeroic() && sGameEventMgr->IsActiveEvent(GAME_EVENT_WINTER_VEIL) && !me->HasAura(SPELL_WEAR_CHRISTMAS_HAT)) + me->AddAura(SPELL_WEAR_CHRISTMAS_HAT, me); } void EnterCombat(Unit* /*who*/) override { Talk(SAY_AGGRO); - instance->SetData(DATA_MAGUS_TELESTRA_EVENT, IN_PROGRESS); + instance->SetBossState(DATA_MAGUS_TELESTRA, IN_PROGRESS); } void JustDied(Unit* /*killer*/) override { Talk(SAY_DEATH); - instance->SetData(DATA_MAGUS_TELESTRA_EVENT, DONE); + instance->SetBossState(DATA_MAGUS_TELESTRA, DONE); } void KilledUnit(Unit* who) override diff --git a/src/server/scripts/Northrend/Nexus/Nexus/boss_ormorok.cpp b/src/server/scripts/Northrend/Nexus/Nexus/boss_ormorok.cpp index 84523c1864d..f065f0679fc 100644 --- a/src/server/scripts/Northrend/Nexus/Nexus/boss_ormorok.cpp +++ b/src/server/scripts/Northrend/Nexus/Nexus/boss_ormorok.cpp @@ -68,7 +68,7 @@ public: struct boss_ormorokAI : public BossAI { - boss_ormorokAI(Creature* creature) : BossAI(creature, DATA_ORMOROK_EVENT) + boss_ormorokAI(Creature* creature) : BossAI(creature, DATA_ORMOROK) { Initialize(); } @@ -95,8 +95,6 @@ public: events.ScheduleEvent(EVENT_CRYSTALLINE_TANGLER, 17000); Talk(SAY_AGGRO); - - instance->SetData(DATA_ORMOROK_EVENT, IN_PROGRESS); } void DamageTaken(Unit* /*attacker*/, uint32& /*damage*/) override @@ -112,10 +110,7 @@ public: void JustDied(Unit* /*killer*/) override { _JustDied(); - Talk(SAY_DEATH); - - instance->SetData(DATA_ORMOROK_EVENT, DONE); } void KilledUnit(Unit* who) override @@ -138,27 +133,27 @@ public: { switch (eventId) { - case EVENT_TRAMPLE: - DoCast(me, SPELL_TRAMPLE); - events.ScheduleEvent(EVENT_TRAMPLE, 10000); - break; - case EVENT_SPELL_REFLECTION: - Talk(SAY_REFLECT); - DoCast(me, SPELL_SPELL_REFLECTION); - events.ScheduleEvent(EVENT_SPELL_REFLECTION, 30000); - break; - case EVENT_CRYSTAL_SPIKES: - Talk(SAY_CRYSTAL_SPIKES); - DoCast(SPELL_CRYSTAL_SPIKES); - events.ScheduleEvent(EVENT_CRYSTAL_SPIKES, 12000); - break; - case EVENT_CRYSTALLINE_TANGLER: - if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, OrmorokTanglerPredicate(me))) - DoCast(target, SPELL_SUMMON_CRYSTALLINE_TANGLER); - events.ScheduleEvent(EVENT_CRYSTALLINE_TANGLER, 17000); - break; - default: - break; + case EVENT_TRAMPLE: + DoCast(me, SPELL_TRAMPLE); + events.ScheduleEvent(EVENT_TRAMPLE, 10000); + break; + case EVENT_SPELL_REFLECTION: + Talk(SAY_REFLECT); + DoCast(me, SPELL_SPELL_REFLECTION); + events.ScheduleEvent(EVENT_SPELL_REFLECTION, 30000); + break; + case EVENT_CRYSTAL_SPIKES: + Talk(SAY_CRYSTAL_SPIKES); + DoCast(SPELL_CRYSTAL_SPIKES); + events.ScheduleEvent(EVENT_CRYSTAL_SPIKES, 12000); + break; + case EVENT_CRYSTALLINE_TANGLER: + if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, OrmorokTanglerPredicate(me))) + DoCast(target, SPELL_SUMMON_CRYSTALLINE_TANGLER); + events.ScheduleEvent(EVENT_CRYSTALLINE_TANGLER, 17000); + break; + default: + break; } } diff --git a/src/server/scripts/Northrend/Nexus/Nexus/instance_nexus.cpp b/src/server/scripts/Northrend/Nexus/Nexus/instance_nexus.cpp index b7f2e23616b..b3b2cdd540f 100644 --- a/src/server/scripts/Northrend/Nexus/Nexus/instance_nexus.cpp +++ b/src/server/scripts/Northrend/Nexus/Nexus/instance_nexus.cpp @@ -18,10 +18,8 @@ #include "ScriptMgr.h" #include "InstanceScript.h" -#include "nexus.h" #include "Player.h" - -#define NUMBER_OF_ENCOUNTERS 4 +#include "nexus.h" enum Factions { @@ -30,229 +28,163 @@ enum Factions class instance_nexus : public InstanceMapScript { -public: - instance_nexus() : InstanceMapScript("instance_nexus", 576) { } - - InstanceScript* GetInstanceScript(InstanceMap* map) const override - { - return new instance_nexus_InstanceMapScript(map); - } + public: + instance_nexus() : InstanceMapScript(NexusScriptName, 576) { } - struct instance_nexus_InstanceMapScript : public InstanceScript - { - instance_nexus_InstanceMapScript(Map* map) : InstanceScript(map) + struct instance_nexus_InstanceMapScript : public InstanceScript { - SetHeaders(DataHeader); - memset(&m_auiEncounter, 0, sizeof(m_auiEncounter)); - } - - uint32 m_auiEncounter[NUMBER_OF_ENCOUNTERS]; - - ObjectGuid Anomalus; - ObjectGuid Keristrasza; - - ObjectGuid AnomalusContainmentSphere; - ObjectGuid OrmoroksContainmentSphere; - ObjectGuid TelestrasContainmentSphere; - - std::string strInstData; - - void OnCreatureCreate(Creature* creature) override - { - Map::PlayerList const &players = instance->GetPlayers(); - uint32 TeamInInstance = 0; - - if (!players.isEmpty()) + instance_nexus_InstanceMapScript(Map* map) : InstanceScript(map) { - if (Player* player = players.begin()->GetSource()) - TeamInInstance = player->GetTeam(); + SetHeaders(DataHeader); + SetBossNumber(EncounterCount); + _teamInInstance = 0; } - switch (creature->GetEntry()) + + void OnPlayerEnter(Player* player) override { - case 26763: - Anomalus = creature->GetGUID(); - break; - case 26723: - Keristrasza = creature->GetGUID(); - break; - // Alliance npcs are spawned by default, if you are alliance, you will fight against horde npcs. - case 26800: - { - if (ServerAllowsTwoSideGroups()) - creature->setFaction(FACTION_HOSTILE_FOR_ALL); - if (TeamInInstance == ALLIANCE) - creature->UpdateEntry(26799); - break; - } - case 26802: - { - if (ServerAllowsTwoSideGroups()) - creature->setFaction(FACTION_HOSTILE_FOR_ALL); - if (TeamInInstance == ALLIANCE) - creature->UpdateEntry(26801); - break; - } - case 26805: - { - if (ServerAllowsTwoSideGroups()) - creature->setFaction(FACTION_HOSTILE_FOR_ALL); - if (TeamInInstance == ALLIANCE) - creature->UpdateEntry(26803); - break; - } - case 27949: - { - if (ServerAllowsTwoSideGroups()) - creature->setFaction(FACTION_HOSTILE_FOR_ALL); - if (TeamInInstance == ALLIANCE) - creature->UpdateEntry(27947); - break; - } - case 26796: - { - if (ServerAllowsTwoSideGroups()) - creature->setFaction(FACTION_HOSTILE_FOR_ALL); - if (TeamInInstance == ALLIANCE) - creature->UpdateEntry(26798); - break; - } + if (!_teamInInstance) + _teamInInstance = player->GetTeam(); } - } - void OnGameObjectCreate(GameObject* go) override - { - switch (go->GetEntry()) + void OnCreatureCreate(Creature* creature) override { - case 188527: - { - AnomalusContainmentSphere = go->GetGUID(); - if (m_auiEncounter[1] == DONE) - go->RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_NOT_SELECTABLE); - break; - } - case 188528: - { - OrmoroksContainmentSphere = go->GetGUID(); - if (m_auiEncounter[2] == DONE) - go->RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_NOT_SELECTABLE); - break; - } - case 188526: + switch (creature->GetEntry()) { - TelestrasContainmentSphere = go->GetGUID(); - if (m_auiEncounter[0] == DONE) - go->RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_NOT_SELECTABLE); - break; + case NPC_ANOMALUS: + AnomalusGUID = creature->GetGUID(); + break; + case NPC_KERISTRASZA: + KeristraszaGUID = creature->GetGUID(); + break; + // Alliance npcs are spawned by default, if you are alliance, you will fight against horde npcs. + case NPC_ALLIANCE_BERSERKER: + if (ServerAllowsTwoSideGroups()) + creature->setFaction(FACTION_HOSTILE_FOR_ALL); + if (_teamInInstance == ALLIANCE) + creature->UpdateEntry(NPC_HORDE_BERSERKER); + break; + case NPC_ALLIANCE_RANGER: + if (ServerAllowsTwoSideGroups()) + creature->setFaction(FACTION_HOSTILE_FOR_ALL); + if (_teamInInstance == ALLIANCE) + creature->UpdateEntry(NPC_HORDE_RANGER); + break; + case NPC_ALLIANCE_CLERIC: + if (ServerAllowsTwoSideGroups()) + creature->setFaction(FACTION_HOSTILE_FOR_ALL); + if (_teamInInstance == ALLIANCE) + creature->UpdateEntry(NPC_HORDE_CLERIC); + break; + case NPC_ALLIANCE_COMMANDER: + if (ServerAllowsTwoSideGroups()) + creature->setFaction(FACTION_HOSTILE_FOR_ALL); + if (_teamInInstance == ALLIANCE) + creature->UpdateEntry(NPC_HORDE_COMMANDER); + break; + case NPC_COMMANDER_STOUTBEARD: + if (ServerAllowsTwoSideGroups()) + creature->setFaction(FACTION_HOSTILE_FOR_ALL); + if (_teamInInstance == ALLIANCE) + creature->UpdateEntry(NPC_COMMANDER_KOLURG); + break; + default: + break; } } - } - - uint32 GetData(uint32 identifier) const override - { - switch (identifier) - { - case DATA_MAGUS_TELESTRA_EVENT: return m_auiEncounter[0]; - case DATA_ANOMALUS_EVENT: return m_auiEncounter[1]; - case DATA_ORMOROK_EVENT: return m_auiEncounter[2]; - case DATA_KERISTRASZA_EVENT: return m_auiEncounter[3]; - } - return 0; - } - void SetData(uint32 identifier, uint32 data) override - { - switch (identifier) + void OnGameObjectCreate(GameObject* go) override { - case DATA_MAGUS_TELESTRA_EVENT: + switch (go->GetEntry()) { - if (data == DONE) - { - GameObject* Sphere = instance->GetGameObject(TelestrasContainmentSphere); - if (Sphere) - Sphere->RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_NOT_SELECTABLE); - } - m_auiEncounter[0] = data; - break; + case GO_ANOMALUS_CONTAINMET_SPHERE: + AnomalusContainmentSphere = go->GetGUID(); + if (GetBossState(DATA_ANOMALUS) == DONE) + go->RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_NOT_SELECTABLE); + break; + case GO_ORMOROKS_CONTAINMET_SPHERE: + OrmoroksContainmentSphere = go->GetGUID(); + if (GetBossState(DATA_ORMOROK) == DONE) + go->RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_NOT_SELECTABLE); + break; + case GO_TELESTRAS_CONTAINMET_SPHERE: + TelestrasContainmentSphere = go->GetGUID(); + if (GetBossState(DATA_MAGUS_TELESTRA) == DONE) + go->RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_NOT_SELECTABLE); + break; + default: + break; } - case DATA_ANOMALUS_EVENT: - { - if (data == DONE) - { - if (GameObject* Sphere = instance->GetGameObject(AnomalusContainmentSphere)) - Sphere->RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_NOT_SELECTABLE); - } - m_auiEncounter[1] = data; - break; - } - case DATA_ORMOROK_EVENT: - { - if (data == DONE) - { - if (GameObject* Sphere = instance->GetGameObject(OrmoroksContainmentSphere)) - Sphere->RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_NOT_SELECTABLE); - } - m_auiEncounter[2] = data; - break; - } - case DATA_KERISTRASZA_EVENT: - m_auiEncounter[3] = data; - break; } - if (data == DONE) + bool SetBossState(uint32 type, EncounterState state) override { - OUT_SAVE_INST_DATA; - - std::ostringstream saveStream; - saveStream << m_auiEncounter[0] << ' ' << m_auiEncounter[1] << ' ' << m_auiEncounter[2] << ' ' - << m_auiEncounter[3]; + if (!InstanceScript::SetBossState(type, state)) + return false; - strInstData = saveStream.str(); + switch (type) + { + case DATA_MAGUS_TELESTRA: + if (state == DONE) + { + if (GameObject* sphere = instance->GetGameObject(TelestrasContainmentSphere)) + sphere->RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_NOT_SELECTABLE); + } + break; + case DATA_ANOMALUS: + if (state == DONE) + { + if (GameObject* sphere = instance->GetGameObject(AnomalusContainmentSphere)) + sphere->RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_NOT_SELECTABLE); + } + break; + case DATA_ORMOROK: + if (state == DONE) + { + if (GameObject* sphere = instance->GetGameObject(OrmoroksContainmentSphere)) + sphere->RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_NOT_SELECTABLE); + } + break; + default: + break; + } - SaveToDB(); - OUT_SAVE_INST_DATA_COMPLETE; + return true; } - } - ObjectGuid GetGuidData(uint32 uiIdentifier) const override - { - switch (uiIdentifier) + ObjectGuid GetGuidData(uint32 type) const override { - case DATA_ANOMALUS: return Anomalus; - case DATA_KERISTRASZA: return Keristrasza; - case ANOMALUS_CONTAINMET_SPHERE: return AnomalusContainmentSphere; - case ORMOROKS_CONTAINMET_SPHERE: return OrmoroksContainmentSphere; - case TELESTRAS_CONTAINMET_SPHERE: return TelestrasContainmentSphere; - } - return ObjectGuid::Empty; - } - - std::string GetSaveData() override - { - return strInstData; - } + switch (type) + { + case DATA_ANOMALUS: + return AnomalusGUID; + case DATA_KERISTRASZA: + return KeristraszaGUID; + case ANOMALUS_CONTAINMET_SPHERE: + return AnomalusContainmentSphere; + case ORMOROKS_CONTAINMET_SPHERE: + return OrmoroksContainmentSphere; + case TELESTRAS_CONTAINMET_SPHERE: + return TelestrasContainmentSphere; + default: + break; + } - void Load(const char *chrIn) - { - if (!chrIn) - { - OUT_LOAD_INST_DATA_FAIL; - return; + return ObjectGuid::Empty; } - OUT_LOAD_INST_DATA(chrIn); - - std::istringstream loadStream(chrIn); - loadStream >> m_auiEncounter[0] >> m_auiEncounter[1] >> m_auiEncounter[2] >> m_auiEncounter[3]; + private: + ObjectGuid AnomalusGUID; + ObjectGuid KeristraszaGUID; + ObjectGuid AnomalusContainmentSphere; + ObjectGuid OrmoroksContainmentSphere; + ObjectGuid TelestrasContainmentSphere; + uint32 _teamInInstance; + }; - for (uint8 i = 0; i < NUMBER_OF_ENCOUNTERS; ++i) - if (m_auiEncounter[i] == IN_PROGRESS) - m_auiEncounter[i] = NOT_STARTED; - - OUT_LOAD_INST_DATA_COMPLETE; + InstanceScript* GetInstanceScript(InstanceMap* map) const override + { + return new instance_nexus_InstanceMapScript(map); } - }; - }; void AddSC_instance_nexus() diff --git a/src/server/scripts/Northrend/Nexus/Nexus/nexus.h b/src/server/scripts/Northrend/Nexus/Nexus/nexus.h index c9f5d44c932..9962b0c884d 100644 --- a/src/server/scripts/Northrend/Nexus/Nexus/nexus.h +++ b/src/server/scripts/Northrend/Nexus/Nexus/nexus.h @@ -18,21 +18,48 @@ #ifndef DEF_NEXUS_H #define DEF_NEXUS_H +#define NexusScriptName "instance_nexus" #define DataHeader "NEX" +uint32 const EncounterCount = 4; + enum DataTypes { - DATA_MAGUS_TELESTRA_EVENT, - DATA_ANOMALUS_EVENT, - DATA_ORMOROK_EVENT, - DATA_KERISTRASZA_EVENT, + DATA_MAGUS_TELESTRA = 0, + DATA_ANOMALUS = 1, + DATA_ORMOROK = 2, + DATA_KERISTRASZA = 3, + + ANOMALUS_CONTAINMET_SPHERE = 4, + ORMOROKS_CONTAINMET_SPHERE = 5, + TELESTRAS_CONTAINMET_SPHERE = 6 +}; - DATA_ANOMALUS, - DATA_KERISTRASZA, +enum CreatureIds +{ + NPC_ANOMALUS = 26763, + NPC_KERISTRASZA = 26723, + + // Alliance + NPC_ALLIANCE_BERSERKER = 26800, + NPC_ALLIANCE_RANGER = 26802, + NPC_ALLIANCE_CLERIC = 26805, + NPC_ALLIANCE_COMMANDER = 27949, + NPC_COMMANDER_STOUTBEARD = 26796, + + // Horde + NPC_HORDE_BERSERKER = 26799, + NPC_HORDE_RANGER = 26801, + NPC_HORDE_CLERIC = 26803, + NPC_HORDE_COMMANDER = 27947, + NPC_COMMANDER_KOLURG = 26798 +}; - ANOMALUS_CONTAINMET_SPHERE, - ORMOROKS_CONTAINMET_SPHERE, - TELESTRAS_CONTAINMET_SPHERE +enum GameObjectIds +{ + GO_ANOMALUS_CONTAINMET_SPHERE = 188527, + GO_ORMOROKS_CONTAINMET_SPHERE = 188528, + GO_TELESTRAS_CONTAINMET_SPHERE = 188526 }; #endif diff --git a/src/server/scripts/Spells/spell_warlock.cpp b/src/server/scripts/Spells/spell_warlock.cpp index 5e745f6ab00..fba40986c31 100644 --- a/src/server/scripts/Spells/spell_warlock.cpp +++ b/src/server/scripts/Spells/spell_warlock.cpp @@ -46,7 +46,9 @@ enum WarlockSpells SPELL_WARLOCK_DEMON_SOUL_FELGUARD = 79452, SPELL_WARLOCK_DEMON_SOUL_SUCCUBUS = 79453, SPELL_WARLOCK_DEMON_SOUL_VOIDWALKER = 79454, + SPELL_WARLOCK_DEVOUR_MAGIC_HEAL = 19658, SPELL_WARLOCK_FEL_SYNERGY_HEAL = 54181, + SPELL_WARLOCK_GLYPH_OF_DEMON_TRAINING = 56249, SPELL_WARLOCK_GLYPH_OF_SHADOWFLAME = 63311, SPELL_WARLOCK_GLYPH_OF_SIPHON_LIFE = 63106, SPELL_WARLOCK_GLYPH_OF_SOUL_SWAP = 56226, @@ -525,6 +527,53 @@ class spell_warl_demonic_empowerment : public SpellScriptLoader } }; +// 67518, 19505 - Devour Magic +class spell_warl_devour_magic : public SpellScriptLoader +{ + public: + spell_warl_devour_magic() : SpellScriptLoader("spell_warl_devour_magic") { } + + class spell_warl_devour_magic_SpellScript : public SpellScript + { + PrepareSpellScript(spell_warl_devour_magic_SpellScript); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + if (!sSpellMgr->GetSpellInfo(SPELL_WARLOCK_GLYPH_OF_DEMON_TRAINING)) + return false; + if (!sSpellMgr->GetSpellInfo(SPELL_WARLOCK_DEVOUR_MAGIC_HEAL)) + return false; + return true; + } + + void OnSuccessfulDispel(SpellEffIndex /*effIndex*/) + { + if (SpellEffectInfo const* effect = GetSpellInfo()->GetEffect(EFFECT_1)) + { + Unit* caster = GetCaster(); + int32 heal_amount = effect->CalcValue(caster); + + caster->CastCustomSpell(caster, SPELL_WARLOCK_DEVOUR_MAGIC_HEAL, &heal_amount, nullptr, nullptr, true); + + // Glyph of Felhunter + if (Unit* owner = caster->GetOwner()) + if (owner->GetAura(SPELL_WARLOCK_GLYPH_OF_DEMON_TRAINING)) + owner->CastCustomSpell(owner, SPELL_WARLOCK_DEVOUR_MAGIC_HEAL, &heal_amount, nullptr, nullptr, true); + } + } + + void Register() override + { + OnEffectSuccessfulDispel += SpellEffectFn(spell_warl_devour_magic_SpellScript::OnSuccessfulDispel, EFFECT_0, SPELL_EFFECT_DISPEL); + } + }; + + SpellScript* GetSpellScript() const override + { + return new spell_warl_devour_magic_SpellScript(); + } +}; + // 47422 - Everlasting Affliction /// Updated 4.3.4 class spell_warl_everlasting_affliction : public SpellScriptLoader @@ -1413,6 +1462,7 @@ void AddSC_warlock_spell_scripts() new spell_warl_demonic_circle_teleport(); new spell_warl_demonic_empowerment(); new spell_warl_demon_soul(); + new spell_warl_devour_magic(); new spell_warl_everlasting_affliction(); //new spell_warl_fel_flame(); new spell_warl_fel_synergy(); diff --git a/src/server/shared/DataStores/DB2FileLoader.cpp b/src/server/shared/DataStores/DB2StorageLoader.cpp index 7a27072dd20..f716b9e805e 100644 --- a/src/server/shared/DataStores/DB2FileLoader.cpp +++ b/src/server/shared/DataStores/DB2StorageLoader.cpp @@ -16,11 +16,12 @@ */ #include "Common.h" +#include "DB2StorageLoader.h" +#include "Database/DatabaseEnv.h" -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include "DB2FileLoader.h" +#include <cstdio> +#include <cstdlib> +#include <cstring> DB2FileLoader::DB2FileLoader() { @@ -221,10 +222,10 @@ uint32 DB2FileLoader::GetFormatRecordSize(const char * format, int32* index_pos) return recordsize; } -uint32 DB2FileLoader::GetFormatStringsFields(const char * format) +uint32 DB2FileLoader::GetFormatStringFieldCount(char const* format) { uint32 stringfields = 0; - for (uint32 x=0; format[x]; ++x) + for (uint32 x = 0; format[x]; ++x) if (format[x] == FT_STRING) ++stringfields; @@ -233,23 +234,22 @@ uint32 DB2FileLoader::GetFormatStringsFields(const char * format) char* DB2FileLoader::AutoProduceData(const char* format, uint32& records, char**& indexTable) { - typedef char * ptr; if (strlen(format) != fieldCount) return NULL; //get struct size and index pos - int32 i; - uint32 recordsize=GetFormatRecordSize(format, &i); + int32 indexField; + uint32 recordsize = GetFormatRecordSize(format, &indexField); - if (i >= 0) + if (indexField >= 0) { uint32 maxi = 0; //find max index for (uint32 y = 0; y < recordCount; y++) { - uint32 ind=getRecord(y).getUInt(i); - if (ind>maxi) + uint32 ind = getRecord(y).getUInt(indexField); + if (ind > maxi) maxi = ind; } @@ -266,14 +266,12 @@ char* DB2FileLoader::AutoProduceData(const char* format, uint32& records, char** char* dataTable = new char[recordCount * recordsize]; - uint32 offset=0; + uint32 offset = 0; - for (uint32 y =0; y < recordCount; y++) + for (uint32 y = 0; y < recordCount; y++) { - if (i>=0) - { - indexTable[getRecord(y).getUInt(i)] = &dataTable[offset]; - } + if (indexField >= 0) + indexTable[getRecord(y).getUInt(indexField)] = &dataTable[offset]; else indexTable[y] = &dataTable[offset]; @@ -310,10 +308,13 @@ static char const* const nullStr = ""; char* DB2FileLoader::AutoProduceStringsArrayHolders(const char* format, char* dataTable) { if (strlen(format) != fieldCount) - return NULL; + return nullptr; // we store flat holders pool as single memory block - size_t stringFields = GetFormatStringsFields(format); + size_t stringFields = GetFormatStringFieldCount(format); + if (!stringFields) + return nullptr; + // each string field at load have array of string for each locale size_t stringHolderSize = sizeof(char*) * TOTAL_LOCALES; size_t stringHoldersRecordPoolSize = stringFields * stringHolderSize; @@ -325,7 +326,7 @@ char* DB2FileLoader::AutoProduceStringsArrayHolders(const char* format, char* da for (size_t i = 0; i < stringHoldersPoolSize / sizeof(char*); ++i) ((char const**)stringHoldersPool)[i] = nullStr; - uint32 offset=0; + uint32 offset = 0; // assign string holders to string field slots for (uint32 y = 0; y < recordCount; y++) @@ -333,6 +334,7 @@ char* DB2FileLoader::AutoProduceStringsArrayHolders(const char* format, char* da uint32 stringFieldNum = 0; for (uint32 x = 0; x < fieldCount; x++) + { switch (format[x]) { case FT_FLOAT: @@ -357,7 +359,8 @@ char* DB2FileLoader::AutoProduceStringsArrayHolders(const char* format, char* da case FT_SORT: break; default: - assert(false && "unknown format character"); + ASSERT(false, "unknown format character %c", format[x]); + } } } @@ -370,39 +373,172 @@ char* DB2FileLoader::AutoProduceStrings(const char* format, char* dataTable, uin if (strlen(format) != fieldCount) return NULL; - char* stringPool= new char[stringSize]; + char* stringPool = new char[stringSize]; memcpy(stringPool, stringTable, stringSize); uint32 offset = 0; - for (uint32 y =0; y < recordCount; y++) + for (uint32 y = 0; y < recordCount; y++) { for (uint32 x = 0; x < fieldCount; x++) - switch (format[x]) { - case FT_FLOAT: - case FT_IND: - case FT_INT: - offset += 4; - break; - case FT_BYTE: - offset += 1; - break; - case FT_STRING: + switch (format[x]) { - // fill only not filled entries - LocalizedString* db2str = *(LocalizedString**)(&dataTable[offset]); - if (db2str->Str[locale] == nullStr) + case FT_FLOAT: + case FT_IND: + case FT_INT: + offset += 4; + break; + case FT_BYTE: + offset += 1; + break; + case FT_STRING: { - const char * st = getRecord(y).getString(x); - db2str->Str[locale] = stringPool + (st - (const char*)stringTable); - } + // fill only not filled entries + LocalizedString* db2str = *(LocalizedString**)(&dataTable[offset]); + if (db2str->Str[locale] == nullStr) + { + const char * st = getRecord(y).getString(x); + db2str->Str[locale] = stringPool + (st - (const char*)stringTable); + } - offset += sizeof(char*); - break; + offset += sizeof(char*); + break; + } } } } return stringPool; } + +char* DB2DatabaseLoader::Load(const char* format, int32 preparedStatement, uint32& records, char**& indexTable, char*& stringHolders, std::list<char*>& stringPool) +{ + // Even though this query is executed only once, prepared statement is used to send data from mysql server in binary format + PreparedQueryResult result = HotfixDatabase.Query(HotfixDatabase.GetPreparedStatement(preparedStatement)); + if (!result) + return nullptr; + + // we store flat holders pool as single memory block + size_t stringFields = DB2FileLoader::GetFormatStringFieldCount(format); + + size_t expectedFields = strlen(format) + 1 /*VerifiedBuild*/; + if (stringFields) + expectedFields += 1 /*ID*/ + stringFields * (TOTAL_LOCALES - 1) + 1 /*VerifiedBuild in locale table*/; + + if (expectedFields != result->GetFieldCount()) + return nullptr; + + //get struct size and index pos + int32 indexField; + uint32 recordSize = DB2FileLoader::GetFormatRecordSize(format, &indexField); + + // each string field at load have array of string for each locale + size_t stringHolderSize = sizeof(char*) * TOTAL_LOCALES; + size_t stringHoldersRecordPoolSize = stringFields * stringHolderSize; + + if (stringFields) + { + size_t stringHoldersPoolSize = stringHoldersRecordPoolSize * result->GetRowCount(); + stringHolders = new char[stringHoldersPoolSize]; + + // DB2 strings expected to have at least empty string + for (size_t i = 0; i < stringHoldersPoolSize / sizeof(char*); ++i) + ((char const**)stringHolders)[i] = nullStr; + + } + else + stringHolders = nullptr; + + std::unordered_map<uint32, char*> tempIndexTable; + tempIndexTable.reserve(result->GetRowCount()); + char* dataTable = new char[result->GetRowCount() * recordSize]; + uint32 offset = 0; + + uint32 const fieldCount = strlen(format); + uint32 const localeFieldsOffset = fieldCount + 2 /*VerifiedBuild in main table, ID in locale table*/; + uint32 oldIndexSize = records; + uint32 rec = 0; + do + { + Field* fields = result->Fetch(); + uint32 stringFieldNumInRecord = 0; + + if (indexField >= 0) + { + uint32 indexValue = fields[indexField].GetUInt32(); + tempIndexTable[indexValue] = &dataTable[offset]; + if (records <= indexValue) + records = indexValue + 1; + } + else + tempIndexTable[records++] = &dataTable[offset]; + + for (uint32 f = 0; f < fieldCount; f++) + { + switch (format[f]) + { + case FT_FLOAT: + *((float*)(&dataTable[offset])) = fields[f].GetFloat(); + offset += 4; + break; + case FT_IND: + case FT_INT: + *((int32*)(&dataTable[offset])) = fields[f].GetInt32(); + offset += 4; + break; + case FT_BYTE: + *((int8*)(&dataTable[offset])) = fields[f].GetInt8(); + offset += 1; + break; + case FT_STRING: + { + LocalizedString** slot = (LocalizedString**)(&dataTable[offset]); + *slot = (LocalizedString*)(&stringHolders[stringHoldersRecordPoolSize * rec++ + stringHolderSize * stringFieldNumInRecord]); + + // Value in database in main table field must be for enUS locale + if (char* str = AddLocaleString(*slot, LOCALE_enUS, fields[f].GetString())) + stringPool.push_back(str); + + for (uint32 locale = LOCALE_koKR; locale < TOTAL_LOCALES; ++locale) + if (char* str = AddLocaleString(*slot, locale, fields[localeFieldsOffset + (locale - 1) + stringFields * stringFieldNumInRecord].GetString())) + stringPool.push_back(str); + + ++stringFieldNumInRecord; + offset += sizeof(char*); + break; + } + } + } + } while (result->NextRow()); + + // Reallocate index if needed + if (records > oldIndexSize) + { + char** tmpIdxTable = new char*[records]; + memset(tmpIdxTable, 0, records * sizeof(char*)); + memcpy(tmpIdxTable, indexTable, oldIndexSize * sizeof(char*)); + delete[] indexTable; + indexTable = tmpIdxTable; + } + + // Merge new data into index + for (auto itr = tempIndexTable.begin(); itr != tempIndexTable.end(); ++itr) + indexTable[itr->first] = itr->second; + + return dataTable; +} + +char* DB2DatabaseLoader::AddLocaleString(LocalizedString* holder, uint32 locale, std::string const& value) +{ + if (!value.empty()) + { + char* str = new char[value.length() + 1]; + memcpy(str, value.c_str(), value.length()); + str[value.length()] = '\0'; + holder->Str[locale] = str; + return str; + } + + return nullptr; +} diff --git a/src/server/shared/DataStores/DB2FileLoader.h b/src/server/shared/DataStores/DB2StorageLoader.h index 86350ebf1d6..4254fcc1121 100644 --- a/src/server/shared/DataStores/DB2FileLoader.h +++ b/src/server/shared/DataStores/DB2StorageLoader.h @@ -82,7 +82,7 @@ class DB2FileLoader char* AutoProduceStringsArrayHolders(const char* fmt, char* dataTable); char* AutoProduceStrings(const char* fmt, char* dataTable, uint32 locale); static uint32 GetFormatRecordSize(const char * format, int32 * index_pos = NULL); - static uint32 GetFormatStringsFields(const char * format); + static uint32 GetFormatStringFieldCount(const char * format); private: uint32 recordSize; @@ -104,4 +104,12 @@ private: int unk5; // WDB2 }; -#endif
\ No newline at end of file +class DB2DatabaseLoader +{ +public: + + char* Load(const char* format, int32 preparedStatement, uint32& records, char**& indexTable, char*& stringHolders, std::list<char*>& stringPool); + static char* AddLocaleString(LocalizedString* holder, uint32 locale, std::string const& value); +}; + +#endif diff --git a/src/server/shared/DataStores/DB2Store.h b/src/server/shared/DataStores/DB2Store.h index 77d6c4144e5..c8f42d6d4e7 100644 --- a/src/server/shared/DataStores/DB2Store.h +++ b/src/server/shared/DataStores/DB2Store.h @@ -18,7 +18,7 @@ #ifndef DB2STORE_H #define DB2STORE_H -#include "DB2FileLoader.h" +#include "DB2StorageLoader.h" #include "Common.h" #include "ByteBuffer.h" #include <vector> @@ -101,12 +101,11 @@ template<class T> class DB2Storage : public DB2StorageBase { typedef std::list<char*> StringPoolList; - typedef std::vector<T*> DataTableEx; typedef bool(*EntryChecker)(DB2Storage<T> const&, uint32); typedef void(*PacketWriter)(DB2Storage<T> const&, uint32, uint32, ByteBuffer&); public: - DB2Storage(char const* f, EntryChecker checkEntry = NULL, PacketWriter writePacket = NULL) : - nCount(0), fieldCount(0), fmt(f), m_dataTable(NULL) + DB2Storage(char const* f, int32 preparedStmtIndex = -1, EntryChecker checkEntry = nullptr, PacketWriter writePacket = nullptr) + : nCount(0), fieldCount(0), fmt(f), m_dataTable(nullptr), m_dataTableEx(nullptr), _hotfixStatement(preparedStmtIndex) { indexTable.asT = NULL; CheckEntry = checkEntry ? checkEntry : (EntryChecker)&DB2StorageHasEntry<T>; @@ -125,30 +124,6 @@ public: WritePacket(*this, id, locale, buffer); } - T* CreateEntry(uint32 id, bool evenIfExists = false) - { - if (evenIfExists && LookupEntry(id)) - return NULL; - - if (id >= nCount) - { - // reallocate index table - char** tmpIdxTable = new char*[id + 1]; - memset(tmpIdxTable, 0, (id + 1) * sizeof(char*)); - memcpy(tmpIdxTable, indexTable.asChar, nCount * sizeof(char*)); - delete[] reinterpret_cast<char*>(indexTable.asT); - nCount = id + 1; - indexTable.asChar = tmpIdxTable; - } - - T* entryDst = new T; - m_dataTableEx.push_back(entryDst); - indexTable.asT[id] = entryDst; - return entryDst; - } - - void EraseEntry(uint32 id) { indexTable.asT[id] = NULL; } - bool Load(char const* fn, uint32 locale) { DB2FileLoader db2; @@ -163,10 +138,13 @@ public: m_dataTable = reinterpret_cast<T*>(db2.AutoProduceData(fmt, nCount, indexTable.asChar)); // create string holders for loaded string fields - m_stringPoolList.push_back(db2.AutoProduceStringsArrayHolders(fmt, (char*)m_dataTable)); + if (char* stringHolders = db2.AutoProduceStringsArrayHolders(fmt, (char*)m_dataTable)) + { + m_stringPoolList.push_back(stringHolders); - // load strings from dbc data - m_stringPoolList.push_back(db2.AutoProduceStrings(fmt, (char*)m_dataTable, locale)); + // load strings from dbc data + m_stringPoolList.push_back(db2.AutoProduceStrings(fmt, (char*)m_dataTable, locale)); + } // error in dbc file at loading if NULL return indexTable.asT != NULL; @@ -184,25 +162,40 @@ public: return false; // load strings from another locale dbc data - m_stringPoolList.push_back(db2.AutoProduceStrings(fmt, (char*)m_dataTable, locale)); + if (DB2FileLoader::GetFormatStringFieldCount(fmt)) + m_stringPoolList.push_back(db2.AutoProduceStrings(fmt, (char*)m_dataTable, locale)); return true; } + void LoadSQLData() + { + if (_hotfixStatement == -1) + return; + + DB2DatabaseLoader db2; + char* extraStringHolders = nullptr; + if (char* dataTable = db2.Load(fmt, _hotfixStatement, nCount, indexTable.asChar, extraStringHolders, m_stringPoolList)) + { + m_dataTableEx = reinterpret_cast<T*>(dataTable); + if (extraStringHolders) + m_stringPoolList.push_back(extraStringHolders); + } + } + void Clear() { if (!indexTable.asT) return; delete[] reinterpret_cast<char*>(indexTable.asT); - indexTable.asT = NULL; + indexTable.asT = nullptr; delete[] reinterpret_cast<char*>(m_dataTable); - m_dataTable = NULL; + m_dataTable = nullptr; - for (typename DataTableEx::iterator itr = m_dataTableEx.begin(); itr != m_dataTableEx.end(); ++itr) - delete *itr; - m_dataTableEx.clear(); + delete[] reinterpret_cast<char*>(m_dataTableEx); + m_dataTableEx = nullptr; while (!m_stringPoolList.empty()) { @@ -226,8 +219,9 @@ private: char** asChar; } indexTable; T* m_dataTable; - DataTableEx m_dataTableEx; + T* m_dataTableEx; StringPoolList m_stringPoolList; + int32 _hotfixStatement; }; #endif diff --git a/src/server/shared/Database/Implementation/HotfixDatabase.cpp b/src/server/shared/Database/Implementation/HotfixDatabase.cpp index f60287ef1a7..aa35580676e 100644 --- a/src/server/shared/Database/Implementation/HotfixDatabase.cpp +++ b/src/server/shared/Database/Implementation/HotfixDatabase.cpp @@ -21,4 +21,7 @@ void HotfixDatabaseConnection::DoPrepareStatements() { if (!m_reconnecting) m_stmts.resize(MAX_HOTFIXDATABASE_STATEMENTS); + + PrepareStatement(HOTFIX_SEL_BROADCAST_TEXT, "SELECT * FROM broadcast_text b LEFT JOIN locales_broadcast_text lb ON b.ID = lb.ID", CONNECTION_SYNCH); + PrepareStatement(HOTFIX_SEL_TAXI_PATH_NODE, "SELECT * FROM taxi_path_node", CONNECTION_SYNCH); } diff --git a/src/server/shared/Database/Implementation/HotfixDatabase.h b/src/server/shared/Database/Implementation/HotfixDatabase.h index 13c3af6714e..56ab6b8c48a 100644 --- a/src/server/shared/Database/Implementation/HotfixDatabase.h +++ b/src/server/shared/Database/Implementation/HotfixDatabase.h @@ -42,6 +42,8 @@ enum HotfixDatabaseStatements name for a suiting suffix. */ + HOTFIX_SEL_BROADCAST_TEXT, + HOTFIX_SEL_TAXI_PATH_NODE, MAX_HOTFIXDATABASE_STATEMENTS }; diff --git a/src/server/shared/Database/Implementation/LoginDatabase.cpp b/src/server/shared/Database/Implementation/LoginDatabase.cpp index 4d0d4df2003..d509939b2b5 100644 --- a/src/server/shared/Database/Implementation/LoginDatabase.cpp +++ b/src/server/shared/Database/Implementation/LoginDatabase.cpp @@ -29,24 +29,16 @@ void LoginDatabaseConnection::DoPrepareStatements() PrepareStatement(LOGIN_INS_IP_AUTO_BANNED, "INSERT INTO ip_banned (ip, bandate, unbandate, bannedby, banreason) VALUES (?, UNIX_TIMESTAMP(), UNIX_TIMESTAMP()+?, 'Trinity Auth', 'Failed login autoban')", CONNECTION_ASYNC); PrepareStatement(LOGIN_SEL_IP_BANNED_ALL, "SELECT ip, bandate, unbandate, bannedby, banreason FROM ip_banned WHERE (bandate = unbandate OR unbandate > UNIX_TIMESTAMP()) ORDER BY unbandate", CONNECTION_SYNCH); PrepareStatement(LOGIN_SEL_IP_BANNED_BY_IP, "SELECT ip, bandate, unbandate, bannedby, banreason FROM ip_banned WHERE (bandate = unbandate OR unbandate > UNIX_TIMESTAMP()) AND ip LIKE CONCAT('%%', ?, '%%') ORDER BY unbandate", CONNECTION_SYNCH); - PrepareStatement(LOGIN_SEL_ACCOUNT_BANNED, "SELECT bandate, unbandate FROM account_banned WHERE id = ? AND active = 1", CONNECTION_SYNCH); PrepareStatement(LOGIN_SEL_ACCOUNT_BANNED_ALL, "SELECT account.id, username FROM account, account_banned WHERE account.id = account_banned.id AND active = 1 GROUP BY account.id", CONNECTION_SYNCH); PrepareStatement(LOGIN_SEL_ACCOUNT_BANNED_BY_USERNAME, "SELECT account.id, username FROM account, account_banned WHERE account.id = account_banned.id AND active = 1 AND username LIKE CONCAT('%%', ?, '%%') GROUP BY account.id", CONNECTION_SYNCH); - PrepareStatement(LOGIN_INS_ACCOUNT_AUTO_BANNED, "INSERT INTO account_banned VALUES (?, UNIX_TIMESTAMP(), UNIX_TIMESTAMP()+?, 'Trinity Auth', 'Failed login autoban', 1)", CONNECTION_ASYNC); PrepareStatement(LOGIN_DEL_ACCOUNT_BANNED, "DELETE FROM account_banned WHERE id = ?", CONNECTION_ASYNC); - PrepareStatement(LOGIN_SEL_SESSIONKEY, "SELECT a.sessionkey, a.id, aa.gmlevel FROM account a LEFT JOIN account_access aa ON (a.id = aa.id) WHERE username = ?", CONNECTION_SYNCH); PrepareStatement(LOGIN_SEL_ACCOUNT_INFO_CONTINUED_SESSION, "SELECT username, sessionkey FROM account WHERE id = ?", CONNECTION_SYNCH); PrepareStatement(LOGIN_UPD_VS, "UPDATE account SET v = ?, s = ? WHERE username = ?", CONNECTION_ASYNC); - PrepareStatement(LOGIN_UPD_LOGONPROOF, "UPDATE account SET sessionkey = ?, last_ip = ?, last_login = NOW(), locale = ?, failed_logins = 0, os = ? WHERE username = ?", CONNECTION_SYNCH); - PrepareStatement(LOGIN_SEL_LOGONCHALLENGE, "SELECT a.sha_pass_hash, a.id, a.locked, a.lock_country, a.last_ip, aa.gmlevel, a.v, a.s, a.token_key, a.battlenet_account FROM account a LEFT JOIN account_access aa ON (a.id = aa.id) WHERE a.username = ?", CONNECTION_SYNCH); PrepareStatement(LOGIN_SEL_LOGON_COUNTRY, "SELECT country FROM ip2nation WHERE ip < ? ORDER BY ip DESC LIMIT 0,1", CONNECTION_SYNCH); - PrepareStatement(LOGIN_UPD_FAILEDLOGINS, "UPDATE account SET failed_logins = failed_logins + 1 WHERE username = ?", CONNECTION_ASYNC); - PrepareStatement(LOGIN_SEL_FAILEDLOGINS, "SELECT id, failed_logins FROM account WHERE username = ?", CONNECTION_SYNCH); PrepareStatement(LOGIN_SEL_ACCOUNT_ID_BY_NAME, "SELECT id FROM account WHERE username = ?", CONNECTION_SYNCH); PrepareStatement(LOGIN_SEL_ACCOUNT_LIST_BY_NAME, "SELECT id, username FROM account WHERE username = ?", CONNECTION_SYNCH); PrepareStatement(LOGIN_SEL_ACCOUNT_INFO_BY_NAME, "SELECT id, sessionkey, last_ip, locked, expansion, mutetime, locale, recruiter, os FROM account WHERE username = ?", CONNECTION_SYNCH); PrepareStatement(LOGIN_SEL_ACCOUNT_LIST_BY_EMAIL, "SELECT id, username FROM account WHERE email = ?", CONNECTION_SYNCH); - PrepareStatement(LOGIN_SEL_NUM_CHARS_ON_REALM, "SELECT numchars FROM realmcharacters WHERE realmid = ? AND acctid= ?", CONNECTION_SYNCH); PrepareStatement(LOGIN_SEL_ACCOUNT_BY_IP, "SELECT id, username FROM account WHERE last_ip = ?", CONNECTION_SYNCH); PrepareStatement(LOGIN_SEL_ACCOUNT_BY_ID, "SELECT 1 FROM account WHERE id = ?", CONNECTION_SYNCH); PrepareStatement(LOGIN_INS_IP_BANNED, "INSERT INTO ip_banned (ip, bandate, unbandate, bannedby, banreason) VALUES (?, UNIX_TIMESTAMP(), UNIX_TIMESTAMP()+?, ?, ?)", CONNECTION_ASYNC); diff --git a/src/server/shared/Database/Implementation/LoginDatabase.h b/src/server/shared/Database/Implementation/LoginDatabase.h index 3667b65e885..7da24b57781 100644 --- a/src/server/shared/Database/Implementation/LoginDatabase.h +++ b/src/server/shared/Database/Implementation/LoginDatabase.h @@ -47,24 +47,16 @@ enum LoginDatabaseStatements LOGIN_UPD_EXPIRED_ACCOUNT_BANS, LOGIN_SEL_IP_BANNED, LOGIN_INS_IP_AUTO_BANNED, - LOGIN_SEL_ACCOUNT_BANNED, LOGIN_SEL_ACCOUNT_BANNED_ALL, LOGIN_SEL_ACCOUNT_BANNED_BY_USERNAME, - LOGIN_INS_ACCOUNT_AUTO_BANNED, LOGIN_DEL_ACCOUNT_BANNED, - LOGIN_SEL_SESSIONKEY, LOGIN_SEL_ACCOUNT_INFO_CONTINUED_SESSION, LOGIN_UPD_VS, - LOGIN_UPD_LOGONPROOF, - LOGIN_SEL_LOGONCHALLENGE, LOGIN_SEL_LOGON_COUNTRY, - LOGIN_UPD_FAILEDLOGINS, - LOGIN_SEL_FAILEDLOGINS, LOGIN_SEL_ACCOUNT_ID_BY_NAME, LOGIN_SEL_ACCOUNT_LIST_BY_NAME, LOGIN_SEL_ACCOUNT_INFO_BY_NAME, LOGIN_SEL_ACCOUNT_LIST_BY_EMAIL, - LOGIN_SEL_NUM_CHARS_ON_REALM, LOGIN_SEL_ACCOUNT_BY_IP, LOGIN_INS_IP_BANNED, LOGIN_DEL_IP_NOT_BANNED, diff --git a/src/server/worldserver/worldserver.conf.dist b/src/server/worldserver/worldserver.conf.dist index 1aefbfa13de..11c081bea44 100644 --- a/src/server/worldserver/worldserver.conf.dist +++ b/src/server/worldserver/worldserver.conf.dist @@ -597,6 +597,22 @@ MinCharterName = 2 MinPetName = 2 # +# Guild.CharterCost +# ArenaTeam.CharterCost.2v2 +# ArenaTeam.CharterCost.3v3 +# ArenaTeam.CharterCost.5v5 +# Description: Amount of money (in Copper) the petitions costs. +# Default: 1000 - (10 Silver) +# 800000 - (80 Gold) +# 1200000 - (120 Gold) +# 2000000 - (200 Gold) + +Guild.CharterCost = 1000 +ArenaTeam.CharterCost.2v2 = 800000 +ArenaTeam.CharterCost.3v3 = 1200000 +ArenaTeam.CharterCost.5v5 = 2000000 + +# # MaxWhoListReturns # Description: Set the max number of players returned in the /who list and interface. # Default: 49 - (stable) |