aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/server/game/Achievements/AchievementMgr.cpp14
-rw-r--r--src/server/game/Achievements/AchievementMgr.h2
-rw-r--r--src/server/game/BattleGrounds/BattleGroundMgr.cpp5
-rw-r--r--src/server/game/CMakeLists.txt1
-rw-r--r--src/server/game/Chat/Chat.cpp4
-rw-r--r--src/server/game/Chat/Chat.h5
-rw-r--r--src/server/game/Chat/Commands/Level3.cpp112
-rw-r--r--src/server/game/Conditions/DisableMgr.cpp254
-rw-r--r--src/server/game/Conditions/DisableMgr.h56
-rw-r--r--src/server/game/Entities/Player/Player.cpp29
-rw-r--r--src/server/game/Globals/ObjectMgr.cpp51
-rw-r--r--src/server/game/Globals/ObjectMgr.h9
-rw-r--r--src/server/game/Server/Protocol/Handlers/BattleGroundHandler.cpp13
-rw-r--r--src/server/game/Spells/Spell.cpp30
-rw-r--r--src/server/game/Spells/SpellMgr.h6
-rw-r--r--src/server/game/World/World.cpp24
-rw-r--r--src/server/game/World/World.h3
-rw-r--r--src/server/worldserver/worldserver.conf.dist8
18 files changed, 371 insertions, 255 deletions
diff --git a/src/server/game/Achievements/AchievementMgr.cpp b/src/server/game/Achievements/AchievementMgr.cpp
index bb156c40ca6..c3217a5df02 100644
--- a/src/server/game/Achievements/AchievementMgr.cpp
+++ b/src/server/game/Achievements/AchievementMgr.cpp
@@ -34,6 +34,7 @@
#include "Player.h"
#include "ProgressBar.h"
#include "SpellMgr.h"
+#include "DisableMgr.h"
#include "MapManager.h"
#include "BattleGround.h"
@@ -107,7 +108,6 @@ bool AchievementCriteriaData::IsValid(AchievementCriteriaEntry const* criteria)
{
case ACHIEVEMENT_CRITERIA_DATA_TYPE_NONE:
case ACHIEVEMENT_CRITERIA_DATA_TYPE_VALUE:
- case ACHIEVEMENT_CRITERIA_DATA_TYPE_DISABLED:
case ACHIEVEMENT_CRITERIA_DATA_INSTANCE_SCRIPT:
return true;
case ACHIEVEMENT_CRITERIA_DATA_TYPE_T_CREATURE:
@@ -305,8 +305,6 @@ bool AchievementCriteriaData::Meets(uint32 criteria_id, Player const* source, Un
if (!target)
return false;
return target->getGender() == gender.gender;
- case ACHIEVEMENT_CRITERIA_DATA_TYPE_DISABLED:
- return false; // always fail
case ACHIEVEMENT_CRITERIA_DATA_TYPE_MAP_DIFFICULTY:
return source->GetMap()->GetSpawnMode() == difficulty.difficulty;
case ACHIEVEMENT_CRITERIA_DATA_TYPE_MAP_PLAYER_COUNT:
@@ -715,6 +713,8 @@ void AchievementMgr::UpdateAchievementCriteria(AchievementCriteriaTypes type, ui
for (AchievementCriteriaEntryList::const_iterator i = achievementCriteriaList.begin(); i != achievementCriteriaList.end(); ++i)
{
AchievementCriteriaEntry const *achievementCriteria = (*i);
+ if (sDisableMgr.IsDisabledFor(DISABLE_TYPE_ACHIEVEMENT_CRITERIA, achievementCriteria->ID, NULL))
+ continue;
AchievementEntry const *achievement = sAchievementStore.LookupEntry(achievementCriteria->referredAchievement);
if (!achievement)
@@ -2084,7 +2084,6 @@ void AchievementGlobalMgr::LoadAchievementCriteriaData()
}
uint32 count = 0;
- uint32 disabled_count = 0;
barGoLink bar(result->GetRowCount());
do
{
@@ -2111,9 +2110,6 @@ void AchievementGlobalMgr::LoadAchievementCriteriaData()
AchievementCriteriaDataSet& dataSet = m_criteriaDataMap[criteria_id];
dataSet.SetCriteriaId(criteria_id);
- if (data.dataType == ACHIEVEMENT_CRITERIA_DATA_TYPE_DISABLED)
- ++disabled_count;
-
// add real data only for not NONE data types
if (data.dataType != ACHIEVEMENT_CRITERIA_DATA_TYPE_NONE)
dataSet.Add(data);
@@ -2193,12 +2189,12 @@ void AchievementGlobalMgr::LoadAchievementCriteriaData()
continue;
}
- if (!GetCriteriaDataSet(criteria))
+ if (!GetCriteriaDataSet(criteria) && !sDisableMgr.IsDisabledFor(DISABLE_TYPE_ACHIEVEMENT_CRITERIA, entryId, NULL))
sLog.outErrorDb("Table `achievement_criteria_data` does not have expected data for criteria (Entry: %u Type: %u) for achievement %u.", criteria->ID, criteria->requiredType, criteria->referredAchievement);
}
sLog.outString();
- sLog.outString(">> Loaded %u additional achievement criteria data (%u disabled).",count,disabled_count);
+ sLog.outString(">> Loaded %u additional achievement criteria data.",count);
}
void AchievementGlobalMgr::LoadCompletedAchievements()
diff --git a/src/server/game/Achievements/AchievementMgr.h b/src/server/game/Achievements/AchievementMgr.h
index 0eedf971c20..3da9b7a6024 100644
--- a/src/server/game/Achievements/AchievementMgr.h
+++ b/src/server/game/Achievements/AchievementMgr.h
@@ -53,7 +53,7 @@ enum AchievementCriteriaDataType
ACHIEVEMENT_CRITERIA_DATA_TYPE_VALUE = 8, // minvalue value provided with achievement update must be not less that limit
ACHIEVEMENT_CRITERIA_DATA_TYPE_T_LEVEL = 9, // minlevel minlevel of target
ACHIEVEMENT_CRITERIA_DATA_TYPE_T_GENDER = 10,// gender 0=male; 1=female
- ACHIEVEMENT_CRITERIA_DATA_TYPE_DISABLED = 11,// used to prevent achievement creteria complete if not all requirement implemented and listed in table
+ ACHIEVEMENT_CRITERIA_DATA_TYPE_REUSE = 11,// TO BE REUSED
ACHIEVEMENT_CRITERIA_DATA_TYPE_MAP_DIFFICULTY = 12,// difficulty normal/heroic difficulty for current event map
ACHIEVEMENT_CRITERIA_DATA_TYPE_MAP_PLAYER_COUNT = 13,// count "with less than %u people in the zone"
ACHIEVEMENT_CRITERIA_DATA_TYPE_T_TEAM = 14,// team HORDE(67), ALLIANCE(469)
diff --git a/src/server/game/BattleGrounds/BattleGroundMgr.cpp b/src/server/game/BattleGrounds/BattleGroundMgr.cpp
index 2450cfe6e24..8cf15984c1e 100644
--- a/src/server/game/BattleGrounds/BattleGroundMgr.cpp
+++ b/src/server/game/BattleGrounds/BattleGroundMgr.cpp
@@ -48,6 +48,7 @@
#include "ProgressBar.h"
#include "SharedDefines.h"
#include "Formulas.h"
+#include "DisableMgr.h"
/*********************************************************/
/*** BATTLEGROUND QUEUE SYSTEM ***/
@@ -1707,7 +1708,7 @@ void BattleGroundMgr::CreateInitialBattleGrounds()
uint32 count = 0;
// 0 1 2 3 4 5 6 7 8
- QueryResult_AutoPtr result = WorldDatabase.Query("SELECT id, MinPlayersPerTeam,MaxPlayersPerTeam,MinLvl,MaxLvl,AllianceStartLoc,AllianceStartO,HordeStartLoc,HordeStartO FROM battleground_template WHERE disable = 0");
+ QueryResult_AutoPtr result = WorldDatabase.Query("SELECT id, MinPlayersPerTeam,MaxPlayersPerTeam,MinLvl,MaxLvl,AllianceStartLoc,AllianceStartO,HordeStartLoc,HordeStartO FROM battleground_template");
if (!result)
{
@@ -1728,6 +1729,8 @@ void BattleGroundMgr::CreateInitialBattleGrounds()
bar.step();
uint32 bgTypeID_ = fields[0].GetUInt32();
+ if (sDisableMgr.IsDisabledFor(DISABLE_TYPE_BATTLEGROUND, bgTypeID_, NULL))
+ continue;
// can be overwrite by values from DB
bl = sBattlemasterListStore.LookupEntry(bgTypeID_);
diff --git a/src/server/game/CMakeLists.txt b/src/server/game/CMakeLists.txt
index 3cb646facbe..b500b686fb9 100644
--- a/src/server/game/CMakeLists.txt
+++ b/src/server/game/CMakeLists.txt
@@ -63,6 +63,7 @@ set(game_STAT_SRCS
Combat/HostileRefManager.cpp
Combat/ThreatManager.cpp
Conditions/ConditionMgr.cpp
+ Conditions/DisableMgr.cpp
DataStores/DBCStores.cpp
DungeonFinding/LFGMgr.cpp
Entities/Corpse/Corpse.cpp
diff --git a/src/server/game/Chat/Chat.cpp b/src/server/game/Chat/Chat.cpp
index f62dee975da..42363124518 100644
--- a/src/server/game/Chat/Chat.cpp
+++ b/src/server/game/Chat/Chat.cpp
@@ -278,8 +278,6 @@ ChatCommand * ChatHandler::getCommandTable()
{ "unbind", SEC_ADMINISTRATOR, false, &ChatHandler::HandleInstanceUnbindCommand, "", NULL },
{ "stats", SEC_ADMINISTRATOR, true, &ChatHandler::HandleInstanceStatsCommand, "", NULL },
{ "savedata", SEC_ADMINISTRATOR, false, &ChatHandler::HandleInstanceSaveDataCommand, "", NULL },
- { "open", SEC_ADMINISTRATOR, true, &ChatHandler::HandleInstanceOpenCommand, "", NULL },
- { "close", SEC_ADMINISTRATOR, true, &ChatHandler::HandleInstanceCloseCommand, "", NULL },
{ NULL, 0, false, NULL, "", NULL }
};
@@ -466,6 +464,7 @@ ChatCommand * ChatHandler::getCommandTable()
{ "creature_questrelation", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadCreatureQuestRelationsCommand, "", NULL },
{ "creature_template", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadCreatureTemplateCommand, "", NULL },
//{ "db_script_string", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadDbScriptStringCommand, "", NULL },
+ { "disables", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadDisablesCommand, "", NULL },
{ "disenchant_loot_template", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadLootTemplatesDisenchantCommand, "", NULL },
{ "event_scripts", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadEventScriptsCommand, "", NULL },
{ "fishing_loot_template", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadLootTemplatesFishingCommand, "", NULL },
@@ -522,7 +521,6 @@ ChatCommand * ChatHandler::getCommandTable()
{ "spell_scripts", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadSpellScriptsCommand, "", NULL },
{ "spell_target_position", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadSpellTargetPositionCommand, "", NULL },
{ "spell_threats", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadSpellThreatsCommand, "", NULL },
- { "spell_disabled", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadSpellDisabledCommand, "", NULL },
{ "spell_group_stack_rules", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadSpellGroupStackRulesCommand, "", NULL },
{ "trinity_string", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadTrinityStringCommand, "", NULL },
{ "auctions", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadAuctionsCommand, "", NULL },
diff --git a/src/server/game/Chat/Chat.h b/src/server/game/Chat/Chat.h
index 6b102129c8a..2a653983aa0 100644
--- a/src/server/game/Chat/Chat.h
+++ b/src/server/game/Chat/Chat.h
@@ -234,9 +234,6 @@ class ChatHandler
bool HandleInstanceUnbindCommand(const char* args);
bool HandleInstanceStatsCommand(const char* args);
bool HandleInstanceSaveDataCommand(const char * args);
- bool HandleInstanceOpenCommand(const char * args);
- bool HandleInstanceCloseCommand(const char * args);
- bool HandleInstanceOpenCloseCommand(const char * args, bool open);
bool HandleLearnCommand(const char* args);
bool HandleLearnAllCommand(const char* args);
@@ -428,7 +425,7 @@ class ChatHandler
bool HandleReloadSpellTargetPositionCommand(const char* args);
bool HandleReloadSpellThreatsCommand(const char* args);
bool HandleReloadSpellPetAurasCommand(const char* args);
- bool HandleReloadSpellDisabledCommand(const char* args);
+ bool HandleReloadDisablesCommand(const char* args);
bool HandleReloadSpellGroupStackRulesCommand(const char* args);
bool HandleReloadAuctionsCommand(const char* args);
bool HandleReloadWpScriptsCommand(const char* args);
diff --git a/src/server/game/Chat/Commands/Level3.cpp b/src/server/game/Chat/Commands/Level3.cpp
index 3ddf9b84365..40c3aae5705 100644
--- a/src/server/game/Chat/Commands/Level3.cpp
+++ b/src/server/game/Chat/Commands/Level3.cpp
@@ -56,6 +56,7 @@
#include "SpellAuraEffects.h"
#include "DBCEnums.h"
#include "ConditionMgr.h"
+#include "DisableMgr.h"
bool ChatHandler::HandleAHBotOptionsCommand(const char *args)
{
@@ -661,7 +662,6 @@ bool ChatHandler::HandleReloadAllSpellCommand(const char*)
HandleReloadSpellThreatsCommand("a");
HandleReloadSpellGroupStackRulesCommand("a");
HandleReloadSpellPetAurasCommand("a");
- HandleReloadSpellDisabledCommand("a");
return true;
}
@@ -1463,14 +1463,13 @@ bool ChatHandler::HandleReloadGameTeleCommand(const char* /*arg*/)
return true;
}
-bool ChatHandler::HandleReloadSpellDisabledCommand(const char* /*arg*/)
+bool ChatHandler::HandleReloadDisablesCommand(const char* /*arg*/)
{
- sLog.outString("Re-Loading spell disabled table...");
-
- objmgr.LoadSpellDisabledEntrys();
-
- SendGlobalGMSysMessage("DB table `spell_disabled` reloaded.");
-
+ sLog.outString("Re-Loading disables table...");
+ sDisableMgr.LoadDisables();
+ sLog.outString("Checking quest disables...");
+ sDisableMgr.CheckQuestDisables();
+ SendGlobalGMSysMessage("DB table `disables` reloaded.");
return true;
}
@@ -7051,103 +7050,6 @@ bool ChatHandler::HandleInstanceSaveDataCommand(const char * /*args*/)
return true;
}
-bool ChatHandler::HandleInstanceOpenCommand(const char *args)
-{
- return HandleInstanceOpenCloseCommand(args,true);
-}
-
-bool ChatHandler::HandleInstanceCloseCommand(const char *args)
-{
- return HandleInstanceOpenCloseCommand(args,false);
-}
-
-bool ChatHandler::HandleInstanceOpenCloseCommand(const char *args,bool open)
-{
- char *mapIdStr;
- char *instanceModeStr;
- extractOptFirstArg((char*)args,&mapIdStr,&instanceModeStr);
- if (!mapIdStr || !instanceModeStr)
- return false;
-
- uint32 mapid = atoi(mapIdStr);
-
- InstanceTemplate const* instance = objmgr.GetInstanceTemplate(mapid);
- if (!instance)
- {
- PSendSysMessage("Invalid map id");
- SetSentErrorMessage(true);
- return false;
- }
-
- uint8 status = objmgr.GetAccessRequirement(instance->access_id)->status;
- uint8 flag = 0;
-
- const MapEntry *entry = sMapStore.LookupEntry(mapid);
- if (!entry)
- return false;
-
- if (entry->IsDungeon())
- {
- if (strcmp(instanceModeStr,"normal"))
- flag = DUNGEON_STATUSFLAG_NORMAL;
- else if (strcmp(instanceModeStr,"heroic"))
- flag = DUNGEON_STATUSFLAG_HEROIC;
- else if (strcmp(instanceModeStr,"all"))
- flag = DUNGEON_STATUSFLAG_NORMAL & DUNGEON_STATUSFLAG_HEROIC;
- else
- {
- PSendSysMessage("Unrecognized difficulty string");
- SetSentErrorMessage(true);
- return false;
- }
- }
-
- else if (entry->IsRaid())
- {
- if (strcmp(instanceModeStr,"normal"))
- flag = RAID_STATUSFLAG_10MAN_NORMAL & RAID_STATUSFLAG_25MAN_NORMAL;
- else if (strcmp(instanceModeStr,"heroic"))
- flag = RAID_STATUSFLAG_10MAN_HEROIC & RAID_STATUSFLAG_25MAN_HEROIC;
- else if (strcmp(instanceModeStr,"10man"))
- flag = RAID_STATUSFLAG_10MAN_NORMAL & RAID_STATUSFLAG_10MAN_HEROIC;
- else if (strcmp(instanceModeStr,"25man"))
- flag = RAID_STATUSFLAG_25MAN_NORMAL & RAID_STATUSFLAG_25MAN_HEROIC;
- else if (strcmp(instanceModeStr,"heroic"))
- flag = RAID_STATUSFLAG_10MAN_HEROIC & RAID_STATUSFLAG_25MAN_HEROIC;
- else if (strcmp(instanceModeStr,"10normal"))
- flag = DUNGEON_STATUSFLAG_NORMAL;
- else if (strcmp(instanceModeStr,"25normal"))
- flag = DUNGEON_STATUSFLAG_HEROIC;
- else if (strcmp(instanceModeStr,"10heroic"))
- flag = RAID_STATUSFLAG_10MAN_HEROIC;
- else if (strcmp(instanceModeStr,"25heroic"))
- flag = RAID_STATUSFLAG_25MAN_HEROIC;
- else if (strcmp(instanceModeStr,"all"))
- flag = RAID_STATUSFLAG_10MAN_NORMAL & RAID_STATUSFLAG_10MAN_HEROIC & RAID_STATUSFLAG_25MAN_NORMAL & RAID_STATUSFLAG_25MAN_HEROIC;
- else
- {
- PSendSysMessage("Unrecognized difficulty string");
- SetSentErrorMessage(true);
- return false;
- }
- }
- else
- {
- PSendSysMessage("Map is not a dungeon/raid");
- SetSentErrorMessage(true);
- return false;
- }
-
- if (open)
- status |= flag;
- else
- status &= ~flag;
-
- WorldDatabase.PExecute("UPDATE access_requirement SET status = '%u' WHERE id = '%u'", status, instance->access_id);
- PSendSysMessage("Instance status changed. Don't forget to reload access_requirement table");
- return true;
-}
-
/// Display the list of GMs
bool ChatHandler::HandleGMListFullCommand(const char* /*args*/)
{
diff --git a/src/server/game/Conditions/DisableMgr.cpp b/src/server/game/Conditions/DisableMgr.cpp
new file mode 100644
index 00000000000..6fc935c5cb5
--- /dev/null
+++ b/src/server/game/Conditions/DisableMgr.cpp
@@ -0,0 +1,254 @@
+/*
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
+ *
+ * Copyright (C) 2008-2010 Trinity <http://www.trinitycore.org/>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "ProgressBar.h"
+#include "SpellMgr.h"
+#include "DisableMgr.h"
+
+DisableMgr::DisableMgr()
+{
+}
+
+DisableMgr::~DisableMgr()
+{
+ for (DisableMap::iterator itr = m_DisableMap.begin(); itr != m_DisableMap.end(); ++itr)
+ itr->second.clear();
+ m_DisableMap.clear();
+}
+
+void DisableMgr::LoadDisables()
+{
+ // reload case
+ for (DisableMap::iterator itr = m_DisableMap.begin(); itr != m_DisableMap.end(); ++itr)
+ itr->second.clear();
+ m_DisableMap.clear();
+
+ QueryResult_AutoPtr result = WorldDatabase.Query("SELECT sourceType,entry,flags FROM disables");
+
+ uint32 total_count = 0;
+
+ if (!result)
+ {
+ barGoLink bar(1);
+ bar.step();
+
+ sLog.outString();
+ sLog.outString(">> Loaded %u disables", total_count);
+ return;
+ }
+
+ barGoLink bar(result->GetRowCount());
+
+ Field* fields;
+ do
+ {
+ bar.step();
+ fields = result->Fetch();
+ DisableType type = DisableType(fields[0].GetUInt32());
+ if (type >= MAX_DISABLE_TYPES)
+ {
+ sLog.outErrorDb("Invalid type %u specified in `disables` table, skipped.", type);
+ continue;
+ }
+ uint32 entry = fields[1].GetUInt32();
+ uint8 flags = fields[2].GetUInt8();
+ switch (type)
+ {
+ case DISABLE_TYPE_SPELL:
+ if (!sSpellStore.LookupEntry(entry))
+ {
+ sLog.outErrorDb("Spell entry %u from `disables` doesn't exist in dbc, skipped.", entry);
+ continue;
+ }
+ if (!flags || flags > 7)
+ {
+ sLog.outErrorDb("Disable flags for spell %u are invalid, skipped.", entry);
+ continue;
+ }
+ break;
+ // checked later
+ case DISABLE_TYPE_QUEST:
+ break;
+ case DISABLE_TYPE_MAP:
+ {
+ MapEntry const* mapEntry = sMapStore.LookupEntry(entry);
+ if (!mapEntry)
+ {
+ sLog.outErrorDb("Map entry %u from `disables` doesn't exist in dbc, skipped.", entry);
+ continue;
+ }
+ bool isFlagInvalid = false;
+ switch (mapEntry->map_type)
+ {
+ case MAP_COMMON:
+ if (flags)
+ isFlagInvalid = true;
+ break;
+ case MAP_INSTANCE:
+ case MAP_RAID:
+ if (flags & DUNGEON_STATUSFLAG_HEROIC && !GetMapDifficultyData(entry, DUNGEON_DIFFICULTY_HEROIC))
+ isFlagInvalid = true;
+ else if (flags & RAID_STATUSFLAG_10MAN_HEROIC && !GetMapDifficultyData(entry, RAID_DIFFICULTY_10MAN_HEROIC))
+ isFlagInvalid = true;
+ else if (flags & RAID_STATUSFLAG_25MAN_HEROIC && !GetMapDifficultyData(entry, RAID_DIFFICULTY_25MAN_HEROIC))
+ isFlagInvalid = true;
+ break;
+ case MAP_BATTLEGROUND:
+ case MAP_ARENA:
+ sLog.outErrorDb("Battleground map specified to be disabled in map case, skipped.", entry);
+ continue;
+ }
+ if (isFlagInvalid)
+ {
+ sLog.outErrorDb("Disable flags for map %u are invalid, skipped.", entry);
+ continue;
+ }
+ break;
+ }
+ case DISABLE_TYPE_BATTLEGROUND:
+ if (!sBattlemasterListStore.LookupEntry(entry))
+ {
+ sLog.outErrorDb("Battleground entry %u from `disables` doesn't exist in dbc, skipped.", entry);
+ continue;
+ }
+ if (flags)
+ sLog.outErrorDb("Disable flags specified for battleground %u, useless data.", entry);
+ break;
+ case DISABLE_TYPE_ACHIEVEMENT_CRITERIA:
+ if (!sAchievementCriteriaStore.LookupEntry(entry))
+ {
+ sLog.outErrorDb("Achievement Criteria entry %u from `disables` doesn't exist in dbc, skipped.", entry);
+ continue;
+ }
+ if (flags)
+ sLog.outErrorDb("Disable flags specified for Achievement Criteria %u, useless data.", entry);
+ break;
+ }
+ m_DisableMap[type].insert(DisableTypeMap::value_type(entry, flags));
+ ++total_count;
+ } while (result->NextRow());
+
+ sLog.outString();
+ sLog.outString(">> Loaded %u disables.", total_count);
+}
+
+void DisableMgr::CheckQuestDisables()
+{
+ uint32 count = m_DisableMap[DISABLE_TYPE_QUEST].size();
+ if (!count)
+ {
+ barGoLink bar(1);
+ bar.step();
+ sLog.outString();
+ sLog.outString(">> Done.");
+ return;
+ }
+
+ barGoLink bar(count);
+ // check only quests, rest already done at startup
+ for (DisableTypeMap::iterator itr = m_DisableMap[DISABLE_TYPE_QUEST].begin(); itr != m_DisableMap[DISABLE_TYPE_QUEST].end();)
+ {
+ bar.step();
+ const uint32 entry = itr->first;
+ if (!objmgr.GetQuestTemplate(entry))
+ {
+ sLog.outErrorDb("Quest entry %u from `disables` doesn't exist, skipped.", entry);
+ m_DisableMap[DISABLE_TYPE_QUEST].erase(itr++);
+ continue;
+ }
+ if (itr->second)
+ sLog.outErrorDb("Disable flags specified for quest %u, useless data.", entry);
+ ++itr;
+ }
+
+ sLog.outString();
+ sLog.outString(">> Done.");
+}
+
+bool DisableMgr::IsDisabledFor(DisableType type, uint32 entry, Unit const* pUnit)
+{
+ assert(type < MAX_DISABLE_TYPES);
+ if (m_DisableMap[type].empty())
+ return false;
+
+ DisableTypeMap::iterator itr = m_DisableMap[type].find(entry);
+ if (itr == m_DisableMap[type].end()) // not disabled
+ return false;
+
+ switch (type)
+ {
+ case DISABLE_TYPE_SPELL:
+ {
+ uint8 flags = itr->second;
+ if (flags & SPELL_DISABLE_PLAYER && pUnit->GetTypeId() == TYPEID_PLAYER)
+ return true;
+ else if (pUnit->GetTypeId() == TYPEID_UNIT)
+ {
+ if (pUnit->ToCreature()->isPet())
+ {
+ if (flags & SPELL_DISABLE_PET)
+ return true;
+ }
+ else if (flags & SPELL_DISABLE_CREATURE)
+ return true;
+ }
+ return false;
+ }
+ case DISABLE_TYPE_MAP:
+ if (!pUnit)
+ return true;
+ if (Player const* pPlayer = pUnit->ToPlayer())
+ {
+ MapEntry const* mapEntry = sMapStore.LookupEntry(entry);
+ if (mapEntry->IsDungeon())
+ {
+ uint8 disabledModes = itr->second;
+ switch(mapEntry->IsRaid() ? pPlayer->GetRaidDifficulty() : pPlayer->GetDungeonDifficulty())
+ {
+ case DUNGEON_DIFFICULTY_NORMAL:
+ return disabledModes & DUNGEON_STATUSFLAG_NORMAL;
+ case DUNGEON_DIFFICULTY_HEROIC:
+ return disabledModes & DUNGEON_STATUSFLAG_HEROIC;
+ case RAID_DIFFICULTY_10MAN_HEROIC:
+ return disabledModes & RAID_STATUSFLAG_10MAN_HEROIC;
+ case RAID_DIFFICULTY_25MAN_HEROIC:
+ return disabledModes & RAID_STATUSFLAG_25MAN_HEROIC;
+ }
+ }
+ else if (mapEntry->map_type == MAP_COMMON)
+ return true;
+ }
+ return false;
+ case DISABLE_TYPE_QUEST:
+ if (!pUnit)
+ return true;
+ if (Player const* pPlayer = pUnit->ToPlayer())
+ if (pPlayer->isGameMaster())
+ return false;
+ return true;
+ case DISABLE_TYPE_BATTLEGROUND:
+ case DISABLE_TYPE_ACHIEVEMENT_CRITERIA:
+ return true;
+ default:
+ return false;
+ }
+
+ return false;
+}
diff --git a/src/server/game/Conditions/DisableMgr.h b/src/server/game/Conditions/DisableMgr.h
new file mode 100644
index 00000000000..4bfacccdfb0
--- /dev/null
+++ b/src/server/game/Conditions/DisableMgr.h
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
+ *
+ * Copyright (C) 2008-2010 Trinity <http://www.trinitycore.org/>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef TRINITY_DISABLEMGR_H
+#define TRINITY_DISABLEMGR_H
+
+enum DisableType
+{
+ DISABLE_TYPE_SPELL = 0,
+ DISABLE_TYPE_QUEST = 1,
+ DISABLE_TYPE_MAP = 2,
+ DISABLE_TYPE_BATTLEGROUND = 3,
+ DISABLE_TYPE_ACHIEVEMENT_CRITERIA = 4
+};
+
+#define MAX_DISABLE_TYPES 5
+
+typedef std::map<uint32, uint8> DisableTypeMap; // single disables here with optional data
+typedef std::map<DisableType, DisableTypeMap> DisableMap; // global disable map by source
+
+class DisableMgr
+{
+ friend class ACE_Singleton<DisableMgr, ACE_Null_Mutex>;
+ DisableMgr();
+
+ public:
+ ~DisableMgr();
+
+ void LoadDisables();
+ bool IsDisabledFor(DisableType type, uint32 entry, Unit const* pUnit);
+ void CheckQuestDisables();
+
+ protected:
+ DisableMap m_DisableMap;
+};
+
+#define sDisableMgr (*ACE_Singleton<DisableMgr, ACE_Null_Mutex>::instance())
+
+#endif //TRINITY_DISABLEMGR_H
diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp
index 7a63a794456..e1708528585 100644
--- a/src/server/game/Entities/Player/Player.cpp
+++ b/src/server/game/Entities/Player/Player.cpp
@@ -67,6 +67,7 @@
#include "SpellAuras.h"
#include "SpellAuraEffects.h"
#include "ConditionMgr.h"
+#include "DisableMgr.h"
#include <cmath>
#define ZONE_UPDATE_INTERVAL (1*IN_MILLISECONDS)
@@ -1809,7 +1810,7 @@ bool Player::TeleportTo(uint32 mapid, float x, float y, float z, float orientati
return false;
}
- if ((GetSession()->GetSecurity() < SEC_GAMEMASTER) && !sWorld.IsAllowedMap(mapid))
+ if ((GetSession()->GetSecurity() < SEC_GAMEMASTER) && sDisableMgr.IsDisabledFor(DISABLE_TYPE_MAP, mapid, NULL))
{
sLog.outError("Player %s tried to enter a forbidden map", GetName());
return false;
@@ -13972,7 +13973,8 @@ bool Player::CanSeeStartQuest(Quest const *pQuest)
if (SatisfyQuestRace(pQuest, false) && SatisfyQuestSkillOrClass(pQuest, false) &&
SatisfyQuestExclusiveGroup(pQuest, false) && SatisfyQuestReputation(pQuest, false) &&
SatisfyQuestPreviousQuest(pQuest, false) && SatisfyQuestNextChain(pQuest, false) &&
- SatisfyQuestPrevChain(pQuest, false) && SatisfyQuestDay(pQuest, false) && SatisfyQuestWeek(pQuest, false))
+ SatisfyQuestPrevChain(pQuest, false) && SatisfyQuestDay(pQuest, false) && SatisfyQuestWeek(pQuest, false) &&
+ !sDisableMgr.IsDisabledFor(DISABLE_TYPE_QUEST, pQuest->GetQuestId(), this))
{
return getLevel() + sWorld.getConfig(CONFIG_QUEST_HIGH_LEVEL_HIDE_DIFF) >= pQuest->GetMinLevel();
}
@@ -13987,7 +13989,8 @@ bool Player::CanTakeQuest(Quest const *pQuest, bool msg)
&& SatisfyQuestSkillOrClass(pQuest, msg) && SatisfyQuestReputation(pQuest, msg)
&& SatisfyQuestPreviousQuest(pQuest, msg) && SatisfyQuestTimed(pQuest, msg)
&& SatisfyQuestNextChain(pQuest, msg) && SatisfyQuestPrevChain(pQuest, msg)
- && SatisfyQuestDay(pQuest, msg) && SatisfyQuestWeek(pQuest, msg);
+ && SatisfyQuestDay(pQuest, msg) && SatisfyQuestWeek(pQuest, msg)
+ && !sDisableMgr.IsDisabledFor(DISABLE_TYPE_QUEST, pQuest->GetQuestId(), this);
}
bool Player::CanAddQuest(Quest const *pQuest, bool msg)
@@ -17446,25 +17449,7 @@ bool Player::Satisfy(AccessRequirement const *ar, uint32 target_map, bool report
if (!mapEntry)
return false;
- bool closed = false;
-
- switch(mapEntry->IsRaid() ? GetRaidDifficulty() : GetDungeonDifficulty())
- {
- case DUNGEON_DIFFICULTY_NORMAL:
- closed = (ar->status & DUNGEON_STATUSFLAG_NORMAL) == 0;
- break;
- case DUNGEON_DIFFICULTY_HEROIC:
- closed = (ar->status & DUNGEON_STATUSFLAG_HEROIC) == 0;
- break;
- case RAID_DIFFICULTY_10MAN_HEROIC:
- closed = (ar->status & RAID_STATUSFLAG_10MAN_HEROIC) == 0;
- break;
- case RAID_DIFFICULTY_25MAN_HEROIC:
- closed = (ar->status & RAID_STATUSFLAG_25MAN_HEROIC) == 0;
- break;
- }
-
- if (closed)
+ if (sDisableMgr.IsDisabledFor(DISABLE_TYPE_MAP, target_map, this))
{
GetSession()->SendAreaTriggerMessage(GetSession()->GetTrinityString(LANG_INSTANCE_CLOSED));
return false;
diff --git a/src/server/game/Globals/ObjectMgr.cpp b/src/server/game/Globals/ObjectMgr.cpp
index 71cd4c46b80..b07c9ecc0f5 100644
--- a/src/server/game/Globals/ObjectMgr.cpp
+++ b/src/server/game/Globals/ObjectMgr.cpp
@@ -45,6 +45,7 @@
#include "GossipDef.h"
#include "Vehicle.h"
#include "AchievementMgr.h"
+#include "DisableMgr.h"
ScriptMapMap sQuestEndScripts;
ScriptMapMap sQuestStartScripts;
@@ -3701,6 +3702,10 @@ void ObjectMgr::LoadQuests()
// Post processing
for (QuestMap::iterator iter = mQuestTemplates.begin(); iter != mQuestTemplates.end(); ++iter)
{
+ // skip post-loading checks for disabled quests
+ if (sDisableMgr.IsDisabledFor(DISABLE_TYPE_QUEST, iter->first, NULL))
+ continue;
+
Quest * qinfo = iter->second;
// additional quest integrity checks (GO, creature_template and item_template must be loaded already)
@@ -7574,52 +7579,6 @@ const char *ObjectMgr::GetTrinityString(int32 entry, int locale_idx) const
return "<error>";
}
-void ObjectMgr::LoadSpellDisabledEntrys()
-{
- m_DisabledPlayerSpells.clear(); // need for reload case
- m_DisabledCreatureSpells.clear();
- m_DisabledPetSpells.clear();
- QueryResult_AutoPtr result = WorldDatabase.Query("SELECT entry, disable_mask FROM spell_disabled");
-
- uint32 total_count = 0;
-
- if (!result)
- {
- barGoLink bar(1);
- bar.step();
-
- sLog.outString();
- sLog.outString(">> Loaded %u disabled spells", total_count);
- return;
- }
-
- barGoLink bar(result->GetRowCount());
-
- Field* fields;
- do
- {
- bar.step();
- fields = result->Fetch();
- uint32 spellid = fields[0].GetUInt32();
- if (!sSpellStore.LookupEntry(spellid))
- {
- sLog.outErrorDb("Spell entry %u from `spell_disabled` doesn't exist in dbc, ignoring.",spellid);
- continue;
- }
- uint32 disable_mask = fields[1].GetUInt32();
- if (disable_mask & SPELL_DISABLE_PLAYER)
- m_DisabledPlayerSpells.insert(spellid);
- if (disable_mask & SPELL_DISABLE_CREATURE)
- m_DisabledCreatureSpells.insert(spellid);
- if (disable_mask & SPELL_DISABLE_PET)
- m_DisabledPetSpells.insert(spellid);
- ++total_count;
- } while (result->NextRow());
-
- sLog.outString();
- sLog.outString(">> Loaded %u disabled spells from `spell_disabled`", total_count);
-}
-
void ObjectMgr::LoadFishingBaseSkillLevel()
{
mFishingBaseForArea.clear(); // for reload case
diff --git a/src/server/game/Globals/ObjectMgr.h b/src/server/game/Globals/ObjectMgr.h
index 7b7e0e2bdb9..e02fe438c5c 100644
--- a/src/server/game/Globals/ObjectMgr.h
+++ b/src/server/game/Globals/ObjectMgr.h
@@ -837,11 +837,6 @@ class ObjectMgr
static bool CheckDeclinedNames(std::wstring mainpart, DeclinedName const& names);
- void LoadSpellDisabledEntrys();
- bool IsPlayerSpellDisabled(uint32 spellid) { return (m_DisabledPlayerSpells.count(spellid) != 0); }
- bool IsCreatureSpellDisabled(uint32 spellid) { return (m_DisabledCreatureSpells.count(spellid) != 0); }
- bool IsPetSpellDisabled(uint32 spellid) { return (m_DisabledPetSpells.count(spellid) != 0); }
-
int GetIndexForLocale(LocaleConstant loc);
LocaleConstant GetLocaleForIndex(int i);
@@ -999,10 +994,6 @@ class ObjectMgr
typedef std::set<std::wstring> ReservedNamesMap;
ReservedNamesMap m_ReservedNames;
- std::set<uint32> m_DisabledPlayerSpells;
- std::set<uint32> m_DisabledCreatureSpells;
- std::set<uint32> m_DisabledPetSpells;
-
// GraveYardMap mGraveYardMap;
GameTeleMap m_GameTeleMap;
diff --git a/src/server/game/Server/Protocol/Handlers/BattleGroundHandler.cpp b/src/server/game/Server/Protocol/Handlers/BattleGroundHandler.cpp
index e779f2a8ab1..a50eb813bb5 100644
--- a/src/server/game/Server/Protocol/Handlers/BattleGroundHandler.cpp
+++ b/src/server/game/Server/Protocol/Handlers/BattleGroundHandler.cpp
@@ -34,6 +34,7 @@
#include "Player.h"
#include "Object.h"
#include "Opcodes.h"
+#include "DisableMgr.h"
void WorldSession::HandleBattlemasterHelloOpcode(WorldPacket & recv_data)
{
@@ -90,6 +91,12 @@ void WorldSession::HandleBattlemasterJoinOpcode(WorldPacket & recv_data)
return;
}
+ if (sDisableMgr.IsDisabledFor(DISABLE_TYPE_BATTLEGROUND, bgTypeId_, NULL))
+ {
+ ChatHandler(this).PSendSysMessage(LANG_BG_DISABLED);
+ return;
+ }
+
BattleGroundTypeId bgTypeId = BattleGroundTypeId(bgTypeId_);
sLog.outDebug("WORLD: Recvd CMSG_BATTLEMASTER_JOIN Message from (GUID: %u TypeId:%u)", GUID_LOPART(guid), GuidHigh2TypeId(GUID_HIPART(guid)));
@@ -659,6 +666,12 @@ void WorldSession::HandleBattlemasterJoinArena(WorldPacket & recv_data)
return;
}
+ if (sDisableMgr.IsDisabledFor(DISABLE_TYPE_BATTLEGROUND, BATTLEGROUND_AA, NULL))
+ {
+ ChatHandler(this).PSendSysMessage(LANG_ARENA_DISABLED);
+ return;
+ }
+
BattleGroundTypeId bgTypeId = bg->GetTypeID();
BattleGroundQueueTypeId bgQueueTypeId = BattleGroundMgr::BGQueueTypeId(bgTypeId, arenatype);
PvPDifficultyEntry const* bracketEntry = GetBattlegroundBracketByLevel(bg->GetMapId(),_player->getLevel());
diff --git a/src/server/game/Spells/Spell.cpp b/src/server/game/Spells/Spell.cpp
index 052c829676b..28248b97c96 100644
--- a/src/server/game/Spells/Spell.cpp
+++ b/src/server/game/Spells/Spell.cpp
@@ -51,6 +51,7 @@
#include "SpellAuraEffects.h"
#include "ScriptMgr.h"
#include "ConditionMgr.h"
+#include "DisableMgr.h"
#define SPELL_CHANNEL_UPDATE_INTERVAL (1 * IN_MILLISECONDS)
@@ -2740,31 +2741,12 @@ void Spell::prepare(SpellCastTargets const* targets, AuraEffect const * triggere
finish(false);
return;
}
- if (m_caster->GetTypeId() == TYPEID_PLAYER)
- {
- if (objmgr.IsPlayerSpellDisabled(m_spellInfo->Id))
- {
- SendCastResult(SPELL_FAILED_SPELL_UNAVAILABLE);
- finish(false);
- return;
- }
- }
- else if (m_caster->GetTypeId() == TYPEID_UNIT && m_caster->ToCreature()->isPet())
- {
- if (objmgr.IsPetSpellDisabled(m_spellInfo->Id))
- {
- SendCastResult(SPELL_FAILED_SPELL_UNAVAILABLE);
- finish(false);
- return;
- }
- }
- else
+
+ if (sDisableMgr.IsDisabledFor(DISABLE_TYPE_SPELL, m_spellInfo->Id, m_caster))
{
- if (objmgr.IsCreatureSpellDisabled(m_spellInfo->Id))
- {
- finish(false);
- return;
- }
+ SendCastResult(SPELL_FAILED_SPELL_UNAVAILABLE);
+ finish(false);
+ return;
}
if (m_caster->GetTypeId() == TYPEID_PLAYER)
diff --git a/src/server/game/Spells/SpellMgr.h b/src/server/game/Spells/SpellMgr.h
index ec0149f3a63..d02efab43b1 100644
--- a/src/server/game/Spells/SpellMgr.h
+++ b/src/server/game/Spells/SpellMgr.h
@@ -52,9 +52,9 @@ enum SpellCategories
enum SpellDisableTypes
{
- SPELL_DISABLE_PLAYER = 1,
- SPELL_DISABLE_CREATURE = 2,
- SPELL_DISABLE_PET = 4
+ SPELL_DISABLE_PLAYER = 1,
+ SPELL_DISABLE_CREATURE = 2,
+ SPELL_DISABLE_PET = 4
};
enum SpellEffectTargetTypes
diff --git a/src/server/game/World/World.cpp b/src/server/game/World/World.cpp
index 05065140c35..691fd1dce22 100644
--- a/src/server/game/World/World.cpp
+++ b/src/server/game/World/World.cpp
@@ -70,6 +70,7 @@
#include "AddonMgr.h"
#include "LFGMgr.h"
#include "ConditionMgr.h"
+#include "DisableMgr.h"
volatile bool World::m_stopEvent = false;
uint8 World::m_ExitCode = SHUTDOWN_EXIT_CODE;
@@ -1224,20 +1225,6 @@ void World::LoadConfigSettings(bool reload)
m_configs[CONFIG_MIN_LOG_UPDATE] = sConfig.GetIntDefault("MinRecordUpdateTimeDiff", 10);
m_configs[CONFIG_NUMTHREADS] = sConfig.GetIntDefault("MapUpdate.Threads", 1);
- std::string forbiddenmaps = sConfig.GetStringDefault("ForbiddenMaps", "");
- char * forbiddenMaps = new char[forbiddenmaps.length() + 1];
- forbiddenMaps[forbiddenmaps.length()] = 0;
- strncpy(forbiddenMaps, forbiddenmaps.c_str(), forbiddenmaps.length());
- const char * delim = ",";
- char * token = strtok(forbiddenMaps, delim);
- while (token != NULL)
- {
- int32 mapid = strtol(token, NULL, 10);
- m_forbiddenMapIds.insert(mapid);
- token = strtok(NULL,delim);
- }
- delete[] forbiddenMaps;
-
// chat logging
m_configs[CONFIG_CHATLOG_CHANNEL] = sConfig.GetBoolDefault("ChatLogs.Channel", false);
m_configs[CONFIG_CHATLOG_WHISPER] = sConfig.GetBoolDefault("ChatLogs.Whisper", false);
@@ -1430,9 +1417,15 @@ void World::SetInitialWorldSettings()
sLog.outString("Loading Weather Data...");
objmgr.LoadWeatherZoneChances();
+ sLog.outString("Loading Disables");
+ sDisableMgr.LoadDisables(); // must be before loading quests
+
sLog.outString("Loading Quests...");
objmgr.LoadQuests(); // must be loaded after DBCs, creature_template, item_template, gameobject tables
+ sLog.outString("Checking Quest Disables");
+ sDisableMgr.CheckQuestDisables(); // must be after loading quests
+
sLog.outString("Loading Quest POI");
objmgr.LoadQuestPOI();
@@ -1499,9 +1492,6 @@ void World::SetInitialWorldSettings()
sLog.outString("Loading Player level dependent mail rewards...");
objmgr.LoadMailLevelRewards();
- sLog.outString("Loading Disabled Spells...");
- objmgr.LoadSpellDisabledEntrys();
-
// Loot tables
LoadLootTables();
diff --git a/src/server/game/World/World.h b/src/server/game/World/World.h
index 07d7d3c51db..f3a92108f60 100644
--- a/src/server/game/World/World.h
+++ b/src/server/game/World/World.h
@@ -637,8 +637,6 @@ class World
uint32 DecreaseScheduledScriptCount(size_t count) { return (uint32)(m_scheduledScripts -= count); }
bool IsScriptScheduled() const { return m_scheduledScripts > 0; }
- bool IsAllowedMap(uint32 mapid) { return m_forbiddenMapIds.count(mapid) == 0 ;}
-
// for max speed access
static float GetMaxVisibleDistanceOnContinents() { return m_MaxVisibleDistanceOnContinents; }
static float GetMaxVisibleDistanceInInstances() { return m_MaxVisibleDistanceInInstances; }
@@ -739,7 +737,6 @@ class World
bool m_allowMovement;
std::string m_motd;
std::string m_dataPath;
- std::set<uint32> m_forbiddenMapIds;
// for max speed access
static float m_MaxVisibleDistanceOnContinents;
diff --git a/src/server/worldserver/worldserver.conf.dist b/src/server/worldserver/worldserver.conf.dist
index d3b0e289711..0f93bef4c06 100644
--- a/src/server/worldserver/worldserver.conf.dist
+++ b/src/server/worldserver/worldserver.conf.dist
@@ -2147,14 +2147,6 @@ Ra.Secure = 1
# Default: 0 = Only 1 Guild Master per guild
# 1 = Allow more than one Guild Master
#
-# ForbiddenMaps
-# Map ids that users below SEC_GAMEMASTER cannot enter,
-# with delimiter ','
-# Default: ""
-# example: "538,90"
-# Note that it's HIGHLY DISCOURAGED to forbid starting maps
-# (0, 1, 530)!
-#
# ShowKickInWorld
# Determines wether a message is broadcasted to the entire server
# when a player gets kicked