Attempts to create custom block types

It can load certain assets (a Cube from a sample) but fails because of missing shaders
My own Cube doesn't even get that far
This commit is contained in:
Norbi Peti 2020-06-14 21:40:47 +02:00
parent ae1f53e119
commit 9b1e2548d1
2 changed files with 178 additions and 0 deletions

View file

@ -0,0 +1,159 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Reflection.Emit;
using System.Text.Formatting;
using DataLoader;
using GamecraftModdingAPI.Utility;
using GPUInstancer;
using HarmonyLib;
using RobocraftX.Common;
using RobocraftX.Schedulers;
using Svelto.Tasks;
using Svelto.Tasks.ExtraLean;
using UnityEngine;
using UnityEngine.AddressableAssets;
namespace GamecraftModdingAPI.Blocks
{
public class CustomBlock
{
private static ushort nextID = 500;
public static void RegisterCustomBlock(string path)
{
var prefabData = new List<PrefabData>();
//category ID:
//0 - regular
//1 - joint
//2 - controller
uint prefabId = PrefabsID.FetchNewPrefabID(PrefabsID.GenerateDBID(0, nextID++));
prefabData.Add(new PrefabData()
{
prefabName = path,
prefabId = prefabId
});
var loadTask = Addressables.LoadAssetAsync<GameObject>(path);
AccessTools.Method("RobocraftX.Common.ECSGPUIResourceManager:RegisterPrefab")
.Invoke(ECSGPUIResourceManager.Instance, new object[] {prefabId, loadTask.Result, 1});
}
[HarmonyPatch]
public static class Patch
{
/*public static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions)
{
var list = new List<CodeInstruction>(instructions);
try
{
*int index = -1;
CodeInstruction loadTask = null;
for (var i = 0; i < list.Count - 1; i++)
{
if (list[i].opcode == OpCodes.Ldfld
&& ((string) list[i].operand).Contains("renderingWorld")
&& list[i + 1].opcode == OpCodes.Brfalse_S)
index = i - 1; //It loads 'this' first
if (list[i].opcode == OpCodes.Ldflda
&& ((string) list[i].operand).Contains("loadTask"))
loadTask = new CodeInstruction(list[i]);
}*
var array = new[]
{
//Set Yield.It to be returned (current)
new CodeInstruction(OpCodes.Ldarg_0), // this
new CodeInstruction(OpCodes.Ldsfld,
typeof(Yield).GetField("It", BindingFlags.Public | BindingFlags.Static)),
new CodeInstruction(OpCodes.Stfld, "object RobocraftX.Common.ECSResourceManagerUtility/'<RegisterPrefabs>d__0'::'<>2__current'"),
//Set which yield return we're at (state)
new CodeInstruction(OpCodes.Ldarg_0), // this
new CodeInstruction(OpCodes.Ldc_I4_1),
//new CodeInstruction(OpCodes.Call, ((Action<StringBuffer>)AddInfo).Method)
};
list.InsertRange(index, array);
*
IL_00ad: ldarg.0 // this
IL_00ae: ldsfld class [Svelto.Tasks]Svelto.Tasks.Yield [Svelto.Tasks]Svelto.Tasks.Yield::It
IL_00b3: stfld object RobocraftX.Common.ECSResourceManagerUtility/'<RegisterPrefabs>d__0'::'<>2__current'
IL_0072: ldarg.0 // this
IL_0073: ldnull
IL_0074: stfld object RobocraftX.Common.ECSResourceManagerUtility/'<RegisterPrefabs>d__0'::'<>2__current'
IL_0079: ldarg.0 // this
IL_007a: ldc.i4.2
IL_007b: stfld object RobocraftX.Common.ECSResourceManagerUtility/'<RegisterPrefabs>d__0'::'<>1__state'
IL_0080: ldc.i4.1
IL_0081: ret
*
yield break;
}
catch (Exception e)
{
Logging.LogWarning("Failed to inject AddInfo method for the debug display!\n" + e);
}
}*/
public static void Prefix(ref Dictionary<string, BaseData> blocks)
{
/*foreach (var block in blocks.Values.Cast<CubeListData>())
{
Console.WriteLine("Block info: " + block);
}*/
/*var res = Addressables.LoadContentCatalogAsync("customCatalog.json");
while (!res.IsDone) yield return Yield.It;*/
blocks.Add("modded_ConsoleBlock", new CubeListData
{
cubeType = CubeType.Block,
cubeCategory = CubeCategory.ConsoleBlock,
inventoryCategory = InventoryCategory.Logic,
ID = 500,
Path = "Assets/Cube.prefab", //Index out of range exception: Asset failed to load (wrong path)
SpriteName = "CTR_CommandBlock",
CubeNameKey = "strConsoleBlock",
SelectableFaces = new[] {0, 1, 2, 3, 4, 5},
GridScale = new[] {1, 1, 1},
Mass = 1,
JointBreakAngle = 1
});
}
public static MethodBase TargetMethod()
{ //General block registration
return AccessTools.Method("RobocraftX.Blocks.BlocksCompositionRoot:RegisterPartPrefabs");
}
}
[HarmonyPatch]
public static class GOPatch
{
public static void Prefix(uint prefabID, GameObject gameObject)
{
Console.WriteLine("ID: " + prefabID + " - Name: " + gameObject.name);
if (gameObject.name == "Cube")
ECSGPUIResourceManager.Instance.RegisterRuntimePrefabs(
new[] {new PrefabData {prefabId = 500, prefabName = "Assets/Cube.prefab"}},
new List<GameObject> {gameObject}, 1).Complete();
}
public static MethodBase TargetMethod()
{
return AccessTools.Method("RobocraftX.Common.ECSGPUIResourceManager:RegisterPrefab",
new[] {typeof(uint), typeof(GameObject), typeof(uint)});
}
}
public static IEnumerator Prep()
{
Console.WriteLine("Loading custom catalog...");
var res = Addressables.LoadContentCatalogAsync("customCatalog.json");
while (!res.IsDone) yield return Yield.It;
Console.WriteLine("Loaded custom catalog: " + res.Result.LocatorId);
Addressables.AddResourceLocator(res.Result);
}
}
}

View file

@ -13,6 +13,9 @@ using RobocraftX.Common;
using RobocraftX.SimulationModeState;
using RobocraftX.FrontEnd;
using Unity.Mathematics;
using RobocraftX.Schedulers;
using Svelto.Tasks.ExtraLean;
using uREPL;
using GamecraftModdingAPI.Commands;
using GamecraftModdingAPI.Events;
@ -283,6 +286,22 @@ namespace GamecraftModdingAPI.Tests
{
Logging.Log("Compatible GamecraftScripting detected");
}
CommandBuilder.Builder("enableCompletions")
.Action(() =>
{
var p = Window.selected.main.parameters;
p.useCommandCompletion = true;
p.useMonoCompletion = true;
p.useGlobalClassCompletion = true;
Log.Output("Submitted: " + Window.selected.submittedCode);
})
.Build();
/*JObject o1 = JObject.Parse(File.ReadAllText(@"Gamecraft_Data\StreamingAssets\aa\Windows\catalog.json"));
JObject o2 = JObject.Parse(File.ReadAllText(@"customCatalog.json"));
o1.Merge(o2, new JsonMergeSettings {MergeArrayHandling = MergeArrayHandling.Union});
File.WriteAllText(@"Gamecraft_Data\StreamingAssets\aa\Windows\catalog.json", o1.ToString());*/
CustomBlock.Prep().RunOn(ExtraLean.UIScheduler);
}
private string modsString;