aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/server/scripts/Northrend/Ulduar/ulduar/boss_flame_leviathan.cpp302
1 files changed, 207 insertions, 95 deletions
diff --git a/src/server/scripts/Northrend/Ulduar/ulduar/boss_flame_leviathan.cpp b/src/server/scripts/Northrend/Ulduar/ulduar/boss_flame_leviathan.cpp
index 54f7dc019f1..e74dc126835 100644
--- a/src/server/scripts/Northrend/Ulduar/ulduar/boss_flame_leviathan.cpp
+++ b/src/server/scripts/Northrend/Ulduar/ulduar/boss_flame_leviathan.cpp
@@ -35,13 +35,13 @@ enum Spells
SPELL_FLAME_VENTS = 62396,
SPELL_MISSILE_BARRAGE = 62400,
SPELL_SYSTEMS_SHUTDOWN = 62475,
-
SPELL_OVERLOAD_CIRCUIT = 62399,
SPELL_START_THE_ENGINE = 62472,
SPELL_SEARING_FLAME = 62402,
SPELL_BLAZE = 62292,
SPELL_SMOKE_TRAIL = 63575,
SPELL_ELECTROSHOCK = 62522,
+ SPELL_NAPALM = 63666,
//TOWER Additional SPELLS
SPELL_THORIM_S_HAMMER = 62911, // Tower of Storms
SPELL_MIMIRON_S_INFERNO = 62909, // Tower of Flames
@@ -99,6 +99,7 @@ enum Events
EVENT_SPEED,
EVENT_SUMMON,
EVENT_SHUTDOWN,
+ EVENT_REPAIR,
EVENT_THORIM_S_HAMMER, // Tower of Storms
EVENT_MIMIRON_S_INFERNO, // Tower of Flames
EVENT_HODIR_S_FURY, // Tower of Frost
@@ -110,6 +111,7 @@ enum Seats
SEAT_PLAYER = 0,
SEAT_TURRET = 1,
SEAT_DEVICE = 2,
+ SEAT_CANNON = 7,
};
enum Vehicles
@@ -145,8 +147,6 @@ enum Yells
enum eAchievementData
{
- //ACHIEV_CHAMPION_OF_ULDUAR = 2903,
- //ACHIEV_CONQUEROR_OF_ULDUAR = 2904,
ACHIEV_10_NUKED_FROM_ORBIT = 2915,
ACHIEV_25_NUKED_FROM_ORBIT = 2917,
ACHIEV_10_ORBITAL_BOMBARDMENT = 2913,
@@ -214,6 +214,7 @@ public:
assert(vehicle);
pInstance = me->GetInstanceScript();
uiActiveTowers = 4;
+ uiShutdown = 0;
ActiveTowers = false;
towerOfStorms = false;
towerOfLife = false;
@@ -221,7 +222,6 @@ public:
towerOfFrost = false;
me->ApplySpellImmune(0, IMMUNITY_EFFECT, SPELL_EFFECT_KNOCK_BACK, true);
me->ApplySpellImmune(0, IMMUNITY_ID, 49560, true); //deathgrip
-
me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_NOT_SELECTABLE | UNIT_FLAG_STUNNED);
me->SetReactState(REACT_PASSIVE);
}
@@ -230,6 +230,7 @@ public:
Vehicle* vehicle;
uint8 uiActiveTowers;
+ uint8 uiShutdown;
bool ActiveTowers;
bool towerOfStorms;
bool towerOfLife;
@@ -243,11 +244,9 @@ public:
me->SetLootMode(LOOT_MODE_HARD_MODE_3);
me->SetLootMode(LOOT_MODE_HARD_MODE_2);
me->SetLootMode(LOOT_MODE_HARD_MODE_1);*/
- if (pInstance)
- pInstance->SetData(TYPE_LEVIATHAN, NOT_STARTED);
- assert(vehicle);
- me->GetVehicleKit();
+ pInstance->SetData(TYPE_LEVIATHAN, NOT_STARTED);
me->SetReactState(REACT_DEFENSIVE);
+ InstallAdds(true);
}
void EnterCombat(Unit* /*who*/)
@@ -255,47 +254,90 @@ public:
_EnterCombat();
pInstance->SetData(TYPE_LEVIATHAN, IN_PROGRESS); //_Reset doesnt do this correctly
me->SetReactState(REACT_AGGRESSIVE);
- events.ScheduleEvent(EVENT_PURSUE, 0);
+ events.ScheduleEvent(EVENT_PURSUE, 30*IN_MILLISECONDS);
events.ScheduleEvent(EVENT_MISSILE, 1500);
- events.ScheduleEvent(EVENT_VENT, 20000);
- events.ScheduleEvent(EVENT_SPEED, 15000);
- events.ScheduleEvent(EVENT_SUMMON, 0);
- if (ActiveTowers)
+ events.ScheduleEvent(EVENT_VENT, 20*IN_MILLISECONDS);
+ events.ScheduleEvent(EVENT_SPEED, 15*IN_MILLISECONDS);
+ events.ScheduleEvent(EVENT_SUMMON, 1*IN_MILLISECONDS);
+ ActiveTower(false); //void ActiveTower
+ InstallAdds(false);
+ }
+
+ void ActiveTower(bool bReset = false)
+ {
+ if (!bReset)
{
- if (towerOfStorms)
+ if (ActiveTowers)
{
- me->AddAura(SPELL_BUFF_TOWER_OF_STORMS, me);
- events.ScheduleEvent(EVENT_THORIM_S_HAMMER, 35000);
- }
+ if (towerOfStorms)
+ {
+ me->AddAura(SPELL_BUFF_TOWER_OF_STORMS, me);
+ events.ScheduleEvent(EVENT_THORIM_S_HAMMER, 35*IN_MILLISECONDS);
+ }
- if (towerOfFlames)
- {
- me->AddAura(SPELL_BUFF_TOWER_OF_FLAMES, me);
- events.ScheduleEvent(EVENT_MIMIRON_S_INFERNO,70000);
- }
+ if (towerOfFlames)
+ {
+ me->AddAura(SPELL_BUFF_TOWER_OF_FLAMES, me);
+ events.ScheduleEvent(EVENT_MIMIRON_S_INFERNO,70*IN_MILLISECONDS);
+ }
- if (towerOfFrost)
- {
- me->AddAura(SPELL_BUFF_TOWER_OF_FR0ST, me);
- events.ScheduleEvent(EVENT_HODIR_S_FURY, 105000);
+ if (towerOfFrost)
+ {
+ me->AddAura(SPELL_BUFF_TOWER_OF_FR0ST, me);
+ events.ScheduleEvent(EVENT_HODIR_S_FURY, 105*IN_MILLISECONDS);
+ }
+
+ if (towerOfLife)
+ {
+ me->AddAura(SPELL_BUFF_TOWER_OF_LIFE, me);
+ events.ScheduleEvent(EVENT_FREYA_S_WARD, 140*IN_MILLISECONDS);
+ }
+
+ if (!towerOfLife && !towerOfFrost && !towerOfFlames && !towerOfStorms)
+ DoScriptText(SAY_TOWER_NONE, me);
+ else
+ DoScriptText(SAY_HARDMODE, me);
}
+ else
+ DoScriptText(SAY_AGGRO, me);
+ }
+ }
- if (towerOfLife)
+ void InstallAdds(bool bReset = false)
+ {
+ if (!bReset)
+ {
+ std::list<Creature*> lSeats;
+ me->GetCreatureListWithEntryInGrid(lSeats, 33114,17.0f);
+ if (lSeats.empty())
+ return;
+ for(std::list<Creature*>::const_iterator itr = lSeats.begin(); itr != lSeats.end(); itr++)
{
- me->AddAura(SPELL_BUFF_TOWER_OF_LIFE, me);
- events.ScheduleEvent(EVENT_FREYA_S_WARD, 140000);
- }
+ Vehicle* pSeat = (*itr)->GetVehicleKit();
+ if (Creature* pTurret = (me->SummonCreature(33142, me->GetPositionX(), me->GetPositionY(), me->GetPositionZ(), 0, TEMPSUMMON_MANUAL_DESPAWN)))
+ pTurret->EnterVehicle(pSeat, SEAT_TURRET);
- if (!towerOfLife && !towerOfFrost && !towerOfFlames && !towerOfStorms)
- DoScriptText(SAY_TOWER_NONE, me);
- else
- DoScriptText(SAY_HARDMODE, me);
+ if (Creature* pDevice = (me->SummonCreature(33143, me->GetPositionX(), me->GetPositionY(), me->GetPositionZ(), 0, TEMPSUMMON_MANUAL_DESPAWN)))
+ pDevice->EnterVehicle(pSeat, SEAT_DEVICE);
+ }
}
else
- DoScriptText(SAY_AGGRO, me);
+ {
+ std::list<Creature*> lSeats;
+ me->GetCreatureListWithEntryInGrid(lSeats, 33114,17.0f);
+ if (lSeats.empty())
+ return;
+ for(std::list<Creature*>::const_iterator itr = lSeats.begin(); itr != lSeats.end(); itr++)
+ {
+ Vehicle* pSeat = (*itr)->GetVehicleKit();
+ if (Unit* pTurret = (pSeat->GetPassenger(SEAT_TURRET)))
+ pTurret->RemoveFromWorld();
- if (Creature *turret = CAST_CRE(vehicle->GetPassenger(SEAT_TURRET)))
- turret->AI()->DoZoneInCombat();
+ if (Unit* pDevice = (pSeat->GetPassenger(SEAT_DEVICE)))
+ pDevice->RemoveFromWorld();
+
+ }
+ }
}
// TODO: effect 0 and effect 1 may be on different target
@@ -318,16 +360,12 @@ public:
{
case 4:
pInstance->DoCompleteAchievement(RAID_MODE(ACHIEV_10_ORBIT_UARY, ACHIEV_25_ORBIT_UARY));
- break;
case 3:
pInstance->DoCompleteAchievement(RAID_MODE(ACHIEV_10_NUKED_FROM_ORBIT, ACHIEV_25_NUKED_FROM_ORBIT));
- break;
case 2:
pInstance->DoCompleteAchievement(RAID_MODE(ACHIEV_10_ORBITAL_DEVASTATION, ACHIEV_25_ORBITAL_DEVASTATION));
- break;
case 1:
pInstance->DoCompleteAchievement(RAID_MODE(ACHIEV_10_ORBITAL_BOMBARDMENT, ACHIEV_25_ORBITAL_BOMBARDMENT));
- break;
}
}
}
@@ -336,9 +374,12 @@ public:
{
if (pSpell->Id == SPELL_START_THE_ENGINE)
vehicle->InstallAllAccessories();
- else
- if (pSpell->Id == SPELL_ELECTROSHOCK)
- me->InterruptSpell(CURRENT_CHANNELED_SPELL);
+
+ if (pSpell->Id == SPELL_ELECTROSHOCK)
+ me->InterruptSpell(CURRENT_CHANNELED_SPELL);
+
+ if (pSpell->Id == SPELL_OVERLOAD_CIRCUIT)
+ uiShutdown++;
}
void UpdateAI(const uint32 diff)
@@ -352,7 +393,22 @@ public:
return;
}
- events.Update(diff);
+ if (uiShutdown == RAID_MODE(2,4))
+ {
+ uiShutdown = 0;
+ events.ScheduleEvent(EVENT_SHUTDOWN, 0);
+ events.ScheduleEvent(EVENT_REPAIR, 0);
+ me->RemoveAurasDueToSpell(SPELL_OVERLOAD_CIRCUIT);
+ me->InterruptNonMeleeSpells(true);
+ return;
+ }
+
+ if (me->HasAura(SPELL_SYSTEMS_SHUTDOWN))
+ {
+ me->SetReactState(REACT_PASSIVE);
+ me->addUnitState(UNIT_STAT_STUNNED | UNIT_STAT_ROOT);
+ return;
+ }
if (me->hasUnitState(UNIT_STAT_CASTING))
return;
@@ -369,48 +425,60 @@ public:
me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_STUNNED);
}
+ events.Update(diff);
+
uint32 eventId = events.GetEvent();
if (!me->getVictim())
- eventId = EVENT_PURSUE;
+ UpdateVictim();
switch(eventId)
{
case 0: break; // this is a must
case EVENT_PURSUE:
- DoCastAOE(SPELL_PURSUED, true);
DoScriptText(RAND(SAY_TARGET_1, SAY_TARGET_2, SAY_TARGET_3), me);
- events.RescheduleEvent(EVENT_PURSUE, 30000);
- UpdateVictim(); // begin to kill other things
- if (me->getVictim())
- me->MonsterTextEmote(EMOTE_PURSUE, me->getVictim()->GetGUID(), true);
- return;
+ if (Unit* pTarget = SelectTarget(SELECT_TARGET_RANDOM))
+ {
+ if (pTarget->GetTypeId() == TYPEID_PLAYER || pTarget->HasFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_PLAYER_VEHICLE))
+ {
+ me->AddAura(SPELL_PURSUED, pTarget);
+ me->MonsterTextEmote(EMOTE_PURSUE, pTarget->GetGUID(), true);
+ }
+ }
+ events.RepeatEvent(30*IN_MILLISECONDS);
+ break;
case EVENT_MISSILE:
if (Unit* pTarget = SelectTarget(SELECT_TARGET_RANDOM))
DoCast(pTarget, SPELL_MISSILE_BARRAGE);
events.RepeatEvent(1500);
- return;
+ break;
case EVENT_VENT:
DoCastAOE(SPELL_FLAME_VENTS);
- events.RepeatEvent(20000);
- return;
+ events.RepeatEvent(20*IN_MILLISECONDS);
+ break;
case EVENT_SPEED:
DoCastAOE(SPELL_GATHERING_SPEED);
- events.RepeatEvent(15000);
+ events.RepeatEvent(15*IN_MILLISECONDS);
return;
case EVENT_SUMMON:
if (summons.size() < 15) // 4seat+1turret+10lift
- if (Creature* pLift = DoSummonFlyer(MOB_MECHANOLIFT, me, urand(20,40), 50, 0))
+ if (Creature* pLift = DoSummonFlyer(MOB_MECHANOLIFT, me, 30.0f, 50.0f, 0))
pLift->GetMotionMaster()->MoveRandom(100);
- events.RepeatEvent(2000);
- return;
+ events.RepeatEvent(2*IN_MILLISECONDS);
+ break;
case EVENT_SHUTDOWN:
DoScriptText(RAND(SAY_OVERLOAD_1, SAY_OVERLOAD_2, SAY_OVERLOAD_3), me);
+ InstallAdds(true);
me->MonsterTextEmote(EMOTE_OVERLOAD, 0, true);
- DoCast(SPELL_SYSTEMS_SHUTDOWN);
+ me->AddAura(SPELL_SYSTEMS_SHUTDOWN, me);
me->RemoveAurasDueToSpell(SPELL_GATHERING_SPEED);
- me->MonsterTextEmote(EMOTE_REPAIR, 0, true);
events.CancelEvent(EVENT_SHUTDOWN);
- return;
+ break;
+ case EVENT_REPAIR:
+ me->MonsterTextEmote(EMOTE_REPAIR, 0, true);
+ me->clearUnitState(UNIT_STAT_STUNNED | UNIT_STAT_ROOT);
+ InstallAdds(false);
+ events.CancelEvent(EVENT_REPAIR);
+ break;
case EVENT_THORIM_S_HAMMER: // Tower of Storms
for (uint8 i = 0; i < 7; ++i)
{
@@ -419,12 +487,12 @@ public:
}
DoScriptText(SAY_TOWER_STORM, me);
events.CancelEvent(EVENT_THORIM_S_HAMMER);
- return;
+ break;
case EVENT_MIMIRON_S_INFERNO: // Tower of Flames
me->SummonCreature(MOB_MIMIRON_BEACON, 390.93f, -13.91f, 409.81f);
DoScriptText(SAY_TOWER_FLAME, me);
events.CancelEvent(EVENT_MIMIRON_S_INFERNO);
- return;
+ break;
case EVENT_HODIR_S_FURY: // Tower of Frost
for (uint8 i = 0; i < 7; ++i)
{
@@ -433,20 +501,21 @@ public:
}
DoScriptText(SAY_TOWER_FROST, me);
events.CancelEvent(EVENT_HODIR_S_FURY);
- return;
+ break;
case EVENT_FREYA_S_WARD: // Tower of Nature
DoScriptText(SAY_TOWER_NATURE, me);
StartFreyaEvent();
if (Unit* pTarget = SelectTarget(SELECT_TARGET_RANDOM))
DoCast(pTarget, SPELL_FREYA_S_WARD);
events.CancelEvent(EVENT_FREYA_S_WARD);
- return;
+ break;
default:
events.PopEvent();
break;
}
- if (me->IsWithinMeleeRange(me->getVictim()))
- DoSpellAttackIfReady(SPELL_BATTERING_RAM);
+ /*if (me->IsWithinMeleeRange(me->getVictim())) //bugged spell casts on units that are boarded on leviathan
+ DoSpellAttackIfReady(SPELL_BATTERING_RAM);*/
+ DoMeleeAttackIfReady();
}
void StartFreyaEvent()//summon these 4 on each corner wich wil spawn additional hostile mobs
@@ -466,7 +535,6 @@ public:
me->GetMotionMaster()->MoveCharge(354.8771f, -12.90240f, 409.803f); //position center
me->SetReactState(REACT_AGGRESSIVE);
me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_NOT_SELECTABLE | UNIT_FLAG_STUNNED);
- DoZoneInCombat();
return;
}
@@ -516,9 +584,6 @@ public:
case 4: // Tower of Nature destroyed
towerOfLife = false;
break;
- case 9: // Schedule event
- events.ScheduleEvent(EVENT_SHUTDOWN, 0);
- break;
}
}
};
@@ -567,33 +632,83 @@ public:
{
if (!apply)
return;
+ else
+ DoScriptText(SAY_PLAYER_RIDING,me);
- if (Creature* turret = CAST_CRE(vehicle->GetPassenger(SEAT_TURRET)))
+ if (Creature* pTurret = CAST_CRE(vehicle->GetPassenger(SEAT_TURRET)))
{
- turret->setFaction(me->GetVehicleBase()->getFaction());
- turret->SetUInt32Value(UNIT_FIELD_FLAGS, 0); // unselectable
- turret->AI()->AttackStart(who);
+ pTurret->setFaction(me->GetVehicleBase()->getFaction());
+ pTurret->SetUInt32Value(UNIT_FIELD_FLAGS, 0); // unselectable
+ pTurret->AI()->AttackStart(who);
}
- if (Unit* device = vehicle->GetPassenger(SEAT_DEVICE))
+ if (Unit* pDevice = CAST_CRE(vehicle->GetPassenger(SEAT_DEVICE)))
{
- device->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_SPELLCLICK);
- device->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
+ pDevice->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_SPELLCLICK);
+ pDevice->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
}
}
- else
- if (seatId == SEAT_TURRET)
- {
- if (apply)
- return;
- if (Unit* device = vehicle->GetPassenger(SEAT_DEVICE))
+ //else //throw passenger bugged, when fixed uncomment this part.
+ // if (seatId == SEAT_TURRET)
+ // {
+ // if (apply)
+ // return;
+ // if (Unit* device = vehicle->GetPassenger(SEAT_DEVICE))
+ // {
+ // device->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_SPELLCLICK);
+ // device->SetUInt32Value(UNIT_FIELD_FLAGS, 0); // unselectable
+ // }
+ // }
+ }
+ };
+
+};
+
+class boss_flame_leviathan_defense_cannon : public CreatureScript
+{
+public:
+ boss_flame_leviathan_defense_cannon() : CreatureScript("boss_flame_leviathan_defense_cannon") { }
+
+ CreatureAI* GetAI(Creature* pCreature) const
+ {
+ return new boss_flame_leviathan_defense_cannonAI (pCreature);
+ }
+
+ struct boss_flame_leviathan_defense_cannonAI : public ScriptedAI
+ {
+ boss_flame_leviathan_defense_cannonAI(Creature* pCreature) : ScriptedAI(pCreature) { }
+
+ uint32 NapalmTimer;
+
+ void Reset ()
+ {
+ NapalmTimer = 5000;
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+ if (!UpdateVictim())
+ return;
+
+ if (NapalmTimer <= diff)
+ {
+ if (Unit* pTarget = SelectUnit(SELECT_TARGET_RANDOM,0))
{
- device->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_SPELLCLICK);
- device->SetUInt32Value(UNIT_FIELD_FLAGS, 0); // unselectable
+ if(CanAIAttack(pTarget))
+ DoCast(pTarget,SPELL_NAPALM,true);
}
- }
+ NapalmTimer = 5000;
+ }
+ else
+ NapalmTimer-=diff;
}
- };
+ bool CanAIAttack(const Unit *who) const
+ {
+ if (who->GetTypeId() != TYPEID_PLAYER || !who->GetVehicle() || who->GetVehicleBase()->GetEntry() != 33114)
+ return false;
+ return true;
+ }
+ };
};
class boss_flame_leviathan_defense_turret : public CreatureScript
@@ -649,17 +764,15 @@ public:
{
if (param == EVENT_SPELLCLICK)
{
- me->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_SPELLCLICK);
- me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
- pInstance->instance->GetCreature(TYPE_LEVIATHAN)->AI()->DoAction(9); //should be called if all 3 overload devices are active
if (me->GetVehicle())
{
+ me->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_SPELLCLICK);
+ me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
if (Unit* pPlayer = me->GetVehicle()->GetPassenger(SEAT_PLAYER))
{
pPlayer->ExitVehicle();
me->GetVehicleBase()->CastSpell(pPlayer, SPELL_SMOKE_TRAIL, true);
- if (Unit* leviathan = me->GetVehicleBase()->GetVehicleBase())
- pPlayer->GetMotionMaster()->MoveKnockbackFrom(leviathan->GetPositionX(), leviathan->GetPositionY(), 30, 30);
+ pPlayer->GetMotionMaster()->MoveKnockbackFrom(me->GetVehicleBase()->GetPositionX(), me->GetVehicleBase()->GetPositionY(), 30, 30);
}
}
}
@@ -1104,7 +1217,6 @@ public:
CAST_AI(boss_flame_leviathan::boss_flame_leviathanAI, (pLeviathan->AI()))->DoAction(0); //enable hard mode activating the 4 additional events spawning additional vehicles
pCreature->SetVisibility(VISIBILITY_OFF);
pCreature->AI()->DoAction(0); // spawn the vehicles
- pCreature->SetVisibility(VISIBILITY_OFF);
if (Creature* Delorah = pCreature->FindNearestCreature(NPC_DELORAH, 1000, true))
{
if (Creature* Branz = pCreature->FindNearestCreature(NPC_BRANZ_BRONZBEARD, 1000, true))