Spending/Research/Improvements/BaseImprovements.cs
using System;
using System.Numerics;
using System.Text.Json.Nodes;
namespace PlanetMeat;
public class BaseImprovement : IPurchaseableUpgrade, ISaveTarget
{
public string Ident { get; private set; }
public string CategoryIdent { get; private set; }
public string UpgradeNameIdent { get; set; } = null;
public int Rank { get; set; }
public virtual double NextCost => CostOffset + Progressions.StairSlow( Rank + CostStart );
public int CostStart { get; set; } = 1;
public int CostOffset { get; set; } = 0;
public string RequiredTech { get => field == "" && Research.Current.IsTech( CategoryIdent ) ? CategoryIdent : field; set; } = "";
public virtual bool Visible => Research.Current.HasTech( RequiredTech );
public virtual bool Purchaseable => true;
public string DisplayedCurrentEffect => GetDisplayedEffectAt( Rank );
public string DisplayedNextEffect => GetDisplayedEffectAt( Rank + 1 );
public string AdvancementText => DisplayedCurrentEffect + " -> " + DisplayedNextEffect;
public string DisplayName => UpgradeNameIdent is null ? ("improvement." + Ident + ".title") : ("upgrade." + UpgradeNameIdent + ".title");
public JsonNode NextSave => new JsonObject { { nameof( Rank ), Rank } };
public BaseImprovement( string ident, string category )
{
Ident = ident;
CategoryIdent = category;
}
public bool TryPurchase()
{
var cost = NextCost;
if ( Purchaseable && Bank.Current.GetAccount( "meat" ).TrySpend( cost ) )
{
Career.Current.IncrementStat( "meat_spent", cost );
Career.Current.IncrementStat( "improvements" );
Rank++;
return true;
}
return false;
}
public virtual void BakeEffects() { }
public virtual string GetDisplayedEffectAt( int rank ) => rank.ToString();
public void LoadFromSave( JsonNode save )
{
if ( save.AsObject() is JsonObject obj && obj.TryGetTypedProperty( nameof( Rank ), out int r ) )
Rank = r;
}
public void ClearSave()
{
Rank = 0;
}
}
public abstract class BaseEffectImprovement<T>( string ident, string category, T effectBase, T effectPerRank, T effectMax ) : BaseImprovement( ident, category ) where T : IAdditionOperators<T, T, T>, IComparable<T>
{
public T CurrentEffect => GetEffectAt( Rank );
public abstract T GetEffectAt( int rank );
public abstract bool HasCap { get; }
public T EffectBase { get; } = effectBase;
public T EffectMax { get; } = effectMax;
public T EffectPerRank { get; } = effectPerRank;
public bool IsIncrease => GetEffectAt( Rank ).CompareTo( GetEffectAt( Rank + 1 ) ) < 0;
protected virtual bool IsUnderCap => CurrentEffect.CompareTo( EffectMax ) < 0;
public override bool Purchaseable => base.Purchaseable && IsIncrease && (!HasCap || IsUnderCap);
public override string GetDisplayedEffectAt( int rank )
{
var effect = GetEffectAt( rank );
if ( effect is double d )
return LargeNumberString.ToCompact( d );
if ( effect is float f )
return f.ToString( "N" );
return effect.ToString();
}
}