/// <summary> /// Called during Preparation /// </summary> SpellFailedReason PrepareAI() { var caster = CasterUnit; SourceLoc = caster.Position; if (caster.Target != null) { caster.SpellCast.TargetLoc = caster.Target.Position; } // init handlers pre-maturely, to make sure we got any targets // revalidate handlers again, later var err = PrepareHandlers(); if (err == SpellFailedReason.Ok && Targets.Count == 0) { // NPC must have targets err = SpellFailedReason.NoValidTargets; } if (Targets.Count == 1) { // look at single target var target = Targets.First() as Unit; if (target != null) { caster.Target = target; } } return(err); }
/// <summary> /// Calculates the delay until a spell impacts its target in milliseconds /// </summary> /// <returns>delay in ms</returns> private int CalculateImpactDelay() { if (Spell.ProjectileSpeed <= 0 || Targets.Count == 0) { return(0); } float distance; if (TriggerAction != null) { distance = TriggerAction.Attacker.GetDist(TriggerAction.Victim); } else if (CasterObject != null) { var target = Targets.First(); distance = target.GetDistance(CasterObject); } else { return(0); } //projectile speed is distance per second return((int)((distance / Spell.ProjectileSpeed) * 1000)); }
/// <summary> /// Makes the main target the first element in 'Targets' List /// </summary> public void ReconsiderMainTarget() { if (Targets.Count > 0) { MainTarget = Targets.First(); RemoveTarget(MainTarget); } }
private void UpdateCurrentState() { int[] idx = new int[3]; idx[0] = 1; idx[1] = Arm.Compartments.Length * 4 / 10; idx[2] = Arm.Compartments.Length - 1; int i = 0; Vector2D target = Targets.First().Position; for (i = 0; i < 3; i++) { IEnumerable <Node> nodes = Enumerable.Concat(Arm.UpperNodes.Skip(idx[i]), Arm.LowerNodes.Skip(idx[i])); double totalMass = nodes.Sum(v => v.Mass); double avx = nodes.Sum(v => v.Position.PositionX * v.Mass) / totalMass; double avy = nodes.Sum(v => v.Position.PositionY * v.Mass) / totalMass; Vector2D point = new Vector2D(avx, avy); CurrentState[i * 2 + 4] = point.Norm - target.Norm; CurrentState[i * 2 + 5] = target.AngleTo(point); if (i == 0) { CurrentState[0] = target.Norm; CurrentState[1] = (new Vector2D(1, 0)).AngleTo(target); Vector2D vel = new Vector2D( nodes.Sum(v => v.Velocity.PositionX) / totalMass, nodes.Sum(v => v.Velocity.PositionY) / totalMass); CurrentState[2] = vel.Norm < 1e-7 ? 0 : vel.Norm * System.Math.Cos(point.AngleTo(vel)); CurrentState[3] = vel.Norm < 1e-7 ? 0 : vel.Norm * System.Math.Sin(point.AngleTo(vel)); } } CurrentState[10] = System.Math.Sign(CurrentState[8]); CurrentState[11] = System.Math.Sign(CurrentState[9]); CurrentState.IsTerminal = Terminal; }