diff --git a/EXILED/Exiled.API/Features/Draw.cs b/EXILED/Exiled.API/Features/Draw.cs new file mode 100644 index 000000000..b6bb32776 --- /dev/null +++ b/EXILED/Exiled.API/Features/Draw.cs @@ -0,0 +1,152 @@ +// ----------------------------------------------------------------------- +// +// Copyright (c) ExMod Team. All rights reserved. +// Licensed under the CC BY-SA 3.0 license. +// +// ----------------------------------------------------------------------- + +namespace Exiled.API.Features +{ + using System; + using System.Collections.Generic; + + using DrawableLine; + + using Mirror; + + using UnityEngine; + + /// + /// A utility class for drawing debug lines, shapes, and bounds for players or globally. + /// + public static class Draw + { + /// + /// Draws a line between two specified points. + /// + /// The starting position of the line. + /// The ending position of the line. + /// The color of the lines. + /// How long the line should remain visible.Warning: Avoid using or extremely large values, as these lines cannot be removed from the client once sent. + /// The single to show the line to. + /// A collection of s to show the line to. + public static void Line(Vector3 start, Vector3 end, Color color, float duration, Player player = null, IEnumerable players = null) + { + Send(player, players, duration, color, start, end); + } + + /// + /// Draws a connected path through a series of points. + /// + /// An array of points to connect sequentially. + /// The color of the lines. + /// How long the line should remain visible.Warning: Avoid using or extremely large values, as these lines cannot be removed from the client once sent. + /// The single to show the path to. + /// A collection of s to show the path to. + public static void Path(Vector3[] points, Color color, float duration, Player player = null, IEnumerable players = null) + { + Send(player, players, duration, color, points); + } + + /// + /// Draws a circle at a specific position. + /// + /// The center point of the circle. + /// The radius of the circle. + /// The color of the lines. + /// How long the line should remain visible.Warning: Avoid using or extremely large values, as these lines cannot be removed from the client once sent. + /// The single to show the circle to. + /// A collection of s to show the circle to. + /// Indicates whether the circle should be drawn on the horizontal plane (XZ) or vertical plane (XY). + /// The number of line segments used to draw the circle. Higher values result in a smoother circle. + public static void Circle(Vector3 origin, float radius, Color color, float duration, Player player = null, IEnumerable players = null, bool horizontal = true, int segments = 16) + { + Vector3[] circlePoints = DrawableLines.GetCircle(origin, radius, horizontal, segments); + Send(player, players, duration, color, circlePoints); + } + + /// + /// Draws a wireframe sphere composed of two circles (horizontal and vertical). + /// + /// The center point of the sphere. + /// The radius of the sphere. + /// The color of the lines. + /// How long the line should remain visible.Warning: Avoid using or extremely large values, as these lines cannot be removed from the client once sent. + /// The single to show the sphere to. + /// A collection of s to show the sphere to. + /// The number of segments for the circles. Higher values result in a smoother sphere. + public static void Sphere(Vector3 origin, float radius, Color color, float duration, Player player = null, IEnumerable players = null, int segments = 16) + { + Vector3[] horizontal = DrawableLines.GetCircle(origin, radius, true, segments); + Send(player, players, duration, color, horizontal); + + Vector3[] vertical = DrawableLines.GetCircle(origin, radius, false, segments); + Send(player, players, duration, color, vertical); + } + + /// + /// Draws the edges of a object. + /// + /// The object to visualize. + /// The color of the lines. + /// How long the line should remain visible.Warning: Avoid using or extremely large values, as these lines cannot be removed from the client once sent. + /// The single to show the bounds to. + /// A collection of s to show the bounds to. + public static void Bounds(Bounds bounds, Color color, float duration, Player player = null, IEnumerable players = null) + { + Vector3 center = bounds.center; + Vector3 extents = bounds.extents; + + Vector3[] bottomRect = new Vector3[5]; + Vector3[] topRect = new Vector3[5]; + + bottomRect[0] = center + new Vector3(-extents.x, -extents.y, -extents.z); + bottomRect[1] = center + new Vector3(extents.x, -extents.y, -extents.z); + bottomRect[2] = center + new Vector3(extents.x, -extents.y, extents.z); + bottomRect[3] = center + new Vector3(-extents.x, -extents.y, extents.z); + bottomRect[4] = bottomRect[0]; + + topRect[0] = center + new Vector3(-extents.x, extents.y, -extents.z); + topRect[1] = center + new Vector3(extents.x, extents.y, -extents.z); + topRect[2] = center + new Vector3(extents.x, extents.y, extents.z); + topRect[3] = center + new Vector3(-extents.x, extents.y, extents.z); + topRect[4] = topRect[0]; + + Send(player, players, duration, color, bottomRect); + Send(player, players, duration, color, topRect); + + for (int i = 0; i < 4; i++) + { + Send(player, players, duration, color, bottomRect[i], topRect[i]); + } + } + + private static void Send(Player player, IEnumerable players, float duration, Color color, params Vector3[] points) + { + if (points == null || points.Length < 2) + return; + + DrawableLineMessage msg = new(duration, color, points); + + if (players != null) + { + using NetworkWriterPooled writer = NetworkWriterPool.Get(); + NetworkMessages.Pack(msg, writer); + ArraySegment segment = writer.ToArraySegment(); + + foreach (Player ply in players) + { + ply?.Connection.Send(segment); + } + } + else if (player != null) + { + player.Connection.Send(msg); + } + else + { + NetworkServer.SendToReady(msg); + } + } + } +} \ No newline at end of file