mirror of
https://github.com/TrinityCore/TrinityCore.git
synced 2026-01-18 08:28:32 +01:00
Script/TheOculus: adapt Mage-Lord Urom's script to use EventMap, fix various issues with Teleport and Empowered Arcane Explosion, add missing heroic-mode spell Frost Buffet.
Closes #19452.
This commit is contained in:
9
sql/updates/world/3.3.5/2019_07_07_00_world.sql
Normal file
9
sql/updates/world/3.3.5/2019_07_07_00_world.sql
Normal file
@@ -0,0 +1,9 @@
|
||||
--
|
||||
DELETE FROM `spell_script_names` WHERE `ScriptName`="spell_frostbomb";
|
||||
INSERT INTO `spell_script_names` (`spell_id`, `ScriptName`) VALUES
|
||||
(51103, "spell_urom_frostbomb");
|
||||
|
||||
DELETE FROM `spelldifficulty_dbc` WHERE `id` IN (51110, 51121);
|
||||
INSERT INTO `spelldifficulty_dbc` (`id`, `spellid0`, `spellid1`) VALUES
|
||||
(51110, 51110, 59377),
|
||||
(51121, 51121, 59376);
|
||||
@@ -15,13 +15,6 @@
|
||||
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/* ScriptData
|
||||
SDName: Urom
|
||||
SD%Complete: 80
|
||||
SDComment: Is not working SPELL_ARCANE_SHIELD. SPELL_FROSTBOMB has some issues, the damage aura should not stack.
|
||||
SDCategory: Instance Script
|
||||
EndScriptData */
|
||||
|
||||
#include "ScriptMgr.h"
|
||||
#include "MotionMaster.h"
|
||||
#include "oculus.h"
|
||||
@@ -30,17 +23,25 @@ EndScriptData */
|
||||
|
||||
enum Spells
|
||||
{
|
||||
SPELL_ARCANE_SHIELD = 53813, //Dummy --> Channeled, shields the caster from damage.
|
||||
SPELL_EMPOWERED_ARCANE_EXPLOSION = 51110,
|
||||
SPELL_EMPOWERED_ARCANE_EXPLOSION_2 = 59377,
|
||||
SPELL_FROSTBOMB = 51103, //Urom throws a bomb, hitting its target with the highest aggro which inflict directly 650 frost damage and drops a frost zone on the ground. This zone deals 650 frost damage per second and reduce the movement speed by 35%. Lasts 1 minute.
|
||||
SPELL_SUMMON_MENAGERIE = 50476, //Summons an assortment of creatures and teleports the caster to safety.
|
||||
SPELL_ARCANE_SHIELD = 53813,
|
||||
SPELL_SUMMON_MENAGERIE = 50476,
|
||||
SPELL_SUMMON_MENAGERIE_2 = 50495,
|
||||
SPELL_SUMMON_MENAGERIE_3 = 50496,
|
||||
SPELL_TELEPORT = 51112, //Teleports to the center of Oculus
|
||||
SPELL_TIME_BOMB = 51121, //Deals arcane damage to a random player, and after 6 seconds, deals zone damage to nearby equal to the health missing of the target afflicted by the debuff.
|
||||
SPELL_TIME_BOMB_2 = 59376,
|
||||
SPELL_EVOCATE = 51602 // He always cast it on reset or after teleportation
|
||||
SPELL_EMPOWERED_ARCANE_EXPLOSION = 51110,
|
||||
SPELL_FROSTBOMB = 51103,
|
||||
SPELL_TELEPORT = 51112,
|
||||
SPELL_TIME_BOMB = 51121,
|
||||
SPELL_EVOCATE = 51602,
|
||||
SPELL_FROST_BUFFET = 58025
|
||||
};
|
||||
|
||||
enum Events
|
||||
{
|
||||
EVENT_FROST_BOMB = 1,
|
||||
EVENT_TIME_BOMB,
|
||||
EVENT_CAST_EXPLOSION,
|
||||
EVENT_TELEPORT,
|
||||
EVENT_TELEPORT_BACK
|
||||
};
|
||||
|
||||
enum Yells
|
||||
@@ -96,42 +97,53 @@ class boss_urom : public CreatureScript
|
||||
{
|
||||
boss_uromAI(Creature* creature) : BossAI(creature, DATA_UROM)
|
||||
{
|
||||
Initialize();
|
||||
platform = 0;
|
||||
_platform = 0;
|
||||
_x = 0.0f;
|
||||
_y = 0.0f;
|
||||
_isInCenter = false;
|
||||
|
||||
for (uint8 i = 0; i < 3; ++i)
|
||||
group[i] = i;
|
||||
_group[i] = i;
|
||||
|
||||
std::random_shuffle(group, group + 3);
|
||||
std::random_shuffle(_group, _group + 3);
|
||||
}
|
||||
|
||||
void Initialize()
|
||||
void EnterEvadeMode(EvadeReason why) override
|
||||
{
|
||||
x = 0.0f;
|
||||
y = 0.0f;
|
||||
canCast = false;
|
||||
canGoBack = false;
|
||||
// We can only evade if we're in the center platform
|
||||
if (_platform > 2)
|
||||
{
|
||||
_EnterEvadeMode(why);
|
||||
|
||||
teleportTimer = urand(30000, 35000);
|
||||
arcaneExplosionTimer = 9000;
|
||||
castArcaneExplosionTimer = 2000;
|
||||
frostBombTimer = urand(5000, 8000);
|
||||
timeBombTimer = urand(20000, 25000);
|
||||
// If we're in the center, teleport to start position
|
||||
if (_isInCenter)
|
||||
me->NearTeleportTo(1118.3101f, 1080.3800f, 508.3610f, 4.25f);
|
||||
else
|
||||
me->GetMotionMaster()->MoveTargetedHome();
|
||||
|
||||
Reset();
|
||||
events.Reset();
|
||||
}
|
||||
}
|
||||
|
||||
void Reset() override
|
||||
{
|
||||
me->CastSpell(me, SPELL_EVOCATE);
|
||||
|
||||
_isInCenter = false;
|
||||
me->SetControlled(false, UNIT_STATE_ROOT);
|
||||
me->SetDisableGravity(false);
|
||||
me->SetReactState(REACT_AGGRESSIVE);
|
||||
DoCastSelf(SPELL_EVOCATE);
|
||||
_Reset();
|
||||
}
|
||||
|
||||
me->GetMotionMaster()->MoveIdle();
|
||||
void JustReachedHome() override
|
||||
{
|
||||
DoCastSelf(SPELL_EVOCATE);
|
||||
}
|
||||
|
||||
void JustEngagedWith(Unit* /*who*/) override
|
||||
{
|
||||
_JustEngagedWith();
|
||||
|
||||
StartAttack();
|
||||
}
|
||||
|
||||
@@ -151,20 +163,20 @@ class boss_urom : public CreatureScript
|
||||
switch (i)
|
||||
{
|
||||
case 0:
|
||||
x = me->GetPositionX() + 4;
|
||||
y = me->GetPositionY() - 4;
|
||||
_x = me->GetPositionX() + 4;
|
||||
_y = me->GetPositionY() - 4;
|
||||
break;
|
||||
case 1:
|
||||
x = me->GetPositionX() + 4;
|
||||
y = me->GetPositionY() + 4;
|
||||
_x = me->GetPositionX() + 4;
|
||||
_y = me->GetPositionY() + 4;
|
||||
break;
|
||||
case 2:
|
||||
x = me->GetPositionX() - 4;
|
||||
y = me->GetPositionY() + 4;
|
||||
_x = me->GetPositionX() - 4;
|
||||
_y = me->GetPositionY() + 4;
|
||||
break;
|
||||
case 3:
|
||||
x = me->GetPositionX() - 4;
|
||||
y = me->GetPositionY() - 4;
|
||||
_x = me->GetPositionX() - 4;
|
||||
_y = me->GetPositionY() - 4;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
@@ -173,23 +185,28 @@ class boss_urom : public CreatureScript
|
||||
|
||||
void StartAttack()
|
||||
{
|
||||
if (platform > 2)
|
||||
// We're in center - start fight normally
|
||||
if (_platform > 2)
|
||||
{
|
||||
me->CastStop(); // Stop casting of Evocation
|
||||
Talk(SAY_AGGRO);
|
||||
events.ScheduleEvent(EVENT_TELEPORT, 30s, 35s);
|
||||
events.ScheduleEvent(EVENT_FROST_BOMB, 5s, 8s);
|
||||
events.ScheduleEvent(EVENT_TIME_BOMB, 20s, 25s);
|
||||
return;
|
||||
}
|
||||
|
||||
// summon guards and jump to next platform
|
||||
// We're on one of the three platforms - summon guards and jump to next platform
|
||||
for (uint8 i = 0; i < 4; ++i)
|
||||
{
|
||||
SetPosition(i);
|
||||
me->SummonCreature(Group[group[platform]].entry[i], x, y, me->GetPositionZ(), me->GetOrientation());
|
||||
me->SummonCreature(Group[_group[_platform]].entry[i], _x, _y, me->GetPositionZ(), me->GetOrientation());
|
||||
}
|
||||
|
||||
Talk(platform);
|
||||
DoCast(TeleportSpells[platform]);
|
||||
Talk(_platform);
|
||||
DoCast(TeleportSpells[_platform]);
|
||||
|
||||
++platform;
|
||||
++_platform;
|
||||
}
|
||||
|
||||
void KilledUnit(Unit* who) override
|
||||
@@ -203,77 +220,59 @@ class boss_urom : public CreatureScript
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
if (platform < 3)
|
||||
if (_platform < 3)
|
||||
return;
|
||||
|
||||
events.Update(diff);
|
||||
|
||||
if (teleportTimer <= diff)
|
||||
if (me->HasUnitState(UNIT_STATE_CASTING))
|
||||
return;
|
||||
|
||||
while (uint32 eventId = events.ExecuteEvent())
|
||||
{
|
||||
me->InterruptNonMeleeSpells(false);
|
||||
me->GetMotionMaster()->MoveIdle();
|
||||
DoCast(SPELL_TELEPORT);
|
||||
teleportTimer = urand(30000, 35000);
|
||||
}
|
||||
else
|
||||
teleportTimer -= diff;
|
||||
|
||||
if (canCast && !me->FindCurrentSpellBySpellId(SPELL_EMPOWERED_ARCANE_EXPLOSION))
|
||||
{
|
||||
if (castArcaneExplosionTimer <= diff)
|
||||
switch (eventId)
|
||||
{
|
||||
canCast = false;
|
||||
canGoBack = true;
|
||||
DoCastAOE(SPELL_EMPOWERED_ARCANE_EXPLOSION);
|
||||
castArcaneExplosionTimer = 2000;
|
||||
case EVENT_TELEPORT:
|
||||
events.DelayEvents(10s);
|
||||
me->SetReactState(REACT_PASSIVE);
|
||||
me->AttackStop();
|
||||
me->StopMoving();
|
||||
me->SetDisableGravity(true);
|
||||
me->SetCanFly(true);
|
||||
me->SetControlled(true, UNIT_STATE_ROOT); // @hack: disabling gravity isn't enough to prevent falling
|
||||
DoCast(SPELL_TELEPORT);
|
||||
_isInCenter = true;
|
||||
events.ScheduleEvent(EVENT_CAST_EXPLOSION, 2s);
|
||||
break;
|
||||
case EVENT_CAST_EXPLOSION:
|
||||
Talk(EMOTE_ARCANE_EXPLOSION);
|
||||
Talk(SAY_ARCANE_EXPLOSION);
|
||||
DoCastAOE(SPELL_EMPOWERED_ARCANE_EXPLOSION);
|
||||
events.ScheduleEvent(EVENT_TELEPORT_BACK, DUNGEON_MODE<uint32>(10000, 8000));
|
||||
break;
|
||||
case EVENT_TELEPORT_BACK:
|
||||
me->SetReactState(REACT_AGGRESSIVE);
|
||||
me->SetDisableGravity(false);
|
||||
me->SetCanFly(false);
|
||||
me->SetControlled(false, UNIT_STATE_ROOT);
|
||||
if (Unit* victim = me->SelectVictim())
|
||||
{
|
||||
me->NearTeleportTo(victim->GetPosition());
|
||||
AttackStart(victim);
|
||||
}
|
||||
_isInCenter = false;
|
||||
events.ScheduleEvent(EVENT_TELEPORT, 30s, 35s);
|
||||
break;
|
||||
case EVENT_FROST_BOMB:
|
||||
DoCastVictim(SPELL_FROSTBOMB);
|
||||
events.ScheduleEvent(EVENT_FROST_BOMB, 5s, 8s);
|
||||
break;
|
||||
case EVENT_TIME_BOMB:
|
||||
if (Unit* unit = SelectTarget(SELECT_TARGET_RANDOM))
|
||||
DoCast(unit, SPELL_TIME_BOMB);
|
||||
events.ScheduleEvent(EVENT_TIME_BOMB, 20s, 25s);
|
||||
break;
|
||||
}
|
||||
else
|
||||
castArcaneExplosionTimer -= diff;
|
||||
}
|
||||
|
||||
if (canGoBack)
|
||||
{
|
||||
if (arcaneExplosionTimer <= diff)
|
||||
{
|
||||
if (me->GetVictim())
|
||||
{
|
||||
Position pos = me->EnsureVictim()->GetPosition();
|
||||
|
||||
me->NearTeleportTo(pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ(), pos.GetOrientation());
|
||||
me->GetMotionMaster()->MoveChase(me->GetVictim());
|
||||
}
|
||||
me->SetWalk(true);
|
||||
|
||||
Talk(EMOTE_ARCANE_EXPLOSION);
|
||||
Talk(SAY_ARCANE_EXPLOSION);
|
||||
|
||||
canCast = false;
|
||||
canGoBack = false;
|
||||
arcaneExplosionTimer = 9000;
|
||||
}
|
||||
else
|
||||
arcaneExplosionTimer -= diff;
|
||||
}
|
||||
|
||||
if (!me->IsNonMeleeSpellCast(false, true, true))
|
||||
{
|
||||
if (frostBombTimer <= diff)
|
||||
{
|
||||
DoCastVictim(SPELL_FROSTBOMB);
|
||||
frostBombTimer = urand(5000, 8000);
|
||||
}
|
||||
else
|
||||
frostBombTimer -= diff;
|
||||
|
||||
if (timeBombTimer <= diff)
|
||||
{
|
||||
if (Unit* unit = SelectTarget(SELECT_TARGET_RANDOM))
|
||||
DoCast(unit, SPELL_TIME_BOMB);
|
||||
|
||||
timeBombTimer = urand(20000, 25000);
|
||||
}
|
||||
else
|
||||
timeBombTimer -= diff;
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
@@ -283,7 +282,7 @@ class boss_urom : public CreatureScript
|
||||
{
|
||||
_JustDied();
|
||||
Talk(SAY_DEATH);
|
||||
DoCast(me, SPELL_DEATH_SPELL, true); // we cast the spell as triggered or the summon effect does not occur
|
||||
DoCastSelf(SPELL_DEATH_SPELL, true);
|
||||
}
|
||||
|
||||
void LeaveCombat()
|
||||
@@ -300,44 +299,41 @@ class boss_urom : public CreatureScript
|
||||
case SPELL_SUMMON_MENAGERIE:
|
||||
me->SetHomePosition(968.66f, 1042.53f, 527.32f, 0.077f);
|
||||
LeaveCombat();
|
||||
me->CastSpell(me, SPELL_EVOCATE);
|
||||
DoCastSelf(SPELL_EVOCATE, true);
|
||||
break;
|
||||
case SPELL_SUMMON_MENAGERIE_2:
|
||||
me->SetHomePosition(1164.02f, 1170.85f, 527.321f, 3.66f);
|
||||
LeaveCombat();
|
||||
me->CastSpell(me, SPELL_EVOCATE);
|
||||
DoCastSelf(SPELL_EVOCATE, true);
|
||||
break;
|
||||
case SPELL_SUMMON_MENAGERIE_3:
|
||||
me->SetHomePosition(1118.31f, 1080.377f, 508.361f, 4.25f);
|
||||
LeaveCombat();
|
||||
me->CastSpell(me, SPELL_EVOCATE);
|
||||
break;
|
||||
case SPELL_TELEPORT:
|
||||
//! Unconfirmed, previous below
|
||||
me->SetDisableGravity(true);
|
||||
//me->AddUnitMovementFlag(MOVEMENTFLAG_CAN_FLY); // with out it the npc will fall down while is casting
|
||||
canCast = true;
|
||||
DoCastSelf(SPELL_EVOCATE, true);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void DamageTaken(Unit* attacker, uint32& damage) override
|
||||
{
|
||||
// If killed while in center, teleport to a valid ground position before dying
|
||||
if (damage >= me->GetHealth())
|
||||
{
|
||||
if (_isInCenter)
|
||||
{
|
||||
_isInCenter = false;
|
||||
me->NearTeleportTo(1124.0432f, 1078.2109f, 508.3597f, 5.4623f);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
float x, y;
|
||||
|
||||
bool canCast;
|
||||
bool canGoBack;
|
||||
|
||||
uint8 platform;
|
||||
|
||||
uint8 group[3];
|
||||
|
||||
uint32 teleportTimer;
|
||||
uint32 arcaneExplosionTimer;
|
||||
uint32 castArcaneExplosionTimer;
|
||||
uint32 frostBombTimer;
|
||||
uint32 timeBombTimer;
|
||||
float _x, _y;
|
||||
bool _isInCenter;
|
||||
uint8 _platform;
|
||||
uint8 _group[3];
|
||||
};
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const override
|
||||
@@ -346,7 +342,31 @@ class boss_urom : public CreatureScript
|
||||
}
|
||||
};
|
||||
|
||||
class spell_urom_frostbomb : public AuraScript
|
||||
{
|
||||
PrepareAuraScript(spell_urom_frostbomb);
|
||||
|
||||
bool Validate(SpellInfo const* /*spell*/) override
|
||||
{
|
||||
return ValidateSpellInfo({ SPELL_FROST_BUFFET });
|
||||
}
|
||||
|
||||
void OnPeriodic(AuraEffect const* /*aurEff*/)
|
||||
{
|
||||
if (Unit* caster = GetCaster())
|
||||
if (caster->GetMap()->IsHeroic() && caster->IsInCombat())
|
||||
if (Unit* target = GetTarget())
|
||||
caster->CastSpell(target, SPELL_FROST_BUFFET, true);
|
||||
}
|
||||
|
||||
void Register() override
|
||||
{
|
||||
OnEffectPeriodic += AuraEffectPeriodicFn(spell_urom_frostbomb::OnPeriodic, EFFECT_1, SPELL_AURA_PERIODIC_DAMAGE);
|
||||
}
|
||||
};
|
||||
|
||||
void AddSC_boss_urom()
|
||||
{
|
||||
new boss_urom();
|
||||
RegisterAuraScript(spell_urom_frostbomb);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user