Пример #1
0
        public SpacialElementFunction(SpacialElement target)
        {
            this.Element = target;

            if (target.Lifetime.IsExpired)
            {
                return;
            }

            if (target.IsAttached())
            {
                Time.CurrentTime.QueueAction(() =>
                {
                    if (target.Lifetime.IsExpired == false && target.IsAttached())
                    {
                        Time.CurrentTime.Add(this);
                    }
                });
            }
            else
            {
                target.Added.SubscribeForLifetime(() => { Time.CurrentTime.Add(this); }, target.Lifetime);
            }


            Element.Lifetime.OnDisposed(() =>
            {
                if (this.Lifetime.IsExpired == false)
                {
                    this.Lifetime.Dispose();
                }
            });
        }
Пример #2
0
        public void E2ESimplestApp()
        {
            var            app   = new ConsoleApp(1, 1);
            var            panel = app.LayoutRoot.Add(new SpaceTimePanel(1, 1));
            SpacialElement element;
            TimeSpan       lastAge = TimeSpan.Zero;

            panel.SpaceTime.InvokeNextCycle(() =>
            {
                element = new SpacialElement();
                panel.SpaceTime.Add(element);

                panel.SpaceTime.Invoke(async() =>
                {
                    lastAge = element.CalculateAge();
                    if (Time.CurrentTime.Now == TimeSpan.FromSeconds(.5))
                    {
                        Time.CurrentTime.Stop();
                    }
                    await Time.CurrentTime.YieldAsync();
                });
            });

            panel.SpaceTime.Start().Then(() => app.Stop());
            app.Start().Wait();
            Assert.AreEqual(.5, lastAge.TotalSeconds);
        }
Пример #3
0
        public void E2ESimplestApp()
        {
            var            app   = new ConsoleApp(1, 1);
            var            panel = app.LayoutRoot.Add(new SpacetimePanel(1, 1));
            SpacialElement element;
            TimeSpan       lastAge = TimeSpan.Zero;

            panel.SpaceTime.QueueAction(() =>
            {
                element = new SpacialElement();
                panel.SpaceTime.Add(element);

                panel.SpaceTime.Add(TimeFunction.Create(() =>
                {
                    lastAge = element.CalculateAge();
                    if (Time.CurrentTime.Now == TimeSpan.FromSeconds(.5))
                    {
                        Time.CurrentTime.Stop();
                        app.Stop();
                    }
                }));
            });

            panel.SpaceTime.Start();
            app.Start().Wait();
            Assert.AreEqual(.5, lastAge.TotalSeconds);
        }
Пример #4
0
 public static void PlaceMineSafe(SpacialElement mine, Character holder, bool throwElement)
 {
     if (throwElement == false)
     {
         var buffer = 2f;
         if (holder.Velocity.Angle >= 315 || holder.Velocity.Angle < 45)
         {
             mine.MoveTo(holder.Left - buffer * mine.Width, holder.Top, holder.ZIndex);
         }
         else if (holder.Velocity.Angle < 135)
         {
             mine.MoveTo(holder.Left, holder.Top - buffer * mine.Height, holder.ZIndex);
         }
         else if (holder.Velocity.Angle < 225)
         {
             mine.MoveTo(holder.Left + buffer * mine.Width, holder.Top, holder.ZIndex);
         }
         else
         {
             mine.MoveTo(holder.Left, holder.Top + buffer * mine.Height, holder.ZIndex);
         }
     }
     else
     {
         var initialPlacement = holder.TopLeft().MoveTowards(holder.Velocity.Angle, 1f);
         mine.MoveTo(initialPlacement.Left, initialPlacement.Top);
         var v = new Velocity(mine);
         v.Speed = holder.Velocity.Speed + 50;
         v.Angle = holder.TargetAngle;
         new Friction(v);
     }
 }
Пример #5
0
        public void TestSeeking()
        {
            SpacialElement seeker = null;
            SpacialElement target = null;

            var w = 10;
            var h = 3;

            ConsoleAppTestHarness.Run(TestContext, (app, panel) =>
            {
                seeker          = SpaceTime.CurrentSpaceTime.Add(new SpacialElement(1, 1, 0, 1));
                seeker.Renderer = new SpacialElementRenderer()
                {
                    Background = ConsoleColor.Green
                };
                target         = SpaceTime.CurrentSpaceTime.Add(new SpacialElement(1, 1, w - 2, 1));
                var seekerV    = new SpeedTracker(seeker);
                var seekerFunc = new Seeker(seeker, target, seekerV, 5)
                {
                    RemoveWhenReached = true
                };
                seekerFunc.Lifetime.LifetimeManager.Manage(() =>
                {
                    panel.SpaceTime.Stop();
                });
            }, w: w, h: h);

            Assert.AreEqual(seeker.CenterX, target.CenterX);
            Assert.AreEqual(seeker.CenterY, target.CenterY);
        }
 private BoundsMessage CreateLocationMessage(string clientId, SpacialElement element) => new BoundsMessage()
 {
     X = element.Left,
     Y = element.Top,
     W = element.Width,
     H = element.Height,
     ClientToUpdate = clientId
 };
Пример #7
0
 public void RegisterItemForPickup(SpacialElement item, Action afterPickup)
 {
     this.Velocity.ImpactOccurred.SubscribeForLifetime((i) =>
     {
         if (i.ObstacleHit == item)
         {
             afterPickup();
             item.Lifetime.Dispose();
         }
     }, item.Lifetime);
 }
Пример #8
0
 private bool IsIncluded(SpacialElement e)
 {
     if (ExcludedTypes == null)
     {
         return(true);
     }
     else
     {
         return(ExcludedTypes.Contains(e.GetType()) == false);
     }
 }
Пример #9
0
        public override void Evaluate()
        {
            var obstacles = Options.Source.GetObstacles();

            var candidates = Options.TargetsEval();
            var target     = candidates
                             .Where(z =>
            {
                var sb    = Options.SourceBounds;
                var angle = sb.Center().CalculateAngleTo(z.Center());
                var delta = Options.Source.Angle.DiffAngle(angle);
                if (delta >= AngularVisibility)
                {
                    return(false);
                }

                var prediction = HitDetection.PredictHit(new HitDetectionOptions()
                {
                    Angle        = angle,
                    MovingObject = sb,
                    Obstacles    = obstacles.Where(o => o is WeaponElement == false),
                    Visibility   = 3 * SpaceTime.CurrentSpaceTime.Bounds.Hypotenous(),
                    Precision    = .5f,
                });

                var elementHit = prediction.ObstacleHit as SpacialElement;

                if (elementHit == z)
                {
                    return(true);
                }
                else if (elementHit != null && z is IHaveMassBounds && (z as IHaveMassBounds).IsPartOfMass(elementHit))
                {
                    return(true);
                }
                else
                {
                    return(false);
                }
            })
                             .OrderBy(z => Geometry.CalculateNormalizedDistanceTo(Options.Source.Element, z))
                             .FirstOrDefault();

            if (target != lastTarget)
            {
                TargetChanged.Fire(target);
                lastTarget = target;
            }
        }
Пример #10
0
        public override void Evaluate()
        {
            var targets = options.TargetsEval()
                          .Where(z =>
            {
                var angle = options.Source.Element.CalculateAngleTo(z);
                var delta = options.Source.Angle.DiffAngle(angle);
                return(delta < 90);
            })
                          .OrderBy(z => Geometry.CalculateNormalizedDistanceTo(options.Source.Element, z));
            var obstacles = new HashSet <IRectangularF>();

            foreach (var target in options.TargetsEval())
            {
                if (options.Source.HitDetectionExclusions.Contains(target) == false && options.Source.HitDetectionExclusionTypes.Contains(target.GetType()) == false)
                {
                    obstacles.Add(target);
                }
            }

            foreach (var element in SpaceTime.CurrentSpaceTime.Elements.Where(e => e.HasSimpleTag(Weapon.WeaponTag) == false && e.ZIndex == options.Source.Element.ZIndex))
            {
                if (options.Source.HitDetectionExclusions.Contains(element) == false && options.Source.HitDetectionExclusionTypes.Contains(element.GetType()) == false)
                {
                    obstacles.Add(element);
                }
            }

            foreach (var target in targets)
            {
                var hasLineOfSight = SpacialAwareness.HasLineOfSight(options.Source.Element, target, obstacles.ToList());

                if (hasLineOfSight)
                {
                    if (target != lastTarget)
                    {
                        TargetChanged.Fire(target);
                        lastTarget = target;
                    }
                    return;
                }
            }

            if (lastTarget != null)
            {
                lastTarget = null;
                TargetChanged.Fire(null);
            }
        }
Пример #11
0
        private void ConnectToElement(SpacialElement element)
        {
            added.Add(element);

            element.Lifetime.OnDisposed(() =>
            {
                removed.Add(element);
            });

            element.SizeOrPositionChanged.SubscribeForLifetime(() =>
            {
                if (element.InternalSpacialState.Changed == false)
                {
                    changed.Add(element);
                    element.InternalSpacialState.Changed = true;
                }
            }, Lifetime.EarliestOf(enablementLifetime, element.Lifetime));
        }
Пример #12
0
        public static void PlaceMineSafe(SpacialElement mine, Character holder)
        {
            var buffer = 2f;

            if (holder.Speed.Angle >= 315 || holder.Speed.Angle < 45)
            {
                mine.MoveTo(holder.Left - buffer * mine.Width, holder.Top, holder.ZIndex);
            }
            else if (holder.Speed.Angle < 135)
            {
                mine.MoveTo(holder.Left, holder.Top - buffer * mine.Height, holder.ZIndex);
            }
            else if (holder.Speed.Angle < 225)
            {
                mine.MoveTo(holder.Left + buffer * mine.Width, holder.Top, holder.ZIndex);
            }
            else
            {
                mine.MoveTo(holder.Left, holder.Top + buffer * mine.Height, holder.ZIndex);
            }
        }
Пример #13
0
        private void ConnectToElement(SpacialElement element)
        {
            added.Add(element);

            element.Lifetime.OnDisposed(() =>
            {
                removed.Add(element);
            });

            element.SizeOrPositionChanged.SubscribeForLifetime(() =>
            {
                if (Time.CurrentTime == null)
                {
                    throw new InvalidOperationException("Change did not occur on the time thread");
                }

                if (element.InternalSpacialState.Changed == false)
                {
                    changed.Add(element);
                    element.InternalSpacialState.Changed = true;
                }
            }, Lifetime.EarliestOf(enablementLifetime, element.Lifetime));
        }
Пример #14
0
 public Orbit(SpacialElement toOrbit) : base(toOrbit)
 {
 }
Пример #15
0
        private void Evaluate()
        {
            var obstacles = Options.Source.GetObstacles().Where(o => o is SpacialElement && o is WeaponElement == false).ToArray();

            SpacialElement target = null;
            float          winningCandidateProximity = float.MaxValue;

            targets.Clear();
            foreach (var element in SpaceTime.CurrentSpaceTime.Elements)
            {
                if (element.ZIndex != Options.Source.Element.ZIndex)
                {
                    continue;
                }
                if (element.HasSimpleTag(Options.TargetTag) == false)
                {
                    continue;
                }

                if (element is Character && (element as Character).IsVisible == false)
                {
                    continue;
                }

                var sb    = Options.SourceBounds;
                var angle = sb.Center().CalculateAngleTo(element.Center());
                var delta = Options.Source.Angle.DiffAngle(angle);
                if (delta >= Options.AngularVisibility)
                {
                    continue;
                }

                var prediction = HitDetection.PredictHit(new HitDetectionOptions()
                {
                    Angle        = angle,
                    MovingObject = sb,
                    Obstacles    = obstacles,
                    Visibility   = 3 * SpaceTime.CurrentSpaceTime.Bounds.Hypotenous(),
                    Mode         = CastingMode.Rough,
                });

                var elementHit = prediction.ObstacleHit as SpacialElement;

                if (elementHit == element)
                {
                    targets.Add(elementHit);
                    var d = Geometry.CalculateNormalizedDistanceTo(Options.Source.Element, element);
                    if (d < winningCandidateProximity)
                    {
                        target = elementHit;
                        winningCandidateProximity = d;
                    }
                }
                else if (elementHit != null && element is IHaveMassBounds && (element as IHaveMassBounds).IsPartOfMass(elementHit))
                {
                    targets.Add(elementHit);
                    var d = Geometry.CalculateNormalizedDistanceTo(Options.Source.Element, element);
                    if (d < winningCandidateProximity)
                    {
                        target = elementHit;
                        winningCandidateProximity = d;
                    }
                }
            }

            if (Options.Source.Element is Character && (Options.Source.Element as Character).IsVisible == false)
            {
                target = null;
            }

            if (target != lastTarget)
            {
                TargetChanged.Fire(target);
                lastTarget = target;
            }
        }