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(); } }); }
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); }
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); }
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); } }
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 };
public void RegisterItemForPickup(SpacialElement item, Action afterPickup) { this.Velocity.ImpactOccurred.SubscribeForLifetime((i) => { if (i.ObstacleHit == item) { afterPickup(); item.Lifetime.Dispose(); } }, item.Lifetime); }
private bool IsIncluded(SpacialElement e) { if (ExcludedTypes == null) { return(true); } else { return(ExcludedTypes.Contains(e.GetType()) == false); } }
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; } }
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); } }
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)); }
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); } }
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)); }
public Orbit(SpacialElement toOrbit) : base(toOrbit) { }
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; } }