diff options
-rw-r--r-- | sql/updates/4854_world_scripts.sql | 35 | ||||
-rw-r--r-- | src/bindings/scripts/ScriptMgr.cpp | 8 | ||||
-rw-r--r-- | src/bindings/scripts/include/sc_creature.cpp | 8 | ||||
-rw-r--r-- | src/bindings/scripts/scripts/zone/ulduar/ulduar/boss_flame_leviathan.cpp | 209 |
4 files changed, 254 insertions, 6 deletions
diff --git a/sql/updates/4854_world_scripts.sql b/sql/updates/4854_world_scripts.sql new file mode 100644 index 00000000000..369d68d4551 --- /dev/null +++ b/sql/updates/4854_world_scripts.sql @@ -0,0 +1,35 @@ +UPDATE creature_template SET scriptname = "boss_flame_leviathan" WHERE entry = 33113; +UPDATE creature_template SET scriptname = "boss_flame_leviathan_turret" WHERE entry = 33139; +UPDATE creature_template SET scriptname = "boss_flame_leviathan_seat" WHERE entry = 33114; +UPDATE creature_template SET scriptname = "boss_flame_leviathan_defense_turret" WHERE entry = 33142; +UPDATE creature_template SET scriptname = "boss_flame_leviathan_overload_device" WHERE entry = 33143; +UPDATE creature_template SET scriptname = "boss_razorscale" WHERE entry = 33186; + +INSERT INTO creature_template (entry, vehicleid) VALUES +(33113, 340), # Flame Leviathan +(33114, 341) # Flame Leviathan Seat +ON DUPLICATE KEY UPDATE +vehicleid = VALUES(vehicleid); + +UPDATE creature_template SET flags_extra = 128 WHERE entry IN (33114); + +INSERT INTO creature_template (entry, spell1, spell2, spell3, spell4, spell5, spell6, vehicleid) VALUES +(33062, 62974, 62286, 62299, 64660, 0, 0, 335), # Salvaged Chopper +(33109, 62306, 62490, 62308, 62324, 0, 0, 338), # Salvaged Demolisher +(33167, 62634, 64979, 62479, 62471, 0, 62428, 345), # Salvaged Demolisher Mechanic Seat +(33060, 62345, 62522, 62346, 0, 0, 0, 336), # Salvaged Siege Engine +(33067, 62358, 62359, 64677, 0, 0, 0, 337) # Salvaged Siege Turret +ON DUPLICATE KEY UPDATE +spell1 = VALUES(spell1), +spell2 = VALUES(spell2), +spell3 = VALUES(spell3), +spell4 = VALUES(spell4), +spell5 = VALUES(spell5), +spell6 = VALUES(spell6), +vehicleid = VALUES(vehicleid); + +DELETE FROM `spell_script_target` WHERE `entry` IN (62374,62399); +INSERT INTO `spell_script_target` (`entry`, `type`, `targetEntry`) VALUES +(62374, 1, 33060), # Pursued +(62374, 1, 33109), +(62399, 1, 33139); # Overload Circuit diff --git a/src/bindings/scripts/ScriptMgr.cpp b/src/bindings/scripts/ScriptMgr.cpp index ae298061984..7a67acef149 100644 --- a/src/bindings/scripts/ScriptMgr.cpp +++ b/src/bindings/scripts/ScriptMgr.cpp @@ -653,6 +653,10 @@ extern void AddSC_boss_archavon(); extern void AddSC_boss_emalon(); extern void AddSC_instance_archavon(); +//Ulduar +extern void AddSC_boss_flame_leviathan(); +extern void AddSC_boss_razorscale(); + //Region extern void AddSC_wintergrasp(); @@ -1563,6 +1567,10 @@ void ScriptsInit(char const* cfg_file = "trinitycore.conf") AddSC_boss_emalon(); AddSC_instance_archavon(); + //Ulduar + AddSC_boss_flame_leviathan(); + AddSC_boss_razorscale(); + //Region AddSC_wintergrasp(); diff --git a/src/bindings/scripts/include/sc_creature.cpp b/src/bindings/scripts/include/sc_creature.cpp index 5edc67f7120..66c4fa58bb9 100644 --- a/src/bindings/scripts/include/sc_creature.cpp +++ b/src/bindings/scripts/include/sc_creature.cpp @@ -790,7 +790,7 @@ void LoadOverridenDBCData() spellInfo->DurationIndex = 21; spellInfo->Effect[0] = SPELL_EFFECT_APPLY_AREA_AURA_ENEMY; break; - // Naxxramas: Gothik : Inform Inf range + // Naxxramas : Gothik : Inform Inf range case 27892: case 27928: case 27935: @@ -799,6 +799,12 @@ void LoadOverridenDBCData() case 27937: spellInfo->rangeIndex = 13; break; + // Ulduar : Flame Leviathan : Pursued + case 62374: + spellInfo->MaxAffectedTargets = 1; + spellInfo->EffectImplicitTargetB[0] = TARGET_UNIT_AREA_ENTRY_SRC; + spellInfo->EffectImplicitTargetB[1] = TARGET_UNIT_AREA_ENTRY_SRC; + break; } } } diff --git a/src/bindings/scripts/scripts/zone/ulduar/ulduar/boss_flame_leviathan.cpp b/src/bindings/scripts/scripts/zone/ulduar/ulduar/boss_flame_leviathan.cpp index c1798cf8893..b00af93b0ac 100644 --- a/src/bindings/scripts/scripts/zone/ulduar/ulduar/boss_flame_leviathan.cpp +++ b/src/bindings/scripts/scripts/zone/ulduar/ulduar/boss_flame_leviathan.cpp @@ -33,6 +33,13 @@ #define SPELL_SEARING_FLAME 62402 +enum Events +{ + EVENT_PURSUE = 1, + EVENT_MISSILE, + EVENT_VENT, +}; + struct TRINITY_DLL_DECL boss_flame_leviathanAI : public BossAI { boss_flame_leviathanAI(Creature *c) : BossAI(c, BOSS_LEVIATHAN) @@ -40,17 +47,113 @@ struct TRINITY_DLL_DECL boss_flame_leviathanAI : public BossAI assert(c->isVehicle()); } + void EnterCombat(Unit *who) + { + _EnterCombat(); + events.ScheduleEvent(EVENT_PURSUE, 0); + events.ScheduleEvent(EVENT_MISSILE, 1500); + events.ScheduleEvent(EVENT_VENT, 20000); + if(Creature *turret = CAST_CRE(CAST_VEH(me)->GetPassenger(7))) + turret->AI()->DoZoneInCombat(); + } + + // TODO: effect 0 and effect 1 may be on different target + void SpellHitTarget(Unit *target, const SpellEntry *spell) + { + if(spell->Id == SPELL_PURSUED) + AttackStart(target); + } + void UpdateAI(const uint32 diff) { - if(!UpdateVictim()) + if(!me->isInCombat()) return; + if(me->getThreatManager().isThreatListEmpty()) + { + EnterEvadeMode(); + return; + } + events.Update(diff); if(me->hasUnitState(UNIT_STAT_CASTING)) return; - DoMeleeAttackIfReady(); + uint32 eventId = events.GetEvent(); + if(!me->getVictim()) + eventId = EVENT_PURSUE; + + switch(eventId) + { + case 0: + return; + case EVENT_PURSUE: + DoCastAOE(SPELL_PURSUED); + events.RepeatEvent(35000); + return; + case EVENT_MISSILE: + //TODO: without unittarget no visual effect + //DoCastAOE(SPELL_MISSILE_BARRAGE); + DoCast(me->getVictim(), SPELL_MISSILE_BARRAGE); + events.RepeatEvent(1500); + return; + case EVENT_VENT: + DoCastAOE(SPELL_FLAME_VENTS); + events.RepeatEvent(20000); + return; + default: + events.PopEvent(); + break; + } + + DoSpellAttackIfReady(SPELL_BATTERING_RAM); + } +}; + + +struct TRINITY_DLL_DECL boss_flame_leviathan_turretAI : public ScriptedAI +{ + boss_flame_leviathan_turretAI(Creature *c) : ScriptedAI(c) + { + me->SetReactState(REACT_PASSIVE); + } + + void Reset() + { + events.Reset(); + } + + EventMap events; + + void EnterCombat(Unit *who) + { + events.ScheduleEvent(1, 5000); + } + + void UpdateAI(const uint32 diff) + { + if(!UpdateCombatState()) + return; + + events.Update(diff); + + if(me->hasUnitState(UNIT_STAT_CASTING)) + return; + + if(uint32 eventId = events.GetEvent()) + { + switch(eventId) + { + case 1: + DoCast(SelectTarget(SELECT_TARGET_RANDOM), SPELL_CANNON); + events.RepeatEvent(10000); + return; + default: + events.PopEvent(); + break; + } + } } }; @@ -60,12 +163,55 @@ struct TRINITY_DLL_DECL boss_flame_leviathan_seatAI : public ScriptedAI boss_flame_leviathan_seatAI(Creature *c) : ScriptedAI(c) { assert(c->isVehicle()); + if(const CreatureInfo *cInfo = me->GetCreatureInfo()) + me->SetDisplayId(cInfo->DisplayID_A[0]); // 0 invisible, 1 visible } void Reset() { - if(const CreatureInfo *cInfo = me->GetCreatureInfo()) - me->SetDisplayId(cInfo->DisplayID_H[1]); // A for gm, H1 invisible + me->SetReactState(REACT_AGGRESSIVE); + } + + void MoveInLineOfSight(Unit *who) // for test + { + if(who->GetTypeId() == TYPEID_PLAYER && !who->m_Vehicle + && !CAST_VEH(me)->GetPassenger(0) && CAST_VEH(me)->GetPassenger(2)) + who->EnterVehicle(CAST_VEH(me), 0); + } + + void UpdateAI(const uint32 diff) + { + if(!CAST_VEH(me)->GetPassenger(2)) + if(Unit *who = CAST_VEH(me)->GetPassenger(0)) + who->ExitVehicle(); + } +}; + +struct TRINITY_DLL_DECL boss_flame_leviathan_defense_turretAI : public ScriptedAI +{ + boss_flame_leviathan_defense_turretAI(Creature *c) : ScriptedAI(c) + { + } + + void Reset() + { + } + + void DamageTaken(Unit *who, uint32 &damage) + { + if(!who->m_Vehicle || who->m_Vehicle->GetEntry() != 33114) + damage = 0; + } + + void MoveInLineOfSight(Unit *who) + { + if(me->getVictim()) + return; + + if(who->GetTypeId() != TYPEID_PLAYER || !who->m_Vehicle || who->m_Vehicle->GetEntry() != 33114) + return; + + AttackStart(who); } void UpdateAI(const uint32 diff) @@ -76,7 +222,30 @@ struct TRINITY_DLL_DECL boss_flame_leviathan_seatAI : public ScriptedAI if(me->hasUnitState(UNIT_STAT_CASTING)) return; - DoMeleeAttackIfReady(); + DoCast(me->getVictim(), SPELL_SEARING_FLAME); + } +}; + +struct TRINITY_DLL_DECL boss_flame_leviathan_overload_deviceAI : public ScriptedAI +{ + boss_flame_leviathan_overload_deviceAI(Creature *c) : ScriptedAI(c) + { + if(const CreatureInfo *cInfo = me->GetCreatureInfo()) + me->SetDisplayId(cInfo->DisplayID_H[0]); // A0 gm, H0 device + } + + void Reset() + { + } + + void DamageTaken(Unit *who, uint32 &damage) + { + if(damage >= me->GetHealth()) + { + damage = 0; + if(!me->hasUnitState(UNIT_STAT_CASTING)) + DoCastAOE(SPELL_OVERLOAD_CIRCUIT); + } } }; @@ -85,11 +254,26 @@ CreatureAI* GetAI_boss_flame_leviathan(Creature *_Creature) return new boss_flame_leviathanAI (_Creature); } +CreatureAI* GetAI_boss_flame_leviathan_turret(Creature *_Creature) +{ + return new boss_flame_leviathan_turretAI (_Creature); +} + CreatureAI* GetAI_boss_flame_leviathan_seat(Creature *_Creature) { return new boss_flame_leviathan_seatAI (_Creature); } +CreatureAI* GetAI_boss_flame_leviathan_defense_turret(Creature *_Creature) +{ + return new boss_flame_leviathan_defense_turretAI (_Creature); +} + +CreatureAI* GetAI_boss_flame_leviathan_overload_device(Creature *_Creature) +{ + return new boss_flame_leviathan_overload_deviceAI (_Creature); +} + void AddSC_boss_flame_leviathan() { Script *newscript; @@ -99,7 +283,22 @@ void AddSC_boss_flame_leviathan() newscript->RegisterSelf(); newscript = new Script; + newscript->Name="boss_flame_leviathan_turret"; + newscript->GetAI = &GetAI_boss_flame_leviathan_turret; + newscript->RegisterSelf(); + + newscript = new Script; newscript->Name="boss_flame_leviathan_seat"; newscript->GetAI = &GetAI_boss_flame_leviathan_seat; newscript->RegisterSelf(); + + newscript = new Script; + newscript->Name="boss_flame_leviathan_defense_turret"; + newscript->GetAI = &GetAI_boss_flame_leviathan_defense_turret; + newscript->RegisterSelf(); + + newscript = new Script; + newscript->Name="boss_flame_leviathan_overload_device"; + newscript->GetAI = &GetAI_boss_flame_leviathan_overload_device; + newscript->RegisterSelf(); } |