aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sql/updates/world/3.3.5/2017_12_16_03_world.sql2
-rw-r--r--src/server/database/Database/Implementation/WorldDatabase.cpp2
-rw-r--r--src/server/game/Entities/Creature/Creature.cpp21
-rw-r--r--src/server/game/Entities/Creature/Creature.h1
-rw-r--r--src/server/game/Entities/Creature/CreatureData.h1
-rw-r--r--src/server/game/Globals/ObjectMgr.cpp15
6 files changed, 34 insertions, 8 deletions
diff --git a/sql/updates/world/3.3.5/2017_12_16_03_world.sql b/sql/updates/world/3.3.5/2017_12_16_03_world.sql
new file mode 100644
index 00000000000..0037fd3549f
--- /dev/null
+++ b/sql/updates/world/3.3.5/2017_12_16_03_world.sql
@@ -0,0 +1,2 @@
+--
+ALTER TABLE `creature_template` ADD COLUMN `spell_school_immune_mask` int(3) unsigned NOT NULL DEFAULT '0' AFTER `mechanic_immune_mask`;
diff --git a/src/server/database/Database/Implementation/WorldDatabase.cpp b/src/server/database/Database/Implementation/WorldDatabase.cpp
index 654074d594b..4281366b1ad 100644
--- a/src/server/database/Database/Implementation/WorldDatabase.cpp
+++ b/src/server/database/Database/Implementation/WorldDatabase.cpp
@@ -77,7 +77,7 @@ void WorldDatabaseConnection::DoPrepareStatements()
PrepareStatement(WORLD_SEL_WAYPOINT_SCRIPT_ID_BY_GUID, "SELECT id FROM waypoint_scripts WHERE guid = ?", CONNECTION_SYNCH);
PrepareStatement(WORLD_DEL_CREATURE, "DELETE FROM creature WHERE guid = ?", CONNECTION_ASYNC);
PrepareStatement(WORLD_SEL_COMMANDS, "SELECT name, permission, help FROM command", CONNECTION_SYNCH);
- PrepareStatement(WORLD_SEL_CREATURE_TEMPLATE, "SELECT entry, difficulty_entry_1, difficulty_entry_2, difficulty_entry_3, KillCredit1, KillCredit2, modelid1, modelid2, modelid3, modelid4, name, subname, IconName, gossip_menu_id, minlevel, maxlevel, exp, faction, npcflag, speed_walk, speed_run, scale, rank, dmgschool, BaseAttackTime, RangeAttackTime, BaseVariance, RangeVariance, unit_class, unit_flags, unit_flags2, dynamicflags, family, trainer_type, trainer_spell, trainer_class, trainer_race, type, type_flags, lootid, pickpocketloot, skinloot, resistance1, resistance2, resistance3, resistance4, resistance5, resistance6, spell1, spell2, spell3, spell4, spell5, spell6, spell7, spell8, PetSpellDataId, VehicleId, mingold, maxgold, AIName, MovementType, InhabitType, HoverHeight, HealthModifier, ManaModifier, ArmorModifier, DamageModifier, ExperienceModifier, RacialLeader, movementId, RegenHealth, mechanic_immune_mask, flags_extra, ScriptName FROM creature_template WHERE entry = ?", CONNECTION_SYNCH);
+ PrepareStatement(WORLD_SEL_CREATURE_TEMPLATE, "SELECT entry, difficulty_entry_1, difficulty_entry_2, difficulty_entry_3, KillCredit1, KillCredit2, modelid1, modelid2, modelid3, modelid4, name, subname, IconName, gossip_menu_id, minlevel, maxlevel, exp, faction, npcflag, speed_walk, speed_run, scale, rank, dmgschool, BaseAttackTime, RangeAttackTime, BaseVariance, RangeVariance, unit_class, unit_flags, unit_flags2, dynamicflags, family, trainer_type, trainer_spell, trainer_class, trainer_race, type, type_flags, lootid, pickpocketloot, skinloot, resistance1, resistance2, resistance3, resistance4, resistance5, resistance6, spell1, spell2, spell3, spell4, spell5, spell6, spell7, spell8, PetSpellDataId, VehicleId, mingold, maxgold, AIName, MovementType, InhabitType, HoverHeight, HealthModifier, ManaModifier, ArmorModifier, DamageModifier, ExperienceModifier, RacialLeader, movementId, RegenHealth, mechanic_immune_mask, spell_school_immune_mask, flags_extra, ScriptName FROM creature_template WHERE entry = ?", CONNECTION_SYNCH);
PrepareStatement(WORLD_SEL_WAYPOINT_SCRIPT_BY_ID, "SELECT guid, delay, command, datalong, datalong2, dataint, x, y, z, o FROM waypoint_scripts WHERE id = ?", CONNECTION_SYNCH);
PrepareStatement(WORLD_SEL_ITEM_TEMPLATE_BY_NAME, "SELECT entry FROM item_template WHERE name = ?", CONNECTION_SYNCH);
PrepareStatement(WORLD_SEL_CREATURE_BY_ID, "SELECT guid FROM creature WHERE id = ?", CONNECTION_SYNCH);
diff --git a/src/server/game/Entities/Creature/Creature.cpp b/src/server/game/Entities/Creature/Creature.cpp
index 7fda65686ed..49f2f7d977a 100644
--- a/src/server/game/Entities/Creature/Creature.cpp
+++ b/src/server/game/Entities/Creature/Creature.cpp
@@ -613,6 +613,7 @@ bool Creature::UpdateEntry(uint32 entry, CreatureData const* data /*= nullptr*/,
UpdateMovementFlags();
LoadCreaturesAddon();
LoadMechanicTemplateImmunity();
+ LoadSpellTemplateImmunity();
return true;
}
@@ -2056,6 +2057,26 @@ void Creature::LoadMechanicTemplateImmunity()
}
}
+void Creature::LoadSpellTemplateImmunity()
+{
+ // uint32 max used for "spell id", the immunity system will not perform SpellInfo checks against invalid spells
+ // used so we know which immunities were loaded from template
+ static uint32 const placeholderSpellId = std::numeric_limits<uint32>::max();
+
+ // unapply template immunities (in case we're updating entry)
+ for (uint8 i = SPELL_SCHOOL_NORMAL; i <= SPELL_SCHOOL_ARCANE; ++i)
+ ApplySpellImmune(placeholderSpellId, IMMUNITY_SCHOOL, i, false);
+
+ // don't inherit immunities for hunter pets
+ if (GetOwnerGUID().IsPlayer() && IsHunterPet())
+ return;
+
+ if (uint8 mask = GetCreatureTemplate()->SpellSchoolImmuneMask)
+ for (uint8 i = SPELL_SCHOOL_NORMAL; i <= SPELL_SCHOOL_ARCANE; ++i)
+ if (mask & (1 << i))
+ ApplySpellImmune(placeholderSpellId, IMMUNITY_SCHOOL, 1 << i, true);
+}
+
bool Creature::IsImmunedToSpell(SpellInfo const* spellInfo, Unit* caster) const
{
if (!spellInfo)
diff --git a/src/server/game/Entities/Creature/Creature.h b/src/server/game/Entities/Creature/Creature.h
index 731b0bf5627..148bfe6ab16 100644
--- a/src/server/game/Entities/Creature/Creature.h
+++ b/src/server/game/Entities/Creature/Creature.h
@@ -107,6 +107,7 @@ class TC_GAME_API Creature : public Unit, public GridObject<Creature>, public Ma
bool isCanTrainingAndResetTalentsOf(Player* player) const;
bool CanCreatureAttack(Unit const* victim, bool force = true) const;
void LoadMechanicTemplateImmunity();
+ void LoadSpellTemplateImmunity();
bool IsImmunedToSpell(SpellInfo const* spellInfo, Unit* caster) const override;
bool IsImmunedToSpellEffect(SpellInfo const* spellInfo, uint32 index, Unit* caster) const override;
bool isElite() const;
diff --git a/src/server/game/Entities/Creature/CreatureData.h b/src/server/game/Entities/Creature/CreatureData.h
index f9ae6f24850..ef0bb7b59a4 100644
--- a/src/server/game/Entities/Creature/CreatureData.h
+++ b/src/server/game/Entities/Creature/CreatureData.h
@@ -144,6 +144,7 @@ struct TC_GAME_API CreatureTemplate
uint32 movementId;
bool RegenHealth;
uint32 MechanicImmuneMask;
+ uint8 SpellSchoolImmuneMask;
uint32 flags_extra;
uint32 ScriptID;
WorldPacket QueryData[TOTAL_LOCALES];
diff --git a/src/server/game/Globals/ObjectMgr.cpp b/src/server/game/Globals/ObjectMgr.cpp
index ddcc9e7cae4..69470e119c6 100644
--- a/src/server/game/Globals/ObjectMgr.cpp
+++ b/src/server/game/Globals/ObjectMgr.cpp
@@ -414,8 +414,8 @@ void ObjectMgr::LoadCreatureTemplates()
"spell2, spell3, spell4, spell5, spell6, spell7, spell8, PetSpellDataId, VehicleId, mingold, maxgold, AIName, MovementType, "
// 62 63 64 65 66 67 68 69
"InhabitType, HoverHeight, HealthModifier, ManaModifier, ArmorModifier, DamageModifier, ExperienceModifier, RacialLeader, "
- // 70 71 72 73 74
- "movementId, RegenHealth, mechanic_immune_mask, flags_extra, ScriptName "
+ // 70 71 72 73 74 75
+ "movementId, RegenHealth, mechanic_immune_mask, spell_school_immune_mask, flags_extra, ScriptName "
"FROM creature_template;");
if (!result)
@@ -511,11 +511,12 @@ void ObjectMgr::LoadCreatureTemplate(Field* fields)
creatureTemplate.ModExperience = fields[68].GetFloat();
creatureTemplate.RacialLeader = fields[69].GetBool();
- creatureTemplate.movementId = fields[70].GetUInt32();
- creatureTemplate.RegenHealth = fields[71].GetBool();
- creatureTemplate.MechanicImmuneMask = fields[72].GetUInt32();
- creatureTemplate.flags_extra = fields[73].GetUInt32();
- creatureTemplate.ScriptID = GetScriptId(fields[74].GetString());
+ creatureTemplate.movementId = fields[70].GetUInt32();
+ creatureTemplate.RegenHealth = fields[71].GetBool();
+ creatureTemplate.MechanicImmuneMask = fields[72].GetUInt32();
+ creatureTemplate.SpellSchoolImmuneMask = fields[73].GetUInt8();
+ creatureTemplate.flags_extra = fields[74].GetUInt32();
+ creatureTemplate.ScriptID = GetScriptId(fields[75].GetString());
}
void ObjectMgr::LoadCreatureTemplateAddons()