@@ -0,0 +1,92 @@ | |||
using System; | |||
using Unity.Mathematics; | |||
using UnityEngine; | |||
namespace GamecraftModdingAPI.Interface.IMGUI | |||
{ | |||
/// <summary> | |||
/// A clickable button. | |||
/// This wraps Unity's IMGUI Button. | |||
/// </summary> | |||
public class Button : UIElement | |||
{ | |||
private bool automaticLayout = false; | |||
private string text; | |||
/// <summary> | |||
/// The rectangular area that the button can use. | |||
/// </summary> | |||
public Rect Box { get; set; } = Rect.zero; | |||
/// <summary> | |||
/// An event that fires when the button is clicked. | |||
/// </summary> | |||
public event EventHandler<bool> OnClick; | |||
public void OnGUI() | |||
{ | |||
if (automaticLayout) | |||
{ | |||
if (GUILayout.Button(text, Constants.Default.button)) | |||
{ | |||
OnClick?.Invoke(this, true); | |||
} | |||
} | |||
else | |||
{ | |||
if (GUI.Button(Box, text, Constants.Default.button)) | |||
{ | |||
OnClick?.Invoke(this, true); | |||
} | |||
} | |||
} | |||
/// <summary> | |||
/// The button's unique name. | |||
/// </summary> | |||
public string Name { get; private set; } | |||
/// <summary> | |||
/// Whether to display the button. | |||
/// </summary> | |||
public bool Enabled { get; set; } = true; | |||
/// <summary> | |||
/// Initialize a new button with automatic layout. | |||
/// </summary> | |||
/// <param name="text">The text to display on the button.</param> | |||
/// <param name="name">The button's name.</param> | |||
public Button(string text, string name = null) | |||
{ | |||
automaticLayout = true; | |||
this.text = text; | |||
if (name == null) | |||
{ | |||
this.Name = typeof(Button).FullName + "::" + text; | |||
} | |||
else | |||
{ | |||
this.Name = name; | |||
} | |||
IMGUIManager.AddElement(this); | |||
} | |||
/// <summary> | |||
/// Initialize a new button. | |||
/// </summary> | |||
/// <param name="text">The text to display on the button.</param> | |||
/// <param name="box">Rectangular area for the button to use.</param> | |||
/// <param name="name">The button's name.</param> | |||
public Button(string text, Rect box, string name = null) : this(text, name) | |||
{ | |||
automaticLayout = false; | |||
this.Box = box; | |||
} | |||
~Button() | |||
{ | |||
IMGUIManager.RemoveElement(this); | |||
} | |||
} | |||
} |
@@ -0,0 +1,168 @@ | |||
using System; | |||
using System.Collections; | |||
using System.Collections.Generic; | |||
using System.Globalization; | |||
using System.Reflection; | |||
using GamecraftModdingAPI.Utility; | |||
using HarmonyLib; | |||
using Svelto.Tasks; | |||
using Svelto.Tasks.Lean; | |||
using UnityEngine; | |||
using UnityEngine.AddressableAssets; | |||
using UnityEngine.ResourceManagement.AsyncOperations; | |||
namespace GamecraftModdingAPI.Interface.IMGUI | |||
{ | |||
/// <summary> | |||
/// Convenient IMGUI values. | |||
/// </summary> | |||
public static class Constants | |||
{ | |||
private static byte _defaultCompletion = 0; | |||
private static GUISkin _default = null; | |||
/// <summary> | |||
/// Best-effort imitation of Gamecraft's UI style. | |||
/// </summary> | |||
public static GUISkin Default | |||
{ | |||
get | |||
{ | |||
if (_defaultCompletion != 0) _default = BuildDefaultGUISkin(); | |||
return _default; | |||
} | |||
} | |||
private static Font _riffic = null; | |||
private static Texture2D _blueBackground = null; | |||
private static Texture2D _grayBackground = null; | |||
private static Texture2D _whiteBackground = null; | |||
private static Texture2D _textInputBackground = null; | |||
private static Texture2D _areaBackground = null; | |||
internal static void Init() | |||
{ | |||
LoadGUIAssets(); | |||
} | |||
private static GUISkin BuildDefaultGUISkin() | |||
{ | |||
_defaultCompletion = 0; | |||
if (_riffic == null) return GUI.skin; | |||
// build GUISkin | |||
GUISkin gui = ScriptableObject.CreateInstance<GUISkin>(); | |||
gui.font = _riffic; | |||
gui.settings.selectionColor = Color.white; | |||
gui.settings.tripleClickSelectsLine = true; | |||
// set properties off all UI elements | |||
foreach (PropertyInfo p in typeof(GUISkin).GetProperties()) | |||
{ | |||
// for a "scriptable" GUI system, it's ironic there's no better way to do this | |||
if (p.GetValue(gui) is GUIStyle style) | |||
{ | |||
style.richText = true; | |||
style.alignment = TextAnchor.MiddleCenter; | |||
style.fontSize = 30; | |||
style.wordWrap = true; | |||
style.border = new RectOffset(4, 4, 4, 4); | |||
style.margin = new RectOffset(4, 4, 4, 4); | |||
style.padding = new RectOffset(4, 4, 4, 4); | |||
// normal state | |||
style.normal.background = _blueBackground; | |||
style.normal.textColor = Color.white; | |||
// hover state | |||
style.hover.background = _grayBackground; | |||
style.hover.textColor = Color.white; | |||
// focused | |||
style.focused.background = _grayBackground; | |||
style.focused.textColor = Color.white; | |||
// clicking state | |||
style.active.background = _whiteBackground; | |||
style.active.textColor = Color.white; | |||
p.SetValue(gui, style); // probably unnecessary | |||
} | |||
} | |||
// set element-specific styles | |||
// label | |||
gui.label.normal.background = null; | |||
gui.label.hover.background = null; | |||
gui.label.focused.background = null; | |||
gui.label.active.background = null; | |||
// text input | |||
gui.textField.normal.background = _textInputBackground; | |||
gui.textField.hover.background = _textInputBackground; | |||
gui.textField.focused.background = _textInputBackground; | |||
gui.textField.active.background = _textInputBackground; | |||
// text area | |||
gui.textArea.normal.background = _textInputBackground; | |||
gui.textArea.hover.background = _textInputBackground; | |||
gui.textArea.focused.background = _textInputBackground; | |||
gui.textArea.active.background = _textInputBackground; | |||
// window | |||
gui.window.normal.background = _areaBackground; | |||
gui.window.hover.background = _areaBackground; | |||
gui.window.focused.background = _areaBackground; | |||
gui.window.active.background = _areaBackground; | |||
// box (also used by layout groups & areas) | |||
gui.box.normal.background = _areaBackground; | |||
gui.box.hover.background = _areaBackground; | |||
gui.box.focused.background = _areaBackground; | |||
gui.box.active.background = _areaBackground; | |||
return gui; | |||
} | |||
private static void LoadGUIAssets() | |||
{ | |||
AsyncOperationHandle<Font> rifficHandle = Addressables.LoadAssetAsync<Font>("Assets/Art/Fonts/riffic-bold.ttf"); | |||
rifficHandle.Completed += handle => | |||
{ | |||
_riffic = handle.Result; | |||
_defaultCompletion++; | |||
}; | |||
_blueBackground = new Texture2D(1, 1); | |||
_blueBackground.SetPixel(0, 0, new Color(0.004f, 0.522f, 0.847f) /* Gamecraft Blue */); | |||
_blueBackground.Apply(); | |||
_grayBackground = new Texture2D(1, 1); | |||
_grayBackground.SetPixel(0, 0, new Color(0.745f, 0.745f, 0.745f) /* Gray */); | |||
_grayBackground.Apply(); | |||
_whiteBackground = new Texture2D(1, 1); | |||
_whiteBackground.SetPixel(0, 0, new Color(0.898f, 0.898f, 0.898f) /* Very light gray */); | |||
_whiteBackground.Apply(); | |||
_textInputBackground = new Texture2D(1, 1); | |||
_textInputBackground.SetPixel(0, 0, new Color(0f, 0f, 0f, 0.25f) /* Translucent gray */); | |||
_textInputBackground.Apply(); | |||
_areaBackground = new Texture2D(1, 1); | |||
_areaBackground.SetPixel(0, 0, new Color(0f, 0f, 0f, 0.25f) /* Translucent gray */); | |||
_areaBackground.Apply(); | |||
/* // this is actually gray (used for the loading screen) | |||
AsyncOperationHandle<Texture2D> backgroundHandle = | |||
Addressables.LoadAssetAsync<Texture2D>("Assets/Art/Textures/UI/FrontEndMap/RCX_Blue_Background_5k.jpg"); | |||
backgroundHandle.Completed += handle => | |||
{ | |||
_blueBackground = handle.Result; | |||
_defaultCompletion++; | |||
};*/ | |||
_defaultCompletion++; | |||
} | |||
} | |||
[HarmonyPatch(typeof(FMODUnity.RuntimeManager), "PlayOneShot", new []{ typeof(Guid), typeof(Vector3)})] | |||
public class FMODRuntimeManagerPlayOneShotPatch | |||
{ | |||
public static void Prefix(Guid guid) | |||
{ | |||
Logging.MetaLog($"Playing sound with guid '{guid.ToString()}'"); | |||
} | |||
} | |||
[HarmonyPatch(typeof(FMODUnity.RuntimeManager), "PlayOneShot", new []{ typeof(string), typeof(Vector3)})] | |||
public class FMODRuntimeManagerPlayOneShotPatch2 | |||
{ | |||
public static void Prefix(string path) | |||
{ | |||
Logging.MetaLog($"Playing sound with str '{path}'"); | |||
} | |||
} | |||
} |
@@ -0,0 +1,157 @@ | |||
using System; | |||
using GamecraftModdingAPI.Utility; | |||
using Svelto.DataStructures; | |||
using UnityEngine; | |||
namespace GamecraftModdingAPI.Interface.IMGUI | |||
{ | |||
/// <summary> | |||
/// A group of elements. | |||
/// This wraps Unity's GUILayout Area and GUI Group system. | |||
/// </summary> | |||
public class Group : UIElement | |||
{ | |||
private bool automaticLayout; | |||
private FasterList<UIElement> elements = new FasterList<UIElement>(); | |||
/// <summary> | |||
/// The rectangular area in the window that the UI group can use | |||
/// </summary> | |||
public Rect Box { get; set; } | |||
public void OnGUI() | |||
{ | |||
/*if (Constants.Default == null) return; | |||
if (Constants.Default.box == null) return;*/ | |||
GUIStyle guiStyle = Constants.Default.box; | |||
UIElement[] elems = elements.ToArrayFast(out uint count); | |||
if (automaticLayout) | |||
{ | |||
GUILayout.BeginArea(Box, guiStyle); | |||
for (uint i = 0; i < count; i++) | |||
{ | |||
/*try | |||
{ | |||
if (elems[i].Enabled) | |||
elems[i].OnGUI(); | |||
} | |||
catch (ArgumentException) | |||
{ | |||
// ignore these, since this is (hopefully) just Unity being dumb | |||
} | |||
catch (Exception e) | |||
{ | |||
Logging.MetaDebugLog($"Element '{elems[i].Name}' threw exception:\n{e.ToString()}"); | |||
}*/ | |||
if (elems[i].Enabled) | |||
elems[i].OnGUI(); | |||
} | |||
GUILayout.EndArea(); | |||
} | |||
else | |||
{ | |||
GUI.BeginGroup(Box, guiStyle); | |||
for (uint i = 0; i < count; i++) | |||
{ | |||
if (elems[i].Enabled) | |||
elems[i].OnGUI(); | |||
} | |||
GUI.EndGroup(); | |||
} | |||
} | |||
/// <summary> | |||
/// The group's unique name. | |||
/// </summary> | |||
public string Name { get; } | |||
/// <summary> | |||
/// Whether to display the group and everything in it. | |||
/// </summary> | |||
public bool Enabled { set; get; } = true; | |||
/// <summary> | |||
/// The amount of elements in the group. | |||
/// </summary> | |||
public int Length | |||
{ | |||
get => elements.count; | |||
} | |||
/// <summary> | |||
/// Initializes a new instance of the <see cref="T:GamecraftModdingAPI.Interface.IMGUI.Group"/> class. | |||
/// </summary> | |||
/// <param name="box">The rectangular area to use in the window.</param> | |||
/// <param name="name">Name of the group.</param> | |||
/// <param name="automaticLayout">Whether to use automatic UI layout.</param> | |||
public Group(Rect box, string name = null, bool automaticLayout = false) | |||
{ | |||
Box = box; | |||
if (name == null) | |||
{ | |||
this.Name = typeof(Group).FullName + "::" + box.ToString().Replace(" ", ""); | |||
} | |||
else | |||
{ | |||
this.Name = name; | |||
} | |||
this.automaticLayout = automaticLayout; | |||
IMGUIManager.AddElement(this); | |||
} | |||
/// <summary> | |||
/// Add an element to the group. | |||
/// </summary> | |||
/// <param name="element">The element to add.</param> | |||
/// <returns>Index of the new element.</returns> | |||
public int AddElement(UIElement element) | |||
{ | |||
IMGUIManager.RemoveElement(element); // groups manage internal elements themselves | |||
elements.Add(element); | |||
return elements.count - 1; | |||
} | |||
/// <summary> | |||
/// Remove an element from the group. | |||
/// </summary> | |||
/// <param name="element">The element to remove.</param> | |||
/// <returns>Whether removal was successful.</returns> | |||
public bool RemoveElement(UIElement element) | |||
{ | |||
int index = IndexOf(element); | |||
return RemoveAt(index); | |||
} | |||
/// <summary> | |||
/// Remove the element in a specific location. | |||
/// </summary> | |||
/// <param name="index">Index of the element.</param> | |||
/// <returns>Whether removal was successful.</returns> | |||
public bool RemoveAt(int index) | |||
{ | |||
if (index < 0 || index >= elements.count) return false; | |||
IMGUIManager.AddElement(elements[index]); // re-add to global manager | |||
elements.RemoveAt(index); | |||
return true; | |||
} | |||
/// <summary> | |||
/// Get the index of an element. | |||
/// </summary> | |||
/// <param name="element">The element to search for.</param> | |||
/// <returns>The element's index, or -1 if not found.</returns> | |||
public int IndexOf(UIElement element) | |||
{ | |||
UIElement[] elems = elements.ToArrayFast(out uint count); | |||
for (int i = 0; i < count; i++) | |||
{ | |||
if (elems[i].Name == element.Name) | |||
{ | |||
return i; | |||
} | |||
} | |||
return -1; | |||
} | |||
} | |||
} |
@@ -0,0 +1,94 @@ | |||
using System; | |||
using System.Collections; | |||
using System.Collections.Generic; | |||
using GamecraftModdingAPI.App; | |||
using GamecraftModdingAPI.Utility; | |||
using Rewired.Internal; | |||
using Svelto.DataStructures; | |||
using Svelto.Tasks; | |||
using Svelto.Tasks.ExtraLean; | |||
using Svelto.Tasks.ExtraLean.Unity; | |||
using UnityEngine; | |||
namespace GamecraftModdingAPI.Interface.IMGUI | |||
{ | |||
public static class IMGUIManager | |||
{ | |||
internal static OnGuiRunner ImguiScheduler = new OnGuiRunner("GamecraftModdingAPI_IMGUIScheduler"); | |||
private static FasterDictionary<string, UIElement> _activeElements = new FasterDictionary<string,UIElement>(); | |||
public static void AddElement(UIElement e) | |||
{ | |||
if (!ExistsElement(e)) | |||
{ | |||
_activeElements[e.Name] = e; | |||
} | |||
} | |||
public static bool ExistsElement(string name) | |||
{ | |||
return _activeElements.ContainsKey(name); | |||
} | |||
public static bool ExistsElement(UIElement element) | |||
{ | |||
return ExistsElement(element.Name); | |||
} | |||
public static bool RemoveElement(string name) | |||
{ | |||
if (ExistsElement(name)) | |||
{ | |||
return _activeElements.Remove(name); | |||
} | |||
return false; | |||
} | |||
public static bool RemoveElement(UIElement element) | |||
{ | |||
return RemoveElement(element.Name); | |||
} | |||
private static void OnGUI() | |||
{ | |||
UIElement[] elements = _activeElements.GetValuesArray(out uint count); | |||
for(uint i = 0; i < count; i++) | |||
{ | |||
if (elements[i].Enabled) | |||
elements[i].OnGUI(); | |||
/*try | |||
{ | |||
if (elements[i].Enabled) | |||
elements[i].OnGUI(); | |||
} | |||
catch (ArgumentException) | |||
{ | |||
// ignore these, since this is (hopefully) just Unity being dumb | |||
} | |||
catch (Exception e) | |||
{ | |||
Logging.MetaDebugLog($"Element '{elements[i].Name}' threw exception:\n{e.ToString()}"); | |||
}*/ | |||
} | |||
} | |||
private static IEnumerator<TaskContract> OnGUIAsync() | |||
{ | |||
yield return (new Svelto.Tasks.Enumerators.WaitForSecondsEnumerator(5)).Continue(); // wait for some startup | |||
while (true) | |||
{ | |||
yield return Yield.It; | |||
GUI.skin = Constants.Default; | |||
OnGUI(); | |||
} | |||
} | |||
internal static void Init() | |||
{ | |||
OnGUIAsync().RunOn(ImguiScheduler); | |||
} | |||
} | |||
} |
@@ -0,0 +1,58 @@ | |||
using UnityEngine; | |||
namespace GamecraftModdingAPI.Interface.IMGUI | |||
{ | |||
public class Image : UIElement | |||
{ | |||
private bool automaticLayout = false; | |||
public Texture Texture { get; set; } | |||
public Rect Box { get; set; } = Rect.zero; | |||
public void OnGUI() | |||
{ | |||
//if (Texture == null) return; | |||
if (automaticLayout) | |||
{ | |||
GUILayout.Label(Texture, Constants.Default.label); | |||
} | |||
else | |||
{ | |||
GUI.Label(Box, Texture, Constants.Default.label); | |||
} | |||
} | |||
public string Name { get; } | |||
public bool Enabled { set; get; } = true; | |||
public Image(Texture texture = null, string name = null) | |||
{ | |||
automaticLayout = true; | |||
Texture = texture; | |||
if (name == null) | |||
{ | |||
if (texture == null) | |||
{ | |||
this.Name = typeof(Image).FullName + "::" + texture; | |||
} | |||
else | |||
{ | |||
this.Name = typeof(Image).FullName + "::" + texture.name + "(" + texture.width + "x" + texture.height + ")"; | |||
} | |||
} | |||
else | |||
{ | |||
this.Name = name; | |||
} | |||
IMGUIManager.AddElement(this); | |||
} | |||
public Image(Rect box, Texture texture = null, string name = null) : this(texture, name) | |||
{ | |||
this.Box = box; | |||
automaticLayout = false; | |||
} | |||
} | |||
} |
@@ -0,0 +1,59 @@ | |||
using UnityEngine; | |||
namespace GamecraftModdingAPI.Interface.IMGUI | |||
{ | |||
/// <summary> | |||
/// A simple text label. | |||
/// This wraps Unity IMGUI's Label. | |||
/// </summary> | |||
public class Label : UIElement | |||
{ | |||
private bool automaticLayout = false; | |||
/// <summary> | |||
/// String to display on the label. | |||
/// </summary> | |||
public string Text { get; set; } | |||
/// <summary> | |||
/// The rectangular area that the label can use. | |||
/// </summary> | |||
public Rect Box { get; set; } = Rect.zero; | |||
public void OnGUI() | |||
{ | |||
if (automaticLayout) | |||
{ | |||
GUILayout.Label(Text, Constants.Default.label); | |||
} | |||
else | |||
{ | |||
GUI.Label(Box, Text, Constants.Default.label); | |||
} | |||
} | |||
public string Name { get; } | |||
public bool Enabled { set; get; } = true; | |||
public Label(string initialText = null, string name = null) | |||
{ | |||
automaticLayout = true; | |||
Text = initialText; | |||
if (name == null) | |||
{ | |||
this.Name = typeof(Label).FullName + "::" + initialText; | |||
} | |||
else | |||
{ | |||
this.Name = name; | |||
} | |||
IMGUIManager.AddElement(this); | |||
} | |||
public Label(Rect box, string initialText = null, string name = null) : this(initialText, name) | |||
{ | |||
this.Box = box; | |||
automaticLayout = false; | |||
} | |||
} | |||
} |
@@ -0,0 +1,109 @@ | |||
using System; | |||
using UnityEngine; | |||
namespace GamecraftModdingAPI.Interface.IMGUI | |||
{ | |||
/// <summary> | |||
/// A text input field. | |||
/// This wraps Unity's IMGUI TextField and TextArea. | |||
/// </summary> | |||
public class Text : UIElement | |||
{ | |||
private bool automaticLayout; | |||
/// <summary> | |||
/// Whether the text input field is multiline (true -> TextArea) or not (false -> TextField). | |||
/// </summary> | |||
public bool Multiline { get; set; } | |||
private string text; | |||
/// <summary> | |||
/// The rectangular area that the text field can use. | |||
/// </summary> | |||
public Rect Box { get; set; } = Rect.zero; | |||
/// <summary> | |||
/// An event that fires whenever the text input is edited. | |||
/// </summary> | |||
public event EventHandler<string> OnEdit; | |||
public void OnGUI() | |||
{ | |||
string editedText = null; | |||
if (automaticLayout) | |||
{ | |||
if (Multiline) | |||
{ | |||
editedText = GUILayout.TextArea(text, Constants.Default.textArea); | |||
} | |||
else | |||
{ | |||
editedText = GUILayout.TextField(text, Constants.Default.textField); | |||
} | |||
} | |||
else | |||
{ | |||
if (Multiline) | |||
{ | |||
editedText = GUI.TextArea(Box, text, Constants.Default.textArea); | |||
} | |||
else | |||
{ | |||
editedText = GUI.TextField(Box, text, Constants.Default.textField); | |||
} | |||
} | |||
if (editedText != null && editedText != text) | |||
{ | |||
OnEdit?.Invoke(this, editedText); | |||
text = editedText; | |||
} | |||
} | |||
/// <summary> | |||
/// The text field's unique name. | |||
/// </summary> | |||
public string Name { get; } | |||
/// <summary> | |||
/// Whether to display the text field. | |||
/// </summary> | |||
public bool Enabled { set; get; } = true; | |||
/// <summary> | |||
/// Initialize the text input field with automatic layout. | |||
/// </summary> | |||
/// <param name="initialText">Initial text in the input field.</param> | |||
/// <param name="name">The text field's name.</param> | |||
/// <param name="multiline">Allow multiple lines?</param> | |||
public Text(string initialText = null, string name = null, bool multiline = false) | |||
{ | |||
this.Multiline = multiline; | |||
automaticLayout = true; | |||
text = initialText ?? ""; | |||
if (name == null) | |||
{ | |||
this.Name = typeof(Text).FullName + "::" + text; | |||
} | |||
else | |||
{ | |||
this.Name = name; | |||
} | |||
IMGUIManager.AddElement(this); | |||
} | |||
/// <summary> | |||
/// Initialize the text input field. | |||
/// </summary> | |||
/// <param name="box">Rectangular area for the text field.</param> | |||
/// <param name="initialText">Initial text in the input field.</param> | |||
/// <param name="name">The text field's name.</param> | |||
/// <param name="multiline">Allow multiple lines?</param> | |||
public Text(Rect box, string initialText = null, string name = null, bool multiline = false) : this(initialText, name, multiline) | |||
{ | |||
this.Box = box; | |||
automaticLayout = false; | |||
} | |||
} | |||
} |
@@ -0,0 +1,28 @@ | |||
using System; | |||
namespace GamecraftModdingAPI.Interface.IMGUI | |||
{ | |||
/// <summary> | |||
/// GUI Element like a text field, button or picture. | |||
/// This interface is used to wrap many elements from Unity's IMGUI system. | |||
/// </summary> | |||
public interface UIElement | |||
{ | |||
/// <summary> | |||
/// GUI operations to perform in the OnGUI scope. | |||
/// This is basically equivalent to a MonoBehaviour's OnGUI method. | |||
/// </summary> | |||
void OnGUI(); | |||
/// <summary> | |||
/// The element's name. | |||
/// This should be unique for every instance of the class. | |||
/// </summary> | |||
string Name { get; } | |||
/// <summary> | |||
/// Whether to display the UI element or not. | |||
/// </summary> | |||
bool Enabled { get; } | |||
} | |||
} |
@@ -89,6 +89,9 @@ namespace GamecraftModdingAPI | |||
AsyncUtils.Init(); | |||
GamecraftModdingAPI.App.Client.Init(); | |||
GamecraftModdingAPI.App.Game.Init(); | |||
// init UI | |||
Interface.IMGUI.Constants.Init(); | |||
Interface.IMGUI.IMGUIManager.Init(); | |||
Logging.MetaLog($"{currentAssembly.GetName().Name} v{currentAssembly.GetName().Version} initialized"); | |||
} | |||
@@ -5,7 +5,7 @@ using System.Linq; | |||
using System.Reflection; | |||
using System.Reflection.Emit; | |||
using System.Text; | |||
using GamecraftModdingAPI.App; | |||
using HarmonyLib; | |||
using IllusionInjector; | |||
// test | |||
@@ -22,8 +22,16 @@ using GamecraftModdingAPI.Commands; | |||
using GamecraftModdingAPI.Events; | |||
using GamecraftModdingAPI.Utility; | |||
using GamecraftModdingAPI.Blocks; | |||
using GamecraftModdingAPI.Interface.IMGUI; | |||
using GamecraftModdingAPI.Players; | |||
using UnityEngine.AddressableAssets; | |||
using UnityEngine.AddressableAssets.ResourceLocators; | |||
using UnityEngine.ResourceManagement.AsyncOperations; | |||
using UnityEngine.ResourceManagement.ResourceLocations; | |||
using UnityEngine.ResourceManagement.ResourceProviders; | |||
using Debug = FMOD.Debug; | |||
using EventType = GamecraftModdingAPI.Events.EventType; | |||
using Label = GamecraftModdingAPI.Interface.IMGUI.Label; | |||
namespace GamecraftModdingAPI.Tests | |||
{ | |||
@@ -347,13 +355,38 @@ namespace GamecraftModdingAPI.Tests | |||
{ | |||
Logging.Log("Compatible GamecraftScripting detected"); | |||
} | |||
// Interface test | |||
/*Interface.IMGUI.Group uiGroup = new Group(new Rect(20, 20, 200, 500), "GamecraftModdingAPI_UITestGroup", true); | |||
Interface.IMGUI.Button button = new Button("TEST"); | |||
button.OnClick += (b, __) => { Logging.MetaDebugLog($"Click on {((Interface.IMGUI.Button)b).Name}");}; | |||
Interface.IMGUI.Button button2 = new Button("TEST2"); | |||
button2.OnClick += (b, __) => { Logging.MetaDebugLog($"Click on {((Interface.IMGUI.Button)b).Name}");}; | |||
Text uiText = new Text("This is text!", multiline: true); | |||
uiText.OnEdit += (t, txt) => { Logging.MetaDebugLog($"Text in {((Text)t).Name} is now '{txt}'"); }; | |||
Label uiLabel = new Label("Label!"); | |||
Image uiImg = new Image(name:"Behold this texture!"); | |||
uiImg.Enabled = false; | |||
uiGroup.AddElement(button); | |||
uiGroup.AddElement(button2); | |||
uiGroup.AddElement(uiText); | |||
uiGroup.AddElement(uiLabel); | |||
uiGroup.AddElement(uiImg); | |||
Addressables.LoadAssetAsync<Texture2D>("Assets/Art/Textures/UI/FrontEndMap/RCX_Blue_Background_5k.jpg") | |||
.Completed += | |||
handle => | |||
{ | |||
uiImg.Texture = handle.Result; | |||
uiImg.Enabled = true; | |||
Logging.MetaDebugLog($"Got blue bg asset {handle.Result}"); | |||
}; | |||
*/ | |||
#if TEST | |||
TestRoot.RunTests(); | |||
#endif | |||
} | |||
private string modsString; | |||
private string modsString; | |||
private string InstalledMods() | |||
{ | |||
if (modsString != null) return modsString; | |||