aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authoroffl <11556157+offl@users.noreply.github.com>2021-12-09 17:10:24 +0200
committerGitHub <noreply@github.com>2021-12-09 17:10:24 +0200
commit36ee9714157e3af4e2b6b3bb9a753e28360ccd58 (patch)
tree835b5bc6c5e067130ee6a82a2bba2e5dcc4afae5
parent8516984ffe1a0241b5cfc47f2d0124291503aec1 (diff)
Scripts/HoS: Update Sjonnir (#27357)
-rw-r--r--sql/updates/world/3.3.5/2021_12_09_05_world.sql100
-rw-r--r--src/server/scripts/Northrend/Ulduar/HallsOfStone/boss_sjonnir.cpp427
2 files changed, 415 insertions, 112 deletions
diff --git a/sql/updates/world/3.3.5/2021_12_09_05_world.sql b/sql/updates/world/3.3.5/2021_12_09_05_world.sql
new file mode 100644
index 00000000000..8b492781663
--- /dev/null
+++ b/sql/updates/world/3.3.5/2021_12_09_05_world.sql
@@ -0,0 +1,100 @@
+-- Sjonnir
+UPDATE `creature_text` SET `Type` = 14, `Sound` = 14181 WHERE `CreatureID` = 27978 AND `GroupID` = 1 AND `ID` = 2;
+DELETE FROM `creature_text` WHERE `CreatureID` = 27978 AND `GroupID` = 3;
+INSERT INTO `creature_text` (`CreatureID`,`GroupID`,`ID`,`Text`,`Type`,`Language`,`Probability`,`Emote`,`Duration`,`Sound`,`BroadcastTextId`,`TextRange`,`comment`) VALUES
+(27978,3,0,"%s goes into a frenzy!",16,0,100,0,0,0,1191,0,"Sjonnir EMOTE_FRENZY");
+
+DELETE FROM `spelldifficulty_dbc` WHERE `id` IN (50792,50801);
+INSERT INTO `spelldifficulty_dbc` (`id`, `spellid0`, `spellid1`, `spellid2`, `spellid3`) VALUES
+(50792,50792,59859,0,0),
+(50801,50801,59858,0,0);
+
+DELETE FROM `conditions` WHERE `SourceTypeOrReferenceId` = 13 AND `SourceEntry` IN (50790,50791,50793,50794,50802,50803,50825,50826);
+INSERT INTO `conditions` (`SourceTypeOrReferenceId`, `SourceGroup`, `SourceEntry`, `SourceId`, `ElseGroup`, `ConditionTypeOrReference`, `ConditionTarget`, `ConditionValue1`, `ConditionValue2`, `ConditionValue3`, `NegativeCondition`, `ErrorType`, `ErrorTextId`, `ScriptName`, `Comment`) VALUES
+(13,1,50790,0,0,31,0,3,22515,126813,0,0,0,"","Group 0: Spell 'Summon Iron Dwarf' (Effect 1) targets creature 'World Trigger'"),
+(13,2,50790,0,0,31,0,5,192163,0,0,0,0,"","Group 0: Spell 'Summon Iron Dwarf' (Effect 2) targets object 'Left Pipe'"),
+
+(13,1,50791,0,0,31,0,3,22515,126812,0,0,0,"","Group 0: Spell 'Summon Iron Dwarf' (Effect 1) targets creature 'World Trigger'"),
+(13,2,50791,0,0,31,0,5,192164,0,0,0,0,"","Group 0: Spell 'Summon Iron Dwarf' (Effect 2) targets object 'Right Pipe'"),
+
+(13,1,50793,0,0,31,0,3,22515,126813,0,0,0,"","Group 0: Spell 'Summon Iron Trogg' (Effect 1) targets creature 'World Trigger'"),
+(13,1,50794,0,0,31,0,3,22515,126812,0,0,0,"","Group 0: Spell 'Summon Iron Trogg' (Effect 1) targets creature 'World Trigger'"),
+
+(13,1,50802,0,0,31,0,3,22515,126813,0,0,0,"","Group 0: Spell 'Summon Malformed Ooze' (Effect 1) targets creature 'World Trigger'"),
+(13,2,50802,0,0,31,0,5,192163,0,0,0,0,"","Group 0: Spell 'Summon Malformed Ooze' (Effect 2) targets object 'Left Pipe'"),
+
+(13,1,50803,0,0,31,0,3,22515,126812,0,0,0,"","Group 0: Spell 'Summon Malformed Ooze' (Effect 1) targets creature 'World Trigger'"),
+(13,2,50803,0,0,31,0,5,192164,0,0,0,0,"","Group 0: Spell 'Summon Malformed Ooze' (Effect 2) targets object 'Right Pipe'"),
+
+(13,1,50825,0,0,31,0,3,22515,126813,0,0,0,"","Group 0: Spell 'Summon Earthen Dwarf' (Effect 1) targets creature 'World Trigger'"),
+(13,2,50825,0,0,31,0,5,192163,0,0,0,0,"","Group 0: Spell 'Summon Earthen Dwarf' (Effect 2) targets object 'Left Pipe'"),
+
+(13,1,50826,0,0,31,0,3,22515,126812,0,0,0,"","Group 0: Spell 'Summon Earthen Dwarf' (Effect 1) targets creature 'World Trigger'"),
+(13,2,50826,0,0,31,0,5,192164,0,0,0,0,"","Group 0: Spell 'Summon Earthen Dwarf' (Effect 2) targets object 'Right Pipe'");
+
+DELETE FROM `spell_script_names` WHERE
+(`spell_id` = 50789 AND `ScriptName` = 'spell_sjonnir_periodic_summon_iron_dwarf') OR
+(`spell_id` = 50792 AND `ScriptName` = 'spell_sjonnir_periodic_summon_iron_trogg') OR
+(`spell_id` = 59859 AND `ScriptName` = 'spell_sjonnir_periodic_summon_iron_trogg') OR
+(`spell_id` = 50801 AND `ScriptName` = 'spell_sjonnir_periodic_summon_malformed_ooze') OR
+(`spell_id` = 59858 AND `ScriptName` = 'spell_sjonnir_periodic_summon_malformed_ooze') OR
+(`spell_id` = 50824 AND `ScriptName` = 'spell_sjonnir_periodic_summon_earthen_dwarf');
+INSERT INTO `spell_script_names` (`spell_id`,`ScriptName`) VALUES
+(50789,'spell_sjonnir_periodic_summon_iron_dwarf'),
+(50792,'spell_sjonnir_periodic_summon_iron_trogg'),
+(59859,'spell_sjonnir_periodic_summon_iron_trogg'),
+(50801,'spell_sjonnir_periodic_summon_malformed_ooze'),
+(59858,'spell_sjonnir_periodic_summon_malformed_ooze'),
+(50824,'spell_sjonnir_periodic_summon_earthen_dwarf');
+
+-- Iron Sludge
+DELETE FROM `spelldifficulty_dbc` WHERE `id` IN (50838);
+INSERT INTO `spelldifficulty_dbc` (`id`, `spellid0`, `spellid1`, `spellid2`, `spellid3`) VALUES
+(50838,50838,59853,0,0);
+
+DELETE FROM `spell_script_names` WHERE `spell_id` = 50777 AND `ScriptName` = 'spell_sjonnir_iron_sludge_spawn_visual';
+INSERT INTO `spell_script_names` (`spell_id`,`ScriptName`) VALUES
+(50777,'spell_sjonnir_iron_sludge_spawn_visual');
+
+-- Malformed Ooze
+UPDATE `creature_template` SET `speed_walk` = 1.6, `speed_run` = 0.571429 WHERE `entry` IN (27981,31388);
+UPDATE `creature_template` SET `maxlevel` = 79 WHERE `entry` = 27981;
+
+DELETE FROM `conditions` WHERE `SourceTypeOrReferenceId` = 13 AND `SourceEntry` IN (50742,50747);
+INSERT INTO `conditions` (`SourceTypeOrReferenceId`, `SourceGroup`, `SourceEntry`, `SourceId`, `ElseGroup`, `ConditionTypeOrReference`, `ConditionTarget`, `ConditionValue1`, `ConditionValue2`, `ConditionValue3`, `NegativeCondition`, `ErrorType`, `ErrorTextId`, `ScriptName`, `Comment`) VALUES
+(13,1,50742,0,0,31,0,3,27981,0,0,0,0,"","Group 0: Spell 'Ooze Combine' (Effect 1) targets creature 'Malformed Ooze'"),
+-- Prevents one creature get targeted by more than one creature
+(13,1,50742,0,0,1,0,50741,0,0,0,0,0,"","Group 0: Spell 'Ooze Combine' (Effect 1) requires aura 'Ooze Combine' on target"),
+
+(13,7,50747,0,0,31,0,3,27981,0,0,0,0,"","Group 0: Spell 'Summon Iron Sludge' (Effect 1 & 2 & 3) targets creature 'Malformed Ooze'"),
+-- Check again target
+(13,7,50747,0,0,1,0,50741,0,0,1,0,0,"","Group 0: Spell 'Summon Iron Sludge' (Effect 1 & 2 & 3) targets creature without aura 'Ooze Combine'");
+
+-- Earthen Dwarf
+UPDATE `creature_template` SET `speed_run` = 0.99206284114, `DamageModifier` = 2 WHERE `entry` = 27980;
+UPDATE `creature_template` SET `speed_run` = 0.99206284114, `DamageModifier` = 2 WHERE `entry` = 31391;
+
+-- Forged Iron Dwarf
+UPDATE `creature_template` SET `speed_run` = 0.99206284114 WHERE `entry` IN (27982,31394);
+UPDATE `creature_template` SET `AIName` = 'SmartAI' WHERE `entry` = 27982;
+
+DELETE FROM `spelldifficulty_dbc` WHERE `id` IN (50895);
+INSERT INTO `spelldifficulty_dbc` (`id`, `spellid0`, `spellid1`, `spellid2`, `spellid3`) VALUES
+(50895,50895,59851,0,0);
+
+DELETE FROM `smart_scripts` WHERE `entryorguid` = 27982 AND `source_type` = 0;
+INSERT INTO `smart_scripts` (`entryorguid`,`source_type`,`id`,`link`,`event_type`,`event_phase_mask`,`event_chance`,`event_flags`,`event_param1`,`event_param2`,`event_param3`,`event_param4`,`event_param5`,`action_type`,`action_param1`,`action_param2`,`action_param3`,`action_param4`,`action_param5`,`action_param6`,`target_type`,`target_param1`,`target_param2`,`target_param3`,`target_param4`,`target_x`,`target_y`,`target_z`,`target_o`,`comment`) VALUES
+(27982,0,0,0,37,0,100,0,0,0,0,0,0,116,5,0,0,0,0,0,1,0,0,0,0,0,0,0,0,"Forged Iron Dwarf - On AI Initialize - Set Corpse Delay"),
+(27982,0,1,0,0,0,100,0,10000,10000,6000,6000,0,11,50895,0,0,0,0,0,2,0,0,0,0,0,0,0,0,"Forged Iron Dwarf - In Combat - Cast 'Lightning Tether'");
+
+-- Forged Iron Trogg
+UPDATE `creature_template` SET `AIName` = 'SmartAI' WHERE `entry` = 27979;
+
+DELETE FROM `spelldifficulty_dbc` WHERE `id` IN (50900);
+INSERT INTO `spelldifficulty_dbc` (`id`, `spellid0`, `spellid1`, `spellid2`, `spellid3`) VALUES
+(50900,50900,59852,0,0);
+
+DELETE FROM `smart_scripts` WHERE `entryorguid` = 27979 AND `source_type` = 0;
+INSERT INTO `smart_scripts` (`entryorguid`,`source_type`,`id`,`link`,`event_type`,`event_phase_mask`,`event_chance`,`event_flags`,`event_param1`,`event_param2`,`event_param3`,`event_param4`,`event_param5`,`action_type`,`action_param1`,`action_param2`,`action_param3`,`action_param4`,`action_param5`,`action_param6`,`target_type`,`target_param1`,`target_param2`,`target_param3`,`target_param4`,`target_x`,`target_y`,`target_z`,`target_o`,`comment`) VALUES
+(27979,0,0,0,37,0,100,0,0,0,0,0,0,116,5,0,0,0,0,0,1,0,0,0,0,0,0,0,0,"Forged Iron Trogg - On AI Initialize - Set Corpse Delay"),
+(27979,0,1,0,0,0,100,0,3000,5000,3000,5000,0,11,50900,0,0,0,0,0,2,0,0,0,0,0,0,0,0,"Forged Iron Trogg - In Combat - Cast 'Lightning Shock'");
diff --git a/src/server/scripts/Northrend/Ulduar/HallsOfStone/boss_sjonnir.cpp b/src/server/scripts/Northrend/Ulduar/HallsOfStone/boss_sjonnir.cpp
index 58654003721..4cb30ef4b87 100644
--- a/src/server/scripts/Northrend/Ulduar/HallsOfStone/boss_sjonnir.cpp
+++ b/src/server/scripts/Northrend/Ulduar/HallsOfStone/boss_sjonnir.cpp
@@ -21,100 +21,157 @@
#include "MotionMaster.h"
#include "ObjectAccessor.h"
#include "ScriptedCreature.h"
+#include "SpellInfo.h"
+#include "SpellMgr.h"
+#include "SpellScript.h"
-enum Spells
+enum Texts
{
- SPELL_LIGHTING_RING = 51849, // Periodic Trigger (interval 2s) spell = 50841
- SPELL_LIGHTING_RING_1 = 50840, // Periodic Trigger (interval 2s) spell = 50841
- SPELL_STATIC_CHARGE = 50834, // Periodic Trigger 2s interval, spell =50835
- SPELL_CHAIN_LIGHTING = 50830,
- SPELL_LIGHTING_SHIELD = 50831,
- SPELL_FRENZY = 28747
+ SAY_AGGRO = 0,
+ SAY_SLAY = 1,
+ SAY_DEATH = 2,
+ EMOTE_FRENZY = 3
};
-enum Yells
+enum Spells
{
- SAY_AGGRO = 0,
- SAY_SLAY = 1,
- SAY_DEATH = 2
+ SPELL_LIGHTNING_RING_1 = 50840,
+ SPELL_LIGHTNING_RING_2 = 51849,
+ SPELL_STATIC_CHARGE = 50834,
+ SPELL_CHAIN_LIGHTNING = 50830,
+ SPELL_LIGHTNING_SHIELD = 50831,
+ SPELL_FRENZY = 28747,
+
+ SPELL_SUMMON_IRON_DWARF_PERIODIC = 50789, // 59860 not used
+ SPELL_SUMMON_IRON_DWARF_1 = 50790,
+ SPELL_SUMMON_IRON_DWARF_2 = 50791,
+ SPELL_SUMMON_IRON_TROGG_PERIODIC = 50792,
+ SPELL_SUMMON_IRON_TROGG_1 = 50793,
+ SPELL_SUMMON_IRON_TROGG_2 = 50794,
+ SPELL_SUMMON_MALFORMED_OOZE_PERIODIC = 50801,
+ SPELL_SUMMON_MALFORMED_OOZE_1 = 50802,
+ SPELL_SUMMON_MALFORMED_OOZE_2 = 50803,
+ SPELL_SUMMON_EARTHEN_DWARF_PERIODIC = 50824,
+ SPELL_SUMMON_EARTHEN_DWARF_1 = 50825,
+ SPELL_SUMMON_EARTHEN_DWARF_2 = 50826,
+
+ // Malformed Ooze
+ SPELL_OOZE_COMBINE_PERIODIC = 50741,
+ SPELL_OOZE_COMBINE_EFFECT = 50742,
+ SPELL_SUMMON_IRON_SLUDGE = 50747,
+
+ // Iron Sludge
+ SPELL_IRON_SLUDGE_SPAWN_VISUAL = 50777,
+ SPELL_TOXIC_VOLLEY = 50838
};
-enum SjonnirCreatures
+enum Creatures
{
- NPC_FORGED_IRON_TROGG = 27979,
- NPC_MALFORMED_OOZE = 27981,
- NPC_FORGED_IRON_DWARF = 27982,
- NPC_IRON_SLUDGE = 28165,
- NPC_EARTHEN_DWARF = 27980
+ NPC_FORGED_IRON_TROGG = 27979,
+ NPC_FORGED_IRON_DWARF = 27982,
+ NPC_EARTHEN_DWARF = 27980
};
enum Misc
{
- ACTION_OOZE_DEAD = 1,
- DATA_ABUSE_THE_OOZE = 2
+ POINT_CENTER = 0,
+ POINT_COMBINE = 1,
+
+ ACTION_SLUDGE_DEAD = 1,
+ DATA_ABUSE_THE_OOZE = 2
};
enum Events
{
- EVENT_CHAIN_LIGHTNING = 1,
+ EVENT_CHAIN_LIGHTNING = 1,
EVENT_LIGHTNING_SHIELD,
EVENT_STATIC_CHARGE,
- EVENT_LIGHTNING_RING,
- EVENT_SUMMON,
- EVENT_FRENZY,
+ EVENT_LIGHTNING_RING_1,
+ EVENT_LIGHTNING_RING_2,
+ EVENT_FRENZY
};
-Position const PipeLocations[] =
-{
- { 1295.44f, 734.07f, 200.3f, 0.0f }, // left
- { 1297.7f, 595.6f, 199.9f, 0.0f } // right
-};
-
-Position const CenterPoint = { 1295.21f, 667.157f, 189.691f, 0.0f };
+Position const CenterPoint = { 1293.8799f, 666.942f, 189.60754f, 0.0f };
struct boss_sjonnir : public BossAI
{
- boss_sjonnir(Creature* creature) : BossAI(creature, DATA_SJONNIR)
- {
- Initialize();
- }
+ boss_sjonnir(Creature* creature) : BossAI(creature, DATA_SJONNIR),
+ _sludgesKilled(0), _summonsTroggs(false), _summonsOozes(false), _summonsDwarfs(false), _frenzied(false) { }
- void Initialize()
+ void JustEngagedWith(Unit* who) override
{
- abuseTheOoze = 0;
+ if (!instance->CheckRequiredBosses(DATA_SJONNIR, who->ToPlayer()))
+ {
+ EnterEvadeMode(EVADE_REASON_SEQUENCE_BREAK);
+ return;
+ }
+
+ BossAI::JustEngagedWith(who);
+ Talk(SAY_AGGRO);
+ DoCastSelf(SPELL_SUMMON_IRON_DWARF_PERIODIC);
+
+ events.ScheduleEvent(EVENT_CHAIN_LIGHTNING, 10s, 15s);
+ events.ScheduleEvent(EVENT_STATIC_CHARGE, 15s, 20s);
+ events.ScheduleEvent(EVENT_LIGHTNING_RING_1, 30s);
+ /// @todo: Schedule both in combat and out of combat
+ events.ScheduleEvent(EVENT_LIGHTNING_SHIELD, 5s, 15s);
}
- void Reset() override
+ void JustSummoned(Creature* summoned) override
{
- _Reset();
- Initialize();
+ switch (summoned->GetEntry())
+ {
+ case NPC_FORGED_IRON_DWARF:
+ case NPC_FORGED_IRON_TROGG:
+ // AttackStart(me->GetVictim()) does not work in case of very first spawn
+ if (Unit* target = SelectTarget(SelectTargetMethod::MaxThreat))
+ summoned->AI()->AttackStart(target);
+ break;
+ case NPC_EARTHEN_DWARF:
+ summoned->AI()->AttackStart(me);
+ break;
+ }
+ summons.Summon(summoned);
}
- void JustEngagedWith(Unit* who) override
+ void DamageTaken(Unit* /*attacker*/, uint32& damage, DamageEffectType /*damageType*/, SpellInfo const* /*spellInfo = nullptr*/) override
{
- if (!instance->CheckRequiredBosses(DATA_SJONNIR, who->ToPlayer()))
+ if (me->HealthBelowPctDamaged(75, damage) && !_summonsTroggs)
{
- EnterEvadeMode();
- return;
+ _summonsTroggs = true;
+ me->RemoveAurasDueToSpell(SPELL_SUMMON_IRON_DWARF_PERIODIC);
+ DoCastSelf(SPELL_SUMMON_IRON_TROGG_PERIODIC, true);
}
- BossAI::JustEngagedWith(who);
- Talk(SAY_AGGRO);
+ if (me->HealthBelowPctDamaged(50, damage) && !_summonsOozes)
+ {
+ _summonsOozes = true;
+ me->RemoveAurasDueToSpell(sSpellMgr->GetSpellIdForDifficulty(SPELL_SUMMON_IRON_TROGG_PERIODIC, me));
+ DoCastSelf(SPELL_SUMMON_MALFORMED_OOZE_PERIODIC, true);
+ }
+
+ if (me->HealthBelowPctDamaged(25, damage) && !_summonsDwarfs)
+ {
+ _summonsDwarfs = true;
+ me->RemoveAurasDueToSpell(sSpellMgr->GetSpellIdForDifficulty(SPELL_SUMMON_MALFORMED_OOZE_PERIODIC, me));
+ DoCastSelf(SPELL_SUMMON_EARTHEN_DWARF_PERIODIC, true);
+ }
- events.ScheduleEvent(EVENT_CHAIN_LIGHTNING, 3s, 8s);
- events.ScheduleEvent(EVENT_LIGHTNING_SHIELD, 20s, 25s);
- events.ScheduleEvent(EVENT_STATIC_CHARGE, 20s, 25s);
- events.ScheduleEvent(EVENT_LIGHTNING_RING, 30s, 35s);
- events.ScheduleEvent(EVENT_SUMMON, 5s);
- events.ScheduleEvent(EVENT_FRENZY, 5min);
+ if (me->HealthBelowPctDamaged(20, damage) && !_frenzied)
+ {
+ _frenzied = true;
+ // Old removed, more powerful added
+ events.CancelEvent(EVENT_LIGHTNING_RING_1);
+ events.ScheduleEvent(EVENT_FRENZY, 0s);
+ events.ScheduleEvent(EVENT_LIGHTNING_RING_2, 0s);
+ }
}
- void JustSummoned(Creature* summon) override
+ void EnterEvadeMode(EvadeReason /*why*/) override
{
- summon->GetMotionMaster()->MovePoint(0, CenterPoint);
- /*if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0, 100, true))
- summon->AI()->AttackStart(target);*/
- summons.Summon(summon);
+ summons.DespawnAll();
+ /// @todo: Despawn Brann too but respawn his pre-fight version (https://www.youtube.com/watch?v=hxAxbjGfuDw)
+ _DespawnAtEvade();
}
void JustDied(Unit* /*killer*/) override
@@ -131,14 +188,14 @@ struct boss_sjonnir : public BossAI
void DoAction(int32 action) override
{
- if (action == ACTION_OOZE_DEAD)
- ++abuseTheOoze;
+ if (action == ACTION_SLUDGE_DEAD)
+ ++_sludgesKilled;
}
uint32 GetData(uint32 type) const override
{
if (type == DATA_ABUSE_THE_OOZE)
- return abuseTheOoze;
+ return _sludgesKilled;
return 0;
}
@@ -158,39 +215,30 @@ struct boss_sjonnir : public BossAI
switch (eventId)
{
case EVENT_CHAIN_LIGHTNING:
- if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0, 100, true))
- DoCast(target, SPELL_CHAIN_LIGHTING);
- events.ScheduleEvent(EVENT_CHAIN_LIGHTNING, 10s, 15s);
+ DoCastVictim(SPELL_CHAIN_LIGHTNING);
+ events.Repeat(10s, 15s);
break;
case EVENT_LIGHTNING_SHIELD:
- DoCast(me, SPELL_LIGHTING_SHIELD);
+ if (!me->HasAura(sSpellMgr->GetSpellIdForDifficulty(SPELL_LIGHTNING_SHIELD, me)))
+ DoCastSelf(SPELL_LIGHTNING_SHIELD);
+ events.Repeat(5s, 15s);
break;
case EVENT_STATIC_CHARGE:
- DoCastVictim(SPELL_STATIC_CHARGE);
- events.ScheduleEvent(EVENT_STATIC_CHARGE, 20s, 25s);
+ if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0, 100, true, true))
+ DoCast(target, SPELL_STATIC_CHARGE);
+ events.Repeat(20s, 27s);
break;
- case EVENT_LIGHTNING_RING:
- DoCast(me, SPELL_LIGHTING_RING);
- events.ScheduleEvent(EVENT_LIGHTNING_RING, 30s, 35s);
+ case EVENT_LIGHTNING_RING_1:
+ DoCastSelf(SPELL_LIGHTNING_RING_1);
+ events.Repeat(50s);
break;
- case EVENT_SUMMON:
- {
- uint8 summonPipe = urand(0, 1);
- if (HealthAbovePct(75))
- me->SummonCreature(NPC_FORGED_IRON_DWARF, PipeLocations[summonPipe], TEMPSUMMON_CORPSE_TIMED_DESPAWN, 30s);
- else if (HealthAbovePct(50))
- me->SummonCreature(NPC_FORGED_IRON_TROGG, PipeLocations[summonPipe], TEMPSUMMON_CORPSE_TIMED_DESPAWN, 30s);
- else if (HealthAbovePct(25))
- me->SummonCreature(NPC_MALFORMED_OOZE, PipeLocations[summonPipe], TEMPSUMMON_CORPSE_TIMED_DESPAWN, 30s);
- else
- me->SummonCreature(NPC_EARTHEN_DWARF, PipeLocations[summonPipe], TEMPSUMMON_CORPSE_TIMED_DESPAWN, 30s);
-
- events.ScheduleEvent(EVENT_SUMMON, 20s);
+ case EVENT_LIGHTNING_RING_2:
+ DoCastSelf(SPELL_LIGHTNING_RING_2);
+ events.Repeat(15s);
break;
- }
case EVENT_FRENZY:
- /// @todo: add emote
- DoCast(me, SPELL_FRENZY, true);
+ Talk(EMOTE_FRENZY);
+ DoCastSelf(SPELL_FRENZY);
break;
default:
break;
@@ -203,65 +251,215 @@ struct boss_sjonnir : public BossAI
DoMeleeAttackIfReady();
}
- private:
- uint8 abuseTheOoze;
+private:
+ uint8 _sludgesKilled;
+ bool _summonsTroggs;
+ bool _summonsOozes;
+ bool _summonsDwarfs;
+ bool _frenzied;
};
struct npc_malformed_ooze : public ScriptedAI
{
- npc_malformed_ooze(Creature* creature) : ScriptedAI(creature)
+ npc_malformed_ooze(Creature* creature) : ScriptedAI(creature) { }
+
+ void InitializeAI() override
{
- Initialize();
+ me->SetCorpseDelay(5, true);
+ me->SetReactState(REACT_PASSIVE);
}
- void Initialize()
+ void JustAppeared() override
{
- _mergeTimer = 10000;
+ me->GetMotionMaster()->MovePoint(POINT_CENTER, CenterPoint);
}
- void Reset() override
+ void MovementInform(uint32 type, uint32 id) override
{
- Initialize();
+ if (type == POINT_MOTION_TYPE && id == POINT_CENTER)
+ {
+ DoCastSelf(SPELL_OOZE_COMBINE_PERIODIC);
+ me->GetMotionMaster()->MoveRandom(10);
+ }
}
- void UpdateAI(uint32 diff) override
+ /* This is far from correct implementation. Once ooze reaches center point, it casts periodic aura. When spell hits another ooze, both
+ caster and target removes periodic aura and caster starts moving to target. Target does not stop random movement. Once caster is close
+ enough to target, caster casts a spell to combine with target. Target despawns instantly, caster despawns after 1sec.
+
+ Since target does not stop random movement, that causes problems because combine spell is used when oozes are close enough to each other
+ but with current implementation it takes too much time to reach target, as result there may be too much oozes trying to combine at
+ the same time.
+ Increasing radius at which combine spell can be used or trying to change the way oozes chases target only creates more problems because
+ combine spell may target not required target but just ooze which was closer to caster. That leaves multiple spawns which can't combine
+ anymore since combining process was started(auras were removed) but wasn't finished sucessfully
+
+ Currently target is forced to stop random movement and caster just casts spell when is close enough to target. Spells has additional
+ conditions in DB. That makes oozes combine every time sucessfully but not too fast and give players more time too kill sludges
+ Ideally both spells should be scripted, filtering targets(if possible) and casting spell on target which was stored previously may look
+ overcomplicated but saves from casting spell on wrong target. Or maybe solving the problem with moving to stored target will be enough */
+ void SpellHitTarget(WorldObject* target, SpellInfo const* spellInfo) override
{
- if (_mergeTimer <= diff)
+ Creature* creatureTarget = target->ToCreature();
+ if (!creatureTarget)
+ return;
+
+ switch (spellInfo->Id)
{
- if (Creature* temp = me->FindNearestCreature(NPC_MALFORMED_OOZE, 3.0f, true))
- {
- DoSpawnCreature(NPC_IRON_SLUDGE, 0, 0, 0, 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 20s);
- temp->DisappearAndDie();
- me->DisappearAndDie();
- }
- _mergeTimer = 3000;
+ case SPELL_OOZE_COMBINE_EFFECT:
+ _combineTarget = creatureTarget->GetGUID();
+ me->RemoveAurasDueToSpell(SPELL_OOZE_COMBINE_PERIODIC);
+ creatureTarget->RemoveAurasDueToSpell(SPELL_OOZE_COMBINE_PERIODIC);
+ creatureTarget->GetMotionMaster()->MoveIdle();
+ me->GetMotionMaster()->MoveIdle();
+ me->GetMotionMaster()->MovePoint(POINT_COMBINE, creatureTarget->GetPosition());
+
+ _scheduler.Schedule(1s, [this](TaskContext task)
+ {
+ Creature* combineTarget = ObjectAccessor::GetCreature(*me, _combineTarget);
+ // Completely unclear what should happen in this case or in case when caster dies
+ if (!combineTarget || !combineTarget->IsAlive())
+ {
+ me->DespawnOrUnsummon();
+ return;
+ }
+
+ if (me->GetExactDist2d(combineTarget) <= 0.1f)
+ DoCast(combineTarget, SPELL_SUMMON_IRON_SLUDGE);
+ else
+ {
+ me->GetMotionMaster()->MovePoint(POINT_COMBINE, combineTarget->GetPosition());
+ task.Repeat();
+ }
+ });
+ break;
+ case SPELL_SUMMON_IRON_SLUDGE:
+ creatureTarget->DespawnOrUnsummon();
+ me->DespawnOrUnsummon(1s);
+ break;
}
- else
- _mergeTimer -= diff;
+ }
+ void UpdateAI(uint32 diff) override
+ {
+ _scheduler.Update(diff);
+ }
+
+private:
+ TaskScheduler _scheduler;
+ ObjectGuid _combineTarget;
+};
+
+struct npc_iron_sludge : public ScriptedAI
+{
+ npc_iron_sludge(Creature* creature) : ScriptedAI(creature), _instance(creature->GetInstanceScript()) { }
+
+ void JustAppeared() override
+ {
+ me->SetCorpseDelay(4, true);
+ DoCastSelf(SPELL_IRON_SLUDGE_SPAWN_VISUAL);
+
+ if (Creature* sjonnir = ObjectAccessor::GetCreature(*me, _instance->GetGuidData(DATA_SJONNIR)))
+ sjonnir->AI()->JustSummoned(me);
+ }
+
+ void JustEngagedWith(Unit* /*who*/) override
+ {
+ _scheduler.Schedule(3s, 6s, [this](TaskContext task)
+ {
+ DoCastSelf(SPELL_TOXIC_VOLLEY);
+ task.Repeat(3s, 6s);
+ });
+ }
+
+ void JustDied(Unit* /*killer*/) override
+ {
+ if (Creature* sjonnir = ObjectAccessor::GetCreature(*me, _instance->GetGuidData(DATA_SJONNIR)))
+ sjonnir->AI()->DoAction(ACTION_SLUDGE_DEAD);
+ }
+
+ void UpdateAI(uint32 diff) override
+ {
if (!UpdateVictim())
return;
- DoMeleeAttackIfReady();
+ _scheduler.Update(diff, [this]
+ {
+ DoMeleeAttackIfReady();
+ });
}
private:
- uint32 _mergeTimer;
+ InstanceScript* _instance;
+ TaskScheduler _scheduler;
};
-struct npc_iron_sludge : public ScriptedAI
+/* 50789 - Summon Iron Dwarf
+ 50792 - Summon Iron Trogg
+ 59859 - Summon Iron Trogg
+ 50801 - Summon Malformed Ooze
+ 59858 - Summon Malformed Ooze
+ 50824 - Summon Earthen Dwarf */
+class spell_sjonnir_periodic_summon : public AuraScript
{
- npc_iron_sludge(Creature* creature) : ScriptedAI(creature)
+ PrepareAuraScript(spell_sjonnir_periodic_summon);
+
+public:
+ spell_sjonnir_periodic_summon(uint32 leftPipeSpell, uint32 rightPipeSpell)
+ : AuraScript(), _leftPipeSpell(leftPipeSpell), _rightPipeSpell(rightPipeSpell) { }
+
+private:
+ bool Validate(SpellInfo const* /*spellInfo*/) override
{
- instance = creature->GetInstanceScript();
+ return ValidateSpellInfo({ _leftPipeSpell, _rightPipeSpell });
}
- InstanceScript* instance;
+ void AfterApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
+ {
+ GetTarget()->CastSpell(GetTarget(), RAND(_leftPipeSpell, _rightPipeSpell), true);
+ }
- void JustDied(Unit* /*killer*/) override
+ void OnPeriodic(AuraEffect const* /*aurEff*/)
+ {
+ GetTarget()->CastSpell(GetTarget(), RAND(_leftPipeSpell, _rightPipeSpell), true);
+ }
+
+ void Register() override
+ {
+ AfterEffectApply += AuraEffectApplyFn(spell_sjonnir_periodic_summon::AfterApply, EFFECT_0, SPELL_AURA_PERIODIC_DUMMY, AURA_EFFECT_HANDLE_REAL);
+ OnEffectPeriodic += AuraEffectPeriodicFn(spell_sjonnir_periodic_summon::OnPeriodic, EFFECT_0, SPELL_AURA_PERIODIC_DUMMY);
+ }
+
+ uint32 _leftPipeSpell;
+ uint32 _rightPipeSpell;
+};
+
+// 50777 - Iron Sludge Spawn Visual
+class spell_sjonnir_iron_sludge_spawn_visual : public AuraScript
+{
+ PrepareAuraScript(spell_sjonnir_iron_sludge_spawn_visual);
+
+ void AfterApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
+ {
+ // They're indeed passive but I'm not sure enough if it's handled by this aura or directly in script
+ if (Creature* creature = GetTarget()->ToCreature())
+ creature->SetReactState(REACT_PASSIVE);
+ }
+
+ void AfterRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
+ {
+ if (Creature* creature = GetTarget()->ToCreature())
+ {
+ creature->SetReactState(REACT_AGGRESSIVE);
+ if (creature->IsAIEnabled() && creature->IsAlive())
+ creature->AI()->DoZoneInCombat();
+ }
+ }
+
+ void Register() override
{
- if (Creature* sjonnir = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_SJONNIR)))
- sjonnir->AI()->DoAction(ACTION_OOZE_DEAD);
+ AfterEffectApply += AuraEffectApplyFn(spell_sjonnir_iron_sludge_spawn_visual::AfterApply, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL);
+ AfterEffectRemove += AuraEffectRemoveFn(spell_sjonnir_iron_sludge_spawn_visual::AfterRemove, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL);
}
};
@@ -290,5 +488,10 @@ void AddSC_boss_sjonnir()
RegisterHallsOfStoneCreatureAI(boss_sjonnir);
RegisterHallsOfStoneCreatureAI(npc_malformed_ooze);
RegisterHallsOfStoneCreatureAI(npc_iron_sludge);
+ RegisterSpellScriptWithArgs(spell_sjonnir_periodic_summon, "spell_sjonnir_periodic_summon_iron_dwarf", SPELL_SUMMON_IRON_DWARF_1, SPELL_SUMMON_IRON_DWARF_2);
+ RegisterSpellScriptWithArgs(spell_sjonnir_periodic_summon, "spell_sjonnir_periodic_summon_iron_trogg", SPELL_SUMMON_IRON_TROGG_1, SPELL_SUMMON_IRON_TROGG_2);
+ RegisterSpellScriptWithArgs(spell_sjonnir_periodic_summon, "spell_sjonnir_periodic_summon_malformed_ooze", SPELL_SUMMON_MALFORMED_OOZE_1, SPELL_SUMMON_MALFORMED_OOZE_2);
+ RegisterSpellScriptWithArgs(spell_sjonnir_periodic_summon, "spell_sjonnir_periodic_summon_earthen_dwarf", SPELL_SUMMON_EARTHEN_DWARF_1, SPELL_SUMMON_EARTHEN_DWARF_2);
+ RegisterSpellScript(spell_sjonnir_iron_sludge_spawn_visual);
new achievement_abuse_the_ooze();
}