/// <summary> /// Checks of the two positions have a clear line of sight on the given MapId. /// </summary> /// <param name="mapId">The <see cref="WCell.Constants.World.MapId"/> that corresponds to the desired map.</param> /// <param name="pos1">The start position for the LOS check.</param> /// <param name="pos2">The end position for the LOS check.</param> /// <returns>True if the LOS check was successful.</returns> public bool HasLOS(MapId mapId, Vector3 pos1, Vector3 pos2) { if (pos1.DistanceSquared(pos2) > _maxLOSRadiusSquared) { log.Warn( "LOS request on points whose distance exceeds the maximum: Point 1: {0}, Point 2: {1}, Max Distance: {2}", pos1, pos2, MaxLOSRadius); return false; } Map map; return (((!TryGetMap(mapId, out map)) || (map.HasLOS(pos1, pos2)))); }
public void Vector3DistanceSquaredTest() { var a = new Vector3(3.0f, 4.0f, 2.0f); var b = new Vector3(6.0f, 8.0f, 4.0f); var expectedResult = 29.0f; var r = a.DistanceSquared(b); Assert.Equal<float>(expectedResult, r); }
public RayTraceHit RayTraceIntersection(Vector3 startSegment, Vector3 endSegment) { // Plane intersection Vector3? southIntersection = Vector3.IntersectPointForSegmentAndPlane(startSegment, endSegment, this.Maximum, Vector3.XAxis); Vector3? northIntersection = Vector3.IntersectPointForSegmentAndPlane(startSegment, endSegment, this.Minimum, Vector3.XAxis); Vector3? topIntersection = Vector3.IntersectPointForSegmentAndPlane(startSegment, endSegment, this.Maximum, Vector3.YAxis); Vector3? bottomIntersection = Vector3.IntersectPointForSegmentAndPlane(startSegment, endSegment, this.Minimum, Vector3.YAxis); Vector3? westIntersection = Vector3.IntersectPointForSegmentAndPlane(startSegment, endSegment, this.Maximum, Vector3.ZAxis); Vector3? eastIntersection = Vector3.IntersectPointForSegmentAndPlane(startSegment, endSegment, this.Minimum, Vector3.ZAxis); // Check each intersection to be sure it lies within the other axis as well if (northIntersection.HasValue && !this.IsVectorWithinYZ(northIntersection.Value)) { northIntersection = null; } if (southIntersection.HasValue && !this.IsVectorWithinYZ(southIntersection.Value)) { southIntersection = null; } if (topIntersection.HasValue && !this.IsVectorWithinXZ(topIntersection.Value)) { topIntersection = null; } if (bottomIntersection.HasValue && !this.IsVectorWithinXZ(bottomIntersection.Value)) { bottomIntersection = null; } if (westIntersection.HasValue && !this.IsVectorWithinXY(westIntersection.Value)) { westIntersection = null; } if (eastIntersection.HasValue && !this.IsVectorWithinXY(eastIntersection.Value)) { eastIntersection = null; } Vector3? rayHitPoint = null; BlockFace faceHit = BlockFace.Self; if (northIntersection != null) { rayHitPoint = northIntersection; faceHit = BlockFace.North; } if (southIntersection != null && (rayHitPoint == null || startSegment.DistanceSquared(southIntersection.Value) < startSegment.DistanceSquared(rayHitPoint.Value))) { rayHitPoint = southIntersection; faceHit = BlockFace.South; } if (topIntersection != null && (rayHitPoint == null || startSegment.DistanceSquared(topIntersection.Value) < startSegment.DistanceSquared(rayHitPoint.Value))) { rayHitPoint = topIntersection; faceHit = BlockFace.Up; } if (bottomIntersection != null && (rayHitPoint == null || startSegment.DistanceSquared(bottomIntersection.Value) < startSegment.DistanceSquared(rayHitPoint.Value))) { rayHitPoint = bottomIntersection; faceHit = BlockFace.Down; } if (westIntersection != null && (rayHitPoint == null || startSegment.DistanceSquared(westIntersection.Value) < startSegment.DistanceSquared(rayHitPoint.Value))) { rayHitPoint = westIntersection; faceHit = BlockFace.West; } if (eastIntersection != null && (rayHitPoint == null || startSegment.DistanceSquared(eastIntersection.Value) < startSegment.DistanceSquared(rayHitPoint.Value))) { rayHitPoint = eastIntersection; faceHit = BlockFace.East; } if (rayHitPoint != null) return new RayTraceHit(rayHitPoint.Value, faceHit); else return null; }
/// <summary> /// Returns if the spell will hit the point when casted /// </summary> /// <param name="point"> /// Vector3 Target /// </param> /// <param name="castPosition"> /// Cast Position /// </param> /// <param name="extraWidth"> /// Extra Width /// </param> /// <returns> /// Will Spell Hit /// </returns> public bool WillHit(Vector3 point, Vector3 castPosition, int extraWidth = 0) { switch (this.Type) { case SkillshotType.SkillshotCircle: if (point.DistanceSquared(castPosition) < this.WidthSqr) { return true; } break; case SkillshotType.SkillshotLine: if (point.ToVector2().DistanceSquared(castPosition.ToVector2(), this.From.ToVector2(), true) < Math.Pow(this.Width + extraWidth, 2)) { return true; } break; case SkillshotType.SkillshotCone: var edge1 = (castPosition.ToVector2() - this.From.ToVector2()).Rotated(-this.Width / 2); var edge2 = edge1.Rotated(this.Width); var v = point.ToVector2() - this.From.ToVector2(); if (point.DistanceSquared(this.From) < this.RangeSqr && edge1.CrossProduct(v) > 0 && v.CrossProduct(edge2) > 0) { return true; } break; } return false; }