diff --git a/APITest/APITest.csproj b/APITest/APITest.csproj index ffb66ef..4cf446b 100644 --- a/APITest/APITest.csproj +++ b/APITest/APITest.csproj @@ -86,7 +86,7 @@ - + ..\Lib\Unity.TextMeshPro.dll @@ -108,7 +108,10 @@ + + + diff --git a/APITest/Commands/AddUI.cs b/APITest/Commands/AddUI.cs index 181553e..1c447c9 100644 --- a/APITest/Commands/AddUI.cs +++ b/APITest/Commands/AddUI.cs @@ -1,4 +1,5 @@ using APITest.UI; +using APITest.UI.Elements; using CommandSystem; using Exiled.API.Features; using MEC; @@ -26,14 +27,25 @@ public class AddUI : NotCommands public override string[] GetPerms() => null; - public override bool Function(string[] args, ICommandSender sender, out string result) + public override bool GetRequirePlayer() => true; + + public override bool PlayerBasedFunction(Player player, string[] args, out string result) { - Player player = Player.Get(sender); + if (!TryGetArgument(args, 1, out string arg1)) + { + PersonalDisplayBuilder display1 = new PersonalDisplayBuilder(StringBuilderPool.Shared.Rent()); + + player.GameObject.AddComponent()._mainDisplay = display1; - PersonalDisplayBuilder display = new PersonalDisplayBuilder(StringBuilderPool.Shared.Rent()); + result = "PersonalDisplay enabled!"; + return true; + } + + PersonalElementDisplay display = new PersonalElementDisplay(StringBuilderPool.Shared.Rent()); player.GameObject.AddComponent()._mainDisplay = display; - result = $"Working."; + + result = $"PersonalElement Enabled"; return false; } diff --git a/APITest/UI/Elements/HelloWorldElement.cs b/APITest/UI/Elements/HelloWorldElement.cs new file mode 100644 index 0000000..5083dd6 --- /dev/null +++ b/APITest/UI/Elements/HelloWorldElement.cs @@ -0,0 +1,33 @@ +using NotAnAPI.Features.UI.API.Elements; +using NotAnAPI.Features.UI.API.Enums; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using UnityEngine; + +namespace APITest.UI.Elements +{ + public class HelloWorldElement : Element + { + public override string Name { get; set; } = "Hello World"; + public override string Text { get; set; } = "Hello World"; + public override Vector2 Position { get; set; } = new Vector2(-500, 300); + + public override TextSettings Settings { get; set; } = new() + { + Size = 60, + }; + + public override UIScreenZone Zone { get; set; } = UIScreenZone.Center; + public override UIType UI { get; set; } = UIType.Alive; + + public override string OnRender() + { + Position = new Vector2(UnityEngine.Random.Range(0, 301), UnityEngine.Random.Range(0, 301)); + + return base.OnRender(); + } + } +} diff --git a/APITest/UI/Elements/ProfilePictureElement.cs b/APITest/UI/Elements/ProfilePictureElement.cs new file mode 100644 index 0000000..6a7cf06 --- /dev/null +++ b/APITest/UI/Elements/ProfilePictureElement.cs @@ -0,0 +1,33 @@ +using NotAnAPI.Features.UI.API.Elements; +using NotAnAPI.Features.UI.API.Enums; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using UnityEngine; + +namespace APITest.UI.Elements +{ + public class ProfilePictureElement : Element + { + public override string Name { get; set; } = "Profile Picture"; + public override string Text { get; set; } = "PFP"; + public override Vector2 Position { get; set; } = new Vector2(-900, 300); + + public override TextSettings Settings { get; set; } = new() + { + Size = 1.5f, + }; + + public override UIScreenZone Zone { get; set; } = UIScreenZone.Center; + public override UIType UI { get; set; } = UIType.Both; + + public override string OnRender() + { + Position = new Vector2(UnityEngine.Random.Range(0, 501), UnityEngine.Random.Range(0, 501)); + + return base.OnRender(); + } + } +} diff --git a/APITest/UI/PersonalElementDisplay.cs b/APITest/UI/PersonalElementDisplay.cs new file mode 100644 index 0000000..6cdef56 --- /dev/null +++ b/APITest/UI/PersonalElementDisplay.cs @@ -0,0 +1,33 @@ +using APITest.UI.Elements; +using NorthwoodLib.Pools; +using NotAnAPI.Features.UI.API.Abstract; +using NotAnAPI.Features.UI.API.Elements; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace APITest.UI +{ + public class PersonalElementDisplay : GameElementDisplay + { + private readonly StringBuilder _builder; + + public PersonalElementDisplay(StringBuilder builder) : base(builder) + { + _builder = builder; + } + + ~PersonalElementDisplay() => StringBuilderPool.Shared.Return(_builder); + + public override List Elements { get; set; } = new() + { + //Alive Elements + new HelloWorldElement(), + + //Both + new ProfilePictureElement(), + }; + } +} diff --git a/NotAnAPI/Features/UI/API/Abstract/GameDisplayBuilder.cs b/NotAnAPI/Features/UI/API/Abstract/GameDisplayBuilder.cs index 307026a..2873581 100644 --- a/NotAnAPI/Features/UI/API/Abstract/GameDisplayBuilder.cs +++ b/NotAnAPI/Features/UI/API/Abstract/GameDisplayBuilder.cs @@ -51,7 +51,7 @@ public void WithContent(UIScreenZone zone, string content) public void WithNotifications(List notifications) => _notifications = notifications; public void WithColor(string color) => _color = color; public void WithPlayer(Player player) => _player = player; - public void WithPFP(string pfp) => PFP = pfp; + public void WithPFP(string pfp) => PFP = "" + pfp + ""; public abstract void CustomUIAlive(StringBuilder builder, UIScreenZone zone); public abstract void CustomUISpectator(StringBuilder builder, UIScreenZone zone); diff --git a/NotAnAPI/Features/UI/API/Abstract/GameElementDisplay.cs b/NotAnAPI/Features/UI/API/Abstract/GameElementDisplay.cs new file mode 100644 index 0000000..0978435 --- /dev/null +++ b/NotAnAPI/Features/UI/API/Abstract/GameElementDisplay.cs @@ -0,0 +1,52 @@ +using Exiled.API.Features; +using NorthwoodLib.Pools; +using NotAnAPI.Features.UI.API.Elements; +using NotAnAPI.Features.UI.API.Enums; +using NotAnAPI.Features.UI.API.Interfaces; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using static System.Net.Mime.MediaTypeNames; + +namespace NotAnAPI.Features.UI.API.Abstract +{ + /// + /// The core and power of the UI + /// + public abstract class GameElementDisplay : GameDisplayBuilder, IElements + { + private readonly StringBuilder _builder; + public abstract List Elements { get; set; } + + public GameElementDisplay(StringBuilder builder) : base(builder) + { + _builder = builder; + } + + ~GameElementDisplay() => StringBuilderPool.Shared.Return(_builder); + + public void Renderer(StringBuilder builder, UIScreenZone zone, UIType type = UIType.Alive) + { + foreach (Element elements in Elements) + { + if (elements.UI != type && elements.UI != UIType.Both) continue; + if (elements.Zone != zone) continue; + + builder.Append(elements.OnRender().Replace("PFP", PFP)); + } + + } + + public override void CustomUIAlive(StringBuilder builder, UIScreenZone zone) + { + Renderer(builder, zone); + } + + public override void CustomUISpectator(StringBuilder builder, UIScreenZone zone) + { + Renderer(builder, zone, UIType.Spectator); + } + } +} diff --git a/NotAnAPI/Features/UI/API/Elements/Element.cs b/NotAnAPI/Features/UI/API/Elements/Element.cs new file mode 100644 index 0000000..b7eeea8 --- /dev/null +++ b/NotAnAPI/Features/UI/API/Elements/Element.cs @@ -0,0 +1,103 @@ +using Exiled.API.Features; +using NotAnAPI.API.Extensions; +using NotAnAPI.Features.UI.API.Enums; +using System; +using System.Collections.Generic; +using System.Drawing; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using UnityEngine; +using static System.Net.Mime.MediaTypeNames; + +namespace NotAnAPI.Features.UI.API.Elements +{ + public abstract class Element + { + + public abstract string Name { get; set; } + + public abstract string Text { get; set; } + + public abstract Vector2 Position { get; set; } + + public abstract TextSettings Settings { get; set; } + + public abstract UIScreenZone Zone { get; set; } + + public abstract UIType UI { get; set; } + + public virtual string OnRender(Player player) => OnRender(); + public virtual string OnRender() + { + StringBuilder sb = new StringBuilder(); + var lineList = Text.Split('\n'); + float yOffset = 0; + + foreach (var line in lineList) + { + //Basic + float xCoordinate = Position.x; + float yCoordinate = GetVOffset(Zone) - yOffset; + + if (xCoordinate != 0) sb.AddHorizontalPos(xCoordinate); + if (Settings.LineHeight >= 0) sb.SetLineHeight(Settings.LineHeight); + if (yCoordinate != 0) sb.AddVOffset(yCoordinate); + if (Settings.Size > 0) sb.SetSize(Settings.Size); + //Other options + + sb.Append(line); + + //Close Basic Settings + if (Settings.Size > 0) sb.CloseSize(); + if (yCoordinate != 0) sb.CloseVOffset(); + + sb.Append("\n"); + yOffset += Settings.Size; + } + + return sb.ToString(); + } + + //Thanks to HintServiceMeow for the screen calculation + //Credits to them + public float GetVOffset(UIScreenZone align) + { + float sizeOffset; + + switch (align) + { + case UIScreenZone.Top: + sizeOffset = -GetTextHeight(); + break; + case UIScreenZone.CenterTop: + sizeOffset = -GetTextHeight(); + break; + case UIScreenZone.Center: + sizeOffset = -GetTextHeight() / 2; + break; + case UIScreenZone.CenterBottom: + sizeOffset = -GetTextHeight(); + break; + case UIScreenZone.Bottom: + sizeOffset = 0; + break; + default: + sizeOffset = 0; + break; + } + + return 700 - Position.y + sizeOffset; + } + + public float GetTextHeight() + { + if (string.IsNullOrEmpty(Text)) + return 0; + + var height = Text.Split('\n').Length; + + return height; + } + } +} diff --git a/NotAnAPI/Features/UI/API/Elements/TextSettings.cs b/NotAnAPI/Features/UI/API/Elements/TextSettings.cs new file mode 100644 index 0000000..5f5e2f3 --- /dev/null +++ b/NotAnAPI/Features/UI/API/Elements/TextSettings.cs @@ -0,0 +1,19 @@ +using NotAnAPI.Features.UI.API.Enums; +using System; +using System.Collections.Generic; +using System.Drawing; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace NotAnAPI.Features.UI.API.Elements +{ + public class TextSettings + { + + public float Size { get; set; } = 0; + + public float LineHeight { get; set; } = 0; + + } +} diff --git a/NotAnAPI/Features/UI/API/Enums/UIType.cs b/NotAnAPI/Features/UI/API/Enums/UIType.cs new file mode 100644 index 0000000..3eb99cc --- /dev/null +++ b/NotAnAPI/Features/UI/API/Enums/UIType.cs @@ -0,0 +1,17 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace NotAnAPI.Features.UI.API.Enums +{ + public enum UIType + { + + Spectator, + Alive, + Both + + } +} diff --git a/NotAnAPI/Features/UI/API/Interfaces/IElements.cs b/NotAnAPI/Features/UI/API/Interfaces/IElements.cs new file mode 100644 index 0000000..6a16781 --- /dev/null +++ b/NotAnAPI/Features/UI/API/Interfaces/IElements.cs @@ -0,0 +1,16 @@ +using NotAnAPI.Features.UI.API.Elements; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace NotAnAPI.Features.UI.API.Interfaces +{ + /// + /// Marks all the classes that uses Elements + /// + public interface IElements + { + } +} diff --git a/NotAnAPI/NotAnAPI.csproj b/NotAnAPI/NotAnAPI.csproj index 8ae8eab..6416e94 100644 --- a/NotAnAPI/NotAnAPI.csproj +++ b/NotAnAPI/NotAnAPI.csproj @@ -255,11 +255,16 @@ + + + + +