diff options
author | Wyreth <32145860+Wyreth@users.noreply.github.com> | 2017-12-17 16:29:22 +0100 |
---|---|---|
committer | funjoker <funjoker109@gmail.com> | 2021-04-15 05:53:27 +0200 |
commit | ed3b34e33f019d9200a3d003c467e0ffa351187a (patch) | |
tree | c8fb8dd52bfc83fa2627efa5502f7d7536404f00 /src | |
parent | dbd9f88bf07d404336c9643dbd74f8fd80db9597 (diff) |
Core/Creature: implement school immunity for creatures in creature_template (#20709)
(cherry picked from commit ae878e18ef121b7b1960f40f2b0f99debd2155d8)
Diffstat (limited to 'src')
-rw-r--r-- | src/server/database/Database/Implementation/WorldDatabase.cpp | 2 | ||||
-rw-r--r-- | src/server/game/Entities/Creature/Creature.cpp | 21 | ||||
-rw-r--r-- | src/server/game/Entities/Creature/Creature.h | 1 | ||||
-rw-r--r-- | src/server/game/Entities/Creature/CreatureData.h | 1 | ||||
-rw-r--r-- | src/server/game/Globals/ObjectMgr.cpp | 11 |
5 files changed, 30 insertions, 6 deletions
diff --git a/src/server/database/Database/Implementation/WorldDatabase.cpp b/src/server/database/Database/Implementation/WorldDatabase.cpp index be89f9d483f..06a9cfeb27d 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, name, femaleName, subname, TitleAlt, IconName, gossip_menu_id, minlevel, maxlevel, HealthScalingExpansion, RequiredExpansion, VignetteID, faction, npcflag, speed_walk, speed_run, scale, `rank`, dmgschool, BaseAttackTime, RangeAttackTime, BaseVariance, RangeVariance, unit_class, unit_flags, unit_flags2, unit_flags3, dynamicflags, family, trainer_class, type, type_flags, type_flags2, lootid, pickpocketloot, skinloot, resistance1, resistance2, resistance3, resistance4, resistance5, resistance6, spell1, spell2, spell3, spell4, spell5, spell6, spell7, spell8, VehicleId, mingold, maxgold, AIName, MovementType, InhabitType, HoverHeight, HealthModifier, HealthModifierExtra, ManaModifier, ManaModifierExtra, ArmorModifier, DamageModifier, ExperienceModifier, RacialLeader, movementId, WidgetSetID, WidgetSetUnitConditionID, RegenHealth, mechanic_immune_mask, flags_extra, ScriptName FROM creature_template WHERE entry = ? OR 1 = ?", CONNECTION_SYNCH); + PrepareStatement(WORLD_SEL_CREATURE_TEMPLATE, "SELECT entry, difficulty_entry_1, difficulty_entry_2, difficulty_entry_3, KillCredit1, KillCredit2, name, femaleName, subname, TitleAlt, IconName, gossip_menu_id, minlevel, maxlevel, HealthScalingExpansion, RequiredExpansion, VignetteID, faction, npcflag, speed_walk, speed_run, scale, `rank`, dmgschool, BaseAttackTime, RangeAttackTime, BaseVariance, RangeVariance, unit_class, unit_flags, unit_flags2, unit_flags3, dynamicflags, family, trainer_class, type, type_flags, type_flags2, lootid, pickpocketloot, skinloot, resistance1, resistance2, resistance3, resistance4, resistance5, resistance6, spell1, spell2, spell3, spell4, spell5, spell6, spell7, spell8, VehicleId, mingold, maxgold, AIName, MovementType, InhabitType, HoverHeight, HealthModifier, HealthModifierExtra, ManaModifier, ManaModifierExtra, ArmorModifier, DamageModifier, ExperienceModifier, RacialLeader, movementId, WidgetSetID, WidgetSetUnitConditionID, RegenHealth, mechanic_immune_mask, spell_school_immune_mask, flags_extra, ScriptName FROM creature_template WHERE entry = ? OR 1 = ?", 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_CREATURE_BY_ID, "SELECT guid FROM creature WHERE id = ?", CONNECTION_SYNCH); PrepareStatement(WORLD_SEL_GAMEOBJECT_NEAREST, "SELECT guid, id, position_x, position_y, position_z, map, (POW(position_x - ?, 2) + POW(position_y - ?, 2) + POW(position_z - ?, 2)) AS order_ FROM gameobject WHERE map = ? AND (POW(position_x - ?, 2) + POW(position_y - ?, 2) + POW(position_z - ?, 2)) <= ? ORDER BY order_", CONNECTION_SYNCH); diff --git a/src/server/game/Entities/Creature/Creature.cpp b/src/server/game/Entities/Creature/Creature.cpp index 4843edd6dbc..bc19dab4571 100644 --- a/src/server/game/Entities/Creature/Creature.cpp +++ b/src/server/game/Entities/Creature/Creature.cpp @@ -668,6 +668,7 @@ bool Creature::UpdateEntry(uint32 entry, CreatureData const* data /*= nullptr*/, UpdateMovementFlags(); LoadCreaturesAddon(); LoadMechanicTemplateImmunity(); + LoadSpellTemplateImmunity(); return true; } @@ -2224,6 +2225,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 5c49fff17b0..a77b07ba6a6 100644 --- a/src/server/game/Entities/Creature/Creature.h +++ b/src/server/game/Entities/Creature/Creature.h @@ -112,6 +112,7 @@ class TC_GAME_API Creature : public Unit, public GridObject<Creature>, public Ma bool CanResetTalents(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 ce201961b80..2f74b757999 100644 --- a/src/server/game/Entities/Creature/CreatureData.h +++ b/src/server/game/Entities/Creature/CreatureData.h @@ -399,6 +399,7 @@ struct TC_GAME_API CreatureTemplate int32 WidgetSetUnitConditionID; 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 54e3b96a02d..a8a42d6a107 100644 --- a/src/server/game/Globals/ObjectMgr.cpp +++ b/src/server/game/Globals/ObjectMgr.cpp @@ -430,9 +430,9 @@ void ObjectMgr::LoadCreatureTemplates() // "spell1, spell2, spell3, spell4, spell5, spell6, spell7, spell8, VehicleId, mingold, maxgold, AIName, MovementType, " // 60 61 62 63 64 65 66 67 68 // "InhabitType, HoverHeight, HealthModifier, HealthModifierExtra, ManaModifier, ManaModifierExtra, ArmorModifier, DamageModifier, ExperienceModifier, " - // 69 70 71 72 73 74 75 - // "RacialLeader, movementId, WidgetSetID, WidgetSetUnitConditionID, RegenHealth, mechanic_immune_mask, flags_extra, " - // 76 + // 69 70 71 72 73 74 75 76 + // "RacialLeader, movementId, WidgetSetID, WidgetSetUnitConditionID, RegenHealth, mechanic_immune_mask, spell_school_immune_mask, flags_extra, " + // 77 // "ScriptName FROM creature_template WHERE entry = ? OR 1 = ?"); WorldDatabasePreparedStatement* stmt = WorldDatabase.GetPreparedStatement(WORLD_SEL_CREATURE_TEMPLATE); @@ -540,8 +540,9 @@ void ObjectMgr::LoadCreatureTemplate(Field* fields) creatureTemplate.WidgetSetUnitConditionID = fields[72].GetInt32(); creatureTemplate.RegenHealth = fields[73].GetBool(); creatureTemplate.MechanicImmuneMask = fields[74].GetUInt32(); - creatureTemplate.flags_extra = fields[75].GetUInt32(); - creatureTemplate.ScriptID = GetScriptId(fields[76].GetString()); + creatureTemplate.SpellSchoolImmuneMask = fields[75].GetUInt8(); + creatureTemplate.flags_extra = fields[76].GetUInt32(); + creatureTemplate.ScriptID = GetScriptId(fields[77].GetString()); } void ObjectMgr::LoadCreatureTemplateModels() |