feat(Core/Creature): implement c_t->spell_school_immune_mask (#4358)

* feat(Core/Creature): implement spell_school_immune_mask

* ae878e18ef

Co-Authored-By: Wyreth <32145860+Wyreth@users.noreply.github.com>

* Import from TC

* just capitalize sql keywords

* Update rev_1611769264588956600.sql

Co-authored-by: Wyreth <32145860+Wyreth@users.noreply.github.com>
This commit is contained in:
Kitzunu
2021-02-03 03:44:09 +01:00
committed by GitHub
parent 887995f348
commit 6e1fb0d525
5 changed files with 98 additions and 26 deletions

View File

@@ -0,0 +1,37 @@
INSERT INTO `version_db_world` (`sql_rev`) VALUES ('1611769264588956600');
ALTER TABLE `creature_template` ADD COLUMN `spell_school_immune_mask` INT(3) UNSIGNED NOT NULL DEFAULT 0 AFTER `mechanic_immune_mask`;
-- Imported from TrinityCore
-- SPELL_SCHOOL_NORMAL
UPDATE `creature_template` SET `spell_school_immune_mask` = 1 WHERE `entry` = 11284;
-- SPELL_SCHOOL_FIRE
UPDATE `creature_template` SET `spell_school_immune_mask` = 4 WHERE `entry` IN (89,575,2091,2108,2447,2726,2745,2760,3417,4036,4037,4038,4676,5850,5852,5893,5896,6073,6520,6073,6520,6521,7135,7136,7137,7266,7738,7846,8281,8608,8616,8680,8909,8910,8911,9016,9017,9026,9178,9376,9816,9878,9879,11502,11583,11666,11667,11668,11981,11983,12056,12143,12265,13020,14460,14461,14601,14668,15203,15209,15438,17003,19203,19973,21706,22323,20703,25001,25417,30847);
-- SPELL_SCHOOL_NATURE
UPDATE `creature_template` SET `spell_school_immune_mask` = 8 WHERE `entry` IN (92,832,2258,2592,2735,2736,2752,2762,2791,4034,4035,4499,4526,5855,5898,5902,6239,8667,9377,9397,11321,11576,11577,11578,11744,11745,11777,11778,11783,11784,12201,12237,14399,14400,14435,14454,14455,14478,14887,14888,14889,14890,15352,16043,17085,17154,17156,17157,17158,17159,17160,18062,18181,21707,23029,11779,22036,26407,28411,28585,28825);
-- SPELL_SCHOOL_FROST
UPDATE `creature_template` SET `spell_school_immune_mask` = 16 WHERE `entry` IN (510,691,2761,2776,2794,3851,3861,3917,3950,4978,5461,5462,5894,5895,5897,6047,6220,6748,7079,7132,7428,7429,8519,8520,8521,8522,8837,9453,10198,10642,10756,10757,10955,11256,11862,12759,12876,13278,13279,13280,13282,13322,13456,13696,13736,14269,14350,14457,14458,15211,15305,17153,17155,17167,17358,19204,21428,21728,22009,22309,17207,26342,26341,26340,26339,26338,20704,22035,16570,25740,25755,25756,25757,25865,26116,26178,26204,26214,26215,26216,24228,24601,25226,25514,25715,26316,30846);
-- SPELL_SCHOOL_SHADOW
UPDATE `creature_template` SET `spell_school_immune_mask` = 32 WHERE `entry` IN (703,1043,1364,19206,20705);
-- SPELL_SCHOOL_ARCANE
UPDATE `creature_template` SET `spell_school_immune_mask` = 64 WHERE `entry` IN (6109,6492,6550,10202,10662,10663,10664,11480,11483,11484,14397,15527,16488,16530,16854,18864,18865,18866,18867,19205,20516,22310,20702,26370,30848);
-- SPELL_SCHOOL_ARCANE & SPELL_SCHOOL_SHADOW
UPDATE `creature_template` SET `spell_school_immune_mask` = 96 WHERE `entry` = 21032;
-- SPELL_SCHOOL_ARCANE & SPELL_SCHOOL_SHADOW & SPELL_SCHOOL_FROST & SPELL_SCHOOL_FIRE
UPDATE `creature_template` SET `spell_school_immune_mask` = 116 WHERE `entry` IN (7734,7735);
-- SPELL_SCHOOL_ARCANE & SPELL_SCHOOL_SHADOW & SPELL_SCHOOL_FROST & SPELL_SCHOOL_FIRE & SPELL_SCHOOL_NATURE
UPDATE `creature_template` SET `spell_school_immune_mask` = 124 WHERE `entry` = 10485;
-- SPELL_SCHOOL_ARCANE & SPELL_SCHOOL_SHADOW & SPELL_SCHOOL_FROST & SPELL_SCHOOL_FIRE & SPELL_SCHOOL_NATURE & SPELL_SCHOOL_HOLY
UPDATE `creature_template` SET `spell_school_immune_mask` = 126 WHERE `entry` IN (12457,16491);
-- SPELL_SCHOOL_ARCANE & SPELL_SCHOOL_SHADOW & SPELL_SCHOOL_FROST & SPELL_SCHOOL_FIRE & SPELL_SCHOOL_NATURE & SPELL_SCHOOL_HOLY & SPELL_SCHOOL_NORMAL
UPDATE `creature_template` SET `spell_school_immune_mask` = 127 WHERE `entry` = 8317;

View File

@@ -65,7 +65,7 @@ void WorldDatabaseConnection::DoPrepareStatements()
PrepareStatement(WORLD_SEL_WAYPOINT_SCRIPT_ID_BY_GUID, "SELECT id FROM waypoint_scripts WHERE guid = ?", CONNECTION_SYNCH); 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_DEL_CREATURE, "DELETE FROM creature WHERE guid = ?", CONNECTION_ASYNC);
PrepareStatement(WORLD_SEL_COMMANDS, "SELECT name, security, help FROM command", CONNECTION_SYNCH); PrepareStatement(WORLD_SEL_COMMANDS, "SELECT name, security, help FROM command", CONNECTION_SYNCH);
PrepareStatement(WORLD_SEL_CREATURE_TEMPLATE, "SELECT 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`, mindmg, maxdmg, dmgschool, attackpower, DamageModifier, BaseAttackTime, RangeAttackTime, unit_class, unit_flags, unit_flags2, dynamicflags, family, trainer_type, trainer_spell, trainer_class, trainer_race, minrangedmg, maxrangedmg, rangedattackpower, 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, RacialLeader, movementId, RegenHealth, mechanic_immune_mask, flags_extra, ScriptName FROM creature_template WHERE entry = ?", CONNECTION_SYNCH); PrepareStatement(WORLD_SEL_CREATURE_TEMPLATE, "SELECT 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`, mindmg, maxdmg, dmgschool, attackpower, DamageModifier, BaseAttackTime, RangeAttackTime, unit_class, unit_flags, unit_flags2, dynamicflags, family, trainer_type, trainer_spell, trainer_class, trainer_race, minrangedmg, maxrangedmg, rangedattackpower, 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, 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_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_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); PrepareStatement(WORLD_SEL_CREATURE_BY_ID, "SELECT guid FROM creature WHERE id = ?", CONNECTION_SYNCH);

View File

@@ -488,6 +488,7 @@ bool Creature::UpdateEntry(uint32 Entry, const CreatureData* data, bool changele
UpdateEnvironmentIfNeeded(3); UpdateEnvironmentIfNeeded(3);
LoadSpellTemplateImmunity();
return true; return true;
} }
@@ -1804,6 +1805,37 @@ bool Creature::HasMechanicTemplateImmunity(uint32 mask) const
return !IS_PLAYER_GUID(GetOwnerGUID()) && (GetCreatureTemplate()->MechanicImmuneMask & mask); return !IS_PLAYER_GUID(GetOwnerGUID()) && (GetCreatureTemplate()->MechanicImmuneMask & mask);
} }
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 (IS_PLAYER_GUID(GetOwnerGUID()) && 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) bool Creature::IsImmunedToSpell(SpellInfo const* spellInfo)
{ {
if (!spellInfo) if (!spellInfo)

View File

@@ -141,6 +141,7 @@ struct CreatureTemplate
uint32 movementId; uint32 movementId;
bool RegenHealth; bool RegenHealth;
uint32 MechanicImmuneMask; uint32 MechanicImmuneMask;
uint8 SpellSchoolImmuneMask;
uint32 flags_extra; uint32 flags_extra;
uint32 ScriptID; uint32 ScriptID;
WorldPacket queryData; // pussywizard WorldPacket queryData; // pussywizard
@@ -479,6 +480,7 @@ public:
bool isCanInteractWithBattleMaster(Player* player, bool msg) const; bool isCanInteractWithBattleMaster(Player* player, bool msg) const;
bool isCanTrainingAndResetTalentsOf(Player* player) const; bool isCanTrainingAndResetTalentsOf(Player* player) const;
bool CanCreatureAttack(Unit const* victim, bool skipDistCheck = false) const; bool CanCreatureAttack(Unit const* victim, bool skipDistCheck = false) const;
void LoadSpellTemplateImmunity();
bool IsImmunedToSpell(SpellInfo const* spellInfo) override; bool IsImmunedToSpell(SpellInfo const* spellInfo) override;
[[nodiscard]] bool HasMechanicTemplateImmunity(uint32 mask) const; [[nodiscard]] bool HasMechanicTemplateImmunity(uint32 mask) const;

View File

@@ -459,20 +459,20 @@ void ObjectMgr::LoadCreatureTemplates()
{ {
uint32 oldMSTime = getMSTime(); uint32 oldMSTime = getMSTime();
// 0 1 2 3 4 5 6 7 8 // 0 1 2 3 4 5 6 7 8
QueryResult result = WorldDatabase.Query("SELECT entry, difficulty_entry_1, difficulty_entry_2, difficulty_entry_3, KillCredit1, KillCredit2, modelid1, modelid2, modelid3, " QueryResult result = WorldDatabase.Query("SELECT entry, difficulty_entry_1, difficulty_entry_2, difficulty_entry_3, KillCredit1, KillCredit2, modelid1, modelid2, modelid3, "
// 9 10 11 12 13 14 15 16 17 18 19 20 21 // 9 10 11 12 13 14 15 16 17 18 19 20
"modelid4, name, subname, IconName, gossip_menu_id, minlevel, maxlevel, exp, faction, npcflag, speed_walk, speed_run, " "modelid4, name, subname, IconName, gossip_menu_id, minlevel, maxlevel, exp, faction, npcflag, speed_walk, speed_run, "
// 22 23 24 25 26 27 28 29 30 31 32 33 // 21 22 23 24 25 26 27 28 29 30 31 32
"scale, `rank`, mindmg, maxdmg, dmgschool, attackpower, DamageModifier, BaseAttackTime, RangeAttackTime, unit_class, unit_flags, unit_flags2, " "scale, `rank`, mindmg, maxdmg, dmgschool, attackpower, DamageModifier, BaseAttackTime, RangeAttackTime, unit_class, unit_flags, unit_flags2, "
// 34 35 36 37 38 39 40 41 42 43 // 33 34 35 36 37 38 39 40 41 42
"dynamicflags, family, trainer_type, trainer_spell, trainer_class, trainer_race, minrangedmg, maxrangedmg, rangedattackpower, type, " "dynamicflags, family, trainer_type, trainer_spell, trainer_class, trainer_race, minrangedmg, maxrangedmg, rangedattackpower, type, "
// 44 45 46 47 48 49 50 51 52 53 54 // 43 44 45 46 47 48 49 50 51 52 53
"type_flags, lootid, pickpocketloot, skinloot, resistance1, resistance2, resistance3, resistance4, resistance5, resistance6, spell1, " "type_flags, lootid, pickpocketloot, skinloot, resistance1, resistance2, resistance3, resistance4, resistance5, resistance6, spell1, "
// 55 56 57 58 59 60 61 62 63 64 65 66 67 // 54 55 56 57 58 59 60 61 62 63 64 65 66
"spell2, spell3, spell4, spell5, spell6, spell7, spell8, PetSpellDataId, VehicleId, mingold, maxgold, AIName, MovementType, " "spell2, spell3, spell4, spell5, spell6, spell7, spell8, PetSpellDataId, VehicleId, mingold, maxgold, AIName, MovementType, "
// 68 69 70 71 72 73 74 75 76 77 78 // 67 68 69 70 71 72 73 74 75 76 77 78
"InhabitType, HoverHeight, HealthModifier, ManaModifier, ArmorModifier, RacialLeader, movementId, RegenHealth, mechanic_immune_mask, flags_extra, ScriptName " "InhabitType, HoverHeight, HealthModifier, ManaModifier, ArmorModifier, RacialLeader, movementId, RegenHealth, mechanic_immune_mask, spell_school_immune_mask, flags_extra, ScriptName "
"FROM creature_template;"); "FROM creature_template;");
if (!result) if (!result)
@@ -547,23 +547,24 @@ void ObjectMgr::LoadCreatureTemplates()
for (uint8 i = 0; i < CREATURE_MAX_SPELLS; ++i) for (uint8 i = 0; i < CREATURE_MAX_SPELLS; ++i)
creatureTemplate.spells[i] = fields[53 + i].GetUInt32(); creatureTemplate.spells[i] = fields[53 + i].GetUInt32();
creatureTemplate.PetSpellDataId = fields[61].GetUInt32(); creatureTemplate.PetSpellDataId = fields[61].GetUInt32();
creatureTemplate.VehicleId = fields[62].GetUInt32(); creatureTemplate.VehicleId = fields[62].GetUInt32();
creatureTemplate.mingold = fields[63].GetUInt32(); creatureTemplate.mingold = fields[63].GetUInt32();
creatureTemplate.maxgold = fields[64].GetUInt32(); creatureTemplate.maxgold = fields[64].GetUInt32();
creatureTemplate.AIName = fields[65].GetString(); creatureTemplate.AIName = fields[65].GetString();
creatureTemplate.MovementType = uint32(fields[66].GetUInt8()); creatureTemplate.MovementType = uint32(fields[66].GetUInt8());
creatureTemplate.InhabitType = uint32(fields[67].GetUInt8()); creatureTemplate.InhabitType = uint32(fields[67].GetUInt8());
creatureTemplate.HoverHeight = fields[68].GetFloat(); creatureTemplate.HoverHeight = fields[68].GetFloat();
creatureTemplate.ModHealth = fields[69].GetFloat(); creatureTemplate.ModHealth = fields[69].GetFloat();
creatureTemplate.ModMana = fields[70].GetFloat(); creatureTemplate.ModMana = fields[70].GetFloat();
creatureTemplate.ModArmor = fields[71].GetFloat(); creatureTemplate.ModArmor = fields[71].GetFloat();
creatureTemplate.RacialLeader = fields[72].GetBool(); creatureTemplate.RacialLeader = fields[72].GetBool();
creatureTemplate.movementId = fields[73].GetUInt32(); creatureTemplate.movementId = fields[73].GetUInt32();
creatureTemplate.RegenHealth = fields[74].GetBool(); creatureTemplate.RegenHealth = fields[74].GetBool();
creatureTemplate.MechanicImmuneMask = fields[75].GetUInt32(); creatureTemplate.MechanicImmuneMask = fields[75].GetUInt32();
creatureTemplate.flags_extra = fields[76].GetUInt32(); creatureTemplate.SpellSchoolImmuneMask = fields[76].GetUInt8();
creatureTemplate.ScriptID = GetScriptId(fields[77].GetCString()); creatureTemplate.flags_extra = fields[77].GetUInt32();
creatureTemplate.ScriptID = GetScriptId(fields[78].GetCString());
++count; ++count;
} while (result->NextRow()); } while (result->NextRow());