diff --git a/Automation/Automation.cs b/Automation/Automation.cs new file mode 100644 index 0000000..92787f6 --- /dev/null +++ b/Automation/Automation.cs @@ -0,0 +1,66 @@ +using System; +using System.IO; +using System.Text; +using System.Text.RegularExpressions; + +namespace Automation +{ + class Automation + { + private static readonly string Name = "automation"; + + private static readonly string XmlPrefix = "\n \n"; + private static readonly string XmlSuffix = " \n"; + + private static readonly string GamecraftModdingAPI_csproj = @"\GamecraftModdingAPI.csproj"; + static void Main(string[] args) + { + if (args.Length != 2 || args[0] == "-h" || args[0] == "--help") + { + Console.WriteLine($"Usage : {Name}.exe "); + Console.WriteLine("Other arguments:"); + Console.WriteLine(" --help : display this message"); + Console.WriteLine($" --version : display {Name}'s version"); + return; + } + Console.WriteLine("Building Assembly references"); + string asmXml = BuildAssemblyReferencesXML(args[0]); + //Console.WriteLine(asmXml); + string csprojPath = args[1].EndsWith(GamecraftModdingAPI_csproj)? args[1] : args[1]+GamecraftModdingAPI_csproj; + Console.WriteLine($"Parsing {csprojPath}"); + string csprojContents = File.ReadAllText(csprojPath); + Match dependenciesStart = (new Regex(@"<\s*!--\s*Start\s+Dependencies\s*--\s*>", RegexOptions.Compiled | RegexOptions.IgnoreCase | RegexOptions.Multiline)).Match(csprojContents); + Match dependenciesEnd = (new Regex(@"<\s*!--\s*End\s+Dependencies\s*--\s*>", RegexOptions.Compiled | RegexOptions.IgnoreCase | RegexOptions.Multiline)).Match(csprojContents); + if (!dependenciesEnd.Success || !dependenciesStart.Success) + { + Console.WriteLine("Unable to find dependency XML comments, aborting!"); + return; + } + csprojContents = csprojContents.Substring(0, dependenciesStart.Index) + asmXml + csprojContents.Substring(dependenciesEnd.Index+dependenciesEnd.Length); + //Console.WriteLine(csprojContents); + Console.WriteLine($"Writing Assembly references into {csprojPath}"); + File.WriteAllText(csprojPath, csprojContents); + Console.WriteLine("Successfully generated Gamecraft assembly DLL references"); + } + + static string BuildAssemblyReferencesXML(string path) + { + StringBuilder result = new StringBuilder(); + result.Append(XmlPrefix); + string[] files = Directory.GetFiles(path, "*.dll"); + for(int i = 0; i\n {files[i]}\n \n"); + } + } + result.Append(XmlSuffix); + return result.ToString(); + } + } +} diff --git a/Automation/Automation.csproj b/Automation/Automation.csproj new file mode 100644 index 0000000..c73e0d1 --- /dev/null +++ b/Automation/Automation.csproj @@ -0,0 +1,8 @@ + + + + Exe + netcoreapp3.1 + + + diff --git a/Automation/bump_version.py b/Automation/bump_version.py deleted file mode 100755 index a6d07b2..0000000 --- a/Automation/bump_version.py +++ /dev/null @@ -1,67 +0,0 @@ -#!/usr/bin/python3 - -import argparse -import re -# this assumes a mostly semver-complient version number - -if __name__ == "__main__": - parser = argparse.ArgumentParser(description="Increment TechbloxModdingAPI version") - parser.add_argument('version', metavar="VN", type=str, help="The version number to increment, or the index of the number (zero-indexed).") - args = parser.parse_args() - - version_index = -1 - try: - version_index = int(args.version) - except Exception: - if args.version.lower() == "major": - version_index = 0 - elif args.version.lower() == "minor": - version_index = 1 - elif args.version.lower() == "patch": - version_index = 2 - - if version_index < 0: - print("Could not parse version argument.") - exit(version_index) - - print(version_index) - old_version = "" - new_version = "" - - with open("../TechbloxModdingAPI/TechbloxModdingAPI.csproj", "r") as xmlFile: - print("Parsing TechbloxModdingAPI.csproj") - fileStr = xmlFile.read() - versionMatch = re.search(r"(.+)", fileStr) - if versionMatch is None: - print("Unable to find version number in TechbloxModdingAPI.csproj") - exit(1) - old_version = versionMatch.group(1) - versionList = old_version.split(".") - if len(versionList) <= version_index: - print("Invalid version string") - exit(1) - versionList[version_index] = str(int(versionList[version_index]) + 1) - for i in range(version_index + 1, len(versionList)): - try: - int(versionList[i]) - versionList[i] = "0" - except Exception: - tmp = versionList[i].split("-") - tmp[0] = "0" - versionList[i] = "-".join(tmp) - new_version = ".".join(versionList) - print(new_version) - newFileContents = fileStr.replace(""+old_version+"", ""+new_version+"") - - with open("../TechbloxModdingAPI/TechbloxModdingAPI.csproj", "w") as xmlFile: - print("Writing new version to project file") - xmlFile.write(newFileContents) - - with open("../doxygen.conf", "r") as doxFile: - print("Parsing doxygen.conf") - doxStr = doxFile.read() - newFileContents = doxStr.replace("= \"v" + old_version + "\"", "= \"v" + new_version + "\"") - - with open("../doxygen.conf", "w") as doxFile: - print("Writing new version to doxygen config") - doxFile.write(newFileContents) diff --git a/Automation/gen_csproj.py b/Automation/gen_csproj.py deleted file mode 100755 index 0c88372..0000000 --- a/Automation/gen_csproj.py +++ /dev/null @@ -1,62 +0,0 @@ -#!/usr/bin/python3 - -import argparse -from pathlib import Path, PurePath -import re -import os - -DLL_EXCLUSIONS_REGEX = r"(System|Microsoft|Mono|IronPython|DiscordRPC|IllusionInjector|IllusionPlugin|netstandard)\." - -def getAssemblyReferences(path): - asmDir = Path(path) - result = list() - addedPath = "" - if not asmDir.exists(): - addedPath = "../" - asmDir = Path(addedPath + path) - for child in asmDir.iterdir(): - if child.is_file() and re.search(DLL_EXCLUSIONS_REGEX, str(child)) is None and str(child).lower().endswith(".dll"): - childstr = str(child) - childstr = os.path.relpath(childstr, addedPath).replace("\\", "/") - result.append(childstr) - result.sort(key=str.lower) - result = [path + "/IllusionInjector.dll", path + "/IllusionPlugin.dll"] + result # Always put it on top - return result - -def buildReferencesXml(path): - assemblyPathes = getAssemblyReferences(path) - result = list() - for asm in assemblyPathes: - asmPath = str(asm) - xml = " \n" \ - + " " + asmPath.replace("/", "\\") + "\n" \ - + " ..\\" + asmPath.replace("/", "\\") + "\n" \ - + " \n" - result.append(xml) - return "\n \n" + "".join(result) + " \n" - -if __name__ == "__main__": - parser = argparse.ArgumentParser(description="Generate TechbloxModdingAPI.csproj") - # TODO (maybe?): add params for custom csproj read and write locations - args = parser.parse_args() - - print("Building Assembly references") - asmXml = buildReferencesXml("../ref_TB/Techblox_Data/Managed") - # print(asmXml) - - with open("../TechbloxModdingAPI/TechbloxModdingAPI.csproj", "r") as xmlFile: - print("Parsing TechbloxModdingAPI.csproj") - fileStr = xmlFile.read() - # print(fileStr) - depsStart = re.search(r"\ - - - ..\ref_TB\Techblox_Data\Managed\IllusionInjector.dll - ..\..\ref_TB\Techblox_Data\Managed\IllusionInjector.dll - - - ..\ref_TB\Techblox_Data\Managed\IllusionPlugin.dll - ..\..\ref_TB\Techblox_Data\Managed\IllusionPlugin.dll - - - ..\ref_TB\Techblox_Data\Managed\Accessibility.dll - ..\..\ref_TB\Techblox_Data\Managed\Accessibility.dll - - - ..\ref_TB\Techblox_Data\Managed\Analytics.dll - ..\..\ref_TB\Techblox_Data\Managed\Analytics.dll - - - ..\ref_TB\Techblox_Data\Managed\Assembly-CSharp-firstpass.dll - ..\..\ref_TB\Techblox_Data\Managed\Assembly-CSharp-firstpass.dll - - - ..\ref_TB\Techblox_Data\Managed\Assembly-CSharp.dll - ..\..\ref_TB\Techblox_Data\Managed\Assembly-CSharp.dll - - - ..\ref_TB\Techblox_Data\Managed\AWSSDK.Core.dll - ..\..\ref_TB\Techblox_Data\Managed\AWSSDK.Core.dll - - - ..\ref_TB\Techblox_Data\Managed\AWSSDK.GameLift.dll - ..\..\ref_TB\Techblox_Data\Managed\AWSSDK.GameLift.dll - - - ..\ref_TB\Techblox_Data\Managed\BevelEffect.dll - ..\..\ref_TB\Techblox_Data\Managed\BevelEffect.dll - - - ..\ref_TB\Techblox_Data\Managed\Boxophobic.TheVehetationEngine.Runtime.dll - ..\..\ref_TB\Techblox_Data\Managed\Boxophobic.TheVehetationEngine.Runtime.dll - - - ..\ref_TB\Techblox_Data\Managed\Boxophobic.Utils.Scripts.dll - ..\..\ref_TB\Techblox_Data\Managed\Boxophobic.Utils.Scripts.dll - - - ..\ref_TB\Techblox_Data\Managed\DataLoader.dll - ..\..\ref_TB\Techblox_Data\Managed\DataLoader.dll - - - ..\ref_TB\Techblox_Data\Managed\DDNA.dll - ..\..\ref_TB\Techblox_Data\Managed\DDNA.dll - - - ..\ref_TB\Techblox_Data\Managed\EasyButtons.dll - ..\..\ref_TB\Techblox_Data\Managed\EasyButtons.dll - - - ..\ref_TB\Techblox_Data\Managed\EOSSDK.dll - ..\..\ref_TB\Techblox_Data\Managed\EOSSDK.dll - - - ..\ref_TB\Techblox_Data\Managed\FMODUnity.dll - ..\..\ref_TB\Techblox_Data\Managed\FMODUnity.dll - - - ..\ref_TB\Techblox_Data\Managed\FMODUnityResonance.dll - ..\..\ref_TB\Techblox_Data\Managed\FMODUnityResonance.dll - - - ..\ref_TB\Techblox_Data\Managed\FMODUnityWrapperClient.dll - ..\..\ref_TB\Techblox_Data\Managed\FMODUnityWrapperClient.dll - - - ..\ref_TB\Techblox_Data\Managed\FullGame.dll - ..\..\ref_TB\Techblox_Data\Managed\FullGame.dll - - - ..\ref_TB\Techblox_Data\Managed\Gamecraft.BlockEntityFactory.dll - ..\..\ref_TB\Techblox_Data\Managed\Gamecraft.BlockEntityFactory.dll - - - ..\ref_TB\Techblox_Data\Managed\Gamecraft.BlockGroups.dll - ..\..\ref_TB\Techblox_Data\Managed\Gamecraft.BlockGroups.dll - - - ..\ref_TB\Techblox_Data\Managed\Gamecraft.Blocks.LogicBlock.dll - ..\..\ref_TB\Techblox_Data\Managed\Gamecraft.Blocks.LogicBlock.dll - - - ..\ref_TB\Techblox_Data\Managed\Gamecraft.BlocksEntityDescriptors.dll - ..\..\ref_TB\Techblox_Data\Managed\Gamecraft.BlocksEntityDescriptors.dll - - - ..\ref_TB\Techblox_Data\Managed\Gamecraft.ColourPalette.dll - ..\..\ref_TB\Techblox_Data\Managed\Gamecraft.ColourPalette.dll - - - ..\ref_TB\Techblox_Data\Managed\Gamecraft.Damage.dll - ..\..\ref_TB\Techblox_Data\Managed\Gamecraft.Damage.dll - - - ..\ref_TB\Techblox_Data\Managed\Gamecraft.Effects.dll - ..\..\ref_TB\Techblox_Data\Managed\Gamecraft.Effects.dll - - - ..\ref_TB\Techblox_Data\Managed\Gamecraft.ExplosionFragments.dll - ..\..\ref_TB\Techblox_Data\Managed\Gamecraft.ExplosionFragments.dll - - - ..\ref_TB\Techblox_Data\Managed\Gamecraft.GraphicsSettings.dll - ..\..\ref_TB\Techblox_Data\Managed\Gamecraft.GraphicsSettings.dll - - - ..\ref_TB\Techblox_Data\Managed\Gamecraft.GUI.BlueprintInventory.dll - ..\..\ref_TB\Techblox_Data\Managed\Gamecraft.GUI.BlueprintInventory.dll - - - ..\ref_TB\Techblox_Data\Managed\Gamecraft.GUI.Blueprints.dll - ..\..\ref_TB\Techblox_Data\Managed\Gamecraft.GUI.Blueprints.dll - - - ..\ref_TB\Techblox_Data\Managed\Gamecraft.GUI.BlueprintSets.dll - ..\..\ref_TB\Techblox_Data\Managed\Gamecraft.GUI.BlueprintSets.dll - - - ..\ref_TB\Techblox_Data\Managed\Gamecraft.GUI.GameOptionsScreen.dll - ..\..\ref_TB\Techblox_Data\Managed\Gamecraft.GUI.GameOptionsScreen.dll - - - ..\ref_TB\Techblox_Data\Managed\Gamecraft.GUI.GraphicsScreen.dll - ..\..\ref_TB\Techblox_Data\Managed\Gamecraft.GUI.GraphicsScreen.dll - - - ..\ref_TB\Techblox_Data\Managed\Gamecraft.GUI.Hotbar.Blocks.dll - ..\..\ref_TB\Techblox_Data\Managed\Gamecraft.GUI.Hotbar.Blocks.dll - - - ..\ref_TB\Techblox_Data\Managed\Gamecraft.GUI.Hotbar.BlueprintsHotbar.dll - ..\..\ref_TB\Techblox_Data\Managed\Gamecraft.GUI.Hotbar.BlueprintsHotbar.dll - - - ..\ref_TB\Techblox_Data\Managed\Gamecraft.GUI.Hotbar.Colours.dll - ..\..\ref_TB\Techblox_Data\Managed\Gamecraft.GUI.Hotbar.Colours.dll - - - ..\ref_TB\Techblox_Data\Managed\Gamecraft.GUI.ModeBar.dll - ..\..\ref_TB\Techblox_Data\Managed\Gamecraft.GUI.ModeBar.dll - - - ..\ref_TB\Techblox_Data\Managed\Gamecraft.GUI.OptionsScreen.dll - ..\..\ref_TB\Techblox_Data\Managed\Gamecraft.GUI.OptionsScreen.dll - - - ..\ref_TB\Techblox_Data\Managed\Gamecraft.GUI.TabsBar.Blocks.dll - ..\..\ref_TB\Techblox_Data\Managed\Gamecraft.GUI.TabsBar.Blocks.dll - - - ..\ref_TB\Techblox_Data\Managed\Gamecraft.GUI.TabsBar.Blueprints.dll - ..\..\ref_TB\Techblox_Data\Managed\Gamecraft.GUI.TabsBar.Blueprints.dll - - - ..\ref_TB\Techblox_Data\Managed\Gamecraft.GUI.TabsBar.Colours.dll - ..\..\ref_TB\Techblox_Data\Managed\Gamecraft.GUI.TabsBar.Colours.dll - - - ..\ref_TB\Techblox_Data\Managed\Gamecraft.GUI.TabsBar.Common.dll - ..\..\ref_TB\Techblox_Data\Managed\Gamecraft.GUI.TabsBar.Common.dll - - - ..\ref_TB\Techblox_Data\Managed\Gamecraft.GUI.Tweaks.dll - ..\..\ref_TB\Techblox_Data\Managed\Gamecraft.GUI.Tweaks.dll - - - ..\ref_TB\Techblox_Data\Managed\Gamecraft.GUI.Wires.dll - ..\..\ref_TB\Techblox_Data\Managed\Gamecraft.GUI.Wires.dll - - - ..\ref_TB\Techblox_Data\Managed\Gamecraft.GUI.WorldSpaceGuis.dll - ..\..\ref_TB\Techblox_Data\Managed\Gamecraft.GUI.WorldSpaceGuis.dll - - - ..\ref_TB\Techblox_Data\Managed\Gamecraft.JointBlocks.dll - ..\..\ref_TB\Techblox_Data\Managed\Gamecraft.JointBlocks.dll - - - ..\ref_TB\Techblox_Data\Managed\Gamecraft.Music.dll - ..\..\ref_TB\Techblox_Data\Managed\Gamecraft.Music.dll - - - ..\ref_TB\Techblox_Data\Managed\Gamecraft.NetStrings.dll - ..\..\ref_TB\Techblox_Data\Managed\Gamecraft.NetStrings.dll - - - ..\ref_TB\Techblox_Data\Managed\Gamecraft.PickupsCommon.dll - ..\..\ref_TB\Techblox_Data\Managed\Gamecraft.PickupsCommon.dll - - - ..\ref_TB\Techblox_Data\Managed\Gamecraft.PopupMessage.dll - ..\..\ref_TB\Techblox_Data\Managed\Gamecraft.PopupMessage.dll - - - ..\ref_TB\Techblox_Data\Managed\Gamecraft.Serialization.dll - ..\..\ref_TB\Techblox_Data\Managed\Gamecraft.Serialization.dll - - - ..\ref_TB\Techblox_Data\Managed\Gamecraft.Tweaks.dll - ..\..\ref_TB\Techblox_Data\Managed\Gamecraft.Tweaks.dll - - - ..\ref_TB\Techblox_Data\Managed\Gamecraft.VisualEffects.Decals.dll - ..\..\ref_TB\Techblox_Data\Managed\Gamecraft.VisualEffects.Decals.dll - - - ..\ref_TB\Techblox_Data\Managed\Gamecraft.Wires.dll - ..\..\ref_TB\Techblox_Data\Managed\Gamecraft.Wires.dll - - - ..\ref_TB\Techblox_Data\Managed\GameLiftServerSDKNet45.dll - ..\..\ref_TB\Techblox_Data\Managed\GameLiftServerSDKNet45.dll - - - ..\ref_TB\Techblox_Data\Managed\GameState.dll - ..\..\ref_TB\Techblox_Data\Managed\GameState.dll - - - ..\ref_TB\Techblox_Data\Managed\GhostShark.Outline.dll - ..\..\ref_TB\Techblox_Data\Managed\GhostShark.Outline.dll - - - ..\ref_TB\Techblox_Data\Managed\Google.Protobuf.dll - ..\..\ref_TB\Techblox_Data\Managed\Google.Protobuf.dll - - - ..\ref_TB\Techblox_Data\Managed\GPUInstancer.CrowdAnimations.dll - ..\..\ref_TB\Techblox_Data\Managed\GPUInstancer.CrowdAnimations.dll - - - ..\ref_TB\Techblox_Data\Managed\GPUInstancer.dll - ..\..\ref_TB\Techblox_Data\Managed\GPUInstancer.dll - - - ..\ref_TB\Techblox_Data\Managed\Havok.Physics.dll - ..\..\ref_TB\Techblox_Data\Managed\Havok.Physics.dll - - - ..\ref_TB\Techblox_Data\Managed\Havok.Physics.Hybrid.dll - ..\..\ref_TB\Techblox_Data\Managed\Havok.Physics.Hybrid.dll - - - ..\ref_TB\Techblox_Data\Managed\LiteNetLib.dll - ..\..\ref_TB\Techblox_Data\Managed\LiteNetLib.dll - - - ..\ref_TB\Techblox_Data\Managed\log4net.dll - ..\..\ref_TB\Techblox_Data\Managed\log4net.dll - - - ..\ref_TB\Techblox_Data\Managed\LZ4.dll - ..\..\ref_TB\Techblox_Data\Managed\LZ4.dll - - - ..\ref_TB\Techblox_Data\Managed\Monobehaviours.dll - ..\..\ref_TB\Techblox_Data\Managed\Monobehaviours.dll - - - ..\ref_TB\Techblox_Data\Managed\mscorlib.dll - ..\..\ref_TB\Techblox_Data\Managed\mscorlib.dll - - - ..\ref_TB\Techblox_Data\Managed\MultiplayerNetworking.dll - ..\..\ref_TB\Techblox_Data\Managed\MultiplayerNetworking.dll - - - ..\ref_TB\Techblox_Data\Managed\Newtonsoft.Json.dll - ..\..\ref_TB\Techblox_Data\Managed\Newtonsoft.Json.dll - - - ..\ref_TB\Techblox_Data\Managed\Novell.Directory.Ldap.dll - ..\..\ref_TB\Techblox_Data\Managed\Novell.Directory.Ldap.dll - - - ..\ref_TB\Techblox_Data\Managed\Prometheus.NetStandard.dll - ..\..\ref_TB\Techblox_Data\Managed\Prometheus.NetStandard.dll - - - ..\ref_TB\Techblox_Data\Managed\RCX.ScreenshotTaker.dll - ..\..\ref_TB\Techblox_Data\Managed\RCX.ScreenshotTaker.dll - - - ..\ref_TB\Techblox_Data\Managed\Rewired_Core.dll - ..\..\ref_TB\Techblox_Data\Managed\Rewired_Core.dll - - - ..\ref_TB\Techblox_Data\Managed\Rewired_Windows.dll - ..\..\ref_TB\Techblox_Data\Managed\Rewired_Windows.dll - - - ..\ref_TB\Techblox_Data\Managed\RichFX.dll - ..\..\ref_TB\Techblox_Data\Managed\RichFX.dll - - - ..\ref_TB\Techblox_Data\Managed\RobocraftECS.dll - ..\..\ref_TB\Techblox_Data\Managed\RobocraftECS.dll - - - ..\ref_TB\Techblox_Data\Managed\RobocraftX.AccountPreferences.dll - ..\..\ref_TB\Techblox_Data\Managed\RobocraftX.AccountPreferences.dll - - - ..\ref_TB\Techblox_Data\Managed\RobocraftX.Blocks.dll - ..\..\ref_TB\Techblox_Data\Managed\RobocraftX.Blocks.dll - - - ..\ref_TB\Techblox_Data\Managed\RobocraftX.Blocks.Ghost.dll - ..\..\ref_TB\Techblox_Data\Managed\RobocraftX.Blocks.Ghost.dll - - - ..\ref_TB\Techblox_Data\Managed\RobocraftX.Blocks.Triggers.dll - ..\..\ref_TB\Techblox_Data\Managed\RobocraftX.Blocks.Triggers.dll - - - ..\ref_TB\Techblox_Data\Managed\RobocraftX.Building.BoxSelect.dll - ..\..\ref_TB\Techblox_Data\Managed\RobocraftX.Building.BoxSelect.dll - - - ..\ref_TB\Techblox_Data\Managed\RobocraftX.Building.Jobs.dll - ..\..\ref_TB\Techblox_Data\Managed\RobocraftX.Building.Jobs.dll - - - ..\ref_TB\Techblox_Data\Managed\RobocraftX.Character.Audio.dll - ..\..\ref_TB\Techblox_Data\Managed\RobocraftX.Character.Audio.dll - - - ..\ref_TB\Techblox_Data\Managed\RobocraftX.Character.dll - ..\..\ref_TB\Techblox_Data\Managed\RobocraftX.Character.dll - - - ..\ref_TB\Techblox_Data\Managed\RobocraftX.Common.dll - ..\..\ref_TB\Techblox_Data\Managed\RobocraftX.Common.dll - - - ..\ref_TB\Techblox_Data\Managed\RobocraftX.ControlsScreen.dll - ..\..\ref_TB\Techblox_Data\Managed\RobocraftX.ControlsScreen.dll - - - ..\ref_TB\Techblox_Data\Managed\RobocraftX.Crosshair.dll - ..\..\ref_TB\Techblox_Data\Managed\RobocraftX.Crosshair.dll - - - ..\ref_TB\Techblox_Data\Managed\RobocraftX.FrontEnd.dll - ..\..\ref_TB\Techblox_Data\Managed\RobocraftX.FrontEnd.dll - - - ..\ref_TB\Techblox_Data\Managed\RobocraftX.GUI.DebugDisplay.dll - ..\..\ref_TB\Techblox_Data\Managed\RobocraftX.GUI.DebugDisplay.dll - - - ..\ref_TB\Techblox_Data\Managed\RobocraftX.GUI.dll - ..\..\ref_TB\Techblox_Data\Managed\RobocraftX.GUI.dll - - - ..\ref_TB\Techblox_Data\Managed\RobocraftX.GUI.Hotbar.dll - ..\..\ref_TB\Techblox_Data\Managed\RobocraftX.GUI.Hotbar.dll - - - ..\ref_TB\Techblox_Data\Managed\RobocraftX.GUI.Inventory.BlocksInventory.dll - ..\..\ref_TB\Techblox_Data\Managed\RobocraftX.GUI.Inventory.BlocksInventory.dll - - - ..\ref_TB\Techblox_Data\Managed\RobocraftX.GUI.Inventory.ColourInventory.dll - ..\..\ref_TB\Techblox_Data\Managed\RobocraftX.GUI.Inventory.ColourInventory.dll - - - ..\ref_TB\Techblox_Data\Managed\RobocraftX.GUI.Inventory.dll - ..\..\ref_TB\Techblox_Data\Managed\RobocraftX.GUI.Inventory.dll - - - ..\ref_TB\Techblox_Data\Managed\RobocraftX.GUI.QuitConfirmation.dll - ..\..\ref_TB\Techblox_Data\Managed\RobocraftX.GUI.QuitConfirmation.dll - - - ..\ref_TB\Techblox_Data\Managed\RobocraftX.GUI.ScaleGhost.dll - ..\..\ref_TB\Techblox_Data\Managed\RobocraftX.GUI.ScaleGhost.dll - - - ..\ref_TB\Techblox_Data\Managed\RobocraftX.GUI.TabsBar.dll - ..\..\ref_TB\Techblox_Data\Managed\RobocraftX.GUI.TabsBar.dll - - - ..\ref_TB\Techblox_Data\Managed\RobocraftX.Input.dll - ..\..\ref_TB\Techblox_Data\Managed\RobocraftX.Input.dll - - - ..\ref_TB\Techblox_Data\Managed\RobocraftX.MachineEditor.dll - ..\..\ref_TB\Techblox_Data\Managed\RobocraftX.MachineEditor.dll - - - ..\ref_TB\Techblox_Data\Managed\RobocraftX.MainGame.dll - ..\..\ref_TB\Techblox_Data\Managed\RobocraftX.MainGame.dll - - - ..\ref_TB\Techblox_Data\Managed\RobocraftX.MainSimulation.Audio.dll - ..\..\ref_TB\Techblox_Data\Managed\RobocraftX.MainSimulation.Audio.dll - - - ..\ref_TB\Techblox_Data\Managed\RobocraftX.MainSimulation.dll - ..\..\ref_TB\Techblox_Data\Managed\RobocraftX.MainSimulation.dll - - - ..\ref_TB\Techblox_Data\Managed\RobocraftX.Multiplayer.dll - ..\..\ref_TB\Techblox_Data\Managed\RobocraftX.Multiplayer.dll - - - ..\ref_TB\Techblox_Data\Managed\RobocraftX.Multiplayer.NetworkEntityStream.dll - ..\..\ref_TB\Techblox_Data\Managed\RobocraftX.Multiplayer.NetworkEntityStream.dll - - - ..\ref_TB\Techblox_Data\Managed\RobocraftX.Multiplayer.Serializers.dll - ..\..\ref_TB\Techblox_Data\Managed\RobocraftX.Multiplayer.Serializers.dll - - - ..\ref_TB\Techblox_Data\Managed\RobocraftX.MultiplayerInput.dll - ..\..\ref_TB\Techblox_Data\Managed\RobocraftX.MultiplayerInput.dll - - - ..\ref_TB\Techblox_Data\Managed\RobocraftX.ObjectIdBlocks.dll - ..\..\ref_TB\Techblox_Data\Managed\RobocraftX.ObjectIdBlocks.dll - - - ..\ref_TB\Techblox_Data\Managed\RobocraftX.Physics.dll - ..\..\ref_TB\Techblox_Data\Managed\RobocraftX.Physics.dll - - - ..\ref_TB\Techblox_Data\Managed\RobocraftX.PilotSeat.dll - ..\..\ref_TB\Techblox_Data\Managed\RobocraftX.PilotSeat.dll - - - ..\ref_TB\Techblox_Data\Managed\RobocraftX.Player.dll - ..\..\ref_TB\Techblox_Data\Managed\RobocraftX.Player.dll - - - ..\ref_TB\Techblox_Data\Managed\RobocraftX.SaveAndLoad.dll - ..\..\ref_TB\Techblox_Data\Managed\RobocraftX.SaveAndLoad.dll - - - ..\ref_TB\Techblox_Data\Managed\RobocraftX.SaveGameDialog.dll - ..\..\ref_TB\Techblox_Data\Managed\RobocraftX.SaveGameDialog.dll - - - ..\ref_TB\Techblox_Data\Managed\RobocraftX.Services.dll - ..\..\ref_TB\Techblox_Data\Managed\RobocraftX.Services.dll - - - ..\ref_TB\Techblox_Data\Managed\RobocraftX.SignalHandling.dll - ..\..\ref_TB\Techblox_Data\Managed\RobocraftX.SignalHandling.dll - - - ..\ref_TB\Techblox_Data\Managed\RobocraftX.StateSync.dll - ..\..\ref_TB\Techblox_Data\Managed\RobocraftX.StateSync.dll - - - ..\ref_TB\Techblox_Data\Managed\Serilog.dll - ..\..\ref_TB\Techblox_Data\Managed\Serilog.dll - - - ..\ref_TB\Techblox_Data\Managed\Serilog.Sinks.Grafana.Loki.dll - ..\..\ref_TB\Techblox_Data\Managed\Serilog.Sinks.Grafana.Loki.dll - - - ..\ref_TB\Techblox_Data\Managed\ShaderVariantsGenerationTool.dll - ..\..\ref_TB\Techblox_Data\Managed\ShaderVariantsGenerationTool.dll - - - ..\ref_TB\Techblox_Data\Managed\SpecializedDescriptors.dll - ..\..\ref_TB\Techblox_Data\Managed\SpecializedDescriptors.dll - - - ..\ref_TB\Techblox_Data\Managed\StringFormatter.dll - ..\..\ref_TB\Techblox_Data\Managed\StringFormatter.dll - - - ..\ref_TB\Techblox_Data\Managed\Svelto.Common.dll - ..\..\ref_TB\Techblox_Data\Managed\Svelto.Common.dll - - - ..\ref_TB\Techblox_Data\Managed\Svelto.ECS.dll - ..\..\ref_TB\Techblox_Data\Managed\Svelto.ECS.dll - - - ..\ref_TB\Techblox_Data\Managed\Svelto.ECS.GUI.dll - ..\..\ref_TB\Techblox_Data\Managed\Svelto.ECS.GUI.dll - - - ..\ref_TB\Techblox_Data\Managed\Svelto.Services.dll - ..\..\ref_TB\Techblox_Data\Managed\Svelto.Services.dll - - - ..\ref_TB\Techblox_Data\Managed\Svelto.Tasks.dll - ..\..\ref_TB\Techblox_Data\Managed\Svelto.Tasks.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.AdditionalParts.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.AdditionalParts.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.AntiAFKServer.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.AntiAFKServer.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.Anticheat.Client.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.Anticheat.Client.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.Anticheat.Common.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.Anticheat.Common.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.AtmosphereBlock.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.AtmosphereBlock.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.AudioBlocks.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.AudioBlocks.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.AudioBlocksClient.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.AudioBlocksClient.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.AutoForward.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.AutoForward.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.Backend.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.Backend.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.BitBlock.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.BitBlock.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.BlockColours.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.BlockColours.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.BlockLabels.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.BlockLabels.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.BlockLabelsServer.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.BlockLabelsServer.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.Blocks.Connections.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.Blocks.Connections.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.Blocks.LightBlock.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.Blocks.LightBlock.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.Building.Rules.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.Building.Rules.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.Building.Shift.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.Building.Shift.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.BuildingDrone.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.BuildingDrone.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.Camera.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.Camera.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.CentreHUDBlock.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.CentreHUDBlock.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.CentreHUDGUI.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.CentreHUDGUI.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.CharacterDamage.Client.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.CharacterDamage.Client.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.CharacterDamage.Server.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.CharacterDamage.Server.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.CharacterRespawnScreen.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.CharacterRespawnScreen.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.CheckpointBlock.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.CheckpointBlock.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.CheckpointBlockClient.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.CheckpointBlockClient.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.Common.Audio.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.Common.Audio.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.ConstantBlockClient.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.ConstantBlockClient.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.ConstantBlockServer.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.ConstantBlockServer.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.ContextSensitiveTextHint.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.ContextSensitiveTextHint.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.CounterBlockClient.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.CounterBlockClient.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.CounterBlockServer.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.CounterBlockServer.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.DamageRbScoreBlockServerServer.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.DamageRbScoreBlockServerServer.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.DirectionalDamageVingette.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.DirectionalDamageVingette.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.DistanceSensorBlock.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.DistanceSensorBlock.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.ECSResourceManagers.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.ECSResourceManagers.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.EngineBlock.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.EngineBlock.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.EnvironmentBlocks.BuildingEnvironment.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.EnvironmentBlocks.BuildingEnvironment.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.EnvironmentBlocks.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.EnvironmentBlocks.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.EnvironmentBlocks.SimulationWorldEnvironment.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.EnvironmentBlocks.SimulationWorldEnvironment.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.Gameplay.Client.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.Gameplay.Client.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.Gameplay.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.Gameplay.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.Gameplay.GameState.Client.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.Gameplay.GameState.Client.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.Gameplay.GameState.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.Gameplay.GameState.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.Gameplay.PlayerGameplayDetails.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.Gameplay.PlayerGameplayDetails.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.Gameplay.Score.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.Gameplay.Score.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.Gameplay.Spawning.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.Gameplay.Spawning.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.Gameplay.Teams.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.Gameplay.Teams.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.Gameplay.WorldResetting.Client.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.Gameplay.WorldResetting.Client.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.Gameplay.WorldResetting.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.Gameplay.WorldResetting.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.GameSelection.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.GameSelection.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.GUI.Building.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.GUI.Building.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.GUI.BuildRules.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.GUI.BuildRules.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.GUI.CharacterHealthFeedback.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.GUI.CharacterHealthFeedback.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.GUI.Collection.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.GUI.Collection.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.GUI.Controls.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.GUI.Controls.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.GUI.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.GUI.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.GUI.GamePortal.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.GUI.GamePortal.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.GUI.GeneralSettingsScreen.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.GUI.GeneralSettingsScreen.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.GUI.Hotbar.Landscapes.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.GUI.Hotbar.Landscapes.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.GUI.Hotbar.Materials.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.GUI.Hotbar.Materials.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.GUI.Inventory.Common.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.GUI.Inventory.Common.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.GUI.Inventory.Landscapes.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.GUI.Inventory.Landscapes.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.GUI.Inventory.Materials.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.GUI.Inventory.Materials.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.GUI.LoadingBar.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.GUI.LoadingBar.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.GUI.Login.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.GUI.Login.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.GUI.MachineReconstructTimer.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.GUI.MachineReconstructTimer.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.GUI.MainGame.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.GUI.MainGame.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.GUI.MainGame.StateMachine.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.GUI.MainGame.StateMachine.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.GUI.MyGamesScreen.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.GUI.MyGamesScreen.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.GUI.PauseMenu.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.GUI.PauseMenu.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.GUI.Progression.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.GUI.Progression.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.GUI.TabsBar.Landscapes.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.GUI.TabsBar.Landscapes.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.GUI.TabsBar.Materials.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.GUI.TabsBar.Materials.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.GUI.UsernameDisplay.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.GUI.UsernameDisplay.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.InputCapture.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.InputCapture.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.JetBlock.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.JetBlock.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.JetBlockClient.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.JetBlockClient.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.KillScoreBlock.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.KillScoreBlock.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.MachineProcessingService.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.MachineProcessingService.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.MachineSimulationPreprocessing.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.MachineSimulationPreprocessing.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.MachineSpawning.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.MachineSpawning.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.MachineVelocityCameraEffects.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.MachineVelocityCameraEffects.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.Matchmaking.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.Matchmaking.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.Monitoring.Server.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.Monitoring.Server.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.Multiplayer.UsernameMessages.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.Multiplayer.UsernameMessages.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.ObjectIDBlockClient.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.ObjectIDBlockClient.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.ObjectIDBlockServer.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.ObjectIDBlockServer.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.Particles.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.Particles.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.PlayUX.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.PlayUX.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.Pointer.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.Pointer.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.ProceduralReflectionProbes.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.ProceduralReflectionProbes.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.Rendering.Common.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.Rendering.Common.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.Rendering.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.Rendering.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.Rendering.DOTS.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.Rendering.DOTS.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.Rendering.GPUI.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.Rendering.GPUI.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.Rendering.Unity.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.Rendering.Unity.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.SaveGamesConversion.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.SaveGamesConversion.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.ScoreHUDBlock.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.ScoreHUDBlock.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.ScoreHUDGUI.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.ScoreHUDGUI.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.ScorePickupBlockClient.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.ScorePickupBlockClient.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.ScorePickupBlockServer.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.ScorePickupBlockServer.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.Server.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.Server.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.Services.Anticheat.Client.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.Services.Anticheat.Client.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.Services.Eos.Common.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.Services.Eos.Common.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.Services.Eos.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.Services.Eos.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.Services.GameDetails.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.Services.GameDetails.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.Services.LocalPreferences.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.Services.LocalPreferences.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.Services.Matchmaking.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.Services.Matchmaking.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.Services.Metrics.Server.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.Services.Metrics.Server.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.Services.Progression.Client.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.Services.Progression.Client.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.Services.Progression.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.Services.Progression.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.Services.Storage.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.Services.Storage.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.Services.Users.Client.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.Services.Users.Client.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.Services.Users.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.Services.Users.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.ServoBlocksClient.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.ServoBlocksClient.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.ServoBlocksServer.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.ServoBlocksServer.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.ServosServer.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.ServosServer.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.SignalHandling.Audio.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.SignalHandling.Audio.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.SignalHandling.Common.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.SignalHandling.Common.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.Simulation.Clusters.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.Simulation.Clusters.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.SpawnBlock.Client.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.SpawnBlock.Client.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.SpawnBlock.Server.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.SpawnBlock.Server.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.StabilizerBlock.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.StabilizerBlock.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.StabilizerBlockClient.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.StabilizerBlockClient.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.SwitchAnimation.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.SwitchAnimation.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.TeamScoreBlockClient.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.TeamScoreBlockClient.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.TeamScoreBlockServer.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.TeamScoreBlockServer.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.TechpointConverterBlock.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.TechpointConverterBlock.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.TechpointConverterGUI.TechPointPoolHUD.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.TechpointConverterGUI.TechPointPoolHUD.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.TechpointConverterGUI.TechpointRewardPanel.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.TechpointConverterGUI.TechpointRewardPanel.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.TextBlock.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.TextBlock.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.TimerBlock.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.TimerBlock.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.TriggerBlock.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.TriggerBlock.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.Tweaks.Validation.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.Tweaks.Validation.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.VFXBlockClient.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.VFXBlockClient.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.VFXBlockServer.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.VFXBlockServer.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.VisualEffects.VFXGraph.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.VisualEffects.VFXGraph.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.Weapons.Aiming.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.Weapons.Aiming.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.Weapons.DisablerBlock.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.Weapons.DisablerBlock.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.Weapons.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.Weapons.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.Weapons.Projectiles.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.Weapons.Projectiles.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.Weapons.Projectiles.Server.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.Weapons.Projectiles.Server.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.Weapons.Server.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.Weapons.Server.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.WheelFX.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.WheelFX.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.WheelRigBlock.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.WheelRigBlock.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.Wheels.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.Wheels.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.WorldEditor.Spawning.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.WorldEditor.Spawning.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.WorldEditor.TestPlayers.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.WorldEditor.TestPlayers.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.WorldResetterBlock.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.WorldResetterBlock.dll - - - ..\ref_TB\Techblox_Data\Managed\UniTask.Addressables.dll - ..\..\ref_TB\Techblox_Data\Managed\UniTask.Addressables.dll - - - ..\ref_TB\Techblox_Data\Managed\UniTask.dll - ..\..\ref_TB\Techblox_Data\Managed\UniTask.dll - - - ..\ref_TB\Techblox_Data\Managed\UniTask.DOTween.dll - ..\..\ref_TB\Techblox_Data\Managed\UniTask.DOTween.dll - - - ..\ref_TB\Techblox_Data\Managed\UniTask.Linq.dll - ..\..\ref_TB\Techblox_Data\Managed\UniTask.Linq.dll - - - ..\ref_TB\Techblox_Data\Managed\UniTask.TextMeshPro.dll - ..\..\ref_TB\Techblox_Data\Managed\UniTask.TextMeshPro.dll - - - ..\ref_TB\Techblox_Data\Managed\Unity.Addressables.dll - ..\..\ref_TB\Techblox_Data\Managed\Unity.Addressables.dll - - - ..\ref_TB\Techblox_Data\Managed\Unity.Burst.dll - ..\..\ref_TB\Techblox_Data\Managed\Unity.Burst.dll - - - ..\ref_TB\Techblox_Data\Managed\Unity.Burst.Unsafe.dll - ..\..\ref_TB\Techblox_Data\Managed\Unity.Burst.Unsafe.dll - - - ..\ref_TB\Techblox_Data\Managed\Unity.Collections.dll - ..\..\ref_TB\Techblox_Data\Managed\Unity.Collections.dll - - - ..\ref_TB\Techblox_Data\Managed\Unity.Collections.LowLevel.ILSupport.dll - ..\..\ref_TB\Techblox_Data\Managed\Unity.Collections.LowLevel.ILSupport.dll - - - ..\ref_TB\Techblox_Data\Managed\Unity.Deformations.dll - ..\..\ref_TB\Techblox_Data\Managed\Unity.Deformations.dll - - - ..\ref_TB\Techblox_Data\Managed\Unity.Entities.dll - ..\..\ref_TB\Techblox_Data\Managed\Unity.Entities.dll - - - ..\ref_TB\Techblox_Data\Managed\Unity.Entities.Hybrid.dll - ..\..\ref_TB\Techblox_Data\Managed\Unity.Entities.Hybrid.dll - - - ..\ref_TB\Techblox_Data\Managed\Unity.InternalAPIEngineBridge.012.dll - ..\..\ref_TB\Techblox_Data\Managed\Unity.InternalAPIEngineBridge.012.dll - - - ..\ref_TB\Techblox_Data\Managed\Unity.Jobs.dll - ..\..\ref_TB\Techblox_Data\Managed\Unity.Jobs.dll - - - ..\ref_TB\Techblox_Data\Managed\Unity.Mathematics.dll - ..\..\ref_TB\Techblox_Data\Managed\Unity.Mathematics.dll - - - ..\ref_TB\Techblox_Data\Managed\Unity.Mathematics.Extensions.dll - ..\..\ref_TB\Techblox_Data\Managed\Unity.Mathematics.Extensions.dll - - - ..\ref_TB\Techblox_Data\Managed\Unity.Mathematics.Extensions.Hybrid.dll - ..\..\ref_TB\Techblox_Data\Managed\Unity.Mathematics.Extensions.Hybrid.dll - - - ..\ref_TB\Techblox_Data\Managed\Unity.MemoryProfiler.dll - ..\..\ref_TB\Techblox_Data\Managed\Unity.MemoryProfiler.dll - - - ..\ref_TB\Techblox_Data\Managed\Unity.Physics.dll - ..\..\ref_TB\Techblox_Data\Managed\Unity.Physics.dll - - - ..\ref_TB\Techblox_Data\Managed\Unity.Physics.Hybrid.dll - ..\..\ref_TB\Techblox_Data\Managed\Unity.Physics.Hybrid.dll - - - ..\ref_TB\Techblox_Data\Managed\Unity.Platforms.Common.dll - ..\..\ref_TB\Techblox_Data\Managed\Unity.Platforms.Common.dll - - - ..\ref_TB\Techblox_Data\Managed\Unity.Profiling.Core.dll - ..\..\ref_TB\Techblox_Data\Managed\Unity.Profiling.Core.dll - - - ..\ref_TB\Techblox_Data\Managed\Unity.Properties.dll - ..\..\ref_TB\Techblox_Data\Managed\Unity.Properties.dll - - - ..\ref_TB\Techblox_Data\Managed\Unity.Properties.Reflection.dll - ..\..\ref_TB\Techblox_Data\Managed\Unity.Properties.Reflection.dll - - - ..\ref_TB\Techblox_Data\Managed\Unity.Properties.UI.dll - ..\..\ref_TB\Techblox_Data\Managed\Unity.Properties.UI.dll - - - ..\ref_TB\Techblox_Data\Managed\Unity.Recorder.Base.dll - ..\..\ref_TB\Techblox_Data\Managed\Unity.Recorder.Base.dll - - - ..\ref_TB\Techblox_Data\Managed\Unity.Recorder.dll - ..\..\ref_TB\Techblox_Data\Managed\Unity.Recorder.dll - - - ..\ref_TB\Techblox_Data\Managed\Unity.Rendering.Hybrid.dll - ..\..\ref_TB\Techblox_Data\Managed\Unity.Rendering.Hybrid.dll - - - ..\ref_TB\Techblox_Data\Managed\Unity.RenderPipelines.Core.Runtime.dll - ..\..\ref_TB\Techblox_Data\Managed\Unity.RenderPipelines.Core.Runtime.dll - - - ..\ref_TB\Techblox_Data\Managed\Unity.RenderPipelines.Core.ShaderLibrary.dll - ..\..\ref_TB\Techblox_Data\Managed\Unity.RenderPipelines.Core.ShaderLibrary.dll - - - ..\ref_TB\Techblox_Data\Managed\Unity.RenderPipelines.HighDefinition.Config.Runtime.dll - ..\..\ref_TB\Techblox_Data\Managed\Unity.RenderPipelines.HighDefinition.Config.Runtime.dll - - - ..\ref_TB\Techblox_Data\Managed\Unity.RenderPipelines.HighDefinition.Runtime.dll - ..\..\ref_TB\Techblox_Data\Managed\Unity.RenderPipelines.HighDefinition.Runtime.dll - - - ..\ref_TB\Techblox_Data\Managed\Unity.RenderPipelines.ShaderGraph.ShaderGraphLibrary.dll - ..\..\ref_TB\Techblox_Data\Managed\Unity.RenderPipelines.ShaderGraph.ShaderGraphLibrary.dll - - - ..\ref_TB\Techblox_Data\Managed\Unity.ResourceManager.dll - ..\..\ref_TB\Techblox_Data\Managed\Unity.ResourceManager.dll - - - ..\ref_TB\Techblox_Data\Managed\Unity.Scenes.dll - ..\..\ref_TB\Techblox_Data\Managed\Unity.Scenes.dll - - - ..\ref_TB\Techblox_Data\Managed\Unity.ScriptableBuildPipeline.dll - ..\..\ref_TB\Techblox_Data\Managed\Unity.ScriptableBuildPipeline.dll - - - ..\ref_TB\Techblox_Data\Managed\Unity.Serialization.dll - ..\..\ref_TB\Techblox_Data\Managed\Unity.Serialization.dll - - - ..\ref_TB\Techblox_Data\Managed\Unity.TextMeshPro.dll - ..\..\ref_TB\Techblox_Data\Managed\Unity.TextMeshPro.dll - - - ..\ref_TB\Techblox_Data\Managed\Unity.Timeline.dll - ..\..\ref_TB\Techblox_Data\Managed\Unity.Timeline.dll - - - ..\ref_TB\Techblox_Data\Managed\Unity.Transforms.dll - ..\..\ref_TB\Techblox_Data\Managed\Unity.Transforms.dll - - - ..\ref_TB\Techblox_Data\Managed\Unity.Transforms.Hybrid.dll - ..\..\ref_TB\Techblox_Data\Managed\Unity.Transforms.Hybrid.dll - - - ..\ref_TB\Techblox_Data\Managed\Unity.VisualEffectGraph.Runtime.dll - ..\..\ref_TB\Techblox_Data\Managed\Unity.VisualEffectGraph.Runtime.dll - - - ..\ref_TB\Techblox_Data\Managed\UnityEngine.AccessibilityModule.dll - ..\..\ref_TB\Techblox_Data\Managed\UnityEngine.AccessibilityModule.dll - - - ..\ref_TB\Techblox_Data\Managed\UnityEngine.AIModule.dll - ..\..\ref_TB\Techblox_Data\Managed\UnityEngine.AIModule.dll - - - ..\ref_TB\Techblox_Data\Managed\UnityEngine.AndroidJNIModule.dll - ..\..\ref_TB\Techblox_Data\Managed\UnityEngine.AndroidJNIModule.dll - - - ..\ref_TB\Techblox_Data\Managed\UnityEngine.AnimationModule.dll - ..\..\ref_TB\Techblox_Data\Managed\UnityEngine.AnimationModule.dll - - - ..\ref_TB\Techblox_Data\Managed\UnityEngine.ARModule.dll - ..\..\ref_TB\Techblox_Data\Managed\UnityEngine.ARModule.dll - - - ..\ref_TB\Techblox_Data\Managed\UnityEngine.AssetBundleModule.dll - ..\..\ref_TB\Techblox_Data\Managed\UnityEngine.AssetBundleModule.dll - - - ..\ref_TB\Techblox_Data\Managed\UnityEngine.AudioModule.dll - ..\..\ref_TB\Techblox_Data\Managed\UnityEngine.AudioModule.dll - - - ..\ref_TB\Techblox_Data\Managed\UnityEngine.ClothModule.dll - ..\..\ref_TB\Techblox_Data\Managed\UnityEngine.ClothModule.dll - - - ..\ref_TB\Techblox_Data\Managed\UnityEngine.ClusterInputModule.dll - ..\..\ref_TB\Techblox_Data\Managed\UnityEngine.ClusterInputModule.dll - - - ..\ref_TB\Techblox_Data\Managed\UnityEngine.ClusterRendererModule.dll - ..\..\ref_TB\Techblox_Data\Managed\UnityEngine.ClusterRendererModule.dll - - - ..\ref_TB\Techblox_Data\Managed\UnityEngine.CoreModule.dll - ..\..\ref_TB\Techblox_Data\Managed\UnityEngine.CoreModule.dll - - - ..\ref_TB\Techblox_Data\Managed\UnityEngine.CrashReportingModule.dll - ..\..\ref_TB\Techblox_Data\Managed\UnityEngine.CrashReportingModule.dll - - - ..\ref_TB\Techblox_Data\Managed\UnityEngine.DirectorModule.dll - ..\..\ref_TB\Techblox_Data\Managed\UnityEngine.DirectorModule.dll - - - ..\ref_TB\Techblox_Data\Managed\UnityEngine.dll - ..\..\ref_TB\Techblox_Data\Managed\UnityEngine.dll - - - ..\ref_TB\Techblox_Data\Managed\UnityEngine.DSPGraphModule.dll - ..\..\ref_TB\Techblox_Data\Managed\UnityEngine.DSPGraphModule.dll - - - ..\ref_TB\Techblox_Data\Managed\UnityEngine.GameCenterModule.dll - ..\..\ref_TB\Techblox_Data\Managed\UnityEngine.GameCenterModule.dll - - - ..\ref_TB\Techblox_Data\Managed\UnityEngine.GIModule.dll - ..\..\ref_TB\Techblox_Data\Managed\UnityEngine.GIModule.dll - - - ..\ref_TB\Techblox_Data\Managed\UnityEngine.GridModule.dll - ..\..\ref_TB\Techblox_Data\Managed\UnityEngine.GridModule.dll - - - ..\ref_TB\Techblox_Data\Managed\UnityEngine.HotReloadModule.dll - ..\..\ref_TB\Techblox_Data\Managed\UnityEngine.HotReloadModule.dll - - - ..\ref_TB\Techblox_Data\Managed\UnityEngine.ImageConversionModule.dll - ..\..\ref_TB\Techblox_Data\Managed\UnityEngine.ImageConversionModule.dll - - - ..\ref_TB\Techblox_Data\Managed\UnityEngine.IMGUIModule.dll - ..\..\ref_TB\Techblox_Data\Managed\UnityEngine.IMGUIModule.dll - - - ..\ref_TB\Techblox_Data\Managed\UnityEngine.InputLegacyModule.dll - ..\..\ref_TB\Techblox_Data\Managed\UnityEngine.InputLegacyModule.dll - - - ..\ref_TB\Techblox_Data\Managed\UnityEngine.InputModule.dll - ..\..\ref_TB\Techblox_Data\Managed\UnityEngine.InputModule.dll - - - ..\ref_TB\Techblox_Data\Managed\UnityEngine.JSONSerializeModule.dll - ..\..\ref_TB\Techblox_Data\Managed\UnityEngine.JSONSerializeModule.dll - - - ..\ref_TB\Techblox_Data\Managed\UnityEngine.LocalizationModule.dll - ..\..\ref_TB\Techblox_Data\Managed\UnityEngine.LocalizationModule.dll - - - ..\ref_TB\Techblox_Data\Managed\UnityEngine.NVIDIAModule.dll - ..\..\ref_TB\Techblox_Data\Managed\UnityEngine.NVIDIAModule.dll - - - ..\ref_TB\Techblox_Data\Managed\UnityEngine.ParticleSystemModule.dll - ..\..\ref_TB\Techblox_Data\Managed\UnityEngine.ParticleSystemModule.dll - - - ..\ref_TB\Techblox_Data\Managed\UnityEngine.PerformanceReportingModule.dll - ..\..\ref_TB\Techblox_Data\Managed\UnityEngine.PerformanceReportingModule.dll - - - ..\ref_TB\Techblox_Data\Managed\UnityEngine.Physics2DModule.dll - ..\..\ref_TB\Techblox_Data\Managed\UnityEngine.Physics2DModule.dll - - - ..\ref_TB\Techblox_Data\Managed\UnityEngine.PhysicsModule.dll - ..\..\ref_TB\Techblox_Data\Managed\UnityEngine.PhysicsModule.dll - - - ..\ref_TB\Techblox_Data\Managed\UnityEngine.ProfilerModule.dll - ..\..\ref_TB\Techblox_Data\Managed\UnityEngine.ProfilerModule.dll - - - ..\ref_TB\Techblox_Data\Managed\UnityEngine.RuntimeInitializeOnLoadManagerInitializerModule.dll - ..\..\ref_TB\Techblox_Data\Managed\UnityEngine.RuntimeInitializeOnLoadManagerInitializerModule.dll - - - ..\ref_TB\Techblox_Data\Managed\UnityEngine.ScreenCaptureModule.dll - ..\..\ref_TB\Techblox_Data\Managed\UnityEngine.ScreenCaptureModule.dll - - - ..\ref_TB\Techblox_Data\Managed\UnityEngine.SharedInternalsModule.dll - ..\..\ref_TB\Techblox_Data\Managed\UnityEngine.SharedInternalsModule.dll - - - ..\ref_TB\Techblox_Data\Managed\UnityEngine.SpriteMaskModule.dll - ..\..\ref_TB\Techblox_Data\Managed\UnityEngine.SpriteMaskModule.dll - - - ..\ref_TB\Techblox_Data\Managed\UnityEngine.SpriteShapeModule.dll - ..\..\ref_TB\Techblox_Data\Managed\UnityEngine.SpriteShapeModule.dll - - - ..\ref_TB\Techblox_Data\Managed\UnityEngine.StreamingModule.dll - ..\..\ref_TB\Techblox_Data\Managed\UnityEngine.StreamingModule.dll - - - ..\ref_TB\Techblox_Data\Managed\UnityEngine.SubstanceModule.dll - ..\..\ref_TB\Techblox_Data\Managed\UnityEngine.SubstanceModule.dll - - - ..\ref_TB\Techblox_Data\Managed\UnityEngine.SubsystemsModule.dll - ..\..\ref_TB\Techblox_Data\Managed\UnityEngine.SubsystemsModule.dll - - - ..\ref_TB\Techblox_Data\Managed\UnityEngine.TerrainModule.dll - ..\..\ref_TB\Techblox_Data\Managed\UnityEngine.TerrainModule.dll - - - ..\ref_TB\Techblox_Data\Managed\UnityEngine.TerrainPhysicsModule.dll - ..\..\ref_TB\Techblox_Data\Managed\UnityEngine.TerrainPhysicsModule.dll - - - ..\ref_TB\Techblox_Data\Managed\UnityEngine.TextCoreFontEngineModule.dll - ..\..\ref_TB\Techblox_Data\Managed\UnityEngine.TextCoreFontEngineModule.dll - - - ..\ref_TB\Techblox_Data\Managed\UnityEngine.TextCoreTextEngineModule.dll - ..\..\ref_TB\Techblox_Data\Managed\UnityEngine.TextCoreTextEngineModule.dll - - - ..\ref_TB\Techblox_Data\Managed\UnityEngine.TextRenderingModule.dll - ..\..\ref_TB\Techblox_Data\Managed\UnityEngine.TextRenderingModule.dll - - - ..\ref_TB\Techblox_Data\Managed\UnityEngine.TilemapModule.dll - ..\..\ref_TB\Techblox_Data\Managed\UnityEngine.TilemapModule.dll - - - ..\ref_TB\Techblox_Data\Managed\UnityEngine.TLSModule.dll - ..\..\ref_TB\Techblox_Data\Managed\UnityEngine.TLSModule.dll - - - ..\ref_TB\Techblox_Data\Managed\UnityEngine.UI.dll - ..\..\ref_TB\Techblox_Data\Managed\UnityEngine.UI.dll - - - ..\ref_TB\Techblox_Data\Managed\UnityEngine.UIElementsModule.dll - ..\..\ref_TB\Techblox_Data\Managed\UnityEngine.UIElementsModule.dll - - - ..\ref_TB\Techblox_Data\Managed\UnityEngine.UIElementsNativeModule.dll - ..\..\ref_TB\Techblox_Data\Managed\UnityEngine.UIElementsNativeModule.dll - - - ..\ref_TB\Techblox_Data\Managed\UnityEngine.UIModule.dll - ..\..\ref_TB\Techblox_Data\Managed\UnityEngine.UIModule.dll - - - ..\ref_TB\Techblox_Data\Managed\UnityEngine.UmbraModule.dll - ..\..\ref_TB\Techblox_Data\Managed\UnityEngine.UmbraModule.dll - - - ..\ref_TB\Techblox_Data\Managed\UnityEngine.UNETModule.dll - ..\..\ref_TB\Techblox_Data\Managed\UnityEngine.UNETModule.dll - - - ..\ref_TB\Techblox_Data\Managed\UnityEngine.UnityAnalyticsModule.dll - ..\..\ref_TB\Techblox_Data\Managed\UnityEngine.UnityAnalyticsModule.dll - - - ..\ref_TB\Techblox_Data\Managed\UnityEngine.UnityConnectModule.dll - ..\..\ref_TB\Techblox_Data\Managed\UnityEngine.UnityConnectModule.dll - - - ..\ref_TB\Techblox_Data\Managed\UnityEngine.UnityCurlModule.dll - ..\..\ref_TB\Techblox_Data\Managed\UnityEngine.UnityCurlModule.dll - - - ..\ref_TB\Techblox_Data\Managed\UnityEngine.UnityTestProtocolModule.dll - ..\..\ref_TB\Techblox_Data\Managed\UnityEngine.UnityTestProtocolModule.dll - - - ..\ref_TB\Techblox_Data\Managed\UnityEngine.UnityWebRequestAssetBundleModule.dll - ..\..\ref_TB\Techblox_Data\Managed\UnityEngine.UnityWebRequestAssetBundleModule.dll - - - ..\ref_TB\Techblox_Data\Managed\UnityEngine.UnityWebRequestAudioModule.dll - ..\..\ref_TB\Techblox_Data\Managed\UnityEngine.UnityWebRequestAudioModule.dll - - - ..\ref_TB\Techblox_Data\Managed\UnityEngine.UnityWebRequestModule.dll - ..\..\ref_TB\Techblox_Data\Managed\UnityEngine.UnityWebRequestModule.dll - - - ..\ref_TB\Techblox_Data\Managed\UnityEngine.UnityWebRequestTextureModule.dll - ..\..\ref_TB\Techblox_Data\Managed\UnityEngine.UnityWebRequestTextureModule.dll - - - ..\ref_TB\Techblox_Data\Managed\UnityEngine.UnityWebRequestWWWModule.dll - ..\..\ref_TB\Techblox_Data\Managed\UnityEngine.UnityWebRequestWWWModule.dll - - - ..\ref_TB\Techblox_Data\Managed\UnityEngine.VehiclesModule.dll - ..\..\ref_TB\Techblox_Data\Managed\UnityEngine.VehiclesModule.dll - - - ..\ref_TB\Techblox_Data\Managed\UnityEngine.VFXModule.dll - ..\..\ref_TB\Techblox_Data\Managed\UnityEngine.VFXModule.dll - - - ..\ref_TB\Techblox_Data\Managed\UnityEngine.VideoModule.dll - ..\..\ref_TB\Techblox_Data\Managed\UnityEngine.VideoModule.dll - - - ..\ref_TB\Techblox_Data\Managed\UnityEngine.VirtualTexturingModule.dll - ..\..\ref_TB\Techblox_Data\Managed\UnityEngine.VirtualTexturingModule.dll - - - ..\ref_TB\Techblox_Data\Managed\UnityEngine.VRModule.dll - ..\..\ref_TB\Techblox_Data\Managed\UnityEngine.VRModule.dll - - - ..\ref_TB\Techblox_Data\Managed\UnityEngine.WindModule.dll - ..\..\ref_TB\Techblox_Data\Managed\UnityEngine.WindModule.dll - - - ..\ref_TB\Techblox_Data\Managed\UnityEngine.XRModule.dll - ..\..\ref_TB\Techblox_Data\Managed\UnityEngine.XRModule.dll - - - ..\ref_TB\Techblox_Data\Managed\VisualProfiler.dll - ..\..\ref_TB\Techblox_Data\Managed\VisualProfiler.dll - - - ..\ref_TB\Techblox_Data\Managed\websocket-sharp.dll - ..\..\ref_TB\Techblox_Data\Managed\websocket-sharp.dll - - - ..\ref_TB\Techblox_Data\Managed\ZFBrowser.dll - ..\..\ref_TB\Techblox_Data\Managed\ZFBrowser.dll - - - - \ No newline at end of file diff --git a/CodeGenerator/Program.cs b/CodeGenerator/Program.cs deleted file mode 100644 index 8d870e3..0000000 --- a/CodeGenerator/Program.cs +++ /dev/null @@ -1,53 +0,0 @@ -using System.Collections.Generic; -using HarmonyLib; -using RobocraftX.Blocks; -using RobocraftX.Common; -using RobocraftX.GroupTags; -using RobocraftX.PilotSeat; -using Svelto.ECS; -using Techblox.EngineBlock; -using Techblox.ServoBlocksServer; -using Techblox.WheelRigBlock; - -namespace CodeGenerator -{ - internal class Program - { - public static void Main(string[] args) - { - GenerateBlockClasses(); - } - - private static void GenerateBlockClasses() - { - var bcg = new BlockClassGenerator(); - bcg.Generate("Engine", null, new Dictionary - { - { "engineOn", "On" } - }, AccessTools.TypeByName("Techblox.EngineBlock.EngineBlockComponent"), // Simulation time properties - typeof(EngineBlockTweakableComponent), typeof(EngineBlockReadonlyComponent)); - bcg.Generate("DampedSpring", "DAMPEDSPRING_BLOCK_GROUP", new Dictionary - { - {"maxExtent", "MaxExtension"} - }, - typeof(TweakableJointDampingComponent), typeof(DampedSpringReadOnlyStruct)); - bcg.Generate("LogicGate", "LOGIC_BLOCK_GROUP"); - bcg.Generate("Servo", types: typeof(ServoReadOnlyTweakableComponent), renames: new Dictionary - { - {"minDeviation", "MinimumAngle"}, - {"maxDeviation", "MaximumAngle"}, - {"servoVelocity", "MaximumForce"} - }); - bcg.Generate("WheelRig", "WHEELRIG_BLOCK_BUILD_GROUP", null, - typeof(WheelRigTweakableStruct), typeof(WheelRigReadOnlyStruct), - typeof(WheelRigSteerableTweakableStruct), typeof(WheelRigSteerableReadOnlyStruct)); - bcg.Generate("Seat", "RobocraftX.PilotSeat.SeatGroups.PILOTSEAT_BLOCK_BUILD_GROUP", null, typeof(SeatFollowCamComponent), typeof(SeatReadOnlySettingsComponent)); - bcg.Generate("Piston", null, new Dictionary - { - {"pistonVelocity", "MaximumForce"} - }, typeof(PistonReadOnlyStruct)); - bcg.Generate("Motor", null, null, typeof(MotorReadOnlyStruct)); - //bcg.Generate("ObjectID", "ObjectIDBlockExclusiveGroups.OBJECT_ID_BLOCK_GROUP", null, typeof(ObjectIDTweakableComponent)); - } - } -} \ No newline at end of file diff --git a/CodeGenerator/packages.config b/CodeGenerator/packages.config deleted file mode 100644 index aeba8bb..0000000 --- a/CodeGenerator/packages.config +++ /dev/null @@ -1,4 +0,0 @@ - - - - \ No newline at end of file diff --git a/GamecraftModdingAPI.sln b/GamecraftModdingAPI.sln new file mode 100644 index 0000000..fe00440 --- /dev/null +++ b/GamecraftModdingAPI.sln @@ -0,0 +1,31 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.29411.108 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "GamecraftModdingAPI", "GamecraftModdingAPI\GamecraftModdingAPI.csproj", "{7FD5A7D8-4F3E-426A-B07D-7DC70442A4DF}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Automation", "Automation\Automation.csproj", "{1DF6E538-4DA4-4708-A567-781AF788921A}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {7FD5A7D8-4F3E-426A-B07D-7DC70442A4DF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {7FD5A7D8-4F3E-426A-B07D-7DC70442A4DF}.Debug|Any CPU.Build.0 = Debug|Any CPU + {7FD5A7D8-4F3E-426A-B07D-7DC70442A4DF}.Release|Any CPU.ActiveCfg = Release|Any CPU + {7FD5A7D8-4F3E-426A-B07D-7DC70442A4DF}.Release|Any CPU.Build.0 = Release|Any CPU + {1DF6E538-4DA4-4708-A567-781AF788921A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {1DF6E538-4DA4-4708-A567-781AF788921A}.Debug|Any CPU.Build.0 = Debug|Any CPU + {1DF6E538-4DA4-4708-A567-781AF788921A}.Release|Any CPU.ActiveCfg = Release|Any CPU + {1DF6E538-4DA4-4708-A567-781AF788921A}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {72FB94D0-6C50-475B-81E0-C94C7D7A2A17} + EndGlobalSection +EndGlobal diff --git a/GamecraftModdingAPI/Blocks/BlockColors.cs b/GamecraftModdingAPI/Blocks/BlockColors.cs new file mode 100644 index 0000000..146bcbf --- /dev/null +++ b/GamecraftModdingAPI/Blocks/BlockColors.cs @@ -0,0 +1,20 @@ +namespace GamecraftModdingAPI.Blocks +{ + /// + /// Preset block colours + /// + public enum BlockColors + { + Default = byte.MaxValue, + White = 0, + Pink, + Purple, + Blue, + Aqua, + Green, + Lime, + Yellow, + Orange, + Red + } +} \ No newline at end of file diff --git a/GamecraftModdingAPI/Blocks/BlockIDs.cs b/GamecraftModdingAPI/Blocks/BlockIDs.cs new file mode 100644 index 0000000..1a7a77a --- /dev/null +++ b/GamecraftModdingAPI/Blocks/BlockIDs.cs @@ -0,0 +1,230 @@ +namespace GamecraftModdingAPI.Blocks +{ + /// + /// Possible block types + /// + public enum BlockIDs + { + AluminiumCube, + AxleS, + HingeS = 3, + MotorS, + HingeM, + MotorM, + TyreM, + AxleM, + IronCube, + RubberCube, + OiledCube, + AluminiumConeSegment, //12 + AluminiumCorner, + AluminiumRoundedCorner, + AluminiumSlicedCube, + AluminiumRoundedSlicedCube, + AluminiumCylinder, + AluminiumPyramidSegment, + AluminiumSlope, + AluminiumRoundedSlope, + AluminiumSphere, + RubberConeSegment, //22 + RubberCorner, + RubberRoundedCorner, + RubberSlicedCube, + RubberRoundedSlicedCube, + RubberCylinder, + RubberPyramidSegment, + RubberSlope, + RubberRoundedSlope, + RubberSphere, + OiledConeSegment, //32 + OiledCorner, + OiledRoundedCorner, + OiledSlicedCube, + OiledRoundedSlicedCube, + OiledCylinder, + OiledPyramidSegment, + OiledSlope, + OiledRoundedSlope, + OiledSphere, + IronConeSegment, //42 + IronCorner, + IronRoundedCorner, + IronSlicedCube, + IronRoundedSlicedCube, + IronCylinder, + IronPyramidSegment, + IronSlope, + IronRoundedSlope, + IronSphere, + GlassCube, //52 + GlassSlicedCube, + GlassSlope, + GlassCorner, + GlassPyramidSegment, + GlassRoundedSlicedCube, + GlassRoundedSlope, + GlassRoundedCorner, + GlassConeSegment, + GlassCylinder, + GlassSphere, + Lever, //63 - two IDs skipped + PlayerSpawn = 66, //Crashes without special handling + SmallSpawn, + MediumSpawn, + LargeSpawn, + BallJoint, + UniversalJoint, + ServoAxle, + ServoHinge, + StepperAxle, + StepperHinge, + TelescopicJoint, + DampedSpring, + ServoPiston, + StepperPiston, + PneumaticPiston, + PneumaticHinge, + PneumaticAxle, //82 + PilotSeat = 90, //Might crash + PassengerSeat, + PilotControls, + GrassCube, + DirtCube, + GrassConeSegment, + GrassCorner, + GrassRoundedCorner, + GrassSlicedCube, + GrassRoundedSlicedCube, + GrassPyramidSegment, + GrassSlope, + GrassRoundedSlope, + DirtConeSegment, + DirtCorner, + DirtRoundedCorner, + DirtSlicedCube, + DirtRoundedSlicedCube, + DirtPyramidSegment, + DirtSlope, + DirtRoundedSlope, + RubberHemisphere, + AluminiumHemisphere, + GrassInnerCornerBulged, + DirtInnerCornerBulged, + IronHemisphere, + OiledHemisphere, + GlassHemisphere, + TyreS, + ThreeWaySwitch, + Dial, //120 + CharacterOnEnterTrigger, //Probably crashes + CharacterOnLeaveTrigger, + CharacterOnStayTrigger, + ObjectOnEnterTrigger, + ObjectOnLeaveTrigger, + ObjectOnStayTrigger, + Button, + Switch, + TextBlock, //Brings up a screen + ConsoleBlock, //Brings up a screen + Door, + GlassDoor, + PoweredDoor, + PoweredGlassDoor, + AluminiumTubeCorner, + IronTubeCorner, + WoodCube, + WoodSlicedCube, + WoodSlope, + WoodCorner, + WoodPyramidSegment, + WoodConeSegment, + WoodRoundedSlicedCube, + WoodRoundedSlope, + WoodRoundedCorner, + WoodCylinder, + WoodHemisphere, + WoodSphere, + BrickCube, //149 + BrickSlicedCube = 151, + BrickSlope, + BrickCorner, + ConcreteCube, + ConcreteSlicedCube, + ConcreteSlope, + ConcreteCorner, + RoadCarTyre, + OffRoadCarTyre, + RacingCarTyre, + BicycleTyre, + FrontBikeTyre, + RearBikeTyre, + ChopperBikeTyre, + TractorTyre, + MonsterTruckTyre, + MotocrossBikeTyre, + CartTyre, //168 + ObjectIdentifier, + ANDLogicBlock, + NANDLogicBlock, + NORLogicBlock, + NOTLogicBlock, + ORLogicBlock, + XNORLogicBlock, + XORLogicBlock, + AbsoluteMathsBlock, + AdderMathsBlock, + DividerMathsBlock, + SignMathsBlock, //180 + MaxMathsBlock, + MinMathsBlock, + MultiplierMathsBlock, + SubtractorMathsBlock, + SimpleConnector, + MeanMathsBlock, + Bit, + Counter, + Timer, + ObjectFilter, + PlayerFilter, + TeamFilter, + Number2Text, //193 + BeachTree1 = 200, + BeachTree2, + BeachTree3, + Rock1, + Rock2, + Rock3, + Rock4, + BirchTree1, + BirchTree2, + BirchTree3, + PineTree1, + PineTree2, + PineTree3, + Flower1, + Flower2, + Flower3, + Shrub1, + Shrub2, + Shrub3, + CliffCube, + CliffSlicedCorner, + CliffCornerA, + CliffCornerB, + CliffSlopeA, + CliffSlopeB, + GrassEdge, + GrassEdgeInnerCorner, + GrassEdgeCorner, + GrassEdgeSlope, + CentreHUD, + ObjectiveHUD, + GameStatsHUD, //231 + Mover = 250, + Rotator, + MovementDampener, + RotationDampener, + AdvancedMover, + AdvancedRotator + } +} \ No newline at end of file diff --git a/GamecraftModdingAPI/Blocks/BlockIdentifiers.cs b/GamecraftModdingAPI/Blocks/BlockIdentifiers.cs new file mode 100644 index 0000000..13bafce --- /dev/null +++ b/GamecraftModdingAPI/Blocks/BlockIdentifiers.cs @@ -0,0 +1,49 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Reflection; + +using Svelto.ECS; +using RobocraftX.Common; + +using Harmony; + +namespace GamecraftModdingAPI.Blocks +{ + /// + /// ExclusiveGroups and IDs used with blocks + /// + public static class BlockIdentifiers + { + /// + /// Blocks placed by the player + /// + public static ExclusiveGroup OWNED_BLOCKS { get { return CommonExclusiveGroups.OWNED_BLOCKS_GROUP; } } + + /// + /// Extra parts used in functional blocks + /// + public static ExclusiveGroup FUNCTIONAL_BLOCK_PARTS { get { return CommonExclusiveGroups.FUNCTIONAL_BLOCK_PART_GROUP; } } + + /// + /// Blocks which are disabled in Simulation mode + /// + public static ExclusiveGroup SIM_BLOCKS_DISABLED { get { return CommonExclusiveGroups.BLOCKS_DISABLED_IN_SIM_GROUP; } } + + public static ExclusiveGroup SPAWN_POINTS { get { return CommonExclusiveGroups.SPAWN_POINTS_GROUP; } } + + public static ExclusiveGroup SPAWN_POINTS_DISABLED { get { return CommonExclusiveGroups.SPAWN_POINTS_DISABLED_GROUP; } } + + /// + /// The ID of the most recently placed block + /// + public static uint LatestBlockID { + get + { + return ((uint) AccessTools.Field(typeof(CommonExclusiveGroups), "_nextBlockEntityID").GetValue(null)) - 1; + } + } + } +} diff --git a/GamecraftModdingAPI/Blocks/BlockUtility.cs b/GamecraftModdingAPI/Blocks/BlockUtility.cs new file mode 100644 index 0000000..342ee73 --- /dev/null +++ b/GamecraftModdingAPI/Blocks/BlockUtility.cs @@ -0,0 +1,31 @@ +using RobocraftX.Blocks.Ghost; +using RobocraftX.Character.Camera; +using RobocraftX.Character.Factories; +using Svelto.ECS; + +namespace GamecraftModdingAPI.Blocks +{ + public class BlockUtility + { + /// + /// Returns the block the player is currently looking at. + /// + /// The player's ID + /// The entities DB + /// The maximum distance from the player (default is the player's building reach) + /// The block's EGID or null if not found + public static EGID? GetBlockLookedAt(uint playerId, EntitiesDB entitiesDB, float maxDistance = -1f) + { + if (!entitiesDB.TryQueryMappedEntities( + CameraExclusiveGroups.CameraGroup, out var mapper)) + return null; + mapper.TryGetEntity(playerId, out CharacterCameraRayCastEntityStruct rayCast); + float distance = maxDistance < 0 + ? GhostBlockUtils.GetBuildInteractionDistance(entitiesDB, rayCast) + : maxDistance; + if (rayCast.hit && rayCast.distance <= distance) + return rayCast.hitEgid; + return null; + } + } +} \ No newline at end of file diff --git a/GamecraftModdingAPI/Blocks/Movement.cs b/GamecraftModdingAPI/Blocks/Movement.cs new file mode 100644 index 0000000..28575a9 --- /dev/null +++ b/GamecraftModdingAPI/Blocks/Movement.cs @@ -0,0 +1,61 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +using Unity.Mathematics; + +namespace GamecraftModdingAPI.Blocks +{ + /// + /// Common block movement operations. + /// The functionality of this class only works in build mode. + /// + public static class Movement + { + private static MovementEngine movementEngine = new MovementEngine(); + + /// + /// Move a single block by a specific (x,y,z) amount (offset). + /// The moved block will remain connected to the blocks it was touching before it was moved. + /// The block's placement grid and collision box are also moved. + /// + /// The block's id + /// The movement amount (x,y,z) + /// Whether the operation was successful + public static bool MoveBlock(uint id, float3 vector) + { + if (movementEngine.IsInGame && GamecraftModdingAPI.Utility.GameState.IsBuildMode()) + { + movementEngine.MoveBlock(id, vector); + return true; + } + return false; + } + + /// + /// Move all connected blocks by a specific (x,y,z) amount (offset). + /// The moved blocks will remain connected to the block they're touching. + /// All of the block's placement grids and collision boxes are also moved. + /// This is equivalent to calling MoveBlock() for every connected block. + /// + /// The starting block's id + /// The movement amount (x,y,z) + /// Whether the operation was successful + public static bool MoveConnectedBlocks(uint id, float3 vector) + { + if (movementEngine.IsInGame && GamecraftModdingAPI.Utility.GameState.IsBuildMode()) + { + movementEngine.MoveConnectedBlocks(id, vector); + return true; + } + return false; + } + + public static void Init() + { + GamecraftModdingAPI.Utility.GameEngineManager.AddGameEngine(movementEngine); + } + } +} diff --git a/GamecraftModdingAPI/Blocks/MovementEngine.cs b/GamecraftModdingAPI/Blocks/MovementEngine.cs new file mode 100644 index 0000000..ab4eaa4 --- /dev/null +++ b/GamecraftModdingAPI/Blocks/MovementEngine.cs @@ -0,0 +1,83 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +using RobocraftX; +using RobocraftX.Blocks; +using RobocraftX.Blocks.Ghost; +using RobocraftX.Common; +using RobocraftX.Multiplayer; +using RobocraftX.SimulationModeState; +using RobocraftX.UECS; +using Unity.Entities; +using Svelto.Context; +using Svelto.ECS; +using Svelto.ECS.EntityStructs; +using Unity.Transforms; +using Unity.Mathematics; +using UnityEngine; + +using GamecraftModdingAPI.Utility; +using Svelto.DataStructures; + +namespace GamecraftModdingAPI.Blocks +{ + /// + /// Engine which executes block movement actions + /// + public class MovementEngine : IApiEngine + { + public string Name { get; } = "GamecraftModdingAPIMovementGameEngine"; + + public EntitiesDB entitiesDB { set; private get; } + + public bool IsInGame = false; + + public void Dispose() + { + IsInGame = false; + } + + public void Ready() + { + IsInGame = true; + } + + // implementations for Movement static class + + public float3 MoveBlock(uint blockID, float3 vector) + { + ref PositionEntityStruct posStruct = ref this.entitiesDB.QueryEntity(blockID, CommonExclusiveGroups.OWNED_BLOCKS_GROUP); + ref GridRotationStruct gridStruct = ref this.entitiesDB.QueryEntity(blockID, CommonExclusiveGroups.OWNED_BLOCKS_GROUP); + ref LocalTransformEntityStruct transStruct = ref this.entitiesDB.QueryEntity(blockID, CommonExclusiveGroups.OWNED_BLOCKS_GROUP); + ref UECSPhysicsEntityStruct phyStruct = ref this.entitiesDB.QueryEntity(blockID, CommonExclusiveGroups.OWNED_BLOCKS_GROUP); + // main (persistent) position + posStruct.position += vector; + // placement grid position + gridStruct.position += vector; + // rendered position + transStruct.position += vector; + // collision position + FullGameFields._physicsWorld.EntityManager.SetComponentData(phyStruct.uecsEntity, new Translation + { + Value = posStruct.position + }); + return posStruct.position; + } + + public float3 MoveConnectedBlocks(uint blockID, float3 vector) + { + Stack cubeStack = new Stack(); + FasterList cubesToMove = new FasterList(); + ConnectedCubesUtility.TreeTraversal.GetConnectedCubes(entitiesDB, blockID, cubeStack, cubesToMove, (in GridConnectionsEntityStruct g) => { return false; }); + for (int i = 0; i < cubesToMove.count; i++) + { + MoveBlock(cubesToMove[i], vector); + entitiesDB.QueryEntity(cubesToMove[i], CommonExclusiveGroups.OWNED_BLOCKS_GROUP).isProcessed = false; + } + return this.entitiesDB.QueryEntity(blockID, CommonExclusiveGroups.OWNED_BLOCKS_GROUP).position; + } + } +} diff --git a/GamecraftModdingAPI/Blocks/Placement.cs b/GamecraftModdingAPI/Blocks/Placement.cs new file mode 100644 index 0000000..c029ebb --- /dev/null +++ b/GamecraftModdingAPI/Blocks/Placement.cs @@ -0,0 +1,55 @@ +using System; + +using Unity.Mathematics; +using Svelto.ECS; + +using GamecraftModdingAPI.Utility; + +namespace GamecraftModdingAPI.Blocks +{ + /// + /// Common block placement operations. + /// The functionality in this class is for build mode. + /// + public static class Placement + { + private static PlacementEngine placementEngine = new PlacementEngine(); + + /// + /// Place a new block at the given position. If scaled, position means the center of the block. The default block size is 0.2 in terms of position. + /// Place blocks next to each other to connect them. + /// The placed block will be a complete block with a placement grid and collision which will be saved along with the game. + /// + /// The block's type + /// The block's color + /// The block color's darkness (0-9) - 0 is default color + /// The block's position in the grid - default block size is 0.2 + /// The block's rotation in degrees + /// The block's uniform scale - default scale is 1 (with 0.2 width) + /// The block's non-uniform scale - 0 means is used + /// The player who placed the block + /// The placed block's ID or null if failed + public static EGID? PlaceBlock(BlockIDs block, float3 position, + float3 rotation = default, BlockColors color = BlockColors.Default, byte darkness = 0, + int uscale = 1, float3 scale = default, uint playerId = 0) + { + if (placementEngine.IsInGame && GameState.IsBuildMode()) + { + try + { + return placementEngine.PlaceBlock(block, color, darkness, position, uscale, scale, playerId, rotation); + } + catch (Exception e) + { + Logging.MetaDebugLog(e); + } + } + return null; + } + + public static void Init() + { + GameEngineManager.AddGameEngine(placementEngine); + } + } +} diff --git a/GamecraftModdingAPI/Blocks/PlacementEngine.cs b/GamecraftModdingAPI/Blocks/PlacementEngine.cs new file mode 100644 index 0000000..0b9293c --- /dev/null +++ b/GamecraftModdingAPI/Blocks/PlacementEngine.cs @@ -0,0 +1,146 @@ +using System; +using System.Reflection; + +using DataLoader; +using Harmony; +using RobocraftX.Blocks; +using RobocraftX.Blocks.Ghost; +using RobocraftX.Blocks.Scaling; +using RobocraftX.Character; +using RobocraftX.CommandLine.Custom; +using RobocraftX.Common; +using RobocraftX.Common.Input; +using RobocraftX.Common.Utilities; +using RobocraftX.CR.MachineEditing; +using RobocraftX.StateSync; +using Svelto.ECS; +using Svelto.ECS.EntityStructs; +using Unity.Jobs; +using Unity.Mathematics; +using UnityEngine; +using uREPL; + +using GamecraftModdingAPI.Utility; + +namespace GamecraftModdingAPI.Blocks +{ + /// + /// Engine which executes block placement actions + /// + public class PlacementEngine : IApiEngine + { + public bool IsInGame = false; + + public void Dispose() + { + IsInGame = false; + } + + public void Ready() + { + IsInGame = true; + } + + public EntitiesDB entitiesDB { get; set; } + private static BlockEntityFactory _blockEntityFactory; //Injected from PlaceBlockEngine + + public EGID PlaceBlock(BlockIDs block, BlockColors color, byte darkness, float3 position, int uscale, + float3 scale, uint playerId, float3 rotation) + { //It appears that only the non-uniform scale has any visible effect, but if that's not given here it will be set to the uniform one + if (darkness > 9) + throw new Exception("That is too dark. Make sure to use 0-9 as darkness. (0 is default.)"); + return BuildBlock((ushort) block, (byte) (color + darkness * 10), position, uscale, scale, rotation, playerId); + } + + private EGID BuildBlock(ushort block, byte color, float3 position, int uscale, float3 scale, float3 rot, uint playerId) + { + if (_blockEntityFactory == null) + throw new Exception("The factory is null."); + if (uscale < 1) + throw new Exception("Scale needs to be at least 1"); + if (scale.x < 4e-5) scale.x = uscale; + if (scale.y < 4e-5) scale.y = uscale; + if (scale.z < 4e-5) scale.z = uscale; + uint dbid = block; + if (!PrefabsID.DBIDMAP.ContainsKey(dbid)) + throw new Exception("Block with ID " + dbid + " not found!"); + //RobocraftX.CR.MachineEditing.PlaceBlockEngine + ScalingEntityStruct scaling = new ScalingEntityStruct {scale = scale}; + Quaternion rotQ = Quaternion.Euler(rot); + RotationEntityStruct rotation = new RotationEntityStruct {rotation = rotQ}; + GridRotationStruct gridRotation = new GridRotationStruct + {position = position, rotation = rotQ}; + CubeCategoryStruct category = new CubeCategoryStruct + {category = CubeCategory.General, type = CubeType.Block}; + DBEntityStruct dbEntity = new DBEntityStruct {DBID = dbid}; + BlockPlacementScaleEntityStruct placementScale = new BlockPlacementScaleEntityStruct + { + blockPlacementHeight = uscale, blockPlacementWidth = uscale, desiredScaleFactor = uscale, + snapGridScale = uscale, + unitSnapOffset = 0, isUsingUnitSize = true + }; + EquippedColourStruct colour = new EquippedColourStruct {indexInPalette = color}; + EGID newBlockID; + switch (category.category) + { + case CubeCategory.SpawnPoint: + case CubeCategory.BuildingSpawnPoint: + newBlockID = MachineEditingGroups.NewSpawnPointBlockID; + break; + default: + newBlockID = MachineEditingGroups.NewBlockID; + break; + } + + EntityStructInitializer + structInitializer = + _blockEntityFactory.Build(newBlockID, dbid); //The ghost block index is only used for triggers + if (colour.indexInPalette != byte.MaxValue) + structInitializer.Init(new ColourParameterEntityStruct + { + indexInPalette = colour.indexInPalette, + needsUpdate = true + }); + uint prefabId = PrefabsID.GetPrefabId(dbid, 0); + structInitializer.Init(new GFXPrefabEntityStructGPUI(prefabId)); + structInitializer.Init(new PhysicsPrefabEntityStruct(prefabId)); + structInitializer.Init(dbEntity); + structInitializer.Init(new PositionEntityStruct {position = position}); + structInitializer.Init(rotation); + structInitializer.Init(scaling); + structInitializer.Init(gridRotation); + structInitializer.Init(new UniformBlockScaleEntityStruct + { + scaleFactor = placementScale.desiredScaleFactor + }); + structInitializer.Init(new BlockPlacementInfoStruct() + { + loadedFromDisk = false, + placedBy = playerId + }); + PrimaryRotationUtility.InitialisePrimaryDirection(rotation.rotation, ref structInitializer); + EGID playerEGID = new EGID(playerId, CharacterExclusiveGroups.OnFootGroup); + ref PickedBlockExtraDataStruct pickedBlock = ref entitiesDB.QueryEntity(playerEGID); + pickedBlock.placedBlockEntityID = playerEGID; + pickedBlock.placedBlockWasAPickedBlock = false; + return newBlockID; + } + + public string Name { get; } = "GamecraftModdingAPIPlacementGameEngine"; + + [HarmonyPatch] + public class FactoryObtainerPatch + { + static void Postfix(BlockEntityFactory blockEntityFactory) + { + _blockEntityFactory = blockEntityFactory; + Logging.MetaDebugLog("Block entity factory injected."); + } + + static MethodBase TargetMethod(HarmonyInstance instance) + { + return AccessTools.TypeByName("RobocraftX.CR.MachineEditing.PlaceBlockEngine").GetConstructors()[0]; + } + } + } +} \ No newline at end of file diff --git a/GamecraftModdingAPI/Blocks/Removal.cs b/GamecraftModdingAPI/Blocks/Removal.cs new file mode 100644 index 0000000..0bb54fb --- /dev/null +++ b/GamecraftModdingAPI/Blocks/Removal.cs @@ -0,0 +1,28 @@ +using Svelto.ECS; + +using GamecraftModdingAPI.Utility; + +namespace GamecraftModdingAPI.Blocks +{ + public class Removal + { + private static RemovalEngine _removalEngine = new RemovalEngine(); + + /// + /// Removes the block with the given ID. Returns false if the block doesn't exist or the game isn't in build mode. + /// + /// The block to remove + /// Whether the block was successfully removed + public static bool RemoveBlock(EGID targetBlock) + { + if (GameState.IsBuildMode()) + return _removalEngine.RemoveBlock(targetBlock); + return false; + } + + public static void Init() + { + GameEngineManager.AddGameEngine(_removalEngine); + } + } +} \ No newline at end of file diff --git a/GamecraftModdingAPI/Blocks/RemovalEngine.cs b/GamecraftModdingAPI/Blocks/RemovalEngine.cs new file mode 100644 index 0000000..41e3c03 --- /dev/null +++ b/GamecraftModdingAPI/Blocks/RemovalEngine.cs @@ -0,0 +1,74 @@ +using System.Reflection; + +using Harmony; +using RobocraftX.Blocks; +using RobocraftX.Blocks.Ghost; +using RobocraftX.Character.Camera; +using RobocraftX.Character.Factories; +using RobocraftX.Common; +using RobocraftX.Players; +using Svelto.ECS; +using uREPL; + +using GamecraftModdingAPI.Commands; +using GamecraftModdingAPI.Utility; + +namespace GamecraftModdingAPI.Blocks +{ + public class RemovalEngine : IApiEngine + { + private static IEntityFunctions _entityFunctions; + private static MachineGraphConnectionEntityFactory _connectionFactory; + + public bool RemoveBlock(EGID target) + { + if (!entitiesDB.Exists(target)) + return false; + var connections = entitiesDB.QueryEntity(target); + for (int i = connections.connections.Length - 1; i >= 0; i--) + _connectionFactory.RemoveConnection(connections, i, entitiesDB); + _entityFunctions.RemoveEntity(target); + return true; + } + + public void Ready() + { + /*CommandManager.AddCommand(new SimpleCustomCommandEngine(() => + { + var block = BlockUtility.GetBlockLookedAt(LocalPlayerIDUtility.GetLocalPlayerID(entitiesDB), entitiesDB); + if (block.HasValue) + { + RemoveBlock(block.Value); + Log.Output("Removed block."); + } + else + Log.Output("No block found where you're looking at."); + }, "removeCube", "Removes the cube you're looking at."));*/ + } + + public EntitiesDB entitiesDB { get; set; } + + public void Dispose() + { + } + + public string Name { get; } = "GamecraftModdingAPIRemovalGameEngine"; + + [HarmonyPatch] + public class FactoryObtainerPatch + { + static void Postfix(IEntityFunctions entityFunctions, + MachineGraphConnectionEntityFactory machineGraphConnectionEntityFactory) + { + _entityFunctions = entityFunctions; + _connectionFactory = machineGraphConnectionEntityFactory; + Logging.MetaDebugLog("Requirements injected."); + } + + static MethodBase TargetMethod(HarmonyInstance instance) + { + return AccessTools.TypeByName("RobocraftX.CR.MachineEditing.RemoveBlockEngine").GetConstructors()[0]; + } + } + } +} \ No newline at end of file diff --git a/GamecraftModdingAPI/Blocks/Rotation.cs b/GamecraftModdingAPI/Blocks/Rotation.cs new file mode 100644 index 0000000..b881cdb --- /dev/null +++ b/GamecraftModdingAPI/Blocks/Rotation.cs @@ -0,0 +1,59 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +using Unity.Mathematics; + +namespace GamecraftModdingAPI.Blocks +{ + /// + /// Common block rotation operations. + /// The functionality in this class is not completely implemented and will only work in build mode. + /// + public static class Rotation + { + private static RotationEngine rotationEngine = new RotationEngine(); + + /// + /// Rotate a single block by a specific amount in degrees. + /// This not destroy inter-block connections, so neighbouring blocks will remain attached despite appearances. + /// The cube placement grid and collision are also rotated. + /// + /// The block's id + /// The rotation amount around the x,y,z-axis + /// Whether the operation was successful + public static bool RotateBlock(uint id, float3 vector) + { + if (rotationEngine.IsInGame && GamecraftModdingAPI.Utility.GameState.IsBuildMode()) + { + rotationEngine.RotateBlock(id, vector); + return true; + } + return false; + } + + /// + /// Rotate all connected blocks by a specific amount in degrees. + /// This does not do anything because it has not been implemented. + /// + /// The starting block's id + /// The rotation around the x,y,z-axis + /// Whether the operation was successful + public static bool RotateConnectedBlocks(uint id, float3 vector) + { + if (rotationEngine.IsInGame && GamecraftModdingAPI.Utility.GameState.IsBuildMode()) + { + rotationEngine.RotateConnectedBlocks(id, vector); + return true; + } + return false; + } + + public static void Init() + { + GamecraftModdingAPI.Utility.GameEngineManager.AddGameEngine(rotationEngine); + } + } +} diff --git a/GamecraftModdingAPI/Blocks/RotationEngine.cs b/GamecraftModdingAPI/Blocks/RotationEngine.cs new file mode 100644 index 0000000..8038739 --- /dev/null +++ b/GamecraftModdingAPI/Blocks/RotationEngine.cs @@ -0,0 +1,82 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +using RobocraftX; +using RobocraftX.Blocks; +using RobocraftX.Blocks.Ghost; +using RobocraftX.Common; +using RobocraftX.Multiplayer; +using RobocraftX.SimulationModeState; +using RobocraftX.UECS; +using Unity.Entities; +using Svelto.Context; +using Svelto.ECS; +using Svelto.ECS.EntityStructs; +using Unity.Transforms; +using Unity.Mathematics; +using UnityEngine; + +using GamecraftModdingAPI.Utility; + +namespace GamecraftModdingAPI.Blocks +{ + /// + /// Engine which executes block movement actions + /// + public class RotationEngine : IApiEngine + { + public string Name { get; } = "GamecraftModdingAPIRotationGameEngine"; + + public EntitiesDB entitiesDB { set; private get; } + + public bool IsInGame = false; + + public void Dispose() + { + IsInGame = false; + } + + public void Ready() + { + IsInGame = true; + } + + // implementations for Rotation static class + + public float3 RotateBlock(uint blockID, Vector3 vector) + { + ref RotationEntityStruct rotStruct = ref this.entitiesDB.QueryEntity(blockID, CommonExclusiveGroups.OWNED_BLOCKS_GROUP); + ref GridRotationStruct gridStruct = ref this.entitiesDB.QueryEntity(blockID, CommonExclusiveGroups.OWNED_BLOCKS_GROUP); + ref LocalTransformEntityStruct transStruct = ref this.entitiesDB.QueryEntity(blockID, CommonExclusiveGroups.OWNED_BLOCKS_GROUP); + ref UECSPhysicsEntityStruct phyStruct = ref this.entitiesDB.QueryEntity(blockID, CommonExclusiveGroups.OWNED_BLOCKS_GROUP); + // main (persistent) position + Quaternion newRotation = (Quaternion)rotStruct.rotation; + newRotation.eulerAngles += vector; + rotStruct.rotation = (quaternion)newRotation; + // placement grid rotation + Quaternion newGridRotation = (Quaternion)gridStruct.rotation; + newGridRotation.eulerAngles += vector; + gridStruct.rotation = (quaternion)newGridRotation; + // rendered position + Quaternion newTransRotation = (Quaternion)rotStruct.rotation; + newTransRotation.eulerAngles += vector; + transStruct.rotation = newTransRotation; + // collision position + FullGameFields._physicsWorld.EntityManager.SetComponentData(phyStruct.uecsEntity, new Unity.Transforms.Rotation + { + Value = rotStruct.rotation + }); + return ((Quaternion)rotStruct.rotation).eulerAngles; + + } + + public float3 RotateConnectedBlocks(uint blockID, Vector3 vector) + { + // TODO: Implement and figure out the math + throw new NotImplementedException(); + } + } +} diff --git a/GamecraftModdingAPI/Blocks/SignalEngine.cs b/GamecraftModdingAPI/Blocks/SignalEngine.cs new file mode 100644 index 0000000..3b732ba --- /dev/null +++ b/GamecraftModdingAPI/Blocks/SignalEngine.cs @@ -0,0 +1,151 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +using RobocraftX; +using RobocraftX.Blocks; +using RobocraftX.Blocks.Ghost; +using RobocraftX.Common; +using RobocraftX.Multiplayer; +using RobocraftX.SimulationModeState; +using RobocraftX.UECS; +using Unity.Entities; +using Svelto.Context; +using Svelto.DataStructures; +using Svelto.ECS; +using Svelto.ECS.EntityStructs; +using Unity.Transforms; +using Unity.Mathematics; +using UnityEngine; +using Gamecraft.Wires; + +using GamecraftModdingAPI.Utility; + +namespace GamecraftModdingAPI.Blocks +{ + /// + /// Engine which executes signal actions + /// + public class SignalEngine : IApiEngine + { + public string Name { get; } = "GamecraftModdingAPISignalGameEngine"; + + public EntitiesDB entitiesDB { set; private get; } + + public bool IsInGame = false; + + public void Dispose() + { + IsInGame = false; + } + + public void Ready() + { + IsInGame = true; + } + + // implementations for Signal static class + + public bool SetSignal(EGID blockID, float signal, out uint signalID, bool input = true) + { + signalID = GetSignalIDs(blockID, input)[0]; + return SetSignal(signalID, signal); + } + + public bool SetSignal(uint signalID, float signal, bool input = true) + { + ExclusiveGroup group = input ? NamedExclusiveGroup.Group : NamedExclusiveGroup.Group; + if (entitiesDB.Exists(signalID, group)) + { + entitiesDB.QueryEntity(signalID, group).anyChannel.valueAsFloat = signal; + return true; + } + return false; + } + + public float AddSignal(EGID blockID, float signal, out uint signalID, bool clamp = true, bool input = true) + { + signalID = GetSignalIDs(blockID, input)[0]; + return AddSignal(signalID, signal, clamp, input); + } + + public float AddSignal(uint signalID, float signal, bool clamp = true, bool input = true) + { + ExclusiveGroup group = input ? NamedExclusiveGroup.Group : NamedExclusiveGroup.Group; + if (entitiesDB.Exists(signalID, group)) + { + ref PortEntityStruct pes = ref entitiesDB.QueryEntity(signalID, group); + pes.anyChannel.valueAsFloat += signal; + if (clamp) + { + if (pes.anyChannel.valueAsFloat > Signals.POSITIVE_HIGH) + { + pes.anyChannel.valueAsFloat = Signals.POSITIVE_HIGH; + } + else if (pes.anyChannel.valueAsFloat < Signals.NEGATIVE_HIGH) + { + pes.anyChannel.valueAsFloat = Signals.NEGATIVE_HIGH; + } + return pes.anyChannel.valueAsFloat; + } + } + return signal; + } + + public float GetSignal(EGID blockID, out uint signalID, bool input = true) + { + signalID = GetSignalIDs(blockID, input)[0]; + return GetSignal(signalID, input); + } + + public float GetSignal(uint signalID, bool input = true) + { + ExclusiveGroup group = input ? NamedExclusiveGroup.Group : NamedExclusiveGroup.Group; + if (entitiesDB.Exists(signalID, group)) + { + return entitiesDB.QueryEntity(signalID, group).anyChannel.valueAsFloat; + } + return 0f; + } + + public uint[] GetSignalIDs(EGID blockID, bool input = true) + { + ref BlockPortsStruct bps = ref entitiesDB.QueryEntity(blockID); + uint[] signals; + if (input) { + signals = new uint[bps.inputCount]; + for (uint i = 0u; i < bps.inputCount; i++) + { + signals[i] = bps.firstInputID + i; + } + } else { + signals = new uint[bps.outputCount]; + for (uint i = 0u; i < bps.outputCount; i++) + { + signals[i] = bps.firstOutputID + i; + } + } + return signals; + } + + public EGID[] GetElectricBlocks() + { + uint count = entitiesDB.Count(BlockIdentifiers.OWNED_BLOCKS) + entitiesDB.Count(BlockIdentifiers.FUNCTIONAL_BLOCK_PARTS); + uint i = 0; + EGID[] res = new EGID[count]; + foreach (ref BlockPortsStruct s in entitiesDB.QueryEntities(BlockIdentifiers.OWNED_BLOCKS)) + { + res[i] = s.ID; + i++; + } + foreach (ref BlockPortsStruct s in entitiesDB.QueryEntities(BlockIdentifiers.FUNCTIONAL_BLOCK_PARTS)) + { + res[i] = s.ID; + i++; + } + return res; + } + } +} diff --git a/GamecraftModdingAPI/Blocks/Signals.cs b/GamecraftModdingAPI/Blocks/Signals.cs new file mode 100644 index 0000000..c844d3a --- /dev/null +++ b/GamecraftModdingAPI/Blocks/Signals.cs @@ -0,0 +1,183 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +using Svelto.ECS; + +using GamecraftModdingAPI.Utility; + +namespace GamecraftModdingAPI.Blocks +{ + /// + /// [EXPERIMENTAL] Common block signal operations + /// The functionality in this class only works when in a game. + /// + public static class Signals + { + // Signal constants + public static readonly float HIGH = 1.0f; + public static readonly float POSITIVE_HIGH = HIGH; + public static readonly float NEGATIVE_HIGH = -1.0f; + public static readonly float LOW = 0.0f; + + private static SignalEngine signalEngine = new SignalEngine(); + + /// + /// Set the electric block's (first) signal value. + /// + /// The block's id. + /// The signal value (-1 to 1; not enforced). + /// Whether to retrieve input IDs (true) or output IDs (false). + /// Whether the block is in the owned group (true) or functional group (false) + public static void SetSignalByBlock(uint blockID, float signal, bool input = true, bool owned = true) + { + EGID egid = new EGID(blockID, owned ? BlockIdentifiers.OWNED_BLOCKS : BlockIdentifiers.FUNCTIONAL_BLOCK_PARTS); + if (signalEngine.IsInGame && GameState.IsSimulationMode()) + { + signalEngine.SetSignal(egid, signal, out uint _, input); + } + } + + public static void SetSignalByBlock(EGID blockID, float signal, bool input = true) + { + if (signalEngine.IsInGame && GameState.IsSimulationMode()) + { + signalEngine.SetSignal(blockID, signal, out uint _, input); + } + } + + /// + /// Set the signal's value. + /// + /// The channel cluster's id. + /// The signal value (-1 to 1; not enforced). + /// Whether to retrieve input IDs (true) or output IDs (false). + public static void SetSignalByID(uint signalID, float signal, bool input = true) + { + if (signalEngine.IsInGame && GamecraftModdingAPI.Utility.GameState.IsSimulationMode()) + { + signalEngine.SetSignal(signalID, signal, input); + } + } + + /// + /// Add a value to an electric block's signal. + /// + /// The block's id. + /// The signal value to add. + /// Whether to clamp the resulting signal value between -1 and 1. + /// Whether to retrieve input IDs (true) or output IDs (false). + /// Whether the block is in the owned group (true) or functional group (false) + /// The signal's new value. + public static float AddSignalByBlock(uint blockID, float signal, bool clamp = true, bool input = true, bool owned = true) + { + EGID egid = new EGID(blockID, owned ? BlockIdentifiers.OWNED_BLOCKS : BlockIdentifiers.FUNCTIONAL_BLOCK_PARTS); + if (signalEngine.IsInGame && GamecraftModdingAPI.Utility.GameState.IsSimulationMode()) + { + return signalEngine.AddSignal(egid, signal, out uint _, clamp, input); + } + return 0f; + } + + public static float AddSignalByBlock(EGID blockID, float signal, bool clamp = true, bool input = true) + { + if (signalEngine.IsInGame && GamecraftModdingAPI.Utility.GameState.IsSimulationMode()) + { + return signalEngine.AddSignal(blockID, signal, out uint _, clamp, input); + } + return 0f; + } + + /// + /// Add a value to a conductive cluster channel. + /// + /// The channel cluster's id. + /// The signal value to add. + /// Whether to clamp the resulting signal value between -1 and 1. + /// Whether to retrieve input IDs (true) or output IDs (false). + /// The signal's new value. + public static float AddSignalByID(uint signalID, float signal, bool clamp = true, bool input = true) + { + if (signalEngine.IsInGame && GamecraftModdingAPI.Utility.GameState.IsSimulationMode()) + { + return signalEngine.AddSignal(signalID, signal, clamp, input); + } + return 0f; + } + + /// + /// Get a electric block's signal's (first) value. + /// + /// The block's id. + /// Whether to retrieve input IDs (true) or output IDs (false). + /// Whether the block is in the owned group (true) or functional group (false) + /// The signal's value. + public static float GetSignalByBlock(uint blockID, bool input = true, bool owned = true) + { + EGID egid = new EGID(blockID, owned? BlockIdentifiers.OWNED_BLOCKS : BlockIdentifiers.FUNCTIONAL_BLOCK_PARTS); + if (signalEngine.IsInGame && GamecraftModdingAPI.Utility.GameState.IsSimulationMode()) + { + return signalEngine.GetSignal(egid, out uint _, input); + } + return 0f; + } + + public static float GetSignalByBlock(EGID blockID, bool input = true) + { + if (signalEngine.IsInGame && GamecraftModdingAPI.Utility.GameState.IsSimulationMode()) + { + return signalEngine.GetSignal(blockID, out uint _, input); + } + return 0f; + } + + /// + /// Get a signal's value. + /// + /// The signal's id. + /// Whether to retrieve input IDs (true) or output IDs (false). + /// The signal's value. + public static float GetSignalByID(uint signalID, bool input = true) + { + if (signalEngine.IsInGame && GamecraftModdingAPI.Utility.GameState.IsSimulationMode()) + { + return signalEngine.GetSignal(signalID, input); + } + return 0f; + } + + /// + /// Get the ID of every electric block in the game world. + /// + /// The block IDs. + public static EGID[] GetElectricBlocks() + { + return signalEngine.GetElectricBlocks(); + } + + /// + /// Get the unique identifiers for the input wires connected to an electric block. + /// + /// The block's id. + /// Whether to retrieve input IDs (true) or output IDs (false). + /// Whether the block is in the owned group (true) or functional group (false) + /// The unique IDs. + public static uint[] GetSignalIDs(uint blockID, bool input = true, bool owned = true) + { + EGID egid = new EGID(blockID, owned ? BlockIdentifiers.OWNED_BLOCKS : BlockIdentifiers.FUNCTIONAL_BLOCK_PARTS); + return signalEngine.GetSignalIDs(egid, input); + } + + public static uint[] GetSignalIDs(EGID blockID, bool input = true, bool owned = true) + { + return signalEngine.GetSignalIDs(blockID, input); + } + + public static void Init() + { + GameEngineManager.AddGameEngine(signalEngine); + } + } +} diff --git a/GamecraftModdingAPI/Blocks/Tweakable.cs b/GamecraftModdingAPI/Blocks/Tweakable.cs new file mode 100644 index 0000000..920bbb6 --- /dev/null +++ b/GamecraftModdingAPI/Blocks/Tweakable.cs @@ -0,0 +1,102 @@ +using System; + +using Svelto.ECS; + +namespace GamecraftModdingAPI.Blocks +{ + /// + /// Common tweakable stats operations. + /// The functionality of this class works best in build mode. + /// + public static class Tweakable + { + private static TweakableEngine tweakableEngine = new TweakableEngine(); + + /// + /// Get the tweakable stat's value using a dynamic variable type. + /// This is similar to GetStat but without strong type enforcement. + /// This should be used in dynamically-typed languages like Python. + /// + /// The stat's value. + /// The block's id. + /// The stat's enumerated id. + public static dynamic GetStatD(uint blockID, TweakableStat stat) + { + return tweakableEngine.GetStatDynamic(blockID, stat); + } + + /// + /// Get the tweakable stat's value. + /// If T is not the same type as the stat, an InvalidCastException will be thrown. + /// + /// The stat's value. + /// The block's id. + /// The stat's enumerated id. + /// The stat's type. + public static T GetStat(uint blockID, TweakableStat stat) + { + return tweakableEngine.GetStatAny(blockID, stat); + } + + /// + /// Set the tweakable stat's value using dynamically-typed variables. + /// This is similar to SetStat but without strong type enforcement. + /// This should be used in dynamically-typed languages like Python. + /// + /// The stat's new value. + /// The block's id. + /// The stat's enumerated id. + /// The stat's new value. + public static dynamic SetStatD(uint blockID, TweakableStat stat, dynamic value) + { + return tweakableEngine.SetStatDynamic(blockID, stat, value); + } + + /// + /// Set the tweakable stat's value. + /// If T is not the stat's actual type, an InvalidCastException will be thrown. + /// + /// The stat's new value. + /// The block's id. + /// The stat's enumerated id. + /// The stat's new value. + /// The stat's type. + public static T SetStat(uint blockID, TweakableStat stat, T value) + { + return tweakableEngine.SetStatAny(blockID, stat, value); + } + + /// + /// Add another value to the tweakable stat's value using dynamically-typed variables. + /// This is similar to AddStat but without strong type enforcement. + /// This should be used in dynamically-typed languages like Python. + /// + /// The stat's new value. + /// The block's id. + /// The stat's enumerated id. + /// The value to be added to the stat. + public static dynamic AddStatD(uint blockID, TweakableStat stat, dynamic value) + { + return tweakableEngine.AddStatDynamic(blockID, stat, value); + } + + /// + /// Add another value to the tweakable stat's value. + /// If T is not the stat's actual type, an InvalidCastException will be thrown. + /// + /// The stat's new value. + /// The block's id. + /// The stat's enumerated id. + /// The value to be added to the stat. + /// The stat's type. + public static T AddStat(uint blockID, TweakableStat stat, T value) + { + return tweakableEngine.AddStatAny(blockID, stat, value); + } + + public static void Init() + { + GamecraftModdingAPI.Utility.GameEngineManager.AddGameEngine(tweakableEngine); + } + } +} diff --git a/GamecraftModdingAPI/Blocks/TweakableEngine.cs b/GamecraftModdingAPI/Blocks/TweakableEngine.cs new file mode 100644 index 0000000..1d029ee --- /dev/null +++ b/GamecraftModdingAPI/Blocks/TweakableEngine.cs @@ -0,0 +1,452 @@ +using System; +using System.Reflection; + +using RobocraftX.Blocks; +using Gamecraft.Wires; + +using GamecraftModdingAPI.Utility; +using Svelto.ECS; + +namespace GamecraftModdingAPI.Blocks +{ + public class TweakableEngine : IApiEngine + { + public string Name { get; } = "GamecraftModdingAPITweakableGameEngine"; + + public EntitiesDB entitiesDB { set; private get; } + + public bool IsInGame = false; + + public void Dispose() + { + IsInGame = false; + } + + public void Ready() + { + IsInGame = true; + } + + // Implementations for Tweakable static class + + public T GetStatAny(EGID blockID, TweakableStat stat) + { + switch (stat) + { + case TweakableStat.TopSpeed: + if (entitiesDB.Exists(blockID)) + { + return (T)(object)entitiesDB.QueryEntity(blockID).maxVelocity; + } + break; + case TweakableStat.Torque: + if (entitiesDB.Exists(blockID)) + { + return (T)(object)entitiesDB.QueryEntity(blockID).maxForce; + } + break; + case TweakableStat.MaxExtension: + if (entitiesDB.Exists(blockID)) + { + return (T)(object)entitiesDB.QueryEntity(blockID).maxDeviation; + } + break; + case TweakableStat.MinAngle: + if (entitiesDB.Exists(blockID)) + { + return (T)(object)entitiesDB.QueryEntity(blockID).minDeviation; + } + break; + case TweakableStat.MaxAngle: + if (entitiesDB.Exists(blockID)) + { + return (T)(object)entitiesDB.QueryEntity(blockID).maxDeviation; + } + break; + case TweakableStat.Reverse: + if (entitiesDB.Exists(blockID)) + { + return (T)(object)entitiesDB.QueryEntity(blockID).reverse; + } + else if (entitiesDB.Exists(blockID)) + { + return (T)(object)entitiesDB.QueryEntity(blockID).reverse; + } + break; + case TweakableStat.StartValue: + if (entitiesDB.Exists(blockID)) + { + return (T)(object)entitiesDB.QueryEntity(blockID).startValue; + } + break; + } + return default(T); + } + + public T GetStatAny(uint blockID, TweakableStat stat) + { + return GetStatAny(new EGID(blockID, BlockIdentifiers.OWNED_BLOCKS), stat); + } + + public dynamic GetStatDynamic(EGID blockID, TweakableStat stat) + { + switch (stat) + { + case TweakableStat.TopSpeed: + if (entitiesDB.Exists(blockID)) + { + return entitiesDB.QueryEntity(blockID).maxVelocity; + } + break; + case TweakableStat.Torque: + if (entitiesDB.Exists(blockID)) + { + return entitiesDB.QueryEntity(blockID).maxForce; + } + break; + case TweakableStat.MaxExtension: + if (entitiesDB.Exists(blockID)) + { + return entitiesDB.QueryEntity(blockID).maxDeviation; + } + break; + case TweakableStat.MinAngle: + if (entitiesDB.Exists(blockID)) + { + return entitiesDB.QueryEntity(blockID).minDeviation; + } + break; + case TweakableStat.MaxAngle: + if (entitiesDB.Exists(blockID)) + { + return entitiesDB.QueryEntity(blockID).maxDeviation; + } + break; + case TweakableStat.Reverse: + if (entitiesDB.Exists(blockID)) + { + return entitiesDB.QueryEntity(blockID).reverse; + } + else if (entitiesDB.Exists(blockID)) + { + return entitiesDB.QueryEntity(blockID).reverse; + } + break; + case TweakableStat.StartValue: + if (entitiesDB.Exists(blockID)) + { + return entitiesDB.QueryEntity(blockID).startValue; + } + break; + } + return null; + } + + public dynamic GetStatDynamic(uint blockID, TweakableStat stat) + { + return GetStatDynamic(new EGID(blockID, BlockIdentifiers.OWNED_BLOCKS), stat); + } + + public T SetStatAny(EGID blockID, TweakableStat stat, T value) + { + switch (stat) + { + case TweakableStat.TopSpeed: + if (entitiesDB.Exists(blockID)) + { + ref MotorReadOnlyStruct refStruct = ref entitiesDB.QueryEntity(blockID); + refStruct.maxVelocity = (float)(object)value; + return (T)(object)refStruct.maxVelocity; + } + break; + case TweakableStat.Torque: + if (entitiesDB.Exists(blockID)) + { + ref MotorReadOnlyStruct refStruct = ref entitiesDB.QueryEntity(blockID); + refStruct.maxForce = (float)(object)value; + return (T)(object)refStruct.maxForce; + } + break; + case TweakableStat.MaxExtension: + if (entitiesDB.Exists(blockID)) + { + ref PistonReadOnlyStruct refStruct = ref entitiesDB.QueryEntity(blockID); + refStruct.maxDeviation = (float)(object)value; + return (T)(object)refStruct.maxDeviation; + } + break; + case TweakableStat.MinAngle: + if (entitiesDB.Exists(blockID)) + { + ref ServoReadOnlyStruct refStruct = ref entitiesDB.QueryEntity(blockID); + refStruct.minDeviation = (float)(object)value; + return (T)(object)refStruct.minDeviation; + } + break; + case TweakableStat.MaxAngle: + if (entitiesDB.Exists(blockID)) + { + ref ServoReadOnlyStruct refStruct = ref entitiesDB.QueryEntity(blockID); + refStruct.maxDeviation = (float)(object)value; + return (T)(object)refStruct.maxDeviation; + } + break; + case TweakableStat.Reverse: + if (entitiesDB.Exists(blockID)) + { + ref MotorReadOnlyStruct refStruct = ref entitiesDB.QueryEntity(blockID); + refStruct.reverse = (bool)(object)value; + return (T)(object)refStruct.reverse; + } + else if (entitiesDB.Exists(blockID)) + { + ref ServoReadOnlyStruct refStruct = ref entitiesDB.QueryEntity(blockID); + refStruct.reverse = (bool)(object)value; + return (T)(object)refStruct.reverse; + } + break; + case TweakableStat.StartValue: + if (entitiesDB.Exists(blockID)) + { + ref SignalGeneratorEntityStruct refStruct = ref entitiesDB.QueryEntity(blockID); + refStruct.startValue = (float)(object)value; + return (T)(object)refStruct.startValue; + } + break; + } + return default(T); + } + + public T SetStatAny(uint blockID, TweakableStat stat, T value) + { + return SetStatAny(new EGID(blockID, BlockIdentifiers.OWNED_BLOCKS), stat, value); + } + + public dynamic SetStatDynamic(EGID blockID, TweakableStat stat, dynamic value) + { + switch (stat) + { + case TweakableStat.TopSpeed: + if (entitiesDB.Exists(blockID)) + { + ref MotorReadOnlyStruct refStruct = ref entitiesDB.QueryEntity(blockID); + refStruct.maxVelocity = value; + return refStruct.maxVelocity; + } + break; + case TweakableStat.Torque: + if (entitiesDB.Exists(blockID)) + { + ref MotorReadOnlyStruct refStruct = ref entitiesDB.QueryEntity(blockID); + refStruct.maxForce = value; + return refStruct.maxForce; + } + break; + case TweakableStat.MaxExtension: + if (entitiesDB.Exists(blockID)) + { + ref PistonReadOnlyStruct refStruct = ref entitiesDB.QueryEntity(blockID); + refStruct.maxDeviation = value; + return refStruct.maxDeviation; + } + break; + case TweakableStat.MinAngle: + if (entitiesDB.Exists(blockID)) + { + ref ServoReadOnlyStruct refStruct = ref entitiesDB.QueryEntity(blockID); + refStruct.minDeviation = value; + return refStruct.minDeviation; + } + break; + case TweakableStat.MaxAngle: + if (entitiesDB.Exists(blockID)) + { + ref ServoReadOnlyStruct refStruct = ref entitiesDB.QueryEntity(blockID); + refStruct.maxDeviation = value; + return refStruct.maxDeviation; + } + break; + case TweakableStat.Reverse: + if (entitiesDB.Exists(blockID)) + { + ref MotorReadOnlyStruct refStruct = ref entitiesDB.QueryEntity(blockID); + refStruct.reverse = value; + return refStruct.reverse; + } + else if (entitiesDB.Exists(blockID)) + { + ref ServoReadOnlyStruct refStruct = ref entitiesDB.QueryEntity(blockID); + refStruct.reverse = value; + return refStruct.reverse; + } + break; + case TweakableStat.StartValue: + if (entitiesDB.Exists(blockID)) + { + ref SignalGeneratorEntityStruct refStruct = ref entitiesDB.QueryEntity(blockID); + refStruct.startValue = value; + return refStruct.startValue; + } + break; + } + return null; + } + + public dynamic SetStatDynamic(uint blockID, TweakableStat stat, dynamic value) + { + return SetStatDynamic(new EGID(blockID, BlockIdentifiers.OWNED_BLOCKS), stat, value); + } + + public T AddStatAny(EGID blockID, TweakableStat stat, T value) + { + switch (stat) + { + case TweakableStat.TopSpeed: + if (entitiesDB.Exists(blockID)) + { + ref MotorReadOnlyStruct refStruct = ref entitiesDB.QueryEntity(blockID); + refStruct.maxVelocity += (float)(object)value; + return (T)(object)refStruct.maxVelocity; + } + break; + case TweakableStat.Torque: + if (entitiesDB.Exists(blockID)) + { + ref MotorReadOnlyStruct refStruct = ref entitiesDB.QueryEntity(blockID); + refStruct.maxForce += (float)(object)value; + return (T)(object)refStruct.maxForce; + } + break; + case TweakableStat.MaxExtension: + if (entitiesDB.Exists(blockID)) + { + ref PistonReadOnlyStruct refStruct = ref entitiesDB.QueryEntity(blockID); + refStruct.maxDeviation += (float)(object)value; + return (T)(object)refStruct.maxDeviation; + } + break; + case TweakableStat.MinAngle: + if (entitiesDB.Exists(blockID)) + { + ref ServoReadOnlyStruct refStruct = ref entitiesDB.QueryEntity(blockID); + refStruct.minDeviation += (float)(object)value; + return (T)(object)refStruct.minDeviation; + } + break; + case TweakableStat.MaxAngle: + if (entitiesDB.Exists(blockID)) + { + ref ServoReadOnlyStruct refStruct = ref entitiesDB.QueryEntity(blockID); + refStruct.maxDeviation += (float)(object)value; + return (T)(object)refStruct.maxDeviation; + } + break; + case TweakableStat.Reverse: + // '+' is associated with logical OR in some fields, so it technically isn't invalid to "add" booleans + if (entitiesDB.Exists(blockID)) + { + ref MotorReadOnlyStruct refStruct = ref entitiesDB.QueryEntity(blockID); + refStruct.reverse = refStruct.reverse || (bool)(object)value; + return (T)(object)refStruct.reverse; + } + else if (entitiesDB.Exists(blockID)) + { + ref ServoReadOnlyStruct refStruct = ref entitiesDB.QueryEntity(blockID); + refStruct.reverse = refStruct.reverse || (bool)(object)value; + return (T)(object)refStruct.reverse; + } + break; + case TweakableStat.StartValue: + if (entitiesDB.Exists(blockID)) + { + ref SignalGeneratorEntityStruct refStruct = ref entitiesDB.QueryEntity(blockID); + refStruct.startValue += (float)(object)value; + return (T)(object)refStruct.startValue; + } + break; + } + return default(T); + } + + public T AddStatAny(uint blockID, TweakableStat stat, T value) + { + return AddStatAny(new EGID(blockID, BlockIdentifiers.OWNED_BLOCKS), stat, value); + } + + public dynamic AddStatDynamic(EGID blockID, TweakableStat stat, dynamic value) + { + switch (stat) + { + case TweakableStat.TopSpeed: + if (entitiesDB.Exists(blockID)) + { + ref MotorReadOnlyStruct refStruct = ref entitiesDB.QueryEntity(blockID); + refStruct.maxVelocity += value; + return refStruct.maxVelocity; + } + break; + case TweakableStat.Torque: + if (entitiesDB.Exists(blockID)) + { + ref MotorReadOnlyStruct refStruct = ref entitiesDB.QueryEntity(blockID); + refStruct.maxForce += value; + return refStruct.maxForce; + } + break; + case TweakableStat.MaxExtension: + if (entitiesDB.Exists(blockID)) + { + ref PistonReadOnlyStruct refStruct = ref entitiesDB.QueryEntity(blockID); + refStruct.maxDeviation += value; + return refStruct.maxDeviation; + } + break; + case TweakableStat.MinAngle: + if (entitiesDB.Exists(blockID)) + { + ref ServoReadOnlyStruct refStruct = ref entitiesDB.QueryEntity(blockID); + refStruct.minDeviation += value; + return refStruct.minDeviation; + } + break; + case TweakableStat.MaxAngle: + if (entitiesDB.Exists(blockID)) + { + ref ServoReadOnlyStruct refStruct = ref entitiesDB.QueryEntity(blockID); + refStruct.maxDeviation += value; + return refStruct.maxDeviation; + } + break; + case TweakableStat.Reverse: + // '+' is associated with logical OR in some fields, so it technically isn't invalid to "add" booleans + if (entitiesDB.Exists(blockID)) + { + ref MotorReadOnlyStruct refStruct = ref entitiesDB.QueryEntity(blockID); + refStruct.reverse = refStruct.reverse || value; + return refStruct.reverse; + } + else if (entitiesDB.Exists(blockID)) + { + ref ServoReadOnlyStruct refStruct = ref entitiesDB.QueryEntity(blockID); + refStruct.reverse = refStruct.reverse || value; + return refStruct.reverse; + } + break; + case TweakableStat.StartValue: + if (entitiesDB.Exists(blockID)) + { + ref SignalGeneratorEntityStruct refStruct = ref entitiesDB.QueryEntity(blockID); + refStruct.startValue += value; + return refStruct.startValue; + } + break; + } + return null; + } + + public dynamic AddStatDynamic(uint blockID, TweakableStat stat, dynamic value) + { + return AddStatDynamic(new EGID(blockID, BlockIdentifiers.OWNED_BLOCKS), stat, value); + } + } +} diff --git a/GamecraftModdingAPI/Blocks/TweakableStat.cs b/GamecraftModdingAPI/Blocks/TweakableStat.cs new file mode 100644 index 0000000..18f5bad --- /dev/null +++ b/GamecraftModdingAPI/Blocks/TweakableStat.cs @@ -0,0 +1,14 @@ +using System; +namespace GamecraftModdingAPI.Blocks +{ + public enum TweakableStat + { + TopSpeed, // MotorReadOnlyStruct + Torque, // MotorReadOnlyStruct + MaxExtension, // PistonReadOnlyStruct + MinAngle, // ServoReadOnlyStruct + MaxAngle, // ServoReadOnlyStruct + Reverse, // MotorReadOnlyStruct or ServoReadOnlyStruct + StartValue, // SignalGeneratorEntityStruct + } +} diff --git a/TechbloxModdingAPI/Commands/CommandEngineFactory.cs b/GamecraftModdingAPI/Commands/CommandEngineFactory.cs similarity index 88% rename from TechbloxModdingAPI/Commands/CommandEngineFactory.cs rename to GamecraftModdingAPI/Commands/CommandEngineFactory.cs index 07e9a67..ddcdcb8 100644 --- a/TechbloxModdingAPI/Commands/CommandEngineFactory.cs +++ b/GamecraftModdingAPI/Commands/CommandEngineFactory.cs @@ -4,7 +4,7 @@ using System.Linq; using System.Text; using System.Threading.Tasks; -namespace TechbloxModdingAPI.Commands +namespace GamecraftModdingAPI.Commands { /// /// UNIMPLEMENTED! diff --git a/TechbloxModdingAPI/Commands/CommandManager.cs b/GamecraftModdingAPI/Commands/CommandManager.cs similarity index 90% rename from TechbloxModdingAPI/Commands/CommandManager.cs rename to GamecraftModdingAPI/Commands/CommandManager.cs index e275ace..f2f79b4 100644 --- a/TechbloxModdingAPI/Commands/CommandManager.cs +++ b/GamecraftModdingAPI/Commands/CommandManager.cs @@ -5,9 +5,10 @@ using System.Text; using System.Threading.Tasks; using Svelto.ECS; -using TechbloxModdingAPI.Utility; -namespace TechbloxModdingAPI.Commands +using GamecraftModdingAPI.Utility; + +namespace GamecraftModdingAPI.Commands { /// /// Keeps track of custom commands @@ -21,10 +22,6 @@ namespace TechbloxModdingAPI.Commands public static void AddCommand(ICustomCommandEngine engine) { - if (ExistsCommand(engine)) - { - throw new CommandAlreadyExistsException($"Command {engine.Name} already exists"); - } _customCommands[engine.Name] = engine; if (_lastEngineRoot != null) { diff --git a/GamecraftModdingAPI/Commands/CommandPatch.cs b/GamecraftModdingAPI/Commands/CommandPatch.cs new file mode 100644 index 0000000..a0392ed --- /dev/null +++ b/GamecraftModdingAPI/Commands/CommandPatch.cs @@ -0,0 +1,42 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Reflection; + +using Harmony; +using Svelto.Context; +using Svelto.ECS; +using RobocraftX; +using RobocraftX.Multiplayer; +using RobocraftX.StateSync; +using Unity.Entities; + +using GamecraftModdingAPI.Utility; + +namespace GamecraftModdingAPI.Commands +{ + /// + /// Patch of RobocraftX.GUI.CommandLine.CommandLineCompositionRoot.Compose() + /// + // TODO: fix + [HarmonyPatch] + //[HarmonyPatch(typeof(RobocraftX.GUI.CommandLine.CommandLineCompositionRoot))] + //[HarmonyPatch("Compose")] + //[HarmonyPatch("Compose", new Type[] { typeof(UnityContext), typeof(EnginesRoot), typeof(World), typeof(Action), typeof(MultiplayerInitParameters), typeof(StateSyncRegistrationHelper)})] + static class CommandPatch + { + public static void Postfix(object contextHolder, EnginesRoot enginesRoot, World physicsWorld, Action reloadGame, MultiplayerInitParameters multiplayerParameters, ref StateSyncRegistrationHelper stateSyncReg) + { + // When a game is loaded, register the command engines + CommandManager.RegisterEngines(enginesRoot); + } + + public static MethodBase TargetMethod(HarmonyInstance instance) + { + return typeof(RobocraftX.GUI.CommandLine.CommandLineCompositionRoot).GetMethod("Compose").MakeGenericMethod(typeof(object)); + //return func.Method; + } + } +} diff --git a/TechbloxModdingAPI/Commands/CommandRegistrationHelper.cs b/GamecraftModdingAPI/Commands/CommandRegistrationHelper.cs similarity index 61% rename from TechbloxModdingAPI/Commands/CommandRegistrationHelper.cs rename to GamecraftModdingAPI/Commands/CommandRegistrationHelper.cs index e33b232..5cb9069 100644 --- a/TechbloxModdingAPI/Commands/CommandRegistrationHelper.cs +++ b/GamecraftModdingAPI/Commands/CommandRegistrationHelper.cs @@ -4,17 +4,22 @@ using System.Linq; using System.Text; using System.Threading.Tasks; -namespace TechbloxModdingAPI.Commands +using uREPL; +using RobocraftX.CommandLine.Custom; + +namespace GamecraftModdingAPI.Commands { /// - /// Convenient methods for registering commands to Techblox. + /// Convenient methods for registering commands to Gamecraft. /// All methods register to the command line and console block by default. /// public static class CommandRegistrationHelper { public static void Register(string name, Action action, string desc, bool noConsole = false) { - CustomCommands.Register(name, action, desc); + RuntimeCommands.Register(name, action, desc); + if (noConsole) { return; } + ConsoleCommands.Register(name, action, desc); } public static void Register(string name, Action action, string desc, bool noConsole = false) @@ -34,42 +39,50 @@ namespace TechbloxModdingAPI.Commands public static void Register(string name, Action action, string desc, bool noConsole = false) { - CustomCommands.Register(name, action, desc); + RuntimeCommands.Register(name, action, desc); + if (noConsole) { return; } + ConsoleCommands.Register(name, action, desc); } public static void Register(string name, Action action, string desc, bool noConsole = false) { - CustomCommands.Register(name, action, desc); + RuntimeCommands.Register(name, action, desc); + if (noConsole) { return; } + ConsoleCommands.Register(name, action, desc); } public static void Register(string name, Action action, string desc, bool noConsole = false) { - CustomCommands.Register(name, action, desc); + RuntimeCommands.Register(name, action, desc); + if (noConsole) { return; } + ConsoleCommands.Register(name, action, desc); } public static void Unregister(string name, bool noConsole = false) { - CustomCommands.Unregister(name); + RuntimeCommands.Unregister(name); + if (noConsole) { return; } + ConsoleCommands.Unregister(name); } public static void Call(string name) { - CustomCommands.Call(name); + RuntimeCommands.Call(name); } public static void Call(string name, Param0 param0) { - CustomCommands.Call(name, param0); + RuntimeCommands.Call(name, param0); } public static void Call(string name, Param0 param0, Param1 param1) { - CustomCommands.Call(name, param0, param1); + RuntimeCommands.Call(name, param0, param1); } public static void Call(string name, Param0 param0, Param1 param1, Param2 param2) { - CustomCommands.Call(name, param0, param1, param2); + RuntimeCommands.Call(name, param0, param1, param2); } } } diff --git a/GamecraftModdingAPI/Commands/ExistingCommands.cs b/GamecraftModdingAPI/Commands/ExistingCommands.cs new file mode 100644 index 0000000..60bd900 --- /dev/null +++ b/GamecraftModdingAPI/Commands/ExistingCommands.cs @@ -0,0 +1,42 @@ +using System; + +using uREPL; + +namespace GamecraftModdingAPI.Commands +{ + public static class ExistingCommands + { + public static void Call(string commandName) + { + RuntimeCommands.Call(commandName); + } + + public static void Call(string commandName, Arg0 arg0) + { + RuntimeCommands.Call(commandName, arg0); + } + + public static void Call(string commandName, Arg0 arg0, Arg1 arg1) + { + RuntimeCommands.Call(commandName, arg0, arg1); + } + + public static void Call(string commandName, Arg0 arg0, Arg1 arg1, Arg2 arg2) + { + RuntimeCommands.Call(commandName, arg0, arg1, arg2); + } + + public static bool Exists(string commandName) + { + return RuntimeCommands.HasRegistered(commandName); + } + + public static string[] GetCommandNames() + { + var keys = RuntimeCommands.table.Keys; + string[] res = new string[keys.Count]; + keys.CopyTo(res, 0); + return res; + } + } +} diff --git a/TechbloxModdingAPI/Commands/ICustomCommandEngine.cs b/GamecraftModdingAPI/Commands/ICustomCommandEngine.cs similarity index 52% rename from TechbloxModdingAPI/Commands/ICustomCommandEngine.cs rename to GamecraftModdingAPI/Commands/ICustomCommandEngine.cs index afb0237..b971390 100644 --- a/TechbloxModdingAPI/Commands/ICustomCommandEngine.cs +++ b/GamecraftModdingAPI/Commands/ICustomCommandEngine.cs @@ -6,15 +6,12 @@ using System.Threading.Tasks; using Svelto.ECS; -using TechbloxModdingAPI.Utility; -using TechbloxModdingAPI.Engines; +using GamecraftModdingAPI.Utility; -namespace TechbloxModdingAPI.Commands +namespace GamecraftModdingAPI.Commands { /// - /// Engine interface to handle command operations. - /// If you are using implementing this yourself, you must manually register the command. - /// See SimpleCustomCommandEngine's Ready() and Dispose() methods for an example of command registration. + /// Engine interface to handle command operations /// public interface ICustomCommandEngine : IApiEngine { diff --git a/TechbloxModdingAPI/Commands/SimpleCustomCommandEngine.cs b/GamecraftModdingAPI/Commands/SimpleCustomCommandEngine.cs similarity index 65% rename from TechbloxModdingAPI/Commands/SimpleCustomCommandEngine.cs rename to GamecraftModdingAPI/Commands/SimpleCustomCommandEngine.cs index 87e0960..e5ea499 100644 --- a/TechbloxModdingAPI/Commands/SimpleCustomCommandEngine.cs +++ b/GamecraftModdingAPI/Commands/SimpleCustomCommandEngine.cs @@ -5,9 +5,8 @@ using System.Text; using System.Threading.Tasks; using Svelto.ECS; -using TechbloxModdingAPI.Utility; -namespace TechbloxModdingAPI.Commands +namespace GamecraftModdingAPI.Commands { /// /// A simple implementation of ICustomCommandEngine sufficient for most commands. @@ -32,18 +31,16 @@ namespace TechbloxModdingAPI.Commands public EntitiesDB entitiesDB { set; private get; } - public bool isRemovable => true; - - public void Dispose() + public void Dispose() { - Logging.MetaDebugLog($"Unregistering SimpleCustomCommandEngine {this.Name}"); + GamecraftModdingAPI.Utility.Logging.MetaDebugLog($"Unregistering SimpleCustomCommandEngine {this.Name}"); CommandRegistrationHelper.Unregister(this.Name); } public void Ready() { - Logging.MetaDebugLog($"Registering SimpleCustomCommandEngine {this.Name}"); - CommandRegistrationHelper.Register(this.Name, this.InvokeCatchError, this.Description); + GamecraftModdingAPI.Utility.Logging.MetaDebugLog($"Registering SimpleCustomCommandEngine {this.Name}"); + CommandRegistrationHelper.Register(this.Name, this.runCommand, this.Description); } /// @@ -58,24 +55,5 @@ namespace TechbloxModdingAPI.Commands this.Name = name; this.Description = description; } - - public void Invoke() - { - runCommand(); - } - - private void InvokeCatchError() - { - try - { - runCommand(); - } - catch (Exception e) - { - CommandRuntimeException wrappedException = new CommandRuntimeException($"Command {Name} threw an exception when executed", e); - Logging.LogWarning(wrappedException.ToString()); - Logging.CommandLogError(wrappedException.ToString()); - } - } } } diff --git a/TechbloxModdingAPI/Commands/SimpleCustomCommandEngine1.cs b/GamecraftModdingAPI/Commands/SimpleCustomCommandEngine1.cs similarity index 57% rename from TechbloxModdingAPI/Commands/SimpleCustomCommandEngine1.cs rename to GamecraftModdingAPI/Commands/SimpleCustomCommandEngine1.cs index ef3bb02..4ec5949 100644 --- a/TechbloxModdingAPI/Commands/SimpleCustomCommandEngine1.cs +++ b/GamecraftModdingAPI/Commands/SimpleCustomCommandEngine1.cs @@ -5,9 +5,8 @@ using System.Text; using System.Threading.Tasks; using Svelto.ECS; -using TechbloxModdingAPI.Utility; -namespace TechbloxModdingAPI.Commands +namespace GamecraftModdingAPI.Commands { /// /// A simple implementation of ICustomCommandEngine sufficient for most commands. @@ -23,18 +22,16 @@ namespace TechbloxModdingAPI.Commands public EntitiesDB entitiesDB { set; private get; } - public bool isRemovable => true; - - public void Dispose() + public void Dispose() { - Logging.MetaDebugLog($"Unregistering SimpleCustomCommandEngine {this.Name}"); + GamecraftModdingAPI.Utility.Logging.MetaDebugLog($"Unregistering SimpleCustomCommandEngine {this.Name}"); CommandRegistrationHelper.Unregister(this.Name); } public void Ready() { - Logging.MetaDebugLog($"Registering SimpleCustomCommandEngine {this.Name}"); - CommandRegistrationHelper.Register(this.Name, this.InvokeCatchError, this.Description); + GamecraftModdingAPI.Utility.Logging.MetaDebugLog($"Registering SimpleCustomCommandEngine {this.Name}"); + CommandRegistrationHelper.Register(this.Name, this.runCommand, this.Description); } /// @@ -48,25 +45,6 @@ namespace TechbloxModdingAPI.Commands this.runCommand = command; this.Name = name; this.Description = description; - } - - public void Invoke(A a) - { - runCommand(a); - } - - private void InvokeCatchError(A a) - { - try - { - runCommand(a); - } - catch (Exception e) - { - CommandRuntimeException wrappedException = new CommandRuntimeException($"Command {Name} threw an exception when executed", e); - Logging.LogWarning(wrappedException.ToString()); - Logging.CommandLogError(wrappedException.ToString()); - } } } } diff --git a/TechbloxModdingAPI/Commands/SimpleCustomCommandEngine2.cs b/GamecraftModdingAPI/Commands/SimpleCustomCommandEngine2.cs similarity index 56% rename from TechbloxModdingAPI/Commands/SimpleCustomCommandEngine2.cs rename to GamecraftModdingAPI/Commands/SimpleCustomCommandEngine2.cs index 8127861..2aa81a3 100644 --- a/TechbloxModdingAPI/Commands/SimpleCustomCommandEngine2.cs +++ b/GamecraftModdingAPI/Commands/SimpleCustomCommandEngine2.cs @@ -5,9 +5,8 @@ using System.Text; using System.Threading.Tasks; using Svelto.ECS; -using TechbloxModdingAPI.Utility; -namespace TechbloxModdingAPI.Commands +namespace GamecraftModdingAPI.Commands { /// /// A simple implementation of ICustomCommandEngine sufficient for most commands. @@ -23,18 +22,16 @@ namespace TechbloxModdingAPI.Commands public EntitiesDB entitiesDB { set; private get; } - public bool isRemovable => true; - - public void Dispose() + public void Dispose() { - Logging.MetaDebugLog($"Unregistering SimpleCustomCommandEngine {this.Name}"); + GamecraftModdingAPI.Utility.Logging.MetaDebugLog($"Unregistering SimpleCustomCommandEngine {this.Name}"); CommandRegistrationHelper.Unregister(this.Name); } public void Ready() { - Logging.MetaDebugLog($"Registering SimpleCustomCommandEngine {this.Name}"); - CommandRegistrationHelper.Register(this.Name, this.InvokeCatchError, this.Description); + GamecraftModdingAPI.Utility.Logging.MetaDebugLog($"Registering SimpleCustomCommandEngine {this.Name}"); + CommandRegistrationHelper.Register(this.Name, this.runCommand, this.Description); } /// @@ -48,25 +45,6 @@ namespace TechbloxModdingAPI.Commands this.runCommand = command; this.Name = name; this.Description = description; - } - - public void Invoke(A a, B b) - { - runCommand(a, b); - } - - private void InvokeCatchError(A a, B b) - { - try - { - runCommand(a, b); - } - catch (Exception e) - { - CommandRuntimeException wrappedException = new CommandRuntimeException($"Command {Name} threw an exception when executed", e); - Logging.LogWarning(wrappedException.ToString()); - Logging.CommandLogError(wrappedException.ToString()); - } } } } diff --git a/TechbloxModdingAPI/Commands/SimpleCustomCommandEngine3.cs b/GamecraftModdingAPI/Commands/SimpleCustomCommandEngine3.cs similarity index 56% rename from TechbloxModdingAPI/Commands/SimpleCustomCommandEngine3.cs rename to GamecraftModdingAPI/Commands/SimpleCustomCommandEngine3.cs index 9b2f6b1..5db84c2 100644 --- a/TechbloxModdingAPI/Commands/SimpleCustomCommandEngine3.cs +++ b/GamecraftModdingAPI/Commands/SimpleCustomCommandEngine3.cs @@ -5,9 +5,8 @@ using System.Text; using System.Threading.Tasks; using Svelto.ECS; -using TechbloxModdingAPI.Utility; -namespace TechbloxModdingAPI.Commands +namespace GamecraftModdingAPI.Commands { /// /// A simple implementation of ICustomCommandEngine sufficient for most commands. @@ -23,18 +22,16 @@ namespace TechbloxModdingAPI.Commands public EntitiesDB entitiesDB { set; private get; } - public bool isRemovable => true; - - public void Dispose() + public void Dispose() { - Logging.MetaDebugLog($"Unregistering SimpleCustomCommandEngine {this.Name}"); + GamecraftModdingAPI.Utility.Logging.MetaDebugLog($"Unregistering SimpleCustomCommandEngine {this.Name}"); CommandRegistrationHelper.Unregister(this.Name); } public void Ready() { - Logging.MetaDebugLog($"Registering SimpleCustomCommandEngine {this.Name}"); - CommandRegistrationHelper.Register(this.Name, this.InvokeCatchError, this.Description); + GamecraftModdingAPI.Utility.Logging.MetaDebugLog($"Registering SimpleCustomCommandEngine {this.Name}"); + CommandRegistrationHelper.Register(this.Name, this.runCommand, this.Description); } /// @@ -48,25 +45,6 @@ namespace TechbloxModdingAPI.Commands this.runCommand = command; this.Name = name; this.Description = description; - } - - public void Invoke(A a, B b, C c) - { - runCommand(a, b, c); - } - - private void InvokeCatchError(A a, B b, C c) - { - try - { - runCommand(a, b, c); - } - catch (Exception e) - { - CommandRuntimeException wrappedException = new CommandRuntimeException($"Command {Name} threw an exception when executed", e); - Logging.LogWarning(wrappedException.ToString()); - Logging.CommandLogError(wrappedException.ToString()); - } } } } diff --git a/GamecraftModdingAPI/Events/DeterministicStepComposeEngineGroupsPatch.cs b/GamecraftModdingAPI/Events/DeterministicStepComposeEngineGroupsPatch.cs new file mode 100644 index 0000000..4779869 --- /dev/null +++ b/GamecraftModdingAPI/Events/DeterministicStepComposeEngineGroupsPatch.cs @@ -0,0 +1,46 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Reflection; +using System.Text; +using System.Threading.Tasks; + +using Harmony; +using Svelto.ECS; +using RobocraftX.Common; +using RobocraftX.StateSync; + +using GamecraftModdingAPI.Utility; + +namespace GamecraftModdingAPI.Events +{ + /// + /// Patch of RobocraftX.StateSync.DeterministicStepCompositionRoot.ComposeEnginesGroups(...) + /// + //[HarmonyPatch(typeof(DeterministicStepCompositionRoot), "DeterministicCompose")] + [HarmonyPatch] + class GameHostTransitionDeterministicGroupEnginePatch + { + + public static readonly GameStateBuildEmitterEngine buildEngine = new GameStateBuildEmitterEngine(); + + public static readonly GameStateSimulationEmitterEngine simEngine = new GameStateSimulationEmitterEngine(); + + public static void Postfix() + { + //stateSyncReg.buildModeInitializationEngines.Add(buildEngine); + //stateSyncReg.simulationModeInitializationEngines.Add(simEngine); + //enginesRoot.AddEngine(buildEngine); + //enginesRoot.AddEngine(simEngine); + buildEngine.EmitIfBuildMode(); + simEngine.EmitIfSimMode(); + } + + [HarmonyTargetMethod] + public static MethodBase TargetMethod(HarmonyInstance harmonyInstance) + { + return AccessTools.Method(AccessTools.TypeByName("RobocraftX.StateSync.GameHostTransitionDeterministicGroupEngine"), "EndTransition"); + //.MakeGenericMethod(typeof(CosmeticEnginesSequenceBuildOrder), typeof(CosmeticEnginesSequenceSimOrder), typeof(DeterministicToCosmeticSyncBuildOrder), typeof(DeterministicToCosmeticSyncSimOrder)); + } + } +} diff --git a/GamecraftModdingAPI/Events/EventEngineFactory.cs b/GamecraftModdingAPI/Events/EventEngineFactory.cs new file mode 100644 index 0000000..f79dfca --- /dev/null +++ b/GamecraftModdingAPI/Events/EventEngineFactory.cs @@ -0,0 +1,60 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +using Svelto.ECS; + +namespace GamecraftModdingAPI.Events +{ + /// + /// Convenient factories for mod event engines + /// + public static class EventEngineFactory + { + /// + /// Factory method which automatically adds the SimpleEventHandlerEngine to the Manager + /// + /// The name of the engine + /// The type of event to handle + /// The operation to do when the event is created + /// The operation to do when the event is destroyed (if applicable) + /// The created object + public static SimpleEventHandlerEngine CreateAddSimpleHandler(string name, int type, Action onActivated, Action onDestroyed) + { + var engine = new SimpleEventHandlerEngine(onActivated, onDestroyed, type, name); + EventManager.AddEventHandler(engine); + return engine; + } + + /// + /// Factory method which automatically adds the SimpleEventHandlerEngine to the Manager + /// + /// The name of the engine + /// The type of event to handle + /// The operation to do when the event is created + /// The operation to do when the event is destroyed (if applicable) + /// The created object + public static SimpleEventHandlerEngine CreateAddSimpleHandler(string name, int type, Action onActivated, Action onDestroyed) + { + var engine = new SimpleEventHandlerEngine(onActivated, onDestroyed, type, name); + EventManager.AddEventHandler(engine); + return engine; + } + + /// + /// Factory method which automatically adds the SimpleEventEmitterEngine to the Manager + /// + /// The name of the engine + /// The type of event to emit + /// Will removing this engine not break your code? + /// The created object + public static SimpleEventEmitterEngine CreateAddSimpleEmitter(string name, int type, bool isRemovable = true) + { + var engine = new SimpleEventEmitterEngine(type, name, isRemovable); + EventManager.AddEventEmitter(engine); + return engine; + } + } +} diff --git a/GamecraftModdingAPI/Events/EventManager.cs b/GamecraftModdingAPI/Events/EventManager.cs new file mode 100644 index 0000000..227c7fd --- /dev/null +++ b/GamecraftModdingAPI/Events/EventManager.cs @@ -0,0 +1,120 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +using Svelto.ECS; + +using GamecraftModdingAPI.Utility; + +namespace GamecraftModdingAPI.Events +{ + /// + /// Keeps track of event handlers and emitters. + /// This is used to add, remove and get API event handlers and emitters. + /// + public static class EventManager + { + private static Dictionary _eventEmitters = new Dictionary(); + + private static Dictionary _eventHandlers = new Dictionary(); + + private static EnginesRoot _lastEngineRoot; + + // event handler management + + public static void AddEventHandler(IEventHandlerEngine engine) + { + _eventHandlers[engine.Name] = engine; + if (_lastEngineRoot != null) + { + Logging.MetaDebugLog($"Registering IEventHandlerEngine {engine.Name}"); + _lastEngineRoot.AddEngine(engine); + } + } + + public static bool ExistsEventHandler(string name) + { + return _eventHandlers.ContainsKey(name); + } + + public static bool ExistsEventHandler(IEventHandlerEngine engine) + { + return ExistsEventHandler(engine.Name); + } + + public static IEventHandlerEngine GetEventHandler(string name) + { + return _eventHandlers[name]; + } + + public static string[] GetEventHandlerNames() + { + return _eventHandlers.Keys.ToArray(); + } + + public static void RemoveEventHandler(string name) + { + _eventHandlers.Remove(name); + } + + // event emitter management + + public static void AddEventEmitter(IEventEmitterEngine engine) + { + _eventEmitters[engine.Name] = engine; + if (_lastEngineRoot != null) + { + Logging.MetaDebugLog($"Registering IEventEmitterEngine {engine.Name}"); + _lastEngineRoot.AddEngine(engine); + } + } + + public static bool ExistsEventEmitter(string name) + { + return _eventEmitters.ContainsKey(name); + } + + public static bool ExistsEventEmitter(IEventEmitterEngine engine) + { + return ExistsEventEmitter(engine.Name); + } + + public static IEventEmitterEngine GetEventEmitter(string name) + { + return _eventEmitters[name]; + } + + public static string[] GetEventEmitterNames() + { + return _eventEmitters.Keys.ToArray(); + } + + public static void RemoveEventEmitter(string name) + { + if (_eventEmitters[name].isRemovable) + { + _eventEmitters.Remove(name); + } + } + + public static void RegisterEngines(EnginesRoot enginesRoot) + { + _lastEngineRoot = enginesRoot; + // Register handlers before emitters so no events are missed + var entityFactory = enginesRoot.GenerateEntityFactory(); + foreach (var key in _eventHandlers.Keys) + { + Logging.MetaDebugLog($"Registering IEventHandlerEngine {_eventHandlers[key].Name}"); + enginesRoot.AddEngine(_eventHandlers[key]); + } + foreach (var key in _eventEmitters.Keys) + { + Logging.MetaDebugLog($"Registering IEventEmitterEngine {_eventEmitters[key].Name}"); + _eventEmitters[key].Factory = entityFactory; + enginesRoot.AddEngine(_eventEmitters[key]); + } + } + } +} diff --git a/GamecraftModdingAPI/Events/EventType.cs b/GamecraftModdingAPI/Events/EventType.cs new file mode 100644 index 0000000..468e214 --- /dev/null +++ b/GamecraftModdingAPI/Events/EventType.cs @@ -0,0 +1,24 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace GamecraftModdingAPI.Events +{ + /// + /// Built-in event types. + /// These are configured to fire when the API is initialized. + /// + public enum EventType + { + ApplicationInitialized, + Menu, + MenuSwitchedTo, + Game, + GameReloaded, + GameSwitchedTo, + SimulationSwitchedTo, + BuildSwitchedTo + } +} diff --git a/GamecraftModdingAPI/Events/GameActivatedComposePatch.cs b/GamecraftModdingAPI/Events/GameActivatedComposePatch.cs new file mode 100644 index 0000000..2c16c0c --- /dev/null +++ b/GamecraftModdingAPI/Events/GameActivatedComposePatch.cs @@ -0,0 +1,56 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Reflection; +using System.Text; +using System.Threading.Tasks; + +using Harmony; +using RobocraftX; +using Svelto.ECS; + +using GamecraftModdingAPI.Utility; +using RobocraftX.CR.MainGame; + +namespace GamecraftModdingAPI.Events +{ + /// + /// Patch of RobocraftX.FullGameCompositionRoot.ActivateGame() + /// + [HarmonyPatch] + class GameActivatedComposePatch + { + public static bool IsGameSwitching = false; + + public static bool IsGameReloading = false; + + public static void Postfix(ref object contextHolder, ref EnginesRoot enginesRoot) + { + // register custom game engines + GameEngineManager.RegisterEngines(enginesRoot); + // A new EnginesRoot is always created when ActivateGame is called + // so all event emitters and handlers must be re-registered. + EventManager.RegisterEngines(enginesRoot); + Logging.Log("Dispatching Game Activated event"); + EventManager.GetEventEmitter("GamecraftModdingAPIGameActivatedEventEmitter").Emit(); + if (IsGameSwitching) + { + IsGameSwitching = false; + Logging.Log("Dispatching Game Switched To event"); + EventManager.GetEventEmitter("GamecraftModdingAPIGameSwitchedToEventEmitter").Emit(); + } + if (IsGameReloading) + { + IsGameReloading = false; + Logging.Log("Dispatching Game Reloaded event"); + EventManager.GetEventEmitter("GamecraftModdingAPIGameReloadedEventEmitter").Emit(); + } + } + + public static MethodBase TargetMethod() + { + return typeof(MainGameCompositionRoot).GetMethods().First(m => m.Name == "Compose") + .MakeGenericMethod(typeof(object)); + } + } +} diff --git a/GamecraftModdingAPI/Events/GameReloadedPatch.cs b/GamecraftModdingAPI/Events/GameReloadedPatch.cs new file mode 100644 index 0000000..becd4dc --- /dev/null +++ b/GamecraftModdingAPI/Events/GameReloadedPatch.cs @@ -0,0 +1,25 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +using Harmony; +using RobocraftX; + +using GamecraftModdingAPI.Utility; + +namespace GamecraftModdingAPI.Events +{ + /// + /// Patch of RobocraftX.FullGameCompositionRoot.ReloadGame() + /// + [HarmonyPatch(typeof(FullGameCompositionRoot), "ReloadGame")] + class GameReloadedPatch + { + public static void Postfix() + { + GameActivatedComposePatch.IsGameReloading = true; + } + } +} diff --git a/GamecraftModdingAPI/Events/GameStateBuildEmitterEngine.cs b/GamecraftModdingAPI/Events/GameStateBuildEmitterEngine.cs new file mode 100644 index 0000000..1c5b363 --- /dev/null +++ b/GamecraftModdingAPI/Events/GameStateBuildEmitterEngine.cs @@ -0,0 +1,54 @@ +using System; + +using Unity.Jobs; +using RobocraftX.SimulationModeState; +using RobocraftX.StateSync; +using Svelto.ECS; + +using GamecraftModdingAPI.Utility; + +namespace GamecraftModdingAPI.Events +{ + /// + /// Event emitter engine for switching to to build mode. + /// + public class GameStateBuildEmitterEngine : IEventEmitterEngine, IInitializeOnBuildStart + { + public string Name { get; } = "GamecraftModdingAPIGameStateBuildEventEmitter" ; + + public EntitiesDB entitiesDB { set; private get; } + + public int type { get; } = (int)EventType.BuildSwitchedTo; + + public bool isRemovable { get; } = false; + + public IEntityFactory Factory { set; private get; } + + public void Dispose() { } + + public void Emit() + { + Logging.Log("Dispatching Build Switched To event"); + if (Factory == null) { return; } + Factory.BuildEntity(ApiExclusiveGroups.eventID++, ApiExclusiveGroups.eventsExclusiveGroup) + .Init(new ModEventEntityStruct { type = type }); + } + + public void EmitIfBuildMode() + { + //Logging.MetaDebugLog($"nextSimulationMode: {entitiesDB.QueryUniqueEntity(SimulationModeStateExclusiveGroups.GAME_STATE_GROUP).nextSimulationMode}"); + if (entitiesDB.QueryUniqueEntity(SimulationModeStateExclusiveGroups.GAME_STATE_GROUP).nextSimulationMode == SimulationMode.Build) + { + Emit(); + } + } + + public JobHandle OnInitializeBuildMode() + { + Emit(); + return default(JobHandle); + } + + public void Ready() { } + } +} diff --git a/GamecraftModdingAPI/Events/GameStateSimulationEmitterEngine.cs b/GamecraftModdingAPI/Events/GameStateSimulationEmitterEngine.cs new file mode 100644 index 0000000..91ee596 --- /dev/null +++ b/GamecraftModdingAPI/Events/GameStateSimulationEmitterEngine.cs @@ -0,0 +1,53 @@ +using System; + +using Unity.Jobs; +using RobocraftX.SimulationModeState; +using RobocraftX.StateSync; +using Svelto.ECS; + +using GamecraftModdingAPI.Utility; + +namespace GamecraftModdingAPI.Events +{ + /// + /// Event emitter engine for switching to simulation mode. + /// + public class GameStateSimulationEmitterEngine : IEventEmitterEngine, IInitializeOnSimulationStart + { + public string Name { get; } = "GamecraftModdingAPIGameStateSimulationEventEmitter" ; + + public EntitiesDB entitiesDB { set; private get; } + + public int type { get; } = (int)EventType.SimulationSwitchedTo; + + public bool isRemovable { get; } = false; + + public IEntityFactory Factory { set; private get; } + + public void Dispose() { } + + public void Emit() + { + Logging.Log("Dispatching Simulation Switched To event"); + if (Factory == null) { return; } + Factory.BuildEntity(ApiExclusiveGroups.eventID++, ApiExclusiveGroups.eventsExclusiveGroup) + .Init(new ModEventEntityStruct { type = type }); + } + + public void EmitIfSimMode() + { + if (entitiesDB.QueryUniqueEntity(SimulationModeStateExclusiveGroups.GAME_STATE_GROUP).nextSimulationMode == SimulationMode.Simulation) + { + Emit(); + } + } + + public JobHandle OnInitializeSimulationMode() + { + Emit(); + return default(JobHandle); + } + + public void Ready() { } + } +} diff --git a/GamecraftModdingAPI/Events/GameSwitchedToPatch.cs b/GamecraftModdingAPI/Events/GameSwitchedToPatch.cs new file mode 100644 index 0000000..eae4652 --- /dev/null +++ b/GamecraftModdingAPI/Events/GameSwitchedToPatch.cs @@ -0,0 +1,29 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Reflection; + +using Harmony; +using RobocraftX; +using RobocraftX.CR.MainGame; +using Svelto.ECS; + +using GamecraftModdingAPI.Utility; + +namespace GamecraftModdingAPI.Events +{ + /// + /// Patch of RobocraftX.FullGameCompositionRoot.ActivateGame() + /// (scheduled for execution during RobocraftX.FullGameCompositionRoot.SwitchToGame()) + /// + [HarmonyPatch(typeof(FullGameCompositionRoot), "SwitchToGame")] + class GameSwitchedToPatch + { + public static void Prefix() + { + GameActivatedComposePatch.IsGameSwitching = true; + } + } +} diff --git a/GamecraftModdingAPI/Events/IEventEmitterEngine.cs b/GamecraftModdingAPI/Events/IEventEmitterEngine.cs new file mode 100644 index 0000000..6a303aa --- /dev/null +++ b/GamecraftModdingAPI/Events/IEventEmitterEngine.cs @@ -0,0 +1,40 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +using Svelto.ECS; + +using GamecraftModdingAPI.Utility; + +namespace GamecraftModdingAPI.Events +{ + /// + /// Engine interface to create a ModEventEntityStruct in entitiesDB when Emit() is called. + /// + public interface IEventEmitterEngine : IApiEngine + { + /// + /// The type of event emitted + /// + int type { get; } + + /// + /// Whether the emitter can be removed with Manager.RemoveEventEmitter(name) + /// + bool isRemovable { get; } + + /// + /// The EntityFactory for the entitiesDB. + /// Use this to create a ModEventEntityStruct when Emit() is called. + /// + IEntityFactory Factory { set; } + + /// + /// Emit the event so IEventHandlerEngines can handle it. + /// Call Emit() to trigger the IEventEmitterEngine's event. + /// + void Emit(); + } +} diff --git a/TechbloxModdingAPI/Engines/IReactionaryEngine.cs b/GamecraftModdingAPI/Events/IEventHandlerEngine.cs similarity index 62% rename from TechbloxModdingAPI/Engines/IReactionaryEngine.cs rename to GamecraftModdingAPI/Events/IEventHandlerEngine.cs index 739d626..7f0aa3f 100644 --- a/TechbloxModdingAPI/Engines/IReactionaryEngine.cs +++ b/GamecraftModdingAPI/Events/IEventHandlerEngine.cs @@ -7,14 +7,14 @@ using System.Threading.Tasks; using Svelto.ECS; using Svelto.ECS.Internal; -using TechbloxModdingAPI.Events; +using GamecraftModdingAPI.Utility; -namespace TechbloxModdingAPI.Engines +namespace GamecraftModdingAPI.Events { /// /// Engine interface to handle ModEventEntityStruct events emitted by IEventEmitterEngines. /// - public interface IReactionaryEngine : IApiEngine, IReactOnAddAndRemove where T : unmanaged, IEntityComponent + public interface IEventHandlerEngine : IApiEngine, IReactOnAddAndRemove, IReactOnAddAndRemove { } } diff --git a/GamecraftModdingAPI/Events/MenuActivatedPatch.cs b/GamecraftModdingAPI/Events/MenuActivatedPatch.cs new file mode 100644 index 0000000..451e71e --- /dev/null +++ b/GamecraftModdingAPI/Events/MenuActivatedPatch.cs @@ -0,0 +1,41 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +using Harmony; +using RobocraftX; +using Svelto.ECS; + +using GamecraftModdingAPI.Utility; + +namespace GamecraftModdingAPI.Events +{ + /// + /// Patch of RobocraftX.FullGameCompositionRoot.ActivateMenu() + /// + [HarmonyPatch(typeof(FullGameCompositionRoot), "ActivateMenu")] + class MenuActivatedPatch + { + + private static bool firstLoad = true; + public static void Postfix(ref EnginesRoot ____frontEndEnginesRoot, FullGameCompositionRoot __instance) + { + // register custom menu engines + MenuEngineManager.RegisterEngines(____frontEndEnginesRoot); + // A new EnginesRoot is always created when ActivateMenu is called + // so all event emitters and handlers must be re-registered. + EventManager.RegisterEngines(____frontEndEnginesRoot); + if (firstLoad) + { + firstLoad = false; + FullGameFields.Init(__instance); + Logging.Log("Dispatching App Init event"); + EventManager.GetEventEmitter("GamecraftModdingAPIApplicationInitializedEventEmitter").Emit(); + } + Logging.Log("Dispatching Menu Activated event"); + EventManager.GetEventEmitter("GamecraftModdingAPIMenuActivatedEventEmitter").Emit(); + } + } +} diff --git a/GamecraftModdingAPI/Events/MenuSwitchedToPatch.cs b/GamecraftModdingAPI/Events/MenuSwitchedToPatch.cs new file mode 100644 index 0000000..ae26268 --- /dev/null +++ b/GamecraftModdingAPI/Events/MenuSwitchedToPatch.cs @@ -0,0 +1,28 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +using Harmony; +using RobocraftX; +using Svelto.ECS; + +using GamecraftModdingAPI.Utility; + +namespace GamecraftModdingAPI.Events +{ + /// + /// Patch of RobocraftX.FullGameCompositionRoot.SwitchToMenu() + /// + [HarmonyPatch(typeof(FullGameCompositionRoot), "SwitchToMenu")] + class MenuSwitchedToPatch + { + public static void Postfix() + { + // Event emitters and handlers should already be registered by MenuActivated event + Logging.Log("Dispatching Menu Switched To event"); + EventManager.GetEventEmitter("GamecraftModdingAPIMenuSwitchedToEventEmitter").Emit(); + } + } +} diff --git a/GamecraftModdingAPI/Events/ModEventEntityDescriptor.cs b/GamecraftModdingAPI/Events/ModEventEntityDescriptor.cs new file mode 100644 index 0000000..5172d9c --- /dev/null +++ b/GamecraftModdingAPI/Events/ModEventEntityDescriptor.cs @@ -0,0 +1,17 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +using Svelto.ECS; + +namespace GamecraftModdingAPI.Events +{ + /// + /// EntityDescriptor for creating ModEventEntityStructs + /// + public class ModEventEntityDescriptor : GenericEntityDescriptor + { + } +} diff --git a/GamecraftModdingAPI/Events/ModEventEntityStruct.cs b/GamecraftModdingAPI/Events/ModEventEntityStruct.cs new file mode 100644 index 0000000..03bd65f --- /dev/null +++ b/GamecraftModdingAPI/Events/ModEventEntityStruct.cs @@ -0,0 +1,23 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +using Svelto.ECS; + +namespace GamecraftModdingAPI.Events +{ + /// + /// The event entity struct + /// + public struct ModEventEntityStruct : IEntityStruct, INeedEGID + { + /// + /// The type of event that has been emitted + /// + public int type; + + public EGID ID { get; set; } + } +} diff --git a/GamecraftModdingAPI/Events/SimpleEventEmitterEngine.cs b/GamecraftModdingAPI/Events/SimpleEventEmitterEngine.cs new file mode 100644 index 0000000..0e51823 --- /dev/null +++ b/GamecraftModdingAPI/Events/SimpleEventEmitterEngine.cs @@ -0,0 +1,65 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +using Svelto.ECS; +using GamecraftModdingAPI.Utility; + +namespace GamecraftModdingAPI.Events +{ + /// + /// A simple implementation of IEventEmitterEngine sufficient for most uses + /// + public class SimpleEventEmitterEngine : IEventEmitterEngine + { + public string Name { get; set; } + public int type { get; set; } + + public bool isRemovable { get; } + + public IEntityFactory Factory { private get; set; } + + public EntitiesDB entitiesDB { set; private get; } + + public void Ready() { } + + /// + /// Emit the event + /// + public void Emit() + { + Factory.BuildEntity(ApiExclusiveGroups.eventID++, ApiExclusiveGroups.eventsExclusiveGroup) + .Init(new ModEventEntityStruct { type = type }); + } + + public void Dispose() { } + + /// + /// Construct the engine + /// + /// The EventType to use for ModEventEntityStruct.type + /// The name of this engine + /// Will removing this engine not break your code? + public SimpleEventEmitterEngine(EventType type, string name, bool isRemovable = true) + { + this.type = (int)type; + this.Name = name; + this.isRemovable = isRemovable; + } + + /// + /// Construct the engine + /// + /// The object to use for ModEventEntityStruct.type + /// The name of this engine + /// Will removing this engine not break your code? + public SimpleEventEmitterEngine(int type, string name, bool isRemovable = true) + { + this.type = type; + this.Name = name; + this.isRemovable = isRemovable; + } + } +} diff --git a/GamecraftModdingAPI/Events/SimpleEventHandlerEngine.cs b/GamecraftModdingAPI/Events/SimpleEventHandlerEngine.cs new file mode 100644 index 0000000..d0bc341 --- /dev/null +++ b/GamecraftModdingAPI/Events/SimpleEventHandlerEngine.cs @@ -0,0 +1,98 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +using Svelto.ECS; + +namespace GamecraftModdingAPI.Events +{ + /// + /// A simple implementation of IEventHandlerEngine sufficient for most uses + /// + public class SimpleEventHandlerEngine : IEventHandlerEngine + { + public int type { get; set; } + public string Name { get; set; } + + private bool isActivated = false; + + private readonly Action onActivated; + + private readonly Action onDestroyed; + + public EntitiesDB entitiesDB { set; private get; } + + public void Add(ref ModEventEntityStruct entityView, EGID egid) + { + if (entityView.type.Equals(this.type)) + { + isActivated = true; + onActivated.Invoke(entitiesDB); + } + } + + /// + /// Manually activate the EventHandler. + /// Once activated, the next remove event will not be ignored. + /// + /// Whether to invoke the activated action + public void Activate(bool handle = false) + { + isActivated = true; + } + + public void Ready() { } + + public void Remove(ref ModEventEntityStruct entityView, EGID egid) + { + if (entityView.type.Equals(this.type) && isActivated) + { + isActivated = false; + onDestroyed.Invoke(entitiesDB); + } + } + + public void Dispose() + { + if (isActivated) + { + isActivated = false; + onDestroyed.Invoke(entitiesDB); + } + } + + /// + /// Construct the engine + /// + /// The operation to do when the event is created + /// The operation to do when the event is destroyed (if applicable) + /// The type of event to handle + /// The name of the engine + /// A useless parameter to use to avoid Python overload resolution errors + public SimpleEventHandlerEngine(Action activated, Action removed, int type, string name, bool simple = true) + : this((EntitiesDB _) => { activated.Invoke(); }, (EntitiesDB _) => { removed.Invoke(); }, type, name) { } + + /// + /// Construct the engine + /// + /// The operation to do when the event is created + /// The operation to do when the event is destroyed (if applicable) + /// The type of event to handler + /// The name of the engine + public SimpleEventHandlerEngine(Action activated, Action removed, int type, string name) + { + this.type = type; + this.Name = name; + this.onActivated = activated; + this.onDestroyed = removed; + } + + public SimpleEventHandlerEngine(Action activated, Action removed, EventType type, string name, bool simple = true) + : this((EntitiesDB _) => { activated.Invoke(); }, (EntitiesDB _) => { removed.Invoke(); }, (int)type, name) { } + + public SimpleEventHandlerEngine(Action activated, Action removed, EventType type, string name, bool simple = true) + : this(activated, removed, (int)type, name) { } + } +} diff --git a/GamecraftModdingAPI/GamecraftModdingAPI.csproj b/GamecraftModdingAPI/GamecraftModdingAPI.csproj new file mode 100644 index 0000000..4371236 --- /dev/null +++ b/GamecraftModdingAPI/GamecraftModdingAPI.csproj @@ -0,0 +1,518 @@ + + + + net472 + true + 0.2.0 + Exmods + GNU General Public Licence 3+ + https://git.exmods.org/modtainers/GamecraftModdingAPI + en-CA + + + + + + + + + + + + + ..\ref\Gamecraft_Data\Managed\Analytics.dll + + + ..\ref\Gamecraft_Data\Managed\Assembly-CSharp-firstpass.dll + + + ..\ref\Gamecraft_Data\Managed\Assembly-CSharp.dll + + + ..\ref\Gamecraft_Data\Managed\Authentication.dll + + + ..\ref\Gamecraft_Data\Managed\BlockEntityFactory.dll + + + ..\ref\Gamecraft_Data\Managed\CommandLine.dll + + + ..\ref\Gamecraft_Data\Managed\DataLoader.dll + + + ..\ref\Gamecraft_Data\Managed\DDNA.dll + + + ..\ref\Gamecraft_Data\Managed\Facepunch.Steamworks.Win64.dll + + + ..\ref\Gamecraft_Data\Managed\FMOD.dll + + + ..\ref\Gamecraft_Data\Managed\FullGame.dll + + + ..\ref\Gamecraft_Data\Managed\Gamecraft.Blocks.ConsoleBlock.dll + + + ..\ref\Gamecraft_Data\Managed\Gamecraft.Effects.dll + + + ..\ref\Gamecraft_Data\Managed\Gamecraft.GUI.GraphicsScreen.dll + + + ..\ref\Gamecraft_Data\Managed\Gamecraft.GUI.Tweaks.dll + + + ..\ref\Gamecraft_Data\Managed\Gamecraft.GUI.Wires.dll + + + ..\ref\Gamecraft_Data\Managed\Gamecraft.Tweaks.dll + + + ..\ref\Gamecraft_Data\Managed\Gamecraft.Wires.dll + + + ..\ref\Gamecraft_Data\Managed\Gamecraft.Wires.Input.dll + + + ..\ref\Gamecraft_Data\Managed\GameState.dll + + + ..\ref\Gamecraft_Data\Managed\GPUInstancer.dll + + + ..\ref\Gamecraft_Data\Managed\Havok.Physics.dll + + + ..\ref\Gamecraft_Data\Managed\Havok.Physics.Hybrid.dll + + + ..\ref\Gamecraft_Data\Managed\IllusionInjector.dll + + + ..\ref\Gamecraft_Data\Managed\IllusionPlugin.dll + + + ..\ref\Gamecraft_Data\Managed\JWT.dll + + + ..\ref\Gamecraft_Data\Managed\LZ4.dll + + + ..\ref\Gamecraft_Data\Managed\MultiplayerNetworking.dll + + + ..\ref\Gamecraft_Data\Managed\MultiplayerTest.dll + + + ..\ref\Gamecraft_Data\Managed\Newtonsoft.Json.dll + + + ..\ref\Gamecraft_Data\Managed\RCX.ScreenshotTaker.dll + + + ..\ref\Gamecraft_Data\Managed\Rewired_Core.dll + + + ..\ref\Gamecraft_Data\Managed\Rewired_Windows.dll + + + ..\ref\Gamecraft_Data\Managed\RobocraftX.AccountPreferences.dll + + + ..\ref\Gamecraft_Data\Managed\RobocraftX.Blocks.dll + + + ..\ref\Gamecraft_Data\Managed\RobocraftX.Blocks.Ghost.dll + + + ..\ref\Gamecraft_Data\Managed\RobocraftX.Blocks.Triggers.dll + + + ..\ref\Gamecraft_Data\Managed\RobocraftX.Character.dll + + + ..\ref\Gamecraft_Data\Managed\RobocraftX.Common.dll + + + ..\ref\Gamecraft_Data\Managed\RobocraftX.ControlsScreen.dll + + + ..\ref\Gamecraft_Data\Managed\RobocraftX.Crosshair.dll + + + ..\ref\Gamecraft_Data\Managed\RobocraftX.FrontEnd.dll + + + ..\ref\Gamecraft_Data\Managed\RobocraftX.GUI.DebugDisplay.dll + + + ..\ref\Gamecraft_Data\Managed\RobocraftX.GUI.dll + + + ..\ref\Gamecraft_Data\Managed\RobocraftX.GUI.RemoveBlock.dll + + + ..\ref\Gamecraft_Data\Managed\RobocraftX.GUI.ScaleGhost.dll + + + ..\ref\Gamecraft_Data\Managed\RobocraftX.GUIs.WorkshopPrefabs.dll + + + ..\ref\Gamecraft_Data\Managed\RobocraftX.Input.dll + + + ..\ref\Gamecraft_Data\Managed\RobocraftX.MachineEditor.dll + + + ..\ref\Gamecraft_Data\Managed\RobocraftX.MainGame.dll + + + ..\ref\Gamecraft_Data\Managed\RobocraftX.MainSimulation.dll + + + ..\ref\Gamecraft_Data\Managed\RobocraftX.Multiplayer.dll + + + ..\ref\Gamecraft_Data\Managed\RobocraftX.Multiplayer.NetworkEntityStream.dll + + + ..\ref\Gamecraft_Data\Managed\RobocraftX.MultiplayerInput.dll + + + ..\ref\Gamecraft_Data\Managed\RobocraftX.Party.dll + + + ..\ref\Gamecraft_Data\Managed\RobocraftX.PartyGui.dll + + + ..\ref\Gamecraft_Data\Managed\RobocraftX.Physics.dll + + + ..\ref\Gamecraft_Data\Managed\RobocraftX.PilotSeat.dll + + + ..\ref\Gamecraft_Data\Managed\RobocraftX.Player.dll + + + ..\ref\Gamecraft_Data\Managed\RobocraftX.Rendering.dll + + + ..\ref\Gamecraft_Data\Managed\RobocraftX.Rendering.Mock.dll + + + ..\ref\Gamecraft_Data\Managed\RobocraftX.SaveAndLoad.dll + + + ..\ref\Gamecraft_Data\Managed\RobocraftX.SaveGameDialog.dll + + + ..\ref\Gamecraft_Data\Managed\RobocraftX.Serializers.dll + + + ..\ref\Gamecraft_Data\Managed\RobocraftX.Services.dll + + + ..\ref\Gamecraft_Data\Managed\RobocraftX.SignalHandling.dll + + + ..\ref\Gamecraft_Data\Managed\RobocraftX.StateSync.dll + + + ..\ref\Gamecraft_Data\Managed\RobocraftX_SpawnPoints.dll + + + ..\ref\Gamecraft_Data\Managed\RobocraftX_TextBlock.dll + + + ..\ref\Gamecraft_Data\Managed\RobocratX.SimulationCompositionRoot.dll + + + ..\ref\Gamecraft_Data\Managed\StringFormatter.dll + + + ..\ref\Gamecraft_Data\Managed\Svelto.Common.dll + + + ..\ref\Gamecraft_Data\Managed\Svelto.ECS.Debugger.dll + + + ..\ref\Gamecraft_Data\Managed\Svelto.ECS.dll + + + ..\ref\Gamecraft_Data\Managed\Svelto.Services.dll + + + ..\ref\Gamecraft_Data\Managed\Svelto.Tasks.dll + + + ..\ref\Gamecraft_Data\Managed\Unity.Addressables.dll + + + ..\ref\Gamecraft_Data\Managed\Unity.Burst.dll + + + ..\ref\Gamecraft_Data\Managed\Unity.Burst.Unsafe.dll + + + ..\ref\Gamecraft_Data\Managed\Unity.Collections.dll + + + ..\ref\Gamecraft_Data\Managed\Unity.Entities.dll + + + ..\ref\Gamecraft_Data\Managed\Unity.Entities.Hybrid.dll + + + ..\ref\Gamecraft_Data\Managed\Unity.Jobs.dll + + + ..\ref\Gamecraft_Data\Managed\Unity.Mathematics.dll + + + ..\ref\Gamecraft_Data\Managed\Unity.Mathematics.Extensions.dll + + + ..\ref\Gamecraft_Data\Managed\Unity.Mathematics.Extensions.Hybrid.dll + + + ..\ref\Gamecraft_Data\Managed\Unity.Physics.dll + + + ..\ref\Gamecraft_Data\Managed\Unity.Physics.Hybrid.dll + + + ..\ref\Gamecraft_Data\Managed\Unity.Postprocessing.Runtime.dll + + + ..\ref\Gamecraft_Data\Managed\Unity.Properties.dll + + + ..\ref\Gamecraft_Data\Managed\Unity.RenderPipelines.Core.Runtime.dll + + + ..\ref\Gamecraft_Data\Managed\Unity.RenderPipelines.Core.ShaderLibrary.dll + + + ..\ref\Gamecraft_Data\Managed\Unity.RenderPipelines.ShaderGraph.ShaderGraphLibrary.dll + + + ..\ref\Gamecraft_Data\Managed\Unity.ResourceManager.dll + + + ..\ref\Gamecraft_Data\Managed\Unity.Scenes.Hybrid.dll + + + ..\ref\Gamecraft_Data\Managed\Unity.ScriptableBuildPipeline.dll + + + ..\ref\Gamecraft_Data\Managed\Unity.TextMeshPro.dll + + + ..\ref\Gamecraft_Data\Managed\Unity.Timeline.dll + + + ..\ref\Gamecraft_Data\Managed\Unity.Transforms.dll + + + ..\ref\Gamecraft_Data\Managed\Unity.Transforms.Hybrid.dll + + + ..\ref\Gamecraft_Data\Managed\UnityEngine.AccessibilityModule.dll + + + ..\ref\Gamecraft_Data\Managed\UnityEngine.AIModule.dll + + + ..\ref\Gamecraft_Data\Managed\UnityEngine.AndroidJNIModule.dll + + + ..\ref\Gamecraft_Data\Managed\UnityEngine.AnimationModule.dll + + + ..\ref\Gamecraft_Data\Managed\UnityEngine.ARModule.dll + + + ..\ref\Gamecraft_Data\Managed\UnityEngine.AssetBundleModule.dll + + + ..\ref\Gamecraft_Data\Managed\UnityEngine.AudioModule.dll + + + ..\ref\Gamecraft_Data\Managed\UnityEngine.ClothModule.dll + + + ..\ref\Gamecraft_Data\Managed\UnityEngine.ClusterInputModule.dll + + + ..\ref\Gamecraft_Data\Managed\UnityEngine.ClusterRendererModule.dll + + + ..\ref\Gamecraft_Data\Managed\UnityEngine.CoreModule.dll + + + ..\ref\Gamecraft_Data\Managed\UnityEngine.CrashReportingModule.dll + + + ..\ref\Gamecraft_Data\Managed\UnityEngine.DirectorModule.dll + + + ..\ref\Gamecraft_Data\Managed\UnityEngine.dll + + + ..\ref\Gamecraft_Data\Managed\UnityEngine.DSPGraphModule.dll + + + ..\ref\Gamecraft_Data\Managed\UnityEngine.GameCenterModule.dll + + + ..\ref\Gamecraft_Data\Managed\UnityEngine.GridModule.dll + + + ..\ref\Gamecraft_Data\Managed\UnityEngine.HotReloadModule.dll + + + ..\ref\Gamecraft_Data\Managed\UnityEngine.ImageConversionModule.dll + + + ..\ref\Gamecraft_Data\Managed\UnityEngine.IMGUIModule.dll + + + ..\ref\Gamecraft_Data\Managed\UnityEngine.InputLegacyModule.dll + + + ..\ref\Gamecraft_Data\Managed\UnityEngine.InputModule.dll + + + ..\ref\Gamecraft_Data\Managed\UnityEngine.JSONSerializeModule.dll + + + ..\ref\Gamecraft_Data\Managed\UnityEngine.LocalizationModule.dll + + + ..\ref\Gamecraft_Data\Managed\UnityEngine.ParticleSystemModule.dll + + + ..\ref\Gamecraft_Data\Managed\UnityEngine.PerformanceReportingModule.dll + + + ..\ref\Gamecraft_Data\Managed\UnityEngine.Physics2DModule.dll + + + ..\ref\Gamecraft_Data\Managed\UnityEngine.PhysicsModule.dll + + + ..\ref\Gamecraft_Data\Managed\UnityEngine.ProfilerModule.dll + + + ..\ref\Gamecraft_Data\Managed\UnityEngine.ScreenCaptureModule.dll + + + ..\ref\Gamecraft_Data\Managed\UnityEngine.SharedInternalsModule.dll + + + ..\ref\Gamecraft_Data\Managed\UnityEngine.SpriteMaskModule.dll + + + ..\ref\Gamecraft_Data\Managed\UnityEngine.SpriteShapeModule.dll + + + ..\ref\Gamecraft_Data\Managed\UnityEngine.StreamingModule.dll + + + ..\ref\Gamecraft_Data\Managed\UnityEngine.SubstanceModule.dll + + + ..\ref\Gamecraft_Data\Managed\UnityEngine.TerrainModule.dll + + + ..\ref\Gamecraft_Data\Managed\UnityEngine.TerrainPhysicsModule.dll + + + ..\ref\Gamecraft_Data\Managed\UnityEngine.TextCoreModule.dll + + + ..\ref\Gamecraft_Data\Managed\UnityEngine.TextRenderingModule.dll + + + ..\ref\Gamecraft_Data\Managed\UnityEngine.TilemapModule.dll + + + ..\ref\Gamecraft_Data\Managed\UnityEngine.TLSModule.dll + + + ..\ref\Gamecraft_Data\Managed\UnityEngine.UI.dll + + + ..\ref\Gamecraft_Data\Managed\UnityEngine.UIElementsModule.dll + + + ..\ref\Gamecraft_Data\Managed\UnityEngine.UIModule.dll + + + ..\ref\Gamecraft_Data\Managed\UnityEngine.UmbraModule.dll + + + ..\ref\Gamecraft_Data\Managed\UnityEngine.UNETModule.dll + + + ..\ref\Gamecraft_Data\Managed\UnityEngine.UnityAnalyticsModule.dll + + + ..\ref\Gamecraft_Data\Managed\UnityEngine.UnityConnectModule.dll + + + ..\ref\Gamecraft_Data\Managed\UnityEngine.UnityTestProtocolModule.dll + + + ..\ref\Gamecraft_Data\Managed\UnityEngine.UnityWebRequestAssetBundleModule.dll + + + ..\ref\Gamecraft_Data\Managed\UnityEngine.UnityWebRequestAudioModule.dll + + + ..\ref\Gamecraft_Data\Managed\UnityEngine.UnityWebRequestModule.dll + + + ..\ref\Gamecraft_Data\Managed\UnityEngine.UnityWebRequestTextureModule.dll + + + ..\ref\Gamecraft_Data\Managed\UnityEngine.UnityWebRequestWWWModule.dll + + + ..\ref\Gamecraft_Data\Managed\UnityEngine.VehiclesModule.dll + + + ..\ref\Gamecraft_Data\Managed\UnityEngine.VFXModule.dll + + + ..\ref\Gamecraft_Data\Managed\UnityEngine.VideoModule.dll + + + ..\ref\Gamecraft_Data\Managed\UnityEngine.VRModule.dll + + + ..\ref\Gamecraft_Data\Managed\UnityEngine.WindModule.dll + + + ..\ref\Gamecraft_Data\Managed\UnityEngine.XRModule.dll + + + ..\ref\Gamecraft_Data\Managed\uREPL.dll + + + ..\ref\Gamecraft_Data\Managed\VisualProfiler.dll + + + + ..\ref\Gamecraft_Data\Managed\Assembly-CSharp.dll + + + ..\ref\Gamecraft_Data\Managed\UnityEngine.CoreModule.dll + + + + + diff --git a/GamecraftModdingAPI/Input/FakeInput.cs b/GamecraftModdingAPI/Input/FakeInput.cs new file mode 100644 index 0000000..3d9a379 --- /dev/null +++ b/GamecraftModdingAPI/Input/FakeInput.cs @@ -0,0 +1,153 @@ +using System; + +using RobocraftX.Common; +using RobocraftX.Common.Input; +using Svelto.ECS; + +using GamecraftModdingAPI.Utility; + +namespace GamecraftModdingAPI.Input +{ + public static class FakeInput + { + private static readonly FakeInputEngine inputEngine = new FakeInputEngine(); + + /// + /// Customize the player input. + /// + /// The custom input. + /// The player. Omit this to use the local player. + public static void CustomInput(InputEntityStruct input, uint playerID = uint.MaxValue) + { + if (playerID == uint.MaxValue) + { + playerID = inputEngine.GetLocalPlayerID(); + } + inputEngine.SendCustomInput(input, playerID); + } + + public static InputEntityStruct GetInput(uint playerID = uint.MaxValue) + { + if (playerID == uint.MaxValue) + { + playerID = inputEngine.GetLocalPlayerID(); + } + return inputEngine.GetInput(playerID); + } + + /// + /// Fake a GUI input. + /// Omit any parameter you do not want to affect. + /// Parameters that end with "?" don't do anything... yet. + /// + /// The player. Omit this to use the local player. + /// Select the hotbar slot by number. + /// Select the hotbar hand. + /// Toggle the command line? + /// Open inventory? + /// Open escape menu? + /// Page return? + /// Toggle debug display? + /// Select next? + /// Select previous? + /// Tab? + /// Toggle to hotbar colour mode? + /// Select the hotbar page by number? + /// Quicksave? + /// Paste? + public static void GuiInput(uint playerID = uint.MaxValue, int hotbar = -1, bool hotbarHand = false, bool commandLine = false, bool inventory = false, bool escape = false, bool enter = false, bool debug = false, bool next = false, bool previous = false, bool tab = false, bool colour = false, int hotbarPage = -1, bool quickSave = false, bool paste = false) + { + if (playerID == uint.MaxValue) + { + playerID = inputEngine.GetLocalPlayerID(); + } + ref InputEntityStruct currentInput = ref inputEngine.GetInputRef(playerID); + Utility.Logging.CommandLog($"Current sim frame {currentInput.frame}"); + // set inputs + switch(hotbar) + { + case 0: currentInput.guiMask |= RobocraftX.Common.Input.GuiInput.Hotbar_0; break; + case 1: currentInput.guiMask |= RobocraftX.Common.Input.GuiInput.Hotbar_1; break; + case 2: currentInput.guiMask |= RobocraftX.Common.Input.GuiInput.Hotbar_2; break; + case 3: currentInput.guiMask |= RobocraftX.Common.Input.GuiInput.Hotbar_3; break; + case 4: currentInput.guiMask |= RobocraftX.Common.Input.GuiInput.Hotbar_4; break; + case 5: currentInput.guiMask |= RobocraftX.Common.Input.GuiInput.Hotbar_5; break; + case 6: currentInput.guiMask |= RobocraftX.Common.Input.GuiInput.Hotbar_6; break; + case 7: currentInput.guiMask |= RobocraftX.Common.Input.GuiInput.Hotbar_7; break; + case 8: currentInput.guiMask |= RobocraftX.Common.Input.GuiInput.Hotbar_8; break; + case 9: currentInput.guiMask |= RobocraftX.Common.Input.GuiInput.Hotbar_9; break; + case 10: currentInput.guiMask |= RobocraftX.Common.Input.GuiInput.Hotbar_Hand; break; + default: break; + } + if (hotbarHand) currentInput.guiMask |= RobocraftX.Common.Input.GuiInput.Hotbar_Hand; + if (commandLine) currentInput.guiMask |= RobocraftX.Common.Input.GuiInput.ToggleCommandLine; + if (inventory) currentInput.guiMask |= RobocraftX.Common.Input.GuiInput.Inventory; + if (escape) currentInput.guiMask |= RobocraftX.Common.Input.GuiInput.Escape; + if (enter) currentInput.guiMask |= RobocraftX.Common.Input.GuiInput.Return; + if (debug) currentInput.guiMask |= RobocraftX.Common.Input.GuiInput.ToggleDebugDisplay; + if (next) currentInput.guiMask |= RobocraftX.Common.Input.GuiInput.SelectNext; + if (previous) currentInput.guiMask |= RobocraftX.Common.Input.GuiInput.SelectPrev; + if (tab) currentInput.guiMask |= RobocraftX.Common.Input.GuiInput.Tab; + if (colour) currentInput.guiMask |= RobocraftX.Common.Input.GuiInput.Hotbar_Colour; + switch (hotbarPage) + { + case 1: currentInput.guiMask |= RobocraftX.Common.Input.GuiInput.HotbarPage1; break; + case 2: currentInput.guiMask |= RobocraftX.Common.Input.GuiInput.HotbarPage2; break; + case 3: currentInput.guiMask |= RobocraftX.Common.Input.GuiInput.HotbarPage3; break; + case 4: currentInput.guiMask |= RobocraftX.Common.Input.GuiInput.HotbarPage4; break; + case 5: currentInput.guiMask |= RobocraftX.Common.Input.GuiInput.HotbarPage5; break; + case 6: currentInput.guiMask |= RobocraftX.Common.Input.GuiInput.HotbarPage6; break; + case 7: currentInput.guiMask |= RobocraftX.Common.Input.GuiInput.HotbarPage7; break; + case 8: currentInput.guiMask |= RobocraftX.Common.Input.GuiInput.HotbarPage8; break; + case 9: currentInput.guiMask |= RobocraftX.Common.Input.GuiInput.HotbarPage9; break; + case 10: currentInput.guiMask |= RobocraftX.Common.Input.GuiInput.HotbarPage10; break; + default: break; + } + if (quickSave) currentInput.guiMask |= RobocraftX.Common.Input.GuiInput.QuickSave; + if (paste) currentInput.guiMask |= RobocraftX.Common.Input.GuiInput.PasteSelection; + } + + public static void ActionInput(uint playerID = uint.MaxValue, bool toggleMode = false, bool forward = false, bool backward = false, bool up = false, bool down = false, bool left = false, bool right = false, bool sprint = false, bool toggleFly = false, bool alt = false, bool primary = false, bool secondary = false, bool tertiary = false, bool primaryRelease = false, bool primaryHeld = false, bool secondaryHeld = false, bool toggleUnitGrid = false, bool ctrl = false, bool toggleColourMode = false, bool scaleBlockUp = false, bool scaleBlockDown = false, bool rotateBlockClockwise = false, bool rotateBlockCounterclockwise = false, bool cutSelection = false, bool copySelection = false, bool deleteSelection = false) + { + if (playerID == uint.MaxValue) + { + playerID = inputEngine.GetLocalPlayerID(); + } + ref InputEntityStruct currentInput = ref inputEngine.GetInputRef(playerID); + Utility.Logging.CommandLog($"Current sim frame {currentInput.frame}"); + // set inputs + if (toggleMode) currentInput.actionMask |= RobocraftX.Common.Input.ActionInput.ToggleSimulation; + if (forward) currentInput.actionMask |= RobocraftX.Common.Input.ActionInput.Forward; + if (backward) currentInput.actionMask |= RobocraftX.Common.Input.ActionInput.Backward; + if (up) currentInput.actionMask |= RobocraftX.Common.Input.ActionInput.Up; + if (down) currentInput.actionMask |= RobocraftX.Common.Input.ActionInput.Down; + if (left) currentInput.actionMask |= RobocraftX.Common.Input.ActionInput.Left; + if (right) currentInput.actionMask |= RobocraftX.Common.Input.ActionInput.Right; + if (sprint) currentInput.actionMask |= RobocraftX.Common.Input.ActionInput.Sprint; + if (toggleFly) currentInput.actionMask |= RobocraftX.Common.Input.ActionInput.SwitchFlyMode; + if (alt) currentInput.actionMask |= RobocraftX.Common.Input.ActionInput.AltAction; + if (primary) currentInput.actionMask |= RobocraftX.Common.Input.ActionInput.PrimaryAction; + if (secondary) currentInput.actionMask |= RobocraftX.Common.Input.ActionInput.SecondaryAction; + if (tertiary) currentInput.actionMask |= RobocraftX.Common.Input.ActionInput.TertiaryAction; + if (primaryRelease) currentInput.actionMask |= RobocraftX.Common.Input.ActionInput.PrimaryActionRelease; + if (primaryHeld) currentInput.actionMask |= RobocraftX.Common.Input.ActionInput.PrimaryActionHeld; + if (secondaryHeld) currentInput.actionMask |= RobocraftX.Common.Input.ActionInput.SecondaryActionHeld; + if (toggleUnitGrid) currentInput.actionMask |= RobocraftX.Common.Input.ActionInput.ToggleUnitGrid; + if (ctrl) currentInput.actionMask |= RobocraftX.Common.Input.ActionInput.CtrlAction; + if (toggleColourMode) currentInput.actionMask |= RobocraftX.Common.Input.ActionInput.ToggleColourMode; + if (scaleBlockUp) currentInput.actionMask |= RobocraftX.Common.Input.ActionInput.ScaleBlockUp; + if (scaleBlockDown) currentInput.actionMask |= RobocraftX.Common.Input.ActionInput.ScaleBlockDown; + if (rotateBlockClockwise) currentInput.actionMask |= RobocraftX.Common.Input.ActionInput.RotateBlockClockwise; + if (rotateBlockCounterclockwise) currentInput.actionMask |= RobocraftX.Common.Input.ActionInput.RotateBlockAnticlockwise; + if (cutSelection) currentInput.actionMask |= RobocraftX.Common.Input.ActionInput.CutSelection; + if (copySelection) currentInput.actionMask |= RobocraftX.Common.Input.ActionInput.CopySelection; + if (deleteSelection) currentInput.actionMask |= RobocraftX.Common.Input.ActionInput.DeleteSelection; + } + + public static void Init() + { + GameEngineManager.AddGameEngine(inputEngine); + MenuEngineManager.AddMenuEngine(inputEngine); + } + } +} diff --git a/GamecraftModdingAPI/Input/FakeInputEngine.cs b/GamecraftModdingAPI/Input/FakeInputEngine.cs new file mode 100644 index 0000000..dea0f3e --- /dev/null +++ b/GamecraftModdingAPI/Input/FakeInputEngine.cs @@ -0,0 +1,62 @@ +using System; + +using RobocraftX.Common.Input; +using RobocraftX.Players; +using Svelto.ECS; + +using GamecraftModdingAPI.Utility; + +namespace GamecraftModdingAPI.Input +{ + public class FakeInputEngine : IApiEngine + { + public string Name { get; } = "GamecraftModdingAPIFakeInputEngine"; + + public EntitiesDB entitiesDB { set; private get; } + + public bool IsReady = false; + + public void Dispose() + { + IsReady = false; + } + + public void Ready() + { + IsReady = true; + } + + public bool SendCustomInput(InputEntityStruct input, uint playerID, bool remote = false) + { + EGID egid = new EGID(playerID, remote ? InputExclusiveGroups.RemotePlayers : InputExclusiveGroups.LocalPlayers); + if (entitiesDB.Exists(egid)) + { + ref InputEntityStruct ies = ref entitiesDB.QueryEntity(egid); + ies = input; + return true; + } + else return false; + } + + public InputEntityStruct GetInput(uint playerID, bool remote = false) + { + EGID egid = new EGID(playerID, remote ? InputExclusiveGroups.RemotePlayers : InputExclusiveGroups.LocalPlayers); + if (entitiesDB.Exists(egid)) + { + return entitiesDB.QueryEntity(egid); + } + else return default(InputEntityStruct); + } + + public ref InputEntityStruct GetInputRef(uint playerID, bool remote = false) + { + EGID egid = new EGID(playerID, remote ? InputExclusiveGroups.RemotePlayers : InputExclusiveGroups.LocalPlayers); + return ref entitiesDB.QueryEntity(egid); + } + + public uint GetLocalPlayerID() + { + return LocalPlayerIDUtility.GetLocalPlayerID(entitiesDB); + } + } +} diff --git a/GamecraftModdingAPI/Inventory/Hotbar.cs b/GamecraftModdingAPI/Inventory/Hotbar.cs new file mode 100644 index 0000000..c649a66 --- /dev/null +++ b/GamecraftModdingAPI/Inventory/Hotbar.cs @@ -0,0 +1,47 @@ +using System; + +using RobocraftX.Common.Input; +using RobocraftX.Multiplayer.Input; + +using GamecraftModdingAPI.Blocks; +using GamecraftModdingAPI.Utility; +using Harmony; + +namespace GamecraftModdingAPI.Inventory +{ + public static class Hotbar + { + private static readonly HotbarEngine hotbarEngine = new HotbarEngine(); + + /// + /// Switch the block in the player's hand + /// + /// The block to switch to. + /// The player. Omit this to use the local player. + public static void EquipBlock(BlockIDs block, uint playerID = uint.MaxValue) + { + if (playerID == uint.MaxValue) + { + playerID = hotbarEngine.GetLocalPlayerID(); + } + hotbarEngine.SelectBlock((int) block, playerID); + // cubeSelectedByPick = true will crash the game + // (this would be equivalent to mouse middle click pick block action) + // reason: the game expects a Dictionary entry for the tweaked stats + } + + /// + /// Gets the block in the player's hand + /// + /// The equipped block. + public static BlockIDs GetEquippedBlock() + { + return HotbarSlotSelectionHandlerEnginePatch.EquippedPartID; + } + + public static void Init() + { + GameEngineManager.AddGameEngine(hotbarEngine); + } + } +} diff --git a/GamecraftModdingAPI/Inventory/HotbarEngine.cs b/GamecraftModdingAPI/Inventory/HotbarEngine.cs new file mode 100644 index 0000000..065298b --- /dev/null +++ b/GamecraftModdingAPI/Inventory/HotbarEngine.cs @@ -0,0 +1,55 @@ +using System; + +using RobocraftX.Character; +using RobocraftX.GUI.Hotbar; +using RobocraftX.Players; +using RobocraftX.Common; +using RobocraftX.Common.Input; +using RobocraftX.Common.Players; +using Svelto.ECS; + +using GamecraftModdingAPI.Blocks; +using GamecraftModdingAPI.Utility; + +namespace GamecraftModdingAPI.Inventory +{ + public class HotbarEngine : IApiEngine + { + public string Name { get; } = "GamecraftModdingAPIHotbarGameEngine"; + + public EntitiesDB entitiesDB { set; private get; } + + public bool IsInGame = false; + + public void Dispose() + { + IsInGame = false; + } + + public void Ready() + { + IsInGame = true; + } + + public bool SelectBlock(int block, uint playerID, bool cubeSelectedByPick = false) + { + InputEntityStruct[] inputs = entitiesDB.QueryEntities(InputExclusiveGroups.LocalPlayers).ToFastAccess(out uint count); + if (count == 0) return false; + for (int i = 0; i < count; i++) + { + if (inputs[i].ID.entityID == playerID) { + inputs[i].cubeSelectedByPick = cubeSelectedByPick; + inputs[i].selectedCube = block; + return true; + } + } + // TODO: expose the rest of the input functionality + return false; + } + + public uint GetLocalPlayerID() + { + return LocalPlayerIDUtility.GetLocalPlayerID(entitiesDB); + } + } +} diff --git a/GamecraftModdingAPI/Inventory/HotbarSlotSelectionHandlerEnginePatch.cs b/GamecraftModdingAPI/Inventory/HotbarSlotSelectionHandlerEnginePatch.cs new file mode 100644 index 0000000..db50e4d --- /dev/null +++ b/GamecraftModdingAPI/Inventory/HotbarSlotSelectionHandlerEnginePatch.cs @@ -0,0 +1,32 @@ +using System; +using System.Reflection; + +using RobocraftX.GUI; +using RobocraftX.GUI.Hotbar; +using Svelto.ECS; + +using Harmony; +using GamecraftModdingAPI.Blocks; + +namespace GamecraftModdingAPI.Inventory +{ + [HarmonyPatch] + public class HotbarSlotSelectionHandlerEnginePatch + { + private static int selectedBlockInt = 0; + + public static BlockIDs EquippedPartID { get => (BlockIDs)selectedBlockInt; } + + private static MethodInfo PatchedMethod { get; } = AccessTools.Method(AccessTools.TypeByName("RobocraftX.GUI.Hotbar.HotbarSlotSelectionHandlerEngine"), "HandleEquippedCubeChanged", parameters: new Type[] { typeof(uint), typeof(int), typeof(ExclusiveGroupStruct) }); + + public static void Prefix(uint playerID, int selectedDBPartID, ExclusiveGroupStruct groupID) + { + selectedBlockInt = selectedDBPartID; + } + + public static MethodBase TargetMethod(HarmonyInstance instance) + { + return PatchedMethod; + } + } +} diff --git a/GamecraftModdingAPI/Main.cs b/GamecraftModdingAPI/Main.cs new file mode 100644 index 0000000..ff8b63c --- /dev/null +++ b/GamecraftModdingAPI/Main.cs @@ -0,0 +1,99 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Reflection; + +using Harmony; + +using GamecraftModdingAPI.Utility; +using GamecraftModdingAPI.Events; +using GamecraftModdingAPI.Tasks; + +namespace GamecraftModdingAPI +{ + /// + /// The main class of the GamecraftModdingAPI. + /// Use this to initialize the API before calling it. + /// + public static class Main + { + private static HarmonyInstance harmony; + + public static bool IsInitialized { + get { return harmony != null; } + } + + private static int referenceCount = 0; + + /// + /// Initializes the GamecraftModdingAPI. + /// Call this as soon as possible after Gamecraft starts up. + /// Ideally, this should be called from your main Plugin class's OnApplicationStart() method. + /// + public static void Init() + { + referenceCount++; + if (referenceCount > 1) { return; } + if (IsInitialized) + { + Logging.LogWarning("GamecraftModdingAPI.Main.Init() called but API is already initialized!"); + return; + } + Logging.MetaDebugLog($"Patching Gamecraft"); + var currentAssembly = Assembly.GetExecutingAssembly(); + harmony = HarmonyInstance.Create(currentAssembly.GetName().Name); + harmony.PatchAll(currentAssembly); + // init utility + Logging.MetaDebugLog($"Initializing Utility"); + Utility.GameState.Init(); + // create default event emitters + Logging.MetaDebugLog($"Initializing Events"); + EventManager.AddEventEmitter(new SimpleEventEmitterEngine(EventType.ApplicationInitialized, "GamecraftModdingAPIApplicationInitializedEventEmitter", false)); + EventManager.AddEventEmitter(new SimpleEventEmitterEngine(EventType.Menu, "GamecraftModdingAPIMenuActivatedEventEmitter", false)); + EventManager.AddEventEmitter(new SimpleEventEmitterEngine(EventType.MenuSwitchedTo, "GamecraftModdingAPIMenuSwitchedToEventEmitter", false)); + EventManager.AddEventEmitter(new SimpleEventEmitterEngine(EventType.Game, "GamecraftModdingAPIGameActivatedEventEmitter", false)); + EventManager.AddEventEmitter(new SimpleEventEmitterEngine(EventType.GameReloaded, "GamecraftModdingAPIGameReloadedEventEmitter", false)); + EventManager.AddEventEmitter(new SimpleEventEmitterEngine(EventType.GameSwitchedTo, "GamecraftModdingAPIGameSwitchedToEventEmitter", false)); + EventManager.AddEventEmitter(GameHostTransitionDeterministicGroupEnginePatch.buildEngine); + EventManager.AddEventEmitter(GameHostTransitionDeterministicGroupEnginePatch.simEngine); + // init block implementors + Logging.MetaDebugLog($"Initializing Blocks"); + Blocks.Movement.Init(); + Blocks.Rotation.Init(); + Blocks.Signals.Init(); + Blocks.Placement.Init(); + Blocks.Tweakable.Init(); + Blocks.Removal.Init(); + // init inventory + Inventory.Hotbar.Init(); + // init input + Input.FakeInput.Init(); + Logging.MetaLog($"{currentAssembly.GetName().Name} v{currentAssembly.GetName().Version} initialized"); + } + + /// + /// Shuts down & cleans up the GamecraftModdingAPI. + /// Call this as late as possible before Gamecraft quits. + /// Ideally, this should be called from your main Plugin class's OnApplicationQuit() method. + /// + public static void Shutdown() + { + if (referenceCount > 0) { referenceCount--; } + if (referenceCount == 0) + { + if (!IsInitialized) + { + Logging.LogWarning("GamecraftModdingAPI.Main.Shutdown() called but API is not initialized!"); + return; + } + Scheduler.Dispose(); + var currentAssembly = Assembly.GetExecutingAssembly(); + harmony.UnpatchAll(currentAssembly.GetName().Name); + harmony = null; + Logging.MetaLog($"{currentAssembly.GetName().Name} v{currentAssembly.GetName().Version} shutdown"); + } + } + } +} diff --git a/TechbloxModdingAPI/Tasks/ISchedulable.cs b/GamecraftModdingAPI/Tasks/ISchedulable.cs similarity index 92% rename from TechbloxModdingAPI/Tasks/ISchedulable.cs rename to GamecraftModdingAPI/Tasks/ISchedulable.cs index 679e999..0b04a3e 100644 --- a/TechbloxModdingAPI/Tasks/ISchedulable.cs +++ b/GamecraftModdingAPI/Tasks/ISchedulable.cs @@ -6,7 +6,7 @@ using System.Threading.Tasks; using Svelto.Tasks; -namespace TechbloxModdingAPI.Tasks +namespace GamecraftModdingAPI.Tasks { /// /// Interface for asynchronous tasks diff --git a/TechbloxModdingAPI/Tasks/Once.cs b/GamecraftModdingAPI/Tasks/Once.cs similarity index 96% rename from TechbloxModdingAPI/Tasks/Once.cs rename to GamecraftModdingAPI/Tasks/Once.cs index 807dae7..52651e6 100644 --- a/TechbloxModdingAPI/Tasks/Once.cs +++ b/GamecraftModdingAPI/Tasks/Once.cs @@ -7,7 +7,7 @@ using System.Threading.Tasks; using Svelto.Tasks; using Svelto.Tasks.Enumerators; -namespace TechbloxModdingAPI.Tasks +namespace GamecraftModdingAPI.Tasks { /// /// An asynchronous task to be performed once. diff --git a/TechbloxModdingAPI/Tasks/Repeatable.cs b/GamecraftModdingAPI/Tasks/Repeatable.cs similarity index 98% rename from TechbloxModdingAPI/Tasks/Repeatable.cs rename to GamecraftModdingAPI/Tasks/Repeatable.cs index 0cafe48..0b9982e 100644 --- a/TechbloxModdingAPI/Tasks/Repeatable.cs +++ b/GamecraftModdingAPI/Tasks/Repeatable.cs @@ -7,7 +7,7 @@ using System.Threading.Tasks; using Svelto.Tasks; using Svelto.Tasks.Enumerators; -namespace TechbloxModdingAPI.Tasks +namespace GamecraftModdingAPI.Tasks { /// /// An asynchronous repeating task. diff --git a/TechbloxModdingAPI/Tasks/Scheduler.cs b/GamecraftModdingAPI/Tasks/Scheduler.cs similarity index 86% rename from TechbloxModdingAPI/Tasks/Scheduler.cs rename to GamecraftModdingAPI/Tasks/Scheduler.cs index 5ad842e..803bd2f 100644 --- a/TechbloxModdingAPI/Tasks/Scheduler.cs +++ b/GamecraftModdingAPI/Tasks/Scheduler.cs @@ -7,7 +7,7 @@ using System.Threading.Tasks; using Svelto.Tasks.Lean; using Svelto.Tasks.ExtraLean; -namespace TechbloxModdingAPI.Tasks +namespace GamecraftModdingAPI.Tasks { /// /// Asynchronous task scheduling for ISchedulables. @@ -20,7 +20,7 @@ namespace TechbloxModdingAPI.Tasks { get { - return RobocraftX.Schedulers.ClientLean.UIScheduler; + return RobocraftX.Schedulers.Lean.UIScheduler; } } @@ -28,13 +28,13 @@ namespace TechbloxModdingAPI.Tasks { get { - return RobocraftX.Schedulers.ClientExtraLean.UIScheduler; + return RobocraftX.Schedulers.ExtraLean.UIScheduler; } } - public static readonly Svelto.Tasks.ExtraLean.Unity.UpdateMonoRunner extraLeanRunner = new Svelto.Tasks.ExtraLean.Unity.UpdateMonoRunner("TechbloxModdingAPIExtraLean"); + public static readonly Svelto.Tasks.ExtraLean.Unity.UpdateMonoRunner extraLeanRunner = new Svelto.Tasks.ExtraLean.Unity.UpdateMonoRunner("GamecraftModdingAPIExtraLean"); - public static readonly Svelto.Tasks.Lean.Unity.UpdateMonoRunner leanRunner = new Svelto.Tasks.Lean.Unity.UpdateMonoRunner("TechbloxModdingAPILean"); + public static readonly Svelto.Tasks.Lean.Unity.UpdateMonoRunner leanRunner = new Svelto.Tasks.Lean.Unity.UpdateMonoRunner("GamecraftModdingAPILean"); /// /// Schedule a task to run asynchronously. @@ -42,7 +42,7 @@ namespace TechbloxModdingAPI.Tasks /// /// The task to run /// Schedule toRun on an extra lean runner? - /// Schedule toRun on Techblox's built-in UI task runner? + /// Schedule toRun on Gamecraft's built-in UI task runner? public static void Schedule(ISchedulable toRun, bool extraLean = false, bool ui = false) { if (extraLean) diff --git a/GamecraftModdingAPI/Tests/GamecraftModdingAPIPluginTest.cs b/GamecraftModdingAPI/Tests/GamecraftModdingAPIPluginTest.cs new file mode 100644 index 0000000..dac4312 --- /dev/null +++ b/GamecraftModdingAPI/Tests/GamecraftModdingAPIPluginTest.cs @@ -0,0 +1,150 @@ +using System; +using System.Reflection; + +using Harmony; +// test +using Svelto.ECS; +using RobocraftX.Blocks; +using RobocraftX.Common; +using RobocraftX.SimulationModeState; + +using GamecraftModdingAPI.Commands; +using GamecraftModdingAPI.Events; +using GamecraftModdingAPI.Utility; + +namespace GamecraftModdingAPI.Tests +{ + // unused by design + /// + /// Modding API implemented as a standalone IPA Plugin. + /// Ideally, GamecraftModdingAPI should be loaded by another mod; not itself + /// + public class GamecraftModdingAPIPluginTest +#if DEBUG + : IllusionPlugin.IEnhancedPlugin +#endif + { + private static HarmonyInstance harmony { get; set; } + + public string[] Filter { get; } = new string[] { "Gamecraft", "GamecraftPreview" }; + + public string Name { get; } = Assembly.GetExecutingAssembly().GetName().Name; + + public string Version { get; } = Assembly.GetExecutingAssembly().GetName().Version.ToString(); + + public string HarmonyID { get; } = "org.git.exmods.modtainers.gamecraftmoddingapi"; + + public void OnApplicationQuit() + { + GamecraftModdingAPI.Main.Shutdown(); + } + + public void OnApplicationStart() + { + FileLog.Reset(); + HarmonyInstance.DEBUG = true; + GamecraftModdingAPI.Main.Init(); + // in case Steam is not installed/running + // this will crash the game slightly later during startup + //SteamInitPatch.ForcePassSteamCheck = true; + // in case running in a VM + //MinimumSpecsCheckPatch.ForcePassMinimumSpecCheck = true; + // disable some Gamecraft analytics + //AnalyticsDisablerPatch.DisableAnalytics = true; + // disable background music + Logging.MetaDebugLog("Audio Mixers: "+string.Join(",", AudioTools.GetMixers())); + //AudioTools.SetVolume(0.0f, "Music"); // The game now sets this from settings again after this is called :( + + // debug/test handlers + EventManager.AddEventHandler(new SimpleEventHandlerEngine(() => { Logging.Log("App Inited event!"); }, () => { }, + EventType.ApplicationInitialized, "appinit API debug")); + EventManager.AddEventHandler(new SimpleEventHandlerEngine(() => { Logging.Log("Menu Activated event!"); }, + () => { Logging.Log("Menu Destroyed event!"); }, + EventType.Menu, "menuact API debug")); + EventManager.AddEventHandler(new SimpleEventHandlerEngine(() => { Logging.Log("Menu Switched To event!"); }, () => { }, + EventType.MenuSwitchedTo, "menuswitch API debug")); + EventManager.AddEventHandler(new SimpleEventHandlerEngine(() => { Logging.Log("Game Activated event!"); }, + () => { Logging.Log("Game Destroyed event!"); }, + EventType.Game, "gameact API debug")); + EventManager.AddEventHandler(new SimpleEventHandlerEngine(() => { Logging.Log("Game Reloaded event!"); }, () => { }, + EventType.GameReloaded, "gamerel API debug")); + EventManager.AddEventHandler(new SimpleEventHandlerEngine(() => { Logging.Log("Game Switched To event!"); }, () => { }, + EventType.GameSwitchedTo, "gameswitch API debug")); + EventManager.AddEventHandler(new SimpleEventHandlerEngine(() => { Logging.Log("Game Mode Simulation Switched To event!"); }, () => { }, + EventType.SimulationSwitchedTo, "simulationswitch API debug")); + EventManager.AddEventHandler(new SimpleEventHandlerEngine(() => { Logging.Log("Game Mode Build Switched To event!"); }, () => { }, + EventType.BuildSwitchedTo, "buildswitch API debug")); + + // debug/test commands + if (Dependency.Hell("ExtraCommands")) + { + CommandManager.AddCommand(new SimpleCustomCommandEngine(() => { UnityEngine.Application.Quit(); }, + "Exit", "Close Gamecraft without any prompts")); + CommandManager.AddCommand(new SimpleCustomCommandEngine((float d) => { UnityEngine.Camera.main.fieldOfView = d; }, + "SetFOV", "Set the player camera's field of view")); + CommandManager.AddCommand(new SimpleCustomCommandEngine( + (x, y, z) => { + bool success = GamecraftModdingAPI.Blocks.Movement.MoveConnectedBlocks( + GamecraftModdingAPI.Blocks.BlockIdentifiers.LatestBlockID, + new Unity.Mathematics.float3(x, y, z)); + if (!success) + { + GamecraftModdingAPI.Utility.Logging.CommandLogError("Blocks can only be moved in Build mode!"); + } + }, "MoveLastBlock", "Move the most-recently-placed block, and any connected blocks by the given offset")); + CommandManager.AddCommand(new SimpleCustomCommandEngine( + (x, y, z) => { Blocks.Placement.PlaceBlock(Blocks.BlockIDs.AluminiumCube, new Unity.Mathematics.float3(x, y, z)); }, + "PlaceAluminium", "Place a block of aluminium at the given coordinates")); + Analytics.DeltaDNAHelper.PlayerLifetimeParameters plp = new Analytics.DeltaDNAHelper.PlayerLifetimeParameters(); + CommandManager.AddCommand(new SimpleCustomCommandEngine( + (s) => { Analytics.DeltaDNAHelper.SendActionCompletedEvent(in plp, s.Replace(", ", " ")); }, + "SendAnalyticsAction", "Send an analytics action")); + System.Random random = new System.Random(); // for command below + CommandManager.AddCommand(new SimpleCustomCommandEngine( + () => { + if (!GameState.IsSimulationMode()) + { + Logging.CommandLogError("You must be in simulation mode for this to work!"); + return; + } + Tasks.Repeatable task = new Tasks.Repeatable(() => { + uint count = 0; + EGID[] eBlocks = Blocks.Signals.GetElectricBlocks(); + for (uint i = 0u; i < eBlocks.Length; i++) + { + uint[] ids = Blocks.Signals.GetSignalIDs(eBlocks[i]); + for (uint j = 0u; j < ids.Length; j++) + { + Blocks.Signals.SetSignalByID(ids[j], (float)random.NextDouble()); + count++; + } + } + Logging.MetaDebugLog($"Did the thing on {count} inputs"); + }, + () => { return GameState.IsSimulationMode(); }); + Tasks.Scheduler.Schedule(task); + }, "RandomizeSignalsInputs", "Do the thing")); + } + + // dependency test + if (Dependency.Hell("GamecraftScripting", new Version("0.0.1.0"))) + { + Logging.LogWarning("You're in GamecraftScripting dependency hell"); + } + else + { + Logging.Log("Compatible GamecraftScripting detected"); + } + } + + public void OnFixedUpdate() { } + + public void OnLateUpdate() { } + + public void OnLevelWasInitialized(int level) { } + + public void OnLevelWasLoaded(int level) { } + + public void OnUpdate() { } + } +} diff --git a/GamecraftModdingAPI/Utility/AnalyticsDisablerPatch.cs b/GamecraftModdingAPI/Utility/AnalyticsDisablerPatch.cs new file mode 100644 index 0000000..b18304a --- /dev/null +++ b/GamecraftModdingAPI/Utility/AnalyticsDisablerPatch.cs @@ -0,0 +1,38 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Reflection; + +using Analytics; +using Harmony; +using RobocraftX.Common; +using Svelto.ECS; + +namespace GamecraftModdingAPI.Utility +{ + /// + /// Patch of Analytics.AnalyticsCompositionRoot.Compose(...) + /// This stops some analytics collection built into Gamecraft. + /// DO NOT USE! (This will likely crash your game on shutdown) + /// + [HarmonyPatch] + class AnalyticsDisablerPatch + { + /// + /// Don't activate gameplay analytics? + /// + public static bool DisableAnalytics = false; + + public static bool Prefix(object contextHolder, EnginesRoot enginesRoot, RCXMode rcxMode) + { + return !DisableAnalytics; + } + + public static MethodBase TargetMethod(HarmonyInstance instance) + { + return typeof(Analytics.AnalyticsCompositionRoot).GetMethod("Compose").MakeGenericMethod(typeof(object)); + } + } +} diff --git a/GamecraftModdingAPI/Utility/ApiExclusiveGroups.cs b/GamecraftModdingAPI/Utility/ApiExclusiveGroups.cs new file mode 100644 index 0000000..df32418 --- /dev/null +++ b/GamecraftModdingAPI/Utility/ApiExclusiveGroups.cs @@ -0,0 +1,17 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +using Svelto.ECS; + +namespace GamecraftModdingAPI.Utility +{ + public static class ApiExclusiveGroups + { + public static readonly ExclusiveGroup eventsExclusiveGroup = new ExclusiveGroup(); + + public static uint eventID; + } +} diff --git a/TechbloxModdingAPI/Utility/AudioTools.cs b/GamecraftModdingAPI/Utility/AudioTools.cs similarity index 98% rename from TechbloxModdingAPI/Utility/AudioTools.cs rename to GamecraftModdingAPI/Utility/AudioTools.cs index 6f78feb..4d4af0d 100644 --- a/TechbloxModdingAPI/Utility/AudioTools.cs +++ b/GamecraftModdingAPI/Utility/AudioTools.cs @@ -7,7 +7,7 @@ using System.Threading.Tasks; using FMODUnity; using FMOD.Studio; -namespace TechbloxModdingAPI.Utility +namespace GamecraftModdingAPI.Utility { /// /// Common operations on audio objects diff --git a/GamecraftModdingAPI/Utility/Dependency.cs b/GamecraftModdingAPI/Utility/Dependency.cs new file mode 100644 index 0000000..c7dd64d --- /dev/null +++ b/GamecraftModdingAPI/Utility/Dependency.cs @@ -0,0 +1,79 @@ +using System; + +using IllusionInjector; +using IllusionPlugin; + +namespace GamecraftModdingAPI.Utility +{ + /// + /// Simple plugin interaction operations + /// + public static class Dependency + { + /// + /// Find a plugin by name + /// + /// The plugin. + /// The plugin's name. + public static IPlugin GetPlugin(string name) + { + foreach(IPlugin plugin in PluginManager.Plugins) + { + if (plugin.Name == name) + { + return plugin; + } + } + return null; + } + + /// + /// Gets the plugin version. + /// This gives priority to the plugin's Version string but falls back to the Assembly's version + /// + /// The plugin's version. + /// The plugin's name. + public static Version GetPluginVersion(string name) + { + IPlugin plugin = GetPlugin(name); + if (plugin != null) { + try + { + return new Version(plugin.Version); + } catch (Exception e) when ( + e is ArgumentException + || e is ArgumentNullException + || e is ArgumentOutOfRangeException + || e is FormatException + || e is OverflowException) {} + return plugin.GetType().Assembly.GetName().Version; + } + return null; + } + + // (I'm leaving the auto-generated version) + // + // Hell the specified name and version. + // + // The hell. + // Name. + // Version. + /// + /// Detect if you're in dependency hell with respect to the plugin. + /// ie Check if the plugin doesn't exist or is out of date. + /// When version is null, this only checks if the plugin exists. + /// The version is retrieved using GetPluginVersion(string name). + /// + /// Are you in dependency hell? + /// The plugin's name' + /// The target version. + public static bool Hell(string name, Version version = null) + { + Version pluginVersion = GetPluginVersion(name); + if (version == null) { + return pluginVersion == null; + } + return (pluginVersion == null || pluginVersion < version); + } + } +} diff --git a/TechbloxModdingAPI/Utility/FullGameFields.cs b/GamecraftModdingAPI/Utility/FullGameFields.cs similarity index 71% rename from TechbloxModdingAPI/Utility/FullGameFields.cs rename to GamecraftModdingAPI/Utility/FullGameFields.cs index f9eb6d1..d90ef44 100644 --- a/TechbloxModdingAPI/Utility/FullGameFields.cs +++ b/GamecraftModdingAPI/Utility/FullGameFields.cs @@ -1,34 +1,32 @@ -using DataLoader; -using HarmonyLib; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +using DataLoader; +using Harmony; using RobocraftX; -using RobocraftX.CR.MainGame; +using RobocraftX.Common.Utilities; using RobocraftX.GUI; using RobocraftX.Multiplayer; +using RobocraftX.Rendering; using Svelto.Context; -using Svelto.DataStructures; using Svelto.ECS; -using Svelto.ECS.GUI; -using Techblox.GameSelection; +using Svelto.ECS.Schedulers.Unity; using UnityEngine; using Unity.Entities; using Unity.Physics.Systems; -namespace TechbloxModdingAPI.Utility +namespace GamecraftModdingAPI.Utility { /// /// Public access to the private variables in RobocraftX.FullGameCompositionRoot /// public static class FullGameFields { - public static FullGameCompositionRoot Instance - { - private set; - get; - } = null; - public static MultiplayerInitParameters _multiplayerParams - { - get + { get { return (MultiplayerInitParameters)fgcr?.Field("_multiplayerParams").GetValue(); } @@ -66,6 +64,14 @@ namespace TechbloxModdingAPI.Utility } } + public static SimpleSubmissionEntityViewScheduler _mainGameSubmissionScheduler + { + get + { + return (SimpleSubmissionEntityViewScheduler)fgcr?.Field("_mainGameSubmissionScheduler").GetValue(); + } + } + public static BuildPhysicsWorld _physicsWorldSystem { get @@ -98,13 +104,21 @@ namespace TechbloxModdingAPI.Utility } } - /*public static UnityEntitySubmissionScheduler _frontEndSubmissionScheduler + public static PhysicsUtility _physicsUtility + { + get + { + return (PhysicsUtility)fgcr?.Field("_physicsUtility").GetValue(); + } + } + + public static UnityEntitySubmissionScheduler _frontEndSubmissionScheduler { get { return (UnityEntitySubmissionScheduler)fgcr?.Field("_frontEndSubmissionScheduler").GetValue(); } - }*/ + } public static LoadingScreenImplementer _loadingScreen { @@ -122,11 +136,11 @@ namespace TechbloxModdingAPI.Utility } } - public static ECSMainGameResourceManagers _managers + public static ECSGameObjectResourceManager _eCsGameObjectResourceManager { get { - return (ECSMainGameResourceManagers)fgcr?.Field("_gameManagers").GetValue(); + return (ECSGameObjectResourceManager)fgcr?.Field("_eCsGameObjectResourceManager").GetValue(); } } @@ -138,36 +152,11 @@ namespace TechbloxModdingAPI.Utility } } - public static FasterList _deserialisedBlockMap - { - get - { - return (FasterList) fgcr?.Field("_deserialisedBlockMap").GetValue(); - } - } - - public static SveltoGUI _frontEndGUI - { - get - { - return (SveltoGUI)fgcr?.Field("_frontEndGUI").GetValue(); - } - } - - public static GameSelectionData _gameSelectionData - { - get - { - return (GameSelectionData)fgcr?.Field("_gameSelectionData").GetValue(); - } - } - private static Traverse fgcr; public static void Init(FullGameCompositionRoot instance) { fgcr = new Traverse(instance); - FullGameFields.Instance = instance; } } } diff --git a/TechbloxModdingAPI/Utility/GameEngineManager.cs b/GamecraftModdingAPI/Utility/GameEngineManager.cs similarity index 54% rename from TechbloxModdingAPI/Utility/GameEngineManager.cs rename to GamecraftModdingAPI/Utility/GameEngineManager.cs index 04b0da7..5a52fd0 100644 --- a/TechbloxModdingAPI/Utility/GameEngineManager.cs +++ b/GamecraftModdingAPI/Utility/GameEngineManager.cs @@ -1,11 +1,12 @@ -using System.Collections.Generic; +using System; +using System.Collections.Generic; using System.Linq; +using System.Text; +using System.Threading.Tasks; -using RobocraftX.StateSync; using Svelto.ECS; -using TechbloxModdingAPI.Engines; -namespace TechbloxModdingAPI.Utility +namespace GamecraftModdingAPI.Utility { /// /// Keeps track of custom game-modifying engines @@ -23,10 +24,6 @@ namespace TechbloxModdingAPI.Utility { Logging.MetaDebugLog($"Registering Game IApiEngine {engine.Name}"); _lastEngineRoot.AddEngine(engine); - if (engine is IFactoryEngine factoryEngine) - factoryEngine.Factory = _lastEngineRoot.GenerateEntityFactory(); - if (engine is IFunEngine funEngine) - funEngine.Functions = _lastEngineRoot.GenerateEntityFunctions(); } } @@ -52,29 +49,16 @@ namespace TechbloxModdingAPI.Utility public static void RemoveGameEngine(string name) { - if (_gameEngines[name].isRemovable) - { - _gameEngines.Remove(name); - } + _gameEngines.Remove(name); } - public static void RegisterEngines(StateSyncRegistrationHelper helper) + public static void RegisterEngines(EnginesRoot enginesRoot) { - var enginesRoot = helper.enginesRoot; _lastEngineRoot = enginesRoot; - IEntityFactory factory = enginesRoot.GenerateEntityFactory(); - IEntityFunctions functions = enginesRoot.GenerateEntityFunctions(); foreach (var key in _gameEngines.Keys) { Logging.MetaDebugLog($"Registering Game IApiEngine {_gameEngines[key].Name}"); - if (_gameEngines[key] is IDeterministicEngine detEngine) - helper.AddDeterministicEngine(detEngine); - else - enginesRoot.AddEngine(_gameEngines[key]); - if (_gameEngines[key] is IFactoryEngine factEngine) - factEngine.Factory = factory; - if (_gameEngines[key] is IFunEngine funEngine) - funEngine.Functions = functions; + enginesRoot.AddEngine(_gameEngines[key]); } } } diff --git a/TechbloxModdingAPI/Utility/GameState.cs b/GamecraftModdingAPI/Utility/GameState.cs similarity index 85% rename from TechbloxModdingAPI/Utility/GameState.cs rename to GamecraftModdingAPI/Utility/GameState.cs index 79a72fe..ed096c4 100644 --- a/TechbloxModdingAPI/Utility/GameState.cs +++ b/GamecraftModdingAPI/Utility/GameState.cs @@ -4,10 +4,10 @@ using System.Linq; using System.Text; using System.Threading.Tasks; -namespace TechbloxModdingAPI.Utility +namespace GamecraftModdingAPI.Utility { /// - /// Utility to get the state of the current Techblox game + /// Utility to get the state of the current Gamecraft game /// public static class GameState { @@ -34,7 +34,7 @@ namespace TechbloxModdingAPI.Utility /// /// Is a game loaded? /// - /// Whether Techblox has a game open (false = Main Menu) + /// Whether Gamecraft has a game open (false = Main Menu) public static bool IsInGame() { return gameEngine.IsInGame; diff --git a/TechbloxModdingAPI/Utility/GameStateEngine.cs b/GamecraftModdingAPI/Utility/GameStateEngine.cs similarity index 64% rename from TechbloxModdingAPI/Utility/GameStateEngine.cs rename to GamecraftModdingAPI/Utility/GameStateEngine.cs index 936a8ef..55c0de2 100644 --- a/TechbloxModdingAPI/Utility/GameStateEngine.cs +++ b/GamecraftModdingAPI/Utility/GameStateEngine.cs @@ -6,13 +6,12 @@ using System.Text; using System.Threading.Tasks; using RobocraftX.SimulationModeState; -using TechbloxModdingAPI.Engines; -namespace TechbloxModdingAPI.Utility +namespace GamecraftModdingAPI.Utility { class GameStateEngine : IApiEngine { - public string Name { get; } = "TechbloxModdingAPIGameStateGameEngine"; + public string Name { get; } = "GamecraftModdingAPIGameStateGameEngine"; public EntitiesDB entitiesDB { set; private get; } @@ -20,9 +19,7 @@ namespace TechbloxModdingAPI.Utility public bool IsInGame { get { return _isInGame; } } - public bool isRemovable => false; - - public void Dispose() + public void Dispose() { _isInGame = false; } @@ -34,12 +31,12 @@ namespace TechbloxModdingAPI.Utility public bool IsBuildMode() { - return _isInGame && TimeRunningModeUtil.IsTimeStoppedMode(entitiesDB); + return _isInGame && SimModeUtil.IsBuildMode(entitiesDB); } public bool IsSimulationMode() { - return _isInGame && TimeRunningModeUtil.IsTimeRunningMode(entitiesDB); + return _isInGame && SimModeUtil.IsSimulationMode(entitiesDB); } } diff --git a/TechbloxModdingAPI/Engines/IApiEngine.cs b/GamecraftModdingAPI/Utility/IApiEngine.cs similarity index 58% rename from TechbloxModdingAPI/Engines/IApiEngine.cs rename to GamecraftModdingAPI/Utility/IApiEngine.cs index 6a8519a..0dd3e78 100644 --- a/TechbloxModdingAPI/Engines/IApiEngine.cs +++ b/GamecraftModdingAPI/Utility/IApiEngine.cs @@ -6,10 +6,10 @@ using System.Threading.Tasks; using Svelto.ECS; -namespace TechbloxModdingAPI.Engines +namespace GamecraftModdingAPI.Utility { /// - /// Base engine interface used by all TechbloxModdingAPI engines + /// Base engine interface used by all GamecraftModdingAPI engines /// public interface IApiEngine : IEngine, IQueryingEntitiesEngine, IDisposable { @@ -17,10 +17,5 @@ namespace TechbloxModdingAPI.Engines /// The name of the engine /// string Name { get; } - - /// - /// Whether the emitter can be removed with Manager.RemoveEventEmitter(name) - /// - bool isRemovable { get; } } } diff --git a/TechbloxModdingAPI/Utility/Logging.cs b/GamecraftModdingAPI/Utility/Logging.cs similarity index 78% rename from TechbloxModdingAPI/Utility/Logging.cs rename to GamecraftModdingAPI/Utility/Logging.cs index 0147eff..20c17cf 100644 --- a/TechbloxModdingAPI/Utility/Logging.cs +++ b/GamecraftModdingAPI/Utility/Logging.cs @@ -6,11 +6,11 @@ using System.Linq; using System.Text; using System.Threading.Tasks; -namespace TechbloxModdingAPI.Utility +namespace GamecraftModdingAPI.Utility { /// - /// Utility class to access Techblox's built-in logging capabilities. - /// The log is saved to %APPDATA%\..\LocalLow\FreeJam\Techblox\Player.Log + /// Utility class to access Gamecraft's built-in logging capabilities. + /// The log is saved to %APPDATA%\..\LocalLow\FreeJam\Gamecraft\Player.Log /// public static class Logging { @@ -21,7 +21,7 @@ namespace TechbloxModdingAPI.Utility } /// - /// Write a regular message to Techblox's log + /// Write a regular message to Gamecraft's log /// /// The object to log [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -37,7 +37,7 @@ namespace TechbloxModdingAPI.Utility } /// - /// Write a debug message to Techblox's log + /// Write a debug message to Gamecraft's log /// /// The object to log [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -53,7 +53,7 @@ namespace TechbloxModdingAPI.Utility } /// - /// Write a debug message and object to Techblox's log + /// Write a debug message and object to Gamecraft's log /// The reason this method exists in Svelto.Console is beyond my understanding /// /// The type of the extra debug object @@ -72,7 +72,7 @@ namespace TechbloxModdingAPI.Utility } /// - /// Write an error message to Techblox's log + /// Write an error message to Gamecraft's log /// /// The object to log /// The extra data to pass to the ILogger @@ -83,7 +83,7 @@ namespace TechbloxModdingAPI.Utility } /// - /// Write an exception to Techblox's log and to the screen and exit game + /// Write an exception to Gamecraft's log /// /// The exception to log /// The extra data to pass to the ILogger. @@ -95,7 +95,7 @@ namespace TechbloxModdingAPI.Utility } /// - /// Write an exception message to Techblox's log and to the screen and exit game + /// Write an exception message to Gamecraft's log /// /// The object to log /// The exception to log @@ -114,7 +114,7 @@ namespace TechbloxModdingAPI.Utility } /// - /// Write a warning message to Techblox's log + /// Write a warning message to Gamecraft's log /// /// The object to log [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -123,10 +123,28 @@ namespace TechbloxModdingAPI.Utility Svelto.Console.LogWarning(obj.ToString()); } + [Obsolete("SystemLog was removed from Svelto.Common")] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void SystemLog(string msg) + { + Svelto.Console.Log(msg); + } + + /// + /// Write a message to stdout (ie the terminal, like Command Prompt or PowerShell) + /// + /// The object to log + [Obsolete("SystemLog was removed from Svelto.Common")] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void SystemLog(object obj) + { + Svelto.Console.Log(obj.ToString()); + } + // descriptive logging /// - /// Write a descriptive message to Techblox's log only when the API is a Debug build + /// Write a descriptive message to Gamecraft's log only when the API is a Debug build /// /// The object to log [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -138,7 +156,7 @@ namespace TechbloxModdingAPI.Utility } /// - /// Write a descriptive message to Techblox's log including the current time and the calling method's name + /// Write a descriptive message to Gamecraft's log including the current time and the calling method's name /// /// The object to log [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -151,7 +169,7 @@ namespace TechbloxModdingAPI.Utility // CLI logging /// - /// Write a message to Techblox's command line + /// Write a message to Gamecraft's command line /// /// The object to log [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -163,11 +181,11 @@ namespace TechbloxModdingAPI.Utility [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void CommandLog(string msg) { - Log(msg); + uREPL.Log.Output(msg); } /// - /// Write an error message to Techblox's command line + /// Write an error message to Gamecraft's command line /// /// The object to log [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -179,11 +197,11 @@ namespace TechbloxModdingAPI.Utility [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void CommandLogError(string msg) { - LogError(msg); + uREPL.Log.Error(msg); } /// - /// Write a warning message to Techblox's command line + /// Write a warning message to Gamecraft's command line /// /// The object to log [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -195,7 +213,7 @@ namespace TechbloxModdingAPI.Utility [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void CommandLogWarning(string msg) { - LogWarning(msg); + uREPL.Log.Warn(msg); } } diff --git a/TechbloxModdingAPI/Utility/MenuEngineManager.cs b/GamecraftModdingAPI/Utility/MenuEngineManager.cs similarity index 69% rename from TechbloxModdingAPI/Utility/MenuEngineManager.cs rename to GamecraftModdingAPI/Utility/MenuEngineManager.cs index 4358ca8..b5d7be1 100644 --- a/TechbloxModdingAPI/Utility/MenuEngineManager.cs +++ b/GamecraftModdingAPI/Utility/MenuEngineManager.cs @@ -5,9 +5,8 @@ using System.Text; using System.Threading.Tasks; using Svelto.ECS; -using TechbloxModdingAPI.Engines; -namespace TechbloxModdingAPI.Utility +namespace GamecraftModdingAPI.Utility { /// /// Keeps track of custom menu-modifying engines @@ -26,10 +25,6 @@ namespace TechbloxModdingAPI.Utility { Logging.MetaDebugLog($"Registering Menu IApiEngine {engine.Name}"); _lastEngineRoot.AddEngine(engine); - if (engine is IFactoryEngine factoryEngine) - factoryEngine.Factory = _lastEngineRoot.GenerateEntityFactory(); - if (engine is IFunEngine funEngine) - funEngine.Functions = _lastEngineRoot.GenerateEntityFunctions(); } } @@ -55,23 +50,16 @@ namespace TechbloxModdingAPI.Utility public static void RemoveMenuEngine(string name) { - if (_menuEngines[name].isRemovable) - { - _menuEngines.Remove(name); - } + _menuEngines.Remove(name); } public static void RegisterEngines(EnginesRoot enginesRoot) { _lastEngineRoot = enginesRoot; - IEntityFactory factory = enginesRoot.GenerateEntityFactory(); - IEntityFunctions functions = enginesRoot.GenerateEntityFunctions(); foreach (var key in _menuEngines.Keys) { Logging.MetaDebugLog($"Registering Menu IApiEngine {_menuEngines[key].Name}"); enginesRoot.AddEngine(_menuEngines[key]); - if (_menuEngines[key] is IFactoryEngine factEngine) factEngine.Factory = factory; - if(_menuEngines[key] is IFunEngine funEngine) funEngine.Functions = functions; } } } diff --git a/GamecraftModdingAPI/Utility/MinimumSpecsCheckPatch.cs b/GamecraftModdingAPI/Utility/MinimumSpecsCheckPatch.cs new file mode 100644 index 0000000..739c232 --- /dev/null +++ b/GamecraftModdingAPI/Utility/MinimumSpecsCheckPatch.cs @@ -0,0 +1,28 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +using Harmony; +using RobocraftX.FrontEnd; + +namespace GamecraftModdingAPI.Utility +{ + /// + /// Patch of bool RobocraftX.FrontEnd.MinimumSpecsCheck.CheckRequirementsMet() + /// + [HarmonyPatch(typeof(MinimumSpecsCheck), "CheckRequirementsMet")] + class MinimumSpecsCheckPatch + { + /// + /// Ignore result of the requirement check? + /// + public static bool ForcePassMinimumSpecCheck = false; + + public static void Postfix(ref bool __result) + { + __result = __result || ForcePassMinimumSpecCheck; + } + } +} diff --git a/GamecraftModdingAPI/Utility/SteamInitPatch.cs b/GamecraftModdingAPI/Utility/SteamInitPatch.cs new file mode 100644 index 0000000..c57b4e8 --- /dev/null +++ b/GamecraftModdingAPI/Utility/SteamInitPatch.cs @@ -0,0 +1,30 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +using Harmony; +using RobocraftX.Common; + +namespace GamecraftModdingAPI.Utility +{ + /// + /// Patch of bool RobocraftX.Common.SteamManager.VerifyOrInit() + /// This does not let you run Gamecraft without Steam. + /// DO NOT USE! + /// + [HarmonyPatch(typeof(SteamManager), "VerifyOrInit")] + class SteamInitPatch + { + /// + /// Ignore the result of steam initialization? + /// + public static bool ForcePassSteamCheck = false; + + public static void Postfix(ref bool __result) + { + __result = __result || ForcePassSteamCheck; + } + } +} diff --git a/MakeEverythingPublicInGame/MakeEverythingPublicInGame.csproj b/MakeEverythingPublicInGame/MakeEverythingPublicInGame.csproj deleted file mode 100644 index dde2177..0000000 --- a/MakeEverythingPublicInGame/MakeEverythingPublicInGame.csproj +++ /dev/null @@ -1,1574 +0,0 @@ - - - - Exe - net6.0 - enable - enable - - - - - - - - - - ..\ref_TB\Techblox_Data\Managed\IllusionInjector.dll - ..\..\ref_TB\Techblox_Data\Managed\IllusionInjector.dll - - - ..\ref_TB\Techblox_Data\Managed\IllusionPlugin.dll - ..\..\ref_TB\Techblox_Data\Managed\IllusionPlugin.dll - - - ..\ref_TB\Techblox_Data\Managed\Accessibility.dll - ..\..\ref_TB\Techblox_Data\Managed\Accessibility.dll - - - ..\ref_TB\Techblox_Data\Managed\Analytics.dll - ..\..\ref_TB\Techblox_Data\Managed\Analytics.dll - - - ..\ref_TB\Techblox_Data\Managed\Assembly-CSharp-firstpass.dll - ..\..\ref_TB\Techblox_Data\Managed\Assembly-CSharp-firstpass.dll - - - ..\ref_TB\Techblox_Data\Managed\Assembly-CSharp.dll - ..\..\ref_TB\Techblox_Data\Managed\Assembly-CSharp.dll - - - ..\ref_TB\Techblox_Data\Managed\AWSSDK.Core.dll - ..\..\ref_TB\Techblox_Data\Managed\AWSSDK.Core.dll - - - ..\ref_TB\Techblox_Data\Managed\AWSSDK.GameLift.dll - ..\..\ref_TB\Techblox_Data\Managed\AWSSDK.GameLift.dll - - - ..\ref_TB\Techblox_Data\Managed\BevelEffect.dll - ..\..\ref_TB\Techblox_Data\Managed\BevelEffect.dll - - - ..\ref_TB\Techblox_Data\Managed\Boxophobic.TheVehetationEngine.Runtime.dll - ..\..\ref_TB\Techblox_Data\Managed\Boxophobic.TheVehetationEngine.Runtime.dll - - - ..\ref_TB\Techblox_Data\Managed\Boxophobic.Utils.Scripts.dll - ..\..\ref_TB\Techblox_Data\Managed\Boxophobic.Utils.Scripts.dll - - - ..\ref_TB\Techblox_Data\Managed\DataLoader.dll - ..\..\ref_TB\Techblox_Data\Managed\DataLoader.dll - - - ..\ref_TB\Techblox_Data\Managed\DDNA.dll - ..\..\ref_TB\Techblox_Data\Managed\DDNA.dll - - - ..\ref_TB\Techblox_Data\Managed\EasyButtons.dll - ..\..\ref_TB\Techblox_Data\Managed\EasyButtons.dll - - - ..\ref_TB\Techblox_Data\Managed\EOSSDK.dll - ..\..\ref_TB\Techblox_Data\Managed\EOSSDK.dll - - - ..\ref_TB\Techblox_Data\Managed\FMODUnity.dll - ..\..\ref_TB\Techblox_Data\Managed\FMODUnity.dll - - - ..\ref_TB\Techblox_Data\Managed\FMODUnityResonance.dll - ..\..\ref_TB\Techblox_Data\Managed\FMODUnityResonance.dll - - - ..\ref_TB\Techblox_Data\Managed\FMODUnityWrapperClient.dll - ..\..\ref_TB\Techblox_Data\Managed\FMODUnityWrapperClient.dll - - - ..\ref_TB\Techblox_Data\Managed\FullGame.dll - ..\..\ref_TB\Techblox_Data\Managed\FullGame.dll - - - ..\ref_TB\Techblox_Data\Managed\Gamecraft.BlockEntityFactory.dll - ..\..\ref_TB\Techblox_Data\Managed\Gamecraft.BlockEntityFactory.dll - - - ..\ref_TB\Techblox_Data\Managed\Gamecraft.BlockGroups.dll - ..\..\ref_TB\Techblox_Data\Managed\Gamecraft.BlockGroups.dll - - - ..\ref_TB\Techblox_Data\Managed\Gamecraft.Blocks.LogicBlock.dll - ..\..\ref_TB\Techblox_Data\Managed\Gamecraft.Blocks.LogicBlock.dll - - - ..\ref_TB\Techblox_Data\Managed\Gamecraft.BlocksEntityDescriptors.dll - ..\..\ref_TB\Techblox_Data\Managed\Gamecraft.BlocksEntityDescriptors.dll - - - ..\ref_TB\Techblox_Data\Managed\Gamecraft.ColourPalette.dll - ..\..\ref_TB\Techblox_Data\Managed\Gamecraft.ColourPalette.dll - - - ..\ref_TB\Techblox_Data\Managed\Gamecraft.Damage.dll - ..\..\ref_TB\Techblox_Data\Managed\Gamecraft.Damage.dll - - - ..\ref_TB\Techblox_Data\Managed\Gamecraft.Effects.dll - ..\..\ref_TB\Techblox_Data\Managed\Gamecraft.Effects.dll - - - ..\ref_TB\Techblox_Data\Managed\Gamecraft.ExplosionFragments.dll - ..\..\ref_TB\Techblox_Data\Managed\Gamecraft.ExplosionFragments.dll - - - ..\ref_TB\Techblox_Data\Managed\Gamecraft.GraphicsSettings.dll - ..\..\ref_TB\Techblox_Data\Managed\Gamecraft.GraphicsSettings.dll - - - ..\ref_TB\Techblox_Data\Managed\Gamecraft.GUI.BlueprintInventory.dll - ..\..\ref_TB\Techblox_Data\Managed\Gamecraft.GUI.BlueprintInventory.dll - - - ..\ref_TB\Techblox_Data\Managed\Gamecraft.GUI.Blueprints.dll - ..\..\ref_TB\Techblox_Data\Managed\Gamecraft.GUI.Blueprints.dll - - - ..\ref_TB\Techblox_Data\Managed\Gamecraft.GUI.BlueprintSets.dll - ..\..\ref_TB\Techblox_Data\Managed\Gamecraft.GUI.BlueprintSets.dll - - - ..\ref_TB\Techblox_Data\Managed\Gamecraft.GUI.GameOptionsScreen.dll - ..\..\ref_TB\Techblox_Data\Managed\Gamecraft.GUI.GameOptionsScreen.dll - - - ..\ref_TB\Techblox_Data\Managed\Gamecraft.GUI.GraphicsScreen.dll - ..\..\ref_TB\Techblox_Data\Managed\Gamecraft.GUI.GraphicsScreen.dll - - - ..\ref_TB\Techblox_Data\Managed\Gamecraft.GUI.Hotbar.Blocks.dll - ..\..\ref_TB\Techblox_Data\Managed\Gamecraft.GUI.Hotbar.Blocks.dll - - - ..\ref_TB\Techblox_Data\Managed\Gamecraft.GUI.Hotbar.BlueprintsHotbar.dll - ..\..\ref_TB\Techblox_Data\Managed\Gamecraft.GUI.Hotbar.BlueprintsHotbar.dll - - - ..\ref_TB\Techblox_Data\Managed\Gamecraft.GUI.Hotbar.Colours.dll - ..\..\ref_TB\Techblox_Data\Managed\Gamecraft.GUI.Hotbar.Colours.dll - - - ..\ref_TB\Techblox_Data\Managed\Gamecraft.GUI.ModeBar.dll - ..\..\ref_TB\Techblox_Data\Managed\Gamecraft.GUI.ModeBar.dll - - - ..\ref_TB\Techblox_Data\Managed\Gamecraft.GUI.OptionsScreen.dll - ..\..\ref_TB\Techblox_Data\Managed\Gamecraft.GUI.OptionsScreen.dll - - - ..\ref_TB\Techblox_Data\Managed\Gamecraft.GUI.TabsBar.Blocks.dll - ..\..\ref_TB\Techblox_Data\Managed\Gamecraft.GUI.TabsBar.Blocks.dll - - - ..\ref_TB\Techblox_Data\Managed\Gamecraft.GUI.TabsBar.Blueprints.dll - ..\..\ref_TB\Techblox_Data\Managed\Gamecraft.GUI.TabsBar.Blueprints.dll - - - ..\ref_TB\Techblox_Data\Managed\Gamecraft.GUI.TabsBar.Colours.dll - ..\..\ref_TB\Techblox_Data\Managed\Gamecraft.GUI.TabsBar.Colours.dll - - - ..\ref_TB\Techblox_Data\Managed\Gamecraft.GUI.TabsBar.Common.dll - ..\..\ref_TB\Techblox_Data\Managed\Gamecraft.GUI.TabsBar.Common.dll - - - ..\ref_TB\Techblox_Data\Managed\Gamecraft.GUI.Tweaks.dll - ..\..\ref_TB\Techblox_Data\Managed\Gamecraft.GUI.Tweaks.dll - - - ..\ref_TB\Techblox_Data\Managed\Gamecraft.GUI.Wires.dll - ..\..\ref_TB\Techblox_Data\Managed\Gamecraft.GUI.Wires.dll - - - ..\ref_TB\Techblox_Data\Managed\Gamecraft.GUI.WorldSpaceGuis.dll - ..\..\ref_TB\Techblox_Data\Managed\Gamecraft.GUI.WorldSpaceGuis.dll - - - ..\ref_TB\Techblox_Data\Managed\Gamecraft.JointBlocks.dll - ..\..\ref_TB\Techblox_Data\Managed\Gamecraft.JointBlocks.dll - - - ..\ref_TB\Techblox_Data\Managed\Gamecraft.Music.dll - ..\..\ref_TB\Techblox_Data\Managed\Gamecraft.Music.dll - - - ..\ref_TB\Techblox_Data\Managed\Gamecraft.NetStrings.dll - ..\..\ref_TB\Techblox_Data\Managed\Gamecraft.NetStrings.dll - - - ..\ref_TB\Techblox_Data\Managed\Gamecraft.PickupsCommon.dll - ..\..\ref_TB\Techblox_Data\Managed\Gamecraft.PickupsCommon.dll - - - ..\ref_TB\Techblox_Data\Managed\Gamecraft.PopupMessage.dll - ..\..\ref_TB\Techblox_Data\Managed\Gamecraft.PopupMessage.dll - - - ..\ref_TB\Techblox_Data\Managed\Gamecraft.Serialization.dll - ..\..\ref_TB\Techblox_Data\Managed\Gamecraft.Serialization.dll - - - ..\ref_TB\Techblox_Data\Managed\Gamecraft.Tweaks.dll - ..\..\ref_TB\Techblox_Data\Managed\Gamecraft.Tweaks.dll - - - ..\ref_TB\Techblox_Data\Managed\Gamecraft.VisualEffects.Decals.dll - ..\..\ref_TB\Techblox_Data\Managed\Gamecraft.VisualEffects.Decals.dll - - - ..\ref_TB\Techblox_Data\Managed\Gamecraft.Wires.dll - ..\..\ref_TB\Techblox_Data\Managed\Gamecraft.Wires.dll - - - ..\ref_TB\Techblox_Data\Managed\GameLiftServerSDKNet45.dll - ..\..\ref_TB\Techblox_Data\Managed\GameLiftServerSDKNet45.dll - - - ..\ref_TB\Techblox_Data\Managed\GameState.dll - ..\..\ref_TB\Techblox_Data\Managed\GameState.dll - - - ..\ref_TB\Techblox_Data\Managed\GhostShark.Outline.dll - ..\..\ref_TB\Techblox_Data\Managed\GhostShark.Outline.dll - - - ..\ref_TB\Techblox_Data\Managed\Google.Protobuf.dll - ..\..\ref_TB\Techblox_Data\Managed\Google.Protobuf.dll - - - ..\ref_TB\Techblox_Data\Managed\GPUInstancer.CrowdAnimations.dll - ..\..\ref_TB\Techblox_Data\Managed\GPUInstancer.CrowdAnimations.dll - - - ..\ref_TB\Techblox_Data\Managed\GPUInstancer.dll - ..\..\ref_TB\Techblox_Data\Managed\GPUInstancer.dll - - - ..\ref_TB\Techblox_Data\Managed\Havok.Physics.dll - ..\..\ref_TB\Techblox_Data\Managed\Havok.Physics.dll - - - ..\ref_TB\Techblox_Data\Managed\Havok.Physics.Hybrid.dll - ..\..\ref_TB\Techblox_Data\Managed\Havok.Physics.Hybrid.dll - - - ..\ref_TB\Techblox_Data\Managed\LiteNetLib.dll - ..\..\ref_TB\Techblox_Data\Managed\LiteNetLib.dll - - - ..\ref_TB\Techblox_Data\Managed\log4net.dll - ..\..\ref_TB\Techblox_Data\Managed\log4net.dll - - - ..\ref_TB\Techblox_Data\Managed\LZ4.dll - ..\..\ref_TB\Techblox_Data\Managed\LZ4.dll - - - ..\ref_TB\Techblox_Data\Managed\Monobehaviours.dll - ..\..\ref_TB\Techblox_Data\Managed\Monobehaviours.dll - - - ..\ref_TB\Techblox_Data\Managed\mscorlib.dll - ..\..\ref_TB\Techblox_Data\Managed\mscorlib.dll - - - ..\ref_TB\Techblox_Data\Managed\MultiplayerNetworking.dll - ..\..\ref_TB\Techblox_Data\Managed\MultiplayerNetworking.dll - - - ..\ref_TB\Techblox_Data\Managed\Newtonsoft.Json.dll - ..\..\ref_TB\Techblox_Data\Managed\Newtonsoft.Json.dll - - - ..\ref_TB\Techblox_Data\Managed\Novell.Directory.Ldap.dll - ..\..\ref_TB\Techblox_Data\Managed\Novell.Directory.Ldap.dll - - - ..\ref_TB\Techblox_Data\Managed\Prometheus.NetStandard.dll - ..\..\ref_TB\Techblox_Data\Managed\Prometheus.NetStandard.dll - - - ..\ref_TB\Techblox_Data\Managed\RCX.ScreenshotTaker.dll - ..\..\ref_TB\Techblox_Data\Managed\RCX.ScreenshotTaker.dll - - - ..\ref_TB\Techblox_Data\Managed\Rewired_Core.dll - ..\..\ref_TB\Techblox_Data\Managed\Rewired_Core.dll - - - ..\ref_TB\Techblox_Data\Managed\Rewired_Windows.dll - ..\..\ref_TB\Techblox_Data\Managed\Rewired_Windows.dll - - - ..\ref_TB\Techblox_Data\Managed\RichFX.dll - ..\..\ref_TB\Techblox_Data\Managed\RichFX.dll - - - ..\ref_TB\Techblox_Data\Managed\RobocraftECS.dll - ..\..\ref_TB\Techblox_Data\Managed\RobocraftECS.dll - - - ..\ref_TB\Techblox_Data\Managed\RobocraftX.AccountPreferences.dll - ..\..\ref_TB\Techblox_Data\Managed\RobocraftX.AccountPreferences.dll - - - ..\ref_TB\Techblox_Data\Managed\RobocraftX.Blocks.dll - ..\..\ref_TB\Techblox_Data\Managed\RobocraftX.Blocks.dll - - - ..\ref_TB\Techblox_Data\Managed\RobocraftX.Blocks.Ghost.dll - ..\..\ref_TB\Techblox_Data\Managed\RobocraftX.Blocks.Ghost.dll - - - ..\ref_TB\Techblox_Data\Managed\RobocraftX.Blocks.Triggers.dll - ..\..\ref_TB\Techblox_Data\Managed\RobocraftX.Blocks.Triggers.dll - - - ..\ref_TB\Techblox_Data\Managed\RobocraftX.Building.BoxSelect.dll - ..\..\ref_TB\Techblox_Data\Managed\RobocraftX.Building.BoxSelect.dll - - - ..\ref_TB\Techblox_Data\Managed\RobocraftX.Building.Jobs.dll - ..\..\ref_TB\Techblox_Data\Managed\RobocraftX.Building.Jobs.dll - - - ..\ref_TB\Techblox_Data\Managed\RobocraftX.Character.Audio.dll - ..\..\ref_TB\Techblox_Data\Managed\RobocraftX.Character.Audio.dll - - - ..\ref_TB\Techblox_Data\Managed\RobocraftX.Character.dll - ..\..\ref_TB\Techblox_Data\Managed\RobocraftX.Character.dll - - - ..\ref_TB\Techblox_Data\Managed\RobocraftX.Common.dll - ..\..\ref_TB\Techblox_Data\Managed\RobocraftX.Common.dll - - - ..\ref_TB\Techblox_Data\Managed\RobocraftX.ControlsScreen.dll - ..\..\ref_TB\Techblox_Data\Managed\RobocraftX.ControlsScreen.dll - - - ..\ref_TB\Techblox_Data\Managed\RobocraftX.Crosshair.dll - ..\..\ref_TB\Techblox_Data\Managed\RobocraftX.Crosshair.dll - - - ..\ref_TB\Techblox_Data\Managed\RobocraftX.FrontEnd.dll - ..\..\ref_TB\Techblox_Data\Managed\RobocraftX.FrontEnd.dll - - - ..\ref_TB\Techblox_Data\Managed\RobocraftX.GUI.DebugDisplay.dll - ..\..\ref_TB\Techblox_Data\Managed\RobocraftX.GUI.DebugDisplay.dll - - - ..\ref_TB\Techblox_Data\Managed\RobocraftX.GUI.dll - ..\..\ref_TB\Techblox_Data\Managed\RobocraftX.GUI.dll - - - ..\ref_TB\Techblox_Data\Managed\RobocraftX.GUI.Hotbar.dll - ..\..\ref_TB\Techblox_Data\Managed\RobocraftX.GUI.Hotbar.dll - - - ..\ref_TB\Techblox_Data\Managed\RobocraftX.GUI.Inventory.BlocksInventory.dll - ..\..\ref_TB\Techblox_Data\Managed\RobocraftX.GUI.Inventory.BlocksInventory.dll - - - ..\ref_TB\Techblox_Data\Managed\RobocraftX.GUI.Inventory.ColourInventory.dll - ..\..\ref_TB\Techblox_Data\Managed\RobocraftX.GUI.Inventory.ColourInventory.dll - - - ..\ref_TB\Techblox_Data\Managed\RobocraftX.GUI.Inventory.dll - ..\..\ref_TB\Techblox_Data\Managed\RobocraftX.GUI.Inventory.dll - - - ..\ref_TB\Techblox_Data\Managed\RobocraftX.GUI.QuitConfirmation.dll - ..\..\ref_TB\Techblox_Data\Managed\RobocraftX.GUI.QuitConfirmation.dll - - - ..\ref_TB\Techblox_Data\Managed\RobocraftX.GUI.ScaleGhost.dll - ..\..\ref_TB\Techblox_Data\Managed\RobocraftX.GUI.ScaleGhost.dll - - - ..\ref_TB\Techblox_Data\Managed\RobocraftX.GUI.TabsBar.dll - ..\..\ref_TB\Techblox_Data\Managed\RobocraftX.GUI.TabsBar.dll - - - ..\ref_TB\Techblox_Data\Managed\RobocraftX.Input.dll - ..\..\ref_TB\Techblox_Data\Managed\RobocraftX.Input.dll - - - ..\ref_TB\Techblox_Data\Managed\RobocraftX.MachineEditor.dll - ..\..\ref_TB\Techblox_Data\Managed\RobocraftX.MachineEditor.dll - - - ..\ref_TB\Techblox_Data\Managed\RobocraftX.MainGame.dll - ..\..\ref_TB\Techblox_Data\Managed\RobocraftX.MainGame.dll - - - ..\ref_TB\Techblox_Data\Managed\RobocraftX.MainSimulation.Audio.dll - ..\..\ref_TB\Techblox_Data\Managed\RobocraftX.MainSimulation.Audio.dll - - - ..\ref_TB\Techblox_Data\Managed\RobocraftX.MainSimulation.dll - ..\..\ref_TB\Techblox_Data\Managed\RobocraftX.MainSimulation.dll - - - ..\ref_TB\Techblox_Data\Managed\RobocraftX.Multiplayer.dll - ..\..\ref_TB\Techblox_Data\Managed\RobocraftX.Multiplayer.dll - - - ..\ref_TB\Techblox_Data\Managed\RobocraftX.Multiplayer.NetworkEntityStream.dll - ..\..\ref_TB\Techblox_Data\Managed\RobocraftX.Multiplayer.NetworkEntityStream.dll - - - ..\ref_TB\Techblox_Data\Managed\RobocraftX.Multiplayer.Serializers.dll - ..\..\ref_TB\Techblox_Data\Managed\RobocraftX.Multiplayer.Serializers.dll - - - ..\ref_TB\Techblox_Data\Managed\RobocraftX.MultiplayerInput.dll - ..\..\ref_TB\Techblox_Data\Managed\RobocraftX.MultiplayerInput.dll - - - ..\ref_TB\Techblox_Data\Managed\RobocraftX.ObjectIdBlocks.dll - ..\..\ref_TB\Techblox_Data\Managed\RobocraftX.ObjectIdBlocks.dll - - - ..\ref_TB\Techblox_Data\Managed\RobocraftX.Physics.dll - ..\..\ref_TB\Techblox_Data\Managed\RobocraftX.Physics.dll - - - ..\ref_TB\Techblox_Data\Managed\RobocraftX.PilotSeat.dll - ..\..\ref_TB\Techblox_Data\Managed\RobocraftX.PilotSeat.dll - - - ..\ref_TB\Techblox_Data\Managed\RobocraftX.Player.dll - ..\..\ref_TB\Techblox_Data\Managed\RobocraftX.Player.dll - - - ..\ref_TB\Techblox_Data\Managed\RobocraftX.SaveAndLoad.dll - ..\..\ref_TB\Techblox_Data\Managed\RobocraftX.SaveAndLoad.dll - - - ..\ref_TB\Techblox_Data\Managed\RobocraftX.SaveGameDialog.dll - ..\..\ref_TB\Techblox_Data\Managed\RobocraftX.SaveGameDialog.dll - - - ..\ref_TB\Techblox_Data\Managed\RobocraftX.Services.dll - ..\..\ref_TB\Techblox_Data\Managed\RobocraftX.Services.dll - - - ..\ref_TB\Techblox_Data\Managed\RobocraftX.SignalHandling.dll - ..\..\ref_TB\Techblox_Data\Managed\RobocraftX.SignalHandling.dll - - - ..\ref_TB\Techblox_Data\Managed\RobocraftX.StateSync.dll - ..\..\ref_TB\Techblox_Data\Managed\RobocraftX.StateSync.dll - - - ..\ref_TB\Techblox_Data\Managed\Serilog.dll - ..\..\ref_TB\Techblox_Data\Managed\Serilog.dll - - - ..\ref_TB\Techblox_Data\Managed\Serilog.Sinks.Grafana.Loki.dll - ..\..\ref_TB\Techblox_Data\Managed\Serilog.Sinks.Grafana.Loki.dll - - - ..\ref_TB\Techblox_Data\Managed\ShaderVariantsGenerationTool.dll - ..\..\ref_TB\Techblox_Data\Managed\ShaderVariantsGenerationTool.dll - - - ..\ref_TB\Techblox_Data\Managed\SpecializedDescriptors.dll - ..\..\ref_TB\Techblox_Data\Managed\SpecializedDescriptors.dll - - - ..\ref_TB\Techblox_Data\Managed\StringFormatter.dll - ..\..\ref_TB\Techblox_Data\Managed\StringFormatter.dll - - - ..\ref_TB\Techblox_Data\Managed\Svelto.Common.dll - ..\..\ref_TB\Techblox_Data\Managed\Svelto.Common.dll - - - ..\ref_TB\Techblox_Data\Managed\Svelto.ECS.dll - ..\..\ref_TB\Techblox_Data\Managed\Svelto.ECS.dll - - - ..\ref_TB\Techblox_Data\Managed\Svelto.ECS.GUI.dll - ..\..\ref_TB\Techblox_Data\Managed\Svelto.ECS.GUI.dll - - - ..\ref_TB\Techblox_Data\Managed\Svelto.Services.dll - ..\..\ref_TB\Techblox_Data\Managed\Svelto.Services.dll - - - ..\ref_TB\Techblox_Data\Managed\Svelto.Tasks.dll - ..\..\ref_TB\Techblox_Data\Managed\Svelto.Tasks.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.AdditionalParts.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.AdditionalParts.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.AntiAFKServer.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.AntiAFKServer.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.Anticheat.Client.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.Anticheat.Client.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.Anticheat.Common.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.Anticheat.Common.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.AtmosphereBlock.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.AtmosphereBlock.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.AudioBlocks.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.AudioBlocks.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.AudioBlocksClient.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.AudioBlocksClient.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.AutoForward.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.AutoForward.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.Backend.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.Backend.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.BitBlock.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.BitBlock.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.BlockColours.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.BlockColours.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.BlockLabels.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.BlockLabels.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.BlockLabelsServer.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.BlockLabelsServer.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.Blocks.Connections.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.Blocks.Connections.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.Blocks.LightBlock.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.Blocks.LightBlock.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.Building.Rules.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.Building.Rules.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.Building.Shift.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.Building.Shift.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.BuildingDrone.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.BuildingDrone.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.Camera.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.Camera.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.CentreHUDBlock.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.CentreHUDBlock.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.CentreHUDGUI.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.CentreHUDGUI.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.CharacterDamage.Client.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.CharacterDamage.Client.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.CharacterDamage.Server.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.CharacterDamage.Server.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.CharacterRespawnScreen.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.CharacterRespawnScreen.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.CheckpointBlock.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.CheckpointBlock.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.CheckpointBlockClient.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.CheckpointBlockClient.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.Common.Audio.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.Common.Audio.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.ConstantBlockClient.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.ConstantBlockClient.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.ConstantBlockServer.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.ConstantBlockServer.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.ContextSensitiveTextHint.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.ContextSensitiveTextHint.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.CounterBlockClient.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.CounterBlockClient.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.CounterBlockServer.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.CounterBlockServer.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.DamageRbScoreBlockServerServer.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.DamageRbScoreBlockServerServer.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.DirectionalDamageVingette.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.DirectionalDamageVingette.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.DistanceSensorBlock.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.DistanceSensorBlock.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.ECSResourceManagers.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.ECSResourceManagers.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.EngineBlock.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.EngineBlock.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.EnvironmentBlocks.BuildingEnvironment.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.EnvironmentBlocks.BuildingEnvironment.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.EnvironmentBlocks.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.EnvironmentBlocks.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.EnvironmentBlocks.SimulationWorldEnvironment.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.EnvironmentBlocks.SimulationWorldEnvironment.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.Gameplay.Client.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.Gameplay.Client.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.Gameplay.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.Gameplay.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.Gameplay.GameState.Client.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.Gameplay.GameState.Client.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.Gameplay.GameState.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.Gameplay.GameState.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.Gameplay.PlayerGameplayDetails.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.Gameplay.PlayerGameplayDetails.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.Gameplay.Score.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.Gameplay.Score.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.Gameplay.Spawning.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.Gameplay.Spawning.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.Gameplay.Teams.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.Gameplay.Teams.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.Gameplay.WorldResetting.Client.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.Gameplay.WorldResetting.Client.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.Gameplay.WorldResetting.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.Gameplay.WorldResetting.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.GameSelection.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.GameSelection.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.GUI.Building.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.GUI.Building.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.GUI.BuildRules.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.GUI.BuildRules.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.GUI.CharacterHealthFeedback.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.GUI.CharacterHealthFeedback.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.GUI.Collection.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.GUI.Collection.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.GUI.Controls.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.GUI.Controls.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.GUI.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.GUI.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.GUI.GamePortal.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.GUI.GamePortal.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.GUI.GeneralSettingsScreen.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.GUI.GeneralSettingsScreen.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.GUI.Hotbar.Landscapes.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.GUI.Hotbar.Landscapes.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.GUI.Hotbar.Materials.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.GUI.Hotbar.Materials.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.GUI.Inventory.Common.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.GUI.Inventory.Common.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.GUI.Inventory.Landscapes.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.GUI.Inventory.Landscapes.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.GUI.Inventory.Materials.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.GUI.Inventory.Materials.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.GUI.LoadingBar.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.GUI.LoadingBar.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.GUI.Login.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.GUI.Login.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.GUI.MachineReconstructTimer.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.GUI.MachineReconstructTimer.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.GUI.MainGame.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.GUI.MainGame.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.GUI.MainGame.StateMachine.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.GUI.MainGame.StateMachine.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.GUI.MyGamesScreen.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.GUI.MyGamesScreen.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.GUI.PauseMenu.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.GUI.PauseMenu.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.GUI.Progression.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.GUI.Progression.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.GUI.TabsBar.Landscapes.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.GUI.TabsBar.Landscapes.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.GUI.TabsBar.Materials.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.GUI.TabsBar.Materials.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.GUI.UsernameDisplay.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.GUI.UsernameDisplay.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.InputCapture.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.InputCapture.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.JetBlock.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.JetBlock.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.JetBlockClient.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.JetBlockClient.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.KillScoreBlock.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.KillScoreBlock.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.MachineProcessingService.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.MachineProcessingService.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.MachineSimulationPreprocessing.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.MachineSimulationPreprocessing.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.MachineSpawning.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.MachineSpawning.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.MachineVelocityCameraEffects.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.MachineVelocityCameraEffects.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.Matchmaking.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.Matchmaking.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.Monitoring.Server.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.Monitoring.Server.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.Multiplayer.UsernameMessages.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.Multiplayer.UsernameMessages.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.ObjectIDBlockClient.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.ObjectIDBlockClient.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.ObjectIDBlockServer.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.ObjectIDBlockServer.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.Particles.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.Particles.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.PlayUX.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.PlayUX.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.Pointer.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.Pointer.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.ProceduralReflectionProbes.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.ProceduralReflectionProbes.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.Rendering.Common.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.Rendering.Common.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.Rendering.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.Rendering.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.Rendering.DOTS.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.Rendering.DOTS.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.Rendering.GPUI.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.Rendering.GPUI.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.Rendering.Unity.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.Rendering.Unity.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.SaveGamesConversion.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.SaveGamesConversion.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.ScoreHUDBlock.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.ScoreHUDBlock.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.ScoreHUDGUI.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.ScoreHUDGUI.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.ScorePickupBlockClient.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.ScorePickupBlockClient.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.ScorePickupBlockServer.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.ScorePickupBlockServer.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.Server.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.Server.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.Services.Anticheat.Client.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.Services.Anticheat.Client.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.Services.Eos.Common.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.Services.Eos.Common.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.Services.Eos.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.Services.Eos.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.Services.GameDetails.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.Services.GameDetails.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.Services.LocalPreferences.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.Services.LocalPreferences.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.Services.Matchmaking.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.Services.Matchmaking.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.Services.Metrics.Server.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.Services.Metrics.Server.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.Services.Progression.Client.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.Services.Progression.Client.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.Services.Progression.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.Services.Progression.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.Services.Storage.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.Services.Storage.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.Services.Users.Client.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.Services.Users.Client.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.Services.Users.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.Services.Users.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.ServoBlocksClient.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.ServoBlocksClient.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.ServoBlocksServer.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.ServoBlocksServer.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.ServosServer.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.ServosServer.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.SignalHandling.Audio.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.SignalHandling.Audio.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.SignalHandling.Common.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.SignalHandling.Common.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.Simulation.Clusters.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.Simulation.Clusters.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.SpawnBlock.Client.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.SpawnBlock.Client.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.SpawnBlock.Server.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.SpawnBlock.Server.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.StabilizerBlock.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.StabilizerBlock.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.StabilizerBlockClient.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.StabilizerBlockClient.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.SwitchAnimation.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.SwitchAnimation.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.TeamScoreBlockClient.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.TeamScoreBlockClient.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.TeamScoreBlockServer.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.TeamScoreBlockServer.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.TechpointConverterBlock.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.TechpointConverterBlock.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.TechpointConverterGUI.TechPointPoolHUD.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.TechpointConverterGUI.TechPointPoolHUD.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.TechpointConverterGUI.TechpointRewardPanel.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.TechpointConverterGUI.TechpointRewardPanel.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.TextBlock.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.TextBlock.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.TimerBlock.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.TimerBlock.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.TriggerBlock.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.TriggerBlock.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.Tweaks.Validation.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.Tweaks.Validation.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.VFXBlockClient.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.VFXBlockClient.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.VFXBlockServer.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.VFXBlockServer.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.VisualEffects.VFXGraph.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.VisualEffects.VFXGraph.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.Weapons.Aiming.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.Weapons.Aiming.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.Weapons.DisablerBlock.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.Weapons.DisablerBlock.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.Weapons.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.Weapons.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.Weapons.Projectiles.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.Weapons.Projectiles.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.Weapons.Projectiles.Server.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.Weapons.Projectiles.Server.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.Weapons.Server.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.Weapons.Server.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.WheelFX.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.WheelFX.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.WheelRigBlock.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.WheelRigBlock.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.Wheels.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.Wheels.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.WorldEditor.Spawning.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.WorldEditor.Spawning.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.WorldEditor.TestPlayers.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.WorldEditor.TestPlayers.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.WorldResetterBlock.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.WorldResetterBlock.dll - - - ..\ref_TB\Techblox_Data\Managed\UniTask.Addressables.dll - ..\..\ref_TB\Techblox_Data\Managed\UniTask.Addressables.dll - - - ..\ref_TB\Techblox_Data\Managed\UniTask.dll - ..\..\ref_TB\Techblox_Data\Managed\UniTask.dll - - - ..\ref_TB\Techblox_Data\Managed\UniTask.DOTween.dll - ..\..\ref_TB\Techblox_Data\Managed\UniTask.DOTween.dll - - - ..\ref_TB\Techblox_Data\Managed\UniTask.Linq.dll - ..\..\ref_TB\Techblox_Data\Managed\UniTask.Linq.dll - - - ..\ref_TB\Techblox_Data\Managed\UniTask.TextMeshPro.dll - ..\..\ref_TB\Techblox_Data\Managed\UniTask.TextMeshPro.dll - - - ..\ref_TB\Techblox_Data\Managed\Unity.Addressables.dll - ..\..\ref_TB\Techblox_Data\Managed\Unity.Addressables.dll - - - ..\ref_TB\Techblox_Data\Managed\Unity.Burst.dll - ..\..\ref_TB\Techblox_Data\Managed\Unity.Burst.dll - - - ..\ref_TB\Techblox_Data\Managed\Unity.Burst.Unsafe.dll - ..\..\ref_TB\Techblox_Data\Managed\Unity.Burst.Unsafe.dll - - - ..\ref_TB\Techblox_Data\Managed\Unity.Collections.dll - ..\..\ref_TB\Techblox_Data\Managed\Unity.Collections.dll - - - ..\ref_TB\Techblox_Data\Managed\Unity.Collections.LowLevel.ILSupport.dll - ..\..\ref_TB\Techblox_Data\Managed\Unity.Collections.LowLevel.ILSupport.dll - - - ..\ref_TB\Techblox_Data\Managed\Unity.Deformations.dll - ..\..\ref_TB\Techblox_Data\Managed\Unity.Deformations.dll - - - ..\ref_TB\Techblox_Data\Managed\Unity.Entities.dll - ..\..\ref_TB\Techblox_Data\Managed\Unity.Entities.dll - - - ..\ref_TB\Techblox_Data\Managed\Unity.Entities.Hybrid.dll - ..\..\ref_TB\Techblox_Data\Managed\Unity.Entities.Hybrid.dll - - - ..\ref_TB\Techblox_Data\Managed\Unity.InternalAPIEngineBridge.012.dll - ..\..\ref_TB\Techblox_Data\Managed\Unity.InternalAPIEngineBridge.012.dll - - - ..\ref_TB\Techblox_Data\Managed\Unity.Jobs.dll - ..\..\ref_TB\Techblox_Data\Managed\Unity.Jobs.dll - - - ..\ref_TB\Techblox_Data\Managed\Unity.Mathematics.dll - ..\..\ref_TB\Techblox_Data\Managed\Unity.Mathematics.dll - - - ..\ref_TB\Techblox_Data\Managed\Unity.Mathematics.Extensions.dll - ..\..\ref_TB\Techblox_Data\Managed\Unity.Mathematics.Extensions.dll - - - ..\ref_TB\Techblox_Data\Managed\Unity.Mathematics.Extensions.Hybrid.dll - ..\..\ref_TB\Techblox_Data\Managed\Unity.Mathematics.Extensions.Hybrid.dll - - - ..\ref_TB\Techblox_Data\Managed\Unity.MemoryProfiler.dll - ..\..\ref_TB\Techblox_Data\Managed\Unity.MemoryProfiler.dll - - - ..\ref_TB\Techblox_Data\Managed\Unity.Physics.dll - ..\..\ref_TB\Techblox_Data\Managed\Unity.Physics.dll - - - ..\ref_TB\Techblox_Data\Managed\Unity.Physics.Hybrid.dll - ..\..\ref_TB\Techblox_Data\Managed\Unity.Physics.Hybrid.dll - - - ..\ref_TB\Techblox_Data\Managed\Unity.Platforms.Common.dll - ..\..\ref_TB\Techblox_Data\Managed\Unity.Platforms.Common.dll - - - ..\ref_TB\Techblox_Data\Managed\Unity.Profiling.Core.dll - ..\..\ref_TB\Techblox_Data\Managed\Unity.Profiling.Core.dll - - - ..\ref_TB\Techblox_Data\Managed\Unity.Properties.dll - ..\..\ref_TB\Techblox_Data\Managed\Unity.Properties.dll - - - ..\ref_TB\Techblox_Data\Managed\Unity.Properties.Reflection.dll - ..\..\ref_TB\Techblox_Data\Managed\Unity.Properties.Reflection.dll - - - ..\ref_TB\Techblox_Data\Managed\Unity.Properties.UI.dll - ..\..\ref_TB\Techblox_Data\Managed\Unity.Properties.UI.dll - - - ..\ref_TB\Techblox_Data\Managed\Unity.Recorder.Base.dll - ..\..\ref_TB\Techblox_Data\Managed\Unity.Recorder.Base.dll - - - ..\ref_TB\Techblox_Data\Managed\Unity.Recorder.dll - ..\..\ref_TB\Techblox_Data\Managed\Unity.Recorder.dll - - - ..\ref_TB\Techblox_Data\Managed\Unity.Rendering.Hybrid.dll - ..\..\ref_TB\Techblox_Data\Managed\Unity.Rendering.Hybrid.dll - - - ..\ref_TB\Techblox_Data\Managed\Unity.RenderPipelines.Core.Runtime.dll - ..\..\ref_TB\Techblox_Data\Managed\Unity.RenderPipelines.Core.Runtime.dll - - - ..\ref_TB\Techblox_Data\Managed\Unity.RenderPipelines.Core.ShaderLibrary.dll - ..\..\ref_TB\Techblox_Data\Managed\Unity.RenderPipelines.Core.ShaderLibrary.dll - - - ..\ref_TB\Techblox_Data\Managed\Unity.RenderPipelines.HighDefinition.Config.Runtime.dll - ..\..\ref_TB\Techblox_Data\Managed\Unity.RenderPipelines.HighDefinition.Config.Runtime.dll - - - ..\ref_TB\Techblox_Data\Managed\Unity.RenderPipelines.HighDefinition.Runtime.dll - ..\..\ref_TB\Techblox_Data\Managed\Unity.RenderPipelines.HighDefinition.Runtime.dll - - - ..\ref_TB\Techblox_Data\Managed\Unity.RenderPipelines.ShaderGraph.ShaderGraphLibrary.dll - ..\..\ref_TB\Techblox_Data\Managed\Unity.RenderPipelines.ShaderGraph.ShaderGraphLibrary.dll - - - ..\ref_TB\Techblox_Data\Managed\Unity.ResourceManager.dll - ..\..\ref_TB\Techblox_Data\Managed\Unity.ResourceManager.dll - - - ..\ref_TB\Techblox_Data\Managed\Unity.Scenes.dll - ..\..\ref_TB\Techblox_Data\Managed\Unity.Scenes.dll - - - ..\ref_TB\Techblox_Data\Managed\Unity.ScriptableBuildPipeline.dll - ..\..\ref_TB\Techblox_Data\Managed\Unity.ScriptableBuildPipeline.dll - - - ..\ref_TB\Techblox_Data\Managed\Unity.Serialization.dll - ..\..\ref_TB\Techblox_Data\Managed\Unity.Serialization.dll - - - ..\ref_TB\Techblox_Data\Managed\Unity.TextMeshPro.dll - ..\..\ref_TB\Techblox_Data\Managed\Unity.TextMeshPro.dll - - - ..\ref_TB\Techblox_Data\Managed\Unity.Timeline.dll - ..\..\ref_TB\Techblox_Data\Managed\Unity.Timeline.dll - - - ..\ref_TB\Techblox_Data\Managed\Unity.Transforms.dll - ..\..\ref_TB\Techblox_Data\Managed\Unity.Transforms.dll - - - ..\ref_TB\Techblox_Data\Managed\Unity.Transforms.Hybrid.dll - ..\..\ref_TB\Techblox_Data\Managed\Unity.Transforms.Hybrid.dll - - - ..\ref_TB\Techblox_Data\Managed\Unity.VisualEffectGraph.Runtime.dll - ..\..\ref_TB\Techblox_Data\Managed\Unity.VisualEffectGraph.Runtime.dll - - - ..\ref_TB\Techblox_Data\Managed\UnityEngine.AccessibilityModule.dll - ..\..\ref_TB\Techblox_Data\Managed\UnityEngine.AccessibilityModule.dll - - - ..\ref_TB\Techblox_Data\Managed\UnityEngine.AIModule.dll - ..\..\ref_TB\Techblox_Data\Managed\UnityEngine.AIModule.dll - - - ..\ref_TB\Techblox_Data\Managed\UnityEngine.AndroidJNIModule.dll - ..\..\ref_TB\Techblox_Data\Managed\UnityEngine.AndroidJNIModule.dll - - - ..\ref_TB\Techblox_Data\Managed\UnityEngine.AnimationModule.dll - ..\..\ref_TB\Techblox_Data\Managed\UnityEngine.AnimationModule.dll - - - ..\ref_TB\Techblox_Data\Managed\UnityEngine.ARModule.dll - ..\..\ref_TB\Techblox_Data\Managed\UnityEngine.ARModule.dll - - - ..\ref_TB\Techblox_Data\Managed\UnityEngine.AssetBundleModule.dll - ..\..\ref_TB\Techblox_Data\Managed\UnityEngine.AssetBundleModule.dll - - - ..\ref_TB\Techblox_Data\Managed\UnityEngine.AudioModule.dll - ..\..\ref_TB\Techblox_Data\Managed\UnityEngine.AudioModule.dll - - - ..\ref_TB\Techblox_Data\Managed\UnityEngine.ClothModule.dll - ..\..\ref_TB\Techblox_Data\Managed\UnityEngine.ClothModule.dll - - - ..\ref_TB\Techblox_Data\Managed\UnityEngine.ClusterInputModule.dll - ..\..\ref_TB\Techblox_Data\Managed\UnityEngine.ClusterInputModule.dll - - - ..\ref_TB\Techblox_Data\Managed\UnityEngine.ClusterRendererModule.dll - ..\..\ref_TB\Techblox_Data\Managed\UnityEngine.ClusterRendererModule.dll - - - ..\ref_TB\Techblox_Data\Managed\UnityEngine.CoreModule.dll - ..\..\ref_TB\Techblox_Data\Managed\UnityEngine.CoreModule.dll - - - ..\ref_TB\Techblox_Data\Managed\UnityEngine.CrashReportingModule.dll - ..\..\ref_TB\Techblox_Data\Managed\UnityEngine.CrashReportingModule.dll - - - ..\ref_TB\Techblox_Data\Managed\UnityEngine.DirectorModule.dll - ..\..\ref_TB\Techblox_Data\Managed\UnityEngine.DirectorModule.dll - - - ..\ref_TB\Techblox_Data\Managed\UnityEngine.dll - ..\..\ref_TB\Techblox_Data\Managed\UnityEngine.dll - - - ..\ref_TB\Techblox_Data\Managed\UnityEngine.DSPGraphModule.dll - ..\..\ref_TB\Techblox_Data\Managed\UnityEngine.DSPGraphModule.dll - - - ..\ref_TB\Techblox_Data\Managed\UnityEngine.GameCenterModule.dll - ..\..\ref_TB\Techblox_Data\Managed\UnityEngine.GameCenterModule.dll - - - ..\ref_TB\Techblox_Data\Managed\UnityEngine.GIModule.dll - ..\..\ref_TB\Techblox_Data\Managed\UnityEngine.GIModule.dll - - - ..\ref_TB\Techblox_Data\Managed\UnityEngine.GridModule.dll - ..\..\ref_TB\Techblox_Data\Managed\UnityEngine.GridModule.dll - - - ..\ref_TB\Techblox_Data\Managed\UnityEngine.HotReloadModule.dll - ..\..\ref_TB\Techblox_Data\Managed\UnityEngine.HotReloadModule.dll - - - ..\ref_TB\Techblox_Data\Managed\UnityEngine.ImageConversionModule.dll - ..\..\ref_TB\Techblox_Data\Managed\UnityEngine.ImageConversionModule.dll - - - ..\ref_TB\Techblox_Data\Managed\UnityEngine.IMGUIModule.dll - ..\..\ref_TB\Techblox_Data\Managed\UnityEngine.IMGUIModule.dll - - - ..\ref_TB\Techblox_Data\Managed\UnityEngine.InputLegacyModule.dll - ..\..\ref_TB\Techblox_Data\Managed\UnityEngine.InputLegacyModule.dll - - - ..\ref_TB\Techblox_Data\Managed\UnityEngine.InputModule.dll - ..\..\ref_TB\Techblox_Data\Managed\UnityEngine.InputModule.dll - - - ..\ref_TB\Techblox_Data\Managed\UnityEngine.JSONSerializeModule.dll - ..\..\ref_TB\Techblox_Data\Managed\UnityEngine.JSONSerializeModule.dll - - - ..\ref_TB\Techblox_Data\Managed\UnityEngine.LocalizationModule.dll - ..\..\ref_TB\Techblox_Data\Managed\UnityEngine.LocalizationModule.dll - - - ..\ref_TB\Techblox_Data\Managed\UnityEngine.NVIDIAModule.dll - ..\..\ref_TB\Techblox_Data\Managed\UnityEngine.NVIDIAModule.dll - - - ..\ref_TB\Techblox_Data\Managed\UnityEngine.ParticleSystemModule.dll - ..\..\ref_TB\Techblox_Data\Managed\UnityEngine.ParticleSystemModule.dll - - - ..\ref_TB\Techblox_Data\Managed\UnityEngine.PerformanceReportingModule.dll - ..\..\ref_TB\Techblox_Data\Managed\UnityEngine.PerformanceReportingModule.dll - - - ..\ref_TB\Techblox_Data\Managed\UnityEngine.Physics2DModule.dll - ..\..\ref_TB\Techblox_Data\Managed\UnityEngine.Physics2DModule.dll - - - ..\ref_TB\Techblox_Data\Managed\UnityEngine.PhysicsModule.dll - ..\..\ref_TB\Techblox_Data\Managed\UnityEngine.PhysicsModule.dll - - - ..\ref_TB\Techblox_Data\Managed\UnityEngine.ProfilerModule.dll - ..\..\ref_TB\Techblox_Data\Managed\UnityEngine.ProfilerModule.dll - - - ..\ref_TB\Techblox_Data\Managed\UnityEngine.RuntimeInitializeOnLoadManagerInitializerModule.dll - ..\..\ref_TB\Techblox_Data\Managed\UnityEngine.RuntimeInitializeOnLoadManagerInitializerModule.dll - - - ..\ref_TB\Techblox_Data\Managed\UnityEngine.ScreenCaptureModule.dll - ..\..\ref_TB\Techblox_Data\Managed\UnityEngine.ScreenCaptureModule.dll - - - ..\ref_TB\Techblox_Data\Managed\UnityEngine.SharedInternalsModule.dll - ..\..\ref_TB\Techblox_Data\Managed\UnityEngine.SharedInternalsModule.dll - - - ..\ref_TB\Techblox_Data\Managed\UnityEngine.SpriteMaskModule.dll - ..\..\ref_TB\Techblox_Data\Managed\UnityEngine.SpriteMaskModule.dll - - - ..\ref_TB\Techblox_Data\Managed\UnityEngine.SpriteShapeModule.dll - ..\..\ref_TB\Techblox_Data\Managed\UnityEngine.SpriteShapeModule.dll - - - ..\ref_TB\Techblox_Data\Managed\UnityEngine.StreamingModule.dll - ..\..\ref_TB\Techblox_Data\Managed\UnityEngine.StreamingModule.dll - - - ..\ref_TB\Techblox_Data\Managed\UnityEngine.SubstanceModule.dll - ..\..\ref_TB\Techblox_Data\Managed\UnityEngine.SubstanceModule.dll - - - ..\ref_TB\Techblox_Data\Managed\UnityEngine.SubsystemsModule.dll - ..\..\ref_TB\Techblox_Data\Managed\UnityEngine.SubsystemsModule.dll - - - ..\ref_TB\Techblox_Data\Managed\UnityEngine.TerrainModule.dll - ..\..\ref_TB\Techblox_Data\Managed\UnityEngine.TerrainModule.dll - - - ..\ref_TB\Techblox_Data\Managed\UnityEngine.TerrainPhysicsModule.dll - ..\..\ref_TB\Techblox_Data\Managed\UnityEngine.TerrainPhysicsModule.dll - - - ..\ref_TB\Techblox_Data\Managed\UnityEngine.TextCoreFontEngineModule.dll - ..\..\ref_TB\Techblox_Data\Managed\UnityEngine.TextCoreFontEngineModule.dll - - - ..\ref_TB\Techblox_Data\Managed\UnityEngine.TextCoreTextEngineModule.dll - ..\..\ref_TB\Techblox_Data\Managed\UnityEngine.TextCoreTextEngineModule.dll - - - ..\ref_TB\Techblox_Data\Managed\UnityEngine.TextRenderingModule.dll - ..\..\ref_TB\Techblox_Data\Managed\UnityEngine.TextRenderingModule.dll - - - ..\ref_TB\Techblox_Data\Managed\UnityEngine.TilemapModule.dll - ..\..\ref_TB\Techblox_Data\Managed\UnityEngine.TilemapModule.dll - - - ..\ref_TB\Techblox_Data\Managed\UnityEngine.TLSModule.dll - ..\..\ref_TB\Techblox_Data\Managed\UnityEngine.TLSModule.dll - - - ..\ref_TB\Techblox_Data\Managed\UnityEngine.UI.dll - ..\..\ref_TB\Techblox_Data\Managed\UnityEngine.UI.dll - - - ..\ref_TB\Techblox_Data\Managed\UnityEngine.UIElementsModule.dll - ..\..\ref_TB\Techblox_Data\Managed\UnityEngine.UIElementsModule.dll - - - ..\ref_TB\Techblox_Data\Managed\UnityEngine.UIElementsNativeModule.dll - ..\..\ref_TB\Techblox_Data\Managed\UnityEngine.UIElementsNativeModule.dll - - - ..\ref_TB\Techblox_Data\Managed\UnityEngine.UIModule.dll - ..\..\ref_TB\Techblox_Data\Managed\UnityEngine.UIModule.dll - - - ..\ref_TB\Techblox_Data\Managed\UnityEngine.UmbraModule.dll - ..\..\ref_TB\Techblox_Data\Managed\UnityEngine.UmbraModule.dll - - - ..\ref_TB\Techblox_Data\Managed\UnityEngine.UNETModule.dll - ..\..\ref_TB\Techblox_Data\Managed\UnityEngine.UNETModule.dll - - - ..\ref_TB\Techblox_Data\Managed\UnityEngine.UnityAnalyticsModule.dll - ..\..\ref_TB\Techblox_Data\Managed\UnityEngine.UnityAnalyticsModule.dll - - - ..\ref_TB\Techblox_Data\Managed\UnityEngine.UnityConnectModule.dll - ..\..\ref_TB\Techblox_Data\Managed\UnityEngine.UnityConnectModule.dll - - - ..\ref_TB\Techblox_Data\Managed\UnityEngine.UnityCurlModule.dll - ..\..\ref_TB\Techblox_Data\Managed\UnityEngine.UnityCurlModule.dll - - - ..\ref_TB\Techblox_Data\Managed\UnityEngine.UnityTestProtocolModule.dll - ..\..\ref_TB\Techblox_Data\Managed\UnityEngine.UnityTestProtocolModule.dll - - - ..\ref_TB\Techblox_Data\Managed\UnityEngine.UnityWebRequestAssetBundleModule.dll - ..\..\ref_TB\Techblox_Data\Managed\UnityEngine.UnityWebRequestAssetBundleModule.dll - - - ..\ref_TB\Techblox_Data\Managed\UnityEngine.UnityWebRequestAudioModule.dll - ..\..\ref_TB\Techblox_Data\Managed\UnityEngine.UnityWebRequestAudioModule.dll - - - ..\ref_TB\Techblox_Data\Managed\UnityEngine.UnityWebRequestModule.dll - ..\..\ref_TB\Techblox_Data\Managed\UnityEngine.UnityWebRequestModule.dll - - - ..\ref_TB\Techblox_Data\Managed\UnityEngine.UnityWebRequestTextureModule.dll - ..\..\ref_TB\Techblox_Data\Managed\UnityEngine.UnityWebRequestTextureModule.dll - - - ..\ref_TB\Techblox_Data\Managed\UnityEngine.UnityWebRequestWWWModule.dll - ..\..\ref_TB\Techblox_Data\Managed\UnityEngine.UnityWebRequestWWWModule.dll - - - ..\ref_TB\Techblox_Data\Managed\UnityEngine.VehiclesModule.dll - ..\..\ref_TB\Techblox_Data\Managed\UnityEngine.VehiclesModule.dll - - - ..\ref_TB\Techblox_Data\Managed\UnityEngine.VFXModule.dll - ..\..\ref_TB\Techblox_Data\Managed\UnityEngine.VFXModule.dll - - - ..\ref_TB\Techblox_Data\Managed\UnityEngine.VideoModule.dll - ..\..\ref_TB\Techblox_Data\Managed\UnityEngine.VideoModule.dll - - - ..\ref_TB\Techblox_Data\Managed\UnityEngine.VirtualTexturingModule.dll - ..\..\ref_TB\Techblox_Data\Managed\UnityEngine.VirtualTexturingModule.dll - - - ..\ref_TB\Techblox_Data\Managed\UnityEngine.VRModule.dll - ..\..\ref_TB\Techblox_Data\Managed\UnityEngine.VRModule.dll - - - ..\ref_TB\Techblox_Data\Managed\UnityEngine.WindModule.dll - ..\..\ref_TB\Techblox_Data\Managed\UnityEngine.WindModule.dll - - - ..\ref_TB\Techblox_Data\Managed\UnityEngine.XRModule.dll - ..\..\ref_TB\Techblox_Data\Managed\UnityEngine.XRModule.dll - - - ..\ref_TB\Techblox_Data\Managed\VisualProfiler.dll - ..\..\ref_TB\Techblox_Data\Managed\VisualProfiler.dll - - - ..\ref_TB\Techblox_Data\Managed\websocket-sharp.dll - ..\..\ref_TB\Techblox_Data\Managed\websocket-sharp.dll - - - ..\ref_TB\Techblox_Data\Managed\ZFBrowser.dll - ..\..\ref_TB\Techblox_Data\Managed\ZFBrowser.dll - - - - diff --git a/MakeEverythingPublicInGame/Program.cs b/MakeEverythingPublicInGame/Program.cs deleted file mode 100644 index e28c4a2..0000000 --- a/MakeEverythingPublicInGame/Program.cs +++ /dev/null @@ -1,25 +0,0 @@ -using System.Text.RegularExpressions; -using Mono.Cecil; - -Console.WriteLine("Starting assembly editing..."); -var fileRegex = - new Regex(".*(Techblox|Gamecraft|RobocraftX|FullGame|RobocraftECS|DataLoader|RCX|GameState|Svelto\\.ECS)[^/]*(\\.dll)"); -foreach (var file in Directory.EnumerateFiles(@"../../../../../ref/Techblox_Data/Managed")) -{ - if (!fileRegex.IsMatch(file)) continue; - Console.WriteLine(file); - ProcessAssembly(file); -} - -void ProcessAssembly(string path) -{ - using var mod = ModuleDefinition.ReadModule(path, new(ReadingMode.Immediate) { ReadWrite = true }); - foreach (var typeDefinition in mod.Types) - { - typeDefinition.IsPublic = true; - foreach (var method in typeDefinition.Methods) method.IsPublic = true; - foreach (var field in typeDefinition.Fields) field.IsPublic = true; - } - - mod.Write(); -} \ No newline at end of file diff --git a/README.md b/README.md index a4c0457..1955de0 100644 --- a/README.md +++ b/README.md @@ -1,31 +1,24 @@ -# TechbloxModdingAPI +# GamecraftModdingAPI -Unofficial Techblox modding API for interfacing Techblox from mods. +Unofficial Gamecraft modding API for interfacing Gamecraft from mods. -The TechbloxModdingAPI aims to simplify the mods in two ways: +The GamecraftModdingAPI aims to simplify the mods in two ways: - *Ease-of-Use* The API provides convenient ways to do common tasks such as moving blocks and adding commands. All of the Harmony patching is done for you, so you can focus on writing your mod instead of reading swathes of undocumented code. - *Stability* The API aims to be reliable and consistent between versions. -This means your code won't break when the TechbloxModdingAPI or Techblox updates. +This means your code won't break when the GamecraftModdingAPI or Gamecraft updates. For more info, please check out the [official documentation](https://mod.exmods.org). -For more support, join the ExMods [Discord](https://discord.exmods.org). +For more support, join the ExMods [Discord](https://discord.gg/xjnFxQV). ## Installation -[Please follow the official mod installation guide](https://www.exmods.org/guides/install.html) or use GCMM. - -## Development -To get started, create a symbolic link called `ref` in the root of the project, or one folder higher, linking to the Techblox install folder. -This will allow your IDE to resolve references to Techblox files for building and IDE tools. - -TechbloxModdingAPI version numbers follow the [Semantic Versioning guidelines](https://semver.org/). +[Please follow the official mod installation guide](https://www.exmods.org/guides/install.html) ## External Libraries -TechbloxModdingAPI includes [Harmony](https://github.com/pardeike/Harmony) to modify the behaviour of existing Techblox code. +GamecraftModdingAPI includes [Harmony](https://github.com/pardeike/Harmony) to modify the behaviour of existing Gamecraft code. # Disclaimer -This API is an unofficial modification of Techblox software, and is not endorsed or supported by FreeJam or Techblox. -The TechbloxModdingAPI developer(s) claim no rights on the Techblox code referenced within this project. -All code contained in this project is licensed under the [GNU Public License v3](https://git.exmods.org/modtainers/TechbloxModdingAPI/src/branch/master/LICENSE). +This API is an unofficial modification of Gamecraft software, and is not endorsed or supported by FreeJam or Gamecraft. +The GamecraftModdingAPI developer(s) claim no rights on the Gamecraft code referenced within this project. diff --git a/TechbloxModdingAPI.sln b/TechbloxModdingAPI.sln deleted file mode 100644 index 20512c0..0000000 --- a/TechbloxModdingAPI.sln +++ /dev/null @@ -1,44 +0,0 @@ - -Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio Version 16 -VisualStudioVersion = 16.0.29411.108 -MinimumVisualStudioVersion = 10.0.40219.1 -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TechbloxModdingAPI", "TechbloxModdingAPI\TechbloxModdingAPI.csproj", "{7FD5A7D8-4F3E-426A-B07D-7DC70442A4DF}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CodeGenerator", "CodeGenerator\CodeGenerator.csproj", "{0EBB6400-95A7-4A3D-B2ED-BF31E364CC10}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MakeEverythingPublicInGame", "MakeEverythingPublicInGame\MakeEverythingPublicInGame.csproj", "{391A3107-E5C6-4A04-9467-6D868AA9A8B4}" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|Any CPU = Debug|Any CPU - Release|Any CPU = Release|Any CPU - Test|Any CPU = Test|Any CPU - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {7FD5A7D8-4F3E-426A-B07D-7DC70442A4DF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {7FD5A7D8-4F3E-426A-B07D-7DC70442A4DF}.Debug|Any CPU.Build.0 = Debug|Any CPU - {7FD5A7D8-4F3E-426A-B07D-7DC70442A4DF}.Release|Any CPU.ActiveCfg = Release|Any CPU - {7FD5A7D8-4F3E-426A-B07D-7DC70442A4DF}.Release|Any CPU.Build.0 = Release|Any CPU - {7FD5A7D8-4F3E-426A-B07D-7DC70442A4DF}.Test|Any CPU.ActiveCfg = Test|Any CPU - {7FD5A7D8-4F3E-426A-B07D-7DC70442A4DF}.Test|Any CPU.Build.0 = Test|Any CPU - {0EBB6400-95A7-4A3D-B2ED-BF31E364CC10}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {0EBB6400-95A7-4A3D-B2ED-BF31E364CC10}.Debug|Any CPU.Build.0 = Debug|Any CPU - {0EBB6400-95A7-4A3D-B2ED-BF31E364CC10}.Release|Any CPU.ActiveCfg = Release|Any CPU - {0EBB6400-95A7-4A3D-B2ED-BF31E364CC10}.Release|Any CPU.Build.0 = Release|Any CPU - {0EBB6400-95A7-4A3D-B2ED-BF31E364CC10}.Test|Any CPU.ActiveCfg = Debug|Any CPU - {0EBB6400-95A7-4A3D-B2ED-BF31E364CC10}.Test|Any CPU.Build.0 = Debug|Any CPU - {391A3107-E5C6-4A04-9467-6D868AA9A8B4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {391A3107-E5C6-4A04-9467-6D868AA9A8B4}.Debug|Any CPU.Build.0 = Debug|Any CPU - {391A3107-E5C6-4A04-9467-6D868AA9A8B4}.Release|Any CPU.ActiveCfg = Release|Any CPU - {391A3107-E5C6-4A04-9467-6D868AA9A8B4}.Release|Any CPU.Build.0 = Release|Any CPU - {391A3107-E5C6-4A04-9467-6D868AA9A8B4}.Test|Any CPU.ActiveCfg = Debug|Any CPU - {391A3107-E5C6-4A04-9467-6D868AA9A8B4}.Test|Any CPU.Build.0 = Debug|Any CPU - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection - GlobalSection(ExtensibilityGlobals) = postSolution - SolutionGuid = {72FB94D0-6C50-475B-81E0-C94C7D7A2A17} - EndGlobalSection -EndGlobal diff --git a/TechbloxModdingAPI/App/AntiAntiCheatPatch.cs b/TechbloxModdingAPI/App/AntiAntiCheatPatch.cs deleted file mode 100644 index 8a6e24a..0000000 --- a/TechbloxModdingAPI/App/AntiAntiCheatPatch.cs +++ /dev/null @@ -1,58 +0,0 @@ -using System; -using System.Collections.Generic; -using HarmonyLib; -using Svelto.Tasks; -using Techblox.Anticheat.Client; - -namespace TechbloxModdingAPI.App -{ - public static class AntiAntiCheatPatch - { - private delegate bool AntiAnticheatDelegate(ref object __result); - - private delegate bool AntiAnticheatDelegateBool(ref bool __result); - - private delegate bool AntiAnticheatDelegateTask(ref IEnumerator __result); - - public static void Init(Harmony harmony) - { - var type = AccessTools.TypeByName("Techblox.Services.Eos.Anticheat.Client.Services.AnticheatClientService"); - harmony.Patch(type.GetConstructors()[0], new HarmonyMethod(((Func) AntiAntiCheat).Method)); - harmony.Patch(AccessTools.Method(type, "Shutdown"), new HarmonyMethod(((Func) AntiAntiCheat).Method)); - harmony.Patch(AccessTools.Method(type, "StartProtectedSession"), new HarmonyMethod(((AntiAnticheatDelegate) AntiAntiCheat).Method)); - harmony.Patch(AccessTools.Method(type, "StopProtectedSession"), new HarmonyMethod(((AntiAnticheatDelegateBool) AntiAntiCheat).Method)); - harmony.Patch(AccessTools.Method("Techblox.Services.Eos.Anticheat.Client.EosGetPendingMessagesToSendServiceRequest:Execute"), new HarmonyMethod(((AntiAnticheatDelegateTask)AntiAntiCheatTask).Method)); - harmony.Patch(AccessTools.Method("Techblox.Anticheat.Client.Engines.ProcessEACViolationEngine:PollAnticheatStatus"), new HarmonyMethod(((AntiAnticheatDelegateTask)AntiAntiCheatTask).Method)); - harmony.Patch(AccessTools.Method(typeof(AnticheatClientCompositionRoot), "ClientComposeTimeRunning"), new HarmonyMethod(((Func)AntiAntiCheat).Method)); - } - - private static bool AntiAntiCheat() => false; - - private static bool AntiAntiCheat(ref object __result) - { - var targetType = - AccessTools.TypeByName("Techblox.Services.Eos.Anticheat.Client.Services.StartProtectedSessionResult"); - var target = Activator.CreateInstance(targetType); - targetType.GetField("Success").SetValue(target, true); - __result = target; - return false; - } - - private static bool AntiAntiCheat(ref bool __result) - { - __result = true; - return false; - } - - private static bool AntiAntiCheatTask(ref IEnumerator __result) - { - IEnumerator Func() - { - yield return Yield.It; - } - - __result = Func(); - return false; - } - } -} \ No newline at end of file diff --git a/TechbloxModdingAPI/App/AppCallbacksTest.cs b/TechbloxModdingAPI/App/AppCallbacksTest.cs deleted file mode 100644 index c1e184b..0000000 --- a/TechbloxModdingAPI/App/AppCallbacksTest.cs +++ /dev/null @@ -1,35 +0,0 @@ -using System; - -using TechbloxModdingAPI.Tests; - -namespace TechbloxModdingAPI.App -{ -#if TEST - /// - /// App callbacks tests. - /// Only available in TEST builds. - /// - [APITestClass] - public static class AppCallbacksTest - { - [APITestStartUp] - public static void StartUp() - { - // this could be split into 6 separate test cases - Game.Enter += Assert.CallsBack("GameEnter"); - Game.Exit += Assert.CallsBack("GameExit"); - Game.Simulate += Assert.CallsBack("GameSimulate"); - Game.Edit += Assert.CallsBack("GameEdit"); - Client.EnterMenu += Assert.CallsBack("MenuEnter"); - Client.ExitMenu += Assert.CallsBack("MenuExit"); - } - - [APITestCase(TestType.Game)] - public static void Test() - { - // the test is actually completely implemented in StartUp() - // this is here just so it looks less weird (not required) - } - } -#endif -} diff --git a/TechbloxModdingAPI/App/AppExceptions.cs b/TechbloxModdingAPI/App/AppExceptions.cs deleted file mode 100644 index dfe3afe..0000000 --- a/TechbloxModdingAPI/App/AppExceptions.cs +++ /dev/null @@ -1,42 +0,0 @@ -using System; -using System.Runtime.Serialization; - -namespace TechbloxModdingAPI.App -{ - public class AppException : TechbloxModdingAPIException - { - public AppException() - { - } - - public AppException(string message) : base(message) - { - } - - public AppException(string message, Exception innerException) : base(message, innerException) - { - } - } - - public class AppStateException : AppException - { - public AppStateException() - { - } - - public AppStateException(string message) : base(message) - { - } - } - - public class GameNotFoundException : AppException - { - public GameNotFoundException() - { - } - - public GameNotFoundException(string message) : base(message) - { - } - } -} diff --git a/TechbloxModdingAPI/App/Client.cs b/TechbloxModdingAPI/App/Client.cs deleted file mode 100644 index 317adec..0000000 --- a/TechbloxModdingAPI/App/Client.cs +++ /dev/null @@ -1,171 +0,0 @@ -using System; -using System.Reflection; -using HarmonyLib; - -using RobocraftX.Services; -using UnityEngine; -using RobocraftX.Common; -using TechbloxModdingAPI.Utility; - -namespace TechbloxModdingAPI.App -{ - /// - /// The Techblox application that is running this code right now. - /// - public class Client - { - public static Client Instance { get; } = new Client(); - - protected static Func ErrorHandlerInstanceGetter; - - protected static Action EnqueueError; - - /// - /// An event that fires whenever the main menu is loaded. - /// - public static event EventHandler EnterMenu - { - add => Game.menuEngine.EnterMenu += value; - remove => Game.menuEngine.EnterMenu -= value; - } - - /// - /// An event that fire whenever the main menu is exited. - /// - public static event EventHandler ExitMenu - { - add => Game.menuEngine.ExitMenu += value; - remove => Game.menuEngine.ExitMenu -= value; - } - - /// - /// Techblox build version string. - /// Usually this is in the form YYYY.mm.DD.HH.MM.SS - /// - /// The version. - public string Version - { - get => Application.version; - } - - /// - /// Unity version string. - /// - /// The unity version. - public string UnityVersion - { - get => Application.unityVersion; - } - - /// - /// Game saves currently visible in the menu. - /// These take a second to completely populate after the EnterMenu event fires. - /// - /// My games. - public Game[] MyGames - { - get - { - if (!Game.menuEngine.IsInMenu) return Array.Empty(); - return Game.menuEngine.GetMyGames(); - } - } - - /// - /// Whether Techblox is in the Main Menu - /// - /// true if in menu; false when loading or in a game. - public bool InMenu - { - get => Game.menuEngine.IsInMenu; - } - - /// - /// Open a popup which prompts the user to click a button. - /// This reuses Techblox's error dialog popup - /// - /// The popup to display. Use an instance of SingleChoicePrompt or DualChoicePrompt. - public void PromptUser(Error popup) - { - // if the stuff wasn't mostly set to internal, this would be written as: - // RobocraftX.Services.ErrorHandler.Instance.EqueueError(error); - object errorHandlerInstance = ErrorHandlerInstanceGetter(); - EnqueueError(errorHandlerInstance, popup); - } - - public void CloseCurrentPrompt() - { - object errorHandlerInstance = ErrorHandlerInstanceGetter(); - var popup = GetPopupCloseMethods(errorHandlerInstance); - popup.Close(); - } - - public void SelectFirstPromptButton() - { - object errorHandlerInstance = ErrorHandlerInstanceGetter(); - var popup = GetPopupCloseMethods(errorHandlerInstance); - popup.FirstButton(); - } - - public void SelectSecondPromptButton() - { - object errorHandlerInstance = ErrorHandlerInstanceGetter(); - var popup = GetPopupCloseMethods(errorHandlerInstance); - popup.SecondButton(); - } - - internal static void Init() - { - // this would have been so much simpler if this didn't involve a bunch of internal fields & classes - Type errorHandler = AccessTools.TypeByName("RobocraftX.Services.ErrorHandler"); - Type errorHandle = AccessTools.TypeByName("RobocraftX.Services.ErrorHandle"); - ErrorHandlerInstanceGetter = (Func) AccessTools.Method("TechbloxModdingAPI.App.Client:GenInstanceGetter") - .MakeGenericMethod(errorHandler) - .Invoke(null, new object[0]); - EnqueueError = (Action) AccessTools.Method("TechbloxModdingAPI.App.Client:GenEnqueueError") - .MakeGenericMethod(errorHandler, errorHandle) - .Invoke(null, new object[0]); - } - - // Creating delegates once is faster than reflection every time - // Admittedly, this way is more difficult to code and less readable - private static Func GenInstanceGetter() - { - Type errorHandler = AccessTools.TypeByName("RobocraftX.Services.ErrorHandler"); - MethodInfo instance = AccessTools.PropertyGetter(errorHandler, "Instance"); - Func getterSimple = (Func) Delegate.CreateDelegate(typeof(Func), null, instance); - Func getterCasted = () => (object) getterSimple(); - return getterCasted; - } - - private static Action GenEnqueueError() - { - Type errorHandler = AccessTools.TypeByName("RobocraftX.Services.ErrorHandler"); - MethodInfo enqueueError = AccessTools.Method(errorHandler, "EnqueueError"); - Func enqueueSimple = - (Func) Delegate.CreateDelegate(typeof(Func), enqueueError); - Action enqueueCasted = - (object instance, Error error) => { enqueueSimple((T) instance, error); }; - return enqueueCasted; - } - - private static (Action Close, Action FirstButton, Action SecondButton) _errorPopup; - - private static (Action Close, Action FirstButton, Action SecondButton) GetPopupCloseMethods(object handler) - { - if (_errorPopup.Close != null) - return _errorPopup; - Type errorHandler = handler.GetType(); - FieldInfo field = AccessTools.Field(errorHandler, "errorPopup"); - var errorPopup = (ErrorPopup)field.GetValue(handler); - MethodInfo info = AccessTools.Method(errorPopup.GetType(), "ClosePopup"); - var close = (Action)Delegate.CreateDelegate(typeof(Action), errorPopup, info); - info = AccessTools.Method(errorPopup.GetType(), "HandleFirstOption"); - var first = (Action)Delegate.CreateDelegate(typeof(Action), errorPopup, info); - info = AccessTools.Method(errorPopup.GetType(), "HandleSecondOption"); - var second = (Action)Delegate.CreateDelegate(typeof(Action), errorPopup, info); - _errorPopup = (close, first, second); - return _errorPopup; - } - } -} diff --git a/TechbloxModdingAPI/App/ClientAlertTest.cs b/TechbloxModdingAPI/App/ClientAlertTest.cs deleted file mode 100644 index 278a826..0000000 --- a/TechbloxModdingAPI/App/ClientAlertTest.cs +++ /dev/null @@ -1,67 +0,0 @@ -using System; -using HarmonyLib; - -using RobocraftX.Services; - -using TechbloxModdingAPI.Tests; - -namespace TechbloxModdingAPI.App -{ -#if TEST - /// - /// Client popups tests. - /// Only available in TEST builds. - /// - [APITestClass] - public static class ClientAlertTest - { - private static DualChoicePrompt popup2 = null; - - private static SingleChoicePrompt popup1 = null; - - [APITestStartUp] - public static void StartUp2() - { - popup2 = new DualChoicePrompt("This is a test double-button popup", - "The cake is a lie", - "lmao", - () => { }, - "kek", - () => { }); - } - - [APITestStartUp] - public static void StartUp1() - { - popup1 = new SingleChoicePrompt("The cake is a lie", - "This is a test single-button popup", - "qwertyuiop", - () => { }); - } - - [APITestCase(TestType.Menu)] - public static void TestPopUp2() - { - Client.Instance.PromptUser(popup2); - } - - [APITestCase(TestType.Menu)] - public static void TestPopUp1() - { - Client.Instance.PromptUser(popup1); - } - - [APITestCase(TestType.Menu)] - public static void TestPopUpClose1() - { - Client.Instance.CloseCurrentPrompt(); - } - - [APITestCase(TestType.Menu)] - public static void TestPopUpClose2() - { - Client.Instance.CloseCurrentPrompt(); - } - } -#endif -} \ No newline at end of file diff --git a/TechbloxModdingAPI/App/CurrentGameMode.cs b/TechbloxModdingAPI/App/CurrentGameMode.cs deleted file mode 100644 index 211b552..0000000 --- a/TechbloxModdingAPI/App/CurrentGameMode.cs +++ /dev/null @@ -1,27 +0,0 @@ -using System; - -namespace TechbloxModdingAPI.App -{ - public enum CurrentGameMode - { - None, - /// - /// Building a world - /// - Build, - /// - /// Playing on a map - /// - Play, - /// - /// Viewing a prefab (doesn't exist anymore) - /// - [Obsolete] - View, - /// - /// Viewing a tutorial (doesn't exist anymore) - /// - [Obsolete] - Tutorial - } -} \ No newline at end of file diff --git a/TechbloxModdingAPI/App/Game.cs b/TechbloxModdingAPI/App/Game.cs deleted file mode 100644 index aac7cb5..0000000 --- a/TechbloxModdingAPI/App/Game.cs +++ /dev/null @@ -1,490 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Runtime.CompilerServices; - -using RobocraftX.GUI.MyGamesScreen; -using Svelto.ECS; -using Techblox.GameSelection; - -using TechbloxModdingAPI.Blocks; -using TechbloxModdingAPI.Tasks; -using TechbloxModdingAPI.Utility; - -namespace TechbloxModdingAPI.App -{ - /// - /// An in-game save. - /// This can be a menu item for a local save or the currently loaded save. - /// Support for Steam Workshop coming soon (hopefully). - /// - public class Game - { - // extensible engines - protected static GameGameEngine gameEngine = new GameGameEngine(); - protected internal static GameMenuEngine menuEngine = new GameMenuEngine(); - protected static DebugInterfaceEngine debugOverlayEngine = new DebugInterfaceEngine(); - protected static GameBuildSimEventEngine buildSimEventEngine = new GameBuildSimEventEngine(); - - private List debugIds = new List(); - - private bool menuMode = true; - private bool hasId = false; - - /// - /// Initializes a new instance of the class. - /// - /// Menu identifier. - public Game(uint id) : this(new EGID(id, MyGamesScreenExclusiveGroups.MyGames)) - { - } - - /// - /// Initializes a new instance of the class. - /// - /// Menu identifier. - public Game(EGID id) - { - this.Id = id.entityID; - this.EGID = id; - this.hasId = true; - menuMode = true; - if (!VerifyMode()) throw new AppStateException("Game cannot be created while not in a game nor in a menu (is the game in a loading screen?)"); - } - - /// - /// Initializes a new instance of the class without id. - /// This is assumed to be the current game. - /// - public Game() - { - menuMode = false; - if (!VerifyMode()) throw new AppStateException("Game cannot be created while not in a game nor in a menu (is the game in a loading screen?)"); - if (menuEngine.IsInMenu) throw new GameNotFoundException("Game not found."); - } - - /// - /// Returns the currently loaded game. - /// If in a menu, manipulating the returned object may not work as intended. - /// - /// The current game. - public static Game CurrentGame() - { - return new Game(); - } - - /// - /// Creates a new game and adds it to the menu. - /// If not in a menu, this will throw AppStateException. - /// - /// The new game. - public static Game NewGame() - { - if (!menuEngine.IsInMenu) throw new AppStateException("New Game cannot be created while not in a menu."); - uint nextId = menuEngine.HighestID() + 1; - EGID egid = new EGID(nextId, MyGamesScreenExclusiveGroups.MyGames); - menuEngine.CreateMyGame(egid); - return new Game(egid); - } - - /// - /// An event that fires whenever a game is switched to simulation mode (time running mode). - /// - public static event EventHandler Simulate - { - add => buildSimEventEngine.SimulationMode += value; - remove => buildSimEventEngine.SimulationMode -= value; - } - - /// - /// An event that fires whenever a game is switched to edit mode (time stopped mode). - /// This does not fire when a game is loaded. - /// - public static event EventHandler Edit - { - add => buildSimEventEngine.BuildMode += value; - remove => buildSimEventEngine.BuildMode -= value; - } - - /// - /// An event that fires right after a game is completely loaded. - /// - public static event EventHandler Enter - { - add => gameEngine.EnterGame += value; - remove => gameEngine.EnterGame -= value; - } - - /// - /// An event that fires right before a game returns to the main menu. - /// At this point, Techblox is transitioning state so many things are invalid/unstable here. - /// - public static event EventHandler Exit - { - add => gameEngine.ExitGame += value; - remove => gameEngine.ExitGame -= value; - } - - /// - /// The game's unique menu identifier. - /// - /// The identifier. - public uint Id - { - get; - private set; - } - - /// - /// The game's unique menu EGID. - /// - /// The egid. - public EGID EGID - { - get; - private set; - } - - /// - /// Whether the game is a (valid) menu item. - /// - /// true if menu item; otherwise, false. - public bool MenuItem - { - get => menuMode && hasId; - } - - /// - /// The game's name. - /// - /// The name. - public string Name - { - get - { - if (!VerifyMode()) return null; - if (menuMode) return menuEngine.GetGameInfo(EGID).GameName; - return gameEngine.GetGameData().saveName; - } - - set - { - if (!VerifyMode()) return; - if (menuMode) - { - menuEngine.SetGameName(EGID, value); - } // Save details are directly saved from user input or not changed at all when in game - } - } - - /// - /// The game's description. - /// - /// The description. - public string Description - { - get - { - if (!VerifyMode()) return null; - if (menuMode) return menuEngine.GetGameInfo(EGID).GameDescription; - return ""; - } - - set - { - if (!VerifyMode()) return; - if (menuMode) - { - menuEngine.SetGameDescription(EGID, value); - } // No description exists in-game - } - } - - /// - /// The path to the game's save folder. - /// - /// The path. - public string Path - { - get - { - if (!VerifyMode()) return null; - if (menuMode) return menuEngine.GetGameInfo(EGID).SavedGamePath; - return gameEngine.GetGameData().gameID; - } - - set - { - if (!VerifyMode()) return; - if (menuMode) - { - menuEngine.GetGameInfo(EGID).SavedGamePath.Set(value); - } - } - } - - /// - /// The Steam Workshop Id of the game save. - /// In most cases this is invalid and returns 0, so this can be ignored. - /// - /// The workshop identifier. - [Obsolete] - public ulong WorkshopId - { - get - { - return 0uL; // Not supported anymore - } - - set - { - } - } - - /// - /// Whether the game is in simulation mode. - /// - /// true if is simulating; otherwise, false. - public bool IsSimulating - { - get - { - if (!VerifyMode()) return false; - return !menuMode && gameEngine.IsTimeRunningMode(); - } - - set - { - if (!VerifyMode()) return; - if (!menuMode && gameEngine.IsTimeRunningMode() != value) - gameEngine.ToggleTimeMode(); - } - } - - /// - /// Whether the game is in time-running mode. - /// Alias of IsSimulating. - /// - /// true if is time running; otherwise, false. - public bool IsTimeRunning - { - get => IsSimulating; - - set - { - IsSimulating = value; - } - } - - /// - /// Whether the game is in time-stopped mode. - /// - /// true if is time stopped; otherwise, false. - public bool IsTimeStopped - { - get - { - if (!VerifyMode()) return false; - return !menuMode && gameEngine.IsTimeStoppedMode(); - } - - set - { - if (!VerifyMode()) return; - if (!menuMode && gameEngine.IsTimeStoppedMode() != value) - gameEngine.ToggleTimeMode(); - } - } - - /// - /// Toggles the time mode. - /// - public void ToggleTimeMode() - { - if (!VerifyMode()) return; - if (menuMode || !gameEngine.IsInGame) - { - throw new AppStateException("Game menu item cannot toggle it's time mode"); - } - gameEngine.ToggleTimeMode(); - } - - /// - /// The mode of the game. - /// - public CurrentGameMode Mode - { - get - { - if (menuMode || !VerifyMode()) return CurrentGameMode.None; - return gameEngine.GetGameData().gameMode == GameMode.CreateWorld ? CurrentGameMode.Build : CurrentGameMode.Play; - } - } - - /// - /// Load the game save. - /// This happens asynchronously, so when this method returns the game not loaded yet. - /// Use the Game.Enter event to perform operations after the game has completely loaded. - /// - public void EnterGame() - { - if (!VerifyMode()) return; - if (!hasId) - { - throw new GameNotFoundException("Game has an invalid ID"); - } - ISchedulable task = new Once(() => { menuEngine.EnterGame(EGID); this.menuMode = false; }); - Scheduler.Schedule(task); - } - - /// - /// Return to the menu. - /// Part of this always happens asynchronously, so when this method returns the game has not exited yet. - /// Use the Client.EnterMenu event to perform operations after the game has completely exited. - /// - /// If set to true, do this async. - public void ExitGame(bool async = false) - { - if (!VerifyMode()) return; - if (menuMode) - { - throw new GameNotFoundException("Cannot exit game using menu ID"); - } - gameEngine.ExitCurrentGame(async); - this.menuMode = true; - } - - /// - /// Saves the game. - /// Part of this happens asynchronously, so when this method returns the game has not been saved yet. - /// - public void SaveGame() - { - if (!VerifyMode()) return; - if (menuMode) - { - throw new GameNotFoundException("Cannot save game using menu ID"); - } - gameEngine.SaveCurrentGame(); - } - - /// - /// Add information to the in-game debug display. - /// When this object is garbage collected, this debug info is automatically removed. - /// The provided getter function is called each frame so make sure it returns quickly. - /// - /// Debug info identifier. - /// A function that returns the current information. - public void AddDebugInfo(string id, Func contentGetter) - { - if (!VerifyMode()) return; - if (menuMode) - { - throw new GameNotFoundException("Game object references a menu item but AddDebugInfo only works on the currently-loaded game"); - } - debugOverlayEngine.SetInfo("game_" + id, contentGetter); - debugIds.Add(id); - } - - /// - /// Remove information from the in-game debug display. - /// - /// true, if debug info was removed, false otherwise. - /// Debug info identifier. - public bool RemoveDebugInfo(string id) - { - if (!VerifyMode()) return false; - if (menuMode) - { - throw new GameNotFoundException("Game object references a menu item but RemoveDebugInfo only works on the currently-loaded game"); - } - if (!debugIds.Contains(id)) return false; - debugOverlayEngine.RemoveInfo("game_" + id); - return debugIds.Remove(id); - } - - /// - /// Add information to the in-game debug display. - /// This debug info will be present for all games until it is manually removed. - /// The provided getter function is called each frame so make sure it returns quickly. - /// - /// Debug info identifier. - /// A function that returns the current information. - public static void AddPersistentDebugInfo(string id, Func contentGetter) - { - debugOverlayEngine.SetInfo("persistent_" + id, contentGetter); - } - - /// - /// Remove persistent information from the in-game debug display. - /// - /// true, if debug info was removed, false otherwise. - /// Debug info identifier. - public static bool RemovePersistentDebugInfo(string id) - { - return debugOverlayEngine.RemoveInfo("persistent_" + id); - } - - /// - /// Gets the blocks in the game. - /// This returns null when in a loading state, and throws AppStateException when in menu. - /// - /// The blocks in game. - /// The block to search for. BlockIDs.Invalid will return all blocks. - public Block[] GetBlocksInGame(BlockIDs filter = BlockIDs.Invalid) - { - if (!VerifyMode()) return null; - if (menuMode) - { - throw new AppStateException("Game object references a menu item but GetBlocksInGame only works on the currently-loaded game"); - } - EGID[] blockEGIDs = gameEngine.GetAllBlocksInGame(filter); - Block[] blocks = new Block[blockEGIDs.Length]; - for (int b = 0; b < blockEGIDs.Length; b++) - { - blocks[b] = Block.New(blockEGIDs[b]); - } - return blocks; - } - - /// - /// Enable the screenshot taker for updating the game's screenshot. Breaks the pause menu in a new save. - /// - public void EnableScreenshotTaker() - { - if (!VerifyMode()) return; - gameEngine.EnableScreenshotTaker(); - } - - ~Game() - { - foreach (string id in debugIds) - { - debugOverlayEngine.RemoveInfo(id); - } - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - private bool VerifyMode() - { - if (menuMode && (!menuEngine.IsInMenu || gameEngine.IsInGame)) - { - // either game loading or API is broken - return false; - } - if (!menuMode && (menuEngine.IsInMenu || !gameEngine.IsInGame)) - { - // either game loading or API is broken - return false; - } - return true; - } - - internal static void Init() - { - GameEngineManager.AddGameEngine(gameEngine); - GameEngineManager.AddGameEngine(debugOverlayEngine); - GameEngineManager.AddGameEngine(buildSimEventEngine); - MenuEngineManager.AddMenuEngine(menuEngine); - } - } -} diff --git a/TechbloxModdingAPI/App/GameBuildSimEventEngine.cs b/TechbloxModdingAPI/App/GameBuildSimEventEngine.cs deleted file mode 100644 index 67e6769..0000000 --- a/TechbloxModdingAPI/App/GameBuildSimEventEngine.cs +++ /dev/null @@ -1,47 +0,0 @@ -using System; - -using RobocraftX.Common; -using RobocraftX.StateSync; -using Svelto.ECS; -using Unity.Jobs; -using TechbloxModdingAPI.Engines; -using TechbloxModdingAPI.Utility; - -namespace TechbloxModdingAPI.App -{ - public class GameBuildSimEventEngine : IApiEngine, IUnorderedInitializeOnTimeRunningModeEntered, IUnorderedInitializeOnTimeStoppedModeEntered - { - public WrappedHandler SimulationMode; - - public WrappedHandler BuildMode; - - public string Name => "TechbloxModdingAPIBuildSimEventGameEngine"; - - public bool isRemovable => false; - - public EntitiesDB entitiesDB { set; private get; } - - public void Dispose() { } - - public void Ready() { } - - public JobHandle OnInitializeTimeRunningMode(JobHandle inputDeps) - { - SimulationMode.Invoke(this, new GameEventArgs { GameName = "", GamePath = "" }); // TODO - return inputDeps; - } - - public JobHandle OnInitializeTimeStoppedMode(JobHandle inputDeps) - { - BuildMode.Invoke(this, new GameEventArgs { GameName = "", GamePath = "" }); - return inputDeps; - } - } - - public struct GameEventArgs - { - public string GameName; - - public string GamePath; - } -} diff --git a/TechbloxModdingAPI/App/GameGameEngine.cs b/TechbloxModdingAPI/App/GameGameEngine.cs deleted file mode 100644 index 8eab6fd..0000000 --- a/TechbloxModdingAPI/App/GameGameEngine.cs +++ /dev/null @@ -1,195 +0,0 @@ -using System.Collections.Generic; - -using HarmonyLib; -using RobocraftX; -using RobocraftX.Common; -using RobocraftX.Schedulers; -using RobocraftX.SimulationModeState; -using Svelto.ECS; -using Svelto.Tasks; -using Svelto.Tasks.Lean; -using RobocraftX.Blocks; -using RobocraftX.Common.Loading; -using RobocraftX.Multiplayer; -using RobocraftX.ScreenshotTaker; -using Techblox.Environment.Transition; -using Techblox.GameSelection; - -using TechbloxModdingAPI.Blocks; -using TechbloxModdingAPI.Engines; -using TechbloxModdingAPI.Input; -using TechbloxModdingAPI.Players; -using TechbloxModdingAPI.Utility; - -namespace TechbloxModdingAPI.App -{ - public class GameGameEngine : IApiEngine, IReactOnAddAndRemove - { - public WrappedHandler EnterGame; - - public WrappedHandler ExitGame; - - public string Name => "TechbloxModdingAPIGameInfoMenuEngine"; - - public bool isRemovable => false; - - public EntitiesDB entitiesDB { set; private get; } - - private bool enteredGame; - private bool loadingFinished; - private bool playerJoined; - - public void Dispose() - { - if (GameReloadedPatch.IsReload) - return; // Toggling time mode - ExitGame.Invoke(this, new GameEventArgs { GameName = GetGameData().saveName, GamePath = GetGameData().gameID }); - IsInGame = false; - loadingFinished = false; - playerJoined = false; - enteredGame = false; - } - - public void Ready() - { - if (GameReloadedPatch.IsReload) - return; // Toggling time mode - enteredGame = true; - Player.Joined += OnPlayerJoined; - } - - private void OnPlayerJoined(object sender, PlayerEventArgs args) - { - if (args.Player.Type != PlayerType.Local) return; - playerJoined = true; - Player.Joined -= OnPlayerJoined; - CheckJoinEvent(); - } - - // game functionality - - public bool IsInGame - { - get; - private set; - } = false; - - public void ExitCurrentGame(bool async = false) - { - if (async) - { - ExitCurrentGameAsync().RunOn(ClientLean.EveryFrameStepRunner_TimeRunningAndStopped); - } - else - { - entitiesDB.QueryEntity(CommonExclusiveGroups.GameSceneEGID).WantsToQuit = true; - entitiesDB.PublishEntityChange(CommonExclusiveGroups.GameSceneEGID); - } - - } - - public IEnumerator ExitCurrentGameAsync() - { - /* - while (Lean.EveryFrameStepRunner_RUNS_IN_TIME_STOPPED_AND_RUNNING.isStopping) { yield return Yield.It; } - AccessTools.Method(typeof(FullGameCompositionRoot), "SwitchToMenu").Invoke(FullGameFields.Instance, new object[0]);*/ - yield return Yield.It; - entitiesDB.QueryEntity(CommonExclusiveGroups.GameSceneEGID).WantsToQuit = true; - entitiesDB.PublishEntityChange(CommonExclusiveGroups.GameSceneEGID); - } - - public void SaveCurrentGame() - { - ref GameSceneEntityStruct gses = ref entitiesDB.QueryEntity(CommonExclusiveGroups.GameSceneEGID); - gses.LoadAfterSaving = false; - gses.SaveNow = true; - entitiesDB.PublishEntityChange(CommonExclusiveGroups.GameSceneEGID); - } - - public bool IsTimeRunningMode() - { - return TimeRunningModeUtil.IsTimeRunningMode(entitiesDB); - } - - public bool IsTimeStoppedMode() - { - return TimeRunningModeUtil.IsTimeStoppedMode(entitiesDB); - } - - public void ToggleTimeMode() - { - if (TimeRunningModeUtil.IsTimeStoppedMode(entitiesDB)) - FakeInput.ActionInput(toggleMode: true); - else - { - IEnumerator ReloadBuildModeTask() - { - SwitchAnimationUtil.Start(entitiesDB); - while (SwitchAnimationUtil.IsFadeOutActive(entitiesDB)) - yield return (TaskContract)Yield.It; - FullGameFields._multiplayerParams.MultiplayerMode = MultiplayerMode.SinglePlayer; - AccessTools.Method(typeof(FullGameCompositionRoot), "ReloadGame") - .Invoke(FullGameFields.Instance, new object[] { }); - } - - ReloadBuildModeTask().RunOn(ClientLean.UIScheduler); - } - } - - public EGID[] GetAllBlocksInGame(BlockIDs filter = BlockIDs.Invalid) - { - var allBlocks = entitiesDB.QueryEntities(); - List blockEGIDs = new List(); - foreach (var ((_, ids, count), group) in allBlocks) - { - for (int i = 0; i < count; i++) - { - var id = new EGID(ids[i], group); - uint dbid; - if (filter == BlockIDs.Invalid) - dbid = (uint)filter; - else - dbid = entitiesDB.QueryEntity(id).DBID; - var ownership = entitiesDB.QueryEntity(id).BlockOwnership; - if ((ownership & BlockOwnership.User) != 0 && dbid == (ulong)filter) - blockEGIDs.Add(id); - } - } - - return blockEGIDs.ToArray(); - } - - public void EnableScreenshotTaker() - { - ref var local = ref entitiesDB.QueryEntity(ScreenshotTakerEgids.ScreenshotTaker); - if (local.enabled) - return; - local.enabled = true; - entitiesDB.PublishEntityChange(ScreenshotTakerEgids.ScreenshotTaker); - } - - public GameSelectionComponent GetGameData() - { - return entitiesDB.QueryEntity(GameSelectionConstants.GameSelectionEGID); - } - - public void Add(ref LoadingActionEntityStruct entityComponent, EGID egid) - { - } - - public void Remove(ref LoadingActionEntityStruct entityComponent, EGID egid) - { // Finished loading - if (!enteredGame) return; - enteredGame = false; - loadingFinished = true; - CheckJoinEvent(); - } - - private void CheckJoinEvent() - { - if (!loadingFinished || !playerJoined) return; - EnterGame.Invoke(this, new GameEventArgs { GameName = GetGameData().saveName, GamePath = GetGameData().gameID }); - IsInGame = true; - } - } -} diff --git a/TechbloxModdingAPI/App/GameMenuEngine.cs b/TechbloxModdingAPI/App/GameMenuEngine.cs deleted file mode 100644 index 8da4742..0000000 --- a/TechbloxModdingAPI/App/GameMenuEngine.cs +++ /dev/null @@ -1,197 +0,0 @@ -using System; -using System.Reflection; -using HarmonyLib; - -using RobocraftX; -using RobocraftX.GUI; -using RobocraftX.GUI.MyGamesScreen; -using RobocraftX.Multiplayer; -using Svelto.ECS; -using Svelto.ECS.Experimental; -using Techblox.GameSelection; - -using TechbloxModdingAPI.Engines; -using TechbloxModdingAPI.Utility; - -namespace TechbloxModdingAPI.App -{ - public class GameMenuEngine : IFactoryEngine - { - public WrappedHandler EnterMenu; - - public WrappedHandler ExitMenu; - public IEntityFactory Factory { set; private get; } - - public string Name => "TechbloxModdingAPIGameInfoGameEngine"; - - public bool isRemovable => false; - - public EntitiesDB entitiesDB { set; private get; } - - public GameMenuEngine() - { - MenuEnteredEnginePatch.EnteredExitedMenu = () => - { - if (IsInMenu) - EnterMenu.Invoke(this, new MenuEventArgs { }); - else - ExitMenu.Invoke(this, new MenuEventArgs { }); - }; - } - - public void Dispose() - { - } - - public void Ready() - { - MenuEnteredEnginePatch.IsInMenu = true; // At first it uses ActivateMenu(), then GoToMenu() which is patched - MenuEnteredEnginePatch.EnteredExitedMenu(); - } - - // game functionality - - public bool IsInMenu => MenuEnteredEnginePatch.IsInMenu; - - public Game[] GetMyGames() - { - var (mgsevs, count) = entitiesDB.QueryEntities(MyGamesScreenExclusiveGroups.MyGames); - Game[] games = new Game[count]; - for (int i = 0; i < count; i++) - { - Utility.Logging.MetaDebugLog($"Found game named {mgsevs[i].GameName}"); - games[i] = new Game(mgsevs[i].ID); - } - return games; - } - - public bool CreateMyGame(EGID id, string path = "", uint thumbnailId = 0, string gameName = "", string creatorName = "", string description = "", long createdDate = 0L) - { - EntityInitializer eci = Factory.BuildEntity(id); - eci.Init(new MyGameDataEntityStruct - { - SavedGamePath = new ECSString(path), - ThumbnailId = thumbnailId, - GameName = new ECSString(gameName), - CreatorName = new ECSString(creatorName), - GameDescription = new ECSString(description), - CreatedDate = createdDate, - }); - // entitiesDB.PublishEntityChange(id); // this will always fail - return true; - } - - public uint HighestID() - { - var (games, count) = entitiesDB.QueryEntities(MyGamesScreenExclusiveGroups.MyGames); - uint max = 0; - for (int i = 0; i < count; i++) - { - if (games[i].ID.entityID > max) - { - max = games[i].ID.entityID; - } - } - return max; - } - - public bool EnterGame(EGID id) - { - if (!ExistsGameInfo(id)) return false; - ref MyGameDataEntityStruct mgdes = ref GetGameInfo(id); - return EnterGame(mgdes.GameName, mgdes.FileId); - } - - public bool EnterGame(ECSString gameName, string fileId, bool autoEnterSim = false) - { - FullGameFields._multiplayerParams.MultiplayerMode = MultiplayerMode.SinglePlayer; - ref var selection = ref entitiesDB.QueryEntity(GameSelectionConstants.GameSelectionEGID); - selection.userContentID.Set(fileId); - selection.triggerStart = true; - selection.saveType = SaveType.ExistingSave; - selection.saveName = gameName; - selection.gameMode = GameMode.PlayGame; - selection.gameID.Set("GAMEID_Road_Track"); //TODO: Expose to the API - return true; - } - - public bool SetGameName(EGID id, string name) - { - if (!ExistsGameInfo(id)) return false; - GetGameInfo(id).GameName.Set(name); - GetGameViewInfo(id).MyGamesSlotComponent.GameName = StringUtil.SanitiseString(name); - return true; - } - - public bool SetGameDescription(EGID id, string name) - { - if (!ExistsGameInfo(id)) return false; - GetGameInfo(id).GameDescription.Set(name); - GetGameViewInfo(id).MyGamesSlotComponent.GameDescription = StringUtil.SanitiseString(name); - return true; - } - - public bool ExistsGameInfo(EGID id) - { - return entitiesDB.Exists(id); - } - - public ref MyGameDataEntityStruct GetGameInfo(EGID id) - { - return ref GetComponent(id); - } - - public dynamic GetGameViewInfo(EGID id) - { - dynamic structOptional = AccessTools.Method("TechbloxModdingAPI.Utility.NativeApiExtensions:QueryEntityOptional", new []{typeof(EntitiesDB), typeof(EGID)}) - .MakeGenericMethod(AccessTools.TypeByName("RobocraftX.GUI.MyGamesScreen.MyGamesSlotEntityViewStruct")) - .Invoke(null, new object[] {entitiesDB, new EGID(id.entityID, MyGamesScreenExclusiveGroups.GameSlotGuiEntities)}); - if (structOptional == null) throw new Exception("Could not get game slot entity"); - return structOptional ? structOptional : null; - } - - public ref T GetComponent(EGID id) where T: unmanaged, IEntityComponent - { - return ref entitiesDB.QueryEntity(id); - } - } - - internal class MyGameDataEntityDescriptor_DamnItFJWhyDidYouMakeThisInternal : GenericEntityDescriptor { } - - [HarmonyPatch] - static class MenuEnteredEnginePatch - { - internal static bool IsInMenu; - internal static Action EnteredExitedMenu; - public static void Postfix() - { - IsInMenu = true; - EnteredExitedMenu(); - } - - public static MethodBase TargetMethod() - { - return AccessTools.Method(typeof(FullGameCompositionRoot), "SwitchToMenu"); - } - } - - [HarmonyPatch] - static class MenuExitedEnginePatch - { - public static void Prefix() - { - MenuEnteredEnginePatch.IsInMenu = false; - MenuEnteredEnginePatch.EnteredExitedMenu(); - } - - public static MethodBase TargetMethod() - { - return AccessTools.Method(typeof(FullGameCompositionRoot), "SwitchToGame"); - } - } - - public struct MenuEventArgs - { - - } -} diff --git a/TechbloxModdingAPI/App/UserPrompts.cs b/TechbloxModdingAPI/App/UserPrompts.cs deleted file mode 100644 index 7548055..0000000 --- a/TechbloxModdingAPI/App/UserPrompts.cs +++ /dev/null @@ -1,27 +0,0 @@ -using System; -using HarmonyLib; - -using RobocraftX.Services; - -namespace TechbloxModdingAPI.App -{ - public class DualChoicePrompt : MultiChoiceError - { - public DualChoicePrompt(string errorMessage, string title, string firstButtonText, Action firstButtonAction, string secondButtonText, Action secondButtonAction) : base(errorMessage, firstButtonText, firstButtonAction, secondButtonText, secondButtonAction) - { - // internal readonly field smh - new Traverse(this).Field("Title").Value = title; - } - } - - public class SingleChoicePrompt : SingleChoiceError - { - public SingleChoicePrompt(string errorMessage, string buttonText, Action buttonClickAction) : base(errorMessage, buttonText, buttonClickAction) - { - } - - public SingleChoicePrompt(string titleText, string errorMessage, string buttonText, Action buttonClickAction) : base(titleText, errorMessage, buttonText, buttonClickAction) - { - } - } -} \ No newline at end of file diff --git a/TechbloxModdingAPI/Block.cs b/TechbloxModdingAPI/Block.cs deleted file mode 100644 index 5c3c897..0000000 --- a/TechbloxModdingAPI/Block.cs +++ /dev/null @@ -1,519 +0,0 @@ -using System; -using System.Collections.Generic; - -using DataLoader; -using Gamecraft.Blocks.BlockGroups; -using Svelto.ECS; -using Svelto.ECS.EntityStructs; -using RobocraftX.Common; -using RobocraftX.Blocks; -using Unity.Mathematics; -using HarmonyLib; -using RobocraftX.PilotSeat; -using RobocraftX.Rendering; -using Techblox.BlockLabelsServer; -using TechbloxModdingAPI.Blocks; -using TechbloxModdingAPI.Blocks.Engines; -using TechbloxModdingAPI.Tests; -using TechbloxModdingAPI.Utility; - -namespace TechbloxModdingAPI -{ - /// - /// A single (perhaps scaled) block. Properties may return default values if the block is removed and then setting them is ignored. - /// For specific block type operations, use the specialised block classes in the TechbloxModdingAPI.Blocks namespace. - /// - public class Block : EcsObjectBase, IEquatable, IEquatable - { - protected static readonly PlacementEngine PlacementEngine = new PlacementEngine(); - protected static readonly MovementEngine MovementEngine = new MovementEngine(); - protected static readonly RotationEngine RotationEngine = new RotationEngine(); - protected static readonly RemovalEngine RemovalEngine = new RemovalEngine(); - protected static readonly SignalEngine SignalEngine = new SignalEngine(); - protected static readonly BlockEventsEngine BlockEventsEngine = new BlockEventsEngine(); - protected static readonly ScalingEngine ScalingEngine = new ScalingEngine(); - protected static readonly BlockCloneEngine BlockCloneEngine = new BlockCloneEngine(); - - protected internal static readonly BlockEngine BlockEngine = new BlockEngine(); - - /// - /// Place a new block at the given position. If scaled, position means the center of the block. The default block size is 0.2 in terms of position. - /// Place blocks next to each other to connect them. - /// The placed block will be a complete block with a placement grid and collision which will be saved along with the game. - /// - /// The block's type - /// The block's position - default block size is 0.2 - /// Whether the block should be auto-wired (if functional) - /// The player who placed the block - /// The placed block or null if failed - public static Block PlaceNew(BlockIDs block, float3 position, bool autoWire = false, Player player = null) - { - if (PlacementEngine.IsInGame && GameState.IsBuildMode()) - { - var initializer = PlacementEngine.PlaceBlock(block, position, player, autoWire); - var egid = initializer.EGID; - var bl = New(egid); - bl.InitData = initializer; - Placed += bl.OnPlacedInit; - return bl; - } - - return null; - } - - /// - /// Returns the most recently placed block. - /// - /// The block object or null if doesn't exist - public static Block GetLastPlacedBlock() - { - uint lastBlockID = CommonExclusiveGroups.blockIDGeneratorClient.Peek() - 1; - EGID? egid = BlockEngine.FindBlockEGID(lastBlockID); - return egid.HasValue ? New(egid.Value) : null; - } - - /*public static Block CreateGhostBlock() - { - return BlockGroup._engine.BuildGhostChild(); - }*/ - - /// - /// An event that fires each time a block is placed. - /// - public static event EventHandler Placed - { //TODO: Rename and add instance version in 3.0 - add => BlockEventsEngine.Placed += value; - remove => BlockEventsEngine.Placed -= value; - } - - /// - /// An event that fires each time a block is removed. - /// - public static event EventHandler Removed - { - add => BlockEventsEngine.Removed += value; - remove => BlockEventsEngine.Removed -= value; - } - - private static readonly Dictionary Constructor, Type Type)> GroupToConstructor = - new Dictionary, Type)> - { - {CommonExclusiveGroups.DAMPEDSPRING_BLOCK_GROUP, (id => new DampedSpring(id), typeof(DampedSpring))}, - {CommonExclusiveGroups.ENGINE_BLOCK_BUILD_GROUP, (id => new Engine(id), typeof(Engine))}, - {CommonExclusiveGroups.LOGIC_BLOCK_GROUP, (id => new LogicGate(id), typeof(LogicGate))}, - {CommonExclusiveGroups.PISTON_BLOCK_GROUP, (id => new Piston(id), typeof(Piston))}, - {CommonExclusiveGroups.SERVO_BLOCK_GROUP, (id => new Servo(id), typeof(Servo))}, - {CommonExclusiveGroups.WHEELRIG_BLOCK_BUILD_GROUP, (id => new WheelRig(id), typeof(WheelRig))} - }; - - static Block() - { - foreach (var group in SeatGroups.SEATS_BLOCK_GROUPS) // Adds driver and passenger seats, occupied and unoccupied - GroupToConstructor.Add(group, (id => new Seat(id), typeof(Seat))); - } - - /// - /// Returns a correctly typed instance of this block. The instances are shared for a specific block. - /// If an instance is no longer referenced a new instance is returned. - /// - /// The EGID of the block - /// Whether the block is definitely a signaling block - /// - internal static Block New(EGID egid, bool signaling = false) - { - if (egid == default) return null; - if (GroupToConstructor.ContainsKey(egid.groupID)) - { - var (constructor, type) = GroupToConstructor[egid.groupID]; - return GetInstance(egid, constructor, type); - } - - return signaling - ? GetInstance(egid, e => new SignalingBlock(e)) - : GetInstance(egid, e => new Block(e)); - } - - public Block(EGID id) : base(id) - { - Type expectedType; - if (GroupToConstructor.ContainsKey(id.groupID) && - !GetType().IsAssignableFrom(expectedType = GroupToConstructor[id.groupID].Type)) - throw new BlockSpecializationException($"Incorrect block type! Expected: {expectedType} Actual: {GetType()}"); - } - - /// - /// This overload searches for the correct group the block is in. - /// It will throw an exception if the block doesn't exist. - /// Use the EGID constructor where possible or subclasses of Block as those specify the group. - /// - public Block(uint id) : this(BlockEngine.FindBlockEGID(id) - ?? throw new BlockTypeException( - "Could not find the appropriate group for the block." + - " The block probably doesn't exist or hasn't been submitted.")) - { - } - - /// - /// Places a new block in the world. - /// - /// The block's type - /// The block's position (a block is 0.2 wide in terms of position) - /// Whether the block should be auto-wired (if functional) - /// The player who placed the block - public Block(BlockIDs type, float3 position, bool autoWire = false, Player player = null) - : base(block => - { - if (!PlacementEngine.IsInGame || !GameState.IsBuildMode()) - throw new BlockException("Blocks can only be placed in build mode."); - var initializer = PlacementEngine.PlaceBlock(type, position, player, autoWire); - block.InitData = initializer; - Placed += ((Block)block).OnPlacedInit; - return initializer.EGID; - }) - { - } - - private EGID copiedFrom; - - /// - /// The block's current position or zero if the block no longer exists. - /// A block is 0.2 wide by default in terms of position. - /// - public float3 Position - { - get => MovementEngine.GetPosition(this); - set - { - MovementEngine.MoveBlock(this, value); - if (blockGroup != null) - blockGroup.PosAndRotCalculated = false; - BlockEngine.UpdateDisplayedBlock(Id); - } - } - - /// - /// The block's current rotation in degrees or zero if the block doesn't exist. - /// - public float3 Rotation - { - get => RotationEngine.GetRotation(this); - set - { - RotationEngine.RotateBlock(this, value); - if (blockGroup != null) - blockGroup.PosAndRotCalculated = false; - BlockEngine.UpdateDisplayedBlock(Id); - } - } - - /// - /// The block's non-uniform scale or zero if the block's invalid. Independent of the uniform scaling. - /// The default scale of 1 means 0.2 in terms of position. - /// - public float3 Scale - { - get => BlockEngine.GetBlockInfo(this).scale; - set - { - int uscale = UniformScale; - if (value.x < 4e-5) value.x = uscale; - if (value.y < 4e-5) value.y = uscale; - if (value.z < 4e-5) value.z = uscale; - BlockEngine.GetBlockInfo(this).scale = value; - //BlockEngine.GetBlockInfo(this).gridScale = value - (int3) value + 1; - if (!Exists) return; //UpdateCollision needs the block to exist - ScalingEngine.UpdateCollision(Id); - BlockEngine.UpdateDisplayedBlock(Id); - } - } - - /// - /// The block's uniform scale or zero if the block's invalid. Also sets the non-uniform scale. - /// The default scale of 1 means 0.2 in terms of position. - /// - public int UniformScale - { - get => BlockEngine.GetBlockInfo(this).scaleFactor; - set - { - if (value < 1) value = 1; - BlockEngine.GetBlockInfo(this).scaleFactor = value; - Scale = new float3(value, value, value); - } - } - - /** - * Whether the block is flipped. - */ - public bool Flipped - { - get => BlockEngine.GetBlockInfo(this).scale.x < 0; - set - { - ref var st = ref BlockEngine.GetBlockInfo(this); - st.scale.x = math.abs(st.scale.x) * (value ? -1 : 1); - BlockEngine.UpdatePrefab(this, (byte) Material, value); - } - } - - /// - /// The block's type (ID). Returns BlockIDs.Invalid if the block doesn't exist anymore. - /// - public BlockIDs Type - { - get - { - var opt = BlockEngine.GetBlockInfoOptional(this); - return opt ? (BlockIDs) opt.Get().DBID : BlockIDs.Invalid; - } - } - - /// - /// The block's color. Returns BlockColors.Default if the block no longer exists. - /// - public BlockColor Color - { - get - { - var opt = BlockEngine.GetBlockInfoOptional(this); - return new BlockColor(opt ? opt.Get().indexInPalette : byte.MaxValue); - } - set - { - if (value.Color == BlockColors.Default) - value = new BlockColor(FullGameFields._dataDb.TryGetValue((int) Type, out CubeListData cld) - ? cld.DefaultColour - : throw new BlockTypeException("Unknown block type! Could not set default color.")); - ref var color = ref BlockEngine.GetBlockInfo(this); - color.indexInPalette = value.Index; - color.hasNetworkChange = true; - color.paletteColour = BlockEngine.ConvertBlockColor(color.indexInPalette); //Setting to 255 results in black - BlockEngine.UpdateBlockColor(Id); - } - } - - /// - /// The block's exact color. Gets reset to the palette color (Color property) after reentering the game. - /// - public float4 CustomColor - { - get => BlockEngine.GetBlockInfo(this).paletteColour; - set - { - ref var color = ref BlockEngine.GetBlockInfo(this); - color.paletteColour = value; - color.hasNetworkChange = true; - } - } - - /** - * The block's material. - */ - public BlockMaterial Material - { - get - { - var opt = BlockEngine.GetBlockInfoOptional(this); - return opt ? (BlockMaterial) opt.Get().materialId : BlockMaterial.Default; - } - set - { - byte val = (byte) value; - if (value == BlockMaterial.Default) - val = FullGameFields._dataDb.TryGetValue((int) Type, out CubeListData cld) - ? cld.DefaultMaterialID - : throw new BlockTypeException("Unknown block type! Could not set default material."); - if (!FullGameFields._dataDb.ContainsKey(val)) - throw new BlockException($"Block material {value} does not exist!"); - ref var comp = ref BlockEngine.GetBlockInfo(this); - if (comp.materialId == val) - return; - comp.materialId = val; - BlockEngine.UpdatePrefab(this, val, Flipped); //The default causes the screen to go black - } - } - - /// - /// The text displayed on the block if applicable, or null. - /// Setting it is temporary to the session, it won't be saved. - /// - [TestValue(null)] - public string Label - { - get - { - var opt = BlockEngine.GetBlockInfoOptional(this); - return opt ? FullGameFields._managers.blockLabelResourceManager.GetText(opt.Get().instanceID) : null; - } - set - { - var opt = BlockEngine.GetBlockInfoOptional(this); - if (opt) FullGameFields._managers.blockLabelResourceManager.SetText(opt.Get().instanceID, value); - } - } - - private BlockGroup blockGroup; - /// - /// Returns the block group this block is a part of. Block groups can also be placed using blueprints. - /// Returns null if not part of a group, although all blocks should have their own by default.
- /// Setting the group after the block has been initialized will not update everything properly, - /// so you can only set this property on blocks newly placed by your code.
- /// To set it for existing blocks, you can use the Copy() method and set the property on the resulting block - /// (and remove this block). - ///
- public BlockGroup BlockGroup - { - get - { - if (blockGroup != null) return blockGroup; - if (!GameState.IsBuildMode()) return null; // Breaks in simulation - var bgec = BlockEngine.GetBlockInfo(this); - return blockGroup = bgec.currentBlockGroup == -1 - ? null - : GetInstance(new EGID((uint)bgec.currentBlockGroup, BlockGroupExclusiveGroups.BlockGroupEntityGroup), - egid => new BlockGroup((int)egid.entityID, this)); - } - set - { - if (Exists) - { - Logging.LogWarning("Attempted to set group of existing block. This is not supported." - + " Copy the block and set the group of the resulting block."); - return; - } - blockGroup?.RemoveInternal(this); - if (!InitData.Valid) - return; - BlockEngine.GetBlockInfo(this).currentBlockGroup = (int?) value?.Id.entityID ?? -1; - value?.AddInternal(this); - blockGroup = value; - } - } - - /// - /// Whether the block should be static in simulation. If set, it cannot be moved. The effect is temporary, it will not be saved with the block. - /// - public bool Static - { - get => BlockEngine.GetBlockInfo(this).isStatic; - set => BlockEngine.GetBlockInfo(this).isStatic = value; - } - - /// - /// The mass of the block. - /// - public float Mass - { - get => BlockEngine.GetBlockInfo(this).mass; - } - - /// - /// Block complexity used for build rules. Determines the 'cost' of the block. - /// - public BlockComplexity Complexity - { - get => new(BlockEngine.GetBlockInfo(this)); - set => BlockEngine.GetBlockInfo(this) = value; - } - - /// - /// Whether the block exists. The other properties will return a default value if the block doesn't exist. - /// If the block was just placed, then this will also return false but the properties will work correctly. - /// - public bool Exists => BlockEngine.BlockExists(Id); - - /// - /// Returns an array of blocks that are connected to this one. Returns an empty array if the block doesn't exist. - /// - public Block[] GetConnectedCubes() => BlockEngine.GetConnectedBlocks(Id); - - /// - /// Removes this block. - /// - /// True if the block exists and could be removed. - public bool Remove() => RemovalEngine.RemoveBlock(Id); - - /// - /// Returns the rigid body of the chunk of blocks this one belongs to during simulation. - /// Can be used to apply forces or move the block around while the simulation is running. - /// - /// The SimBody of the chunk or null if the block doesn't exist or not in simulation mode. - public SimBody GetSimBody() - { - var st = BlockEngine.GetBlockInfo(this); - /*return st.machineRigidBodyId != uint.MaxValue - ? new SimBody(st.machineRigidBodyId, st.clusterId) - TODO: - : null;*/ - return null; - } - - /// - /// Creates a copy of the block in the game with the same properties, stats and wires. - /// - /// - public Block Copy() - { - var block = PlaceNew(Type, Position); - block.Rotation = Rotation; - block.Color = Color; - block.Material = Material; - block.UniformScale = UniformScale; - block.Scale = Scale; - block.copiedFrom = Id; - return block; - } - - private void OnPlacedInit(object sender, BlockPlacedRemovedEventArgs e) - { //Member method instead of lambda to avoid constantly creating delegates - if (e.ID != Id) return; - Placed -= OnPlacedInit; //And we can reference it - InitData = default; //Remove initializer as it's no longer valid - if the block gets removed it shouldn't be used again - if (copiedFrom != default) - BlockCloneEngine.CopyBlockStats(copiedFrom, Id); - } - - public override string ToString() - { - return $"{nameof(Id)}: {Id}, {nameof(Position)}: {Position}, {nameof(Type)}: {Type}, {nameof(Color)}: {Color}, {nameof(Exists)}: {Exists}"; - } - - public bool Equals(Block other) - { - if (ReferenceEquals(null, other)) return false; - if (ReferenceEquals(this, other)) return true; - return Id.Equals(other.Id); - } - - public bool Equals(EGID other) - { - return Id.Equals(other); - } - - public override bool Equals(object obj) - { - if (ReferenceEquals(null, obj)) return false; - if (ReferenceEquals(this, obj)) return true; - if (obj.GetType() != this.GetType()) return false; - return Equals((Block) obj); - } - - public override int GetHashCode() - { - return Id.GetHashCode(); - } - - public static void Init() - { - GameEngineManager.AddGameEngine(PlacementEngine); - GameEngineManager.AddGameEngine(MovementEngine); - GameEngineManager.AddGameEngine(RotationEngine); - GameEngineManager.AddGameEngine(RemovalEngine); - GameEngineManager.AddGameEngine(BlockEngine); - GameEngineManager.AddGameEngine(BlockEventsEngine); - GameEngineManager.AddGameEngine(ScalingEngine); - GameEngineManager.AddGameEngine(SignalEngine); - GameEngineManager.AddGameEngine(BlockCloneEngine); - Wire.signalEngine = SignalEngine; // requires same functionality, no need to duplicate the engine - } - } -} \ No newline at end of file diff --git a/TechbloxModdingAPI/BlockGroup.cs b/TechbloxModdingAPI/BlockGroup.cs deleted file mode 100644 index 82f0be0..0000000 --- a/TechbloxModdingAPI/BlockGroup.cs +++ /dev/null @@ -1,217 +0,0 @@ -using System; -using System.Collections; -using System.Collections.Generic; - -using Gamecraft.Blocks.BlockGroups; -using Svelto.ECS; -using Unity.Mathematics; -using UnityEngine; - -using TechbloxModdingAPI.Blocks; -using TechbloxModdingAPI.Blocks.Engines; -using TechbloxModdingAPI.Utility; - -namespace TechbloxModdingAPI -{ - /// - /// A group of blocks that can be selected together. The placed version of blueprints. Dispose after usage. - /// - public class BlockGroup : EcsObjectBase, ICollection, IDisposable - { - internal static BlueprintEngine _engine = new BlueprintEngine(); - private readonly Block sourceBlock; - private readonly List blocks; - private float3 position, rotation; - internal bool PosAndRotCalculated; - - internal BlockGroup(int id, Block block) : base(new EGID((uint)id, - BlockGroupExclusiveGroups.BlockGroupEntityGroup)) - { - if (id == BlockGroupUtility.GROUP_UNASSIGNED) - throw new BlockException("Cannot create a block group for blocks without a group!"); - sourceBlock = block; - blocks = new List(GetBlocks()); - Block.Removed += OnBlockRemoved; - } - - private void OnBlockRemoved(object sender, BlockPlacedRemovedEventArgs e) - { - //blocks.RemoveAll(block => block.Id == e.ID); - Allocation heavy - int index = -1; - for (int i = 0; i < blocks.Count; i++) - { - if (blocks[i].Id == e.ID) - { - index = i; - break; - } - } - - if (index != -1) blocks.RemoveAt(index); - } - - public void Dispose() - { - Block.Removed -= OnBlockRemoved; - } - - /// - /// The position of the block group (center). Can only be used after initialization is complete. - /// - public float3 Position - { - get - { - if (!PosAndRotCalculated) - Refresh(); - return position; - } - set - { - var diff = value - position; - foreach (var block in blocks) - block.Position += diff; - if (!PosAndRotCalculated) //The condition can only be true if a block has been added/removed manually - Refresh(); //So the blocks array is up to date - else - position += diff; - } - } - - /// - /// The rotation of the block group. Can only be used after initialization is complete. - /// - public float3 Rotation - { - get - { - if (!PosAndRotCalculated) - Refresh(); - return rotation; - } - set - { - var diff = value - rotation; - var qdiff = Quaternion.Euler(diff); - foreach (var block in blocks) - { - block.Rotation += diff; - block.Position = qdiff * block.Position; - } - if (!PosAndRotCalculated) - Refresh(); - else - rotation += diff; - } - } - - /*/// - /// Removes all of the blocks in this group from the world. - /// - public void RemoveBlocks() - { - _engine.RemoveBlockGroup(Id); - TODO: Causes a hard crash - }*/ - - /// - /// Creates a new block group consisting of a single block. - /// You can add more blocks using the Add() method or by setting the BlockGroup property of the blocks.
- /// Note that only newly placed blocks can be added to groups. - ///
- /// The block to add - /// A new block group containing the given block - public static BlockGroup Create(Block block) - { - var bg = new BlockGroup(_engine.CreateBlockGroup(block.Position, Quaternion.Euler(block.Rotation)), block); - block.BlockGroup = bg; - return bg; - } - - /// - /// Collects each block that is a part of this group. Also sets the position and rotation. - /// - /// An array of blocks - private Block[] GetBlocks() - { - if (!sourceBlock.Exists) return new[] {sourceBlock}; //The block must exist to get the others - var ret = _engine.GetBlocksFromGroup(sourceBlock.Id, out var pos, out var rot); - position = pos; - rotation = ((Quaternion) rot).eulerAngles; - PosAndRotCalculated = true; - return ret; - } - - private void Refresh() - { - blocks.Clear(); - blocks.AddRange(GetBlocks()); - } - - internal static void Init() - { - GameEngineManager.AddGameEngine(_engine); - } - - public IEnumerator GetEnumerator() => blocks.GetEnumerator(); - IEnumerator IEnumerable.GetEnumerator() => blocks.GetEnumerator(); - - /// - /// Adds a block to the group. You can only add newly placed blocks - /// so that the game initializes the group membership properly. - /// - /// - /// - public void Add(Block item) - { - if (item == null) throw new NullReferenceException("Cannot add null to a block group"); - item.BlockGroup = this; //Calls AddInternal - } - - internal void AddInternal(Block item) - { - blocks.Add(item); - _engine.AddBlockToGroup(item.Id, (int) Id.entityID); - } - - /// - /// Removes all blocks from this group. - /// You cannot remove blocks that have been initialized, only those that you placed recently. - /// - public void Clear() - { - while (blocks.Count > 0) - Remove(blocks[blocks.Count - 1]); - } - - public bool Contains(Block item) => blocks.Contains(item); - public void CopyTo(Block[] array, int arrayIndex) => blocks.CopyTo(array, arrayIndex); - - /// - /// Removes a block from this group. - /// You cannot remove blocks that have been initialized, only those that you placed recently. - /// - /// - /// - /// - public bool Remove(Block item) - { - if (item == null) throw new NullReferenceException("Cannot remove null from a block group"); - bool ret = item.BlockGroup == this; - if (ret) - item.BlockGroup = null; //Calls RemoveInternal - return ret; - } - - internal void RemoveInternal(Block item) => blocks.Remove(item); - - public int Count => blocks.Count; - public bool IsReadOnly { get; } = false; - - public Block this[int index] => blocks[index]; //Setting is not supported, since the order doesn't matter - - public override string ToString() - { - return $"{nameof(Id)}: {Id}, {nameof(Position)}: {Position}, {nameof(Rotation)}: {Rotation}, {nameof(Count)}: {Count}"; - } - } -} \ No newline at end of file diff --git a/TechbloxModdingAPI/Blocks/BlockColor.cs b/TechbloxModdingAPI/Blocks/BlockColor.cs deleted file mode 100644 index 42e1f9b..0000000 --- a/TechbloxModdingAPI/Blocks/BlockColor.cs +++ /dev/null @@ -1,64 +0,0 @@ -using System; -using Unity.Mathematics; - -namespace TechbloxModdingAPI.Blocks -{ - public struct BlockColor - { - public BlockColors Color => Index == byte.MaxValue - ? BlockColors.Default - : (BlockColors) (Index % 10); - - public byte Darkness => (byte) (Index == byte.MaxValue - ? 0 - : Index / 10); - - public byte Index { get; } - - public BlockColor(byte index) - { - if (index > 99 && index != byte.MaxValue) - throw new ArgumentOutOfRangeException(nameof(index), "Invalid color index. Must be 0-90 or 255."); - Index = index; - } - - public BlockColor(BlockColors color, byte darkness = 0) - { - if (darkness > 9) - throw new ArgumentOutOfRangeException(nameof(darkness), "Darkness must be 0-9 where 0 is default."); - if (color > BlockColors.Red && color != BlockColors.Default) //Last valid color - throw new ArgumentOutOfRangeException(nameof(color), "Invalid color!"); - Index = (byte) (darkness * 10 + (byte) color); - } - - public static implicit operator BlockColor(BlockColors color) - { - return new BlockColor(color); - } - - public float4 RGBA => Block.BlockEngine.ConvertBlockColor(Index); - - public override string ToString() - { - return $"{nameof(Color)}: {Color}, {nameof(Darkness)}: {Darkness}"; - } - } - - /// - /// Preset block colours - /// - public enum BlockColors : byte - { - Default = byte.MaxValue, - White = 0, - Pink, - Purple, - Blue, - Aqua, - Green, - Lime, - Yellow, - Orange, - Red - } -} \ No newline at end of file diff --git a/TechbloxModdingAPI/Blocks/BlockComplexity.cs b/TechbloxModdingAPI/Blocks/BlockComplexity.cs deleted file mode 100644 index 9f32866..0000000 --- a/TechbloxModdingAPI/Blocks/BlockComplexity.cs +++ /dev/null @@ -1,17 +0,0 @@ -using RobocraftX.Blocks; - -namespace TechbloxModdingAPI.Blocks -{ - public record BlockComplexity(int Cpu, int Power) - { - public BlockComplexity(BlockComplexityComponent component) : this(component.cpu, component.power) - { - } - - public int Cpu { get; } = Cpu; - public int Power { get; } = Power; - - public static implicit operator BlockComplexityComponent(BlockComplexity complexity) => - new() { cpu = complexity.Cpu, power = complexity.Power }; - } -} \ No newline at end of file diff --git a/TechbloxModdingAPI/Blocks/BlockExceptions.cs b/TechbloxModdingAPI/Blocks/BlockExceptions.cs deleted file mode 100644 index 4029185..0000000 --- a/TechbloxModdingAPI/Blocks/BlockExceptions.cs +++ /dev/null @@ -1,65 +0,0 @@ -using System; - -using TechbloxModdingAPI; - -namespace TechbloxModdingAPI.Blocks -{ - public class BlockException : TechbloxModdingAPIException - { - public BlockException() - { - } - - public BlockException(System.String message) : base(message) - { - } - - public BlockException(System.String message, Exception innerException) : base(message, innerException) - { - } - } - - public class BlockTypeException : BlockException - { - public BlockTypeException() - { - } - - public BlockTypeException(string message) : base(message) - { - } - } - - public class BlockSpecializationException : BlockException - { - public BlockSpecializationException() - { - } - - public BlockSpecializationException(string message) : base(message) - { - } - } - - public class WiringException : BlockException - { - public WiringException() - { - } - - public WiringException(string message) : base(message) - { - } - } - - public class WireInvalidException : WiringException - { - public WireInvalidException() - { - } - - public WireInvalidException(string message) : base(message) - { - } - } -} diff --git a/TechbloxModdingAPI/Blocks/BlockIDs.cs b/TechbloxModdingAPI/Blocks/BlockIDs.cs deleted file mode 100644 index 3970824..0000000 --- a/TechbloxModdingAPI/Blocks/BlockIDs.cs +++ /dev/null @@ -1,383 +0,0 @@ -namespace TechbloxModdingAPI.Blocks -{ - /// - /// Possible block types - /// - public enum BlockIDs : ushort - { - /// - /// Called "nothing" in Techblox. (DBID.NOTHING) - /// - Invalid = ushort.MaxValue, - Cube = 0, - Wedge, - QuarterPyramid, - Tetrahedron, - RoundedWedge, - RoundedQuarterPyramid, - RoundedTetrahedron, - NegativeQuarterPyramid, - NegativeTetrahedron, - RoundedNegativeQuarterPyramid, - RoundedNegativeTetrahedron, - Plate, - PlateWedge, - PlateQuarterPyramid, - PlateTetrahedron, - Sphere, - CarWheelArch = 47, - CarArchSmallFlare, - CarArchFlare, - CarArchExtrudedFlare, - Axle = 100, - Hinge, - BallJoint, - UniversalJoint, - TelescopicJoint, - DampedHingeSpring, - DampedAxleSpring, - DampedSpring, - WheelRigNoSteering, - WheelRigWithSteering, - PlateTriangle = 130, - PlateCircle, - PlateQuarterCircle, - PlateRoundedWedge, - PlateRoundedTetrahedron, - Cone, - ConeSegment, - DoubleSliced, - HalfDoubleSliced, - EighthPyramid, - Hemisphere, - WideCylinder, - WideCylinderBend, - WideCylinderT, - WideCylinderCross, - WideCylinderCorner, - NarrowCylinder, - NarrowCylinderBend, - NarrowCylinderT, - NarrowCylinderCross, - DriverSeat, - PassengerSeat, - Engine, - NarrowCylinderCorner, - PlateWideCylinder, - PlateNarrowCylinder, - PlateNegativeTetrahedron, - PlateNegativeQuarterPyramid, - PlateRoundedNegativeTetrahedron, - PlateRoundedNegativeQuarterPyramid, - HeadlampSquare, - HeadlampCircle, - HeadlampWedge, - WideCylinderDiagonal, - NarrowCylinderDiagonal, - HeadlampTetrahedron, - GoKartEngine, - Screen5X2Y2Z, - Screen5X2Y3Z, - Screen5X2Y5Z, - Screen9X2Y2Z, - Screen9X3Y2Z, - Screen9X2Y3Z, - Screen9X3Y3Z, - Screen9X2Y5Z, - Screen9X3Y5Z, - Screen11X3Y2Z, - Screen11X3Y3Z, - Screen11X3Y5Z, - Window6X2Y2Z, - Window6X3Y2Z, - Window6X2Y2ZS1, - Window6X3Y2ZS1, - Window6X2Y2ZS2, - Window6X3Y2ZS2, - Window6X2Y2ZS4, - Window6X3Y2ZS4, - FrameSquare, - FrameSkewedSquare, - FrameTriangle, - FrameSkewedTriangle, - GlassFrameSquare, - GlassFrameSkewedSquare, - GlassFrameTriangle, - GlassFrameSkewedTriangle, - GlassPlate, - GlassPlateTriangle, - GoKartWheelRigNoSteering, - GoKartWheelRigWithSteering, - GoKartSeat, - CarWheelWideProfile, - CarWheel, - GoKartWheelWideProfile, - GoKartWheel, - ANDLogicGate, - ORLogicGate, - NOTLogicGate, - NANDLogicGate, - NORLogicGate, - XORLogicGate, - XNORLogicGate, - AdderMathBlock, - SubtractorMathBlock, - MultiplierMathBlock, - DividerMathBlock, - InverterMathBlock, - AverageMathBlock, - AbsoluteMathBlock, - MinMathBlock, - MaxMathBlock, - SimpleConnector, - Motor, - AxleServo, - HingeServo, - Piston, - Button, - Switch, - Dial, - Lever, - ThreeWaySwitch, - EqualsMathBlock, - LessThanMathBlock, - LessThanOrEqualMathBlock, - GreaterThanMathBlock, - GreaterThanOrEqualMathBlock, - HatchbackWheelRigNoSteering, - HatchbackWheelRigWithSteering, - HatchbackEngine, - HatchbackWheel, - HatchbackWheelArch, - HatchbackArchSmallFlare, - HatchbackArchFlare, - CeilingStripLight, - CardboardBox, - BarrierRail, - BarrierRailEnd, - TruckWheel, - HatchbackWheelWideProfile, - TruckWheelRigWithSteering = 249, - TruckWheelRigNoSteering, - HatchbackDriverSeat, - HatchbackPassengerSeat, - FormulaEngine, - SmallGrass, - SmallGrassRoad, - GrassBridge, - SmallGrassTurn, - MediumGrassTurn, - LargeGrassTurn, - ExtraLargeGrassTurn, - TruckWheelDouble, - TruckWheelArch, - TruckArchSingleFlare, - WoodenDoorWithWindow, - TyreBarrierCorner, - TyreBarrierEdge, - TyreBarrierCenter, - AppleTree, - AppleForestTree, - FormulaWheel, - FormulaWheelRear, - AppleSapling, - GrassHill, - GrassHillInnerCorner, - GrassHillOuterCorner, - GrassRoadHill, - FormulaSeat, - SmallDirt, - SmallDirtRoad, - SmallDirtTurn, - MediumDirtTurn, - LargeDirtTurn, - ExtraLargeDirtTurn, - SmallGrid, - MonsterTruckWheel, - SmallGrassGridStart, - SmallGrassRumbleStripRoad, - SmallGrassRumbleStripEndRoad, - SmallGrassStartLine, - MonsterTruckEngine, - DirtHill, - DirtHillInnerCorner, - DirtHillOuterCorner, - BuildingWindowEdge, - BuildingWindowCorner, - BuildingWindowStraight, - BuildingWindowTJunction, - BuildingWindowCross, - BuildingWindowEdgeSill, - BuildingWindowCornerSill, - BuildingWindowTJunctionSill, - Broadleaf, - ForestBroadleaf, - AzaleaBush, - AzaleaFlowers1, - AzaleaFlowers2, - TreeStump1, - TreeStump2, - FieldJuniper, - ForestJuniper, - JuniperSapling, - JuniperSeedling, - FieldRedMaple, - RedMapleForest1, - RedMapleForest2, - RedMapleSapling, - FieldWhiteSpruce, - ForestWhiteSpruce, - WhiteSpruceSapling, - GirderBase, - GirderStraight, - GirderDiagonal, - GirderCorner, - PostBase, - PostStraight, - PostLShape, - PostTJunction, - PostCross, - PostCorner, - PostDiagonal, - DirtRock1, - DirtRock2, - DirtRock3, - DirtRock4, - DirtRoadHill, - WoodenPalette, - ElderberryBush, - BarrelCactus, - KnapweedFlower, - MarigoldFlowers, - TrampledBushyBluestep, - RoughGrass, - DogRose, - WesternSwordFern, - BackyardGrass, - ThickGrass, - FireExtinguisher, - DirtLowRamp, - DirtTabletopRamp, - MonsterTruckWheelRigNoSteering, - MonsterTruckWheelRigWithSteering, - MeadowCloudyDayAtmosphere, - BarrierRailDiagonal, - DirtHighRamp, - GrassRock1, - GrassRock2, - GrassRock3, - GrassRock4, - GreenFieldsSunnyDayAtmosphere, - RedMountainsDawnAtmosphere, - HighFantasySunriseAtmosphere, - /// - /// The grid block used by the world editor, named Small Grid like the other one - /// - SmallGridInWorldEditor, - CityDoubleCrossing, - CityDoubleCrossroads, - CitySmallDoubleJunction, - CityDoubleJunction, - CityDoubleToSingleJunction, - CitySmallDoubleRoad, - CityDoubleRoad, - CitySmallDoubleTurn, - CityLargeDoubleTurn, - CitySmallSingleTurn, - CityLargeSingleTurn, - CitySingleJunction, - CitySingleRoad, - SegoeUITextblock, - GravtracTextblock, - HauserTextblock, - TechnopollasTextblock, - CityDoubleHillRoad, - DiagonalTrackTile, - DiagonalTrackTile2, - DiagonalTransitionTile, - SplitLane, - BitBlock, - Timer, - CityNightAtmosphere, - FloodLight, - SoccerBall, - CircularWallLight, - BlueSkyAtmos, - DirtToGrassTransitionTile = 393, - DirtToGrassTransitionInnerTile, - DirtToGrassTransitionOuterTile, - DirtToGrassTransitionHillTile, - DirtToGrassTransitionRoadTile, - DirtHill2 = 399, - DirtHill3, - DirtInnerCorner2 = 402, - DirtInnerCorner3, - DirtOuterCorner2 = 405, - DirtOuterCorner3, - CityTarmacEdgeInner, - CityTarmacEdgeOuter, - CityTarmacEdgeRoad, - CityTarmac, - SmallGrassQuarterTile, - CityToRacetrackTransition, - HUDTimer, - CentreHUD, - Checkpoint, - ScoreboardHUD, - GameplaySFX, - SpawnPoint, - AreaSensor, - WorldResetter, - SmallJet, - MediumJet, - LargeJet, - DistanceSensor, - Stabilizer, - ObjectID, - ScoreToTechpointConversion, - TeamScore, - ScorePickupBlock, - SportyHatchbackDriverSeat, - SportyHatchbackPassengerSeat, - FlamingExhaust = 433, - SmokingExhaust, - StreetLamp, - Vector7HatchbackWheel, - Vector7HatchbackWheelWideProfile, - Vector7SedanWheel, - Vector7SedanWideProfile, - Vector7FormulaWheel, - Vector7FormulaWheelRear, - Vector7MonsterTruckWheel, - Vector7TruckWheel, - Vector7TruckWheelDouble, - BusSeat, - XLJet, - XXLJet, - ElectricSedanEngine, - HeadlampIndicator, - HeadlampSrip, - HeadlampStripEdge, - ConstantBlock, - CounterBlock, - SmallGridHill, - SmallGridHillInnerCorner, - SmallGridHillOuterCorner, - AimingAxleServo, - AimingHingeServo, - WeaponDisabler, - Vector7SmallJet, - Vector7MediumJet, - Vector7LargeJet, - Vector7XLJet, - Vector7XXLJet, - APCWheelRigNoSteering, - APCWheelRigWithSteering, - APCWheel, - APCSeat, - APCEngine, - DamageScoreBlock, - KillScoreBlock, - Autocannon = 480 - } -} \ No newline at end of file diff --git a/TechbloxModdingAPI/Blocks/BlockMaterial.cs b/TechbloxModdingAPI/Blocks/BlockMaterial.cs deleted file mode 100644 index 51d0694..0000000 --- a/TechbloxModdingAPI/Blocks/BlockMaterial.cs +++ /dev/null @@ -1,46 +0,0 @@ -namespace TechbloxModdingAPI.Blocks -{ - public enum BlockMaterial : byte - { - Default = byte.MaxValue, - SteelBodywork = 0, - RigidSteel, - CarbonFiber, - Plastic, - Wood = 6, - RigidSteelPainted, - RigidSteelRustedPaint, - RigidSteelHeavyRust, - SteelBodyworkMetallicPaint, - SteelBodyworkRustedPaint, - SteelBodyworkHeavyRust, - WoodVarnishedDark, - Chrome, - FenceChainLink, - ConcreteUnpainted, - Grid9x9, - CeramicTileFloor, - PlasticBumpy, - PlasticDustySmeared, - AluminiumGarageDoor, - SteelRigidScratched, - AluminiumBrushedTinted, - AluminiumSheetStained, - ConcretePaintedGrooves, - PlasticSpecklySatin, - SteelBodyworkPaintedChipped, - WoodPainted, - WoodRoughGrungy, - Boundary, - Emissive, - AircraftPanelingRivetedPainted, - AircraftPanelingRivetedMetallic, - SteelBodyworkPearlescent, - SteelBodyworkRadWrap, - SteelBodyworkGlitter, - BouncyRubber, - BouncyRubberTieDye, - BrickPainted, - FuturisticPanelingRivetedPainted, - } -} \ No newline at end of file diff --git a/TechbloxModdingAPI/Blocks/BlockTests.cs b/TechbloxModdingAPI/Blocks/BlockTests.cs deleted file mode 100644 index a0ee0e9..0000000 --- a/TechbloxModdingAPI/Blocks/BlockTests.cs +++ /dev/null @@ -1,256 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Reflection; - -using DataLoader; -using Svelto.Tasks; -using Unity.Mathematics; - -using TechbloxModdingAPI.Tests; -using TechbloxModdingAPI.Utility; - -namespace TechbloxModdingAPI.Blocks -{ -#if TEST - /// - /// Block test cases. Not accessible in release versions. - /// - [APITestClass] - public static class BlockTests - { - [APITestCase(TestType.Game)] //At least one block must be placed for simulation to work - public static void TestPlaceNew() - { - Block newBlock = Block.PlaceNew(BlockIDs.Cube, float3.zero); - Assert.NotNull(newBlock.Id, "Newly placed block is missing Id. This should be populated when the block is placed.", "Newly placed block Id is not null, block successfully placed."); - } - - [APITestCase(TestType.EditMode)] - public static void TestInitProperty() - { - Block newBlock = Block.PlaceNew(BlockIDs.Cube, float3.zero + 2); - if (!Assert.CloseTo(newBlock.Position, (float3.zero + 2), $"Newly placed block at {newBlock.Position} is expected at {Unity.Mathematics.float3.zero + 2}.", "Newly placed block position matches.")) return; - //Assert.Equal(newBlock.Exists, true, "Newly placed block does not exist, possibly because Sync() skipped/missed/failed.", "Newly placed block exists, Sync() successful."); - } - - [APITestCase(TestType.EditMode)] - public static void TestBlockIDCoverage() - { - Assert.Equal( - FullGameFields._dataDb.GetValues().Keys.Select(ushort.Parse).OrderBy(id => id) - .SequenceEqual(Enum.GetValues(typeof(BlockIDs)).Cast().OrderBy(id => id) - .Except(new[] {(ushort) BlockIDs.Invalid})), true, - "Block ID enum is different than the known block types, update needed.", - "Block ID enum matches the known block types."); - } - - private static Block[] blocks; // Store placed blocks as some blocks are already present as the workshop and the game save - [APITestCase(TestType.EditMode)] - public static void TestBlockIDs() - { - float3 pos = new float3(); - var values = Enum.GetValues(typeof(BlockIDs)); - blocks = new Block[values.Length - 1]; // Minus the invalid ID - int i = 0; - foreach (BlockIDs id in values) - { - if (id == BlockIDs.Invalid) continue; - try - { - blocks[i++] = Block.PlaceNew(id, pos); - pos += 0.2f; - } - catch (Exception e) - { //Only print failed case - Assert.Fail($"Failed to place block type {id}: {e}"); - return; - } - } - - Assert.Pass("Placing all possible block types succeeded."); - } - - [APITestCase(TestType.EditMode)] - public static IEnumerator TestBlockProperties() - { //Uses the result of the previous test case - yield return Yield.It; - if (blocks is null) - yield break; - for (var index = 0; index < blocks.Length; index++) - { - var block = blocks[index]; - if (!block.Exists) continue; - foreach (var property in block.GetType().GetProperties()) - { - //Includes specialised block properties - if (property.SetMethod == null) continue; - - bool3 Float3Compare(float3 a, float3 b) - { // From Unity reference code - return math.abs(b - a) < math.max( - 0.000001f * math.max(math.abs(a), math.abs(b)), - float.Epsilon * 8 - ); - } - bool4 Float4Compare(float4 a, float4 b) - { // From Unity reference code - return math.abs(b - a) < math.max( - 0.000001f * math.max(math.abs(a), math.abs(b)), - float.Epsilon * 8 - ); - } - - var testValues = new (Type, object, Predicate<(object Value, object Default)>)[] - { - //(type, default value, predicate or null for equality) - (typeof(long), 3, null), - (typeof(int), 4, null), - (typeof(double), 5.2f, t => Math.Abs((double) t.Value - (double) t.Default) < float.Epsilon), - (typeof(float), 5.2f, t => Math.Abs((float) t.Value - (float) t.Default) < float.Epsilon), - (typeof(bool), true, t => (bool) t.Value), - (typeof(string), "Test", t => (string) t.Value == "Test"), //String equality check - (typeof(float3), (float3) 20, t => math.all(Float3Compare((float3)t.Value, (float3)t.Default))), - (typeof(BlockColor), new BlockColor(BlockColors.Aqua, 2), null), - (typeof(float4), (float4) 5, t => math.all(Float4Compare((float4)t.Value, (float4)t.Default))) - }; - var propType = property.PropertyType; - if (!propType.IsValueType) continue; - (object valueToUse, Predicate<(object Value, object Default)> predicateToUse) = (null, null); - foreach (var (type, value, predicate) in testValues) - { - if (type.IsAssignableFrom(propType)) - { - valueToUse = value; - predicateToUse = predicate ?? (t => Equals(t.Value, t.Default)); - break; - } - } - - if (propType.IsEnum) - { - var values = propType.GetEnumValues(); - valueToUse = values.GetValue(values.Length / 2); - predicateToUse = t => Equals(t.Value, t.Default); - } - - if (valueToUse == null) - { - Assert.Fail($"Property {block.GetType().Name}.{property.Name} has an unknown type {propType}, test needs fixing."); - yield break; - } - - try - { - property.SetValue(block, valueToUse); - } - catch (Exception e) - { - Assert.Fail($"Failed to set property {block.GetType().Name}.{property.Name} to {valueToUse}\n{e}"); - } - object got; - try - { - got = property.GetValue(block); - } - catch (Exception e) - { - Assert.Fail($"Failed to get property {block.GetType().Name}.{property.Name}\n{e}"); - continue; - } - var attr = property.GetCustomAttribute(); - if (!predicateToUse((got, valueToUse)) && (attr == null || !Equals(attr.PossibleValue, got))) - { - Assert.Fail($"Property {block.GetType().Name}.{property.Name} value {got} does not equal {valueToUse} for block {block}."); - yield break; - } - } - } - - Assert.Pass("Setting all possible properties of all registered API block types succeeded."); - } - - [APITestCase(TestType.EditMode)] - public static IEnumerator TestDefaultValue() - { - for (int i = 0; i < 2; i++) - { //Tests shared defaults - var block = Block.PlaceNew(BlockIDs.Cube, 1); - while (!block.Exists) - yield return Yield.It; - block.Remove(); - while (block.Exists) - yield return Yield.It; - if(!Assert.Equal(block.Position, default, - $"Block position default value {block.Position} is incorrect, should be 0.", - $"Block position default value {block.Position} matches default.")) - yield break; - block.Position = 4; - } - } - - [APITestCase(TestType.EditMode)] - public static void TestDampedSpring() - { - Block newBlock = Block.PlaceNew(BlockIDs.DampedSpring, Unity.Mathematics.float3.zero + 1); - DampedSpring b = null; // Note: the assignment operation is a lambda, which slightly confuses the compiler - Assert.Errorless(() => { b = (DampedSpring) newBlock; }, "Casting block to DampedSpring raised an exception: ", "Casting block to DampedSpring completed without issue."); - if (!Assert.CloseTo(b.Stiffness, 1f, $"DampedSpring.Stiffness {b.Stiffness} does not equal default value, possibly because it failed silently.", "DampedSpring.Stiffness is close enough to default.")) return; - if (!Assert.CloseTo(b.Damping, 0.1f, $"DampedSpring.Damping {b.Damping} does not equal default value, possibly because it failed silently.", "DampedSpring.Damping is close enough to default.")) return; - if (!Assert.CloseTo(b.MaxExtension, 0.3f, $"DampedSpring.MaxExtension {b.MaxExtension} does not equal default value, possibly because it failed silently.", "DampedSpring.MaxExtension is close enough to default.")) return; - } - - /*[APITestCase(TestType.Game)] - public static void TestMusicBlock1() - { - Block newBlock = Block.PlaceNew(BlockIDs.MusicBlock, Unity.Mathematics.float3.zero + 2); - MusicBlock b = null; // Note: the assignment operation is a lambda, which slightly confuses the compiler - Assert.Errorless(() => { b = newBlock.Specialise(); }, "Block.Specialize() raised an exception: ", "Block.Specialize() completed without issue."); - if (!Assert.NotNull(b, "Block.Specialize() returned null, possibly because it failed silently.", "Specialized MusicBlock is not null.")) return; - if (!Assert.CloseTo(b.Volume, 100f, $"MusicBlock.Volume {b.Volume} does not equal default value, possibly because it failed silently.", "MusicBlock.Volume is close enough to default.")) return; - if (!Assert.Equal(b.TrackIndex, 0, $"MusicBlock.TrackIndex {b.TrackIndex} does not equal default value, possibly because it failed silently.", "MusicBlock.TrackIndex is equal to default.")) return; - _musicBlock = b; - } - - private static MusicBlock _musicBlock; - - [APITestCase(TestType.EditMode)] - public static void TestMusicBlock2() - { - //Block newBlock = Block.GetLastPlacedBlock(); - var b = _musicBlock; - if (!Assert.NotNull(b, "Block.Specialize() returned null, possibly because it failed silently.", "Specialized MusicBlock is not null.")) return; - b.IsPlaying = true; // play sfx - if (!Assert.Equal(b.IsPlaying, true, $"MusicBlock.IsPlaying {b.IsPlaying} does not equal true, possibly because it failed silently.", "MusicBlock.IsPlaying is set properly.")) return; - if (!Assert.Equal(b.ChannelType, ChannelType.None, $"MusicBlock.ChannelType {b.ChannelType} does not equal default value, possibly because it failed silently.", "MusicBlock.ChannelType is equal to default.")) return; - //Assert.Log(b.Track.ToString()); - if (!Assert.Equal(b.Track.ToString(), new Guid("3237ff8f-f5f2-4f84-8144-496ca280f8c0").ToString(), $"MusicBlock.Track {b.Track} does not equal default value, possibly because it failed silently.", "MusicBlock.Track is equal to default.")) return; - } - - [APITestCase(TestType.EditMode)] - public static void TestLogicGate() - { - Block newBlock = Block.PlaceNew(BlockIDs.NOTLogicBlock, Unity.Mathematics.float3.zero + 1); - LogicGate b = null; // Note: the assignment operation is a lambda, which slightly confuses the compiler - Assert.Errorless(() => { b = newBlock.Specialise(); }, "Block.Specialize() raised an exception: ", "Block.Specialize() completed without issue."); - if (!Assert.NotNull(b, "Block.Specialize() returned null, possibly because it failed silently.", "Specialized LogicGate is not null.")) return; - if (!Assert.Equal(b.InputCount, 1u, $"LogicGate.InputCount {b.InputCount} does not equal default value, possibly because it failed silently.", "LogicGate.InputCount is default.")) return; - if (!Assert.Equal(b.OutputCount, 1u, $"LogicGate.OutputCount {b.OutputCount} does not equal default value, possibly because it failed silently.", "LogicGate.OutputCount is default.")) return; - if (!Assert.NotNull(b, "Block.Specialize() returned null, possibly because it failed silently.", "Specialized LogicGate is not null.")) return; - //if (!Assert.Equal(b.PortName(0, true), "Input", $"LogicGate.PortName(0, input:true) {b.PortName(0, true)} does not equal default value, possibly because it failed silently.", "LogicGate.PortName(0, input:true) is close enough to default.")) return; - LogicGate target = null; - if (!Assert.Errorless(() => { target = Block.PlaceNew(BlockIDs.ANDLogicBlock, Unity.Mathematics.float3.zero + 2); })) return; - Wire newWire = null; - if (!Assert.Errorless(() => { newWire = b.Connect(0, target, 0);})) return; - if (!Assert.NotNull(newWire, "SignalingBlock.Connect(...) returned null, possible because it failed silently.", "SignalingBlock.Connect(...) returned a non-null value.")) return; - }*/ - - /*[APITestCase(TestType.EditMode)] - public static void TestSpecialiseError() - { - Block newBlock = Block.PlaceNew(BlockIDs.Bench, new float3(1, 1, 1)); - if (Assert.Errorful(() => newBlock.Specialise(), "Block.Specialise() was expected to error on a bench block.", "Block.Specialise() errored as expected for a bench block.")) return; - }*/ - } -#endif -} diff --git a/TechbloxModdingAPI/Blocks/DampedSpring.cs b/TechbloxModdingAPI/Blocks/DampedSpring.cs deleted file mode 100644 index 9408f31..0000000 --- a/TechbloxModdingAPI/Blocks/DampedSpring.cs +++ /dev/null @@ -1,71 +0,0 @@ -namespace TechbloxModdingAPI.Blocks -{ - using RobocraftX.Common; - using Svelto.ECS; - - - public class DampedSpring : SignalingBlock - { - - /// - /// Constructs a(n) DampedSpring object representing an existing block. - /// - public DampedSpring(EGID egid) : - base(egid) - { - } - - /// - /// Constructs a(n) DampedSpring object representing an existing block. - /// - public DampedSpring(uint id) : - base(new EGID(id, CommonExclusiveGroups.DAMPEDSPRING_BLOCK_GROUP)) - { - } - - /// - /// Gets or sets the DampedSpring's Stiffness property. Tweakable stat. - /// - public float Stiffness - { - get - { - return BlockEngine.GetBlockInfo(this).stiffness; - } - set - { - BlockEngine.GetBlockInfo(this).stiffness = value; - } - } - - /// - /// Gets or sets the DampedSpring's Damping property. Tweakable stat. - /// - public float Damping - { - get - { - return BlockEngine.GetBlockInfo(this).damping; - } - set - { - BlockEngine.GetBlockInfo(this).damping = value; - } - } - - /// - /// Gets or sets the DampedSpring's MaxExtension property. Tweakable stat. - /// - public float MaxExtension - { - get - { - return BlockEngine.GetBlockInfo(this).maxExtent; - } - set - { - BlockEngine.GetBlockInfo(this).maxExtent = value; - } - } - } -} diff --git a/TechbloxModdingAPI/Blocks/Engine.cs b/TechbloxModdingAPI/Blocks/Engine.cs deleted file mode 100644 index e3d7ade..0000000 --- a/TechbloxModdingAPI/Blocks/Engine.cs +++ /dev/null @@ -1,382 +0,0 @@ -namespace TechbloxModdingAPI.Blocks -{ - using RobocraftX.Common; - using Svelto.ECS; - - - public class Engine : SignalingBlock - { - - /// - /// Constructs a(n) Engine object representing an existing block. - /// - public Engine(EGID egid) : - base(egid) - { - } - - /// - /// Constructs a(n) Engine object representing an existing block. - /// - public Engine(uint id) : - base(new EGID(id, CommonExclusiveGroups.ENGINE_BLOCK_BUILD_GROUP)) - { - } - - /*/// - TODO: Internal struct access - /// Gets or sets the Engine's On property. May not be saved. - /// - public bool On - { - get - { - return BlockEngine.GetBlockInfo(this).engineOn; - } - set - { - BlockEngine.GetBlockInfo(this).engineOn = value; - } - } - - /// - /// Gets or sets the Engine's CurrentGear property. May not be saved. - /// - public int CurrentGear - { - get - { - return BlockEngine.GetBlockInfo(this).currentGear; - } - set - { - BlockEngine.GetBlockInfo(this).currentGear = value; - } - } - - /// - /// Gets or sets the Engine's GearChangeCountdown property. May not be saved. - /// - public float GearChangeCountdown - { - get - { - return BlockEngine.GetBlockInfo(this).gearChangeCountdown; - } - set - { - BlockEngine.GetBlockInfo(this).gearChangeCountdown = value; - } - } - - /// - /// Gets or sets the Engine's CurrentRpmAV property. May not be saved. - /// - public float CurrentRpmAV - { - get - { - return BlockEngine.GetBlockInfo(this).currentRpmAV; - } - set - { - BlockEngine.GetBlockInfo(this).currentRpmAV = value; - } - } - - /// - /// Gets or sets the Engine's CurrentRpmLV property. May not be saved. - /// - public float CurrentRpmLV - { - get - { - return BlockEngine.GetBlockInfo(this).currentRpmLV; - } - set - { - BlockEngine.GetBlockInfo(this).currentRpmLV = value; - } - } - - /// - /// Gets or sets the Engine's TargetRpmAV property. May not be saved. - /// - public float TargetRpmAV - { - get - { - return BlockEngine.GetBlockInfo(this).targetRpmAV; - } - set - { - BlockEngine.GetBlockInfo(this).targetRpmAV = value; - } - } - - /// - /// Gets or sets the Engine's TargetRpmLV property. May not be saved. - /// - public float TargetRpmLV - { - get - { - return BlockEngine.GetBlockInfo(this).targetRpmLV; - } - set - { - BlockEngine.GetBlockInfo(this).targetRpmLV = value; - } - } - - /// - /// Gets or sets the Engine's CurrentTorque property. May not be saved. - /// - public float CurrentTorque - { - get - { - return BlockEngine.GetBlockInfo(this).currentTorque; - } - set - { - BlockEngine.GetBlockInfo(this).currentTorque = value; - } - } - - /// - /// Gets or sets the Engine's TotalWheelVelocityAV property. May not be saved. - /// - public float TotalWheelVelocityAV - { - get - { - return BlockEngine.GetBlockInfo(this).totalWheelVelocityAV; - } - set - { - BlockEngine.GetBlockInfo(this).totalWheelVelocityAV = value; - } - } - - /// - /// Gets or sets the Engine's TotalWheelVelocityLV property. May not be saved. - /// - public float TotalWheelVelocityLV - { - get - { - return BlockEngine.GetBlockInfo(this).totalWheelVelocityLV; - } - set - { - BlockEngine.GetBlockInfo(this).totalWheelVelocityLV = value; - } - } - - /// - /// Gets or sets the Engine's TotalWheelCount property. May not be saved. - /// - public int TotalWheelCount - { - get - { - return BlockEngine.GetBlockInfo(this).totalWheelCount; - } - set - { - BlockEngine.GetBlockInfo(this).totalWheelCount = value; - } - } - - /// - /// Gets or sets the Engine's LastGearUpInput property. May not be saved. - /// - public bool LastGearUpInput - { - get - { - return BlockEngine.GetBlockInfo(this).lastGearUpInput; - } - set - { - BlockEngine.GetBlockInfo(this).lastGearUpInput = value; - } - } - - /// - /// Gets or sets the Engine's LastGearDownInput property. May not be saved. - /// - public bool LastGearDownInput - { - get - { - return BlockEngine.GetBlockInfo(this).lastGearDownInput; - } - set - { - BlockEngine.GetBlockInfo(this).lastGearDownInput = value; - } - } - - /// - /// Gets or sets the Engine's ManualToAutoGearCoolOffCounter property. May not be saved. - /// - public float ManualToAutoGearCoolOffCounter - { - get - { - return BlockEngine.GetBlockInfo(this).manualToAutoGearCoolOffCounter; - } - set - { - BlockEngine.GetBlockInfo(this).manualToAutoGearCoolOffCounter = value; - } - } - - /// - /// Gets or sets the Engine's Load property. May not be saved. - /// - public float Load - { - get - { - return BlockEngine.GetBlockInfo(this).load; - } - set - { - BlockEngine.GetBlockInfo(this).load = value; - } - } - - /// - /// Gets or sets the Engine's Power property. Tweakable stat. - /// - public float Power - { - get - { - return BlockEngine.GetBlockInfo(this).power; - } - set - { - BlockEngine.GetBlockInfo(this).power = value; - } - } - - /// - /// Gets or sets the Engine's AutomaticGears property. Tweakable stat. - /// - public bool AutomaticGears - { - get - { - return BlockEngine.GetBlockInfo(this).automaticGears; - } - set - { - BlockEngine.GetBlockInfo(this).automaticGears = value; - } - } - - /// - /// Gets or sets the Engine's GearChangeTime property. May not be saved. - /// - public float GearChangeTime - { - get - { - return BlockEngine.GetBlockInfo(this).gearChangeTime; - } - set - { - BlockEngine.GetBlockInfo(this).gearChangeTime = value; - } - } - - /// - /// Gets or sets the Engine's MinRpm property. May not be saved. - /// - public float MinRpm - { - get - { - return BlockEngine.GetBlockInfo(this).minRpm; - } - set - { - BlockEngine.GetBlockInfo(this).minRpm = value; - } - } - - /// - /// Gets or sets the Engine's MaxRpm property. May not be saved. - /// - public float MaxRpm - { - get - { - return BlockEngine.GetBlockInfo(this).maxRpm; - } - set - { - BlockEngine.GetBlockInfo(this).maxRpm = value; - } - } - - /// - /// Gets the Engine's GearDownRpms property. May not be saved. - /// - public float[] GearDownRpms - { - get - { - return BlockEngine.GetBlockInfo(this).gearDownRpms.ToManagedArray(); - } - } - - /// - /// Gets or sets the Engine's GearUpRpm property. May not be saved. - /// - public float GearUpRpm - { - get - { - return BlockEngine.GetBlockInfo(this).gearUpRpm; - } - set - { - BlockEngine.GetBlockInfo(this).gearUpRpm = value; - } - } - - /// - /// Gets or sets the Engine's MaxRpmChange property. May not be saved. - /// - public float MaxRpmChange - { - get - { - return BlockEngine.GetBlockInfo(this).maxRpmChange; - } - set - { - BlockEngine.GetBlockInfo(this).maxRpmChange = value; - } - } - - /// - /// Gets or sets the Engine's ManualToAutoGearCoolOffTime property. May not be saved. - /// - public float ManualToAutoGearCoolOffTime - { - get - { - return BlockEngine.GetBlockInfo(this).manualToAutoGearCoolOffTime; - } - set - { - BlockEngine.GetBlockInfo(this).manualToAutoGearCoolOffTime = value; - } - }*/ - } -} diff --git a/TechbloxModdingAPI/Blocks/Engines/BlockCloneEngine.cs b/TechbloxModdingAPI/Blocks/Engines/BlockCloneEngine.cs deleted file mode 100644 index 3d64280..0000000 --- a/TechbloxModdingAPI/Blocks/Engines/BlockCloneEngine.cs +++ /dev/null @@ -1,105 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Reflection; -using Gamecraft.Wires; -using HarmonyLib; -using RobocraftX.Blocks; -using RobocraftX.Character; -using RobocraftX.Common; -using Svelto.DataStructures; -using Svelto.ECS; -using TechbloxModdingAPI.Engines; - -namespace TechbloxModdingAPI.Blocks.Engines -{ - public class BlockCloneEngine : IApiEngine - { - private static Type copyEngineType = - AccessTools.TypeByName("Gamecraft.GUI.Tweaks.Engines.CopyTweaksOnPickEngine"); - private static Type copyWireEngineType = - AccessTools.TypeByName("Gamecraft.Wires.WireConnectionCopyOnPickEngine"); - private static Type createWireEngineType = - AccessTools.TypeByName("RobocraftX.GUI.Wires.WireConnectionCreateOnPlaceEngine"); - - private MethodBase copyFromBlock = AccessTools.Method(copyEngineType, "CopyTweaksFromBlock"); - private MethodBase copyToBlock = AccessTools.Method(copyEngineType, "ApplyTweaksToPlacedBlock"); - private MethodBase copyWireFromBlock = AccessTools.Method(copyWireEngineType, "CopyWireInputsAndOutputs"); - private MethodBase copyWireToBlock = AccessTools.Method(createWireEngineType, "PlaceWiresOnPlaceNewCube"); - - public void Ready() - { - } - - public EntitiesDB entitiesDB { get; set; } - - public void Dispose() - { - } - - public void CopyBlockStats(EGID sourceID, EGID targetID) - { - var allCharacters = (LocalFasterReadOnlyList) CharacterExclusiveGroups.AllCharacters; - foreach (var ((pickedBlockColl, count), _) in entitiesDB.QueryEntities(allCharacters)) - { - for (int i = 0; i < count; ++i) - { - ref PickedBlockExtraDataStruct pickedBlock = ref pickedBlockColl[i]; - var oldStruct = pickedBlock; - pickedBlock.pickedBlockEntityID = sourceID; - pickedBlock.placedBlockEntityID = targetID; - pickedBlock.placedBlockTweaksMustCopy = true; - if (entitiesDB.Exists(pickedBlock.pickedBlockEntityID) - && entitiesDB.Exists(pickedBlock.placedBlockEntityID)) - { - copyFromBlock.Invoke(Patch.copyEngine, new object[] {pickedBlock.ID, pickedBlock}); - - uint playerID = Player.LocalPlayer.Id; - var parameters = new object[] {playerID, pickedBlock}; - copyWireFromBlock.Invoke(Patch.copyWireEngine, parameters); - pickedBlock = (PickedBlockExtraDataStruct) parameters[1]; //ref arg - - copyToBlock.Invoke(Patch.copyEngine, new object[] {pickedBlock.ID, pickedBlock}); - - ExclusiveGroupStruct group = BuildModeWiresGroups.WIRES_COPY_GROUP + playerID; - copyWireToBlock.Invoke(Patch.createWireEngine, new object[] {group, pickedBlock.ID}); - - pickedBlock.placedBlockTweaksMustCopy = false; - } - - pickedBlock = oldStruct; //Make sure to not interfere with the game - Although that might not be the case with the wire copying - } - } - } - - [HarmonyPatch] - private static class Patch - { - public static object copyEngine; - public static object copyWireEngine; - public static object createWireEngine; - - public static void Postfix(object __instance) - { - if (__instance.GetType() == copyEngineType) - copyEngine = __instance; - else if (__instance.GetType() == copyWireEngineType) - copyWireEngine = __instance; - else if (__instance.GetType() == createWireEngineType) - createWireEngine = __instance; - } - - public static IEnumerable TargetMethods() - { - return new[] - { - AccessTools.GetDeclaredConstructors(copyEngineType)[0], - AccessTools.GetDeclaredConstructors(copyWireEngineType)[0], - AccessTools.GetDeclaredConstructors(createWireEngineType)[0] - }; - } - } - - public string Name { get; } = "TechbloxModdingAPIBlockCloneGameEngine"; - public bool isRemovable { get; } = false; - } -} \ No newline at end of file diff --git a/TechbloxModdingAPI/Blocks/Engines/BlockEngine.cs b/TechbloxModdingAPI/Blocks/Engines/BlockEngine.cs deleted file mode 100644 index fd16d2f..0000000 --- a/TechbloxModdingAPI/Blocks/Engines/BlockEngine.cs +++ /dev/null @@ -1,292 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using HarmonyLib; - -using Gamecraft.ColourPalette; -using Gamecraft.Wires; -using RobocraftX.Blocks; -using RobocraftX.Common; -using RobocraftX.Physics; -using RobocraftX.Rendering; -using RobocraftX.Rendering.GPUI; -using Svelto.DataStructures; -using Svelto.ECS; -using Svelto.ECS.EntityStructs; -using Svelto.ECS.Experimental; -using Svelto.ECS.Hybrid; -using Techblox.BuildingDrone; -using Techblox.ObjectIDBlockServer; -using Unity.Mathematics; - -using TechbloxModdingAPI.Engines; -using TechbloxModdingAPI.Utility; -using TechbloxModdingAPI.Utility.ECS; -using PrefabsID = RobocraftX.Common.PrefabsID; - -namespace TechbloxModdingAPI.Blocks.Engines -{ - /// - /// Engine for executing general block actions - /// - public partial class BlockEngine : IApiEngine - { - public string Name { get; } = "TechbloxModdingAPIBlockGameEngine"; - - public EntitiesDB entitiesDB { set; private get; } - - public bool isRemovable => false; - - public void Dispose() - { - } - - public void Ready() - { - } - - public Block[] GetConnectedBlocks(EGID blockID) - { - if (!BlockExists(blockID)) return Array.Empty(); - Stack cubeStack = new Stack(); - FasterList cubes = new FasterList(10); - var coll = entitiesDB.QueryEntities(); - foreach (var ((ecoll, count), _) in coll) - { - for(int i = 0; i < count; i++) - { - ecoll[i].areConnectionsAssigned = false; - } - } - - //TODO: GetConnectedCubesUtility - /*ConnectedCubesUtility.TreeTraversal.GetConnectedCubes(entitiesDB, blockID, cubeStack, cubes, - (in GridConnectionsEntityStruct _) => false);*/ - - var ret = new Block[cubes.count]; - for (int i = 0; i < cubes.count; i++) - ret[i] = Block.New(cubes[i]); - return ret; - } - - public float4 ConvertBlockColor(byte index) => index == byte.MaxValue - ? new float4(-1f, -1f, -1f, -1f) - : entitiesDB.QueryEntity(index, - ColourPaletteExclusiveGroups.COLOUR_PALETTE_GROUP).Colour; - - public OptionalRef GetBlockInfoOptional(Block block) where T : unmanaged, IEntityComponent - { - return entitiesDB.QueryEntityOptional(block); - } - - public ref T GetBlockInfo(Block block) where T : unmanaged, IEntityComponent - { - #if DEBUG - if (!typeof(BlockTagEntityStruct).IsAssignableFrom(typeof(T)) && block.Exists && block.InitData.Valid) - throw new ArgumentException("The block exists but the init data has not been removed!"); - #endif - return ref entitiesDB.QueryEntityOrDefault(block); - } - - internal ref T GetBlockInfo(EcsObjectBase obj) where T : unmanaged, IEntityComponent - { - return ref entitiesDB.QueryEntityOrDefault(obj); - } - - public ref T GetBlockInfoViewComponent(Block block) where T : struct, IEntityViewComponent - { - return ref entitiesDB.QueryEntityOrDefault(block); - } - - internal object GetBlockInfo(Block block, Type type, string name) - { - var opt = AccessTools.Method(typeof(NativeApiExtensions), "QueryEntityOptional", - new[] { typeof(EntitiesDB), typeof(EcsObjectBase), typeof(ExclusiveGroupStruct) }, new[] { type }) - .Invoke(null, new object[] { entitiesDB, block, null }); - var str = AccessTools.Property(opt.GetType(), "Value").GetValue(opt); - return AccessTools.Field(str.GetType(), name).GetValue(str); - } - - internal void SetBlockInfo(Block block, Type type, string name, object value) - { - var opt = AccessTools.Method(typeof(BlockEngine), "GetBlockInfoOptional", generics: new[] { type }) - .Invoke(this, new object[] { block }); - var prop = AccessTools.Property(opt.GetType(), "Value"); - var str = prop.GetValue(opt); - AccessTools.Field(str.GetType(), name).SetValue(str, value); - prop.SetValue(opt, str); - } - - public void UpdateDisplayedBlock(EGID id) - { - if (!BlockExists(id)) return; - var pos = entitiesDB.QueryEntity(id); - var rot = entitiesDB.QueryEntity(id); - var scale = entitiesDB.QueryEntity(id); - var skew = entitiesDB.QueryEntity(id); - entitiesDB.QueryEntity(id).matrix = - math.mul(float4x4.TRS(pos.position, rot.rotation, scale.scale), skew.skewMatrix); - entitiesDB.PublishEntityChangeDelayed(id); // Signal a prefab change so it updates the render buffers - } - - internal void UpdatePrefab(Block block, byte material, bool flipped) - { - var prefabAssetIDOpt = entitiesDB.QueryEntityOptional(block); - uint prefabAssetID = prefabAssetIDOpt - ? prefabAssetIDOpt.Get().prefabAssetID - : uint.MaxValue; - if (prefabAssetID == uint.MaxValue) - { - if (entitiesDB.QueryEntityOptional(block)) //The block exists - throw new BlockException("Prefab asset ID not found for block " + block); //Set by the game - return; - } - - uint prefabId = - PrefabsID.GetOrAddPrefabID((ushort) prefabAssetID, material, 1, flipped); - entitiesDB.QueryEntityOrDefault(block).prefabID = prefabId; - if (block.Exists) - { - entitiesDB.PublishEntityChangeDelayed(block.Id); - entitiesDB.PublishEntityChangeDelayed(block.Id); - - ref BuildingActionComponent local = - ref entitiesDB.QueryEntity(BuildingDroneUtility - .GetLocalBuildingDrone(entitiesDB).ToEGID(entitiesDB)); - local.buildAction = BuildAction.ChangeMaterial; - local.targetPosition = block.Position; - this.entitiesDB.PublishEntityChangeDelayed(local.ID); - } - //Phyiscs prefab: prefabAssetID, set on block creation from the CubeListData - } - - public void UpdateBlockColor(EGID id) - { - entitiesDB.PublishEntityChangeDelayed(id); - } - - public bool BlockExists(EGID blockID) - { - return entitiesDB.Exists(blockID); - } - - public SimBody[] GetSimBodiesFromID(byte id) - { - var ret = new FasterList(4); - var oids = entitiesDB.QueryEntitiesOptional(ObjectIDBlockExclusiveGroups.OBJECT_ID_BLOCK_GROUP); - EGIDMapper? connections = null; - foreach (var oid in oids) - { - if (oid.Get().objectId != id) continue; - if (!connections.HasValue) //Would need reflection to get the group from the build group otherwise - connections = entitiesDB.QueryMappedEntities(oid.EGID.groupID); - //var rid = connections.Value.Entity(tag.ID.entityID).machineRigidBodyId; - /*foreach (var rb in ret) - TODO - { - if (rb.Id.entityID == rid) - goto DUPLICATE; //Multiple Object Identifiers on one rigid body - } - - ret.Add(new SimBody(rid)); - DUPLICATE: ;*/ - } - - return ret.ToArray(); - } - - public SimBody[] GetConnectedSimBodies(uint id) - { - var (joints, count) = entitiesDB.QueryEntities(MachineSimulationGroups.JOINTS_GROUP); - var list = new FasterList(4); - for (int i = 0; i < count; i++) - { - ref var joint = ref joints[i]; - if (joint.isBroken) continue; - /*if (joint.connectedEntityA == id) list.Add(new SimBody(joint.connectedEntityB)); - TODO: - else if (joint.connectedEntityB == id) list.Add(new SimBody(joint.connectedEntityA));*/ - } - - return list.ToArray(); - } - - public SimBody[] GetClusterBodies(uint cid) - { - var groups = entitiesDB.QueryEntities(); - var bodies = new HashSet(); - foreach (var ((coll, count), _) in groups) - { - for (var index = 0; index < count; index++) - { - var conn = coll[index]; - /*if (conn.clusterId == cid) - TODO - bodies.Add(conn.machineRigidBodyId);*/ - } - } - - return bodies.Select(id => new SimBody(id, cid)).ToArray(); - } - - public EGID? FindBlockEGID(uint id) - { - var groups = entitiesDB.FindGroups(); - foreach (ExclusiveGroupStruct group in groups) - { - if (entitiesDB.Exists(id, group)) - return new EGID(id, group); - } - - return null; - } - - public Cluster GetCluster(uint sbid) - { - var groups = entitiesDB.QueryEntities(); - foreach (var ((coll, count), _) in groups) - { - for (var index = 0; index < count; index++) - { - var conn = coll[index]; - //Static blocks don't have a cluster ID but the cluster destruction manager should have one - /*if (conn.machineRigidBodyId == sbid && conn.clusterId != uint.MaxValue) - TODO: - return new Cluster(conn.clusterId);*/ - } - } - - return null; - } - - public Block[] GetBodyBlocks(uint sbid) - { - var groups = entitiesDB.FindGroups(); - groups = new QueryGroups(groups).Except(CommonExclusiveGroups.DISABLED_JOINTS_IN_SIM_GROUP).Evaluate().result; - var set = new HashSet(); - foreach (var ((coll, tags, count), _) in entitiesDB.QueryEntities(groups)) - { - for (var index = 0; index < count; index++) - { - var conn = coll[index]; - /*if (conn.machineRigidBodyId == sbid) - TODO - set.Add(Block.New(tags[index].ID));*/ - } - } - - return set.ToArray(); - } - - public ObjectID[] GetObjectIDsFromID(byte id) - { - if (!entitiesDB.HasAny(ObjectIDBlockExclusiveGroups.OBJECT_ID_BLOCK_GROUP)) - return Array.Empty(); - - var ret = new FasterList(4); - var oids = entitiesDB.QueryEntitiesOptional(ObjectIDBlockExclusiveGroups.OBJECT_ID_BLOCK_GROUP); - foreach (var oid in oids) - { - if (oid.Get().objectIDToTrigger == id) - ret.Add(new ObjectID(oid.EGID)); - } - - return ret.ToArray(); - } - } -} \ No newline at end of file diff --git a/TechbloxModdingAPI/Blocks/Engines/BlockEventsEngine.cs b/TechbloxModdingAPI/Blocks/Engines/BlockEventsEngine.cs deleted file mode 100644 index 4b7a514..0000000 --- a/TechbloxModdingAPI/Blocks/Engines/BlockEventsEngine.cs +++ /dev/null @@ -1,47 +0,0 @@ -using System; - -using RobocraftX.Blocks; -using Svelto.ECS; - -using TechbloxModdingAPI.Engines; -using TechbloxModdingAPI.Utility; - -namespace TechbloxModdingAPI.Blocks.Engines -{ - public class BlockEventsEngine : IReactionaryEngine - { - public WrappedHandler Placed; - public WrappedHandler Removed; - - public void Ready() - { - } - - public EntitiesDB entitiesDB { get; set; } - - public void Dispose() - { - } - - public string Name { get; } = "TechbloxModdingAPIBlockEventsEngine"; - public bool isRemovable { get; } = false; - - public void Add(ref BlockTagEntityStruct entityComponent, EGID egid) - { - Placed.Invoke(this, new BlockPlacedRemovedEventArgs {ID = egid}); - } - - public void Remove(ref BlockTagEntityStruct entityComponent, EGID egid) - { - Removed.Invoke(this, new BlockPlacedRemovedEventArgs {ID = egid}); - } - } - - public struct BlockPlacedRemovedEventArgs - { - public EGID ID; - private Block block; - - public Block Block => block ??= Block.New(ID); - } -} \ No newline at end of file diff --git a/TechbloxModdingAPI/Blocks/Engines/BlueprintEngine.cs b/TechbloxModdingAPI/Blocks/Engines/BlueprintEngine.cs deleted file mode 100644 index f04b3a3..0000000 --- a/TechbloxModdingAPI/Blocks/Engines/BlueprintEngine.cs +++ /dev/null @@ -1,404 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Reflection; -using Gamecraft.Blocks.BlockGroups; -using Gamecraft.GUI.Blueprints; -using HarmonyLib; -using RobocraftX.Blocks; -using RobocraftX.Blocks.Ghost; -using RobocraftX.Common; -using RobocraftX.CR.MachineEditing.BoxSelect; -using RobocraftX.CR.MachineEditing.BoxSelect.ClipboardOperations; -using RobocraftX.Physics; -using RobocraftX.Rendering; -using RobocraftX.Rendering.GPUI; -using Svelto.DataStructures; -using Svelto.ECS; -using Svelto.ECS.DataStructures; -using Svelto.ECS.EntityStructs; -using Svelto.ECS.Native; -using Svelto.ECS.Serialization; -using Techblox.Blocks.Connections; -using TechbloxModdingAPI.Engines; -using TechbloxModdingAPI.Utility; -using TechbloxModdingAPI.Utility.ECS; -using Unity.Collections; -using Unity.Mathematics; -using UnityEngine; -using Allocator = Svelto.Common.Allocator; - -namespace TechbloxModdingAPI.Blocks.Engines -{ - public class BlueprintEngine : IFactoryEngine - { - private readonly MethodInfo getBlocksFromGroup = - AccessTools.Method("RobocraftX.CR.MachineEditing.PlaceBlockUtility:GetBlocksSharingBlockgroup"); - - private NativeDynamicArray selectedBlocksInGroup; - private NativeHashSet removedConnections = new NativeHashSet(); - private int addingToBlockGroup = -1; - - private static readonly Type PlaceBlueprintUtilityType = - AccessTools.TypeByName("RobocraftX.CR.MachineEditing.PlaceBlueprintUtility"); - private static readonly FieldInfo LocalBlockMap = - AccessTools.DeclaredField(PlaceBlueprintUtilityType, "_localBlockMap"); - private static readonly MethodInfo BuildBlock = AccessTools.Method(PlaceBlueprintUtilityType, "BuildBlock"); - private static readonly MethodInfo BuildWires = AccessTools.Method(PlaceBlueprintUtilityType, "BuildWires"); - private static readonly Type SerializeGhostBlueprintType = - AccessTools.TypeByName("RobocraftX.CR.MachineEditing.BoxSelect.SerializeGhostChildrenOnAddEngine"); - private static readonly MethodInfo SerializeGhostBlueprint = - AccessTools.Method(SerializeGhostBlueprintType, "SerializeClipboardGhostEntities"); - - private static NativeEntityRemove nativeBlockRemove; - private static NativeEntityRemove nativeConnectionRemove; - private static MachineGraphConnectionEntityFactory connectionFactory; - private static IEntityFunctions entityFunctions; - private static ClipboardSerializationDataResourceManager clipboardManager; - private static IEntitySerialization entitySerialization; - private static IEntityFactory entityFactory; - private static FasterList globalBlockMap; - private static object SerializeGhostBlueprintInstance; - private static GhostChildEntityFactory BuildGhostBlueprintFactory; - - public void Ready() - { - selectedBlocksInGroup = NativeDynamicArray.Alloc(Allocator.Persistent); - } - - public EntitiesDB entitiesDB { get; set; } - - public void Dispose() - { - selectedBlocksInGroup.Dispose(); - } - - public Block[] GetBlocksFromGroup(EGID blockID, out float3 pos, out quaternion rot) - { - var blockPos = default(float3); - var blockRot = default(quaternion); - var parameters = new object[] {blockID, selectedBlocksInGroup, entitiesDB, blockPos, blockRot}; - getBlocksFromGroup.Invoke(null, parameters); - pos = (float3) parameters[3]; - rot = (quaternion) parameters[4]; - int count = selectedBlocksInGroup.Count(); - var ret = new Block[count]; - for (uint i = 0; i < count; i++) - ret[i] = Block.New(selectedBlocksInGroup.Get(i)); - selectedBlocksInGroup.FastClear(); - return ret; - } - - public void RemoveBlockGroup(int id) - { - BlockGroupUtility.RemoveAllBlocksInBlockGroup(id, entitiesDB, removedConnections, nativeBlockRemove, - nativeConnectionRemove, connectionFactory, default).Complete(); - } - - public int CreateBlockGroup(float3 position, quaternion rotation) - { - int nextFilterId = BlockGroupUtility.NextFilterId; - Factory.BuildEntity((uint) nextFilterId, - BlockGroupExclusiveGroups.BlockGroupEntityGroup).Init(new BlockGroupTransformEntityComponent - { - blockGroupGridRotation = rotation, - blockGroupGridPosition = position - }); - return nextFilterId; - } - - public void AddBlockToGroup(EGID blockID, int groupID) - { - if (globalBlockMap == null) - globalBlockMap = FullGameFields._deserialisedBlockMap; - if (groupID != addingToBlockGroup) - { - Logging.MetaDebugLog("Changing current block group from " + addingToBlockGroup + " to " + groupID); - addingToBlockGroup = groupID; - globalBlockMap.Clear(); - } - - globalBlockMap.Add(blockID); - } - - public void SelectBlueprint(uint resourceID) - { - if (resourceID == uint.MaxValue) - BlueprintUtil.UnselectBlueprint(entitiesDB); - else - BlueprintUtil.SelectBlueprint(entitiesDB, resourceID, false, -1); - } - - public uint CreateBlueprint() - { - uint index = clipboardManager.AllocateSerializationData(); - return index; - } - - public void ReplaceBlueprint(uint playerID, uint blueprintID, ICollection selected, float3 pos, quaternion rot) - { - var blockIDs = new EGID[selected.Count]; - using (var enumerator = selected.GetEnumerator()) - { - for (var i = 0; enumerator.MoveNext(); i++) - { - var block = enumerator.Current; - blockIDs[i] = block.Id; - } - } - - var serializationData = clipboardManager.GetSerializationData(blueprintID); - SelectionSerializationUtility.ClearClipboard(playerID, entitiesDB, entityFunctions, serializationData.blueprintData, -1); - if (selected.Count == 0) - return; - //ref BlockGroupTransformEntityComponent groupTransform = ref EntityNativeDBExtensions.QueryEntity(entitiesDb, (uint) local1.currentBlockGroup, BlockGroupExclusiveGroups.BlockGroupEntityGroup); - //ref ColliderAabb collider = ref EntityNativeDBExtensions.QueryEntity(entitiesDB, (uint) groupID, BlockGroupExclusiveGroups.BlockGroupEntityGroup); - //float3 bottomOffset = PlaceBlockUtility.GetBottomOffset(collider); - //var rootPosition = math.mul(groupTransform.blockGroupGridRotation, bottomOffset) + groupTransform.blockGroupGridPosition; - //var rootRotation = groupTransform.blockGroupGridRotation; - - clipboardManager.SetGhostSerialized(blueprintID, false); - SelectionSerializationUtility.CopySelectionToClipboard(playerID, entitiesDB, - serializationData.blueprintData, entitySerialization, entityFactory, blockIDs, - (uint) blockIDs.Length, pos, rot, -1); - BuildGhostBlueprint(selected, pos, rot, playerID); - SerializeGhostBlueprint.Invoke(SerializeGhostBlueprintInstance, new object[] {playerID, blueprintID}); - - } - - private void BuildGhostBlueprint(ICollection blocks, float3 pos, quaternion rot, uint playerID) - { - GhostChildUtility.ClearGhostChildren(playerID, entitiesDB, entityFunctions); - var bssesopt = entitiesDB.QueryEntityOptional(new EGID(playerID, - BoxSelectExclusiveGroups.BoxSelectVolumeExclusiveGroup)); - if (!bssesopt) - return; - foreach (var block in blocks) - { - GhostChildUtility.BuildGhostChild(in playerID, block.Id, in pos, in rot, entitiesDB, - BuildGhostBlueprintFactory, false, bssesopt.Get().buildingDroneReference, - FullGameFields._managers.blockLabelResourceManager); - } - } - - public Block[] PlaceBlueprintBlocks(uint blueprintID, uint playerID, float3 pos, float3 rot) - { //RobocraftX.CR.MachineEditing.PlaceBlueprintUtility.PlaceBlocksFromSerialisedData - var serializationData = clipboardManager.GetSerializationData(blueprintID); - var blueprintData = serializationData.blueprintData; - blueprintData.dataPos = 0U; - uint selectionSize; - PositionEntityStruct selectionPosition; - RotationEntityStruct selectionRotation; - uint version; - BoxSelectSerializationUtilities.ReadClipboardHeader(blueprintData, out selectionSize, out selectionPosition, out selectionRotation, out version); - ((FasterList) LocalBlockMap.GetValue(null)).Clear(); - if (version <= 1U) - { - uint groupsCount; - BoxSelectSerializationUtilities.ReadBlockGroupData(blueprintData, out groupsCount); - for (int index = 0; (long) index < (long) groupsCount; ++index) - { - int nextFilterId = BlockGroupUtility.NextFilterId; - entitySerialization.DeserializeNewEntity(new EGID((uint) nextFilterId, BlockGroupExclusiveGroups.BlockGroupEntityGroup), blueprintData, 1); - } - } - int nextFilterId1 = BlockGroupUtility.NextFilterId; - entityFactory.BuildEntity(new EGID((uint) nextFilterId1, - BlockGroupExclusiveGroups.BlockGroupEntityGroup)).Init(new BlockGroupTransformEntityComponent - { - blockGroupGridPosition = selectionPosition.position, - blockGroupGridRotation = selectionRotation.rotation - }); - var frot = Quaternion.Euler(rot); - var grid = new GridRotationStruct {position = pos, rotation = frot}; - var poss = new PositionEntityStruct {position = pos}; - var rots = new RotationEntityStruct {rotation = frot}; - for (int index = 0; (long) index < (long) selectionSize; ++index) - BuildBlock.Invoke(null, - new object[] - { - playerID, grid, poss, rots, selectionPosition, selectionRotation, blueprintData, - entitySerialization, nextFilterId1 - }); - /* - uint playerId, in GridRotationStruct ghostParentGrid, - in PositionEntityStruct ghostParentPosition, in RotationEntityStruct ghostParentRotation, - in PositionEntityStruct selectionPosition, in RotationEntityStruct selectionRotation, - ISerializationData serializationData, EntitiesDB entitiesDb, - IEntitySerialization entitySerialization, int blockGroupId - */ - if (globalBlockMap == null) - globalBlockMap = FullGameFields._deserialisedBlockMap; - var placedBlocks = (FasterList) LocalBlockMap.GetValue(null); - globalBlockMap.Clear(); - globalBlockMap.AddRange(placedBlocks); - BuildWires.Invoke(null, - new object[] {playerID, blueprintData, entitySerialization, entitiesDB, entityFactory}); - var blocks = new Block[placedBlocks.count]; - for (int i = 0; i < blocks.Length; i++) - blocks[i] = Block.New(placedBlocks[i]); - return blocks; - } - - public void GetBlueprintInfo(uint blueprintID, out float3 pos, out quaternion rot, out uint selectionSize) - { - var serializationData = clipboardManager.GetSerializationData(blueprintID); - var blueprintData = serializationData.blueprintData; - blueprintData.dataPos = 0U; - BoxSelectSerializationUtilities.ReadClipboardHeader(blueprintData, out selectionSize, out var posst, - out var rotst, out _); - blueprintData.dataPos = 0U; //Just to be sure, it gets reset when it's read anyway - pos = posst.position; - rot = rotst.rotation; - } - - public void InitBlueprint(uint blueprintID) - { - clipboardManager.IncrementRefCount(blueprintID); - } - - public void DisposeBlueprint(uint blueprintID) - { - clipboardManager.DecrementRefCount(blueprintID); - } - - - //GhostChildUtility.BuildGhostChild - public Block BuildGhostChild() - { - var sourceId = new EGID(Player.LocalPlayer.Id, GHOST_BLOCKS_ENABLED.Group); - var positionEntityStruct = entitiesDB.QueryEntity(sourceId); - var rotationEntityStruct = entitiesDB.QueryEntity(sourceId); - var scalingEntityStruct = entitiesDB.QueryEntity(sourceId); - var dbStruct = entitiesDB.QueryEntity(sourceId); - var colliderStruct = entitiesDB.QueryEntity(sourceId); - var colorStruct = entitiesDB.QueryEntity(sourceId); - uint ghostChildBlockId = CommonExclusiveGroups.GetNewGhostChildBlockID(); - var ghostEntityReference = GhostBlockUtils.GetGhostEntityReference(sourceId.entityID, entitiesDB); - var entityInitializer = BuildGhostBlueprintFactory.Build( - new EGID(ghostChildBlockId, BoxSelectExclusiveGroups.GhostChildEntitiesExclusiveGroup), /*dbStruct.DBID*/ (uint)BlockIDs.Cube, - FullGameFields._managers.blockLabelResourceManager); - entityInitializer.Init(dbStruct); - entityInitializer.Init(new GFXPrefabEntityStructGPUI( - PrefabsID.GetOrAddPrefabID((ushort)entityInitializer.Get().prefabAssetID, - entitiesDB.QueryEntity(sourceId).materialId, 7, - FlippedBlockUtils.IsFlipped(in scalingEntityStruct.scale)), true)); - entityInitializer.Init(entitiesDB.QueryEntity(sourceId)); - entityInitializer.Init(new GhostParentEntityStruct - { - ghostBlockParentEntityReference = ghostEntityReference, - ownerMustSerializeOnAdd = false - }); - entityInitializer.Init(colorStruct); - entityInitializer.Init(colliderStruct); - entityInitializer.Init(new RigidBodyEntityStruct - { - position = positionEntityStruct.position, - rotation = rotationEntityStruct.rotation - }); - entityInitializer.Init(new ScalingEntityStruct - { - scale = scalingEntityStruct.scale - }); - entityInitializer.Init(new LocalTransformEntityStruct - { - position = positionEntityStruct.position, - rotation = rotationEntityStruct.rotation - }); - entityInitializer.Init(new RotationEntityStruct - { - rotation = rotationEntityStruct.rotation - }); - entityInitializer.Init(new PositionEntityStruct - { - position = positionEntityStruct.position - }); - entityInitializer.Init(new SkewComponent - { - skewMatrix = entitiesDB.QueryEntity(sourceId).skewMatrix - }); - entityInitializer.Init(new BlockPlacementInfoStruct - { - placedByBuildingDrone = entitiesDB - .QueryEntityOptional(new EGID(Player.LocalPlayer.Id, - BoxSelectExclusiveGroups.BoxSelectVolumeExclusiveGroup)).Get().buildingDroneReference - }); - entityInitializer.Init(new GridRotationStruct - { - position = float3.zero, - rotation = quaternion.identity - }); - var block = Block.New(entityInitializer.EGID); - block.InitData = entityInitializer; - return block; - } - - public string Name { get; } = "TechbloxModdingAPIBlueprintGameEngine"; - public bool isRemovable { get; } = false; - - [HarmonyPatch] - private static class RemoveEnginePatch - { - public static void Prefix(IEntityFunctions entityFunctions, - MachineGraphConnectionEntityFactory machineGraphConnectionEntityFactory) - { - nativeBlockRemove = entityFunctions.ToNativeRemove("TBAPI" + nameof(BlueprintEngine)); - nativeConnectionRemove = entityFunctions.ToNativeRemove("TBAPI" + nameof(BlueprintEngine)); - connectionFactory = machineGraphConnectionEntityFactory; - BlueprintEngine.entityFunctions = entityFunctions; - } - - public static MethodBase TargetMethod() - { - return AccessTools.GetDeclaredConstructors(AccessTools.TypeByName("RobocraftX.CR.MachineEditing.RemoveBlockEngine"))[0]; - } - } - - [HarmonyPatch] - private static class SelectEnginePatch - { - public static void Prefix(ClipboardSerializationDataResourceManager clipboardSerializationDataResourceManager, - IEntitySerialization entitySerialization, - IEntityFactory entityFactory) - { - clipboardManager = clipboardSerializationDataResourceManager; - BlueprintEngine.entitySerialization = entitySerialization; - BlueprintEngine.entityFactory = entityFactory; - } - - public static MethodBase TargetMethod() - { - return AccessTools.GetDeclaredConstructors(AccessTools.TypeByName("RobocraftX.CR.MachineEditing.SelectBlockEngine"))[0]; - } - } - - [HarmonyPatch] - private static class SerializeGhostBlueprintPatch - { - public static void Postfix(object __instance) - { - SerializeGhostBlueprintInstance = __instance; - } - - public static MethodBase TargetMethod() - { - return AccessTools.GetDeclaredConstructors(SerializeGhostBlueprintType)[0]; - } - } - - [HarmonyPatch] - private static class BuildGhostBlueprintPatch - { - public static void Postfix(GhostChildEntityFactory ghostChildEntityFactory) - { - BuildGhostBlueprintFactory = ghostChildEntityFactory; - } - - public static MethodBase TargetMethod() - { - return AccessTools.GetDeclaredConstructors(AccessTools.TypeByName("RobocraftX.CR.MachineEditing.BuildGhostChildForMultiblockPickEngine"))[0]; - } - } - - public IEntityFactory Factory { get; set; } - } -} \ No newline at end of file diff --git a/TechbloxModdingAPI/Blocks/Engines/MovementEngine.cs b/TechbloxModdingAPI/Blocks/Engines/MovementEngine.cs deleted file mode 100644 index 7f8acfd..0000000 --- a/TechbloxModdingAPI/Blocks/Engines/MovementEngine.cs +++ /dev/null @@ -1,69 +0,0 @@ -using RobocraftX.Common; -using RobocraftX.DOTS; -using Svelto.ECS; -using Svelto.ECS.EntityStructs; -using Unity.Mathematics; -using Unity.Transforms; - -using TechbloxModdingAPI.Engines; -using TechbloxModdingAPI.Utility; -using TechbloxModdingAPI.Utility.ECS; - -namespace TechbloxModdingAPI.Blocks.Engines -{ - /// - /// Engine which executes block movement actions - /// - public class MovementEngine : IApiEngine - { - public string Name { get; } = "TechbloxModdingAPIMovementGameEngine"; - - public EntitiesDB entitiesDB { set; private get; } - - public bool isRemovable => false; - - public bool IsInGame = false; - - public void Dispose() - { - IsInGame = false; - } - - public void Ready() - { - IsInGame = true; - } - - // implementations for Movement static class - - internal float3 MoveBlock(Block block, float3 vector) - { - ref PositionEntityStruct posStruct = ref this.entitiesDB.QueryEntityOrDefault(block); - ref GridRotationStruct gridStruct = ref this.entitiesDB.QueryEntityOrDefault(block); - ref LocalTransformEntityStruct transStruct = ref this.entitiesDB.QueryEntityOrDefault(block); - var phyStruct = this.entitiesDB.QueryEntityOptional(block); - // main (persistent) position - posStruct.position = vector; - // placement grid position - gridStruct.position = vector; - // rendered position - transStruct.position = vector; - // collision position - if (phyStruct) - { //It exists - FullGameFields._physicsWorld.EntityManager.SetComponentData(phyStruct.Get().dotsEntity, new Translation - { - Value = posStruct.position - }); - } - - entitiesDB.QueryEntityOrDefault(block).areConnectionsAssigned = false; - return posStruct.position; - } - - internal float3 GetPosition(Block block) - { - return entitiesDB.QueryEntityOrDefault(block).position; - } - } -} diff --git a/TechbloxModdingAPI/Blocks/Engines/PlacementEngine.cs b/TechbloxModdingAPI/Blocks/Engines/PlacementEngine.cs deleted file mode 100644 index d32f7f1..0000000 --- a/TechbloxModdingAPI/Blocks/Engines/PlacementEngine.cs +++ /dev/null @@ -1,131 +0,0 @@ -using System.Reflection; - -using DataLoader; -using Gamecraft.Blocks.BlockGroups; -using Gamecraft.Wires; -using HarmonyLib; -using RobocraftX.Blocks; -using RobocraftX.Character; -using RobocraftX.Common; -using RobocraftX.CR.MachineEditing.BoxSelect; -using RobocraftX.Rendering; -using RobocraftX.Rendering.GPUI; -using Svelto.ECS; -using Svelto.ECS.EntityStructs; -using Unity.Mathematics; - -using TechbloxModdingAPI.Engines; -using TechbloxModdingAPI.Utility; -using TechbloxModdingAPI.Utility.ECS; - -namespace TechbloxModdingAPI.Blocks.Engines -{ - /// - /// Engine which executes block placement actions - /// - public class PlacementEngine : IApiEngine - { - public bool IsInGame; - - public void Dispose() - { - IsInGame = false; - } - - public void Ready() - { - IsInGame = true; - } - - public EntitiesDB entitiesDB { get; set; } - private static BlockEntityFactory _blockEntityFactory; //Injected from PlaceSingleBlockEngine - private static IEntityFactory _entityFactory; - - public EntityInitializer PlaceBlock(BlockIDs block, float3 position, Player player, bool autoWire) - { //It appears that only the non-uniform scale has any visible effect, but if that's not given here it will be set to the uniform one - return BuildBlock((ushort) block, position, autoWire, (player ?? Player.LocalPlayer).Id); - } - - private EntityInitializer BuildBlock(ushort block, float3 position, bool autoWire, uint playerId) - { - if (_blockEntityFactory == null) - throw new BlockException("The factory is null."); - if(!FullGameFields._dataDb.ContainsKey(block)) - throw new BlockException("Block with ID " + block + " not found!"); - //RobocraftX.CR.MachineEditing.PlaceSingleBlockEngine - DBEntityStruct dbEntity = new DBEntityStruct {DBID = block}; - - EntityInitializer structInitializer = _blockEntityFactory.Build(CommonExclusiveGroups.blockIDGeneratorClient.Next(), block); //The ghost block index is only used for triggers - uint prefabAssetID = structInitializer.Has() - ? structInitializer.Get().prefabAssetID - : throw new BlockException("Prefab asset ID not found!"); //Set by the game - uint prefabId = PrefabsID.GetOrAddPrefabID((ushort) prefabAssetID, (byte) BlockMaterial.SteelBodywork, 1, false); - structInitializer.Init(new GFXPrefabEntityStructGPUI(prefabId)); - structInitializer.Init(dbEntity); - structInitializer.Init(new PositionEntityStruct {position = position}); - structInitializer.Init(new RotationEntityStruct {rotation = quaternion.identity}); - structInitializer.Init(new ScalingEntityStruct {scale = new float3(1, 1, 1)}); - structInitializer.Init(new GridRotationStruct - { - position = position, - rotation = quaternion.identity - }); - structInitializer.Init(new UniformBlockScaleEntityStruct {scaleFactor = 1}); - structInitializer.Get().materialId = (byte) BlockMaterial.SteelBodywork; - var bssesopt = entitiesDB.QueryEntityOptional(new EGID(playerId, - BoxSelectExclusiveGroups.BoxSelectVolumeExclusiveGroup)); - if (!bssesopt) - throw new BlockException("Invalid player ID specified for block placement"); - structInitializer.Init(new BlockPlacementInfoStruct - { - loadedFromDisk = false, - placedByBuildingDrone = bssesopt.Get().buildingDroneReference, - triggerAutoWiring = autoWire && structInitializer.Has() - }); - - int nextFilterId = BlockGroupUtility.NextFilterId; - structInitializer.Init(new BlockGroupEntityComponent - { - currentBlockGroup = nextFilterId - }); - _entityFactory.BuildEntity((uint) nextFilterId, - BlockGroupExclusiveGroups.BlockGroupEntityGroup) - .Init(new BlockGroupTransformEntityComponent - { - blockGroupGridRotation = quaternion.identity, - blockGroupGridPosition = position - }); - - foreach (var group in CharacterExclusiveGroups.AllCharacters) - { - EGID playerEGID = new EGID(playerId, group); - if (!entitiesDB.TryQueryEntitiesAndIndex(playerEGID, out uint index, - out var array)) continue; - ref PickedBlockExtraDataStruct pickedBlock = ref array[index]; - pickedBlock.placedBlockEntityID = structInitializer.EGID; - pickedBlock.placedBlockWasAPickedBlock = false; - } - return structInitializer; - } - - public string Name => "TechbloxModdingAPIPlacementGameEngine"; - - public bool isRemovable => false; - - [HarmonyPatch] - class FactoryObtainerPatch - { - static void Postfix(BlockEntityFactory blockEntityFactory, IEntityFactory entityFactory) - { - _blockEntityFactory = blockEntityFactory; - _entityFactory = entityFactory; - Logging.MetaDebugLog("Block entity factory injected."); - } - - static MethodBase TargetMethod(Harmony instance) - { - return AccessTools.TypeByName("RobocraftX.CR.MachineEditing.PlaceSingleBlockEngine").GetConstructors()[0]; - } - } - } -} \ No newline at end of file diff --git a/TechbloxModdingAPI/Blocks/Engines/RemovalEngine.cs b/TechbloxModdingAPI/Blocks/Engines/RemovalEngine.cs deleted file mode 100644 index e4e899b..0000000 --- a/TechbloxModdingAPI/Blocks/Engines/RemovalEngine.cs +++ /dev/null @@ -1,86 +0,0 @@ -using System.Reflection; - -using Gamecraft.Blocks.BlockGroups; -using HarmonyLib; -using RobocraftX.Blocks; -using RobocraftX.Common; -using RobocraftX.GroupTags; -using RobocraftX.StateSync; -using Svelto.ECS; -using Svelto.ECS.Native; -using Techblox.Blocks.Connections; -using Unity.Collections; -using Unity.Jobs; -using Allocator = Unity.Collections.Allocator; - -using TechbloxModdingAPI.Engines; -using TechbloxModdingAPI.Utility; - -namespace TechbloxModdingAPI.Blocks.Engines -{ - public class RemovalEngine : IApiEngine, IDeterministicTimeStopped - { - private static IEntityFunctions _entityFunctions; - private static MachineGraphConnectionEntityFactory _connectionFactory; - private NativeHashSet removedConnections; - - public bool RemoveBlock(EGID target) - { - if (!entitiesDB.Exists(target)) - return false; - using var connStructMapper = - entitiesDB.QueryNativeMappedEntities(GroupTag.Groups, - Svelto.Common.Allocator.Temp); - if (entitiesDB.TryQueryNativeMappedEntities( - ConnectionsExclusiveGroups.MACHINE_CONNECTION_GROUP, out var mapper)) - { - BlockGroupUtility.RemoveBlockConnections(target, removedConnections, _connectionFactory, - connStructMapper, mapper, entitiesDB.GetEntityReferenceMap(), _entityFunctions); - } - - _entityFunctions.RemoveEntity(target); - return true; - } - - public void Ready() - { - removedConnections = new(2000, Allocator.Persistent); - } - - public EntitiesDB entitiesDB { get; set; } - - public void Dispose() - { - removedConnections.Dispose(); - } - - public string Name => "TechbloxModdingAPIRemovalGameEngine"; - public string name => Name; - - public bool isRemovable => false; - - [HarmonyPatch] - class FactoryObtainerPatch - { - static void Postfix(IEntityFunctions entityFunctions, - MachineGraphConnectionEntityFactory machineGraphConnectionEntityFactory) - { - _entityFunctions = entityFunctions; - _connectionFactory = machineGraphConnectionEntityFactory; - Logging.MetaDebugLog("Requirements injected."); - } - - static MethodBase TargetMethod(Harmony instance) - { - return AccessTools.TypeByName("RobocraftX.CR.MachineEditing.RemoveBlockEngine").GetConstructors()[0]; - } - } - - public JobHandle DeterministicStep(in float deltaTime, JobHandle inputDeps) - { - if (removedConnections.IsCreated) - removedConnections.Clear(); - return default; - } - } -} \ No newline at end of file diff --git a/TechbloxModdingAPI/Blocks/Engines/RotationEngine.cs b/TechbloxModdingAPI/Blocks/Engines/RotationEngine.cs deleted file mode 100644 index ccfc13e..0000000 --- a/TechbloxModdingAPI/Blocks/Engines/RotationEngine.cs +++ /dev/null @@ -1,76 +0,0 @@ -using RobocraftX.Common; -using RobocraftX.DOTS; -using Svelto.ECS; -using Svelto.ECS.EntityStructs; -using Unity.Mathematics; -using UnityEngine; - -using TechbloxModdingAPI.Engines; -using TechbloxModdingAPI.Utility; -using TechbloxModdingAPI.Utility.ECS; - -namespace TechbloxModdingAPI.Blocks.Engines -{ - /// - /// Engine which executes block movement actions - /// - public class RotationEngine : IApiEngine - { - public string Name { get; } = "TechbloxModdingAPIRotationGameEngine"; - - public EntitiesDB entitiesDB { set; private get; } - - public bool isRemovable => false; - - public bool IsInGame = false; - - public void Dispose() - { - IsInGame = false; - } - - public void Ready() - { - IsInGame = true; - } - - // implementations for Rotation static class - - internal float3 RotateBlock(Block block, Vector3 vector) - { - ref RotationEntityStruct rotStruct = ref this.entitiesDB.QueryEntityOrDefault(block); - ref GridRotationStruct gridStruct = ref this.entitiesDB.QueryEntityOrDefault(block); - ref LocalTransformEntityStruct transStruct = ref this.entitiesDB.QueryEntityOrDefault(block); - var phyStruct = this.entitiesDB.QueryEntityOptional(block); - // main (persistent) rotation - Quaternion newRotation = rotStruct.rotation; - newRotation.eulerAngles = vector; - rotStruct.rotation = newRotation; - // placement grid rotation - gridStruct.rotation = newRotation; - // rendered rotation - transStruct.rotation = newRotation; - // collision rotation - if (phyStruct) - { //It exists - FullGameFields._physicsWorld.EntityManager.SetComponentData(phyStruct.Get().dotsEntity, - new Unity.Transforms.Rotation - { - Value = rotStruct.rotation - }); - } - - // TODO: Connections probably need to be assigned (maybe) - // They are assigned during machine processing anyway - entitiesDB.QueryEntityOrDefault(block).areConnectionsAssigned = false; - return ((Quaternion)rotStruct.rotation).eulerAngles; - - } - - internal float3 GetRotation(Block block) - { - ref RotationEntityStruct rotStruct = ref entitiesDB.QueryEntityOrDefault(block); - return ((Quaternion) rotStruct.rotation).eulerAngles; - } - } -} diff --git a/TechbloxModdingAPI/Blocks/Engines/ScalingEngine.cs b/TechbloxModdingAPI/Blocks/Engines/ScalingEngine.cs deleted file mode 100644 index ef5cfe4..0000000 --- a/TechbloxModdingAPI/Blocks/Engines/ScalingEngine.cs +++ /dev/null @@ -1,59 +0,0 @@ -using System.Reflection; - -using HarmonyLib; -using RobocraftX.Common; -using RobocraftX.DOTS; -using Svelto.ECS; -using Unity.Entities; - -using TechbloxModdingAPI.Engines; -using TechbloxModdingAPI.Utility; - -namespace TechbloxModdingAPI.Blocks.Engines -{ - public class ScalingEngine : IApiEngine - { - private static IReactOnAddAndRemove physicsEngine; - - public void Ready() - { - } - - public EntitiesDB entitiesDB { get; set; } - public void Dispose() - { - } - - public string Name { get; } = "TechbloxModdingAPIScalingEngine"; - public bool isRemovable { get; } = false; - - private EntityManager _entityManager; //Unity entity manager - - public void UpdateCollision(EGID egid) - { - if (_entityManager == default) - _entityManager = FullGameFields._physicsWorld.EntityManager; - //Assuming the block exists - var entity = entitiesDB.QueryEntity(egid).dotsEntity; - var pes = new DOTSPhysicsEntityCreationStruct(); - physicsEngine.Add(ref pes, egid); //Create new DOTS entity - _entityManager.DestroyEntity(entity); - } - - [HarmonyPatch] - class PhysicsEnginePatch - { - static void Postfix(IReactOnAddAndRemove __instance) - { - physicsEngine = __instance; - Logging.MetaDebugLog("Physics engine injected."); - } - - static MethodBase TargetMethod(Harmony instance) - { - return AccessTools.Method("RobocraftX.StateSync.HandleDOTSPhysicEntitiesWithPrefabCreationEngine" + - ":Ready"); - } - } - } -} \ No newline at end of file diff --git a/TechbloxModdingAPI/Blocks/Engines/SignalEngine.cs b/TechbloxModdingAPI/Blocks/Engines/SignalEngine.cs deleted file mode 100644 index 45d6e75..0000000 --- a/TechbloxModdingAPI/Blocks/Engines/SignalEngine.cs +++ /dev/null @@ -1,357 +0,0 @@ -using System; - -using Gamecraft.Wires; -using Svelto.DataStructures; -using Svelto.ECS; - -using TechbloxModdingAPI.Engines; -using TechbloxModdingAPI.Utility; -using TechbloxModdingAPI.Utility.ECS; - -namespace TechbloxModdingAPI.Blocks.Engines -{ - /// - /// Engine which executes signal actions - /// - public class SignalEngine : IApiEngine, IFactoryEngine - { - public const float POSITIVE_HIGH = 1.0f; - public const float NEGATIVE_HIGH = -1.0f; - public const float HIGH = 1.0f; - public const float ZERO = 0.0f; - - public string Name { get; } = "TechbloxModdingAPISignalGameEngine"; - - public EntitiesDB entitiesDB { set; private get; } - - public IEntityFactory Factory { get; set; } - - public bool isRemovable => false; - - public bool IsInGame = false; - - public void Dispose() - { - IsInGame = false; - } - - public void Ready() - { - IsInGame = true; - } - - // implementations for block wiring - - public (WireEntityStruct Wire, EGID ID) CreateNewWire(EGID startBlock, byte startPort, EGID endBlock, byte endPort) - { - EGID wireEGID = new EGID(BuildModeWiresGroups.NewWireEntityId, BuildModeWiresGroups.WiresGroup.Group); - EntityInitializer wireInitializer = Factory.BuildEntity(wireEGID); - wireInitializer.Init(new WireEntityStruct - { - sourceBlockEGID = startBlock, - sourcePortUsage = startPort, - destinationBlockEGID = endBlock, - destinationPortUsage = endPort - }); - return (wireInitializer.Get(), wireEGID); - } - - public ref WireEntityStruct GetWire(EGID wire) - { - if (!entitiesDB.Exists(wire)) - { - throw new WiringException($"Wire {wire} does not exist"); - } - return ref entitiesDB.QueryEntity(wire); - } - - public ref PortEntityStruct GetPort(EGID port) - { - if (!entitiesDB.Exists(port)) - { - throw new WiringException($"Port {port} does not exist (yet?)"); - } - return ref entitiesDB.QueryEntity(port); - } - - public ref PortEntityStruct GetPortByOffset(BlockPortsStruct bps, byte portNumber, bool input) - { - ExclusiveGroup group = input - ? NamedExclusiveGroup.Group - : NamedExclusiveGroup.Group; - uint id = (input ? bps.firstInputID : bps.firstOutputID) + portNumber; - EGID egid = new EGID(id, group); - if (!entitiesDB.Exists(egid)) - { - throw new WiringException("Port does not exist"); - } - return ref entitiesDB.QueryEntity(egid); - } - - public ref PortEntityStruct GetPortByOffset(Block block, byte portNumber, bool input) - { - var bps = entitiesDB.QueryEntityOptional(block); - if (!bps) - { - throw new BlockException("Block does not exist"); - } - return ref GetPortByOffset(bps, portNumber, input); - } - - public ref T GetComponent(EGID egid) where T : unmanaged, IEntityComponent - { - return ref entitiesDB.QueryEntity(egid); - } - - public bool Exists(EGID egid) where T : struct, IEntityComponent - { - return entitiesDB.Exists(egid); - } - - public bool SetSignal(EGID blockID, float signal, out uint signalID, bool input = true) - { - signalID = GetSignalIDs(blockID, input)[0]; - return SetSignal(signalID, signal); - } - - public bool SetSignal(uint signalID, float signal, bool input = true) - { - var (array, count) = GetSignalStruct(signalID, out uint index, input); - if (count > 0) array[index].valueAsFloat = signal; - return false; - } - - public float AddSignal(EGID blockID, float signal, out uint signalID, bool clamp = true, bool input = true) - { - signalID = GetSignalIDs(blockID, input)[0]; - return AddSignal(signalID, signal, clamp, input); - } - - public float AddSignal(uint signalID, float signal, bool clamp = true, bool input = true) - { - var (array, count) = GetSignalStruct(signalID, out uint index, input); - if (count > 0) - { - ref var channelData = ref array[index]; - channelData.valueAsFloat += signal; - if (clamp) - { - if (channelData.valueAsFloat > POSITIVE_HIGH) - { - channelData.valueAsFloat = POSITIVE_HIGH; - } - else if (channelData.valueAsFloat < NEGATIVE_HIGH) - { - channelData.valueAsFloat = NEGATIVE_HIGH; - } - - return channelData.valueAsFloat; - } - } - - return signal; - } - - public float GetSignal(EGID blockID, out uint signalID, bool input = true) - { - signalID = GetSignalIDs(blockID, input)[0]; - return GetSignal(signalID, input); - } - - public float GetSignal(uint signalID, bool input = true) - { - var (array, count) = GetSignalStruct(signalID, out uint index, input); - return count > 0 ? array[index].valueAsFloat : 0f; - } - - public uint[] GetSignalIDs(EGID blockID, bool input = true) - { - ref BlockPortsStruct bps = ref entitiesDB.QueryEntity(blockID); - uint[] signals; - if (input) { - signals = new uint[bps.inputCount]; - for (uint i = 0u; i < bps.inputCount; i++) - { - signals[i] = bps.firstInputID + i; - } - } else { - signals = new uint[bps.outputCount]; - for (uint i = 0u; i < bps.outputCount; i++) - { - signals[i] = bps.firstOutputID + i; - } - } - return signals; - } - - public EGID[] GetSignalInputs(EGID blockID) - { - BlockPortsStruct ports = entitiesDB.QueryEntity(blockID); - EGID[] inputs = new EGID[ports.inputCount]; - for (uint i = 0; i < ports.inputCount; i++) - { - inputs[i] = new EGID(i + ports.firstInputID, NamedExclusiveGroup.Group); - } - return inputs; - } - - public EGID[] GetSignalOutputs(EGID blockID) - { - BlockPortsStruct ports = entitiesDB.QueryEntity(blockID); - EGID[] outputs = new EGID[ports.outputCount]; - for (uint i = 0; i < ports.outputCount; i++) - { - outputs[i] = new EGID(i + ports.firstOutputID, NamedExclusiveGroup.Group); - } - return outputs; - } - - public OptionalRef MatchBlockIOToPort(Block block, byte portUsage, bool output) - { - return MatchBlockIOToPort(block.Id, portUsage, output); - } - - public OptionalRef MatchBlockIOToPort(EGID block, byte portUsage, bool output) - { - if (!entitiesDB.Exists(block)) - return default; - var group = output - ? NamedExclusiveGroup.Group - : NamedExclusiveGroup.Group; - BlockPortsStruct ports = entitiesDB.QueryEntity(block); - if (!entitiesDB.TryQueryMappedEntities(group, out var mapper)) - return default; - for (uint i = 0; i < (output ? ports.outputCount : ports.inputCount); ++i) - { - uint entityID = (output ? ports.firstOutputID : ports.firstInputID) + i; - if (!mapper.TryGetArrayAndEntityIndex(entityID, out var index, out var array) || - array[index].usage != portUsage) continue; - return new OptionalRef(array, index, new EGID(entityID, group)); - } - - return default; - } - - public OptionalRef MatchPortToWire(PortEntityStruct port, EGID blockID, out EGID wireID) - { - var (wires, ids, count) = entitiesDB.QueryEntities(NamedExclusiveGroup.Group); - for (uint i = 0; i < count; i++) - { - if ((wires[i].destinationPortUsage == port.usage && wires[i].destinationBlockEGID == blockID) - || (wires[i].sourcePortUsage == port.usage && wires[i].sourceBlockEGID == blockID)) - { - wireID = new EGID(ids[i], BuildModeWiresGroups.WiresGroup.Group); - return new OptionalRef(wires, i); - } - } - - wireID = default; - return default; - } - - public EGID MatchBlocksToWire(EGID startBlock, EGID endBlock, byte startPort = byte.MaxValue, byte endPort = byte.MaxValue) - { - EGID[] startPorts; - if (startPort == byte.MaxValue) - { - // search all output ports on source block - startPorts = GetSignalOutputs(startBlock); - } - else - { - BlockPortsStruct ports = entitiesDB.QueryEntity(startBlock); - startPorts = new EGID[] {new EGID(ports.firstOutputID + startPort, NamedExclusiveGroup.Group) }; - } - - EGID[] endPorts; - if (startPort == byte.MaxValue) - { - // search all input ports on destination block - endPorts = GetSignalInputs(endBlock); - } - else - { - BlockPortsStruct ports = entitiesDB.QueryEntity(endBlock); - endPorts = new EGID[] {new EGID(ports.firstInputID + endPort, NamedExclusiveGroup.Group) }; - } - - for (int endIndex = 0; endIndex < endPorts.Length; endIndex++) - { - PortEntityStruct endPES = entitiesDB.QueryEntity(endPorts[endIndex]); - for (int startIndex = 0; startIndex < startPorts.Length; startIndex++) - { - PortEntityStruct startPES = entitiesDB.QueryEntity(startPorts[startIndex]); - foreach (var wireOpt in entitiesDB.QueryEntitiesOptional( - NamedExclusiveGroup.Group)) - { - var wire = wireOpt.Get(); - if ((wire.destinationPortUsage == endPES.usage && wire.destinationBlockEGID == endBlock) - && (wire.sourcePortUsage == startPES.usage && wire.sourceBlockEGID == startBlock)) - { - return wireOpt.EGID; - } - } - } - } - - return default; - } - - public OptionalRef GetChannelDataStruct(EGID portID) - { - var port = GetPort(portID); - var (channels, count) = entitiesDB.QueryEntities(NamedExclusiveGroup.Group); - return port.firstChannelIndexCachedInSim < count - ? new OptionalRef(channels, port.firstChannelIndexCachedInSim) - : default; - } - - public EGID[] GetElectricBlocks() - { - var res = new FasterList(); - foreach (var ((coll, ids, count), _) in entitiesDB.QueryEntities()) - { - for (int i = 0; i < count; i++) - { - ref BlockPortsStruct s = ref coll[i]; - //res.Add(s.ID); - TODO: Would need to search for the groups for each block - } - } - - return res.ToArray(); - } - - public EGID[] WiredToInput(EGID block, byte port) - { - return entitiesDB - .QueryEntitiesOptional(NamedExclusiveGroup.Group) - .ToArray(wire => wire.ID, - wire => wire.Component.destinationPortUsage == port && wire.Component.destinationBlockEGID == block); - } - - public EGID[] WiredToOutput(EGID block, byte port) - { - return entitiesDB - .QueryEntitiesOptional(NamedExclusiveGroup.Group) - .ToArray(wire => wire.ID, - wire => wire.Component.sourcePortUsage == port && wire.Component.sourceBlockEGID == block); - } - - private EntityCollection GetSignalStruct(uint signalID, out uint index, bool input = true) - { - ExclusiveGroup group = input - ? NamedExclusiveGroup.Group - : NamedExclusiveGroup.Group; - if (entitiesDB.Exists(signalID, group)) - { - index = entitiesDB.QueryEntity(signalID, group).firstChannelIndexCachedInSim; - var channelData = - entitiesDB.QueryEntities(NamedExclusiveGroup.Group); - return channelData; - } - - index = 0; - return default; //count: 0 - } - } -} diff --git a/TechbloxModdingAPI/Blocks/LogicGate.cs b/TechbloxModdingAPI/Blocks/LogicGate.cs deleted file mode 100644 index 05cc3bf..0000000 --- a/TechbloxModdingAPI/Blocks/LogicGate.cs +++ /dev/null @@ -1,26 +0,0 @@ -namespace TechbloxModdingAPI.Blocks -{ - using RobocraftX.Common; - using Svelto.ECS; - - - public class LogicGate : SignalingBlock - { - - /// - /// Constructs a(n) LogicGate object representing an existing block. - /// - public LogicGate(EGID egid) : - base(egid) - { - } - - /// - /// Constructs a(n) LogicGate object representing an existing block. - /// - public LogicGate(uint id) : - base(new EGID(id, CommonExclusiveGroups.LOGIC_BLOCK_GROUP)) - { - } - } -} diff --git a/TechbloxModdingAPI/Blocks/Motor.cs b/TechbloxModdingAPI/Blocks/Motor.cs deleted file mode 100644 index 233d5f6..0000000 --- a/TechbloxModdingAPI/Blocks/Motor.cs +++ /dev/null @@ -1,71 +0,0 @@ -namespace TechbloxModdingAPI.Blocks -{ - using RobocraftX.Common; - using Svelto.ECS; - - - public class Motor : SignalingBlock - { - - /// - /// Constructs a(n) Motor object representing an existing block. - /// - public Motor(EGID egid) : - base(egid) - { - } - - /// - /// Constructs a(n) Motor object representing an existing block. - /// - public Motor(uint id) : - base(new EGID(id, CommonExclusiveGroups.MOTOR_BLOCK_GROUP)) - { - } - - /// - /// Gets or sets the Motor's TopSpeed property. Tweakable stat. - /// - public float TopSpeed - { - get - { - return BlockEngine.GetBlockInfo(this).maxVelocity; - } - set - { - BlockEngine.GetBlockInfo(this).maxVelocity = value; - } - } - - /// - /// Gets or sets the Motor's Torque property. Tweakable stat. - /// - public float Torque - { - get - { - return BlockEngine.GetBlockInfo(this).maxForce; - } - set - { - BlockEngine.GetBlockInfo(this).maxForce = value; - } - } - - /// - /// Gets or sets the Motor's Reverse property. Tweakable stat. - /// - public bool Reverse - { - get - { - return BlockEngine.GetBlockInfo(this).reverse; - } - set - { - BlockEngine.GetBlockInfo(this).reverse = value; - } - } - } -} diff --git a/TechbloxModdingAPI/Blocks/ObjectID.cs b/TechbloxModdingAPI/Blocks/ObjectID.cs deleted file mode 100644 index 0496882..0000000 --- a/TechbloxModdingAPI/Blocks/ObjectID.cs +++ /dev/null @@ -1,50 +0,0 @@ -using System; -using Techblox.ObjectIDBlockServer; - -namespace TechbloxModdingAPI.Blocks -{ - using Svelto.ECS; - - - public class ObjectID : SignalingBlock - { - - /// - /// Constructs a(n) ObjectID object representing an existing block. - /// - public ObjectID(EGID egid) : - base(egid) - { - } - - /// - /// Constructs a(n) ObjectID object representing an existing block. - /// - public ObjectID(uint id) : - base(new EGID(id, ObjectIDBlockExclusiveGroups.OBJECT_ID_BLOCK_GROUP)) - { - } - - /// - /// Gets or sets the ObjectID's Identifier property. Tweakable stat. - /// - public char Identifier - { - get => (char) (BlockEngine.GetBlockInfo(this).objectIDToTrigger + 'A'); - set - { - if(value is < 'A' or > 'Z') - throw new ArgumentOutOfRangeException(nameof(value), "ObjectIdentifier must be set to a letter between A and Z."); - BlockEngine.GetBlockInfo(this).objectIDToTrigger = (byte) (value - 'A'); - Label = value + ""; //The label isn't updated automatically - } - } - - /// - /// Finds the identifier blocks with the given ID. - /// - /// The ID to look for - /// An array that may be empty - public static ObjectID[] GetByID(char id) => BlockEngine.GetObjectIDsFromID((byte) (id - 'A')); - } -} diff --git a/TechbloxModdingAPI/Blocks/Piston.cs b/TechbloxModdingAPI/Blocks/Piston.cs deleted file mode 100644 index c351d59..0000000 --- a/TechbloxModdingAPI/Blocks/Piston.cs +++ /dev/null @@ -1,71 +0,0 @@ -namespace TechbloxModdingAPI.Blocks -{ - using RobocraftX.Common; - using Svelto.ECS; - - - public class Piston : SignalingBlock - { - - /// - /// Constructs a(n) Piston object representing an existing block. - /// - public Piston(EGID egid) : - base(egid) - { - } - - /// - /// Constructs a(n) Piston object representing an existing block. - /// - public Piston(uint id) : - base(new EGID(id, CommonExclusiveGroups.PISTON_BLOCK_GROUP)) - { - } - - /// - /// Gets or sets the Piston's MaximumForce property. Tweakable stat. - /// - public float MaximumForce - { - get - { - return BlockEngine.GetBlockInfo(this).pistonVelocity; - } - set - { - BlockEngine.GetBlockInfo(this).pistonVelocity = value; - } - } - - /// - /// Gets or sets the Piston's MaxExtension property. Tweakable stat. - /// - public float MaxExtension - { - get - { - return BlockEngine.GetBlockInfo(this).maxDeviation; - } - set - { - BlockEngine.GetBlockInfo(this).maxDeviation = value; - } - } - - /// - /// Gets or sets the Piston's InputIsExtension property. Tweakable stat. - /// - public bool InputIsExtension - { - get - { - return BlockEngine.GetBlockInfo(this).hasProportionalInput; - } - set - { - BlockEngine.GetBlockInfo(this).hasProportionalInput = value; - } - } - } -} diff --git a/TechbloxModdingAPI/Blocks/Seat.cs b/TechbloxModdingAPI/Blocks/Seat.cs deleted file mode 100644 index e06077f..0000000 --- a/TechbloxModdingAPI/Blocks/Seat.cs +++ /dev/null @@ -1,56 +0,0 @@ -namespace TechbloxModdingAPI.Blocks -{ - using RobocraftX.Common; - using Svelto.ECS; - - - public class Seat : SignalingBlock - { - - /// - /// Constructs a(n) Seat object representing an existing block. - /// - public Seat(EGID egid) : - base(egid) - { - } - - /// - /// Constructs a(n) Seat object representing an existing block. - /// - public Seat(uint id) : - base(new EGID(id, RobocraftX.PilotSeat.SeatGroups.PILOTSEAT_BLOCK_BUILD_GROUP)) - { - } - - /// - /// Gets or sets the Seat's FollowCam property. Tweakable stat. - /// - public bool FollowCam - { - get - { - return BlockEngine.GetBlockInfo(this).followCam; - } - set - { - BlockEngine.GetBlockInfo(this).followCam = value; - } - } - - /// - /// Gets or sets the Seat's CharacterColliderHeight property. May not be saved. - /// - public float CharacterColliderHeight - { - get - { - return BlockEngine.GetBlockInfo(this).characterColliderHeight; - } - set - { - BlockEngine.GetBlockInfo(this).characterColliderHeight = value; - } - } - } -} diff --git a/TechbloxModdingAPI/Blocks/Servo.cs b/TechbloxModdingAPI/Blocks/Servo.cs deleted file mode 100644 index 8f626df..0000000 --- a/TechbloxModdingAPI/Blocks/Servo.cs +++ /dev/null @@ -1,146 +0,0 @@ -namespace TechbloxModdingAPI.Blocks -{ - using RobocraftX.Common; - using Svelto.ECS; - - - public class Servo : SignalingBlock - { - - /// - /// Constructs a(n) Servo object representing an existing block. - /// - public Servo(EGID egid) : - base(egid) - { - } - - /// - /// Constructs a(n) Servo object representing an existing block. - /// - public Servo(uint id) : - base(new EGID(id, CommonExclusiveGroups.SERVO_BLOCK_GROUP)) - { - } - - /// - /// Gets or sets the Servo's MaximumForce property. Tweakable stat. - /// - public float MaximumForce - { - get - { - return BlockEngine.GetBlockInfo(this).servoVelocity; - } - set - { - BlockEngine.GetBlockInfo(this).servoVelocity = value; - } - } - - /// - /// Gets or sets the Servo's MinimumAngle property. Tweakable stat. - /// - public float MinimumAngle - { - get - { - return BlockEngine.GetBlockInfo(this).minDeviation; - } - set - { - BlockEngine.GetBlockInfo(this).minDeviation = value; - } - } - - /// - /// Gets or sets the Servo's MaximumAngle property. Tweakable stat. - /// - public float MaximumAngle - { - get - { - return BlockEngine.GetBlockInfo(this).maxDeviation; - } - set - { - BlockEngine.GetBlockInfo(this).maxDeviation = value; - } - } - - /// - /// Gets or sets the Servo's Reverse property. Tweakable stat. - /// - public bool Reverse - { - get - { - return BlockEngine.GetBlockInfo(this).reverse; - } - set - { - BlockEngine.GetBlockInfo(this).reverse = value; - } - } - - /// - /// Gets or sets the Servo's InputIsAngle property. Tweakable stat. - /// - public bool InputIsAngle - { - get - { - return BlockEngine.GetBlockInfo(this).hasProportionalInput; - } - set - { - BlockEngine.GetBlockInfo(this).hasProportionalInput = value; - } - } - - /// - /// Gets or sets the Servo's DirectionVector property. May not be saved. - /// - public Unity.Mathematics.float3 DirectionVector - { - get - { - return BlockEngine.GetBlockInfo(this).directionVector; - } - set - { - BlockEngine.GetBlockInfo(this).directionVector = value; - } - } - - /// - /// Gets or sets the Servo's RotationAxis property. May not be saved. - /// - public Unity.Mathematics.float3 RotationAxis - { - get - { - return BlockEngine.GetBlockInfo(this).rotationAxis; - } - set - { - BlockEngine.GetBlockInfo(this).rotationAxis = value; - } - } - - /// - /// Gets or sets the Servo's ForceAxis property. May not be saved. - /// - public Unity.Mathematics.float3 ForceAxis - { - get - { - return BlockEngine.GetBlockInfo(this).forceAxis; - } - set - { - BlockEngine.GetBlockInfo(this).forceAxis = value; - } - } - } -} diff --git a/TechbloxModdingAPI/Blocks/SignalingBlock.cs b/TechbloxModdingAPI/Blocks/SignalingBlock.cs deleted file mode 100644 index bf679c4..0000000 --- a/TechbloxModdingAPI/Blocks/SignalingBlock.cs +++ /dev/null @@ -1,165 +0,0 @@ -using System; - -using Gamecraft.Wires; -using Svelto.ECS; -using Unity.Mathematics; - -using TechbloxModdingAPI; -using TechbloxModdingAPI.Utility; - -namespace TechbloxModdingAPI.Blocks -{ - /// - /// Common implementation for blocks that support wiring. - /// - public class SignalingBlock : Block - { - public SignalingBlock(EGID id) : base(id) - { - } - - public SignalingBlock(uint id) : base(id) - { - } - - /// - /// Generates the input port identifiers. - /// - /// The input identifiers. - protected EGID[] GetInputIds() - { - return SignalEngine.GetSignalInputs(Id); - } - - /// - /// Generates the output port identifiers. - /// - /// The output identifiers. - protected EGID[] GetOutputIds() - { - return SignalEngine.GetSignalOutputs(Id); - } - - /// - /// Gets the connected wire. - /// - /// The connected wire. - /// Port identifier. - /// Whether the port has a wire connected to it. - protected OptionalRef GetConnectedWire(PortEntityStruct port, out EGID egid) - { - return SignalEngine.MatchPortToWire(port, Id, out egid); - } - - /// - /// [EXPERIMENTAL] Gets the channel data. - /// - /// The channel data. - /// Port identifier. - protected OptionalRef GetChannelData(EGID portId) - { - return SignalEngine.GetChannelDataStruct(portId); - } - - /// - /// The input port count. - /// - public uint InputCount - { - get => BlockEngine.GetBlockInfo(this).inputCount; - } - - /// - /// The output port count. - /// - public uint OutputCount - { - get => BlockEngine.GetBlockInfo(this).outputCount; - } - - /// - /// Connect an output on this block to an input on another block. - /// - /// Output port number. - /// Input block. - /// Input port number. - /// The wire connection - /// The wire could not be created. - public Wire Connect(byte sourcePort, SignalingBlock destination, byte destinationPort) - { - if (sourcePort >= OutputCount) - { - throw new WiringException("Source port does not exist"); - } - - if (destinationPort >= destination.InputCount) - { - throw new WiringException("Destination port does not exist"); - } - return Wire.Connect(this, sourcePort, destination, destinationPort); - } - - /// - /// The port's name. - /// This is localized to the user's language, so this is not reliable for port identification. - /// - /// Port number. - /// Whether the port is an input (true) or an output (false). - /// The localized port name. - public string PortName(byte port, bool input) - { - PortEntityStruct pes = SignalEngine.GetPortByOffset(this, port, input); - return pes.portNameLocalised; - } - - /// - /// The input port's name. - /// - /// Input port number. - /// The port name, localized to the user's language. - public string InputPortName(byte port) => PortName(port, true); - - /// - /// The output port's name. - /// - /// Output port number. - /// The port name, localized to the user's language. - public string OutputPortName(byte port) => PortName(port, false); - - /// - /// All wires connected to the input port. - /// These wires will always be wired output -> input. - /// - /// Port number. - /// Wires connected to the input port. - public Wire[] ConnectedToInput(byte port) - { - if (port >= InputCount) throw new WiringException($"Port input {port} does not exist"); - EGID[] wireEgids = SignalEngine.WiredToInput(Id, port); - Wire[] wires = new Wire[wireEgids.Length]; - for (uint i = 0; i < wireEgids.Length; i++) - { - wires[i] = new Wire(wireEgids[i]); - } - return wires; - } - - /// - /// All wires connected to the output port. - /// These wires will always be wired output -> input. - /// - /// Port number. - /// Wires connected to the output port. - public Wire[] ConnectedToOutput(byte port) - { - if (port >= OutputCount) throw new WiringException($"Port output {port} does not exist"); - EGID[] wireEgids = SignalEngine.WiredToOutput(Id, port); - Wire[] wires = new Wire[wireEgids.Length]; - for (uint i = 0; i < wireEgids.Length; i++) - { - wires[i] = new Wire(wireEgids[i]); - } - return wires; - } - } -} diff --git a/TechbloxModdingAPI/Blocks/WheelRig.cs b/TechbloxModdingAPI/Blocks/WheelRig.cs deleted file mode 100644 index f978ea1..0000000 --- a/TechbloxModdingAPI/Blocks/WheelRig.cs +++ /dev/null @@ -1,137 +0,0 @@ -using TechbloxModdingAPI.Tests; - -namespace TechbloxModdingAPI.Blocks -{ - using RobocraftX.Common; - using Svelto.ECS; - - - public class WheelRig : SignalingBlock - { - - /// - /// Constructs a(n) WheelRig object representing an existing block. - /// - public WheelRig(EGID egid) : - base(egid) - { - } - - /// - /// Constructs a(n) WheelRig object representing an existing block. - /// - public WheelRig(uint id) : - base(new EGID(id, CommonExclusiveGroups.WHEELRIG_BLOCK_BUILD_GROUP)) - { - } - - /// - /// Gets or sets the WheelRig's BrakingStrength property. Tweakable stat. - /// - public float BrakingStrength - { - get - { - return BlockEngine.GetBlockInfo(this).brakingStrength; - } - set - { - BlockEngine.GetBlockInfo(this).brakingStrength = value; - } - } - - /// - /// Gets or sets the WheelRig's FlipDirection property. Tweakable stat. - /// - public bool FlipDirection - { - get - { - return BlockEngine.GetBlockInfo(this).flipDirection; - } - set - { - BlockEngine.GetBlockInfo(this).flipDirection = value; - } - } - - /// - /// Gets or sets the WheelRig's MaxVelocity property. May not be saved. - /// - public float MaxVelocity - { - get - { - return BlockEngine.GetBlockInfo(this).maxVelocity; - } - set - { - BlockEngine.GetBlockInfo(this).maxVelocity = value; - } - } - - /// - /// Gets or sets the WheelRig's SteerAngle property. Tweakable stat. - /// - [TestValue(0f)] // Can be 0 for no steer variant - public float SteerAngle - { - get - { - return BlockEngine.GetBlockInfo(this).steerAngle; - } - set - { - BlockEngine.GetBlockInfo(this).steerAngle = value; - } - } - - /// - /// Gets or sets the WheelRig's FlipSteering property. Tweakable stat. - /// - [TestValue(false)] - public bool FlipSteering - { - get - { - return BlockEngine.GetBlockInfo(this).flipSteering; - } - set - { - BlockEngine.GetBlockInfo(this).flipSteering = value; - } - } - - /// - /// Gets or sets the WheelRig's VelocityForMinAngle property. May not be saved. - /// - [TestValue(0f)] - public float VelocityForMinAngle - { - get - { - return BlockEngine.GetBlockInfo(this).velocityForMinAngle; - } - set - { - BlockEngine.GetBlockInfo(this).velocityForMinAngle = value; - } - } - - /// - /// Gets or sets the WheelRig's MinSteerAngleFactor property. May not be saved. - /// - [TestValue(0f)] - public float MinSteerAngleFactor - { - get - { - return BlockEngine.GetBlockInfo(this).minSteerAngleFactor; - } - set - { - BlockEngine.GetBlockInfo(this).minSteerAngleFactor = value; - } - } - } -} diff --git a/TechbloxModdingAPI/Blocks/Wire.cs b/TechbloxModdingAPI/Blocks/Wire.cs deleted file mode 100644 index 1a949dd..0000000 --- a/TechbloxModdingAPI/Blocks/Wire.cs +++ /dev/null @@ -1,313 +0,0 @@ -using System; - -using Gamecraft.Wires; -using Svelto.ECS; -using Svelto.ECS.Experimental; - -using TechbloxModdingAPI.Blocks.Engines; -using TechbloxModdingAPI.Utility; - -namespace TechbloxModdingAPI.Blocks -{ - public class Wire : EcsObjectBase - { - internal static SignalEngine signalEngine; - - protected EGID startPortEGID; - - protected EGID endPortEGID; - - protected EGID startBlockEGID; - - protected EGID endBlockEGID; - - protected EGID wireEGID; - - protected bool inputToOutput; - - protected byte startPort; - - protected byte endPort; - - public static Wire Connect(SignalingBlock start, byte startPort, SignalingBlock end, byte endPort) - { - var (wire, id) = signalEngine.CreateNewWire(start.Id, startPort, end.Id, endPort); - return new Wire(wire, start, end, id); - } - - /// - /// An existing wire connection ending at the specified input. - /// If multiple exist, this will return the first one found. - /// - /// Destination block. - /// Port number. - /// The wire, where the end of the wire is the block port specified, or null if does not exist. - public static Wire ConnectedToInputPort(SignalingBlock end, byte endPort) - { - var port = signalEngine.MatchBlockIOToPort(end, endPort, false); - if (!port) return null; - var wire = signalEngine.MatchPortToWire(port, end.Id, out var egid); - return wire - ? new Wire(wire.Get().sourceBlockEGID, end.Id, wire.Get().sourcePortUsage, endPort, egid, false) - : null; - } - - /// - /// An existing wire connection starting at the specified output. - /// If multiple exist, this will return the first one found. - /// - /// Source block entity ID. - /// Port number. - /// The wire, where the start of the wire is the block port specified, or null if does not exist. - public static Wire ConnectedToOutputPort(SignalingBlock start, byte startPort) - { - var port = signalEngine.MatchBlockIOToPort(start, startPort, true); - if (!port) return null; - var wire = signalEngine.MatchPortToWire(port, start.Id, out var egid); - return wire - ? new Wire(start.Id, wire.Get().destinationBlockEGID, startPort, wire.Get().destinationPortUsage, egid, false) - : null; - } - - /// - /// Construct a wire object froam n existing connection. - /// - /// Starting block ID. - /// Ending block ID. - /// Starting port number, or guess if omitted. - /// Ending port number, or guess if omitted. - /// Guessing failed or wire does not exist. - public Wire(Block start, Block end, byte startPort = Byte.MaxValue, byte endPort = Byte.MaxValue) : base(ecs => - { - var th = (Wire)ecs; - th.startBlockEGID = start.Id; - th.endBlockEGID = end.Id; - bool flipped = false; - // find block ports - EGID wire = signalEngine.MatchBlocksToWire(start.Id, end.Id, startPort, endPort); - if (wire == default) - { - // flip I/O around and try again - wire = signalEngine.MatchBlocksToWire(end.Id, start.Id, endPort, startPort); - flipped = true; - // NB: start and end are handled exactly as they're received as params. - // This makes wire traversal easier, but makes logic in this class a bit more complex - } - - if (wire != default) - { - th.Construct(start.Id, end.Id, startPort, endPort, wire, flipped); - } - else - { - throw new WireInvalidException("Wire not found"); - } - - return th.wireEGID; - }) - { - } - - /// - /// Construct a wire object from an existing wire connection. - /// - /// Starting block ID. - /// Ending block ID. - /// Starting port number. - /// Ending port number. - /// The wire ID. - /// Whether the wire direction goes input -> output (true) or output -> input (false, preferred). - public Wire(Block start, Block end, byte startPort, byte endPort, EGID wire, bool inputToOutput) - : this(start.Id, end.Id, startPort, endPort, wire, inputToOutput) - { - } - - private Wire(EGID startBlock, EGID endBlock, byte startPort, byte endPort, EGID wire, bool inputToOutput) : base(wire) - { - Construct(startBlock, endBlock, startPort, endPort, wire, inputToOutput); - } - - private void Construct(EGID startBlock, EGID endBlock, byte startPort, byte endPort, EGID wire, bool inputToOutput) - { - this.startBlockEGID = startBlock; - this.endBlockEGID = endBlock; - this.inputToOutput = inputToOutput; - this.wireEGID = wire; - endPortEGID = signalEngine.MatchBlockIOToPort(startBlock, startPort, inputToOutput).EGID; - if (endPortEGID == default) throw new WireInvalidException("Wire end port not found"); - startPortEGID = signalEngine.MatchBlockIOToPort(endBlock, endPort, !inputToOutput).EGID; - if (startPortEGID == default) throw new WireInvalidException("Wire start port not found"); - this.startPort = startPort; - this.endPort = endPort; - } - - /// - /// Construct a wire object from an existing wire connection. - /// - /// The wire ID. - public Wire(EGID wireEgid) : base(wireEgid) - { - WireEntityStruct wire = signalEngine.GetWire(wireEGID); - Construct(wire.sourceBlockEGID, wire.destinationBlockEGID, wire.sourcePortUsage, wire.destinationPortUsage, - wireEgid, false); - } - - private Wire(WireEntityStruct wire, SignalingBlock src, SignalingBlock dest, EGID wireEgid) - : this(src, dest, wire.sourcePortUsage, wire.destinationPortUsage, wireEgid, false) - { - } - - /// - /// The wire's signal value, as a float. - /// - public float Float - { - get - { - return signalEngine.GetChannelDataStruct(startPortEGID).Get().valueAsFloat; - } - - set - { - signalEngine.GetChannelDataStruct(startPortEGID).Get().valueAsFloat = value; - } - } - - /// - /// The wire's string signal. - /// - public string String - { - get - { - return signalEngine.GetChannelDataStruct(startPortEGID).Get().valueAsEcsString; - } - - set - { - signalEngine.GetChannelDataStruct(startPortEGID).Get().valueAsEcsString.Set(value); - } - } - - /// - /// The wire's raw string signal. - /// - public ECSString ECSString - { - get - { - return signalEngine.GetChannelDataStruct(startPortEGID).Get().valueAsEcsString; - } - - set - { - signalEngine.GetChannelDataStruct(startPortEGID).Get().valueAsEcsString = value; - } - } - - /// - /// The wire's signal id. - /// I'm 50% sure this is useless. - /// - public uint SignalId - { - get - { - return signalEngine.GetChannelDataStruct(startPortEGID).Get().valueAsID; - } - - set - { - signalEngine.GetChannelDataStruct(startPortEGID).Get().valueAsID = value; - } - } - - /// - /// The block at the beginning of the wire. - /// - public SignalingBlock Start - { - get => (SignalingBlock)Block.New(startBlockEGID); - } - - /// - /// The port number that the beginning of the wire connects to. - /// - public byte StartPort - { - get => startPort; - } - - /// - /// The display name of the start port. - /// - public string StartPortName - { - get => signalEngine.GetPort(startPortEGID).portNameLocalised; - } - - /// - /// The block at the end of the wire. - /// - public SignalingBlock End - { - get => (SignalingBlock)Block.New(endBlockEGID); - } - - /// - /// The port number that the end of the wire connects to. - /// - public byte EndPort - { - get => endPort; - } - - /// - /// The display name of the end port. - /// - public string EndPortName - { - get => signalEngine.GetPort(endPortEGID).portNameLocalised; - } - - /// - /// Create a copy of the wire object where the direction of the wire is guaranteed to be from a block output to a block input. - /// This is simply a different memory configuration and does not affect the in-game wire (which is always output -> input). - /// - /// A copy of the wire object. - public Wire OutputToInputCopy() - { - return GetInstance(wireEGID, egid => new Wire(egid)); - } - - /// - /// Convert the wire object to the direction the signal flows. - /// Signals on wires always flow from a block output port to a block input port. - /// This is simply a different memory configuration and does not affect the in-game wire (which is always output -> input). - /// - public void OutputToInputInPlace() - { - if (inputToOutput) - { - inputToOutput = false; - // swap inputs and outputs - (endBlockEGID, startBlockEGID) = (startBlockEGID, endBlockEGID); - var tempPort = endPortEGID; - endPortEGID = startPortEGID; - startPortEGID = tempPort; - (endPort, startPort) = (startPort, endPort); - } - } - - public override string ToString() - { - if (signalEngine.Exists(wireEGID)) - { - return $"{nameof(Id)}: {Id}, Start{nameof(Start.Id)}: {Start.Id}, End{nameof(End.Id)}: {End.Id}, ({Start.Type}::{StartPort} aka {(StartPort != byte.MaxValue ? Start.PortName(StartPort, inputToOutput) : "")}) -> ({End.Type}::{EndPort} aka {(EndPort != byte.MaxValue ? End.PortName(EndPort, !inputToOutput) : "")})"; - } - return $"{nameof(Id)}: {Id}, Start{nameof(Start.Id)}: {Start.Id}, End{nameof(End.Id)}: {End.Id}, ({Start.Type}::{StartPort} -> {End.Type}::{EndPort})"; - } - - internal static void Init() { } - } -} \ No newline at end of file diff --git a/TechbloxModdingAPI/Blueprint.cs b/TechbloxModdingAPI/Blueprint.cs deleted file mode 100644 index c49d598..0000000 --- a/TechbloxModdingAPI/Blueprint.cs +++ /dev/null @@ -1,102 +0,0 @@ -using System; -using Unity.Mathematics; -using UnityEngine; - -namespace TechbloxModdingAPI -{ - /// - /// Represents a blueprint in the inventory. When placed it becomes a block group. - /// - public class Blueprint : IDisposable - { - public uint Id { get; } - - internal Blueprint(uint id) - { - Id = id; - BlockGroup._engine.InitBlueprint(id); - Refresh(); - } - - /// - /// The center of the blueprint. Can only be set using the StoreBlocks() method. - /// - public float3 Position { get; private set; } - - /// - /// The rotation of the blueprint. Can only be set using the StoreBlocks() method. - /// - public float3 Rotation { get; private set; } - - /// - /// The amount of blocks in the blueprint. Gan only be set using the StoreBlocks() method. - /// - public uint BlockCount { get; private set; } - - /// - /// Creates a new, empty blueprint. It will be deleted on disposal unless the game holds a reference to it. - /// - /// A blueprint that doesn't have any blocks - public static Blueprint Create() - { - return new Blueprint(BlockGroup._engine.CreateBlueprint()); - } - - /// - /// Set the blocks that the blueprint contains. - /// Use the BlockGroup overload for automatically calculated position and rotation. - /// - /// The array of blocks to use - /// The anchor (center) position of the blueprint - /// The base rotation of the blueprint - public void StoreBlocks(Block[] blocks, float3 position, float3 rotation) - { - BlockGroup._engine.ReplaceBlueprint(Player.LocalPlayer.Id, Id, blocks, position, - quaternion.Euler(rotation)); - Refresh(); - } - - /// - /// Store the blocks from the given group in the blueprint with correct position and rotation for the blueprint. - /// - /// The block group to store - public void StoreBlocks(BlockGroup group) - { - BlockGroup._engine.ReplaceBlueprint(Player.LocalPlayer.Id, Id, group, group.Position, - Quaternion.Euler(group.Rotation)); - Refresh(); - } - - /// - /// Places the blocks the blueprint contains at the specified position and rotation. - /// - /// The position of the blueprint - /// The rotation of the blueprint - /// An array of the placed blocks - public Block[] PlaceBlocks(float3 position, float3 rotation) - { - return BlockGroup._engine.PlaceBlueprintBlocks(Id, Player.LocalPlayer.Id, position, rotation); - } - - /// - /// Updates the properties based on the blueprint data. Only necessary if the blueprint is changed from the game. - /// - public void Refresh() - { - BlockGroup._engine.GetBlueprintInfo(Id, out var pos, out var rot, out uint count); - Position = pos; - Rotation = ((Quaternion) rot).eulerAngles; - BlockCount = count; - } - - public void Dispose() - { - BlockGroup._engine.DisposeBlueprint(Id); - } - - public override string ToString() - { - return $"{nameof(Id)}: {Id}, {nameof(Position)}: {Position}, {nameof(Rotation)}: {Rotation}, {nameof(BlockCount)}: {BlockCount}"; - } - } -} \ No newline at end of file diff --git a/TechbloxModdingAPI/Cluster.cs b/TechbloxModdingAPI/Cluster.cs deleted file mode 100644 index 378d4db..0000000 --- a/TechbloxModdingAPI/Cluster.cs +++ /dev/null @@ -1,75 +0,0 @@ -using Svelto.ECS; -using Techblox.TimeRunning.Clusters; - -namespace TechbloxModdingAPI -{ - /// - /// Represnts a cluster of blocks in time running mode, meaning blocks that are connected either directly or via joints. - /// Only exists if a cluster destruction manager is present. Static blocks like grass and dirt aren't part of a cluster. - /// - public class Cluster : EcsObjectBase - { - public Cluster(EGID id) : base(id) - { - } - - public Cluster(uint id) : this(new EGID(id, ClustersExclusiveGroups.SIMULATION_CLUSTERS_GROUP)) - { - } - - public float InitialHealth //TODO - { - get => 0f; - set { } - } - - public float CurrentHealth - { - get => 0f; - set { } - } - - public float HealthMultiplier - { - get => 0f; - set { } - } - - /// - /// The mass of the cluster. - /// - public float Mass => Block.BlockEngine.GetBlockInfo(this).mass; - - /// - /// Returns the simulation-time rigid bodies for the chunks in this cluster. - /// - /// An array of sim-bodies - public SimBody[] GetSimBodies() - { - return Block.BlockEngine.GetClusterBodies(Id.entityID); - } - - public override string ToString() - { - return $"{nameof(Id)}: {Id}"; - } - - protected bool Equals(Cluster other) - { - return Id.Equals(other.Id); - } - - public override bool Equals(object obj) - { - if (ReferenceEquals(null, obj)) return false; - if (ReferenceEquals(this, obj)) return true; - if (obj.GetType() != this.GetType()) return false; - return Equals((Cluster) obj); - } - - public override int GetHashCode() - { - return Id.GetHashCode(); - } - } -} \ No newline at end of file diff --git a/TechbloxModdingAPI/Commands/CommandBuilder.cs b/TechbloxModdingAPI/Commands/CommandBuilder.cs deleted file mode 100644 index 1a34f45..0000000 --- a/TechbloxModdingAPI/Commands/CommandBuilder.cs +++ /dev/null @@ -1,276 +0,0 @@ -using System; - -using Svelto.ECS; -using TechbloxModdingAPI.Utility; - -namespace TechbloxModdingAPI.Commands -{ - /// - /// Custom Command builder. - /// - public class CommandBuilder - { - private string name; - - private string description; - - private short parameterCount; - - private ICustomCommandEngine commandEngine; - - private bool fromExisting = false; - - /// - /// Create a new command builder. - /// - public CommandBuilder() - { - name = ""; - description = null; - parameterCount = -1; - } - - /// - /// Create and return a command builder. - /// - /// The builder. - public static CommandBuilder Builder() - { - return new CommandBuilder(); - } - - /// - /// Create a new command builder. - /// - /// The command name. - /// The command description (shown in help). - public CommandBuilder(string name, string description = null) - { - this.name = name; - this.description = description; - parameterCount = -1; - } - - /// - /// Create and return a command builder. - /// If name and description are provided, this is equivalent to Builder().Name(name).Description(description) - /// - /// The command name. - /// The command description (shown in help). - /// The builder. - public static CommandBuilder Builder(string name, string description = null) - { - return new CommandBuilder(name, description); - } - - /// - /// Name the command. - /// - /// The builder. - /// The command name. - public CommandBuilder Name(string name) - { - this.name = name; - return this; - } - - /// - /// Describe the command. - /// - /// The builder. - /// The command description (shown in help). - public CommandBuilder Description(string description) - { - this.description = description; - return this; - } - - /// - /// Set the action the command performs. - /// - /// The builder. - /// The action to perform when the command is called. - public CommandBuilder Action(Action action) - { - parameterCount = 0; - commandEngine = new SimpleCustomCommandEngine(action, name, description); - return this; - } - - /// - /// Set the action the command performs. - /// - /// The builder. - /// The action to perform when the command is called. - /// The 1st parameter's type. - public CommandBuilder Action(Action action) - { - parameterCount = 1; - commandEngine = new SimpleCustomCommandEngine(action, name, description); - return this; - } - - /// - /// Set the action the command performs. - /// - /// The builder. - /// The action to perform when the command is called. - /// The 1st parameter's type. - /// The 2nd parameter's type. - public CommandBuilder Action(Action action) - { - parameterCount = 2; - commandEngine = new SimpleCustomCommandEngine(action, name, description); - return this; - } - - /// - /// Set the action the command performs. - /// - /// The builder. - /// The action to perform when the command is called. - /// The 1st parameter's type. - /// The 2nd parameter's type. - /// The 3rd parameter's type. - public CommandBuilder Action(Action action) - { - parameterCount = 3; - commandEngine = new SimpleCustomCommandEngine(action, name, description); - return this; - } - - /// - /// Build the command from an existing command. - /// - /// The command. Use Invoke() to execute it. - public SimpleCustomCommandEngine FromExisting() - { - if (string.IsNullOrWhiteSpace(name)) - { - throw new CommandParameterMissingException("Command name must be defined before FromExisting() is called"); - } - if (!ExistingCommands.Exists(name)) - { - throw new CommandNotFoundException("Command cannot be built from existing because it does not exist."); - } - fromExisting = true; - return new SimpleCustomCommandEngine( - () => { ExistingCommands.Call(name); }, - name, - description); - } - - /// - /// Build the command from an existing command. - /// - /// The command. Use Invoke() to execute it. - /// The 1st parameter's type. - public SimpleCustomCommandEngine FromExisting() - { - if (string.IsNullOrWhiteSpace(name)) - { - throw new CommandParameterMissingException("Command name must be defined before FromExisting() is called"); - } - if (!ExistingCommands.Exists(name)) - { - throw new CommandNotFoundException("Command cannot be built from existing because it does not exist."); - } - fromExisting = true; - return new SimpleCustomCommandEngine( - (A a) => { ExistingCommands.Call(name, a); }, - name, - description); - } - - /// - /// Build the command from an existing command. - /// - /// The command. Use Invoke() to execute it. - /// The 1st parameter's type. - /// The 2nd parameter's type. - public SimpleCustomCommandEngine FromExisting() - { - if (string.IsNullOrWhiteSpace(name)) - { - throw new CommandParameterMissingException("Command name must be defined before FromExisting() is called"); - } - if (!ExistingCommands.Exists(name)) - { - throw new CommandNotFoundException("Command cannot be built from existing because it does not exist."); - } - fromExisting = true; - return new SimpleCustomCommandEngine( - (A a, B b) => { ExistingCommands.Call(name, a, b); }, - name, - description); - } - - /// - /// Build the command from an existing command. - /// - /// The command. Use Invoke() to execute it. - /// The 1st parameter's type. - /// The 2nd parameter's type. - /// The 3rd parameter's type. - public SimpleCustomCommandEngine FromExisting() - { - if (string.IsNullOrWhiteSpace(name)) - { - throw new CommandParameterMissingException("Command name must be defined before FromExisting() is called"); - } - if (!ExistingCommands.Exists(name)) - { - throw new CommandNotFoundException("Command cannot be built from existing because it does not exist."); - } - fromExisting = true; - return new SimpleCustomCommandEngine( - (A a, B b, C c) => { ExistingCommands.Call(name, a, b, c); }, - name, - description); - } - - /// - /// Build the command. - /// - /// The built command. - /// Automatically register the command with CommandManager.AddCommand()? - public ICustomCommandEngine Build(bool register = true) - { - if (string.IsNullOrWhiteSpace(name)) - { - throw new CommandParameterMissingException("Command name must be defined before Build() is called"); - } - if (fromExisting) - { - throw new CommandAlreadyBuiltException("Command was already built by FromExisting()"); - } - if (commandEngine == null) - { - throw new CommandParameterMissingException("Command action must be defined before Build() is called"); - } - if (string.IsNullOrWhiteSpace(description)) - { - Logging.LogWarning($"Command {FullName()} was built without a description"); - } - if (register) - { - CommandManager.AddCommand(commandEngine); - Logging.MetaDebugLog($"Command {FullName()} was automatically registered"); - } - return commandEngine; - } - - /// - /// Get the full command name, in the form [name]::[description]::[# of parameters] - /// - /// The name. - public string FullName() - { - if (string.IsNullOrWhiteSpace(description)) - { - return name + "::" + parameterCount; - } - return name + "::" + description + "::" + parameterCount; - } - } -} diff --git a/TechbloxModdingAPI/Commands/CommandExceptions.cs b/TechbloxModdingAPI/Commands/CommandExceptions.cs deleted file mode 100644 index b860093..0000000 --- a/TechbloxModdingAPI/Commands/CommandExceptions.cs +++ /dev/null @@ -1,71 +0,0 @@ -using System; -namespace TechbloxModdingAPI.Commands -{ - public class CommandException : TechbloxModdingAPIException - { - public CommandException() : base() {} - - public CommandException(string msg) : base(msg) {} - - public CommandException(string msg, Exception innerException) : base(msg, innerException) {} - } - - public class CommandNotFoundException : CommandException - { - public CommandNotFoundException() - { - } - - public CommandNotFoundException(string msg) : base(msg) - { - } - } - - public class CommandAlreadyExistsException : CommandException - { - public CommandAlreadyExistsException() - { - } - - public CommandAlreadyExistsException(string msg) : base(msg) - { - } - } - - public class CommandRuntimeException : CommandException - { - public CommandRuntimeException() - { - } - - public CommandRuntimeException(string msg) : base(msg) - { - } - - public CommandRuntimeException(string msg, Exception innerException) : base(msg, innerException) - { - } - } - - public class CommandAlreadyBuiltException : CommandException - { - public CommandAlreadyBuiltException() - { - } - - public CommandAlreadyBuiltException(string msg) : base(msg) - { - } - } - - public class CommandParameterMissingException : CommandException - { - public CommandParameterMissingException() - { - } - - public CommandParameterMissingException(string msg) : base(msg) - { - } - } -} diff --git a/TechbloxModdingAPI/Commands/CustomCommands.cs b/TechbloxModdingAPI/Commands/CustomCommands.cs deleted file mode 100644 index 0cacff8..0000000 --- a/TechbloxModdingAPI/Commands/CustomCommands.cs +++ /dev/null @@ -1,57 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Collections.ObjectModel; -using System.Runtime.InteropServices; - -namespace TechbloxModdingAPI.Commands -{ - internal static class CustomCommands - { - public struct CommandData - { - public string Name; - public string Description; - public Delegate Action; - } - - private static Dictionary _commands = new Dictionary(); - public static void Register(string name, Delegate action, string desc) - { - _commands.Add(name, new CommandData - { - Name = name, - Description = desc, - Action = action - }); - } - - public static void Call(string name, params object[] args) - { - if (_commands.TryGetValue(name, out var command)) - { - var paramz = command.Action.Method.GetParameters(); - if (paramz.Length > args.Length) - throw new CommandParameterMissingException( - $"This command requires {paramz.Length} arguments, {args.Length} given"); - for (var index = 0; index < paramz.Length; index++) - { - args[index] = Convert.ChangeType(args[index], paramz[index].ParameterType); - } - - command.Action.DynamicInvoke(args); - } - else - throw new CommandNotFoundException($"Command {name} does not exist!"); - } - - public static void Unregister(string name) - { - _commands.Remove(name); - } - - public static bool Exists(string name) => _commands.ContainsKey(name); - - public static ReadOnlyDictionary GetAllCommandData() => - new ReadOnlyDictionary(_commands); - } -} \ No newline at end of file diff --git a/TechbloxModdingAPI/Commands/ExistingCommands.cs b/TechbloxModdingAPI/Commands/ExistingCommands.cs deleted file mode 100644 index dd61cc8..0000000 --- a/TechbloxModdingAPI/Commands/ExistingCommands.cs +++ /dev/null @@ -1,37 +0,0 @@ -using System.Linq; - -namespace TechbloxModdingAPI.Commands -{ - public static class ExistingCommands - { - public static void Call(string commandName) - { - CustomCommands.Call(commandName); - } - - public static void Call(string commandName, Arg0 arg0) - { - CustomCommands.Call(commandName, arg0); - } - - public static void Call(string commandName, Arg0 arg0, Arg1 arg1) - { - CustomCommands.Call(commandName, arg0, arg1); - } - - public static void Call(string commandName, Arg0 arg0, Arg1 arg1, Arg2 arg2) - { - CustomCommands.Call(commandName, arg0, arg1, arg2); - } - - public static bool Exists(string commandName) - { - return CustomCommands.Exists(commandName); - } - - public static (string Name, string Description)[] GetCommandNamesAndDescriptions() - { - return CustomCommands.GetAllCommandData().Values.Select(command => (command.Name, command.Description)).ToArray(); - } - } -} diff --git a/TechbloxModdingAPI/EcsObjectBase.cs b/TechbloxModdingAPI/EcsObjectBase.cs deleted file mode 100644 index 13a74f9..0000000 --- a/TechbloxModdingAPI/EcsObjectBase.cs +++ /dev/null @@ -1,128 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq.Expressions; -using Svelto.DataStructures; -using Svelto.ECS; -using Svelto.ECS.Internal; -using TechbloxModdingAPI.Utility; - -namespace TechbloxModdingAPI -{ - public abstract class EcsObjectBase - { - public EGID Id { get; } - - private static readonly Dictionary> _instances = - new Dictionary>(); - - private static readonly WeakDictionary _noInstance = - new WeakDictionary(); - - internal static WeakDictionary GetInstances(Type type) - { - return _instances.TryGetValue(type, out var dict) ? dict : null; - } - - /// - /// Returns a cached instance if there's an actively used instance of the object already. - /// Objects still get garbage collected and then they will be removed from the cache. - /// - /// The EGID of the entity - /// The constructor to construct the object - /// The object type - /// - internal static T GetInstance(EGID egid, Func constructor, Type type = null) where T : EcsObjectBase - { - var instances = GetInstances(type ?? typeof(T)); - if (instances == null || !instances.TryGetValue(egid, out var instance)) - return constructor(egid); // It will be added by the constructor - return (T)instance; - } - - protected EcsObjectBase(EGID id) - { - if (!_instances.TryGetValue(GetType(), out var dict)) - { - dict = new WeakDictionary(); - _instances.Add(GetType(), dict); - } - if (!dict.ContainsKey(id)) // Multiple instances may be created - dict.Add(id, this); - Id = id; - } - - protected EcsObjectBase(Func initializer) - { - if (!_instances.TryGetValue(GetType(), out var dict)) - { - dict = new WeakDictionary(); - _instances.Add(GetType(), dict); - } - - var id = initializer(this); - if (!dict.ContainsKey(id)) // Multiple instances may be created - dict.Add(id, this); - else - { - Logging.MetaDebugLog($"An object of this type and ID is already stored: {GetType()} - {id}"); - Logging.MetaDebugLog(this); - Logging.MetaDebugLog(dict[id]); - } - - Id = id; - } - - #region ECS initializer stuff - - protected internal EcsInitData InitData; - - /// - /// Holds information needed to construct a component initializer - /// - protected internal struct EcsInitData - { - private FasterDictionary group; - private EntityReference reference; - - public static implicit operator EcsInitData(EntityInitializer initializer) => new EcsInitData - { group = GetInitGroup(initializer), reference = initializer.reference }; - - public EntityInitializer Initializer(EGID id) => new EntityInitializer(id, group, reference); - public bool Valid => group != null; - } - - private delegate FasterDictionary GetInitGroupFunc( - EntityInitializer initializer); - - /// - /// Accesses the group field of the initializer - /// - private static GetInitGroupFunc GetInitGroup = CreateAccessor("_group"); - - //https://stackoverflow.com/questions/55878525/unit-testing-ref-structs-with-private-fields-via-reflection - private static TDelegate CreateAccessor(string memberName) where TDelegate : Delegate - { - var invokeMethod = typeof(TDelegate).GetMethod("Invoke"); - if (invokeMethod == null) - throw new InvalidOperationException($"{typeof(TDelegate)} signature could not be determined."); - - var delegateParameters = invokeMethod.GetParameters(); - if (delegateParameters.Length != 1) - throw new InvalidOperationException("Delegate must have a single parameter."); - - var paramType = delegateParameters[0].ParameterType; - - var objParam = Expression.Parameter(paramType, "obj"); - var memberExpr = Expression.PropertyOrField(objParam, memberName); - Expression returnExpr = memberExpr; - if (invokeMethod.ReturnType != memberExpr.Type) - returnExpr = Expression.ConvertChecked(memberExpr, invokeMethod.ReturnType); - - var lambda = - Expression.Lambda(returnExpr, $"Access{paramType.Name}_{memberName}", new[] { objParam }); - return lambda.Compile(); - } - - #endregion - } -} \ No newline at end of file diff --git a/TechbloxModdingAPI/Engines/EnginePatches.cs b/TechbloxModdingAPI/Engines/EnginePatches.cs deleted file mode 100644 index d6b61a9..0000000 --- a/TechbloxModdingAPI/Engines/EnginePatches.cs +++ /dev/null @@ -1,98 +0,0 @@ -using System.Reflection; -using HarmonyLib; -using RobocraftX; -using RobocraftX.CR.MainGame; -using RobocraftX.FrontEnd; -using RobocraftX.StateSync; -using Svelto.ECS; -using Svelto.ECS.Schedulers; -using TechbloxModdingAPI.Commands; -using TechbloxModdingAPI.Utility; - -namespace TechbloxModdingAPI.Engines -{ - [HarmonyPatch] - static class GameLoadedTimeStoppedEnginePatch - { - public static void Postfix(StateSyncRegistrationHelper stateSyncReg) - { - // register all game engines, including deterministic - GameEngineManager.RegisterEngines(stateSyncReg); - // register command engines - /*CommandLineCompositionRoot.Compose(contextHolder, stateSyncReg.enginesRoot, reloadGame, multiplayerParameters, - stateSyncReg); - uREPL C# compilation not supported anymore */ - CommandManager.RegisterEngines(stateSyncReg.enginesRoot); - } - - public static MethodBase TargetMethod() - { - return AccessTools.Method(typeof(MainGameCompositionRoot), "DeterministicTimeStoppedCompose").MakeGenericMethod(typeof(object)); - } - } - - [HarmonyPatch] - static class GameLoadedTimeRunningEnginePatch - { - public static void Postfix(StateSyncRegistrationHelper stateSyncReg) - { - GameEngineManager.RegisterEngines(stateSyncReg); - CommandManager.RegisterEngines(stateSyncReg.enginesRoot); - } - - public static MethodBase TargetMethod() - { - return AccessTools.Method(typeof(MainGameCompositionRoot), "DeterministicTimeRunningCompose").MakeGenericMethod(typeof(object)); - } - } - - [HarmonyPatch] - static class GameReloadedPatch - { - internal static bool IsReload; - public static void Prefix() => IsReload = true; - public static MethodBase TargetMethod() => AccessTools.Method(typeof(FullGameCompositionRoot), "ReloadGame"); - } - - [HarmonyPatch] - static class GameSwitchedToPatch - { - public static void Prefix() => GameReloadedPatch.IsReload = false; - public static MethodBase TargetMethod() => AccessTools.Method(typeof(FullGameCompositionRoot), "SwitchToGame"); - } - - [HarmonyPatch] - static class MenuSwitchedToPatch - { - public static void Prefix() => GameReloadedPatch.IsReload = false; - public static MethodBase TargetMethod() => AccessTools.Method(typeof(FullGameCompositionRoot), "SwitchToMenu"); - } - - [HarmonyPatch] - class MenuLoadedEnginePatch - { - public static void Postfix(EnginesRoot enginesRoot) - { - // register menu engines - MenuEngineManager.RegisterEngines(enginesRoot); - } - - public static MethodBase TargetMethod() - { - return AccessTools.Method(typeof(FrontEndCompositionRoot), "Compose").MakeGenericMethod(typeof(object)); - } - } - - [HarmonyPatch] - class FullGameCreatedEnginePatch - { - public static void Postfix(FullGameCompositionRoot __instance) - { - FullGameFields.Init(__instance); - } - - public static MethodBase TargetMethod() - { - return AccessTools.DeclaredConstructor(typeof(FullGameCompositionRoot)); - } - } -} diff --git a/TechbloxModdingAPI/Engines/IFactoryEngine.cs b/TechbloxModdingAPI/Engines/IFactoryEngine.cs deleted file mode 100644 index d03b4e3..0000000 --- a/TechbloxModdingAPI/Engines/IFactoryEngine.cs +++ /dev/null @@ -1,24 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -using Svelto.ECS; - -using TechbloxModdingAPI.Utility; - -namespace TechbloxModdingAPI.Engines -{ - /// - /// Engine interface to create a ModEventEntityStruct in entitiesDB when Emit() is called. - /// - public interface IFactoryEngine : IApiEngine - { - /// - /// The EntityFactory for the entitiesDB. - /// Use this to create a ModEventEntityStruct when Emit() is called. - /// - IEntityFactory Factory { set; } - } -} diff --git a/TechbloxModdingAPI/Engines/IFunEngine.cs b/TechbloxModdingAPI/Engines/IFunEngine.cs deleted file mode 100644 index d9ee7fe..0000000 --- a/TechbloxModdingAPI/Engines/IFunEngine.cs +++ /dev/null @@ -1,9 +0,0 @@ -using Svelto.ECS; - -namespace TechbloxModdingAPI.Engines -{ - public interface IFunEngine : IApiEngine - { - public IEntityFunctions Functions { set; } - } -} \ No newline at end of file diff --git a/TechbloxModdingAPI/Events/EventExceptions.cs b/TechbloxModdingAPI/Events/EventExceptions.cs deleted file mode 100644 index 0273ace..0000000 --- a/TechbloxModdingAPI/Events/EventExceptions.cs +++ /dev/null @@ -1,33 +0,0 @@ -using System; -namespace TechbloxModdingAPI.Events -{ - public class EventException : TechbloxModdingAPIException - { - public EventException() - { - } - - public EventException(string message) : base(message) - { - } - - public EventException(string message, Exception innerException) : base(message, innerException) - { - } - } - - public class EventRuntimeException : EventException - { - public EventRuntimeException() - { - } - - public EventRuntimeException(string message) : base(message) - { - } - - public EventRuntimeException(string message, Exception innerException) : base(message, innerException) - { - } - } -} diff --git a/TechbloxModdingAPI/Input/FakeInput.cs b/TechbloxModdingAPI/Input/FakeInput.cs deleted file mode 100644 index 0b0a7f9..0000000 --- a/TechbloxModdingAPI/Input/FakeInput.cs +++ /dev/null @@ -1,145 +0,0 @@ -using RobocraftX.Common.Input; - -using TechbloxModdingAPI.App; -using TechbloxModdingAPI.Utility; - -namespace TechbloxModdingAPI.Input -{ - public static class FakeInput - { - internal static readonly FakeInputEngine inputEngine = new FakeInputEngine(); - - /// - /// Customize the local input. - /// - /// The custom input. - public static void CustomInput(LocalCosmeticInputEntityComponent input) - { - inputEngine.SendCustomInput(input); - } - - /// - /// Customize the player input. - /// - /// The custom input. - /// The player. Omit this to use the local player. - public static void CustomPlayerInput(LocalPlayerInputEntityStruct input, uint playerID = uint.MaxValue) - { - if (playerID == uint.MaxValue) - { - playerID = inputEngine.GetLocalPlayerID(); - } - inputEngine.SendCustomPlayerInput(input, playerID); - } - - public static LocalCosmeticInputEntityComponent GetInput() - { - return inputEngine.GetInput(); - } - - public static LocalPlayerInputEntityStruct GetPlayerInput(uint playerID = uint.MaxValue) - { - if (playerID == uint.MaxValue) - { - playerID = inputEngine.GetLocalPlayerID(); - } - return inputEngine.GetPlayerInput(playerID); - } - - /// - /// Fake a GUI input. - /// Omit any parameter you do not want to affect. - /// Parameters that end with "?" don't do anything... yet. - /// - /// Select the hotbar slot by number. - /// Toggle the command line? - /// Open escape menu? - /// Page return? - /// Toggle debug display? - /// Toggle to hotbar colour mode? - /// Select the hotbar page by number? - /// Quicksave? - /// Paste? - public static void GuiInput(int hotbar = -1, bool escape = false, bool enter = false, bool debug = false, int hotbarPage = -1, bool quickSave = false, bool paste = false) - { - ref LocalCosmeticInputEntityComponent currentInput = ref inputEngine.GetInputRef(); - //Utility.Logging.CommandLog($"Current sim frame {currentInput.frame}"); - // set inputs - switch(hotbar) - { - case 0: currentInput.guiMask |= RobocraftX.Common.Input.GuiInput.Hotbar_0; break; - case 1: currentInput.guiMask |= RobocraftX.Common.Input.GuiInput.Hotbar_1; break; - case 2: currentInput.guiMask |= RobocraftX.Common.Input.GuiInput.Hotbar_2; break; - case 3: currentInput.guiMask |= RobocraftX.Common.Input.GuiInput.Hotbar_3; break; - case 4: currentInput.guiMask |= RobocraftX.Common.Input.GuiInput.Hotbar_4; break; - case 5: currentInput.guiMask |= RobocraftX.Common.Input.GuiInput.Hotbar_5; break; - case 6: currentInput.guiMask |= RobocraftX.Common.Input.GuiInput.Hotbar_6; break; - case 7: currentInput.guiMask |= RobocraftX.Common.Input.GuiInput.Hotbar_7; break; - case 8: currentInput.guiMask |= RobocraftX.Common.Input.GuiInput.Hotbar_8; break; - case 9: currentInput.guiMask |= RobocraftX.Common.Input.GuiInput.Hotbar_9; break; - default: break; - } - if (escape) currentInput.guiMask |= RobocraftX.Common.Input.GuiInput.Escape; - if (enter) currentInput.guiMask |= RobocraftX.Common.Input.GuiInput.Return; - if (debug) currentInput.guiMask |= RobocraftX.Common.Input.GuiInput.ToggleDebugDisplay; - switch (hotbarPage) - { - case 1: currentInput.guiMask |= RobocraftX.Common.Input.GuiInput.HotbarPage1; break; - case 2: currentInput.guiMask |= RobocraftX.Common.Input.GuiInput.HotbarPage2; break; - case 3: currentInput.guiMask |= RobocraftX.Common.Input.GuiInput.HotbarPage3; break; - case 4: currentInput.guiMask |= RobocraftX.Common.Input.GuiInput.HotbarPage4; break; - case 5: currentInput.guiMask |= RobocraftX.Common.Input.GuiInput.HotbarPage5; break; - case 6: currentInput.guiMask |= RobocraftX.Common.Input.GuiInput.HotbarPage6; break; - case 7: currentInput.guiMask |= RobocraftX.Common.Input.GuiInput.HotbarPage7; break; - case 8: currentInput.guiMask |= RobocraftX.Common.Input.GuiInput.HotbarPage8; break; - case 9: currentInput.guiMask |= RobocraftX.Common.Input.GuiInput.HotbarPage9; break; - case 10: currentInput.guiMask |= RobocraftX.Common.Input.GuiInput.HotbarPage10; break; - } - //RewiredConsts.Action - if (quickSave) currentInput.guiMask |= RobocraftX.Common.Input.GuiInput.QuickSave; - if (paste) currentInput.guiMask |= RobocraftX.Common.Input.GuiInput.SelectLastCopiedBlueprint; - } - - public static void ActionInput(uint playerID = uint.MaxValue, bool toggleMode = false, bool forward = false, bool backward = false, bool up = false, bool down = false, bool left = false, bool right = false, bool sprint = false, bool toggleFly = false, bool alt = false, bool primary = false, bool secondary = false, bool tertiary = false, bool primaryHeld = false, bool secondaryHeld = false, bool toggleUnitGrid = false, bool ctrl = false, bool toggleColourMode = false, bool scaleBlockUp = false, bool scaleBlockDown = false, bool rotateBlockClockwise = false, bool rotateBlockCounterclockwise = false, bool cutSelection = false, bool copySelection = false, bool deleteSelection = false) - { // TODO: We can only alter our own inputs clientside - ref var currentInput = ref inputEngine._localInputCache; - - //Utility.Logging.CommandLog($"Current sim frame {currentInput.frame}"); - // set inputs - if (toggleMode) currentInput |= RobocraftX.Common.Input.ActionInput.ToggleTimeRunningModePlay; //TODO: Test, play - if (forward) currentInput |= RobocraftX.Common.Input.ActionInput.Forward; - if (backward) currentInput |= RobocraftX.Common.Input.ActionInput.Backward; - if (up) currentInput |= RobocraftX.Common.Input.ActionInput.Up; - if (down) currentInput |= RobocraftX.Common.Input.ActionInput.Down; - if (left) currentInput |= RobocraftX.Common.Input.ActionInput.Left; - if (right) currentInput |= RobocraftX.Common.Input.ActionInput.Right; - if (sprint) currentInput |= RobocraftX.Common.Input.ActionInput.Sprint; - //if (toggleFly) currentInput |= RobocraftX.Common.Input.ActionInput.SwitchFlyMode; - //if (alt) currentInput |= RobocraftX.Common.Input.ActionInput.AltAction; - if (primary) currentInput |= RobocraftX.Common.Input.ActionInput.PrimaryActionClick; - if (secondary) currentInput |= RobocraftX.Common.Input.ActionInput.SecondaryActionClick; - if (tertiary) currentInput |= RobocraftX.Common.Input.ActionInput.TertiaryAction; - if (primaryHeld) currentInput |= RobocraftX.Common.Input.ActionInput.PrimaryActionHeld; - if (secondaryHeld) currentInput |= RobocraftX.Common.Input.ActionInput.SecondaryActionHeld; - //if (toggleUnitGrid) currentInput |= RobocraftX.Common.Input.ActionInput.ToggleUnitGrid; - if (ctrl) currentInput |= RobocraftX.Common.Input.ActionInput.CtrlAction; - if (toggleColourMode) currentInput |= RobocraftX.Common.Input.ActionInput.ToggleColourMode; - if (scaleBlockUp) currentInput |= RobocraftX.Common.Input.ActionInput.ScaleBlockUp; - if (scaleBlockDown) currentInput |= RobocraftX.Common.Input.ActionInput.ScaleBlockDown; - if (rotateBlockClockwise) currentInput |= RobocraftX.Common.Input.ActionInput.RotateBlockClockwise; - if (rotateBlockCounterclockwise) currentInput |= RobocraftX.Common.Input.ActionInput.RotateBlockAnticlockwise; - if (cutSelection) currentInput |= RobocraftX.Common.Input.ActionInput.CutSelection; - if (copySelection) currentInput |= RobocraftX.Common.Input.ActionInput.CopySelection; - if (deleteSelection) currentInput |= RobocraftX.Common.Input.ActionInput.DeleteSelection; - - if(Game.CurrentGame().IsTimeStopped) - inputEngine.HandleCustomInput(); // Only gets called when online, so calling it here as well - } - - public static void Init() - { - GameEngineManager.AddGameEngine(inputEngine); - MenuEngineManager.AddMenuEngine(inputEngine); - } - } -} diff --git a/TechbloxModdingAPI/Input/FakeInputEngine.cs b/TechbloxModdingAPI/Input/FakeInputEngine.cs deleted file mode 100644 index cc6a6c2..0000000 --- a/TechbloxModdingAPI/Input/FakeInputEngine.cs +++ /dev/null @@ -1,104 +0,0 @@ -using System; - -using RobocraftX.Common; -using RobocraftX.Common.Input; -using RobocraftX.Players; -using Svelto.ECS; - -using TechbloxModdingAPI.Utility; -using TechbloxModdingAPI.Engines; - -namespace TechbloxModdingAPI.Input -{ - public class FakeInputEngine : IApiEngine - { - public string Name { get; } = "TechbloxModdingAPIFakeInputEngine"; - - public EntitiesDB entitiesDB { set; private get; } - - public bool isRemovable => false; - - public bool IsReady = false; - - internal ActionInput _localInputCache; - - public void Dispose() - { - IsReady = false; - } - - public void Ready() - { - IsReady = true; - } - - public bool SendCustomInput(LocalCosmeticInputEntityComponent input) - { - EGID egid = CommonExclusiveGroups.GameStateEGID; - if (entitiesDB.Exists(egid)) - { - ref LocalCosmeticInputEntityComponent ies = ref entitiesDB.QueryEntity(egid); - ies = input; - return true; - } - else return false; - } - - public bool SendCustomPlayerInput(LocalPlayerInputEntityStruct input, uint playerID, bool remote = false) - { - EGID egid = new EGID(playerID, remote ? InputExclusiveGroups.RemotePlayers : InputExclusiveGroups.LocalPlayers); - if (entitiesDB.Exists(egid)) - { - ref LocalPlayerInputEntityStruct ies = ref entitiesDB.QueryEntity(egid); - ies = input; - return true; - } - else return false; - } - - public LocalCosmeticInputEntityComponent GetInput() - { - EGID egid = CommonExclusiveGroups.GameStateEGID; - if (entitiesDB.Exists(egid)) - { - return entitiesDB.QueryEntity(egid); - } - else return default(LocalCosmeticInputEntityComponent); - } - - public LocalPlayerInputEntityStruct GetPlayerInput(uint playerID, bool remote = false) - { - EGID egid = new EGID(playerID, remote ? InputExclusiveGroups.RemotePlayers : InputExclusiveGroups.LocalPlayers); - if (entitiesDB.Exists(egid)) - { - return entitiesDB.QueryEntity(egid); - } - else return default; - } - - public ref LocalCosmeticInputEntityComponent GetInputRef() - { - EGID egid = CommonExclusiveGroups.GameStateEGID; - return ref entitiesDB.QueryEntity(egid); - } - - public ref LocalPlayerInputEntityStruct GetPlayerInputRef(uint playerID, bool remote = false) - { - EGID egid = new EGID(playerID, remote ? InputExclusiveGroups.RemotePlayers : InputExclusiveGroups.LocalPlayers); - return ref entitiesDB.QueryEntity(egid); - } - - internal void HandleCustomInput() - { - if (!LocalPlayerIDUtility.DoesLocalPlayerExist(entitiesDB)) - return; - GetPlayerInputRef(GetLocalPlayerID()).actionMask |= _localInputCache; - _localInputCache = default; - } - - public uint GetLocalPlayerID() - { - return LocalPlayerIDUtility.GetLocalPlayerID(entitiesDB); - } - } -} diff --git a/TechbloxModdingAPI/Input/FakeInputPatch.cs b/TechbloxModdingAPI/Input/FakeInputPatch.cs deleted file mode 100644 index 7168e05..0000000 --- a/TechbloxModdingAPI/Input/FakeInputPatch.cs +++ /dev/null @@ -1,19 +0,0 @@ -using System.Reflection; -using HarmonyLib; - -namespace TechbloxModdingAPI.Input -{ - [HarmonyPatch] - public static class FakeInputPatch - { - public static void Prefix() - { - FakeInput.inputEngine.HandleCustomInput(); // This gets called right before the input is sent to the server - } - - public static MethodBase TargetMethod() - { - return AccessTools.Method("RobocraftX.Multiplayer.Input.DeterministicInputRecorderEngine:RecordDeterministicInput"); - } - } -} \ No newline at end of file diff --git a/TechbloxModdingAPI/Interface/IMGUI/Button.cs b/TechbloxModdingAPI/Interface/IMGUI/Button.cs deleted file mode 100644 index 6cf5fc8..0000000 --- a/TechbloxModdingAPI/Interface/IMGUI/Button.cs +++ /dev/null @@ -1,68 +0,0 @@ -using System; -using Unity.Mathematics; -using UnityEngine; - -namespace TechbloxModdingAPI.Interface.IMGUI -{ - /// - /// A clickable button. - /// This wraps Unity's IMGUI Button. - /// - public class Button : UIElement - { - private bool automaticLayout = false; - - private string text; - - /// - /// The rectangular area that the button can use. - /// - public Rect Box { get; set; } = Rect.zero; - - /// - /// An event that fires when the button is clicked. - /// - public event EventHandler OnClick; - - public override 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); - } - } - } - - /// - /// Initialize a new button with automatic layout. - /// - /// The text to display on the button. - /// The button's name. - public Button(string text, string name = null) : base(text, name) - { - automaticLayout = true; - this.text = text; - } - - /// - /// Initialize a new button. - /// - /// The text to display on the button. - /// Rectangular area for the button to use. - /// The button's name. - public Button(string text, Rect box, string name = null) : this(text, name) - { - automaticLayout = false; - this.Box = box; - } - } -} \ No newline at end of file diff --git a/TechbloxModdingAPI/Interface/IMGUI/Constants.cs b/TechbloxModdingAPI/Interface/IMGUI/Constants.cs deleted file mode 100644 index ecb292a..0000000 --- a/TechbloxModdingAPI/Interface/IMGUI/Constants.cs +++ /dev/null @@ -1,146 +0,0 @@ -using System; -using System.Collections; -using System.Collections.Generic; -using System.Globalization; -using System.Reflection; -using TechbloxModdingAPI.Utility; -using HarmonyLib; -using Svelto.Tasks; -using Svelto.Tasks.Lean; -using UnityEngine; -using UnityEngine.AddressableAssets; -using UnityEngine.ResourceManagement.AsyncOperations; - -namespace TechbloxModdingAPI.Interface.IMGUI -{ - /// - /// Convenient IMGUI values. - /// - public static class Constants - { - private static byte _defaultCompletion = 0; - private static GUISkin _default = null; - - /// - /// Best-effort imitation of Techblox's UI style. - /// - public static GUISkin Default - { - get - { - if (_defaultCompletion != 0) _default = BuildDefaultGUISkin(); - return _default; - } - } - - private static Font _font = 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 (_font == null) return GUI.skin; - // build GUISkin - GUISkin gui = ScriptableObject.CreateInstance(); - gui.font = _font; - gui.settings.selectionColor = Color.white; - gui.settings.tripleClickSelectsLine = true; - Color textColour = new Color(0.706f, 0.706f, 0.706f); - // 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 = 16; - 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 = _grayBackground; - style.normal.textColor = textColour; - // hover state - style.hover.background = _grayBackground; - style.hover.textColor = textColour; - // focused - style.focused.background = _grayBackground; - style.focused.textColor = textColour; - // clicking state - style.active.background = _whiteBackground; - style.active.textColor = textColour; - - p.SetValue(gui, style); // probably unnecessary - } - } - // set element-specific styles - // label - gui.label.fontSize = 20; - 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 fontHandle = Addressables.LoadAssetAsync("Assets/Plugins/TextMesh Pro/Fonts/LiberationSans.ttf"); - fontHandle.Completed += handle => - { - _font = handle.Result; - _defaultCompletion++; - };*/ - _font = Resources.Load("Assets/Plugins/TextMesh Pro/Fonts/LiberationSans.ttf"); - // TODO generate larger textures with borders on them so it actually looks more like Techblox - _blueBackground = new Texture2D(1, 1); - _blueBackground.SetPixel(0, 0, new Color(0.004f, 0.522f, 0.847f) /* Gamecraft Blue, unused */); - _blueBackground.Apply(); - _grayBackground = new Texture2D(1, 1); - _grayBackground.SetPixel(0, 0, new Color(0.11f, 0.11f, 0.11f, 1f) /* Very dark gray */); - _grayBackground.Apply(); - _whiteBackground = new Texture2D(1, 1); - _whiteBackground.SetPixel(0, 0, new Color(0.961f, 0.961f, 0.961f) /* Very light gray */); - _whiteBackground.Apply(); - _textInputBackground = new Texture2D(1, 1); - _textInputBackground.SetPixel(0, 0, new Color(0.961f, 0.961f, 0.961f) /* Very light gray */); - _textInputBackground.Apply(); - _areaBackground = new Texture2D(1, 1); - _areaBackground.SetPixel(0, 0, new Color(0.051f, 0.051f, 0.051f, 1f) /* Very very dark gray */); - _areaBackground.Apply(); - _defaultCompletion++; - } - } -} \ No newline at end of file diff --git a/TechbloxModdingAPI/Interface/IMGUI/Group.cs b/TechbloxModdingAPI/Interface/IMGUI/Group.cs deleted file mode 100644 index 88a36c2..0000000 --- a/TechbloxModdingAPI/Interface/IMGUI/Group.cs +++ /dev/null @@ -1,138 +0,0 @@ -using System; -using TechbloxModdingAPI.Utility; -using Svelto.DataStructures; -using UnityEngine; - -namespace TechbloxModdingAPI.Interface.IMGUI -{ - /// - /// A group of elements. - /// This wraps Unity's GUILayout Area and GUI Group system. - /// - public class Group : UIElement - { - private bool automaticLayout; - - private FasterList elements = new FasterList(); - - /// - /// The rectangular area in the window that the UI group can use - /// - public Rect Box { get; set; } - - public override void OnGUI() - { - /*if (Constants.Default == null) return; - if (Constants.Default.box == null) return;*/ - GUIStyle guiStyle = Constants.Default.box; - UIElement[] elems = elements.ToArrayFast(out int 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(); - } - } - - /// - /// The amount of elements in the group. - /// - public int Length - { - get => elements.count; - } - - /// - /// Initializes a new instance of the class. - /// - /// The rectangular area to use in the window. - /// Name of the group. - /// Whether to use automatic UI layout. - public Group(Rect box, string name = null, bool automaticLayout = false) : base(box.ToString().Replace(" ", ""), name) - { - Box = box; - this.automaticLayout = automaticLayout; - } - - /// - /// Add an element to the group. - /// - /// The element to add. - /// Index of the new element. - public int AddElement(UIElement element) - { - IMGUIManager.RemoveElement(element); // groups manage internal elements themselves - elements.Add(element); - return elements.count - 1; - } - - /// - /// Remove an element from the group. - /// - /// The element to remove. - /// Whether removal was successful. - public bool RemoveElement(UIElement element) - { - int index = IndexOf(element); - return RemoveAt(index); - } - - /// - /// Remove the element in a specific location. - /// - /// Index of the element. - /// Whether removal was successful. - public bool RemoveAt(int index) - { - if (index < 0 || index >= elements.count) return false; - IMGUIManager.AddElement(elements[index]); // re-add to global manager - elements.RemoveAt((uint) index); - return true; - } - - /// - /// Get the index of an element. - /// - /// The element to search for. - /// The element's index, or -1 if not found. - public int IndexOf(UIElement element) - { - UIElement[] elems = elements.ToArrayFast(out int count); - for (int i = 0; i < count; i++) - { - if (elems[i].Name == element.Name) - { - return i; - } - } - return -1; - } - } -} \ No newline at end of file diff --git a/TechbloxModdingAPI/Interface/IMGUI/IMGUIManager.cs b/TechbloxModdingAPI/Interface/IMGUI/IMGUIManager.cs deleted file mode 100644 index d68f14b..0000000 --- a/TechbloxModdingAPI/Interface/IMGUI/IMGUIManager.cs +++ /dev/null @@ -1,120 +0,0 @@ -using System.Collections.Generic; -using Svelto.Tasks; -using Svelto.Tasks.ExtraLean; -using TechbloxModdingAPI.Tasks; -using TechbloxModdingAPI.Utility; -using UnityEngine; - -namespace TechbloxModdingAPI.Interface.IMGUI -{ - /// - /// Keeps track of UIElement instances. - /// This also handles displaying and processing them during the MonoBehaviour.OnGUI phase of screen updates. - /// Most of this functionality is handled implicitly by the included UIElement implementations, - /// but this is left as a public API so it can be expanded. - /// - public static class IMGUIManager - { - internal static OnGuiRunner ImguiScheduler = new("TechbloxModdingAPI_IMGUIScheduler"); - - private static readonly WeakDictionary _activeElements = new(); - - /// - /// Add an UIElement instance to be managed by IMGUIManager. - /// - /// The UIElement instance. - public static void AddElement(UIElement e) - { - if (!ExistsElement(e)) - { - _activeElements[e.Name] = e; - } - } - - /// - /// Determine whether the UIElement instance is already tracked by IMGUIManager. - /// - /// The UIElement's unique name. - /// Whether the UIElement instance is already tracked by IMGUIManager (true) or not (false). - public static bool ExistsElement(string name) - { - return _activeElements.ContainsKey(name); - } - - /// - /// Determine whether the UIElement instance is already tracked by IMGUIManager. - /// - /// The UIElement instance. - /// Whether the UIElement instance is already tracked by IMGUIManager (true) or not (false). - public static bool ExistsElement(UIElement element) - { - return ExistsElement(element.Name); - } - - /// - /// Remove an UIElement instance from IMGUIManager. - /// The UIElement will become invisible and stop generating events. - /// - /// The UIElement's unique name. - /// Whether the UIElement instance existed in IMGUIManager (true) or not (false). - public static bool RemoveElement(string name) - { - if (ExistsElement(name)) - { - return _activeElements.Remove(name); - } - - return false; - } - - /// - /// Remove an UIElement instance from IMGUIManager. - /// The UIElement will become invisible and stop generating events. - /// - /// The UIElement instance. - /// Whether the UIElement instance existed in IMGUIManager (true) or not (false). - public static bool RemoveElement(UIElement element) - { - return RemoveElement(element.Name); - } - - private static void OnGUI() - { - foreach (var element in _activeElements.Values) - { - if (element.Enabled) - element.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 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); - } - } -} \ No newline at end of file diff --git a/TechbloxModdingAPI/Interface/IMGUI/Image.cs b/TechbloxModdingAPI/Interface/IMGUI/Image.cs deleted file mode 100644 index 88e82c1..0000000 --- a/TechbloxModdingAPI/Interface/IMGUI/Image.cs +++ /dev/null @@ -1,59 +0,0 @@ -using UnityEngine; - -namespace TechbloxModdingAPI.Interface.IMGUI -{ - /// - /// An image. - /// This wraps Unity's IMGUI Label. - /// - public class Image : UIElement - { - private bool automaticLayout = false; - - /// - /// The image texture to display - /// - public Texture Texture { get; set; } - - /// - /// The rectangular area in the window that the image can use - /// - public Rect Box { get; set; } = Rect.zero; - - public override void OnGUI() - { - //if (Texture == null) return; - if (automaticLayout) - { - GUILayout.Label(Texture, Constants.Default.label); - } - else - { - GUI.Label(Box, Texture, Constants.Default.label); - } - } - - /// - /// Initializes a new instance of the class with automatic layout. - /// - /// Image to display. - /// The element's name. - public Image(Texture texture = null, string name = null) : base(texture == null ? "" : $"{texture.name}({texture.width}x{texture.height})", name) - { - automaticLayout = true; - Texture = texture; - } - - /// - /// Initializes a new instance of the class. - /// - /// Rectangular area for the image. - /// Image to display. - /// The element's name. - public Image(Rect box, Texture texture = null, string name = null) : this(texture, name) - { - this.Box = box; - automaticLayout = false; - } - } -} \ No newline at end of file diff --git a/TechbloxModdingAPI/Interface/IMGUI/Label.cs b/TechbloxModdingAPI/Interface/IMGUI/Label.cs deleted file mode 100644 index e394f35..0000000 --- a/TechbloxModdingAPI/Interface/IMGUI/Label.cs +++ /dev/null @@ -1,58 +0,0 @@ -using UnityEngine; - -namespace TechbloxModdingAPI.Interface.IMGUI -{ - /// - /// A simple text label. - /// This wraps Unity IMGUI's Label. - /// - public class Label : UIElement - { - private bool automaticLayout = false; - - /// - /// String to display on the label. - /// - public string Text { get; set; } - - /// - /// The rectangular area that the label can use. - /// - public Rect Box { get; set; } = Rect.zero; - - public override void OnGUI() - { - if (automaticLayout) - { - GUILayout.Label(Text, Constants.Default.label); - } - else - { - GUI.Label(Box, Text, Constants.Default.label); - } - } - - /// - /// Initializes a new instance of the class with automatic layout. - /// - /// Initial string to display on the label. - /// The element's name. - public Label(string initialText = null, string name = null) : base(initialText, name) - { - automaticLayout = true; - Text = initialText; - } - - /// - /// Initializes a new instance of the . - /// - /// Rectangular area for the label. - /// Initial string to display on the label. - /// The element's name. - public Label(Rect box, string initialText = null, string name = null) : this(initialText, name) - { - this.Box = box; - automaticLayout = false; - } - } -} \ No newline at end of file diff --git a/TechbloxModdingAPI/Interface/IMGUI/Text.cs b/TechbloxModdingAPI/Interface/IMGUI/Text.cs deleted file mode 100644 index 8f6033d..0000000 --- a/TechbloxModdingAPI/Interface/IMGUI/Text.cs +++ /dev/null @@ -1,90 +0,0 @@ -using System; -using UnityEngine; - -namespace TechbloxModdingAPI.Interface.IMGUI -{ - /// - /// A text input field. - /// This wraps Unity's IMGUI TextField and TextArea. - /// - public class Text : UIElement - { - private bool automaticLayout; - - /// - /// Whether the text input field is multiline (true -> TextArea) or not (false -> TextField). - /// - public bool Multiline { get; set; } - - private string text; - - /// - /// The rectangular area that the text field can use. - /// - public Rect Box { get; set; } = Rect.zero; - - /// - /// An event that fires whenever the text input is edited. - /// - public event EventHandler OnEdit; - - public override 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; - } - } - - /// - /// Initialize the text input field with automatic layout. - /// - /// Initial text in the input field. - /// The text field's name. - /// Allow multiple lines? - public Text(string initialText = null, string name = null, bool multiline = false) : base(initialText, name) - { - this.Multiline = multiline; - automaticLayout = true; - text = initialText ?? ""; - } - - /// - /// Initialize the text input field. - /// - /// Rectangular area for the text field. - /// Initial text in the input field. - /// The text field's name. - /// Allow multiple lines? - public Text(Rect box, string initialText = null, string name = null, bool multiline = false) : this(initialText, name, multiline) - { - this.Box = box; - automaticLayout = false; - } - } -} \ No newline at end of file diff --git a/TechbloxModdingAPI/Interface/IMGUI/UIElement.cs b/TechbloxModdingAPI/Interface/IMGUI/UIElement.cs deleted file mode 100644 index fb25c38..0000000 --- a/TechbloxModdingAPI/Interface/IMGUI/UIElement.cs +++ /dev/null @@ -1,39 +0,0 @@ -using System; - -namespace TechbloxModdingAPI.Interface.IMGUI -{ - /// - /// GUI Element like a text field, button or picture. - /// This interface is used to wrap many elements from Unity's IMGUI system. - /// - public abstract class UIElement - { - protected UIElement(string text, string name) - { - Name = name ?? GetType().FullName + "::" + text; - IMGUIManager.AddElement(this); - } - - ~UIElement() - { - IMGUIManager.RemoveElement(this); - } - - /// - /// GUI operations to perform in the OnGUI scope. - /// This is basically equivalent to a MonoBehaviour's OnGUI method. - /// - public abstract void OnGUI(); - - /// - /// The element's name. - /// This should be unique for every instance of the class. - /// - public string Name { get; } - - /// - /// Whether to display the UI element or not. - /// - public bool Enabled { get; set; } = true; - } -} \ No newline at end of file diff --git a/TechbloxModdingAPI/Inventory/HotbarSlotSelectionHandlerEnginePatch.cs b/TechbloxModdingAPI/Inventory/HotbarSlotSelectionHandlerEnginePatch.cs deleted file mode 100644 index 79c6d5a..0000000 --- a/TechbloxModdingAPI/Inventory/HotbarSlotSelectionHandlerEnginePatch.cs +++ /dev/null @@ -1,30 +0,0 @@ -using System; -using System.Reflection; - -using Svelto.ECS; - -using HarmonyLib; -using TechbloxModdingAPI.Blocks; - -namespace TechbloxModdingAPI.Inventory -{ - [HarmonyPatch] - class HotbarSlotSelectionHandlerEnginePatch - { - private static int selectedBlockInt = 0; - - public static BlockIDs EquippedPartID { get => (BlockIDs)selectedBlockInt; } - - private static MethodInfo PatchedMethod { get; } = AccessTools.Method("Gamecraft.GUI.Hotbar.Blocks.SyncHotbarSlotSelectedToEquippedPartEngine:ActivateSlotForCube", parameters: new Type[] { typeof(uint), typeof(int) }); - - public static void Prefix(uint playerID, int selectedDBPartID) - { - selectedBlockInt = selectedDBPartID; - } - - public static MethodBase TargetMethod(Harmony harmonyInstance) - { - return PatchedMethod; - } - } -} diff --git a/TechbloxModdingAPI/Main.cs b/TechbloxModdingAPI/Main.cs deleted file mode 100644 index de38cc6..0000000 --- a/TechbloxModdingAPI/Main.cs +++ /dev/null @@ -1,140 +0,0 @@ -using System; -using System.Reflection; -using HarmonyLib; - -using RobocraftX; -using RobocraftX.Services; -using Svelto.Context; - -using TechbloxModdingAPI.App; -using TechbloxModdingAPI.Blocks; -using TechbloxModdingAPI.Tasks; -using TechbloxModdingAPI.Utility; - -namespace TechbloxModdingAPI -{ - /// - /// The main class of the TechbloxModdingAPI. - /// Use this to initialize the API before calling it. - /// - public static class Main - { - private static Harmony harmony; - - public static bool IsInitialized { - get { return harmony != null; } - } - - private static int referenceCount = 0; - - /// - /// Initializes the TechbloxModdingAPI. - /// Call this as soon as possible after Techblox starts up. - /// Ideally, this should be called from your main Plugin class's OnApplicationStart() method. - /// - public static void Init() - { - referenceCount++; - if (referenceCount > 1) { return; } - if (IsInitialized) - { - Logging.LogWarning("TechbloxModdingAPI.Main.Init() called but API is already initialized!"); - return; - } - Logging.MetaDebugLog($"Patching Techblox"); - var currentAssembly = Assembly.GetExecutingAssembly(); - harmony = new Harmony(currentAssembly.GetName().Name); - try - { - harmony.PatchAll(currentAssembly); - } - catch (Exception e) - { - HandleError(e, "Failed to patch Techblox. Attempting to patch to display error...", OnPatchError); - return; - } - - try - { - // init utility - Logging.MetaDebugLog($"Initializing Utility"); - Utility.GameState.Init(); - // init block implementors - Logging.MetaDebugLog($"Initializing Blocks"); - // init input - Input.FakeInput.Init(); - // init object-oriented classes - Player.Init(); - Block.Init(); - BlockGroup.Init(); - Wire.Init(); - // init client - Logging.MetaDebugLog($"Initializing Client"); - Client.Init(); - Game.Init(); - // init UI - Logging.MetaDebugLog($"Initializing UI"); - Interface.IMGUI.Constants.Init(); - Interface.IMGUI.IMGUIManager.Init(); - // init anti-anticheat - Logging.MetaDebugLog("Initializing anti-anticheat"); - AntiAntiCheatPatch.Init(harmony); - Logging.MetaLog($"{currentAssembly.GetName().Name} v{currentAssembly.GetName().Version} initialized"); - } - catch (Exception e) - { - HandleError(e, "Failed to initialize the API! Attempting to patch to display error...", OnInitError); - } - } - - /// - /// Shuts down & cleans up the TechbloxModdingAPI. - /// Call this as late as possible before Techblox quits. - /// Ideally, this should be called from your main Plugin class's OnApplicationQuit() method. - /// - public static void Shutdown() - { - if (referenceCount > 0) { referenceCount--; } - if (referenceCount == 0) - { - if (!IsInitialized) - { - Logging.LogWarning("TechbloxModdingAPI.Main.Shutdown() called but API is not initialized!"); - return; - } - Scheduler.Dispose(); - var currentAssembly = Assembly.GetExecutingAssembly(); - harmony.UnpatchSelf(); - harmony = null; - Logging.MetaLog($"{currentAssembly.GetName().Name} v{currentAssembly.GetName().Version} shutdown"); - } - } - - private static void OnPatchError() - { - ErrorBuilder.DisplayMustQuitError("Failed to patch Techblox!\n" + - "Make sure you're using the latest version of TechbloxModdingAPI or disable mods if the API isn't released yet."); - } - - private static void OnInitError() - { - ErrorBuilder.DisplayMustQuitError("Failed to initialize the modding API!\n" + - "Make sure you're using the latest version. If you are, please report the error."); - } - - /// - /// Handles an init error. Logs the exception, a log message, and allows displaying an error in-game. - /// - /// The exception - /// The log message - /// The action to run when the game is ready to display error messages - private static void HandleError(Exception e, string logMsg, Action onInit) - { //Can't use ErrorBuilder or Logging.LogException (which eventually uses ErrorBuilder) yet - Logging.Log(e.ToString()); - Logging.LogWarning(logMsg); - harmony.Patch(AccessTools.Method(typeof(FullGameCompositionRoot), "OnContextInitialized") - .MakeGenericMethod(typeof(UnityContext)), - new HarmonyMethod(onInit.Method)); //Can't use lambdas here :( - } - } -} diff --git a/TechbloxModdingAPI/Persistence/DeserializeFromDiskEntitiesEnginePatch.cs b/TechbloxModdingAPI/Persistence/DeserializeFromDiskEntitiesEnginePatch.cs deleted file mode 100644 index 6219ed1..0000000 --- a/TechbloxModdingAPI/Persistence/DeserializeFromDiskEntitiesEnginePatch.cs +++ /dev/null @@ -1,89 +0,0 @@ -using System; -using System.Text; -using System.Reflection; - -using RobocraftX.Common; -using Svelto.DataStructures; -using Svelto.ECS; -using Svelto.ECS.Serialization; - -using HarmonyLib; -using TechbloxModdingAPI.Utility; - -namespace TechbloxModdingAPI.Persistence -{ - //[HarmonyPatch] - TODO - class DeserializeFromDiskEntitiesEnginePatch - { - internal static EntitiesDB entitiesDB = null; - - private static readonly byte[] frameStart = Encoding.UTF8.GetBytes("\0\0\0TechbloxModdingAPI\0\0\0"); - - public static void Prefix(ref ISerializationData ____serializationData, ref FasterList ____bytesStream, ref IEntitySerialization ____entitySerializer, bool ____spawnBlocksOnly) - { - if (____spawnBlocksOnly) return; // only run after second deserialization call (when all vanilla stuff is already deserialized) - if (SaveAndLoadCompositionRootPatch.currentEnginesRoot == null) return; - SerializerManager.RegisterSerializers(SaveAndLoadCompositionRootPatch.currentEnginesRoot); - uint originalPos = ____serializationData.dataPos; - Logging.MetaDebugLog($"dataPos: {originalPos}"); - BinaryBufferReader bbr = new BinaryBufferReader(____bytesStream.ToArrayFast(out int count), ____serializationData.dataPos); - byte[] frameBuffer = new byte[frameStart.Length]; - Logging.MetaDebugLog($"serial data count: {____serializationData.data.count} capacity: {____serializationData.data.capacity}"); - int i = 0; - // match frame start - while (frameBuffer != frameStart && bbr.Position < count-frameStart.Length) - { - i = 0; - frameBuffer[0] = bbr.ReadByte(); - while (frameBuffer[i] == frameStart[i] && bbr.Position < count - frameStart.Length + i) - { - i++; - if (i == frameStart.Length) break; - frameBuffer[i] = bbr.ReadByte(); - } - if (i == frameStart.Length) break; - } - // abort if at end of file - if (bbr.Position >= count - frameStart.Length) - { - Logging.MetaLog("Skipping deserialization (no frame found)"); - return; - } - //____serializationData.dataPos = bbr.Position; - Logging.MetaDebugLog($"dataPos (after frame): {bbr.Position}"); - uint customComponentsCount = bbr.ReadUint(); - for (uint c = 0; c < customComponentsCount; c++) - { - // determine component from info - uint nameLength = bbr.ReadUint(); - byte[] nameBytes = new byte[nameLength]; - bbr.ReadBytes(nameBytes, nameLength); - string name = Encoding.UTF8.GetString(nameBytes); - Logging.MetaDebugLog($"Component name: {name} (len: {nameLength})"); - uint componentEnd = bbr.ReadUint(); - ____serializationData.dataPos = bbr.Position; - if (SerializerManager.ExistsSerializer(name)) - { - // deserialize component - IEntitySerializer serial = SerializerManager.GetSerializer(name); - if (!serial.Deserialize(ref ____serializationData, ____entitySerializer)) - { - Logging.MetaDebugLog("Component deserialization failed!"); - } - } - else - { - Logging.MetaDebugLog("Skipping component deserialization: not found!"); - } - bbr = new BinaryBufferReader(____bytesStream.ToArrayFast(out count), componentEnd); - } - ____serializationData.dataPos = originalPos; // change back to original end point (just in case) - Logging.MetaDebugLog("Deserialization complete"); - } - - public static MethodBase TargetMethod() - { - return AccessTools.Method("RobocraftX.SaveAndLoad.DeserializeFromDiskEntitiesEngine:LoadingFinished");//AccessTools.TypeByName("RobocraftX.SaveAndLoad.DeserializeFromDiskEntities") - } - } -} diff --git a/TechbloxModdingAPI/Persistence/IEntitySerializer.cs b/TechbloxModdingAPI/Persistence/IEntitySerializer.cs deleted file mode 100644 index 0d6e599..0000000 --- a/TechbloxModdingAPI/Persistence/IEntitySerializer.cs +++ /dev/null @@ -1,32 +0,0 @@ -using System; - -using Svelto.ECS; -using Svelto.ECS.Serialization; - -using TechbloxModdingAPI.Utility; - -namespace TechbloxModdingAPI.Persistence -{ - /// - /// Entity serializer and deserializer interface for storing and retrieving data in a Techblox save file (GameSave.GC). - /// - public interface IEntitySerializer : IDeserializationFactory, IQueryingEntitiesEngine - { - /// - /// Serialize the entities. - /// - /// Whether serialization was successful. - /// Serialized data to write to (writes to GameSave.GC). - /// Entities db for the game. - /// Entity serializer with support for single-entity serialization. - bool Serialize(ref ISerializationData serializationData, EntitiesDB entitiesDB, IEntitySerialization entitySerializer); - - /// - /// Deserialize the entities. - /// - /// Whether deserialization was successful. - /// Serialized data to read from (read from GameSave.GC). - /// Entity serializer with support for single-entity deserialization. - bool Deserialize(ref ISerializationData serializationData, IEntitySerialization entitySerializer); - } -} diff --git a/TechbloxModdingAPI/Persistence/SaveAndLoadCompositionRootPatch.cs b/TechbloxModdingAPI/Persistence/SaveAndLoadCompositionRootPatch.cs deleted file mode 100644 index 5b65834..0000000 --- a/TechbloxModdingAPI/Persistence/SaveAndLoadCompositionRootPatch.cs +++ /dev/null @@ -1,22 +0,0 @@ -using System; - -using RobocraftX.SaveAndLoad; -using Svelto.ECS; - -using HarmonyLib; -using RobocraftX.StateSync; - -namespace TechbloxModdingAPI.Persistence -{ - [HarmonyPatch(typeof(SaveAndLoadCompositionRoot), "ClientComposeTimeStopped")] - class SaveAndLoadCompositionRootPatch - { - public static EnginesRoot currentEnginesRoot; - - public static void Prefix(StateSyncRegistrationHelper stateSyncHelper) - { - currentEnginesRoot = stateSyncHelper.enginesRoot; - //SerializerManager.RegisterSerializers(enginesRoot); - } - } -} diff --git a/TechbloxModdingAPI/Persistence/SaveGameEnginePatch.cs b/TechbloxModdingAPI/Persistence/SaveGameEnginePatch.cs deleted file mode 100644 index 06f4a1a..0000000 --- a/TechbloxModdingAPI/Persistence/SaveGameEnginePatch.cs +++ /dev/null @@ -1,80 +0,0 @@ -using System; -using System.Text; -using System.Reflection; - -using RobocraftX.Common; -using RobocraftX.SaveAndLoad; -using Svelto.DataStructures; -using Svelto.ECS; -using Svelto.ECS.Serialization; -using HarmonyLib; -using TechbloxModdingAPI.Utility; - -namespace TechbloxModdingAPI.Persistence -{ - //[HarmonyPatch] - TODO - class SaveGameEnginePatch - { - private static readonly byte[] frameStart = Encoding.UTF8.GetBytes("\0\0\0TechbloxModdingAPI\0\0\0"); - - public static void Postfix(ref ISerializationData serializationData, EntitiesDB entitiesDB, IEntitySerialization entitySerializer) - { - Logging.MetaDebugLog("Running Postfix on SerializeGameToBuffer: serializing custom components..."); - if (SerializerManager.GetSerializersCount() == 0) - { - Logging.MetaDebugLog("Skipping component serialization: no serializers registered!"); - return; - } - serializationData.data.IncreaseCapacityBy((uint)frameStart.Length); - BinaryBufferWriter bbw = new BinaryBufferWriter(serializationData.data.ToArrayFast(out int buffLen), serializationData.dataPos); - uint originalPos = serializationData.dataPos; - Logging.MetaDebugLog($"dataPos: {originalPos}"); - // Add frame start so it's easier to find TechbloxModdingAPI-serialized components - for (int i = 0; i < frameStart.Length; i++) - { - bbw.Write(frameStart[i]); - } - Logging.MetaDebugLog($"dataPos (after frame start): {bbw.Position}"); - serializationData.data.IncreaseCapacityBy(4u); - bbw.Write((uint)SerializerManager.GetSerializersCount()); - string[] serializerKeys = SerializerManager.GetSerializerNames(); - for (uint c = 0; c < serializerKeys.Length; c++) - { - Logging.MetaDebugLog($"dataPos (loop start): {bbw.Position}"); - // write component info - serializationData.data.IncreaseCapacityBy(4u + (uint)serializerKeys[c].Length); - bbw.Write((uint)serializerKeys[c].Length); - Logging.MetaDebugLog($"dataPos (now): {bbw.Position}"); - byte[] nameBytes = Encoding.UTF8.GetBytes(serializerKeys[c]); - for (int i = 0; i < nameBytes.Length; i++) - { - bbw.Write(nameBytes[i]); - } - Logging.MetaDebugLog($"dataPos (now): {bbw.Position}"); - serializationData.data.IncreaseCapacityBy(4u); - serializationData.dataPos = bbw.Position + 4u; - Logging.MetaDebugLog($"dataPos (now): {bbw.Position}"); - Logging.MetaDebugLog($"dataPos (appears to be): {serializationData.dataPos}"); - // serialize component - IEntitySerializer serializer = SerializerManager.GetSerializer(serializerKeys[c]); - if (!serializer.Serialize(ref serializationData, entitiesDB, entitySerializer)) - { - Logging.MetaDebugLog("Component serialization failed!"); - } - Logging.MetaDebugLog($"dataPos (now): {bbw.Position}"); - bbw.Write((uint)serializationData.dataPos); - Logging.MetaDebugLog($"dataPos (now): {bbw.Position}"); - bbw = new BinaryBufferWriter(serializationData.data.ToArrayFast(out buffLen), serializationData.dataPos); - Logging.MetaDebugLog($"dataPos (loop end): {bbw.Position}"); - } - serializationData.data.Trim(); - Logging.MetaDebugLog($"dataPos (end): {bbw.Position}"); - Logging.MetaDebugLog("Serialization complete"); - } - - public static MethodBase TargetMethod() - { - return AccessTools.TypeByName("RobocraftX.SaveAndLoad.SaveGameEngine").GetMethod("SerializeGameToBuffer"); - } - } -} diff --git a/TechbloxModdingAPI/Persistence/SerializerManager.cs b/TechbloxModdingAPI/Persistence/SerializerManager.cs deleted file mode 100644 index fe11320..0000000 --- a/TechbloxModdingAPI/Persistence/SerializerManager.cs +++ /dev/null @@ -1,73 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; - -using Svelto.ECS; -using Svelto.ECS.Serialization; -using TechbloxModdingAPI.Utility; - -namespace TechbloxModdingAPI.Persistence -{ - /// - /// Keeps track of serializers. - /// This is used to add and retrieve serializers. - /// Added IEntitySerializations are used in serializing and deserializing Techblox save files (GameSave.GC). - /// - public static class SerializerManager - { - private static Dictionary _serializers = new Dictionary(); - - private static Dictionary> _registrations = new Dictionary>(); - - private static EnginesRoot _lastEnginesRoot; - - public static void AddSerializer(IEntitySerializer serializer) where T : ISerializableEntityDescriptor, new() - { - string name = typeof(T).FullName; - _serializers[name] = serializer; - _registrations[name] = (IEntitySerialization ies) => { ies.RegisterSerializationFactory(serializer); }; - if (_lastEnginesRoot != null) - { - _registrations[name].Invoke(_lastEnginesRoot.GenerateEntitySerializer()); - _lastEnginesRoot.AddEngine(serializer); - } - } - - public static bool ExistsSerializer(string name) - { - return _serializers.ContainsKey(name); - } - - public static bool ExistsSerializer(IEntitySerializer serializer) where T : ISerializableEntityDescriptor, new() - { - return ExistsSerializer(typeof(T).FullName); - } - - public static IEntitySerializer GetSerializer(string name) - { - return _serializers[name]; - } - - public static string[] GetSerializerNames() - { - return _serializers.Keys.ToArray(); - } - - public static int GetSerializersCount() - { - return _serializers.Count; - } - - internal static void RegisterSerializers(EnginesRoot enginesRoot) - { - _lastEnginesRoot = enginesRoot; - IEntitySerialization ies = enginesRoot.GenerateEntitySerializer(); - foreach (string key in _serializers.Keys) - { - Logging.MetaDebugLog($"Registering IEntitySerializer for {key}"); - _registrations[key].Invoke(ies); - enginesRoot.AddEngine(_serializers[key]); - } - } - } -} diff --git a/TechbloxModdingAPI/Persistence/SimpleEntitySerializer.cs b/TechbloxModdingAPI/Persistence/SimpleEntitySerializer.cs deleted file mode 100644 index 57f787a..0000000 --- a/TechbloxModdingAPI/Persistence/SimpleEntitySerializer.cs +++ /dev/null @@ -1,71 +0,0 @@ -using System; - -using Svelto.ECS; -using Svelto.ECS.Serialization; - -using RobocraftX.Common; - -namespace TechbloxModdingAPI.Persistence -{ - /// - /// Simple entity serializer sufficient for simple entity components. - /// - public class SimpleEntitySerializer : IEntitySerializer where Descriptor : ISerializableEntityDescriptor, new() - { - /// - /// Delegate function called when the serializer needs to know what entities to serialize. - /// - public delegate EGID[] GetEntitiesToSerialize(EntitiesDB entitiesDB); - - private GetEntitiesToSerialize getEntitiesToSerialize; - - protected int serializationType; - - public EntitiesDB entitiesDB { set; protected get; } - - public EntityInitializer BuildDeserializedEntity(EGID egid, ISerializationData serializationData, ISerializableEntityDescriptor entityDescriptor, int serializationType, IEntitySerialization entitySerialization, IEntityFactory factory, bool enginesRootIsDeserializationOnly) - { - EntityInitializer esi = factory.BuildEntity(egid); - entitySerialization.DeserializeEntityComponents(serializationData, entityDescriptor, ref esi, serializationType); - return esi; - } - - public bool Deserialize(ref ISerializationData serializationData, IEntitySerialization entitySerializer) - { - BinaryBufferReader bbr = new BinaryBufferReader(serializationData.data.ToArrayFast(out int count), serializationData.dataPos); - uint entityCount = bbr.ReadUint(); - serializationData.dataPos = bbr.Position; - for (uint i = 0; i < entityCount; i++) - { - entitySerializer.DeserializeEntity(serializationData, serializationType); - } - return true; - } - - public void Ready() { } - - public bool Serialize(ref ISerializationData serializationData, EntitiesDB entitiesDB, IEntitySerialization entitySerializer) - { - serializationData.data.IncreaseCapacityBy(4u); - BinaryBufferWriter bbw = new BinaryBufferWriter(serializationData.data.ToArrayFast(out int count), serializationData.dataPos); - EGID[] toSerialize = getEntitiesToSerialize(entitiesDB); - bbw.Write((uint)toSerialize.Length); - serializationData.dataPos = bbw.Position; - for (uint i = 0; i < toSerialize.Length; i++) - { - entitySerializer.SerializeEntity(toSerialize[i], serializationData, serializationType); - } - return true; - } - - /// - /// Construct the entity serializer. - /// - /// Provider of entity IDs to serialize. - public SimpleEntitySerializer(GetEntitiesToSerialize getEntitiesToSerialize) - { - this.getEntitiesToSerialize = getEntitiesToSerialize; - serializationType = (int)SerializationType.Storage; - } - } -} diff --git a/TechbloxModdingAPI/Player.Events.cs b/TechbloxModdingAPI/Player.Events.cs deleted file mode 100644 index 8d8cd10..0000000 --- a/TechbloxModdingAPI/Player.Events.cs +++ /dev/null @@ -1,52 +0,0 @@ -using System; -using Svelto.ECS; -using TechbloxModdingAPI.Blocks; -using TechbloxModdingAPI.Utility; - -namespace TechbloxModdingAPI -{ - public partial class Player - { - internal WrappedHandler seatEntered; - public event EventHandler SeatEntered - { - add => seatEntered += value; - remove => seatEntered -= value; - } - - internal WrappedHandler seatExited; - public event EventHandler SeatExited - { - add => seatExited += value; - remove => seatExited -= value; - } - - internal static WrappedHandler joined; - - public static event EventHandler Joined - { - add => joined += value; - remove => joined -= value; - } - - internal static WrappedHandler left; - - public static event EventHandler Left - { - add => left += value; - remove => left -= value; - } - } - - public struct PlayerSeatEventArgs - { - public EGID SeatId; - public Seat Seat => (Seat)Block.New(SeatId); - } - - public struct PlayerEventArgs - { - public EGID PlayerId; - public Player Player => Player.GetInstance(PlayerId.entityID); - } -} \ No newline at end of file diff --git a/TechbloxModdingAPI/Player.cs b/TechbloxModdingAPI/Player.cs deleted file mode 100644 index 24799f3..0000000 --- a/TechbloxModdingAPI/Player.cs +++ /dev/null @@ -1,578 +0,0 @@ -using System; -using Gamecraft.Wires; -using RobocraftX.Character; -using RobocraftX.Character.Movement; -using Unity.Mathematics; -using RobocraftX.Common; -using RobocraftX.Common.Players; -using RobocraftX.GUI.Wires; -using RobocraftX.Physics; -using Svelto.ECS; -using Techblox.BuildingDrone; -using Techblox.Camera; -using Techblox.Character; -using TechbloxModdingAPI.Blocks; -using TechbloxModdingAPI.Players; -using TechbloxModdingAPI.Utility; -using UnityEngine; - -namespace TechbloxModdingAPI -{ - /// - /// An in-game player character. Any Leo you see is a player. - /// - public partial class Player : EcsObjectBase, IEquatable, IEquatable - { - // static functionality - private static readonly PlayerEngine playerEngine = new PlayerEngine(); - private static readonly PlayerEventsEngine playerEventsEngine = new PlayerEventsEngine(); - private static Player localPlayer; - - /// - /// Checks if the specified player exists. - /// - /// Whether the player exists. - /// Player type. - public static bool Exists(PlayerType player) - { - switch (player) - { - case PlayerType.Remote: - return playerEngine.GetRemotePlayer() != uint.MaxValue; - case PlayerType.Local: - return playerEngine.GetLocalPlayer() != uint.MaxValue; - } - return false; - } - - /// - /// Checks if the specified player exists. - /// - /// Whether the player exists. - /// The player's unique identifier. - public static bool Exists(uint player) - { - return playerEngine.ExistsById(player); - } - - /// - /// The amount of Players in the current game. - /// - /// The count. - public static uint Count() - { - return (uint) playerEngine.GetAllPlayerCount(); - } - - /// - /// Returns the current player belonging to this client. It will be different after entering/leaving simulation. - /// May return null if the local player doesn't exist. - /// - public static Player LocalPlayer - { - get - { - var playerId = playerEngine.GetLocalPlayer(); - if (playerId == uint.MaxValue) return null; - if (localPlayer == null || localPlayer.Id != playerId) - localPlayer = GetInstance(playerId); - return localPlayer; - } - } - - internal static Player GetInstance(uint id) - { - return EcsObjectBase.GetInstance(new EGID(id, CharacterExclusiveGroups.OnFootGroup), - e => new Player(e.entityID)); - } - - /// - /// Initializes a new instance of the class. - /// - /// The player's unique identifier. - public Player(uint id) : base(new EGID(id, CharacterExclusiveGroups.OnFootGroup)) - { - this.Id = id; - if (!Exists(id)) - { - throw new PlayerNotFoundException($"No player with id {id} exists"); - } - this.Type = playerEngine.GetLocalPlayer() == id ? PlayerType.Local : PlayerType.Remote; - } - - /// - /// Initializes a new instance of the class. - /// - /// The player type. Chooses the first available player matching the criteria. - public Player(PlayerType player) : base(ecs => - { - uint id; - switch (player) - { - case PlayerType.Local: - id = playerEngine.GetLocalPlayer(); - break; - case PlayerType.Remote: - id = playerEngine.GetRemotePlayer(); - break; - default: - id = uint.MaxValue; - break; - } - - if (id == uint.MaxValue) - { - throw new PlayerNotFoundException($"No player of {player} type exists"); - } - - return new EGID(id, CharacterExclusiveGroups.OnFootGroup); - }) - { - this.Type = player; - Id = base.Id.entityID; - } - - // object fields & properties - - /// - /// The player's type. - /// The player type is always relative to the current client, not the game host. - /// - /// The enumerated player type. - public PlayerType Type { get; } - - /// - /// The player's unique identifier. - /// - /// The identifier. - public new uint Id { get; } - - /// - /// The player's current position. - /// - /// The position. - public float3 Position - { - get => playerEngine.GetCharacterStruct(Id).Get().position; - set => playerEngine.SetLocation(Id, value, false); - } - - /// - /// The player's current rotation. - /// - /// The rotation. - public float3 Rotation - { - get => ((Quaternion) (GameState.IsBuildMode() - ? playerEngine.GetCameraStruct(Id).Get().rotation - : playerEngine.GetCharacterStruct(Id).Get().rotation)).eulerAngles; - set => _ = GameState.IsBuildMode() - ? playerEngine.GetCameraStruct(Id).Get().rotation = quaternion.Euler(value) - : playerEngine.GetCharacterStruct(Id).Get().rotation = quaternion.Euler(value); - } - - /// - /// The player's current velocity. - /// - /// The velocity. - public float3 Velocity - { - get => playerEngine.GetCharacterStruct(Id).Get().velocity; - set => playerEngine.GetCharacterStruct(Id).Get().velocity = value; - } - - /// - /// The player's current angular velocity. - /// - /// The angular velocity. - public float3 AngularVelocity - { - get => playerEngine.GetCharacterStruct(Id).Get().angularVelocity; - set => playerEngine.GetCharacterStruct(Id).Get().angularVelocity = value; - } - - /// - /// The player's mass. - /// - /// The mass. - [Obsolete] // We cannot get it clientside or something - public float Mass => 0; - - /// - /// The player's latest network ping time. - /// - /// The ping (s). - public float Ping - { - get - { - return playerEngine.GetPing() / 1000f; - } - } - - /// - /// The player's initial health when entering Simulation (aka Time Running) mode. - /// - /// The initial health. - [Obsolete("We can no longer get initial health, returns max health.")] - public float InitialHealth - { - get - { - var opt = playerEngine.GetCharacterStruct(Id); - return opt ? opt.Get().maxHealth : -1f; - } - - set => playerEngine.GetCharacterStruct(Id).Get().maxHealth = value; - } - - /// - /// The player's current health in Simulation (aka Time Running) mode. - /// - /// The current health. - public float CurrentHealth - { - get - { - var opt = playerEngine.GetCharacterStruct(Id); - return opt ? opt.Get().currentHealth : -1f; - } - - set => playerEngine.GetCharacterStruct(Id).Get().currentHealth = value; - } - - /// - /// Whether this is damageable. - /// - /// true if damageable; otherwise, false. - [Obsolete("Players are probably always damageable")] - public bool Damageable - { - get => true; - - // ReSharper disable once ValueParameterNotUsed - set - { - } - } - - /// - /// The player's lives when initially entering Simulation (aka Time Running) mode. - /// - /// The initial lives. - [Obsolete("The player has infinite lives")] - public uint InitialLives - { - get => uint.MaxValue; - - // ReSharper disable once ValueParameterNotUsed - set { } - } - - /// - /// The player's current lives in Simulation (aka Time Running) mode. - /// - /// The current lives. - [Obsolete("The player has infinite lives")] - public uint CurrentLives - { - get => uint.MaxValue; - - // ReSharper disable once ValueParameterNotUsed - set { } - } - - /*/// - /// Whether the Game Over screen is displayed for the player. - /// - /// true if game over; otherwise, false. - public bool GameOver - { - get => playerEngine.GetGameOverScreen(Id); - }*/ - - /// - /// Whether the player is dead. - /// If true, hopefully it was quick. - /// - /// true if dead; otherwise, false. - public bool Dead - { - get => playerEngine.IsDead(Id); - } - - /// - /// The player's selected block ID in their hand. - /// - /// The selected block. - public BlockIDs SelectedBlock - { - get - { - var optstruct = playerEngine.GetCharacterStruct(Id); - return optstruct ? (BlockIDs) optstruct.Get().selectedDBPartID : BlockIDs.Invalid; - } - } - - /// - /// The player's selected block color in their hand. - /// - /// The selected block's color. - public BlockColor SelectedColor - { - get - { - var optstruct = playerEngine.GetCharacterStruct(Id); - return optstruct ? new BlockColor(optstruct.Get().indexInPalette) : BlockColors.Default; - } - } - - /// - /// The player's selected block colour in their hand. - /// - /// The selected block's colour. - public BlockColor SelectedColour - { - get - { - var optstruct = playerEngine.GetCharacterStruct(Id); - return optstruct ? new BlockColor(optstruct.Get().indexInPalette) : BlockColors.Default; - } - } - - /// - /// The player's selected blueprint in their hand. Set to null to clear. Dispose after usage. - /// - public Blueprint SelectedBlueprint - { - get - { - var lbiso = playerEngine.GetPlayerStruct(Id, Type); - return lbiso ? new Blueprint(lbiso.Get().selectedBlueprintId) : null; - } - set => BlockGroup._engine.SelectBlueprint(value?.Id ?? uint.MaxValue); - } - - /// - /// The player's mode in time stopped mode, determining what they place. - /// - public PlayerBuildingMode BuildingMode => (PlayerBuildingMode)Math.Log((double)playerEngine - .GetCharacterStruct(Id).Get().timeStoppedContext, 2); // It's a bit field in game now - - public PlayerState State => - playerEngine.GetCharacterStruct(Id).Get().ID.groupID switch - { - var group when group == CharacterExclusiveGroups.MachineSpawningGroup => PlayerState.HoldingMachine, - var group when group == CharacterExclusiveGroups.OnFootGroup => PlayerState.OnFoot, - var group when group == CharacterExclusiveGroups.InPilotSeatGroup => PlayerState.InSeat, - var group when group == CharacterExclusiveGroups.DyingOnFootGroup => PlayerState.OnFoot, - var group when group == CharacterExclusiveGroups.DyingInPilotSeatGroup => PlayerState.InSeat, - var group when group == CharacterExclusiveGroups.DeadGroup => PlayerState.OnFoot, - _ => throw new ArgumentOutOfRangeException("", "Unknown player state") - }; - - /// - /// Whether the player is sprinting. - /// - public bool Sprinting - { - get => GameState.IsBuildMode() - ? playerEngine.GetCharacterStruct(Id).Get().sprinting - : playerEngine.GetCharacterStruct(Id).Get().isSprinting; - set => _ = GameState.IsBuildMode() - ? playerEngine.GetCharacterStruct(Id).Get().sprinting = value - : playerEngine.GetCharacterStruct(Id).Get().isSprinting = value; - } - - /// - /// Movement speed setting. Build mode (camera) and simulation mode settings are separate. - /// - public float SpeedSetting - { - get => GameState.IsBuildMode() - ? playerEngine.GetCharacterStruct(Id).Get().speed - : playerEngine.GetCharacterStruct(Id).Get().moveSpeed; - set => _ = GameState.IsBuildMode() - ? playerEngine.GetCharacterStruct(Id).Get().speed = value - : playerEngine.GetCharacterStruct(Id).Get().moveSpeed = value; - } - - /// - /// The multiplier setting to use when sprinting. Build mode (camera) and simulation mode settings are separate. - /// - public float SpeedSprintMultiplierSetting - { - get => GameState.IsBuildMode() - ? playerEngine.GetCharacterStruct(Id).Get().speedSprintMultiplier - : playerEngine.GetCharacterStruct(Id).Get().sprintSpeedMultiplier; - set => _ = GameState.IsBuildMode() - ? playerEngine.GetCharacterStruct(Id).Get().speedSprintMultiplier = value - : playerEngine.GetCharacterStruct(Id).Get().sprintSpeedMultiplier = value; - } - - /// - /// The acceleration setting of the player. Build mode (camera) and simulation mode settings are separate. - /// - public float AccelerationSetting - { - get => GameState.IsBuildMode() - ? playerEngine.GetCharacterStruct(Id).Get().acceleration - : playerEngine.GetCharacterStruct(Id).Get().acceleration; - set => _ = GameState.IsBuildMode() - ? playerEngine.GetCharacterStruct(Id).Get().acceleration = value - : playerEngine.GetCharacterStruct(Id).Get().acceleration = value; - } - - // object methods - - /// - /// Teleport the player to the specified coordinates. - /// - /// The x coordinate. - /// The y coordinate. - /// The z coordinate. - /// If set to true teleport relative to the player's current position. - /// If set to true exit any seat the player is in. - public void Teleport(float x, float y, float z, bool relative = true, bool exitSeat = true) - { - float3 location = new float3(x, y, z); - if (relative) - { - location += Position; - } - playerEngine.SetLocation(Id, location, exitSeat: exitSeat); - } - - /// - /// Enter the given seat. - /// - /// The seat to enter. - public void EnterSeat(Seat seat) - { - playerEngine.EnterSeat(Id, seat.Id); - } - - /// - /// Exit the seat the player is currently in. - /// - public void ExitSeat() - { - playerEngine.ExitSeat(Id); - } - - /// - /// Spawn the machine the player is holding in time running mode. - /// - public bool SpawnMachine() - { - return playerEngine.SpawnMachine(Id); - } - - /// - /// Despawn the player's machine in time running mode and place it in their hand. - /// - public bool DespawnMachine() - { - return playerEngine.DespawnMachine(Id); - } - - /// - /// Returns the block the player is currently looking at in build mode. - /// - /// The maximum distance from the player (default is the player's building reach) - /// The block or null if not found - public Block GetBlockLookedAt(float maxDistance = -1f) - { - var egid = playerEngine.GetThingLookedAt(Id, maxDistance); - return egid != default && egid.groupID != CommonExclusiveGroups.SIMULATION_BODIES_GROUP - && egid.groupID != WiresGUIExclusiveGroups.WireGroup - ? Block.New(egid) - : null; - } - - /// - /// Returns the rigid body the player is currently looking at during simulation. - /// - /// The maximum distance from the player (default is the player's building reach) - /// The body or null if not found - public SimBody GetSimBodyLookedAt(float maxDistance = -1f) - { - var egid = playerEngine.GetThingLookedAt(Id, maxDistance); - return egid != default && egid.groupID == CommonExclusiveGroups.SIMULATION_BODIES_GROUP - ? EcsObjectBase.GetInstance(egid, e => new SimBody(e)) - : null; - } - - /// - /// Returns the wire the player is currently looking at in build mode. - /// - /// The maximum distance from the player (default is the player's building reach) - /// The wire or null if not found - public Wire GetWireLookedAt(float maxDistance = -1f) - { - var egid = playerEngine.GetThingLookedAt(Id, maxDistance); - return egid != default && egid.groupID == WiresGUIExclusiveGroups.WireGroup - ? EcsObjectBase.GetInstance(new EGID(egid.entityID, BuildModeWiresGroups.WiresGroup.Group), - e => new Wire(e)) - : null; - } - - /// - /// Returns the blocks that are in the player's current selection. - /// - /// An array of blocks or an empty array - public Block[] GetSelectedBlocks() - { - return playerEngine.GetSelectedBlocks(Id); - } - - /// - /// Returns the ghost block that shows the block to be placed in build mode. - /// - /// A block instance or null if not found - public Block GetGhostBlock() - { - return playerEngine.GetGhostBlock(Id); - } - - public bool Equals(Player other) - { - if (ReferenceEquals(null, other)) return false; - if (ReferenceEquals(this, other)) return true; - return Id == other.Id; - } - - public bool Equals(EGID other) - { - return Id == other.entityID && other.groupID == (Type == PlayerType.Local - ? PlayersExclusiveGroups.LocalPlayers - : PlayersExclusiveGroups.RemotePlayers); - } - - public override bool Equals(object obj) - { - if (ReferenceEquals(null, obj)) return false; - if (ReferenceEquals(this, obj)) return true; - if (obj.GetType() != this.GetType()) return false; - return Equals((Player) obj); - } - - public override int GetHashCode() - { - return (int) Id; - } - - public override string ToString() - { - return $"{nameof(Type)}: {Type}, {nameof(Id)}: {Id}, {nameof(Position)}: {Position}, {nameof(Rotation)}: {Rotation}, {nameof(Mass)}: {Mass}"; - } - - // internal methods - - internal static void Init() - { - Utility.GameEngineManager.AddGameEngine(playerEngine); - Utility.GameEngineManager.AddGameEngine(playerEventsEngine); - } - } -} diff --git a/TechbloxModdingAPI/Players/PlayerBuildingMode.cs b/TechbloxModdingAPI/Players/PlayerBuildingMode.cs deleted file mode 100644 index 7bc25a8..0000000 --- a/TechbloxModdingAPI/Players/PlayerBuildingMode.cs +++ /dev/null @@ -1,12 +0,0 @@ -namespace TechbloxModdingAPI.Players -{ - public enum PlayerBuildingMode - { - BlockMode, - ColourMode, - ConfigMode, - BlueprintMode, - MaterialMode, - LandscapeMode - } -} \ No newline at end of file diff --git a/TechbloxModdingAPI/Players/PlayerEngine.cs b/TechbloxModdingAPI/Players/PlayerEngine.cs deleted file mode 100644 index a1965fd..0000000 --- a/TechbloxModdingAPI/Players/PlayerEngine.cs +++ /dev/null @@ -1,274 +0,0 @@ -using System; -using System.Runtime.CompilerServices; - -using RobocraftX.Character; -using RobocraftX.Character.Movement; -using RobocraftX.Common.Players; -using RobocraftX.Common.Input; -using RobocraftX.CR.MachineEditing.BoxSelect; -using RobocraftX.Physics; -using RobocraftX.Blocks.Ghost; -using RobocraftX.Common; -using RobocraftX.Multiplayer; -using RobocraftX.SimulationModeState; -using Svelto.ECS; -using Techblox.Camera; -using Unity.Mathematics; -using Svelto.ECS.DataStructures; -using Techblox.BuildingDrone; -using Techblox.Character; - -using TechbloxModdingAPI.Engines; -using TechbloxModdingAPI.Input; -using TechbloxModdingAPI.Utility; -using TechbloxModdingAPI.Utility.ECS; - -namespace TechbloxModdingAPI.Players -{ - internal class PlayerEngine : IFunEngine - { - public string Name { get; } = "TechbloxModdingAPIPlayerGameEngine"; - - public EntitiesDB entitiesDB { set; private get; } - - public bool isRemovable => false; - - public IEntityFunctions Functions { get; set; } - - private bool isReady = false; - - public void Dispose() - { - isReady = false; - } - - public void Ready() - { - isReady = true; - } - - public uint GetLocalPlayer() - { - if (!isReady) return uint.MaxValue; - var (localPlayers, count) = entitiesDB.QueryEntities(PlayersExclusiveGroups.LocalPlayers); - if (count > 0) - { - return localPlayers[0].ID.entityID; - } - return uint.MaxValue; - } - - public uint GetRemotePlayer() - { - if (!isReady) return uint.MaxValue; - var (localPlayers, count) = entitiesDB.QueryEntities(PlayersExclusiveGroups.RemotePlayers); - if (count > 0) - { - return localPlayers[0].ID.entityID; - } - return uint.MaxValue; - } - - public long GetAllPlayerCount() - { - if (entitiesDB == null) return 0; - long count = 0; - foreach (ExclusiveGroupStruct eg in PlayersExclusiveGroups.AllPlayers) - { - count += entitiesDB.Count(eg); - } - return count; - } - - public long GetLocalPlayerCount() - { - if (entitiesDB == null) return 0; - return entitiesDB.Count(PlayersExclusiveGroups.LocalPlayers); - } - - public long GetRemotePlayerCount() - { - if (entitiesDB == null) return 0; - return entitiesDB.Count(PlayersExclusiveGroups.RemotePlayers); - } - - public bool ExistsById(uint playerId) - { - if (entitiesDB == null) return false; - return entitiesDB.Exists(playerId, PlayersExclusiveGroups.LocalPlayers) - || entitiesDB.Exists(playerId, PlayersExclusiveGroups.RemotePlayers); - } - - public bool SetLocation(uint playerId, float3 location, bool exitSeat = true) - { - if (entitiesDB == null) return false; - var rbesOpt = GetCharacterStruct(playerId, out var group); - if (!rbesOpt) - return false; - if (group == CharacterExclusiveGroups.InPilotSeatGroup && exitSeat) - { - ExitSeat(playerId); - } - rbesOpt.Get().position = location; - return true; - } - - public bool IsDead(uint playerId) - { - if (entitiesDB == null) return true; - return entitiesDB.Exists(playerId, CharacterExclusiveGroups.DeadGroup); - } - - // reusable methods - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public OptionalRef GetCharacterStruct(uint playerId) where T : unmanaged, IEntityComponent => - GetCharacterStruct(playerId, out _); - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public OptionalRef GetCharacterStruct(uint playerId, out ExclusiveGroupStruct group) where T : unmanaged, IEntityComponent - { - group = default; - if (GameState.IsBuildMode()) - return entitiesDB.QueryEntityOptional(new EGID(playerId, LocalBuildingDrone.BuildGroup)); - - var characterGroups = CharacterExclusiveGroups.AllCharacters; - for (int i = 0; i < characterGroups.count; i++) - { - EGID egid = new EGID(playerId, characterGroups[i]); - var opt = entitiesDB.QueryEntityOptional(egid); - if (opt.Exists) - { - group = characterGroups[i]; - return opt; - } - } - - return new OptionalRef(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public OptionalRef GetPlayerStruct(uint playerId, PlayerType type) where T : unmanaged, IEntityComponent - { - var playerGroup = type == PlayerType.Local ? PlayersExclusiveGroups.LocalPlayers : PlayersExclusiveGroups.RemotePlayers; - EGID egid = new EGID(playerId, playerGroup); - return entitiesDB.QueryEntityOptional(egid); - } - - public OptionalRef GetCameraStruct(uint playerId) where T : unmanaged, IEntityComponent - { - return entitiesDB.QueryEntityOptional(new EGID(playerId, CameraExclusiveGroups.PhysicCameraGroup)); - } - - public EGID GetThingLookedAt(uint playerId, float maxDistance = -1f) - { - var opt = GetCameraStruct(playerId); - if (!opt) return default; - PhysicCameraRayCastEntityStruct rayCast = opt; - EGID physicCameraEgid = new EGID(playerId, CameraExclusiveGroups.PhysicCameraGroup); - float distance = maxDistance < 0 - ? GhostBlockUtils.GetBuildInteractionDistance(entitiesDB, rayCast, physicCameraEgid, - GhostBlockUtils.GhostCastMethod.GhostCastProportionalToBlockSize) - : maxDistance; - if (rayCast.hit && rayCast.distance <= distance) - return rayCast.hitEgid; //May be EGID.Empty (default) - - return default; - } - - public unsafe Block[] GetSelectedBlocks(uint playerid) - { - if (!entitiesDB.Exists(playerid, - BoxSelectExclusiveGroups.BoxSelectVolumeExclusiveGroup)) - return Array.Empty(); - var state = entitiesDB.QueryEntity(playerid, - BoxSelectExclusiveGroups.BoxSelectVolumeExclusiveGroup); - var blocks = entitiesDB.QueryEntity(playerid, - BoxSelectExclusiveGroups.BoxSelectVolumeExclusiveGroup); - if (!state.active) return Array.Empty(); - var pointer = (EGID*) blocks.selectedBlocks.ToPointer(); - var ret = new Block[blocks.count]; - for (int j = 0; j < blocks.count; j++) - { - var egid = pointer[j]; - ret[j] = Block.New(egid); - } - - return ret; - } - - public void EnterSeat(uint playerId, EGID seatId) - { - if (!TimeRunningModeUtil.IsTimeRunningMode(entitiesDB)) - return; - /*PilotSeatGroupUtils.SwapTagTo(Functions, seatId); - var opt = GetCharacterStruct(playerId, out var group); - if (!opt) return; - TODO: This is server code and mods run in client code atm. We can only send inputs even in singleplayer as it is. - ref CharacterPilotSeatEntityStruct charSeat = ref opt.Get(); - var charId = new EGID(playerId, group); - charSeat.pilotSeatEntity = entitiesDB.GetEntityReference(seatId); - charSeat.entryPositionOffset = - entitiesDB.QueryEntity(charId).position - - entitiesDB.QueryEntity(seatId).position; - ref var seat = ref entitiesDB.QueryEntity(seatId); - seat.occupyingCharacter = entitiesDB.GetEntityReference(charId); - charSeat.followCam = entitiesDB.QueryEntity(seatId).followCam; - Functions.SwapEntityGroup(charId, CharacterExclusiveGroups.InPilotSeatGroup);*/ - } - - public void ExitSeat(uint playerId) - { - if (!TimeRunningModeUtil.IsTimeRunningMode(entitiesDB)) - return; - /*EGID egid = new EGID(playerId, CharacterExclusiveGroups.InPilotSeatGroup); - var opt = entitiesDB.QueryEntityOptional(egid); - if (!opt) return; - opt.Get().instantExit = true; - entitiesDB.PublishEntityChange(egid);*/ - } - - public bool SpawnMachine(uint playerId) - { - if (!TimeRunningModeUtil.IsTimeRunningMode(entitiesDB)) - return false; - EGID egid = new EGID(playerId, CharacterExclusiveGroups.MachineSpawningGroup); - if (!entitiesDB.Exists(egid)) - return false; - if (entitiesDB.QueryEntity(egid).isMachinePlacementInvalid) - { - Logging.MetaDebugLog("Machine placement invalid"); - return false; - } - //Functions.SwapEntityGroup(egid, CharacterExclusiveGroups.OnFootGroup); - FakeInput.ActionInput(playerId, primary: true); - return true; - } - - public bool DespawnMachine(uint playerId) - { - if (!TimeRunningModeUtil.IsTimeRunningMode(entitiesDB)) - return false; - GetCharacterStruct(playerId, out var group); - if (group.isInvalid) - return false; - EGID egid = new EGID(playerId, group); - if (!entitiesDB.Exists(egid)) - return false; - Functions.SwapEntityGroup(egid, CharacterExclusiveGroups.MachineSpawningGroup); - return true; - } - - public uint GetPing() - { - return entitiesDB - .QueryUniqueEntity(MultiplayerExclusiveGroups.MultiplayerStateGroup) - .networkStats.PingMs; - } - - public Block GetGhostBlock(uint playerId) - { - var egid = new EGID(playerId, GHOST_BLOCKS_ENABLED.Group); - return entitiesDB.Exists(egid) ? Block.New(egid) : null; - } - } -} diff --git a/TechbloxModdingAPI/Players/PlayerEventsEngine.cs b/TechbloxModdingAPI/Players/PlayerEventsEngine.cs deleted file mode 100644 index cf90c40..0000000 --- a/TechbloxModdingAPI/Players/PlayerEventsEngine.cs +++ /dev/null @@ -1,45 +0,0 @@ -using System; -using RobocraftX.Character; -using RobocraftX.Character.Movement; -using RobocraftX.Common.Input; -using Svelto.ECS; - -using TechbloxModdingAPI.Engines; - -namespace TechbloxModdingAPI.Players -{ - public class PlayerEventsEngine : IApiEngine, IReactOnSwap, IReactOnAddAndRemove - { - public void Ready() - { - } - - public EntitiesDB entitiesDB { get; set; } - public void Dispose() - { - } - - public string Name => "TechbloxModdingAPIPlayerEventsEngine"; - public bool isRemovable => false; - - public void MovedTo(ref CharacterPilotSeatEntityStruct entityComponent, ExclusiveGroupStruct previousGroup, EGID egid) - { - entitiesDB.TryGetEGID(entityComponent.pilotSeatEntity, out var seatId); //TODO: Can't get EGID - var player = Player.GetInstance(egid.entityID); - if (previousGroup == CharacterExclusiveGroups.InPilotSeatGroup) - player.seatExited.Invoke(this, new PlayerSeatEventArgs { SeatId = seatId}); - else if (egid.groupID == CharacterExclusiveGroups.InPilotSeatGroup) - player.seatEntered.Invoke(this, new PlayerSeatEventArgs { SeatId = seatId }); - } - - public void Add(ref PlayerIDStruct entityComponent, EGID egid) - { - Player.joined.Invoke(this, new PlayerEventArgs { PlayerId = egid }); - } - - public void Remove(ref PlayerIDStruct entityComponent, EGID egid) - { - Player.left.Invoke(this, new PlayerEventArgs { PlayerId = egid }); - } - } -} \ No newline at end of file diff --git a/TechbloxModdingAPI/Players/PlayerExceptions.cs b/TechbloxModdingAPI/Players/PlayerExceptions.cs deleted file mode 100644 index 20dbea6..0000000 --- a/TechbloxModdingAPI/Players/PlayerExceptions.cs +++ /dev/null @@ -1,29 +0,0 @@ -using System; -namespace TechbloxModdingAPI.Players -{ - public class PlayerException : TechbloxModdingAPIException - { - public PlayerException() - { - } - - public PlayerException(string message) : base(message) - { - } - - public PlayerException(string message, Exception innerException) : base(message, innerException) - { - } - } - - public class PlayerNotFoundException : PlayerException - { - public PlayerNotFoundException() - { - } - - public PlayerNotFoundException(string message) : base(message) - { - } - } -} diff --git a/TechbloxModdingAPI/Players/PlayerState.cs b/TechbloxModdingAPI/Players/PlayerState.cs deleted file mode 100644 index 6ec6cbd..0000000 --- a/TechbloxModdingAPI/Players/PlayerState.cs +++ /dev/null @@ -1,9 +0,0 @@ -namespace TechbloxModdingAPI.Players -{ - public enum PlayerState - { - HoldingMachine, - OnFoot, - InSeat - } -} \ No newline at end of file diff --git a/TechbloxModdingAPI/Players/PlayerTests.cs b/TechbloxModdingAPI/Players/PlayerTests.cs deleted file mode 100644 index 32e9c14..0000000 --- a/TechbloxModdingAPI/Players/PlayerTests.cs +++ /dev/null @@ -1,97 +0,0 @@ -using System; -using System.Collections.Generic; - -using Svelto.Tasks; -using Svelto.Tasks.Enumerators; -using Unity.Mathematics; - -using TechbloxModdingAPI.App; -using TechbloxModdingAPI.Blocks; -using TechbloxModdingAPI.Tests; -using TechbloxModdingAPI.Utility; - -namespace TechbloxModdingAPI.Players -{ -#if TEST - /// - /// Player test cases. Not accessible in release versions. - /// - [APITestClass] - public static class PlayerTests - { - [APITestCase(TestType.EditMode)] - public static void ExistsTest() - { - if (!Assert.Equal(Player.Exists(PlayerType.Local), true, "Local player does not exist.", "Local player detected.")) return; - Assert.Equal(Player.Count(), 1u, "Player.Count() is not one, possibly because it failed silently.", "Player count is one for single player game."); - } - - [APITestCase(TestType.EditMode)] - public static void PositionTest() - { - Player p = Player.LocalPlayer; - if (!Assert.Errorless(() => { p.Teleport(0, 0, 0, relative: false); }, "Player.Teleport(origin) errored: ", "Player teleported to origin successfully.")) return; - if (!Assert.CloseTo(p.Position, float3.zero, "Player is not close to origin despite being teleported there.", "Player.Position is at origin.")) return; - if (!Assert.Errorless(() => { p.Position = float3.zero + 1; }, "Player.Position = origin+1 errored: ", "Player moved to origin+1.")) return; - Assert.CloseTo(p.Position, float3.zero + 1, "Player is not close to origin+1 despite being teleported there.", "Player.Position is at origin+1."); - } - - [APITestCase(TestType.Game)] - public static void SeatEventTestBuild() - { - Block.PlaceNew(BlockIDs.DriverSeat, Player.LocalPlayer.Position); - } - - [APITestCase(TestType.SimulationMode)] - public static IEnumerator SeatEventTestSim() - { - Player.LocalPlayer.SeatEntered += Assert.CallsBack("SeatEntered"); - Player.LocalPlayer.SeatExited += Assert.CallsBack("SeatExited"); - Assert.Equal(Player.LocalPlayer.SpawnMachine(), true, "Failed to spawn the player's machine.", "Successfully spawned the player's machine."); - yield return new WaitForSecondsEnumerator(1).Continue(); - var seats = Game.CurrentGame().GetBlocksInGame(BlockIDs.DriverSeat); - int c = 0; - while (seats.Length == 0 && c < 10) - { - Logging.MetaLog("Waiting for a seat to be spawned..."); - yield return new WaitForSecondsEnumerator(1).Continue(); - Logging.MetaLog("Spawn machine: " + Player.LocalPlayer.SpawnMachine()); - seats = Game.CurrentGame().GetBlocksInGame(BlockIDs.DriverSeat); - c++; - } - - if (seats.Length == 0) - { - Assert.Fail("No driver seat found!"); - yield break; - } - - if (seats[0] is Seat seat) - { - Assert.Errorless(() => Player.LocalPlayer.EnterSeat(seat), "Failed to enter seat.", - "Entered seat successfully."); - while (Player.LocalPlayer.State != PlayerState.InSeat) - { - bool cont = false; - Client.Instance.PromptUser(new SingleChoicePrompt("Testing", $"Enter the seat at {seat.Position} pls", "OK", () => cont = true)); - while (!cont) - yield return Yield.It; - yield return new WaitForSecondsEnumerator(5f).Continue(); - } - } - else - Assert.Fail("Found a seat that is not a seat!"); - yield return new WaitForSecondsEnumerator(5).Continue(); - Assert.Errorless(() => Player.LocalPlayer.ExitSeat(), "Failed to exit seat.", - "Exited seat successfully."); - } - - [APITestCase(TestType.Menu)] - public static void InvalidStateTest() - { - if (!Assert.Errorless(() => { Player.Count(); }, "Player.Count() errored in menu.", "Player.Count() succeeded in menu.")) return; - Assert.Equal(Player.Count(), 0u, "Player.Count() is not zero in menu.", "Player count is zero in menu as expected."); - } - } -#endif -} diff --git a/TechbloxModdingAPI/Players/PlayerType.cs b/TechbloxModdingAPI/Players/PlayerType.cs deleted file mode 100644 index 3e2214f..0000000 --- a/TechbloxModdingAPI/Players/PlayerType.cs +++ /dev/null @@ -1,9 +0,0 @@ -using System; -namespace TechbloxModdingAPI.Players -{ - public enum PlayerType - { - Local, - Remote - } -} diff --git a/TechbloxModdingAPI/SimBody.cs b/TechbloxModdingAPI/SimBody.cs deleted file mode 100644 index 1120103..0000000 --- a/TechbloxModdingAPI/SimBody.cs +++ /dev/null @@ -1,178 +0,0 @@ -using System; -using Svelto.ECS; -using Unity.Mathematics; -using UnityEngine; - -using Gamecraft.Damage; -using RobocraftX.Common; -using RobocraftX.Physics; -using Techblox.TimeRunning.Clusters; - -namespace TechbloxModdingAPI -{ - /// - /// A rigid body (like a chunk of connected blocks) during simulation. - /// - public class SimBody : EcsObjectBase, IEquatable, IEquatable - { - /// - /// The cluster this chunk belongs to, or null if no cluster destruction manager present or the chunk doesn't exist. - /// Get the SimBody from a Block if possible for good performance here. - /// - public Cluster Cluster => cluster ??= clusterId == uint.MaxValue // Return cluster or if it's null then set it - ? Block.BlockEngine.GetCluster(Id.entityID) // If we don't have a clusterId set then get it from the game - : GetInstance(new EGID(clusterId, ClustersExclusiveGroups.SIMULATION_CLUSTERS_GROUP), - egid => new Cluster(egid)); // Otherwise get the cluster from the ID - - private Cluster cluster; - private readonly uint clusterId = uint.MaxValue; - - public SimBody(EGID id) : base(id) - { - } - - public SimBody(uint id) : this(new EGID(id, CommonExclusiveGroups.SIMULATION_BODIES_GROUP)) - { - } - - internal SimBody(uint id, uint clusterID) : this(id) - { - clusterId = clusterID; - } - - /// - /// The position of this body. When setting the position, update the position of the connected bodies as well, - /// otherwise unexpected forces may arise. - /// - public float3 Position - { - get => GetStruct().position; - set => GetStruct().position = value; - } - - public float3 Velocity - { - get => GetStruct().velocity; - set => GetStruct().velocity = value; - } - - public float3 AngularVelocity - { - get => GetStruct().angularVelocity; - set => GetStruct().angularVelocity = value; - } //Delta versions are used internally, can't be set or get - - public float3 Rotation - { - get => ((Quaternion) GetStruct().rotation).eulerAngles; - set - { - ref var str = ref GetStruct(); - Quaternion quaternion = str.rotation; - quaternion.eulerAngles = value; - str.rotation = quaternion; - } - } - - [Obsolete] //Cannot get mass even from UECS - public float Mass - { - get => 0f; - //set => GetStruct().physicsMass.InverseMass = math.rcp(value); - } - - public float3 CenterOfMass - { - get => 0f; //TODO - //set => GetStruct().physicsMass.CenterOfMass = value; - } - - public float Volume - { - get => GetStruct().volume; - } - - public float InitialHealth - { - get => 0f; - set { } - } - - public float CurrentHealth - { - get => 0f; - set { } - } - - public float HealthMultiplier - { - get => 0f; - set { } - } - - /// - /// Whether the body can be moved or static. - /// - public bool Static => Block.BlockEngine.GetBlockInfo(this).isStatic; //Setting it doesn't have any effect - - /// - /// The rigid bodies connected to this one via functional joints (broken ones don't count). - /// - public SimBody[] GetConnectedBodies() - { - return Block.BlockEngine.GetConnectedSimBodies(Id.entityID); - } - - /// - /// The blocks that form this rigid body. - /// - /// - public Block[] GetBlocks() - { - return Block.BlockEngine.GetBodyBlocks(Id.entityID); - } - - private ref RigidBodyEntityStruct GetStruct() - { - return ref Block.BlockEngine.GetBlockInfo(this); - } - - public override string ToString() - { - return $"{nameof(Id)}: {Id}, {nameof(Position)}: {Position}, {nameof(Mass)}: {Mass}, {nameof(Static)}: {Static}"; - } - - public bool Equals(SimBody other) - { - if (ReferenceEquals(null, other)) return false; - if (ReferenceEquals(this, other)) return true; - return Id.Equals(other.Id); - } - - public bool Equals(EGID other) - { - return Id.Equals(other); - } - - public override bool Equals(object obj) - { - if (ReferenceEquals(null, obj)) return false; - if (ReferenceEquals(this, obj)) return true; - if (obj.GetType() != this.GetType()) return false; - return Equals((SimBody) obj); - } - - public override int GetHashCode() - { - return Id.GetHashCode(); - } - - /// - /// Returns the object identified by the given ID (A-Z). - /// This has the same result as calling ObjectIdentifier.GetByID(id) and then GetRigidBody() with the duplicates filtered out. - /// - /// The alphabetical ID - /// An array that may be empty - public static SimBody[] GetFromObjectID(char id) => Block.BlockEngine.GetSimBodiesFromID((byte) (id - 'A')); - } -} \ No newline at end of file diff --git a/TechbloxModdingAPI/Tasks/OnGuiRunner.cs b/TechbloxModdingAPI/Tasks/OnGuiRunner.cs deleted file mode 100644 index c1cc689..0000000 --- a/TechbloxModdingAPI/Tasks/OnGuiRunner.cs +++ /dev/null @@ -1,17 +0,0 @@ -using System.Collections; -using RobocraftX.Schedulers; -using Svelto.Tasks; -using Svelto.Tasks.ExtraLean; -using Svelto.Tasks.Unity.Internal; - -namespace TechbloxModdingAPI.Tasks -{ - public class OnGuiRunner : SteppableRunner> - { - public OnGuiRunner(string name, uint runningOrder = 0) - : base(name) - { - UnityCoroutineRunner.StartOnGuiCoroutine(this._processEnumerator, runningOrder); - } - } -} \ No newline at end of file diff --git a/TechbloxModdingAPI/TechbloxModdingAPI.csproj b/TechbloxModdingAPI/TechbloxModdingAPI.csproj deleted file mode 100644 index 5f6e410..0000000 --- a/TechbloxModdingAPI/TechbloxModdingAPI.csproj +++ /dev/null @@ -1,1592 +0,0 @@ - - - - netstandard2.1 - TechbloxModdingAPI - An object-oriented API for Techblox mods. - 3.0.0 - Exmods - GNU General Public Licence 3+ - https://git.exmods.org/modtainers/GamecraftModdingAPI - en-CA - true - latest - - - - - - - - - - - - - - - - - - - ..\ref_TB\Techblox_Data\Managed\Accessibility.dll - ..\..\ref_TB\Techblox_Data\Managed\Accessibility.dll - - - ..\ref_TB\Techblox_Data\Managed\Analytics.dll - ..\..\ref_TB\Techblox_Data\Managed\Analytics.dll - - - ..\ref_TB\Techblox_Data\Managed\Assembly-CSharp-firstpass.dll - ..\..\ref_TB\Techblox_Data\Managed\Assembly-CSharp-firstpass.dll - - - ..\ref_TB\Techblox_Data\Managed\Assembly-CSharp.dll - ..\..\ref_TB\Techblox_Data\Managed\Assembly-CSharp.dll - - - ..\ref_TB\Techblox_Data\Managed\Assembly-Csharp.dll - ..\..\ref_TB\Techblox_Data\Managed\Assembly-Csharp.dll - - - ..\ref_TB\Techblox_Data\Managed\AWSSDK.Core.dll - ..\..\ref_TB\Techblox_Data\Managed\AWSSDK.Core.dll - - - ..\ref_TB\Techblox_Data\Managed\AWSSDK.GameLift.dll - ..\..\ref_TB\Techblox_Data\Managed\AWSSDK.GameLift.dll - - - ..\ref_TB\Techblox_Data\Managed\BevelEffect.dll - ..\..\ref_TB\Techblox_Data\Managed\BevelEffect.dll - - - ..\ref_TB\Techblox_Data\Managed\Boxophobic.TheVehetationEngine.Runtime.dll - ..\..\ref_TB\Techblox_Data\Managed\Boxophobic.TheVehetationEngine.Runtime.dll - - - ..\ref_TB\Techblox_Data\Managed\Boxophobic.Utils.Scripts.dll - ..\..\ref_TB\Techblox_Data\Managed\Boxophobic.Utils.Scripts.dll - - - ..\ref_TB\Techblox_Data\Managed\DataLoader.dll - ..\..\ref_TB\Techblox_Data\Managed\DataLoader.dll - - - ..\ref_TB\Techblox_Data\Managed\DDNA.dll - ..\..\ref_TB\Techblox_Data\Managed\DDNA.dll - - - ..\ref_TB\Techblox_Data\Managed\EasyButtons.dll - ..\..\ref_TB\Techblox_Data\Managed\EasyButtons.dll - - - ..\ref_TB\Techblox_Data\Managed\EOSSDK.dll - ..\..\ref_TB\Techblox_Data\Managed\EOSSDK.dll - - - ..\ref_TB\Techblox_Data\Managed\FMODUnity.dll - ..\..\ref_TB\Techblox_Data\Managed\FMODUnity.dll - - - ..\ref_TB\Techblox_Data\Managed\FMODUnityResonance.dll - ..\..\ref_TB\Techblox_Data\Managed\FMODUnityResonance.dll - - - ..\ref_TB\Techblox_Data\Managed\FMODUnityWrapperClient.dll - ..\..\ref_TB\Techblox_Data\Managed\FMODUnityWrapperClient.dll - - - ..\ref_TB\Techblox_Data\Managed\FullGame.dll - ..\..\ref_TB\Techblox_Data\Managed\FullGame.dll - - - ..\ref_TB\Techblox_Data\Managed\Gamecraft.BlockEntityFactory.dll - ..\..\ref_TB\Techblox_Data\Managed\Gamecraft.BlockEntityFactory.dll - - - ..\ref_TB\Techblox_Data\Managed\Gamecraft.BlockGroups.dll - ..\..\ref_TB\Techblox_Data\Managed\Gamecraft.BlockGroups.dll - - - ..\ref_TB\Techblox_Data\Managed\Gamecraft.Blocks.LogicBlock.dll - ..\..\ref_TB\Techblox_Data\Managed\Gamecraft.Blocks.LogicBlock.dll - - - ..\ref_TB\Techblox_Data\Managed\Gamecraft.BlocksEntityDescriptors.dll - ..\..\ref_TB\Techblox_Data\Managed\Gamecraft.BlocksEntityDescriptors.dll - - - ..\ref_TB\Techblox_Data\Managed\Gamecraft.ColourPalette.dll - ..\..\ref_TB\Techblox_Data\Managed\Gamecraft.ColourPalette.dll - - - ..\ref_TB\Techblox_Data\Managed\Gamecraft.Damage.dll - ..\..\ref_TB\Techblox_Data\Managed\Gamecraft.Damage.dll - - - ..\ref_TB\Techblox_Data\Managed\Gamecraft.Effects.dll - ..\..\ref_TB\Techblox_Data\Managed\Gamecraft.Effects.dll - - - ..\ref_TB\Techblox_Data\Managed\Gamecraft.ExplosionFragments.dll - ..\..\ref_TB\Techblox_Data\Managed\Gamecraft.ExplosionFragments.dll - - - ..\ref_TB\Techblox_Data\Managed\Gamecraft.GraphicsSettings.dll - ..\..\ref_TB\Techblox_Data\Managed\Gamecraft.GraphicsSettings.dll - - - ..\ref_TB\Techblox_Data\Managed\Gamecraft.GUI.BlueprintInventory.dll - ..\..\ref_TB\Techblox_Data\Managed\Gamecraft.GUI.BlueprintInventory.dll - - - ..\ref_TB\Techblox_Data\Managed\Gamecraft.GUI.Blueprints.dll - ..\..\ref_TB\Techblox_Data\Managed\Gamecraft.GUI.Blueprints.dll - - - ..\ref_TB\Techblox_Data\Managed\Gamecraft.GUI.BlueprintSets.dll - ..\..\ref_TB\Techblox_Data\Managed\Gamecraft.GUI.BlueprintSets.dll - - - ..\ref_TB\Techblox_Data\Managed\Gamecraft.GUI.GameOptionsScreen.dll - ..\..\ref_TB\Techblox_Data\Managed\Gamecraft.GUI.GameOptionsScreen.dll - - - ..\ref_TB\Techblox_Data\Managed\Gamecraft.GUI.GraphicsScreen.dll - ..\..\ref_TB\Techblox_Data\Managed\Gamecraft.GUI.GraphicsScreen.dll - - - ..\ref_TB\Techblox_Data\Managed\Gamecraft.GUI.Hotbar.Blocks.dll - ..\..\ref_TB\Techblox_Data\Managed\Gamecraft.GUI.Hotbar.Blocks.dll - - - ..\ref_TB\Techblox_Data\Managed\Gamecraft.GUI.Hotbar.BlueprintsHotbar.dll - ..\..\ref_TB\Techblox_Data\Managed\Gamecraft.GUI.Hotbar.BlueprintsHotbar.dll - - - ..\ref_TB\Techblox_Data\Managed\Gamecraft.GUI.Hotbar.Colours.dll - ..\..\ref_TB\Techblox_Data\Managed\Gamecraft.GUI.Hotbar.Colours.dll - - - ..\ref_TB\Techblox_Data\Managed\Gamecraft.GUI.ModeBar.dll - ..\..\ref_TB\Techblox_Data\Managed\Gamecraft.GUI.ModeBar.dll - - - ..\ref_TB\Techblox_Data\Managed\Gamecraft.GUI.OptionsScreen.dll - ..\..\ref_TB\Techblox_Data\Managed\Gamecraft.GUI.OptionsScreen.dll - - - ..\ref_TB\Techblox_Data\Managed\Gamecraft.GUI.TabsBar.Blocks.dll - ..\..\ref_TB\Techblox_Data\Managed\Gamecraft.GUI.TabsBar.Blocks.dll - - - ..\ref_TB\Techblox_Data\Managed\Gamecraft.GUI.TabsBar.Blueprints.dll - ..\..\ref_TB\Techblox_Data\Managed\Gamecraft.GUI.TabsBar.Blueprints.dll - - - ..\ref_TB\Techblox_Data\Managed\Gamecraft.GUI.TabsBar.Colours.dll - ..\..\ref_TB\Techblox_Data\Managed\Gamecraft.GUI.TabsBar.Colours.dll - - - ..\ref_TB\Techblox_Data\Managed\Gamecraft.GUI.TabsBar.Common.dll - ..\..\ref_TB\Techblox_Data\Managed\Gamecraft.GUI.TabsBar.Common.dll - - - ..\ref_TB\Techblox_Data\Managed\Gamecraft.GUI.Tweaks.dll - ..\..\ref_TB\Techblox_Data\Managed\Gamecraft.GUI.Tweaks.dll - - - ..\ref_TB\Techblox_Data\Managed\Gamecraft.GUI.Wires.dll - ..\..\ref_TB\Techblox_Data\Managed\Gamecraft.GUI.Wires.dll - - - ..\ref_TB\Techblox_Data\Managed\Gamecraft.GUI.WorldSpaceGuis.dll - ..\..\ref_TB\Techblox_Data\Managed\Gamecraft.GUI.WorldSpaceGuis.dll - - - ..\ref_TB\Techblox_Data\Managed\Gamecraft.JointBlocks.dll - ..\..\ref_TB\Techblox_Data\Managed\Gamecraft.JointBlocks.dll - - - ..\ref_TB\Techblox_Data\Managed\Gamecraft.Music.dll - ..\..\ref_TB\Techblox_Data\Managed\Gamecraft.Music.dll - - - ..\ref_TB\Techblox_Data\Managed\Gamecraft.NetStrings.dll - ..\..\ref_TB\Techblox_Data\Managed\Gamecraft.NetStrings.dll - - - ..\ref_TB\Techblox_Data\Managed\Gamecraft.PickupsCommon.dll - ..\..\ref_TB\Techblox_Data\Managed\Gamecraft.PickupsCommon.dll - - - ..\ref_TB\Techblox_Data\Managed\Gamecraft.PopupMessage.dll - ..\..\ref_TB\Techblox_Data\Managed\Gamecraft.PopupMessage.dll - - - ..\ref_TB\Techblox_Data\Managed\Gamecraft.Serialization.dll - ..\..\ref_TB\Techblox_Data\Managed\Gamecraft.Serialization.dll - - - ..\ref_TB\Techblox_Data\Managed\Gamecraft.Tweaks.dll - ..\..\ref_TB\Techblox_Data\Managed\Gamecraft.Tweaks.dll - - - ..\ref_TB\Techblox_Data\Managed\Gamecraft.VisualEffects.Decals.dll - ..\..\ref_TB\Techblox_Data\Managed\Gamecraft.VisualEffects.Decals.dll - - - ..\ref_TB\Techblox_Data\Managed\Gamecraft.Wires.dll - ..\..\ref_TB\Techblox_Data\Managed\Gamecraft.Wires.dll - - - ..\ref_TB\Techblox_Data\Managed\GameLiftServerSDKNet45.dll - ..\..\ref_TB\Techblox_Data\Managed\GameLiftServerSDKNet45.dll - - - ..\ref_TB\Techblox_Data\Managed\GameState.dll - ..\..\ref_TB\Techblox_Data\Managed\GameState.dll - - - ..\ref_TB\Techblox_Data\Managed\GhostShark.Outline.dll - ..\..\ref_TB\Techblox_Data\Managed\GhostShark.Outline.dll - - - ..\ref_TB\Techblox_Data\Managed\Google.Protobuf.dll - ..\..\ref_TB\Techblox_Data\Managed\Google.Protobuf.dll - - - ..\ref_TB\Techblox_Data\Managed\GPUInstancer.CrowdAnimations.dll - ..\..\ref_TB\Techblox_Data\Managed\GPUInstancer.CrowdAnimations.dll - - - ..\ref_TB\Techblox_Data\Managed\GPUInstancer.dll - ..\..\ref_TB\Techblox_Data\Managed\GPUInstancer.dll - - - ..\ref_TB\Techblox_Data\Managed\Havok.Physics.dll - ..\..\ref_TB\Techblox_Data\Managed\Havok.Physics.dll - - - ..\ref_TB\Techblox_Data\Managed\Havok.Physics.Hybrid.dll - ..\..\ref_TB\Techblox_Data\Managed\Havok.Physics.Hybrid.dll - - - ..\ref_TB\Techblox_Data\Managed\LiteNetLib.dll - ..\..\ref_TB\Techblox_Data\Managed\LiteNetLib.dll - - - ..\ref_TB\Techblox_Data\Managed\log4net.dll - ..\..\ref_TB\Techblox_Data\Managed\log4net.dll - - - ..\ref_TB\Techblox_Data\Managed\LZ4.dll - ..\..\ref_TB\Techblox_Data\Managed\LZ4.dll - - - ..\ref_TB\Techblox_Data\Managed\Monobehaviours.dll - ..\..\ref_TB\Techblox_Data\Managed\Monobehaviours.dll - - - ..\ref_TB\Techblox_Data\Managed\mscorlib.dll - ..\..\ref_TB\Techblox_Data\Managed\mscorlib.dll - - - ..\ref_TB\Techblox_Data\Managed\MultiplayerNetworking.dll - ..\..\ref_TB\Techblox_Data\Managed\MultiplayerNetworking.dll - - - ..\ref_TB\Techblox_Data\Managed\Newtonsoft.Json.dll - ..\..\ref_TB\Techblox_Data\Managed\Newtonsoft.Json.dll - - - ..\ref_TB\Techblox_Data\Managed\Novell.Directory.Ldap.dll - ..\..\ref_TB\Techblox_Data\Managed\Novell.Directory.Ldap.dll - - - ..\ref_TB\Techblox_Data\Managed\Prometheus.NetStandard.dll - ..\..\ref_TB\Techblox_Data\Managed\Prometheus.NetStandard.dll - - - ..\ref_TB\Techblox_Data\Managed\RCX.ScreenshotTaker.dll - ..\..\ref_TB\Techblox_Data\Managed\RCX.ScreenshotTaker.dll - - - ..\ref_TB\Techblox_Data\Managed\Rewired_Core.dll - ..\..\ref_TB\Techblox_Data\Managed\Rewired_Core.dll - - - ..\ref_TB\Techblox_Data\Managed\Rewired_Windows.dll - ..\..\ref_TB\Techblox_Data\Managed\Rewired_Windows.dll - - - ..\ref_TB\Techblox_Data\Managed\RichFX.dll - ..\..\ref_TB\Techblox_Data\Managed\RichFX.dll - - - ..\ref_TB\Techblox_Data\Managed\RobocraftECS.dll - ..\..\ref_TB\Techblox_Data\Managed\RobocraftECS.dll - - - ..\ref_TB\Techblox_Data\Managed\RobocraftX.AccountPreferences.dll - ..\..\ref_TB\Techblox_Data\Managed\RobocraftX.AccountPreferences.dll - - - ..\ref_TB\Techblox_Data\Managed\RobocraftX.Blocks.dll - ..\..\ref_TB\Techblox_Data\Managed\RobocraftX.Blocks.dll - - - ..\ref_TB\Techblox_Data\Managed\RobocraftX.Blocks.Ghost.dll - ..\..\ref_TB\Techblox_Data\Managed\RobocraftX.Blocks.Ghost.dll - - - ..\ref_TB\Techblox_Data\Managed\RobocraftX.Blocks.Triggers.dll - ..\..\ref_TB\Techblox_Data\Managed\RobocraftX.Blocks.Triggers.dll - - - ..\ref_TB\Techblox_Data\Managed\RobocraftX.Building.BoxSelect.dll - ..\..\ref_TB\Techblox_Data\Managed\RobocraftX.Building.BoxSelect.dll - - - ..\ref_TB\Techblox_Data\Managed\RobocraftX.Building.Jobs.dll - ..\..\ref_TB\Techblox_Data\Managed\RobocraftX.Building.Jobs.dll - - - ..\ref_TB\Techblox_Data\Managed\RobocraftX.Character.Audio.dll - ..\..\ref_TB\Techblox_Data\Managed\RobocraftX.Character.Audio.dll - - - ..\ref_TB\Techblox_Data\Managed\RobocraftX.Character.dll - ..\..\ref_TB\Techblox_Data\Managed\RobocraftX.Character.dll - - - ..\ref_TB\Techblox_Data\Managed\RobocraftX.Common.dll - ..\..\ref_TB\Techblox_Data\Managed\RobocraftX.Common.dll - - - ..\ref_TB\Techblox_Data\Managed\RobocraftX.ControlsScreen.dll - ..\..\ref_TB\Techblox_Data\Managed\RobocraftX.ControlsScreen.dll - - - ..\ref_TB\Techblox_Data\Managed\RobocraftX.Crosshair.dll - ..\..\ref_TB\Techblox_Data\Managed\RobocraftX.Crosshair.dll - - - ..\ref_TB\Techblox_Data\Managed\RobocraftX.FrontEnd.dll - ..\..\ref_TB\Techblox_Data\Managed\RobocraftX.FrontEnd.dll - - - ..\ref_TB\Techblox_Data\Managed\RobocraftX.GUI.DebugDisplay.dll - ..\..\ref_TB\Techblox_Data\Managed\RobocraftX.GUI.DebugDisplay.dll - - - ..\ref_TB\Techblox_Data\Managed\RobocraftX.GUI.dll - ..\..\ref_TB\Techblox_Data\Managed\RobocraftX.GUI.dll - - - ..\ref_TB\Techblox_Data\Managed\RobocraftX.GUI.Hotbar.dll - ..\..\ref_TB\Techblox_Data\Managed\RobocraftX.GUI.Hotbar.dll - - - ..\ref_TB\Techblox_Data\Managed\RobocraftX.GUI.Inventory.BlocksInventory.dll - ..\..\ref_TB\Techblox_Data\Managed\RobocraftX.GUI.Inventory.BlocksInventory.dll - - - ..\ref_TB\Techblox_Data\Managed\RobocraftX.GUI.Inventory.ColourInventory.dll - ..\..\ref_TB\Techblox_Data\Managed\RobocraftX.GUI.Inventory.ColourInventory.dll - - - ..\ref_TB\Techblox_Data\Managed\RobocraftX.GUI.Inventory.dll - ..\..\ref_TB\Techblox_Data\Managed\RobocraftX.GUI.Inventory.dll - - - ..\ref_TB\Techblox_Data\Managed\RobocraftX.GUI.QuitConfirmation.dll - ..\..\ref_TB\Techblox_Data\Managed\RobocraftX.GUI.QuitConfirmation.dll - - - ..\ref_TB\Techblox_Data\Managed\RobocraftX.GUI.ScaleGhost.dll - ..\..\ref_TB\Techblox_Data\Managed\RobocraftX.GUI.ScaleGhost.dll - - - ..\ref_TB\Techblox_Data\Managed\RobocraftX.GUI.TabsBar.dll - ..\..\ref_TB\Techblox_Data\Managed\RobocraftX.GUI.TabsBar.dll - - - ..\ref_TB\Techblox_Data\Managed\RobocraftX.Input.dll - ..\..\ref_TB\Techblox_Data\Managed\RobocraftX.Input.dll - - - ..\ref_TB\Techblox_Data\Managed\RobocraftX.MachineEditor.dll - ..\..\ref_TB\Techblox_Data\Managed\RobocraftX.MachineEditor.dll - - - ..\ref_TB\Techblox_Data\Managed\RobocraftX.MainGame.dll - ..\..\ref_TB\Techblox_Data\Managed\RobocraftX.MainGame.dll - - - ..\ref_TB\Techblox_Data\Managed\RobocraftX.MainSimulation.Audio.dll - ..\..\ref_TB\Techblox_Data\Managed\RobocraftX.MainSimulation.Audio.dll - - - ..\ref_TB\Techblox_Data\Managed\RobocraftX.MainSimulation.dll - ..\..\ref_TB\Techblox_Data\Managed\RobocraftX.MainSimulation.dll - - - ..\ref_TB\Techblox_Data\Managed\RobocraftX.Multiplayer.dll - ..\..\ref_TB\Techblox_Data\Managed\RobocraftX.Multiplayer.dll - - - ..\ref_TB\Techblox_Data\Managed\RobocraftX.Multiplayer.NetworkEntityStream.dll - ..\..\ref_TB\Techblox_Data\Managed\RobocraftX.Multiplayer.NetworkEntityStream.dll - - - ..\ref_TB\Techblox_Data\Managed\RobocraftX.Multiplayer.Serializers.dll - ..\..\ref_TB\Techblox_Data\Managed\RobocraftX.Multiplayer.Serializers.dll - - - ..\ref_TB\Techblox_Data\Managed\RobocraftX.MultiplayerInput.dll - ..\..\ref_TB\Techblox_Data\Managed\RobocraftX.MultiplayerInput.dll - - - ..\ref_TB\Techblox_Data\Managed\RobocraftX.ObjectIdBlocks.dll - ..\..\ref_TB\Techblox_Data\Managed\RobocraftX.ObjectIdBlocks.dll - - - ..\ref_TB\Techblox_Data\Managed\RobocraftX.Physics.dll - ..\..\ref_TB\Techblox_Data\Managed\RobocraftX.Physics.dll - - - ..\ref_TB\Techblox_Data\Managed\RobocraftX.PilotSeat.dll - ..\..\ref_TB\Techblox_Data\Managed\RobocraftX.PilotSeat.dll - - - ..\ref_TB\Techblox_Data\Managed\RobocraftX.Player.dll - ..\..\ref_TB\Techblox_Data\Managed\RobocraftX.Player.dll - - - ..\ref_TB\Techblox_Data\Managed\RobocraftX.SaveAndLoad.dll - ..\..\ref_TB\Techblox_Data\Managed\RobocraftX.SaveAndLoad.dll - - - ..\ref_TB\Techblox_Data\Managed\RobocraftX.SaveGameDialog.dll - ..\..\ref_TB\Techblox_Data\Managed\RobocraftX.SaveGameDialog.dll - - - ..\ref_TB\Techblox_Data\Managed\RobocraftX.Services.dll - ..\..\ref_TB\Techblox_Data\Managed\RobocraftX.Services.dll - - - ..\ref_TB\Techblox_Data\Managed\RobocraftX.SignalHandling.dll - ..\..\ref_TB\Techblox_Data\Managed\RobocraftX.SignalHandling.dll - - - ..\ref_TB\Techblox_Data\Managed\RobocraftX.StateSync.dll - ..\..\ref_TB\Techblox_Data\Managed\RobocraftX.StateSync.dll - - - ..\ref_TB\Techblox_Data\Managed\Serilog.dll - ..\..\ref_TB\Techblox_Data\Managed\Serilog.dll - - - ..\ref_TB\Techblox_Data\Managed\Serilog.Sinks.Grafana.Loki.dll - ..\..\ref_TB\Techblox_Data\Managed\Serilog.Sinks.Grafana.Loki.dll - - - ..\ref_TB\Techblox_Data\Managed\ShaderVariantsGenerationTool.dll - ..\..\ref_TB\Techblox_Data\Managed\ShaderVariantsGenerationTool.dll - - - ..\ref_TB\Techblox_Data\Managed\SpecializedDescriptors.dll - ..\..\ref_TB\Techblox_Data\Managed\SpecializedDescriptors.dll - - - ..\ref_TB\Techblox_Data\Managed\StringFormatter.dll - ..\..\ref_TB\Techblox_Data\Managed\StringFormatter.dll - - - ..\ref_TB\Techblox_Data\Managed\Svelto.Common.dll - ..\..\ref_TB\Techblox_Data\Managed\Svelto.Common.dll - - - ..\ref_TB\Techblox_Data\Managed\Svelto.ECS.dll - ..\..\ref_TB\Techblox_Data\Managed\Svelto.ECS.dll - - - ..\ref_TB\Techblox_Data\Managed\Svelto.ECS.GUI.dll - ..\..\ref_TB\Techblox_Data\Managed\Svelto.ECS.GUI.dll - - - ..\ref_TB\Techblox_Data\Managed\Svelto.Services.dll - ..\..\ref_TB\Techblox_Data\Managed\Svelto.Services.dll - - - ..\ref_TB\Techblox_Data\Managed\Svelto.Tasks.dll - ..\..\ref_TB\Techblox_Data\Managed\Svelto.Tasks.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.AdditionalParts.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.AdditionalParts.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.AntiAFKServer.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.AntiAFKServer.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.Anticheat.Client.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.Anticheat.Client.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.Anticheat.Common.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.Anticheat.Common.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.AtmosphereBlock.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.AtmosphereBlock.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.AudioBlocks.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.AudioBlocks.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.AudioBlocksClient.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.AudioBlocksClient.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.AutoForward.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.AutoForward.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.Backend.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.Backend.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.BitBlock.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.BitBlock.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.BlockColours.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.BlockColours.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.BlockLabels.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.BlockLabels.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.BlockLabelsServer.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.BlockLabelsServer.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.Blocks.Connections.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.Blocks.Connections.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.Blocks.LightBlock.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.Blocks.LightBlock.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.Building.Rules.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.Building.Rules.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.Building.Shift.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.Building.Shift.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.BuildingDrone.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.BuildingDrone.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.Camera.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.Camera.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.CentreHUDBlock.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.CentreHUDBlock.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.CentreHUDGUI.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.CentreHUDGUI.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.CharacterDamage.Client.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.CharacterDamage.Client.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.CharacterDamage.Server.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.CharacterDamage.Server.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.CharacterRespawnScreen.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.CharacterRespawnScreen.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.CheckpointBlock.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.CheckpointBlock.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.CheckpointBlockClient.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.CheckpointBlockClient.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.Common.Audio.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.Common.Audio.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.ConstantBlockClient.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.ConstantBlockClient.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.ConstantBlockServer.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.ConstantBlockServer.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.ContextSensitiveTextHint.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.ContextSensitiveTextHint.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.CounterBlockClient.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.CounterBlockClient.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.CounterBlockServer.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.CounterBlockServer.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.DamageRbScoreBlockServerServer.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.DamageRbScoreBlockServerServer.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.DirectionalDamageVingette.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.DirectionalDamageVingette.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.DistanceSensorBlock.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.DistanceSensorBlock.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.ECSResourceManagers.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.ECSResourceManagers.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.EngineBlock.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.EngineBlock.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.EnvironmentBlocks.BuildingEnvironment.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.EnvironmentBlocks.BuildingEnvironment.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.EnvironmentBlocks.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.EnvironmentBlocks.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.EnvironmentBlocks.SimulationWorldEnvironment.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.EnvironmentBlocks.SimulationWorldEnvironment.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.Gameplay.Client.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.Gameplay.Client.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.Gameplay.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.Gameplay.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.Gameplay.GameState.Client.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.Gameplay.GameState.Client.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.Gameplay.GameState.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.Gameplay.GameState.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.Gameplay.PlayerGameplayDetails.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.Gameplay.PlayerGameplayDetails.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.Gameplay.Score.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.Gameplay.Score.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.Gameplay.Spawning.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.Gameplay.Spawning.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.Gameplay.Teams.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.Gameplay.Teams.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.Gameplay.WorldResetting.Client.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.Gameplay.WorldResetting.Client.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.Gameplay.WorldResetting.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.Gameplay.WorldResetting.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.GameSelection.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.GameSelection.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.GUI.Building.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.GUI.Building.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.GUI.BuildRules.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.GUI.BuildRules.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.GUI.CharacterHealthFeedback.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.GUI.CharacterHealthFeedback.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.GUI.Collection.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.GUI.Collection.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.GUI.Controls.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.GUI.Controls.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.GUI.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.GUI.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.GUI.GamePortal.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.GUI.GamePortal.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.GUI.GeneralSettingsScreen.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.GUI.GeneralSettingsScreen.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.GUI.Hotbar.Landscapes.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.GUI.Hotbar.Landscapes.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.GUI.Hotbar.Materials.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.GUI.Hotbar.Materials.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.GUI.Inventory.Common.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.GUI.Inventory.Common.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.GUI.Inventory.Landscapes.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.GUI.Inventory.Landscapes.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.GUI.Inventory.Materials.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.GUI.Inventory.Materials.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.GUI.LoadingBar.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.GUI.LoadingBar.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.GUI.Login.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.GUI.Login.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.GUI.MachineReconstructTimer.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.GUI.MachineReconstructTimer.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.GUI.MainGame.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.GUI.MainGame.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.GUI.MainGame.StateMachine.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.GUI.MainGame.StateMachine.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.GUI.MyGamesScreen.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.GUI.MyGamesScreen.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.GUI.PauseMenu.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.GUI.PauseMenu.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.GUI.Progression.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.GUI.Progression.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.GUI.TabsBar.Landscapes.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.GUI.TabsBar.Landscapes.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.GUI.TabsBar.Materials.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.GUI.TabsBar.Materials.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.GUI.UsernameDisplay.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.GUI.UsernameDisplay.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.InputCapture.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.InputCapture.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.JetBlock.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.JetBlock.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.JetBlockClient.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.JetBlockClient.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.KillScoreBlock.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.KillScoreBlock.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.MachineProcessingService.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.MachineProcessingService.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.MachineSimulationPreprocessing.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.MachineSimulationPreprocessing.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.MachineSpawning.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.MachineSpawning.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.MachineVelocityCameraEffects.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.MachineVelocityCameraEffects.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.Matchmaking.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.Matchmaking.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.Monitoring.Server.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.Monitoring.Server.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.Multiplayer.UsernameMessages.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.Multiplayer.UsernameMessages.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.ObjectIDBlockClient.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.ObjectIDBlockClient.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.ObjectIDBlockServer.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.ObjectIDBlockServer.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.Particles.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.Particles.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.PlayUX.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.PlayUX.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.Pointer.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.Pointer.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.ProceduralReflectionProbes.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.ProceduralReflectionProbes.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.Rendering.Common.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.Rendering.Common.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.Rendering.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.Rendering.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.Rendering.DOTS.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.Rendering.DOTS.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.Rendering.GPUI.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.Rendering.GPUI.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.Rendering.Unity.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.Rendering.Unity.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.SaveGamesConversion.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.SaveGamesConversion.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.ScoreHUDBlock.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.ScoreHUDBlock.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.ScoreHUDGUI.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.ScoreHUDGUI.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.ScorePickupBlockClient.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.ScorePickupBlockClient.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.ScorePickupBlockServer.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.ScorePickupBlockServer.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.Server.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.Server.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.Services.Anticheat.Client.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.Services.Anticheat.Client.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.Services.Eos.Common.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.Services.Eos.Common.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.Services.Eos.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.Services.Eos.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.Services.GameDetails.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.Services.GameDetails.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.Services.LocalPreferences.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.Services.LocalPreferences.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.Services.Matchmaking.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.Services.Matchmaking.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.Services.Metrics.Server.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.Services.Metrics.Server.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.Services.Progression.Client.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.Services.Progression.Client.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.Services.Progression.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.Services.Progression.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.Services.Storage.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.Services.Storage.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.Services.Users.Client.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.Services.Users.Client.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.Services.Users.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.Services.Users.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.ServoBlocksClient.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.ServoBlocksClient.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.ServoBlocksServer.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.ServoBlocksServer.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.ServosServer.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.ServosServer.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.SignalHandling.Audio.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.SignalHandling.Audio.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.SignalHandling.Common.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.SignalHandling.Common.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.Simulation.Clusters.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.Simulation.Clusters.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.SpawnBlock.Client.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.SpawnBlock.Client.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.SpawnBlock.Server.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.SpawnBlock.Server.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.StabilizerBlock.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.StabilizerBlock.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.StabilizerBlockClient.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.StabilizerBlockClient.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.SwitchAnimation.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.SwitchAnimation.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.TeamScoreBlockClient.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.TeamScoreBlockClient.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.TeamScoreBlockServer.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.TeamScoreBlockServer.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.TechpointConverterBlock.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.TechpointConverterBlock.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.TechpointConverterGUI.TechPointPoolHUD.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.TechpointConverterGUI.TechPointPoolHUD.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.TechpointConverterGUI.TechpointRewardPanel.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.TechpointConverterGUI.TechpointRewardPanel.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.TextBlock.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.TextBlock.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.TimerBlock.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.TimerBlock.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.TriggerBlock.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.TriggerBlock.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.Tweaks.Validation.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.Tweaks.Validation.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.VFXBlockClient.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.VFXBlockClient.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.VFXBlockServer.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.VFXBlockServer.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.VisualEffects.VFXGraph.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.VisualEffects.VFXGraph.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.Weapons.Aiming.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.Weapons.Aiming.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.Weapons.DisablerBlock.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.Weapons.DisablerBlock.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.Weapons.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.Weapons.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.Weapons.Projectiles.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.Weapons.Projectiles.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.Weapons.Projectiles.Server.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.Weapons.Projectiles.Server.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.Weapons.Server.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.Weapons.Server.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.WheelFX.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.WheelFX.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.WheelRigBlock.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.WheelRigBlock.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.Wheels.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.Wheels.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.WorldEditor.Spawning.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.WorldEditor.Spawning.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.WorldEditor.TestPlayers.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.WorldEditor.TestPlayers.dll - - - ..\ref_TB\Techblox_Data\Managed\Techblox.WorldResetterBlock.dll - ..\..\ref_TB\Techblox_Data\Managed\Techblox.WorldResetterBlock.dll - - - ..\ref_TB\Techblox_Data\Managed\UniTask.Addressables.dll - ..\..\ref_TB\Techblox_Data\Managed\UniTask.Addressables.dll - - - ..\ref_TB\Techblox_Data\Managed\UniTask.dll - ..\..\ref_TB\Techblox_Data\Managed\UniTask.dll - - - ..\ref_TB\Techblox_Data\Managed\UniTask.DOTween.dll - ..\..\ref_TB\Techblox_Data\Managed\UniTask.DOTween.dll - - - ..\ref_TB\Techblox_Data\Managed\UniTask.Linq.dll - ..\..\ref_TB\Techblox_Data\Managed\UniTask.Linq.dll - - - ..\ref_TB\Techblox_Data\Managed\UniTask.TextMeshPro.dll - ..\..\ref_TB\Techblox_Data\Managed\UniTask.TextMeshPro.dll - - - ..\ref_TB\Techblox_Data\Managed\Unity.Addressables.dll - ..\..\ref_TB\Techblox_Data\Managed\Unity.Addressables.dll - - - ..\ref_TB\Techblox_Data\Managed\Unity.Burst.dll - ..\..\ref_TB\Techblox_Data\Managed\Unity.Burst.dll - - - ..\ref_TB\Techblox_Data\Managed\Unity.Burst.Unsafe.dll - ..\..\ref_TB\Techblox_Data\Managed\Unity.Burst.Unsafe.dll - - - ..\ref_TB\Techblox_Data\Managed\Unity.Collections.dll - ..\..\ref_TB\Techblox_Data\Managed\Unity.Collections.dll - - - ..\ref_TB\Techblox_Data\Managed\Unity.Collections.LowLevel.ILSupport.dll - ..\..\ref_TB\Techblox_Data\Managed\Unity.Collections.LowLevel.ILSupport.dll - - - ..\ref_TB\Techblox_Data\Managed\Unity.Deformations.dll - ..\..\ref_TB\Techblox_Data\Managed\Unity.Deformations.dll - - - ..\ref_TB\Techblox_Data\Managed\Unity.Entities.dll - ..\..\ref_TB\Techblox_Data\Managed\Unity.Entities.dll - - - ..\ref_TB\Techblox_Data\Managed\Unity.Entities.Hybrid.dll - ..\..\ref_TB\Techblox_Data\Managed\Unity.Entities.Hybrid.dll - - - ..\ref_TB\Techblox_Data\Managed\Unity.InternalAPIEngineBridge.012.dll - ..\..\ref_TB\Techblox_Data\Managed\Unity.InternalAPIEngineBridge.012.dll - - - ..\ref_TB\Techblox_Data\Managed\Unity.Jobs.dll - ..\..\ref_TB\Techblox_Data\Managed\Unity.Jobs.dll - - - ..\ref_TB\Techblox_Data\Managed\Unity.Mathematics.dll - ..\..\ref_TB\Techblox_Data\Managed\Unity.Mathematics.dll - - - ..\ref_TB\Techblox_Data\Managed\Unity.Mathematics.Extensions.dll - ..\..\ref_TB\Techblox_Data\Managed\Unity.Mathematics.Extensions.dll - - - ..\ref_TB\Techblox_Data\Managed\Unity.Mathematics.Extensions.Hybrid.dll - ..\..\ref_TB\Techblox_Data\Managed\Unity.Mathematics.Extensions.Hybrid.dll - - - ..\ref_TB\Techblox_Data\Managed\Unity.MemoryProfiler.dll - ..\..\ref_TB\Techblox_Data\Managed\Unity.MemoryProfiler.dll - - - ..\ref_TB\Techblox_Data\Managed\Unity.Physics.dll - ..\..\ref_TB\Techblox_Data\Managed\Unity.Physics.dll - - - ..\ref_TB\Techblox_Data\Managed\Unity.Physics.Hybrid.dll - ..\..\ref_TB\Techblox_Data\Managed\Unity.Physics.Hybrid.dll - - - ..\ref_TB\Techblox_Data\Managed\Unity.Platforms.Common.dll - ..\..\ref_TB\Techblox_Data\Managed\Unity.Platforms.Common.dll - - - ..\ref_TB\Techblox_Data\Managed\Unity.Profiling.Core.dll - ..\..\ref_TB\Techblox_Data\Managed\Unity.Profiling.Core.dll - - - ..\ref_TB\Techblox_Data\Managed\Unity.Properties.dll - ..\..\ref_TB\Techblox_Data\Managed\Unity.Properties.dll - - - ..\ref_TB\Techblox_Data\Managed\Unity.Properties.Reflection.dll - ..\..\ref_TB\Techblox_Data\Managed\Unity.Properties.Reflection.dll - - - ..\ref_TB\Techblox_Data\Managed\Unity.Properties.UI.dll - ..\..\ref_TB\Techblox_Data\Managed\Unity.Properties.UI.dll - - - ..\ref_TB\Techblox_Data\Managed\Unity.Recorder.Base.dll - ..\..\ref_TB\Techblox_Data\Managed\Unity.Recorder.Base.dll - - - ..\ref_TB\Techblox_Data\Managed\Unity.Recorder.dll - ..\..\ref_TB\Techblox_Data\Managed\Unity.Recorder.dll - - - ..\ref_TB\Techblox_Data\Managed\Unity.Rendering.Hybrid.dll - ..\..\ref_TB\Techblox_Data\Managed\Unity.Rendering.Hybrid.dll - - - ..\ref_TB\Techblox_Data\Managed\Unity.RenderPipelines.Core.Runtime.dll - ..\..\ref_TB\Techblox_Data\Managed\Unity.RenderPipelines.Core.Runtime.dll - - - ..\ref_TB\Techblox_Data\Managed\Unity.RenderPipelines.Core.ShaderLibrary.dll - ..\..\ref_TB\Techblox_Data\Managed\Unity.RenderPipelines.Core.ShaderLibrary.dll - - - ..\ref_TB\Techblox_Data\Managed\Unity.RenderPipelines.HighDefinition.Config.Runtime.dll - ..\..\ref_TB\Techblox_Data\Managed\Unity.RenderPipelines.HighDefinition.Config.Runtime.dll - - - ..\ref_TB\Techblox_Data\Managed\Unity.RenderPipelines.HighDefinition.Runtime.dll - ..\..\ref_TB\Techblox_Data\Managed\Unity.RenderPipelines.HighDefinition.Runtime.dll - - - ..\ref_TB\Techblox_Data\Managed\Unity.RenderPipelines.ShaderGraph.ShaderGraphLibrary.dll - ..\..\ref_TB\Techblox_Data\Managed\Unity.RenderPipelines.ShaderGraph.ShaderGraphLibrary.dll - - - ..\ref_TB\Techblox_Data\Managed\Unity.ResourceManager.dll - ..\..\ref_TB\Techblox_Data\Managed\Unity.ResourceManager.dll - - - ..\ref_TB\Techblox_Data\Managed\Unity.Scenes.dll - ..\..\ref_TB\Techblox_Data\Managed\Unity.Scenes.dll - - - ..\ref_TB\Techblox_Data\Managed\Unity.ScriptableBuildPipeline.dll - ..\..\ref_TB\Techblox_Data\Managed\Unity.ScriptableBuildPipeline.dll - - - ..\ref_TB\Techblox_Data\Managed\Unity.Serialization.dll - ..\..\ref_TB\Techblox_Data\Managed\Unity.Serialization.dll - - - ..\ref_TB\Techblox_Data\Managed\Unity.TextMeshPro.dll - ..\..\ref_TB\Techblox_Data\Managed\Unity.TextMeshPro.dll - - - ..\ref_TB\Techblox_Data\Managed\Unity.Timeline.dll - ..\..\ref_TB\Techblox_Data\Managed\Unity.Timeline.dll - - - ..\ref_TB\Techblox_Data\Managed\Unity.Transforms.dll - ..\..\ref_TB\Techblox_Data\Managed\Unity.Transforms.dll - - - ..\ref_TB\Techblox_Data\Managed\Unity.Transforms.Hybrid.dll - ..\..\ref_TB\Techblox_Data\Managed\Unity.Transforms.Hybrid.dll - - - ..\ref_TB\Techblox_Data\Managed\Unity.VisualEffectGraph.Runtime.dll - ..\..\ref_TB\Techblox_Data\Managed\Unity.VisualEffectGraph.Runtime.dll - - - ..\ref_TB\Techblox_Data\Managed\UnityEngine.AccessibilityModule.dll - ..\..\ref_TB\Techblox_Data\Managed\UnityEngine.AccessibilityModule.dll - - - ..\ref_TB\Techblox_Data\Managed\UnityEngine.AIModule.dll - ..\..\ref_TB\Techblox_Data\Managed\UnityEngine.AIModule.dll - - - ..\ref_TB\Techblox_Data\Managed\UnityEngine.AndroidJNIModule.dll - ..\..\ref_TB\Techblox_Data\Managed\UnityEngine.AndroidJNIModule.dll - - - ..\ref_TB\Techblox_Data\Managed\UnityEngine.AnimationModule.dll - ..\..\ref_TB\Techblox_Data\Managed\UnityEngine.AnimationModule.dll - - - ..\ref_TB\Techblox_Data\Managed\UnityEngine.ARModule.dll - ..\..\ref_TB\Techblox_Data\Managed\UnityEngine.ARModule.dll - - - ..\ref_TB\Techblox_Data\Managed\UnityEngine.AssetBundleModule.dll - ..\..\ref_TB\Techblox_Data\Managed\UnityEngine.AssetBundleModule.dll - - - ..\ref_TB\Techblox_Data\Managed\UnityEngine.AudioModule.dll - ..\..\ref_TB\Techblox_Data\Managed\UnityEngine.AudioModule.dll - - - ..\ref_TB\Techblox_Data\Managed\UnityEngine.ClothModule.dll - ..\..\ref_TB\Techblox_Data\Managed\UnityEngine.ClothModule.dll - - - ..\ref_TB\Techblox_Data\Managed\UnityEngine.ClusterInputModule.dll - ..\..\ref_TB\Techblox_Data\Managed\UnityEngine.ClusterInputModule.dll - - - ..\ref_TB\Techblox_Data\Managed\UnityEngine.ClusterRendererModule.dll - ..\..\ref_TB\Techblox_Data\Managed\UnityEngine.ClusterRendererModule.dll - - - ..\ref_TB\Techblox_Data\Managed\UnityEngine.CoreModule.dll - ..\..\ref_TB\Techblox_Data\Managed\UnityEngine.CoreModule.dll - - - ..\ref_TB\Techblox_Data\Managed\UnityEngine.CrashReportingModule.dll - ..\..\ref_TB\Techblox_Data\Managed\UnityEngine.CrashReportingModule.dll - - - ..\ref_TB\Techblox_Data\Managed\UnityEngine.DirectorModule.dll - ..\..\ref_TB\Techblox_Data\Managed\UnityEngine.DirectorModule.dll - - - ..\ref_TB\Techblox_Data\Managed\UnityEngine.dll - ..\..\ref_TB\Techblox_Data\Managed\UnityEngine.dll - - - ..\ref_TB\Techblox_Data\Managed\UnityEngine.DSPGraphModule.dll - ..\..\ref_TB\Techblox_Data\Managed\UnityEngine.DSPGraphModule.dll - - - ..\ref_TB\Techblox_Data\Managed\UnityEngine.GameCenterModule.dll - ..\..\ref_TB\Techblox_Data\Managed\UnityEngine.GameCenterModule.dll - - - ..\ref_TB\Techblox_Data\Managed\UnityEngine.GIModule.dll - ..\..\ref_TB\Techblox_Data\Managed\UnityEngine.GIModule.dll - - - ..\ref_TB\Techblox_Data\Managed\UnityEngine.GridModule.dll - ..\..\ref_TB\Techblox_Data\Managed\UnityEngine.GridModule.dll - - - ..\ref_TB\Techblox_Data\Managed\UnityEngine.HotReloadModule.dll - ..\..\ref_TB\Techblox_Data\Managed\UnityEngine.HotReloadModule.dll - - - ..\ref_TB\Techblox_Data\Managed\UnityEngine.ImageConversionModule.dll - ..\..\ref_TB\Techblox_Data\Managed\UnityEngine.ImageConversionModule.dll - - - ..\ref_TB\Techblox_Data\Managed\UnityEngine.IMGUIModule.dll - ..\..\ref_TB\Techblox_Data\Managed\UnityEngine.IMGUIModule.dll - - - ..\ref_TB\Techblox_Data\Managed\UnityEngine.InputLegacyModule.dll - ..\..\ref_TB\Techblox_Data\Managed\UnityEngine.InputLegacyModule.dll - - - ..\ref_TB\Techblox_Data\Managed\UnityEngine.InputModule.dll - ..\..\ref_TB\Techblox_Data\Managed\UnityEngine.InputModule.dll - - - ..\ref_TB\Techblox_Data\Managed\UnityEngine.JSONSerializeModule.dll - ..\..\ref_TB\Techblox_Data\Managed\UnityEngine.JSONSerializeModule.dll - - - ..\ref_TB\Techblox_Data\Managed\UnityEngine.LocalizationModule.dll - ..\..\ref_TB\Techblox_Data\Managed\UnityEngine.LocalizationModule.dll - - - ..\ref_TB\Techblox_Data\Managed\UnityEngine.NVIDIAModule.dll - ..\..\ref_TB\Techblox_Data\Managed\UnityEngine.NVIDIAModule.dll - - - ..\ref_TB\Techblox_Data\Managed\UnityEngine.ParticleSystemModule.dll - ..\..\ref_TB\Techblox_Data\Managed\UnityEngine.ParticleSystemModule.dll - - - ..\ref_TB\Techblox_Data\Managed\UnityEngine.PerformanceReportingModule.dll - ..\..\ref_TB\Techblox_Data\Managed\UnityEngine.PerformanceReportingModule.dll - - - ..\ref_TB\Techblox_Data\Managed\UnityEngine.Physics2DModule.dll - ..\..\ref_TB\Techblox_Data\Managed\UnityEngine.Physics2DModule.dll - - - ..\ref_TB\Techblox_Data\Managed\UnityEngine.PhysicsModule.dll - ..\..\ref_TB\Techblox_Data\Managed\UnityEngine.PhysicsModule.dll - - - ..\ref_TB\Techblox_Data\Managed\UnityEngine.ProfilerModule.dll - ..\..\ref_TB\Techblox_Data\Managed\UnityEngine.ProfilerModule.dll - - - ..\ref_TB\Techblox_Data\Managed\UnityEngine.RuntimeInitializeOnLoadManagerInitializerModule.dll - ..\..\ref_TB\Techblox_Data\Managed\UnityEngine.RuntimeInitializeOnLoadManagerInitializerModule.dll - - - ..\ref_TB\Techblox_Data\Managed\UnityEngine.ScreenCaptureModule.dll - ..\..\ref_TB\Techblox_Data\Managed\UnityEngine.ScreenCaptureModule.dll - - - ..\ref_TB\Techblox_Data\Managed\UnityEngine.SharedInternalsModule.dll - ..\..\ref_TB\Techblox_Data\Managed\UnityEngine.SharedInternalsModule.dll - - - ..\ref_TB\Techblox_Data\Managed\UnityEngine.SpriteMaskModule.dll - ..\..\ref_TB\Techblox_Data\Managed\UnityEngine.SpriteMaskModule.dll - - - ..\ref_TB\Techblox_Data\Managed\UnityEngine.SpriteShapeModule.dll - ..\..\ref_TB\Techblox_Data\Managed\UnityEngine.SpriteShapeModule.dll - - - ..\ref_TB\Techblox_Data\Managed\UnityEngine.StreamingModule.dll - ..\..\ref_TB\Techblox_Data\Managed\UnityEngine.StreamingModule.dll - - - ..\ref_TB\Techblox_Data\Managed\UnityEngine.SubstanceModule.dll - ..\..\ref_TB\Techblox_Data\Managed\UnityEngine.SubstanceModule.dll - - - ..\ref_TB\Techblox_Data\Managed\UnityEngine.SubsystemsModule.dll - ..\..\ref_TB\Techblox_Data\Managed\UnityEngine.SubsystemsModule.dll - - - ..\ref_TB\Techblox_Data\Managed\UnityEngine.TerrainModule.dll - ..\..\ref_TB\Techblox_Data\Managed\UnityEngine.TerrainModule.dll - - - ..\ref_TB\Techblox_Data\Managed\UnityEngine.TerrainPhysicsModule.dll - ..\..\ref_TB\Techblox_Data\Managed\UnityEngine.TerrainPhysicsModule.dll - - - ..\ref_TB\Techblox_Data\Managed\UnityEngine.TextCoreFontEngineModule.dll - ..\..\ref_TB\Techblox_Data\Managed\UnityEngine.TextCoreFontEngineModule.dll - - - ..\ref_TB\Techblox_Data\Managed\UnityEngine.TextCoreTextEngineModule.dll - ..\..\ref_TB\Techblox_Data\Managed\UnityEngine.TextCoreTextEngineModule.dll - - - ..\ref_TB\Techblox_Data\Managed\UnityEngine.TextRenderingModule.dll - ..\..\ref_TB\Techblox_Data\Managed\UnityEngine.TextRenderingModule.dll - - - ..\ref_TB\Techblox_Data\Managed\UnityEngine.TilemapModule.dll - ..\..\ref_TB\Techblox_Data\Managed\UnityEngine.TilemapModule.dll - - - ..\ref_TB\Techblox_Data\Managed\UnityEngine.TLSModule.dll - ..\..\ref_TB\Techblox_Data\Managed\UnityEngine.TLSModule.dll - - - ..\ref_TB\Techblox_Data\Managed\UnityEngine.UI.dll - ..\..\ref_TB\Techblox_Data\Managed\UnityEngine.UI.dll - - - ..\ref_TB\Techblox_Data\Managed\UnityEngine.UIElementsModule.dll - ..\..\ref_TB\Techblox_Data\Managed\UnityEngine.UIElementsModule.dll - - - ..\ref_TB\Techblox_Data\Managed\UnityEngine.UIElementsNativeModule.dll - ..\..\ref_TB\Techblox_Data\Managed\UnityEngine.UIElementsNativeModule.dll - - - ..\ref_TB\Techblox_Data\Managed\UnityEngine.UIModule.dll - ..\..\ref_TB\Techblox_Data\Managed\UnityEngine.UIModule.dll - - - ..\ref_TB\Techblox_Data\Managed\UnityEngine.UmbraModule.dll - ..\..\ref_TB\Techblox_Data\Managed\UnityEngine.UmbraModule.dll - - - ..\ref_TB\Techblox_Data\Managed\UnityEngine.UNETModule.dll - ..\..\ref_TB\Techblox_Data\Managed\UnityEngine.UNETModule.dll - - - ..\ref_TB\Techblox_Data\Managed\UnityEngine.UnityAnalyticsModule.dll - ..\..\ref_TB\Techblox_Data\Managed\UnityEngine.UnityAnalyticsModule.dll - - - ..\ref_TB\Techblox_Data\Managed\UnityEngine.UnityConnectModule.dll - ..\..\ref_TB\Techblox_Data\Managed\UnityEngine.UnityConnectModule.dll - - - ..\ref_TB\Techblox_Data\Managed\UnityEngine.UnityCurlModule.dll - ..\..\ref_TB\Techblox_Data\Managed\UnityEngine.UnityCurlModule.dll - - - ..\ref_TB\Techblox_Data\Managed\UnityEngine.UnityTestProtocolModule.dll - ..\..\ref_TB\Techblox_Data\Managed\UnityEngine.UnityTestProtocolModule.dll - - - ..\ref_TB\Techblox_Data\Managed\UnityEngine.UnityWebRequestAssetBundleModule.dll - ..\..\ref_TB\Techblox_Data\Managed\UnityEngine.UnityWebRequestAssetBundleModule.dll - - - ..\ref_TB\Techblox_Data\Managed\UnityEngine.UnityWebRequestAudioModule.dll - ..\..\ref_TB\Techblox_Data\Managed\UnityEngine.UnityWebRequestAudioModule.dll - - - ..\ref_TB\Techblox_Data\Managed\UnityEngine.UnityWebRequestModule.dll - ..\..\ref_TB\Techblox_Data\Managed\UnityEngine.UnityWebRequestModule.dll - - - ..\ref_TB\Techblox_Data\Managed\UnityEngine.UnityWebRequestTextureModule.dll - ..\..\ref_TB\Techblox_Data\Managed\UnityEngine.UnityWebRequestTextureModule.dll - - - ..\ref_TB\Techblox_Data\Managed\UnityEngine.UnityWebRequestWWWModule.dll - ..\..\ref_TB\Techblox_Data\Managed\UnityEngine.UnityWebRequestWWWModule.dll - - - ..\ref_TB\Techblox_Data\Managed\UnityEngine.VehiclesModule.dll - ..\..\ref_TB\Techblox_Data\Managed\UnityEngine.VehiclesModule.dll - - - ..\ref_TB\Techblox_Data\Managed\UnityEngine.VFXModule.dll - ..\..\ref_TB\Techblox_Data\Managed\UnityEngine.VFXModule.dll - - - ..\ref_TB\Techblox_Data\Managed\UnityEngine.VideoModule.dll - ..\..\ref_TB\Techblox_Data\Managed\UnityEngine.VideoModule.dll - - - ..\ref_TB\Techblox_Data\Managed\UnityEngine.VirtualTexturingModule.dll - ..\..\ref_TB\Techblox_Data\Managed\UnityEngine.VirtualTexturingModule.dll - - - ..\ref_TB\Techblox_Data\Managed\UnityEngine.VRModule.dll - ..\..\ref_TB\Techblox_Data\Managed\UnityEngine.VRModule.dll - - - ..\ref_TB\Techblox_Data\Managed\UnityEngine.WindModule.dll - ..\..\ref_TB\Techblox_Data\Managed\UnityEngine.WindModule.dll - - - ..\ref_TB\Techblox_Data\Managed\UnityEngine.XRModule.dll - ..\..\ref_TB\Techblox_Data\Managed\UnityEngine.XRModule.dll - - - ..\ref_TB\Techblox_Data\Managed\VisualProfiler.dll - ..\..\ref_TB\Techblox_Data\Managed\VisualProfiler.dll - - - ..\ref_TB\Techblox_Data\Managed\websocket-sharp.dll - ..\..\ref_TB\Techblox_Data\Managed\websocket-sharp.dll - - - ..\ref_TB\Techblox_Data\Managed\ZFBrowser.dll - ..\..\ref_TB\Techblox_Data\Managed\ZFBrowser.dll - - - - - - - - - - - diff --git a/TechbloxModdingAPI/TechbloxModdingAPIException.cs b/TechbloxModdingAPI/TechbloxModdingAPIException.cs deleted file mode 100644 index 3a1b73f..0000000 --- a/TechbloxModdingAPI/TechbloxModdingAPIException.cs +++ /dev/null @@ -1,24 +0,0 @@ -using System; -using System.Runtime.Serialization; - -namespace TechbloxModdingAPI -{ - public class TechbloxModdingAPIException : Exception - { - public TechbloxModdingAPIException() - { - } - - public TechbloxModdingAPIException(string message) : base(message) - { - } - - public TechbloxModdingAPIException(string message, Exception innerException) : base(message, innerException) - { - } - - protected TechbloxModdingAPIException(SerializationInfo info, StreamingContext context) : base(info, context) - { - } - } -} diff --git a/TechbloxModdingAPI/Tests/APITestAttributes.cs b/TechbloxModdingAPI/Tests/APITestAttributes.cs deleted file mode 100644 index 0ebe81d..0000000 --- a/TechbloxModdingAPI/Tests/APITestAttributes.cs +++ /dev/null @@ -1,65 +0,0 @@ -using System; -namespace TechbloxModdingAPI.Tests -{ - /// - /// Test type. - /// When provided to APITestCaseAttribute, this dictates when the test case is called. - /// - public enum TestType - { - Menu, - Game, - SimulationMode, - EditMode, - } - - /// - /// API Test Class attribute. - /// Classes without this attribute will be ignored when searching for test cases. - /// - [AttributeUsage(AttributeTargets.Class)] - public class APITestClassAttribute : Attribute - { - internal string Name; - - public APITestClassAttribute(string name = "") - { - this.Name = name; - } - } - - /// - /// API Test Case attribute. - /// Static methods with this attribute will be called when the API test system is running. - /// - [AttributeUsage(AttributeTargets.Method)] - public class APITestCaseAttribute : Attribute - { - internal TestType TestType; - - public APITestCaseAttribute(TestType testType) - { - this.TestType = testType; - } - } - - /// - /// API Test StartUp attribute. - /// Static methods with this attribute will be called before any test case is run by the API test system. - /// - [AttributeUsage(AttributeTargets.Method)] - public class APITestStartUpAttribute : Attribute - { - - } - - /// - /// API Test TearDown attribute. - /// Static methods with this attribute will be called after all API test system test cases have completed (failed or succeeded). - /// - [AttributeUsage(AttributeTargets.Method)] - public class APITestTearDownAttribute : Attribute - { - - } -} diff --git a/TechbloxModdingAPI/Tests/Assert.cs b/TechbloxModdingAPI/Tests/Assert.cs deleted file mode 100644 index f71b132..0000000 --- a/TechbloxModdingAPI/Tests/Assert.cs +++ /dev/null @@ -1,239 +0,0 @@ -using System; -using System.Collections.Concurrent; -using System.IO; -using System.Runtime.CompilerServices; - -using Unity.Mathematics; - -namespace TechbloxModdingAPI.Tests -{ - /// - /// API test system assertion utilities. - /// - public static class Assert - { - private static StreamWriter logFile = null; - - private static ConcurrentDictionary callbacks = new ConcurrentDictionary(); - - private const string PASS = "SUCCESS: "; - - private const string FAIL = "FAILURE: "; - - private const string WARN = "WARNING: "; - - private const string INFO = "DEBUG: "; - - /// - /// Log a message to the test log. - /// - /// Message. - /// Message ending. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void Log(string msg, string end = "\n") - { - if (logFile == null) openTestLog(); - logFile.Write(msg + end); - logFile.Flush(); - } - - /// - /// Asserts that the event receives a callback... eventually. - /// Add the eventhandler returned by this method to the relevant event. - /// This does not assert that the callback happens under that event's intended circumstances. - /// Add another event handler to assert specific circumstance requirements. - /// - /// The callback event handler. - /// Event name. - /// Event error message. - /// The event handler callback argument object. - public static EventHandler CallsBack(string eventName, string eventMsg = null) - { - if (eventMsg == null) eventMsg = $"expected callback to {eventName} but it never occurred..."; - callbacks[eventName] = eventMsg; - - return (sender, args) => - { - string value = null; - if (!callbacks.TryRemove(eventName, out value)) { Log(WARN + $"callback to {eventName} occurred again or a related error occurred... (Received '{args.ToString()}' from '{(sender == null ? (string)sender : sender.ToString())}')"); } - Log(PASS + $"callback to {eventName} occurred... (Received '{args.ToString()}' from '{(sender == null ? (string)sender : sender.ToString())}')"); - TestRoot.TestsPassed = true; - }; - } - - public static bool NotNull(T obj, string err = null, string success = null) - { - if (err == null) err = $"{nameof(T)} object was null."; - if (success == null) success = $"{nameof(T)} '{obj}' not null"; - if (obj == null) - { - Log(FAIL + err); - TestRoot.TestsPassed = false; - return false; - } - else - { - Log(PASS + success); - TestRoot.TestsPassed = true; - return true; - } - } - - public static bool Equal(T obj1, T obj2, string err = null, string success = null) - { - if (err == null) err = $"{nameof(T)} '{obj1}' is not equal to '{obj2}'."; - if (success == null) success = $"{nameof(T)} '{obj1}' is equal to '{obj2}'."; - if ((obj1 == null && obj2 == null) - || (obj1 != null && obj2 != null && obj1.Equals(obj2) && obj2.Equals(obj1))) - { - // pass - Log(PASS + success); - TestRoot.TestsPassed = true; - return true; - } - else - { - // fail - Log(FAIL + err); - TestRoot.TestsPassed = false; - return false; - } - } - - public static bool Errorless(Action tryThis, string err = null, string success = null) - { - if (err == null) err = $"{tryThis} raised an exception: "; - if (success == null) success = $"{tryThis} completed without raising an exception."; - try - { - tryThis(); - } - catch (Exception e) - { - Log(FAIL + err + e); - TestRoot.TestsPassed = false; - return false; - } - TestRoot.TestsPassed = true; - Log(PASS + success); - return true; - } - - public static bool Errorful(Action tryThis, string err = null, string success = null) where T : Exception - { - if (err == null) err = $"{tryThis} was expected to error but completed without errors."; - if (success == null) success = $"{tryThis} completed with an expected error."; - try - { - tryThis(); - } - catch (T e) - { - TestRoot.TestsPassed = true; - Log(PASS + success + " " + e.GetType().Name + ": " + e.Message); - return true; - } - Log(FAIL + err); - TestRoot.TestsPassed = false; - return false; - } - - public static bool CloseTo(float a, float b, string err = null, string success = null, float delta = float.Epsilon) - { - if (err == null) err = $"{a} is not within {delta} of {b}."; - if (success == null) success = $"{a} is close enough to {b}."; - if (Math.Abs(a - b) > delta) - { - Log(FAIL + err); - TestRoot.TestsPassed = false; - return false; - } - else - { - TestRoot.TestsPassed = true; - Log(PASS + success); - return true; - } - } - - public static bool CloseTo(double a, double b, string err = null, string success = null, double delta = double.Epsilon) - { - if (err == null) err = $"{a} is not within {delta} of {b}."; - if (success == null) success = $"{a} is close enough to {b}."; - if (Math.Abs(a - b) > delta) - { - Log(FAIL + err); - TestRoot.TestsPassed = false; - return false; - } - else - { - TestRoot.TestsPassed = true; - Log(PASS + success); - return true; - } - } - - public static bool CloseTo(float3 a, float3 b, string err = null, string success = null, float delta = float.Epsilon) - { - if (err == null) err = $"{a} is not within {delta} of {b} in every direction."; - if (success == null) success = $"{a} is close enough to {b}."; - bool xClose = CloseTo(a.x, b.x, err, success, delta); - bool yClose = CloseTo(a.y, b.y, err, success, delta); - bool zClose = CloseTo(a.z, b.z, err, success, delta); - if (xClose && yClose && zClose) - { - //TestRoot.TestsPassed = true; - //Log(PASS + success); - return true; - } - else - { - //Log(FAIL + err); - //TestRoot.TestsPassed = false; - return false; - } - } - - public static void Fail(string msg = null) - { - if (msg == null) msg = $"Manual test failure with no message provided."; - Log(FAIL + msg); - TestRoot.TestsPassed = false; - } - - public static void Pass(string msg = null) - { - if (msg == null) msg = $"Manual test pass with no message provided."; - Log(PASS + msg); - TestRoot.TestsPassed = true; - } - - public static void Warn(string msg = null) - { - if (msg == null) msg = $"Manual test warning with no message provided."; - Log(WARN + msg); - TestRoot.TestsPassed = true; - } - - internal static void CallsComplete() - { - foreach(string key in callbacks.Keys) - { - Log(FAIL + callbacks[key]); - TestRoot.TestsPassed = false; - } - } - - internal static void CloseLog() - { - if (logFile != null) logFile.Close(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - private static void openTestLog() - { - logFile = File.CreateText(TestRoot.ReportFile); - } - } -} diff --git a/TechbloxModdingAPI/Tests/TechbloxModdingAPIPluginTest.cs b/TechbloxModdingAPI/Tests/TechbloxModdingAPIPluginTest.cs deleted file mode 100644 index 1f9c5f9..0000000 --- a/TechbloxModdingAPI/Tests/TechbloxModdingAPIPluginTest.cs +++ /dev/null @@ -1,84 +0,0 @@ -using System; -using System.Reflection; -using System.Text; -using BepInEx; -using BepInEx.Bootstrap; -using HarmonyLib; -using RobocraftX.FrontEnd; -using TechbloxModdingAPI.App; -using TechbloxModdingAPI.Commands; - -namespace TechbloxModdingAPI.Tests -{ - #if DEBUG // The API should be loaded by other plugins, but it can be used by itself for testing - [BepInPlugin("org.exmods.TechbloxModdingAPIPluginTest", PluginInfo.PLUGIN_NAME, PluginInfo.PLUGIN_VERSION)] - [BepInProcess("Techblox.exe")] - public class TechbloxModdingAPIPluginTest : BaseUnityPlugin - { - private void Awake() - { - Main.Init(); - Client.EnterMenu += (sender, args) => throw new Exception("Test handler always throws an exception!"); - Client.EnterMenu += (sender, args) => Console.WriteLine("EnterMenu handler after erroring handler"); - Game.Enter += (s, a) => - { - Player.LocalPlayer.SeatEntered += (sender, args) => - Console.WriteLine($"Player {Player.LocalPlayer} entered seat {args.Seat}"); - Player.LocalPlayer.SeatExited += (sender, args) => - Console.WriteLine($"Player {Player.LocalPlayer} exited seat {args.Seat}"); - }; - - CommandBuilder.Builder() - .Name("Exit") - .Description("Close Techblox immediately, without any prompts") - .Action(() => { UnityEngine.Application.Quit(); }) - .Build(); - - CommandBuilder.Builder() - .Name("SetFOV") - .Description("Set the player camera's field of view") - .Action((float d) => { UnityEngine.Camera.main.fieldOfView = d; }) - .Build(); - - Game.AddPersistentDebugInfo("InstalledMods", InstalledMods); - - // Plugin startup logic - Logger.LogInfo($"Plugin {PluginInfo.PLUGIN_GUID} is loaded!"); - -#if TEST - TestRoot.RunTests(); -#endif - } - - private void OnDestroy() - { - Main.Shutdown(); - } - - private string modsString; - private string InstalledMods() - { - if (modsString != null) return modsString; - StringBuilder sb = new StringBuilder("Installed mods:"); - foreach (var (_, plugin) in Chainloader.PluginInfos) - sb.Append("\n" + plugin.Metadata.Name + " - " + plugin.Metadata.Version); - return modsString = sb.ToString(); - } - } - - [HarmonyPatch] - public class MinimumSpecsPatch - { - public static bool Prefix(ref bool __result) - { - __result = true; - return false; - } - - public static MethodInfo TargetMethod() - { - return ((Func) MinimumSpecsCheck.CheckRequirementsMet).Method; - } - } - #endif -} diff --git a/TechbloxModdingAPI/Tests/TestRoot.cs b/TechbloxModdingAPI/Tests/TestRoot.cs deleted file mode 100644 index 5306adc..0000000 --- a/TechbloxModdingAPI/Tests/TestRoot.cs +++ /dev/null @@ -1,303 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Diagnostics; -using System.Reflection; -using System.Linq; // welcome to the dark side - -using Svelto.Tasks; -using Svelto.Tasks.Lean; -using Svelto.Tasks.Enumerators; -using Svelto.Tasks.Lean.Unity; -using UnityEngine; - -using TechbloxModdingAPI.App; -using TechbloxModdingAPI.Tasks; -using TechbloxModdingAPI.Utility; - -namespace TechbloxModdingAPI.Tests -{ - /// - /// API test system root class. - /// - public static class TestRoot - { - public static bool AutoShutdown = true; - - public const string ReportFile = "TechbloxModdingAPI_tests.log"; - - private static bool _testsPassed = false; - - private static uint _testsCount = 0; - - private static uint _testsCountPassed = 0; - - private static uint _testsCountFailed = 0; - - private static string state = "StartingUp"; - - private static Stopwatch timer; - - private static List testTypes = null; - - public static bool TestsPassed - { - get => _testsPassed; - set - { - _testsPassed = _testsPassed && value; - _testsCount++; - if (value) - { - _testsCountPassed++; - } - else - { - _testsCountFailed++; - } - } - } - - private static void StartUp() - { - // init - timer = Stopwatch.StartNew(); - _testsPassed = true; - _testsCount = 0; - _testsCountPassed = 0; - _testsCountFailed = 0; - // flow control - Game.Enter += (sender, args) => { GameTests().RunOn(new UpdateMonoRunner("TechbloxModdingAPITestRunner")); }; - Game.Exit += (s, a) => state = "ReturningFromGame"; - Client.EnterMenu += (sender, args) => - { - if (state == "EnteringMenu") - { - MenuTests().RunOn(Scheduler.leanRunner); - state = "EnteringGame"; - } - if (state == "ReturningFromGame") - { - TearDown().RunOn(Scheduler.leanRunner); - state = "ShuttingDown"; - } - }; - // init tests here - foreach (Type t in testTypes) - { - foreach (MethodBase m in t.GetMethods()) - { - if (m.GetCustomAttribute() != null) - { - try - { - m.Invoke(null, new object[0]); - } - catch (Exception e) - { - Assert.Fail($"Start up method '{m}' raised an exception: {e.ToString()}"); - } - } - } - } - state = "EnteringMenu"; - } - - private static IEnumerator MenuTests() - { - yield return Yield.It; - // menu tests - foreach (Type t in testTypes) - { - foreach (MethodBase m in t.GetMethods()) - { - APITestCaseAttribute a = m.GetCustomAttribute(); - if (a != null && a.TestType == TestType.Menu) - { - try - { - m.Invoke(null, new object[0]); - } - catch (Exception e) - { - Assert.Fail($"Menu test '{m}' raised an exception: {e.ToString()}"); - } - yield return Yield.It; - } - } - } - // load game - yield return GoToGameTests().Continue(); - } - - private static IEnumerator GoToGameTests() - { - Client app = Client.Instance; - int oldLength = 0; - while (app.MyGames.Length == 0 || oldLength != app.MyGames.Length) - { - oldLength = app.MyGames.Length; - yield return new WaitForSecondsEnumerator(1).Continue(); - } - yield return Yield.It; - try - { - app.MyGames[0].EnterGame(); - } - catch (Exception e) - { - Console.WriteLine("Failed to go to game tests"); - Console.WriteLine(e); - } - /*Game newGame = Game.NewGame(); - yield return new WaitForSecondsEnumerator(5).Continue(); // wait for sync - newGame.EnterGame();*/ - } - - private static IEnumerator GameTests() - { - yield return Yield.It; - Game currentGame = Game.CurrentGame(); - // in-game tests - yield return new WaitForSecondsEnumerator(5).Continue(); // wait for game to finish loading - var testTypesToRun = new[] - { - TestType.Game, - TestType.SimulationMode, - TestType.EditMode - }; - for (var index = 0; index < testTypesToRun.Length; index++) - { - Logging.MetaLog($"Running test type {testTypesToRun[index]}"); - foreach (Type t in testTypes) - { - foreach (MethodBase m in t.GetMethods()) - { - APITestCaseAttribute a = m.GetCustomAttribute(); - if (a == null || a.TestType != testTypesToRun[index]) continue; - - object ret = null; - try - { - ret = m.Invoke(null, new object[0]); - } - catch (Exception e) - { - Assert.Fail($"{a.TestType} test '{m}' raised an exception: {e}"); - } - - if (ret is IEnumerator enumerator) - { //Support enumerator methods with added exception handling - bool cont; - do - { //Can't use yield return in a try block... - try - { //And with Continue() exceptions aren't caught - cont = enumerator.MoveNext(); - } - catch (Exception e) - { - Assert.Fail($"{a.TestType} test '{m}' raised an exception: {e}"); - cont = false; - } - - if (cont) - yield return enumerator.Current; - } while (cont); - } - - yield return new WaitForSecondsEnumerator(1f).Continue(); - } - } - - if (index + 1 < testTypesToRun.Length) //Don't toggle on the last test - { - bool running = currentGame.IsTimeRunning; - currentGame.ToggleTimeMode(); - while (running ? !currentGame.IsTimeStopped : !currentGame.IsTimeRunning) - { - Logging.MetaLog($"Waiting for time to {(running?"stop":"start")}..."); - yield return new WaitForSecondsEnumerator(1).Continue(); - } - } - - yield return new WaitForSecondsEnumerator(5).Continue(); - } - // exit game - yield return ReturnToMenu().Continue(); - } - - private static IEnumerator ReturnToMenu() - { - Logging.MetaLog("Returning to main menu"); - yield return Yield.It; - Game.CurrentGame().ExitGame(); - } - - private static IEnumerator TearDown() - { - yield return new WaitForSecondsEnumerator(5).Continue(); - Logging.MetaLog("Tearing down test run"); - // dispose tests here - foreach (Type t in testTypes) - { - foreach (MethodBase m in t.GetMethods()) - { - if (m.GetCustomAttribute() != null) - { - try - { - m.Invoke(null, new object[0]); - } - catch (Exception e) - { - Assert.Warn($"Tear down method '{m}' raised an exception: {e.ToString()}"); - } - yield return Yield.It; - } - } - } - // finish up - Assert.CallsComplete(); - timer.Stop(); - string verdict = _testsPassed ? "--- PASSED :) ---" : "--- FAILED :( ---"; - Assert.Log($"VERDICT: {verdict} ({_testsCountPassed}/{_testsCountFailed}/{_testsCount} P/F/T in {timer.ElapsedMilliseconds}ms)"); - yield return Yield.It; - // end game - Logging.MetaLog("Completed test run: " + verdict); - yield return Yield.It; - Assert.CloseLog(); - if (AutoShutdown) Application.Quit(); - } - - private static void FindTests(Assembly asm) - { - testTypes = new List(); - foreach (Type t in asm.GetTypes()) - { - if (t.GetCustomAttribute() != null) - { - testTypes.Add(t); - } - } - } - - /// - /// Runs the tests. - /// - /// Assembly to search for tests. When set to null, this uses the TechbloxModdingAPI assembly. - public static void RunTests(Assembly asm = null) - { - if (asm == null) asm = Assembly.GetExecutingAssembly(); - FindTests(asm); - Logging.MetaLog("Starting test run"); - // log metadata - Assert.Log($"Unity {Application.unityVersion}"); - Assert.Log($"Techblox {Application.version}"); - Assert.Log($"TechbloxModdingAPI {Assembly.GetExecutingAssembly().GetName().Version}"); - Assert.Log($"Testing {asm.GetName().Name} {asm.GetName().Version}"); - Assert.Log($"START: --- {DateTime.Now.ToString()} --- ({testTypes.Count} tests classes detected)"); - StartUp(); - Logging.MetaLog("Test StartUp complete"); - } - } -} diff --git a/TechbloxModdingAPI/Tests/TestTest.cs b/TechbloxModdingAPI/Tests/TestTest.cs deleted file mode 100644 index 5e0ed46..0000000 --- a/TechbloxModdingAPI/Tests/TestTest.cs +++ /dev/null @@ -1,52 +0,0 @@ -using System; - -using System.Reflection; - -using HarmonyLib; - -namespace TechbloxModdingAPI.Tests -{ -#if TEST - /// - /// Test test test. - /// - [APITestClass] - public static class TestTest - { - public static event EventHandler StartUp; - - public static event EventHandler Test; - - public static event EventHandler TearDown; - - [APITestStartUp] - public static void Init() - { - StartUp += Assert.CallsBack("TestStartUp"); - Test += Assert.CallsBack("TestCase"); - TearDown += Assert.CallsBack("TestTearDown"); - StartUp(null, default(TestEventArgs)); - } - - [APITestCase(TestType.Menu)] - public static void RunTest() - { - Test(null, default(TestEventArgs)); - } - - [APITestTearDown] - public static void End() - { - TearDown(null, default(TestEventArgs)); - } - } - - public struct TestEventArgs - { - public override string ToString() - { - return "TestEventArgs{}"; - } - } -#endif -} diff --git a/TechbloxModdingAPI/Tests/TestValueAttribute.cs b/TechbloxModdingAPI/Tests/TestValueAttribute.cs deleted file mode 100644 index 48794c9..0000000 --- a/TechbloxModdingAPI/Tests/TestValueAttribute.cs +++ /dev/null @@ -1,18 +0,0 @@ -using System; - -namespace TechbloxModdingAPI.Tests -{ - [AttributeUsage(AttributeTargets.Property)] - public class TestValueAttribute : Attribute - { - public object PossibleValue { get; } - - /// - /// - /// When set, the property test accepts the specified value in addition to the test input.
- /// Useful if setting the property isn't always possible. - /// - ///
- public TestValueAttribute(object possibleValue) => PossibleValue = possibleValue; - } -} \ No newline at end of file diff --git a/TechbloxModdingAPI/Utility/ApiExclusiveGroups.cs b/TechbloxModdingAPI/Utility/ApiExclusiveGroups.cs deleted file mode 100644 index a451673..0000000 --- a/TechbloxModdingAPI/Utility/ApiExclusiveGroups.cs +++ /dev/null @@ -1,55 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -using Svelto.ECS; - -namespace TechbloxModdingAPI.Utility -{ - public static class ApiExclusiveGroups - { - private static ExclusiveGroup _eventsExclusiveGroup = null; - - public static ExclusiveGroup eventsExclusiveGroup - { - get - { - if (_eventsExclusiveGroup == null) - { - _eventsExclusiveGroup = new ExclusiveGroup("TechbloxModdingAPI EventGroup"); - } - return _eventsExclusiveGroup; - } - } - - public static uint eventID; - - private static ExclusiveGroup _versionGroup = null; - - public static ExclusiveGroup versionGroup - { - get - { - if (_versionGroup == null) - { - _versionGroup = new ExclusiveGroup("TechbloxModdingAPI VersionGroup"); - } - return _versionGroup; - } - } - - private static ExclusiveGroup _customBlockGroup; - - public static ExclusiveGroup customBlockGroup - { - get - { - if (_customBlockGroup == null) - _customBlockGroup = new ExclusiveGroup("TechbloxModdingAPI CustomBlockGroup"); - return _customBlockGroup; - } - } - } -} diff --git a/TechbloxModdingAPI/Utility/Audio.cs b/TechbloxModdingAPI/Utility/Audio.cs deleted file mode 100644 index 71b7f66..0000000 --- a/TechbloxModdingAPI/Utility/Audio.cs +++ /dev/null @@ -1,90 +0,0 @@ -using System; -using System.Reflection; - -using FMOD.Studio; -using FMODUnity; -using RobocraftX.Common.Audio; -using Unity.Mathematics; - -namespace TechbloxModdingAPI.Utility -{ - public class Audio - { - private EventInstance sound; - - public Audio(string uri) : this(RuntimeManager.PathToGUID(uri)) - { - } - - public Audio(Guid uri) - { - sound = RuntimeManager.CreateInstance(uri); - } - - public static Audio Random() - { - System.Random potato = new System.Random(); - FieldInfo[] options = typeof(FMODAudioEvents).GetFields(); - Guid audio_uri; - while (true) - { - int index = potato.Next(0, options.Length); - try - { - audio_uri = (Guid)options[index].GetValue(null); - break; - } - catch (InvalidCastException) { } - } - return new Audio(audio_uri); - } - - public float this[string key] - { - get - { - sound.getParameterByName(key, out float val, out float finalVal); - return val; - } - - set => sound.setParameterByName(key, value); - } - - public float this[PARAMETER_ID index] - { - get - { - sound.getParameterByID(index, out float val, out float finalVal); - return val; - } - - set => sound.setParameterByID(index, value); - } - - public float3 Position - { - get - { - sound.get3DAttributes(out FMOD.ATTRIBUTES_3D attr); - return new float3(attr.position.x, attr.position.y, attr.position.z); - } - - set => sound.set3DAttributes(RuntimeUtils.To3DAttributes(value)); - } - - public void Play() - { - sound.start(); - } - - public void Stop(FMOD.Studio.STOP_MODE mode = FMOD.Studio.STOP_MODE.IMMEDIATE) - { - sound.stop(mode); - } - - ~Audio() // Use the wannabe C++ destructor to destroy the C++ object - { - sound.release(); - } - } -} diff --git a/TechbloxModdingAPI/Utility/DebugInterfaceEngine.cs b/TechbloxModdingAPI/Utility/DebugInterfaceEngine.cs deleted file mode 100644 index 7f9d97c..0000000 --- a/TechbloxModdingAPI/Utility/DebugInterfaceEngine.cs +++ /dev/null @@ -1,85 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Reflection; -using System.Reflection.Emit; -using System.Text; -using System.Text.Formatting; -using TechbloxModdingAPI.Blocks; -using TechbloxModdingAPI.Players; -using HarmonyLib; -using RobocraftX.GUI.Debug; -using Svelto.ECS; -using Svelto.ECS.Experimental; -using TechbloxModdingAPI.Engines; - -namespace TechbloxModdingAPI.Utility -{ - public class DebugInterfaceEngine : IApiEngine - { - private static Dictionary> _extraInfo=new Dictionary>(); - public void Ready() - { - } - - public EntitiesDB entitiesDB { get; set; } - - public void Dispose() - { - } - - public void SetInfo(string id, Func contentGetter) => _extraInfo[id] = contentGetter; - public bool RemoveInfo(string id) => _extraInfo.Remove(id); - - public string Name => "TechbloxModdingAPIDebugInterfaceGameEngine"; - public bool isRemovable => true; - - [HarmonyPatch] - private class Patch - { - public static IEnumerable Transpiler(IEnumerable instructions) - { - var list = new List(instructions); - try - { - //Before setting the text from the StringBuffer - int index = list.FindLastIndex(inst => inst.opcode == OpCodes.Ldfld); - var array = new CodeInstruction[] - { - new CodeInstruction(OpCodes.Ldloc_0), //StringBuffer - new CodeInstruction(OpCodes.Call, ((Action)AddInfo).Method) - }; - list.InsertRange(index - 1, array); //-1: ldloc.1 ("local") before ldfld - } - catch (Exception e) - { - Logging.LogWarning("Failed to inject AddInfo method for the debug display!\n" + e); - } - - return list; - } - - public static void AddInfo(StringBuilder sb) - { - foreach (var info in _extraInfo) - { - try - { - string text = info.Value().Trim(); - if (text.Length != 0) - sb.Append(text + "\n"); - } - catch (Exception e) - { - Logging.LogWarning("Unable to get info for " + info.Key + "\n" + e); - } - } - } - - public static MethodInfo TargetMethod() - { - return AccessTools.Method("RobocraftX.GUI.Debug.DebugDisplayEngine:UpdateDisplay"); - } - } - } -} \ No newline at end of file diff --git a/TechbloxModdingAPI/Utility/Dependency.cs b/TechbloxModdingAPI/Utility/Dependency.cs deleted file mode 100644 index b160ac9..0000000 --- a/TechbloxModdingAPI/Utility/Dependency.cs +++ /dev/null @@ -1,47 +0,0 @@ -using System; -using BepInEx.Bootstrap; - -namespace TechbloxModdingAPI.Utility -{ - /// - /// Simple plugin interaction operations - /// - public static class Dependency - { - /// - /// Find a plugin by name - /// - /// The plugin. - /// The plugin's name. - public static BepInEx.PluginInfo GetPlugin(string name) - { - foreach(var plugin in Chainloader.PluginInfos.Values) - { - if (plugin.Metadata.Name == name) - { - return plugin; - } - } - return null; - } - - /// - /// Gets the plugin version. - /// This gives priority to the plugin's Version string but falls back to the Assembly's version - /// - /// The plugin's version. - /// The plugin's name. - public static Version GetPluginVersion(string name) - { - var plugin = GetPlugin(name); - if (plugin != null) { - try - { - return plugin.Metadata.Version; - } catch (Exception e) when (e is ArgumentException or FormatException or OverflowException) {} - return plugin.GetType().Assembly.GetName().Version; - } - return null; - } - } -} diff --git a/TechbloxModdingAPI/Utility/ECS/ManagedApiExtensions.cs b/TechbloxModdingAPI/Utility/ECS/ManagedApiExtensions.cs deleted file mode 100644 index e689666..0000000 --- a/TechbloxModdingAPI/Utility/ECS/ManagedApiExtensions.cs +++ /dev/null @@ -1,75 +0,0 @@ -using Svelto.ECS; -using Svelto.ECS.Hybrid; - -namespace TechbloxModdingAPI.Utility.ECS -{ - public static class ManagedApiExtensions - { - /// - /// Attempts to query an entity and returns an optional that contains the result if succeeded. - /// This overload does not take initializer data into account. - /// - /// The entities DB - /// The EGID to query - /// The component type to query - /// An optional that contains the result on success or is empty if not found - public static OptionalRef QueryEntityOptional(this EntitiesDB entitiesDB, EGID egid) - where T : struct, IEntityViewComponent - { - return entitiesDB.TryQueryEntitiesAndIndex(egid, out uint index, out var array) - ? new OptionalRef(array, index) - : new OptionalRef(); - } - - /// - /// Attempts to query an entity and returns the result in an optional reference. - /// - /// The entities DB to query from - /// The ECS object to query - /// The group of the entity if the object can have multiple - /// The component to query - /// A reference to the component or a dummy value - public static OptionalRef QueryEntityOptional(this EntitiesDB entitiesDB, EcsObjectBase obj, - ExclusiveGroupStruct group = default) - where T : struct, IEntityViewComponent - { - EGID id = group == ExclusiveGroupStruct.Invalid ? obj.Id : new EGID(obj.Id.entityID, group); - var opt = QueryEntityOptional(entitiesDB, id); - return opt ? opt : new OptionalRef(obj, false); - } - - /// - /// Attempts to query an entity and returns the result or a dummy value that can be modified. - /// - /// The entities DB to query from - /// The ECS object to query - /// The group of the entity if the object can have multiple - /// The component to query - /// A reference to the component or a dummy value - public static ref T QueryEntityOrDefault(this EntitiesDB entitiesDB, EcsObjectBase obj, - ExclusiveGroupStruct group = default) - where T : struct, IEntityViewComponent - { - EGID id = group == ExclusiveGroupStruct.Invalid ? obj.Id : new EGID(obj.Id.entityID, group); - var opt = QueryEntityOptional(entitiesDB, id); - if (opt) return ref opt.Get(); - if (obj.InitData.Valid) return ref obj.InitData.Initializer(id).GetOrAdd(); - return ref opt.Get(); //Default value - } - - /// - /// Query entities as OptionalRefs. The elements always exist, it's just a nice way to encapsulate the data. - /// - /// - /// - /// - /// - /// - /// - public static RefCollection QueryEntitiesOptional(this EntitiesDB entitiesDB, ExclusiveGroupStruct group) where T : struct, IEntityViewComponent - { - var (buffer, ids, count) = entitiesDB.QueryEntities(group); - return new RefCollection(count, buffer, ids, group); - } - } -} \ No newline at end of file diff --git a/TechbloxModdingAPI/Utility/ECS/NativeApiExtensions.EntitiesDBHelper.cs b/TechbloxModdingAPI/Utility/ECS/NativeApiExtensions.EntitiesDBHelper.cs deleted file mode 100644 index 5922478..0000000 --- a/TechbloxModdingAPI/Utility/ECS/NativeApiExtensions.EntitiesDBHelper.cs +++ /dev/null @@ -1,56 +0,0 @@ -using System; -using System.Diagnostics.CodeAnalysis; -using System.Linq; -using System.Reflection; -using HarmonyLib; -using Svelto.DataStructures; -using Svelto.ECS; - -namespace TechbloxModdingAPI.Utility.ECS -{ - public static partial class NativeApiExtensions - { - [SuppressMessage("ReSharper", "StaticMemberInGenericType")] - private static class EntitiesDBHelper where T : unmanaged, IEntityComponent - { // Each type gets a new set of fields here (that's what the ReSharper warning is about too) - public static readonly Lazy EntityStream = - new(() => AccessTools.PropertyGetter(typeof(EntitiesDB), "_entityStream")); - - public static readonly Lazy Streams = new(() => - AccessTools.Field(EntityStream.Value.ReturnType, "_streams")); - - public static readonly Lazy Consumers = new(() => - AccessTools.Field(typeof(EntityStream), "_consumers")); - - public static readonly Lazy TryGetValue = - new(AccessTools.Method(Streams.Value.FieldType, "TryGetValue")); - - public static readonly Lazy RingBuffer = - new(() => AccessTools.Field(typeof(Consumer), "_ringBuffer")); - } - - private static EntityStream GetEntityStream(this EntitiesDB entitiesDB) where T : unmanaged, IEntityComponent - { - // EntitiesStreams (internal) - var entitiesStreams = EntitiesDBHelper.EntityStream.Value.Invoke(entitiesDB, Array.Empty()); - // FasterDictionary (interface is internal) - var streams = EntitiesDBHelper.Streams.Value.GetValue(entitiesStreams); - - var parameters = new object[] { TypeRefWrapper.wrapper, null }; - var success = EntitiesDBHelper.TryGetValue.Value.Invoke(streams, parameters); - if (!(bool)success) - return null; // There is no entity stream for this type - return (EntityStream)parameters[1]; - } - - private static ThreadSafeFasterList> GetConsumers(this EntityStream stream) where T : unmanaged, IEntityComponent - { - return (ThreadSafeFasterList>)EntitiesDBHelper.Consumers.Value.GetValue(stream); - } - - private static RingBuffer<(T, EGID)> GetRingBuffer(this Consumer consumer) where T : unmanaged, IEntityComponent - { - return (RingBuffer<(T, EGID)>)EntitiesDBHelper.RingBuffer.Value.GetValue(consumer); - } - } -} \ No newline at end of file diff --git a/TechbloxModdingAPI/Utility/ECS/NativeApiExtensions.cs b/TechbloxModdingAPI/Utility/ECS/NativeApiExtensions.cs deleted file mode 100644 index 9cd0b64..0000000 --- a/TechbloxModdingAPI/Utility/ECS/NativeApiExtensions.cs +++ /dev/null @@ -1,129 +0,0 @@ -using System; -using System.Collections.Generic; -using Svelto.DataStructures; -using Svelto.ECS; -using Svelto.Tasks; -using Svelto.Tasks.Lean; -using TechbloxModdingAPI.Tasks; - -namespace TechbloxModdingAPI.Utility.ECS -{ - public static partial class NativeApiExtensions - { - /// - /// Attempts to query an entity and returns an optional that contains the result if succeeded. - /// This overload does not take initializer data into account. - /// - /// The entities DB - /// The EGID to query - /// The component type to query - /// An optional that contains the result on success or is empty if not found - public static OptionalRef QueryEntityOptional(this EntitiesDB entitiesDB, EGID egid) - where T : unmanaged, IEntityComponent - { - return entitiesDB.TryQueryEntitiesAndIndex(egid, out uint index, out var array) - ? new OptionalRef(array, index) - : new OptionalRef(); - } - - /// - /// Attempts to query an entity and returns the result in an optional reference. - /// - /// The entities DB to query from - /// The ECS object to query - /// The group of the entity if the object can have multiple - /// The component to query - /// A reference to the component or a dummy value - public static OptionalRef QueryEntityOptional(this EntitiesDB entitiesDB, EcsObjectBase obj, - ExclusiveGroupStruct group = default) - where T : unmanaged, IEntityComponent - { - EGID id = group == ExclusiveGroupStruct.Invalid ? obj.Id : new EGID(obj.Id.entityID, group); - var opt = QueryEntityOptional(entitiesDB, id); - return opt ? opt : new OptionalRef(obj, true); - } - - /// - /// Attempts to query an entity and returns the result or a dummy value that can be modified. - /// - /// The entities DB to query from - /// The ECS object to query - /// The group of the entity if the object can have multiple - /// The component to query - /// A reference to the component or a dummy value - public static ref T QueryEntityOrDefault(this EntitiesDB entitiesDB, EcsObjectBase obj, - ExclusiveGroupStruct group = default) - where T : unmanaged, IEntityComponent - { - EGID id = group == ExclusiveGroupStruct.Invalid ? obj.Id : new EGID(obj.Id.entityID, group); - var opt = QueryEntityOptional(entitiesDB, id); - if (opt) return ref opt.Get(); - if (obj.InitData.Valid) return ref obj.InitData.Initializer(id).GetOrAdd(); - /*if (!obj.InitData.Valid) return ref opt.Get(); //Default value - var init = obj.InitData.Initializer(id); - // Do not create the component if missing, as that can trigger Add() listeners that, in some cases, may be - // invalid if (ab)using the classes in an unusual way - TODO: Check entity descriptor or something - if (init.Has()) return ref init.Get();*/ - return ref opt.Get(); //Default value - } - - /// - /// Publishes an entity change, ignoring duplicate publishes and delaying changes as necessary. - /// It will only publish in the next frame. - /// - /// The entities DB to publish to - /// The ECS object that got changed - /// The component that changed - public static void PublishEntityChangeDelayed(this EntitiesDB entitiesDB, EGID id) - where T : unmanaged, IEntityComponent - { - PublishChanges(entitiesDB, id).RunOn(Scheduler.leanRunner); - } - - private static IEnumerator PublishChanges(EntitiesDB entitiesDB, EGID id) - where T : unmanaged, IEntityComponent - { - yield return Yield.It; - var entityStream = entitiesDB.GetEntityStream(); - if (entityStream is null) - yield break; // There is no entity stream for this type - var consumers = entityStream.GetConsumers(); - if (consumers == null) - { - Console.WriteLine("Consumers is null"); - yield break; - } - - bool waitForConsumers; - do - { - waitForConsumers = false; - for (int i = 0; i < consumers.count; i++) - { - var buffer = consumers[i].GetRingBuffer(); - if (buffer.Count + 1 <= buffer.Capacity) continue; - waitForConsumers = true; - break; - } - - if (waitForConsumers) yield return Yield.It; - } while (waitForConsumers); - entitiesDB.PublishEntityChange(id); - } - - /// - /// Query entities as OptionalRefs. The elements always exist, it's just a nice way to encapsulate the data. - /// - /// - /// - /// - /// - /// - /// - public static RefCollection QueryEntitiesOptional(this EntitiesDB entitiesDB, ExclusiveGroupStruct group) where T : unmanaged, IEntityComponent - { - var (buffer, ids, count) = entitiesDB.QueryEntities(group); - return new RefCollection(count, buffer, ids, group); - } - } -} \ No newline at end of file diff --git a/TechbloxModdingAPI/Utility/OptionalRef.cs b/TechbloxModdingAPI/Utility/OptionalRef.cs deleted file mode 100644 index 4e3325b..0000000 --- a/TechbloxModdingAPI/Utility/OptionalRef.cs +++ /dev/null @@ -1,116 +0,0 @@ -using System; -using Svelto.DataStructures; -using Svelto.ECS; - -namespace TechbloxModdingAPI.Utility -{ - public ref struct OptionalRef where T : struct, IBaseEntityComponent - { - private readonly EGID entityId; - private readonly State state; - private readonly uint index; - private NB array; - private MB managedArray; - private readonly EntityInitializer initializer; - //The possible fields are: (index && (array || managedArray)) || initializer - - public OptionalRef(NB array, uint index, EGID entityId = default) - { - state = State.Native; - this.array = array; - this.index = index; - this.entityId = entityId; - initializer = default; - managedArray = default; - } - - public OptionalRef(MB array, uint index, EGID entityId = default) - { - state = State.Managed; - managedArray = array; - this.index = index; - this.entityId = entityId; - initializer = default; - this.array = default; - } - - /// - /// Wraps the initializer data, if present. - /// - /// The object with the initializer - /// Whether the struct is unmanaged - public OptionalRef(EcsObjectBase obj, bool unmanaged, EGID entityId = default) - { - this.entityId = entityId; - if (obj.InitData.Valid) - { - initializer = obj.InitData.Initializer(obj.Id); - state = (unmanaged ? State.Native : State.Managed) | State.Initializer; - } - else - { - initializer = default; - state = State.Empty; - } - array = default; - index = default; - managedArray = default; - } - - /// - /// Returns the value or a default value if empty. Supports objects that are being initialized. - /// - /// The value or the default value - public ref T Get() - { - CompRefCache.Default = default; //The default value can be changed by mods - if (state == State.Empty) return ref CompRefCache.Default; - if ((state & State.Initializer) != State.Empty) return ref initializer.GetOrAdd(); - if ((state & State.Native) != State.Empty) return ref array[index]; - return ref managedArray[index]; - } - - /// - /// A non-by-ref view that allows getting and setting the value. - /// - public T Value - { - get => Get(); - set => Get() = value; - } - - /// - /// The ID of the entity this component belongs to or default if it doesn't exist. - /// - public EGID EGID => entityId; - - public bool Exists => state != State.Empty; - public T? Nullable() => this ? Get() : default; - - public static implicit operator T(OptionalRef opt) => opt.Get(); - - public static implicit operator bool(OptionalRef opt) => opt.state != State.Empty; - - public static implicit operator EGID(OptionalRef opt) => opt.entityId; - - /// - /// Creates an instance of a struct T that can be referenced. - /// - private struct CompRefCache - { - public static T Default; - } - - /// - /// A byte that holds state in its bits. - /// - [Flags] - private enum State : byte - { - Empty, - Native, - Managed, - Initializer = 4 - } - } -} \ No newline at end of file diff --git a/TechbloxModdingAPI/Utility/RefCollection.cs b/TechbloxModdingAPI/Utility/RefCollection.cs deleted file mode 100644 index 29d82d5..0000000 --- a/TechbloxModdingAPI/Utility/RefCollection.cs +++ /dev/null @@ -1,94 +0,0 @@ -using System; -using Svelto.DataStructures; -using Svelto.ECS; -using Svelto.ECS.Hybrid; -using Svelto.ECS.Internal; - -namespace TechbloxModdingAPI.Utility -{ - public readonly ref struct RefCollection where T : struct, IBaseEntityComponent - { - private readonly bool managed; - private readonly int count; - private readonly NB nativeArray; - private readonly MB managedArray; - private readonly NativeEntityIDs nativeIDs; - private readonly ManagedEntityIDs managedIDs; - private readonly ExclusiveGroupStruct group; - - public RefCollection(int count, MB managedArray, ManagedEntityIDs managedIDs, ExclusiveGroupStruct group) - { - this.count = count; - this.managedArray = managedArray; - this.managedIDs = managedIDs; - this.group = group; - managed = true; - nativeArray = default; - nativeIDs = default; - } - - public RefCollection(int count, NB nativeArray, NativeEntityIDs nativeIDs, ExclusiveGroupStruct group) - { - this.count = count; - this.nativeArray = nativeArray; - this.nativeIDs = nativeIDs; - this.group = group; - managed = false; - managedArray = default; - managedIDs = default; - } - - public Enumerator GetEnumerator() => new(this); - - /// - /// The amount of items in the collection. - /// - public int Count => count; - - public T[] ToArray() => ToArray(a => a.Component); - - public TA[] ToArray(Func<(T Component, EGID ID), TA> transformFunction, Predicate<(T Component, EGID ID)> predicateFunction = null) - { - var result = new TA[Count]; - int i = 0; - foreach (var opt in this) - { - if (predicateFunction != null && !predicateFunction((opt.Get(), opt.EGID))) continue; - result[i] = transformFunction((opt.Get(), opt.EGID)); - i++; - } - - return result; - } - - public ref struct Enumerator - { - private RefCollection coll; - private int index; - - public Enumerator(RefCollection collection) - { - index = -1; - coll = collection; - } - - public OptionalRef Current - { - get - { - if (coll.count <= index && index >= 0) return default; - if (coll.managed) - return new OptionalRef(coll.managedArray, (uint)index, - new EGID(coll.managedIDs[index], coll.group)); - return new OptionalRef(coll.nativeArray, (uint)index, - new EGID(coll.nativeIDs[index], coll.group)); - } - } - - public bool MoveNext() - { - return ++index < coll.count; - } - } - } -} \ No newline at end of file diff --git a/TechbloxModdingAPI/Utility/WeakDictionary.cs b/TechbloxModdingAPI/Utility/WeakDictionary.cs deleted file mode 100644 index 6c4cf57..0000000 --- a/TechbloxModdingAPI/Utility/WeakDictionary.cs +++ /dev/null @@ -1,105 +0,0 @@ -using System; -using System.Collections; -using System.Collections.Generic; -using System.Linq; - -namespace TechbloxModdingAPI.Utility -{ - public class WeakDictionary : IDictionary where TValue : class - { - private readonly Dictionary> _dictionary = new(); - - public IEnumerator> GetEnumerator() - { - using var enumerator = _dictionary.GetEnumerator(); - while (enumerator.MoveNext()) - { - if (enumerator.Current.Value.TryGetTarget(out var value)) - yield return new KeyValuePair(enumerator.Current.Key, value); - } - } - - IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); - public void Add(KeyValuePair item) => Add(item.Key, item.Value); - public void Clear() => _dictionary.Clear(); - public bool Contains(KeyValuePair item) => - TryGetValue(item.Key, out var value) && item.Value == value; - public void CopyTo(KeyValuePair[] array, int arrayIndex) => - throw new System.NotImplementedException(); - public bool Remove(KeyValuePair item) => Contains(item) && Remove(item.Key); - public int Count => _dictionary.Count; - public bool IsReadOnly => false; - public bool ContainsKey(TKey key) => TryGetValue(key, out _); - public void Add(TKey key, TValue value) => _dictionary.Add(key, new WeakReference(value)); - public bool Remove(TKey key) => _dictionary.Remove(key); - - public bool TryGetValue(TKey key, out TValue value) - { - value = null; - bool ret = _dictionary.TryGetValue(key, out var reference) && reference.TryGetTarget(out value); - if (!ret) _dictionary.Remove(key); - return ret; - } - - public TValue this[TKey key] - { - get => TryGetValue(key, out var value) - ? value - : throw new KeyNotFoundException($"Key {key} not found in WeakDictionary."); - set => _dictionary[key] = new WeakReference(value); - } - - public ICollection Keys => new KeyCollection(this); - public ICollection Values => new ValueCollection(this); - - public class KeyCollection : ICollection, IReadOnlyCollection - { - private readonly WeakDictionary _dictionary; - internal KeyCollection(WeakDictionary dictionary) - { - _dictionary = dictionary; - } - - public IEnumerator GetEnumerator() - { - using var enumerator = _dictionary.GetEnumerator(); - while (enumerator.MoveNext()) - yield return enumerator.Current.Key; - } - - IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); - public void Add(TKey item) => throw new NotSupportedException("The key collection is read only."); - public void Clear() => throw new NotSupportedException("The key collection is read only."); - public bool Contains(TKey item) => _dictionary.ContainsKey(item); - public void CopyTo(TKey[] array, int arrayIndex) => throw new NotImplementedException(); - public bool Remove(TKey item) => throw new NotSupportedException("The key collection is read only."); - public int Count => _dictionary.Count; - public bool IsReadOnly => true; - } - - public class ValueCollection : ICollection, IReadOnlyCollection - { - private readonly WeakDictionary _dictionary; - internal ValueCollection(WeakDictionary dictionary) - { - _dictionary = dictionary; - } - - public IEnumerator GetEnumerator() - { - using var enumerator = _dictionary.GetEnumerator(); - while (enumerator.MoveNext()) - yield return enumerator.Current.Value; - } - - IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); - public void Add(TValue item) => throw new NotSupportedException("The value collection is read only."); - public void Clear() => throw new NotSupportedException("The value collection is read only."); - public bool Contains(TValue item) => _dictionary.Any(kv => kv.Value == item); - public void CopyTo(TValue[] array, int arrayIndex) => throw new NotImplementedException(); - public bool Remove(TValue item) => throw new NotSupportedException("The value collection is read only."); - public int Count => _dictionary.Count; - public bool IsReadOnly => true; - } - } -} \ No newline at end of file diff --git a/TechbloxModdingAPI/Utility/WrappedHandler.cs b/TechbloxModdingAPI/Utility/WrappedHandler.cs deleted file mode 100644 index 41e2fc7..0000000 --- a/TechbloxModdingAPI/Utility/WrappedHandler.cs +++ /dev/null @@ -1,59 +0,0 @@ -using System; -using System.Collections.Generic; -using TechbloxModdingAPI.Events; - -namespace TechbloxModdingAPI.Utility -{ - /// - /// Wraps the event handler in a try-catch block to avoid propagating exceptions. - /// - /// The event arguments type - public struct WrappedHandler - { - private EventHandler eventHandler; - - /// - /// Store wrappers so we can unregister them properly - /// - private static Dictionary, EventHandler> wrappers = - new Dictionary, EventHandler>(); - - public static WrappedHandler operator +(WrappedHandler original, EventHandler added) - { - EventHandler wrapped = (sender, e) => - { - try - { - added(sender, e); - } - catch (Exception e1) - { - EventRuntimeException wrappedException = - new EventRuntimeException($"EventHandler with arg type {typeof(T).Name} threw an exception", - e1); - Logging.LogWarning(wrappedException.ToString()); - } - }; - if (wrappers.ContainsKey(added)) - { - original.eventHandler -= wrapped; - wrappers.Remove(added); - } - - wrappers.Add(added, wrapped); - return new WrappedHandler { eventHandler = original.eventHandler + wrapped }; - } - - public static WrappedHandler operator -(WrappedHandler original, EventHandler removed) - { - if (!wrappers.TryGetValue(removed, out var wrapped)) return original; - wrappers.Remove(removed); - return new WrappedHandler { eventHandler = original.eventHandler - wrapped }; - } - - public void Invoke(object sender, T args) - { - eventHandler?.Invoke(sender, args); - } - } -} \ No newline at end of file diff --git a/docs/footer.html b/docs/footer.html index 314cef7..7150873 100644 --- a/docs/footer.html +++ b/docs/footer.html @@ -7,7 +7,7 @@ - + @@ -17,7 +17,7 @@ $generatedby   doxygen $doxygenversion -Contact ExMods | Discord | Twitter | Email | +Contact ExMods | Discord | Twitter | Email | diff --git a/doxygen.conf b/doxygen.conf index 23d4257..396453c 100644 --- a/doxygen.conf +++ b/doxygen.conf @@ -32,19 +32,19 @@ DOXYFILE_ENCODING = UTF-8 # title of most generated pages and in a few other places. # The default value is: My Project. -PROJECT_NAME = "TechbloxModdingAPI" +PROJECT_NAME = "GamecraftModdingAPI" # The PROJECT_NUMBER tag can be used to enter a project or revision number. This # could be handy for archiving the generated documentation or if some version # control system is used. -PROJECT_NUMBER = "v2.2.0" +PROJECT_NUMBER = "v0.2.0" # Using the PROJECT_BRIEF tag one can provide an optional one line description # for a project that appears at the top of each page and should give viewer a # quick idea about the purpose of the project. Keep the description short. -PROJECT_BRIEF = "The unofficial Techblox modding API" +PROJECT_BRIEF = "The unofficial Gamecraft modding API" # With the PROJECT_LOGO tag one can specify a logo or an icon that is included # in the documentation. The maximum height of the logo should not exceed 55 @@ -829,7 +829,7 @@ WARN_LOGFILE = dox.log # spaces. See also FILE_PATTERNS and EXTENSION_MAPPING # Note: If this tag is empty the current directory is searched. -INPUT =./TechbloxModdingAPI/ +INPUT =./GamecraftModdingAPI/ # This tag can be used to specify the character encoding of the source files # that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses @@ -917,7 +917,7 @@ RECURSIVE = YES # Note that relative paths are relative to the directory from which doxygen is # run. -EXCLUDE = ./TechbloxModdingAPI/bin ./TechbloxModdingAPI/obj +EXCLUDE = ./GamecraftModdingAPI/bin ./GamecraftModdingAPI/obj # The EXCLUDE_SYMLINKS tag can be used to select whether or not files or # directories that are symbolic links (a Unix file system feature) are excluded