MetaProgression.cs

Component that manages a player's meta-progression: credits, three upgradeable stats (Force, Mass, Energy), prestige level and tokens. It handles credit awarding (with prestige multiplier), computing upgrade costs, attempting upgrades, prestige reset, and saving/loading progression to a local JSON file.

File Access
using Sandbox;
using System;

public sealed class MetaProgression : Component
{
	[Property] public int Credits { get; private set; } = 0;

	// Уровни мета-прокачки
	[Property] public int ForceLevel { get; private set; } = 0;
	[Property] public int MassLevel { get; private set; } = 0;
	[Property] public int EnergyLevel { get; private set; } = 0;

	// Престиж
	[Property] public int PrestigeLevel { get; private set; } = 0;
	[Property] public int PrestigeTokens { get; private set; } = 0;

	// Требования для сброса (сумма уровней прокачки)
	public const int REQUIRED_TOTAL_LEVELS_FOR_PRESTIGE = 15;

	private const string SAVE_FILE = "one_more_push_meta.json";

	protected override void OnStart()
	{
		LoadProgress();
	}

	public void AddCredits( int amount )
	{
		// Множитель престижа (+50% за каждый уровень престижа)
		float multiplier = 1.0f + (PrestigeLevel * 0.5f);
		Credits += (int)(amount * multiplier);
		SaveProgress();
	}

	public int GetUpgradeCost( int currentLevel )
	{
		return (int)(100 * Math.Pow( 1.5, currentLevel ));
	}

	public bool TryUpgradeForce()
	{
		int cost = GetUpgradeCost( ForceLevel );
		if ( Credits >= cost )
		{
			Credits -= cost;
			ForceLevel++;
			SaveProgress();
			return true;
		}
		return false;
	}

	public bool TryUpgradeMass()
	{
		int cost = GetUpgradeCost( MassLevel );
		if ( Credits >= cost )
		{
			Credits -= cost;
			MassLevel++;
			SaveProgress();
			return true;
		}
		return false;
	}

	public bool TryUpgradeEnergy()
	{
		int cost = GetUpgradeCost( EnergyLevel );
		if ( Credits >= cost )
		{
			Credits -= cost;
			EnergyLevel++;
			SaveProgress();
			return true;
		}
		return false;
	}

	// Проверка: готов ли игрок к престижу
	public bool CanPrestige()
	{
		int totalLevels = ForceLevel + MassLevel + EnergyLevel;
		return totalLevels >= REQUIRED_TOTAL_LEVELS_FOR_PRESTIGE;
	}

	// Сброс прогресса ради Престижа
	public bool TryPrestige()
	{
		if ( !CanPrestige() ) return false;

		// Сбрасываем обычные уровни и кредиты
		ForceLevel = 0;
		MassLevel = 0;
		EnergyLevel = 0;
		Credits = 0;

		// Повышаем уровень престижа и выдаем токены
		PrestigeLevel++;
		PrestigeTokens += 1;

		SaveProgress();
		return true;
	}

	public void SaveProgress()
	{
		var data = new ProgressData
		{
			Credits = this.Credits,
			ForceLevel = this.ForceLevel,
			MassLevel = this.MassLevel,
			EnergyLevel = this.EnergyLevel,
			PrestigeLevel = this.PrestigeLevel,
			PrestigeTokens = this.PrestigeTokens
		};

		FileSystem.Data.WriteJson( SAVE_FILE, data );
	}

	public void LoadProgress()
	{
		if ( FileSystem.Data.FileExists( SAVE_FILE ) )
		{
			var data = FileSystem.Data.ReadJson<ProgressData>( SAVE_FILE );
			if ( data != null )
			{
				Credits = data.Credits;
				ForceLevel = data.ForceLevel;
				MassLevel = data.MassLevel;
				EnergyLevel = data.EnergyLevel;
				PrestigeLevel = data.PrestigeLevel;
				PrestigeTokens = data.PrestigeTokens;
			}
		}
	}

	private class ProgressData
	{
		public int Credits { get; set; }
		public int ForceLevel { get; set; }
		public int MassLevel { get; set; }
		public int EnergyLevel { get; set; }
		public int PrestigeLevel { get; set; }
		public int PrestigeTokens { get; set; }
	}
}