Removed all instance scripts so we can have script project back and spells will work again.

This commit is contained in:
hondacrx
2020-12-07 15:29:06 -05:00
parent a702e070f3
commit 900362a7d7
104 changed files with 2273 additions and 41604 deletions
-117
View File
@@ -1,117 +0,0 @@
/*
* Copyright (C) 2012-2020 CypherCore <http://github.com/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 <http://www.gnu.org/licenses/>.
*/
using Framework.Constants;
using Game.AI;
using Game.Entities;
using Game.Maps;
using Game.Scripting;
using Game.Spells;
using System;
using System.Collections.Generic;
namespace Scripts.Pets
{
[Script]
class npc_pet_dk_ebon_gargoyle : CasterAI
{
public npc_pet_dk_ebon_gargoyle(Creature creature) : base(creature) { }
public override void InitializeAI()
{
base.InitializeAI();
ObjectGuid ownerGuid = me.GetOwnerGUID();
if (ownerGuid.IsEmpty())
return;
// Find victim of Summon Gargoyle spell
List<Unit> targets = new List<Unit>();
var u_check = new AnyUnfriendlyUnitInObjectRangeCheck(me, me, 30.0f);
var searcher = new UnitListSearcher(me, targets, u_check);
Cell.VisitAllObjects(me, searcher, 30.0f);
foreach (var iter in targets)
{
if (iter.GetAura(SpellSummonGargoyle1, ownerGuid) != null)
{
me.Attack(iter, false);
break;
}
}
}
public override void JustDied(Unit killer)
{
// Stop Feeding Gargoyle when it dies
Unit owner = me.GetOwner();
if (owner)
owner.RemoveAurasDueToSpell(SpellSummonGargoyle2);
}
// Fly away when dismissed
public override void SpellHit(Unit source, SpellInfo spell)
{
if (spell.Id != SpellDismissGargoyle || !me.IsAlive())
return;
Unit owner = me.GetOwner();
if (!owner || owner != source)
return;
// Stop Fighting
me.AddUnitFlag(UnitFlags.NonAttackable);
// Sanctuary
me.CastSpell(me, SpellSanctuary, true);
me.SetReactState(ReactStates.Passive);
//! HACK: Creature's can't have MOVEMENTFLAG_FLYING
// Fly Away
me.SetCanFly(true);
me.SetSpeedRate(UnitMoveType.Flight, 0.75f);
me.SetSpeedRate(UnitMoveType.Run, 0.75f);
float x = me.GetPositionX() + 20 * (float)Math.Cos(me.GetOrientation());
float y = me.GetPositionY() + 20 * (float)Math.Sin(me.GetOrientation());
float z = me.GetPositionZ() + 40;
me.GetMotionMaster().Clear(false);
me.GetMotionMaster().MovePoint(0, x, y, z);
// Despawn as soon as possible
me.DespawnOrUnsummon(4 * Time.InMilliseconds);
}
const uint SpellSummonGargoyle1 = 49206;
const uint SpellSummonGargoyle2 = 50514;
const uint SpellDismissGargoyle = 50515;
const uint SpellSanctuary = 54661;
}
[Script]
class npc_pet_dk_guardian : AggressorAI
{
public npc_pet_dk_guardian(Creature creature) : base(creature) { }
public override bool CanAIAttack(Unit target)
{
if (!target)
return false;
Unit owner = me.GetOwner();
if (owner && !target.IsInCombatWith(owner))
return false;
return base.CanAIAttack(target);
}
}
}
+125
View File
@@ -0,0 +1,125 @@
/*
* Copyright (C) 2012-2020 CypherCore <http://github.com/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 <http://www.gnu.org/licenses/>.
*/
using Framework.Constants;
using Game.AI;
using Game.Entities;
using Game.Maps;
using Game.Scripting;
using Game.Spells;
using System;
using System.Collections.Generic;
namespace Scripts.Pets
{
namespace DeathKnight
{
struct SpellIds
{
public const uint SummonGargoyle1 = 49206;
public const uint SummonGargoyle2 = 50514;
public const uint DismissGargoyle = 50515;
public const uint Sanctuary = 54661;
}
[Script]
class npc_pet_dk_ebon_gargoyle : CasterAI
{
public npc_pet_dk_ebon_gargoyle(Creature creature) : base(creature) { }
public override void InitializeAI()
{
base.InitializeAI();
ObjectGuid ownerGuid = me.GetOwnerGUID();
if (ownerGuid.IsEmpty())
return;
// Find victim of Summon Gargoyle spell
List<Unit> targets = new List<Unit>();
var u_check = new AnyUnfriendlyUnitInObjectRangeCheck(me, me, 30.0f);
var searcher = new UnitListSearcher(me, targets, u_check);
Cell.VisitAllObjects(me, searcher, 30.0f);
foreach (var iter in targets)
{
if (iter.GetAura(SpellIds.SummonGargoyle1, ownerGuid) != null)
{
me.Attack(iter, false);
break;
}
}
}
public override void JustDied(Unit killer)
{
// Stop Feeding Gargoyle when it dies
Unit owner = me.GetOwner();
if (owner)
owner.RemoveAurasDueToSpell(SpellIds.SummonGargoyle2);
}
// Fly away when dismissed
public override void SpellHit(Unit source, SpellInfo spell)
{
if (spell.Id != SpellIds.DismissGargoyle || !me.IsAlive())
return;
Unit owner = me.GetOwner();
if (!owner || owner != source)
return;
// Stop Fighting
me.AddUnitFlag(UnitFlags.NonAttackable);
// Sanctuary
me.CastSpell(me, SpellIds.Sanctuary, true);
me.SetReactState(ReactStates.Passive);
//! HACK: Creature's can't have MOVEMENTFLAG_FLYING
// Fly Away
me.SetCanFly(true);
me.SetSpeedRate(UnitMoveType.Flight, 0.75f);
me.SetSpeedRate(UnitMoveType.Run, 0.75f);
float x = me.GetPositionX() + 20 * (float)Math.Cos(me.GetOrientation());
float y = me.GetPositionY() + 20 * (float)Math.Sin(me.GetOrientation());
float z = me.GetPositionZ() + 40;
me.GetMotionMaster().Clear(false);
me.GetMotionMaster().MovePoint(0, x, y, z);
// Despawn as soon as possible
me.DespawnOrUnsummon(4 * Time.InMilliseconds);
}
}
[Script]
class npc_pet_dk_guardian : AggressorAI
{
public npc_pet_dk_guardian(Creature creature) : base(creature) { }
public override bool CanAIAttack(Unit target)
{
if (!target)
return false;
Unit owner = me.GetOwner();
if (owner && !target.IsInCombatWith(owner))
return false;
return base.CanAIAttack(target);
}
}
}
}
+51 -41
View File
@@ -22,54 +22,64 @@ using Game.Scripting;
namespace Scripts.Pets
{
[Script]
class npc_pet_gen_mojo : ScriptedAI
namespace Generic
{
public npc_pet_gen_mojo(Creature creature) : base(creature) { }
public override void Reset()
struct SpellIds
{
_victimGUID.Clear();
Unit owner = me.GetOwner();
if (owner)
me.GetMotionMaster().MoveFollow(owner, 0.0f, 0.0f);
public const uint FeelingFroggy = 43906;
public const uint SeductionVisual = 43919;
}
public override void EnterCombat(Unit who) { }
public override void UpdateAI(uint diff) { }
public override void ReceiveEmote(Player player, TextEmotes emote)
struct TextIds
{
me.HandleEmoteCommand((Emote)emote);
Unit owner = me.GetOwner();
if (emote != TextEmotes.Kiss || !owner || !owner.IsTypeId(TypeId.Player) ||
owner.ToPlayer().GetTeam() != player.GetTeam())
{
return;
}
Talk(SayMojo, player);
if (!_victimGUID.IsEmpty())
{
Player victim = Global.ObjAccessor.GetPlayer(me, _victimGUID);
if (victim)
victim.RemoveAura(SpellFeelingFroggy);
}
_victimGUID = player.GetGUID();
DoCast(player, SpellFeelingFroggy, true);
DoCast(me, SpellSeductionVisual, true);
me.GetMotionMaster().MoveFollow(player, 0.0f, 0.0f);
public const uint SayMojo = 0;
}
ObjectGuid _victimGUID;
[Script]
class npc_pet_gen_mojo : ScriptedAI
{
public npc_pet_gen_mojo(Creature creature) : base(creature) { }
const uint SayMojo = 0;
const uint SpellFeelingFroggy = 43906;
const uint SpellSeductionVisual = 43919;
public override void Reset()
{
_victimGUID.Clear();
Unit owner = me.GetOwner();
if (owner)
me.GetMotionMaster().MoveFollow(owner, 0.0f, 0.0f);
}
public override void EnterCombat(Unit who) { }
public override void UpdateAI(uint diff) { }
public override void ReceiveEmote(Player player, TextEmotes emote)
{
me.HandleEmoteCommand((Emote)emote);
Unit owner = me.GetOwner();
if (emote != TextEmotes.Kiss || !owner || !owner.IsTypeId(TypeId.Player) ||
owner.ToPlayer().GetTeam() != player.GetTeam())
{
return;
}
Talk(TextIds.SayMojo, player);
if (!_victimGUID.IsEmpty())
{
Player victim = Global.ObjAccessor.GetPlayer(me, _victimGUID);
if (victim)
victim.RemoveAura(SpellIds.FeelingFroggy);
}
_victimGUID = player.GetGUID();
DoCast(player, SpellIds.FeelingFroggy, true);
DoCast(me, SpellIds.SeductionVisual, true);
me.GetMotionMaster().MoveFollow(player, 0.0f, 0.0f);
}
ObjectGuid _victimGUID;
}
}
}
+81 -71
View File
@@ -22,96 +22,106 @@ using Game.Scripting;
namespace Scripts.Pets
{
[Script]
class npc_pet_hunter_snake_trap : ScriptedAI
namespace Hunter
{
public npc_pet_hunter_snake_trap(Creature creature) : base(creature) { }
public override void EnterCombat(Unit who) { }
public override void Reset()
struct SpellIds
{
_spellTimer = 0;
public const uint CripplingPoison = 30981; // Viper
public const uint DeadlyPoisonPassive = 34657; // Venomous Snake
public const uint MindNumbingPoison = 25810; // Viper
CreatureTemplate Info = me.GetCreatureTemplate();
_isViper = Info.Entry == NpcViper ? true : false;
me.SetMaxHealth((uint)(107 * (me.GetLevel() - 40) * 0.025f));
// Add delta to make them not all hit the same time
uint delta = (RandomHelper.Rand32() % 7) * 100;
me.SetBaseAttackTime(WeaponAttackType.BaseAttack, Info.BaseAttackTime + delta);
//me.SetStatFloatValue(UnitFields.RangedAttackPower, (float)Info.AttackPower);
// Start attacking attacker of owner on first ai update after spawn - move in line of sight may choose better target
if (!me.GetVictim() && me.IsSummon())
{
Unit owner = me.ToTempSummon().GetSummoner();
if (owner)
if (owner.GetAttackerForHelper())
AttackStart(owner.GetAttackerForHelper());
}
if (!_isViper)
DoCast(me, SpellDeadlyPoisonPassive, true);
}
// Redefined for random target selection:
public override void MoveInLineOfSight(Unit who)
struct CreatureIds
{
if (!me.GetVictim() && me.CanCreatureAttack(who))
{
if (me.GetDistanceZ(who) > SharedConst.CreatureAttackRangeZ)
return;
public const int Viper = 19921;
}
float attackRadius = me.GetAttackDistance(who);
if (me.IsWithinDistInMap(who, attackRadius) && me.IsWithinLOSInMap(who))
[Script]
class npc_pet_hunter_snake_trap : ScriptedAI
{
public npc_pet_hunter_snake_trap(Creature creature) : base(creature) { }
public override void EnterCombat(Unit who) { }
public override void Reset()
{
_spellTimer = 0;
CreatureTemplate Info = me.GetCreatureTemplate();
_isViper = Info.Entry == CreatureIds.Viper ? true : false;
me.SetMaxHealth((uint)(107 * (me.GetLevel() - 40) * 0.025f));
// Add delta to make them not all hit the same time
uint delta = (RandomHelper.Rand32() % 7) * 100;
me.SetBaseAttackTime(WeaponAttackType.BaseAttack, Info.BaseAttackTime + delta);
//me.SetStatFloatValue(UnitFields.RangedAttackPower, (float)Info.AttackPower);
// Start attacking attacker of owner on first ai update after spawn - move in line of sight may choose better target
if (!me.GetVictim() && me.IsSummon())
{
if ((RandomHelper.Rand32() % 5) == 0)
Unit owner = me.ToTempSummon().GetSummoner();
if (owner)
if (owner.GetAttackerForHelper())
AttackStart(owner.GetAttackerForHelper());
}
if (!_isViper)
DoCast(me, SpellIds.DeadlyPoisonPassive, true);
}
// Redefined for random target selection:
public override void MoveInLineOfSight(Unit who)
{
if (!me.GetVictim() && me.CanCreatureAttack(who))
{
if (me.GetDistanceZ(who) > SharedConst.CreatureAttackRangeZ)
return;
float attackRadius = me.GetAttackDistance(who);
if (me.IsWithinDistInMap(who, attackRadius) && me.IsWithinLOSInMap(who))
{
me.SetAttackTimer(WeaponAttackType.BaseAttack, (RandomHelper.Rand32() % 10) * 100);
_spellTimer = (RandomHelper.Rand32() % 10) * 100;
AttackStart(who);
if ((RandomHelper.Rand32() % 5) == 0)
{
me.SetAttackTimer(WeaponAttackType.BaseAttack, (RandomHelper.Rand32() % 10) * 100);
_spellTimer = (RandomHelper.Rand32() % 10) * 100;
AttackStart(who);
}
}
}
}
}
public override void UpdateAI(uint diff)
{
if (!UpdateVictim() || !me.GetVictim())
return;
if (me.GetVictim().HasBreakableByDamageCrowdControlAura(me))
public override void UpdateAI(uint diff)
{
me.InterruptNonMeleeSpells(false);
return;
}
if (!UpdateVictim() || !me.GetVictim())
return;
//Viper
if (_isViper)
{
if (_spellTimer <= diff)
if (me.GetVictim().HasBreakableByDamageCrowdControlAura(me))
{
if (RandomHelper.IRand(0, 2) == 0) //33% chance to cast
DoCastVictim(RandomHelper.RAND(SpellMindNumbingPoison, SpellCripplingPoison));
_spellTimer = 3000;
me.InterruptNonMeleeSpells(false);
return;
}
else
_spellTimer -= diff;
//Viper
if (_isViper)
{
if (_spellTimer <= diff)
{
if (RandomHelper.IRand(0, 2) == 0) //33% chance to cast
DoCastVictim(RandomHelper.RAND(SpellIds.MindNumbingPoison, SpellIds.CripplingPoison));
_spellTimer = 3000;
}
else
_spellTimer -= diff;
}
DoMeleeAttackIfReady();
}
DoMeleeAttackIfReady();
bool _isViper;
uint _spellTimer;
}
bool _isViper;
uint _spellTimer;
const uint SpellCripplingPoison = 30981; // Viper
const uint SpellDeadlyPoisonPassive = 34657; // Venomous Snake
const uint SpellMindNumbingPoison = 25810; // Viper
const int NpcViper = 19921;
}
}
+190 -179
View File
@@ -21,221 +21,232 @@ using Game.Entities;
using Game.Maps;
using Game.Scripting;
using System.Collections.Generic;
using System;
namespace Scripts.Pets
{
struct PetMageConst
namespace Mage
{
public const uint SpellCloneMe = 45204;
public const uint SpellMastersThreatList = 58838;
public const uint SpellMageFrostBolt = 59638;
public const uint SpellMageFireBlast = 59637;
public const uint TimerMirrorImageInit = 0;
public const uint TimerMirrorImageFrostBolt = 4000;
public const uint TimerMirrorImageFireBlast = 6000;
}
[Script]
class npc_pet_mage_mirror_image : CasterAI
{
public npc_pet_mage_mirror_image(Creature creature) : base(creature) { }
void Init()
struct SpellIds
{
Unit owner = me.GetCharmerOrOwner();
List<Unit> targets = new List<Unit>();
var u_check = new AnyUnfriendlyUnitInObjectRangeCheck(me, me, 30.0f);
var searcher = new UnitListSearcher(me, targets, u_check);
Cell.VisitAllObjects(me, searcher, 40.0f);
Unit highestThreatUnit = null;
float highestThreat = 0.0f;
Unit nearestPlayer = null;
foreach (var unit in targets)
{
// Consider only units without CC
if (!unit.HasBreakableByDamageCrowdControlAura(unit))
{
// Take first found unit
if (!highestThreatUnit && !unit.IsTypeId(TypeId.Player))
{
highestThreatUnit = unit;
continue;
}
if (!nearestPlayer && unit.IsTypeId(TypeId.Player))
{
nearestPlayer = unit;
continue;
}
// else compare best fit unit with current unit
var triggers = unit.GetThreatManager().GetThreatList();
foreach (var reference in triggers)
{
// Try to find threat referenced to owner
if (reference.GetTarget() == owner)
{
// Check if best fit hostile unit hs lower threat than this current unit
if (highestThreat < reference.GetThreat())
{
// If so, update best fit unit
highestThreat = reference.GetThreat();
highestThreatUnit = unit;
break;
}
}
}
// In case no unit with threat was found so far, always check for nearest unit (only for players)
if (unit.IsTypeId(TypeId.Player))
{
// If this player is closer than the previous one, update it
if (me.GetDistance(unit.GetPosition()) < me.GetDistance(nearestPlayer.GetPosition()))
nearestPlayer = unit;
}
}
}
// Prioritize units with threat referenced to owner
if (highestThreat > 0.0f && highestThreatUnit)
me.Attack(highestThreatUnit, false);
// If there is no such target, try to attack nearest hostile unit if such exists
else if (nearestPlayer)
me.Attack(nearestPlayer, false);
public const uint CloneMe = 45204;
public const uint MastersThreatList = 58838;
public const uint MageFrostBolt = 59638;
public const uint MageFireBlast = 59637;
}
bool IsInThreatList(Unit target)
struct MiscConst
{
Unit owner = me.GetCharmerOrOwner();
public const uint TimerMirrorImageInit = 0;
public const uint TimerMirrorImageFrostBolt = 4000;
public const uint TimerMirrorImageFireBlast = 6000;
}
List<Unit> targets = new List<Unit>();
var u_check = new AnyUnfriendlyUnitInObjectRangeCheck(me, me, 30.0f);
var searcher = new UnitListSearcher(me, targets, u_check);
Cell.VisitAllObjects(me, searcher, 40.0f);
[Script]
class npc_pet_mage_mirror_image : CasterAI
{
public npc_pet_mage_mirror_image(Creature creature) : base(creature) { }
foreach (var unit in targets)
void Init()
{
if (unit == target)
Unit owner = me.GetCharmerOrOwner();
List<Unit> targets = new List<Unit>();
var u_check = new AnyUnfriendlyUnitInObjectRangeCheck(me, me, 30.0f);
var searcher = new UnitListSearcher(me, targets, u_check);
Cell.VisitAllObjects(me, searcher, 40.0f);
Unit highestThreatUnit = null;
float highestThreat = 0.0f;
Unit nearestPlayer = null;
foreach (var unit in targets)
{
// Consider only units without CC
if (!unit.HasBreakableByDamageCrowdControlAura(unit))
{
// Take first found unit
if (!highestThreatUnit && !unit.IsTypeId(TypeId.Player))
{
highestThreatUnit = unit;
continue;
}
if (!nearestPlayer && unit.IsTypeId(TypeId.Player))
{
nearestPlayer = unit;
continue;
}
// else compare best fit unit with current unit
var triggers = unit.GetThreatManager().GetThreatList();
foreach (var reference in triggers)
{
// Try to find threat referenced to owner
if (reference.GetTarget() == owner)
return true;
{
// Check if best fit hostile unit hs lower threat than this current unit
if (highestThreat < reference.GetThreat())
{
// If so, update best fit unit
highestThreat = reference.GetThreat();
highestThreatUnit = unit;
break;
}
}
}
// In case no unit with threat was found so far, always check for nearest unit (only for players)
if (unit.IsTypeId(TypeId.Player))
{
// If this player is closer than the previous one, update it
if (me.GetDistance(unit.GetPosition()) < me.GetDistance(nearestPlayer.GetPosition()))
nearestPlayer = unit;
}
}
}
}
return false;
}
public override void InitializeAI()
{
base.InitializeAI();
Unit owner = me.GetOwner();
if (!owner)
return;
// here mirror image casts on summoner spell (not present in client dbc) 49866
// here should be auras (not present in client dbc): 35657, 35658, 35659, 35660 selfcasted by mirror images (stats related?)
// Clone Me!
owner.CastSpell(me, PetMageConst.SpellCloneMe, false);
}
public override void EnterCombat(Unit victim)
{
if (me.GetVictim() && !me.GetVictim().HasBreakableByDamageCrowdControlAura(me))
{
me.CastSpell(victim, PetMageConst.SpellMageFireBlast, false);
_events.ScheduleEvent(PetMageConst.SpellMageFrostBolt, PetMageConst.TimerMirrorImageInit);
_events.ScheduleEvent(PetMageConst.SpellMageFireBlast, PetMageConst.TimerMirrorImageFireBlast);
}
else
EnterEvadeMode(EvadeReason.Other);
}
public override void Reset()
{
_events.Reset();
}
public override void UpdateAI(uint diff)
{
Unit owner = me.GetCharmerOrOwner();
if (!owner)
return;
Unit target = owner.GetAttackerForHelper();
_events.Update(diff);
// prevent CC interrupts by images
if (me.GetVictim() && me.GetVictim().HasBreakableByDamageCrowdControlAura(me))
{
me.InterruptNonMeleeSpells(false);
return;
// Prioritize units with threat referenced to owner
if (highestThreat > 0.0f && highestThreatUnit)
me.Attack(highestThreatUnit, false);
// If there is no such target, try to attack nearest hostile unit if such exists
else if (nearestPlayer)
me.Attack(nearestPlayer, false);
}
if (me.HasUnitState(UnitState.Casting))
return;
// assign target if image doesnt have any or the target is not actual
if (!target || me.GetVictim() != target)
bool IsInThreatList(Unit target)
{
Unit ownerTarget = null;
Player owner1 = me.GetCharmerOrOwner().ToPlayer();
if (owner1)
ownerTarget = owner1.GetSelectedUnit();
Unit owner = me.GetCharmerOrOwner();
// recognize which victim will be choosen
if (ownerTarget && ownerTarget.IsTypeId(TypeId.Player))
List<Unit> targets = new List<Unit>();
var u_check = new AnyUnfriendlyUnitInObjectRangeCheck(me, me, 30.0f);
var searcher = new UnitListSearcher(me, targets, u_check);
Cell.VisitAllObjects(me, searcher, 40.0f);
foreach (var unit in targets)
{
if (!ownerTarget.HasBreakableByDamageCrowdControlAura(ownerTarget))
me.Attack(ownerTarget, false);
if (unit == target)
{
// Consider only units without CC
if (!unit.HasBreakableByDamageCrowdControlAura(unit))
{
var triggers = unit.GetThreatManager().GetThreatList();
foreach (var reference in triggers)
{
// Try to find threat referenced to owner
if (reference.GetTarget() == owner)
return true;
}
}
}
}
else if (ownerTarget && !ownerTarget.IsTypeId(TypeId.Player) && IsInThreatList(ownerTarget))
return false;
}
public override void InitializeAI()
{
base.InitializeAI();
Unit owner = me.GetOwner();
if (!owner)
return;
// here mirror image casts on summoner spell (not present in client dbc) 49866
// here should be auras (not present in client dbc): 35657, 35658, 35659, 35660 selfcasted by mirror images (stats related?)
// Clone Me!
owner.CastSpell(me, SpellIds.CloneMe, false);
}
public override void EnterCombat(Unit victim)
{
if (me.GetVictim() && !me.GetVictim().HasBreakableByDamageCrowdControlAura(me))
{
if (!ownerTarget.HasBreakableByDamageCrowdControlAura(ownerTarget))
me.Attack(ownerTarget, false);
me.CastSpell(victim, SpellIds.MageFireBlast, false);
_scheduler.Schedule(TimeSpan.FromSeconds(0), task =>
{
DoCastVictim(SpellIds.MageFrostBolt);
task.Repeat(TimeSpan.FromSeconds(4));
});
_scheduler.Schedule(TimeSpan.FromSeconds(6), task =>
{
DoCastVictim(SpellIds.MageFireBlast);
task.Repeat();
});
}
else
Init();
EnterEvadeMode(EvadeReason.Other);
}
_events.ExecuteEvents(spellId =>
public override void Reset()
{
if (spellId == PetMageConst.SpellMageFrostBolt)
{
_events.ScheduleEvent(PetMageConst.SpellMageFrostBolt, PetMageConst.TimerMirrorImageFrostBolt);
DoCastVictim(spellId);
}
else if (spellId == PetMageConst.SpellMageFireBlast)
{
DoCastVictim(spellId);
_events.ScheduleEvent(PetMageConst.SpellMageFireBlast, PetMageConst.TimerMirrorImageFireBlast);
}
});
}
// Do not reload Creature templates on evade mode enter - prevent visual lost
public override void EnterEvadeMode(EvadeReason why)
{
if (me.IsInEvadeMode() || !me.IsAlive())
return;
Unit owner = me.GetCharmerOrOwner();
me.CombatStop(true);
if (owner && !me.HasUnitState(UnitState.Follow))
{
me.GetMotionMaster().Clear(false);
me.GetMotionMaster().MoveFollow(owner, SharedConst.PetFollowDist, me.GetFollowAngle(), MovementSlot.Active);
_scheduler.CancelAll();
}
public override void UpdateAI(uint diff)
{
Unit owner = me.GetCharmerOrOwner();
if (!owner)
return;
Unit target = owner.GetAttackerForHelper();
_scheduler.Update(diff);
// prevent CC interrupts by images
if (me.GetVictim() && me.GetVictim().HasBreakableByDamageCrowdControlAura(me))
{
me.InterruptNonMeleeSpells(false);
return;
}
if (me.HasUnitState(UnitState.Casting))
return;
// assign target if image doesnt have any or the target is not actual
if (!target || me.GetVictim() != target)
{
Unit ownerTarget = null;
Player owner1 = me.GetCharmerOrOwner().ToPlayer();
if (owner1)
ownerTarget = owner1.GetSelectedUnit();
// recognize which victim will be choosen
if (ownerTarget && ownerTarget.IsTypeId(TypeId.Player))
{
if (!ownerTarget.HasBreakableByDamageCrowdControlAura(ownerTarget))
me.Attack(ownerTarget, false);
}
else if (ownerTarget && !ownerTarget.IsTypeId(TypeId.Player) && IsInThreatList(ownerTarget))
{
if (!ownerTarget.HasBreakableByDamageCrowdControlAura(ownerTarget))
me.Attack(ownerTarget, false);
}
else
Init();
}
_events.ExecuteEvents(eventId =>
{
if (eventId == SpellIds.MageFrostBolt)
{
}
else if (eventId == SpellIds.MageFireBlast)
{
}
});
}
// Do not reload Creature templates on evade mode enter - prevent visual lost
public override void EnterEvadeMode(EvadeReason why)
{
if (me.IsInEvadeMode() || !me.IsAlive())
return;
Unit owner = me.GetCharmerOrOwner();
me.CombatStop(true);
if (owner && !me.HasUnitState(UnitState.Follow))
{
me.GetMotionMaster().Clear(false);
me.GetMotionMaster().MoveFollow(owner, SharedConst.PetFollowDist, me.GetFollowAngle(), MovementSlot.Active);
}
Init();
}
Init();
}
}
}
+30 -27
View File
@@ -20,43 +20,46 @@ using Game.AI;
using Game.Entities;
using Game.Scripting;
namespace Scripts.Pets.Priest
namespace Scripts.Pets
{
struct SpellIds
namespace Priest
{
public const uint GlyphOfShadowFiend = 58228;
public const uint ShadowFiendDeath = 57989;
public const uint LightWellCharges = 59907;
}
[Script]
class npc_pet_pri_lightwell : PassiveAI
{
public npc_pet_pri_lightwell(Creature creature) : base(creature)
struct SpellIds
{
DoCast(creature, SpellIds.LightWellCharges, false);
public const uint GlyphOfShadowFiend = 58228;
public const uint ShadowFiendDeath = 57989;
public const uint LightWellCharges = 59907;
}
public override void EnterEvadeMode(EvadeReason why)
[Script]
class npc_pet_pri_lightwell : PassiveAI
{
if (!me.IsAlive())
return;
public npc_pet_pri_lightwell(Creature creature) : base(creature)
{
DoCast(creature, SpellIds.LightWellCharges, false);
}
me.GetThreatManager().ClearAllThreat();
me.CombatStop(true);
me.ResetPlayerDamageReq();
public override void EnterEvadeMode(EvadeReason why)
{
if (!me.IsAlive())
return;
me.GetThreatManager().ClearAllThreat();
me.CombatStop(true);
me.ResetPlayerDamageReq();
}
}
}
[Script]
class npc_pet_pri_shadowfiend : PetAI
{
public npc_pet_pri_shadowfiend(Creature creature) : base(creature) { }
public override void IsSummonedBy(Unit summoner)
[Script]
class npc_pet_pri_shadowfiend : PetAI
{
if (summoner.HasAura(SpellIds.GlyphOfShadowFiend))
DoCastAOE(SpellIds.ShadowFiendDeath);
public npc_pet_pri_shadowfiend(Creature creature) : base(creature) { }
public override void IsSummonedBy(Unit summoner)
{
if (summoner.HasAura(SpellIds.GlyphOfShadowFiend))
DoCastAOE(SpellIds.ShadowFiendDeath);
}
}
}
}
+67 -73
View File
@@ -19,95 +19,89 @@ using Framework.Constants;
using Game.AI;
using Game.Entities;
using Game.Scripting;
using System;
namespace Scripts.Pets
{
[Script]
class npc_pet_shaman_earth_elemental : ScriptedAI
namespace Shaman
{
public npc_pet_shaman_earth_elemental(Creature creature) : base(creature) { }
public override void Reset()
struct SpellIds
{
_events.Reset();
_events.ScheduleEvent(EventAngeredEarth, 0);
me.ApplySpellImmune(0, SpellImmunity.School, SpellSchoolMask.Nature, true);
//npc_pet_shaman_earth_elemental
public const uint AngeredEarth = 36213;
//npc_pet_shaman_fire_elemental
public const uint FireBlast = 57984;
public const uint FireNova = 12470;
public const uint FireShield = 13376;
}
public override void UpdateAI(uint diff)
[Script]
class npc_pet_shaman_earth_elemental : ScriptedAI
{
if (!UpdateVictim())
return;
public npc_pet_shaman_earth_elemental(Creature creature) : base(creature) { }
_events.Update(diff);
if (_events.ExecuteEvent() == EventAngeredEarth)
public override void Reset()
{
DoCastVictim(SpellAngeredEarth);
_events.ScheduleEvent(EventAngeredEarth, RandomHelper.URand(5000, 20000));
_scheduler.CancelAll();
_scheduler.Schedule(TimeSpan.FromSeconds(0), task =>
{
DoCastVictim(SpellIds.AngeredEarth);
task.Repeat(TimeSpan.FromSeconds(5), TimeSpan.FromSeconds(20));
});
me.ApplySpellImmune(0, SpellImmunity.School, SpellSchoolMask.Nature, true);
}
DoMeleeAttackIfReady();
}
const int EventAngeredEarth = 1;
const uint SpellAngeredEarth = 36213;
}
[Script]
public class npc_pet_shaman_fire_elemental : ScriptedAI
{
public npc_pet_shaman_fire_elemental(Creature creature) : base(creature) { }
public override void Reset()
{
_events.Reset();
_events.ScheduleEvent(EventFireNova, RandomHelper.URand(5000, 20000));
_events.ScheduleEvent(EventFireBlast, RandomHelper.URand(5000, 20000));
_events.ScheduleEvent(EventFireShield, 0);
me.ApplySpellImmune(0, SpellImmunity.School, SpellSchoolMask.Fire, true);
}
public override void UpdateAI(uint diff)
{
if (!UpdateVictim())
return;
if (me.HasUnitState(UnitState.Casting))
return;
_events.Update(diff);
_events.ExecuteEvents(eventId =>
public override void UpdateAI(uint diff)
{
switch (eventId)
{
case EventFireNova:
DoCastVictim(SpellFireNova);
_events.ScheduleEvent(EventFireNova, RandomHelper.URand(5000, 20000));
break;
case EventFireShield:
DoCastVictim(SpellFireShield);
_events.ScheduleEvent(EventFireShield, 2000);
break;
case EventFireBlast:
DoCastVictim(SpellFireBlast);
_events.ScheduleEvent(EventFireBlast, RandomHelper.URand(5000, 20000));
break;
default:
break;
}
});
if (!UpdateVictim())
return;
DoMeleeAttackIfReady();
_scheduler.Update(diff);
DoMeleeAttackIfReady();
}
}
const int EventFireNova = 1;
const int EventFireShield = 2;
const int EventFireBlast = 3;
[Script]
public class npc_pet_shaman_fire_elemental : ScriptedAI
{
public npc_pet_shaman_fire_elemental(Creature creature) : base(creature) { }
const uint SpellFireBlast = 57984;
const uint SpellFireNova = 12470;
const uint SpellFireShield = 13376;
public override void Reset()
{
_scheduler.CancelAll();
_scheduler.Schedule(TimeSpan.FromSeconds(5), TimeSpan.FromSeconds(20), task =>
{
DoCastVictim(SpellIds.FireNova);
task.Repeat(TimeSpan.FromSeconds(5), TimeSpan.FromSeconds(20));
});
_scheduler.Schedule(TimeSpan.FromSeconds(5), TimeSpan.FromSeconds(20), task =>
{
DoCastVictim(SpellIds.FireShield);
task.Repeat(TimeSpan.FromSeconds(2));
});
_scheduler.Schedule(TimeSpan.FromSeconds(0), task =>
{
DoCastVictim(SpellIds.FireBlast);
task.Repeat(TimeSpan.FromSeconds(5), TimeSpan.FromSeconds(20));
});
me.ApplySpellImmune(0, SpellImmunity.School, SpellSchoolMask.Fire, true);
}
public override void UpdateAI(uint diff)
{
if (!UpdateVictim())
return;
_scheduler.Update(diff);
if (me.HasUnitState(UnitState.Casting))
return;
DoMeleeAttackIfReady();
}
}
}
}