edit: here is the patch
diff --git a/sql/mangos_spell_disabled.sql b/sql/mangos_spell_disabled.sql
new file mode 100644
index 0000000..d4fc43c
--- /dev/null
+++ b/sql/mangos_spell_disabled.sql
@@ -0,0 +1,6 @@
+CREATE TABLE spell_disabled (
+ entry int(11) unsigned NOT NULL default '0' COMMENT 'spell entry',
+ ischeat_spell tinyint(3) unsigned NOT NULL default '0' COMMENT 'mark spell as cheat',
+ active tinyint(3) unsigned NOT NULL default '1' COMMENT 'enable check of this spell',
+ PRIMARY KEY (entry)
+) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=FIXED COMMENT='Disabled Spell System';
\\ No newline at end of file
diff --git a/src/game/Chat.cpp b/src/game/Chat.cpp
index c024989..891d96b 100644
--- a/src/game/Chat.cpp
+++ b/src/game/Chat.cpp
@@ -465,6 +465,7 @@ 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 },
{ NULL, 0, false, NULL, "", NULL }
};
diff --git a/src/game/Chat.h b/src/game/Chat.h
index 45a0293..9c3ff0a 100644
--- a/src/game/Chat.h
+++ b/src/game/Chat.h
@@ -386,6 +386,7 @@ class ChatHandler
bool HandleReloadSpellTargetPositionCommand(const char* args);
bool HandleReloadSpellThreatsCommand(const char* args);
bool HandleReloadSpellPetAurasCommand(const char* args);
+ bool HandleReloadSpellDisabledCommand(const char* args);
bool HandleResetAchievementsCommand(const char * args);
bool HandleResetAllCommand(const char * args);
diff --git a/src/game/Level3.cpp b/src/game/Level3.cpp
index 3e3e650..af40fc2 100644
--- a/src/game/Level3.cpp
+++ b/src/game/Level3.cpp
@@ -163,6 +163,7 @@ bool ChatHandler::HandleReloadAllSpellCommand(const char*)
HandleReloadSpellTargetPositionCommand("a");
HandleReloadSpellThreatsCommand("a");
HandleReloadSpellPetAurasCommand("a");
+ HandleReloadSpellDisabledCommand("a");
return true;
}
@@ -822,6 +823,17 @@ bool ChatHandler::HandleReloadLocalesQuestCommand(const char* /*arg*/)
return true;
}
+bool ChatHandler::HandleReloadSpellDisabledCommand(const char* /*arg*/)
+{
+ sLog.outString( "Re-Loading spell disabled table...");
+
+ objmgr.LoadSpellDisabledEntrys();
+
+ SendGlobalSysMessage("DB table `spell_disabled` reloaded.");
+
+ return true;
+}
+
bool ChatHandler::HandleLoadScriptsCommand(const char* args)
{
if(!LoadScriptingModule(args)) return true;
diff --git a/src/game/ObjectMgr.cpp b/src/game/ObjectMgr.cpp
index 6791db9..8b137f0 100644
--- a/src/game/ObjectMgr.cpp
+++ b/src/game/ObjectMgr.cpp
@@ -7040,6 +7040,46 @@ const char *ObjectMgr::GetMangosString(int32 entry, int locale_idx) const
return "<error>";
}
+void ObjectMgr::LoadSpellDisabledEntrys()
+{
+ m_spell_disabled.clear(); // need for reload case
+ QueryResult *result = WorldDatabase.Query("SELECT entry, ischeat_spell FROM spell_disabled where active=1");
+
+ uint32 total_count = 0;
+ uint32 cheat_spell_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();
+ bool ischeater = fields[1].GetBool();
+ m_spell_disabled[spellid] = ischeater;
+ ++total_count;
+ if(ischeater)
+ ++cheat_spell_count;
+
+ } while ( result->NextRow() );
+
+ delete result;
+
+ sLog.outString();
+ sLog.outString( ">> Loaded %u disabled spells ( %u - is cheaters spells)", total_count, cheat_spell_count);
+}
+
void ObjectMgr::LoadFishingBaseSkillLevel()
{
mFishingBaseForArea.clear(); // for reload case
diff --git a/src/game/ObjectMgr.h b/src/game/ObjectMgr.h
index b36394c..6091439 100644
--- a/src/game/ObjectMgr.h
+++ b/src/game/ObjectMgr.h
@@ -702,6 +702,20 @@ class ObjectMgr
static bool CheckDeclinedNames(std::wstring mainpart, DeclinedName const& names);
+ void LoadSpellDisabledEntrys();
+ uint8 IsSpellDisabled(uint32 spellid)
+ {
+ uint8 result=0;
+ SpellDisabledMap::const_iterator itr = m_spell_disabled.find(spellid);
+ if(itr != m_spell_disabled.end())
+ {
+ result=1;
+ if(itr->second != 0)
+ result=2;
+ }
+ return result;
+ }
+
int GetIndexForLocale(LocaleConstant loc);
LocaleConstant GetLocaleForIndex(int i);
@@ -826,6 +840,9 @@ class ObjectMgr
typedef std::set<std::wstring> ReservedNamesMap;
ReservedNamesMap m_ReservedNames;
+ typedef UNORDERED_MAP<uint32, uint32> SpellDisabledMap;
+ SpellDisabledMap m_spell_disabled;
+
GraveYardMap mGraveYardMap;
GameTeleMap m_GameTeleMap;
diff --git a/src/game/Spell.cpp b/src/game/Spell.cpp
index 8a68ea7..3b39f19 100644
--- a/src/game/Spell.cpp
+++ b/src/game/Spell.cpp
@@ -2382,6 +2382,19 @@ void Spell::Prepare(SpellCastTargets const* targets, Aura* triggeredByAura)
return;
}
+ if(uint8 result = objmgr.IsSpellDisabled(m_spellInfo->Id))
+ {
+ if(m_caster->GetTypeId() == TYPEID_PLAYER)
+ {
+ sLog.outDebug("Player %s cast a spell %u which was disabled by server administrator", m_caster->GetName(), m_spellInfo->Id);
+ if(result == 2)
+ sLog.outChar("Player %s cast a spell %u which was disabled by server administrator and marked as CheatSpell", m_caster->GetName(), m_spellInfo->Id);
+ }
+ SendCastResult(SPELL_FAILED_SPELL_UNAVAILABLE);
+ finish(false);
+ return;
+ }
+
// Fill cost data
m_powerCost = CalculatePowerCost();
diff --git a/src/game/World.cpp b/src/game/World.cpp
index c418d72..450de87 100644
--- a/src/game/World.cpp
+++ b/src/game/World.cpp
@@ -1331,6 +1331,9 @@ void World::SetInitialWorldSettings()
sLog.outString( "Loading Player Corpses..." );
objmgr.LoadCorpses();
+ sLog.outString( "Loading Spell disabled..." );
+ objmgr.LoadSpellDisabledEntrys();
+
sLog.outString( "Loading Loot Tables..." );
sLog.outString();
LoadLootTables();