using NewHorizons.External.Configs; using NewHorizons.External.Modules; using NewHorizons.Handlers; using NewHorizons.Utility; using System; using System.Collections.Generic; using System.Xml.Linq; using UnityEngine; using Logger = NewHorizons.Utility.Logger; namespace NewHorizons.Builder.ShipLog { public static class RumorModeBuilder { private static Dictionary _curiosityColors; private static Dictionary _curiosityHighlightColors; private static Dictionary _rawNameToCuriosityName; private static Dictionary _entryIdToRawName; public static void Init() { _curiosityColors = new Dictionary(); _curiosityHighlightColors = new Dictionary(); _rawNameToCuriosityName = new Dictionary(); _entryIdToRawName = new Dictionary(); } public static void AddCuriosityColors(ShipLogModule.CuriosityColorInfo[] newColors) { foreach (ShipLogModule.CuriosityColorInfo newColor in newColors) { if (_rawNameToCuriosityName.ContainsKey(newColor.id) == false) { CuriosityName newName = (CuriosityName)8 + _rawNameToCuriosityName.Count; _rawNameToCuriosityName.Add(newColor.id, newName); _curiosityColors.Add(newName, newColor.color.ToColor()); _curiosityHighlightColors.Add(newName, newColor.highlightColor.ToColor()); } } } public static Color GetCuriosityColor(CuriosityName curiosityName, bool highlighted, Color defaultColor, Color defaultHighlight) { if (_curiosityColors.ContainsKey(curiosityName) && _curiosityHighlightColors.ContainsKey(curiosityName)) { return (highlighted ? _curiosityHighlightColors : _curiosityColors)[curiosityName]; } else { return highlighted ? defaultHighlight : defaultColor; } } public static void AddBodyToShipLog(ShipLogManager manager, NewHorizonsBody body) { string systemName = body.Config.starSystem; XElement astroBodyFile = XElement.Load(body.Mod.ModHelper.Manifest.ModFolderPath + "/" + body.Config.ShipLog.xmlFile); XElement astroBodyId = astroBodyFile.Element("ID"); if (astroBodyId == null) { Logger.LogError("Failed to load ship logs for " + systemName + "!"); } else { var entryIDs = new List(); foreach (XElement entryElement in astroBodyFile.DescendantsAndSelf("Entry")) { XElement curiosityName = entryElement.Element("Curiosity"); XElement id = entryElement.Element("ID"); if (id != null) { entryIDs.Add(id.Value); if (curiosityName != null && _entryIdToRawName.ContainsKey(id.Value) == false) { _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) { entryIDs.Add(childId.Value); if (_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()); List newBodies = new List(manager._shipLogXmlAssets) { newAsset }; manager._shipLogXmlAssets = newBodies.ToArray(); ShipLogHandler.AddConfig(astroBodyId.Value, entryIDs, body); } } public static void GenerateEntryData(ShipLogManager manager) { const int step = 400; int colAccumulator = 0; int rowAccumulator = 0; foreach (ShipLogEntry entry in manager._entryList) { if (manager._entryDataDict.ContainsKey(entry._id) == false) { NewHorizonsBody body = ShipLogHandler.GetConfigFromEntryID(entry._id); Vector2? manualEntryPosition = GetManualEntryPosition(entry._id, body.Config); Vector2 entryPosition; if (manualEntryPosition == null) { entryPosition = new Vector2(colAccumulator, rowAccumulator); } else { entryPosition = (Vector2)manualEntryPosition; } EntryData newData = new EntryData { id = entry._id, cardPosition = entryPosition, sprite = body.Config.ShipLog.spriteFolder == null ? null : GetEntrySprite(entry._id, body, true), altSprite = body.Config.ShipLog.spriteFolder == null ? null : GetEntrySprite(entry._id + "_ALT", body, false) }; entry.SetSprite(newData.sprite == null ? manager._shipLogLibrary.defaultEntrySprite : newData.sprite); entry.SetAltSprite(newData.sprite == null ? manager._shipLogLibrary.defaultEntrySprite : newData.altSprite); manager._entryDataDict.Add(entry._id, newData); int index = manager._entryList.IndexOf(entry); if (index < manager._entryList.Count - 2 && manager._entryList[index + 1]._astroObjectID != entry._astroObjectID) { rowAccumulator += step; colAccumulator = 0; } else { colAccumulator += step; } } } } private static void AddTranslation(XElement entry) { XElement nameElement = entry.Element("Name"); if (nameElement != null) { string name = nameElement.Value; TranslationHandler.AddShipLog(name); foreach (XElement rumorFact in entry.Elements("RumorFact")) { AddTranslationForElement(rumorFact, "RumorName", string.Empty); AddTranslationForElement(rumorFact, "Text", name); AddTranslationForAltText(rumorFact, name); } foreach (XElement exploreFact in entry.Elements("ExploreFact")) { AddTranslationForElement(exploreFact, "Text", name); AddTranslationForAltText(exploreFact, name); } } } private static void AddTranslationForElement(XElement parent, string elementName, string keyName) { XElement element = parent.Element(elementName); if (element != null) { TranslationHandler.AddShipLog(element.Value, keyName); } } private static void AddTranslationForAltText(XElement fact, string keyName) { XElement altText = fact.Element("AltText"); if (altText != null) { AddTranslationForElement(altText, "Text", keyName); } } public static void UpdateEntryCuriosity(ref ShipLogEntry entry) { if (_entryIdToRawName.ContainsKey(entry._id)) { var raw = _entryIdToRawName[entry._id]; if (_rawNameToCuriosityName.ContainsKey(raw)) { entry._curiosity = _rawNameToCuriosityName[raw]; } else { Logger.LogError($"Couldn't find {raw}. Did you define the curiosity in a json config? Because you have to."); } } } private static Sprite GetEntrySprite(string entryId, NewHorizonsBody body, bool logError) { string relativePath = body.Config.ShipLog.spriteFolder + "/" + entryId + ".png"; try { Texture2D newTexture = ImageUtilities.GetTexture(body.Mod, relativePath); Rect rect = new Rect(0, 0, newTexture.width, newTexture.height); Vector2 pivot = new Vector2(newTexture.width / 2, newTexture.height / 2); return Sprite.Create(newTexture, rect, pivot); } catch (Exception) { if (logError) Logger.LogError($"Couldn't load image for {entryId} at {relativePath}"); return null; } } private static Vector2? GetManualEntryPosition(string entryId, PlanetConfig config) { Main.SystemDict.TryGetValue(config.starSystem, out var system); var entryPositions = system?.Config?.entryPositions; if (entryPositions == null) return null; foreach (ShipLogModule.EntryPositionInfo position in entryPositions) { if (position.id == entryId) { return position.position; } } return null; } } }