[svn] Implement a new table (spell_disabled) to allow disabling some spells for players and / or creatures. To disable a spell for a players and pets, set 2^0 in the disable_mask, to disable for creatures, set 2^1. The comment field is optional. Original patch provided by Craker.

--HG--
branch : trunk
This commit is contained in:
w12x
2008-10-21 03:58:38 -05:00
parent 23ff96ded9
commit 5e1c19e4d9
10 changed files with 136 additions and 15 deletions

7
sql/updates/90_world.sql Normal file
View File

@@ -0,0 +1,7 @@
DROP TABLE IF EXISTS `spell_disabled`;
CREATE TABLE `spell_disabled` (
`entry` int(11) unsigned NOT NULL default '0' COMMENT 'Spell entry',
`disable_mask` int(8) unsigned NOT NULL default '0',
`comment` varchar(64) NOT NULL default '',
PRIMARY KEY (`entry`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=FIXED COMMENT='Disabled Spell System';

View File

@@ -2946,6 +2946,27 @@ LOCK TABLES `spell_chain` WRITE;
/*!40000 ALTER TABLE `spell_chain` ENABLE KEYS */;
UNLOCK TABLES;
--
-- Table structure for table `spell_disabled`
--
DROP TABLE IF EXISTS `spell_disabled`;
CREATE TABLE `spell_disabled` (
`entry` int(11) unsigned NOT NULL default '0' COMMENT 'Spell entry',
`disable_mask` int(8) unsigned NOT NULL default '0',
`comment` varchar(64) NOT NULL default '',
PRIMARY KEY (`entry`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=FIXED COMMENT='Disabled Spell System';
--
-- Dumping data for table `spell_disabled`
--
LOCK TABLES `spell_disabled` WRITE;
/*!40000 ALTER TABLE `spell_disabled` DISABLE KEYS */;
/*!40000 ALTER TABLE `spell_disabled` ENABLE KEYS */;
UNLOCK TABLES;
--
-- Table structure for table `spell_elixir`
--

View File

@@ -197,6 +197,7 @@ ChatCommand * ChatHandler::getCommandTable()
{ "spell_scripts", SEC_ADMINISTRATOR, &ChatHandler::HandleReloadSpellScriptsCommand, "", NULL },
{ "spell_target_position", SEC_ADMINISTRATOR, &ChatHandler::HandleReloadSpellTargetPositionCommand, "", NULL },
{ "spell_threats", SEC_ADMINISTRATOR, &ChatHandler::HandleReloadSpellThreatsCommand, "", NULL },
{ "spell_disabled", SEC_ADMINISTRATOR, &ChatHandler::HandleReloadSpellDisabledCommand, "", NULL },
{ "locales_creature", SEC_ADMINISTRATOR, &ChatHandler::HandleReloadLocalesCreatureCommand, "", NULL },
{ "locales_gameobject", SEC_ADMINISTRATOR, &ChatHandler::HandleReloadLocalesGameobjectCommand, "", NULL },
{ "locales_item", SEC_ADMINISTRATOR, &ChatHandler::HandleReloadLocalesItemCommand, "", NULL },

View File

@@ -193,6 +193,7 @@ class ChatHandler
bool HandleReloadSpellTargetPositionCommand(const char* args);
bool HandleReloadSpellThreatsCommand(const char* args);
bool HandleReloadSpellPetAurasCommand(const char* args);
bool HandleReloadSpellDisabledCommand(const char* args);
bool HandleReloadPageTextsCommand(const char* args);
bool HandleReloadItemEnchantementsCommand(const char* args);
bool HandleReloadLocalesCreatureCommand(const char* args);

View File

@@ -150,6 +150,7 @@ bool ChatHandler::HandleReloadAllSpellCommand(const char*)
HandleReloadSpellTargetPositionCommand("a");
HandleReloadSpellThreatsCommand("a");
HandleReloadSpellPetAurasCommand("a");
HandleReloadSpellDisabledCommand("a");
return true;
}
@@ -613,6 +614,17 @@ bool ChatHandler::HandleReloadGameTeleCommand(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::HandleReloadLocalesCreatureCommand(const char* /*arg*/)
{
sLog.outString( "Re-Loading Locales Creature ...");
@@ -5576,7 +5588,7 @@ bool ChatHandler::HandleFreezeCommand(const char *args)
if (!TargetName) //if no name entered use target
{
player = getSelectedPlayer();
if (player) //prevent crash with creature as target
if (player) //prevent crash with creature as target
{
name = player->GetName();
normalizePlayerName(name);
@@ -5609,12 +5621,12 @@ bool ChatHandler::HandleFreezeCommand(const char *args)
//stop combat + make player unattackable + duel stop + stop some spells
player->setFaction(35);
player->CombatStop();
if(player->IsNonMeleeSpellCasted(true))
if(player->IsNonMeleeSpellCasted(true))
player->InterruptNonMeleeSpells(true);
player->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
player->SetUInt32Value(PLAYER_DUEL_TEAM, 1);
//if player class = hunter || warlock remove pet if alive
//if player class = hunter || warlock remove pet if alive
if((player->getClass() == CLASS_HUNTER) || (player->getClass() == CLASS_WARLOCK))
{
if(Pet* pet = player->GetPet())
@@ -5661,7 +5673,7 @@ bool ChatHandler::HandleUnFreezeCommand(const char *args)
if (!TargetName) //if no name entered use target
{
player = getSelectedPlayer();
if (player) //prevent crash with creature as target
if (player) //prevent crash with creature as target
{
name = player->GetName();
}
@@ -5696,25 +5708,25 @@ bool ChatHandler::HandleUnFreezeCommand(const char *args)
if (TargetName)
{
//check for offline players
QueryResult *result = CharacterDatabase.PQuery("SELECT characters.guid FROM `characters` WHERE characters.name = '%s'",name.c_str());
QueryResult *result = CharacterDatabase.PQuery("SELECT characters.guid FROM `characters` WHERE characters.name = '%s'",name.c_str());
if(!result)
{
SendSysMessage(LANG_COMMAND_FREEZE_WRONG);
{
SendSysMessage(LANG_COMMAND_FREEZE_WRONG);
return true;
}
//if player found: delete his freeze aura
Field *fields=result->Fetch();
}
//if player found: delete his freeze aura
Field *fields=result->Fetch();
uint64 pguid = fields[0].GetUInt64();
delete result;
delete result;
CharacterDatabase.PQuery("DELETE FROM `character_aura` WHERE character_aura.spell = 9454 AND character_aura.guid = '%u'",pguid);
PSendSysMessage(LANG_COMMAND_UNFREEZE,name.c_str());
return true;
}
else
}
else
{
SendSysMessage(LANG_COMMAND_FREEZE_WRONG);
SendSysMessage(LANG_COMMAND_FREEZE_WRONG);
return true;
}
}
}
return true;

View File

@@ -6291,6 +6291,51 @@ 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();
QueryResult *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);
++total_count;
} while ( result->NextRow() );
delete result;
sLog.outString();
sLog.outString( ">> Loaded %u disabled spells from `spell_disabled`", total_count);
}
void ObjectMgr::LoadFishingBaseSkillLevel()
{
mFishingBaseForArea.clear(); // for relaod case

View File

@@ -689,6 +689,10 @@ 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); }
int GetIndexForLocale(LocaleConstant loc);
LocaleConstant GetLocaleForIndex(int i);
// guild bank tabs
@@ -798,6 +802,9 @@ class ObjectMgr
typedef std::set<std::string> ReservedNamesMap;
ReservedNamesMap m_ReservedNames;
std::set<uint32> m_DisabledPlayerSpells;
std::set<uint32> m_DisabledCreatureSpells;
GraveYardMap mGraveYardMap;
GameTeleMap m_GameTeleMap;

View File

@@ -2032,6 +2032,24 @@ void Spell::prepare(SpellCastTargets * targets, Aura* triggeredByAura)
return;
}
if(m_caster->GetTypeId() == TYPEID_PLAYER || (m_caster->GetTypeId() == TYPEID_UNIT && ((Creature*)m_caster)->isPet()))
{
if(objmgr.IsPlayerSpellDisabled(m_spellInfo->Id))
{
SendCastResult(SPELL_FAILED_SPELL_UNAVAILABLE);
finish(false);
return;
}
}
else
{
if(objmgr.IsCreatureSpellDisabled(m_spellInfo->Id))
{
finish(false);
return;
}
}
// Fill cost data
m_powerCost = CalculatePowerCost();

View File

@@ -227,6 +227,12 @@ enum SpellFamilyNames
SPELLFAMILY_POTION = 13
};
enum SpellDisableTypes
{
SPELL_DISABLE_PLAYER = 1,
SPELL_DISABLE_CREATURE = 2
};
//Some SpellFamilyFlags
#define SPELLFAMILYFLAG_ROGUE_VANISH 0x000000800LL
#define SPELLFAMILYFLAG_ROGUE_STEALTH 0x000400000LL

View File

@@ -1109,6 +1109,9 @@ void World::SetInitialWorldSettings()
sLog.outString( "Loading Player Corpses..." );
objmgr.LoadCorpses();
sLog.outString( "Loading Disabled Spells..." );
objmgr.LoadSpellDisabledEntrys();
sLog.outString( "Loading Loot Tables..." );
LoadLootTables();