Merge branch 'master' into Playerbot

This commit is contained in:
Yunfan Li
2024-06-19 14:32:16 +08:00
84 changed files with 3708 additions and 2951 deletions

View File

@@ -63,7 +63,7 @@ struct npc_eye_of_acherus : public ScriptedAI
{
npc_eye_of_acherus(Creature* creature) : ScriptedAI(creature)
{
creature->SetDisplayId(creature->GetCreatureTemplate()->Modelid1);
creature->SetDisplayFromModel(0);
creature->SetReactState(REACT_PASSIVE);
}
@@ -968,7 +968,7 @@ public:
{
me->SetImmuneToAll(true);
me->SetFaction(FACTION_FRIENDLY);
me->SetDisplayId(me->GetCreatureTemplate()->Modelid1); // Modelid2 is a horse.
me->SetDisplayFromModel(0); // Modelid2 is a horse.
}
ObjectGuid minerGUID;

View File

@@ -94,7 +94,7 @@ struct boss_jindo : public BossAI
void EnterEvadeMode(EvadeReason evadeReason) override
{
if (_EnterEvadeMode(evadeReason))
if (CreatureAI::_EnterEvadeMode(evadeReason))
{
Reset();
me->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_STATE_DANCE);

View File

@@ -141,24 +141,17 @@ private:
struct npc_doomfire_spirit : public ScriptedAI
{
npc_doomfire_spirit(Creature* creature) : ScriptedAI(creature)
{
_instance = creature->GetInstanceScript();
}
npc_doomfire_spirit(Creature* creature) : ScriptedAI(creature){ }
void Reset() override
{
Position randomPosition;
scheduler.CancelAll();
ScheduleTimedEvent(0s, [&] {
DoomfireMovement(randomPosition, me->GetPosition());
me->GetMotionMaster()->MovePoint(NEAR_POINT, randomPosition);
me->GetMotionMaster()->MovePoint(NEAR_POINT, DoomfireMovement(me->GetPosition()));
}, 1500ms);
}
void DoomfireMovement(Position& targetPos, Position mePos)
Position DoomfireMovement(Position mePos)
{
float angle = mePos.GetOrientation();
float distance = 100.0f;
@@ -166,8 +159,8 @@ struct npc_doomfire_spirit : public ScriptedAI
float x = mePos.GetPositionX() + distance * cos(newAngle);
float y = mePos.GetPositionY() + distance * sin(newAngle);
targetPos = Position(x, y, me->GetPositionZ());
return;
Position targetPos = Position(x, y, me->GetPositionZ());
return targetPos;
}
void UpdateAI(uint32 diff) override
@@ -180,8 +173,6 @@ struct npc_doomfire_spirit : public ScriptedAI
if (me->HasUnitState(UNIT_STATE_CASTING))
return;
}
private:
InstanceScript* _instance;
};
struct boss_archimonde : public BossAI
@@ -196,22 +187,13 @@ struct boss_archimonde : public BossAI
void Reset() override
{
BossAI::Reset();
_Reset();
_wispCount = 0;
_isChanneling = false;
_enraged = false;
_availableAuras.clear();
_availableSpells.clear();
if (Map* map = me->GetMap())
{
map->DoForAllPlayers([&](Player* player)
{
player->ApplySpellImmune(SPELL_HAND_OF_DEATH, IMMUNITY_ID, SPELL_HAND_OF_DEATH, false);
player->ApplySpellImmune(0, IMMUNITY_ID, SPELL_HAND_OF_DEATH, false);
});
}
if (instance->GetBossState(DATA_AZGALOR) != DONE)
{
me->SetVisible(false);
@@ -225,7 +207,7 @@ struct boss_archimonde : public BossAI
ScheduleHealthCheckEvent(10, [&]{
scheduler.CancelAll();
me->SetReactState(REACT_PASSIVE);
DoCastProtection();
DoCastAOE(SPELL_PROTECTION_OF_ELUNE, true);
Talk(SAY_ENRAGE);
_enraged = true;
me->GetMotionMaster()->Clear(false);
@@ -234,7 +216,7 @@ struct boss_archimonde : public BossAI
{
if (_wispCount >= 30)
{
Unit::DealDamage(me, me, me->GetHealth(), nullptr, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, nullptr, false);
me->KillSelf();
}
Position wispPosition = { me->GetPositionX() + float(rand() % WISP_OFFSET), me->GetPositionY() + float(rand() % WISP_OFFSET), me->GetPositionZ(), 0.0f };
if (Creature* wisp = me->SummonCreature(CREATURE_ANCIENT_WISP, wispPosition))
@@ -262,8 +244,6 @@ struct boss_archimonde : public BossAI
{
if (Creature* nordrassil = me->SummonCreature(CREATURE_CHANNEL_TARGET, nordrassilPosition, TEMPSUMMON_TIMED_DESPAWN, 1200000))
{
nordrassil->SetUnitFlag(UNIT_FLAG_NOT_SELECTABLE);
nordrassil->SetDisplayId(DISPLAY_ID_TRIGGER);
DoCast(nordrassil, SPELL_DRAIN_WORLD_TREE);
_isChanneling = true;
nordrassil->AI()->DoCast(me, SPELL_DRAIN_WORLD_TREE_2, true);
@@ -273,29 +253,16 @@ struct boss_archimonde : public BossAI
}
}
void DoCastProtection()
void JustEngagedWith(Unit* /*who*/) override
{
if (Map* map = me->GetMap())
{
map->DoForAllPlayers([&](Player* player)
{
player->AddAura(SPELL_PROTECTION_OF_ELUNE, player);
player->ApplySpellImmune(SPELL_HAND_OF_DEATH, IMMUNITY_ID, SPELL_HAND_OF_DEATH, true);
player->ApplySpellImmune(0, IMMUNITY_ID, SPELL_HAND_OF_DEATH, true);
});
}
}
void JustEngagedWith(Unit* who) override
{
BossAI::JustEngagedWith(who);
_JustEngagedWith();
me->InterruptNonMeleeSpells(false);
Talk(SAY_AGGRO);
ScheduleTimedEvent(25s, 35s, [&]
{
scheduler.DelayGroup(GROUP_FEAR, 5s);
Talk(SAY_AIR_BURST);
DoCastAOE(SPELL_AIR_BURST);
DoCastRandomTarget(SPELL_AIR_BURST);
}, 25s, 40s);
ScheduleTimedEvent(25s, 35s, [&]
{
@@ -354,49 +321,46 @@ struct boss_archimonde : public BossAI
instance->SetData(DATA_SPAWN_WAVES, 1);
}
void KilledUnit(Unit* victim) override
void KilledUnit(Unit* /*victim*/) override
{
Talk(SAY_SLAY);
if (victim->IsPlayer())
{
GainSoulCharge(victim->ToPlayer());
}
}
void GainSoulCharge(Player* player)
void SetGUID(ObjectGuid guid, int32 type) override
{
switch (player->getClass())
if (type == GUID_GAIN_SOUL_CHARGE_PLAYER)
{
case CLASS_PALADIN:
case CLASS_PRIEST:
case CLASS_WARLOCK:
player->CastSpell(me, SPELL_SOUL_CHARGE_RED, true);
break;
case CLASS_DEATH_KNIGHT:
case CLASS_MAGE:
case CLASS_ROGUE:
case CLASS_WARRIOR:
player->CastSpell(me, SPELL_SOUL_CHARGE_YELLOW, true);
break;
case CLASS_DRUID:
case CLASS_HUNTER:
case CLASS_SHAMAN:
player->CastSpell(me, SPELL_SOUL_CHARGE_GREEN, true);
break;
case CLASS_NONE:
default:
break;
}
scheduler.Schedule(2s, 10s, [this](TaskContext)
{
UnleashSoulCharge();
});
}
if (Player* player = ObjectAccessor::GetPlayer(*me, guid))
{
switch (player->getClass())
{
case CLASS_PALADIN:
case CLASS_PRIEST:
case CLASS_WARLOCK:
player->CastSpell(me, SPELL_SOUL_CHARGE_RED, true);
break;
case CLASS_DEATH_KNIGHT:
case CLASS_MAGE:
case CLASS_ROGUE:
case CLASS_WARRIOR:
player->CastSpell(me, SPELL_SOUL_CHARGE_YELLOW, true);
break;
case CLASS_DRUID:
case CLASS_HUNTER:
case CLASS_SHAMAN:
player->CastSpell(me, SPELL_SOUL_CHARGE_GREEN, true);
break;
case CLASS_NONE:
default:
break;
}
void JustDied(Unit* killer) override
{
BossAI::JustDied(killer);
scheduler.Schedule(2s, 10s, [this](TaskContext)
{
UnleashSoulCharge();
});
}
}
}
void EnterEvadeMode(EvadeReason why) override
@@ -443,8 +407,6 @@ struct boss_archimonde : public BossAI
{
if (Creature* doomfire = me->SummonCreature(CREATURE_DOOMFIRE, doomfirePosition, TEMPSUMMON_TIMED_DESPAWN, 27000))
{
doomfireSpirit->SetVisible(false);
doomfire->SetVisible(false);
doomfireSpirit->SetWalk(false);
doomfireSpirit->SetReactState(REACT_PASSIVE);
doomfire->SetReactState(REACT_PASSIVE);
@@ -507,42 +469,6 @@ class spell_red_sky_effect : public SpellScript
}
};
class spell_finger_of_death : public SpellScript
{
PrepareSpellScript(spell_finger_of_death);
void HandleHit(SpellEffIndex /*effIndex*/)
{
if (GetHitUnit() && GetHitUnit()->GetAura(SPELL_PROTECTION_OF_ELUNE))
PreventHitDamage();
else
GetHitUnit()->RemoveAurasByType(SPELL_AURA_EFFECT_IMMUNITY);
}
void Register() override
{
OnEffectHitTarget += SpellEffectFn(spell_finger_of_death::HandleHit, EFFECT_0, SPELL_EFFECT_SCHOOL_DAMAGE);
}
};
class spell_hand_of_death : public SpellScript
{
PrepareSpellScript(spell_hand_of_death);
void HandleHit(SpellEffIndex /*effIndex*/)
{
if (GetHitUnit() && GetHitUnit()->GetAura(SPELL_PROTECTION_OF_ELUNE))
PreventHitDamage();
else
GetHitUnit()->RemoveAurasByType(SPELL_AURA_EFFECT_IMMUNITY);
}
void Register() override
{
OnEffectHitTarget += SpellEffectFn(spell_hand_of_death::HandleHit, EFFECT_0, SPELL_EFFECT_SCHOOL_DAMAGE);
}
};
class spell_air_burst : public SpellScript
{
PrepareSpellScript(spell_air_burst);
@@ -564,8 +490,6 @@ class spell_air_burst : public SpellScript
void AddSC_boss_archimonde()
{
RegisterSpellScript(spell_red_sky_effect);
RegisterSpellScript(spell_hand_of_death);
RegisterSpellScript(spell_finger_of_death);
RegisterSpellScript(spell_air_burst);
RegisterHyjalAI(boss_archimonde);
RegisterHyjalAI(npc_ancient_wisp);

View File

@@ -27,18 +27,13 @@
uint32 const EncounterCount = 5;
enum HyjalBosses
{
BOSS_ARCHIMONDE = 0,
};
enum DataTypes
{
DATA_WINTERCHILL = 1,
DATA_ANETHERON = 2,
DATA_KAZROGAL = 3,
DATA_AZGALOR = 4,
DATA_ARCHIMONDE = 5,
DATA_WINTERCHILL = 0,
DATA_ANETHERON = 1,
DATA_KAZROGAL = 2,
DATA_AZGALOR = 3,
DATA_ARCHIMONDE = 4,
DATA_ALLIANCE_RETREAT = 11,
DATA_HORDE_RETREAT = 12,
@@ -90,6 +85,7 @@ enum HyjalCreaturesIds
NPC_ALLIANCE_RIFLEMAN = 17921,
NPC_ALLIANCE_PRIEST = 17928,
NPC_ALLIANCE_SORCERESS = 17922,
NPC_GUARDIAN_ELEMENTAL = 18001,
// Horde Base
NPC_THRALL = 17852,
@@ -102,6 +98,7 @@ enum HyjalCreaturesIds
NPC_HORDE_PEON = 17937,
NPC_INFERNAL_RELAY = 18242,
NPC_INFERNAL_TARGET = 21075,
NPC_DIRE_WOLF = 17854,
// Night Elf Base
NPC_TYRANDE = 17948,
@@ -152,7 +149,9 @@ enum HyjalMisc
AREA_NORDRASSIL = 3710,
SPELL_ETERNAL_SILENCE = 42201
SPELL_ETERNAL_SILENCE = 42201,
GUID_GAIN_SOUL_CHARGE_PLAYER = 1
};
enum HyjalPaths

View File

@@ -51,11 +51,6 @@ ObjectData const creatureData[] =
{ 0, 0 }
};
ObjectData const objectData[] =
{
{ 0, 0 }
};
Milliseconds hyjalWaveTimers[4][MAX_WAVES_STANDARD]
{
{ 130000ms, 130000ms, 130000ms, 130000ms, 130000ms, 130000ms, 130000ms, 190000ms, 0ms }, // Winterchill
@@ -92,12 +87,12 @@ public:
SetHeaders(DataHeader);
SetBossNumber(EncounterCount);
LoadDoorData(doorData);
LoadObjectData(creatureData, objectData);
LoadObjectData(creatureData, nullptr);
}
void Initialize() override
{
_bossWave = 0;
_bossWave = TO_BE_DECIDED;
_retreat = 0;
trash = 0;
_currentWave = 0;
@@ -190,12 +185,12 @@ public:
case NPC_GARGO:
case NPC_FROST:
case NPC_INFER:
if (_bossWave)
if (_bossWave != TO_BE_DECIDED)
creature->AI()->DoAction(_bossWave);
else if (_retreat)
creature->AI()->DoAction(_retreat);
if (creature->IsSummon() && _bossWave)
if (creature->IsSummon() && _bossWave != TO_BE_DECIDED)
{
DoUpdateWorldState(WORLD_STATE_ENEMYCOUNT, ++trash); // Update the instance wave count on new trash spawn
_encounterNPCs.insert(creature->GetGUID()); // Used for despawning on wipe
@@ -203,6 +198,8 @@ public:
break;
case NPC_TOWERING_INFERNAL:
case NPC_LESSER_DOOMGUARD:
case NPC_DIRE_WOLF:
case NPC_GUARDIAN_ELEMENTAL:
if (creature->IsSummon())
{
_summonedNPCs.insert(creature->GetGUID());
@@ -231,7 +228,7 @@ public:
case NPC_STALK:
if (creature->IsSummon())
{
if (_bossWave)
if (_bossWave != TO_BE_DECIDED)
{
DoUpdateWorldState(WORLD_STATE_ENEMYCOUNT, --trash); // Update the instance wave count on new trash death
_encounterNPCs.erase(creature->GetGUID()); // Used for despawning on wipe
@@ -243,6 +240,8 @@ public:
break;
case NPC_TOWERING_INFERNAL:
case NPC_LESSER_DOOMGUARD:
case NPC_DIRE_WOLF:
case NPC_GUARDIAN_ELEMENTAL:
_summonedNPCs.erase(creature->GetGUID());
break;
case NPC_WINTERCHILL:
@@ -250,13 +249,18 @@ public:
case NPC_KAZROGAL:
case NPC_AZGALOR:
if (Creature* jaina = GetCreature(DATA_JAINA))
jaina->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP);
jaina->SetNpcFlag(UNIT_NPC_FLAG_GOSSIP);
if (Creature* thrall = GetCreature(DATA_THRALL))
thrall->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP);
thrall->SetNpcFlag(UNIT_NPC_FLAG_GOSSIP);
SetData(DATA_RESET_WAVES, 1);
break;
}
}
else if (unit->IsPlayer() && GetBossState(DATA_ARCHIMONDE) == IN_PROGRESS)
{
if (Creature* archimonde = GetCreature(DATA_ARCHIMONDE))
archimonde->AI()->SetGUID(unit->GetGUID(), GUID_GAIN_SOUL_CHARGE_PLAYER);
}
}
void SetData(uint32 type, uint32 data) override
@@ -264,7 +268,7 @@ public:
switch (type)
{
case DATA_ALLIANCE_RETREAT:
_bossWave = 0;
_bossWave = TO_BE_DECIDED;
_retreat = DATA_ALLIANCE_RETREAT;
// Spawn Ancient Gems
for (ObjectGuid const& guid : _ancientGemAlliance)
@@ -290,14 +294,14 @@ public:
}
// Despawn all alliance NPCs
_scheduler.Schedule(21000ms, [this](TaskContext)
scheduler.Schedule(21000ms, [this](TaskContext)
{
for (ObjectGuid const& guid : _baseAlliance)
if (Creature* creature = instance->GetCreature(guid))
creature->DespawnOrUnsummon();
// Spawn Roaring Flame after a delay
_scheduler.Schedule(30s, [this](TaskContext)
scheduler.Schedule(30s, [this](TaskContext)
{
for (ObjectGuid const& guid : _roaringFlameAlliance)
{
@@ -313,7 +317,7 @@ public:
SaveToDB();
break;
case DATA_HORDE_RETREAT:
_bossWave = 0;
_bossWave = TO_BE_DECIDED;
_retreat = DATA_HORDE_RETREAT;
for (ObjectGuid const& guid : _ancientGemHorde)
{
@@ -338,13 +342,13 @@ public:
}
}
_scheduler.Schedule(21000ms, [this](TaskContext)
scheduler.Schedule(21000ms, [this](TaskContext)
{
for (ObjectGuid const& guid : _baseHorde)
if (Creature* creature = instance->GetCreature(guid))
creature->DespawnOrUnsummon();
_scheduler.Schedule(30s, [this](TaskContext)
scheduler.Schedule(30s, [this](TaskContext)
{
for (ObjectGuid const& guid : _roaringFlameHorde)
if (GameObject* flame = instance->GetGameObject(guid))
@@ -360,45 +364,49 @@ public:
_retreat = 0;
if (GetBossState(DATA_WINTERCHILL) != DONE)
{
if (!_bossWave)
if (_bossWave == TO_BE_DECIDED)
for (ObjectGuid const& guid : _baseAlliance)
if (Creature* creature = instance->GetCreature(guid))
creature->Respawn();
_bossWave = DATA_WINTERCHILL;
ScheduleWaves(1ms, START_WAVE_WINTERCHILL, MAX_WAVES_STANDARD, hyjalWaveTimers[DATA_WINTERCHILL - 1]);
ScheduleWaves(1ms, START_WAVE_WINTERCHILL, MAX_WAVES_STANDARD, hyjalWaveTimers[DATA_WINTERCHILL]);
}
else if (GetBossState(DATA_ANETHERON) != DONE)
{
if (!_bossWave)
if (_bossWave == TO_BE_DECIDED)
for (ObjectGuid const& guid : _baseAlliance)
if (Creature* creature = instance->GetCreature(guid))
creature->Respawn();
_bossWave = DATA_ANETHERON;
ScheduleWaves(1ms, START_WAVE_ANETHERON, MAX_WAVES_STANDARD, hyjalWaveTimers[DATA_ANETHERON - 1]);
ScheduleWaves(1ms, START_WAVE_ANETHERON, MAX_WAVES_STANDARD, hyjalWaveTimers[DATA_ANETHERON]);
}
else if (GetBossState(DATA_KAZROGAL) != DONE)
{
if (!_bossWave)
if (_bossWave == TO_BE_DECIDED)
for (ObjectGuid const& guid : _baseHorde)
if (Creature* creature = instance->GetCreature(guid))
creature->Respawn();
_bossWave = DATA_KAZROGAL;
ScheduleWaves(1ms, START_WAVE_KAZROGAL, MAX_WAVES_STANDARD, hyjalWaveTimers[DATA_KAZROGAL - 1]);
ScheduleWaves(1ms, START_WAVE_KAZROGAL, MAX_WAVES_STANDARD, hyjalWaveTimers[DATA_KAZROGAL]);
}
else if (GetBossState(DATA_AZGALOR) != DONE)
{
if (!_bossWave)
if (_bossWave == TO_BE_DECIDED)
for (ObjectGuid const& guid : _baseHorde)
if (Creature* creature = instance->GetCreature(guid))
creature->Respawn();
_bossWave = DATA_AZGALOR;
ScheduleWaves(1ms, START_WAVE_AZGALOR, MAX_WAVES_STANDARD, hyjalWaveTimers[DATA_AZGALOR - 1]);
ScheduleWaves(1ms, START_WAVE_AZGALOR, MAX_WAVES_STANDARD, hyjalWaveTimers[DATA_AZGALOR]);
}
else if (GetBossState(DATA_ARCHIMONDE) != DONE)
{
_bossWave = DATA_ARCHIMONDE;
ScheduleWaves(1ms, START_WAVE_NIGHT_ELF, MAX_WAVES_NIGHT_ELF, hyjalNightElfWaveTimers[0]);
}
if (_bossWave != TO_BE_DECIDED)
DoUpdateWorldState(WORLD_STATE_WAVES, 0);
break;
case DATA_SPAWN_INFERNALS:
{
@@ -419,89 +427,51 @@ public:
}
}
break;
case DATA_RESET_ALLIANCE:
for (ObjectGuid const& guid : _baseAlliance)
if (Creature* creature = instance->GetCreature(guid))
creature->DespawnOrUnsummon();
for (ObjectGuid const& guid : _encounterNPCs)
if (Creature* creature = instance->GetCreature(guid))
creature->DespawnOrUnsummon();
// also force despawn boss summons
for (ObjectGuid const& guid : _summonedNPCs)
if (Creature* creature = instance->GetCreature(guid))
creature->DespawnOrUnsummon();
if (_bossWave && (GetBossState(_bossWave) != DONE))
SetBossState(_bossWave, NOT_STARTED);
_scheduler.Schedule(300s, [this](TaskContext)
{
for (ObjectGuid const& guid : _baseAlliance)
if (Creature* creature = instance->GetCreature(guid))
creature->Respawn();
});
SetData(DATA_RESET_WAVES, 0);
break;
case DATA_RESET_HORDE:
for (ObjectGuid const& guid : _baseHorde)
if (Creature* creature = instance->GetCreature(guid))
creature->DespawnOrUnsummon();
for (ObjectGuid const& guid : _encounterNPCs)
if (Creature* creature = instance->GetCreature(guid))
creature->DespawnOrUnsummon();
// also force despawn boss summons
for (ObjectGuid const& guid : _summonedNPCs)
if (Creature* creature = instance->GetCreature(guid))
creature->DespawnOrUnsummon();
if (_bossWave && (GetBossState(_bossWave) != DONE))
SetBossState(_bossWave, NOT_STARTED);
_scheduler.Schedule(300s, [this](TaskContext)
{
for (ObjectGuid const& guid : _baseHorde)
if (Creature* creature = instance->GetCreature(guid))
creature->Respawn();
});
SetData(DATA_RESET_WAVES, 0);
break;
case DATA_RESET_NIGHT_ELF:
if (Creature* archimonde = GetCreature(DATA_ARCHIMONDE))
archimonde->DespawnOrUnsummon(0s, 300s);
[[fallthrough]];
case DATA_RESET_ALLIANCE:
case DATA_RESET_HORDE:
if (GetBossState(DATA_ANETHERON) != DONE)
{
for (ObjectGuid const& guid : _baseAlliance)
if (Creature* creature = instance->GetCreature(guid))
creature->DespawnOrUnsummon(0s, 300s);
}
if (GetBossState(DATA_AZGALOR) != DONE)
{
for (ObjectGuid const& guid : _baseHorde)
if (Creature* creature = instance->GetCreature(guid))
creature->DespawnOrUnsummon(0s, 300s);
}
for (ObjectGuid const& guid : _baseNightElf)
if (Creature* creature = instance->GetCreature(guid))
creature->DespawnOrUnsummon();
creature->DespawnOrUnsummon(0s, 300s);
for (ObjectGuid const& guid : _encounterNPCs)
if (Creature* creature = instance->GetCreature(guid))
creature->DespawnOrUnsummon();
if (Creature* archimonde = GetCreature(DATA_ARCHIMONDE))
archimonde->DespawnOrUnsummon();
// also force despawn boss summons
for (ObjectGuid const& guid : _summonedNPCs)
if (Creature* creature = instance->GetCreature(guid))
creature->DespawnOrUnsummon();
_scheduler.Schedule(300s, [this](TaskContext)
{
for (ObjectGuid const& guid : _baseNightElf)
if (Creature* creature = instance->GetCreature(guid))
creature->Respawn();
if (Creature* archi = GetCreature(DATA_ARCHIMONDE))
archi->Respawn();
});
if (_bossWave != TO_BE_DECIDED && (GetBossState(_bossWave) != DONE))
SetBossState(_bossWave, NOT_STARTED);
SetData(DATA_RESET_WAVES, 0);
break;
case DATA_RESET_WAVES:
_scheduler.CancelGroup(CONTEXT_GROUP_WAVES);
scheduler.CancelGroup(CONTEXT_GROUP_WAVES);
_encounterNPCs.clear();
_summonedNPCs.clear();
_currentWave = 0;
trash = 0;
_bossWave = 0;
_bossWave = TO_BE_DECIDED;
_retreat = 0;
DoUpdateWorldState(WORLD_STATE_WAVES, _currentWave);
DoUpdateWorldState(WORLD_STATE_ENEMY, trash);
@@ -533,10 +503,10 @@ public:
void ScheduleWaves(Milliseconds /* time */, uint8 startWaves, uint8 maxWaves, Milliseconds timerptr[])
{
// No overlapping!
_scheduler.CancelGroup(CONTEXT_GROUP_WAVES);
scheduler.CancelGroup(CONTEXT_GROUP_WAVES);
trash = 0; // Reset counter here to avoid resetting the counter from scheduled waves. Required because creatures killed for RP events counts towards the kill counter as well, confirmed in Retail.
_scheduler.Schedule(1ms, [this, startWaves, maxWaves, timerptr](TaskContext context)
scheduler.Schedule(1ms, [this, startWaves, maxWaves, timerptr](TaskContext context)
{
// If all waves reached, cancel scheduling new ones
if (_currentWave >= maxWaves)
@@ -572,7 +542,7 @@ public:
void Update(uint32 diff) override
{
_scheduler.Update(diff);
scheduler.Update(diff);
}
void OnPlayerInWaterStateUpdate(Player* player, bool inWater) override
@@ -588,7 +558,6 @@ public:
uint8 _currentWave;
uint8 _bossWave;
uint8 _retreat;
TaskScheduler _scheduler;
GuidSet _encounterNPCs;
GuidSet _summonedNPCs;
GuidSet _baseAlliance;

View File

@@ -82,6 +82,7 @@ enum Spells
SPELL_SARTHARION_FLAME_BREATH = 56908,
SPELL_SARTHARION_TAIL_LASH = 56910,
SPELL_CYCLONE_AURA_PERIODIC = 57598,
SPELL_LAVA_STRIKE_DUMMY = 57578,
SPELL_LAVA_STRIKE_DUMMY_TRIGGER = 57697,
SPELL_LAVA_STRIKE_SUMMON = 57572,
SPELL_SARTHARION_PYROBUFFET = 56916,
@@ -102,6 +103,7 @@ enum Spells
// Misc
SPELL_FADE_ARMOR = 60708,
SPELL_FLAME_TSUNAMI_DAMAGE_AURA = 57492,
SPELL_FLAME_TSUNAMI_LEAP = 60241,
SPELL_SARTHARION_PYROBUFFET_TRIGGER = 57557,
};
@@ -1512,65 +1514,107 @@ public:
};
};
class spell_sartharion_lava_strike : public SpellScriptLoader
class spell_sartharion_lava_strike : public SpellScript
{
public:
spell_sartharion_lava_strike() : SpellScriptLoader("spell_sartharion_lava_strike") {}
PrepareSpellScript(spell_sartharion_lava_strike);
class spell_sartharion_lava_strike_SpellScript : public SpellScript
bool Validate(SpellInfo const* /*spellInfo*/) override
{
PrepareSpellScript(spell_sartharion_lava_strike_SpellScript);
return ValidateSpellInfo({ SPELL_LAVA_STRIKE_SUMMON, SPELL_LAVA_STRIKE_DUMMY_TRIGGER });
}
bool spawned;
bool Load() override
{
spawned = false;
return true;
}
void HandleDummy(SpellEffIndex /*effIndex*/)
{
if (!GetCaster() || !GetHitUnit())
return;
GetCaster()->CastSpell(GetHitUnit()->GetPositionX(), GetHitUnit()->GetPositionY(), GetHitUnit()->GetPositionZ(), SPELL_LAVA_STRIKE_DUMMY_TRIGGER, true);
}
void HandleSchoolDamage(SpellEffIndex /*effIndex*/)
{
if (!GetCaster() || !GetHitUnit() || spawned)
{
return;
}
if (InstanceScript* pInstance = GetCaster()->GetInstanceScript())
{
if (Creature* sarth = ObjectAccessor::GetCreature(*GetHitUnit(), pInstance->GetGuidData(DATA_SARTHARION)))
{
sarth->AI()->SetData(DATA_VOLCANO_BLOWS, GetHitUnit()->GetGUID().GetCounter());
sarth->CastSpell(GetHitUnit(), SPELL_LAVA_STRIKE_SUMMON, true);
spawned = true;
}
}
}
void Register() override
{
if (m_scriptSpellId == 57578) // Dummy lava strike
{
OnEffectHitTarget += SpellEffectFn(spell_sartharion_lava_strike_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY);
}
else
{
OnEffectHitTarget += SpellEffectFn(spell_sartharion_lava_strike_SpellScript::HandleSchoolDamage, EFFECT_0, SPELL_EFFECT_SCHOOL_DAMAGE);
}
}
};
SpellScript* GetSpellScript() const override
bool Load() override
{
return new spell_sartharion_lava_strike_SpellScript();
_spawned = false;
return true;
}
void HandleDummy(SpellEffIndex /*effIndex*/)
{
if (!GetCaster() || !GetHitUnit())
{
return;
}
GetCaster()->CastSpell(GetHitUnit()->GetPositionX(), GetHitUnit()->GetPositionY(), GetHitUnit()->GetPositionZ(), SPELL_LAVA_STRIKE_DUMMY_TRIGGER, true);
}
void HandleSchoolDamage(SpellEffIndex /*effIndex*/)
{
if (!GetCaster() || !GetHitUnit() || _spawned)
{
return;
}
if (InstanceScript* instance = GetCaster()->GetInstanceScript())
{
if (Creature* sarth = ObjectAccessor::GetCreature(*GetHitUnit(), instance->GetGuidData(DATA_SARTHARION)))
{
sarth->AI()->SetData(DATA_VOLCANO_BLOWS, GetHitUnit()->GetGUID().GetCounter());
sarth->CastSpell(GetHitUnit(), SPELL_LAVA_STRIKE_SUMMON, true);
_spawned = true;
}
}
}
void Register() override
{
if (m_scriptSpellId == SPELL_LAVA_STRIKE_DUMMY)
{
OnEffectHitTarget += SpellEffectFn(spell_sartharion_lava_strike::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY);
}
else
{
OnEffectHitTarget += SpellEffectFn(spell_sartharion_lava_strike::HandleSchoolDamage, EFFECT_0, SPELL_EFFECT_SCHOOL_DAMAGE);
}
}
private:
bool _spawned;
};
// 57491 - Flame Tsunami
class spell_obsidian_sanctum_flame_tsunami : public SpellScript
{
PrepareSpellScript(spell_obsidian_sanctum_flame_tsunami);
bool Validate(SpellInfo const* /*spellInfo*/) override
{
return ValidateSpellInfo({ SPELL_FLAME_TSUNAMI_LEAP });
}
void HandleHit(SpellEffIndex /*effIndex*/)
{
if (Unit* target = GetHitUnit())
{
if (!target->HasAura(SPELL_FLAME_TSUNAMI_LEAP))
{
target->CastSpell(target, SPELL_FLAME_TSUNAMI_LEAP, true);
bool isFacingSouth = std::fabs(GetCaster()->GetOrientation() - M_PI) < M_PI / 4;
target->KnockbackFrom(isFacingSouth ? 3283.44f : 3208.44f , target->GetPositionY(), 12.5f, 9.0f);
}
}
}
void Register() override
{
OnEffectHitTarget += SpellEffectFn(spell_obsidian_sanctum_flame_tsunami::HandleHit, EFFECT_0, SPELL_EFFECT_SCHOOL_DAMAGE);
}
};
// 60241 - Flame Tsunami
class spell_obsidian_sanctum_flame_tsunami_leap : public SpellScript
{
PrepareSpellScript(spell_obsidian_sanctum_flame_tsunami_leap);
void HandleLeapBack(SpellEffIndex effIndex)
{
PreventHitEffect(effIndex);
}
void Register() override
{
OnEffectHitTarget += SpellEffectFn(spell_obsidian_sanctum_flame_tsunami_leap::HandleLeapBack, EFFECT_0, SPELL_EFFECT_LEAP_BACK);
}
};
@@ -1581,7 +1625,7 @@ void AddSC_boss_sartharion()
new boss_sartharion_tenebron();
new boss_sartharion_vesperon();
new npc_twilight_summon();
new spell_sartharion_lava_strike();
RegisterSpellScript(spell_sartharion_lava_strike);
RegisterSpellScript(spell_obsidian_sanctum_flame_tsunami);
RegisterSpellScript(spell_obsidian_sanctum_flame_tsunami_leap);
}

View File

@@ -555,6 +555,11 @@ public:
BossAI::AttackStart(target);
}
void EnterEvadeMode(EvadeReason why = EVADE_REASON_OTHER) override
{
CreatureAI::EnterEvadeMode(why);
}
void MoveInLineOfSight(Unit* /*who*/) override {}
bool CanAIAttack(Unit const* target) const override

View File

@@ -1192,68 +1192,51 @@ public:
}
};
class spell_algalon_phase_punch : public SpellScriptLoader
class spell_algalon_phase_punch_aura : public AuraScript
{
public:
spell_algalon_phase_punch() : SpellScriptLoader("spell_algalon_phase_punch") { }
PrepareAuraScript(spell_algalon_phase_punch_aura);
class spell_algalon_phase_punch_AuraScript : public AuraScript
bool Validate(SpellInfo const* /*spellInfo*/) override
{
PrepareAuraScript(spell_algalon_phase_punch_AuraScript);
return ValidateSpellInfo(PhasePunchAlphaId);
}
void HandlePeriodic(AuraEffect const* /*aurEff*/)
{
PreventDefaultAction();
if (GetStackAmount() != 1)
GetTarget()->RemoveAurasDueToSpell(PhasePunchAlphaId[GetStackAmount() - 2]);
GetTarget()->CastSpell(GetTarget(), PhasePunchAlphaId[GetStackAmount() - 1], TRIGGERED_FULL_MASK);
if (GetStackAmount() == 5)
Remove(AURA_REMOVE_BY_DEFAULT);
}
void OnRemove(AuraEffect const*, AuraEffectHandleModes)
{
if (GetStackAmount() != 5)
GetTarget()->RemoveAurasDueToSpell(PhasePunchAlphaId[GetStackAmount() - 1]);
}
void Register() override
{
OnEffectPeriodic += AuraEffectPeriodicFn(spell_algalon_phase_punch_AuraScript::HandlePeriodic, EFFECT_0, SPELL_AURA_PERIODIC_DUMMY);
OnEffectRemove += AuraEffectRemoveFn(spell_algalon_phase_punch_AuraScript::OnRemove, EFFECT_0, SPELL_AURA_PERIODIC_DUMMY, AURA_EFFECT_HANDLE_REAL);
}
};
AuraScript* GetAuraScript() const override
void HandlePeriodic(AuraEffect const* /*aurEff*/)
{
return new spell_algalon_phase_punch_AuraScript();
PreventDefaultAction();
if (GetStackAmount() != 1)
GetTarget()->RemoveAurasDueToSpell(PhasePunchAlphaId[GetStackAmount() - 2]);
GetTarget()->CastSpell(GetTarget(), PhasePunchAlphaId[GetStackAmount() - 1], TRIGGERED_FULL_MASK);
if (GetStackAmount() == 5)
Remove(AURA_REMOVE_BY_DEFAULT);
}
void OnRemove(AuraEffect const*, AuraEffectHandleModes)
{
if (GetStackAmount() != 5)
GetTarget()->RemoveAurasDueToSpell(PhasePunchAlphaId[GetStackAmount() - 1]);
}
void Register() override
{
OnEffectPeriodic += AuraEffectPeriodicFn(spell_algalon_phase_punch_aura::HandlePeriodic, EFFECT_0, SPELL_AURA_PERIODIC_DUMMY);
OnEffectRemove += AuraEffectRemoveFn(spell_algalon_phase_punch_aura::OnRemove, EFFECT_0, SPELL_AURA_PERIODIC_DUMMY, AURA_EFFECT_HANDLE_REAL);
}
};
class spell_algalon_collapse : public SpellScriptLoader
class spell_algalon_collapse_aura : public AuraScript
{
public:
spell_algalon_collapse() : SpellScriptLoader("spell_algalon_collapse") { }
PrepareAuraScript(spell_algalon_collapse_aura);
class spell_algalon_collapse_AuraScript : public AuraScript
void HandlePeriodic(AuraEffect const* /*aurEff*/)
{
PrepareAuraScript(spell_algalon_collapse_AuraScript);
PreventDefaultAction();
Unit::DealDamage(GetTarget(), GetTarget(), GetTarget()->CountPctFromMaxHealth(1), nullptr, NODAMAGE);
}
void HandlePeriodic(AuraEffect const* /*aurEff*/)
{
PreventDefaultAction();
Unit::DealDamage(GetTarget(), GetTarget(), GetTarget()->CountPctFromMaxHealth(1), nullptr, NODAMAGE);
}
void Register() override
{
OnEffectPeriodic += AuraEffectPeriodicFn(spell_algalon_collapse_AuraScript::HandlePeriodic, EFFECT_0, SPELL_AURA_PERIODIC_DUMMY);
}
};
AuraScript* GetAuraScript() const override
void Register() override
{
return new spell_algalon_collapse_AuraScript();
OnEffectPeriodic += AuraEffectPeriodicFn(spell_algalon_collapse_aura::HandlePeriodic, EFFECT_0, SPELL_AURA_PERIODIC_DUMMY);
}
};
@@ -1266,172 +1249,123 @@ public:
}
};
class spell_algalon_trigger_3_adds : public SpellScriptLoader
class spell_algalon_trigger_3_adds : public SpellScript
{
public:
spell_algalon_trigger_3_adds() : SpellScriptLoader("spell_algalon_trigger_3_adds") { }
PrepareSpellScript(spell_algalon_trigger_3_adds);
class spell_algalon_trigger_3_adds_SpellScript : public SpellScript
void SelectTarget(std::list<WorldObject*>& targets)
{
PrepareSpellScript(spell_algalon_trigger_3_adds_SpellScript);
targets.remove_if(ActiveConstellationFilter());
}
void SelectTarget(std::list<WorldObject*>& targets)
{
targets.remove_if(ActiveConstellationFilter());
}
void HandleDummyEffect(SpellEffIndex effIndex)
{
PreventHitDefaultEffect(effIndex);
Creature* target = GetHitCreature();
if (!target)
return;
target->AI()->DoAction(ACTION_ACTIVATE_STAR);
}
void Register() override
{
OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_algalon_trigger_3_adds_SpellScript::SelectTarget, EFFECT_0, TARGET_UNIT_SRC_AREA_ENTRY);
OnEffectHitTarget += SpellEffectFn(spell_algalon_trigger_3_adds_SpellScript::HandleDummyEffect, EFFECT_0, SPELL_EFFECT_DUMMY);
}
};
SpellScript* GetSpellScript() const override
void HandleDummyEffect(SpellEffIndex effIndex)
{
return new spell_algalon_trigger_3_adds_SpellScript();
PreventHitDefaultEffect(effIndex);
Creature* target = GetHitCreature();
if (!target)
return;
target->AI()->DoAction(ACTION_ACTIVATE_STAR);
}
void Register() override
{
OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_algalon_trigger_3_adds::SelectTarget, EFFECT_0, TARGET_UNIT_SRC_AREA_ENTRY);
OnEffectHitTarget += SpellEffectFn(spell_algalon_trigger_3_adds::HandleDummyEffect, EFFECT_0, SPELL_EFFECT_DUMMY);
}
};
class spell_algalon_cosmic_smash_damage : public SpellScriptLoader
class spell_algalon_cosmic_smash_damage : public SpellScript
{
public:
spell_algalon_cosmic_smash_damage() : SpellScriptLoader("spell_algalon_cosmic_smash_damage") { }
PrepareSpellScript(spell_algalon_cosmic_smash_damage);
class spell_algalon_cosmic_smash_damage_SpellScript : public SpellScript
void RecalculateDamage()
{
PrepareSpellScript(spell_algalon_cosmic_smash_damage_SpellScript);
if (!GetExplTargetDest() || !GetHitUnit())
return;
void RecalculateDamage()
{
if (!GetExplTargetDest() || !GetHitUnit())
return;
float distance = GetHitUnit()->GetDistance2d(GetExplTargetDest()->GetPositionX(), GetExplTargetDest()->GetPositionY());
if (distance >= 10.0f)
SetHitDamage(int32(float(GetHitDamage()) / distance));
else if (distance > 6.0f)
SetHitDamage(int32(float(GetHitDamage()) / distance) * 2);
}
float distance = GetHitUnit()->GetDistance2d(GetExplTargetDest()->GetPositionX(), GetExplTargetDest()->GetPositionY());
if (distance >= 10.0f)
SetHitDamage(int32(float(GetHitDamage()) / distance));
else if (distance > 6.0f)
SetHitDamage(int32(float(GetHitDamage()) / distance) * 2);
}
void Register() override
{
OnHit += SpellHitFn(spell_algalon_cosmic_smash_damage_SpellScript::RecalculateDamage);
}
};
SpellScript* GetSpellScript() const override
void Register() override
{
return new spell_algalon_cosmic_smash_damage_SpellScript();
OnHit += SpellHitFn(spell_algalon_cosmic_smash_damage::RecalculateDamage);
}
};
class spell_algalon_big_bang : public SpellScriptLoader
class spell_algalon_big_bang : public SpellScript
{
public:
spell_algalon_big_bang() : SpellScriptLoader("spell_algalon_big_bang") { }
PrepareSpellScript(spell_algalon_big_bang);
class spell_algalon_big_bang_SpellScript : public SpellScript
bool Load() override
{
PrepareSpellScript(spell_algalon_big_bang_SpellScript);
_targetCount = 0;
return true;
}
bool Load() override
{
_targetCount = 0;
return true;
}
void CountTargets(std::list<WorldObject*>& targets)
{
_targetCount = targets.size();
}
void CheckTargets()
{
Unit* caster = GetCaster();
if (!_targetCount && caster && caster->GetAI())
caster->GetAI()->DoAction(ACTION_ASCEND);
}
void Register() override
{
OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_algalon_big_bang_SpellScript::CountTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY);
AfterCast += SpellCastFn(spell_algalon_big_bang_SpellScript::CheckTargets);
}
uint32 _targetCount;
};
SpellScript* GetSpellScript() const override
void CountTargets(std::list<WorldObject*>& targets)
{
return new spell_algalon_big_bang_SpellScript();
_targetCount = targets.size();
}
void CheckTargets()
{
Unit* caster = GetCaster();
if (!_targetCount && caster && caster->GetAI())
caster->GetAI()->DoAction(ACTION_ASCEND);
}
void Register() override
{
OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_algalon_big_bang::CountTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY);
AfterCast += SpellCastFn(spell_algalon_big_bang::CheckTargets);
}
private:
uint32 _targetCount;
};
class spell_algalon_remove_phase_aura : public AuraScript
{
PrepareAuraScript(spell_algalon_remove_phase_aura);
bool Validate(SpellInfo const* /*spellInfo*/) override
{
return ValidateSpellInfo({ SPELL_BLACK_HOLE_DAMAGE });
}
void HandlePeriodic(AuraEffect const* /*aurEff*/)
{
PreventDefaultAction();
GetTarget()->RemoveAurasByType(SPELL_AURA_PHASE);
GetTarget()->RemoveAurasDueToSpell(SPELL_BLACK_HOLE_DAMAGE);
}
void Register() override
{
OnEffectPeriodic += AuraEffectPeriodicFn(spell_algalon_remove_phase_aura::HandlePeriodic, EFFECT_0, SPELL_AURA_PERIODIC_TRIGGER_SPELL);
}
};
class spell_algalon_remove_phase : public SpellScriptLoader
class spell_algalon_supermassive_fail : public SpellScript
{
public:
spell_algalon_remove_phase() : SpellScriptLoader("spell_algalon_remove_phase") { }
PrepareSpellScript(spell_algalon_supermassive_fail);
class spell_algalon_remove_phase_AuraScript : public AuraScript
void RecalculateDamage()
{
PrepareAuraScript(spell_algalon_remove_phase_AuraScript);
if (!GetHitPlayer())
return;
void HandlePeriodic(AuraEffect const* /*aurEff*/)
{
PreventDefaultAction();
GetTarget()->RemoveAurasByType(SPELL_AURA_PHASE);
GetTarget()->RemoveAurasDueToSpell(SPELL_BLACK_HOLE_DAMAGE);
}
void Register() override
{
OnEffectPeriodic += AuraEffectPeriodicFn(spell_algalon_remove_phase_AuraScript::HandlePeriodic, EFFECT_0, SPELL_AURA_PERIODIC_TRIGGER_SPELL);
}
};
AuraScript* GetAuraScript() const override
{
return new spell_algalon_remove_phase_AuraScript();
GetHitPlayer()->ResetAchievementCriteria(ACHIEVEMENT_CRITERIA_CONDITION_NO_SPELL_HIT, GetSpellInfo()->Id, true);
}
};
class spell_algalon_supermassive_fail : public SpellScriptLoader
{
public:
spell_algalon_supermassive_fail() : SpellScriptLoader("spell_algalon_supermassive_fail") { }
class spell_algalon_supermassive_fail_SpellScript : public SpellScript
void Register() override
{
PrepareSpellScript(spell_algalon_supermassive_fail_SpellScript);
void RecalculateDamage()
{
if (!GetHitPlayer())
return;
GetHitPlayer()->ResetAchievementCriteria(ACHIEVEMENT_CRITERIA_CONDITION_NO_SPELL_HIT, GetSpellInfo()->Id, true);
}
void Register() override
{
OnHit += SpellHitFn(spell_algalon_supermassive_fail_SpellScript::RecalculateDamage);
}
};
SpellScript* GetSpellScript() const override
{
return new spell_algalon_supermassive_fail_SpellScript();
OnHit += SpellHitFn(spell_algalon_supermassive_fail::RecalculateDamage);
}
};
@@ -1470,13 +1404,13 @@ void AddSC_boss_algalon_the_observer()
new go_celestial_planetarium_access();
// Spells
new spell_algalon_phase_punch();
new spell_algalon_collapse();
new spell_algalon_trigger_3_adds();
new spell_algalon_cosmic_smash_damage();
new spell_algalon_big_bang();
new spell_algalon_remove_phase();
new spell_algalon_supermassive_fail();
RegisterSpellScript(spell_algalon_phase_punch_aura);
RegisterSpellScript(spell_algalon_collapse_aura);
RegisterSpellScript(spell_algalon_trigger_3_adds);
RegisterSpellScript(spell_algalon_cosmic_smash_damage);
RegisterSpellScript(spell_algalon_big_bang);
RegisterSpellScript(spell_algalon_remove_phase_aura);
RegisterSpellScript(spell_algalon_supermassive_fail);
// Achievements
new achievement_algalon_he_feeds_on_your_tears();

View File

@@ -844,94 +844,71 @@ public:
};
};
class spell_shield_of_runes : public SpellScriptLoader
class spell_shield_of_runes_aura : public AuraScript
{
public:
spell_shield_of_runes() : SpellScriptLoader("spell_shield_of_runes") { }
PrepareAuraScript(spell_shield_of_runes_aura);
class spell_shield_of_runes_AuraScript : public AuraScript
bool Validate(SpellInfo const* /*spellInfo*/) override
{
PrepareAuraScript(spell_shield_of_runes_AuraScript);
return ValidateSpellInfo({ SPELL_SHIELD_OF_RUNES_BUFF });
}
void OnRemove(AuraEffect const* aurEff, AuraEffectHandleModes /*mode*/)
{
if (Unit* owner = GetUnitOwner())
if (GetTargetApplication()->GetRemoveMode() == AURA_REMOVE_BY_ENEMY_SPELL && aurEff->GetAmount() <= 0)
owner->CastSpell(owner, SPELL_SHIELD_OF_RUNES_BUFF, false);
}
void Register() override
{
AfterEffectRemove += AuraEffectRemoveFn(spell_shield_of_runes_AuraScript::OnRemove, EFFECT_0, SPELL_AURA_SCHOOL_ABSORB, AURA_EFFECT_HANDLE_REAL);
}
};
AuraScript* GetAuraScript() const override
void OnRemove(AuraEffect const* aurEff, AuraEffectHandleModes /*mode*/)
{
return new spell_shield_of_runes_AuraScript();
if (Unit* owner = GetUnitOwner())
if (GetTargetApplication()->GetRemoveMode() == AURA_REMOVE_BY_ENEMY_SPELL && aurEff->GetAmount() <= 0)
owner->CastSpell(owner, SPELL_SHIELD_OF_RUNES_BUFF, false);
}
void Register() override
{
AfterEffectRemove += AuraEffectRemoveFn(spell_shield_of_runes_aura::OnRemove, EFFECT_0, SPELL_AURA_SCHOOL_ABSORB, AURA_EFFECT_HANDLE_REAL);
}
};
class spell_assembly_meltdown : public SpellScriptLoader
class spell_assembly_meltdown : public SpellScript
{
public:
spell_assembly_meltdown() : SpellScriptLoader("spell_assembly_meltdown") { }
PrepareSpellScript(spell_assembly_meltdown);
class spell_assembly_meltdown_SpellScript : public SpellScript
void HandleInstaKill(SpellEffIndex /*effIndex*/)
{
PrepareSpellScript(spell_assembly_meltdown_SpellScript);
if (InstanceScript* instance = GetCaster()->GetInstanceScript())
if (Creature* Steelbreaker = ObjectAccessor::GetCreature(*GetCaster(), instance->GetGuidData(DATA_STEELBREAKER)))
Steelbreaker->AI()->DoAction(ACTION_ADD_CHARGE);
}
void HandleInstaKill(SpellEffIndex /*effIndex*/)
{
if (InstanceScript* instance = GetCaster()->GetInstanceScript())
if (Creature* Steelbreaker = ObjectAccessor::GetCreature(*GetCaster(), instance->GetGuidData(DATA_STEELBREAKER)))
Steelbreaker->AI()->DoAction(ACTION_ADD_CHARGE);
}
void Register() override
{
OnEffectHitTarget += SpellEffectFn(spell_assembly_meltdown_SpellScript::HandleInstaKill, EFFECT_1, SPELL_EFFECT_INSTAKILL);
}
};
SpellScript* GetSpellScript() const override
void Register() override
{
return new spell_assembly_meltdown_SpellScript();
OnEffectHitTarget += SpellEffectFn(spell_assembly_meltdown::HandleInstaKill, EFFECT_1, SPELL_EFFECT_INSTAKILL);
}
};
class spell_assembly_rune_of_summoning : public SpellScriptLoader
class spell_assembly_rune_of_summoning_aura : public AuraScript
{
public:
spell_assembly_rune_of_summoning() : SpellScriptLoader("spell_assembly_rune_of_summoning") { }
PrepareAuraScript(spell_assembly_rune_of_summoning_aura);
class spell_assembly_rune_of_summoning_AuraScript : public AuraScript
bool Validate(SpellInfo const* /*spellInfo*/) override
{
PrepareAuraScript(spell_assembly_rune_of_summoning_AuraScript);
return ValidateSpellInfo({ SPELL_RUNE_OF_SUMMONING_SUMMON });
}
void OnPeriodic(AuraEffect const* aurEff)
{
PreventDefaultAction();
if (aurEff->GetTickNumber() % 2 == 0)
GetTarget()->CastSpell(GetTarget(), SPELL_RUNE_OF_SUMMONING_SUMMON, true, nullptr, aurEff, GetTarget()->IsSummon() ? GetTarget()->ToTempSummon()->GetSummonerGUID() : ObjectGuid::Empty);
}
void OnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
{
if (TempSummon* summ = GetTarget()->ToTempSummon())
summ->DespawnOrUnsummon(1);
}
void Register() override
{
OnEffectPeriodic += AuraEffectPeriodicFn(spell_assembly_rune_of_summoning_AuraScript::OnPeriodic, EFFECT_0, SPELL_AURA_PERIODIC_DUMMY);
OnEffectRemove += AuraEffectRemoveFn(spell_assembly_rune_of_summoning_AuraScript::OnRemove, EFFECT_0, SPELL_AURA_PERIODIC_DUMMY, AURA_EFFECT_HANDLE_REAL);
}
};
AuraScript* GetAuraScript() const override
void OnPeriodic(AuraEffect const* aurEff)
{
return new spell_assembly_rune_of_summoning_AuraScript();
PreventDefaultAction();
if (aurEff->GetTickNumber() % 2 == 0)
GetTarget()->CastSpell(GetTarget(), SPELL_RUNE_OF_SUMMONING_SUMMON, true, nullptr, aurEff, GetTarget()->IsSummon() ? GetTarget()->ToTempSummon()->GetSummonerGUID() : ObjectGuid::Empty);
}
void OnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
{
if (TempSummon* summ = GetTarget()->ToTempSummon())
summ->DespawnOrUnsummon(1);
}
void Register() override
{
OnEffectPeriodic += AuraEffectPeriodicFn(spell_assembly_rune_of_summoning_aura::OnPeriodic, EFFECT_0, SPELL_AURA_PERIODIC_DUMMY);
OnEffectRemove += AuraEffectRemoveFn(spell_assembly_rune_of_summoning_aura::OnRemove, EFFECT_0, SPELL_AURA_PERIODIC_DUMMY, AURA_EFFECT_HANDLE_REAL);
}
};
@@ -978,9 +955,9 @@ void AddSC_boss_assembly_of_iron()
new boss_stormcaller_brundir();
new npc_assembly_lightning();
new spell_shield_of_runes();
new spell_assembly_meltdown();
new spell_assembly_rune_of_summoning();
RegisterSpellScript(spell_shield_of_runes_aura);
RegisterSpellScript(spell_assembly_meltdown);
RegisterSpellScript(spell_assembly_rune_of_summoning_aura);
new achievement_assembly_of_iron("achievement_but_im_on_your_side", 0);
new achievement_assembly_of_iron("achievement_assembly_steelbreaker", NPC_STEELBREAKER);

View File

@@ -432,29 +432,18 @@ public:
};
};
class spell_auriaya_sentinel_blast : public SpellScriptLoader
class spell_auriaya_sentinel_blast : public SpellScript
{
public:
spell_auriaya_sentinel_blast() : SpellScriptLoader("spell_auriaya_sentinel_blast") { }
PrepareSpellScript(spell_auriaya_sentinel_blast);
class spell_auriaya_sentinel_blast_SpellScript : public SpellScript
void FilterTargets(std::list<WorldObject*>& unitList)
{
PrepareSpellScript(spell_auriaya_sentinel_blast_SpellScript);
unitList.remove_if(PlayerOrPetCheck());
}
void FilterTargets(std::list<WorldObject*>& unitList)
{
unitList.remove_if(PlayerOrPetCheck());
}
void Register() override
{
OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_auriaya_sentinel_blast_SpellScript::FilterTargets, EFFECT_ALL, TARGET_UNIT_SRC_AREA_ENEMY);
}
};
SpellScript* GetSpellScript() const override
void Register() override
{
return new spell_auriaya_sentinel_blast_SpellScript();
OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_auriaya_sentinel_blast::FilterTargets, EFFECT_ALL, TARGET_UNIT_SRC_AREA_ENEMY);
}
};
@@ -496,7 +485,7 @@ void AddSC_boss_auriaya()
new npc_auriaya_sanctum_sentry();
new npc_auriaya_feral_defender();
new spell_auriaya_sentinel_blast();
RegisterSpellScript(spell_auriaya_sentinel_blast);
new achievement_auriaya_crazy_cat_lady();
new achievement_auriaya_nine_lives();

View File

@@ -1437,151 +1437,133 @@ public:
}
};
class spell_load_into_catapult : public SpellScriptLoader
enum LoadIntoCataPult
{
enum Spells
SPELL_PASSENGER_LOADED = 62340
};
class spell_load_into_catapult_aura : public AuraScript
{
PrepareAuraScript(spell_load_into_catapult_aura);
bool Validate(SpellInfo const* /*spellInfo*/) override
{
SPELL_PASSENGER_LOADED = 62340,
};
return ValidateSpellInfo({ SPELL_PASSENGER_LOADED });
}
public:
spell_load_into_catapult() : SpellScriptLoader("spell_load_into_catapult") { }
class spell_load_into_catapult_AuraScript : public AuraScript
void OnApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
{
PrepareAuraScript(spell_load_into_catapult_AuraScript);
Unit* owner = GetOwner()->ToUnit();
if (!owner)
return;
void OnApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
{
Unit* owner = GetOwner()->ToUnit();
if (!owner)
return;
owner->CastSpell(owner, SPELL_PASSENGER_LOADED, true);
}
owner->CastSpell(owner, SPELL_PASSENGER_LOADED, true);
}
void OnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
{
Unit* owner = GetOwner()->ToUnit();
if (!owner)
return;
owner->RemoveAurasDueToSpell(SPELL_PASSENGER_LOADED);
}
void Register() override
{
OnEffectApply += AuraEffectApplyFn(spell_load_into_catapult_AuraScript::OnApply, EFFECT_0, SPELL_AURA_CONTROL_VEHICLE, AURA_EFFECT_HANDLE_REAL);
OnEffectRemove += AuraEffectRemoveFn(spell_load_into_catapult_AuraScript::OnRemove, EFFECT_0, SPELL_AURA_CONTROL_VEHICLE, AURA_EFFECT_HANDLE_REAL_OR_REAPPLY_MASK);
}
};
AuraScript* GetAuraScript() const override
void OnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
{
return new spell_load_into_catapult_AuraScript();
Unit* owner = GetOwner()->ToUnit();
if (!owner)
return;
owner->RemoveAurasDueToSpell(SPELL_PASSENGER_LOADED);
}
void Register() override
{
OnEffectApply += AuraEffectApplyFn(spell_load_into_catapult_aura::OnApply, EFFECT_0, SPELL_AURA_CONTROL_VEHICLE, AURA_EFFECT_HANDLE_REAL);
OnEffectRemove += AuraEffectRemoveFn(spell_load_into_catapult_aura::OnRemove, EFFECT_0, SPELL_AURA_CONTROL_VEHICLE, AURA_EFFECT_HANDLE_REAL_OR_REAPPLY_MASK);
}
};
class spell_auto_repair : public SpellScriptLoader
enum AutoRepair
{
enum Spells
SPELL_AUTO_REPAIR = 62705,
};
class spell_auto_repair : public SpellScript
{
PrepareSpellScript(spell_auto_repair);
bool Validate(SpellInfo const* /*spellInfo*/) override
{
SPELL_AUTO_REPAIR = 62705,
};
return ValidateSpellInfo({ SPELL_AUTO_REPAIR });
}
public:
spell_auto_repair() : SpellScriptLoader("spell_auto_repair") {}
class spell_auto_repair_SpellScript : public SpellScript
void FilterTargets(std::list<WorldObject*>& targets)
{
PrepareSpellScript(spell_auto_repair_SpellScript);
std::list<WorldObject*> tmplist;
for (std::list<WorldObject*>::iterator itr = targets.begin(); itr != targets.end(); ++itr)
if (!(*itr)->ToUnit()->HasAura(SPELL_AUTO_REPAIR))
tmplist.push_back(*itr);
void FilterTargets(std::list<WorldObject*>& targets)
{
std::list<WorldObject*> tmplist;
for (std::list<WorldObject*>::iterator itr = targets.begin(); itr != targets.end(); ++itr)
if (!(*itr)->ToUnit()->HasAura(SPELL_AUTO_REPAIR))
tmplist.push_back(*itr);
targets.clear();
for (std::list<WorldObject*>::iterator itr = tmplist.begin(); itr != tmplist.end(); ++itr)
targets.push_back(*itr);
}
targets.clear();
for (std::list<WorldObject*>::iterator itr = tmplist.begin(); itr != tmplist.end(); ++itr)
targets.push_back(*itr);
}
void HandleScript(SpellEffIndex /*eff*/)
{
Vehicle* vehicle = GetHitUnit()->GetVehicleKit();
if (!vehicle)
return;
Unit* driver = vehicle->GetPassenger(0);
if (!driver)
return;
//driver->TextEmote(VEHICLE_EMOTE_REPAIR, driver, true); // No source
// Actually should/could use basepoints (100) for this spell effect as percentage of health, but oh well.
vehicle->GetBase()->SetFullHealth();
// Achievement
if (InstanceScript* instance = vehicle->GetBase()->GetInstanceScript())
instance->SetData(DATA_UNBROKEN_ACHIEVEMENT, 0);
}
void Register() override
{
OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_auto_repair_SpellScript::FilterTargets, EFFECT_ALL, TARGET_UNIT_DEST_AREA_ENTRY);
OnEffectHitTarget += SpellEffectFn(spell_auto_repair_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT);
}
};
SpellScript* GetSpellScript() const override
void HandleScript(SpellEffIndex /*eff*/)
{
return new spell_auto_repair_SpellScript();
Vehicle* vehicle = GetHitUnit()->GetVehicleKit();
if (!vehicle)
return;
Unit* driver = vehicle->GetPassenger(0);
if (!driver)
return;
//driver->TextEmote(VEHICLE_EMOTE_REPAIR, driver, true); // No source
// Actually should/could use basepoints (100) for this spell effect as percentage of health, but oh well.
vehicle->GetBase()->SetFullHealth();
// Achievement
if (InstanceScript* instance = vehicle->GetBase()->GetInstanceScript())
instance->SetData(DATA_UNBROKEN_ACHIEVEMENT, 0);
}
void Register() override
{
OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_auto_repair::FilterTargets, EFFECT_ALL, TARGET_UNIT_DEST_AREA_ENTRY);
OnEffectHitTarget += SpellEffectFn(spell_auto_repair::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT);
}
};
class spell_systems_shutdown : public SpellScriptLoader
class spell_systems_shutdown_aura : public AuraScript
{
public:
spell_systems_shutdown() : SpellScriptLoader("spell_systems_shutdown") { }
PrepareAuraScript(spell_systems_shutdown_aura);
class spell_systems_shutdown_AuraScript : public AuraScript
bool Validate(SpellInfo const* /*spellInfo*/) override
{
PrepareAuraScript(spell_systems_shutdown_AuraScript);
return ValidateSpellInfo({ SPELL_GATHERING_SPEED });
}
void OnApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
{
Creature* owner = GetOwner()->ToCreature();
if (!owner)
return;
owner->SetControlled(true, UNIT_STATE_STUNNED);
owner->RemoveAurasDueToSpell(SPELL_GATHERING_SPEED);
if (Vehicle* veh = owner->GetVehicleKit())
if (Unit* cannon = veh->GetPassenger(SEAT_CANNON))
cannon->GetAI()->DoAction(ACTION_DELAY_CANNON);
}
void OnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
{
Creature* owner = GetOwner()->ToCreature();
if (!owner)
return;
owner->SetControlled(false, UNIT_STATE_STUNNED);
}
void Register() override
{
OnEffectApply += AuraEffectApplyFn(spell_systems_shutdown_AuraScript::OnApply, EFFECT_0, SPELL_AURA_MOD_DAMAGE_PERCENT_TAKEN, AURA_EFFECT_HANDLE_REAL);
OnEffectRemove += AuraEffectRemoveFn(spell_systems_shutdown_AuraScript::OnRemove, EFFECT_0, SPELL_AURA_MOD_DAMAGE_PERCENT_TAKEN, AURA_EFFECT_HANDLE_REAL);
}
};
AuraScript* GetAuraScript() const override
void OnApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
{
return new spell_systems_shutdown_AuraScript();
Creature* owner = GetOwner()->ToCreature();
if (!owner)
return;
owner->SetControlled(true, UNIT_STATE_STUNNED);
owner->RemoveAurasDueToSpell(SPELL_GATHERING_SPEED);
if (Vehicle* vehicle = owner->GetVehicleKit())
if (Unit* cannon = vehicle->GetPassenger(SEAT_CANNON))
cannon->GetAI()->DoAction(ACTION_DELAY_CANNON);
}
void OnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
{
Creature* owner = GetOwner()->ToCreature();
if (!owner)
return;
owner->SetControlled(false, UNIT_STATE_STUNNED);
}
void Register() override
{
OnEffectApply += AuraEffectApplyFn(spell_systems_shutdown_aura::OnApply, EFFECT_0, SPELL_AURA_MOD_DAMAGE_PERCENT_TAKEN, AURA_EFFECT_HANDLE_REAL);
OnEffectRemove += AuraEffectRemoveFn(spell_systems_shutdown_aura::OnRemove, EFFECT_0, SPELL_AURA_MOD_DAMAGE_PERCENT_TAKEN, AURA_EFFECT_HANDLE_REAL);
}
};
@@ -1625,431 +1607,344 @@ public:
}
};
class spell_pursue : public SpellScriptLoader
class spell_pursue : public SpellScript
{
public:
spell_pursue() : SpellScriptLoader("spell_pursue") {}
PrepareSpellScript(spell_pursue);
class spell_pursue_SpellScript : public SpellScript
void FilterTargets(std::list<WorldObject*>& targets)
{
PrepareSpellScript(spell_pursue_SpellScript);
void FilterTargets(std::list<WorldObject*>& targets)
targets.remove_if(FlameLeviathanPursuedTargetSelector());
if (targets.empty())
{
targets.remove_if(FlameLeviathanPursuedTargetSelector());
if (targets.empty())
{
if (Creature* caster = GetCaster()->ToCreature())
caster->AI()->EnterEvadeMode();
}
else
{
//! In the end, only one target should be selected
WorldObject* _target = Acore::Containers::SelectRandomContainerElement(targets);
targets.clear();
if (_target)
targets.push_back(_target);
}
if (Creature* caster = GetCaster()->ToCreature())
caster->AI()->EnterEvadeMode();
}
void HandleScript(SpellEffIndex /*eff*/)
else
{
Creature* target = GetHitCreature();
Unit* caster = GetCaster();
if (!target || !caster)
return;
caster->GetThreatMgr().ResetAllThreat();
caster->GetAI()->AttackStart(target); // Chase target
caster->AddThreat(target, 10000000.0f);
//! In the end, only one target should be selected
WorldObject* _target = Acore::Containers::SelectRandomContainerElement(targets);
targets.clear();
if (_target)
targets.push_back(_target);
}
}
void Register() override
{
OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_pursue_SpellScript::FilterTargets, EFFECT_ALL, TARGET_UNIT_SRC_AREA_ENEMY);
OnEffectHitTarget += SpellEffectFn(spell_pursue_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_APPLY_AURA);
}
};
SpellScript* GetSpellScript() const override
void HandleScript(SpellEffIndex /*eff*/)
{
return new spell_pursue_SpellScript();
Creature* target = GetHitCreature();
Unit* caster = GetCaster();
if (!target || !caster)
return;
caster->GetThreatMgr().ResetAllThreat();
caster->GetAI()->AttackStart(target); // Chase target
caster->AddThreat(target, 10000000.0f);
}
void Register() override
{
OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_pursue::FilterTargets, EFFECT_ALL, TARGET_UNIT_SRC_AREA_ENEMY);
OnEffectHitTarget += SpellEffectFn(spell_pursue::HandleScript, EFFECT_0, SPELL_EFFECT_APPLY_AURA);
}
};
class spell_vehicle_throw_passenger : public SpellScriptLoader
class spell_vehicle_throw_passenger : public SpellScript
{
public:
spell_vehicle_throw_passenger() : SpellScriptLoader("spell_vehicle_throw_passenger") {}
PrepareSpellScript(spell_vehicle_throw_passenger);
class spell_vehicle_throw_passenger_SpellScript : public SpellScript
void HandleScript()
{
PrepareSpellScript(spell_vehicle_throw_passenger_SpellScript);
void HandleScript()
{
Spell* baseSpell = GetSpell();
SpellCastTargets targets = baseSpell->m_targets;
if (Vehicle* vehicle = GetCaster()->GetVehicleKit())
if (Unit* passenger = vehicle->GetPassenger(3))
Spell* baseSpell = GetSpell();
SpellCastTargets targets = baseSpell->m_targets;
if (Vehicle* vehicle = GetCaster()->GetVehicleKit())
if (Unit* passenger = vehicle->GetPassenger(3))
{
// use 99 because it is 3d search
std::list<WorldObject*> targetList;
Acore::WorldObjectSpellAreaTargetCheck check(99, GetExplTargetDest(), GetCaster(), GetCaster(), GetSpellInfo(), TARGET_CHECK_DEFAULT, nullptr);
Acore::WorldObjectListSearcher<Acore::WorldObjectSpellAreaTargetCheck> searcher(GetCaster(), targetList, check);
Cell::VisitAllObjects(GetCaster(), searcher, 99.0f);
float minDist = 99 * 99;
Unit* target = nullptr;
for (std::list<WorldObject*>::iterator itr = targetList.begin(); itr != targetList.end(); ++itr)
{
// use 99 because it is 3d search
std::list<WorldObject*> targetList;
Acore::WorldObjectSpellAreaTargetCheck check(99, GetExplTargetDest(), GetCaster(), GetCaster(), GetSpellInfo(), TARGET_CHECK_DEFAULT, nullptr);
Acore::WorldObjectListSearcher<Acore::WorldObjectSpellAreaTargetCheck> searcher(GetCaster(), targetList, check);
Cell::VisitAllObjects(GetCaster(), searcher, 99.0f);
float minDist = 99 * 99;
Unit* target = nullptr;
for (std::list<WorldObject*>::iterator itr = targetList.begin(); itr != targetList.end(); ++itr)
{
if (Unit* unit = (*itr)->ToUnit())
if (unit->GetEntry() == NPC_SEAT)
if (Vehicle* seat = unit->GetVehicleKit())
if (!seat->GetPassenger(0))
if (Unit* device = seat->GetPassenger(2))
if (!device->GetCurrentSpell(CURRENT_CHANNELED_SPELL))
if (Unit* unit = (*itr)->ToUnit())
if (unit->GetEntry() == NPC_SEAT)
if (Vehicle* seat = unit->GetVehicleKit())
if (!seat->GetPassenger(0))
if (Unit* device = seat->GetPassenger(2))
if (!device->GetCurrentSpell(CURRENT_CHANNELED_SPELL))
{
float dist = unit->GetExactDistSq(targets.GetDstPos());
if (dist < minDist)
{
float dist = unit->GetExactDistSq(targets.GetDstPos());
if (dist < minDist)
{
minDist = dist;
target = unit;
}
minDist = dist;
target = unit;
}
}
if (target && target->IsWithinDist2d(targets.GetDstPos(), GetSpellInfo()->Effects[EFFECT_0].CalcRadius() * 2)) // now we use *2 because the location of the seat is not correct
{
passenger->ExitVehicle();
passenger->EnterVehicle(target, 0);
}
else
{
passenger->ExitVehicle();
float x, y, z;
targets.GetDstPos()->GetPosition(x, y, z);
passenger->GetMotionMaster()->MoveJump(x, y, z, targets.GetSpeedXY(), targets.GetSpeedZ());
}
}
}
}
void Register() override
{
AfterCast += SpellCastFn(spell_vehicle_throw_passenger_SpellScript::HandleScript);
}
};
SpellScript* GetSpellScript() const override
{
return new spell_vehicle_throw_passenger_SpellScript();
}
};
class spell_tar_blaze : public SpellScriptLoader
{
public:
spell_tar_blaze() : SpellScriptLoader("spell_tar_blaze") { }
class spell_tar_blaze_AuraScript : public AuraScript
{
PrepareAuraScript(spell_tar_blaze_AuraScript);
void OnPeriodic(AuraEffect const* aurEff)
{
GetUnitOwner()->CastSpell((Unit*)nullptr, GetSpellInfo()->Effects[aurEff->GetEffIndex()].TriggerSpell, true);
}
void Register() override
{
OnEffectPeriodic += AuraEffectPeriodicFn(spell_tar_blaze_AuraScript::OnPeriodic, EFFECT_0, SPELL_AURA_PERIODIC_DUMMY);
}
};
AuraScript* GetAuraScript() const override
{
return new spell_tar_blaze_AuraScript();
}
};
class spell_vehicle_grab_pyrite : public SpellScriptLoader
{
public:
spell_vehicle_grab_pyrite() : SpellScriptLoader("spell_vehicle_grab_pyrite") {}
class spell_vehicle_grab_pyrite_SpellScript : public SpellScript
{
PrepareSpellScript(spell_vehicle_grab_pyrite_SpellScript);
void HandleScript(SpellEffIndex /*effIndex*/)
{
if (Unit* target = GetHitUnit())
if (Unit* seat = GetCaster()->GetVehicleBase())
if (target && target->IsWithinDist2d(targets.GetDstPos(), GetSpellInfo()->Effects[EFFECT_0].CalcRadius() * 2)) // now we use *2 because the location of the seat is not correct
{
if (Vehicle* vSeat = seat->GetVehicleKit())
if (Unit* pyrite = vSeat->GetPassenger(1))
pyrite->ExitVehicle();
if (Unit* parent = seat->GetVehicleBase())
{
GetCaster()->CastSpell(parent, 62496 /*SPELL_ADD_PYRITE*/, true);
target->CastSpell(seat, GetEffectValue());
if (target->GetTypeId() == TYPEID_UNIT)
target->ToCreature()->DespawnOrUnsummon(1300);
}
passenger->ExitVehicle();
passenger->EnterVehicle(target, 0);
}
}
void Register() override
{
OnEffectHitTarget += SpellEffectFn(spell_vehicle_grab_pyrite_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT);
}
};
SpellScript* GetSpellScript() const override
{
return new spell_vehicle_grab_pyrite_SpellScript();
}
};
class spell_vehicle_circuit_overload : public SpellScriptLoader
{
public:
spell_vehicle_circuit_overload() : SpellScriptLoader("spell_vehicle_circuit_overload") { }
class spell_vehicle_circuit_overload_AuraScript : public AuraScript
{
PrepareAuraScript(spell_vehicle_circuit_overload_AuraScript);
void OnPeriodic(AuraEffect const* /*aurEff*/)
{
if (Unit* target = GetTarget())
if (int(target->GetAppliedAuras().count(SPELL_OVERLOAD_CIRCUIT)) >= (target->GetMap()->Is25ManRaid() ? 4 : 2))
else
{
target->CastSpell(target, SPELL_SYSTEMS_SHUTDOWN, true);
target->RemoveAurasDueToSpell(SPELL_OVERLOAD_CIRCUIT);
passenger->ExitVehicle();
float x, y, z;
targets.GetDstPos()->GetPosition(x, y, z);
passenger->GetMotionMaster()->MoveJump(x, y, z, targets.GetSpeedXY(), targets.GetSpeedZ());
}
}
}
}
void Register() override
{
OnEffectPeriodic += AuraEffectPeriodicFn(spell_vehicle_circuit_overload_AuraScript::OnPeriodic, EFFECT_1, SPELL_AURA_PERIODIC_DUMMY);
}
};
AuraScript* GetAuraScript() const override
void Register() override
{
return new spell_vehicle_circuit_overload_AuraScript();
AfterCast += SpellCastFn(spell_vehicle_throw_passenger::HandleScript);
}
};
class spell_orbital_supports : public SpellScriptLoader
class spell_tar_blaze_aura : public AuraScript
{
public:
spell_orbital_supports() : SpellScriptLoader("spell_orbital_supports") { }
PrepareAuraScript(spell_tar_blaze_aura);
class spell_orbital_supports_AuraScript : public AuraScript
void OnPeriodic(AuraEffect const* aurEff)
{
PrepareAuraScript(spell_orbital_supports_AuraScript);
GetUnitOwner()->CastSpell((Unit*)nullptr, GetSpellInfo()->Effects[aurEff->GetEffIndex()].TriggerSpell, true);
}
bool CheckAreaTarget(Unit* target)
{
return target->GetEntry() == NPC_LEVIATHAN;
}
void Register() override
{
DoCheckAreaTarget += AuraCheckAreaTargetFn(spell_orbital_supports_AuraScript::CheckAreaTarget);
}
};
AuraScript* GetAuraScript() const override
void Register() override
{
return new spell_orbital_supports_AuraScript();
OnEffectPeriodic += AuraEffectPeriodicFn(spell_tar_blaze_aura::OnPeriodic, EFFECT_0, SPELL_AURA_PERIODIC_DUMMY);
}
};
class spell_thorims_hammer : public SpellScriptLoader
enum VehicleGrabPyrite
{
public:
spell_thorims_hammer() : SpellScriptLoader("spell_thorims_hammer") { }
SPELL_ADD_PYRITE = 62496
};
class spell_thorims_hammer_SpellScript : public SpellScript
class spell_vehicle_grab_pyrite : public SpellScript
{
PrepareSpellScript(spell_vehicle_grab_pyrite);
bool Validate(SpellInfo const* /*spellInfo*/) override
{
PrepareSpellScript(spell_thorims_hammer_SpellScript);
return ValidateSpellInfo({ SPELL_ADD_PYRITE });
}
void RecalculateDamage(SpellEffIndex effIndex)
{
if (!GetHitUnit() || effIndex == EFFECT_1)
{
PreventHitDefaultEffect(effIndex);
return;
}
float dist = GetHitUnit()->GetExactDist2d(GetCaster());
if (dist <= 7.0f)
{
SetHitDamage(GetSpellInfo()->Effects[EFFECT_1].CalcValue());
}
else
{
dist -= 6.0f;
SetHitDamage(int32(GetSpellInfo()->Effects[EFFECT_1].CalcValue() / std::max(dist, 1.0f)));
}
}
void Register() override
{
OnEffectHitTarget += SpellEffectFn(spell_thorims_hammer_SpellScript::RecalculateDamage, EFFECT_ALL, SPELL_EFFECT_SCHOOL_DAMAGE);
}
};
SpellScript* GetSpellScript() const override
void HandleScript(SpellEffIndex /*effIndex*/)
{
return new spell_thorims_hammer_SpellScript();
if (Unit* target = GetHitUnit())
if (Unit* seat = GetCaster()->GetVehicleBase())
{
if (Vehicle* vehicle = seat->GetVehicleKit())
if (Unit* pyrite = vehicle->GetPassenger(1))
pyrite->ExitVehicle();
if (Unit* parent = seat->GetVehicleBase())
{
GetCaster()->CastSpell(parent, SPELL_ADD_PYRITE, true);
target->CastSpell(seat, GetEffectValue());
if (target->GetTypeId() == TYPEID_UNIT)
target->ToCreature()->DespawnOrUnsummon(1300);
}
}
}
void Register() override
{
OnEffectHitTarget += SpellEffectFn(spell_vehicle_grab_pyrite::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT);
}
};
class spell_transitus_shield_beam : public SpellScriptLoader
class spell_vehicle_circuit_overload_aura : public AuraScript
{
public:
spell_transitus_shield_beam() : SpellScriptLoader("spell_transitus_shield_beam") { }
PrepareAuraScript(spell_vehicle_circuit_overload_aura);
class spell_transitus_shield_beam_AuraScript : public AuraScript
bool Validate(SpellInfo const* /*spellInfo*/) override
{
PrepareAuraScript(spell_transitus_shield_beam_AuraScript);
return ValidateSpellInfo({ SPELL_SYSTEMS_SHUTDOWN });
}
void HandleOnEffectApply(AuraEffect const* aurEff, AuraEffectHandleModes /*mode*/)
{
Unit* caster = GetCaster();
if (!caster)
{
return;
}
Unit* target = GetTarget();
if (!target)
{
return;
}
switch (aurEff->GetEffIndex())
{
case EFFECT_0:
caster->AddAura(SPELL_TRANSITUS_SHIELD_IMPACT, target);
break;
}
}
void HandleOnEffectRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
{
Unit* caster = GetCaster();
if (!caster)
{
return;
}
Unit* target = GetTarget();
if (target)
{
target->RemoveAurasDueToSpell(SPELL_TRANSITUS_SHIELD_IMPACT);
}
}
void Register()
{
OnEffectApply += AuraEffectApplyFn(spell_transitus_shield_beam_AuraScript::HandleOnEffectApply, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL_OR_REAPPLY_MASK);
OnEffectRemove += AuraEffectRemoveFn(spell_transitus_shield_beam_AuraScript::HandleOnEffectRemove, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL_OR_REAPPLY_MASK);
}
};
AuraScript* GetAuraScript() const override
void OnPeriodic(AuraEffect const* /*aurEff*/)
{
return new spell_transitus_shield_beam_AuraScript();
if (Unit* target = GetTarget())
if (int(target->GetAppliedAuras().count(SPELL_OVERLOAD_CIRCUIT)) >= (target->GetMap()->Is25ManRaid() ? 4 : 2))
{
target->CastSpell(target, SPELL_SYSTEMS_SHUTDOWN, true);
target->RemoveAurasDueToSpell(SPELL_OVERLOAD_CIRCUIT);
}
}
void Register() override
{
OnEffectPeriodic += AuraEffectPeriodicFn(spell_vehicle_circuit_overload_aura::OnPeriodic, EFFECT_1, SPELL_AURA_PERIODIC_DUMMY);
}
};
class spell_shield_generator : public SpellScriptLoader
class spell_orbital_supports_aura : public AuraScript
{
public:
spell_shield_generator() : SpellScriptLoader("spell_shield_generator") { }
PrepareAuraScript(spell_orbital_supports_aura);
class spell_shield_generator_AuraScript : public AuraScript
bool CheckAreaTarget(Unit* target)
{
PrepareAuraScript(spell_shield_generator_AuraScript);
uint32 absorbPct;
bool Load() override
{
absorbPct = GetSpellInfo()->Effects[EFFECT_0].CalcValue(GetCaster());
return true;
}
void CalculateAmount(AuraEffect const* /*aurEff*/, int32& amount, bool& /*canBeRecalculated*/)
{
// Set absorbtion amount to unlimited
amount = -1;
}
void Absorb(AuraEffect* /*aurEff*/, DamageInfo& dmgInfo, uint32& absorbAmount)
{
absorbAmount = CalculatePct(dmgInfo.GetDamage(), absorbPct);
}
void Register() override
{
DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_shield_generator_AuraScript::CalculateAmount, EFFECT_0, SPELL_AURA_SCHOOL_ABSORB);
OnEffectAbsorb += AuraEffectAbsorbFn(spell_shield_generator_AuraScript::Absorb, EFFECT_0);
}
};
AuraScript* GetAuraScript() const override
return target->GetEntry() == NPC_LEVIATHAN;
}
void Register() override
{
return new spell_shield_generator_AuraScript();
DoCheckAreaTarget += AuraCheckAreaTargetFn(spell_orbital_supports_aura::CheckAreaTarget);
}
};
class spell_demolisher_ride_vehicle : public SpellScriptLoader
class spell_thorims_hammer : public SpellScript
{
public:
spell_demolisher_ride_vehicle() : SpellScriptLoader("spell_demolisher_ride_vehicle") {}
PrepareSpellScript(spell_thorims_hammer);
class spell_demolisher_ride_vehicle_SpellScript : public SpellScript
void RecalculateDamage(SpellEffIndex effIndex)
{
PrepareSpellScript(spell_demolisher_ride_vehicle_SpellScript);
SpellCastResult CheckCast()
if (!GetHitUnit() || effIndex == EFFECT_1)
{
if (GetCaster()->GetTypeId() != TYPEID_PLAYER)
return SPELL_CAST_OK;
PreventHitDefaultEffect(effIndex);
return;
}
Unit* target = this->GetExplTargetUnit();
if (!target || target->GetEntry() != NPC_SALVAGED_DEMOLISHER)
return SPELL_FAILED_DONT_REPORT;
float dist = GetHitUnit()->GetExactDist2d(GetCaster());
if (dist <= 7.0f)
{
SetHitDamage(GetSpellInfo()->Effects[EFFECT_1].CalcValue());
}
else
{
dist -= 6.0f;
SetHitDamage(int32(GetSpellInfo()->Effects[EFFECT_1].CalcValue() / std::max(dist, 1.0f)));
}
}
Vehicle* veh = target->GetVehicleKit();
if (veh && veh->GetPassenger(0))
if (Unit* target2 = veh->GetPassenger(1))
if (Vehicle* veh2 = target2->GetVehicleKit())
{
if (!veh2->GetPassenger(0))
target2->HandleSpellClick(GetCaster());
void Register() override
{
OnEffectHitTarget += SpellEffectFn(spell_thorims_hammer::RecalculateDamage, EFFECT_ALL, SPELL_EFFECT_SCHOOL_DAMAGE);
}
};
return SPELL_FAILED_DONT_REPORT;
}
class spell_transitus_shield_beam_aura : public AuraScript
{
PrepareAuraScript(spell_transitus_shield_beam_aura);
bool Validate(SpellInfo const* /*spellInfo*/) override
{
return ValidateSpellInfo({ SPELL_TRANSITUS_SHIELD_IMPACT });
}
void HandleOnEffectApply(AuraEffect const* aurEff, AuraEffectHandleModes /*mode*/)
{
Unit* caster = GetCaster();
if (!caster)
{
return;
}
Unit* target = GetTarget();
if (!target)
{
return;
}
switch (aurEff->GetEffIndex())
{
case EFFECT_0:
caster->AddAura(SPELL_TRANSITUS_SHIELD_IMPACT, target);
break;
}
}
void HandleOnEffectRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
{
Unit* caster = GetCaster();
if (!caster)
{
return;
}
Unit* target = GetTarget();
if (target)
{
target->RemoveAurasDueToSpell(SPELL_TRANSITUS_SHIELD_IMPACT);
}
}
void Register() override
{
OnEffectApply += AuraEffectApplyFn(spell_transitus_shield_beam_aura::HandleOnEffectApply, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL_OR_REAPPLY_MASK);
OnEffectRemove += AuraEffectRemoveFn(spell_transitus_shield_beam_aura::HandleOnEffectRemove, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL_OR_REAPPLY_MASK);
}
};
class spell_shield_generator_aura : public AuraScript
{
PrepareAuraScript(spell_shield_generator_aura);
bool Load() override
{
_absorbPct = GetSpellInfo()->Effects[EFFECT_0].CalcValue(GetCaster());
return true;
}
void CalculateAmount(AuraEffect const* /*aurEff*/, int32& amount, bool& /*canBeRecalculated*/)
{
// Set absorbtion amount to unlimited
amount = -1;
}
void Absorb(AuraEffect* /*aurEff*/, DamageInfo& dmgInfo, uint32& absorbAmount)
{
absorbAmount = CalculatePct(dmgInfo.GetDamage(), _absorbPct);
}
void Register() override
{
DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_shield_generator_aura::CalculateAmount, EFFECT_0, SPELL_AURA_SCHOOL_ABSORB);
OnEffectAbsorb += AuraEffectAbsorbFn(spell_shield_generator_aura::Absorb, EFFECT_0);
}
private:
uint32 _absorbPct;
};
class spell_demolisher_ride_vehicle : public SpellScript
{
PrepareSpellScript(spell_demolisher_ride_vehicle);
SpellCastResult CheckCast()
{
if (GetCaster()->GetTypeId() != TYPEID_PLAYER)
return SPELL_CAST_OK;
}
void Register() override
{
OnCheckCast += SpellCheckCastFn(spell_demolisher_ride_vehicle_SpellScript::CheckCast);
}
};
Unit* target = this->GetExplTargetUnit();
if (!target || target->GetEntry() != NPC_SALVAGED_DEMOLISHER)
return SPELL_FAILED_DONT_REPORT;
SpellScript* GetSpellScript() const override
Vehicle* vehicle = target->GetVehicleKit();
if (vehicle && vehicle->GetPassenger(0))
if (Unit* target2 = vehicle->GetPassenger(1))
if (Vehicle* vehicle2 = target2->GetVehicleKit())
{
if (!vehicle2->GetPassenger(0))
target2->HandleSpellClick(GetCaster());
return SPELL_FAILED_DONT_REPORT;
}
return SPELL_CAST_OK;
}
void Register() override
{
return new spell_demolisher_ride_vehicle_SpellScript();
OnCheckCast += SpellCheckCastFn(spell_demolisher_ride_vehicle::CheckCast);
}
};
@@ -2143,19 +2038,19 @@ void AddSC_boss_flame_leviathan()
new go_ulduar_tower();
// Spells
new spell_load_into_catapult();
new spell_auto_repair();
new spell_systems_shutdown();
new spell_pursue();
new spell_vehicle_throw_passenger();
new spell_tar_blaze();
new spell_vehicle_grab_pyrite();
new spell_vehicle_circuit_overload();
new spell_orbital_supports();
new spell_thorims_hammer();
new spell_transitus_shield_beam();
new spell_shield_generator();
new spell_demolisher_ride_vehicle();
RegisterSpellScript(spell_load_into_catapult_aura);
RegisterSpellScript(spell_auto_repair);
RegisterSpellScript(spell_systems_shutdown_aura);
RegisterSpellScript(spell_pursue);
RegisterSpellScript(spell_vehicle_throw_passenger);
RegisterSpellScript(spell_tar_blaze_aura);
RegisterSpellScript(spell_vehicle_grab_pyrite);
RegisterSpellScript(spell_vehicle_circuit_overload_aura);
RegisterSpellScript(spell_orbital_supports_aura);
RegisterSpellScript(spell_thorims_hammer);
RegisterSpellScript(spell_transitus_shield_beam_aura);
RegisterSpellScript(spell_shield_generator_aura);
RegisterSpellScript(spell_demolisher_ride_vehicle);
// Achievements
new achievement_flame_leviathan_towers("achievement_flame_leviathan_orbital_bombardment", 1);

View File

@@ -472,173 +472,138 @@ public:
};
};
class spell_aura_of_despair : public SpellScriptLoader
class spell_aura_of_despair_aura : public AuraScript
{
public:
spell_aura_of_despair() : SpellScriptLoader("spell_aura_of_despair") { }
PrepareAuraScript(spell_aura_of_despair_aura);
class spell_aura_of_despair_AuraScript : public AuraScript
bool Validate(SpellInfo const* /*spellInfo*/) override
{
PrepareAuraScript(spell_aura_of_despair_AuraScript)
return ValidateSpellInfo({ SPELL_AURA_OF_DESPAIR_2, SPELL_CORRUPTED_RAGE, SPELL_CORRUPTED_WISDOM });
}
void OnApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
{
if (Unit* caster = GetCaster())
if (Unit* target = GetTarget())
{
if (target->GetTypeId() != TYPEID_PLAYER)
return;
target->CastSpell(target, SPELL_AURA_OF_DESPAIR_2, true);
if( target->HasSpell(SPELL_SHAMANISTIC_RAGE) )
caster->CastSpell(target, SPELL_CORRUPTED_RAGE, true);
else if( target->HasSpell(SPELL_JUDGEMENTS_OF_THE_WISDOM_RANK_1) || target->HasSpell(SPELL_JUDGEMENTS_OF_THE_WISDOM_RANK_1 + 1) || target->HasSpell(SPELL_JUDGEMENTS_OF_THE_WISDOM_RANK_1 + 2) )
caster->CastSpell(target, SPELL_CORRUPTED_WISDOM, true);
}
}
void OnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
{
void OnApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
{
if (Unit* caster = GetCaster())
if (Unit* target = GetTarget())
{
target->RemoveAurasDueToSpell(SPELL_AURA_OF_DESPAIR_2);
target->RemoveAurasDueToSpell(SPELL_CORRUPTED_RAGE);
target->RemoveAurasDueToSpell(SPELL_CORRUPTED_WISDOM);
if (target->GetTypeId() != TYPEID_PLAYER)
return;
target->CastSpell(target, SPELL_AURA_OF_DESPAIR_2, true);
if (target->HasSpell(SPELL_SHAMANISTIC_RAGE))
caster->CastSpell(target, SPELL_CORRUPTED_RAGE, true);
else if (target->HasSpell(SPELL_JUDGEMENTS_OF_THE_WISDOM_RANK_1) || target->HasSpell(SPELL_JUDGEMENTS_OF_THE_WISDOM_RANK_1 + 1) || target->HasSpell(SPELL_JUDGEMENTS_OF_THE_WISDOM_RANK_1 + 2))
caster->CastSpell(target, SPELL_CORRUPTED_WISDOM, true);
}
}
}
void Register() override
{
OnEffectApply += AuraEffectApplyFn(spell_aura_of_despair_AuraScript::OnApply, EFFECT_0, SPELL_AURA_PREVENT_REGENERATE_POWER, AURA_EFFECT_HANDLE_REAL);
AfterEffectRemove += AuraEffectRemoveFn(spell_aura_of_despair_AuraScript::OnRemove, EFFECT_0, SPELL_AURA_PREVENT_REGENERATE_POWER, AURA_EFFECT_HANDLE_REAL);
}
};
AuraScript* GetAuraScript() const override
void OnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
{
return new spell_aura_of_despair_AuraScript();
if (Unit* target = GetTarget())
{
target->RemoveAurasDueToSpell(SPELL_AURA_OF_DESPAIR_2);
target->RemoveAurasDueToSpell(SPELL_CORRUPTED_RAGE);
target->RemoveAurasDueToSpell(SPELL_CORRUPTED_WISDOM);
}
}
void Register() override
{
OnEffectApply += AuraEffectApplyFn(spell_aura_of_despair_aura::OnApply, EFFECT_0, SPELL_AURA_PREVENT_REGENERATE_POWER, AURA_EFFECT_HANDLE_REAL);
AfterEffectRemove += AuraEffectRemoveFn(spell_aura_of_despair_aura::OnRemove, EFFECT_0, SPELL_AURA_PREVENT_REGENERATE_POWER, AURA_EFFECT_HANDLE_REAL);
}
};
class spell_mark_of_the_faceless_periodic : public SpellScriptLoader
class spell_mark_of_the_faceless_periodic_aura : public AuraScript
{
public:
spell_mark_of_the_faceless_periodic() : SpellScriptLoader("spell_mark_of_the_faceless_periodic") { }
PrepareAuraScript(spell_mark_of_the_faceless_periodic_aura);
class spell_mark_of_the_faceless_periodic_AuraScript : public AuraScript
bool Validate(SpellInfo const* /*spellInfo*/) override
{
PrepareAuraScript(spell_mark_of_the_faceless_periodic_AuraScript)
void HandleEffectPeriodic(AuraEffect const* /*aurEff*/)
{
if (Unit* caster = GetCaster())
if (Unit* target = GetTarget())
if (target->GetMapId() == 603)
{
int32 dmg = 5000;
caster->CastCustomSpell(target, SPELL_MARK_OF_THE_FACELESS_EFFECT, 0, &dmg, 0, true);
}
}
void Register() override
{
OnEffectPeriodic += AuraEffectPeriodicFn(spell_mark_of_the_faceless_periodic_AuraScript::HandleEffectPeriodic, EFFECT_0, SPELL_AURA_PERIODIC_DUMMY);
}
};
AuraScript* GetAuraScript() const override
{
return new spell_mark_of_the_faceless_periodic_AuraScript();
return ValidateSpellInfo({ SPELL_MARK_OF_THE_FACELESS_EFFECT });
}
};
class spell_mark_of_the_faceless_drainhealth : public SpellScriptLoader
{
public:
spell_mark_of_the_faceless_drainhealth() : SpellScriptLoader("spell_mark_of_the_faceless_drainhealth") { }
class spell_mark_of_the_faceless_drainhealth_SpellScript : public SpellScript
void HandleEffectPeriodic(AuraEffect const* /*aurEff*/)
{
PrepareSpellScript(spell_mark_of_the_faceless_drainhealth_SpellScript);
void FilterTargets(std::list<WorldObject*>& targets)
{
targets.remove(GetExplTargetUnit());
if (targets.empty())
Cancel();
}
void Register() override
{
OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_mark_of_the_faceless_drainhealth_SpellScript::FilterTargets, EFFECT_1, TARGET_UNIT_DEST_AREA_ENEMY);
}
};
SpellScript* GetSpellScript() const override
{
return new spell_mark_of_the_faceless_drainhealth_SpellScript();
}
};
class spell_saronite_vapors_dummy : public SpellScriptLoader
{
public:
spell_saronite_vapors_dummy() : SpellScriptLoader("spell_saronite_vapors_dummy") { }
class spell_saronite_vapors_dummy_AuraScript : public AuraScript
{
PrepareAuraScript(spell_saronite_vapors_dummy_AuraScript)
void HandleAfterEffectApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
{
if (Unit* caster = GetCaster())
{
int32 damage = 100 * pow(2.0f, (float)GetStackAmount());
caster->CastCustomSpell(GetTarget(), SPELL_SARONITE_VAPORS_DMG, &damage, nullptr, nullptr, true);
}
}
void Register() override
{
AfterEffectApply += AuraEffectApplyFn(spell_saronite_vapors_dummy_AuraScript::HandleAfterEffectApply, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL_OR_REAPPLY_MASK);
}
};
AuraScript* GetAuraScript() const override
{
return new spell_saronite_vapors_dummy_AuraScript();
}
};
class spell_saronite_vapors_damage : public SpellScriptLoader
{
public:
spell_saronite_vapors_damage() : SpellScriptLoader("spell_saronite_vapors_damage") { }
class spell_saronite_vapors_damage_SpellScript : public SpellScript
{
PrepareSpellScript(spell_saronite_vapors_damage_SpellScript);
void HandleAfterHit()
{
if (Unit* caster = GetCaster())
if (GetHitDamage() > 2)
if (Unit* caster = GetCaster())
if (Unit* target = GetTarget())
if (target->GetMapId() == 603)
{
int32 mana = GetHitDamage() / 2;
if (Unit* t = GetHitUnit())
caster->CastCustomSpell(t, SPELL_SARONITE_VAPORS_ENERGIZE, &mana, nullptr, nullptr, true);
int32 dmg = 5000;
caster->CastCustomSpell(target, SPELL_MARK_OF_THE_FACELESS_EFFECT, 0, &dmg, 0, true);
}
}
}
void Register() override
{
AfterHit += SpellHitFn(spell_saronite_vapors_damage_SpellScript::HandleAfterHit);
}
};
SpellScript* GetSpellScript() const override
void Register() override
{
return new spell_saronite_vapors_damage_SpellScript();
OnEffectPeriodic += AuraEffectPeriodicFn(spell_mark_of_the_faceless_periodic_aura::HandleEffectPeriodic, EFFECT_0, SPELL_AURA_PERIODIC_DUMMY);
}
};
class spell_mark_of_the_faceless_drainhealth : public SpellScript
{
PrepareSpellScript(spell_mark_of_the_faceless_drainhealth);
void FilterTargets(std::list<WorldObject*>& targets)
{
targets.remove(GetExplTargetUnit());
if (targets.empty())
Cancel();
}
void Register() override
{
OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_mark_of_the_faceless_drainhealth::FilterTargets, EFFECT_1, TARGET_UNIT_DEST_AREA_ENEMY);
}
};
class spell_saronite_vapors_dummy_aura : public AuraScript
{
PrepareAuraScript(spell_saronite_vapors_dummy_aura);
bool Validate(SpellInfo const* /*spellInfo*/) override
{
return ValidateSpellInfo({ SPELL_SARONITE_VAPORS_DMG });
}
void HandleAfterEffectApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
{
if (Unit* caster = GetCaster())
{
int32 damage = 100 * pow(2.0f, (float)GetStackAmount());
caster->CastCustomSpell(GetTarget(), SPELL_SARONITE_VAPORS_DMG, &damage, nullptr, nullptr, true);
}
}
void Register() override
{
AfterEffectApply += AuraEffectApplyFn(spell_saronite_vapors_dummy_aura::HandleAfterEffectApply, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL_OR_REAPPLY_MASK);
}
};
class spell_saronite_vapors_damage : public SpellScript
{
PrepareSpellScript(spell_saronite_vapors_damage);
bool Validate(SpellInfo const* /*spellInfo*/) override
{
return ValidateSpellInfo({ SPELL_SARONITE_VAPORS_ENERGIZE });
}
void HandleAfterHit()
{
if (Unit* caster = GetCaster())
if (GetHitDamage() > 2)
{
int32 mana = GetHitDamage() / 2;
if (Unit* target = GetHitUnit())
caster->CastCustomSpell(target, SPELL_SARONITE_VAPORS_ENERGIZE, &mana, nullptr, nullptr, true);
}
}
void Register() override
{
AfterHit += SpellHitFn(spell_saronite_vapors_damage::HandleAfterHit);
}
};
@@ -693,11 +658,11 @@ void AddSC_boss_vezax()
new npc_ulduar_saronite_vapors();
new npc_ulduar_saronite_animus();
new spell_aura_of_despair();
new spell_mark_of_the_faceless_periodic();
new spell_mark_of_the_faceless_drainhealth();
new spell_saronite_vapors_dummy();
new spell_saronite_vapors_damage();
RegisterSpellScript(spell_aura_of_despair_aura);
RegisterSpellScript(spell_mark_of_the_faceless_periodic_aura);
RegisterSpellScript(spell_mark_of_the_faceless_drainhealth);
RegisterSpellScript(spell_saronite_vapors_dummy_aura);
RegisterSpellScript(spell_saronite_vapors_damage);
new achievement_smell_saronite();
new achievement_shadowdodger();

View File

@@ -426,112 +426,112 @@ public:
};
};
class spell_ignis_scorch : public SpellScriptLoader
class spell_ignis_scorch_aura : public AuraScript
{
public:
spell_ignis_scorch() : SpellScriptLoader("spell_ignis_scorch") { }
PrepareAuraScript(spell_ignis_scorch_aura);
class spell_ignis_scorch_AuraScript : public AuraScript
bool Validate(SpellInfo const* /*spellInfo*/) override
{
PrepareAuraScript(spell_ignis_scorch_AuraScript)
return ValidateSpellInfo( { SPELL_SCORCHED_GROUND_10, SPELL_SCORCHED_GROUND_25 });
}
void HandleEffectPeriodic(AuraEffect const* aurEff)
{
if (aurEff->GetTotalTicks() >= 0 && aurEff->GetTickNumber() == uint32(aurEff->GetTotalTicks()))
if (Unit* c = GetCaster())
if (Creature* s = c->SummonCreature(NPC_SCORCHED_GROUND, c->GetPositionX() + 20.0f * cos(c->GetOrientation()), c->GetPositionY() + 20.0f * std::sin(c->GetOrientation()), 361.0f, 0.0f, TEMPSUMMON_TIMED_DESPAWN, 30000))
{
if (!s->FindNearestCreature(NPC_WATER_TRIGGER, 25.0f, true)) // must be away from the water
s->CastSpell(s, (aurEff->GetId() == 62546 ? SPELL_SCORCHED_GROUND_10 : SPELL_SCORCHED_GROUND_25), true);
}
}
void Register() override
{
OnEffectPeriodic += AuraEffectPeriodicFn(spell_ignis_scorch_AuraScript::HandleEffectPeriodic, EFFECT_0, SPELL_AURA_PERIODIC_TRIGGER_SPELL);
}
};
AuraScript* GetAuraScript() const override
void HandleEffectPeriodic(AuraEffect const* aurEff)
{
return new spell_ignis_scorch_AuraScript();
if (aurEff->GetTotalTicks() >= 0 && aurEff->GetTickNumber() == uint32(aurEff->GetTotalTicks()))
if (Unit* caster = GetCaster())
if (Creature* summon = caster->SummonCreature(NPC_SCORCHED_GROUND, caster->GetPositionX() + 20.0f * cos(caster->GetOrientation()), caster->GetPositionY() + 20.0f * std::sin(caster->GetOrientation()), 361.0f, 0.0f, TEMPSUMMON_TIMED_DESPAWN, 30000))
{
if (!summon->FindNearestCreature(NPC_WATER_TRIGGER, 25.0f, true)) // must be away from the water
summon->CastSpell(summon, (aurEff->GetId() == SPELL_SCORCH_10 ? SPELL_SCORCHED_GROUND_10 : SPELL_SCORCHED_GROUND_25), true);
}
}
void Register() override
{
OnEffectPeriodic += AuraEffectPeriodicFn(spell_ignis_scorch_aura::HandleEffectPeriodic, EFFECT_0, SPELL_AURA_PERIODIC_TRIGGER_SPELL);
}
};
class spell_ignis_grab_initial : public SpellScriptLoader
class spell_ignis_grab_initial : public SpellScript
{
public:
spell_ignis_grab_initial() : SpellScriptLoader("spell_ignis_grab_initial") { }
PrepareSpellScript(spell_ignis_grab_initial);
class spell_ignis_grab_initial_SpellScript : public SpellScript
bool Validate(SpellInfo const* /*spellInfo*/) override
{
PrepareSpellScript(spell_ignis_grab_initial_SpellScript);
return ValidateSpellInfo( { SPELL_GRAB_TRIGGERED });
}
void HandleScript(SpellEffIndex /*effIndex*/)
{
if (Unit* t = GetHitUnit())
t->CastSpell(t, SPELL_GRAB_TRIGGERED, true);
}
void Register() override
{
OnEffectHitTarget += SpellEffectFn(spell_ignis_grab_initial_SpellScript::HandleScript, EFFECT_2, SPELL_EFFECT_SCRIPT_EFFECT);
}
};
SpellScript* GetSpellScript() const override
void HandleScript(SpellEffIndex /*effIndex*/)
{
return new spell_ignis_grab_initial_SpellScript();
if (Unit* target = GetHitUnit())
target->CastSpell(target, SPELL_GRAB_TRIGGERED, true);
}
void Register() override
{
OnEffectHitTarget += SpellEffectFn(spell_ignis_grab_initial::HandleScript, EFFECT_2, SPELL_EFFECT_SCRIPT_EFFECT);
}
};
class spell_ignis_slag_pot : public SpellScriptLoader
enum SlagPot
{
public:
spell_ignis_slag_pot() : SpellScriptLoader("spell_ignis_slag_pot") { }
SPELL_SLAG_POT_DAMAGE_1 = 65722,
SPELL_SLAG_POT_DAMAGE_2 = 65723,
SPELL_SCORCH_DAMAGE_1 = 62549,
SPELL_SCORCH_DAMAGE_2 = 63475,
SPELL_SLAG_IMBUED_1 = 62836,
SPELL_SLAG_IMBUED_2 = 63536
};
class spell_ignis_slag_pot_AuraScript : public AuraScript
class spell_ignis_slag_pot_aura : public AuraScript
{
PrepareAuraScript(spell_ignis_slag_pot_aura);
bool Validate(SpellInfo const* /*spellInfo*/) override
{
PrepareAuraScript(spell_ignis_slag_pot_AuraScript)
void HandleEffectPeriodic(AuraEffect const* /*aurEff*/)
{
if (Unit* c = GetCaster())
if (Unit* t = GetTarget())
c->CastSpell(t, (GetId() == 62717 ? 65722 : 65723), true);
}
void OnApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
{
if (Unit* t = GetTarget())
return ValidateSpellInfo(
{
t->ApplySpellImmune(GetId(), IMMUNITY_ID, 62549, true);
t->ApplySpellImmune(GetId(), IMMUNITY_ID, 63475, true);
}
}
SPELL_SLAG_POT_DAMAGE_1,
SPELL_SLAG_POT_DAMAGE_2,
SPELL_SCORCH_DAMAGE_1,
SPELL_SCORCH_DAMAGE_2,
SPELL_SLAG_IMBUED_1,
SPELL_SLAG_IMBUED_2
});
}
void OnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
{
if (Unit* t = GetTarget())
{
t->ApplySpellImmune(GetId(), IMMUNITY_ID, 62549, false);
t->ApplySpellImmune(GetId(), IMMUNITY_ID, 63475, false);
if (t->IsAlive())
t->CastSpell(t, (GetId() == 62717 ? 62836 : 63536), true);
}
}
void Register() override
{
OnEffectPeriodic += AuraEffectPeriodicFn(spell_ignis_slag_pot_AuraScript::HandleEffectPeriodic, EFFECT_0, SPELL_AURA_PERIODIC_DUMMY);
OnEffectApply += AuraEffectApplyFn(spell_ignis_slag_pot_AuraScript::OnApply, EFFECT_0, SPELL_AURA_PERIODIC_DUMMY, AURA_EFFECT_HANDLE_REAL);
AfterEffectRemove += AuraEffectRemoveFn(spell_ignis_slag_pot_AuraScript::OnRemove, EFFECT_0, SPELL_AURA_PERIODIC_DUMMY, AURA_EFFECT_HANDLE_REAL);
}
};
AuraScript* GetAuraScript() const override
void HandleEffectPeriodic(AuraEffect const* /*aurEff*/)
{
return new spell_ignis_slag_pot_AuraScript();
if (Unit* caster = GetCaster())
if (Unit* target = GetTarget())
caster->CastSpell(target, (GetId() == SPELL_SLAG_POT_10 ? SPELL_SLAG_POT_DAMAGE_1 : SPELL_SLAG_POT_DAMAGE_2), true);
}
void OnApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
{
if (Unit* target = GetTarget())
{
target->ApplySpellImmune(GetId(), IMMUNITY_ID, SPELL_SCORCH_DAMAGE_1, true);
target->ApplySpellImmune(GetId(), IMMUNITY_ID, SPELL_SCORCH_DAMAGE_2, true);
}
}
void OnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
{
if (Unit* target = GetTarget())
{
target->ApplySpellImmune(GetId(), IMMUNITY_ID, SPELL_SCORCH_DAMAGE_1, false);
target->ApplySpellImmune(GetId(), IMMUNITY_ID, SPELL_SCORCH_DAMAGE_2, false);
if (target->IsAlive())
target->CastSpell(target, (GetId() == SPELL_SLAG_POT_10 ? SPELL_SLAG_IMBUED_1 : SPELL_SLAG_IMBUED_2), true);
}
}
void Register() override
{
OnEffectPeriodic += AuraEffectPeriodicFn(spell_ignis_slag_pot_aura::HandleEffectPeriodic, EFFECT_0, SPELL_AURA_PERIODIC_DUMMY);
OnEffectApply += AuraEffectApplyFn(spell_ignis_slag_pot_aura::OnApply, EFFECT_0, SPELL_AURA_PERIODIC_DUMMY, AURA_EFFECT_HANDLE_REAL);
AfterEffectRemove += AuraEffectRemoveFn(spell_ignis_slag_pot_aura::OnRemove, EFFECT_0, SPELL_AURA_PERIODIC_DUMMY, AURA_EFFECT_HANDLE_REAL);
}
};
@@ -552,8 +552,8 @@ void AddSC_boss_ignis()
{
new boss_ignis();
new npc_ulduar_iron_construct();
new spell_ignis_scorch();
new spell_ignis_grab_initial();
new spell_ignis_slag_pot();
RegisterSpellScript(spell_ignis_scorch_aura);
RegisterSpellScript(spell_ignis_grab_initial);
RegisterSpellScript(spell_ignis_slag_pot_aura);
new achievement_ignis_shattered();
}

View File

@@ -718,156 +718,107 @@ private:
Unit const* _victim;
};
class spell_ulduar_stone_grip_cast_target : public SpellScriptLoader
class spell_ulduar_stone_grip_cast_target : public SpellScript
{
public:
spell_ulduar_stone_grip_cast_target() : SpellScriptLoader("spell_ulduar_stone_grip_cast_target") { }
PrepareSpellScript(spell_ulduar_stone_grip_cast_target);
class spell_ulduar_stone_grip_cast_target_SpellScript : public SpellScript
bool Load() override
{
PrepareSpellScript(spell_ulduar_stone_grip_cast_target_SpellScript);
if (GetCaster()->GetTypeId() != TYPEID_UNIT)
return false;
return true;
}
bool Load() override
{
if (GetCaster()->GetTypeId() != TYPEID_UNIT)
return false;
return true;
}
void FilterTargetsInitial(std::list<WorldObject*>& targets)
{
// Remove "main tank" and non-player targets
targets.remove_if (StoneGripTargetSelector(GetCaster()->ToCreature(), GetCaster()->GetVictim()));
// Maximum affected targets per difficulty mode
uint32 maxTargets = 1;
if (GetSpellInfo()->Id == 63981)
maxTargets = 3;
// Return a random amount of targets based on maxTargets
while (maxTargets < targets.size())
{
std::list<WorldObject*>::iterator itr = targets.begin();
advance(itr, urand(0, targets.size() - 1));
targets.erase(itr);
}
}
void Register() override
{
OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_ulduar_stone_grip_cast_target_SpellScript::FilterTargetsInitial, EFFECT_ALL, TARGET_UNIT_SRC_AREA_ENEMY);
}
};
SpellScript* GetSpellScript() const override
void FilterTargetsInitial(std::list<WorldObject*>& targets)
{
return new spell_ulduar_stone_grip_cast_target_SpellScript();
// Remove "main tank" and non-player targets
targets.remove_if (StoneGripTargetSelector(GetCaster()->ToCreature(), GetCaster()->GetVictim()));
// Maximum affected targets per difficulty mode
uint32 maxTargets = 1;
if (GetSpellInfo()->Id == 63981)
maxTargets = 3;
// Return a random amount of targets based on maxTargets
while (maxTargets < targets.size())
{
std::list<WorldObject*>::iterator itr = targets.begin();
advance(itr, urand(0, targets.size() - 1));
targets.erase(itr);
}
}
void Register() override
{
OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_ulduar_stone_grip_cast_target::FilterTargetsInitial, EFFECT_ALL, TARGET_UNIT_SRC_AREA_ENEMY);
}
};
class spell_ulduar_stone_grip : public SpellScriptLoader
class spell_ulduar_stone_grip_aura : public AuraScript
{
public:
spell_ulduar_stone_grip() : SpellScriptLoader("spell_ulduar_stone_grip") { }
PrepareAuraScript(spell_ulduar_stone_grip_aura);
class spell_ulduar_stone_grip_AuraScript : public AuraScript
void OnRemoveStun(AuraEffect const* aurEff, AuraEffectHandleModes /*mode*/)
{
PrepareAuraScript(spell_ulduar_stone_grip_AuraScript);
if (Player* owner = GetOwner()->ToPlayer())
owner->RemoveAurasDueToSpell(aurEff->GetAmount());
}
void OnRemoveStun(AuraEffect const* aurEff, AuraEffectHandleModes /*mode*/)
{
if (Player* owner = GetOwner()->ToPlayer())
owner->RemoveAurasDueToSpell(aurEff->GetAmount());
}
void Register() override
{
OnEffectRemove += AuraEffectRemoveFn(spell_ulduar_stone_grip_AuraScript::OnRemoveStun, EFFECT_2, SPELL_AURA_MOD_STUN, AURA_EFFECT_HANDLE_REAL);
}
};
AuraScript* GetAuraScript() const override
void Register() override
{
return new spell_ulduar_stone_grip_AuraScript();
OnEffectRemove += AuraEffectRemoveFn(spell_ulduar_stone_grip_aura::OnRemoveStun, EFFECT_2, SPELL_AURA_MOD_STUN, AURA_EFFECT_HANDLE_REAL);
}
};
class spell_ulduar_squeezed_lifeless : public SpellScriptLoader
class spell_ulduar_squeezed_lifeless : public SpellScript
{
public:
spell_ulduar_squeezed_lifeless() : SpellScriptLoader("spell_ulduar_squeezed_lifeless") { }
PrepareSpellScript(spell_ulduar_squeezed_lifeless);
class spell_ulduar_squeezed_lifeless_SpellScript : public SpellScript
void HandleInstaKill(SpellEffIndex /*effIndex*/)
{
PrepareSpellScript(spell_ulduar_squeezed_lifeless_SpellScript);
if (!GetHitPlayer() || !GetHitPlayer()->GetVehicle())
return;
void HandleInstaKill(SpellEffIndex /*effIndex*/)
{
if (!GetHitPlayer() || !GetHitPlayer()->GetVehicle())
return;
// Hack to set correct position is in _ExitVehicle()
GetHitPlayer()->ExitVehicle();
}
// Hack to set correct position is in _ExitVehicle()
GetHitPlayer()->ExitVehicle();
}
void Register() override
{
OnEffectHitTarget += SpellEffectFn(spell_ulduar_squeezed_lifeless_SpellScript::HandleInstaKill, EFFECT_1, SPELL_EFFECT_INSTAKILL);
}
};
SpellScript* GetSpellScript() const override
void Register() override
{
return new spell_ulduar_squeezed_lifeless_SpellScript();
OnEffectHitTarget += SpellEffectFn(spell_ulduar_squeezed_lifeless::HandleInstaKill, EFFECT_1, SPELL_EFFECT_INSTAKILL);
}
};
class spell_kologarn_stone_shout : public SpellScriptLoader
class spell_kologarn_stone_shout : public SpellScript
{
public:
spell_kologarn_stone_shout() : SpellScriptLoader("spell_kologarn_stone_shout") { }
PrepareSpellScript(spell_kologarn_stone_shout);
class spell_kologarn_stone_shout_AuraScript : public AuraScript
void FilterTargets(std::list<WorldObject*>& targets)
{
PrepareAuraScript(spell_kologarn_stone_shout_AuraScript);
void OnPeriodic(AuraEffect const* /*aurEff*/)
{
uint32 triggerSpellId = GetSpellInfo()->Effects[EFFECT_0].TriggerSpell;
if (Unit* caster = GetCaster())
caster->CastSpell(caster, triggerSpellId, false);
}
void Register() override
{
if (m_scriptSpellId == SPELL_STONE_SHOUT_10 || m_scriptSpellId == SPELL_STONE_SHOUT_25)
OnEffectPeriodic += AuraEffectPeriodicFn(spell_kologarn_stone_shout_AuraScript::OnPeriodic, EFFECT_0, SPELL_AURA_PERIODIC_TRIGGER_SPELL);
}
};
AuraScript* GetAuraScript() const override
{
return new spell_kologarn_stone_shout_AuraScript();
targets.remove_if (PlayerOrPetCheck());
}
class spell_kologarn_stone_shout_SpellScript : public SpellScript
void Register() override
{
PrepareSpellScript(spell_kologarn_stone_shout_SpellScript);
if (m_scriptSpellId != SPELL_STONE_SHOUT_10 && m_scriptSpellId != SPELL_STONE_SHOUT_25)
OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_kologarn_stone_shout::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY);
}
};
void FilterTargets(std::list<WorldObject*>& targets)
{
targets.remove_if (PlayerOrPetCheck());
}
class spell_kologarn_stone_shout_aura : public AuraScript
{
PrepareAuraScript(spell_kologarn_stone_shout_aura);
void Register() override
{
if (m_scriptSpellId != SPELL_STONE_SHOUT_10 && m_scriptSpellId != SPELL_STONE_SHOUT_25)
OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_kologarn_stone_shout_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY);
}
};
SpellScript* GetSpellScript() const override
void OnPeriodic(AuraEffect const* /*aurEff*/)
{
return new spell_kologarn_stone_shout_SpellScript();
uint32 triggerSpellId = GetSpellInfo()->Effects[EFFECT_0].TriggerSpell;
if (Unit* caster = GetCaster())
caster->CastSpell(caster, triggerSpellId, false);
}
void Register() override
{
if (m_scriptSpellId == SPELL_STONE_SHOUT_10 || m_scriptSpellId == SPELL_STONE_SHOUT_25)
OnEffectPeriodic += AuraEffectPeriodicFn(spell_kologarn_stone_shout_aura::OnPeriodic, EFFECT_0, SPELL_AURA_PERIODIC_TRIGGER_SPELL);
}
};
@@ -928,10 +879,10 @@ void AddSC_boss_kologarn()
RegisterUlduarCreatureAI(boss_kologarn_pit_kill_bunny);
// Spells
new spell_ulduar_stone_grip_cast_target();
new spell_ulduar_stone_grip();
new spell_ulduar_squeezed_lifeless();
new spell_kologarn_stone_shout();
RegisterSpellScript(spell_ulduar_stone_grip_cast_target);
RegisterSpellScript(spell_ulduar_stone_grip_aura);
RegisterSpellScript(spell_ulduar_squeezed_lifeless);
RegisterSpellAndAuraScriptPair(spell_kologarn_stone_shout, spell_kologarn_stone_shout_aura);
// Achievements
new achievement_kologarn_looks_could_kill();

View File

@@ -2104,87 +2104,83 @@ public:
};
};
class spell_mimiron_rapid_burst : public SpellScriptLoader
class spell_mimiron_rapid_burst_aura : public AuraScript
{
public:
spell_mimiron_rapid_burst() : SpellScriptLoader("spell_mimiron_rapid_burst") { }
PrepareAuraScript(spell_mimiron_rapid_burst_aura);
class spell_mimiron_rapid_burst_AuraScript : public AuraScript
bool Validate(SpellInfo const* /*spellInfo*/) override
{
PrepareAuraScript(spell_mimiron_rapid_burst_AuraScript)
void HandleEffectPeriodic(AuraEffect const* aurEff)
{
if (Unit* c = GetCaster())
return ValidateSpellInfo(
{
uint32 id = ( c->GetMap()->Is25ManRaid() ? ((aurEff->GetTickNumber() % 2) ? SPELL_RAPID_BURST_DAMAGE_25_2 : SPELL_RAPID_BURST_DAMAGE_25_1) : ((aurEff->GetTickNumber() % 2) ? SPELL_RAPID_BURST_DAMAGE_10_2 : SPELL_RAPID_BURST_DAMAGE_10_1) );
c->CastSpell((Unit*)nullptr, id, true);
}
}
SPELL_RAPID_BURST_DAMAGE_10_1,
SPELL_RAPID_BURST_DAMAGE_10_2,
SPELL_RAPID_BURST_DAMAGE_25_1,
SPELL_RAPID_BURST_DAMAGE_25_2
});
}
void Register() override
{
OnEffectPeriodic += AuraEffectPeriodicFn(spell_mimiron_rapid_burst_AuraScript::HandleEffectPeriodic, EFFECT_1, SPELL_AURA_PERIODIC_DUMMY);
}
};
AuraScript* GetAuraScript() const override
void HandleEffectPeriodic(AuraEffect const* aurEff)
{
return new spell_mimiron_rapid_burst_AuraScript();
if (Unit* caster = GetCaster())
{
uint32 id = (caster->GetMap()->Is25ManRaid() ? ((aurEff->GetTickNumber() % 2) ? SPELL_RAPID_BURST_DAMAGE_25_2 : SPELL_RAPID_BURST_DAMAGE_25_1) : ((aurEff->GetTickNumber() % 2) ? SPELL_RAPID_BURST_DAMAGE_10_2 : SPELL_RAPID_BURST_DAMAGE_10_1));
caster->CastSpell((Unit*)nullptr, id, true);
}
}
void Register() override
{
OnEffectPeriodic += AuraEffectPeriodicFn(spell_mimiron_rapid_burst_aura::HandleEffectPeriodic, EFFECT_1, SPELL_AURA_PERIODIC_DUMMY);
}
};
class spell_mimiron_p3wx2_laser_barrage : public SpellScriptLoader
enum p3wx2LaserBarrage
{
public:
spell_mimiron_p3wx2_laser_barrage() : SpellScriptLoader("spell_mimiron_p3wx2_laser_barrage") { }
SPELL_P3WX2_LASER_BARRAGE_1 = 63297,
SPELL_P3WX2_LASER_BARRAGE_2 = 64042
};
class spell_mimiron_p3wx2_laser_barrage_AuraScript : public AuraScript
class spell_mimiron_p3wx2_laser_barrage_aura : public AuraScript
{
PrepareAuraScript(spell_mimiron_p3wx2_laser_barrage_aura);
bool Load() override
{
PrepareAuraScript(spell_mimiron_p3wx2_laser_barrage_AuraScript)
uint32 lastMSTime;
float lastOrientation;
bool Load() override
{
lastMSTime = GameTime::GetGameTimeMS().count();
lastOrientation = -1.0f;
return true;
}
void HandleEffectPeriodic(AuraEffect const* /*aurEff*/)
{
if (Unit* c = GetCaster())
{
if (c->GetTypeId() != TYPEID_UNIT)
return;
uint32 diff = getMSTimeDiff(lastMSTime, GameTime::GetGameTimeMS().count());
if (lastOrientation == -1.0f)
{
lastOrientation = (c->ToCreature()->AI()->GetData(0) * 2 * M_PI) / 100.0f;
diff = 0;
}
float new_o = Position::NormalizeOrientation(lastOrientation - (M_PI / 60) * (diff / 250.0f));
lastMSTime = GameTime::GetGameTimeMS().count();
lastOrientation = new_o;
c->SetFacingTo(new_o);
c->CastSpell((Unit*)nullptr, 63297, true);
c->CastSpell((Unit*)nullptr, 64042, true);
}
}
void Register() override
{
OnEffectPeriodic += AuraEffectPeriodicFn(spell_mimiron_p3wx2_laser_barrage_AuraScript::HandleEffectPeriodic, EFFECT_1, SPELL_AURA_PERIODIC_TRIGGER_SPELL);
}
};
AuraScript* GetAuraScript() const override
{
return new spell_mimiron_p3wx2_laser_barrage_AuraScript();
_lastMSTime = GameTime::GetGameTimeMS().count();
_lastOrientation = -1.0f;
return true;
}
void HandleEffectPeriodic(AuraEffect const* /*aurEff*/)
{
if (Unit* caster = GetCaster())
{
if (caster->GetTypeId() != TYPEID_UNIT)
return;
uint32 diff = getMSTimeDiff(_lastMSTime, GameTime::GetGameTimeMS().count());
if (_lastOrientation == -1.0f)
{
_lastOrientation = (caster->ToCreature()->AI()->GetData(0) * 2 * M_PI) / 100.0f;
diff = 0;
}
float new_o = Position::NormalizeOrientation(_lastOrientation - (M_PI / 60) * (diff / 250.0f));
_lastMSTime = GameTime::GetGameTimeMS().count();
_lastOrientation = new_o;
caster->SetFacingTo(new_o);
caster->CastSpell((Unit*)nullptr, SPELL_P3WX2_LASER_BARRAGE_1, true);
caster->CastSpell((Unit*)nullptr, SPELL_P3WX2_LASER_BARRAGE_2, true);
}
}
void Register() override
{
OnEffectPeriodic += AuraEffectPeriodicFn(spell_mimiron_p3wx2_laser_barrage_aura::HandleEffectPeriodic, EFFECT_1, SPELL_AURA_PERIODIC_TRIGGER_SPELL);
}
private:
uint32 _lastMSTime;
float _lastOrientation;
};
class go_ulduar_do_not_push_this_button : public GameObjectScript
@@ -2518,8 +2514,8 @@ void AddSC_boss_mimiron()
new npc_ulduar_mimiron_rocket();
new npc_ulduar_magnetic_core();
new npc_ulduar_bot_summon_trigger();
new spell_mimiron_rapid_burst();
new spell_mimiron_p3wx2_laser_barrage();
RegisterSpellScript(spell_mimiron_rapid_burst_aura);
RegisterSpellScript(spell_mimiron_p3wx2_laser_barrage_aura);
new go_ulduar_do_not_push_this_button();
new npc_ulduar_flames_initial();
new npc_ulduar_flames_spread();

View File

@@ -1729,59 +1729,37 @@ public:
}
};
class spell_thorim_lightning_pillar_P2 : public SpellScriptLoader
class spell_thorim_lightning_pillar_P2_aura : public AuraScript
{
public:
spell_thorim_lightning_pillar_P2() : SpellScriptLoader("spell_thorim_lightning_pillar_P2") { }
PrepareAuraScript(spell_thorim_lightning_pillar_P2_aura);
class spell_thorim_lightning_pillar_P2_AuraScript : public AuraScript
void OnPeriodic(AuraEffect const* aurEff)
{
PrepareAuraScript(spell_thorim_lightning_pillar_P2_AuraScript);
PreventDefaultAction();
if (Unit* caster = GetCaster())
GetUnitOwner()->CastSpell(caster, GetSpellInfo()->Effects[aurEff->GetEffIndex()].TriggerSpell, true);
}
void OnPeriodic(AuraEffect const* aurEff)
{
PreventDefaultAction();
if (Unit* caster = GetCaster())
GetUnitOwner()->CastSpell(caster, GetSpellInfo()->Effects[aurEff->GetEffIndex()].TriggerSpell, true);
}
void Register() override
{
OnEffectPeriodic += AuraEffectPeriodicFn(spell_thorim_lightning_pillar_P2_AuraScript::OnPeriodic, EFFECT_0, SPELL_AURA_PERIODIC_TRIGGER_SPELL);
}
};
AuraScript* GetAuraScript() const override
void Register() override
{
return new spell_thorim_lightning_pillar_P2_AuraScript();
OnEffectPeriodic += AuraEffectPeriodicFn(spell_thorim_lightning_pillar_P2_aura::OnPeriodic, EFFECT_0, SPELL_AURA_PERIODIC_TRIGGER_SPELL);
}
};
class spell_thorim_trash_impale : public SpellScriptLoader
class spell_thorim_trash_impale_aura : public AuraScript
{
public:
spell_thorim_trash_impale() : SpellScriptLoader("spell_thorim_trash_impale") { }
PrepareAuraScript(spell_thorim_trash_impale_aura);
class spell_thorim_trash_impale_AuraScript : public AuraScript
void OnPeriodic(AuraEffect const* /*aurEff*/)
{
PrepareAuraScript(spell_thorim_trash_impale_AuraScript);
// deals damage until target is healed above 90%
if (GetUnitOwner()->HealthAbovePct(90))
SetDuration(0);
}
void OnPeriodic(AuraEffect const* /*aurEff*/)
{
// deals damage until target is healed above 90%
if (GetUnitOwner()->HealthAbovePct(90))
SetDuration(0);
}
void Register() override
{
OnEffectPeriodic += AuraEffectPeriodicFn(spell_thorim_trash_impale_AuraScript::OnPeriodic, EFFECT_0, SPELL_AURA_PERIODIC_DAMAGE);
}
};
AuraScript* GetAuraScript() const override
void Register() override
{
return new spell_thorim_trash_impale_AuraScript();
OnEffectPeriodic += AuraEffectPeriodicFn(spell_thorim_trash_impale_aura::OnPeriodic, EFFECT_0, SPELL_AURA_PERIODIC_DAMAGE);
}
};
@@ -1838,8 +1816,8 @@ void AddSC_boss_thorim()
new go_thorim_lever();
// Spells
new spell_thorim_lightning_pillar_P2();
new spell_thorim_trash_impale();
RegisterSpellScript(spell_thorim_lightning_pillar_P2_aura);
RegisterSpellScript(spell_thorim_trash_impale_aura);
// Achievements
new achievement_thorim_stand_in_the_lightning();

View File

@@ -857,191 +857,147 @@ public:
};
// 62775 - Tympanic Tantrum
class spell_xt002_tympanic_tantrum : public SpellScriptLoader
class spell_xt002_tympanic_tantrum : public SpellScript
{
public:
spell_xt002_tympanic_tantrum() : SpellScriptLoader("spell_xt002_tympanic_tantrum") { }
PrepareSpellScript(spell_xt002_tympanic_tantrum);
class spell_xt002_tympanic_tantrum_SpellScript : public SpellScript
void FilterTargets(std::list<WorldObject*>& targets)
{
PrepareSpellScript(spell_xt002_tympanic_tantrum_SpellScript);
targets.remove_if(PlayerOrPetCheck());
}
void FilterTargets(std::list<WorldObject*>& targets)
{
targets.remove_if(PlayerOrPetCheck());
}
void RecalculateDamage()
{
if (GetHitUnit())
SetHitDamage(GetHitUnit()->CountPctFromMaxHealth(GetHitDamage()));
}
void Register() override
{
OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_xt002_tympanic_tantrum_SpellScript::FilterTargets, EFFECT_ALL, TARGET_UNIT_SRC_AREA_ENEMY);
OnHit += SpellHitFn(spell_xt002_tympanic_tantrum_SpellScript::RecalculateDamage);
}
};
SpellScript* GetSpellScript() const override
void RecalculateDamage()
{
return new spell_xt002_tympanic_tantrum_SpellScript();
if (GetHitUnit())
SetHitDamage(GetHitUnit()->CountPctFromMaxHealth(GetHitDamage()));
}
void Register() override
{
OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_xt002_tympanic_tantrum::FilterTargets, EFFECT_ALL, TARGET_UNIT_SRC_AREA_ENEMY);
OnHit += SpellHitFn(spell_xt002_tympanic_tantrum::RecalculateDamage);
}
};
// 64234, 63024 - Gravity Bomb
class spell_xt002_gravity_bomb_aura : public SpellScriptLoader
enum GravityBomb
{
public:
spell_xt002_gravity_bomb_aura() : SpellScriptLoader("spell_xt002_gravity_bomb_aura") { }
SPELL_GRAVTY_BOMB_10 = 63025
};
class spell_xt002_gravity_bomb_aura_AuraScript : public AuraScript
class spell_xt002_gravity_bomb : public SpellScript
{
PrepareSpellScript(spell_xt002_gravity_bomb);
void SelectTarget(std::list<WorldObject*>& targets)
{
PrepareAuraScript(spell_xt002_gravity_bomb_aura_AuraScript);
void OnRemove(AuraEffect const* aurEff, AuraEffectHandleModes /*mode*/)
{
if (Player* player = GetOwner()->ToPlayer())
if (Unit* xt002 = GetCaster())
if (xt002->HasAura(aurEff->GetAmount())) // Heartbreak aura indicating hard mode
if (Creature* cr = xt002->SummonCreature(NPC_VOID_ZONE, player->GetPositionX(), player->GetPositionY(), player->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN, 180000))
{
int32 damage = GetSpellInfo()->Id == 63025 ? 5000 : 7500;
cr->CastCustomSpell(cr, SPELL_VOID_ZONE_DAMAGE, &damage, 0, 0, true);
}
}
void OnPeriodic(AuraEffect const* aurEff)
{
Unit* xt002 = GetCaster();
if (!xt002)
return;
Unit* owner = GetOwner()->ToUnit();
if (!owner)
return;
if (aurEff->GetAmount() >= int32(owner->GetHealth()))
if (xt002->GetAI())
xt002->GetAI()->DoAction(DATA_XT002_GRAVITY_ACHIEV);
}
void Register() override
{
OnEffectPeriodic += AuraEffectPeriodicFn(spell_xt002_gravity_bomb_aura_AuraScript::OnPeriodic, EFFECT_2, SPELL_AURA_PERIODIC_DAMAGE);
AfterEffectRemove += AuraEffectRemoveFn(spell_xt002_gravity_bomb_aura_AuraScript::OnRemove, EFFECT_0, SPELL_AURA_PERIODIC_TRIGGER_SPELL, AURA_EFFECT_HANDLE_REAL);
}
};
AuraScript* GetAuraScript() const override
{
return new spell_xt002_gravity_bomb_aura_AuraScript();
if (Unit* victim = GetCaster()->GetVictim())
targets.remove_if(Acore::ObjectGUIDCheck(victim->GetGUID(), true));
}
class spell_xt002_gravity_bomb_aura_SpellScript : public SpellScript
void Register() override
{
PrepareSpellScript(spell_xt002_gravity_bomb_aura_SpellScript);
OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_xt002_gravity_bomb::SelectTarget, EFFECT_ALL, TARGET_UNIT_DEST_AREA_ENEMY);
}
};
void SelectTarget(std::list<WorldObject*>& targets)
{
if (Unit* victim = GetCaster()->GetVictim())
targets.remove_if(Acore::ObjectGUIDCheck(victim->GetGUID(), true));
}
class spell_xt002_gravity_bomb_aura : public AuraScript
{
PrepareAuraScript(spell_xt002_gravity_bomb_aura);
void Register() override
{
OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_xt002_gravity_bomb_aura_SpellScript::SelectTarget, EFFECT_ALL, TARGET_UNIT_DEST_AREA_ENEMY);
}
};
SpellScript* GetSpellScript() const override
bool Validate(SpellInfo const* /*spellInfo*/) override
{
return new spell_xt002_gravity_bomb_aura_SpellScript();
return ValidateSpellInfo({ SPELL_VOID_ZONE_DAMAGE });
}
void OnRemove(AuraEffect const* aurEff, AuraEffectHandleModes /*mode*/)
{
if (Player* player = GetOwner()->ToPlayer())
if (Unit* xt002 = GetCaster())
if (xt002->HasAura(aurEff->GetAmount())) // Heartbreak aura indicating hard mode
if (Creature* creature = xt002->SummonCreature(NPC_VOID_ZONE, player->GetPositionX(), player->GetPositionY(), player->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN, 180000))
{
int32 damage = GetSpellInfo()->Id == SPELL_GRAVTY_BOMB_10 ? 5000 : 7500;
creature->CastCustomSpell(creature, SPELL_VOID_ZONE_DAMAGE, &damage, 0, 0, true);
}
}
void OnPeriodic(AuraEffect const* aurEff)
{
Unit* xt002 = GetCaster();
if (!xt002)
return;
Unit* owner = GetOwner()->ToUnit();
if (!owner)
return;
if (aurEff->GetAmount() >= int32(owner->GetHealth()))
if (xt002->GetAI())
xt002->GetAI()->DoAction(DATA_XT002_GRAVITY_ACHIEV);
}
void Register() override
{
OnEffectPeriodic += AuraEffectPeriodicFn(spell_xt002_gravity_bomb_aura::OnPeriodic, EFFECT_2, SPELL_AURA_PERIODIC_DAMAGE);
AfterEffectRemove += AuraEffectRemoveFn(spell_xt002_gravity_bomb_aura::OnRemove, EFFECT_0, SPELL_AURA_PERIODIC_TRIGGER_SPELL, AURA_EFFECT_HANDLE_REAL);
}
};
// 64233, 63025 - Gravity Bomb
class spell_xt002_gravity_bomb_damage : public SpellScriptLoader
class spell_xt002_gravity_bomb_damage : public SpellScript
{
public:
spell_xt002_gravity_bomb_damage() : SpellScriptLoader("spell_xt002_gravity_bomb_damage") { }
PrepareSpellScript(spell_xt002_gravity_bomb_damage);
class spell_xt002_gravity_bomb_damage_SpellScript : public SpellScript
void HandleScript(SpellEffIndex /*eff*/)
{
PrepareSpellScript(spell_xt002_gravity_bomb_damage_SpellScript);
Unit* caster = GetCaster();
if (!caster)
return;
void HandleScript(SpellEffIndex /*eff*/)
{
Unit* caster = GetCaster();
if (!caster)
return;
if (GetHitDamage() >= int32(GetHitUnit()->GetHealth()))
if (caster->GetAI())
caster->GetAI()->DoAction(DATA_XT002_GRAVITY_ACHIEV);
}
if (GetHitDamage() >= int32(GetHitUnit()->GetHealth()))
if (caster->GetAI())
caster->GetAI()->DoAction(DATA_XT002_GRAVITY_ACHIEV);
}
void Register() override
{
OnEffectHitTarget += SpellEffectFn(spell_xt002_gravity_bomb_damage_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_SCHOOL_DAMAGE);
}
};
SpellScript* GetSpellScript() const override
void Register() override
{
return new spell_xt002_gravity_bomb_damage_SpellScript();
OnEffectHitTarget += SpellEffectFn(spell_xt002_gravity_bomb_damage::HandleScript, EFFECT_0, SPELL_EFFECT_SCHOOL_DAMAGE);
}
};
// 63018, 65121 - Searing Light
class spell_xt002_searing_light_spawn_life_spark : public SpellScriptLoader
class spell_xt002_searing_light_spawn_life_spark : public SpellScript
{
public:
spell_xt002_searing_light_spawn_life_spark() : SpellScriptLoader("spell_xt002_searing_light_spawn_life_spark") { }
PrepareSpellScript(spell_xt002_searing_light_spawn_life_spark);
class spell_xt002_searing_light_spawn_life_spark_AuraScript : public AuraScript
void SelectTarget(std::list<WorldObject*>& targets)
{
PrepareAuraScript(spell_xt002_searing_light_spawn_life_spark_AuraScript);
void OnRemove(AuraEffect const* aurEff, AuraEffectHandleModes /*mode*/)
{
if (Player* player = GetOwner()->ToPlayer())
if (Unit* xt002 = GetCaster())
if (xt002->HasAura(aurEff->GetAmount())) // Heartbreak aura indicating hard mode
xt002->SummonCreature(NPC_LIFE_SPARK, player->GetPositionX(), player->GetPositionY(), player->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN, 180000);
}
void Register() override
{
OnEffectRemove += AuraEffectRemoveFn(spell_xt002_searing_light_spawn_life_spark_AuraScript::OnRemove, EFFECT_0, SPELL_AURA_PERIODIC_TRIGGER_SPELL, AURA_EFFECT_HANDLE_REAL);
}
};
AuraScript* GetAuraScript() const override
{
return new spell_xt002_searing_light_spawn_life_spark_AuraScript();
if (Unit* victim = GetCaster()->GetVictim())
targets.remove_if(Acore::ObjectGUIDCheck(victim->GetGUID(), true));
}
class spell_xt002_searing_light_spawn_life_spark_SpellScript : public SpellScript
void Register() override
{
PrepareSpellScript(spell_xt002_searing_light_spawn_life_spark_SpellScript);
OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_xt002_searing_light_spawn_life_spark::SelectTarget, EFFECT_ALL, TARGET_UNIT_DEST_AREA_ENEMY);
}
};
void SelectTarget(std::list<WorldObject*>& targets)
{
if (Unit* victim = GetCaster()->GetVictim())
targets.remove_if(Acore::ObjectGUIDCheck(victim->GetGUID(), true));
}
class spell_xt002_searing_light_spawn_life_spark_aura : public AuraScript
{
PrepareAuraScript(spell_xt002_searing_light_spawn_life_spark_aura);
void Register() override
{
OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_xt002_searing_light_spawn_life_spark_SpellScript::SelectTarget, EFFECT_ALL, TARGET_UNIT_DEST_AREA_ENEMY);
}
};
SpellScript* GetSpellScript() const override
void OnRemove(AuraEffect const* aurEff, AuraEffectHandleModes /*mode*/)
{
return new spell_xt002_searing_light_spawn_life_spark_SpellScript();
if (Player* player = GetOwner()->ToPlayer())
if (Unit* xt002 = GetCaster())
if (xt002->HasAura(aurEff->GetAmount())) // Heartbreak aura indicating hard mode
xt002->SummonCreature(NPC_LIFE_SPARK, player->GetPositionX(), player->GetPositionY(), player->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN, 180000);
}
void Register() override
{
OnEffectRemove += AuraEffectRemoveFn(spell_xt002_searing_light_spawn_life_spark_aura::OnRemove, EFFECT_0, SPELL_AURA_PERIODIC_TRIGGER_SPELL, AURA_EFFECT_HANDLE_REAL);
}
};
@@ -1088,10 +1044,10 @@ void AddSC_boss_xt002()
new npc_xt002_life_spark();
// Spells
new spell_xt002_tympanic_tantrum();
new spell_xt002_gravity_bomb_aura();
new spell_xt002_gravity_bomb_damage();
new spell_xt002_searing_light_spawn_life_spark();
RegisterSpellScript(spell_xt002_tympanic_tantrum);
RegisterSpellAndAuraScriptPair(spell_xt002_gravity_bomb, spell_xt002_gravity_bomb_aura);
RegisterSpellScript(spell_xt002_gravity_bomb_damage);
RegisterSpellAndAuraScriptPair(spell_xt002_searing_light_spawn_life_spark, spell_xt002_searing_light_spawn_life_spark_aura);
// Achievements
new achievement_xt002_nerf_engineering();

File diff suppressed because it is too large Load Diff

View File

@@ -79,7 +79,8 @@ enum UldSpells
{
SPELL_SIMPLE_TELEPORT = 12980,
SPELL_KEEPER_TELEPORT = 62940,
SPELL_SNOW_MOUND_PARTICLES = 64615
SPELL_SNOW_MOUND_PARTICLES = 64615,
SPELL_ENERGY_SAP_10 = 64740
};
class npc_ulduar_keeper : public CreatureScript
@@ -201,30 +202,30 @@ public:
}
};
class spell_ulduar_energy_sap : public SpellScriptLoader
enum EnergySap
{
public:
spell_ulduar_energy_sap() : SpellScriptLoader("spell_ulduar_energy_sap") { }
SPELL_ENERGY_SAP_DAMAGE_1 = 64747,
SPELL_ENERGY_SAP_DAMAGE_2 = 64863,
};
class spell_ulduar_energy_sap_AuraScript : public AuraScript
class spell_ulduar_energy_sap_aura : public AuraScript
{
PrepareAuraScript(spell_ulduar_energy_sap_aura);
bool Validate(SpellInfo const* /*spellInfo*/) override
{
PrepareAuraScript(spell_ulduar_energy_sap_AuraScript)
return ValidateSpellInfo({ SPELL_ENERGY_SAP_DAMAGE_1, SPELL_ENERGY_SAP_DAMAGE_2 });
}
void HandleEffectPeriodic(AuraEffect const* aurEff)
{
if (Unit* target = GetTarget())
target->CastSpell(target, (aurEff->GetId() == 64740) ? 64747 : 64863, true);
}
void Register() override
{
OnEffectPeriodic += AuraEffectPeriodicFn(spell_ulduar_energy_sap_AuraScript::HandleEffectPeriodic, EFFECT_0, SPELL_AURA_PERIODIC_DAMAGE);
}
};
AuraScript* GetAuraScript() const override
void HandleEffectPeriodic(AuraEffect const* aurEff)
{
return new spell_ulduar_energy_sap_AuraScript();
if (Unit* target = GetTarget())
target->CastSpell(target, (aurEff->GetId() == SPELL_ENERGY_SAP_10) ? SPELL_ENERGY_SAP_DAMAGE_1 : SPELL_ENERGY_SAP_DAMAGE_2, true);
}
void Register() override
{
OnEffectPeriodic += AuraEffectPeriodicFn(spell_ulduar_energy_sap_aura::HandleEffectPeriodic, EFFECT_0, SPELL_AURA_PERIODIC_DAMAGE);
}
};
@@ -500,30 +501,19 @@ public:
};
};
class spell_ulduar_arachnopod_damaged : public SpellScriptLoader
class spell_ulduar_arachnopod_damaged_aura : public AuraScript
{
public:
spell_ulduar_arachnopod_damaged() : SpellScriptLoader("spell_ulduar_arachnopod_damaged") { }
PrepareAuraScript(spell_ulduar_arachnopod_damaged_aura);
class spell_ulduar_arachnopod_damaged_AuraScript : public AuraScript
void HandleEffectPeriodic(AuraEffect const* /*aurEff*/)
{
PrepareAuraScript(spell_ulduar_arachnopod_damaged_AuraScript)
if (Unit* caster = GetCaster())
Unit::Kill(caster, caster, false);
}
void HandleEffectPeriodic(AuraEffect const* /*aurEff*/)
{
if (Unit* c = GetCaster())
Unit::Kill(c, c, false);
}
void Register() override
{
OnEffectPeriodic += AuraEffectPeriodicFn(spell_ulduar_arachnopod_damaged_AuraScript::HandleEffectPeriodic, EFFECT_0, SPELL_AURA_PERIODIC_TRIGGER_SPELL);
}
};
AuraScript* GetAuraScript() const override
void Register() override
{
return new spell_ulduar_arachnopod_damaged_AuraScript();
OnEffectPeriodic += AuraEffectPeriodicFn(spell_ulduar_arachnopod_damaged_aura::HandleEffectPeriodic, EFFECT_0, SPELL_AURA_PERIODIC_TRIGGER_SPELL);
}
};
@@ -576,11 +566,11 @@ struct npc_salvaged_siege_engine : public VehicleAI
void AddSC_ulduar()
{
new npc_ulduar_keeper();
new spell_ulduar_energy_sap();
RegisterSpellScript(spell_ulduar_energy_sap_aura);
RegisterUlduarCreatureAI(npc_ulduar_snow_mound);
new npc_ulduar_storm_tempered_keeper();
new npc_ulduar_arachnopod_destroyer();
new spell_ulduar_arachnopod_damaged();
RegisterSpellScript(spell_ulduar_arachnopod_damaged_aura);
new AreaTrigger_at_celestial_planetarium_enterance();
RegisterCreatureAI(npc_salvaged_siege_engine);
}

View File

@@ -213,6 +213,7 @@ struct npc_akama_shade : public ScriptedAI
me->SetNpcFlag(UNIT_NPC_FLAG_GOSSIP);
DoCastSelf(SPELL_STEALTH, true);
me->SetWalk(true);
_sayLowHealth = false;
scheduler.CancelAll();
}
@@ -261,6 +262,15 @@ struct npc_akama_shade : public ScriptedAI
}
}
void DamageTaken(Unit* /*unit*/, uint32& damage, DamageEffectType, SpellSchoolMask) override
{
if (me->HealthBelowPctDamaged(20, damage) && !_sayLowHealth)
{
_sayLowHealth = true;
Talk(SAY_LOW_HEALTH);
}
}
void DoAction(int32 param) override
{
if (param == ACTION_AKAMA_START_OUTRO)
@@ -284,6 +294,7 @@ struct npc_akama_shade : public ScriptedAI
void JustDied(Unit* /*killer*/) override
{
Talk(SAY_DEATH);
if (Creature* shade = instance->GetCreature(DATA_SHADE_OF_AKAMA))
{
shade->SetHomePosition(shade->GetHomePosition());
@@ -318,6 +329,9 @@ struct npc_akama_shade : public ScriptedAI
scheduler.Update(diff);
DoMeleeAttackIfReady();
}
private:
bool _sayLowHealth;
};
struct npc_creature_generator_akama : public ScriptedAI

View File

@@ -43,14 +43,20 @@ enum Spells
enum Events
{
EVENT_SPELL_BERSERK = 1,
EVENT_TALK_CHECK = 2
EVENT_TALK_CHECK = 1,
EVENT_ENRAGE = 2
};
struct boss_najentus : public BossAI
{
boss_najentus(Creature* creature) : BossAI(creature, DATA_HIGH_WARLORD_NAJENTUS), _canTalk(true) { }
void Reset() override
{
_Reset();
me->m_Events.CancelEventGroup(EVENT_ENRAGE);
}
void JustEngagedWith(Unit* who) override
{
_canTalk = true;
@@ -58,11 +64,10 @@ struct boss_najentus : public BossAI
BossAI::JustEngagedWith(who);
Talk(SAY_AGGRO);
ScheduleUniqueTimedEvent(8min, [&]
{
me->m_Events.AddEventAtOffset([this] {
Talk(SAY_ENRAGE);
DoCastSelf(SPELL_BERSERK, true);
}, EVENT_SPELL_BERSERK);
}, 8min, EVENT_ENRAGE);
ScheduleTimedEvent(25s, 100s, [&]
{

View File

@@ -253,16 +253,8 @@ public:
void HandleScriptEffect(SpellEffIndex effIndex)
{
PreventHitDefaultEffect(effIndex);
Unit* target = GetHitUnit();
if (!target)
return;
target->RemoveAurasDueToSpell(SPELL_AURA_MOD_CHARM);
target->RemoveAurasDueToSpell(SPELL_AURA_MOD_STUN);
target->RemoveAurasDueToSpell(SPELL_AURA_MOD_DECREASE_SPEED);
target->RemoveAurasDueToSpell(SPELL_AURA_MOD_ROOT);
target->RemoveAurasDueToSpell(SPELL_AURA_MOD_CONFUSE);
target->RemoveAurasDueToSpell(SPELL_AURA_MOD_FEAR);
if (Unit* target = GetHitUnit())
target->RemoveAurasWithMechanic(IMMUNE_TO_MOVEMENT_IMPAIRMENT_AND_LOSS_CONTROL_MASK);
}
void Register() override

View File

@@ -201,7 +201,7 @@ class spell_serpentshrine_cavern_serpentshrine_parasite : public AuraScript
void HandleEffectRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
{
if (GetTarget()->GetInstanceScript() && GetTarget()->GetInstanceScript()->IsEncounterInProgress())
if (GetTarget()->GetInstanceScript())
GetTarget()->CastSpell(GetTarget(), SPELL_SUMMON_SERPENTSHRINE_PARASITE, true);
}

View File

@@ -30,8 +30,18 @@
ObjectData const creatureData[] =
{
{ NPC_QUAGMIRRAN, DATA_QUAGMIRRAN },
{ 0, 0 }
{ NPC_QUAGMIRRAN, DATA_QUAGMIRRAN },
{ NPC_AHUNE, DATA_AHUNE },
{ NPC_AHUNE_LOC_BUNNY, DATA_AHUNE_BUNNY },
{ NPC_FROZEN_CORE, DATA_FROZEN_CORE },
{ NPC_SHAMAN_BONFIRE_BUNNY_000, DATA_BONFIRE_BUNNY_000 },
{ NPC_SHAMAN_BONFIRE_BUNNY_001, DATA_BONFIRE_BUNNY_001 },
{ NPC_SHAMAN_BONFIRE_BUNNY_002, DATA_BONFIRE_BUNNY_002 },
{ NPC_SHAMAN_BEAM_BUNNY_000, DATA_BEAM_BUNNY_000 },
{ NPC_SHAMAN_BEAM_BUNNY_001, DATA_BEAM_BUNNY_001 },
{ NPC_SHAMAN_BEAM_BUNNY_002, DATA_BEAM_BUNNY_002 },
{ NPC_LUMA_SKYMOTHER, DATA_LUMA_SKYMOTHER },
{ 0, 0 }
};
class instance_the_slave_pens : public InstanceMapScript

View File

@@ -114,6 +114,12 @@ private:
bool _hasFlag;
};
enum FlagOfOwnership
{
TEXT_FLAG_OF_OWNERSHIP = 28008,
SPELL_TAUNT_FLAG = 52605
};
// 51640 - Taunt Flag Targeting
class spell_the_flag_of_ownership : public SpellScript
{
@@ -126,7 +132,7 @@ class spell_the_flag_of_ownership : public SpellScript
return true;
}
void HandleScript(SpellEffIndex /*effIndex*/)
void HandleScript(SpellEffIndex /*effIndex*/)
{
Unit* caster = GetCaster();
if (!caster || caster->GetTypeId() != TYPEID_PLAYER)
@@ -134,10 +140,13 @@ class spell_the_flag_of_ownership : public SpellScript
Player* target = GetHitPlayer();
if (!target)
return;
caster->CastSpell(target, 52605, true);
char buff[100];
snprintf(buff, sizeof(buff), "%s plants the Flag of Ownership in the corpse of %s.", caster->GetName().c_str(), target->GetName().c_str());
caster->TextEmote(buff, caster);
caster->CastSpell(target, SPELL_TAUNT_FLAG, true);
LocaleConstant loc_idx = caster->ToPlayer()->GetSession()->GetSessionDbLocaleIndex();
BroadcastText const* bct = sObjectMgr->GetBroadcastText(TEXT_FLAG_OF_OWNERSHIP);
std::string bctMsg = Acore::StringFormat(bct->GetText(loc_idx, caster->getGender()), caster->GetName().c_str(), target->GetName().c_str());
caster->Talk(bctMsg, CHAT_MSG_MONSTER_EMOTE, LANG_UNIVERSAL, sWorld->getFloatConfig(CONFIG_LISTEN_RANGE_TEXTEMOTE), target);
haveTarget = true;
}

View File

@@ -90,7 +90,12 @@ enum PaladinSpells
// Crystalforge Raiment - Tier 5 Holy 2 Set
SPELL_IMPROVED_JUDGEMENT = 37188,
SPELL_IMPROVED_JUDGEMENT_ENERGIZE = 43838
SPELL_IMPROVED_JUDGEMENT_ENERGIZE = 43838,
SPELL_PALADIN_HOLY_VENGEANCE = 31803,
SPELL_PALADIN_BLOOD_CORRUPTION = 53742,
SPELL_PALADIN_SEAL_OF_VENGEANCE_EFFECT = 42463,
SPELL_PALADIN_SEAL_OF_CORRUPTION_EFFECT = 53739
};
enum PaladinSpellIcons
@@ -1105,6 +1110,45 @@ class spell_pal_seal_of_righteousness : public AuraScript
}
};
// 42463 - Seal of Vengeance
// 53739 - Seal of Corruption
class spell_pal_seal_of_vengeance : public SpellScript
{
PrepareSpellScript(spell_pal_seal_of_vengeance);
bool Validate(SpellInfo const* /*spellInfo*/) override
{
return ValidateSpellInfo({ SPELL_PALADIN_SEAL_OF_VENGEANCE_EFFECT, SPELL_PALADIN_SEAL_OF_CORRUPTION_EFFECT });
}
void HandleScriptEffect(SpellEffIndex /*effIndex*/)
{
Unit* target = GetExplTargetUnit();
uint32 spellId = GetSpell()->GetSpellInfo()->Id;
uint32 auraId = (spellId == SPELL_PALADIN_SEAL_OF_VENGEANCE_EFFECT)
? SPELL_PALADIN_HOLY_VENGEANCE
: SPELL_PALADIN_BLOOD_CORRUPTION;
int32 damage = GetHitDamage();
uint8 stacks = 0;
if (target)
{
Aura* aura = target->GetAura(auraId, GetCaster()->GetGUID());
if (aura)
stacks = aura->GetStackAmount();
damage = ((damage * stacks) / 5);
SetHitDamage(damage);
}
}
void Register() override
{
OnEffectHitTarget += SpellEffectFn(spell_pal_seal_of_vengeance::HandleScriptEffect, EFFECT_0, SPELL_EFFECT_WEAPON_PERCENT_DAMAGE);
}
};
void AddSC_paladin_spell_scripts()
{
RegisterSpellAndAuraScriptPair(spell_pal_seal_of_command, spell_pal_seal_of_command_aura);
@@ -1132,5 +1176,6 @@ void AddSC_paladin_spell_scripts()
RegisterSpellScript(spell_pal_lay_on_hands);
RegisterSpellScript(spell_pal_righteous_defense);
RegisterSpellScript(spell_pal_seal_of_righteousness);
RegisterSpellScript(spell_pal_seal_of_vengeance);
}

View File

@@ -2602,6 +2602,17 @@ public:
events.Reset();
}
bool CanAIAttack(Unit const* target) const override
{
if (Unit* summoner = me->GetCharmerOrOwner())
{
if (target->IsPlayer() && (!summoner->IsPvP() || !target->IsPvP()))
return false;
}
return true;
}
void JustEngagedWith(Unit* /*who*/) override
{
events.ScheduleEvent(EVENT_FLAME_BUFFET, 4s);
@@ -2610,12 +2621,9 @@ public:
void IsSummonedBy(WorldObject* summoner) override
{
if (summoner->GetTypeId() != TYPEID_UNIT)
{
return;
}
if (summoner->GetTypeId() == TYPEID_UNIT || summoner->IsPlayer())
me->GetMotionMaster()->MoveFollow(summoner->ToUnit(), PET_FOLLOW_DIST, PET_FOLLOW_ANGLE);
me->GetMotionMaster()->MoveFollow(summoner->ToUnit(), PET_FOLLOW_DIST, PET_FOLLOW_ANGLE);
}
void UpdateAI(uint32 diff) override