fix(Scripts/BlackwingLair): Nefarian (#10536)
This commit is contained in:
@@ -0,0 +1,53 @@
|
|||||||
|
INSERT INTO `version_db_world` (`sql_rev`) VALUES ('1643946548773673200');
|
||||||
|
|
||||||
|
DELETE FROM `spell_script_names` WHERE `ScriptName` IN ('spell_class_call_handler', 'spell_corrupted_totems', 'spell_class_call_polymorph', 'aura_class_call_wild_magic', 'aura_class_call_siphon_blessing', 'aura_class_call_berserk', 'spell_shadowblink');
|
||||||
|
INSERT INTO `spell_script_names` (`spell_id`, `ScriptName`) VALUES
|
||||||
|
(23410, 'spell_class_call_handler'), -- Mage
|
||||||
|
(23397, 'spell_class_call_handler'), -- Warrior
|
||||||
|
(23398, 'spell_class_call_handler'), -- Druid
|
||||||
|
(23401, 'spell_class_call_handler'), -- Priest
|
||||||
|
(23418, 'spell_class_call_handler'), -- Paladin
|
||||||
|
(23425, 'spell_class_call_handler'), -- Shaman
|
||||||
|
(23427, 'spell_class_call_handler'), -- Warlock
|
||||||
|
(23436, 'spell_class_call_handler'), -- Hunter
|
||||||
|
(23414, 'spell_class_call_handler'), -- Rogue
|
||||||
|
(23424, 'spell_corrupted_totems'),
|
||||||
|
(23603, 'spell_class_call_polymorph'),
|
||||||
|
(23410, 'aura_class_call_wild_magic'),
|
||||||
|
(23418, 'aura_class_call_siphon_blessing'),
|
||||||
|
(23397, 'aura_class_call_berserk'),
|
||||||
|
(22664, 'spell_shadowblink');
|
||||||
|
|
||||||
|
DELETE FROM `spell_target_position` WHERE `ID` IN (22668, 22669, 22670, 22671, 22672, 22673, 22674, 22675, 22676);
|
||||||
|
INSERT INTO `spell_target_position` (`ID`, `EffectIndex`, `MapID`, `PositionX`, `PositionY`, `PositionZ`, `Orientation`) VALUES
|
||||||
|
(22668, 0, 469, -7581.11, -1216.19, 476.800, 0),
|
||||||
|
(22669, 0, 469, -7561.54, -1244.01, 476.800, 0),
|
||||||
|
(22670, 0, 469, -7542.47, -1191.92, 476.355, 0),
|
||||||
|
(22671, 0, 469, -7538.63, -1273.64, 476.800, 0),
|
||||||
|
(22672, 0, 469, -7524.36, -1219.12, 476.794, 0),
|
||||||
|
(22673, 0, 469, -7506.58, -1165.26, 476.796, 0),
|
||||||
|
(22674, 0, 469, -7500.70, -1249.89, 476.798, 0),
|
||||||
|
(22675, 0, 469, -7486.36, -1194.32, 476.800, 0),
|
||||||
|
(22676, 0, 469, -7469.93, -1227.93, 476.777, 0);
|
||||||
|
|
||||||
|
DELETE FROM `waypoint_data` WHERE `id` = 11583;
|
||||||
|
INSERT INTO `waypoint_data` (`id`, `point`, `position_x`, `position_y`, `position_z`, `orientation`, `delay`, `move_type`, `action`, `action_chance`, `wpguid`) VALUES
|
||||||
|
(11583, 1, -7348.85, -1495.13, 552.515, 2.190162, 0, 2, 0, 100, 0),
|
||||||
|
(11583, 2, -7348.54, -1494.18, 552.515, 2.190162, 0, 2, 0, 100, 0),
|
||||||
|
(11583, 3, -7392.87, -1475.70, 544.619, 2.190162, 0, 2, 0, 100, 0),
|
||||||
|
(11583, 4, -7423.42, -1437.66, 535.314, 2.190162, 0, 2, 0, 100, 0),
|
||||||
|
(11583, 5, -7445.25, -1402.11, 523.842, 2.190162, 0, 2, 0, 100, 0),
|
||||||
|
(11583, 6, -7460.38, -1372.60, 513.092, 2.190162, 0, 2, 0, 100, 0),
|
||||||
|
(11583, 7, -7479.81, -1331.76, 498.759, 2.190162, 0, 2, 0, 100, 0),
|
||||||
|
(11583, 8, -7492.58, -1295.35, 488.091, 2.190162, 0, 2, 0, 100, 0),
|
||||||
|
(11583, 9, -7502.00, -1256.50, 476.758, 2.174731, 0, 2, 0, 100, 0);
|
||||||
|
|
||||||
|
UPDATE `creature_template_movement` SET `Flight` = 2 WHERE `CreatureID` = 11583;
|
||||||
|
|
||||||
|
UPDATE `creature_template` SET `unit_flags` = `unit_flags`|2|256|131072|33554432, `flags_extra` = `flags_extra`|128|256 WHERE `entry` = 14667;
|
||||||
|
|
||||||
|
UPDATE `creature_template` SET `unit_flags` = `unit_flags`|131072, `flags_extra` = `flags_extra`|1|256|16384|4194304, `mechanic_immune_mask`=`mechanic_immune_mask`|1|2|4|8|16|128|256|512|1024|2048|4096|8192|16384|65536|131072|4194304|8388608|33554432|67108864|536870912 , `ScriptName` = 'npc_corrupted_totem' WHERE `entry` IN (14662, 14663, 14664, 14666);
|
||||||
|
|
||||||
|
UPDATE `creature_template` SET `mingold` = 0, `maxgold` = 0 WHERE `entry` = 14668;
|
||||||
|
|
||||||
|
DELETE FROM `creature_loot_template` WHERE `entry` = 11583 AND `Item` = 19364;
|
||||||
@@ -6377,6 +6377,14 @@ SpellCastResult Spell::CheckCast(bool strict)
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case SPELL_AURA_MOD_SHAPESHIFT:
|
||||||
|
{
|
||||||
|
if (m_caster && m_caster->HasAura(23397)) // Nefarian Class Call (Warrior): Berserk -- Nefertum: I don't really like this but I didn't find another way.
|
||||||
|
{
|
||||||
|
return SPELL_FAILED_NOT_SHAPESHIFT;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1590,6 +1590,19 @@ void Spell::EffectHeal(SpellEffIndex /*effIndex*/)
|
|||||||
addhealth = unitTarget->SpellHealingBonusTaken(caster, m_spellInfo, addhealth, HEAL);
|
addhealth = unitTarget->SpellHealingBonusTaken(caster, m_spellInfo, addhealth, HEAL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Implemented this way as there is no other way to do it currently (that I know :P)...
|
||||||
|
if (caster->ToPlayer() && caster->ToPlayer()->HasAura(23401)) // Nefarian Corrupted Healing (priest)
|
||||||
|
{
|
||||||
|
if (m_spellInfo->Effects[EFFECT_0].ApplyAuraName != SPELL_AURA_PERIODIC_HEAL ||
|
||||||
|
m_spellInfo->Effects[EFFECT_1].ApplyAuraName != SPELL_AURA_PERIODIC_HEAL ||
|
||||||
|
m_spellInfo->Effects[EFFECT_2].ApplyAuraName != SPELL_AURA_PERIODIC_HEAL)
|
||||||
|
{
|
||||||
|
m_damage = 0;
|
||||||
|
caster->CastSpell(unitTarget, 23402, false); // Nefarian Corrupted Healing Periodic Damage effect.
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
m_damage -= addhealth;
|
m_damage -= addhealth;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4154,6 +4154,20 @@ void SpellMgr::LoadSpellInfoCorrections()
|
|||||||
spellInfo->Effects[EFFECT_1].SpellClassMask[1] = 0x00020000;
|
spellInfo->Effects[EFFECT_1].SpellClassMask[1] = 0x00020000;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Nefarian: Shadowbolt, Shadow Command
|
||||||
|
ApplySpellFix({ 22667, 22677 }, [](SpellInfo* spellInfo)
|
||||||
|
{
|
||||||
|
spellInfo->RangeEntry = sSpellRangeStore.LookupEntry(152); // 150 yards
|
||||||
|
});
|
||||||
|
|
||||||
|
// Shadowbolt Volley
|
||||||
|
ApplySpellFix({ 22665 }, [](SpellInfo* spellInfo)
|
||||||
|
{
|
||||||
|
spellInfo->RangeEntry = sSpellRangeStore.LookupEntry(152); // 150 yards
|
||||||
|
spellInfo->Effects[EFFECT_0].RadiusEntry = sSpellRadiusStore.LookupEntry(41); // 150 yards
|
||||||
|
spellInfo->AttributesEx2 |= SPELL_ATTR2_IGNORE_LINE_OF_SIGHT;
|
||||||
|
});
|
||||||
|
|
||||||
// Manastorm
|
// Manastorm
|
||||||
ApplySpellFix({ 21097 }, [](SpellInfo* spellInfo)
|
ApplySpellFix({ 21097 }, [](SpellInfo* spellInfo)
|
||||||
{
|
{
|
||||||
@@ -4180,6 +4194,12 @@ void SpellMgr::LoadSpellInfoCorrections()
|
|||||||
spellInfo->AuraInterruptFlags |= AURA_INTERRUPT_FLAG_CHANGE_MAP;
|
spellInfo->AuraInterruptFlags |= AURA_INTERRUPT_FLAG_CHANGE_MAP;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Improved Blessing Protection (Nefarian Class Call)
|
||||||
|
ApplySpellFix({ 23415 }, [](SpellInfo* spellInfo)
|
||||||
|
{
|
||||||
|
spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(TARGET_DEST_TARGET_ENEMY);
|
||||||
|
});
|
||||||
|
|
||||||
// Bestial Wrath
|
// Bestial Wrath
|
||||||
ApplySpellFix({ 19574 }, [](SpellInfo* spellInfo)
|
ApplySpellFix({ 19574 }, [](SpellInfo* spellInfo)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -99,4 +99,6 @@ inline AI* GetBlackwingLairAI(T* obj)
|
|||||||
return GetInstanceAI<AI>(obj, BWLScriptName);
|
return GetInstanceAI<AI>(obj, BWLScriptName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define RegisterBlackwingLairCreatureAI(ai_name) RegisterCreatureAIWithFactory(ai_name, GetBlackwingLairAI)
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
+625
-101
@@ -22,30 +22,37 @@
|
|||||||
#include "ScriptMgr.h"
|
#include "ScriptMgr.h"
|
||||||
#include "ScriptedCreature.h"
|
#include "ScriptedCreature.h"
|
||||||
#include "ScriptedGossip.h"
|
#include "ScriptedGossip.h"
|
||||||
|
#include "SpellScript.h"
|
||||||
#include "TemporarySummon.h"
|
#include "TemporarySummon.h"
|
||||||
#include "blackwing_lair.h"
|
#include "blackwing_lair.h"
|
||||||
|
#include "TaskScheduler.h"
|
||||||
|
|
||||||
enum Events
|
enum Events
|
||||||
{
|
{
|
||||||
// Victor Nefarius
|
// Victor Nefarius
|
||||||
EVENT_SPAWN_ADD = 1,
|
EVENT_SPAWN_ADD = 1,
|
||||||
EVENT_SHADOW_BOLT = 2,
|
EVENT_START_EVENT,
|
||||||
EVENT_FEAR = 3,
|
EVENT_SHADOW_BOLT,
|
||||||
EVENT_MIND_CONTROL = 4,
|
EVENT_FEAR,
|
||||||
|
EVENT_SILENCE,
|
||||||
|
EVENT_MIND_CONTROL,
|
||||||
|
EVENT_SHADOWBLINK,
|
||||||
// Nefarian
|
// Nefarian
|
||||||
EVENT_SHADOWFLAME = 5,
|
EVENT_SHADOWFLAME,
|
||||||
EVENT_VEILOFSHADOW = 6,
|
EVENT_VEILOFSHADOW,
|
||||||
EVENT_CLEAVE = 7,
|
EVENT_CLEAVE,
|
||||||
EVENT_TAILLASH = 8,
|
EVENT_TAILLASH,
|
||||||
EVENT_CLASSCALL = 9,
|
EVENT_CLASSCALL,
|
||||||
// UBRS
|
// UBRS
|
||||||
EVENT_CHAOS_1 = 10,
|
EVENT_CHAOS_1,
|
||||||
EVENT_CHAOS_2 = 11,
|
EVENT_CHAOS_2,
|
||||||
EVENT_PATH_2 = 12,
|
EVENT_PATH_2,
|
||||||
EVENT_PATH_3 = 13,
|
EVENT_PATH_3,
|
||||||
EVENT_SUCCESS_1 = 14,
|
EVENT_SUCCESS_1,
|
||||||
EVENT_SUCCESS_2 = 15,
|
EVENT_SUCCESS_2,
|
||||||
EVENT_SUCCESS_3 = 16,
|
EVENT_SUCCESS_3,
|
||||||
|
|
||||||
|
ACTION_RESET = 0
|
||||||
};
|
};
|
||||||
|
|
||||||
enum Says
|
enum Says
|
||||||
@@ -60,7 +67,7 @@ enum Says
|
|||||||
SAY_GAMESBEGIN_2 = 13,
|
SAY_GAMESBEGIN_2 = 13,
|
||||||
|
|
||||||
// Nefarian
|
// Nefarian
|
||||||
SAY_RANDOM = 0,
|
SAY_INTRO = 0,
|
||||||
SAY_RAISE_SKELETONS = 1,
|
SAY_RAISE_SKELETONS = 1,
|
||||||
SAY_SLAY = 2,
|
SAY_SLAY = 2,
|
||||||
SAY_DEATH = 3,
|
SAY_DEATH = 3,
|
||||||
@@ -86,7 +93,8 @@ enum Gossip
|
|||||||
enum Paths
|
enum Paths
|
||||||
{
|
{
|
||||||
NEFARIUS_PATH_2 = 1379671,
|
NEFARIUS_PATH_2 = 1379671,
|
||||||
NEFARIUS_PATH_3 = 1379672
|
NEFARIUS_PATH_3 = 1379672,
|
||||||
|
NEFARIAN_PATH = 11583
|
||||||
};
|
};
|
||||||
|
|
||||||
enum GameObjects
|
enum GameObjects
|
||||||
@@ -104,6 +112,10 @@ enum Creatures
|
|||||||
NPC_BLACK_DRAKANOID = 14265,
|
NPC_BLACK_DRAKANOID = 14265,
|
||||||
NPC_CHROMATIC_DRAKANOID = 14302,
|
NPC_CHROMATIC_DRAKANOID = 14302,
|
||||||
NPC_BONE_CONSTRUCT = 14605,
|
NPC_BONE_CONSTRUCT = 14605,
|
||||||
|
NPC_TOTEM_C_FIRE_NOVA = 14662,
|
||||||
|
NPC_TOTEM_C_STONESKIN = 14663,
|
||||||
|
NPC_TOTEM_C_HEALING = 14664,
|
||||||
|
NPC_TOTEM_C_WINDFURY = 14666,
|
||||||
// UBRS
|
// UBRS
|
||||||
NPC_GYTH = 10339
|
NPC_GYTH = 10339
|
||||||
};
|
};
|
||||||
@@ -117,8 +129,10 @@ enum Spells
|
|||||||
// BWL Spells
|
// BWL Spells
|
||||||
SPELL_SHADOWBOLT = 22677,
|
SPELL_SHADOWBOLT = 22677,
|
||||||
SPELL_SHADOWBOLT_VOLLEY = 22665,
|
SPELL_SHADOWBOLT_VOLLEY = 22665,
|
||||||
|
SPELL_SILENCE = 22666,
|
||||||
SPELL_SHADOW_COMMAND = 22667,
|
SPELL_SHADOW_COMMAND = 22667,
|
||||||
SPELL_FEAR = 22678,
|
SPELL_FEAR = 22678,
|
||||||
|
SPELL_SHADOWBLINK = 22664,
|
||||||
|
|
||||||
SPELL_NEFARIANS_BARRIER = 22663,
|
SPELL_NEFARIANS_BARRIER = 22663,
|
||||||
|
|
||||||
@@ -126,7 +140,7 @@ enum Spells
|
|||||||
SPELL_SHADOWFLAME_INITIAL = 22992,
|
SPELL_SHADOWFLAME_INITIAL = 22992,
|
||||||
SPELL_SHADOWFLAME = 22539,
|
SPELL_SHADOWFLAME = 22539,
|
||||||
SPELL_BELLOWINGROAR = 22686,
|
SPELL_BELLOWINGROAR = 22686,
|
||||||
SPELL_VEILOFSHADOW = 7068,
|
SPELL_VEILOFSHADOW = 22687,
|
||||||
SPELL_CLEAVE = 20691,
|
SPELL_CLEAVE = 20691,
|
||||||
SPELL_TAILLASH = 23364,
|
SPELL_TAILLASH = 23364,
|
||||||
|
|
||||||
@@ -134,17 +148,23 @@ enum Spells
|
|||||||
SPELL_WARRIOR = 23397, // beserk
|
SPELL_WARRIOR = 23397, // beserk
|
||||||
SPELL_DRUID = 23398, // cat form
|
SPELL_DRUID = 23398, // cat form
|
||||||
SPELL_PRIEST = 23401, // corrupted healing
|
SPELL_PRIEST = 23401, // corrupted healing
|
||||||
SPELL_PALADIN = 23418, // syphon blessing
|
SPELL_PALADIN = 23418, // siphon blessing
|
||||||
SPELL_SHAMAN = 23425, // totems
|
SPELL_SHAMAN = 23425, // totems
|
||||||
SPELL_WARLOCK = 23427, // infernals
|
SPELL_WARLOCK = 23427, // infernals
|
||||||
SPELL_HUNTER = 23436, // bow broke
|
SPELL_HUNTER = 23436, // bow broke
|
||||||
SPELL_ROGUE = 23414, // Paralise
|
SPELL_ROGUE = 23414, // Paralise
|
||||||
SPELL_DEATH_KNIGHT = 49576 // Death Grip
|
SPELL_DEATH_KNIGHT = 49576, // Death Grip
|
||||||
|
SPELL_ROOT_SELF = 17507,
|
||||||
|
|
||||||
// 19484
|
// Class Call effects
|
||||||
// 22664
|
SPELL_POLYMORPH = 23603,
|
||||||
// 22674
|
SPELL_BLESSING_PROTECTION = 23415,
|
||||||
// 22666
|
SPELL_SUMMON_INFERNALS = 23426,
|
||||||
|
SPELL_WARRIOR_BERSERK = 2458,
|
||||||
|
SPELL_CORRUPTED_FIRE_NOVA_TOTEM = 23419,
|
||||||
|
SPELL_CORRUPTED_STONESKIN_TOTEM = 23420,
|
||||||
|
SPELL_CORRUPTED_HEALING_TOTEM = 23422,
|
||||||
|
SPELL_CORRUPTED_WINDFURY_TOTEM = 23423
|
||||||
};
|
};
|
||||||
|
|
||||||
Position const DrakeSpawnLoc[2] = // drakonid
|
Position const DrakeSpawnLoc[2] = // drakonid
|
||||||
@@ -153,11 +173,7 @@ Position const DrakeSpawnLoc[2] = // drakonid
|
|||||||
{-7514.598633f, -1150.448853f, 476.796570f, 3.0f}
|
{-7514.598633f, -1150.448853f, 476.796570f, 3.0f}
|
||||||
};
|
};
|
||||||
|
|
||||||
Position const NefarianLoc[2] =
|
Position const NefarianSpawn = { -7348.849f, -1495.134f, 552.5152f, 1.798f };
|
||||||
{
|
|
||||||
{-7449.763672f, -1387.816040f, 526.783691f, 3.0f}, // nefarian spawn
|
|
||||||
{-7535.456543f, -1279.562500f, 476.798706f, 3.0f} // nefarian move
|
|
||||||
};
|
|
||||||
|
|
||||||
uint32 const Entry[5] = {NPC_BRONZE_DRAKANOID, NPC_BLUE_DRAKANOID, NPC_RED_DRAKANOID, NPC_GREEN_DRAKANOID, NPC_BLACK_DRAKANOID};
|
uint32 const Entry[5] = {NPC_BRONZE_DRAKANOID, NPC_BLUE_DRAKANOID, NPC_RED_DRAKANOID, NPC_GREEN_DRAKANOID, NPC_BLACK_DRAKANOID};
|
||||||
|
|
||||||
@@ -175,7 +191,7 @@ public:
|
|||||||
|
|
||||||
void Initialize()
|
void Initialize()
|
||||||
{
|
{
|
||||||
SpawnedAdds = 0;
|
KilledAdds = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Reset() override
|
void Reset() override
|
||||||
@@ -193,36 +209,42 @@ public:
|
|||||||
me->SetFaction(FACTION_FRIENDLY);
|
me->SetFaction(FACTION_FRIENDLY);
|
||||||
me->SetStandState(UNIT_STAND_STATE_SIT_HIGH_CHAIR);
|
me->SetStandState(UNIT_STAND_STATE_SIT_HIGH_CHAIR);
|
||||||
me->RemoveAura(SPELL_NEFARIANS_BARRIER);
|
me->RemoveAura(SPELL_NEFARIANS_BARRIER);
|
||||||
|
me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CanAIAttack(Unit const* /*target*/) const override { return me->IsVisible(); }
|
|
||||||
|
|
||||||
void JustReachedHome() override
|
void JustReachedHome() override
|
||||||
{
|
{
|
||||||
Reset();
|
Reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
void BeginEvent(Player* target)
|
void DoAction(int32 action) override
|
||||||
|
{
|
||||||
|
if (action == ACTION_RESET)
|
||||||
|
{
|
||||||
|
me->RemoveAura(SPELL_ROOT_SELF);
|
||||||
|
summons.DespawnAll();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void BeginEvent()
|
||||||
{
|
{
|
||||||
_EnterCombat();
|
_EnterCombat();
|
||||||
|
|
||||||
Talk(SAY_GAMESBEGIN_2);
|
Talk(SAY_GAMESBEGIN_2);
|
||||||
|
|
||||||
me->SetFaction(FACTION_DRAGONFLIGHT_BLACK);
|
|
||||||
me->SetUInt32Value(UNIT_NPC_FLAGS, 0);
|
|
||||||
DoCast(me, SPELL_NEFARIANS_BARRIER);
|
DoCast(me, SPELL_NEFARIANS_BARRIER);
|
||||||
me->SetStandState(UNIT_STAND_STATE_STAND);
|
SetCombatMovement(false);
|
||||||
me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC);
|
AttackStart(SelectTarget(SelectTargetMethod::Random, 0, 200.f, true));
|
||||||
AttackStart(target);
|
events.ScheduleEvent(EVENT_SHADOWBLINK, 500);
|
||||||
events.ScheduleEvent(EVENT_SHADOW_BOLT, urand(3000, 10000));
|
events.ScheduleEvent(EVENT_SHADOW_BOLT, urand(3000, 10000));
|
||||||
events.ScheduleEvent(EVENT_FEAR, urand(10000, 20000));
|
events.ScheduleEvent(EVENT_FEAR, urand(10000, 20000));
|
||||||
|
events.ScheduleEvent(EVENT_SILENCE, urand(20000, 25000));
|
||||||
events.ScheduleEvent(EVENT_MIND_CONTROL, urand(30000, 35000));
|
events.ScheduleEvent(EVENT_MIND_CONTROL, urand(30000, 35000));
|
||||||
events.ScheduleEvent(EVENT_SPAWN_ADD, 10000);
|
events.ScheduleEvent(EVENT_SPAWN_ADD, 10000);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SummonedCreatureDies(Creature* summon, Unit* /*killer*/) override
|
void SummonedCreatureDies(Creature* summon, Unit* /*killer*/) override
|
||||||
|
|
||||||
{
|
{
|
||||||
if (summon->GetEntry() != NPC_NEFARIAN)
|
if (summon->GetEntry() != NPC_NEFARIAN)
|
||||||
{
|
{
|
||||||
@@ -230,10 +252,11 @@ public:
|
|||||||
summon->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
|
summon->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
|
||||||
summon->SetReactState(REACT_PASSIVE);
|
summon->SetReactState(REACT_PASSIVE);
|
||||||
summon->SetStandState(UNIT_STAND_STATE_DEAD);
|
summon->SetStandState(UNIT_STAND_STATE_DEAD);
|
||||||
|
++KilledAdds;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void JustSummoned(Creature* /*summon*/) override { }
|
void JustSummoned(Creature* summon) override { summons.Summon(summon); }
|
||||||
|
|
||||||
void SetData(uint32 type, uint32 data) override
|
void SetData(uint32 type, uint32 data) override
|
||||||
{
|
{
|
||||||
@@ -292,6 +315,9 @@ public:
|
|||||||
case EVENT_PATH_3:
|
case EVENT_PATH_3:
|
||||||
me->GetMotionMaster()->MovePath(NEFARIUS_PATH_3, false);
|
me->GetMotionMaster()->MovePath(NEFARIUS_PATH_3, false);
|
||||||
break;
|
break;
|
||||||
|
case EVENT_START_EVENT:
|
||||||
|
BeginEvent();
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -300,7 +326,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Only do this if we haven't spawned nefarian yet
|
// Only do this if we haven't spawned nefarian yet
|
||||||
if (UpdateVictim() && SpawnedAdds <= 42)
|
if (UpdateVictim() && KilledAdds <= 42)
|
||||||
{
|
{
|
||||||
events.Update(diff);
|
events.Update(diff);
|
||||||
|
|
||||||
@@ -315,11 +341,10 @@ public:
|
|||||||
switch (urand(0, 1))
|
switch (urand(0, 1))
|
||||||
{
|
{
|
||||||
case 0:
|
case 0:
|
||||||
DoCastVictim(SPELL_SHADOWBOLT_VOLLEY);
|
DoCastAOE(SPELL_SHADOWBOLT_VOLLEY);
|
||||||
break;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0, 40, true))
|
DoCastRandomTarget(SPELL_SHADOWBOLT, 0, 150.f);
|
||||||
DoCast(target, SPELL_SHADOWBOLT);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
DoResetThreat();
|
DoResetThreat();
|
||||||
@@ -330,11 +355,19 @@ public:
|
|||||||
DoCast(target, SPELL_FEAR);
|
DoCast(target, SPELL_FEAR);
|
||||||
events.ScheduleEvent(EVENT_FEAR, urand(10000, 20000));
|
events.ScheduleEvent(EVENT_FEAR, urand(10000, 20000));
|
||||||
break;
|
break;
|
||||||
|
case EVENT_SILENCE:
|
||||||
|
DoCastRandomTarget(SPELL_SILENCE, 0, 150.f);
|
||||||
|
events.ScheduleEvent(EVENT_SILENCE, urand(14000, 23000));
|
||||||
|
break;
|
||||||
case EVENT_MIND_CONTROL:
|
case EVENT_MIND_CONTROL:
|
||||||
if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0, 40, true))
|
if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0, 40, true))
|
||||||
DoCast(target, SPELL_SHADOW_COMMAND);
|
DoCast(target, SPELL_SHADOW_COMMAND);
|
||||||
events.ScheduleEvent(EVENT_MIND_CONTROL, urand(30000, 35000));
|
events.ScheduleEvent(EVENT_MIND_CONTROL, urand(30000, 35000));
|
||||||
break;
|
break;
|
||||||
|
case EVENT_SHADOWBLINK:
|
||||||
|
DoCastSelf(SPELL_SHADOWBLINK);
|
||||||
|
events.ScheduleEvent(EVENT_SHADOWBLINK, urand(30000, 40000));
|
||||||
|
break;
|
||||||
case EVENT_SPAWN_ADD:
|
case EVENT_SPAWN_ADD:
|
||||||
for (uint8 i=0; i<2; ++i)
|
for (uint8 i=0; i<2; ++i)
|
||||||
{
|
{
|
||||||
@@ -349,19 +382,20 @@ public:
|
|||||||
dragon->AI()->AttackStart(me->GetVictim());
|
dragon->AI()->AttackStart(me->GetVictim());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (++SpawnedAdds >= 42)
|
if (KilledAdds >= 42)
|
||||||
{
|
{
|
||||||
if (Creature* nefarian = me->SummonCreature(NPC_NEFARIAN, NefarianLoc[0]))
|
if (Creature* nefarian = me->SummonCreature(NPC_NEFARIAN, NefarianSpawn))
|
||||||
{
|
{
|
||||||
nefarian->setActive(true);
|
nefarian->setActive(true);
|
||||||
nefarian->SetCanFly(true);
|
nefarian->SetCanFly(true);
|
||||||
nefarian->SetDisableGravity(true);
|
nefarian->SetDisableGravity(true);
|
||||||
nefarian->CastSpell(nullptr, SPELL_SHADOWFLAME_INITIAL);
|
nefarian->GetMotionMaster()->MovePath(NEFARIAN_PATH, false);
|
||||||
nefarian->GetMotionMaster()->MovePoint(1, NefarianLoc[1]);
|
|
||||||
}
|
}
|
||||||
events.CancelEvent(EVENT_MIND_CONTROL);
|
events.CancelEvent(EVENT_MIND_CONTROL);
|
||||||
events.CancelEvent(EVENT_FEAR);
|
events.CancelEvent(EVENT_FEAR);
|
||||||
events.CancelEvent(EVENT_SHADOW_BOLT);
|
events.CancelEvent(EVENT_SHADOW_BOLT);
|
||||||
|
events.CancelEvent(EVENT_SILENCE);
|
||||||
|
DoCastSelf(SPELL_ROOT_SELF, true);
|
||||||
me->SetVisible(false);
|
me->SetVisible(false);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -387,12 +421,16 @@ public:
|
|||||||
|
|
||||||
CloseGossipMenuFor(player);
|
CloseGossipMenuFor(player);
|
||||||
Talk(SAY_GAMESBEGIN_1);
|
Talk(SAY_GAMESBEGIN_1);
|
||||||
BeginEvent(player);
|
events.ScheduleEvent(EVENT_START_EVENT, 4000);
|
||||||
|
me->SetFaction(FACTION_DRAGONFLIGHT_BLACK);
|
||||||
|
me->SetUInt32Value(UNIT_NPC_FLAGS, 0);
|
||||||
|
me->SetStandState(UNIT_STAND_STATE_STAND);
|
||||||
|
me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC | UNIT_FLAG_NOT_SELECTABLE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
uint32 SpawnedAdds;
|
uint32 KilledAdds;
|
||||||
};
|
};
|
||||||
|
|
||||||
CreatureAI* GetAI(Creature* creature) const override
|
CreatureAI* GetAI(Creature* creature) const override
|
||||||
@@ -401,14 +439,9 @@ public:
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
class boss_nefarian : public CreatureScript
|
struct boss_nefarian : public BossAI
|
||||||
{
|
{
|
||||||
public:
|
boss_nefarian(Creature* creature) : BossAI(creature, DATA_NEFARIAN), _introDone(false)
|
||||||
boss_nefarian() : CreatureScript("boss_nefarian") { }
|
|
||||||
|
|
||||||
struct boss_nefarianAI : public BossAI
|
|
||||||
{
|
|
||||||
boss_nefarianAI(Creature* creature) : BossAI(creature, DATA_NEFARIAN)
|
|
||||||
{
|
{
|
||||||
Initialize();
|
Initialize();
|
||||||
}
|
}
|
||||||
@@ -416,30 +449,30 @@ public:
|
|||||||
void Initialize()
|
void Initialize()
|
||||||
{
|
{
|
||||||
Phase3 = false;
|
Phase3 = false;
|
||||||
canDespawn = false;
|
|
||||||
DespawnTimer = 30000;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Reset() override
|
void Reset() override
|
||||||
{
|
{
|
||||||
Initialize();
|
Initialize();
|
||||||
|
me->SetReactState(REACT_PASSIVE);
|
||||||
|
me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
|
||||||
|
me->SetCanFly(true);
|
||||||
|
me->SetDisableGravity(true);
|
||||||
|
if (_introDone) // already in combat, reset properly.
|
||||||
|
{
|
||||||
|
_Reset();
|
||||||
|
if (Unit* victor = me->FindNearestCreature(NPC_VICTOR_NEFARIUS, 200.f, true))
|
||||||
|
{
|
||||||
|
if (victor->ToCreature() && victor->ToCreature()->AI())
|
||||||
|
{
|
||||||
|
victor->ToCreature()->AI()->DoAction(ACTION_RESET);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
me->DespawnOrUnsummon();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void JustReachedHome() override
|
void EnterCombat(Unit* /*who*/) override {}
|
||||||
{
|
|
||||||
canDespawn = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void EnterCombat(Unit* /*who*/) override
|
|
||||||
{
|
|
||||||
events.ScheduleEvent(EVENT_SHADOWFLAME, 12000);
|
|
||||||
events.ScheduleEvent(EVENT_FEAR, urand(25000, 35000));
|
|
||||||
events.ScheduleEvent(EVENT_VEILOFSHADOW, urand(25000, 35000));
|
|
||||||
events.ScheduleEvent(EVENT_CLEAVE, 7000);
|
|
||||||
//events.ScheduleEvent(EVENT_TAILLASH, 10000);
|
|
||||||
events.ScheduleEvent(EVENT_CLASSCALL, urand(30000, 35000));
|
|
||||||
Talk(SAY_RANDOM);
|
|
||||||
}
|
|
||||||
|
|
||||||
void JustDied(Unit* /*killer*/) override
|
void JustDied(Unit* /*killer*/) override
|
||||||
{
|
{
|
||||||
@@ -450,50 +483,70 @@ public:
|
|||||||
void KilledUnit(Unit* victim) override
|
void KilledUnit(Unit* victim) override
|
||||||
{
|
{
|
||||||
if (rand32() % 5)
|
if (rand32() % 5)
|
||||||
|
{
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
Talk(SAY_SLAY, victim);
|
Talk(SAY_SLAY, victim);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MovementInform(uint32 type, uint32 id) override
|
void MovementInform(uint32 type, uint32 id) override
|
||||||
{
|
{
|
||||||
if (type != POINT_MOTION_TYPE)
|
if (type != WAYPOINT_MOTION_TYPE)
|
||||||
return;
|
|
||||||
|
|
||||||
if (id == 1)
|
|
||||||
{
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (id == 3)
|
||||||
|
{
|
||||||
|
Talk(SAY_INTRO);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (id == 5)
|
||||||
|
{
|
||||||
|
DoCastAOE(SPELL_SHADOWFLAME_INITIAL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void PathEndReached(uint32 /*pathId*/) override
|
||||||
|
{
|
||||||
|
me->HandleEmoteCommand(EMOTE_ONESHOT_LAND);
|
||||||
|
me->SetCanFly(false);
|
||||||
|
me->SetDisableGravity(false);
|
||||||
|
Position land = me->GetPosition();
|
||||||
|
me->GetMotionMaster()->MoveLand(0, land, 8.5f);
|
||||||
|
me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
|
||||||
|
me->GetMotionMaster()->MoveIdle();
|
||||||
|
|
||||||
|
me->SetReactState(REACT_AGGRESSIVE);
|
||||||
DoZoneInCombat();
|
DoZoneInCombat();
|
||||||
if (me->GetVictim())
|
if (me->GetVictim())
|
||||||
|
{
|
||||||
AttackStart(me->GetVictim());
|
AttackStart(me->GetVictim());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
events.ScheduleEvent(EVENT_SHADOWFLAME, 12000);
|
||||||
|
events.ScheduleEvent(EVENT_FEAR, urand(25000, 35000));
|
||||||
|
events.ScheduleEvent(EVENT_VEILOFSHADOW, urand(25000, 35000));
|
||||||
|
events.ScheduleEvent(EVENT_CLEAVE, 7000);
|
||||||
|
events.ScheduleEvent(EVENT_TAILLASH, 10000);
|
||||||
|
events.ScheduleEvent(EVENT_CLASSCALL, urand(30000, 35000));
|
||||||
|
_introDone = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void UpdateAI(uint32 diff) override
|
void UpdateAI(uint32 diff) override
|
||||||
{
|
{
|
||||||
if (canDespawn && DespawnTimer <= diff)
|
|
||||||
{
|
|
||||||
instance->SetBossState(DATA_NEFARIAN, FAIL);
|
|
||||||
|
|
||||||
std::list<Creature*> constructList;
|
|
||||||
me->GetCreatureListWithEntryInGrid(constructList, NPC_BONE_CONSTRUCT, 500.0f);
|
|
||||||
for (std::list<Creature*>::const_iterator itr = constructList.begin(); itr != constructList.end(); ++itr)
|
|
||||||
(*itr)->DespawnOrUnsummon();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
DespawnTimer -= diff;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!UpdateVictim())
|
if (!UpdateVictim())
|
||||||
|
{
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
if (canDespawn)
|
|
||||||
canDespawn = false;
|
|
||||||
|
|
||||||
events.Update(diff);
|
events.Update(diff);
|
||||||
|
|
||||||
if (me->HasUnitState(UNIT_STATE_CASTING))
|
if (me->HasUnitState(UNIT_STATE_CASTING))
|
||||||
|
{
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
while (uint32 eventId = events.ExecuteEvent())
|
while (uint32 eventId = events.ExecuteEvent())
|
||||||
{
|
{
|
||||||
@@ -522,6 +575,7 @@ public:
|
|||||||
break;
|
break;
|
||||||
case EVENT_CLASSCALL:
|
case EVENT_CLASSCALL:
|
||||||
if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0, 100.0f, true))
|
if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0, 100.0f, true))
|
||||||
|
{
|
||||||
switch (target->getClass())
|
switch (target->getClass())
|
||||||
{
|
{
|
||||||
case CLASS_MAGE:
|
case CLASS_MAGE:
|
||||||
@@ -562,18 +616,27 @@ public:
|
|||||||
break;
|
break;
|
||||||
case CLASS_DEATH_KNIGHT:
|
case CLASS_DEATH_KNIGHT:
|
||||||
Talk(SAY_DEATH_KNIGHT);
|
Talk(SAY_DEATH_KNIGHT);
|
||||||
DoCast(me, SPELL_DEATH_KNIGHT);
|
me->GetMap()->DoForAllPlayers([&](Player* p)
|
||||||
|
{
|
||||||
|
if (!p->IsGameMaster())
|
||||||
|
{
|
||||||
|
me->CastSpell(p, SPELL_DEATH_KNIGHT, true);
|
||||||
|
}
|
||||||
|
});
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
events.ScheduleEvent(EVENT_CLASSCALL, urand(30000, 35000));
|
events.ScheduleEvent(EVENT_CLASSCALL, urand(30000, 35000));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (me->HasUnitState(UNIT_STATE_CASTING))
|
if (me->HasUnitState(UNIT_STATE_CASTING))
|
||||||
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Phase3 begins when health below 20 pct
|
// Phase3 begins when health below 20 pct
|
||||||
if (!Phase3 && HealthBelowPct(20))
|
if (!Phase3 && HealthBelowPct(20))
|
||||||
@@ -581,6 +644,7 @@ public:
|
|||||||
std::list<Creature*> constructList;
|
std::list<Creature*> constructList;
|
||||||
me->GetCreatureListWithEntryInGrid(constructList, NPC_BONE_CONSTRUCT, 500.0f);
|
me->GetCreatureListWithEntryInGrid(constructList, NPC_BONE_CONSTRUCT, 500.0f);
|
||||||
for (std::list<Creature*>::const_iterator itr = constructList.begin(); itr != constructList.end(); ++itr)
|
for (std::list<Creature*>::const_iterator itr = constructList.begin(); itr != constructList.end(); ++itr)
|
||||||
|
{
|
||||||
if ((*itr) && !(*itr)->IsAlive())
|
if ((*itr) && !(*itr)->IsAlive())
|
||||||
{
|
{
|
||||||
(*itr)->Respawn();
|
(*itr)->Respawn();
|
||||||
@@ -589,6 +653,7 @@ public:
|
|||||||
(*itr)->SetReactState(REACT_AGGRESSIVE);
|
(*itr)->SetReactState(REACT_AGGRESSIVE);
|
||||||
(*itr)->SetStandState(UNIT_STAND_STATE_STAND);
|
(*itr)->SetStandState(UNIT_STAND_STATE_STAND);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Phase3 = true;
|
Phase3 = true;
|
||||||
Talk(SAY_RAISE_SKELETONS);
|
Talk(SAY_RAISE_SKELETONS);
|
||||||
@@ -598,19 +663,478 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool canDespawn;
|
|
||||||
uint32 DespawnTimer;
|
|
||||||
bool Phase3;
|
bool Phase3;
|
||||||
|
bool _introDone;
|
||||||
};
|
};
|
||||||
|
|
||||||
CreatureAI* GetAI(Creature* creature) const override
|
enum TotemSpells
|
||||||
{
|
{
|
||||||
return GetBlackwingLairAI<boss_nefarianAI>(creature);
|
AURA_AVOIDANCE = 23198,
|
||||||
|
|
||||||
|
SPELL_STONESKIN_EFFECT = 10405,
|
||||||
|
SPELL_HEALING_EFFECT = 10461,
|
||||||
|
SPELL_WINDFURY_EFFECT = 8515,
|
||||||
|
SPELL_FIRE_NOVA_EFFECT = 11307
|
||||||
|
};
|
||||||
|
|
||||||
|
struct npc_corrupted_totem : public ScriptedAI
|
||||||
|
{
|
||||||
|
npc_corrupted_totem(Creature* creature) : ScriptedAI(creature)
|
||||||
|
{
|
||||||
|
uint32 hp = urand(200, 2000);
|
||||||
|
me->SetMaxHealth(hp);
|
||||||
|
me->SetHealth(hp);
|
||||||
|
_auraAdded = false;
|
||||||
|
Reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Reset() override
|
||||||
|
{
|
||||||
|
me->AddUnitState(UNIT_STATE_ROOT);
|
||||||
|
if (!me->HasAura(SPELL_ROOT_SELF))
|
||||||
|
{
|
||||||
|
me->AddAura(SPELL_ROOT_SELF, me);
|
||||||
|
}
|
||||||
|
|
||||||
|
me->AddAura(AURA_AVOIDANCE, me);
|
||||||
|
_scheduler.CancelAll();
|
||||||
|
}
|
||||||
|
|
||||||
|
void SetAura(bool apply) const
|
||||||
|
{
|
||||||
|
uint32 spellId = 0;
|
||||||
|
|
||||||
|
switch (me->GetEntry())
|
||||||
|
{
|
||||||
|
case NPC_TOTEM_C_STONESKIN:
|
||||||
|
spellId = SPELL_STONESKIN_EFFECT;
|
||||||
|
break;
|
||||||
|
case NPC_TOTEM_C_HEALING:
|
||||||
|
spellId = SPELL_HEALING_EFFECT;
|
||||||
|
break;
|
||||||
|
case NPC_TOTEM_C_WINDFURY:
|
||||||
|
spellId = SPELL_WINDFURY_EFFECT;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!spellId)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<uint32> mobsEntries;
|
||||||
|
mobsEntries.push_back(NPC_NEFARIAN);
|
||||||
|
mobsEntries.push_back(NPC_BONE_CONSTRUCT);
|
||||||
|
mobsEntries.push_back(NPC_BRONZE_DRAKANOID);
|
||||||
|
mobsEntries.push_back(NPC_BLUE_DRAKANOID);
|
||||||
|
mobsEntries.push_back(NPC_RED_DRAKANOID);
|
||||||
|
mobsEntries.push_back(NPC_GREEN_DRAKANOID);
|
||||||
|
mobsEntries.push_back(NPC_BLACK_DRAKANOID);
|
||||||
|
mobsEntries.push_back(NPC_CHROMATIC_DRAKANOID);
|
||||||
|
|
||||||
|
for (auto& entry : mobsEntries)
|
||||||
|
{
|
||||||
|
std::list<Creature*> tmpMobList;
|
||||||
|
GetCreatureListWithEntryInGrid(tmpMobList, me, entry, 100.f);
|
||||||
|
while (!tmpMobList.empty())
|
||||||
|
{
|
||||||
|
Creature* curr = tmpMobList.front();
|
||||||
|
tmpMobList.pop_front();
|
||||||
|
|
||||||
|
if (!curr->IsAlive())
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (apply && me->IsAlive())
|
||||||
|
{
|
||||||
|
if (me->IsWithinDistInMap(curr, 40.f))
|
||||||
|
{
|
||||||
|
if (!curr->HasAura(spellId))
|
||||||
|
{
|
||||||
|
curr->AddAura(spellId, curr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (curr->HasAura(spellId))
|
||||||
|
{
|
||||||
|
curr->RemoveAurasDueToSpell(spellId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
curr->RemoveAurasDueToSpell(spellId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void IsSummonedBy(Unit* /*summoner*/) override
|
||||||
|
{
|
||||||
|
me->SetInCombatWithZone();
|
||||||
|
|
||||||
|
_scheduler
|
||||||
|
.Schedule(1ms, [this](TaskContext context)
|
||||||
|
{
|
||||||
|
if (me->GetEntry() == NPC_TOTEM_C_FIRE_NOVA)
|
||||||
|
{
|
||||||
|
if (!_auraAdded)
|
||||||
|
{
|
||||||
|
context.Schedule(4s, [this](TaskContext /*context*/)
|
||||||
|
{
|
||||||
|
if (me->IsAlive())
|
||||||
|
{
|
||||||
|
DoCastAOE(SPELL_FIRE_NOVA_EFFECT, true);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
_auraAdded = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SetAura(true);
|
||||||
|
context.Repeat(1s);
|
||||||
|
})
|
||||||
|
.Schedule(me->GetEntry() == NPC_TOTEM_C_WINDFURY ? 89s : 59s, [this](TaskContext /*context*/)
|
||||||
|
{
|
||||||
|
SetAura(false);
|
||||||
|
me->DespawnOrUnsummon();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void JustDied(Unit* /*killer*/) override
|
||||||
|
{
|
||||||
|
if (me->GetEntry() != NPC_TOTEM_C_FIRE_NOVA)
|
||||||
|
{
|
||||||
|
SetAura(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
_scheduler.CancelAll();
|
||||||
|
}
|
||||||
|
|
||||||
|
void UpdateAI(uint32 diff) override
|
||||||
|
{
|
||||||
|
if (!UpdateVictim())
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
_scheduler.Update(diff);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
TaskScheduler _scheduler;
|
||||||
|
bool _auraAdded;
|
||||||
|
};
|
||||||
|
|
||||||
|
std::unordered_map<uint32, uint8> const classCallSpells =
|
||||||
|
{
|
||||||
|
{ SPELL_MAGE, CLASS_MAGE },
|
||||||
|
{ SPELL_WARRIOR, CLASS_WARRIOR },
|
||||||
|
{ SPELL_DRUID, CLASS_DRUID },
|
||||||
|
{ SPELL_PRIEST, CLASS_PRIEST },
|
||||||
|
{ SPELL_PALADIN, CLASS_PALADIN },
|
||||||
|
{ SPELL_SHAMAN, CLASS_SHAMAN },
|
||||||
|
{ SPELL_WARLOCK, CLASS_WARLOCK },
|
||||||
|
{ SPELL_HUNTER, CLASS_HUNTER },
|
||||||
|
{ SPELL_ROGUE, CLASS_ROGUE }
|
||||||
|
};
|
||||||
|
|
||||||
|
class spell_class_call_handler : public SpellScript
|
||||||
|
{
|
||||||
|
PrepareSpellScript(spell_class_call_handler);
|
||||||
|
|
||||||
|
bool Validate(SpellInfo const* /*spellInfo*/) override
|
||||||
|
{
|
||||||
|
return ValidateSpellInfo({ SPELL_SUMMON_INFERNALS });
|
||||||
|
}
|
||||||
|
|
||||||
|
void FilterTargets(std::list<WorldObject*>& targets)
|
||||||
|
{
|
||||||
|
if (SpellInfo const* spellInfo = GetSpellInfo())
|
||||||
|
{
|
||||||
|
targets.remove_if([spellInfo](WorldObject const* target) -> bool
|
||||||
|
{
|
||||||
|
Player const* player = target->ToPlayer();
|
||||||
|
if (!player || player->getClass() == CLASS_DEATH_KNIGHT) // ignore all death knights from whatever spell, for some reason the condition below is not working x.x
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto it = classCallSpells.find(spellInfo->Id);
|
||||||
|
if (it != classCallSpells.end()) // should never happen but only to be sure.
|
||||||
|
{
|
||||||
|
return target->ToPlayer()->getClass() != it->second;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void HandleOnHitRogue()
|
||||||
|
{
|
||||||
|
Unit* caster = GetCaster();
|
||||||
|
Unit* target = GetHitUnit();
|
||||||
|
|
||||||
|
if (!caster || !target)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
float angle = rand_norm() * 2 * M_PI;
|
||||||
|
Position tp = caster->GetPosition();
|
||||||
|
tp.m_positionX += std::cos(angle) * 5.f;
|
||||||
|
tp.m_positionY += std::sin(angle) * 5.f;
|
||||||
|
float z = tp.m_positionZ + 0.5f;
|
||||||
|
caster->UpdateAllowedPositionZ(tp.GetPositionX(), tp.GetPositionY(), z);
|
||||||
|
target->NearTeleportTo(tp.GetPositionX(), tp.GetPositionY(), z, angle - M_PI);
|
||||||
|
target->UpdatePositionData();
|
||||||
|
}
|
||||||
|
|
||||||
|
void HandleOnHitWarlock()
|
||||||
|
{
|
||||||
|
if (GetHitUnit())
|
||||||
|
{
|
||||||
|
GetHitUnit()->CastSpell(GetHitUnit(), SPELL_SUMMON_INFERNALS, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Register() override
|
||||||
|
{
|
||||||
|
OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_class_call_handler::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY);
|
||||||
|
|
||||||
|
if (m_scriptSpellId == SPELL_ROGUE)
|
||||||
|
{
|
||||||
|
OnHit += SpellHitFn(spell_class_call_handler::HandleOnHitRogue);
|
||||||
|
}
|
||||||
|
else if (m_scriptSpellId == SPELL_WARLOCK)
|
||||||
|
{
|
||||||
|
OnHit += SpellHitFn(spell_class_call_handler::HandleOnHitWarlock);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class aura_class_call_wild_magic : public AuraScript
|
||||||
|
{
|
||||||
|
PrepareAuraScript(aura_class_call_wild_magic);
|
||||||
|
|
||||||
|
bool Validate(SpellInfo const* /*spellInfo*/) override
|
||||||
|
{
|
||||||
|
return ValidateSpellInfo({ SPELL_POLYMORPH });
|
||||||
|
}
|
||||||
|
|
||||||
|
void HandlePeriodic(AuraEffect const* /*aurEff*/)
|
||||||
|
{
|
||||||
|
if (!GetTarget())
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
GetTarget()->CastSpell(GetTarget(), SPELL_POLYMORPH, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Register() override
|
||||||
|
{
|
||||||
|
OnEffectPeriodic += AuraEffectPeriodicFn(aura_class_call_wild_magic::HandlePeriodic, EFFECT_0, SPELL_AURA_PERIODIC_TRIGGER_SPELL);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class aura_class_call_siphon_blessing : public AuraScript
|
||||||
|
{
|
||||||
|
PrepareAuraScript(aura_class_call_siphon_blessing);
|
||||||
|
|
||||||
|
bool Validate(SpellInfo const* /*spellInfo*/) override
|
||||||
|
{
|
||||||
|
return ValidateSpellInfo({ SPELL_BLESSING_PROTECTION });
|
||||||
|
}
|
||||||
|
|
||||||
|
void HandlePeriodic(AuraEffect const* /*aurEff*/)
|
||||||
|
{
|
||||||
|
PreventDefaultAction();
|
||||||
|
|
||||||
|
if (Unit* target = GetTarget())
|
||||||
|
{
|
||||||
|
if (Unit* nefarian = target->FindNearestCreature(NPC_NEFARIAN, 100.f))
|
||||||
|
{
|
||||||
|
target->CastSpell(nefarian, SPELL_BLESSING_PROTECTION, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Register() override
|
||||||
|
{
|
||||||
|
OnEffectPeriodic += AuraEffectPeriodicFn(aura_class_call_siphon_blessing::HandlePeriodic, EFFECT_0, SPELL_AURA_PERIODIC_TRIGGER_SPELL);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class spell_class_call_polymorph : public SpellScript
|
||||||
|
{
|
||||||
|
PrepareSpellScript(spell_class_call_polymorph);
|
||||||
|
|
||||||
|
std::list<WorldObject*> targetList;
|
||||||
|
|
||||||
|
void FilterTargets(std::list<WorldObject*>& targets)
|
||||||
|
{
|
||||||
|
targets.remove_if([&](WorldObject const* target) -> bool
|
||||||
|
{
|
||||||
|
return target->GetTypeId() != TYPEID_PLAYER || target->ToPlayer()->IsGameMaster() || target->ToPlayer()->HasAura(SPELL_POLYMORPH);
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!targets.empty())
|
||||||
|
{
|
||||||
|
Acore::Containers::RandomResize(targets, 1);
|
||||||
|
targetList.clear();
|
||||||
|
targetList = targets;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void FilterTargetsEff(std::list<WorldObject*>& targets)
|
||||||
|
{
|
||||||
|
targets.clear();
|
||||||
|
targets = targetList;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Register() override
|
||||||
|
{
|
||||||
|
OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_class_call_polymorph::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ALLY);
|
||||||
|
OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_class_call_polymorph::FilterTargetsEff, EFFECT_1, TARGET_UNIT_SRC_AREA_ALLY);
|
||||||
|
OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_class_call_polymorph::FilterTargetsEff, EFFECT_2, TARGET_UNIT_SRC_AREA_ALLY);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class aura_class_call_berserk : public AuraScript
|
||||||
|
{
|
||||||
|
PrepareAuraScript(aura_class_call_berserk);
|
||||||
|
|
||||||
|
bool Validate(SpellInfo const* /*spellInfo*/) override
|
||||||
|
{
|
||||||
|
return ValidateSpellInfo({ SPELL_WARRIOR_BERSERK });
|
||||||
|
}
|
||||||
|
|
||||||
|
void HandleOnEffectRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
|
||||||
|
{
|
||||||
|
if (Unit* target = GetTarget())
|
||||||
|
{
|
||||||
|
target->CastSpell(target, SPELL_WARRIOR_BERSERK);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Register() override
|
||||||
|
{
|
||||||
|
OnEffectRemove += AuraEffectRemoveFn(aura_class_call_berserk::HandleOnEffectRemove, EFFECT_0, SPELL_AURA_MOD_SHAPESHIFT, AURA_EFFECT_HANDLE_REAL);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class spell_corrupted_totems : public SpellScript
|
||||||
|
{
|
||||||
|
PrepareSpellScript(spell_corrupted_totems);
|
||||||
|
|
||||||
|
bool Validate(SpellInfo const* /*spellInfo*/) override
|
||||||
|
{
|
||||||
|
return ValidateSpellInfo({ SPELL_CORRUPTED_FIRE_NOVA_TOTEM, SPELL_CORRUPTED_HEALING_TOTEM, SPELL_CORRUPTED_STONESKIN_TOTEM, SPELL_CORRUPTED_WINDFURY_TOTEM });
|
||||||
|
}
|
||||||
|
|
||||||
|
void HandleDummy(SpellEffIndex effIndex)
|
||||||
|
{
|
||||||
|
PreventHitDefaultEffect(effIndex);
|
||||||
|
if (!GetCaster())
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::list<uint32> spellList = { SPELL_CORRUPTED_FIRE_NOVA_TOTEM, SPELL_CORRUPTED_HEALING_TOTEM, SPELL_CORRUPTED_STONESKIN_TOTEM, SPELL_CORRUPTED_WINDFURY_TOTEM };
|
||||||
|
uint32 spellId = Acore::Containers::SelectRandomContainerElement(spellList);
|
||||||
|
GetCaster()->CastSpell(GetCaster(), spellId);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Register() override
|
||||||
|
{
|
||||||
|
OnEffectHitTarget += SpellEffectFn(spell_corrupted_totems::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
enum ShadowblinkRandomSpells
|
||||||
|
{
|
||||||
|
SPELL_SHADOWBLINK_TRIGGERED_1 = 22668,
|
||||||
|
SPELL_SHADOWBLINK_TRIGGERED_2 = 22669,
|
||||||
|
SPELL_SHADOWBLINK_TRIGGERED_3 = 22670,
|
||||||
|
SPELL_SHADOWBLINK_TRIGGERED_4 = 22671,
|
||||||
|
SPELL_SHADOWBLINK_TRIGGERED_5 = 22672,
|
||||||
|
SPELL_SHADOWBLINK_TRIGGERED_6 = 22673,
|
||||||
|
SPELL_SHADOWBLINK_TRIGGERED_7 = 22674,
|
||||||
|
SPELL_SHADOWBLINK_TRIGGERED_8 = 22675,
|
||||||
|
SPELL_SHADOWBLINK_TRIGGERED_9 = 22676,
|
||||||
|
};
|
||||||
|
|
||||||
|
std::unordered_map<uint32, const Position> const spellPos = {
|
||||||
|
{ SPELL_SHADOWBLINK_TRIGGERED_1, Position(-7581.11f, -1216.19f) },
|
||||||
|
{ SPELL_SHADOWBLINK_TRIGGERED_2, Position(-7561.54f, -1244.01f) },
|
||||||
|
{ SPELL_SHADOWBLINK_TRIGGERED_3, Position(-7542.47f, -1191.92f) },
|
||||||
|
{ SPELL_SHADOWBLINK_TRIGGERED_4, Position(-7538.63f, -1273.64f) },
|
||||||
|
{ SPELL_SHADOWBLINK_TRIGGERED_5, Position(-7524.36f, -1219.12f) },
|
||||||
|
{ SPELL_SHADOWBLINK_TRIGGERED_6, Position(-7506.58f, -1165.26f) },
|
||||||
|
{ SPELL_SHADOWBLINK_TRIGGERED_7, Position(-7500.70f, -1249.89f) },
|
||||||
|
{ SPELL_SHADOWBLINK_TRIGGERED_8, Position(-7486.36f, -1194.32f) },
|
||||||
|
{ SPELL_SHADOWBLINK_TRIGGERED_9, Position(-7469.93f, -1227.93f) },
|
||||||
|
};
|
||||||
|
|
||||||
|
class spell_shadowblink : public SpellScript
|
||||||
|
{
|
||||||
|
PrepareSpellScript(spell_shadowblink);
|
||||||
|
|
||||||
|
bool Validate(SpellInfo const* /*spellInfo*/) override
|
||||||
|
{
|
||||||
|
return ValidateSpellInfo({ SPELL_SHADOWBLINK_TRIGGERED_1, SPELL_SHADOWBLINK_TRIGGERED_2, SPELL_SHADOWBLINK_TRIGGERED_3, SPELL_SHADOWBLINK_TRIGGERED_4, SPELL_SHADOWBLINK_TRIGGERED_5, SPELL_SHADOWBLINK_TRIGGERED_6, SPELL_SHADOWBLINK_TRIGGERED_7, SPELL_SHADOWBLINK_TRIGGERED_8, SPELL_SHADOWBLINK_TRIGGERED_9 });
|
||||||
|
}
|
||||||
|
|
||||||
|
void HandleDummy(SpellEffIndex /*effIndex*/)
|
||||||
|
{
|
||||||
|
Unit* caster = GetCaster();
|
||||||
|
if (!caster || !caster->ToCreature() || !caster->ToCreature()->AI())
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Unit* target = caster->ToCreature()->AI()->SelectTarget(SelectTargetMethod::Random, 0, 200.f, true);
|
||||||
|
if (!target)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (auto itr : spellPos)
|
||||||
|
{
|
||||||
|
float distTarget = target->GetDistance2d(itr.second.m_positionX, itr.second.m_positionY);
|
||||||
|
if (distTarget <= 30.f)
|
||||||
|
{
|
||||||
|
caster->CastSpell(caster, itr.first, true);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Selected target is not near any known position, randomize
|
||||||
|
auto spellId = Acore::Containers::SelectRandomContainerElement(spellPos);
|
||||||
|
caster->CastSpell(caster, spellId.first, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Register() override
|
||||||
|
{
|
||||||
|
OnEffectHitTarget += SpellEffectFn(spell_shadowblink::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
void AddSC_boss_nefarian()
|
void AddSC_boss_nefarian()
|
||||||
{
|
{
|
||||||
new boss_victor_nefarius();
|
new boss_victor_nefarius();
|
||||||
new boss_nefarian();
|
RegisterCreatureAI(boss_nefarian);
|
||||||
|
RegisterCreatureAI(npc_corrupted_totem);
|
||||||
|
RegisterSpellScript(spell_class_call_handler);
|
||||||
|
RegisterSpellScript(aura_class_call_wild_magic);
|
||||||
|
RegisterSpellScript(aura_class_call_siphon_blessing);
|
||||||
|
RegisterSpellScript(spell_class_call_polymorph);
|
||||||
|
RegisterSpellScript(aura_class_call_berserk);
|
||||||
|
RegisterSpellScript(spell_corrupted_totems);
|
||||||
|
RegisterSpellScript(spell_shadowblink);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user