|
- using System;
- using System.Collections;
- using System.Collections.Generic;
- using System.Linq;
- using System.Reflection;
- using DataLoader;
- using GPUInstancer;
- using HarmonyLib;
- using RobocraftX.Blocks;
- using RobocraftX.Common;
- using RobocraftX.Rendering;
- using Svelto.DataStructures;
- using Svelto.Tasks;
- using Unity.Entities;
- using Unity.Entities.Conversion;
- using Unity.Physics;
- using UnityEngine;
- using UnityEngine.AddressableAssets;
- using BoxCollider = UnityEngine.BoxCollider;
- using Material = UnityEngine.Material;
- using Object = UnityEngine.Object;
-
- 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);
- }
- }*/
-
- private static Material[] materials;
-
- public static void Prefix(List<PrefabData> prefabData, IList<GameObject> prefabs)
- {
- /*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;*/
- for (int i = 0; i < prefabData.Count; i++)
- {
- var gameObject = prefabs[i];
- switch (gameObject.name)
- {
- case "Cube":
- gameObject.GetComponentsInChildren<MeshRenderer>()[0].sharedMaterials = materials;
- break;
- case "CTR_CommandBlock":
- materials = gameObject.GetComponentsInChildren<MeshRenderer>()[0].sharedMaterials;
- break;
- }
- }
- }
-
- public static MethodBase TargetMethod()
- { //General block registration
- //return AccessTools.Method("RobocraftX.Blocks.BlocksCompositionRoot:RegisterPartPrefabs");
- return AccessTools.Method("RobocraftX.Rendering.ECSGPUIResourceManager:InitPreRegisteredPrefabs");
- }
- }
-
- /*[HarmonyPatch]
- public static class RendererPatch
- {
- private static Material[] materials;
- public static void Prefix(uint prefabID, GameObject gameObject)
- {
- Console.WriteLine("ID: " + prefabID + " - Name: " + gameObject.name);
- if (gameObject.name == "Cube")
- {
- //Console.WriteLine("Length: " + gameObject.GetComponentsInChildren<MeshRenderer>().Length);
- if (materials != null)
- gameObject.GetComponentsInChildren<MeshRenderer>()[0].sharedMaterials = materials;
- /*ECSGPUIResourceManager.Instance.RegisterGhostsPrefabsAtRuntime(
- new[] {new PrefabData {prefabId = prefabID, prefabName = "Assets/Prefabs/Cube.prefab"}},
- new List<GameObject> {gameObject});#1#
- GameObject go = Object.Instantiate(gameObject);
- go.SetActive(false);
- AccessTools.Method("RobocraftX.Rendering.ECSGPUIResourceManager:RegisterNewPrefabAtRuntime")
- .Invoke(ECSGPUIResourceManager.Instance,
- new object[] {(uint) ((int) prefabID * 2 + 1), gameObject, true});
- //ECSGPUIResourceManager.Instance.RegisterNewPrefabAtRuntime((uint) ((int)prefabID * 2 + 1), gameObject, true); //.isOcclusionCulling = false;
- UnityEngine.Object.Destroy(gameObject);
- GPUInstancerAPI.AddInstancesToPrefabPrototypeAtRuntime(ECSGPUIResourceManager.Instance.prefabManager,
- gameObject.GetComponent<GPUInstancerPrefab>().prefabPrototype, new[] {gameObject});
- Console.WriteLine("Registered prefab to instancer");
-
- /*var register = AccessTools.Method("RobocraftX.Common.ECSPhysicResourceManager:RegisterPrefab",
- new[] {typeof(uint), typeof(GameObject), typeof(World), typeof(BlobAssetStore)});
- register.Invoke(ECSPhysicResourceManager.Instance,
- new object[] {prefabID, gameObject, MGPatch.data.Item1, MGPatch.data.Item2});#1#
- /*Console.WriteLine(
- "Entity: " + ECSPhysicResourceManager.Instance.GetUECSPhysicEntityPrefab(prefabID));
- Console.WriteLine("Prefab ID: " + PrefabsID.DBIDMAP[500]);
- PhysicsCollider componentData = MGPatch.data.Item1.EntityManager.GetComponentData<PhysicsCollider>(ECSPhysicResourceManager.Instance.GetUECSPhysicEntityPrefab(prefabID));
- Console.WriteLine("Collider valid: " + componentData.IsValid);
- unsafe
- {
- Console.WriteLine("Collider type: " + componentData.ColliderPtr->Type);
- CollisionFilter filter = componentData.Value.Value.Filter;
- Console.WriteLine("Filter not empty: " + !filter.IsEmpty);
- }#1#
- //MGPatch.data.Item1.EntityManager.GetComponentData<>()
- gameObject.AddComponent<BoxCollider>();
- gameObject.AddComponent<Transform>();
- Console.WriteLine("Registered prefab to physics");
- ECSGPUIResourceManager.Instance.RegisterGhostsPrefabsAtRuntime();
- }
- else if (gameObject.name == "CTR_CommandBlock")
- materials = gameObject.GetComponentsInChildren<MeshRenderer>()[0].sharedMaterials;
- }
-
- public static MethodBase TargetMethod()
- {RobocraftX.Common.ECSGPUIResourceManager.RegisterPrefab
- return AccessTools.Method("RobocraftX.Common.ECSGPUIResourceManager:RegisterPrefab",
- new[] {typeof(uint), typeof(GameObject)});
- }
- }*/
-
- [HarmonyPatch]
- public static class RMPatch
- {
- public static void Prefix(World physicsWorld,
- GameObjectConversionSystem getExistingSystem,
- FasterList<GameObject> gos,
- List<PrefabData> prefabData)
- {
- Console.WriteLine("First game object data:\n" + gos[0].GetComponents<Component>()
- .Select(c => c + " - " + c.name + " " + c.GetType())
- .Aggregate((a, b) => a + "\n" + b));
- for (var index = 0; index < prefabData.Count; index++)
- {
- var data = prefabData[index];
- if (!data.prefabName.EndsWith("Cube.prefab")) continue;
- //getExistingSystem.DeclareLinkedEntityGroup(gos[index]);
- /*Entity entity = GameObjectConversionUtility.ConvertGameObjectHierarchy(gos[index],
- GameObjectConversionSettings.FromWorld(physicsWorld, MGPatch.data.Item2));*/
- Console.WriteLine("Transform: " + gos[index].transform.childCount);
- Entity primaryEntity = getExistingSystem.GetPrimaryEntity(gos[index]);
- MultiListEnumerator<Entity> entities = getExistingSystem.GetEntities(gos[index]);
- Console.WriteLine("ID: " + data.prefabId + " - Name: " + data.prefabName);
- Console.WriteLine("Primary entity: " + primaryEntity);
- EntityManager entityManager = physicsWorld.EntityManager;
- Console.WriteLine("Has collider: " + entityManager.HasComponent<PhysicsCollider>(primaryEntity));
- while (entities.MoveNext())
- {
- Entity current = entities.Current;
- Console.WriteLine("Entity " + current + " has collider: " +
- entityManager.HasComponent<PhysicsCollider>(current));
- }
-
- Console.WriteLine("Adding GPUI prefab");
- ((GPUInstancerPrefabManager) GPUInstancerManager.activeManagerList.Single(gim =>
- gim is GPUInstancerPrefabManager))
- .AddRuntimeRegisteredPrefab(gos[index].GetComponent<GPUInstancerPrefab>());
- Console.WriteLine("Added GPUI prefab");
- }
- }
-
- public static MethodBase TargetMethod()
- {
- return AccessTools.Method("RobocraftX.Blocks.ECSResourceManagerUtility:RelinkEntities",
- new[]
- {
- typeof(World),
- typeof(GameObjectConversionSystem),
- typeof(FasterList<GameObject>),
- typeof(List<PrefabData>)
- });
- }
- }
-
- [HarmonyPatch]
- public static class MGPatch
- {
- internal static (World, BlobAssetStore) data;
- public static void Prefix(World physicsWorld, BlobAssetStore blobStore, IDataDB dataDB)
- {
- data = (physicsWorld, blobStore);
- var blocks = dataDB.GetValues<CubeListData>();
- blocks.Add("modded_ConsoleBlock", new CubeListData
- {
- cubeType = CubeType.Block,
- cubeCategory = CubeCategory.ConsoleBlock,
- inventoryCategory = InventoryCategory.Logic,
- ID = 500,
- Path = "Assets/Prefabs/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()
- {
- return AccessTools.Method("RobocraftX.CR.MainGame.MainGameCompositionRoot:Init");
- }
- }
-
- public static IEnumerator Prep()
- { //TODO: Don't let the game load until this finishes
- 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);
- /*Console.WriteLine("Loading Cube asset...");
- var loadTask = Addressables.LoadAssetAsync<GameObject>("Assets/Cube.prefab");
- while (!loadTask.IsDone) yield return Yield.It;
- Console.WriteLine("Exception: "+loadTask.OperationException);
- Console.WriteLine("Result: " + loadTask.Result.name);*/
- }
- }
- }
|