From 4324123be58fcd0abc6c4a4b4e8879f7439d8980 Mon Sep 17 00:00:00 2001 From: Joshua Thome Date: Mon, 30 Oct 2023 23:28:32 -0500 Subject: [PATCH 01/10] Item and Item Socket wrapper components --- NewHorizons/Components/Props/NHItem.cs | 64 +++++++++++++++ NewHorizons/Components/Props/NHItemSocket.cs | 82 ++++++++++++++++++++ 2 files changed, 146 insertions(+) create mode 100644 NewHorizons/Components/Props/NHItem.cs create mode 100644 NewHorizons/Components/Props/NHItemSocket.cs diff --git a/NewHorizons/Components/Props/NHItem.cs b/NewHorizons/Components/Props/NHItem.cs new file mode 100644 index 00000000..24134749 --- /dev/null +++ b/NewHorizons/Components/Props/NHItem.cs @@ -0,0 +1,64 @@ +using NewHorizons.Handlers; +using OWML.Utils; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Net.Sockets; +using System.Text; +using System.Threading.Tasks; +using UnityEngine; + +namespace NewHorizons.Components.Props +{ + public class NHItem : OWItem + { + public string DisplayName; + public bool Droppable; + public string PickupCondition; + public bool ClearPickupConditionOnDrop; + + public ItemType ItemType + { + get => _type; + set => _type = value; + } + + public override string GetDisplayName() + { + return TranslationHandler.GetTranslation(DisplayName, TranslationHandler.TextType.UI); + } + + public override bool CheckIsDroppable() + { + return Droppable; + } + + public override void PickUpItem(Transform holdTranform) + { + base.PickUpItem(holdTranform); + TriggerPickupConditions(); + } + + public override void DropItem(Vector3 position, Vector3 normal, Transform parent, Sector sector, IItemDropTarget customDropTarget) + { + base.DropItem(position, normal, parent, sector, customDropTarget); + TriggerDropConditions(); + } + + internal void TriggerPickupConditions() + { + if (!string.IsNullOrEmpty(PickupCondition)) + { + DialogueConditionManager.SharedInstance.SetConditionState(PickupCondition, true); + } + } + + internal void TriggerDropConditions() + { + if (ClearPickupConditionOnDrop && !string.IsNullOrEmpty(PickupCondition)) + { + DialogueConditionManager.SharedInstance.SetConditionState(PickupCondition, false); + } + } + } +} diff --git a/NewHorizons/Components/Props/NHItemSocket.cs b/NewHorizons/Components/Props/NHItemSocket.cs new file mode 100644 index 00000000..29acb1bb --- /dev/null +++ b/NewHorizons/Components/Props/NHItemSocket.cs @@ -0,0 +1,82 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using UnityEngine; + +namespace NewHorizons.Components.Props +{ + public class NHItemSocket : OWItemSocket + { + public bool UseGiveTakePrompts; + public string InsertCondition; + public bool ClearInsertConditionOnRemoval; + public string RemovalCondition; + public bool ClearRemovalConditionOnInsert; + + public ItemType ItemType + { + get => _acceptableType; + set => _acceptableType = value; + } + + public override bool UsesGiveTakePrompts() + { + return UseGiveTakePrompts; + } + + public override bool AcceptsItem(OWItem item) + { + if (item == null || item._type == ItemType.Invalid) + { + return false; + } + return ItemType == item._type; + } + + public override bool PlaceIntoSocket(OWItem item) + { + if (base.PlaceIntoSocket(item)) + { + TriggerInsertConditions(); + return true; + } + return false; + } + + public override OWItem RemoveFromSocket() + { + var removedItem = base.RemoveFromSocket(); + if (removedItem != null) + { + TriggerRemovalConditions(); + } + return removedItem; + } + + internal void TriggerInsertConditions() + { + if (!string.IsNullOrEmpty(InsertCondition)) + { + DialogueConditionManager.SharedInstance.SetConditionState(InsertCondition, true); + } + if (ClearRemovalConditionOnInsert && !string.IsNullOrEmpty(RemovalCondition)) + { + DialogueConditionManager.SharedInstance.SetConditionState(RemovalCondition, false); + } + } + + internal void TriggerRemovalConditions() + { + if (!string.IsNullOrEmpty(RemovalCondition)) + { + DialogueConditionManager.SharedInstance.SetConditionState(RemovalCondition, true); + } + if (ClearInsertConditionOnRemoval && !string.IsNullOrEmpty(InsertCondition)) + { + DialogueConditionManager.SharedInstance.SetConditionState(InsertCondition, false); + } + } + } +} From 6d1bbfb84eaede37034105e7ad36705fb3c172ca Mon Sep 17 00:00:00 2001 From: Joshua Thome Date: Mon, 30 Oct 2023 23:29:10 -0500 Subject: [PATCH 02/10] Info data structures for item and item socket --- .../External/Modules/Props/DetailInfo.cs | 11 ++++ .../External/Modules/Props/Item/ItemInfo.cs | 54 +++++++++++++++++++ .../Modules/Props/Item/ItemSocketInfo.cs | 50 +++++++++++++++++ 3 files changed, 115 insertions(+) create mode 100644 NewHorizons/External/Modules/Props/Item/ItemInfo.cs create mode 100644 NewHorizons/External/Modules/Props/Item/ItemSocketInfo.cs diff --git a/NewHorizons/External/Modules/Props/DetailInfo.cs b/NewHorizons/External/Modules/Props/DetailInfo.cs index 48b3b125..d9654562 100644 --- a/NewHorizons/External/Modules/Props/DetailInfo.cs +++ b/NewHorizons/External/Modules/Props/DetailInfo.cs @@ -1,3 +1,4 @@ +using NewHorizons.External.Modules.Props.Item; using NewHorizons.External.SerializableData; using Newtonsoft.Json; using System; @@ -101,6 +102,16 @@ namespace NewHorizons.External.Modules.Props /// [DefaultValue(true)] public bool blinkWhenActiveChanged = true; + /// + /// Should this detail be treated as an interactible item + /// + public ItemInfo item; + + /// + /// Should this detail be treated as a socket for an interactible item + /// + public ItemSocketInfo itemSocket; + [Obsolete("alignToNormal is deprecated. Use alignRadial instead")] public bool alignToNormal; } diff --git a/NewHorizons/External/Modules/Props/Item/ItemInfo.cs b/NewHorizons/External/Modules/Props/Item/ItemInfo.cs new file mode 100644 index 00000000..5728e2a5 --- /dev/null +++ b/NewHorizons/External/Modules/Props/Item/ItemInfo.cs @@ -0,0 +1,54 @@ +using NewHorizons.External.SerializableData; +using Newtonsoft.Json; +using Newtonsoft.Json.Converters; +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Linq; +using System.Runtime.Serialization; +using System.Text; +using System.Threading.Tasks; + +namespace NewHorizons.External.Modules.Props.Item +{ + [JsonObject] + public class ItemInfo + { + /// + /// The name of the item to be displayed in the UI. Defaults to the name of the detail object. + /// + public string name; + /// + /// The type of the item, which determines its orientation when held and what sockets it fits into. This can be a custom string, or a vanilla ItemType (Scroll, WarpCode, SharedStone, ConversationStone, Lantern, SlideReel, DreamLantern, or VisionTorch). Defaults to the item name. + /// + public string itemType; + /// + /// The furthest distance where the player can interact with this item. Defaults to two meters, same as most vanilla items. Set this to zero to disable all interaction by default. + /// + [DefaultValue(2f)] public float interactRange = 2f; + /// + /// Whether the item can be dropped. Defaults to true. + /// + [DefaultValue(true)] public bool droppable = true; + /// + /// A relative offset to apply to the item's position when dropping it on the ground. + /// + public MVector3 dropOffset; + /// + /// The direction the item will be oriented when dropping it on the ground. Defaults to up (0, 1, 0). + /// + public MVector3 dropNormal; + /// + /// A dialogue condition to set when picking up this item. + /// + public string pickupCondition; + /// + /// Whether the pickup condition should be cleared when dropping the item. Defaults to true. + /// + [DefaultValue(true)] public bool clearPickupConditionOnDrop = true; + /// + /// A relative path from the planet to a socket that this item will be automatically inserted into. + /// + public string pathToInitialSocket; + } +} diff --git a/NewHorizons/External/Modules/Props/Item/ItemSocketInfo.cs b/NewHorizons/External/Modules/Props/Item/ItemSocketInfo.cs new file mode 100644 index 00000000..c7a2b3b2 --- /dev/null +++ b/NewHorizons/External/Modules/Props/Item/ItemSocketInfo.cs @@ -0,0 +1,50 @@ +using NewHorizons.External.SerializableData; +using Newtonsoft.Json; +using Newtonsoft.Json.Converters; +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Linq; +using System.Runtime.Serialization; +using System.Text; +using System.Threading.Tasks; + +namespace NewHorizons.External.Modules.Props.Item +{ + [JsonObject] + public class ItemSocketInfo : GeneralPropInfo + { + /// + /// The relative path to a child game object of this detail that will act as the socket point for the item. Will be used instead of this socket's positioning info if set. + /// + public string socketPath; + /// + /// The type of item allowed in this socket. This can be a custom string, or a vanilla ItemType (Scroll, WarpCode, SharedStone, ConversationStone, Lantern, SlideReel, DreamLantern, or VisionTorch). + /// + public string itemType; + /// + /// The furthest distance where the player can interact with this item socket. Defaults to two meters, same as most vanilla item sockets. Set this to zero to disable all interaction by default. + /// + [DefaultValue(2f)] public float interactRange = 2f; + /// + /// Whether to use "Give Item" / "Take Item" prompts instead of "Insert Item" / "Remove Item". + /// + public bool useGiveTakePrompts; + /// + /// A dialogue condition to set when inserting an item into this socket. + /// + public string insertCondition; + /// + /// Whether the insert condition should be cleared when removing the socketed item. Defaults to true. + /// + [DefaultValue(true)] public bool clearInsertConditionOnRemoval = true; + /// + /// A dialogue condition to set when removing an item from this socket, or when the socket is empty. + /// + public string removalCondition; + /// + /// Whether the removal condition should be cleared when inserting a socketed item. Defaults to true. + /// + [DefaultValue(true)] public bool clearRemovalConditionOnInsert = true; + } +} From cb7bece10702f385ed80278c297cf160a1bead19 Mon Sep 17 00:00:00 2001 From: Joshua Thome Date: Mon, 30 Oct 2023 23:29:28 -0500 Subject: [PATCH 03/10] Item builder --- NewHorizons/Builder/Props/DetailBuilder.cs | 10 ++ NewHorizons/Builder/Props/ItemBuilder.cs | 155 +++++++++++++++++++++ NewHorizons/Main.cs | 1 + 3 files changed, 166 insertions(+) create mode 100644 NewHorizons/Builder/Props/ItemBuilder.cs diff --git a/NewHorizons/Builder/Props/DetailBuilder.cs b/NewHorizons/Builder/Props/DetailBuilder.cs index 245ba6c1..1c7d25b3 100644 --- a/NewHorizons/Builder/Props/DetailBuilder.cs +++ b/NewHorizons/Builder/Props/DetailBuilder.cs @@ -163,6 +163,16 @@ namespace NewHorizons.Builder.Props } } + if (detail.item != null) + { + ItemBuilder.MakeItem(prop, go, sector, detail.item); + } + + if (detail.itemSocket != null) + { + ItemBuilder.MakeSocket(prop, go, sector, detail.itemSocket); + } + // Items should always be kept loaded else they will vanish in your hand as you leave the sector if (isItem) detail.keepLoaded = true; diff --git a/NewHorizons/Builder/Props/ItemBuilder.cs b/NewHorizons/Builder/Props/ItemBuilder.cs new file mode 100644 index 00000000..04b6180b --- /dev/null +++ b/NewHorizons/Builder/Props/ItemBuilder.cs @@ -0,0 +1,155 @@ +using NewHorizons.Components.Props; +using NewHorizons.External.Modules.Props.Item; +using NewHorizons.Utility.OWML; +using OWML.Utils; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using UnityEngine; + +namespace NewHorizons.Builder.Props +{ + public static class ItemBuilder + { + private static Dictionary _itemTypes; + + internal static void Init() + { + if (_itemTypes != null) + { + foreach (var value in _itemTypes.Values) + { + EnumUtils.Remove(value); + } + } + _itemTypes = new Dictionary(); + } + + public static NHItem MakeItem(GameObject go, GameObject planetGO, Sector sector, ItemInfo info) + { + var itemName = info.name; + if (string.IsNullOrEmpty(itemName)) + { + itemName = go.name; + } + + var itemTypeName = info.itemType; + if (string.IsNullOrEmpty(itemTypeName)) + { + itemTypeName = itemName; + } + + var itemType = GetOrCreateItemType(itemTypeName); + + var item = go.GetAddComponent(); + item._sector = sector; + item._interactable = info.interactRange > 0f; + item._interactRange = info.interactRange; + item._localDropOffset = info.dropOffset ?? Vector3.zero; + item._localDropNormal = info.dropNormal ?? Vector3.up; + + item.DisplayName = itemName; + item.ItemType = itemType; + item.Droppable = info.droppable; + item.PickupCondition = info.pickupCondition; + item.ClearPickupConditionOnDrop = info.clearPickupConditionOnDrop; + + Delay.FireInNUpdates(() => + { + if (item != null && !string.IsNullOrEmpty(info.pathToInitialSocket)) + { + var socketGO = planetGO.transform.Find(info.pathToInitialSocket); + if (socketGO != null) + { + var socket = socketGO.GetComponent(); + if (socket != null) + { + if (socket.PlaceIntoSocket(item)) + { + // Successfully socketed + } + else + { + NHLogger.LogError($"Could not insert item {itemName} into socket at path {socketGO}"); + } + } + else + { + NHLogger.LogError($"Could not find a socket to parent item {itemName} to at path {socketGO}"); + } + } + else + { + NHLogger.LogError($"Could not find a socket to parent item {itemName} to at path {socketGO}"); + } + } + }, 1); + + return item; + } + + public static NHItemSocket MakeSocket(GameObject go, GameObject planetGO, Sector sector, ItemSocketInfo info) + { + + var socketGO = GeneralPropBuilder.MakeNew("Socket", planetGO, sector, info, defaultParent: go.transform); + + var itemType = EnumUtils.TryParse(info.itemType, true, out ItemType result) ? result : ItemType.Invalid; + if (itemType == ItemType.Invalid && !string.IsNullOrEmpty(info.itemType)) + { + itemType = EnumUtilities.Create(info.itemType); + } + + var socket = socketGO.GetAddComponent(); + socket._sector = sector; + socket._interactable = info.interactRange > 0f; + socket._interactRange = info.interactRange; + + if (!string.IsNullOrEmpty(info.socketPath)) + { + socket._socketTransform = go.transform.Find(info.socketPath); + } + if (socket._socketTransform == null) + { + socket._socketTransform = socket.transform; + } + + socket.ItemType = itemType; + socket.UseGiveTakePrompts = info.useGiveTakePrompts; + socket.InsertCondition = info.insertCondition; + socket.ClearInsertConditionOnRemoval = info.clearInsertConditionOnRemoval; + socket.RemovalCondition = info.removalCondition; + socket.ClearRemovalConditionOnInsert = info.clearRemovalConditionOnInsert; + + Delay.FireInNUpdates(() => + { + if (socket != null && !socket._socketedItem) + { + socket.TriggerRemovalConditions(); + } + }, 2); + + return socket; + } + + public static ItemType GetOrCreateItemType(string name) + { + var itemType = ItemType.Invalid; + if (_itemTypes.ContainsKey(name)) + { + itemType = _itemTypes[name]; + } + else if (EnumUtils.TryParse(name, true, out ItemType result)) + { + itemType = result; + } + else if (!string.IsNullOrEmpty(name)) + { + itemType = EnumUtils.Create(name); + _itemTypes.Add(name, itemType); + } + return itemType; + } + } +} diff --git a/NewHorizons/Main.cs b/NewHorizons/Main.cs index e996ce2b..5d438e9d 100644 --- a/NewHorizons/Main.cs +++ b/NewHorizons/Main.cs @@ -437,6 +437,7 @@ namespace NewHorizons // Some builders have to be reset each loop SignalBuilder.Init(); BrambleDimensionBuilder.Init(); + ItemBuilder.Init(); AstroObjectLocator.Init(); StreamingHandler.Init(); AudioTypeHandler.Init(); From ee154fdb33717a7fd9b22f26c73a8039dbc6c0b2 Mon Sep 17 00:00:00 2001 From: Joshua Thome Date: Mon, 30 Oct 2023 23:29:47 -0500 Subject: [PATCH 04/10] Add translation helper methods to API --- NewHorizons/INewHorizons.cs | 31 +++++++++++++++++++++++++++++++ NewHorizons/NewHorizonsApi.cs | 8 ++++++++ 2 files changed, 39 insertions(+) diff --git a/NewHorizons/INewHorizons.cs b/NewHorizons/INewHorizons.cs index 903b76e5..096960d3 100644 --- a/NewHorizons/INewHorizons.cs +++ b/NewHorizons/INewHorizons.cs @@ -173,5 +173,36 @@ namespace NewHorizons /// A dictionary of each curiousity ID to its colour and highlight colour in the ship log. Optional. void AddShipLogXML(IModBehaviour mod, XElement xml, string planetName, string imageFolder = null, Dictionary entryPositions = null, Dictionary curiousityColours = null); #endregion + + #region Translations + /// + /// Look up shiplog-related translated text for the given text key. + /// Defaults to English if no translation in the current language is available, and just the key if no English translation is available. + /// + /// The text key to look up. + /// + string GetTranslationForShipLog(string text); + /// + /// Look up dialogue-related translated text for the given text key. + /// Defaults to English if no translation in the current language is available, and just the key if no English translation is available. + /// + /// The text key to look up. + /// + string GetTranslationForDialogue(string text); + /// + /// Look up UI-related translated text for the given text key. + /// Defaults to English if no translation in the current language is available, and just the key if no English translation is available. + /// + /// The text key to look up. + /// + string GetTranslationForUI(string text); + /// + /// Look up miscellaneous translated text for the given text key. + /// Defaults to English if no translation in the current language is available, and just the key if no English translation is available. + /// + /// The text key to look up. + /// + string GetTranslationForOtherText(string text); + #endregion } } diff --git a/NewHorizons/NewHorizonsApi.cs b/NewHorizons/NewHorizonsApi.cs index 0b25a339..f269cce9 100644 --- a/NewHorizons/NewHorizonsApi.cs +++ b/NewHorizons/NewHorizonsApi.cs @@ -322,5 +322,13 @@ namespace NewHorizons /// /// public void RegisterCustomBuilder(Action builder) => PlanetCreationHandler.CustomBuilders.Add(builder); + + public string GetTranslationForShipLog(string text) => TranslationHandler.GetTranslation(text, TranslationHandler.TextType.SHIPLOG); + + public string GetTranslationForDialogue(string text) => TranslationHandler.GetTranslation(text, TranslationHandler.TextType.DIALOGUE); + + public string GetTranslationForUI(string text) => TranslationHandler.GetTranslation(text, TranslationHandler.TextType.UI); + + public string GetTranslationForOtherText(string text) => TranslationHandler.GetTranslation(text, TranslationHandler.TextType.OTHER); } } From fbc92b7cd7ddd9a01466bfdce93fbbb99d126247 Mon Sep 17 00:00:00 2001 From: Ben C Date: Tue, 31 Oct 2023 04:32:18 +0000 Subject: [PATCH 05/10] Updated Schemas --- NewHorizons/Schemas/body_schema.json | 123 +++++++++++++++++++++++++++ 1 file changed, 123 insertions(+) diff --git a/NewHorizons/Schemas/body_schema.json b/NewHorizons/Schemas/body_schema.json index 380c4dfb..222fe780 100644 --- a/NewHorizons/Schemas/body_schema.json +++ b/NewHorizons/Schemas/body_schema.json @@ -1381,6 +1381,129 @@ "type": "boolean", "description": "Should the player close their eyes while the activation state changes. Only relevant if activationCondition or deactivationCondition are set.", "default": true + }, + "item": { + "description": "Should this detail be treated as an interactible item", + "$ref": "#/definitions/ItemInfo" + }, + "itemSocket": { + "description": "Should this detail be treated as a socket for an interactible item", + "$ref": "#/definitions/ItemSocketInfo" + } + } + }, + "ItemInfo": { + "type": "object", + "additionalProperties": false, + "properties": { + "name": { + "type": "string", + "description": "The name of the item to be displayed in the UI. Defaults to the name of the detail object." + }, + "itemType": { + "type": "string", + "description": "The type of the item, which determines its orientation when held and what sockets it fits into. This can be a custom string, or a vanilla ItemType (Scroll, WarpCode, SharedStone, ConversationStone, Lantern, SlideReel, DreamLantern, or VisionTorch). Defaults to the item name." + }, + "interactRange": { + "type": "number", + "description": "The furthest distance where the player can interact with this item. Defaults to two meters, same as most vanilla items. Set this to zero to disable all interaction by default.", + "format": "float", + "default": 2.0 + }, + "droppable": { + "type": "boolean", + "description": "Whether the item can be dropped. Defaults to true.", + "default": true + }, + "dropOffset": { + "description": "A relative offset to apply to the item's position when dropping it on the ground.", + "$ref": "#/definitions/MVector3" + }, + "dropNormal": { + "description": "The direction the item will be oriented when dropping it on the ground. Defaults to up (0, 1, 0).", + "$ref": "#/definitions/MVector3" + }, + "pickupCondition": { + "type": "string", + "description": "A dialogue condition to set when picking up this item." + }, + "clearPickupConditionOnDrop": { + "type": "boolean", + "description": "Whether the pickup condition should be cleared when dropping the item. Defaults to true.", + "default": true + }, + "pathToInitialSocket": { + "type": "string", + "description": "A relative path from the planet to a socket that this item will be automatically inserted into." + } + } + }, + "ItemSocketInfo": { + "type": "object", + "additionalProperties": false, + "properties": { + "rotation": { + "description": "Rotation of the object", + "$ref": "#/definitions/MVector3" + }, + "alignRadial": { + "type": [ + "boolean", + "null" + ], + "description": "Do we try to automatically align this object to stand upright relative to the body's center? Stacks with rotation.\nDefaults to true for geysers, tornados, and volcanoes, and false for everything else." + }, + "position": { + "description": "Position of the object", + "$ref": "#/definitions/MVector3" + }, + "parentPath": { + "type": "string", + "description": "The relative path from the planet to the parent of this object. Optional (will default to the root sector)." + }, + "isRelativeToParent": { + "type": "boolean", + "description": "Whether the positional and rotational coordinates are relative to parent instead of the root planet object." + }, + "rename": { + "type": "string", + "description": "An optional rename of this object" + }, + "socketPath": { + "type": "string", + "description": "The relative path to a child game object of this detail that will act as the socket point for the item. Will be used instead of this socket's positioning info if set." + }, + "itemType": { + "type": "string", + "description": "The type of item allowed in this socket. This can be a custom string, or a vanilla ItemType (Scroll, WarpCode, SharedStone, ConversationStone, Lantern, SlideReel, DreamLantern, or VisionTorch)." + }, + "interactRange": { + "type": "number", + "description": "The furthest distance where the player can interact with this item socket. Defaults to two meters, same as most vanilla item sockets. Set this to zero to disable all interaction by default.", + "format": "float", + "default": 2.0 + }, + "useGiveTakePrompts": { + "type": "boolean", + "description": "Whether to use \"Give Item\" / \"Take Item\" prompts instead of \"Insert Item\" / \"Remove Item\"." + }, + "insertCondition": { + "type": "string", + "description": "A dialogue condition to set when inserting an item into this socket." + }, + "clearInsertConditionOnRemoval": { + "type": "boolean", + "description": "Whether the insert condition should be cleared when removing the socketed item. Defaults to true.", + "default": true + }, + "removalCondition": { + "type": "string", + "description": "A dialogue condition to set when removing an item from this socket, or when the socket is empty." + }, + "clearRemovalConditionOnInsert": { + "type": "boolean", + "description": "Whether the removal condition should be cleared when inserting a socketed item. Defaults to true.", + "default": true } } }, From 358f130c0d231ea4b04dc6c13e39d9e313fb854c Mon Sep 17 00:00:00 2001 From: Joshua Thome Date: Tue, 31 Oct 2023 01:31:05 -0500 Subject: [PATCH 06/10] Add IModBehavior params to detail builder and hierarchy --- .../Builder/Body/BrambleDimensionBuilder.cs | 5 +++-- NewHorizons/Builder/Props/DetailBuilder.cs | 20 ++++++------------- .../Builder/Props/GravityCannonBuilder.cs | 8 ++++---- NewHorizons/Builder/Props/NomaiTextBuilder.cs | 4 ++-- .../Builder/Props/ProjectionBuilder.cs | 4 ++-- NewHorizons/Builder/Props/PropBuildManager.cs | 6 +++--- NewHorizons/Builder/Props/RemoteBuilder.cs | 8 ++++---- NewHorizons/Builder/Props/ScatterBuilder.cs | 2 +- NewHorizons/Builder/Props/ShuttleBuilder.cs | 5 +++-- .../TranslatorText/TranslatorTextBuilder.cs | 6 +++--- NewHorizons/Builder/Props/WarpPadBuilder.cs | 15 +++++++------- NewHorizons/Handlers/PlanetCreationHandler.cs | 2 +- NewHorizons/INewHorizons.cs | 5 ++++- NewHorizons/NewHorizonsApi.cs | 11 ++++++++-- .../Utility/DebugTools/DebugPropPlacer.cs | 2 +- 15 files changed, 54 insertions(+), 49 deletions(-) diff --git a/NewHorizons/Builder/Body/BrambleDimensionBuilder.cs b/NewHorizons/Builder/Body/BrambleDimensionBuilder.cs index f92d1daf..6672b15f 100644 --- a/NewHorizons/Builder/Body/BrambleDimensionBuilder.cs +++ b/NewHorizons/Builder/Body/BrambleDimensionBuilder.cs @@ -6,6 +6,7 @@ using NewHorizons.External.Modules; using NewHorizons.External.Modules.Props; using NewHorizons.Utility; using NewHorizons.Utility.OWML; +using OWML.Common; using System.Collections.Generic; using System.Linq; using UnityEngine; @@ -80,7 +81,7 @@ namespace NewHorizons.Builder.Body if (_wallCollision == null) _wallCollision = Main.NHPrivateAssetBundle.LoadAsset("BrambleCollision"); } - public static GameObject Make(NewHorizonsBody body, GameObject go, NHAstroObject ao, Sector sector, OWRigidbody owRigidBody) + public static GameObject Make(NewHorizonsBody body, GameObject go, NHAstroObject ao, Sector sector, IModBehaviour mod, OWRigidbody owRigidBody) { InitPrefabs(); @@ -102,7 +103,7 @@ namespace NewHorizons.Builder.Body default: geometryPrefab = _hubGeometry; break; } - var geometry = DetailBuilder.Make(go, sector, geometryPrefab, new DetailInfo()); + var geometry = DetailBuilder.Make(go, sector, mod, geometryPrefab, new DetailInfo()); var exitWarps = _exitWarps.InstantiateInactive(); var repelVolume = _repelVolume.InstantiateInactive(); diff --git a/NewHorizons/Builder/Props/DetailBuilder.cs b/NewHorizons/Builder/Props/DetailBuilder.cs index 1c7d25b3..727e0a2a 100644 --- a/NewHorizons/Builder/Props/DetailBuilder.cs +++ b/NewHorizons/Builder/Props/DetailBuilder.cs @@ -52,24 +52,16 @@ namespace NewHorizons.Builder.Props /// /// Create a detail using an asset bundle or a path in the scene hierarchy of the item to copy. /// - public static GameObject Make(GameObject go, Sector sector, IModBehaviour mod, DetailInfo detail) + public static GameObject Make(GameObject planetGO, Sector sector, IModBehaviour mod, DetailInfo info) { - if (detail.assetBundle != null) + if (info.assetBundle != null) { // Shouldn't happen if (mod == null) return null; - return Make(go, sector, AssetBundleUtilities.LoadPrefab(detail.assetBundle, detail.path, mod), detail); + return Make(planetGO, sector, mod, AssetBundleUtilities.LoadPrefab(info.assetBundle, info.path, mod), info); } - else - return Make(go, sector, detail); - } - /// - /// Create a detail using a path in the scene hierarchy of the item to copy. - /// - public static GameObject Make(GameObject planetGO, Sector sector, DetailInfo info) - { if (_emptyPrefab == null) _emptyPrefab = new GameObject("Empty"); // Allow for empty game objects so you can set up conditional activation on them and parent other props to them @@ -82,14 +74,14 @@ namespace NewHorizons.Builder.Props } else { - return Make(planetGO, sector, prefab, info); + return Make(planetGO, sector, mod, prefab, info); } } /// /// Create a detail using a prefab. /// - public static GameObject Make(GameObject go, Sector sector, GameObject prefab, DetailInfo detail) + public static GameObject Make(GameObject go, Sector sector, IModBehaviour mod, GameObject prefab, DetailInfo detail) { if (prefab == null) return null; @@ -165,7 +157,7 @@ namespace NewHorizons.Builder.Props if (detail.item != null) { - ItemBuilder.MakeItem(prop, go, sector, detail.item); + ItemBuilder.MakeItem(prop, go, sector, detail.item, mod); } if (detail.itemSocket != null) diff --git a/NewHorizons/Builder/Props/GravityCannonBuilder.cs b/NewHorizons/Builder/Props/GravityCannonBuilder.cs index 44b1f075..b0a16a4d 100644 --- a/NewHorizons/Builder/Props/GravityCannonBuilder.cs +++ b/NewHorizons/Builder/Props/GravityCannonBuilder.cs @@ -76,7 +76,7 @@ namespace NewHorizons.Builder.Props if (_interfacePrefab == null || planetGO == null || sector == null || _detailedPlatformPrefab == null || _platformPrefab == null || _orbPrefab == null) return null; var detailInfo = new DetailInfo(info.controls) { keepLoaded = true }; - var gravityCannonObject = DetailBuilder.Make(planetGO, sector, _interfacePrefab, detailInfo); + var gravityCannonObject = DetailBuilder.Make(planetGO, sector, mod, _interfacePrefab, detailInfo); gravityCannonObject.SetActive(false); var gravityCannonController = gravityCannonObject.GetComponent(); @@ -87,7 +87,7 @@ namespace NewHorizons.Builder.Props gravityCannonController._retrieveShipLogFact = info.retrieveReveal ?? string.Empty; gravityCannonController._launchShipLogFact = info.launchReveal ?? string.Empty; - CreatePlatform(planetGO, sector, gravityCannonController, info); + CreatePlatform(planetGO, sector, mod, gravityCannonController, info); if (info.computer != null) { @@ -175,9 +175,9 @@ namespace NewHorizons.Builder.Props return computer; } - private static GameObject CreatePlatform(GameObject planetGO, Sector sector, GravityCannonController gravityCannonController, GravityCannonInfo platformInfo) + private static GameObject CreatePlatform(GameObject planetGO, Sector sector, IModBehaviour mod, GravityCannonController gravityCannonController, GravityCannonInfo platformInfo) { - var platform = DetailBuilder.Make(planetGO, sector, platformInfo.detailed ? _detailedPlatformPrefab : _platformPrefab, new DetailInfo(platformInfo) { keepLoaded = true }); + var platform = DetailBuilder.Make(planetGO, sector, mod, platformInfo.detailed ? _detailedPlatformPrefab : _platformPrefab, new DetailInfo(platformInfo) { keepLoaded = true }); gravityCannonController._forceVolume = platform.FindChild("ForceVolume").GetComponent(); gravityCannonController._platformTrigger = platform.FindChild("PlatformTrigger").GetComponent(); diff --git a/NewHorizons/Builder/Props/NomaiTextBuilder.cs b/NewHorizons/Builder/Props/NomaiTextBuilder.cs index e7035365..ce4ed43d 100644 --- a/NewHorizons/Builder/Props/NomaiTextBuilder.cs +++ b/NewHorizons/Builder/Props/NomaiTextBuilder.cs @@ -376,7 +376,7 @@ namespace NewHorizons.Builder.Props } case NomaiTextType.PreCrashComputer: { - var computerObject = DetailBuilder.Make(planetGO, sector, _preCrashComputerPrefab, new DetailInfo(info)); + var computerObject = DetailBuilder.Make(planetGO, sector, mod, _preCrashComputerPrefab, new DetailInfo(info)); computerObject.SetActive(false); var up = computerObject.transform.position - planetGO.transform.position; @@ -493,7 +493,7 @@ namespace NewHorizons.Builder.Props case NomaiTextType.Recorder: { var prefab = (info.type == NomaiTextType.PreCrashRecorder ? _preCrashRecorderPrefab : _recorderPrefab); - var recorderObject = DetailBuilder.Make(planetGO, sector, prefab, new DetailInfo(info)); + var recorderObject = DetailBuilder.Make(planetGO, sector, mod, prefab, new DetailInfo(info)); recorderObject.SetActive(false); if (info.rotation == null) diff --git a/NewHorizons/Builder/Props/ProjectionBuilder.cs b/NewHorizons/Builder/Props/ProjectionBuilder.cs index c73b330e..2827203d 100644 --- a/NewHorizons/Builder/Props/ProjectionBuilder.cs +++ b/NewHorizons/Builder/Props/ProjectionBuilder.cs @@ -203,7 +203,7 @@ namespace NewHorizons.Builder.Props if (_visionTorchDetectorPrefab == null) return null; // spawn a trigger for the vision torch - var g = DetailBuilder.Make(planetGO, sector, _visionTorchDetectorPrefab, new DetailInfo(info) { scale = 2, rename = !string.IsNullOrEmpty(info.rename) ? info.rename : "VisionStaffDetector" }); + var g = DetailBuilder.Make(planetGO, sector, mod, _visionTorchDetectorPrefab, new DetailInfo(info) { scale = 2, rename = !string.IsNullOrEmpty(info.rename) ? info.rename : "VisionStaffDetector" }); if (g == null) { @@ -240,7 +240,7 @@ namespace NewHorizons.Builder.Props if (_standingVisionTorchPrefab == null) return null; // Spawn the torch itself - var standingTorch = DetailBuilder.Make(planetGO, sector, _standingVisionTorchPrefab, new DetailInfo(info)); + var standingTorch = DetailBuilder.Make(planetGO, sector, mod, _standingVisionTorchPrefab, new DetailInfo(info)); if (standingTorch == null) { diff --git a/NewHorizons/Builder/Props/PropBuildManager.cs b/NewHorizons/Builder/Props/PropBuildManager.cs index af781f52..86dcf826 100644 --- a/NewHorizons/Builder/Props/PropBuildManager.cs +++ b/NewHorizons/Builder/Props/PropBuildManager.cs @@ -39,7 +39,7 @@ namespace NewHorizons.Builder.Props { try { - ShuttleBuilder.Make(go, sector, shuttleInfo); + ShuttleBuilder.Make(go, sector, nhBody.Mod, shuttleInfo); } catch (Exception ex) { @@ -283,7 +283,7 @@ namespace NewHorizons.Builder.Props { try { - WarpPadBuilder.Make(go, sector, warpReceiver); + WarpPadBuilder.Make(go, sector, nhBody.Mod, warpReceiver); } catch (Exception ex) { @@ -297,7 +297,7 @@ namespace NewHorizons.Builder.Props { try { - WarpPadBuilder.Make(go, sector, warpTransmitter); + WarpPadBuilder.Make(go, sector, nhBody.Mod, warpTransmitter); } catch (Exception ex) { diff --git a/NewHorizons/Builder/Props/RemoteBuilder.cs b/NewHorizons/Builder/Props/RemoteBuilder.cs index e4d6b547..4ae0ac01 100644 --- a/NewHorizons/Builder/Props/RemoteBuilder.cs +++ b/NewHorizons/Builder/Props/RemoteBuilder.cs @@ -149,7 +149,7 @@ namespace NewHorizons.Builder.Props { try { - MakeWhiteboard(go, sector, id, decal, info.whiteboard, nhBody); + MakeWhiteboard(go, sector, nhBody.Mod, id, decal, info.whiteboard, nhBody); } catch (Exception ex) { @@ -173,9 +173,9 @@ namespace NewHorizons.Builder.Props } } - public static void MakeWhiteboard(GameObject go, Sector sector, NomaiRemoteCameraPlatform.ID id, Texture2D decal, RemoteWhiteboardInfo info, NewHorizonsBody nhBody) + public static void MakeWhiteboard(GameObject go, Sector sector, IModBehaviour mod, NomaiRemoteCameraPlatform.ID id, Texture2D decal, RemoteWhiteboardInfo info, NewHorizonsBody nhBody) { - var whiteboard = DetailBuilder.Make(go, sector, _whiteboardPrefab, new DetailInfo(info)); + var whiteboard = DetailBuilder.Make(go, sector, mod, _whiteboardPrefab, new DetailInfo(info)); whiteboard.SetActive(false); var decalMat = new Material(_decalMaterial); @@ -215,7 +215,7 @@ namespace NewHorizons.Builder.Props public static void MakePlatform(GameObject go, Sector sector, NomaiRemoteCameraPlatform.ID id, Texture2D decal, PlatformInfo info, IModBehaviour mod) { - var platform = DetailBuilder.Make(go, sector, _remoteCameraPlatformPrefab, new DetailInfo(info)); + var platform = DetailBuilder.Make(go, sector, mod, _remoteCameraPlatformPrefab, new DetailInfo(info)); platform.SetActive(false); var decalMat = new Material(_decalMaterial); diff --git a/NewHorizons/Builder/Props/ScatterBuilder.cs b/NewHorizons/Builder/Props/ScatterBuilder.cs index 1ec4e2d3..e725bf8a 100644 --- a/NewHorizons/Builder/Props/ScatterBuilder.cs +++ b/NewHorizons/Builder/Props/ScatterBuilder.cs @@ -77,7 +77,7 @@ namespace NewHorizons.Builder.Props stretch = propInfo.stretch, keepLoaded = propInfo.keepLoaded }; - var scatterPrefab = DetailBuilder.Make(go, sector, prefab, detailInfo); + var scatterPrefab = DetailBuilder.Make(go, sector, mod, prefab, detailInfo); for (int i = 0; i < propInfo.count; i++) { diff --git a/NewHorizons/Builder/Props/ShuttleBuilder.cs b/NewHorizons/Builder/Props/ShuttleBuilder.cs index f855990d..e4c58b94 100644 --- a/NewHorizons/Builder/Props/ShuttleBuilder.cs +++ b/NewHorizons/Builder/Props/ShuttleBuilder.cs @@ -3,6 +3,7 @@ using NewHorizons.External.Modules.Props; using NewHorizons.External.Modules.Props.Shuttle; using NewHorizons.Handlers; using NewHorizons.Utility; +using OWML.Common; using System.Collections.Generic; using UnityEngine; @@ -69,14 +70,14 @@ namespace NewHorizons.Builder.Props } } - public static GameObject Make(GameObject planetGO, Sector sector, ShuttleInfo info) + public static GameObject Make(GameObject planetGO, Sector sector, IModBehaviour mod, ShuttleInfo info) { InitPrefab(); if (_prefab == null || planetGO == null || sector == null) return null; var detailInfo = new DetailInfo(info) { keepLoaded = true }; - var shuttleObject = DetailBuilder.Make(planetGO, sector, _prefab, detailInfo); + var shuttleObject = DetailBuilder.Make(planetGO, sector, mod, _prefab, detailInfo); shuttleObject.SetActive(false); StreamingHandler.SetUpStreaming(shuttleObject, sector); diff --git a/NewHorizons/Builder/Props/TranslatorText/TranslatorTextBuilder.cs b/NewHorizons/Builder/Props/TranslatorText/TranslatorTextBuilder.cs index 6ff148ef..9ad3ba5c 100644 --- a/NewHorizons/Builder/Props/TranslatorText/TranslatorTextBuilder.cs +++ b/NewHorizons/Builder/Props/TranslatorText/TranslatorTextBuilder.cs @@ -242,7 +242,7 @@ namespace NewHorizons.Builder.Props.TranslatorText } case NomaiTextType.PreCrashComputer: { - var computerObject = DetailBuilder.Make(planetGO, sector, PreCrashComputerPrefab, new DetailInfo(info)); + var computerObject = DetailBuilder.Make(planetGO, sector, nhBody.Mod, PreCrashComputerPrefab, new DetailInfo(info)); computerObject.SetActive(false); var computer = computerObject.GetComponent(); @@ -323,7 +323,7 @@ namespace NewHorizons.Builder.Props.TranslatorText case NomaiTextType.Recorder: { var prefab = (info.type == NomaiTextType.PreCrashRecorder ? _preCrashRecorderPrefab : _recorderPrefab); - var recorderObject = DetailBuilder.Make(planetGO, sector, prefab, new DetailInfo(info)); + var recorderObject = DetailBuilder.Make(planetGO, sector, nhBody.Mod, prefab, new DetailInfo(info)); recorderObject.SetActive(false); var nomaiText = recorderObject.GetComponentInChildren(); @@ -373,7 +373,7 @@ namespace NewHorizons.Builder.Props.TranslatorText path = "BrittleHollow_Body/Sector_BH/Sector_NorthHemisphere/Sector_NorthPole/Sector_HangingCity/Sector_HangingCity_District2/Interactables_HangingCity_District2/VisibleFrom_HangingCity/Props_NOM_Whiteboard (1)", rename = info.rename ?? "Props_NOM_Whiteboard", }; - var whiteboardObject = DetailBuilder.Make(planetGO, sector, whiteboardInfo); + var whiteboardObject = DetailBuilder.Make(planetGO, sector, nhBody.Mod, whiteboardInfo); // Spawn a scroll and insert it into the whiteboard, but only if text is provided if (!string.IsNullOrEmpty(info.xmlFile)) diff --git a/NewHorizons/Builder/Props/WarpPadBuilder.cs b/NewHorizons/Builder/Props/WarpPadBuilder.cs index 4c5a9ae8..4342a374 100644 --- a/NewHorizons/Builder/Props/WarpPadBuilder.cs +++ b/NewHorizons/Builder/Props/WarpPadBuilder.cs @@ -6,6 +6,7 @@ using NewHorizons.External.Modules.WarpPad; using NewHorizons.Utility; using NewHorizons.Utility.OuterWilds; using NewHorizons.Utility.OWML; +using OWML.Common; using OWML.Utils; using UnityEngine; @@ -86,10 +87,10 @@ namespace NewHorizons.Builder.Props } } - public static void Make(GameObject planetGO, Sector sector, NomaiWarpReceiverInfo info) + public static void Make(GameObject planetGO, Sector sector, IModBehaviour mod, NomaiWarpReceiverInfo info) { var detailInfo = new DetailInfo(info); - var receiverObject = DetailBuilder.Make(planetGO, sector, info.detailed ? _detailedReceiverPrefab : _receiverPrefab, detailInfo); + var receiverObject = DetailBuilder.Make(planetGO, sector, mod, info.detailed ? _detailedReceiverPrefab : _receiverPrefab, detailInfo); NHLogger.Log($"Position is {detailInfo.position} was {info.position}"); @@ -122,13 +123,13 @@ namespace NewHorizons.Builder.Props if (info.computer != null) { - CreateComputer(planetGO, sector, info.computer, receiver); + CreateComputer(planetGO, sector, mod, info.computer, receiver); } } - public static void Make(GameObject planetGO, Sector sector, NomaiWarpTransmitterInfo info) + public static void Make(GameObject planetGO, Sector sector, IModBehaviour mod, NomaiWarpTransmitterInfo info) { - var transmitterObject = DetailBuilder.Make(planetGO, sector, _transmitterPrefab, new DetailInfo(info)); + var transmitterObject = DetailBuilder.Make(planetGO, sector, mod, _transmitterPrefab, new DetailInfo(info)); var transmitter = transmitterObject.GetComponentInChildren(); transmitter._frequency = GetFrequency(info.frequency); @@ -145,9 +146,9 @@ namespace NewHorizons.Builder.Props transmitterObject.SetActive(true); } - private static void CreateComputer(GameObject planetGO, Sector sector, GeneralPropInfo computerInfo, NomaiWarpReceiver receiver) + private static void CreateComputer(GameObject planetGO, Sector sector, IModBehaviour mod, GeneralPropInfo computerInfo, NomaiWarpReceiver receiver) { - var computerObject = DetailBuilder.Make(planetGO, sector, TranslatorTextBuilder.ComputerPrefab, new DetailInfo(computerInfo)); + var computerObject = DetailBuilder.Make(planetGO, sector, mod, TranslatorTextBuilder.ComputerPrefab, new DetailInfo(computerInfo)); var computer = computerObject.GetComponentInChildren(); computer.SetSector(sector); diff --git a/NewHorizons/Handlers/PlanetCreationHandler.cs b/NewHorizons/Handlers/PlanetCreationHandler.cs index 9b73c8ba..26e8eef6 100644 --- a/NewHorizons/Handlers/PlanetCreationHandler.cs +++ b/NewHorizons/Handlers/PlanetCreationHandler.cs @@ -377,7 +377,7 @@ namespace NewHorizons.Handlers ao._rootSector = sector; ao._type = AstroObject.Type.None; - BrambleDimensionBuilder.Make(body, go, ao, sector, owRigidBody); + BrambleDimensionBuilder.Make(body, go, ao, sector, body.Mod, owRigidBody); go = SharedGenerateBody(body, go, sector, owRigidBody); diff --git a/NewHorizons/INewHorizons.cs b/NewHorizons/INewHorizons.cs index 096960d3..22132568 100644 --- a/NewHorizons/INewHorizons.cs +++ b/NewHorizons/INewHorizons.cs @@ -16,6 +16,9 @@ namespace NewHorizons [Obsolete("Create(Dictionary config) is deprecated, please use LoadConfigs(IModBehaviour mod) instead")] void Create(Dictionary config, IModBehaviour mod); + + [Obsolete("SpawnObject(GameObject planet, Sector sector, string propToCopyPath, Vector3 position, Vector3 eulerAngles, float scale, bool alignRadial) is deprecated, please use SpawnObject(IModBehaviour mod, GameObject planet, Sector sector, string propToCopyPath, Vector3 position, Vector3 eulerAngles, float scale, bool alignRadial) instead")] + GameObject SpawnObject(GameObject planet, Sector sector, string propToCopyPath, Vector3 position, Vector3 eulerAngles, float scale, bool alignWithNormal); #endregion /// @@ -105,7 +108,7 @@ namespace NewHorizons /// 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, + GameObject SpawnObject(IModBehaviour mod, GameObject planet, Sector sector, string propToCopyPath, Vector3 position, Vector3 eulerAngles, float scale, bool alignWithNormal); /// diff --git a/NewHorizons/NewHorizonsApi.cs b/NewHorizons/NewHorizonsApi.cs index f269cce9..e5507abc 100644 --- a/NewHorizons/NewHorizonsApi.cs +++ b/NewHorizons/NewHorizonsApi.cs @@ -70,6 +70,13 @@ namespace NewHorizons } } + [Obsolete("SpawnObject(GameObject planet, Sector sector, string propToCopyPath, Vector3 position, Vector3 eulerAngles, float scale, bool alignRadial) is deprecated, please use SpawnObject(IModBehaviour mod, GameObject planet, Sector sector, string propToCopyPath, Vector3 position, Vector3 eulerAngles, float scale, bool alignRadial) instead")] + public GameObject SpawnObject(GameObject planet, Sector sector, string propToCopyPath, Vector3 position, Vector3 eulerAngles, + float scale, bool alignRadial) + { + return SpawnObject(null, planet, sector, propToCopyPath, position, eulerAngles, scale, alignRadial); + } + public void LoadConfigs(IModBehaviour mod) { Main.Instance.LoadConfigs(mod); @@ -170,7 +177,7 @@ namespace NewHorizons return default; } - public GameObject SpawnObject(GameObject planet, Sector sector, string propToCopyPath, Vector3 position, Vector3 eulerAngles, + public GameObject SpawnObject(IModBehaviour mod, GameObject planet, Sector sector, string propToCopyPath, Vector3 position, Vector3 eulerAngles, float scale, bool alignRadial) { var prefab = SearchUtilities.Find(propToCopyPath); @@ -181,7 +188,7 @@ namespace NewHorizons scale = scale, alignRadial = alignRadial }; - return DetailBuilder.Make(planet, sector, prefab, detailInfo); + return DetailBuilder.Make(planet, sector, mod, prefab, detailInfo); } public AudioSignal SpawnSignal(IModBehaviour mod, GameObject root, string audio, string name, string frequency, diff --git a/NewHorizons/Utility/DebugTools/DebugPropPlacer.cs b/NewHorizons/Utility/DebugTools/DebugPropPlacer.cs index 1db7bd36..4a107eaf 100644 --- a/NewHorizons/Utility/DebugTools/DebugPropPlacer.cs +++ b/NewHorizons/Utility/DebugTools/DebugPropPlacer.cs @@ -157,7 +157,7 @@ namespace NewHorizons.Utility.DebugTools position = data.pos, rotation = data.rot.eulerAngles, }; - var prop = DetailBuilder.Make(planetGO, sector, prefab, detailInfo); + var prop = DetailBuilder.Make(planetGO, sector, null, prefab, detailInfo); var body = data.hitBodyGameObject.GetComponent(); if (body != null) RegisterProp(body, prop); From 9c87237174b092e522596f43c1099aef54bf9e05 Mon Sep 17 00:00:00 2001 From: Joshua Thome Date: Tue, 31 Oct 2023 01:31:23 -0500 Subject: [PATCH 07/10] Item audio and minor fixes --- NewHorizons/Builder/Props/ItemBuilder.cs | 42 ++++++++++++++++--- NewHorizons/Components/Props/NHItem.cs | 34 +++++++++++++++ .../External/Modules/Props/Item/ItemInfo.cs | 20 +++++++++ 3 files changed, 90 insertions(+), 6 deletions(-) diff --git a/NewHorizons/Builder/Props/ItemBuilder.cs b/NewHorizons/Builder/Props/ItemBuilder.cs index 04b6180b..1557351f 100644 --- a/NewHorizons/Builder/Props/ItemBuilder.cs +++ b/NewHorizons/Builder/Props/ItemBuilder.cs @@ -1,6 +1,8 @@ using NewHorizons.Components.Props; using NewHorizons.External.Modules.Props.Item; +using NewHorizons.Handlers; using NewHorizons.Utility.OWML; +using OWML.Common; using OWML.Utils; using System; using System.Collections.Generic; @@ -27,7 +29,7 @@ namespace NewHorizons.Builder.Props _itemTypes = new Dictionary(); } - public static NHItem MakeItem(GameObject go, GameObject planetGO, Sector sector, ItemInfo info) + public static NHItem MakeItem(GameObject go, GameObject planetGO, Sector sector, ItemInfo info, IModBehaviour mod) { var itemName = info.name; if (string.IsNullOrEmpty(itemName)) @@ -53,6 +55,30 @@ namespace NewHorizons.Builder.Props item.DisplayName = itemName; item.ItemType = itemType; item.Droppable = info.droppable; + if (!string.IsNullOrEmpty(info.pickupAudio)) + { + item.PickupAudio = AudioTypeHandler.GetAudioType(info.pickupAudio, mod); + } + if (!string.IsNullOrEmpty(info.dropAudio)) + { + item.DropAudio = AudioTypeHandler.GetAudioType(info.dropAudio, mod); + } + if (!string.IsNullOrEmpty(info.socketAudio)) + { + item.SocketAudio = AudioTypeHandler.GetAudioType(info.socketAudio, mod); + } + else + { + item.SocketAudio = item.DropAudio; + } + if (!string.IsNullOrEmpty(info.unsocketAudio)) + { + item.UnsocketAudio = AudioTypeHandler.GetAudioType(info.unsocketAudio, mod); + } + else + { + item.UnsocketAudio = item.PickupAudio; + } item.PickupCondition = info.pickupCondition; item.ClearPickupConditionOnDrop = info.clearPickupConditionOnDrop; @@ -92,16 +118,13 @@ namespace NewHorizons.Builder.Props public static NHItemSocket MakeSocket(GameObject go, GameObject planetGO, Sector sector, ItemSocketInfo info) { - - var socketGO = GeneralPropBuilder.MakeNew("Socket", planetGO, sector, info, defaultParent: go.transform); - var itemType = EnumUtils.TryParse(info.itemType, true, out ItemType result) ? result : ItemType.Invalid; if (itemType == ItemType.Invalid && !string.IsNullOrEmpty(info.itemType)) { itemType = EnumUtilities.Create(info.itemType); } - var socket = socketGO.GetAddComponent(); + var socket = go.GetAddComponent(); socket._sector = sector; socket._interactable = info.interactRange > 0f; socket._interactRange = info.interactRange; @@ -112,7 +135,9 @@ namespace NewHorizons.Builder.Props } if (socket._socketTransform == null) { - socket._socketTransform = socket.transform; + var socketGO = GeneralPropBuilder.MakeNew("Socket", planetGO, sector, info, defaultParent: go.transform); + socketGO.SetActive(true); + socket._socketTransform = socketGO.transform; } socket.ItemType = itemType; @@ -151,5 +176,10 @@ namespace NewHorizons.Builder.Props } return itemType; } + + public static bool IsCustomItemType(ItemType type) + { + return _itemTypes.ContainsValue(type); + } } } diff --git a/NewHorizons/Components/Props/NHItem.cs b/NewHorizons/Components/Props/NHItem.cs index 24134749..5090c330 100644 --- a/NewHorizons/Components/Props/NHItem.cs +++ b/NewHorizons/Components/Props/NHItem.cs @@ -1,3 +1,4 @@ +using NewHorizons.Builder.Props; using NewHorizons.Handlers; using OWML.Utils; using System; @@ -14,6 +15,10 @@ namespace NewHorizons.Components.Props { public string DisplayName; public bool Droppable; + public AudioType PickupAudio; + public AudioType DropAudio; + public AudioType SocketAudio; + public AudioType UnsocketAudio; public string PickupCondition; public bool ClearPickupConditionOnDrop; @@ -37,12 +42,28 @@ namespace NewHorizons.Components.Props { base.PickUpItem(holdTranform); TriggerPickupConditions(); + PlayCustomSound(PickupAudio); } public override void DropItem(Vector3 position, Vector3 normal, Transform parent, Sector sector, IItemDropTarget customDropTarget) { base.DropItem(position, normal, parent, sector, customDropTarget); TriggerDropConditions(); + PlayCustomSound(DropAudio); + } + + public override void SocketItem(Transform socketTransform, Sector sector) + { + base.SocketItem(socketTransform, sector); + TriggerDropConditions(); + PlayCustomSound(SocketAudio); + } + + public override void OnCompleteUnsocket() + { + base.OnCompleteUnsocket(); + TriggerPickupConditions(); + PlayCustomSound(UnsocketAudio); } internal void TriggerPickupConditions() @@ -60,5 +81,18 @@ namespace NewHorizons.Components.Props DialogueConditionManager.SharedInstance.SetConditionState(PickupCondition, false); } } + + void PlayCustomSound(AudioType audioType) + { + if (ItemBuilder.IsCustomItemType(ItemType)) + { + Locator.GetPlayerAudioController()._oneShotExternalSource.PlayOneShot(audioType); + } + else + { + // Vanilla items play sounds via hard-coded ItemType switch statements + // in the PlayerAudioController code, so there's no clean way to override them + } + } } } diff --git a/NewHorizons/External/Modules/Props/Item/ItemInfo.cs b/NewHorizons/External/Modules/Props/Item/ItemInfo.cs index 5728e2a5..5386a9a7 100644 --- a/NewHorizons/External/Modules/Props/Item/ItemInfo.cs +++ b/NewHorizons/External/Modules/Props/Item/ItemInfo.cs @@ -39,6 +39,26 @@ namespace NewHorizons.External.Modules.Props.Item /// public MVector3 dropNormal; /// + /// The audio to play when this item is picked up. Only applies to custom/non-vanilla item types. + /// Can be a path to a .wav/.ogg/.mp3 file, or taken from the AudioClip list. + /// + public string pickupAudio; + /// + /// The audio to play when this item is dropped. Only applies to custom/non-vanilla item types. + /// Can be a path to a .wav/.ogg/.mp3 file, or taken from the AudioClip list. + /// + public string dropAudio; + /// + /// The audio to play when this item is inserted into a socket. Only applies to custom/non-vanilla item types. + /// Can be a path to a .wav/.ogg/.mp3 file, or taken from the AudioClip list. + /// + public string socketAudio; + /// + /// The audio to play when this item is removed from a socket. Only applies to custom/non-vanilla item types. + /// Can be a path to a .wav/.ogg/.mp3 file, or taken from the AudioClip list. + /// + public string unsocketAudio; + /// /// A dialogue condition to set when picking up this item. /// public string pickupCondition; From 698317e747555d7b5eefe2d0f6f5ea74fb46ad2b Mon Sep 17 00:00:00 2001 From: Ben C Date: Tue, 31 Oct 2023 06:33:56 +0000 Subject: [PATCH 08/10] Updated Schemas --- NewHorizons/Schemas/body_schema.json | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/NewHorizons/Schemas/body_schema.json b/NewHorizons/Schemas/body_schema.json index 222fe780..7feb1a6d 100644 --- a/NewHorizons/Schemas/body_schema.json +++ b/NewHorizons/Schemas/body_schema.json @@ -1423,6 +1423,22 @@ "description": "The direction the item will be oriented when dropping it on the ground. Defaults to up (0, 1, 0).", "$ref": "#/definitions/MVector3" }, + "pickupAudio": { + "type": "string", + "description": "The audio to play when this item is picked up. Only applies to custom/non-vanilla item types.\nCan be a path to a .wav/.ogg/.mp3 file, or taken from the AudioClip list." + }, + "dropAudio": { + "type": "string", + "description": "The audio to play when this item is dropped. Only applies to custom/non-vanilla item types.\nCan be a path to a .wav/.ogg/.mp3 file, or taken from the AudioClip list." + }, + "socketAudio": { + "type": "string", + "description": "The audio to play when this item is inserted into a socket. Only applies to custom/non-vanilla item types.\nCan be a path to a .wav/.ogg/.mp3 file, or taken from the AudioClip list." + }, + "unsocketAudio": { + "type": "string", + "description": "The audio to play when this item is removed from a socket. Only applies to custom/non-vanilla item types.\nCan be a path to a .wav/.ogg/.mp3 file, or taken from the AudioClip list." + }, "pickupCondition": { "type": "string", "description": "A dialogue condition to set when picking up this item." From 5d4e09a3f8b176621d932c31fbd13871ce332a20 Mon Sep 17 00:00:00 2001 From: Joshua Thome Date: Thu, 2 Nov 2023 22:30:10 -0500 Subject: [PATCH 09/10] Items and sockets can reveal ship log facts --- NewHorizons/Builder/Props/ItemBuilder.cs | 7 +++++-- NewHorizons/Components/Props/NHItem.cs | 5 +++++ NewHorizons/Components/Props/NHItemSocket.cs | 10 ++++++++++ NewHorizons/External/Modules/Props/Item/ItemInfo.cs | 4 ++++ .../External/Modules/Props/Item/ItemSocketInfo.cs | 8 ++++++++ 5 files changed, 32 insertions(+), 2 deletions(-) diff --git a/NewHorizons/Builder/Props/ItemBuilder.cs b/NewHorizons/Builder/Props/ItemBuilder.cs index 1557351f..ae3d420f 100644 --- a/NewHorizons/Builder/Props/ItemBuilder.cs +++ b/NewHorizons/Builder/Props/ItemBuilder.cs @@ -81,8 +81,9 @@ namespace NewHorizons.Builder.Props } item.PickupCondition = info.pickupCondition; item.ClearPickupConditionOnDrop = info.clearPickupConditionOnDrop; + item.PickupFact = info.pickupFact; - Delay.FireInNUpdates(() => + Delay.FireOnNextUpdate(() => { if (item != null && !string.IsNullOrEmpty(info.pathToInitialSocket)) { @@ -111,7 +112,7 @@ namespace NewHorizons.Builder.Props NHLogger.LogError($"Could not find a socket to parent item {itemName} to at path {socketGO}"); } } - }, 1); + }); return item; } @@ -144,8 +145,10 @@ namespace NewHorizons.Builder.Props socket.UseGiveTakePrompts = info.useGiveTakePrompts; socket.InsertCondition = info.insertCondition; socket.ClearInsertConditionOnRemoval = info.clearInsertConditionOnRemoval; + socket.InsertFact = info.insertFact; socket.RemovalCondition = info.removalCondition; socket.ClearRemovalConditionOnInsert = info.clearRemovalConditionOnInsert; + socket.RemovalFact = info.removalFact; Delay.FireInNUpdates(() => { diff --git a/NewHorizons/Components/Props/NHItem.cs b/NewHorizons/Components/Props/NHItem.cs index 5090c330..b21db7ea 100644 --- a/NewHorizons/Components/Props/NHItem.cs +++ b/NewHorizons/Components/Props/NHItem.cs @@ -21,6 +21,7 @@ namespace NewHorizons.Components.Props public AudioType UnsocketAudio; public string PickupCondition; public bool ClearPickupConditionOnDrop; + public string PickupFact; public ItemType ItemType { @@ -72,6 +73,10 @@ namespace NewHorizons.Components.Props { DialogueConditionManager.SharedInstance.SetConditionState(PickupCondition, true); } + if (!string.IsNullOrEmpty(PickupFact)) + { + Locator.GetShipLogManager().RevealFact(PickupFact); + } } internal void TriggerDropConditions() diff --git a/NewHorizons/Components/Props/NHItemSocket.cs b/NewHorizons/Components/Props/NHItemSocket.cs index 29acb1bb..bd40a96d 100644 --- a/NewHorizons/Components/Props/NHItemSocket.cs +++ b/NewHorizons/Components/Props/NHItemSocket.cs @@ -12,8 +12,10 @@ namespace NewHorizons.Components.Props public bool UseGiveTakePrompts; public string InsertCondition; public bool ClearInsertConditionOnRemoval; + public string InsertFact; public string RemovalCondition; public bool ClearRemovalConditionOnInsert; + public string RemovalFact; public ItemType ItemType { @@ -65,6 +67,10 @@ namespace NewHorizons.Components.Props { DialogueConditionManager.SharedInstance.SetConditionState(RemovalCondition, false); } + if (!string.IsNullOrEmpty(InsertFact)) + { + Locator.GetShipLogManager().RevealFact(InsertFact); + } } internal void TriggerRemovalConditions() @@ -77,6 +83,10 @@ namespace NewHorizons.Components.Props { DialogueConditionManager.SharedInstance.SetConditionState(InsertCondition, false); } + if (!string.IsNullOrEmpty(RemovalFact)) + { + Locator.GetShipLogManager().RevealFact(RemovalFact); + } } } } diff --git a/NewHorizons/External/Modules/Props/Item/ItemInfo.cs b/NewHorizons/External/Modules/Props/Item/ItemInfo.cs index 5386a9a7..6876bd4c 100644 --- a/NewHorizons/External/Modules/Props/Item/ItemInfo.cs +++ b/NewHorizons/External/Modules/Props/Item/ItemInfo.cs @@ -67,6 +67,10 @@ namespace NewHorizons.External.Modules.Props.Item /// [DefaultValue(true)] public bool clearPickupConditionOnDrop = true; /// + /// A ship log fact to reveal when picking up this item. + /// + public string pickupFact; + /// /// A relative path from the planet to a socket that this item will be automatically inserted into. /// public string pathToInitialSocket; diff --git a/NewHorizons/External/Modules/Props/Item/ItemSocketInfo.cs b/NewHorizons/External/Modules/Props/Item/ItemSocketInfo.cs index c7a2b3b2..76ac16f7 100644 --- a/NewHorizons/External/Modules/Props/Item/ItemSocketInfo.cs +++ b/NewHorizons/External/Modules/Props/Item/ItemSocketInfo.cs @@ -39,6 +39,10 @@ namespace NewHorizons.External.Modules.Props.Item /// [DefaultValue(true)] public bool clearInsertConditionOnRemoval = true; /// + /// A ship log fact to reveal when inserting an item into this socket. + /// + public string insertFact; + /// /// A dialogue condition to set when removing an item from this socket, or when the socket is empty. /// public string removalCondition; @@ -46,5 +50,9 @@ namespace NewHorizons.External.Modules.Props.Item /// Whether the removal condition should be cleared when inserting a socketed item. Defaults to true. /// [DefaultValue(true)] public bool clearRemovalConditionOnInsert = true; + /// + /// A ship log fact to reveal when removing an item from this socket, or when the socket is empty. + /// + public string removalFact; } } From 2549d9392a97c8383dc57aebe134ebadadf78193 Mon Sep 17 00:00:00 2001 From: Ben C Date: Fri, 3 Nov 2023 03:31:49 +0000 Subject: [PATCH 10/10] Updated Schemas --- NewHorizons/Schemas/body_schema.json | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/NewHorizons/Schemas/body_schema.json b/NewHorizons/Schemas/body_schema.json index 7feb1a6d..c7cd13e6 100644 --- a/NewHorizons/Schemas/body_schema.json +++ b/NewHorizons/Schemas/body_schema.json @@ -1448,6 +1448,10 @@ "description": "Whether the pickup condition should be cleared when dropping the item. Defaults to true.", "default": true }, + "pickupFact": { + "type": "string", + "description": "A ship log fact to reveal when picking up this item." + }, "pathToInitialSocket": { "type": "string", "description": "A relative path from the planet to a socket that this item will be automatically inserted into." @@ -1512,6 +1516,10 @@ "description": "Whether the insert condition should be cleared when removing the socketed item. Defaults to true.", "default": true }, + "insertFact": { + "type": "string", + "description": "A ship log fact to reveal when inserting an item into this socket." + }, "removalCondition": { "type": "string", "description": "A dialogue condition to set when removing an item from this socket, or when the socket is empty." @@ -1520,6 +1528,10 @@ "type": "boolean", "description": "Whether the removal condition should be cleared when inserting a socketed item. Defaults to true.", "default": true + }, + "removalFact": { + "type": "string", + "description": "A ship log fact to reveal when removing an item from this socket, or when the socket is empty." } } },