NHSE/NHSE.Core/Structures/Misc/MuseumEditor.cs
2026-01-17 22:12:37 -06:00

109 lines
3.2 KiB
C#

using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
namespace NHSE.Core;
public sealed record MuseumEditor(Museum Museum)
{
public readonly GSaveDate[] Dates = Museum.GetDates();
public readonly Item[] Items = Museum.GetItems();
public readonly byte[] Players = Museum.GetPlayers();
public void Save()
{
Museum.SetDates(Dates);
Museum.SetItems(Items);
Museum.SetPlayers(Players);
}
public IEnumerable<string> GetDonationSummary(GameStrings str)
{
for (int i = 0; i < Museum.EntryCount; i++)
{
var item = Items[i];
if (item.IsNone)
continue;
yield return GetDonationSummary(str, item, i);
}
}
public string GetDonationSummary(GameStrings str, int index) => GetDonationSummary(str, Items[index], index);
public string GetDonationText(GameStrings str, int index) => $"{Dates[index]}: {str.GetItemName(Items[index])}";
private string GetDonationSummary(GameStrings str, Item item, int index)
{
var date = Dates[index];
var player = Players[index];
var name = str.GetItemName(item);
var result = $"On {date}, Player {player} donated a(n) {name}.";
return result;
}
public int GiveAll(ReadOnlySpan<string> englishNames, int interval = 20)
{
var list = new List<ushort>(GameLists.Art.Length);
foreach (var item in GameLists.Art)
{
// ignore forgeries
if (!englishNames[item].Contains('('))
list.Add(item);
}
list.AddRange(GameLists.Fish);
list.AddRange(GameLists.Fossils);
list.AddRange(GameLists.Bugs);
list.AddRange(GameLists.Dive);
RandUtil.Shuffle(list);
return AddItems(CollectionsMarshal.AsSpan(list), interval);
}
private int AddItems(ReadOnlySpan<ushort> items, int interval = 20)
{
var processed = Items.Select(z => z.ItemId).Where(z => z != Item.NONE).Distinct();
var hashset = new HashSet<ushort>(processed);
var latestDate = Dates.Max(z => (DateTime)z);
int added = 0;
foreach (var id in items)
{
if (hashset.Contains(id))
continue;
if (added % interval == 0)
latestDate = latestDate.AddDays(1);
int openIndex = GetFirstOpenIndex();
Dates[openIndex] = latestDate;
Items[openIndex] = new Item(id);
Players[openIndex] = 0; // first player
added++;
}
return added;
}
private int GetFirstOpenIndex() => Array.FindIndex(Items, z => z.ItemId == Item.NONE);
public void SortAll()
{
var lump = Enumerable.Range(0, Items.Length)
.Select(z => new {Index = z, Item = Items[z], Date = Dates[z], Player = Players[z]})
.OrderBy(z => z.Date.IsEmpty)
.ThenBy(z => (DateTime)z.Date);
int ctr = 0;
foreach (var x in lump)
{
Dates[ctr] = x.Date;
Items[ctr] = x.Item;
Players[ctr] = x.Player;
ctr++;
}
}
}