protected void AddTargetedProjectile(string name, AttackableUnit target, bool serverOnly = false) { var record = SpellRecord.GetSpell(name); var position = new Vector3(Owner.Position.X, Owner.Position.Y, 100); var casterPosition = new Vector3(Owner.Position.X, Owner.Position.Y, 100); var angle = Geo.GetAngle(Owner.Position, target.Position); var direction = Geo.GetDirection(angle); var velocity = new Vector3(1, 1, 1) * 100; var startPoint = new Vector3(Owner.Position.X, Owner.Position.Y, 100); var endPoint = new Vector3(target.Position.X, target.Position.Y, 100); var targetedProjectile = new TargetedProjectile(Owner.Game.NetIdProvider.PopNextNetId(), Owner, target, startPoint.ToVector2(), SpellRecord.MissileSpeed, OnProjectileReach); Owner.Game.AddUnitToTeam(targetedProjectile, Owner.Team.Id); Owner.Game.Map.AddUnit(targetedProjectile); if (!serverOnly) { var castInfo = Spell.GetCastInformations(position, endPoint, name, targetedProjectile.NetId, new AttackableUnit[] { target }); Owner.Game.Send(new SpawnProjectileMessage(targetedProjectile.NetId, position, casterPosition, direction.ToVector3(), velocity, startPoint, endPoint, casterPosition, 0, record.MissileSpeed, 1f, 1f, 1f, false, castInfo)); } }
protected void AddSkillShot(string name, Vector2 toPosition, Vector2 endPosition, float range, bool serverOnly = false) { var record = SpellRecord.GetSpell(name); var position = new Vector3(Owner.Position.X, Owner.Position.Y, 100); var casterPosition = new Vector3(Owner.Position.X, Owner.Position.Y, 100); var angle = Geo.GetAngle(Owner.Position, endPosition); var direction = Geo.GetDirection(angle); var velocity = new Vector3(1, 1, 1) * 100; var startPoint = new Vector3(Owner.Position.X, Owner.Position.Y, 100); var endPoint = new Vector3(endPosition.X, endPosition.Y, 100); var skillShot = new SkillShot(Owner.Game.NetIdProvider.PopNextNetId(), Owner, position.ToVector2(), record.MissileSpeed, record.LineWidth, OnProjectileReach, direction, range, OnSkillShotRangeReached); Owner.Game.AddUnitToTeam(skillShot, Owner.Team.Id); Owner.Game.Map.AddUnit(skillShot); if (!serverOnly) { var castInfo = Spell.GetCastInformations(position, endPoint, name, skillShot.NetId); Owner.Game.Send(new SpawnProjectileMessage(skillShot.NetId, position, casterPosition, direction.ToVector3(), velocity, startPoint, endPoint, casterPosition, 0, record.MissileSpeed, 1f, 1f, 1f, false, castInfo)); } }
/// <summary> /// Compute the new angle given a <c>Point</c>. /// </summary> /// <param name="newPoint">a <c>Point</c> in model coordinates</param> /// <returns>the new angle, in degrees</returns> /// <remarks> /// If the angle is close (by <see cref="SnapAngleEpsilon"/> degrees) /// to a multiple of <see cref="SnapAngleMultiple"/> degrees, make it /// exactly that multiple. /// </remarks> protected virtual double ComputeRotate(Point newPoint) { double dx = newPoint.X - this.RotationPoint.X; double dy = newPoint.Y - this.RotationPoint.Y; double a = Geo.GetAngle(dx, dy); // apparent angle from RotationPoint to newPoint double interval = Math.Min(Math.Abs(this.SnapAngleMultiple), 180); double epsilon = Math.Min(Math.Abs(this.SnapAngleEpsilon), interval / 2); // if it's close to a multiple of INTERVAL degrees, make it exactly so if (!IsShiftKeyDown() && interval > 0 && epsilon > 0) { if (a % interval < epsilon) { a = ((int)(a / interval)) * interval; } else if (a % interval > interval - epsilon) { a = ((int)(a / interval) + 1) * interval; } } double ang = a; if (ang >= 360) { ang -= 360; } else if (ang < 0) { ang += 360; } return(ang); }
public override void Update(float deltaTime) { m_deltaMovement = Speed * 0.001f * deltaTime; // deltaTime float angle = Geo.GetAngle(Position, Target.Position); float xOffset = (float)Math.Cos(angle) * m_deltaMovement; float yOffset = (float)Math.Sin(angle) * m_deltaMovement; Position = new Vector2(Position.X + xOffset, Position.Y + yOffset); if (Collide(Target)) { OnReach(Target, this); } base.Update(deltaTime); }
public override void Update(float deltaTime) { float deltaMovement = Speed * 0.001f * deltaTime; // deltaTime float angle = Geo.GetAngle(Position, Target.Position); float xOffset = (float)Math.Cos(angle) * deltaMovement; float yOffset = (float)Math.Sin(angle) * deltaMovement; Position = new Vector2(Position.X + xOffset, Position.Y + yOffset); // if (Unit is AIHero) // ((AIHero)Unit).AttentionPing(Position, 0, Protocol.GameClient.Enum.PingTypeEnum.Ping_OnMyWay); var distanceToTarget = Target.GetDistanceTo(this); if (distanceToTarget <= deltaMovement) { OnReach(Target, this); } base.Update(deltaTime); }
/// <summary> /// Arrange the child elements of this panel and of any label nodes. /// </summary> /// <param name="finalSize"></param> /// <returns></returns> /// <remarks> /// This positions each child element based on the attached property values of /// <see cref="GetIndex"/>, <see cref="GetFraction"/>, <see cref="GetAlignment"/>, /// and <see cref="GetOrientation"/>. /// This also positions any <see cref="Link.LabelNode"/>, /// using the <see cref="LinkPanel"/> attached properties on the node's <see cref="Part.VisualElement"/>, /// even though such a node is not within the visual tree of this panel. /// If the label node is a <see cref="Group"/>, this will instead position all of the /// group's <see cref="Group.MemberNodes"/>. /// </remarks> protected override Size ArrangeOverride(Size finalSize) { Part part = Diagram.FindAncestor <Part>(this); if (part == null) { return(new Size()); } Link link = part as Link; if (link == null) { Adornment node = part as Adornment; if (node != null) { link = node.AdornedPart as Link; } } if (link != null) { //Diagram.Debug(" LinkPanelA- " + (link.Data != null ? link.Data.ToString() : "")); Shape stroke = this.Path; // may be null Route route = link.Route; Rect routeBounds = route.RouteBounds; IList <Point> pts = (List <Point>)route.Points; int nPoints = pts.Count; int childidx = 0; if (stroke != null) { if (childidx < childrenBounds.Count) { stroke.Arrange(childrenBounds[childidx++]); } } foreach (UIElement e in this.Children) { if (e == stroke) { continue; } if (childidx < childrenBounds.Count) { //if (e.GetType().Name.Contains("Expander")) Diagram.Debug(e.ToString() + " arranged: " + Diagram.Str(childrenBounds[childidx])); e.Arrange(childrenBounds[childidx++]); } } //Diagram.Debug(" LinkPanelA+ " + (link.Data != null ? link.Data.ToString() : "")); Node label = link.LabelNode; if (label != null) { Group labelgroup = label as Group; foreach (Node m in (labelgroup != null ? labelgroup.MemberNodes : new Node[1] { label })) { if (nPoints < 2) { continue; } UIElement e = m.VisualElement; Size sz = new Size(m.Bounds.Width, m.Bounds.Height); int index = GetIndex(e); double frac = ComputeFraction(GetFraction(e)); Spot align = GetAlignment(e); if (align.IsNoSpot) { align = Spot.Center; } LabelOrientation orient = GetOrientation(e); Point nodept; // model coordinates if (index < -nPoints || index >= nPoints) // beyond range? assume at the MidPoint, with the MidAngle { Point mid = route.MidPoint; double segangle = route.MidAngle; // maybe rotate the label double labelangle = 0; if (orient != LabelOrientation.None) { labelangle = ComputeAngle(e, orient, segangle); m.SetAngle(e, labelangle, align); } // maybe the alignment point is away from the line nodept = mid; // model coordinates Point offset = ComputeOffset(e, index, segangle, sz, labelangle); nodept = Geo.Add(nodept, offset); } else // on a particular segment, given by Index, at a point given by Fraction // negative index means start from last point, going "backwards" { Point a, b; if (index >= 0) { a = pts[index]; b = (index < nPoints - 1) ? pts[index + 1] : a; } else { int i = nPoints + index; // remember that index is negative here a = pts[i]; b = (i > 0) ? pts[i - 1] : a; } // compute the fractional point along the line, in model coordinates nodept = new Point(a.X + (b.X - a.X) * frac, a.Y + (b.Y - a.Y) * frac); double segangle = (index >= 0 ? Geo.GetAngle(a, b) : Geo.GetAngle(b, a)); // maybe rotate the label double labelangle = 0; if (orient != LabelOrientation.None) { labelangle = ComputeAngle(e, orient, segangle); m.SetAngle(e, labelangle, align); } // maybe the alignment point is away from the line Point offset = ComputeOffset(e, index, segangle, sz, labelangle); nodept = Geo.Add(nodept, offset); } Rect hb = align.RectForPoint(nodept, sz); m.Position = new Point(hb.X, hb.Y); } } } return(finalSize); }
/// <summary> /// Determine the size of the union of the bounds of the positioned and rotated child elements. /// </summary> /// <param name="availableSize"></param> /// <returns></returns> protected override Size MeasureOverride(Size availableSize) { Part part = Diagram.FindAncestor <Part>(this); if (part == null) { return(new Size()); } if (!part.IsMeasuringArranging) { return(new Size()); } Link link = part as Link; if (link == null) { Adornment ad = part as Adornment; if (ad != null) { link = ad.AdornedPart as Link; } if (link == null) { return(new Size()); } } //Diagram.Debug(" LinkPanelM- " + (link.Data != null ? link.Data.ToString() : "")); Shape stroke = this.Path; // may be null link.Path = stroke; // the Link caches what the Path really is Route route = link.Route; Rect routeBounds = route.RouteBounds; // in model coordinates Rect linkBounds = routeBounds; // includes all labels childrenBounds = new List <Rect>(); // in local coordinates if (stroke != null) { stroke.Measure(Geo.Unlimited); Size sz = stroke.DesiredSize; linkBounds.Width = Math.Max(linkBounds.Width, sz.Width); linkBounds.Height = Math.Max(linkBounds.Height, sz.Height); childrenBounds.Add(new Rect(0, 0, linkBounds.Width, linkBounds.Height)); } IList <Point> pts = (List <Point>)route.Points; int nPoints = pts.Count; foreach (UIElement e in this.Children) { if (e == stroke) { continue; // already measured the stroke, above } e.Measure(Geo.Unlimited); //if (e.GetType().Name.Contains("Expander")) Diagram.Debug(e.ToString() + " measured: " + Diagram.Str(e.DesiredSize)); if (nPoints < 2) { continue; } Size sz = e.DesiredSize; int index = GetIndex(e); double frac = ComputeFraction(GetFraction(e)); Spot align = GetAlignment(e); if (align.IsNoSpot) { align = Spot.Center; } LabelOrientation orient = GetOrientation(e); Point eltpt; // local coordinates if (index < -nPoints || index >= nPoints) // beyond range? assume at the MidPoint, with the MidAngle { Point mid = route.MidPoint; if (this.Implementation == LinkPanelImplementation.Stretch) { Point p0 = pts[0]; Point pn = pts[nPoints - 1]; sz.Width = Math.Sqrt(Geo.DistanceSquared(pn, p0)); } double segangle = route.MidAngle; // maybe rotate the label double labelangle = 0; if (orient != LabelOrientation.None) { labelangle = ComputeAngle(e, orient, segangle); link.SetAngle(e, labelangle, align); } // maybe the alignment point is away from the line eltpt = new Point(mid.X - routeBounds.X, mid.Y - routeBounds.Y); // local coordinates Point offset = ComputeOffset(e, index, segangle, sz, labelangle); eltpt = Geo.Add(eltpt, offset); } else // on a particular segment, given by Index, at a point given by Fraction // negative index means start from last point, going "backwards" { Point a, b; if (index >= 0) { a = pts[index]; b = (index < nPoints - 1) ? pts[index + 1] : a; } else { int i = nPoints + index; // remember that index is negative here a = pts[i]; b = (i > 0) ? pts[i - 1] : a; } // compute the fractional point along the line, in local coordinates eltpt = new Point(a.X + (b.X - a.X) * frac - routeBounds.X, a.Y + (b.Y - a.Y) * frac - routeBounds.Y); double segangle = (index >= 0 ? Geo.GetAngle(a, b) : Geo.GetAngle(b, a)); // maybe rotate the label double labelangle = 0; if (orient != LabelOrientation.None) { labelangle = ComputeAngle(e, orient, segangle); link.SetAngle(e, labelangle, align); } // maybe the alignment point is away from the line Point offset = ComputeOffset(e, index, segangle, sz, labelangle); eltpt = Geo.Add(eltpt, offset); } Rect cb = align.RectForPoint(eltpt, sz); childrenBounds.Add(cb); // local coordinates linkBounds.Union(new Rect(cb.X + routeBounds.X, cb.Y + routeBounds.Y, cb.Width, cb.Height)); // model coordinates } // if this panel is the "whole" link, update the link's Bounds if (link.VisualElement == this) { //Diagram.Debug(" LinkPanelM+ " + (link.Data != null ? link.Data.ToString() : "") + " " + Diagram.Str(routeBounds) + Diagram.Str(linkBounds)); link.Bounds = new Rect(routeBounds.X, routeBounds.Y, linkBounds.Width, linkBounds.Height); } return(new Size(routeBounds.Width, routeBounds.Height)); }
/// <summary> /// In Radians /// </summary> /// <param name="other"></param> /// <returns></returns> public float GetAngleBetween(Unit other) { return(Geo.GetAngle(Position, other.Position)); }