コード例 #1
0
ファイル: Spell.CastParams.cs プロジェクト: Skizot/WCell
		/// <summary>
		/// Checks whether the given target is valid for the given caster.
		/// Is called automatically when SpellCast selects Targets.
		/// Does not do maximum range check.
		/// </summary>
		public SpellFailedReason CheckValidTarget(WorldObject caster, WorldObject target)
		{
			if (target is Unit)
			{
				// AuraState
				if (RequiredTargetAuraState != 0 || ExcludeTargetAuraState != 0)
				{
					var state = ((Unit)target).AuraState;
                    if ((RequiredTargetAuraState != 0 && !state.HasAnyFlag(RequiredTargetAuraState)) ||
                        (ExcludeTargetAuraState != 0 && state.HasAnyFlag(ExcludeTargetAuraState)))
					{
						return SpellFailedReason.TargetAurastate;
					}
				}

				// Required Auras
				if ((ExcludeTargetAuraId != 0 && ((Unit)target).Auras.Contains(ExcludeTargetAuraId)) ||
					(RequiredTargetAuraId != 0 && !((Unit)target).Auras.Contains(RequiredTargetAuraId)))
				{
					return SpellFailedReason.TargetAurastate;
				}
			}

			// Make sure that we have a GameObject if the Spell requires one
            if (TargetFlags.HasAnyFlag(SpellTargetFlags.UnkUnit_0x100) &&
				(!(target is GameObject) || !target.IsInWorld))
			{
				return SpellFailedReason.BadTargets;
			}

			// CreatureTypes
			if (TargetCreatureTypes != TargetCreatureMask.None &&
				(!(target is NPC) || !((NPC)target).CheckCreatureType(TargetCreatureTypes)))
			{
				return SpellFailedReason.BadImplicitTargets;
			}
			if (!CanCastOnPlayer && target is Character)
			{
				return SpellFailedReason.BadImplicitTargets;
			}


			// Corpse target
			if (ReqDeadTarget)
			{
                if (TargetFlags.HasAnyFlag(SpellTargetFlags.PvPCorpse | SpellTargetFlags.Corpse))
				{
					if (!(target is Corpse) ||
                        (TargetFlags.HasAnyFlag(SpellTargetFlags.PvPCorpse) && !caster.IsHostileWith(target)))
					{
						return SpellFailedReason.BadImplicitTargets;
					}
				}
				else if (!(target is NPC) || ((NPC)target).IsAlive || target.Loot != null)
				{
					// need to be dead and looted empty
					return SpellFailedReason.TargetNotDead;
				}
			}
			else
			{
				if (target is Unit && !((Unit)target).IsAlive)
				{
					return SpellFailedReason.TargetsDead;
				}
			}

			// Rogues do it from behind
            if (AttributesExB.HasFlag(SpellAttributesExB.RequiresBehindTarget))
			{
				if (!caster.IsBehind(target))
				{
					return SpellFailedReason.NotBehind;
				}
			}

            if (AttributesExC.HasFlag(SpellAttributesExC.NoInitialAggro))
			{
				if (target is Unit && ((Unit)target).IsInCombat)
				{
					return SpellFailedReason.TargetAffectingCombat;
				}
			}

			if (Range.MinDist > 0 &&
				//caster.IsInRadius(target, caster.GetSpellMinRange(Range.MinDist, target)))
				caster.IsInRadius(target, Range.MinDist))
			{
				return SpellFailedReason.TooClose;
			}

			return SpellFailedReason.Ok;
		}
コード例 #2
0
ファイル: SpellCast.cs プロジェクト: ebakkedahl/WCell
        public void ValidateAndTrigger(Spell spell, Unit triggerOwner, WorldObject target, IUnitAction action = null, SpellEffect triggerEffect = null)
        {
            WorldObject[] targets;

            if (triggerOwner == null)
            {
                _log.Warn("triggerOwner is null when trying to proc spell: {0} (target: {1})", spell, target);
                return;
            }

            if (spell.CasterIsTarget || !spell.HasTargets)
            {
                targets = new[] { triggerOwner };
            }
            else if (target != null)
            {
                if (spell.IsAreaSpell ||
                    CasterObject == null ||
                    spell.IsHarmfulFor(CasterReference, target) != target.IsHostileWith(CasterObject))
                {
                    targets = null;
                }
                else
                {
                    targets = new[] { target };
                }
            }
            else
            {
                targets = null;
            }

            if (action != null)
            {
                action.ReferenceCount++;
                TriggerAction = action;
            }

            Start(spell, triggerEffect, true, targets);
        }