aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/server/bnetserver/Realms/WorldListener.cpp20
-rw-r--r--src/server/bnetserver/Server/Session.cpp2
-rw-r--r--src/server/bnetserver/Server/Session.h4
-rw-r--r--src/server/bnetserver/Server/SessionManager.cpp6
-rw-r--r--src/server/game/AuctionHouseBot/AuctionHouseBotSeller.cpp20
-rw-r--r--src/server/game/DataStores/DB2Stores.cpp22
-rw-r--r--src/server/game/DataStores/DB2Stores.h2
-rw-r--r--src/server/game/DataStores/DB2Structure.h14
-rw-r--r--src/server/game/DataStores/DB2fmt.h1
-rw-r--r--src/server/game/Entities/Creature/GossipDef.cpp8
-rw-r--r--src/server/game/Entities/Item/Item.cpp8
-rw-r--r--src/server/game/Entities/Player/Player.cpp8
-rw-r--r--src/server/game/Entities/Unit/Unit.cpp6
-rw-r--r--src/server/game/Globals/ObjectMgr.cpp184
-rw-r--r--src/server/game/Globals/ObjectMgr.h57
-rw-r--r--src/server/game/Handlers/PetitionsHandler.cpp24
-rw-r--r--src/server/game/OutdoorPvP/OutdoorPvPMgr.cpp4
-rw-r--r--src/server/game/Spells/Spell.cpp13
-rw-r--r--src/server/game/Spells/Spell.h1
-rw-r--r--src/server/game/Spells/SpellEffects.cpp17
-rw-r--r--src/server/game/Spells/SpellScript.cpp4
-rw-r--r--src/server/game/Spells/SpellScript.h5
-rw-r--r--src/server/game/Texts/ChatTextBuilder.h4
-rw-r--r--src/server/game/Texts/CreatureTextMgr.cpp6
-rw-r--r--src/server/game/World/World.cpp12
-rw-r--r--src/server/game/World/World.h4
-rw-r--r--src/server/scripts/Commands/cs_reload.cpp10
-rw-r--r--src/server/scripts/Northrend/Nexus/Nexus/boss_anomalus.cpp6
-rw-r--r--src/server/scripts/Northrend/Nexus/Nexus/boss_keristrasza.cpp6
-rw-r--r--src/server/scripts/Northrend/Nexus/Nexus/boss_magus_telestra.cpp17
-rw-r--r--src/server/scripts/Northrend/Nexus/Nexus/boss_ormorok.cpp49
-rw-r--r--src/server/scripts/Northrend/Nexus/Nexus/instance_nexus.cpp328
-rw-r--r--src/server/scripts/Northrend/Nexus/Nexus/nexus.h45
-rw-r--r--src/server/scripts/Spells/spell_warlock.cpp50
-rw-r--r--src/server/shared/DataStores/DB2StorageLoader.cpp (renamed from src/server/shared/DataStores/DB2FileLoader.cpp)220
-rw-r--r--src/server/shared/DataStores/DB2StorageLoader.h (renamed from src/server/shared/DataStores/DB2FileLoader.h)12
-rw-r--r--src/server/shared/DataStores/DB2Store.h70
-rw-r--r--src/server/shared/Database/Implementation/HotfixDatabase.cpp3
-rw-r--r--src/server/shared/Database/Implementation/HotfixDatabase.h2
-rw-r--r--src/server/shared/Database/Implementation/LoginDatabase.cpp8
-rw-r--r--src/server/shared/Database/Implementation/LoginDatabase.h8
-rw-r--r--src/server/worldserver/worldserver.conf.dist16
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)