new-horizons/NewHorizons/Builder/ShipLog/RumorModeBuilder.cs
2022-05-22 18:57:05 -04:00

236 lines
10 KiB
C#

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<CuriosityName, Color> _curiosityColors;
private static Dictionary<CuriosityName, Color> _curiosityHighlightColors;
private static Dictionary<string, CuriosityName> _rawNameToCuriosityName;
private static Dictionary<string, string> _entryIdToRawName;
public static void Init()
{
_curiosityColors = new Dictionary<CuriosityName, Color>();
_curiosityHighlightColors = new Dictionary<CuriosityName, Color>();
_rawNameToCuriosityName = new Dictionary<string, CuriosityName>();
_entryIdToRawName = new Dictionary<string, string>();
}
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<string>();
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<TextAsset> newBodies = new List<TextAsset>(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.ShipLog);
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, ShipLogModule config)
{
if (config.entryPositions == null) return null;
foreach (ShipLogModule.EntryPositionInfo position in config.entryPositions)
{
if (position.id == entryId)
{
return position.position;
}
}
return null;
}
}
}