diff --git a/NewHorizons/Builder/ShipLog/MapModeBuilder.cs b/NewHorizons/Builder/ShipLog/MapModeBuilder.cs index cfe6051d..c25c891c 100644 --- a/NewHorizons/Builder/ShipLog/MapModeBuilder.cs +++ b/NewHorizons/Builder/ShipLog/MapModeBuilder.cs @@ -15,28 +15,44 @@ namespace NewHorizons.Builder.ShipLog { public static class MapModeBuilder { - private class MapModeObject + #region General + public static ShipLogAstroObject[][] ConstructMapMode(string systemName, GameObject transformParent, ShipLogAstroObject[][] currentNav, int layer) { - public int x; - public int y; - public int branch_width; - public int branch_height; - public int level; - public NewHorizonsBody mainBody; - public ShipLogAstroObject astroObject; - public List children; - public MapModeObject parent; - public MapModeObject lastSibling; - public void Increment_width() + Material greyScaleMaterial = GameObject.Find(ShipLogHandler.PAN_ROOT_PATH + "/TimberHearth/Sprite").GetComponent().material; + List bodies = Main.BodyDict[systemName].Where(b => (b.Config.ShipLog?.mapMode?.remove ?? false) == false).ToList(); + bool flagManualPositionUsed = systemName == "SolarSystem"; + bool flagAutoPositionUsed = false; + foreach (NewHorizonsBody body in bodies.Where(b => ShipLogHandler.IsVanillaBody(b) == false)) { - branch_width++; - parent?.Increment_width(); + if (body.Config.ShipLog?.mapMode?.manualPosition == null) + { + flagAutoPositionUsed = true; + } + else + { + flagManualPositionUsed = true; + if (body.Config.ShipLog?.mapMode?.manualNavigationPosition == null) + { + Logger.LogError("Navigation position is missing for: " + body.Config.Name); + return null; + } + } } - public void Increment_height() + + if (flagAutoPositionUsed && flagManualPositionUsed) { - branch_height++; - parent?.Increment_height(); + Logger.LogError("Can't mix manual and automatic layout of ship log map mode, skipping generation"); + return null; } + else if (flagAutoPositionUsed) + { + return ConstructMapModeAuto(bodies, transformParent, greyScaleMaterial, layer); + } + else if (flagManualPositionUsed) + { + return ConstructMapModeManual(bodies, transformParent, greyScaleMaterial, currentNav, layer); + } + return null; } public static string GetAstroBodyShipLogName(string id) @@ -44,53 +60,6 @@ namespace NewHorizons.Builder.ShipLog return ShipLogHandler.GetConfigFromID(id)?.Config?.Name ?? id; } - public static ShipLogAstroObject[][] ConstructMapMode(string systemName, GameObject transformParent, int layer) - { - MapModeObject rootObject = ConstructPrimaryNode(systemName); - if (rootObject.mainBody != null) - { - MakeAllNodes(ref rootObject, transformParent, layer); - } - - int maxAmount = Main.BodyDict[Main.Instance.CurrentStarSystem].Count; - ShipLogAstroObject[][] navMatrix = new ShipLogAstroObject[maxAmount][]; - for (int i = 0; i < maxAmount; i++) - { - navMatrix[i] = new ShipLogAstroObject[maxAmount]; - } - - CreateNavigationMatrix(rootObject, ref navMatrix); - navMatrix = navMatrix.Where(a => a.Count(c => c != null) > 0).Prepend(new ShipLogAstroObject[1]).ToArray(); - for (var index = 0; index < navMatrix.Length; index++) - { - navMatrix[index] = navMatrix[index].Where(a => a != null).ToArray(); - } - return navMatrix; - } - - private static void CreateNavigationMatrix(MapModeObject root, ref ShipLogAstroObject[][] navMatrix) - { - if (root.astroObject != null) - { - navMatrix[root.y][root.x] = root.astroObject; - } - foreach (MapModeObject child in root.children) - { - CreateNavigationMatrix(child, ref navMatrix); - } - } - - private static void MakeAllNodes(ref MapModeObject parentNode, GameObject parent, int layer) - { - MakeNode(ref parentNode, parent, layer); - for (var i = 0; i < parentNode.children.Count; i++) - { - MapModeObject child = parentNode.children[i]; - MakeAllNodes(ref child, parent, layer); - parentNode.children[i] = child; - } - } - private static GameObject CreateImage(GameObject nodeGO, IModAssets assets, string imagePath, string name, int layer) { GameObject newImageGO = new GameObject(name); @@ -117,33 +86,314 @@ namespace NewHorizons.Builder.ShipLog return newImageGO; } - private static void CreateShipLogAstroObject(GameObject nodeGO, ref MapModeObject node, GameObject referenceUnviewedSprite, int layer) + private static GameObject CreateMapModeGameObject(NewHorizonsBody body, GameObject parent, int layer, Vector2 position) + { + GameObject newGameObject = new GameObject(body.Config.Name + "_ShipLog"); + newGameObject.layer = layer; + newGameObject.transform.SetParent(parent.transform); + + RectTransform transform = newGameObject.AddComponent(); + float scale = body.Config.ShipLog?.mapMode?.scale ?? 1f; + transform.localPosition = position; + transform.localRotation = Quaternion.identity; + transform.localScale = Vector3.one * scale; + transform.SetAsFirstSibling(); + return newGameObject; + } + + private static ShipLogAstroObject AddShipLogAstroObject(GameObject gameObject, NewHorizonsBody body, Material greyScaleMaterial, int layer) { const float unviewedIconOffset = 15; - ShipLogAstroObject astroObject = nodeGO.AddComponent(); - astroObject._id = ShipLogHandler.GetAstroObjectId(node.mainBody); + + GameObject unviewedReference = GameObject.Find(ShipLogHandler.PAN_ROOT_PATH + "/TimberHearth/UnviewedIcon"); + + ShipLogAstroObject astroObject = gameObject.AddComponent(); + astroObject._id = ShipLogHandler.GetAstroObjectId(body); - string imagePath = node.mainBody.Config.ShipLog?.mapMode?.revealedSprite ?? "DEFAULT"; - string outlinePath = node.mainBody.Config.ShipLog?.mapMode?.outlineSprite ?? imagePath; - astroObject._imageObj = CreateImage(nodeGO, node.mainBody.Mod.Assets, imagePath, node.mainBody.Config.Name + " Revealed", layer); - astroObject._outlineObj = CreateImage(nodeGO, node.mainBody.Mod.Assets, outlinePath, node.mainBody.Config.Name + " Outline", layer); - - astroObject._unviewedObj = Object.Instantiate(referenceUnviewedSprite, nodeGO.transform, false); - if (node.mainBody.Config.FocalPoint != null) + string imagePath = body.Config.ShipLog?.mapMode?.revealedSprite ?? "DEFAULT"; + string outlinePath = body.Config.ShipLog?.mapMode?.outlineSprite ?? imagePath; + astroObject._imageObj = CreateImage(gameObject, body.Mod.Assets, imagePath, body.Config.Name + " Revealed", layer); + if (ShipLogHandler.BodyHasEntries(body)) { - astroObject._imageObj.GetComponent().enabled = false; - astroObject._outlineObj.GetComponent().enabled = false; - astroObject._unviewedObj.GetComponent().enabled = false; - astroObject.transform.localScale = node.lastSibling.astroObject.transform.localScale; + Image revealedImage = astroObject._imageObj.GetComponent(); + astroObject._greyscaleMaterial = greyScaleMaterial; + revealedImage.material = greyScaleMaterial; + revealedImage.color = Color.white; + astroObject._image = revealedImage; } - astroObject._invisibleWhenHidden = node.mainBody.Config.ShipLog?.mapMode?.invisibleWhenHidden ?? false; + astroObject._outlineObj = CreateImage(gameObject, body.Mod.Assets, outlinePath, body.Config.Name + " Outline", layer); + + astroObject._unviewedObj = Object.Instantiate(unviewedReference, gameObject.transform, false); + astroObject._invisibleWhenHidden = body.Config.ShipLog?.mapMode?.invisibleWhenHidden ?? false; Rect imageRect = astroObject._imageObj.GetComponent().rect; astroObject._unviewedObj.transform.localPosition = new Vector3(imageRect.width / 2 + unviewedIconOffset, imageRect.height / 2 + unviewedIconOffset, 0); - node.astroObject = astroObject; + return astroObject; + } + #endregion + + # region Details + private static void MakeDetail(ShipLogModule.ShipLogDetailInfo info, Transform parent, IModAssets assets, Material greyScaleMaterial) + { + GameObject detailGameObject = new GameObject("Detail"); + detailGameObject.transform.SetParent(parent); + detailGameObject.SetActive(false); + + RectTransform detailTransform = detailGameObject.AddComponent(); + detailTransform.localPosition = (Vector2)(info.position ?? new MVector2(0, 0)); + detailTransform.localRotation = Quaternion.Euler(0f, 0f, info.rotation); + detailTransform.localScale = (Vector2)(info.scale ?? new MVector2(0, 0)); + + string revealedPath = info.revealedSprite ?? "DEFAULT"; + string outlinePath = info.outlineSprite ?? revealedPath; + + Image revealedImage = CreateImage(detailGameObject, assets, revealedPath, "Detail Revealed", parent.gameObject.layer).GetComponent(); + Image outlineImage = CreateImage(detailGameObject, assets, outlinePath, "Detail Outline", parent.gameObject.layer).GetComponent(); + + ShipLogDetail detail = detailGameObject.AddComponent(); + detail.Init(info, revealedImage, outlineImage, greyScaleMaterial); + detailGameObject.SetActive(true); } - private static void ConnectNodeToLastSibling(MapModeObject node) + private static void MakeDetails(NewHorizonsBody body, Transform parent, Material greyScaleMaterial) + { + if (body.Config.ShipLog?.mapMode?.details?.Length > 0) + { + GameObject detailsParent = new GameObject("Details"); + detailsParent.transform.SetParent(parent); + detailsParent.SetActive(false); + + RectTransform detailsTransform = detailsParent.AddComponent(); + detailsTransform.localPosition = Vector3.zero; + detailsTransform.localRotation = Quaternion.identity; + detailsTransform.localScale = Vector3.one; + + foreach (ShipLogModule.ShipLogDetailInfo detailInfo in body.Config.ShipLog.mapMode.details) + { + MakeDetail(detailInfo, detailsTransform, body.Mod.Assets, greyScaleMaterial); + } + detailsParent.SetActive(true); + } + } + #endregion + + #region Manual Map Mode + private static ShipLogAstroObject[][] ConstructMapModeManual(List bodies, GameObject transformParent, Material greyScaleMaterial, ShipLogAstroObject[][] currentNav, int layer) + { + int maxAmount = bodies.Count + 20; + ShipLogAstroObject[][] navMatrix = new ShipLogAstroObject[maxAmount][]; + for (int i = 0; i < maxAmount; i++) + { + navMatrix[i] = new ShipLogAstroObject[maxAmount]; + } + + Dictionary astroIdToNavIndex = new Dictionary(); + + if (Main.Instance.CurrentStarSystem == "SolarSystem") + { + + for (int y = 0; y < currentNav.Length; y++) + { + for (int x = 0; x < currentNav[y].Length; x++) + { + navMatrix[y][x] = currentNav[y][x]; + astroIdToNavIndex.Add(currentNav[y][x].GetID(), new [] {y, x}); + } + } + } + + foreach (NewHorizonsBody body in bodies.Where(b => ShipLogHandler.IsVanillaBody(b) == false)) + { + GameObject newMapModeGO = CreateMapModeGameObject(body, transformParent, layer, body.Config.ShipLog?.mapMode?.manualPosition); + ShipLogAstroObject newAstroObject = AddShipLogAstroObject(newMapModeGO, body, greyScaleMaterial, layer); + MakeDetails(body, newMapModeGO.transform, greyScaleMaterial); + Vector2 navigationPosition = body.Config.ShipLog?.mapMode?.manualNavigationPosition; + navMatrix[(int) navigationPosition.y][(int) navigationPosition.x] = newAstroObject; + } + + if (Main.Instance.CurrentStarSystem == "SolarSystem") + { + foreach (NewHorizonsBody body in Main.BodyDict["SolarSystem"].Where(ShipLogHandler.IsVanillaBody)) + { + GameObject gameObject = GameObject.Find(ShipLogHandler.PAN_ROOT_PATH + "/" + body.Config.Name.Replace(" ", "")); + if (body.Config.Destroy || (body.Config.ShipLog?.mapMode?.remove ?? false)) + { + ShipLogAstroObject astroObject = gameObject.GetComponent(); + if (astroObject != null) + { + int[] navIndex = astroIdToNavIndex[astroObject.GetID()]; + navMatrix[navIndex[0]][navIndex[1]] = null; + if (astroObject.GetID() == "CAVE_TWIN" || astroObject.GetID() == "TOWER_TWIN") + { + Object.Destroy(GameObject.Find(ShipLogHandler.PAN_ROOT_PATH + "/" + "SandFunnel")); + } + } + Object.Destroy(gameObject); + } + else + { + if (body.Config.ShipLog?.mapMode?.manualPosition != null) + { + gameObject.transform.localPosition = (Vector2)body.Config.ShipLog.mapMode.manualPosition; + } + if (body.Config.ShipLog?.mapMode?.manualNavigationPosition != null) + { + Vector2 navigationPosition = body.Config.ShipLog?.mapMode?.manualNavigationPosition; + navMatrix[(int) navigationPosition.y][(int) navigationPosition.x] = gameObject.GetComponent(); + } + if (body.Config.ShipLog?.mapMode?.scale != null) + { + gameObject.transform.localScale = Vector3.one * body.Config.ShipLog.mapMode.scale; + } + } + } + } + + navMatrix = navMatrix.Where(a => a.Count(c => c != null && c.gameObject != null) > 0).Prepend(new ShipLogAstroObject[1]).ToArray(); + for (var index = 0; index < navMatrix.Length; index++) + { + navMatrix[index] = navMatrix[index].Where(a => a != null && a.gameObject != null).ToArray(); + } + + return navMatrix; + } + #endregion + + #region Automatic Map Mode + private class MapModeObject + { + public int x; + public int y; + public int branch_width; + public int branch_height; + public int level; + public NewHorizonsBody mainBody; + public ShipLogAstroObject astroObject; + public List children; + public MapModeObject parent; + public MapModeObject lastSibling; + public void Increment_width() + { + branch_width++; + parent?.Increment_width(); + } + public void Increment_height() + { + branch_height++; + parent?.Increment_height(); + } + } + + private static ShipLogAstroObject[][] ConstructMapModeAuto(List bodies, GameObject transformParent, Material greyScaleMaterial, int layer) + { + MapModeObject rootObject = ConstructPrimaryNode(bodies); + if (rootObject.mainBody != null) + { + MakeAllNodes(ref rootObject, transformParent, greyScaleMaterial, layer); + } + + int maxAmount = bodies.Count; + ShipLogAstroObject[][] navMatrix = new ShipLogAstroObject[maxAmount][]; + for (int i = 0; i < maxAmount; i++) + { + navMatrix[i] = new ShipLogAstroObject[maxAmount]; + } + + CreateNavigationMatrix(rootObject, ref navMatrix); + navMatrix = navMatrix.Where(a => a.Count(c => c != null) > 0).Prepend(new ShipLogAstroObject[1]).ToArray(); + for (var index = 0; index < navMatrix.Length; index++) + { + navMatrix[index] = navMatrix[index].Where(a => a != null).ToArray(); + } + return navMatrix; + } + + private static void CreateNavigationMatrix(MapModeObject root, ref ShipLogAstroObject[][] navMatrix) + { + if (root.astroObject != null) + { + navMatrix[root.y][root.x] = root.astroObject; + } + foreach (MapModeObject child in root.children) + { + CreateNavigationMatrix(child, ref navMatrix); + } + } + + private static void MakeAllNodes(ref MapModeObject parentNode, GameObject parent, Material greyScaleMaterial, int layer) + { + MakeNode(ref parentNode, parent, greyScaleMaterial, layer); + for (var i = 0; i < parentNode.children.Count; i++) + { + MapModeObject child = parentNode.children[i]; + MakeAllNodes(ref child, parent, greyScaleMaterial, layer); + parentNode.children[i] = child; + } + } + + private static MapModeObject ConstructPrimaryNode(List bodies) + { + foreach (NewHorizonsBody body in bodies.Where(b => b.Config.Base.CenterOfSolarSystem)) + { + bodies.Sort((b, o) => b.Config.Orbit.SemiMajorAxis.CompareTo(o.Config.Orbit.SemiMajorAxis)); + MapModeObject newNode = new MapModeObject + { + mainBody = body, + level = 0, + x = 0, + y = 0 + }; + newNode.children = ConstructChildrenNodes(newNode, bodies); + return newNode; + } + Logger.LogError("Couldn't find center of system!"); + return new MapModeObject(); + } + + private static List ConstructChildrenNodes(MapModeObject parent, List searchList) + { + List children = new List(); + int newX = parent.x; + int newY = parent.y; + int newLevel = parent.level + 1; + MapModeObject lastSibling = parent; + foreach (NewHorizonsBody body in searchList.Where(b => b.Config.Orbit.PrimaryBody == parent.mainBody.Config.Name)) + { + if (body.Config.Orbit.PrimaryBody == parent.mainBody.Config.Name) + { + bool even = newLevel % 2 == 0; + newX = even ? newX : newX + 1; + newY = even ? newY + 1 : newY; + MapModeObject newNode = new MapModeObject() + { + mainBody = body, + level = newLevel, + x = newX, + y = newY, + parent = parent, + lastSibling = lastSibling + }; + newNode.children = ConstructChildrenNodes(newNode, searchList); + if (even) + { + newY += newNode.branch_height; + parent.Increment_height(); + newY += 1; + } + else + { + newX += newNode.branch_width; + parent.Increment_width(); + newX += 1; + } + lastSibling = newNode; + children.Add(newNode); + } + } + return children; + } + + private static void ConnectNodeToLastSibling(MapModeObject node, Material greyScaleMaterial) { Vector2 fromPosition = node.astroObject.transform.localPosition; Vector2 toPosition = node.lastSibling.astroObject.transform.localPosition; @@ -167,66 +417,16 @@ namespace NewHorizons.Builder.ShipLog }; ShipLogDetail linkDetail = newLink.AddComponent(); - linkDetail.Init(linkDetailInfo, linkImage, linkImage); + linkDetail.Init(linkDetailInfo, linkImage, linkImage, greyScaleMaterial); transform.SetParent(node.astroObject.transform); transform.SetAsFirstSibling(); newLink.SetActive(true); } - private static void MakeDetail(ShipLogModule.ShipLogDetailInfo info, Transform parent, IModAssets assets) - { - GameObject detailGameObject = new GameObject("Detail"); - detailGameObject.transform.SetParent(parent); - detailGameObject.SetActive(false); - - RectTransform detailTransform = detailGameObject.AddComponent(); - detailTransform.localPosition = (Vector2)(info.position ?? new MVector2(0, 0)); - detailTransform.localRotation = Quaternion.Euler(0f, 0f, info.rotation); - detailTransform.localScale = (Vector2)(info.scale ?? new MVector2(0, 0)); - - string revealedPath = info.revealedSprite ?? "DEFAULT"; - string outlinePath = info.outlineSprite ?? revealedPath; - - Image revealedImage = CreateImage(detailGameObject, assets, revealedPath, "Detail Revealed", parent.gameObject.layer).GetComponent(); - Image outlineImage = CreateImage(detailGameObject, assets, outlinePath, "Detail Outline", parent.gameObject.layer).GetComponent(); - - ShipLogDetail detail = detailGameObject.AddComponent(); - detail.Init(info, revealedImage, outlineImage); - detailGameObject.SetActive(true); - } - - private static void MakeDetails(MapModeObject node) - { - if (node.mainBody.Config.ShipLog?.mapMode?.details?.Length > 0) - { - GameObject detailsParent = new GameObject("Details"); - detailsParent.transform.SetParent(node.astroObject.transform); - detailsParent.SetActive(false); - - RectTransform detailsTransform = detailsParent.AddComponent(); - detailsTransform.localPosition = Vector3.zero; - detailsTransform.localRotation = Quaternion.identity; - detailsTransform.localScale = Vector3.one; - - foreach (ShipLogModule.ShipLogDetailInfo detailInfo in node.mainBody.Config.ShipLog.mapMode.details) - { - MakeDetail(detailInfo, detailsTransform, node.mainBody.Mod.Assets); - } - detailsParent.SetActive(true); - } - } - - private static void MakeNode(ref MapModeObject node, GameObject parent, int layer) + private static void MakeNode(ref MapModeObject node, GameObject parent, Material greyScaleMaterial, int layer) { const float padding = 250f; - - GameObject newNodeGO = new GameObject(node.mainBody.Config.Name + "_ShipLog"); - newNodeGO.layer = layer; - newNodeGO.transform.SetParent(parent.transform); - - RectTransform transform = newNodeGO.AddComponent(); - float scale = node.mainBody.Config.ShipLog?.mapMode?.scale ?? 1f; Vector2 position = Vector2.zero; if (node.lastSibling != null) { @@ -243,77 +443,19 @@ namespace NewHorizons.Builder.ShipLog position.x += padding * (node.x - node.lastSibling.x) + extraDistance; } } - transform.localPosition = new Vector3(position.x, position.y, 0); - transform.localRotation = Quaternion.identity; - transform.localScale = Vector3.one * scale; - CreateShipLogAstroObject(newNodeGO, ref node, GameObject.Find("Ship_Body/Module_Cabin/Systems_Cabin/ShipLogPivot/ShipLog/ShipLogPivot/ShipLogCanvas/MapMode/ScaleRoot/PanRoot/TimberHearth/UnviewedIcon"), layer); - if (node.lastSibling != null) ConnectNodeToLastSibling(node); - MakeDetails(node); - transform.SetAsFirstSibling(); - } - - private static MapModeObject ConstructPrimaryNode(string systemName) - { - foreach (NewHorizonsBody body in Main.BodyDict[systemName].Where(b => b.Config.Base.CenterOfSolarSystem)) + GameObject newNodeGO = CreateMapModeGameObject(node.mainBody, parent, layer, position); + ShipLogAstroObject astroObject = AddShipLogAstroObject(newNodeGO, node.mainBody, greyScaleMaterial, layer); + if (node.mainBody.Config.FocalPoint != null) { - List searchList = Main.BodyDict[systemName].Where(b => (b.Config.ShipLog?.mapMode?.remove ?? false) == false).ToList(); - searchList.Sort((b, o) => b.Config.Orbit.SemiMajorAxis.CompareTo(o.Config.Orbit.SemiMajorAxis)); - MapModeObject newNode = new MapModeObject - { - mainBody = body, - level = 0, - x = 0, - y = 0 - }; - newNode.children = ConstructChildrenNodes(systemName, newNode, searchList); - return newNode; + astroObject._imageObj.GetComponent().enabled = false; + astroObject._outlineObj.GetComponent().enabled = false; + astroObject._unviewedObj.GetComponent().enabled = false; + astroObject.transform.localScale = node.lastSibling.astroObject.transform.localScale; } - Logger.LogError("Couldn't find center of system!"); - return new MapModeObject(); - } - - private static List ConstructChildrenNodes(string systemName, MapModeObject parent, List searchList) - { - List children = new List(); - int newX = parent.x; - int newY = parent.y; - int newLevel = parent.level + 1; - MapModeObject lastSibling = parent; - foreach (NewHorizonsBody body in searchList.Where(b => b.Config.Orbit.PrimaryBody == parent.mainBody.Config.Name)) - { - if (body.Config.Orbit.PrimaryBody == parent.mainBody.Config.Name) - { - bool even = newLevel % 2 == 0; - newX = even ? newX : newX + 1; - newY = even ? newY + 1 : newY; - MapModeObject newNode = new MapModeObject() - { - mainBody = body, - level = newLevel, - x = newX, - y = newY, - parent = parent, - lastSibling = lastSibling - }; - newNode.children = ConstructChildrenNodes(systemName, newNode, searchList); - if (even) - { - newY += newNode.branch_height; - parent.Increment_height(); - newY += 1; - } - else - { - newX += newNode.branch_width; - parent.Increment_width(); - newX += 1; - } - lastSibling = newNode; - children.Add(newNode); - } - } - return children; + node.astroObject = astroObject; + if (node.lastSibling != null) ConnectNodeToLastSibling(node, greyScaleMaterial); + MakeDetails(node.mainBody, newNodeGO.transform, greyScaleMaterial); } + #endregion } - } diff --git a/NewHorizons/Builder/ShipLog/RumorModeBuilder.cs b/NewHorizons/Builder/ShipLog/RumorModeBuilder.cs index 2495d090..948dfa33 100644 --- a/NewHorizons/Builder/ShipLog/RumorModeBuilder.cs +++ b/NewHorizons/Builder/ShipLog/RumorModeBuilder.cs @@ -1,4 +1,5 @@ -using NewHorizons.Components; +using System; +using NewHorizons.Components; using System.Collections.Generic; using System.IO; using System.Linq; @@ -66,6 +67,23 @@ namespace NewHorizons.Builder.ShipLog { _entryIdToRawName.Add(id.Value, curiosityName.Value); } + foreach (XElement childEntryElement in entryElement.Elements("Entry")) + { + XElement childCuriosityName = childEntryElement.Element("Curiosity"); + XElement childId = childEntryElement.Element("ID"); + if (childId != null && _entryIdToRawName.ContainsKey(childId.Value)) + { + if (childCuriosityName == null && curiosityName != null) + { + _entryIdToRawName.Add(childId.Value, curiosityName.Value); + } + else if (childCuriosityName != null) + { + _entryIdToRawName.Add(childId.Value, childCuriosityName.Value); + } + } + AddTranslation(childEntryElement); + } AddTranslation(entryElement); } TextAsset newAsset = new TextAsset(astroBodyFile.ToString()); @@ -99,7 +117,8 @@ namespace NewHorizons.Builder.ShipLog { id = entry._id, cardPosition = entryPosition, - sprite = body.Config.ShipLog.spriteFolder == null ? null : GetEntrySprite(entry._id, body) + sprite = body.Config.ShipLog.spriteFolder == null ? null : GetEntrySprite(entry._id, body), + altSprite = body.Config.ShipLog.spriteFolder == null ? null : GetEntrySprite(entry._id + "_ALT", body) }; entry.SetSprite(newData.sprite == null ? manager._shipLogLibrary.defaultEntrySprite : newData.sprite); manager._entryDataDict.Add(entry._id, newData); @@ -127,29 +146,36 @@ namespace NewHorizons.Builder.ShipLog table[name] = name; foreach (XElement rumorFact in entry.Elements("RumorFact")) { - XElement rumorName = rumorFact.Element("RumorName"); - if (rumorName != null) - { - table[rumorName.Value] = rumorName.Value; - } - - XElement rumorText = rumorFact.Element("Text"); - if (rumorText != null) - { - table[name + rumorText.Value] = rumorText.Value; - } + AddTranslationForElement(rumorFact, "RumorName", string.Empty, table); + AddTranslationForElement(rumorFact, "Text", name, table); + AddTranslationForAltText(rumorFact, name, table); } foreach (XElement exploreFact in entry.Elements("ExploreFact")) { - XElement exploreText = exploreFact.Element("Text"); - if (exploreText != null) - { - table[name + exploreText.Value] = exploreText.Value; - } + AddTranslationForElement(exploreFact, "Text", name, table); + AddTranslationForAltText(exploreFact, name, table); } } } + private static void AddTranslationForElement(XElement parent, string elementName, string keyName, Dictionary table) + { + XElement element = parent.Element(elementName); + if (element != null) + { + table[keyName + element.Value] = element.Value; + } + } + + private static void AddTranslationForAltText(XElement fact, string keyName, Dictionary table) + { + XElement altText = fact.Element("AltText"); + if (altText != null) + { + AddTranslationForElement(altText, "Text", keyName, table); + } + } + public static void UpdateEntryCuriosity(ref ShipLogEntry entry) { if (_entryIdToRawName.ContainsKey(entry._id)) @@ -177,8 +203,8 @@ namespace NewHorizons.Builder.ShipLog private static Vector2? GetManualEntryPosition(string entryId, ShipLogModule config) { - if (config.positions == null) return null; - foreach (ShipLogModule.EntryPositionInfo position in config.positions) + if (config.entryPositions == null) return null; + foreach (ShipLogModule.EntryPositionInfo position in config.entryPositions) { if (position.id == entryId) { diff --git a/NewHorizons/Components/ShipLogDetail.cs b/NewHorizons/Components/ShipLogDetail.cs index c6f77304..e1936a30 100644 --- a/NewHorizons/Components/ShipLogDetail.cs +++ b/NewHorizons/Components/ShipLogDetail.cs @@ -1,4 +1,5 @@ -using NewHorizons.External; +using System; +using NewHorizons.External; using OWML.Common; using UnityEngine; using UnityEngine.UI; @@ -8,17 +9,19 @@ namespace NewHorizons.Components { public class ShipLogDetail : MonoBehaviour { - private Image revealedImage; - private Image outlineImage; - private ShipLogModule.ShipLogDetailInfo detailInfo; + private Image _revealedImage; + private Image _outlineImage; + private Material _greyScaleMaterial; + private ShipLogModule.ShipLogDetailInfo _detailInfo; - public void Init(ShipLogModule.ShipLogDetailInfo info, Image revealed, Image outline) + public void Init(ShipLogModule.ShipLogDetailInfo info, Image revealed, Image outline, Material greyScale) { - detailInfo = info; - revealedImage = revealed; - outlineImage = outline; - revealedImage.enabled = false; - outlineImage.enabled = false; + _detailInfo = info; + _revealedImage = revealed; + _outlineImage = outline; + _greyScaleMaterial = greyScale; + _revealedImage.enabled = false; + _outlineImage.enabled = false; } public void UpdateState(ShipLogEntry.State parentState) @@ -26,22 +29,32 @@ namespace NewHorizons.Components switch (parentState) { case ShipLogEntry.State.Explored: - outlineImage.enabled = false; - revealedImage.enabled = true; + _outlineImage.enabled = false; + _revealedImage.enabled = true; + SetGreyScale(false); break; case ShipLogEntry.State.Rumored: - revealedImage.enabled = false; - outlineImage.enabled = true; + _outlineImage.enabled = false; + _revealedImage.enabled = true; + SetGreyScale(true); break; case ShipLogEntry.State.Hidden: - revealedImage.enabled = false; - outlineImage.enabled = !detailInfo.invisibleWhenHidden; + _revealedImage.enabled = false; + _outlineImage.enabled = !_detailInfo.invisibleWhenHidden; break; case ShipLogEntry.State.None: - revealedImage.enabled = false; - outlineImage.enabled = false; + _revealedImage.enabled = false; + _outlineImage.enabled = false; + break; + default: + Logger.LogError("Invalid ShipLogEntryState for " + _revealedImage.transform.parent.parent.gameObject.name); break; } } + + private void SetGreyScale(bool greyScale) + { + _revealedImage.material = (greyScale ? _greyScaleMaterial : null); + } } } \ No newline at end of file diff --git a/NewHorizons/External/ShipLogModule.cs b/NewHorizons/External/ShipLogModule.cs index 14ee2cdd..9b3be829 100644 --- a/NewHorizons/External/ShipLogModule.cs +++ b/NewHorizons/External/ShipLogModule.cs @@ -9,7 +9,7 @@ namespace NewHorizons.External public string[] initialReveal; public MapModeInfo mapMode; public CuriosityColorInfo[] curiosities; - public EntryPositionInfo[] positions; + public EntryPositionInfo[] entryPositions; public class MapModeInfo { @@ -18,6 +18,8 @@ namespace NewHorizons.External public float scale = 1f; public bool invisibleWhenHidden; public float offset = 0f; + public MVector2 manualPosition; + public MVector2 manualNavigationPosition; public bool remove = false; public ShipLogDetailInfo[] details; } diff --git a/NewHorizons/Handlers/ShipLogHandler.cs b/NewHorizons/Handlers/ShipLogHandler.cs index ff565b54..2ce83ffe 100644 --- a/NewHorizons/Handlers/ShipLogHandler.cs +++ b/NewHorizons/Handlers/ShipLogHandler.cs @@ -17,6 +17,25 @@ namespace NewHorizons.Builder.Handlers public static readonly string PAN_ROOT_PATH = "Ship_Body/Module_Cabin/Systems_Cabin/ShipLogPivot/ShipLog/ShipLogPivot/ShipLogCanvas/MapMode/ScaleRoot/PanRoot"; private static Dictionary _astroIdToBody = new Dictionary(); + private static string[] vanillaBodies; + private static string[] vanillaIDs; + + public static void Init() + { + List gameObjects = SearchUtilities.GetAllChildren(GameObject.Find(PAN_ROOT_PATH)); + vanillaBodies = gameObjects.ConvertAll(g => g.name).ToArray(); + vanillaIDs = gameObjects.ConvertAll(g => g.GetComponent()?.GetID()).ToArray(); + } + + public static bool IsVanillaAstroID(string astroId) + { + return vanillaIDs.Contains(astroId); + } + + public static bool IsVanillaBody(NewHorizonsBody body) + { + return vanillaBodies.Contains(body.Config.Name.Replace(" ", "")); + } public static NewHorizonsBody GetConfigFromID(string id) { @@ -33,7 +52,7 @@ namespace NewHorizons.Builder.Handlers public static string GetAstroObjectId(NewHorizonsBody body) { - if (_astroIdToBody.ContainsValue(body)) + if (BodyHasEntries(body)) { return CollectionUtilities.KeyByValue(_astroIdToBody, body); } @@ -42,5 +61,10 @@ namespace NewHorizons.Builder.Handlers return body.Config.Name; } } + + public static bool BodyHasEntries(NewHorizonsBody body) + { + return _astroIdToBody.ContainsValue(body); + } } } diff --git a/NewHorizons/Tools/ShipLogPatches.cs b/NewHorizons/Tools/ShipLogPatches.cs index 982e7e8b..efb474d7 100644 --- a/NewHorizons/Tools/ShipLogPatches.cs +++ b/NewHorizons/Tools/ShipLogPatches.cs @@ -33,6 +33,7 @@ namespace NewHorizons.Tools public static void OnShipLogManagerAwake(ShipLogManager __instance) { + ShipLogHandler.Init(); Logger.Log("Beginning Ship Log Generation For: " + Main.Instance.CurrentStarSystem, Logger.LogType.Log); if (Main.Instance.CurrentStarSystem != "SolarSystem") { @@ -42,6 +43,7 @@ namespace NewHorizons.Tools logEntryLocation._initialized = true; } } + foreach (NewHorizonsBody body in Main.BodyDict[Main.Instance.CurrentStarSystem]) { if (body.Config.ShipLog?.curiosities != null) @@ -49,6 +51,7 @@ namespace NewHorizons.Tools RumorModeBuilder.AddCuriosityColors(body.Config.ShipLog.curiosities); } } + foreach (NewHorizonsBody body in Main.BodyDict[Main.Instance.CurrentStarSystem]) { if (body.Config.ShipLog?.xmlFile != null) @@ -66,6 +69,7 @@ namespace NewHorizons.Tools ShipLogEntry logEntry = __instance._entryList[i]; RumorModeBuilder.UpdateEntryCuriosity(ref logEntry); } + Logger.Log("Ship Log Generation Complete For: " + Main.Instance.CurrentStarSystem, Logger.LogType.Log); } @@ -81,29 +85,39 @@ namespace NewHorizons.Tools { __result = false; } + return false; } - public static bool OnShipLogManagerCheckForCompletionAchievement() + public static bool OnShipLogManagerCheckForCompletionAchievement(ShipLogManager __instance) { - return Main.Instance.CurrentStarSystem == "SolarSystem"; + foreach (KeyValuePair keyValuePair in __instance._factDict) + { + if (ShipLogHandler.IsVanillaAstroID(__instance.GetEntry(keyValuePair.Value.GetEntryID()).GetAstroObjectID()) && !keyValuePair.Value.IsRumor() && !keyValuePair.Value.IsRevealed() && !keyValuePair.Key.Equals("TH_VILLAGE_X3") && !keyValuePair.Key.Equals("GD_GABBRO_ISLAND_X1") && __instance.GetEntry(keyValuePair.Value.GetEntryID()).GetCuriosityName() != CuriosityName.InvisiblePlanet) + { + return false; + } + } + Achievements.Earn(Achievements.Type.STUDIOUS); + return false; } public static bool OnShipLogManagerStart(ShipLogManager __instance) { + foreach (NewHorizonsBody body in Main.BodyDict[Main.Instance.CurrentStarSystem]) + { + foreach (string fact in body.Config.ShipLog?.initialReveal ?? Array.Empty()) + { + __instance.RevealFact(fact, false, false); + } + } + if (Main.Instance.CurrentStarSystem == "SolarSystem") { return true; } else { - foreach (NewHorizonsBody body in Main.BodyDict[Main.Instance.CurrentStarSystem]) - { - foreach (string fact in body.Config.ShipLog?.initialReveal ?? Array.Empty()) - { - __instance.RevealFact(fact, false, false); - } - } EntryLocationBuilder.InitializeLocations(); return false; } @@ -111,7 +125,7 @@ namespace NewHorizons.Tools public static bool OnUIStyleManagerGetCuriosityColor(UIStyleManager __instance, CuriosityName __0, bool __1, ref Color __result) { - if (Main.Instance.CurrentStarSystem == "SolarSystem") + if ((int) __0 < 7) { return true; } @@ -124,34 +138,37 @@ namespace NewHorizons.Tools public static void OnShipLogMapModeInitialize(ShipLogMapMode __instance) { - if (Main.Instance.CurrentStarSystem != "SolarSystem") + GameObject panRoot = GameObject.Find(ShipLogHandler.PAN_ROOT_PATH); + GameObject sunObject = GameObject.Find(ShipLogHandler.PAN_ROOT_PATH + "/Sun"); + ShipLogAstroObject[][] navMatrix = MapModeBuilder.ConstructMapMode(Main.Instance.CurrentStarSystem, panRoot, __instance._astroObjects, sunObject.layer); + if (navMatrix == null || navMatrix.Length <= 1) { - GameObject panRoot = GameObject.Find(ShipLogHandler.PAN_ROOT_PATH); - GameObject sunObject = GameObject.Find(ShipLogHandler.PAN_ROOT_PATH + "/Sun"); - ShipLogAstroObject[][] navMatrix = MapModeBuilder.ConstructMapMode(Main.Instance.CurrentStarSystem, panRoot, sunObject.layer); - if (navMatrix.Length <= 1) + Logger.LogWarning("Skipping Map Mode Generation."); + } + else + { + __instance._astroObjects = navMatrix; + __instance._startingAstroObjectID = navMatrix[1][0].GetID(); + if (Main.Instance.CurrentStarSystem != "SolarSystem") { - Logger.LogWarning("No planets suitable for map mode found! Defaulting to vanilla menu (expect weirdness!)."); - } - else - { - __instance._astroObjects = navMatrix; - __instance._startingAstroObjectID = navMatrix[1][0].GetID(); List delete = SearchUtilities.GetAllChildren(panRoot).Where(g => g.name.Contains("_ShipLog") == false).ToList(); foreach (GameObject gameObject in delete) { Object.Destroy(GameObject.Find(ShipLogHandler.PAN_ROOT_PATH + "/" + gameObject.name)); } - // Just Lie About Having A Sand Funnel - __instance._sandFunnel = __instance.gameObject.AddComponent(); + if (GameObject.Find(ShipLogHandler.PAN_ROOT_PATH + "/" + "SandFunnel") == null) + { + __instance._sandFunnel = __instance.gameObject.AddComponent(); + } } } + Logger.Log("Map Mode Construction Complete", Logger.LogType.Log); } public static bool OnShipLogAstroObjectGetName(ShipLogAstroObject __instance, ref string __result) { - if (Main.Instance.CurrentStarSystem == "SolarSystem") + if (ShipLogHandler.IsVanillaAstroID(__instance.GetID())) { return true; } @@ -196,5 +213,4 @@ namespace NewHorizons.Tools __result = __result.Where(e => manager.GetFact(e) != null).ToList(); } } -} - \ No newline at end of file +} \ No newline at end of file diff --git a/NewHorizons/schema.json b/NewHorizons/schema.json index 934b3218..966be976 100644 --- a/NewHorizons/schema.json +++ b/NewHorizons/schema.json @@ -1266,7 +1266,7 @@ "type": "string" } }, - "positions": { + "entryPositions": { "type": "array", "description": "A set of positions to use instead of automatic layout in rumor mode", "items": { @@ -1303,6 +1303,34 @@ "type": "string", "description": "The path to the sprite to show when the planet is unexplored in map mode" }, + "manualPosition": { + "type": "object", + "description": "Manually place this planet at the specified position", + "properties": { + "x": { + "type": "number", + "default": 0 + }, + "y": { + "type": "number", + "default": 0 + } + } + }, + "manualNavigationPosition": { + "type": "object", + "description": "Specify where this planet is in terms of navigation", + "properties": { + "x": { + "type": "integer", + "default": 0 + }, + "y": { + "type": "integer", + "default": 0 + } + } + }, "scale": { "type": "number", "description": "Scale to apply to the planet in map mode", diff --git a/NewHorizons/shiplog_schema.xsd b/NewHorizons/shiplog_schema.xsd index fe3ade33..c6b77898 100644 --- a/NewHorizons/shiplog_schema.xsd +++ b/NewHorizons/shiplog_schema.xsd @@ -1,38 +1,65 @@  + - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file