275 lines
No EOL
14 KiB
C#
275 lines
No EOL
14 KiB
C#
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);
|
|
}
|
|
}*/
|
|
|
|
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;*/
|
|
}
|
|
|
|
public static MethodBase TargetMethod()
|
|
{ //General block registration
|
|
return AccessTools.Method("RobocraftX.Blocks.BlocksCompositionRoot:RegisterPartPrefabs");
|
|
}
|
|
}
|
|
|
|
/*[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);*/
|
|
}
|
|
}
|
|
} |