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 @@
+
+
+
+
+