Scripts/Ulduar: Boss Ignis

- Update Boss Ignis thanks to snakeice for main patch
- add support for spell slagpot thanks to Shauren and Linencloth
- apply trinity coding standard to patch

--HG--
branch : trunk
This commit is contained in:
Supabad
2010-10-08 18:04:11 +02:00
parent 04566e5be9
commit f6645ce6e8
9 changed files with 434 additions and 49 deletions
+2
View File
@@ -26838,6 +26838,8 @@ INSERT INTO `spell_script_names` (`spell_id`,`ScriptName`) VALUES
( 71222, 'spell_festergut_blighted_spores'),
( 73033, 'spell_festergut_blighted_spores'),
( 73034, 'spell_festergut_blighted_spores'),
( 62717, 'spell_ignis_slag_pot'),
( 63477, 'spell_ignis_slag_pot'),
-- quest
( 8913, 'spell_q55_sacred_cleansing'),
( 17271, 'spell_q5206_test_fetid_skull'),
+1
View File
@@ -2485,6 +2485,7 @@ INSERT INTO `script_texts` (`npc_entry`,`entry`,`content_default`,`content_loc1`
(33118,-1603226,'Let the inferno consume you!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,15567,1,0,0,'Ignis SAY_SCORCH_1'),
(33118,-1603227,'BURN! Burn in the makers fire!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,15568,1,0,0,'Ignis SAY_SCORCH_2'),
(33118,-1603228,'Let it be finished!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,15571,1,0,0,'Ignis SAY_BERSERK'),
(33118,-1603229,'Ignis the Furnace Master begins to cast Flame Jets!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,0,3,0,0,'IGNIS EMOTE_JETS'),
-- Kologarn
(32930,-1603230,'None shall pass!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,15586,1,0,0,'Kologarn SAY_AGGRO'),
+2
View File
@@ -1486,6 +1486,8 @@ UPDATE `creature_template` SET `ScriptName`='boss_flame_leviathan_overload_devic
UPDATE `creature_template` SET `ScriptName`='npc_colossus' WHERE `entry`=33237;
UPDATE `creature_template` SET `ScriptName`='spell_pool_of_tar' WHERE `entry`=33090;
UPDATE `creature_template` SET `ScriptName`='boss_ignis' WHERE `entry`=33118;
UPDATE `creature_template` SET `ScriptName`='npc_iron_construct' WHERE `entry`=33121;
UPDATE `creature_template` SET `ScriptName`='npc_scorch_ground' WHERE `entry`=33221;
UPDATE `creature_template` SET `ScriptName`='boss_razorscale' WHERE `entry`=33186;
UPDATE `creature_template` SET `ScriptName`='boss_xt002' WHERE `entry`=33293;
UPDATE `creature_template` SET `ScriptName`='mob_xt002_heart' WHERE `entry`=33329;
+3
View File
@@ -0,0 +1,3 @@
-- Add script name to boss ignis adds
UPDATE `creature_template` SET `ScriptName`='npc_iron_construct' WHERE `entry`=33121;
UPDATE `creature_template` SET `ScriptName`='npc_scorch_ground' WHERE `entry`=33221;
+3
View File
@@ -0,0 +1,3 @@
DELETE FROM `script_texts` WHERE `entry` IN (-1571043,-1571042);
INSERT INTO `script_texts` (`npc_entry`,`entry`,`content_default`,`content_loc1`,`content_loc2`,`content_loc3`,`content_loc4`,`content_loc5`,`content_loc6`,`content_loc7`,`content_loc8`,`sound`,`type`,`language`,`emote`,`comment`) VALUES
(33118,-1603229,'Ignis the Furnace Master begins to cast Flame Jets!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,0,3,0,0,'IGNIS EMOTE_JETS');
@@ -0,0 +1,4 @@
DELETE FROM `spell_script_names` WHERE `spell_id`=62717 AND `ScriptName`='spell_ignis_slag_pot';
INSERT INTO `spell_script_names` (`spell_id`, `ScriptName`) VALUES
(62717, 'spell_ignis_slag_pot'); -- boss Ignis 10man
(62717, 'spell_ignis_slag_pot'); -- boss Ignis 25man
@@ -17,10 +17,7 @@
#include "ScriptPCH.h"
#include "ulduar.h"
#define SPELL_FLAME_JETS 62680
#define SPELL_SCORCH 62546
#define SPELL_SLAG_POT 62717
#include "SpellAuraEffects.h"
enum Yells
{
@@ -33,11 +30,83 @@ enum Yells
SAY_SCORCH_1 = -1603226,
SAY_SCORCH_2 = -1603227,
SAY_BERSERK = -1603228,
EMOTE_JETS = -1603229,
};
enum
enum Spells
{
ACHIEV_TIMED_START_EVENT = 20951,
SPELL_FLAME_JETS = 62680,
SPELL_SCORCH = 62546,
SPELL_SLAG_POT = 62717,
SPELL_SLAG_POT_DAMAGE = 65722,
SPELL_SLAG_IMBUED = 62836,
SPELL_ACTIVATE_CONSTRUCT = 62488,
SPELL_STRENGHT = 64473,
SPELL_GRAB = 62707,
SPELL_BERSERK = 47008
};
enum Events
{
EVENT_NONE,
EVENT_JET,
EVENT_SCORCH,
EVENT_SLAG_POT,
EVENT_GRAB_POT,
EVENT_CHANGE_POT,
EVENT_END_POT,
EVENT_CONSTRUCT,
EVENT_BERSERK,
ACTION_REMOVE_BUFF = 20
};
enum eCreatures
{
NPC_IRON_CONSTRUCT = 33121,
NPC_GROUND_SCORCH = 33221
};
enum ConstructSpells
{
SPELL_HEAT = 65667,
SPELL_MOLTEN = 62373,
SPELL_BRITTLE = 62382,
SPELL_SHATTER = 62383,
SPELL_GROUND = 62548,
};
enum eAchievementData
{
ACHIEVEMENT_STOKIN_THE_FURNACE_10 = 2930,
ACHIEVEMENT_STOKIN_THE_FURNACE_25 = 2929,
ACHIEVEMENT_SHATTERED_10 = 2925,
ACHIEVEMENT_SHATTERED_25 = 2926,
};
#define MAX_ENCOUNTER_TIME 4 * 60 * 1000
const Position Pos[20] =
{
{630.366f,216.772f,360.891f,3.001970f},
{630.594f,231.846f,360.891f,3.124140f},
{630.435f,337.246f,360.886f,3.211410f},
{630.493f,313.349f,360.886f,3.054330f},
{630.444f,321.406f,360.886f,3.124140f},
{630.366f,247.307f,360.888f,3.211410f},
{630.698f,305.311f,360.886f,3.001970f},
{630.500f,224.559f,360.891f,3.054330f},
{630.668f,239.840f,360.890f,3.159050f},
{630.384f,329.585f,360.886f,3.159050f},
{543.220f,313.451f,360.886f,0.104720f},
{543.356f,329.408f,360.886f,6.248280f},
{543.076f,247.458f,360.888f,6.213370f},
{543.117f,232.082f,360.891f,0.069813f},
{543.161f,305.956f,360.886f,0.157080f},
{543.277f,321.482f,360.886f,0.052360f},
{543.316f,337.468f,360.886f,6.195920f},
{543.280f,239.674f,360.890f,6.265730f},
{543.265f,217.147f,360.891f,0.174533f},
{543.256f,224.831f,360.891f,0.122173f}
};
class boss_ignis : public CreatureScript
@@ -52,51 +121,68 @@ public:
struct boss_ignis_AI : public BossAI
{
boss_ignis_AI(Creature *pCreature) : BossAI(pCreature, TYPE_IGNIS) {}
boss_ignis_AI(Creature *pCreature) : BossAI(pCreature, TYPE_IGNIS), vehicle(me->GetVehicleKit())
{
assert(vehicle);
me->ApplySpellImmune(0, IMMUNITY_EFFECT, SPELL_EFFECT_KNOCK_BACK, true);
me->ApplySpellImmune(0, IMMUNITY_ID, 49560, true); // Death Grip jump effect
}
uint32 uiFlameJetsTimer;
uint32 uiScorchTimer;
uint32 uiSlagPotTimer;
Vehicle *vehicle;
std::vector<Creature*> triggers;
bool Shattered;
uint32 SlagPotGUID;
uint32 EncounterTime;
uint32 ConstructTimer;
void Reset()
{
_Reset();
uiFlameJetsTimer = 32000;
uiScorchTimer = 100;
uiSlagPotTimer = 100;
if (instance)
instance->DoStopTimedAchievement(ACHIEVEMENT_TIMED_TYPE_EVENT, ACHIEV_TIMED_START_EVENT);
if (vehicle)
vehicle->RemoveAllPassengers();
}
void EnterCombat(Unit* /*who*/)
void EnterCombat(Unit *who)
{
DoScriptText(SAY_AGGRO,me);
_EnterCombat();
if (instance)
instance->DoStartTimedAchievement(ACHIEVEMENT_TIMED_TYPE_EVENT, ACHIEV_TIMED_START_EVENT);
DoScriptText(SAY_AGGRO, me);
events.ScheduleEvent(EVENT_JET, 30000);
events.ScheduleEvent(EVENT_SCORCH, 25000);
events.ScheduleEvent(EVENT_SLAG_POT, 35000);
events.ScheduleEvent(EVENT_CONSTRUCT, 15000);
events.ScheduleEvent(EVENT_END_POT, 40000);
events.ScheduleEvent(EVENT_BERSERK, 480000);
SlagPotGUID = 0;
EncounterTime = 0;
ConstructTimer = 0;
Shattered = false;
}
void KilledUnit(Unit* /*victim*/)
void JustDied(Unit *victim)
{
DoScriptText(RAND(SAY_SLAY_1,SAY_SLAY_2), me);
}
void JustDied(Unit * /*victim*/)
{
DoScriptText(SAY_DEATH, me);
_JustDied();
}
DoScriptText(SAY_DEATH, me);
void MoveInLineOfSight(Unit* /*who*/) {}
// Achievements
if (instance)
{
// Shattered
if (Shattered)
instance->DoCompleteAchievement(RAID_MODE(ACHIEVEMENT_SHATTERED_10,ACHIEVEMENT_SHATTERED_25));
// Stokin' the Furnace
if (EncounterTime <= MAX_ENCOUNTER_TIME)
instance->DoCompleteAchievement(RAID_MODE(ACHIEVEMENT_STOKIN_THE_FURNACE_10,ACHIEVEMENT_STOKIN_THE_FURNACE_25));
}
}
void UpdateAI(const uint32 diff)
{
if (!UpdateVictim())
return;
if (me->GetPositionY() < 150 || me->GetPositionX() < 450) // Not Blizzlike, anti-exploit to prevent players from pulling bosses to vehicles.
if(me->GetPositionY() < 150 || me->GetPositionX() < 450 || me->getVictim()->GetTypeId() == !TYPEID_PLAYER)
{
me->RemoveAllAuras();
me->DeleteThreatList();
@@ -104,35 +190,299 @@ public:
me->GetMotionMaster()->MoveTargetedHome();
}
if (uiFlameJetsTimer <= diff)
{
DoCast(SPELL_FLAME_JETS);
uiFlameJetsTimer = 25000;
} else uiFlameJetsTimer -= diff;
events.Update(diff);
if (uiScorchTimer <= diff)
{
DoScriptText(RAND(SAY_SCORCH_1,SAY_SCORCH_2), me);
DoCast(SPELL_SCORCH);
uiScorchTimer = 20000;
} else uiScorchTimer -= diff;
if (me->hasUnitState(UNIT_STAT_CASTING))
return;
if (uiSlagPotTimer <= diff)
EncounterTime += diff;
ConstructTimer += diff;
while(uint32 eventId = events.ExecuteEvent())
{
if (Unit *pTarget = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true))
switch(eventId)
{
DoScriptText(SAY_SLAG_POT, me);
DoCast(pTarget, SPELL_SLAG_POT);
case EVENT_JET:
me->MonsterTextEmote(EMOTE_JETS, 0, true);
DoCastAOE(SPELL_FLAME_JETS);
events.RescheduleEvent(EVENT_JET,urand(35000,40000));
break;
case EVENT_SLAG_POT:
if (Unit *pTarget = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true))
{
DoScriptText(SAY_SLAG_POT, me);
SlagPotGUID = pTarget->GetGUID();
DoCast(pTarget, SPELL_GRAB);
events.DelayEvents(3000);
events.ScheduleEvent(EVENT_GRAB_POT, 500);
}
events.RescheduleEvent(EVENT_SLAG_POT,RAID_MODE(30000, 15000));
break;
case EVENT_GRAB_POT:
if (Unit* SlagPotTarget = Unit::GetUnit(*me, SlagPotGUID))
{
SlagPotTarget->EnterVehicle(me, 0);
events.CancelEvent(EVENT_GRAB_POT);
events.ScheduleEvent(EVENT_CHANGE_POT, 1000);
}
break;
case EVENT_CHANGE_POT:
if (Unit* SlagPotTarget = Unit::GetUnit(*me, SlagPotGUID))
{
SlagPotTarget->AddAura(SPELL_SLAG_POT, SlagPotTarget);
SlagPotTarget->EnterVehicle(me, 1);
events.CancelEvent(EVENT_CHANGE_POT);
events.ScheduleEvent(EVENT_END_POT, 10000);
}
break;
case EVENT_END_POT:
if (Unit* SlagPotTarget = Unit::GetUnit(*me, SlagPotGUID))
{
SlagPotTarget->ExitVehicle();
SlagPotTarget = NULL;
SlagPotGUID = NULL;
events.CancelEvent(EVENT_END_POT);
}
break;
case EVENT_SCORCH:
DoScriptText(RAND(SAY_SCORCH_1, SAY_SCORCH_2), me);
if (Unit *pTarget = me->getVictim())
me->SummonCreature(NPC_GROUND_SCORCH, pTarget->GetPositionX(), pTarget->GetPositionY(), pTarget->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN, 45000);
DoCast(SPELL_SCORCH);
events.RescheduleEvent(EVENT_SCORCH,25000);
break;
case EVENT_CONSTRUCT:
DoScriptText(SAY_SUMMON, me);
DoSummon(NPC_IRON_CONSTRUCT, Pos[rand()%20], 30000, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT);
DoCast(SPELL_STRENGHT);
DoCast(me, SPELL_ACTIVATE_CONSTRUCT);
events.RescheduleEvent(EVENT_CONSTRUCT,RAID_MODE(40000, 30000));
break;
case EVENT_BERSERK:
DoCast(me, SPELL_BERSERK, true);
DoScriptText(SAY_BERSERK, me);
break;
}
uiSlagPotTimer = 30000;
} else uiSlagPotTimer -= diff;
}
DoMeleeAttackIfReady();
}
void KilledUnit(Unit* Victim)
{
if (!(rand()%5))
DoScriptText(RAND(SAY_SLAY_1, SAY_SLAY_2), me);
}
void JustSummoned(Creature *summon)
{
if (summon->GetEntry() == NPC_IRON_CONSTRUCT)
{
summon->setFaction(16);
summon->SetReactState(REACT_AGGRESSIVE);
summon->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_NOT_SELECTABLE | UNIT_FLAG_PACIFIED | UNIT_FLAG_STUNNED | UNIT_FLAG_DISABLE_MOVE);
}
summon->AI()->AttackStart(me->getVictim());
summon->AI()->DoZoneInCombat();
summons.Summon(summon);
}
void DoAction(const int32 action)
{
switch(action)
{
case ACTION_REMOVE_BUFF:
me->RemoveAuraFromStack(SPELL_STRENGHT);
// Shattered Achievement
if (ConstructTimer >= 5000)
ConstructTimer = 0;
else
Shattered = true;
break;
}
}
};
};
class npc_iron_construct : public CreatureScript
{
public:
npc_iron_construct() : CreatureScript("npc_iron_construct") { }
CreatureAI *GetAI(Creature *creature) const
{
return new npc_iron_constructAI(creature);
}
struct npc_iron_constructAI : public ScriptedAI
{
npc_iron_constructAI(Creature* pCreature) : ScriptedAI(pCreature)
{
instance = pCreature->GetInstanceScript();
pCreature->SetReactState(REACT_PASSIVE);
}
InstanceScript* instance;
bool Brittled;
void Reset()
{
Brittled = false;
}
void DamageTaken(Unit *attacker, uint32 &damage)
{
if (me->HasAura(SPELL_BRITTLE) && damage >= 5000)
{
DoCast(SPELL_SHATTER);
if (Creature *pIgnis = me->GetCreature(*me, instance->GetData64(TYPE_IGNIS)))
if (pIgnis->AI())
pIgnis->AI()->DoAction(ACTION_REMOVE_BUFF);
me->ForcedDespawn(1000);
}
}
void UpdateAI(const uint32 uiDiff)
{
if (!UpdateVictim())
return;
if (Aura * aur = me->GetAura(SPELL_HEAT))
{
if (aur->GetStackAmount() >= 10)
{
me->RemoveAura(SPELL_HEAT);
DoCast(SPELL_MOLTEN);
Brittled = false;
}
}
// Water pools
if (me->IsInWater() && !Brittled && me->HasAura(SPELL_MOLTEN))
{
DoCast(SPELL_BRITTLE);
me->RemoveAura(SPELL_MOLTEN);
Brittled = true;
}
DoMeleeAttackIfReady();
}
};
};
class npc_scorch_ground : public CreatureScript
{
public:
npc_scorch_ground() : CreatureScript("npc_scorch_ground") { }
CreatureAI *GetAI(Creature *creature) const
{
return new npc_scorch_groundAI(creature);
}
struct npc_scorch_groundAI : public ScriptedAI
{
npc_scorch_groundAI(Creature* pCreature) : ScriptedAI(pCreature)
{
me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_DISABLE_MOVE |UNIT_FLAG_NOT_SELECTABLE | UNIT_FLAG_PACIFIED);
pCreature->SetDisplayId(16925); //model 2 in db cannot overwrite wdb fields
}
uint64 ConstructGUID;
uint32 HeatTimer;
bool Heat;
void MoveInLineOfSight(Unit* pWho)
{
if (!Heat)
{
if (pWho->GetEntry() == NPC_IRON_CONSTRUCT)
{
if (!pWho->HasAura(SPELL_HEAT) || !pWho->HasAura(SPELL_MOLTEN))
{
ConstructGUID = pWho->GetGUID();
Heat=true;
}
}
}
}
void Reset()
{
Heat=false;
DoCast(me, SPELL_GROUND);
ConstructGUID=0;
HeatTimer=0;
}
void UpdateAI(const uint32 uiDiff)
{
if (Heat)
{
if(HeatTimer <= uiDiff)
{
Creature* Construct = me->GetCreature(*me ,ConstructGUID);
if (Construct && !Construct->HasAura(SPELL_MOLTEN))
{
me->AddAura(SPELL_HEAT,Construct);
HeatTimer=1000;
}
}
else
HeatTimer -= uiDiff;
}
}
};
};
class spell_ignis_slag_pot : public SpellScriptLoader
{
public:
spell_ignis_slag_pot() : SpellScriptLoader("spell_ignis_slag_pot") { }
class spell_ignis_slag_pot_AuraScript : public AuraScript
{
bool Validate(SpellEntry const * /*spellEntry*/)
{
if (!sSpellStore.LookupEntry(SPELL_SLAG_POT_DAMAGE))
return false;
if (!sSpellStore.LookupEntry(SPELL_SLAG_POT))
return false;
if (!sSpellStore.LookupEntry(SPELL_SLAG_IMBUED))
return false;
return true;
}
void HandleEffectPeriodic(AuraEffect const * aurEff, AuraApplication const * aurApp)
{
Unit* aurEffCaster = aurEff->GetCaster();
if (!aurEffCaster)
return;
Unit * target = aurApp->GetTarget();
aurEffCaster->CastSpell(target, SPELL_SLAG_POT_DAMAGE, true);
if (target->isAlive() && !GetDuration())
target->CastSpell(target, SPELL_SLAG_IMBUED, true);
}
void Register()
{
OnEffectPeriodic += AuraEffectPeriodicFn(spell_ignis_slag_pot_AuraScript::HandleEffectPeriodic, EFFECT_0, SPELL_AURA_PERIODIC_DUMMY);
}
};
AuraScript* GetAuraScript() const
{
return new spell_ignis_slag_pot_AuraScript();
}
};
void AddSC_boss_ignis()
{
new boss_ignis();
new npc_iron_construct();
new npc_scorch_ground();
new spell_ignis_slag_pot();
// has to be done or else players wil absorb dmg from slag pot vehicle seat 1 slagpot
if (VehicleSeatEntry* vehSeat = const_cast<VehicleSeatEntry*>(sVehicleSeatStore.LookupEntry(3206)))
vehSeat->m_flags |= 0x400;
}
@@ -326,6 +326,20 @@ public:
return 0;
}
bool CheckAchievementCriteriaMeet(uint32 criteria_id, Player const* /*source*/, Unit const* /*target*/, uint32 /*miscvalue1*/)
{
switch (criteria_id)
{
case ACHIEVEMENT_CRITERIA_HOT_POCKET_10:
return true;
case ACHIEVEMENT_CRITERIA_HOT_POCKET_25:
return true;
default:
break;
}
return false;
}
uint32 GetData(uint32 type)
{
switch(type)
@@ -66,4 +66,10 @@ enum eTypes
EVENT_TOWER_OF_FLAMES_DESTROYED = 21033,
EVENT_TOWER_OF_LIFE_DESTROYED = 21030
};
enum eAchievementCriteria
{
ACHIEVEMENT_CRITERIA_HOT_POCKET_10 = 10430, //ignis
ACHIEVEMENT_CRITERIA_HOT_POCKET_25 = 10431,
};
#endif