NorbiPeti
4e16f251ee
It adds it with its ID as key but the ID hasn't been set at that point It works until the second simulation start now
299 lines
No EOL
15 KiB
C#
299 lines
No EOL
15 KiB
C#
using System;
|
|
using System.Collections;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Reflection;
|
|
using DataLoader;
|
|
using GamecraftModdingAPI.Utility;
|
|
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;*/
|
|
foreach (var gameObject in prefabs)
|
|
{
|
|
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);
|
|
//RobocraftX.CR.MachineEditing.UpdateSelectedGhostBlockEngine.UpdateGhostBlock
|
|
//var cld = (CubeListData) ((DataImplementor) dataDB).CreateDataObject("500", typeof(CubeListData), null);
|
|
var abd = dataDB.GetValue<CubeListData>((int) BlockIDs.AluminiumCube);
|
|
var cld = new CubeListData
|
|
{
|
|
cubeType = CubeType.Block,
|
|
cubeCategory = CubeCategory.General,
|
|
inventoryCategory = InventoryCategory.Shapes,
|
|
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,
|
|
Material = abd.Material
|
|
};
|
|
Console.WriteLine("Aluminium block data:\n" + abd);
|
|
Console.WriteLine("Material: " + abd.Material);
|
|
dataDB.GetValues<CubeListData>().Add("500", cld); //The registration needs to happen after the ID has been set
|
|
dataDB.GetFasterValues<CubeListData>().Add(500, cld);
|
|
//RobocraftX.ExplosionFragments.Engines.PlayFragmentExplodeEngine.PlayRigidBodyEffect
|
|
}
|
|
|
|
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);*/
|
|
}
|
|
}
|
|
} |