From 135aae99744784408a2e23da19cefafad8d1a73d Mon Sep 17 00:00:00 2001 From: Ben C Date: Sun, 28 Aug 2022 21:02:34 -0400 Subject: [PATCH 01/18] Add Support For Extra Modules --- NewHorizons/Handlers/PlanetCreationHandler.cs | 1 + NewHorizons/INewHorizons.cs | 11 +++++ NewHorizons/Main.cs | 2 + NewHorizons/NewHorizonsApi.cs | 40 ++++++++++++------- 4 files changed, 40 insertions(+), 14 deletions(-) diff --git a/NewHorizons/Handlers/PlanetCreationHandler.cs b/NewHorizons/Handlers/PlanetCreationHandler.cs index 73df7daa..fcb82a02 100644 --- a/NewHorizons/Handlers/PlanetCreationHandler.cs +++ b/NewHorizons/Handlers/PlanetCreationHandler.cs @@ -248,6 +248,7 @@ namespace NewHorizons.Handlers } } } + Main.Instance.OnPlanetLoaded?.Invoke(body.Config.name); return true; } diff --git a/NewHorizons/INewHorizons.cs b/NewHorizons/INewHorizons.cs index 7c647003..7b9936ba 100644 --- a/NewHorizons/INewHorizons.cs +++ b/NewHorizons/INewHorizons.cs @@ -43,6 +43,17 @@ namespace NewHorizons /// UnityEvent GetStarSystemLoadedEvent(); + /// + /// An event invoked when NH has finished a planet for a star system. + /// Gives the name of the planet that was just loaded. + /// + UnityEvent GetBodyLoadedEvent(); + + /// + /// Gets an object in the `extras` object of a config, returns null if the key doesn't exist + /// + object GetExtraModule(Type moduleType, string extrasModuleName, string planetName); + /// /// Allows you to overwrite the default system. This is where the player is respawned after dying. /// diff --git a/NewHorizons/Main.cs b/NewHorizons/Main.cs index cb64f092..000eb46b 100644 --- a/NewHorizons/Main.cs +++ b/NewHorizons/Main.cs @@ -68,6 +68,7 @@ namespace NewHorizons public class StarSystemEvent : UnityEvent { } public StarSystemEvent OnChangeStarSystem; public StarSystemEvent OnStarSystemLoaded; + public StarSystemEvent OnPlanetLoaded; // For warping to the eye system private GameObject _ship; @@ -170,6 +171,7 @@ namespace NewHorizons OnChangeStarSystem = new StarSystemEvent(); OnStarSystemLoaded = new StarSystemEvent(); + OnPlanetLoaded = new StarSystemEvent(); SceneManager.sceneLoaded += OnSceneLoaded; SceneManager.sceneUnloaded += OnSceneUnloaded; diff --git a/NewHorizons/NewHorizonsApi.cs b/NewHorizons/NewHorizonsApi.cs index 0ddb9f14..13a0fae1 100644 --- a/NewHorizons/NewHorizonsApi.cs +++ b/NewHorizons/NewHorizonsApi.cs @@ -5,14 +5,17 @@ using OWML.Common; using OWML.Utils; using System; using System.Collections.Generic; +using System.Data.SqlTypes; using System.IO; using System.Linq; +using Newtonsoft.Json.Linq; using UnityEngine; using UnityEngine.Events; using Logger = NewHorizons.Utility.Logger; namespace NewHorizons { + public class NewHorizonsApi : INewHorizons { [Obsolete("Create(Dictionary config) is deprecated, please use LoadConfigs(IModBehaviour mod) instead")] @@ -64,20 +67,10 @@ namespace NewHorizons return Main.BodyDict.Values.SelectMany(x => x)?.ToList()?.FirstOrDefault(x => x.Config.name == name)?.Object; } - public string GetCurrentStarSystem() - { - return Main.Instance.CurrentStarSystem; - } - - public UnityEvent GetChangeStarSystemEvent() - { - return Main.Instance.OnChangeStarSystem; - } - - public UnityEvent GetStarSystemLoadedEvent() - { - return Main.Instance.OnStarSystemLoaded; - } + public string GetCurrentStarSystem() => Main.Instance.CurrentStarSystem; + public UnityEvent GetChangeStarSystemEvent() => Main.Instance.OnChangeStarSystem; + public UnityEvent GetStarSystemLoadedEvent() => Main.Instance.OnStarSystemLoaded; + public UnityEvent GetBodyLoadedEvent() => Main.Instance.OnPlanetLoaded; public bool SetDefaultSystem(string name) { @@ -108,6 +101,25 @@ namespace NewHorizons } } + public object GetExtraModule(Type moduleType, string extraModuleKey, string planetName) + { + var planet = Main.BodyDict[Main.Instance.CurrentStarSystem].Find((b) => b.Config.name == planetName); + if (planet == null) + { + // Uh idk if we need this but ye it do be here etc. + Logger.LogVerbose($"Attempting To Get Extras On Planet That Doesn't Exist! ({planetName})"); + return null; + } + var jsonText = File.ReadAllText(planet.Mod.ModHelper.Manifest.ModFolderPath + planet.RelativePath); + var jsonData = JObject.Parse(jsonText); + var possibleExtras = jsonData.Property("extras")?.Value; + if (possibleExtras is JObject extras) + { + return extras.Property(extraModuleKey)?.Value.ToObject(moduleType); + } + return null; + } + public GameObject SpawnObject(GameObject planet, Sector sector, string propToCopyPath, Vector3 position, Vector3 eulerAngles, float scale, bool alignWithNormal) { From 60d26822298f5fcb4bdd90af8828f937ac0f988e Mon Sep 17 00:00:00 2001 From: Ben C Date: Mon, 29 Aug 2022 08:04:09 -0400 Subject: [PATCH 02/18] Add To Body Schema --- SchemaExporter/SchemaExporter.cs | 191 ++++++++++++++++--------------- 1 file changed, 96 insertions(+), 95 deletions(-) diff --git a/SchemaExporter/SchemaExporter.cs b/SchemaExporter/SchemaExporter.cs index f0c802f5..450d6833 100644 --- a/SchemaExporter/SchemaExporter.cs +++ b/SchemaExporter/SchemaExporter.cs @@ -1,96 +1,97 @@ -using System; -using System.Collections.Generic; -using System.IO; -using NewHorizons.External.Configs; -using NJsonSchema; -using NJsonSchema.Generation; - -namespace SchemaExporter; - -public static class SchemaExporter -{ - public static void Main(string[] args) - { - const string folderName = "NewHorizons/Schemas"; - - Directory.CreateDirectory(folderName); - Console.WriteLine("Schema Generator: We're winning!"); - var settings = new JsonSchemaGeneratorSettings - { - IgnoreObsoleteProperties = true, - DefaultReferenceTypeNullHandling = ReferenceTypeNullHandling.NotNull, - FlattenInheritanceHierarchy = true, - AllowReferencesWithProperties = true - }; - var bodySchema = new Schema("Celestial Body Schema", "Schema for a celestial body in New Horizons", $"{folderName}/body_schema", settings); - bodySchema.Output(); - var systemSchema = - new Schema("Star System Schema", "Schema for a star system in New Horizons", $"{folderName}/star_system_schema", settings); - systemSchema.Output(); - var addonSchema = new Schema("Addon Manifest Schema", - "Schema for an addon manifest in New Horizons", $"{folderName}/addon_manifest_schema", settings); - addonSchema.Output(); - var translationSchema = - new Schema("Translation Schema", "Schema for a translation file in New Horizons", $"{folderName}/translation_schema", settings); - translationSchema.Output(); - Console.WriteLine("Done!"); - } - - private readonly struct Schema - { - private readonly JsonSchemaGeneratorSettings _generatorSettings; - private readonly string _title, _description; - private readonly string _outFileName; - - public Schema(string schemaTitle, string schemaDescription, string fileName, JsonSchemaGeneratorSettings settings) - { - _title = schemaTitle; - _description = schemaDescription; - _outFileName = fileName; - _generatorSettings = settings; - } - - public void Output() - { - Console.WriteLine($"Outputting {_title}"); - File.WriteAllText($"{_outFileName}.json", ToString()); - } - - public override string ToString() - { - return GetJsonSchema().ToJson(); - } - - private JsonSchema GetJsonSchema() - { - var schema = JsonSchema.FromType(_generatorSettings); - schema.Title = _title; - var schemaLinkProp = new JsonSchemaProperty - { - Type = JsonObjectType.String, - Description = "The schema to validate with" - }; - schema.Properties.Add("$schema", schemaLinkProp); - schema.ExtensionData ??= new Dictionary(); - schema.ExtensionData.Add("$docs", new Dictionary - { - {"title", _title}, - {"description", _description} - }); - - if (_title == "Celestial Body Schema") - { - schema.Definitions["OrbitModule"].Properties["semiMajorAxis"].Default = 5000f; - } - - if (_title == "Star System Schema") - { - schema.Definitions["NomaiCoordinates"].Properties["x"].UniqueItems = true; - schema.Definitions["NomaiCoordinates"].Properties["y"].UniqueItems = true; - schema.Definitions["NomaiCoordinates"].Properties["z"].UniqueItems = true; - } - - return schema; - } - } +using System; +using System.Collections.Generic; +using System.IO; +using NewHorizons.External.Configs; +using NJsonSchema; +using NJsonSchema.Generation; + +namespace SchemaExporter; + +public static class SchemaExporter +{ + public static void Main(string[] args) + { + const string folderName = "NewHorizons/Schemas"; + + Directory.CreateDirectory(folderName); + Console.WriteLine("Schema Generator: We're winning!"); + var settings = new JsonSchemaGeneratorSettings + { + IgnoreObsoleteProperties = true, + DefaultReferenceTypeNullHandling = ReferenceTypeNullHandling.NotNull, + FlattenInheritanceHierarchy = true, + AllowReferencesWithProperties = true + }; + var bodySchema = new Schema("Celestial Body Schema", "Schema for a celestial body in New Horizons", $"{folderName}/body_schema", settings); + bodySchema.Output(); + var systemSchema = + new Schema("Star System Schema", "Schema for a star system in New Horizons", $"{folderName}/star_system_schema", settings); + systemSchema.Output(); + var addonSchema = new Schema("Addon Manifest Schema", + "Schema for an addon manifest in New Horizons", $"{folderName}/addon_manifest_schema", settings); + addonSchema.Output(); + var translationSchema = + new Schema("Translation Schema", "Schema for a translation file in New Horizons", $"{folderName}/translation_schema", settings); + translationSchema.Output(); + Console.WriteLine("Done!"); + } + + private readonly struct Schema + { + private readonly JsonSchemaGeneratorSettings _generatorSettings; + private readonly string _title, _description; + private readonly string _outFileName; + + public Schema(string schemaTitle, string schemaDescription, string fileName, JsonSchemaGeneratorSettings settings) + { + _title = schemaTitle; + _description = schemaDescription; + _outFileName = fileName; + _generatorSettings = settings; + } + + public void Output() + { + Console.WriteLine($"Outputting {_title}"); + File.WriteAllText($"{_outFileName}.json", ToString()); + } + + public override string ToString() + { + return GetJsonSchema().ToJson(); + } + + private JsonSchema GetJsonSchema() + { + var schema = JsonSchema.FromType(_generatorSettings); + schema.Title = _title; + var schemaLinkProp = new JsonSchemaProperty + { + Type = JsonObjectType.String, + Description = "The schema to validate with" + }; + schema.Properties.Add("$schema", schemaLinkProp); + schema.ExtensionData ??= new Dictionary(); + schema.ExtensionData.Add("$docs", new Dictionary + { + {"title", _title}, + {"description", _description} + }); + + if (_title == "Celestial Body Schema") + { + schema.Definitions["OrbitModule"].Properties["semiMajorAxis"].Default = 5000f; + schema.Properties.Add("extras", new Dictionary()); + } + + if (_title == "Star System Schema") + { + schema.Definitions["NomaiCoordinates"].Properties["x"].UniqueItems = true; + schema.Definitions["NomaiCoordinates"].Properties["y"].UniqueItems = true; + schema.Definitions["NomaiCoordinates"].Properties["z"].UniqueItems = true; + } + + return schema; + } + } } \ No newline at end of file From 549bea956713a5dfa49932e924ac941d91bb0bd8 Mon Sep 17 00:00:00 2001 From: Ben C Date: Mon, 29 Aug 2022 08:08:36 -0400 Subject: [PATCH 03/18] Ok try again --- SchemaExporter/SchemaExporter.cs | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/SchemaExporter/SchemaExporter.cs b/SchemaExporter/SchemaExporter.cs index 450d6833..2dba6386 100644 --- a/SchemaExporter/SchemaExporter.cs +++ b/SchemaExporter/SchemaExporter.cs @@ -81,7 +81,10 @@ public static class SchemaExporter if (_title == "Celestial Body Schema") { schema.Definitions["OrbitModule"].Properties["semiMajorAxis"].Default = 5000f; - schema.Properties.Add("extras", new Dictionary()); + schema.Properties.Add("extras", new JsonSchemaProperty { + Type = JsonObjectType.Object, + Description = "Extra data that may be used by extension mods" + }); } if (_title == "Star System Schema") @@ -89,6 +92,10 @@ public static class SchemaExporter schema.Definitions["NomaiCoordinates"].Properties["x"].UniqueItems = true; schema.Definitions["NomaiCoordinates"].Properties["y"].UniqueItems = true; schema.Definitions["NomaiCoordinates"].Properties["z"].UniqueItems = true; + schema.Properties.Add("extras", new JsonSchemaProperty { + Type = JsonObjectType.Object, + Description = "Extra data that may be used by extension mods" + }); } return schema; From a8ca79896b519a82036b2b195d15477f40545fb4 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Mon, 29 Aug 2022 12:13:22 +0000 Subject: [PATCH 04/18] Updated Schemas --- NewHorizons/Schemas/body_schema.json | 4 ++++ NewHorizons/Schemas/star_system_schema.json | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/NewHorizons/Schemas/body_schema.json b/NewHorizons/Schemas/body_schema.json index bc88b9f7..c4fe13eb 100644 --- a/NewHorizons/Schemas/body_schema.json +++ b/NewHorizons/Schemas/body_schema.json @@ -131,6 +131,10 @@ "$schema": { "type": "string", "description": "The schema to validate with" + }, + "extras": { + "type": "object", + "description": "Extra data that may be used by extension mods" } }, "definitions": { diff --git a/NewHorizons/Schemas/star_system_schema.json b/NewHorizons/Schemas/star_system_schema.json index b1f5e2cc..54770b00 100644 --- a/NewHorizons/Schemas/star_system_schema.json +++ b/NewHorizons/Schemas/star_system_schema.json @@ -74,6 +74,10 @@ "$schema": { "type": "string", "description": "The schema to validate with" + }, + "extras": { + "type": "object", + "description": "Extra data that may be used by extension mods" } }, "definitions": { From 21dc7fc8dd5769221855de124e1afffa2bf1957a Mon Sep 17 00:00:00 2001 From: Ben C Date: Mon, 29 Aug 2022 08:33:20 -0400 Subject: [PATCH 05/18] Updated Docs --- docs/content/pages/tutorials/api.md | 95 ++++++++++++++++++++--- docs/content/pages/tutorials/extending.md | 65 ++++++++++++++++ 2 files changed, 149 insertions(+), 11 deletions(-) create mode 100644 docs/content/pages/tutorials/extending.md diff --git a/docs/content/pages/tutorials/api.md b/docs/content/pages/tutorials/api.md index 8689943c..114cbe68 100644 --- a/docs/content/pages/tutorials/api.md +++ b/docs/content/pages/tutorials/api.md @@ -9,21 +9,94 @@ First create the following interface in your mod: ```cs public interface INewHorizons -{ - void LoadConfigs(IModBehaviour mod); + { + [Obsolete("Create(Dictionary config) is deprecated, please use LoadConfigs(IModBehaviour mod) instead")] + void Create(Dictionary config); - GameObject GetPlanet(string name); - - string GetCurrentStarSystem(); + [Obsolete("Create(Dictionary config) is deprecated, please use LoadConfigs(IModBehaviour mod) instead")] + void Create(Dictionary config, IModBehaviour mod); - UnityEvent GetChangeStarSystemEvent(); + /// + /// Will load all configs in the regular folders (planets, systems, translations, etc) for this mod. + /// The NH addon config template is just a single call to this API method. + /// + void LoadConfigs(IModBehaviour mod); - UnityEvent GetStarSystemLoadedEvent(); - - GameObject SpawnObject(GameObject planet, Sector sector, string propToCopyPath, Vector3 position, Vector3 eulerAngles, float scale, bool alignWithNormal); + /// + /// Retrieve the root GameObject of a custom planet made by creating configs. + /// Will only work if the planet has been created (see GetStarSystemLoadedEvent) + /// + GameObject GetPlanet(string name); - string[] GetInstalledAddons(); -} + /// + /// The name of the current star system loaded. + /// + string GetCurrentStarSystem(); + + /// + /// An event invoked when the player begins loading the new star system, before the scene starts to load. + /// Gives the name of the star system being switched to. + /// + UnityEvent GetChangeStarSystemEvent(); + + /// + /// An event invoked when NH has finished generating all planets for a new star system. + /// Gives the name of the star system that was just loaded. + /// + UnityEvent GetStarSystemLoadedEvent(); + + /// + /// An event invoked when NH has finished a planet for a star system. + /// Gives the name of the planet that was just loaded. + /// + UnityEvent GetBodyLoadedEvent(); + + /// + /// Gets an object in the `extras` object of a config, returns null if the key doesn't exist + /// + object GetExtraModule(Type moduleType, string extrasModuleName, string planetName); + + /// + /// Allows you to overwrite the default system. This is where the player is respawned after dying. + /// + bool SetDefaultSystem(string name); + + /// + /// Allows you to instantly begin a warp to a new star system. + /// Will return false if that system does not exist (cannot be warped to). + /// + bool ChangeCurrentStarSystem(string name); + + /// + /// Returns the uniqueIDs of each installed NH addon. + /// + string[] GetInstalledAddons(); + + /// + /// Allows you to spawn a copy of a prop by specifying its path. + /// This is the same as using Props->details in a config, but also returns the spawned gameObject to you. + /// + GameObject SpawnObject(GameObject planet, Sector sector, string propToCopyPath, Vector3 position, Vector3 eulerAngles, + float scale, bool alignWithNormal); + + /// + /// Allows you to spawn an AudioSignal on a planet. + /// This is the same as using Props->signals in a config, but also returns the spawned AudioSignal to you. + /// This method will not set its position. You will have to do that with the returned object. + /// + AudioSignal SpawnSignal(IModBehaviour mod, GameObject root, string audio, string name, string frequency, + float sourceRadius = 1f, float detectionRadius = 20f, float identificationRadius = 10f, bool insideCloak = false, + bool onlyAudibleToScope = true, string reveals = ""); + + /// + /// Allows you to spawn character dialogue on a planet. Also returns the RemoteDialogueTrigger if remoteTriggerRadius is specified. + /// This is the same as using Props->dialogue in a config, but also returns the spawned game objects to you. + /// This method will not set the position of the dialogue or remote trigger. You will have to do that with the returned objects. + /// + (CharacterDialogueTree, RemoteDialogueTrigger) SpawnDialogue(IModBehaviour mod, GameObject root, string xmlFile, float radius = 1f, + float range = 1f, string blockAfterPersistentCondition = null, float lookAtRadius = 1f, string pathToAnimController = null, + float remoteTriggerRadius = 0f); + } ``` In your main `ModBehaviour` class you can get the NewHorizons API like so: diff --git a/docs/content/pages/tutorials/extending.md b/docs/content/pages/tutorials/extending.md new file mode 100644 index 00000000..649c2473 --- /dev/null +++ b/docs/content/pages/tutorials/extending.md @@ -0,0 +1,65 @@ +--- +Title: Extending Configs +Description: A guide on extending config files with the New Horizons API +Sort_Priority: 5 +--- + + + +# Extending Configs + +This guide will explain how to use the API to add new features to New Horizons. + +## How Extending Works + +Addon developers will add a key to the `extras` object in the root of the config + +```json +{ + "name": "Wetrock", + "extras": { + "myCoolExtensionData": { + "myCoolExtensionProperty": 2 + } + } +} +``` + +Your mod will then use the API's `GetExtraModule` method to obtain the `myCoolExtensionData` object. + +## Extending Planets + +You can extend all planets by hooking into the `OnBodyLoaded` event of the API: + +```cs +var api = ModHelper.Interactions.TryGetModApi("xen.NewHorizons"); +api.GetBodyLoadedEvent().AddListener((name) => { + ModHelper.Console.WriteLine($"Body: {name} Loaded!"); +}); +``` + +In order to get your extra module, first define the module as a class: + +```cs +public class MyCoolExtensionData { + int myCoolExtensionProperty; +} +``` + +Then, use the `GetExtraModule` method: + +```cs +var api = ModHelper.Interactions.TryGetModApi("xen.NewHorizons"); +api.GetBodyLoadedEvent().AddListener((name) => { + ModHelper.Console.WriteLine($"Body: {name} Loaded!"); + var potentialData = api.GetExtraModule(typeof(MyCoolExtensionData), "myCoolExtensionData", name); + // Makes sure the module is valid and not null + if (potentialData is MyCoolExtensionData data) { + ModHelper.Console.WriteLine($"myCoolExtensionProperty for {name} is {data.myCoolExtensionProperty}!"); + } +}); +``` + +## Extending Systems + + From 44984bde2729c58cfe29a697b9edc24cd17bef8c Mon Sep 17 00:00:00 2001 From: Ben C Date: Mon, 29 Aug 2022 08:38:31 -0400 Subject: [PATCH 06/18] Update API docs to use TryGetModApi --- docs/content/pages/tutorials/api.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/content/pages/tutorials/api.md b/docs/content/pages/tutorials/api.md index 114cbe68..817c89ba 100644 --- a/docs/content/pages/tutorials/api.md +++ b/docs/content/pages/tutorials/api.md @@ -106,7 +106,7 @@ public class MyMod : ModBehaviour { void Start() { - INewHorizons NewHorizonsAPI = ModHelper.Interaction.GetModApi("xen.NewHorizons"); + INewHorizons NewHorizonsAPI = ModHelper.Interaction.TryGetModApi("xen.NewHorizons"); } } ``` From 202eb808aa28addffc79610ca9e7df9ed7c31f50 Mon Sep 17 00:00:00 2001 From: Ben C Date: Mon, 29 Aug 2022 08:52:26 -0400 Subject: [PATCH 07/18] Add Mod Dep Warning --- docs/content/pages/tutorials/extending.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/content/pages/tutorials/extending.md b/docs/content/pages/tutorials/extending.md index 649c2473..67e7e5ca 100644 --- a/docs/content/pages/tutorials/extending.md +++ b/docs/content/pages/tutorials/extending.md @@ -25,6 +25,8 @@ Addon developers will add a key to the `extras` object in the root of the config } ``` +**It's up to the addon dev to list your mod as a dependency!** + Your mod will then use the API's `GetExtraModule` method to obtain the `myCoolExtensionData` object. ## Extending Planets From 6722ff7ad40fce6a84804e326514f9786fdfea09 Mon Sep 17 00:00:00 2001 From: Ben C Date: Mon, 29 Aug 2022 17:25:42 -0400 Subject: [PATCH 08/18] Added Support for Systems --- NewHorizons/INewHorizons.cs | 9 +- NewHorizons/Main.cs | 8 +- NewHorizons/NewHorizonsApi.cs | 41 +++-- NewHorizons/Utility/NewHorizonsSystem.cs | 4 +- SchemaExporter/SchemaExporter.cs | 211 ++++++++++++----------- 5 files changed, 152 insertions(+), 121 deletions(-) diff --git a/NewHorizons/INewHorizons.cs b/NewHorizons/INewHorizons.cs index 7b9936ba..aa014ea6 100644 --- a/NewHorizons/INewHorizons.cs +++ b/NewHorizons/INewHorizons.cs @@ -50,9 +50,14 @@ namespace NewHorizons UnityEvent GetBodyLoadedEvent(); /// - /// Gets an object in the `extras` object of a config, returns null if the key doesn't exist + /// Gets an object in the `extras` object of a body config, returns null if the key doesn't exist /// - object GetExtraModule(Type moduleType, string extrasModuleName, string planetName); + object GetExtraModuleForBody(Type moduleType, string extrasModuleName, string planetName); + + /// + /// Gets an object in the `extras` object of a system config, returns null if the key doesn't exist + /// + object GetExtraModuleForSystem(Type moduleType, string extrasModuleName, string systemName); /// /// Allows you to overwrite the default system. This is where the player is respawned after dying. diff --git a/NewHorizons/Main.cs b/NewHorizons/Main.cs index 000eb46b..97ba6124 100644 --- a/NewHorizons/Main.cs +++ b/NewHorizons/Main.cs @@ -127,7 +127,7 @@ namespace NewHorizons BodyDict["SolarSystem"] = new List(); BodyDict["EyeOfTheUniverse"] = new List(); // Keep this empty tho fr - SystemDict["SolarSystem"] = new NewHorizonsSystem("SolarSystem", new StarSystemConfig(), Instance) + SystemDict["SolarSystem"] = new NewHorizonsSystem("SolarSystem", new StarSystemConfig(), "", Instance) { Config = { @@ -143,7 +143,7 @@ namespace NewHorizons } } }; - SystemDict["EyeOfTheUniverse"] = new NewHorizonsSystem("EyeOfTheUniverse", new StarSystemConfig(), Instance) + SystemDict["EyeOfTheUniverse"] = new NewHorizonsSystem("EyeOfTheUniverse", new StarSystemConfig(), "", Instance) { Config = { @@ -517,7 +517,7 @@ namespace NewHorizons } else { - SystemDict[name] = new NewHorizonsSystem(name, starSystemConfig, mod); + SystemDict[name] = new NewHorizonsSystem(name, starSystemConfig, relativePath, mod); } } } @@ -618,7 +618,7 @@ namespace NewHorizons starSystemConfig.Migrate(); starSystemConfig.FixCoordinates(); - var system = new NewHorizonsSystem(config.starSystem, starSystemConfig, mod); + var system = new NewHorizonsSystem(config.starSystem, starSystemConfig, "", mod); SystemDict.Add(config.starSystem, system); diff --git a/NewHorizons/NewHorizonsApi.cs b/NewHorizons/NewHorizonsApi.cs index 13a0fae1..e8e36a24 100644 --- a/NewHorizons/NewHorizonsApi.cs +++ b/NewHorizons/NewHorizonsApi.cs @@ -101,23 +101,42 @@ namespace NewHorizons } } - public object GetExtraModule(Type moduleType, string extraModuleKey, string planetName) + private object GetExtraModule(Type moduleType, string key, string path) { - var planet = Main.BodyDict[Main.Instance.CurrentStarSystem].Find((b) => b.Config.name == planetName); - if (planet == null) + if (path == "") return null; + try { - // Uh idk if we need this but ye it do be here etc. - Logger.LogVerbose($"Attempting To Get Extras On Planet That Doesn't Exist! ({planetName})"); + var jsonText = File.ReadAllText(path); + var jsonData = JObject.Parse(jsonText); + var possibleExtras = jsonData.Property("extras")?.Value; + if (possibleExtras is JObject extras) + { + return extras.Property(key)?.Value.ToObject(moduleType); + } return null; } - var jsonText = File.ReadAllText(planet.Mod.ModHelper.Manifest.ModFolderPath + planet.RelativePath); - var jsonData = JObject.Parse(jsonText); - var possibleExtras = jsonData.Property("extras")?.Value; - if (possibleExtras is JObject extras) + catch (FileNotFoundException) { - return extras.Property(extraModuleKey)?.Value.ToObject(moduleType); + return null; } - return null; + } + + public object GetExtraModuleForBody(Type moduleType, string extraModuleKey, string planetName) + { + var planet = Main.BodyDict[Main.Instance.CurrentStarSystem].Find((b) => b.Config.name == planetName); + return planet == null + ? null + : GetExtraModule(moduleType, extraModuleKey, + planet.Mod.ModHelper.Manifest.ModFolderPath + planet.RelativePath); + } + + public object GetExtraModuleForSystem(Type moduleType, string extraModuleKey, string systemName) + { + var system = Main.SystemDict[Main.Instance.CurrentStarSystem]; + return system == null + ? null + : GetExtraModule(moduleType, extraModuleKey, + system.Mod.ModHelper.Manifest.ModFolderPath + system.RelativePath); } public GameObject SpawnObject(GameObject planet, Sector sector, string propToCopyPath, Vector3 position, Vector3 eulerAngles, diff --git a/NewHorizons/Utility/NewHorizonsSystem.cs b/NewHorizons/Utility/NewHorizonsSystem.cs index ae6bafa3..be9a539f 100644 --- a/NewHorizons/Utility/NewHorizonsSystem.cs +++ b/NewHorizons/Utility/NewHorizonsSystem.cs @@ -11,15 +11,17 @@ namespace NewHorizons.Utility public class NewHorizonsSystem { public string UniqueID; + public string RelativePath; public SpawnModule Spawn = null; public SpawnPoint SpawnPoint = null; public StarSystemConfig Config; public IModBehaviour Mod; - public NewHorizonsSystem(string uniqueID, StarSystemConfig config, IModBehaviour mod) + public NewHorizonsSystem(string uniqueID, StarSystemConfig config, string relativePath, IModBehaviour mod) { UniqueID = uniqueID; Config = config; + RelativePath = relativePath; Mod = mod; } } diff --git a/SchemaExporter/SchemaExporter.cs b/SchemaExporter/SchemaExporter.cs index 2dba6386..33c12666 100644 --- a/SchemaExporter/SchemaExporter.cs +++ b/SchemaExporter/SchemaExporter.cs @@ -1,104 +1,109 @@ -using System; -using System.Collections.Generic; -using System.IO; -using NewHorizons.External.Configs; -using NJsonSchema; -using NJsonSchema.Generation; - -namespace SchemaExporter; - -public static class SchemaExporter -{ - public static void Main(string[] args) - { - const string folderName = "NewHorizons/Schemas"; - - Directory.CreateDirectory(folderName); - Console.WriteLine("Schema Generator: We're winning!"); - var settings = new JsonSchemaGeneratorSettings - { - IgnoreObsoleteProperties = true, - DefaultReferenceTypeNullHandling = ReferenceTypeNullHandling.NotNull, - FlattenInheritanceHierarchy = true, - AllowReferencesWithProperties = true - }; - var bodySchema = new Schema("Celestial Body Schema", "Schema for a celestial body in New Horizons", $"{folderName}/body_schema", settings); - bodySchema.Output(); - var systemSchema = - new Schema("Star System Schema", "Schema for a star system in New Horizons", $"{folderName}/star_system_schema", settings); - systemSchema.Output(); - var addonSchema = new Schema("Addon Manifest Schema", - "Schema for an addon manifest in New Horizons", $"{folderName}/addon_manifest_schema", settings); - addonSchema.Output(); - var translationSchema = - new Schema("Translation Schema", "Schema for a translation file in New Horizons", $"{folderName}/translation_schema", settings); - translationSchema.Output(); - Console.WriteLine("Done!"); - } - - private readonly struct Schema - { - private readonly JsonSchemaGeneratorSettings _generatorSettings; - private readonly string _title, _description; - private readonly string _outFileName; - - public Schema(string schemaTitle, string schemaDescription, string fileName, JsonSchemaGeneratorSettings settings) - { - _title = schemaTitle; - _description = schemaDescription; - _outFileName = fileName; - _generatorSettings = settings; - } - - public void Output() - { - Console.WriteLine($"Outputting {_title}"); - File.WriteAllText($"{_outFileName}.json", ToString()); - } - - public override string ToString() - { - return GetJsonSchema().ToJson(); - } - - private JsonSchema GetJsonSchema() - { - var schema = JsonSchema.FromType(_generatorSettings); - schema.Title = _title; - var schemaLinkProp = new JsonSchemaProperty - { - Type = JsonObjectType.String, - Description = "The schema to validate with" - }; - schema.Properties.Add("$schema", schemaLinkProp); - schema.ExtensionData ??= new Dictionary(); - schema.ExtensionData.Add("$docs", new Dictionary - { - {"title", _title}, - {"description", _description} - }); - - if (_title == "Celestial Body Schema") - { - schema.Definitions["OrbitModule"].Properties["semiMajorAxis"].Default = 5000f; - schema.Properties.Add("extras", new JsonSchemaProperty { - Type = JsonObjectType.Object, - Description = "Extra data that may be used by extension mods" - }); - } - - if (_title == "Star System Schema") - { - schema.Definitions["NomaiCoordinates"].Properties["x"].UniqueItems = true; - schema.Definitions["NomaiCoordinates"].Properties["y"].UniqueItems = true; - schema.Definitions["NomaiCoordinates"].Properties["z"].UniqueItems = true; - schema.Properties.Add("extras", new JsonSchemaProperty { - Type = JsonObjectType.Object, - Description = "Extra data that may be used by extension mods" - }); - } - - return schema; - } - } +using System; +using System.Collections.Generic; +using System.IO; +using NewHorizons.External.Configs; +using NJsonSchema; +using NJsonSchema.Generation; + +namespace SchemaExporter; + +public static class SchemaExporter +{ + public static void Main(string[] args) + { + const string folderName = "NewHorizons/Schemas"; + + Directory.CreateDirectory(folderName); + Console.WriteLine("Schema Generator: We're winning!"); + var settings = new JsonSchemaGeneratorSettings + { + IgnoreObsoleteProperties = true, + DefaultReferenceTypeNullHandling = ReferenceTypeNullHandling.NotNull, + FlattenInheritanceHierarchy = true, + AllowReferencesWithProperties = true + }; + var bodySchema = new Schema("Celestial Body Schema", "Schema for a celestial body in New Horizons", $"{folderName}/body_schema", settings); + bodySchema.Output(); + var systemSchema = + new Schema("Star System Schema", "Schema for a star system in New Horizons", $"{folderName}/star_system_schema", settings); + systemSchema.Output(); + var addonSchema = new Schema("Addon Manifest Schema", + "Schema for an addon manifest in New Horizons", $"{folderName}/addon_manifest_schema", settings); + addonSchema.Output(); + var translationSchema = + new Schema("Translation Schema", "Schema for a translation file in New Horizons", $"{folderName}/translation_schema", settings); + translationSchema.Output(); + Console.WriteLine("Done!"); + } + + private readonly struct Schema + { + private readonly JsonSchemaGeneratorSettings _generatorSettings; + private readonly string _title, _description; + private readonly string _outFileName; + + public Schema(string schemaTitle, string schemaDescription, string fileName, JsonSchemaGeneratorSettings settings) + { + _title = schemaTitle; + _description = schemaDescription; + _outFileName = fileName; + _generatorSettings = settings; + } + + public void Output() + { + Console.WriteLine($"Outputting {_title}"); + File.WriteAllText($"{_outFileName}.json", ToString()); + } + + public override string ToString() + { + return GetJsonSchema().ToJson(); + } + + private JsonSchema GetJsonSchema() + { + var schema = JsonSchema.FromType(_generatorSettings); + schema.Title = _title; + var schemaLinkProp = new JsonSchemaProperty + { + Type = JsonObjectType.String, + Description = "The schema to validate with" + }; + schema.Properties.Add("$schema", schemaLinkProp); + schema.ExtensionData ??= new Dictionary(); + schema.ExtensionData.Add("$docs", new Dictionary + { + {"title", _title}, + {"description", _description} + }); + + switch (_title) + { + case "Celestial Body Schema": + schema.Definitions["OrbitModule"].Properties["semiMajorAxis"].Default = 5000f; + break; + case "Star System Schema": + schema.Definitions["NomaiCoordinates"].Properties["x"].UniqueItems = true; + schema.Definitions["NomaiCoordinates"].Properties["y"].UniqueItems = true; + schema.Definitions["NomaiCoordinates"].Properties["z"].UniqueItems = true; + break; + } + + if (_title is "Star System Schema" or "Celestial Body Schema") + { + schema.Properties.Add("extras", new JsonSchemaProperty { + Type = JsonObjectType.Object, + Description = "Extra data that may be used by extension mods", + AllowAdditionalProperties = true, + AdditionalPropertiesSchema = new JsonSchema + { + Type = JsonObjectType.Object + } + }); + } + + return schema; + } + } } \ No newline at end of file From 6aad0edd33b40b7980a9f422d06a2c63e2d26f85 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Mon, 29 Aug 2022 21:29:01 +0000 Subject: [PATCH 09/18] Updated Schemas --- NewHorizons/Schemas/body_schema.json | 5 ++++- NewHorizons/Schemas/star_system_schema.json | 5 ++++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/NewHorizons/Schemas/body_schema.json b/NewHorizons/Schemas/body_schema.json index c4fe13eb..02771c9b 100644 --- a/NewHorizons/Schemas/body_schema.json +++ b/NewHorizons/Schemas/body_schema.json @@ -134,7 +134,10 @@ }, "extras": { "type": "object", - "description": "Extra data that may be used by extension mods" + "description": "Extra data that may be used by extension mods", + "additionalProperties": { + "type": "object" + } } }, "definitions": { diff --git a/NewHorizons/Schemas/star_system_schema.json b/NewHorizons/Schemas/star_system_schema.json index 54770b00..d8073db0 100644 --- a/NewHorizons/Schemas/star_system_schema.json +++ b/NewHorizons/Schemas/star_system_schema.json @@ -77,7 +77,10 @@ }, "extras": { "type": "object", - "description": "Extra data that may be used by extension mods" + "description": "Extra data that may be used by extension mods", + "additionalProperties": { + "type": "object" + } } }, "definitions": { From 1c99f6c3d43e9d576b572a1fa87e6d5d52482f1a Mon Sep 17 00:00:00 2001 From: Ben C Date: Mon, 29 Aug 2022 17:31:01 -0400 Subject: [PATCH 10/18] Update Docs Again --- docs/content/pages/tutorials/api.md | 9 +++++++-- docs/content/pages/tutorials/extending.md | 12 +++++------- 2 files changed, 12 insertions(+), 9 deletions(-) diff --git a/docs/content/pages/tutorials/api.md b/docs/content/pages/tutorials/api.md index 817c89ba..0400351f 100644 --- a/docs/content/pages/tutorials/api.md +++ b/docs/content/pages/tutorials/api.md @@ -52,9 +52,14 @@ public interface INewHorizons UnityEvent GetBodyLoadedEvent(); /// - /// Gets an object in the `extras` object of a config, returns null if the key doesn't exist + /// Gets an object in the `extras` object of a body config, returns null if the key doesn't exist /// - object GetExtraModule(Type moduleType, string extrasModuleName, string planetName); + object GetExtraModuleForBody(Type moduleType, string extrasModuleName, string planetName); + + /// + /// Gets an object in the `extras` object of a system config, returns null if the key doesn't exist + /// + object GetExtraModuleForSystem(Type moduleType, string extrasModuleName, string systemName); /// /// Allows you to overwrite the default system. This is where the player is respawned after dying. diff --git a/docs/content/pages/tutorials/extending.md b/docs/content/pages/tutorials/extending.md index 67e7e5ca..406b5e0a 100644 --- a/docs/content/pages/tutorials/extending.md +++ b/docs/content/pages/tutorials/extending.md @@ -4,8 +4,6 @@ Description: A guide on extending config files with the New Horizons API Sort_Priority: 5 --- - - # Extending Configs This guide will explain how to use the API to add new features to New Horizons. @@ -25,9 +23,9 @@ Addon developers will add a key to the `extras` object in the root of the config } ``` -**It's up to the addon dev to list your mod as a dependency!** +Your mod will then use the API's `GetExtraModuleForBody` method to obtain the `myCoolExtensionData` object. -Your mod will then use the API's `GetExtraModule` method to obtain the `myCoolExtensionData` object. +**It's up to the addon dev to list your mod as a dependency!** ## Extending Planets @@ -48,13 +46,13 @@ public class MyCoolExtensionData { } ``` -Then, use the `GetExtraModule` method: +Then, use the `GetExtraModuleForBody` method: ```cs var api = ModHelper.Interactions.TryGetModApi("xen.NewHorizons"); api.GetBodyLoadedEvent().AddListener((name) => { ModHelper.Console.WriteLine($"Body: {name} Loaded!"); - var potentialData = api.GetExtraModule(typeof(MyCoolExtensionData), "myCoolExtensionData", name); + var potentialData = api.GetExtraModuleForBody(typeof(MyCoolExtensionData), "myCoolExtensionData", name); // Makes sure the module is valid and not null if (potentialData is MyCoolExtensionData data) { ModHelper.Console.WriteLine($"myCoolExtensionProperty for {name} is {data.myCoolExtensionProperty}!"); @@ -64,4 +62,4 @@ api.GetBodyLoadedEvent().AddListener((name) => { ## Extending Systems - +Extending systems is the exact same as extending planets, except you use the `GetExtraModuleForSystem` method instead. From 7cc26d66d972638044f7a7cd7d338859ffe8f4d7 Mon Sep 17 00:00:00 2001 From: Ben C Date: Mon, 29 Aug 2022 17:34:55 -0400 Subject: [PATCH 11/18] Add path for funny --- NewHorizons/Main.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/NewHorizons/Main.cs b/NewHorizons/Main.cs index 97ba6124..8c9a7b34 100644 --- a/NewHorizons/Main.cs +++ b/NewHorizons/Main.cs @@ -618,7 +618,7 @@ namespace NewHorizons starSystemConfig.Migrate(); starSystemConfig.FixCoordinates(); - var system = new NewHorizonsSystem(config.starSystem, starSystemConfig, "", mod); + var system = new NewHorizonsSystem(config.starSystem, starSystemConfig, $"systems/{config.starSystem}.json", mod); SystemDict.Add(config.starSystem, system); From 1fcf21ff0e8134c4ae22c3339d6f420a89a01280 Mon Sep 17 00:00:00 2001 From: Ben C Date: Mon, 29 Aug 2022 17:38:00 -0400 Subject: [PATCH 12/18] Do da stanky leg 2 --- NewHorizons/Main.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/NewHorizons/Main.cs b/NewHorizons/Main.cs index 8c9a7b34..a975b0ba 100644 --- a/NewHorizons/Main.cs +++ b/NewHorizons/Main.cs @@ -618,7 +618,7 @@ namespace NewHorizons starSystemConfig.Migrate(); starSystemConfig.FixCoordinates(); - var system = new NewHorizonsSystem(config.starSystem, starSystemConfig, $"systems/{config.starSystem}.json", mod); + var system = new NewHorizonsSystem(config.starSystem, starSystemConfig, $"", mod); SystemDict.Add(config.starSystem, system); From c31064c68ed7a1b7346e12bb0cea38f7601cdbfa Mon Sep 17 00:00:00 2001 From: Ben C Date: Mon, 29 Aug 2022 18:47:53 -0400 Subject: [PATCH 13/18] What if I like changed it LOL!!! --- NewHorizons/Handlers/PlanetCreationHandler.cs | 11 ++++++- NewHorizons/INewHorizons.cs | 8 ++--- NewHorizons/NewHorizonsApi.cs | 32 +++++++++---------- docs/content/pages/tutorials/api.md | 8 ++--- docs/content/pages/tutorials/extending.md | 23 +++++++++---- 5 files changed, 50 insertions(+), 32 deletions(-) diff --git a/NewHorizons/Handlers/PlanetCreationHandler.cs b/NewHorizons/Handlers/PlanetCreationHandler.cs index fcb82a02..4147fdb9 100644 --- a/NewHorizons/Handlers/PlanetCreationHandler.cs +++ b/NewHorizons/Handlers/PlanetCreationHandler.cs @@ -248,7 +248,16 @@ namespace NewHorizons.Handlers } } } - Main.Instance.OnPlanetLoaded?.Invoke(body.Config.name); + + try + { + Main.Instance.OnPlanetLoaded?.Invoke(body.Config.name); + } + catch (Exception e) + { + Logger.LogError($"Error in event handler for OnPlanetLoaded on body {body.Config.name}: {e.Message} : {e.StackTrace}"); + } + return true; } diff --git a/NewHorizons/INewHorizons.cs b/NewHorizons/INewHorizons.cs index aa014ea6..8f132ee7 100644 --- a/NewHorizons/INewHorizons.cs +++ b/NewHorizons/INewHorizons.cs @@ -50,14 +50,14 @@ namespace NewHorizons UnityEvent GetBodyLoadedEvent(); /// - /// Gets an object in the `extras` object of a body config, returns null if the key doesn't exist + /// Uses JSONPath to query a body /// - object GetExtraModuleForBody(Type moduleType, string extrasModuleName, string planetName); + object QueryBody(Type outType, string bodyName, string path); /// - /// Gets an object in the `extras` object of a system config, returns null if the key doesn't exist + /// Uses JSONPath to query a system /// - object GetExtraModuleForSystem(Type moduleType, string extrasModuleName, string systemName); + object QuerySystem(Type outType, string path); /// /// Allows you to overwrite the default system. This is where the player is respawned after dying. diff --git a/NewHorizons/NewHorizonsApi.cs b/NewHorizons/NewHorizonsApi.cs index e8e36a24..0ac47b68 100644 --- a/NewHorizons/NewHorizonsApi.cs +++ b/NewHorizons/NewHorizonsApi.cs @@ -8,6 +8,8 @@ using System.Collections.Generic; using System.Data.SqlTypes; using System.IO; using System.Linq; +using System.Reflection; +using Newtonsoft.Json; using Newtonsoft.Json.Linq; using UnityEngine; using UnityEngine.Events; @@ -101,42 +103,40 @@ namespace NewHorizons } } - private object GetExtraModule(Type moduleType, string key, string path) + private static object QueryJson(Type outType, string filePath, string jsonPath) { - if (path == "") return null; + if (filePath == "") return null; try { - var jsonText = File.ReadAllText(path); + var jsonText = File.ReadAllText(filePath); var jsonData = JObject.Parse(jsonText); - var possibleExtras = jsonData.Property("extras")?.Value; - if (possibleExtras is JObject extras) - { - return extras.Property(key)?.Value.ToObject(moduleType); - } - return null; + return jsonData.SelectToken(jsonPath)?.ToObject(outType); } catch (FileNotFoundException) { return null; } + catch (JsonException e) + { + Logger.LogError($"{e.Message} : {e.StackTrace}"); + return null; + } } - public object GetExtraModuleForBody(Type moduleType, string extraModuleKey, string planetName) + public object QueryBody(Type outType, string bodyName, string jsonPath) { - var planet = Main.BodyDict[Main.Instance.CurrentStarSystem].Find((b) => b.Config.name == planetName); + var planet = Main.BodyDict[Main.Instance.CurrentStarSystem].Find((b) => b.Config.name == bodyName); return planet == null ? null - : GetExtraModule(moduleType, extraModuleKey, - planet.Mod.ModHelper.Manifest.ModFolderPath + planet.RelativePath); + : QueryJson(outType, planet.Mod.ModHelper.Manifest.ModFolderPath + planet.RelativePath, jsonPath); } - public object GetExtraModuleForSystem(Type moduleType, string extraModuleKey, string systemName) + public object QuerySystem(Type outType, string jsonPath) { var system = Main.SystemDict[Main.Instance.CurrentStarSystem]; return system == null ? null - : GetExtraModule(moduleType, extraModuleKey, - system.Mod.ModHelper.Manifest.ModFolderPath + system.RelativePath); + : QueryJson(outType, system.Mod.ModHelper.Manifest.ModFolderPath + system.RelativePath, jsonPath); } public GameObject SpawnObject(GameObject planet, Sector sector, string propToCopyPath, Vector3 position, Vector3 eulerAngles, diff --git a/docs/content/pages/tutorials/api.md b/docs/content/pages/tutorials/api.md index 0400351f..5c7a8996 100644 --- a/docs/content/pages/tutorials/api.md +++ b/docs/content/pages/tutorials/api.md @@ -52,14 +52,14 @@ public interface INewHorizons UnityEvent GetBodyLoadedEvent(); /// - /// Gets an object in the `extras` object of a body config, returns null if the key doesn't exist + /// Uses JSONPath to query a body /// - object GetExtraModuleForBody(Type moduleType, string extrasModuleName, string planetName); + object QueryBody(Type outType, string bodyName, string path); /// - /// Gets an object in the `extras` object of a system config, returns null if the key doesn't exist + /// Uses JSONPath to query a system /// - object GetExtraModuleForSystem(Type moduleType, string extrasModuleName, string systemName); + object QuerySystem(Type outType, string path); /// /// Allows you to overwrite the default system. This is where the player is respawned after dying. diff --git a/docs/content/pages/tutorials/extending.md b/docs/content/pages/tutorials/extending.md index 406b5e0a..7c3b4ec4 100644 --- a/docs/content/pages/tutorials/extending.md +++ b/docs/content/pages/tutorials/extending.md @@ -23,7 +23,7 @@ Addon developers will add a key to the `extras` object in the root of the config } ``` -Your mod will then use the API's `GetExtraModuleForBody` method to obtain the `myCoolExtensionData` object. +Your mod will then use the API's `QueryBody` method to obtain the `myCoolExtensionData` object. **It's up to the addon dev to list your mod as a dependency!** @@ -31,7 +31,7 @@ Your mod will then use the API's `GetExtraModuleForBody` method to obtain the `m You can extend all planets by hooking into the `OnBodyLoaded` event of the API: -```cs +```csharp var api = ModHelper.Interactions.TryGetModApi("xen.NewHorizons"); api.GetBodyLoadedEvent().AddListener((name) => { ModHelper.Console.WriteLine($"Body: {name} Loaded!"); @@ -40,19 +40,19 @@ api.GetBodyLoadedEvent().AddListener((name) => { In order to get your extra module, first define the module as a class: -```cs +```csharp public class MyCoolExtensionData { int myCoolExtensionProperty; } ``` -Then, use the `GetExtraModuleForBody` method: +Then, use the `QueryBody` method: -```cs +```csharp var api = ModHelper.Interactions.TryGetModApi("xen.NewHorizons"); api.GetBodyLoadedEvent().AddListener((name) => { ModHelper.Console.WriteLine($"Body: {name} Loaded!"); - var potentialData = api.GetExtraModuleForBody(typeof(MyCoolExtensionData), "myCoolExtensionData", name); + var potentialData = api.QueryBody(typeof(MyCoolExtensionData), "$.extras.myCoolExtensionData", name); // Makes sure the module is valid and not null if (potentialData is MyCoolExtensionData data) { ModHelper.Console.WriteLine($"myCoolExtensionProperty for {name} is {data.myCoolExtensionProperty}!"); @@ -62,4 +62,13 @@ api.GetBodyLoadedEvent().AddListener((name) => { ## Extending Systems -Extending systems is the exact same as extending planets, except you use the `GetExtraModuleForSystem` method instead. +Extending systems is the exact same as extending planets, except you use the `QuerySystem` method instead. + +## Accessing Other Values + +You can also use the `QueryBody` method to get values of the config outside of your extension object + +```csharp +var primaryBody = NHAPI.QueryBody(typeof(string), "Wetrock", "$.Orbit.primaryBody"); + ModHelper.Console.WriteLine($"Primary of {bodyName} is {primaryBody ?? "NULL"}!"); +``` From a9a9b20e31ae35e54717bbb2f536580c6f86723b Mon Sep 17 00:00:00 2001 From: Ben C Date: Mon, 29 Aug 2022 18:55:58 -0400 Subject: [PATCH 14/18] Fix name inconsistency in docs --- docs/content/pages/tutorials/extending.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/content/pages/tutorials/extending.md b/docs/content/pages/tutorials/extending.md index 7c3b4ec4..0e9b30bc 100644 --- a/docs/content/pages/tutorials/extending.md +++ b/docs/content/pages/tutorials/extending.md @@ -69,6 +69,6 @@ Extending systems is the exact same as extending planets, except you use the `Qu You can also use the `QueryBody` method to get values of the config outside of your extension object ```csharp -var primaryBody = NHAPI.QueryBody(typeof(string), "Wetrock", "$.Orbit.primaryBody"); +var primaryBody = api.QueryBody(typeof(string), "Wetrock", "$.Orbit.primaryBody"); ModHelper.Console.WriteLine($"Primary of {bodyName} is {primaryBody ?? "NULL"}!"); ``` From 5c04f456b6af51d3fc6bfa19ff3c658ffc48a8b5 Mon Sep 17 00:00:00 2001 From: Noah Pilarski Date: Mon, 29 Aug 2022 20:51:41 -0400 Subject: [PATCH 15/18] Just log the exception entirely so that it includes inner exceptions --- NewHorizons/Handlers/PlanetCreationHandler.cs | 2 +- NewHorizons/NewHorizonsApi.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/NewHorizons/Handlers/PlanetCreationHandler.cs b/NewHorizons/Handlers/PlanetCreationHandler.cs index 4147fdb9..ba0ea8f8 100644 --- a/NewHorizons/Handlers/PlanetCreationHandler.cs +++ b/NewHorizons/Handlers/PlanetCreationHandler.cs @@ -255,7 +255,7 @@ namespace NewHorizons.Handlers } catch (Exception e) { - Logger.LogError($"Error in event handler for OnPlanetLoaded on body {body.Config.name}: {e.Message} : {e.StackTrace}"); + Logger.LogError($"Error in event handler for OnPlanetLoaded on body {body.Config.name}: {e}"); } return true; diff --git a/NewHorizons/NewHorizonsApi.cs b/NewHorizons/NewHorizonsApi.cs index 0ac47b68..2c551f59 100644 --- a/NewHorizons/NewHorizonsApi.cs +++ b/NewHorizons/NewHorizonsApi.cs @@ -118,7 +118,7 @@ namespace NewHorizons } catch (JsonException e) { - Logger.LogError($"{e.Message} : {e.StackTrace}"); + Logger.LogError(e.ToString()); return null; } } From 11dc7551d8b369f5d56b0ca268bd7d6f0a156277 Mon Sep 17 00:00:00 2001 From: Noah Pilarski Date: Mon, 29 Aug 2022 21:14:20 -0400 Subject: [PATCH 16/18] Remove unused namespaces --- NewHorizons/NewHorizonsApi.cs | 2 -- 1 file changed, 2 deletions(-) diff --git a/NewHorizons/NewHorizonsApi.cs b/NewHorizons/NewHorizonsApi.cs index 2c551f59..4924834f 100644 --- a/NewHorizons/NewHorizonsApi.cs +++ b/NewHorizons/NewHorizonsApi.cs @@ -5,10 +5,8 @@ using OWML.Common; using OWML.Utils; using System; using System.Collections.Generic; -using System.Data.SqlTypes; using System.IO; using System.Linq; -using System.Reflection; using Newtonsoft.Json; using Newtonsoft.Json.Linq; using UnityEngine; From 11b3381ac291ded01dfc55f403d842f1fab43309 Mon Sep 17 00:00:00 2001 From: Noah Pilarski Date: Tue, 30 Aug 2022 03:13:45 -0400 Subject: [PATCH 17/18] Stop dev tools from deleting extras --- NewHorizons/External/Configs/PlanetConfig.cs | 5 +++++ NewHorizons/External/Configs/StarSystemConfig.cs | 5 +++++ SchemaExporter/SchemaExporter.cs | 4 ++-- 3 files changed, 12 insertions(+), 2 deletions(-) diff --git a/NewHorizons/External/Configs/PlanetConfig.cs b/NewHorizons/External/Configs/PlanetConfig.cs index 4a353011..2b071244 100644 --- a/NewHorizons/External/Configs/PlanetConfig.cs +++ b/NewHorizons/External/Configs/PlanetConfig.cs @@ -169,6 +169,11 @@ namespace NewHorizons.External.Configs /// public WaterModule Water; + /// + /// Extra data that may be used by extension mods + /// + public object extras; + public PlanetConfig() { // Always have to have a base module diff --git a/NewHorizons/External/Configs/StarSystemConfig.cs b/NewHorizons/External/Configs/StarSystemConfig.cs index 2df0dc8c..ce311174 100644 --- a/NewHorizons/External/Configs/StarSystemConfig.cs +++ b/NewHorizons/External/Configs/StarSystemConfig.cs @@ -102,6 +102,11 @@ namespace NewHorizons.External.Configs /// public CuriosityColorInfo[] curiosities; + /// + /// Extra data that may be used by extension mods + /// + public object extras; + public class NomaiCoordinates { [MinLength(2)] diff --git a/SchemaExporter/SchemaExporter.cs b/SchemaExporter/SchemaExporter.cs index 33c12666..c2e94e25 100644 --- a/SchemaExporter/SchemaExporter.cs +++ b/SchemaExporter/SchemaExporter.cs @@ -92,7 +92,7 @@ public static class SchemaExporter if (_title is "Star System Schema" or "Celestial Body Schema") { - schema.Properties.Add("extras", new JsonSchemaProperty { + schema.Properties["extras"] = new JsonSchemaProperty { Type = JsonObjectType.Object, Description = "Extra data that may be used by extension mods", AllowAdditionalProperties = true, @@ -100,7 +100,7 @@ public static class SchemaExporter { Type = JsonObjectType.Object } - }); + }; } return schema; From 9709601048decd8c64acb56d17873458b8fe97b8 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Tue, 30 Aug 2022 07:22:48 +0000 Subject: [PATCH 18/18] Updated Schemas --- NewHorizons/Schemas/body_schema.json | 8 ++++---- NewHorizons/Schemas/star_system_schema.json | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/NewHorizons/Schemas/body_schema.json b/NewHorizons/Schemas/body_schema.json index 02771c9b..3783d7e7 100644 --- a/NewHorizons/Schemas/body_schema.json +++ b/NewHorizons/Schemas/body_schema.json @@ -128,16 +128,16 @@ "description": "Add water to this planet", "$ref": "#/definitions/WaterModule" }, - "$schema": { - "type": "string", - "description": "The schema to validate with" - }, "extras": { "type": "object", "description": "Extra data that may be used by extension mods", "additionalProperties": { "type": "object" } + }, + "$schema": { + "type": "string", + "description": "The schema to validate with" } }, "definitions": { diff --git a/NewHorizons/Schemas/star_system_schema.json b/NewHorizons/Schemas/star_system_schema.json index d8073db0..032fb8f1 100644 --- a/NewHorizons/Schemas/star_system_schema.json +++ b/NewHorizons/Schemas/star_system_schema.json @@ -71,16 +71,16 @@ "$ref": "#/definitions/CuriosityColorInfo" } }, - "$schema": { - "type": "string", - "description": "The schema to validate with" - }, "extras": { "type": "object", "description": "Extra data that may be used by extension mods", "additionalProperties": { "type": "object" } + }, + "$schema": { + "type": "string", + "description": "The schema to validate with" } }, "definitions": {