From c6cd2db71ecbd8ba54ba366ac8c8d1e4bd4c42d6 Mon Sep 17 00:00:00 2001 From: MSaska Date: Mon, 9 Feb 2026 21:44:16 +0100 Subject: [PATCH 1/5] Implemented Ruei hints :steamhappy: --- .../Helpers/FrameworkExtensions/RueiBridge.cs | 14 ++++ Code/MethodSystem/MethodIndex.cs | 1 + .../Methods/RueiMethods/RueHint.cs | 77 +++++++++++++++++++ .../Methods/RueiMethods/RueHintVisibility.cs | 44 +++++++++++ .../Structures/IDependOnFramework.cs | 3 +- Code/Plugin/MainPlugin.cs | 1 + SER.csproj | 3 + 7 files changed, 142 insertions(+), 1 deletion(-) create mode 100644 Code/Helpers/FrameworkExtensions/RueiBridge.cs create mode 100644 Code/MethodSystem/Methods/RueiMethods/RueHint.cs create mode 100644 Code/MethodSystem/Methods/RueiMethods/RueHintVisibility.cs diff --git a/Code/Helpers/FrameworkExtensions/RueiBridge.cs b/Code/Helpers/FrameworkExtensions/RueiBridge.cs new file mode 100644 index 0000000..53f50bf --- /dev/null +++ b/Code/Helpers/FrameworkExtensions/RueiBridge.cs @@ -0,0 +1,14 @@ +using MEC; + +namespace SER.Code.Helpers.FrameworkExtensions; + +public sealed class RueiBridge : FrameworkBridge +{ + public static event Action? OnDetected; + protected override string Name { get; } = "RueI"; + + public void Load() + { + Await(OnDetected).RunCoroutine(); + } +} \ No newline at end of file diff --git a/Code/MethodSystem/MethodIndex.cs b/Code/MethodSystem/MethodIndex.cs index 97bd59f..79c769f 100644 --- a/Code/MethodSystem/MethodIndex.cs +++ b/Code/MethodSystem/MethodIndex.cs @@ -25,6 +25,7 @@ internal static void Initialize() ExiledBridge.OnDetected += () => LoadMethodsOfFramework(IDependOnFramework.Type.Exiled); CallvoteBridge.OnDetected += () => LoadMethodsOfFramework(IDependOnFramework.Type.Callvote); UcrBridge.OnDetected += () => LoadMethodsOfFramework(IDependOnFramework.Type.Ucr); + RueiBridge.OnDetected += () => LoadMethodsOfFramework(IDependOnFramework.Type.Ruei); } /// diff --git a/Code/MethodSystem/Methods/RueiMethods/RueHint.cs b/Code/MethodSystem/Methods/RueiMethods/RueHint.cs new file mode 100644 index 0000000..2bd346b --- /dev/null +++ b/Code/MethodSystem/Methods/RueiMethods/RueHint.cs @@ -0,0 +1,77 @@ +using RueI.API; +using RueI.API.Elements; +using SER.Code.ArgumentSystem.Arguments; +using SER.Code.ArgumentSystem.BaseArguments; +using SER.Code.ArgumentSystem.Structures; +using SER.Code.MethodSystem.BaseMethods.Synchronous; +using SER.Code.MethodSystem.MethodDescriptors; +using SER.Code.MethodSystem.Structures; +using YamlDotNet.Core.Tokens; +using Tag = RueI.API.Elements.Tag; + +namespace SER.Code.MethodSystem.Methods.RueiMethods; + +public class RueHint : SynchronousMethod, IDependOnFramework +{ + public override string Description { get; } = "Sends or removes hints (in Rue library) of players"; + public override Argument[] ExpectedArguments { get; } = + [ + new PlayersArgument("players") + { + Description = "The players that will have hint shown/removed", + }, + new OptionsArgument("Modified option", + new Option("Show", "Shows the player hint with certain tag text and position"), + new Option("Remove", "Removes hint with certain id, doesn't require arguments after id.") + ) + { + Description = "Main option argument required." + }, + new TextArgument("Id") + { + Description = "Id required for the hint (if same id will be shown again it will override the last hint)", + }, + new TextArgument("Message") + { + DefaultValue = new("", null), + Description = "The message of hint shown, optional in case Option is set to Remove.", + }, + new FloatArgument("Position", 0, 1000) + { + DefaultValue = new(0, null), + Description = "The position of hint (Y position), optional in case Option is set to Remove." + }, + new DurationArgument("Duration") + { + DefaultValue = new(TimeSpan.MaxValue, null), + Description = "The duration of hint, optional in case Option is set to Remove." + } + ]; + public override void Execute() + { + var players = Args.GetPlayers("players"); + var option = Args.GetOption("Modified option"); + var id = Args.GetText("Id"); + var tag = new Tag(id); + var message = Args.GetText("Message"); + var position = Args.GetFloat("Position"); + var duration = Args.GetDuration("Duration"); + + foreach (var plr in players) + { + var display = RueDisplay.Get(plr); + if (option == "Remove") + { + display.Remove(tag); + continue; + } + + if (option == "Show") + { + display.Show(tag, new BasicElement(position, message), duration); + } + } + } + public IDependOnFramework.Type DependsOn { get; } = IDependOnFramework.Type.Ruei; +} + diff --git a/Code/MethodSystem/Methods/RueiMethods/RueHintVisibility.cs b/Code/MethodSystem/Methods/RueiMethods/RueHintVisibility.cs new file mode 100644 index 0000000..9f0b27e --- /dev/null +++ b/Code/MethodSystem/Methods/RueiMethods/RueHintVisibility.cs @@ -0,0 +1,44 @@ +using RueI.API; +using RueI.API.Elements; +using SER.Code.ArgumentSystem.Arguments; +using SER.Code.ArgumentSystem.BaseArguments; +using SER.Code.MethodSystem.BaseMethods.Synchronous; +using SER.Code.MethodSystem.Structures; + +namespace SER.Code.MethodSystem.Methods.RueiMethods; + +public class RueHintVisibility : SynchronousMethod, IDependOnFramework +{ + public override string Description { get; } = "Manages the visibility of already created hints of player"; + public override Argument[] ExpectedArguments { get; } = + [ + new PlayersArgument("players") + { + Description = "The players that will have hint shown/removed", + }, + new TextArgument("Id") + { + Description = "Id required for the hint (if same id will be shown again it will override the last hint)", + }, + new BoolArgument("IsVisible") + { + DefaultValue = new (true, null), + Description = "Sets the visibility of hint if Option set to Visibility" + }, + ]; + public override void Execute() + { + var players = Args.GetPlayers("players"); + var id = Args.GetText("Id"); + var tag = new Tag(id); + var isVisible = Args.GetBool("IsVisible"); + + foreach (var player in players) + { + var display = RueDisplay.Get(player); + display.SetVisible(tag, isVisible); + } + } + + public IDependOnFramework.Type DependsOn { get; } = IDependOnFramework.Type.Ruei; +} \ No newline at end of file diff --git a/Code/MethodSystem/Structures/IDependOnFramework.cs b/Code/MethodSystem/Structures/IDependOnFramework.cs index 7bc28bd..3f25cb5 100644 --- a/Code/MethodSystem/Structures/IDependOnFramework.cs +++ b/Code/MethodSystem/Structures/IDependOnFramework.cs @@ -10,7 +10,8 @@ public enum Type None, Exiled, Callvote, - Ucr + Ucr, + Ruei, } public Type DependsOn { get; } diff --git a/Code/Plugin/MainPlugin.cs b/Code/Plugin/MainPlugin.cs index c6f7dde..e1cc786 100644 --- a/Code/Plugin/MainPlugin.cs +++ b/Code/Plugin/MainPlugin.cs @@ -111,6 +111,7 @@ public override void Enable() new ExiledBridge().Load(); new CallvoteBridge().Load(); new UcrBridge().Load(); + new RueiBridge().Load(); SendLogo(); Events.ServerEvents.WaitingForPlayers += OnServerFullyInit; diff --git a/SER.csproj b/SER.csproj index f8800a5..8446655 100644 --- a/SER.csproj +++ b/SER.csproj @@ -70,6 +70,9 @@ $(SL_DEV_REFERENCES)\UncomplicatedCustomRoles-LabAPI.dll + + $(SL_DEV_REFERENCES)\RueI.dll + From e19c32a7c58ba583c6706543c8101bafb36dd3e5 Mon Sep 17 00:00:00 2001 From: MSaska Date: Mon, 9 Feb 2026 22:20:46 +0100 Subject: [PATCH 2/5] default value was broken and both needs method at the end of their name --- .../Methods/RueiMethods/{RueHint.cs => RueHintMethod.cs} | 8 ++++---- .../{RueHintVisibility.cs => RueHintVisibilityMethod.cs} | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) rename Code/MethodSystem/Methods/RueiMethods/{RueHint.cs => RueHintMethod.cs} (93%) rename Code/MethodSystem/Methods/RueiMethods/{RueHintVisibility.cs => RueHintVisibilityMethod.cs} (94%) diff --git a/Code/MethodSystem/Methods/RueiMethods/RueHint.cs b/Code/MethodSystem/Methods/RueiMethods/RueHintMethod.cs similarity index 93% rename from Code/MethodSystem/Methods/RueiMethods/RueHint.cs rename to Code/MethodSystem/Methods/RueiMethods/RueHintMethod.cs index 2bd346b..3b03a93 100644 --- a/Code/MethodSystem/Methods/RueiMethods/RueHint.cs +++ b/Code/MethodSystem/Methods/RueiMethods/RueHintMethod.cs @@ -11,7 +11,7 @@ namespace SER.Code.MethodSystem.Methods.RueiMethods; -public class RueHint : SynchronousMethod, IDependOnFramework +public class RueHintMethod : SynchronousMethod, IDependOnFramework { public override string Description { get; } = "Sends or removes hints (in Rue library) of players"; public override Argument[] ExpectedArguments { get; } = @@ -38,7 +38,7 @@ public class RueHint : SynchronousMethod, IDependOnFramework }, new FloatArgument("Position", 0, 1000) { - DefaultValue = new(0, null), + DefaultValue = new(0f, null), Description = "The position of hint (Y position), optional in case Option is set to Remove." }, new DurationArgument("Duration") @@ -60,13 +60,13 @@ public override void Execute() foreach (var plr in players) { var display = RueDisplay.Get(plr); - if (option == "Remove") + if (option == "remove") { display.Remove(tag); continue; } - if (option == "Show") + if (option == "show") { display.Show(tag, new BasicElement(position, message), duration); } diff --git a/Code/MethodSystem/Methods/RueiMethods/RueHintVisibility.cs b/Code/MethodSystem/Methods/RueiMethods/RueHintVisibilityMethod.cs similarity index 94% rename from Code/MethodSystem/Methods/RueiMethods/RueHintVisibility.cs rename to Code/MethodSystem/Methods/RueiMethods/RueHintVisibilityMethod.cs index 9f0b27e..bf00357 100644 --- a/Code/MethodSystem/Methods/RueiMethods/RueHintVisibility.cs +++ b/Code/MethodSystem/Methods/RueiMethods/RueHintVisibilityMethod.cs @@ -7,7 +7,7 @@ namespace SER.Code.MethodSystem.Methods.RueiMethods; -public class RueHintVisibility : SynchronousMethod, IDependOnFramework +public class RueHintVisibilityMethod : SynchronousMethod, IDependOnFramework { public override string Description { get; } = "Manages the visibility of already created hints of player"; public override Argument[] ExpectedArguments { get; } = From 390f66ca94168d8d9ff62a9a25bdda54546e3d38 Mon Sep 17 00:00:00 2001 From: MSaska Date: Tue, 10 Feb 2026 19:12:53 +0100 Subject: [PATCH 3/5] Bridge system rework to be dynamic. Ruei method now takes bool as last argument which is completely optional --- Code/ArgumentSystem/BaseArguments/Argument.cs | 2 +- .../FrameworkExtensions/CallVoteHelper.cs | 9 +- .../FrameworkExtensions/ExiledHelper.cs | 8 +- ...IFrameworkHelper.cs => FrameworkBridge.cs} | 16 ++- .../Registerable/Registerable.cs | 104 ++++++++++++++++++ .../Registerable/RegisterableList.cs | 52 +++++++++ Code/Helpers/FrameworkExtensions/RueBridge.cs | 15 +++ .../Helpers/FrameworkExtensions/RueiBridge.cs | 14 --- Code/Helpers/FrameworkExtensions/UcrBridge.cs | 9 +- Code/MethodSystem/MethodIndex.cs | 10 +- .../Methods/RueiMethods/RueHintMethod.cs | 16 ++- Code/Plugin/MainPlugin.cs | 15 ++- 12 files changed, 228 insertions(+), 42 deletions(-) rename Code/Helpers/FrameworkExtensions/{IFrameworkHelper.cs => FrameworkBridge.cs} (59%) create mode 100644 Code/Helpers/FrameworkExtensions/Registerable/Registerable.cs create mode 100644 Code/Helpers/FrameworkExtensions/Registerable/RegisterableList.cs create mode 100644 Code/Helpers/FrameworkExtensions/RueBridge.cs delete mode 100644 Code/Helpers/FrameworkExtensions/RueiBridge.cs diff --git a/Code/ArgumentSystem/BaseArguments/Argument.cs b/Code/ArgumentSystem/BaseArguments/Argument.cs index 45a1c6a..a786fae 100644 --- a/Code/ArgumentSystem/BaseArguments/Argument.cs +++ b/Code/ArgumentSystem/BaseArguments/Argument.cs @@ -20,7 +20,7 @@ public abstract class Argument(string name) /// public string? Description { get; init; } = null; - public record Default(object? Value, string? StringRep); + public record Default(object? Value, string? StringRep = null); /// /// Sets the default value for this argument, allowing it to be skipped by the user. diff --git a/Code/Helpers/FrameworkExtensions/CallVoteHelper.cs b/Code/Helpers/FrameworkExtensions/CallVoteHelper.cs index cb2c716..bf25140 100644 --- a/Code/Helpers/FrameworkExtensions/CallVoteHelper.cs +++ b/Code/Helpers/FrameworkExtensions/CallVoteHelper.cs @@ -1,14 +1,15 @@ using MEC; +using SER.Code.MethodSystem.Structures; namespace SER.Code.Helpers.FrameworkExtensions; public sealed class CallvoteBridge : FrameworkBridge { - public static event Action? OnDetected; protected override string Name => "Callvote"; - - public void Load() + public override IDependOnFramework.Type FrameworkType { get; } = IDependOnFramework.Type.Callvote; + + public CallvoteBridge() { - Await(OnDetected).RunCoroutine(); + } } \ No newline at end of file diff --git a/Code/Helpers/FrameworkExtensions/ExiledHelper.cs b/Code/Helpers/FrameworkExtensions/ExiledHelper.cs index 8de57b9..6e6654e 100644 --- a/Code/Helpers/FrameworkExtensions/ExiledHelper.cs +++ b/Code/Helpers/FrameworkExtensions/ExiledHelper.cs @@ -1,14 +1,16 @@ using MEC; +using SER.Code.MethodSystem.Structures; namespace SER.Code.Helpers.FrameworkExtensions; public sealed class ExiledBridge : FrameworkBridge { protected override string Name => "Exiled Loader"; - public static event Action? OnDetected; + public override bool ShouldRegister { get; } = false; + public override IDependOnFramework.Type FrameworkType { get; } = IDependOnFramework.Type.Exiled; - public void Load() + public ExiledBridge() { - Await(OnDetected).RunCoroutine(); + } } \ No newline at end of file diff --git a/Code/Helpers/FrameworkExtensions/IFrameworkHelper.cs b/Code/Helpers/FrameworkExtensions/FrameworkBridge.cs similarity index 59% rename from Code/Helpers/FrameworkExtensions/IFrameworkHelper.cs rename to Code/Helpers/FrameworkExtensions/FrameworkBridge.cs index 147ef6e..44052f6 100644 --- a/Code/Helpers/FrameworkExtensions/IFrameworkHelper.cs +++ b/Code/Helpers/FrameworkExtensions/FrameworkBridge.cs @@ -1,12 +1,26 @@ using LabApi.Features.Console; using LabApi.Loader; using MEC; +using PluginSCPSL.Library.Utility; +using SER.Code.MethodSystem; +using SER.Code.MethodSystem.Structures; namespace SER.Code.Helpers.FrameworkExtensions; -public abstract class FrameworkBridge +public abstract class FrameworkBridge : Registerable { protected abstract string Name { get; } + public abstract IDependOnFramework.Type FrameworkType { get; } + public event Action? OnDetected; + + public override bool IsDebug { get; } = true; + + protected override void OnRegistered() + { + OnDetected += () => MethodIndex.LoadMethodsOfFramework(FrameworkType); + Await(OnDetected).RunCoroutine(); + base.OnRegistered(); + } protected IEnumerator Await(Action? onDetected) { diff --git a/Code/Helpers/FrameworkExtensions/Registerable/Registerable.cs b/Code/Helpers/FrameworkExtensions/Registerable/Registerable.cs new file mode 100644 index 0000000..a8b87e0 --- /dev/null +++ b/Code/Helpers/FrameworkExtensions/Registerable/Registerable.cs @@ -0,0 +1,104 @@ +using System; +using System.Reflection; +using SER.Code.Helpers; +using Log = Exiled.API.Features.Log; + +namespace PluginSCPSL.Library.Utility; + +public class Registerable where TSelf : Registerable +{ + public static RegisterableList Registered { get; } = new(OnAdd, OnRemove, () => {}); + + public virtual bool IsDebug => false; + public virtual bool ShouldRegister => true; + private Assembly _assembly = null; + + private static void OnAdd(TSelf item) + { + item._assembly ??= typeof(TSelf).Assembly; + item.OnRegistered(); + } + + private static void OnRemove(TSelf item) + { + item.OnUnregistered(); + } + + protected virtual void OnRegistered() { } + protected virtual void OnUnregistered() { } + + public static void RegisterAll(Assembly assembly = null) + { + assembly ??= Assembly.GetCallingAssembly(); + foreach (var type in assembly.GetTypes()) + { + if (type.IsAbstract) continue; + if (typeof(TSelf) == type) + { + Log.Info($"Skipping {type.Name}, because it's the original instance."); + continue; + } + if (!type.IsSubclassOf(typeof(TSelf))) continue; + if (type.GetConstructor([]) == null) + { + Log.Error($"Type {type.Name} could not be registered, please add default constructor"); + continue; + } + TSelf instance; + try + { + instance = (TSelf)Activator.CreateInstance(type); + } + catch (Exception e) + { + Log.Error($"Instance registration error. Type: {type}\nMessage: {e}"); + continue; + } + instance._assembly = assembly; + + if (instance.ShouldRegister && instance.ShouldAddInstance()) + { + if (instance.IsDebug) + { + Log.Info($"Adding {type.Name} as {typeof(TSelf).Name}"); + } + Registered.Add(instance); + } + } + } + + public virtual TSelf CloneMyself() + { + if (this.GetType().GetConstructor([]) == null) + { + Log.Error($"{this.GetType().Name} does not have default constructor"); + return null; + } + return (TSelf)Activator.CreateInstance(this.GetType()); + } + + public virtual bool ShouldAddInstance() + { + return true; + } + + public static void Register(TSelf instance) + { + Registered.Add(instance); + } + + public static void Unregister(TSelf instance) + { + Registered.Remove(instance); + } + + public static void UnregisterAll(Assembly assembly = null) + { + assembly ??= Assembly.GetCallingAssembly(); + foreach (var i in Registered) + { + i.OnUnregistered(); + } + Registered.RemoveAll(r => r._assembly == assembly); + } +} \ No newline at end of file diff --git a/Code/Helpers/FrameworkExtensions/Registerable/RegisterableList.cs b/Code/Helpers/FrameworkExtensions/Registerable/RegisterableList.cs new file mode 100644 index 0000000..bd93d08 --- /dev/null +++ b/Code/Helpers/FrameworkExtensions/Registerable/RegisterableList.cs @@ -0,0 +1,52 @@ +#nullable enable +namespace SER.Code.Helpers; + +public class RegisterableList : List +{ + public Action OnAdd { get; set; } + public Action OnRemove { get; set; } + public Action OnClear { get; set; } + + public RegisterableList() + { + + } + + public RegisterableList(Action onAdd, Action onRemove, Action onClear) + { + OnAdd = onAdd; + OnRemove = onRemove; + OnClear = onClear; + } + + public new void Add(T item) + { + OnAdd?.Invoke(item); + base.Add(item); + } + + public new bool Remove(T item) + { + OnRemove?.Invoke(item); + return base.Remove(item); + } + + public new void Clear() + { + OnClear?.Invoke(); + foreach (var i in this) + { + OnRemove?.Invoke(i); + } + base.Clear(); + } + + public new void RemoveAll(Predicate match) + { + foreach (var item in this) + { + if(match(item)) OnRemove?.Invoke(item); + } + base.RemoveAll(match); + } +} \ No newline at end of file diff --git a/Code/Helpers/FrameworkExtensions/RueBridge.cs b/Code/Helpers/FrameworkExtensions/RueBridge.cs new file mode 100644 index 0000000..dd5c265 --- /dev/null +++ b/Code/Helpers/FrameworkExtensions/RueBridge.cs @@ -0,0 +1,15 @@ +using MEC; +using SER.Code.MethodSystem.Structures; + +namespace SER.Code.Helpers.FrameworkExtensions; + +public sealed class RueBridge : FrameworkBridge +{ + protected override string Name { get; } = "RueI"; + public override IDependOnFramework.Type FrameworkType { get; } = IDependOnFramework.Type.Ruei; + + public RueBridge() + { + + } +} \ No newline at end of file diff --git a/Code/Helpers/FrameworkExtensions/RueiBridge.cs b/Code/Helpers/FrameworkExtensions/RueiBridge.cs deleted file mode 100644 index 53f50bf..0000000 --- a/Code/Helpers/FrameworkExtensions/RueiBridge.cs +++ /dev/null @@ -1,14 +0,0 @@ -using MEC; - -namespace SER.Code.Helpers.FrameworkExtensions; - -public sealed class RueiBridge : FrameworkBridge -{ - public static event Action? OnDetected; - protected override string Name { get; } = "RueI"; - - public void Load() - { - Await(OnDetected).RunCoroutine(); - } -} \ No newline at end of file diff --git a/Code/Helpers/FrameworkExtensions/UcrBridge.cs b/Code/Helpers/FrameworkExtensions/UcrBridge.cs index 04615e3..f03a8bb 100644 --- a/Code/Helpers/FrameworkExtensions/UcrBridge.cs +++ b/Code/Helpers/FrameworkExtensions/UcrBridge.cs @@ -1,14 +1,15 @@ using MEC; +using SER.Code.MethodSystem.Structures; namespace SER.Code.Helpers.FrameworkExtensions; public sealed class UcrBridge : FrameworkBridge { - public static event Action? OnDetected; protected override string Name => "UncomplicatedCustomRoles"; - - public void Load() + public override IDependOnFramework.Type FrameworkType { get; } = IDependOnFramework.Type.Ucr; + + public UcrBridge() { - Await(OnDetected).RunCoroutine(); + } } \ No newline at end of file diff --git a/Code/MethodSystem/MethodIndex.cs b/Code/MethodSystem/MethodIndex.cs index 79c769f..9862e82 100644 --- a/Code/MethodSystem/MethodIndex.cs +++ b/Code/MethodSystem/MethodIndex.cs @@ -1,6 +1,7 @@ using System.Reflection; using LabApi.Features.Console; using SER.Code.Extensions; +using SER.Code.Helpers; using SER.Code.Helpers.FrameworkExtensions; using SER.Code.Helpers.ResultSystem; using SER.Code.MethodSystem.BaseMethods; @@ -21,11 +22,8 @@ internal static void Initialize() NameToMethodIndex.Clear(); AddAllDefinedMethodsInAssembly(); - - ExiledBridge.OnDetected += () => LoadMethodsOfFramework(IDependOnFramework.Type.Exiled); - CallvoteBridge.OnDetected += () => LoadMethodsOfFramework(IDependOnFramework.Type.Callvote); - UcrBridge.OnDetected += () => LoadMethodsOfFramework(IDependOnFramework.Type.Ucr); - RueiBridge.OnDetected += () => LoadMethodsOfFramework(IDependOnFramework.Type.Ruei); + + FrameworkBridge.RegisterAll(); } /// @@ -104,7 +102,7 @@ public static TryGet TryGetMethod(string name) return $"There is no method with name '{name}'. Did you mean '{closestMethod ?? ""}'?"; } - private static void LoadMethodsOfFramework(IDependOnFramework.Type framework) + public static void LoadMethodsOfFramework(IDependOnFramework.Type framework) { foreach (var method in FrameworkDependentMethods.TryGetValue(framework, out var methods) ? methods : []) { diff --git a/Code/MethodSystem/Methods/RueiMethods/RueHintMethod.cs b/Code/MethodSystem/Methods/RueiMethods/RueHintMethod.cs index 3b03a93..2f27c59 100644 --- a/Code/MethodSystem/Methods/RueiMethods/RueHintMethod.cs +++ b/Code/MethodSystem/Methods/RueiMethods/RueHintMethod.cs @@ -33,19 +33,24 @@ public class RueHintMethod : SynchronousMethod, IDependOnFramework }, new TextArgument("Message") { - DefaultValue = new("", null), + DefaultValue = new(""), Description = "The message of hint shown, optional in case Option is set to Remove.", }, new FloatArgument("Position", 0, 1000) { - DefaultValue = new(0f, null), + DefaultValue = new(0f), Description = "The position of hint (Y position), optional in case Option is set to Remove." }, new DurationArgument("Duration") { - DefaultValue = new(TimeSpan.MaxValue, null), + DefaultValue = new(TimeSpan.MaxValue), Description = "The duration of hint, optional in case Option is set to Remove." - } + }, + new BoolArgument("UseResolution") + { + DefaultValue = new(false), + Description = "Automatically formats hint on the Y position to use resolution player sets (option) (X resolution is unable to be calculated)", + }, ]; public override void Execute() { @@ -56,6 +61,7 @@ public override void Execute() var message = Args.GetText("Message"); var position = Args.GetFloat("Position"); var duration = Args.GetDuration("Duration"); + var resolution = Args.GetBool("UseResolution"); foreach (var plr in players) { @@ -68,7 +74,7 @@ public override void Execute() if (option == "show") { - display.Show(tag, new BasicElement(position, message), duration); + display.Show(tag, new BasicElement(position, message) {ResolutionBasedAlign = resolution}, duration); } } } diff --git a/Code/Plugin/MainPlugin.cs b/Code/Plugin/MainPlugin.cs index e1cc786..fde190d 100644 --- a/Code/Plugin/MainPlugin.cs +++ b/Code/Plugin/MainPlugin.cs @@ -104,14 +104,18 @@ public override void Enable() Script.StopAll(); EventHandler.Initialize(); + MethodIndex.Initialize(); VariableIndex.Initialize(); Flag.RegisterFlags(); CommandEvents.Initialize(); - new ExiledBridge().Load(); - new CallvoteBridge().Load(); - new UcrBridge().Load(); - new RueiBridge().Load(); + + + /*foreach (var i in FrameworkBridge.Registered) + { + i.Load(); + }*/ + SendLogo(); Events.ServerEvents.WaitingForPlayers += OnServerFullyInit; @@ -124,6 +128,9 @@ public override void Enable() public override void Disable() { Script.StopAll(); + + FrameworkBridge.Registered.Clear(); + SetPlayerDataMethod.PlayerData.Clear(); } From 8f6e0f47ff53434875cb5b4390d2d87ba231a5f0 Mon Sep 17 00:00:00 2001 From: MSaska Date: Tue, 10 Feb 2026 19:40:16 +0100 Subject: [PATCH 4/5] So like I removed generics, can be added back when CLR issues are resolved. --- .../Synchronous/ReferenceReturningMethod.cs | 2 +- .../Methods/UCRMethods/GetUCRRoleMethod.cs | 11 ++++++----- .../Methods/VotingMethods/StartVoteAndWaitMethod.cs | 4 +++- .../Methods/VotingMethods/VoteOptionMethod.cs | 9 ++++++--- Code/ValueSystem/TypeOfValue.cs | 4 ++-- 5 files changed, 18 insertions(+), 12 deletions(-) diff --git a/Code/MethodSystem/BaseMethods/Synchronous/ReferenceReturningMethod.cs b/Code/MethodSystem/BaseMethods/Synchronous/ReferenceReturningMethod.cs index 000805a..db24aea 100644 --- a/Code/MethodSystem/BaseMethods/Synchronous/ReferenceReturningMethod.cs +++ b/Code/MethodSystem/BaseMethods/Synchronous/ReferenceReturningMethod.cs @@ -13,7 +13,7 @@ public abstract class ReferenceReturningMethod : ReturningMethod public abstract class ReferenceReturningMethod : ReferenceReturningMethod { - public override Type ReturnType => typeof(T); + public sealed override Type ReturnType => typeof(T); protected new T ReturnValue { diff --git a/Code/MethodSystem/Methods/UCRMethods/GetUCRRoleMethod.cs b/Code/MethodSystem/Methods/UCRMethods/GetUCRRoleMethod.cs index baa81e7..68cac70 100644 --- a/Code/MethodSystem/Methods/UCRMethods/GetUCRRoleMethod.cs +++ b/Code/MethodSystem/Methods/UCRMethods/GetUCRRoleMethod.cs @@ -5,6 +5,7 @@ using SER.Code.MethodSystem.MethodDescriptors; using SER.Code.MethodSystem.Methods.ReferenceVariableMethods; using SER.Code.MethodSystem.Structures; +using SER.Code.ValueSystem; using UncomplicatedCustomRoles.API.Features; using UncomplicatedCustomRoles.API.Interfaces; @@ -12,10 +13,8 @@ namespace SER.Code.MethodSystem.Methods.UCRMethods; [UsedImplicitly] // ReSharper disable once InconsistentNaming -public class GetUCRRoleMethod : ReferenceReturningMethod, IAdditionalDescription, IDependOnFramework +public class GetUCRRoleMethod : ReferenceReturningMethod, IAdditionalDescription, IDependOnFramework { - public override Type ReturnType => typeof(ICustomRole); - public IDependOnFramework.Type DependsOn => IDependOnFramework.Type.Ucr; public override string Description => "Returns a reference to the UCR role a player has."; @@ -28,9 +27,11 @@ public class GetUCRRoleMethod : ReferenceReturningMethod, IAddition [ new PlayerArgument("player") ]; - + public override void Execute() { - ReturnValue = SummonedCustomRole.Get(Args.GetPlayer("player"))?.Role!; + ReturnValue = new ReferenceValue(SummonedCustomRole.Get(Args.GetPlayer("player"))?.Role!); } + + public override Type ReturnType { get; } = typeof(ICustomRole); } \ No newline at end of file diff --git a/Code/MethodSystem/Methods/VotingMethods/StartVoteAndWaitMethod.cs b/Code/MethodSystem/Methods/VotingMethods/StartVoteAndWaitMethod.cs index 5b20a62..e3a6510 100644 --- a/Code/MethodSystem/Methods/VotingMethods/StartVoteAndWaitMethod.cs +++ b/Code/MethodSystem/Methods/VotingMethods/StartVoteAndWaitMethod.cs @@ -15,7 +15,7 @@ namespace SER.Code.MethodSystem.Methods.VotingMethods; [UsedImplicitly] -public class StartVoteAndWaitMethod : YieldingReturningMethod, IAdditionalDescription, IDependOnFramework +public class StartVoteAndWaitMethod : YieldingReturningMethod, IAdditionalDescription, IDependOnFramework { public IDependOnFramework.Type DependsOn => IDependOnFramework.Type.Callvote; @@ -76,4 +76,6 @@ void Callback(Voting vote) result = topKeys.Length > 1 ? "tie" : topKeys[0]; } } + + public override TypeOfValue Returns => new TypesOfValue(typeof(TextValue)); } \ No newline at end of file diff --git a/Code/MethodSystem/Methods/VotingMethods/VoteOptionMethod.cs b/Code/MethodSystem/Methods/VotingMethods/VoteOptionMethod.cs index 7ab3834..111d741 100644 --- a/Code/MethodSystem/Methods/VotingMethods/VoteOptionMethod.cs +++ b/Code/MethodSystem/Methods/VotingMethods/VoteOptionMethod.cs @@ -3,14 +3,15 @@ using SER.Code.ArgumentSystem.BaseArguments; using SER.Code.MethodSystem.BaseMethods.Synchronous; using SER.Code.MethodSystem.Structures; +using SER.Code.ValueSystem; namespace SER.Code.MethodSystem.Methods.VotingMethods; [UsedImplicitly] -public class VoteOptionMethod : ReferenceReturningMethod, IDependOnFramework +public class VoteOptionMethod : ReferenceReturningMethod, IDependOnFramework { public IDependOnFramework.Type DependsOn => IDependOnFramework.Type.Callvote; - + public record VoteOption(string Key, string DisplayText); public override string Description => "Creates a vote option, which can be used in a vote."; @@ -32,6 +33,8 @@ public override void Execute() var key = Args.GetText("key"); var displayText = Args.GetText("display text"); - ReturnValue = new(key, displayText); + ReturnValue = new ReferenceValue(new VoteOption(key, displayText)); } + + public override Type ReturnType { get; } = typeof(VoteOption); } \ No newline at end of file diff --git a/Code/ValueSystem/TypeOfValue.cs b/Code/ValueSystem/TypeOfValue.cs index f0a870b..5b09d03 100644 --- a/Code/ValueSystem/TypeOfValue.cs +++ b/Code/ValueSystem/TypeOfValue.cs @@ -22,12 +22,12 @@ protected TypeOfValue(Type? required) public class TypesOfValue : TypeOfValue { - public TypesOfValue(SingleTypeOfValue[] types) : base(types.Select(t => t.Type).ToArray()) + public TypesOfValue(params SingleTypeOfValue[] types) : base(types.Select(t => t.Type).ToArray()) { _types = types.Select(t => t.Type).ToArray(); } - public TypesOfValue(Type[] types) : base(types) + public TypesOfValue(params Type[] types) : base(types) { _types = types; } From 56e7b58eb563e4ff440e62506259d0d7bfbe5634 Mon Sep 17 00:00:00 2001 From: MSaska Date: Tue, 10 Feb 2026 21:06:29 +0100 Subject: [PATCH 5/5] Some object methods and TypeOfValue pmo --- .../ObjectMethods/CreatePrimitiveMethod.cs | 92 +++++++++++++++++++ .../GetPrimitiveStructureMethod.cs | 54 +++++++++++ .../ObjectMethods/HitSomethingMethod.cs | 48 ++++++++++ .../ObjectMethods/IsPrimitiveMethod.cs | 41 +++++++++ .../Methods/ObjectMethods/MaskHelper.cs | 37 ++++++++ .../ObjectMethods/ParentObjectsMethod.cs | 49 ++++++++++ .../ObjectMethods/PrimitiveColorMethod.cs | 40 ++++++++ .../ObjectMethods/PrimitiveStructureMethod.cs | 62 +++++++++++++ .../Methods/ObjectMethods/RaycastMethod.cs | 46 ++++++++++ Code/ValueSystem/TypeOfValue.cs | 12 ++- 10 files changed, 480 insertions(+), 1 deletion(-) create mode 100644 Code/MethodSystem/Methods/ObjectMethods/CreatePrimitiveMethod.cs create mode 100644 Code/MethodSystem/Methods/ObjectMethods/GetPrimitiveStructureMethod.cs create mode 100644 Code/MethodSystem/Methods/ObjectMethods/HitSomethingMethod.cs create mode 100644 Code/MethodSystem/Methods/ObjectMethods/IsPrimitiveMethod.cs create mode 100644 Code/MethodSystem/Methods/ObjectMethods/MaskHelper.cs create mode 100644 Code/MethodSystem/Methods/ObjectMethods/ParentObjectsMethod.cs create mode 100644 Code/MethodSystem/Methods/ObjectMethods/PrimitiveColorMethod.cs create mode 100644 Code/MethodSystem/Methods/ObjectMethods/PrimitiveStructureMethod.cs create mode 100644 Code/MethodSystem/Methods/ObjectMethods/RaycastMethod.cs diff --git a/Code/MethodSystem/Methods/ObjectMethods/CreatePrimitiveMethod.cs b/Code/MethodSystem/Methods/ObjectMethods/CreatePrimitiveMethod.cs new file mode 100644 index 0000000..d9aff30 --- /dev/null +++ b/Code/MethodSystem/Methods/ObjectMethods/CreatePrimitiveMethod.cs @@ -0,0 +1,92 @@ +using AdminToys; +using SER.Code.ArgumentSystem.Arguments; +using SER.Code.ArgumentSystem.BaseArguments; +using SER.Code.MethodSystem.BaseMethods.Synchronous; +using UnityEngine; +using PrimitiveObjectToy = LabApi.Features.Wrappers.PrimitiveObjectToy; + +namespace SER.Code.MethodSystem.Methods.ObjectMethods; + +public class CreatePrimitiveMethod : ReferenceReturningMethod +{ + public override string Description { get; } = "Method to create primitive"; + + public override Argument[] ExpectedArguments { get; } = + [ + new EnumArgument("primitiveType"), + new ColorArgument("color"), + + new FloatArgument("x_position"), + new FloatArgument("y_position"), + new FloatArgument("z_position"), + + new FloatArgument("x_rotation") + { + DefaultValue = new(1f), + }, + new FloatArgument("y_rotation") + { + DefaultValue = new(1f), + }, + new FloatArgument("z_rotation") + { + DefaultValue = new(1f), + }, + + new FloatArgument("x_scale") + { + DefaultValue = new(1f) + }, + new FloatArgument("y_scale") + { + DefaultValue = new(1f) + }, + new FloatArgument("z_scale") + { + DefaultValue = new(1f) + }, + + new BoolArgument("IsNetworked") + { + DefaultValue = new(true), + }, + + new EnumArgument("flags") + { + DefaultValue = new(PrimitiveFlags.Collidable | PrimitiveFlags.Visible), + } + ]; + + public override void Execute() + { + var type = Args.GetEnum("primitiveType"); + var color = Args.GetColor("color"); + var flags = Args.GetEnum("flags"); + + var xPos = Args.GetFloat("x_position"); + var yPos = Args.GetFloat("y_position"); + var zPos = Args.GetFloat("z_position"); + + var xRot = Args.GetFloat("x_rotation"); + var yRot = Args.GetFloat("y_rotation"); + var zRot = Args.GetFloat("z_rotation"); + + var xScl = Args.GetFloat("x_scale"); + var yScl = Args.GetFloat("y_scale"); + var zScl = Args.GetFloat("z_scale"); + + var spawn = Args.GetBool("IsNetworked"); + + var pos = new Vector3(xPos, yPos, zPos); + var rot = new Vector3(xRot, yRot, zRot); + var scl = new Vector3(xScl, yScl, zScl); + + var prim = PrimitiveObjectToy.Create(pos, Quaternion.Euler(rot), scl, null, false); + prim.Base.NetworkPrimitiveType = type; + prim.Color = color; + prim.Flags = flags; + + if (spawn) + prim.Spawn(); + } +} \ No newline at end of file diff --git a/Code/MethodSystem/Methods/ObjectMethods/GetPrimitiveStructureMethod.cs b/Code/MethodSystem/Methods/ObjectMethods/GetPrimitiveStructureMethod.cs new file mode 100644 index 0000000..80eab23 --- /dev/null +++ b/Code/MethodSystem/Methods/ObjectMethods/GetPrimitiveStructureMethod.cs @@ -0,0 +1,54 @@ +using AdminToys; +using LabApi.Features.Wrappers; +using SER.Code.ArgumentSystem.Arguments; +using SER.Code.ArgumentSystem.BaseArguments; +using SER.Code.ArgumentSystem.Structures; +using SER.Code.MethodSystem.BaseMethods.Synchronous; +using SER.Code.MethodSystem.MethodDescriptors; +using UnityEngine; +using PrimitiveObjectToy = LabApi.Features.Wrappers.PrimitiveObjectToy; + +namespace SER.Code.MethodSystem.Methods.ObjectMethods; + +public class GetPrimitiveStructureMethod : ReferenceReturningMethod, ICanError +{ + public override string Description { get; } = "Changes the position of primitive."; + public override Argument[] ExpectedArguments { get; } = + [ + new ReferenceArgument("object") + { + Description = "The GameObject that you want to change Position/Rotation/Scale of", + }, + new OptionsArgument("option", "Position, Rotation, Scale"), + ]; + public override void Execute() + { + var obj = Args.GetReference("object"); + var option = Args.GetOption("option"); + + var adminToy = AdminToy.Get(obj.GetComponent()); + if (adminToy is not PrimitiveObjectToy primitiveObjectToy) + { + Script.Executor.Error(ErrorReasons[0], Script); + return; + } + + switch (option) + { + case "position": + ReturnValue = primitiveObjectToy.Position; + break; + case "rotation": + ReturnValue = primitiveObjectToy.Rotation.eulerAngles; + break; + case "scale": + ReturnValue = primitiveObjectToy.Scale; + break; + } + } + + public string[] ErrorReasons { get; } = + [ + "Not all gameObjects can change colour. This one is not Primitive (cube, sphere, circle, cylinder, etc.)" + ]; +} \ No newline at end of file diff --git a/Code/MethodSystem/Methods/ObjectMethods/HitSomethingMethod.cs b/Code/MethodSystem/Methods/ObjectMethods/HitSomethingMethod.cs new file mode 100644 index 0000000..3e3fbfd --- /dev/null +++ b/Code/MethodSystem/Methods/ObjectMethods/HitSomethingMethod.cs @@ -0,0 +1,48 @@ +using SER.Code.ArgumentSystem.Arguments; +using SER.Code.ArgumentSystem.BaseArguments; +using SER.Code.MethodSystem.BaseMethods.Synchronous; +using SER.Code.ValueSystem; +using UnityEngine; + +namespace SER.Code.MethodSystem.Methods.ObjectMethods; + +public class HitSomethingMethod : ReturningMethod +{ + public override string Description { get; } = + "Returns true if raycast hit something, false if out of bounds (player didn't see anything in range)"; + public override Argument[] ExpectedArguments { get; } = + [ + new PlayerArgument("player") + { + Description = "Single player which will return the game object the player is looking at", + }, + new FloatArgument("max distance") + { + Description = "Maximum distance of the raycast", + }, + new EnumArgument("layer") + { + Description = "Layer mask meaning what raycast can and can't go through.", + DefaultValue = new (MaskHelper.Layers.TransparentFX | MaskHelper.Layers.Hitbox | MaskHelper.Layers.InvisibleCollider | MaskHelper.Layers.Skybox), + } + ]; + public override void Execute() + { + var player = Args.GetPlayer("player"); + var maxDistance = Args.GetFloat("max distance"); + var layer = Args.GetEnum("layer"); + var mask = MaskHelper.GetLayerMask(layer); + + if (!Physics.Raycast(player.Camera.position, player.Camera.forward, out var raycastHit, + maxDistance, ~mask)) + { + // Out of range + ReturnValue = new BoolValue(false); + return; + } + + ReturnValue = new BoolValue(true); + } + + public override TypeOfValue Returns { get; } = typeof(bool); +} \ No newline at end of file diff --git a/Code/MethodSystem/Methods/ObjectMethods/IsPrimitiveMethod.cs b/Code/MethodSystem/Methods/ObjectMethods/IsPrimitiveMethod.cs new file mode 100644 index 0000000..2a90525 --- /dev/null +++ b/Code/MethodSystem/Methods/ObjectMethods/IsPrimitiveMethod.cs @@ -0,0 +1,41 @@ +using AdminToys; +using LabApi.Features.Wrappers; +using SER.Code.ArgumentSystem.Arguments; +using SER.Code.ArgumentSystem.BaseArguments; +using SER.Code.MethodSystem.BaseMethods.Synchronous; +using SER.Code.MethodSystem.MethodDescriptors; +using SER.Code.ValueSystem; +using UnityEngine; +using PrimitiveObjectToy = LabApi.Features.Wrappers.PrimitiveObjectToy; + +namespace SER.Code.MethodSystem.Methods.ObjectMethods; + +public class IsPrimitiveMethod : ReturningMethod +{ + public override string Description { get; } = "Checks if GameObject is primitive, also checks if GameObject is null or not (can be pared with raycast)."; + public override Argument[] ExpectedArguments { get; } = + [ + new ReferenceArgument("object"), + ]; + public override void Execute() + { + var obj = Args.GetReference("object"); + + if (obj == null) + { + ReturnValue = new BoolValue(false); + return; + } + + var adminToy = AdminToy.Get(obj.GetComponent()); + if (adminToy is not PrimitiveObjectToy primitiveObjectToy) + { + ReturnValue = new BoolValue(false); + return; + } + + ReturnValue = new BoolValue(true); + } + + public override TypeOfValue Returns { get; } = typeof(bool); +} \ No newline at end of file diff --git a/Code/MethodSystem/Methods/ObjectMethods/MaskHelper.cs b/Code/MethodSystem/Methods/ObjectMethods/MaskHelper.cs new file mode 100644 index 0000000..c9e77df --- /dev/null +++ b/Code/MethodSystem/Methods/ObjectMethods/MaskHelper.cs @@ -0,0 +1,37 @@ +namespace SER.Code.MethodSystem.Methods.ObjectMethods; + +public class MaskHelper +{ + public static int GetLayerMask(Layers layers) + { + return (int)layers; + } + + [Flags] + public enum Layers + { + None = 0, + + Default = 1 << 0, + TransparentFX = 1 << 1, + IgnoreRaycast = 1 << 2, + Water = 1 << 4, + UI = 1 << 5, + Player = 1 << 8, + InteractableNoPlayerCollision = 1 << 9, + Viewmodel = 1 << 10, + RenderAfterFog = 1 << 12, + Hitbox = 1 << 13, + Glass = 1 << 14, + InvisibleCollider = 1 << 16, + Ragdoll = 1 << 17, + CCTV = 1 << 18, + Grenade = 1 << 20, + Phantom = 1 << 21, + OnlyWorldCollision = 1 << 25, + Door = 1 << 27, + Skybox = 1 << 28, + Fence = 1 << 29, + } + +} \ No newline at end of file diff --git a/Code/MethodSystem/Methods/ObjectMethods/ParentObjectsMethod.cs b/Code/MethodSystem/Methods/ObjectMethods/ParentObjectsMethod.cs new file mode 100644 index 0000000..f710c0b --- /dev/null +++ b/Code/MethodSystem/Methods/ObjectMethods/ParentObjectsMethod.cs @@ -0,0 +1,49 @@ +using SER.Code.ArgumentSystem.Arguments; +using SER.Code.ArgumentSystem.BaseArguments; +using SER.Code.MethodSystem.BaseMethods.Synchronous; +using SER.Code.MethodSystem.MethodDescriptors; +using UnityEngine; + +namespace SER.Code.MethodSystem.Methods.ObjectMethods; + +public class ParentObjectsMethod : SynchronousMethod, ICanError +{ + public override string Description { get; } = "Parents child to parent"; + + public override Argument[] ExpectedArguments { get; } = + [ + new ReferenceArgument("child") + { + Description = "The child that will follor parents position", + }, + new ReferenceArgument("parent") + { + Description = "The parent that will have object under itself." + }, + ]; + public override void Execute() + { + var child = Args.GetReference("child"); + var parent = Args.GetReference("parent"); + + if (child == null) + { + Script.Error(ErrorReasons[0]); + return; + } + + if (parent == null) + { + Script.Error(ErrorReasons[1]); + return; + } + + child.transform.parent = parent.transform; + } + + public string[] ErrorReasons { get; } = + [ + "Child is null (not existent)", + "Parent is null (not existent)", + ]; +} \ No newline at end of file diff --git a/Code/MethodSystem/Methods/ObjectMethods/PrimitiveColorMethod.cs b/Code/MethodSystem/Methods/ObjectMethods/PrimitiveColorMethod.cs new file mode 100644 index 0000000..6b51b9b --- /dev/null +++ b/Code/MethodSystem/Methods/ObjectMethods/PrimitiveColorMethod.cs @@ -0,0 +1,40 @@ +using AdminToys; +using LabApi.Features.Wrappers; +using SER.Code.ArgumentSystem.Arguments; +using SER.Code.ArgumentSystem.BaseArguments; +using SER.Code.MethodSystem.BaseMethods.Synchronous; +using SER.Code.MethodSystem.MethodDescriptors; +using UnityEngine; +using PrimitiveObjectToy = LabApi.Features.Wrappers.PrimitiveObjectToy; + +namespace SER.Code.MethodSystem.Methods.ObjectMethods; + +public class PrimitiveColorMethod : ReferenceReturningMethod, ICanError +{ + public override string Description { get; } = "Changes the color of primitive."; + public override Argument[] ExpectedArguments { get; } = + [ + new ReferenceArgument("object"), + new ColorArgument("color") + ]; + public override void Execute() + { + var obj = Args.GetReference("object"); + ReturnValue = obj; + var color = Args.GetColor("color"); + + var adminToy = AdminToy.Get(obj.GetComponent()); + if (adminToy is not PrimitiveObjectToy primitiveObjectToy) + { + Script.Executor.Error(ErrorReasons[0], Script); + return; + } + + primitiveObjectToy.Color = color; + } + + public string[] ErrorReasons { get; } = + [ + "Not all gameObjects can change colour. This one is not Primitive (cube, sphere, circle, cylinder, etc.)" + ]; +} \ No newline at end of file diff --git a/Code/MethodSystem/Methods/ObjectMethods/PrimitiveStructureMethod.cs b/Code/MethodSystem/Methods/ObjectMethods/PrimitiveStructureMethod.cs new file mode 100644 index 0000000..5108a71 --- /dev/null +++ b/Code/MethodSystem/Methods/ObjectMethods/PrimitiveStructureMethod.cs @@ -0,0 +1,62 @@ +using AdminToys; +using LabApi.Features.Wrappers; +using SER.Code.ArgumentSystem.Arguments; +using SER.Code.ArgumentSystem.BaseArguments; +using SER.Code.ArgumentSystem.Structures; +using SER.Code.MethodSystem.BaseMethods.Synchronous; +using SER.Code.MethodSystem.MethodDescriptors; +using UnityEngine; +using PrimitiveObjectToy = LabApi.Features.Wrappers.PrimitiveObjectToy; + +namespace SER.Code.MethodSystem.Methods.ObjectMethods; + +public class PrimitiveStructureMethod : ReferenceReturningMethod, ICanError +{ + public override string Description { get; } = "Changes the position of primitive."; + public override Argument[] ExpectedArguments { get; } = + [ + new ReferenceArgument("object") + { + Description = "The GameObject that you want to change Position/Rotation/Scale of", + }, + new OptionsArgument("option", "Position, Rotation, Scale"), + new FloatArgument("x"), + new FloatArgument("y"), + new FloatArgument("z"), + ]; + public override void Execute() + { + var obj = Args.GetReference("object"); + ReturnValue = obj; + var option = Args.GetOption("option"); + var x = Args.GetFloat("x"); + var y = Args.GetFloat("y"); + var z = Args.GetFloat("z"); + var vector = new Vector3(x, y, z); + + var adminToy = AdminToy.Get(obj.GetComponent()); + if (adminToy is not PrimitiveObjectToy primitiveObjectToy) + { + Script.Executor.Error(ErrorReasons[0], Script); + return; + } + + switch (option) + { + case "position": + primitiveObjectToy.Position = vector; + break; + case "rotation": + primitiveObjectToy.Rotation = Quaternion.Euler(vector); + break; + case "scale": + primitiveObjectToy.Scale = vector; + break; + } + } + + public string[] ErrorReasons { get; } = + [ + "Not all gameObjects can change colour. This one is not Primitive (cube, sphere, circle, cylinder, etc.)" + ]; +} \ No newline at end of file diff --git a/Code/MethodSystem/Methods/ObjectMethods/RaycastMethod.cs b/Code/MethodSystem/Methods/ObjectMethods/RaycastMethod.cs new file mode 100644 index 0000000..e294362 --- /dev/null +++ b/Code/MethodSystem/Methods/ObjectMethods/RaycastMethod.cs @@ -0,0 +1,46 @@ +using System.Collections.ObjectModel; +using SER.Code.ArgumentSystem.Arguments; +using SER.Code.ArgumentSystem.BaseArguments; +using SER.Code.MethodSystem.BaseMethods.Synchronous; +using UnityEngine; + +namespace SER.Code.MethodSystem.Methods.ObjectMethods; + +public class RaycastMethod : ReferenceReturningMethod +{ + public override string Description { get; } = "Get gameobject infront of player"; + public override Argument[] ExpectedArguments { get; } = + [ + new PlayerArgument("player") + { + Description = "Single player which will return the game object the player is looking at", + }, + new FloatArgument("max distance") + { + Description = "Maximum distance of the raycast", + }, + new EnumArgument("layer") + { + Description = "Layer mask meaning what raycast can and can't go through.", + DefaultValue = new (MaskHelper.Layers.TransparentFX | MaskHelper.Layers.Hitbox | MaskHelper.Layers.InvisibleCollider | MaskHelper.Layers.Skybox), + } + ]; + public override void Execute() + { + var player = Args.GetPlayer("player"); + var maxDistance = Args.GetFloat("max distance"); + var layer = Args.GetEnum("layer"); + var mask = MaskHelper.GetLayerMask(layer); + + if (!Physics.Raycast(player.Camera.position, player.Camera.forward, out var raycastHit, + maxDistance, ~mask)) + { + // Out of range + ReturnValue = null; + return; + } + + ReturnValue = raycastHit.collider.gameObject; + } +} + diff --git a/Code/ValueSystem/TypeOfValue.cs b/Code/ValueSystem/TypeOfValue.cs index 5b09d03..0010c19 100644 --- a/Code/ValueSystem/TypeOfValue.cs +++ b/Code/ValueSystem/TypeOfValue.cs @@ -2,7 +2,7 @@ public abstract class TypeOfValue { - protected TypeOfValue(Type[] required) + protected TypeOfValue(params Type[] required) { Required = required; } @@ -18,6 +18,16 @@ protected TypeOfValue(Type? required) public bool AreKnown(out Type[] known) => (known = Required!) is not null; public abstract override string ToString(); + + /// + /// This fucking pmo, it's literally the same thing :pray: + /// + /// fuck documentation + /// nuh uh + public static implicit operator TypeOfValue(Type type) + { + return new TypesOfValue(type); + } } public class TypesOfValue : TypeOfValue