Spending/Research/Techs/BaseTech.cs
using System.Text.Json.Nodes;

namespace PlanetMeat;

public class BaseTech : ISaveTarget
{
	public static string GetToolTitle( string tool ) => "tool." + tool + ".title";
	public static string GetToolDesc( string tool ) => "tool." + tool + ".desc";
	public static string TrToolTitle( string t ) => Game.Language.GetPhrase( GetToolTitle( t ) );

	public string Ident { get; }
	public int Duration { get; }
	public int Progress { get; private set; }
	public bool Completed => Progress >= Duration;
	public int Remaining => Duration - Progress;

	public virtual bool Visible => true;
	public string DisplayName => "tech." + Ident + ".title";

	public bool ShowTool { get; set; }
	public string DisplayToolName => GetToolTitle( Ident );
	public string DisplayToolDesc => GetToolDesc( Ident );
	public string DisplayToolIcon => Catalogue.Current.Categories[Ident].DisplayIcon;

	public JsonNode NextSave => new JsonObject
	{
		{ nameof( Progress ), Progress },
		{ nameof( Completed ), Completed },
	};

	public BaseTech( string ident, int duration )
	{
		Ident = ident;
		Duration = duration;
	}

	public void AdvanceProgress( int amount )
	{
		Progress += amount;
	}

	public void LoadFromSave( JsonNode save )
	{
		if ( save.AsObject() is JsonObject obj && obj.TryGetTypedProperty( nameof( Progress ), out int p ) )
		{
			Progress = p;
			if ( !Completed && obj.TryGetTypedProperty( nameof( Completed ), out bool c ) && c )
				Progress = Duration;
		}
	}

	public void ClearSave()
	{
		Progress = 0;
	}
}