Beispiel #1
0
        public override void Process(CmdTrigger<RealmServerCmdArgs> trigger)
        {
            var spellId = trigger.Text.NextEnum(SpellId.None);
            var radius = trigger.Text.NextFloat(5);
            var scale = trigger.Text.NextFloat(1);
            var dynObj = new DynamicObject(trigger.Args.Character, spellId, radius,
                trigger.Args.Target.Map, trigger.Args.Target.Position)
                {
                    ScaleX = scale
                };

            SpellHandler.StaticDOs.Add(dynObj.EntityId, dynObj);
            trigger.Reply("DynamicObject created.");
        }
Beispiel #2
0
		/// <summary>
		/// Validates targets and applies all SpellEffects
		/// </summary>
		public SpellFailedReason Impact()
		{
			if (!IsCasting)
			{
				return SpellFailedReason.Ok;
			}

			// apply effects
			foreach (var handler in Handlers)
			{
				if (handler.Effect.IsPeriodic || handler.Effect.IsStrikeEffect)
				{
					// weapon ability or handled by Aura or Channel
					continue;
				}

				handler.Apply();
				if (!IsCasting)
				{
					// the last handler cancelled the SpellCast
					return SpellFailedReason.DontReport;
				}
			}

			if (CasterObject is Unit && Spell.IsPhysicalAbility)
			{
				// strike at everyone
				foreach (var target in UnitTargets)
				{
					ProcHitFlags hitFlags = CasterUnit.Strike(GetWeapon(), target, this);
					m_hitInfoByTarget[target] = hitFlags;
				}
			}

			// open Channel and spawn DynamicObject
			DynamicObject dynObj = null;
			if (Spell.DOEffect != null)
			{
				dynObj = new DynamicObject(this, Spell.DOEffect.GetRadius(CasterReference));
			}

			if (!IsCasting)
			{
				return SpellFailedReason.Ok;
			}

			List<MissedTarget> missedTargets = null;
			// create auras
			List<IAura> auras = null;
			if (m_auraApplicationInfos != null)
			{
				CreateAuras(ref missedTargets, ref auras, dynObj);
			}

			// check for missed targets
			if (missedTargets != null)
			{
				if (missedTargets.Count > 0)
				{
					// TODO: Flash message ontop of missed heads when impact is delayed
					CombatLogHandler.SendSpellMiss(this, true, missedTargets);
					missedTargets.Clear();
				}

				CastMissListPool.Recycle(missedTargets);
			}

			// open channel
			if (Spell.IsChanneled && CasterObject != null)
			{
				Channel = SpellChannel.SpellChannelPool.Obtain();
				Channel.m_cast = this;

				if (CasterObject is Unit)
				{
					if (dynObj != null)
					{
						CasterUnit.ChannelObject = dynObj;
					}
					else if (Selected != null)
					{
						CasterUnit.ChannelObject = Selected;
						if (Selected is NPC && Spell.IsTame)
						{
							((NPC)Selected).CurrentTamer = CasterObject as Character;
						}
					}
				}

				var len = Handlers.Length;
				var channelEffectHandlers = SpellEffectHandlerListPool.Obtain();
				//var channelEffectHandlers = new List<SpellEffectHandler>(6);
				for (var i = 0; i < len; i++)
				{
					var handler = Handlers[i];
					if (handler.Effect.IsPeriodic)
					{
						channelEffectHandlers.Add(handler);
					}
				}
				Channel.Open(channelEffectHandlers, auras);
			}

			// start Auras
			if (auras != null)
			{
				for (var i = 0; i < auras.Count; i++)
				{
					var aura = auras[i];
					aura.Start(Spell.IsChanneled ? Channel : null, false);
				}

				if (!IsChanneling)
				{
					auras.Clear();
					AuraListPool.Recycle(auras);
					auras = null;
				}
			}

			// applying debuffs might cancel other Auras
			if (Spell.HasHarmfulEffects && !Spell.IsPreventionDebuff)
			{
				foreach (var target in Targets)
				{
					if (target is Unit && Spell.IsHarmfulFor(CasterReference, target))
					{
						((Unit)target).Auras.RemoveByFlag(AuraInterruptFlags.OnHostileSpellInflicted);
					}
				}
			}

			//if (CasterChar != null)
			//{
			//    CasterChar.SendSystemMessage("SpellCast (Impact): {0} ms", sw1.ElapsedTicks / 10000d);
			//}

			return SpellFailedReason.Ok;
		}
Beispiel #3
0
		/// <summary>
		/// Sets the Character's selected GameObject
		/// </summary>
		internal GameObject this[Character chr]
		{
			get
			{
				return chr.ExtraInfo.SelectedGO;
			}
			set
			{
				var info = chr.ExtraInfo;
				Deselect(info);

				if (value != null)
				{
					var selection = new GOSelection(value);
					if (MarkerId != SpellId.None)
					{
						var marker = new DynamicObject(chr, MarkerId, MarkerRadius, value.Map, value.Position);
						selection.Marker = marker;
					}
					info.m_goSelection = selection;
				}
			}
		}
Beispiel #4
0
		public void Dispose()
		{
			GO = null;
			if (Marker != null)
			{
				Marker.Delete();
				Marker = null;
			}
		}
Beispiel #5
0
		void CreateAuras(ref List<CastMiss> missedTargets, ref List<IAura> auras, DynamicObject dynObj)
		{
			auras = AuraListPool.Obtain();
			var allowDead = m_spell.PersistsThroughDeath;

			// create AreaAura
			if (m_spell.IsAreaAura)
			{
				if (dynObj != null || (CasterObject != null && (allowDead || !(CasterObject is Unit) || ((Unit)CasterObject).IsAlive)))
				{
					// AreaAura is created at the target location if it is a DynamicObject, else its applied to the caster
					var aaura = new AreaAura(dynObj ?? CasterObject, m_spell);
					if (dynObj != null)
					{
						// also start the area aura
						auras.Add(aaura);
					}
					// else: Is coupled to an Aura instance
				}
				else
				{
					LogManager.GetCurrentClassLogger().Warn(
						"Tried to cast Spell {0} with invalid dynObj or Caster - dynObj: {1}, CasterObject: {2}, CasterUnit: {3}",
						m_spell, dynObj, CasterObject, CasterUnit);
				}
			}

			// remove missed targets
			for (var i = m_auraApplicationInfos.Count - 1; i >= 0; i--)
			{
				var app = m_auraApplicationInfos[i];
				if (!m_targets.Contains(app.Target))
				{
					m_auraApplicationInfos.RemoveAt(i);
				}
			}
			if (m_auraApplicationInfos.Count == 0)
			{
				return;
			}

			// create Aura-Handlers
			for (var i = 0; i < m_handlers.Length; i++)
			{
				var spellHandler = m_handlers[i];
				if (spellHandler is ApplyAuraEffectHandler)
				{
					((ApplyAuraEffectHandler)spellHandler).AddAuraHandlers(m_auraApplicationInfos);
				}
			}
			if (missedTargets == null)
			{
				missedTargets = CastMissListPool.Obtain();
			}

			// apply all new Auras
			for (var i = 0; i < m_auraApplicationInfos.Count; i++)
			{
				var info = m_auraApplicationInfos[i];
				var target = info.Target;

				if (!target.IsInContext)
				{
					continue;
				}

				if (info.Handlers == null || (!allowDead && !target.IsAlive))
				{
					continue;
				}

				// check for immunities and resistances
				CastMissReason missReason;
				var hostile = m_spell.IsHarmfulFor(CasterReference, target);

				if (!IsPassive && !m_spell.IsPreventionDebuff &&
					(missReason = CheckDebuffResist(target, m_spell, CasterReference.Level, hostile)) != CastMissReason.None)
				{
					// debuff miss
					missedTargets.Add(new CastMiss(target, missReason));
				}
				else
				{
					// create aura
					var newAura = target.Auras.CreateAura(CasterReference, m_spell, info.Handlers, UsedItem, !m_spell.IsPreventionDebuff && !hostile);
					if (newAura != null)
					{
						// check for debuff
						if (!m_spell.IsPreventionDebuff && hostile && target.IsInWorld && target.IsAlive)
						{
							// force combat mode
							target.IsInCombat = true;
						}
						// add Aura now
						auras.Add(newAura);
					}
				}
			}

			//m_auraApplicationInfos.Clear();
			//AuraAppListPool.Recycle(m_auraApplicationInfos);
			m_auraApplicationInfos = null;
		}
Beispiel #6
0
		/// <summary>
		/// Validates targets and applies all SpellEffects
		/// </summary>
		public SpellFailedReason Impact(bool delayed)
		{
			if (!m_casting || !Caster.IsInWorld)
			{
				return SpellFailedReason.Ok;
			}

			// figure out whether targets are still valid if delayed
			List<CastMiss> missedTargets;
			if (delayed)
			{
				missedTargets = CheckHit(m_spell);
			}
			else
			{
				missedTargets = null;
			}

			// apply effects
			foreach (var handler in m_handlers)
			{
				if (handler.Effect.IsPeriodic || handler.Effect.IsStrikeEffect)
				{
					// weapon ability or handled by Aura or Channel
					continue;
				}

				handler.Apply();
				if (!m_casting)
				{
					// the last handler cancelled the SpellCast
					return SpellFailedReason.DontReport;
				}
			}

			// open Channel and spawn DynamicObject
			DynamicObject dynObj = null;
			if (m_spell.DOEffect != null)
			{
				dynObj = new DynamicObject(this, m_spell.DOEffect.GetRadius(Caster));
			}

			if (!m_casting)
			{
				return SpellFailedReason.Ok;
			}

			// create auras
			List<IAura> auras = null;
			if (m_auraApplicationInfos != null)
			{
				CreateAuras(ref missedTargets, ref auras, dynObj);
			}

			// check for missed targets
			if (missedTargets != null)
			{
				if (missedTargets.Count > 0)
				{
					// TODO: Flash message ontop of missed heads when impact is delayed
					CombatLogHandler.SendSpellMiss(m_spell.SpellId, Caster, true, missedTargets);
				}

				missedTargets.Clear();
				CastMissListPool.Recycle(missedTargets);
			}

			// channeling
			if (m_spell.IsChanneled)
			{
				m_channel = SpellChannel.SpellChannelPool.Obtain();
				m_channel.m_cast = this;

				if (Caster is Unit)
				{
					if (dynObj != null)
					{
						CasterUnit.ChannelObject = dynObj;
					}
					else if (Selected != null)
					{
						CasterUnit.ChannelObject = Selected;
						if (Selected is NPC && m_spell.IsTame)
						{
							((NPC)Selected).CurrentTamer = Caster as Character;
						}
					}
				}

				var len = m_handlers.Length;
				var channelEffectHandlers = SpellEffectHandlerListPool.Obtain();
				//var channelEffectHandlers = new List<SpellEffectHandler>(6);
				for (var i = 0; i < len; i++)
				{
					var handler = m_handlers[i];
					if (handler.Effect.IsPeriodic)
					{
						channelEffectHandlers.Add(handler);
					}
				}
				m_channel.Open(channelEffectHandlers, auras);
			}

			// start Auras
			if (auras != null)
			{
				for (var i = 0; i < auras.Count; i++)
				{
					var aura = auras[i];
					aura.Start(m_spell.IsChanneled ? m_channel : null, false);
				}

				if (!IsChanneling)
				{
					auras.Clear();
					AuraListPool.Recycle(auras);
				}
			}

			// applying debuffs might cancel other Auras
			if (m_spell.HasHarmfulEffects && !m_spell.IsPreventionDebuff)
			{
				foreach (var target in m_targets)
				{
					if (target is Unit && m_spell.IsHarmfulFor(Caster, target))
					{
						((Unit)target).Auras.RemoveByFlag(AuraInterruptFlags.OnHostileSpellInflicted);
					}
				}
			}

			// check for weapon abilities
			if (m_spell.IsPhysicalAbility && !IsChanneling)
			{
				if (Caster is Unit)
				{
					if (m_spell.IsRangedAbility)
					{
						// reset SpellCast so it cannot be cancelled anymore
						CasterUnit.SpellCast = null;
						CasterUnit.m_pendingCombatAbility = this;
						CasterUnit.Strike(GetWeapon());
					}

					if (!IsChanneling)
					{
						OnCasted();
					}
				}
			}

			//if (CasterChar != null)
			//{
			//    CasterChar.SendSystemMessage("SpellCast (Impact): {0} ms", sw1.ElapsedTicks / 10000d);
			//}

			// clean it up
			if ((delayed || m_spell.IsPhysicalAbility) && (!m_spell.IsChanneled) && m_casting)
			{
				Cleanup(true);
			}
			return SpellFailedReason.Ok;
		}
Beispiel #7
0
		public override void Process(CmdTrigger<RealmServerCmdArgs> trigger)
		{
			Dictionary<DynamicObject, GameObject> highlighters;
			var exists = Highlighters.TryGetValue(trigger.Args.Character, out highlighters);
			var create = trigger.Text.NextBool() || (!trigger.Text.HasNext && !exists);

			if (!create)
			{
				if (exists)
				{
					foreach (var dynObj in highlighters.Keys)
					{
						dynObj.Delete();
					}
					highlighters.Clear();
					Highlighters.Remove(trigger.Args.Character);
				}
				trigger.Reply("GO Highlighters OFF");
			}
			else
			{
				if (!exists)
				{
					Highlighters.Add(trigger.Args.Character, highlighters = new Dictionary<DynamicObject, GameObject>());
				}
				else
				{
					foreach (var dynObj in highlighters.Keys)
					{
						dynObj.Delete();
					}
					highlighters.Clear();
				}

				var caster = trigger.Args.Character;

				var gos = caster.GetObjectsInRadius(50f, ObjectTypes.GameObject, false, 0);
				foreach (GameObject go in gos)
				{
					var region = go.Region;
					var pos = go.Position;
					pos.Z += 7 * go.ScaleX;						// make it appear above the object

					var dO = new DynamicObject(caster, SpellId.ABOUTTOSPAWN, 5, region, pos);
					highlighters.Add(dO, go);
				}
				trigger.Reply("Highlighting {0} GameObjects", highlighters.Count);
			}
		}
Beispiel #8
0
        /// <summary>
        /// Sets the Character's selected GameObject
        /// </summary>
        internal GameObject this[Character chr]
        {
            get
            {
                return chr.ExtraInfo.SelectedGO;
            }
            set
            {
                var info = chr.ExtraInfo;
                Deselect(info);

                if (value != null)
                {
                    var selection = new GOSelection(value);
                    if (MarkerId != SpellId.None)
                    {
                        var marker = new DynamicObject(chr, MarkerId, MarkerRadius, value.Map, value.Position);
                        selection.Marker = marker;

                        // also delete marker
                        marker.CallPeriodically(2000, obj =>
                                                    {
                                                        if (!chr.IsInWorld || chr.Map != marker.Map || selection.GO == null || !selection.GO.IsInWorld)
                                                        {
                                                            marker.Delete();
                                                        }
                                                    });
                    }
                    info.m_goSelection = selection;
                }
            }
        }
Beispiel #9
0
        public void Dispose()
        {
            GO = null;

            var marker = Marker;
            if (marker != null)
            {
                marker.Delete();
                Marker = null;
            }
        }
Beispiel #10
0
		void CreateAuras(ref List<CastMiss> missedTargets, ref List<IAura> auras, DynamicObject dynObj)
		{
			auras = AuraListPool.Obtain();
			var allowDead = m_spell.PersistsThroughDeath;

			// create AreaAura
			if (m_spell.IsAreaAura)
			{
				if (allowDead || !(Caster is Unit) || ((Unit)Caster).IsAlive)
				{
					// AreaAura is created at the target location if it is a DynamicObject, else its applied to the caster
					var areaAura = new AreaAura(dynObj ?? Caster, m_spell);
					auras.Add(areaAura);
				}
			}

			// remove missed targets
			for (var i = m_auraApplicationInfos.Count-1; i >= 0; i--)
			{
				var app = m_auraApplicationInfos[i];
				if (!m_targets.Contains(app.Target))
				{
					m_auraApplicationInfos.RemoveAt(i);
				}
			}
			if (m_auraApplicationInfos.Count == 0)
			{
				return;
			}

			// create Aura-Handlers
			for (var i = 0; i < m_handlers.Length; i++)
			{
				var spellHandler = m_handlers[i];
				if (spellHandler is ApplyAuraEffectHandler)
				{
					((ApplyAuraEffectHandler) spellHandler).AddAuraHandlers(m_auraApplicationInfos);
				}
			}
			if (missedTargets == null)
			{
				missedTargets = CastMissListPool.Obtain();
			}

			// apply all new Auras
			for (var i = 0; i < m_auraApplicationInfos.Count; i++)
			{
				var info = m_auraApplicationInfos[i];
				var target = info.Target;

				if (info.Handlers == null || (!allowDead && !target.IsAlive))
				{
					continue;
				}

				// check for immunities and resistances
				CastMissReason missReason;
				var hostile = m_spell.IsHarmfulFor(Caster, target);
				var casterInfo = Caster.CasterInfo;

				if (!IsPassive && !m_spell.IsPreventionDebuff && 
					(missReason = CheckDebuffResist(target, m_spell, casterInfo.Level, hostile)) != CastMissReason.None)
				{
					missedTargets.Add(new CastMiss(target, missReason));
				}
				else
				{
					var newAura = target.Auras.AddAura(casterInfo, m_spell, info.Handlers, !m_spell.IsPreventionDebuff && !hostile);
					if (newAura != null)
					{
						auras.Add(newAura);

						// check for debuff
						if (!m_spell.IsPreventionDebuff && hostile && target.IsInWorld)
						{
							// trigger Debuff event
							target.OnDebuff(this, newAura);
						}
					}
				}
			}

			//m_auraApplicationInfos.Clear();
			//AuraAppListPool.Recycle(m_auraApplicationInfos);
			m_auraApplicationInfos = null;
		}