aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sql/updates/world/3.3.5/2025_07_08_01_world.sql4
-rw-r--r--src/server/scripts/Outland/TempestKeep/arcatraz/boss_dalliah_the_doomsayer.cpp162
-rw-r--r--src/server/scripts/Outland/TempestKeep/arcatraz/boss_wrath_scryer_soccothrates.cpp151
3 files changed, 193 insertions, 124 deletions
diff --git a/sql/updates/world/3.3.5/2025_07_08_01_world.sql b/sql/updates/world/3.3.5/2025_07_08_01_world.sql
new file mode 100644
index 00000000000..f364d63db02
--- /dev/null
+++ b/sql/updates/world/3.3.5/2025_07_08_01_world.sql
@@ -0,0 +1,4 @@
+--
+DELETE FROM `spell_script_names` WHERE `ScriptName` = 'spell_dalliah_the_doomsayer_whirlwind';
+INSERT INTO `spell_script_names` (`spell_id`, `ScriptName`) VALUES
+(36142, 'spell_dalliah_the_doomsayer_whirlwind');
diff --git a/src/server/scripts/Outland/TempestKeep/arcatraz/boss_dalliah_the_doomsayer.cpp b/src/server/scripts/Outland/TempestKeep/arcatraz/boss_dalliah_the_doomsayer.cpp
index d445cd2b7e8..6a5f6358062 100644
--- a/src/server/scripts/Outland/TempestKeep/arcatraz/boss_dalliah_the_doomsayer.cpp
+++ b/src/server/scripts/Outland/TempestKeep/arcatraz/boss_dalliah_the_doomsayer.cpp
@@ -15,13 +15,21 @@
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
+/*
+ * Whirlwind gets interrupted in lots of cases
+ * Conversation between creatures requires rechecks and improvements
+ */
+
#include "ScriptMgr.h"
#include "arcatraz.h"
#include "InstanceScript.h"
#include "ObjectAccessor.h"
#include "ScriptedCreature.h"
+#include "SpellInfo.h"
+#include "SpellMgr.h"
+#include "SpellScript.h"
-enum Say
+enum DalliahTexts
{
// Dalliah the Doomsayer
SAY_AGGRO = 1,
@@ -36,83 +44,112 @@ enum Say
SAY_DALLIAH_25_PERCENT = 5
};
-enum Spells
+enum DalliahSpells
{
SPELL_GIFT_OF_THE_DOOMSAYER = 36173,
SPELL_WHIRLWIND = 36142,
SPELL_HEAL = 36144,
- SPELL_SHADOW_WAVE = 39016 // Heroic only
+ SPELL_SHADOW_WAVE = 39016, // Heroic only
+
+ SPELL_DUMMY = 36177
};
-enum Events
+enum DalliahEvents
{
EVENT_GIFT_OF_THE_DOOMSAYER = 1,
- EVENT_WHIRLWIND = 2,
- EVENT_HEAL = 3,
- EVENT_SHADOW_WAVE = 4, // Heroic only
- EVENT_ME_FIRST = 5,
- EVENT_SOCCOTHRATES_DEATH = 6
+ EVENT_WHIRLWIND,
+ EVENT_HEAL,
+ EVENT_SHADOW_WAVE,
+
+ EVENT_ME_FIRST,
+ EVENT_SOCCOTHRATES_DEATH
};
+// 20885 - Dalliah the Doomsayer
struct boss_dalliah_the_doomsayer : public BossAI
{
- boss_dalliah_the_doomsayer(Creature* creature) : BossAI(creature, DATA_DALLIAH)
- {
- soccothratesTaunt = false;
- soccothratesDeath = false;
- }
+ boss_dalliah_the_doomsayer(Creature* creature) : BossAI(creature, DATA_DALLIAH),
+ _soccothratesTaunt(false), _soccothratesDeath(false) { }
void Reset() override
{
_Reset();
- soccothratesTaunt = false;
- soccothratesDeath = false;
- }
-
- void JustDied(Unit* /*killer*/) override
- {
- _JustDied();
- Talk(SAY_DEATH);
-
- if (Creature* soccothrates = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_SOCCOTHRATES)))
- if (soccothrates->IsAlive() && !soccothrates->IsInCombat())
- soccothrates->AI()->SetData(1, 1);
+ _soccothratesTaunt = false;
+ _soccothratesDeath = false;
}
void JustEngagedWith(Unit* who) override
{
BossAI::JustEngagedWith(who);
- events.ScheduleEvent(EVENT_GIFT_OF_THE_DOOMSAYER, 1s, 4s);
- events.ScheduleEvent(EVENT_WHIRLWIND, 7s, 9s);
+ events.ScheduleEvent(EVENT_GIFT_OF_THE_DOOMSAYER, 0s, 10s);
+ events.ScheduleEvent(EVENT_WHIRLWIND, 5s, 10s);
if (IsHeroic())
- events.ScheduleEvent(EVENT_SHADOW_WAVE, 11s, 16s);
+ events.ScheduleEvent(EVENT_SHADOW_WAVE, 10s, 15s);
events.ScheduleEvent(EVENT_ME_FIRST, 6s);
Talk(SAY_AGGRO);
}
- void KilledUnit(Unit* /*victim*/) override
- {
- Talk(SAY_SLAY);
- }
-
void SetData(uint32 /*type*/, uint32 data) override
{
switch (data)
{
case 1:
events.ScheduleEvent(EVENT_SOCCOTHRATES_DEATH, 6s);
- soccothratesDeath = true;
+ _soccothratesDeath = true;
break;
default:
break;
}
}
+ void DamageTaken(Unit* /*attacker*/, uint32& damage, DamageEffectType /*damageType*/, SpellInfo const* /*spellInfo = nullptr*/) override
+ {
+ if (!_soccothratesTaunt && me->HealthBelowPctDamaged(25, damage))
+ {
+ _soccothratesTaunt = true;
+
+ if (Creature* soccothrates = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_SOCCOTHRATES)))
+ soccothrates->AI()->Talk(SAY_DALLIAH_25_PERCENT);
+ }
+ }
+
+ void SpellHit(WorldObject* /*caster*/, SpellInfo const* spellInfo) override
+ {
+ if (spellInfo->Id == SPELL_DUMMY)
+ events.ScheduleEvent(EVENT_HEAL, 0s);
+ }
+
+ void OnSpellCast(SpellInfo const* spell) override
+ {
+ if (spell->Id == SPELL_WHIRLWIND)
+ if (roll_chance_i(30))
+ Talk(SAY_WHIRLWIND);
+
+ if (spell->Id == sSpellMgr->GetSpellIdForDifficulty(SPELL_HEAL, me))
+ if (roll_chance_i(50))
+ Talk(SAY_HEAL);
+ }
+
+ void KilledUnit(Unit* /*victim*/) override
+ {
+ Talk(SAY_SLAY);
+ }
+
+ void JustDied(Unit* /*killer*/) override
+ {
+ _JustDied();
+ Talk(SAY_DEATH);
+
+ if (Creature* soccothrates = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_SOCCOTHRATES)))
+ if (soccothrates->IsAlive() && !soccothrates->IsInCombat())
+ soccothrates->AI()->SetData(1, 1);
+ }
+
void UpdateAI(uint32 diff) override
{
if (!UpdateVictim())
{
- if (soccothratesDeath)
+ if (_soccothratesDeath)
{
events.Update(diff);
@@ -142,23 +179,21 @@ struct boss_dalliah_the_doomsayer : public BossAI
switch (eventId)
{
case EVENT_GIFT_OF_THE_DOOMSAYER:
- DoCastVictim(SPELL_GIFT_OF_THE_DOOMSAYER, true);
- events.ScheduleEvent(EVENT_GIFT_OF_THE_DOOMSAYER, 16s, 21s);
+ DoCastVictim(SPELL_GIFT_OF_THE_DOOMSAYER);
+ events.Repeat(10s, 20s);
break;
case EVENT_WHIRLWIND:
- DoCast(me, SPELL_WHIRLWIND);
- Talk(SAY_WHIRLWIND);
- events.ScheduleEvent(EVENT_WHIRLWIND, 19s, 21s);
- events.ScheduleEvent(EVENT_HEAL, 6s);
+ DoCastSelf(SPELL_WHIRLWIND);
+ events.Repeat(15s, 25s);
break;
case EVENT_HEAL:
- DoCast(me, SPELL_HEAL);
- Talk(SAY_HEAL);
+ DoCastSelf(SPELL_HEAL);
break;
case EVENT_SHADOW_WAVE:
- DoCastVictim(SPELL_SHADOW_WAVE, true);
- events.ScheduleEvent(EVENT_SHADOW_WAVE, 11s, 16s);
+ DoCastVictim(SPELL_SHADOW_WAVE);
+ events.Repeat(10s, 15s);
break;
+
case EVENT_ME_FIRST:
if (Creature* soccothrates = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_SOCCOTHRATES)))
if (soccothrates->IsAlive() && !soccothrates->IsInCombat())
@@ -172,22 +207,39 @@ struct boss_dalliah_the_doomsayer : public BossAI
return;
}
- if (HealthBelowPct(25) && !soccothratesTaunt)
- {
- if (Creature* soccothrates = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_SOCCOTHRATES)))
- soccothrates->AI()->Talk(SAY_DALLIAH_25_PERCENT);
- soccothratesTaunt = true;
- }
-
DoMeleeAttackIfReady();
}
private:
- bool soccothratesTaunt;
- bool soccothratesDeath;
+ bool _soccothratesTaunt;
+ bool _soccothratesDeath;
+};
+
+// 36142 - Whirlwind
+class spell_dalliah_the_doomsayer_whirlwind : public AuraScript
+{
+ PrepareAuraScript(spell_dalliah_the_doomsayer_whirlwind);
+
+ bool Validate(SpellInfo const* /*spellInfo*/) override
+ {
+ return ValidateSpellInfo({ SPELL_DUMMY });
+ }
+
+ void AfterRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
+ {
+ // When Whirlwind ends, creature casts Dummy spell. When Dummy spell hits,
+ // creature casts Heal spell and this is how Heal after Whirlwind is handled
+ GetTarget()->CastSpell(GetTarget(), SPELL_DUMMY, true);
+ }
+
+ void Register() override
+ {
+ AfterEffectRemove += AuraEffectRemoveFn(spell_dalliah_the_doomsayer_whirlwind::AfterRemove, EFFECT_0, SPELL_AURA_PERIODIC_TRIGGER_SPELL, AURA_EFFECT_HANDLE_REAL);
+ }
};
void AddSC_boss_dalliah_the_doomsayer()
{
RegisterArcatrazCreatureAI(boss_dalliah_the_doomsayer);
+ RegisterSpellScript(spell_dalliah_the_doomsayer_whirlwind);
}
diff --git a/src/server/scripts/Outland/TempestKeep/arcatraz/boss_wrath_scryer_soccothrates.cpp b/src/server/scripts/Outland/TempestKeep/arcatraz/boss_wrath_scryer_soccothrates.cpp
index 0af123ae289..3334fbc7e9c 100644
--- a/src/server/scripts/Outland/TempestKeep/arcatraz/boss_wrath_scryer_soccothrates.cpp
+++ b/src/server/scripts/Outland/TempestKeep/arcatraz/boss_wrath_scryer_soccothrates.cpp
@@ -15,12 +15,10 @@
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-/* ScriptData
-SDName: boss_wrath_scryer_soccothrates
-SD%Complete: 95%
-SDComment: charge left to script
-SDCategory: Tempest Keep, The Arcatraz
-EndScriptData */
+/*
+ * Charge left to script
+ * Conversation between creatures requires rechecks and improvements
+ */
#include "ScriptMgr.h"
#include "arcatraz.h"
@@ -28,8 +26,9 @@ EndScriptData */
#include "MotionMaster.h"
#include "ObjectAccessor.h"
#include "ScriptedCreature.h"
+#include "SpellInfo.h"
-enum Say
+enum SoccothratesTexts
{
// Wrath-Scryer Soccothrates
SAY_AGGRO = 1,
@@ -50,75 +49,61 @@ enum Say
SAY_DALLIAH_CONVO_3 = 10
};
-enum Spells
+enum SoccothratesSpells
{
SPELL_FELFIRE_SHOCK = 35759,
SPELL_KNOCK_AWAY = 36512,
+
SPELL_FELFIRE_LINE_UP = 35770,
+ SPELL_TRIGGER_CHARGE_TARGETING = 36564,
SPELL_CHARGE_TARGETING = 36038,
SPELL_CHARGE = 35754
};
-enum Events
+enum SoccothratesEvents
{
EVENT_FELFIRE_SHOCK = 1,
- EVENT_KNOCK_AWAY = 2,
-
- EVENT_PREFIGHT_1 = 3,
- EVENT_PREFIGHT_2 = 4,
- EVENT_PREFIGHT_3 = 5,
- EVENT_PREFIGHT_4 = 6,
- EVENT_PREFIGHT_5 = 7,
- EVENT_PREFIGHT_6 = 8,
- EVENT_PREFIGHT_7 = 9,
- EVENT_PREFIGHT_8 = 10,
- EVENT_PREFIGHT_9 = 11,
- EVENT_ME_FIRST = 12,
- EVENT_DALLIAH_DEATH = 13
+ EVENT_KNOCK_AWAY,
+
+ EVENT_PREFIGHT_1,
+ EVENT_PREFIGHT_2,
+ EVENT_PREFIGHT_3,
+ EVENT_PREFIGHT_4,
+ EVENT_PREFIGHT_5,
+ EVENT_PREFIGHT_6,
+ EVENT_PREFIGHT_7,
+ EVENT_PREFIGHT_8,
+ EVENT_PREFIGHT_9,
+
+ EVENT_ME_FIRST,
+ EVENT_DALLIAH_DEATH
};
+// 20886 - Wrath-Scryer Soccothrates
struct boss_wrath_scryer_soccothrates : public BossAI
{
- boss_wrath_scryer_soccothrates(Creature* creature) : BossAI(creature, DATA_SOCCOTHRATES)
- {
- preFight = false;
- dalliahTaunt = false;
- dalliahDeath = false;
- }
+ boss_wrath_scryer_soccothrates(Creature* creature) : BossAI(creature, DATA_SOCCOTHRATES),
+ _preFight(false), _dalliahTaunt(false), _dalliahDeath(false) { }
void Reset() override
{
_Reset();
- preFight = false;
- dalliahTaunt = false;
- dalliahDeath = false;
- }
-
- void JustDied(Unit* /*killer*/) override
- {
- _JustDied();
- Talk(SAY_DEATH);
-
- if (Creature* dalliah = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_DALLIAH)))
- if (dalliah->IsAlive() && !dalliah->IsInCombat())
- dalliah->AI()->SetData(1, 1);
+ _preFight = false;
+ _dalliahTaunt = false;
+ _dalliahDeath = false;
}
void JustEngagedWith(Unit* who) override
{
BossAI::JustEngagedWith(who);
- events.ScheduleEvent(EVENT_FELFIRE_SHOCK, 12s, 14s);
- events.ScheduleEvent(EVENT_KNOCK_AWAY, 11s, 12s);
+ events.ScheduleEvent(EVENT_FELFIRE_SHOCK, 8s, 18s);
+ events.ScheduleEvent(EVENT_KNOCK_AWAY, 25s, 30s);
events.ScheduleEvent(EVENT_ME_FIRST, 6s);
Talk(SAY_AGGRO);
- preFight = false;
- }
-
- void KilledUnit(Unit* /*victim*/) override
- {
- Talk(SAY_SLAY);
+ _preFight = false;
}
+ /// @todo: Maybe this is handled by Gameobject 184953 (Tempest Keep Prison - Boss React - Trigger 001) or it belongs to Mellichar's event
void MoveInLineOfSight(Unit* who) override
{
if (instance->GetData(DATA_CONVERSATION) == NOT_STARTED && who->GetTypeId() == TYPEID_PLAYER && me->IsWithinDistInMap(who, 70.0f))
@@ -126,9 +111,11 @@ struct boss_wrath_scryer_soccothrates : public BossAI
Talk(SAY_SOCCOTHRATES_CONVO_1);
instance->SetData(DATA_CONVERSATION, DONE);
- preFight = true;
+ _preFight = true;
events.ScheduleEvent(EVENT_PREFIGHT_1, 2s);
}
+
+ BossAI::MoveInLineOfSight(who);
}
void SetData(uint32 /*type*/, uint32 data) override
@@ -137,18 +124,51 @@ struct boss_wrath_scryer_soccothrates : public BossAI
{
case 1:
events.ScheduleEvent(EVENT_DALLIAH_DEATH, 6s);
- dalliahDeath = true;
+ _dalliahDeath = true;
break;
default:
break;
}
}
+ void DamageTaken(Unit* /*attacker*/, uint32& damage, DamageEffectType /*damageType*/, SpellInfo const* /*spellInfo = nullptr*/) override
+ {
+ if (!_dalliahTaunt && me->HealthBelowPctDamaged(25, damage))
+ {
+ _dalliahTaunt = true;
+
+ if (Creature* dalliah = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_DALLIAH)))
+ dalliah->AI()->Talk(SAY_SOCCOTHRATES_25_PERCENT);
+ }
+ }
+
+ void OnSpellCast(SpellInfo const* spell) override
+ {
+ if (spell->Id == SPELL_KNOCK_AWAY)
+ if (roll_chance_i(50))
+ Talk(SAY_KNOCK_AWAY);
+ }
+
+ void KilledUnit(Unit* /*victim*/) override
+ {
+ Talk(SAY_SLAY);
+ }
+
+ void JustDied(Unit* /*killer*/) override
+ {
+ _JustDied();
+ Talk(SAY_DEATH);
+
+ if (Creature* dalliah = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_DALLIAH)))
+ if (dalliah->IsAlive() && !dalliah->IsInCombat())
+ dalliah->AI()->SetData(1, 1);
+ }
+
void UpdateAI(uint32 diff) override
{
if (!UpdateVictim())
{
- if (preFight)
+ if (_preFight)
{
events.Update(diff);
@@ -199,7 +219,7 @@ struct boss_wrath_scryer_soccothrates : public BossAI
me->SetFacingToObject(dalliah);
dalliah->SetHomePosition(dalliah->GetPositionX(), dalliah->GetPositionY(), dalliah->GetPositionZ(), 1.51737f);
me->SetHomePosition(me->GetPositionX(), me->GetPositionY(), me->GetPositionZ(), 4.725722f);
- preFight = false;
+ _preFight = false;
}
break;
default:
@@ -208,7 +228,7 @@ struct boss_wrath_scryer_soccothrates : public BossAI
}
}
- if (dalliahDeath)
+ if (_dalliahDeath)
{
events.Update(diff);
@@ -238,14 +258,14 @@ struct boss_wrath_scryer_soccothrates : public BossAI
switch (eventId)
{
case EVENT_FELFIRE_SHOCK:
- DoCastVictim(SPELL_FELFIRE_SHOCK, true);
- events.ScheduleEvent(EVENT_FELFIRE_SHOCK, 12s, 14s);
+ DoCastVictim(SPELL_FELFIRE_SHOCK);
+ events.Repeat(10s, 15s);
break;
case EVENT_KNOCK_AWAY:
- DoCast(me, SPELL_KNOCK_AWAY);
- Talk(SAY_KNOCK_AWAY);
- events.ScheduleEvent(EVENT_KNOCK_AWAY, 11s, 12s);
+ DoCastSelf(SPELL_KNOCK_AWAY);
+ events.Repeat(25s, 30s);
break;
+
case EVENT_ME_FIRST:
if (Creature* dalliah = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_DALLIAH)))
if (dalliah->IsAlive() && !dalliah->IsInCombat())
@@ -259,20 +279,13 @@ struct boss_wrath_scryer_soccothrates : public BossAI
return;
}
- if (HealthBelowPct(25) && !dalliahTaunt)
- {
- if (Creature* dalliah = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_DALLIAH)))
- dalliah->AI()->Talk(SAY_SOCCOTHRATES_25_PERCENT);
- dalliahTaunt = true;
- }
-
DoMeleeAttackIfReady();
}
private:
- bool preFight;
- bool dalliahTaunt;
- bool dalliahDeath;
+ bool _preFight;
+ bool _dalliahTaunt;
+ bool _dalliahDeath;
};
void AddSC_boss_wrath_scryer_soccothrates()