From fdc47832f4b75a6d58187bab1dd9c61d90150c87 Mon Sep 17 00:00:00 2001 From: NorbiPeti Date: Sat, 26 Dec 2020 01:59:06 +0100 Subject: [PATCH] Store custom block IDs in save files --- GamecraftModdingAPI/Blocks/CustomBlock.cs | 33 ++++++++--- .../Blocks/CustomBlockEntityDescriptor.cs | 57 +++++++++++++++++++ GamecraftModdingAPI/Main.cs | 2 +- .../Utility/ApiExclusiveGroups.cs | 14 ++++- 4 files changed, 97 insertions(+), 9 deletions(-) create mode 100644 GamecraftModdingAPI/Blocks/CustomBlockEntityDescriptor.cs diff --git a/GamecraftModdingAPI/Blocks/CustomBlock.cs b/GamecraftModdingAPI/Blocks/CustomBlock.cs index 15cfb15..c72475e 100644 --- a/GamecraftModdingAPI/Blocks/CustomBlock.cs +++ b/GamecraftModdingAPI/Blocks/CustomBlock.cs @@ -6,10 +6,12 @@ using System.Reflection; using HarmonyLib; using DataLoader; -using RobocraftX.Blocks; using RobocraftX.Rendering; +using RobocraftX.Schedulers; using Svelto.ECS; +using Svelto.ECS.Experimental; using Svelto.Tasks; +using Svelto.Tasks.ExtraLean; using UnityEngine; using UnityEngine.AddressableAssets; using Material = UnityEngine.Material; @@ -18,13 +20,17 @@ using GamecraftModdingAPI.Utility; namespace GamecraftModdingAPI.Blocks { + /// + /// Experimental support for adding custom blocks to the game. + /// public class CustomBlock : Block { private static ushort nextID = 500; /// /// Key: Prefab path /// - private static Dictionary _customBlocks = new Dictionary(); + private static readonly Dictionary CustomBlocks = new Dictionary(); + private static readonly CustomBlockEngine Engine = new CustomBlockEngine(); private static bool _canRegister = true; @@ -48,7 +54,7 @@ namespace GamecraftModdingAPI.Blocks throw new ArgumentException("The given block type doesn't have a concrete full name."); if (!File.Exists(attr.Catalog)) throw new FileNotFoundException("The specified catalog cannot be found for " + typeName); - _customBlocks.Add(attr.AssetPath, type); + CustomBlocks.Add(attr.AssetPath, type); Logging.MetaDebugLog("Registered custom block type " + typeName); } @@ -79,7 +85,7 @@ namespace GamecraftModdingAPI.Blocks for (var index = 0; index < prefabs.Count; index++) { - if (_customBlocks.ContainsKey(prefabData[index].prefabName)) //This is a custom block + if (CustomBlocks.ContainsKey(prefabData[index].prefabName)) //This is a custom block prefabs[index].GetComponentsInChildren()[0].sharedMaterials = materials; } } @@ -96,7 +102,7 @@ namespace GamecraftModdingAPI.Blocks public static void Prefix(IDataDB dataDB) { //var abd = dataDB.GetValue((int) BlockIDs.AluminiumCube); - foreach (var (key, type) in _customBlocks) + foreach (var (key, type) in CustomBlocks) { var attr = type.GetCustomAttribute(); var cld = new CubeListData @@ -123,6 +129,7 @@ namespace GamecraftModdingAPI.Blocks }; dataDB.GetValues().Add(cld.ID.ToString(), cld); //The registration needs to happen after the ID has been set dataDB.GetFasterValues().Add(cld.ID, cld); //So can't use the builtin method to create a CubeListData + Engine.RegisterBlock((ushort) cld.ID, key); } _canRegister = false; @@ -150,9 +157,9 @@ namespace GamecraftModdingAPI.Blocks } }*/ - internal static IEnumerator Prepare() + private static IEnumerator Prepare() { //Should be pretty quick - foreach (var type in _customBlocks.Values) + foreach (var type in CustomBlocks.Values) { var attr = type.GetCustomAttribute(); Logging.Log("Loading custom block catalog " + attr.Catalog); @@ -163,11 +170,23 @@ namespace GamecraftModdingAPI.Blocks } } + internal new static void Init() + { + Prepare().RunOn(ExtraLean.UIScheduler); + GameEngineManager.AddGameEngine(Engine); + } + /*internal static void OnBlockFactoryObtained(BlockEntityFactory factory) { var builders = (Dictionary) AccessTools.Field(factory.GetType(), "_blockBuilders").GetValue(factory); builders.Add((CubeCategory) 1000, new BlockBuilder(Group)); }*/ + + internal struct DataStruct : IEntityComponent + { + public ECSString Name; + public ushort ID; + } } } \ No newline at end of file diff --git a/GamecraftModdingAPI/Blocks/CustomBlockEntityDescriptor.cs b/GamecraftModdingAPI/Blocks/CustomBlockEntityDescriptor.cs new file mode 100644 index 0000000..7e8ea6e --- /dev/null +++ b/GamecraftModdingAPI/Blocks/CustomBlockEntityDescriptor.cs @@ -0,0 +1,57 @@ +using System; +using GamecraftModdingAPI.Engines; +using GamecraftModdingAPI.Persistence; +using GamecraftModdingAPI.Utility; +using RobocraftX.Common; +using Svelto.ECS; +using Svelto.ECS.Experimental; +using Svelto.ECS.Serialization; + +namespace GamecraftModdingAPI.Blocks +{ + public class CustomBlockEngine : IFactoryEngine + { + public class CustomBlockEntityDescriptor : SerializableEntityDescriptor< + CustomBlockEntityDescriptor._CustomBlockDescriptor> + { + [HashName("GamecraftModdingAPICustomBlockV0")] + public class _CustomBlockDescriptor : IEntityDescriptor + { + public IComponentBuilder[] componentsToBuild { get; } = + { + new SerializableComponentBuilder( + ((int) SerializationType.Network, new DefaultSerializer()), + ((int) SerializationType.Storage, new DefaultSerializer())) + }; + } + } + + public void Ready() + { + SerializerManager.AddSerializer(new SimpleEntitySerializer(db => + { + var (coll, c) = db.QueryEntities(ApiExclusiveGroups.customBlockGroup); + var egids = new EGID[c]; + for (int i = 0; i < c; i++) + egids[i] = new EGID(coll[i].ID, ApiExclusiveGroups.customBlockGroup); + + return egids; + })); + } + + public EntitiesDB entitiesDB { get; set; } + public void Dispose() + { + } + + public void RegisterBlock(ushort id, string name) + { + Factory.BuildEntity(id, ApiExclusiveGroups.customBlockGroup) + .Init(new CustomBlock.DataStruct {Name = new ECSString(name), ID = id}); + } + + public string Name { get; } = "GamecraftModdingAPICustomBlockEngine"; + public bool isRemovable { get; } = false; + public IEntityFactory Factory { get; set; } + } +} \ No newline at end of file diff --git a/GamecraftModdingAPI/Main.cs b/GamecraftModdingAPI/Main.cs index 66e923e..36a0db4 100644 --- a/GamecraftModdingAPI/Main.cs +++ b/GamecraftModdingAPI/Main.cs @@ -91,7 +91,7 @@ namespace GamecraftModdingAPI AsyncUtils.Init(); GamecraftModdingAPI.App.Client.Init(); GamecraftModdingAPI.App.Game.Init(); - CustomBlock.Prepare().RunOn(ExtraLean.UIScheduler); + CustomBlock.Init(); // init UI Interface.IMGUI.Constants.Init(); Interface.IMGUI.IMGUIManager.Init(); diff --git a/GamecraftModdingAPI/Utility/ApiExclusiveGroups.cs b/GamecraftModdingAPI/Utility/ApiExclusiveGroups.cs index 19211e6..8dc052d 100644 --- a/GamecraftModdingAPI/Utility/ApiExclusiveGroups.cs +++ b/GamecraftModdingAPI/Utility/ApiExclusiveGroups.cs @@ -38,6 +38,18 @@ namespace GamecraftModdingAPI.Utility } return _versionGroup; } - } + } + + private static ExclusiveGroup _customBlockGroup; + + public static ExclusiveGroup customBlockGroup + { + get + { + if (_customBlockGroup == null) + _customBlockGroup = new ExclusiveGroup("GamecraftModdingAPI CustomBlockGroup"); + return _customBlockGroup; + } + } } }