public virtual NPC Summon(SpellCast cast, ref Vector3 targetLoc, NPCEntry entry) { var caster = cast.CasterUnit; var duration = cast.Spell.GetDuration(cast.CasterReference); NPC minion; if (caster != null) { minion = caster.SpawnMinion(entry, ref targetLoc, duration); } else { minion = entry.Create(cast.TargetMap.DifficultyIndex); minion.Position = targetLoc; minion.Brain.IsRunning = true; minion.Phase = cast.Phase; cast.Map.AddObject(minion); } if (caster is Character) { minion.Level = caster.Level; } minion.Summoner = caster; minion.Creator = cast.CasterReference.EntityId; return minion; }
public DynamicObject(SpellCast cast, float radius) : this(cast.CasterUnit, cast.Spell.SpellId, radius, cast.Caster.Region, cast.TargetLoc) { }
public virtual NPC Summon(SpellCast cast, ref Vector3 targetLoc, NPCEntry entry) { var caster = cast.CasterUnit; var pet = caster.SpawnMinion(entry, ref targetLoc, cast.Spell.GetDuration(caster.CasterInfo)); pet.Summoner = caster; pet.Creator = caster.EntityId; return pet; }
internal void NotifyCancelled(SpellCast cast, SpellFailedReason reason) { var evt = Cancelling; if (evt != null) { evt(cast, reason); } }
internal void NotifyCasted(SpellCast cast) { var evt = Casted; if (evt != null) { evt(cast); } }
/// <summary> /// Called when this Unit got the given debuff by the given SpellCast /// </summary> /// <param name="cast"></param> internal void OnDebuff(SpellCast cast, Aura debuff) { // force combat mode IsInCombat = true; var evt = Debuff; if (evt != null) { evt(this, cast, debuff); } }
public override NPC Summon(SpellCast cast, ref Vector3 targetLoc, NPCEntry entry) { var caster = cast.CasterUnit; if (caster is Character) { return ((Character)caster).SpawnPet(entry, ref targetLoc, cast.Spell.GetDuration(caster.SharedReference)); } else { return base.Summon(cast, ref targetLoc, entry); } }
/// <summary> /// Triggers the Casting event /// </summary> internal SpellFailedReason NotifyCasting(SpellCast cast) { var evt = Casting; if (evt != null) { var err = evt(cast); if (err != SpellFailedReason.Ok) { cast.Cancel(err); return err; } } return SpellFailedReason.Ok; }
/// <summary> /// Ensure that the constraints are correct for the Flag aura to be applied /// </summary> protected override void CheckInitialize(SpellCast creatingCast, ObjectReference casterReference, Unit target, ref SpellFailedReason failReason) { if (!(target is Character)) { failReason = SpellFailedReason.BadTargets; } else { Instance = target.Region as WarsongGulch; if (Instance == null) { failReason = SpellFailedReason.IncorrectArea; } } }
/// <summary> /// Correct 3.0.9 /// </summary> public static void SendSpellMiss(SpellCast cast, bool display, ICollection<MissedTarget> missedTargets) { using (var packet = new RealmPacketOut(RealmServerOpCode.SMSG_SPELLLOGMISS, 34)) { packet.Write(cast.Spell.Id); packet.Write(cast.CasterReference.EntityId); packet.Write(display);// TODO: test this value. Its a bool that seems to determine whether to display this packet in the combat log packet.Write(missedTargets.Count); foreach (var miss in missedTargets) { packet.Write(miss.Target.EntityId); packet.Write((byte)miss.Reason); } cast.SendPacketToArea(packet); } }
protected override void CheckInitialize(SpellCast creatingCast, ObjectReference casterReference, Unit target, ref SpellFailedReason failReason) { if (target is Character) { var chr = (Character)target; var ap = target.TotalMeleeAP; var sp = chr.GetDamageDoneMod(DamageSchool.Holy); if (ap > sp) { totalBonus = ap; } else { totalBonus = sp; } } }
/// <summary> /// Find valid targets for AI cast during preparation /// </summary> SpellFailedReason PrepareAI(SpellCast cast) { var caster = cast.CasterUnit; cast.SourceLoc = caster.Position; if (caster.Target != null) { caster.SpellCast.TargetLoc = caster.Target.Position; } // TODO: Init handlers //var targets = FindValidTargetsForCaster(caster); //if (targets == null) //{ // return SpellFailedReason.NoValidTargets; //} return SpellFailedReason.NoValidTargets; }
public static void SendCastStart(SpellCast cast) { // TODO: can len be dynamic? int len = 150; var spell = cast.Spell; if (spell == null) return; using (var packet = new RealmPacketOut(RealmServerOpCode.SMSG_SPELL_START, len)) { // Common to start and go packets WriteCaster(cast, packet); packet.Write(cast.Id); packet.Write(spell.Id); packet.Write((int)cast.StartFlags); // start specific stuff packet.Write(cast.CastDelay); WriteTargets(packet, cast); if ((cast.StartFlags & CastFlags.Flag_0x800) != 0) { packet.Write(0); } if ((cast.StartFlags & CastFlags.Flag_0x200000) != 0) { byte b1 = 0; byte b2 = 0; packet.Write(b1); packet.Write(b2); for (int i = 0; i < 6; i++) { byte mask = (byte)(1 << i); if ((mask & b1) != 0) { if (!((mask & b2) != 0)) { packet.WriteByte(0); } } } } if ((cast.StartFlags & CastFlags.Ranged) != 0) { WriteAmmoInfo(cast, packet); } if ((cast.StartFlags & CastFlags.Flag_0x4000000) != 0) { // since 3.2.0 packet.Write(0); packet.Write(0); } if (cast.TargetFlags.Has(SpellTargetFlags.DestinationLocation)) { packet.Write((byte)0); // unk 3.3.x? } cast.Caster.SendPacketToArea(packet, true); } }
internal AuraEffectHandler CreateAuraEffectHandler(ObjectReference caster, Unit target, ref SpellFailedReason failedReason, SpellCast triggeringCast) { var handler = AuraEffectHandlerCreator(); if (triggeringCast != null && triggeringCast.TriggerEffect != null && triggeringCast.TriggerEffect.OverrideEffectValue) { if (Spell.Effects.Length > 1) { // it does not make sense to override multiple effects with a single effect... log.Warn("Spell {0} had overriding SpellEffect although the spell that was triggered had {2} (> 1) effects", Spell, Spell.Effects.Length); } handler.m_spellEffect = triggeringCast.TriggerEffect; } else { handler.m_spellEffect = this; } handler.BaseEffectValue = CalcEffectValue(caster); handler.CheckInitialize(triggeringCast, caster, target, ref failedReason); return(handler); }
public static void SendUnitCastStart(IRealmClient client, SpellCast cast, WorldObject target) { // TODO: research and implement this. // maybe sent for all targets in SpellCast object? using (var packet = new RealmPacketOut(RealmServerOpCode.SMSG_UNIT_SPELLCAST_START, 28)) { cast.Caster.EntityId.WritePacked(packet); // caster pguid target.EntityId.WritePacked(packet); // target pguid packet.Write(cast.Spell.Id); // spell id packet.Write(cast.Spell.CastDelay); // cast time? packet.Write(cast.Spell.CastDelay); // cast time mod? client.Send(packet); } }
public ReadinessHandler(SpellCast cast, SpellEffect effect) : base(cast, effect) { }
public QuestCompleteEffectHandler(SpellCast cast, SpellEffect effect) : base(cast, effect) { }
/// <summary> /// Sent after spell start. Triggers the casting animation /// </summary> public static void SendSpellGo(ObjectBase caster2, SpellCast cast, ICollection<WorldObject> hitTargets, ICollection<CastMiss> missedTargets) { // TODO: Dynamic packet length? if (!cast.IsCasting) { return; } //int len = 200; int len = 24 + (hitTargets != null ? hitTargets.Count * 8 : 0) + (missedTargets != null ? missedTargets.Count * 10 : 0); using (var packet = new RealmPacketOut(RealmServerOpCode.SMSG_SPELL_GO, len)) { //caster1.EntityId.WritePacked(packet); cast.Caster.EntityId.WritePacked(packet); caster2.EntityId.WritePacked(packet); packet.Write(cast.Id); packet.Write(cast.Spell.Id); var castGoFlags = cast.GoFlags; packet.Write((int)castGoFlags); //packet.Write(Util.Utility.GetEpochTime()); packet.Write(Utility.GetEpochTime()); //packet.Write(cast.CastDelay); packet.WriteByte(hitTargets != null ? hitTargets.Count : 0); if (hitTargets != null) { foreach (var target in hitTargets) { packet.Write(target.EntityId); if (target is Character) { SendCastSuccess(cast.Caster, cast.Spell.Id, target as Character); } } } packet.WriteByte(missedTargets != null ? missedTargets.Count : 0); if (missedTargets != null) { foreach (var miss in missedTargets) { packet.Write(miss.Target.EntityId); packet.Write((byte)miss.Reason); if (miss.Reason == CastMissReason.Reflect) { packet.Write((byte)0);// relfectreason } } } WriteTargets(packet, cast); if ((castGoFlags & CastFlags.Flag_0x800) != 0) { packet.Write(0); } if ((castGoFlags & CastFlags.Flag_0x200000) != 0) { byte b1 = 0; byte b2 = 0; packet.Write(b1); packet.Write(b2); for (int i = 0; i < 6; i++) { byte mask = (byte)(1 << i); if ((mask & b1) != 0) { if (!((mask & b2) != 0)) { packet.WriteByte(0); } } } } if ((castGoFlags & CastFlags.Flag_0x20000) != 0) { packet.WriteFloat(0); packet.Write(0); } if ((cast.StartFlags & CastFlags.Ranged) != 0) { WriteAmmoInfo(cast, packet); } if ((castGoFlags & CastFlags.Flag_0x80000) != 0) { packet.Write(0); packet.Write(0); } if (cast.TargetFlags.Has(SpellTargetFlags.DestinationLocation)) { packet.Write((byte)0); // unk 3.3.x? } cast.Caster.SendPacketToArea(packet, true); } }
/// <summary> /// Spell went wrong or got cancelled /// </summary> internal static void SendCastFailPackets(SpellCast spellCast, SpellFailedReason reason) { if (spellCast.Client == null) { return; } SendCastFailed(spellCast.Client, spellCast.Id, spellCast.Spell, reason); SendSpellFailure(spellCast, reason); SendSpellFailedOther(spellCast, reason); }
public DeathStrikeHealHandler(SpellCast cast, SpellEffect effect) : base(cast, effect) { }
internal AuraEffectHandler CreateAuraEffectHandler(ObjectReference caster, Unit target, ref SpellFailedReason failedReason, SpellCast triggeringCast) { var handler = AuraEffectHandlerCreator(); if (triggeringCast != null && triggeringCast.TriggerEffect != null && triggeringCast.TriggerEffect.OverrideEffectValue) { if (Spell.Effects.Length > 1) { // it does not make sense to override multiple effects with a single effect... log.Warn("Spell {0} had overriding SpellEffect although the spell that was triggered had {2} (> 1) effects", Spell, Spell.Effects.Length); } handler.m_spellEffect = triggeringCast.TriggerEffect; } else { handler.m_spellEffect = this; } handler.BaseEffectValue = CalcEffectValue(caster); handler.CheckInitialize(triggeringCast, caster, target, ref failedReason); return handler; }
public DamageFromPrcAtackHandler(SpellCast cast, SpellEffect effect) : base(cast, effect) { }
public AddBleedWeaponDamageHandler(SpellCast cast, SpellEffect effect) : base(cast, effect) { }
public override NPC Summon(SpellCast cast, ref Vector3 targetLoc, NPCEntry entry) { var pet = base.Summon(cast, ref targetLoc, entry); return(pet); }
protected SpellEffectHandler(SpellCast cast, SpellEffect effect) { m_cast = cast; Effect = effect; }
public CastAnotherSpellHandler(SpellCast cast, SpellEffect effect) : base(cast, effect) { }
static void WriteAmmoInfo(SpellCast cast, RealmPacketOut packet) { var caster = cast.Caster; if (caster is Character) { var weapon = ((Unit)caster).RangedWeapon as Item; if (weapon != null) { var inv = ((Character)caster).Inventory; var templ = weapon.Template; if (!templ.IsThrowable) { var ammo = inv.Ammo; if (ammo != null) { templ = ammo.Template; } } packet.Write(templ.DisplayId); packet.Write((uint)templ.InventorySlotType); return; } } // resort to default packet.Write(5996); packet.Write((uint)InventorySlotType.Ammo); }
public BurnoutHandler(SpellCast cast, SpellEffect effect) : base(cast, effect) { }
private static void WriteTargets(RealmPacketOut packet, SpellCast cast) { var flags = cast.TargetFlags; if (flags == 0 || flags == SpellTargetFlags.Self) { var spell = cast.Spell; if (cast.Selected is Unit && !spell.IsAreaSpell && (spell.Visual != 0 || spell.IsWeaponAbility)) { flags = SpellTargetFlags.Unit; } } packet.Write((uint)flags); if (flags.Has( SpellTargetFlags.SpellTargetFlag_Dynamic_0x10000 | SpellTargetFlags.Corpse | SpellTargetFlags.Object | SpellTargetFlags.PvPCorpse | SpellTargetFlags.Unit)) { if (cast.Selected == null) { #if DEBUG log.Warn("{0} casted Spell {1} with TargetFlags {2} but with nothing Selected", cast.Caster, cast.Spell, flags); #endif packet.Write((byte)0); } else { cast.Selected.EntityId.WritePacked(packet); } } // 0x1010 if (flags.Has(SpellTargetFlags.TradeItem | SpellTargetFlags.Item)) { if (cast.UsedItem != null) { cast.UsedItem.EntityId.WritePacked(packet); } } // 0x20 if (flags.Has(SpellTargetFlags.SourceLocation)) { if (cast.Selected != null) { cast.Selected.EntityId.WritePacked(packet); } else { packet.Write((byte)0); } packet.Write(cast.SourceLoc.X); packet.Write(cast.SourceLoc.Y); packet.Write(cast.SourceLoc.Z); } // 0x40 if (flags.Has(SpellTargetFlags.DestinationLocation)) { if (cast.Selected != null) { cast.Selected.EntityId.WritePacked(packet); } else { packet.Write((byte)0); } packet.Write(cast.TargetLoc); } // 0x2000 if (flags.Has(SpellTargetFlags.String)) { packet.WriteCString(cast.StringTarget); } }
/// <summary>Get rid of circular references</summary> internal void Dispose() { this.m_cast = (SpellCast)null; SpellChannel.SpellChannelPool.Recycle(this); }
private static void WriteCaster(SpellCast cast, RealmPacketOut packet) { if (cast.Caster == null) return; if (cast.UsedItem != null) { //packet.Write(cast.UsedItem.EntityId); cast.UsedItem.EntityId.WritePacked(packet); } else { //cast.UsedItem.EntityId.WritePacked(packet); cast.Caster.EntityId.WritePacked(packet); } //packet.Write(cast.Caster.EntityId); cast.Caster.EntityId.WritePacked(packet); }
/// <summary>Triggers a new tick</summary> protected void Tick(int timeElapsed) { ++this.m_ticks; SpellCast cast = this.m_cast; if (cast == null || !cast.IsCasting) { return; } Spell spell = cast.Spell; List <SpellEffectHandler> channelHandlers = this.m_channelHandlers; if (spell.PowerPerSecond > 0) { int amount = spell.PowerPerSecond; if (this.m_amplitude != 1000 && this.m_amplitude != 0) { amount = (int)((double)amount * ((double)this.m_amplitude / 1000.0)); } SpellFailedReason reason = cast.ConsumePower(amount); if (reason != SpellFailedReason.Ok) { this.m_cast.Cancel(reason); return; } } foreach (SpellEffectHandler spellEffectHandler in channelHandlers) { spellEffectHandler.OnChannelTick(); if (!this.m_channeling) { return; } } if (this.m_auras != null) { this.m_auras.RemoveAll((Predicate <IAura>)(aura => { if (!aura.IsAdded) { return(true); } aura.Apply(); return(!aura.IsAdded); })); } if (!this.m_channeling) { return; } Action <SpellChannel> ticked = SpellChannel.Ticked; if (ticked != null) { ticked(this); } if (this.m_maxTicks > 0 && this.m_ticks < this.m_maxTicks) { return; } this.Close(false); if (!cast.IsCasting) { return; } cast.Cleanup(); }
internal static void SendSpellFailedOther(SpellCast spellCast, SpellFailedReason reason) { using (var packet = new RealmPacketOut(RealmServerOpCode.SMSG_SPELL_FAILED_OTHER, 15)) { spellCast.Caster.EntityId.WritePacked(packet); packet.Write(spellCast.Id); packet.Write(spellCast.Spell.Id); packet.Write((byte)reason); spellCast.Caster.SendPacketToArea(packet); } }
/// <summary>Get rid of circular references</summary> internal void Dispose() { m_cast = null; SpellChannelPool.Recycle(this); }
public FerociousBiteHandler(SpellCast cast, SpellEffect effect) : base(cast, effect) { }
public virtual bool CanSummon(SpellCast cast, NPCEntry entry) { return(true); }
public DeathCoilHandler(SpellCast cast, SpellEffect effect) : base(cast, effect) { }
public static void SendCastStart(SpellCast cast) { if (cast.CasterObject != null && !cast.CasterObject.IsAreaActive) { return; } int len = 150; var spell = cast.Spell; if (spell == null) { return; } using (var packet = new RealmPacketOut(RealmServerOpCode.SMSG_SPELL_START, len)) { // Common to start and go packets WriteCaster(cast, packet); //packet.Write(cast.Id); packet.Write(spell.Id); packet.Write((int)cast.StartFlags); // start specific stuff packet.Write(cast.CastDelay); WriteTargets(packet, cast); if (cast.StartFlags.HasFlag(CastFlags.RunicPowerGain)) { packet.Write(0); } if (cast.StartFlags.HasFlag(CastFlags.RuneCooldownList)) { byte b1 = 0; byte b2 = 0; packet.Write(b1); packet.Write(b2); for (int i = 0; i < 6; i++) { byte mask = (byte)(1 << i); if ((mask & b1) != 0) { if ((mask & b2) == 0) { packet.WriteByte(0); } } } } if (cast.StartFlags.HasFlag(CastFlags.Ranged)) { WriteAmmoInfo(cast, packet); } if (cast.StartFlags.HasFlag(CastFlags.Flag_0x4000000)) { // since 3.2.0 packet.Write(0); packet.Write(0); } if (cast.TargetFlags.HasAnyFlag(SpellTargetFlags.DestinationLocation)) { packet.Write((byte)0); // unk 3.3.x? } cast.SendPacketToArea(packet); } }
public CorpseExplosionHandler(SpellCast cast, SpellEffect effect) : base(cast, effect) { }
private static void WriteTargets(RealmPacketOut packet, SpellCast cast) { var flags = cast.TargetFlags; if (flags == 0 || flags == SpellTargetFlags.Self) { var spell = cast.Spell; if (cast.SelectedTarget is Unit && !spell.IsAreaSpell && (spell.Visual != 0 || spell.IsPhysicalAbility)) { flags = SpellTargetFlags.Unit; } } packet.Write((uint)flags); if (flags.HasAnyFlag( SpellTargetFlags.SpellTargetFlag_Dynamic_0x10000 | SpellTargetFlags.Corpse | SpellTargetFlags.GameObject | SpellTargetFlags.PvPCorpse | SpellTargetFlags.Unit)) { if (cast.SelectedTarget == null) { #if DEBUG log.Warn("{0} casted Spell {1} with TargetFlags {2} but with nothing Selected", cast.CasterObject, cast.Spell, flags); #endif packet.Write((byte)0); } else { cast.SelectedTarget.EntityId.WritePacked(packet); } } // 0x1010 if (flags.HasAnyFlag(SpellTargetFlags.TradeItem | SpellTargetFlags.Item)) { if (cast.TargetItem != null) { cast.TargetItem.EntityId.WritePacked(packet); } } // 0x20 if (flags.HasAnyFlag(SpellTargetFlags.SourceLocation)) { if (cast.SelectedTarget != null) { cast.SelectedTarget.EntityId.WritePacked(packet); } else { packet.Write((byte)0); } packet.Write(cast.SourceLoc.X); packet.Write(cast.SourceLoc.Y); packet.Write(cast.SourceLoc.Z); } // 0x40 if (flags.HasAnyFlag(SpellTargetFlags.DestinationLocation)) { if (cast.SelectedTarget != null) { cast.SelectedTarget.EntityId.WritePacked(packet); } else { packet.Write((byte)0); } packet.Write(cast.TargetLoc); } // 0x2000 if (flags.HasAnyFlag(SpellTargetFlags.String)) { packet.WriteCString(cast.StringTarget); } }
public ClearCastingAndPresenceOfMindHandler(SpellCast cast, SpellEffect effect) : base(cast, effect) { }
/// <summary> /// Sent after spell start. Triggers the casting animation. /// </summary> public static void SendSpellGo(IEntity caster2, SpellCast cast, ICollection <WorldObject> hitTargets, ICollection <MissedTarget> missedTargets, byte previousRuneMask) { if (cast.CasterObject != null && !cast.CasterObject.IsAreaActive) { return; } // TODO: Dynamic packet length? if (!cast.IsCasting) { return; } //int len = 200; int len = 24 + (hitTargets != null ? hitTargets.Count * 8 : 0) + (missedTargets != null ? missedTargets.Count * 10 : 0); using (var packet = new RealmPacketOut(RealmServerOpCode.SMSG_SPELL_GO, len)) { //caster1.EntityId.WritePacked(packet); cast.CasterReference.EntityId.WritePacked(packet); caster2.EntityId.WritePacked(packet); //packet.Write(cast.Id); packet.Write(cast.Spell.Id); var castGoFlags = cast.GoFlags; packet.Write((int)castGoFlags); //packet.Write(Util.Utility.GetEpochTime()); packet.Write(Utility.GetEpochTime()); //packet.Write(cast.CastDelay); packet.WriteByte(hitTargets != null ? hitTargets.Count : 0); if (hitTargets != null && cast.CasterObject != null) { foreach (var target in hitTargets) { packet.Write(target.EntityId); if (target is Character) { SendCastSuccess(cast.CasterObject, cast.Spell.Id, target as Character); } } } packet.WriteByte(missedTargets != null ? missedTargets.Count : 0); if (missedTargets != null) { foreach (var miss in missedTargets) { packet.Write(miss.Target.EntityId); packet.Write((byte)miss.Reason); if (miss.Reason == CastMissReason.Reflect) { packet.Write((byte)0); // relfectreason } } } WriteTargets(packet, cast); // runes if (castGoFlags.HasFlag(CastFlags.RunicPowerGain)) { packet.Write(0); } if (castGoFlags.HasFlag(CastFlags.RuneCooldownList)) { var chr = cast.CasterChar; var newRuneMask = chr.PlayerSpells.Runes.GetActiveRuneMask(); packet.Write(previousRuneMask); packet.Write(newRuneMask); for (int i = 0; i < SpellConstants.MaxRuneCount; i++) { var mask = (byte)(1 << i); if ((mask & previousRuneMask) != 0) { if ((mask & newRuneMask) == 0) { packet.WriteByte(0); } } } } if (castGoFlags.HasFlag(CastFlags.Flag_0x20000)) { packet.WriteFloat(0); packet.Write(0); } if (cast.StartFlags.HasFlag(CastFlags.Ranged)) { WriteAmmoInfo(cast, packet); } if (castGoFlags.HasFlag(CastFlags.Flag_0x80000)) { packet.Write(0); packet.Write(0); } if (cast.TargetFlags.HasAnyFlag(SpellTargetFlags.DestinationLocation)) { packet.Write((byte)0); // unk 3.3.x? } cast.SendPacketToArea(packet); } }
public QuestCompleteEffectHandler(SpellCast cast, SpellEffect effect) : base(cast, effect) { }
public BossSummonHelpSpellHandler(SpellCast cast, SpellEffect effect) : base(cast, effect) { }