/* * Copyright (C) 2012-2017 CypherCore * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ using Framework.Constants; using Game.AI; using Game.Entities; using Game.Maps; using Game.Scripting; using Game.Spells; using System; namespace Scripts.Northrend.AzjolNerub.Ahnkahet.PrinceTaldaram { struct SpellIds { public const uint Bloodthirst = 55968; // Trigger Spell + Add Aura public const uint ConjureFlameSphere = 55931; public const uint FlameSphereSummon1 = 55895; // 1x 30106 public const uint FlameSphereSummon2 = 59511; // 1x 31686 public const uint FlameSphereSummon3 = 59512; // 1x 31687 public const uint FlameSphereSpawnEffect = 55891; public const uint FlameSphereVisual = 55928; public const uint FlameSpherePeriodic = 55926; public const uint FlameSphereDeathEffect = 55947; public const uint EmbraceOfTheVampyr = 55959; public const uint Vanish = 55964; public const uint BeamVisual = 60342; public const uint HoverFall = 60425; } struct CreatureIds { public const uint FlameSphere1 = 30106; public const uint FlameSphere2 = 31686; public const uint FlameSphere3 = 31687; } struct TextIds { public const uint Say1 = 0; public const uint SayWarning = 1; public const uint SayAggro = 2; public const uint SaySlay = 3; public const uint SayDeath = 4; public const uint SayFeed = 5; public const uint SayVanish = 6; } struct Misc { public const uint EventConjureFlameSpheres = 1; public const uint EventBloodthirst = 2; public const uint EventVanish = 3; public const uint EventJustVanished = 4; public const uint EventVanished = 5; public const uint EventFeeding = 6; // Flame Sphere public const uint EventStartMove = 7; public const uint EventDespawn = 8; public const uint DataEmbraceDmg = 20000; public const uint DataEmbraceDmgH = 40000; public const float DataSphereDistance = 25.0f; public const float DataSphereAngleOffset = MathFunctions.PI / 2; public const float DataGroundPositionZ = 11.30809f; } [Script] class boss_prince_taldaram : CreatureScript { public boss_prince_taldaram() : base("boss_prince_taldaram") { } public class boss_prince_taldaramAI : BossAI { public boss_prince_taldaramAI(Creature creature) : base(creature, DataTypes.PrinceTaldaram) { me.SetDisableGravity(true); _embraceTakenDamage = 0; } public override void Reset() { _Reset(); _flameSphereTargetGUID.Clear(); _embraceTargetGUID.Clear(); _embraceTakenDamage = 0; } public override void EnterCombat(Unit who) { _EnterCombat(); Talk(TextIds.SayAggro); _events.ScheduleEvent(Misc.EventBloodthirst, 10000); _events.ScheduleEvent(Misc.EventVanish, RandomHelper.URand(25000, 35000)); _events.ScheduleEvent(Misc.EventConjureFlameSpheres, 5000); } public override void JustSummoned(Creature summon) { base.JustSummoned(summon); switch (summon.GetEntry()) { case CreatureIds.FlameSphere1: case CreatureIds.FlameSphere2: case CreatureIds.FlameSphere3: summon.GetAI().SetGUID(_flameSphereTargetGUID); break; } } public override void UpdateAI(uint diff) { if (!UpdateVictim()) return; _events.Update(diff); if (me.HasUnitState(UnitState.Casting)) return; _events.ExecuteEvents(eventId => { switch (eventId) { case Misc.EventBloodthirst: DoCast(me, SpellIds.Bloodthirst); _events.ScheduleEvent(Misc.EventBloodthirst, 10000); break; case Misc.EventConjureFlameSpheres: // random target? Unit victim = me.GetVictim(); if (victim) { _flameSphereTargetGUID = victim.GetGUID(); DoCast(victim, SpellIds.ConjureFlameSphere); } _events.ScheduleEvent(Misc.EventConjureFlameSpheres, 15000); break; case Misc.EventVanish: { var players = me.GetMap().GetPlayers(); uint targets = 0; foreach (var player in players) { if (player && player.IsAlive()) ++targets; } if (targets > 2) { Talk(TextIds.SayVanish); DoCast(me, SpellIds.Vanish); me.SetInCombatState(true); // Prevents the boss from resetting _events.DelayEvents(500); _events.ScheduleEvent(Misc.EventJustVanished, 500); Unit embraceTarget = SelectTarget(SelectAggroTarget.Random, 0, 100.0f, true); if (embraceTarget) _embraceTargetGUID = embraceTarget.GetGUID(); } _events.ScheduleEvent(Misc.EventVanish, RandomHelper.URand(25000, 35000)); break; } case Misc.EventJustVanished: { Unit embraceTarget = GetEmbraceTarget(); if (embraceTarget) { me.GetMotionMaster().Clear(); me.SetSpeedRate(UnitMoveType.Walk, 2.0f); me.GetMotionMaster().MoveChase(embraceTarget); } _events.ScheduleEvent(Misc.EventVanished, 1300); } break; case Misc.EventVanished: { Unit embraceTarget = GetEmbraceTarget(); if (embraceTarget) DoCast(embraceTarget, SpellIds.EmbraceOfTheVampyr); Talk(TextIds.SayFeed); me.GetMotionMaster().Clear(); me.SetSpeedRate(UnitMoveType.Walk, 1.0f); me.GetMotionMaster().MoveChase(me.GetVictim()); _events.ScheduleEvent(Misc.EventFeeding, 20000); } break; case Misc.EventFeeding: _embraceTargetGUID.Clear(); break; default: break; } }); DoMeleeAttackIfReady(); } public override void DamageTaken(Unit doneBy, ref uint damage) { Unit embraceTarget = GetEmbraceTarget(); if (embraceTarget && embraceTarget.IsAlive()) { _embraceTakenDamage += damage; if (_embraceTakenDamage > DungeonMode(Misc.DataEmbraceDmg, Misc.DataEmbraceDmgH)) { _embraceTargetGUID.Clear(); me.CastStop(); } } } public override void JustDied(Unit killer) { Talk(TextIds.SayDeath); _JustDied(); } public override void KilledUnit(Unit victim) { if (!victim.IsTypeId(TypeId.Player)) return; if (victim.GetGUID() == _embraceTargetGUID) _embraceTargetGUID.Clear(); Talk(TextIds.SaySlay); } public bool CheckSpheres() { for (byte i = 0; i < 2; ++i) { if (instance.GetData(DataTypes.Sphere1 + i) == 0) return false; } RemovePrison(); return true; } Unit GetEmbraceTarget() { if (!_embraceTargetGUID.IsEmpty()) return Global.ObjAccessor.GetUnit(me, _embraceTargetGUID); return null; } void RemovePrison() { me.RemoveFlag(UnitFields.Flags, UnitFlags.NotSelectable); me.RemoveAurasDueToSpell(SpellIds.BeamVisual); me.SetHomePosition(me.GetPositionX(), me.GetPositionY(), Misc.DataGroundPositionZ, me.GetOrientation()); DoCast(SpellIds.HoverFall); me.SetDisableGravity(false); me.GetMotionMaster().MoveLand(0, me.GetHomePosition()); Talk(TextIds.SayWarning); instance.HandleGameObject(instance.GetGuidData(DataTypes.PrinceTaldaramPlatform), true); } ObjectGuid _flameSphereTargetGUID; ObjectGuid _embraceTargetGUID; uint _embraceTakenDamage; } public override CreatureAI GetAI(Creature creature) { return GetInstanceAI(creature); } } [Script] // 30106, 31686, 31687 - Flame Sphere class npc_prince_taldaram_flame_sphere : CreatureScript { public npc_prince_taldaram_flame_sphere() : base("npc_prince_taldaram_flame_sphere") { } class npc_prince_taldaram_flame_sphereAI : ScriptedAI { public npc_prince_taldaram_flame_sphereAI(Creature creature) : base(creature) { } public override void Reset() { DoCast(me, SpellIds.FlameSphereSpawnEffect, true); DoCast(me, SpellIds.FlameSphereVisual, true); _flameSphereTargetGUID.Clear(); _events.Reset(); _events.ScheduleEvent(Misc.EventStartMove, 3 * Time.InMilliseconds); _events.ScheduleEvent(Misc.EventDespawn, 13 * Time.InMilliseconds); } public override void SetGUID(ObjectGuid guid, int id = 0) { _flameSphereTargetGUID = guid; } public override void EnterCombat(Unit who) { } public override void MoveInLineOfSight(Unit who) { } public override void UpdateAI(uint diff) { _events.Update(diff); _events.ExecuteEvents(eventId => { switch (eventId) { case Misc.EventStartMove: { DoCast(me, SpellIds.FlameSpherePeriodic, true); /// @todo: find correct values float angleOffset = 0.0f; float distOffset = Misc.DataSphereDistance; switch (me.GetEntry()) { case CreatureIds.FlameSphere1: break; case CreatureIds.FlameSphere2: angleOffset = Misc.DataSphereAngleOffset; break; case CreatureIds.FlameSphere3: angleOffset = -Misc.DataSphereAngleOffset; break; default: return; } Unit sphereTarget = Global.ObjAccessor.GetUnit(me, _flameSphereTargetGUID); if (!sphereTarget) return; float angle = me.GetAngle(sphereTarget) + angleOffset; float x = me.GetPositionX() + distOffset * (float)Math.Cos(angle); float y = me.GetPositionY() + distOffset * (float)Math.Sin(angle); /// @todo: correct speed me.GetMotionMaster().MovePoint(0, x, y, me.GetPositionZ()); break; } case Misc.EventDespawn: DoCast(me, SpellIds.FlameSphereDeathEffect, true); me.DespawnOrUnsummon(1000); break; default: break; } }); } ObjectGuid _flameSphereTargetGUID; } public override CreatureAI GetAI(Creature creature) { return new npc_prince_taldaram_flame_sphereAI(creature); } } [Script] // 193093, 193094 - Ancient Nerubian Device class go_prince_taldaram_sphere : GameObjectScript { public go_prince_taldaram_sphere() : base("go_prince_taldaram_sphere") { } public override bool OnGossipHello(Player player, GameObject go) { InstanceScript instance = go.GetInstanceScript(); if (instance == null) return false; Creature PrinceTaldaram = ObjectAccessor.GetCreature(go, instance.GetGuidData(DataTypes.PrinceTaldaram)); if (PrinceTaldaram && PrinceTaldaram.IsAlive()) { go.SetFlag(GameObjectFields.Flags, GameObjectFlags.NotSelectable); go.SetGoState(GameObjectState.Active); switch (go.GetEntry()) { case GameObjectIds.Sphere1: instance.SetData(DataTypes.Sphere1, (uint)EncounterState.InProgress); PrinceTaldaram.GetAI().Talk(TextIds.Say1); break; case GameObjectIds.Sphere2: instance.SetData(DataTypes.Sphere2, (uint)EncounterState.InProgress); PrinceTaldaram.GetAI().Talk(TextIds.Say1); break; } PrinceTaldaram.GetAI().CheckSpheres(); } return true; } } [Script] // 55931 - Conjure Flame Sphere class spell_prince_taldaram_conjure_flame_sphere : SpellScriptLoader { public spell_prince_taldaram_conjure_flame_sphere() : base("spell_prince_taldaram_conjure_flame_sphere") { } class spell_prince_taldaram_conjure_flame_sphere_SpellScript : SpellScript { public override bool Validate(SpellInfo spellInfo) { return ValidateSpellInfo(SpellIds.FlameSphereSummon1, SpellIds.FlameSphereSummon2, SpellIds.FlameSphereSummon3); } void HandleScript(uint effIndex) { Unit caster = GetCaster(); caster.CastSpell(caster, SpellIds.FlameSphereSummon1, true); if (caster.GetMap().IsHeroic()) { caster.CastSpell(caster, SpellIds.FlameSphereSummon2, true); caster.CastSpell(caster, SpellIds.FlameSphereSummon3, true); } } public override void Register() { OnEffectHitTarget.Add(new EffectHandler(HandleScript, 0, SpellEffectName.Dummy)); } } public override SpellScript GetSpellScript() { return new spell_prince_taldaram_conjure_flame_sphere_SpellScript(); } } [Script] // 55895, 59511, 59512 - Flame Sphere Summon class spell_prince_taldaram_flame_sphere_summon : SpellScriptLoader { public spell_prince_taldaram_flame_sphere_summon() : base("spell_prince_taldaram_flame_sphere_summon") { } class spell_prince_taldaram_flame_sphere_summon_SpellScript : SpellScript { void SetDest(ref SpellDestination dest) { dest.RelocateOffset(new Position(0.0f, 0.0f, 5.5f, 0.0f)); } public override void Register() { OnDestinationTargetSelect.Add(new DestinationTargetSelectHandler(SetDest, 0, Targets.DestCaster)); } } public override SpellScript GetSpellScript() { return new spell_prince_taldaram_flame_sphere_summon_SpellScript(); } } }