diff --git a/Source/Game/OutdoorPVP/Zones/HellfirePeninsulaPvP.cs b/Source/Game/OutdoorPVP/Zones/HellfirePeninsulaPvP.cs index 4d0ecc6b3..07f3aaf0c 100644 --- a/Source/Game/OutdoorPVP/Zones/HellfirePeninsulaPvP.cs +++ b/Source/Game/OutdoorPVP/Zones/HellfirePeninsulaPvP.cs @@ -19,10 +19,11 @@ using Framework.Constants; using Game.Entities; using Game.Maps; using Game.Network.Packets; +using Game.Scripting; namespace Game.PvP { - public class HellfirePeninsulaPvP : OutdoorPvP + class HellfirePeninsulaPvP : OutdoorPvP { public HellfirePeninsulaPvP() { @@ -309,6 +310,17 @@ namespace Game.PvP uint m_TowerType; } + [Script] + class OutdoorPvP_hellfire_peninsula : OutdoorPvPScript + { + public OutdoorPvP_hellfire_peninsula() : base("outdoorpvp_hp") { } + + public override OutdoorPvP GetOutdoorPvP() + { + return new HellfirePeninsulaPvP(); + } + } + struct HPConst { public static uint[] LangCapture_A = { DefenseMessages.BrokenHillTakenAlliance, DefenseMessages.OverlookTakenAlliance, DefenseMessages.StadiumTakenAlliance }; diff --git a/Source/Game/Scripting/CoreScripts.cs b/Source/Game/Scripting/CoreScripts.cs index 12ff52182..159f547a9 100644 --- a/Source/Game/Scripting/CoreScripts.cs +++ b/Source/Game/Scripting/CoreScripts.cs @@ -64,6 +64,26 @@ namespace Game.Scripting return null; } + public void ClearGossipMenuFor(Player player) { player.PlayerTalkClass.ClearMenus(); } + // Using provided text, not from DB + public void AddGossipItemFor(Player player, GossipOptionIcon icon, string text, uint sender, uint action) + { + player.PlayerTalkClass.GetGossipMenu().AddMenuItem(-1, icon, text, sender, action, "", 0); + } + // Using provided texts, not from DB + public void AddGossipItemFor(Player player, GossipOptionIcon icon, string text, uint sender, uint action, string popupText, uint popupMoney, bool coded) + { + player.PlayerTalkClass.GetGossipMenu().AddMenuItem(-1, icon, text, sender, action, popupText, popupMoney, coded); + } + // Uses gossip item info from DB + public void AddGossipItemFor(Player player, uint gossipMenuID, uint gossipMenuItemID, uint sender, uint action) + { + player.PlayerTalkClass.GetGossipMenu().AddMenuItem(gossipMenuID, gossipMenuItemID, sender, action); + } + public void SendGossipMenuFor(Player player, uint npcTextID, ObjectGuid guid) { player.PlayerTalkClass.SendGossipMenu(npcTextID, guid); } + public void SendGossipMenuFor(Player player, uint npcTextID, Creature creature) { if (creature) SendGossipMenuFor(player, npcTextID, creature.GetGUID()); } + public void CloseGossipMenuFor(Player player) { player.PlayerTalkClass.SendCloseGossip(); } + string _name; } diff --git a/Source/Scripts/EasternKingdoms/ScarletEnclave/Chapter1.cs b/Source/Scripts/EasternKingdoms/ScarletEnclave/Chapter1.cs index 87f093ced..2c3ba64fa 100644 --- a/Source/Scripts/EasternKingdoms/ScarletEnclave/Chapter1.cs +++ b/Source/Scripts/EasternKingdoms/ScarletEnclave/Chapter1.cs @@ -20,16 +20,115 @@ using Game; using Game.AI; using Game.Entities; using Game.Scripting; +using Game.Movement; +using Game.Spells; +using System.Collections.Generic; namespace Scripts.EasternKingdoms { - enum UnworthyInitiatePhase + struct SpellIds { - Chained, - ToEquip, - Equiping, - ToAttack, - Attacking + //Unworthy Initiate + public const uint SoulPrisonChainSelf = 54612; + public const uint SoulPrisonChain = 54613; + public const uint DKInitateVisual = 51519; + public const uint IcyTouch = 52372; + public const uint PlagueStrike = 52373; + public const uint BloodStrike = 52374; + public const uint DeathCoil = 52375; + + //EyeOfAcherus + public const uint EyeVisual = 51892; + public const uint EyeFlightBoost = 51923; + public const uint EyeFlight = 51890; + + //DeathKnightInitiate + public const uint Duel = 52996; + //public const uint SPELL_DUEL_TRIGGERED = 52990; + public const uint DuelVictory = 52994; + public const uint DuelFlag = 52991; + public const uint Grovel = 7267; + + //DarkRiderOfAcherus + public const uint DespawnHorse = 51918; + + //SalanarTheHorseman + public const uint EffectStolenHorse = 52263; + public const uint DeliverStolenHorse = 52264; + public const uint CallDarkRider = 52266; + public const uint EffectOvertake = 52349; + public const uint RealmOfShadows = 52693; + + //ScarletMinerCart + public const uint CartCheck = 54173; + public const uint SummonCart = 52463; + public const uint SummonMiner = 52464; + public const uint CartDrag = 52465; + } + + struct TextIds + { + //Unworthy Initiate + public const uint SayEventStart = 0; + public const uint SayEventAttack = 1; + + //EyeOfAcherus + public const uint TalkMoveStart = 0; + public const uint TalkControl = 1; + + //DeathKnightInitiate + public const uint SayDuel = 0; + + //DarkRiderOfAcherus + public const uint SayDarkRider = 0; + + //SalanarTheHorseman + public const uint SaySalanar = 0; + + //ScarletMiner + public const uint SayScarletMiner0 = 0; + public const uint SayScarletMiner1 = 1; + } + + struct CreatureIds + { + //SalanarTheHorseman + public const uint DarkRiderOfAcherus = 28654; + public const uint SalanarInRealmOfShadows = 28788; + + //dkc1_gothik + public const uint Ghouls = 28845; + public const uint Ghosts = 28846; + + //ScarletMinerCart + public const uint Miner = 28841; + } + + struct EventIds + { + //Unworthy Initiate + public const uint IcyTouch = 1; + public const uint PlagueStrike = 2; + public const uint BloodStrike = 3; + public const uint DeathCoil = 4; + } + + struct MiscConst + { + //Unworthy Initiate + public static uint[] acherus_soul_prison = { 191577, 191580, 191581, 191582, 191583, 191584, 191585, 191586, 191587, 191588, 191589, 191590 }; + + //EyeOfAcherus + public static Position EyeOFAcherusFallPoint = new Position(2361.21f, -5660.45f, 496.7444f, 0.0f); + + //DeathKnightInitiate + public static uint QuestDeathChallenge = 12733; + public static uint FactionHostile = 2068; + + //SalanarTheHorseman + public static uint GossipSalanarMenu = 9739; + public static uint GossipSalanarOption = 0; + public static uint QuestIntoRealmOfShadows = 12687; } [Script] @@ -37,15 +136,21 @@ namespace Scripts.EasternKingdoms { public npc_unworthy_initiate(Creature creature) : base(creature) { + Initialize(); me.SetReactState(ReactStates.Passive); if (me.GetCurrentEquipmentId() == 0) me.SetCurrentEquipmentId((byte)me.GetOriginalEquipmentId()); } - public override void Reset() + void Initialize() { anchorGUID.Clear(); phase = UnworthyInitiatePhase.Chained; + } + + public override void Reset() + { + Initialize(); _events.Reset(); me.SetFaction(7); me.SetFlag(UnitFields.Flags, UnitFlags.ImmuneToPc); @@ -55,10 +160,10 @@ namespace Scripts.EasternKingdoms public override void EnterCombat(Unit who) { - _events.ScheduleEvent(EventIcyTouch, 1000, 1); - _events.ScheduleEvent(EventPlagueStrike, 3000, 1); - _events.ScheduleEvent(EventBloodStrike, 2000, 1); - _events.ScheduleEvent(EventDeathCoil, 5000, 1); + _events.ScheduleEvent(EventIds.IcyTouch, 1000, 1); + _events.ScheduleEvent(EventIds.PlagueStrike, 3000, 1); + _events.ScheduleEvent(EventIds.BloodStrike, 2000, 1); + _events.ScheduleEvent(EventIds.DeathCoil, 5000, 1); } public override void MovementInform(MovementGeneratorType type, uint id) @@ -69,11 +174,12 @@ namespace Scripts.EasternKingdoms if (id == 1) { wait_timer = 5000; - me.CastSpell(me, SpellDKInitateVisual, true); + me.LoadEquipment(1); + me.CastSpell(me, SpellIds.DKInitateVisual, true); Player starter = Global.ObjAccessor.GetPlayer(me, playerGUID); if (starter) - Global.CreatureTextMgr.SendChat(me, (byte)SayEventAttack, null, ChatMsg.Addon, Language.Addon, CreatureTextRange.Normal, 0, Team.Other, false, starter); + Talk(TextIds.SayEventAttack, starter); phase = UnworthyInitiatePhase.ToAttack; } @@ -85,14 +191,14 @@ namespace Scripts.EasternKingdoms phase = UnworthyInitiatePhase.ToEquip; me.SetStandState(UnitStandStateType.Stand); - me.RemoveAurasDueToSpell(SpellSoulPrisonChainSelf); - me.RemoveAurasDueToSpell(SpellSoulPrisonChain); + me.RemoveAurasDueToSpell(SpellIds.SoulPrisonChainSelf); + me.RemoveAurasDueToSpell(SpellIds.SoulPrisonChain); float z; anchor.GetContactPoint(me, out anchorX, out anchorY, out z, 1.0f); playerGUID = target.GetGUID(); - Talk(SayEventStart); + Talk(TextIds.SayEventStart); } public override void UpdateAI(uint diff) @@ -106,7 +212,7 @@ namespace Scripts.EasternKingdoms if (anchor) { anchor.GetAI().SetGUID(me.GetGUID()); - anchor.CastSpell(me, SpellSoulPrisonChain, true); + anchor.CastSpell(me, SpellIds.SoulPrisonChain, true); anchorGUID = anchor.GetGUID(); } else @@ -117,7 +223,7 @@ namespace Scripts.EasternKingdoms for (byte i = 0; i < 12; ++i) { - GameObject temp_prison = me.FindNearestGameObject(acherus_soul_prison[i], 30); + GameObject temp_prison = me.FindNearestGameObject(MiscConst.acherus_soul_prison[i], 30); if (temp_prison) { if (me.IsWithinDist(temp_prison, dist, false)) @@ -174,25 +280,25 @@ namespace Scripts.EasternKingdoms { switch (eventId) { - case EventIcyTouch: - DoCastVictim(SpellIcyTouch); + case EventIds.IcyTouch: + DoCastVictim(SpellIds.IcyTouch); _events.DelayEvents(1000, 1); - _events.ScheduleEvent(EventIcyTouch, 5000, 1); + _events.ScheduleEvent(EventIds.IcyTouch, 5000, 1); break; - case EventPlagueStrike: - DoCastVictim(SpellPlagueStrike); + case EventIds.PlagueStrike: + DoCastVictim(SpellIds.PlagueStrike); _events.DelayEvents(1000, 1); - _events.ScheduleEvent(EventPlagueStrike, 5000, 1); + _events.ScheduleEvent(EventIds.PlagueStrike, 5000, 1); break; - case EventBloodStrike: - DoCastVictim(SpellBloodStrike); + case EventIds.BloodStrike: + DoCastVictim(SpellIds.BloodStrike); _events.DelayEvents(1000, 1); - _events.ScheduleEvent(EventBloodStrike, 5000, 1); + _events.ScheduleEvent(EventIds.BloodStrike, 5000, 1); break; - case EventDeathCoil: - DoCastVictim(SpellDeathCoil); + case EventIds.DeathCoil: + DoCastVictim(SpellIds.DeathCoil); _events.DelayEvents(1000, 1); - _events.ScheduleEvent(EventDeathCoil, 5000, 1); + _events.ScheduleEvent(EventIds.DeathCoil, 5000, 1); break; } }); @@ -210,24 +316,14 @@ namespace Scripts.EasternKingdoms float anchorX, anchorY; ObjectGuid anchorGUID; - const uint SpellSoulPrisonChainSelf = 54612; - const uint SpellSoulPrisonChain = 54613; - const uint SpellDKInitateVisual = 51519; - - const uint SpellIcyTouch = 52372; - const uint SpellPlagueStrike = 52373; - const uint SpellBloodStrike = 52374; - const uint SpellDeathCoil = 52375; - - const uint SayEventStart = 0; - const uint SayEventAttack = 1; - - const uint EventIcyTouch = 1; - const uint EventPlagueStrike = 2; - const uint EventBloodStrike = 3; - const uint EventDeathCoil = 4; - - static uint[] acherus_soul_prison = { 191577, 191580, 191581, 191582, 191583, 191584, 191585, 191586, 191587, 191588, 191589, 191590 }; + enum UnworthyInitiatePhase + { + Chained, + ToEquip, + Equiping, + ToAttack, + Attacking, + } } [Script] @@ -272,82 +368,706 @@ namespace Scripts.EasternKingdoms } } - struct EyeOfAcherus - { - public const uint EyeHugeDisplayId = 26320; - public const uint EyeSmallDisplayId = 25499; - - public const uint SpellEyePhasemask = 70889; - public const uint SpellEyeVisual = 51892; - public const uint SpellEyeFlight = 51923; - public const uint SpellEyeFlightBoost = 51890; - public const uint SpellEyeControl = 51852; - - public const string SayEyeLaunched = "Eye of Acherus is launched towards its destination."; - public const string SayEyeUnderControl = "You are now in control of the eye."; - - public static float[] EyeDestination = { 1750.8276f, -5873.788f, 147.2266f }; - } - [Script] class npc_eye_of_acherus : ScriptedAI { public npc_eye_of_acherus(Creature creature) : base(creature) { - Reset(); + me.SetDisplayId(me.GetCreatureTemplate().ModelId1); + + Player owner = me.GetCharmerOrOwner().ToPlayer(); + if (owner) + { + me.GetCharmInfo().InitPossessCreateSpells(); + owner.SendAutoRepeatCancel(me); + } + + me.SetReactState(ReactStates.Passive); + + me.GetMotionMaster().MovePoint(1, MiscConst.EyeOFAcherusFallPoint, false); + + MoveSplineInit init = new MoveSplineInit(me); + init.MoveTo(MiscConst.EyeOFAcherusFallPoint.GetPositionX(), MiscConst.EyeOFAcherusFallPoint.GetPositionY(), MiscConst.EyeOFAcherusFallPoint.GetPositionZ(), false); + init.SetFall(); + init.Launch(); } - uint startTimer; + public override void OnCharmed(bool apply) { } + + public override void UpdateAI(uint diff) + { + _scheduler.Update(diff); + } + + public override void MovementInform(MovementGeneratorType movementType, uint pointId) + { + if (movementType == MovementGeneratorType.Waypoint && pointId == 2) + { + me.SetSheath(SheathState.Melee); + me.RemoveAllAuras(); + + Player owner = me.GetCharmerOrOwner().ToPlayer(); + if (owner) + { + owner.RemoveAura(SpellIds.EyeFlightBoost); + for (UnitMoveType i = 0; i < UnitMoveType.Max; ++i) + me.SetSpeedRate(i, owner.GetSpeedRate(i)); + + Talk(TextIds.TalkControl, owner); + } + me.SetDisableGravity(false); + DoCast(me, SpellIds.EyeFlight); + } + + if (movementType == MovementGeneratorType.Point && pointId == 1) + { + me.SetDisableGravity(true); + me.SetControlled(true, UnitState.Root); + _scheduler.Schedule(System.TimeSpan.FromSeconds(5), task => + { + DoCast(me, SpellIds.EyeFlightBoost); + + me.SetControlled(false, UnitState.Root); + + Player owner = me.GetCharmerOrOwner().ToPlayer(); + if (owner) + { + for (UnitMoveType i = 0; i < UnitMoveType.Max; ++i) + me.SetSpeedRate(i, owner.GetSpeedRate(i)); + Talk(TextIds.TalkMoveStart, owner); + } + me.GetMotionMaster().MovePath(me.GetEntry() * 100, false); + }); + } + } + } + + [Script] + class npc_death_knight_initiate : CreatureScript + { + public npc_death_knight_initiate() : base("npc_death_knight_initiate") { } + + class npc_death_knight_initiateAI : CombatAI + { + public npc_death_knight_initiateAI(Creature creature) : base(creature) + { + Initialize(); + } + + void Initialize() + { + m_uiDuelerGUID.Clear(); + m_uiDuelTimer = 5000; + m_bIsDuelInProgress = false; + lose = false; + } + + public override void Reset() + { + Initialize(); + + me.RestoreFaction(); + base.Reset(); + me.SetFlag(UnitFields.Flags, UnitFlags.Unk15); + } + + public override void SpellHit(Unit pCaster, SpellInfo pSpell) + { + if (!m_bIsDuelInProgress && pSpell.Id == SpellIds.Duel) + { + m_uiDuelerGUID = pCaster.GetGUID(); + Talk(TextIds.SayDuel, pCaster); + m_bIsDuelInProgress = true; + } + } + + public override void DamageTaken(Unit pDoneBy, ref uint uiDamage) + { + if (m_bIsDuelInProgress && pDoneBy.IsControlledByPlayer()) + { + if (pDoneBy.GetGUID() != m_uiDuelerGUID && pDoneBy.GetOwnerGUID() != m_uiDuelerGUID) // other players cannot help + uiDamage = 0; + else if (uiDamage >= me.GetHealth()) + { + uiDamage = 0; + + if (!lose) + { + pDoneBy.RemoveGameObject(SpellIds.DuelFlag, true); + pDoneBy.AttackStop(); + me.CastSpell(pDoneBy, SpellIds.DuelVictory, true); + lose = true; + me.CastSpell(me, SpellIds.Grovel, true); + me.RestoreFaction(); + } + } + } + } + + public override void UpdateAI(uint uiDiff) + { + if (!UpdateVictim()) + { + if (m_bIsDuelInProgress) + { + if (m_uiDuelTimer <= uiDiff) + { + me.SetFaction(MiscConst.FactionHostile); + + Unit unit = Global.ObjAccessor.GetUnit(me, m_uiDuelerGUID); + if (unit) + AttackStart(unit); + } + else + m_uiDuelTimer -= uiDiff; + } + return; + } + + if (m_bIsDuelInProgress) + { + if (lose) + { + if (!me.HasAura(SpellIds.Grovel)) + EnterEvadeMode(); + return; + } + else if (me.GetVictim() && me.GetVictim().IsTypeId(TypeId.Player) && me.GetVictim().HealthBelowPct(10)) + { + me.GetVictim().CastSpell(me.GetVictim(), SpellIds.Grovel, true); // beg + me.GetVictim().RemoveGameObject(SpellIds.DuelFlag, true); + EnterEvadeMode(); + return; + } + } + + /// @todo spells + + base.UpdateAI(uiDiff); + } + + bool lose; + ObjectGuid m_uiDuelerGUID; + uint m_uiDuelTimer; + public bool m_bIsDuelInProgress; + } + + public override bool OnGossipSelect(Player player, Creature creature, uint sender, uint action) + { + ClearGossipMenuFor(player); + if (action == eTradeskill.GossipActionInfoDef) + { + CloseGossipMenuFor(player); + + if (player.IsInCombat() || creature.IsInCombat()) + return true; + + npc_death_knight_initiateAI pInitiateAI = creature.GetAI(); + if (pInitiateAI != null) + { + if (pInitiateAI.m_bIsDuelInProgress) + return true; + } + + creature.RemoveFlag(UnitFields.Flags, UnitFlags.ImmuneToPc); + creature.RemoveFlag(UnitFields.Flags, UnitFlags.Unk15); + + player.CastSpell(creature, SpellIds.Duel, false); + player.CastSpell(player, SpellIds.DuelFlag, true); + } + return true; + } + + public override bool OnGossipHello(Player player, Creature creature) + { + if (player.GetQuestStatus(MiscConst.QuestDeathChallenge) == QuestStatus.Incomplete && creature.IsFullHealth()) + { + if (player.HealthBelowPct(10)) + return true; + + if (player.IsInCombat() || creature.IsInCombat()) + return true; + + AddGossipItemFor(player, Player.GetDefaultGossipMenuForSource(creature), 0, eTradeskill.GossipSenderMain, eTradeskill.GossipActionInfoDef); + SendGossipMenuFor(player, player.GetGossipTextId(creature), creature.GetGUID()); + } + return true; + } + + public override CreatureAI GetAI(Creature creature) + { + return new npc_death_knight_initiateAI(creature); + } + } + + [Script] + class npc_dark_rider_of_acherus : ScriptedAI + { + public npc_dark_rider_of_acherus(Creature creature) : base(creature) + { + Initialize(); + } + + void Initialize() + { + PhaseTimer = 4000; + Phase = 0; + Intro = false; + TargetGUID.Clear(); + } public override void Reset() { - startTimer = 2000; - } - - public override void AttackStart(Unit u) { } - - public override void MoveInLineOfSight(Unit u) { } - - public override void JustDied(Unit killer) - { - Unit charmer = me.GetCharmer(); - if (charmer) - charmer.RemoveAurasDueToSpell(EyeOfAcherus.SpellEyeControl); + Initialize(); } public override void UpdateAI(uint diff) { - if (me.IsCharmed()) - { - if (startTimer <= diff) // fly to start point - { - me.CastSpell(me, EyeOfAcherus.SpellEyePhasemask, true); - me.CastSpell(me, EyeOfAcherus.SpellEyeVisual, true); - me.CastSpell(me, EyeOfAcherus.SpellEyeFlightBoost, true); - me.SetSpeedRate(UnitMoveType.Flight, 4f); - - me.GetMotionMaster().MovePoint(0, EyeOfAcherus.EyeDestination[0], EyeOfAcherus.EyeDestination[1], EyeOfAcherus.EyeDestination[2]); - return; - } - else - startTimer -= diff; - } - else - me.ForcedDespawn(); - } - - public override void MovementInform(MovementGeneratorType type, uint id) - { - if (type != MovementGeneratorType.Point || id != 0) + if (!Intro || TargetGUID.IsEmpty()) return; - me.SetDisplayId(EyeOfAcherus.EyeSmallDisplayId); + if (PhaseTimer <= diff) + { + switch (Phase) + { + case 0: + Talk(TextIds.SayDarkRider); + PhaseTimer = 5000; + Phase = 1; + break; + case 1: + Unit target = Global.ObjAccessor.GetUnit(me, TargetGUID); + if (target) + DoCast(target, SpellIds.DespawnHorse, true); + PhaseTimer = 3000; + Phase = 2; + break; + case 2: + me.SetVisible(false); + PhaseTimer = 2000; + Phase = 3; + break; + case 3: + me.DespawnOrUnsummon(); + break; + default: + break; + } + } + else + PhaseTimer -= diff; + } - me.CastSpell(me, EyeOfAcherus.SpellEyeFlight, true); - me.Say(EyeOfAcherus.SayEyeUnderControl, Language.Universal); + public void InitDespawnHorse(Unit who) + { + if (!who) + return; - if (me.GetCharmer() && me.GetCharmer().IsTypeId(TypeId.Player)) - me.GetCharmer().ToPlayer().SetClientControl(me, true); + TargetGUID = who.GetGUID(); + me.SetWalk(true); + me.SetSpeedRate(UnitMoveType.Run, 0.4f); + me.GetMotionMaster().MoveChase(who); + me.SetTarget(TargetGUID); + Intro = true; + } + + uint PhaseTimer; + uint Phase; + bool Intro; + ObjectGuid TargetGUID; + } + + [Script] + class npc_salanar_the_horseman : ScriptedAI + { + public npc_salanar_the_horseman(Creature creature) : base(creature) { } + + public override void sGossipSelect(Player player, uint menuId, uint gossipListId) + { + if (menuId == MiscConst.GossipSalanarMenu && gossipListId == MiscConst.GossipSalanarOption) + { + player.CastSpell(player, SpellIds.RealmOfShadows, true); + player.PlayerTalkClass.SendCloseGossip(); + } + } + + public override void SpellHit(Unit caster, SpellInfo spell) + { + if (spell.Id == SpellIds.DeliverStolenHorse) + { + if (caster.IsTypeId(TypeId.Unit) && caster.IsVehicle()) + { + Unit charmer = caster.GetCharmer(); + if (charmer) + { + if (charmer.HasAura(SpellIds.EffectStolenHorse)) + { + charmer.RemoveAurasDueToSpell(SpellIds.EffectStolenHorse); + caster.RemoveFlag(UnitFields.NpcFlags, NPCFlags.SpellClick); + caster.SetFaction(35); + DoCast(caster, SpellIds.CallDarkRider, true); + Creature Dark_Rider = me.FindNearestCreature(CreatureIds.DarkRiderOfAcherus, 15); + if (Dark_Rider) + Dark_Rider.GetAI().InitDespawnHorse(caster); + } + } + } + } + } + + public override void MoveInLineOfSight(Unit who) + { + base.MoveInLineOfSight(who); + + if (who.IsTypeId(TypeId.Unit) && who.IsVehicle() && me.IsWithinDistInMap(who, 5.0f)) + { + Unit charmer = who.GetCharmer(); + if (charmer) + { + Player player = charmer.ToPlayer(); + if (player) + { + // for quest Into the Realm of Shadows(QUEST_INTO_REALM_OF_SHADOWS) + if (me.GetEntry() == CreatureIds.SalanarInRealmOfShadows && player.GetQuestStatus(MiscConst.QuestIntoRealmOfShadows) == QuestStatus.Incomplete) + { + player.GroupEventHappens(MiscConst.QuestIntoRealmOfShadows, me); + Talk(TextIds.SaySalanar); + charmer.RemoveAurasDueToSpell(SpellIds.EffectOvertake); + Creature creature = who.ToCreature(); + if (creature) + { + creature.DespawnOrUnsummon(); + //creature.Respawn(true); + } + } + + player.RemoveAurasDueToSpell(SpellIds.RealmOfShadows); + } + } + } } } + + [Script] + class npc_ros_dark_rider : ScriptedAI + { + public npc_ros_dark_rider(Creature creature) : base(creature) { } + + public override void EnterCombat(Unit who) + { + me.ExitVehicle(); + } + + public override void Reset() + { + Creature deathcharger = me.FindNearestCreature(28782, 30); + if (!deathcharger) + return; + + deathcharger.RestoreFaction(); + deathcharger.RemoveFlag(UnitFields.NpcFlags, NPCFlags.SpellClick); + deathcharger.SetFlag(UnitFields.Flags, UnitFlags.NotSelectable); + if (!me.GetVehicle() && deathcharger.IsVehicle() && deathcharger.GetVehicleKit().HasEmptySeat(0)) + me.EnterVehicle(deathcharger); + } + + public override void JustDied(Unit killer) + { + Creature deathcharger = me.FindNearestCreature(28782, 30); + if (!deathcharger) + return; + + if (killer.IsTypeId(TypeId.Player) && deathcharger.IsTypeId(TypeId.Unit) && deathcharger.IsVehicle()) + { + deathcharger.SetFlag(UnitFields.NpcFlags, NPCFlags.SpellClick); + deathcharger.RemoveFlag(UnitFields.Flags, UnitFlags.NotSelectable); + deathcharger.SetFaction(2096); + } + } + } + + [Script] + class npc_dkc1_gothik : ScriptedAI + { + public npc_dkc1_gothik(Creature creature) : base(creature) { } + + public override void MoveInLineOfSight(Unit who) + { + base.MoveInLineOfSight(who); + + if (who.GetEntry() == CreatureIds.Ghouls && me.IsWithinDistInMap(who, 10.0f)) + { + Unit owner = who.GetOwner(); + if (owner) + { + Player player = owner.ToPlayer(); + if (player) + { + Creature creature = who.ToCreature(); + if (player.GetQuestStatus(12698) == QuestStatus.Incomplete) + creature.CastSpell(owner, 52517, true); + + /// @todo Creatures must not be removed, but, must instead + // stand next to Gothik and be commanded into the pit + // and dig into the ground. + creature.DespawnOrUnsummon(); + + if (player.GetQuestStatus(12698) == QuestStatus.Complete) + owner.RemoveAllMinionsByEntry(CreatureIds.Ghosts); + } + } + } + } + } + + [Script] + class npc_scarlet_ghoul : ScriptedAI + { + public npc_scarlet_ghoul(Creature creature) : base(creature) + { + // Ghouls should display their Birth Animation + // Crawling out of the ground + //DoCast(me, 35177, true); + //me.MonsterSay("Mommy?", LANG_UNIVERSAL, 0); + me.SetReactState(ReactStates.Defensive); + } + + void FindMinions(Unit owner) + { + List MinionList = new List(); + owner.GetAllMinionsByEntry(MinionList, CreatureIds.Ghouls); + + foreach (TempSummon summon in MinionList) + if (summon.GetOwnerGUID() == me.GetOwnerGUID()) + if (summon.IsInCombat() && summon.getAttackerForHelper()) + AttackStart(summon.getAttackerForHelper()); + } + + public override void UpdateAI(uint diff) + { + if (!me.IsInCombat()) + { + Unit owner = me.GetOwner(); + if (owner) + { + Player plrOwner = owner.ToPlayer(); + if (plrOwner && plrOwner.IsInCombat()) + { + if (plrOwner.getAttackerForHelper() && plrOwner.getAttackerForHelper().GetEntry() == CreatureIds.Ghosts) + AttackStart(plrOwner.getAttackerForHelper()); + else + FindMinions(owner); + } + } + } + + if (!UpdateVictim() || !me.GetVictim()) + return; + + //ScriptedAI::UpdateAI(diff); + //Check if we have a current target + if (me.GetVictim().GetEntry() == CreatureIds.Ghosts) + { + if (me.isAttackReady()) + { + //If we are within range melee the target + if (me.IsWithinMeleeRange(me.GetVictim())) + { + me.AttackerStateUpdate(me.GetVictim()); + me.resetAttackTimer(); + } + } + } + } + } + + [Script] + class npc_scarlet_miner_cart : PassiveAI + { + public npc_scarlet_miner_cart(Creature creature) : base(creature) + { + me.SetDisplayId(me.GetCreatureTemplate().ModelId1); // Modelid2 is a horse. + } + + public override void JustSummoned(Creature summon) + { + if (summon.GetEntry() == CreatureIds.Miner) + { + _minerGUID = summon.GetGUID(); + summon.GetAI().SetGUID(_playerGUID); + } + } + + public override void SummonedCreatureDespawn(Creature summon) + { + if (summon.GetEntry() == CreatureIds.Miner) + _minerGUID.Clear(); + } + + public override void DoAction(int param) + { + Creature miner = ObjectAccessor.GetCreature(me, _minerGUID); + if (miner) + { + me.SetWalk(false); + + // Not 100% correct, but movement is smooth. Sometimes miner walks faster + // than normal, this speed is fast enough to keep up at those times. + me.SetSpeedRate(UnitMoveType.Run, 1.25f); + + me.GetMotionMaster().MoveFollow(miner, 1.0f, 0); + } + } + + public override void PassengerBoarded(Unit who, sbyte seatId, bool apply) + { + if (apply) + { + _playerGUID = who.GetGUID(); + me.CastSpell((Unit)null, SpellIds.SummonMiner, true); + } + else + { + _playerGUID.Clear(); + Creature miner = ObjectAccessor.GetCreature(me, _minerGUID); + if (miner) + miner.DespawnOrUnsummon(); + } + } + + ObjectGuid _minerGUID; + ObjectGuid _playerGUID; + } + + [Script] + class npc_scarlet_minerAI : npc_escortAI + { + public npc_scarlet_minerAI(Creature creature) : base(creature) + { + Initialize(); + me.SetReactState(ReactStates.Passive); + } + + void Initialize() + { + carGUID.Clear(); + IntroTimer = 0; + IntroPhase = 0; + } + + public override void Reset() + { + Initialize(); + } + + public override void IsSummonedBy(Unit summoner) + { + carGUID = summoner.GetGUID(); + } + + void InitWaypoint() + { + AddWaypoint(1, 2389.03f, -5902.74f, 109.014f, 5000); + AddWaypoint(2, 2341.812012f, -5900.484863f, 102.619743f); + AddWaypoint(3, 2306.561279f, -5901.738281f, 91.792419f); + AddWaypoint(4, 2300.098389f, -5912.618652f, 86.014885f); + AddWaypoint(5, 2294.142090f, -5927.274414f, 75.316849f); + AddWaypoint(6, 2286.984375f, -5944.955566f, 63.714966f); + AddWaypoint(7, 2280.001709f, -5961.186035f, 54.228283f); + AddWaypoint(8, 2259.389648f, -5974.197754f, 42.359348f); + AddWaypoint(9, 2242.882812f, -5984.642578f, 32.827850f); + AddWaypoint(10, 2217.265625f, -6028.959473f, 7.675705f); + AddWaypoint(11, 2202.595947f, -6061.325684f, 5.882018f); + AddWaypoint(12, 2188.974609f, -6080.866699f, 3.370027f); + + if (RandomHelper.URand(0, 1) != 0) + { + AddWaypoint(13, 2176.483887f, -6110.407227f, 1.855181f); + AddWaypoint(14, 2172.516602f, -6146.752441f, 1.074235f); + AddWaypoint(15, 2138.918457f, -6158.920898f, 1.342926f); + AddWaypoint(16, 2129.866699f, -6174.107910f, 4.380779f); + AddWaypoint(17, 2117.709473f, -6193.830078f, 13.3542f, 10000); + } + else + { + AddWaypoint(13, 2184.190186f, -6166.447266f, 0.968877f); + AddWaypoint(14, 2234.265625f, -6163.741211f, 0.916021f); + AddWaypoint(15, 2268.071777f, -6158.750977f, 1.822252f); + AddWaypoint(16, 2270.028320f, -6176.505859f, 6.340538f); + AddWaypoint(17, 2271.739014f, -6195.401855f, 13.3542f, 10000); + } + } + + public override void SetGUID(ObjectGuid guid, int id = 0) + { + InitWaypoint(); + Start(false, false, guid); + SetDespawnAtFar(false); + } + + public override void WaypointReached(uint waypointId) + { + switch (waypointId) + { + case 1: + { + Unit car = ObjectAccessor.GetCreature(me, carGUID); + if (car) + me.SetFacingToObject(car); + Talk(TextIds.SayScarletMiner0); + SetRun(true); + IntroTimer = 4000; + IntroPhase = 1; + break; + } + case 17: + { + Unit car = ObjectAccessor.GetCreature(me, carGUID); + if (car) + { + me.SetFacingToObject(car); + car.Relocate(car.GetPositionX(), car.GetPositionY(), me.GetPositionZ() + 1); + car.StopMoving(); + car.RemoveAura(SpellIds.CartDrag); + } + Talk(TextIds.SayScarletMiner1); + break; + } + default: + break; + } + } + + public override void UpdateAI(uint diff) + { + if (IntroPhase != 0) + { + if (IntroTimer <= diff) + { + if (IntroPhase == 1) + { + Creature car = ObjectAccessor.GetCreature(me, carGUID); + if (car) + DoCast(car, SpellIds.CartDrag); + IntroTimer = 800; + IntroPhase = 2; + } + else + { + Creature car = ObjectAccessor.GetCreature(me, carGUID); + if (car) + car.GetAI().DoAction(0); + IntroPhase = 0; + } + } + else + IntroTimer -= diff; + } + base.UpdateAI(diff); + } + + uint IntroTimer; + uint IntroPhase; + ObjectGuid carGUID; + } } diff --git a/Source/Scripts/Outlands/HellfirePeninsula.cs b/Source/Scripts/Outlands/HellfirePeninsula.cs index 4b7dacca9..dfb8edddc 100644 --- a/Source/Scripts/Outlands/HellfirePeninsula.cs +++ b/Source/Scripts/Outlands/HellfirePeninsula.cs @@ -298,16 +298,5 @@ namespace Scripts.Outlands const uint SPELL_SUMMON_POO = 37688; const uint NPC_DERANGED_HELBOAR = 16863; } - - [Script] - class HellfirePeninsulaPvPScript : OutdoorPvPScript - { - public HellfirePeninsulaPvPScript() : base("outdoorpvp_hp") { } - - public override OutdoorPvP GetOutdoorPvP() - { - return new HellfirePeninsulaPvP(); - } - } }