mirror of
https://github.com/kwsch/NHSE.git
synced 2026-04-18 06:36:11 -05:00
257 lines
8.9 KiB
C#
257 lines
8.9 KiB
C#
using System.Collections.Generic;
|
|
|
|
namespace NHSE.Core
|
|
{
|
|
/// <summary>
|
|
/// Stores game localization strings for use by logic.
|
|
/// </summary>
|
|
public sealed class GameStrings : IRemakeString
|
|
{
|
|
private readonly string lang;
|
|
|
|
public readonly string[] villagers;
|
|
public readonly string[] itemlist;
|
|
public readonly string[] itemlistdisplay;
|
|
public readonly string[] villagerDefaultPhrases;
|
|
public readonly Dictionary<string, string> VillagerMap;
|
|
public readonly Dictionary<string, string> VillagerDefaultPhraseMap;
|
|
public readonly List<ComboItem> ItemDataSource;
|
|
public readonly Dictionary<string, string> InternalNameTranslation = new();
|
|
|
|
public IReadOnlyDictionary<string, string> BodyParts { get; }
|
|
public IReadOnlyDictionary<string, string> BodyColor { get; }
|
|
public IReadOnlyDictionary<string, string> FabricParts { get; }
|
|
public IReadOnlyDictionary<string, string> FabricColor { get; }
|
|
|
|
private string[] Get(string ident) => GameLanguage.GetStrings(ident, lang);
|
|
|
|
public GameStrings(string l)
|
|
{
|
|
lang = l;
|
|
villagers = Get("villager");
|
|
VillagerMap = GetMap(villagers);
|
|
villagerDefaultPhrases = Get("phrase");
|
|
VillagerDefaultPhraseMap = GetMap(villagerDefaultPhrases);
|
|
itemlist = Get("item");
|
|
itemlistdisplay = GetItemDisplayList(itemlist);
|
|
ItemDataSource = CreateItemDataSource(itemlistdisplay);
|
|
|
|
BodyParts = GetDictionary(Get("body_parts"));
|
|
BodyColor = GetDictionary(Get("body_color"));
|
|
FabricParts = GetDictionary(Get("fabric_parts"));
|
|
FabricColor = GetDictionary(Get("fabric_color"));
|
|
}
|
|
|
|
private static IReadOnlyDictionary<string, string> GetDictionary(IEnumerable<string> lines, char split = '\t')
|
|
{
|
|
var result = new Dictionary<string, string>();
|
|
foreach (var s in lines)
|
|
{
|
|
if (s.Length == 0)
|
|
continue;
|
|
var index = s.IndexOf(split);
|
|
var key = s.Substring(0, index);
|
|
var value = s.Substring(index + 1);
|
|
result.Add(key, value);
|
|
}
|
|
return result;
|
|
}
|
|
|
|
private List<ComboItem> CreateItemDataSource(string[] strings)
|
|
{
|
|
var dataSource = ComboItemUtil.GetArray(strings);
|
|
|
|
// load special
|
|
dataSource.Add(new ComboItem(itemlist[0], Item.NONE));
|
|
dataSource.SortByText();
|
|
|
|
return dataSource;
|
|
}
|
|
|
|
public List<ComboItem> CreateItemDataSource(IReadOnlyCollection<ushort> dict, bool none = true)
|
|
{
|
|
var display = itemlistdisplay;
|
|
var result = new List<ComboItem>(dict.Count);
|
|
foreach (var x in dict)
|
|
result.Add(new ComboItem(display[x], x));
|
|
|
|
if (none)
|
|
result.Add(new ComboItem(itemlist[0], Item.NONE));
|
|
|
|
result.SortByText();
|
|
return result;
|
|
}
|
|
|
|
public List<ComboItem> CreateItemDataSource(IReadOnlyCollection<KeyValuePair<ushort, ushort>> dict, bool none = true)
|
|
{
|
|
var display = itemlistdisplay;
|
|
var result = new List<ComboItem>(dict.Count);
|
|
foreach (var x in dict)
|
|
result.Add(new ComboItem(display[x.Value], x.Key));
|
|
|
|
if (none)
|
|
result.Add(new ComboItem(itemlist[0], Item.NONE));
|
|
|
|
result.SortByText();
|
|
return result;
|
|
}
|
|
|
|
private static Dictionary<string, string> GetMap(IReadOnlyCollection<string> arr)
|
|
{
|
|
var map = new Dictionary<string, string>(arr.Count);
|
|
foreach (var kvp in arr)
|
|
{
|
|
var index = kvp.IndexOf('\t');
|
|
if (index < 0)
|
|
continue;
|
|
var abbrev = kvp.Substring(0, index);
|
|
var name = kvp.Substring(index + 1);
|
|
map.Add(abbrev, name);
|
|
}
|
|
return map;
|
|
}
|
|
|
|
public string GetVillager(string name)
|
|
{
|
|
return VillagerMap.TryGetValue(name, out var result) ? result : name;
|
|
}
|
|
|
|
public string GetVillagerDefaultPhrase(string name)
|
|
{
|
|
return VillagerDefaultPhraseMap.TryGetValue(name, out var result) ? result : name; // I know it shouldn't be name but I have to return something
|
|
}
|
|
|
|
public static string[] GetItemDisplayList(string[] items)
|
|
{
|
|
items = (string[])items.Clone();
|
|
items[0] = string.Empty;
|
|
var set = new HashSet<string>();
|
|
for (int i = 0; i < items.Length; i++)
|
|
{
|
|
var item = items[i];
|
|
if (string.IsNullOrEmpty(item))
|
|
items[i] = $"(Item #{i:000})";
|
|
else if (set.Contains(item))
|
|
items[i] += $" (#{i:000})";
|
|
else
|
|
set.Add(item);
|
|
}
|
|
return items;
|
|
}
|
|
|
|
public string GetItemName(Item item)
|
|
{
|
|
var index = item.ItemId;
|
|
if (index == Item.NONE)
|
|
return itemlist[0];
|
|
if (index == Item.EXTENSION)
|
|
return GetItemName(item.ExtensionItemId);
|
|
|
|
var kind = ItemInfo.GetItemKind(index);
|
|
|
|
if (kind.IsFlowerGene(index))
|
|
{
|
|
var display = GetItemName(index);
|
|
if (item.Genes != 0)
|
|
return $"{display} - {item.Genes}";
|
|
}
|
|
|
|
if (kind == ItemKind.Kind_DIYRecipe || kind == ItemKind.Kind_MessageBottle)
|
|
{
|
|
var display = itemlistdisplay[index];
|
|
var recipeID = (ushort)item.FreeParam;
|
|
var isKnown = RecipeList.Recipes.TryGetValue(recipeID, out var result);
|
|
var makes = isKnown ? GetItemName(result) : recipeID.ToString("000");
|
|
return $"{display} - {makes}";
|
|
}
|
|
|
|
if (kind == ItemKind.Kind_FossilUnknown)
|
|
{
|
|
var display = itemlistdisplay[index];
|
|
var fossilID = (ushort)item.FreeParam;
|
|
var fossilName = GetItemName(fossilID);
|
|
return $"{display} - {fossilName}";
|
|
}
|
|
|
|
if (kind == ItemKind.Kind_Tree)
|
|
{
|
|
var display = GetItemName(index);
|
|
var willDrop = item.Count;
|
|
if (willDrop != 0)
|
|
{
|
|
var dropName = GetItemName(willDrop);
|
|
return $"{display} - {dropName}";
|
|
}
|
|
}
|
|
|
|
return GetItemName(index);
|
|
}
|
|
|
|
public string GetItemName(ushort index)
|
|
{
|
|
if (index >= itemlistdisplay.Length)
|
|
return GetItemName60000(index);
|
|
return itemlistdisplay[index];
|
|
}
|
|
|
|
private static string GetItemName60000(ushort index)
|
|
{
|
|
if (FieldItemList.Items.TryGetValue(index, out var val))
|
|
return val.Name;
|
|
|
|
// 63,000 ???
|
|
if (index == Item.LLOYD)
|
|
return "Lloyd";
|
|
|
|
return "???";
|
|
}
|
|
|
|
/// <summary>
|
|
/// Returns clothing or item recolors not a part of ItemRemake with brackets in their names
|
|
/// </summary>
|
|
/// <param name="id">ItemID of the color variation search</param>
|
|
/// <param name="baseItemName">Item name without the associated recolors</param>
|
|
/// <returns>Map of ItemID, ItemName</returns>
|
|
public List<ComboItem> GetAssociatedItems(ushort id, out string baseItemName)
|
|
{
|
|
baseItemName = string.Empty;
|
|
var stringMatch = GetItemName(id);
|
|
var index = stringMatch.IndexOf('(');
|
|
if (index < 0)
|
|
return new List<ComboItem>();
|
|
|
|
var search = baseItemName = stringMatch.Substring(0, index);
|
|
if (!string.IsNullOrWhiteSpace(search))
|
|
return ItemDataSource.FindAll(x => x.Text.StartsWith(search));
|
|
else
|
|
return new List<ComboItem>();
|
|
}
|
|
|
|
|
|
public bool HasAssociatedItems(string baseName, out List<ComboItem>? items)
|
|
{
|
|
if (string.IsNullOrWhiteSpace(baseName))
|
|
{
|
|
items = null;
|
|
return false;
|
|
}
|
|
|
|
baseName = baseName.Trim().ToLower();
|
|
if (!baseName.EndsWith(" "))
|
|
baseName += " ";
|
|
baseName += "(";
|
|
|
|
items = ItemDataSource.FindAll(x => x.Text.ToLower().StartsWith(baseName));
|
|
return items.Count > 0;
|
|
}
|
|
}
|
|
|
|
public interface IRemakeString
|
|
{
|
|
IReadOnlyDictionary<string, string> BodyParts { get; }
|
|
IReadOnlyDictionary<string, string> BodyColor { get; }
|
|
IReadOnlyDictionary<string, string> FabricParts { get; }
|
|
IReadOnlyDictionary<string, string> FabricColor { get; }
|
|
}
|
|
}
|