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();