Game/PumpTier.cs
namespace DesertPump;

/// <summary>
/// One of the twelve tiers. A tier is nine pumps that share a setting - you finish
/// the desert before you ever see a glacier.
/// </summary>
public sealed class PumpTier
{
	/// <summary>1 to 12, the way the player sees it.</summary>
	public int Number { get; init; }

	public string Name { get; init; }
	public string Tagline { get; init; }

	/// <summary>Drives the placeholder pump art for every pump in this tier.</summary>
	public Color Tint { get; init; }

	/// <summary>The nine pump names, cheapest first.</summary>
	public string[] PumpNames { get; init; }

	public int FirstPumpIndex => (Number - 1) * PumpsPerTier;
	public int LastPumpIndex => FirstPumpIndex + PumpsPerTier - 1;

	public const int PumpsPerTier = 9;

	/// <summary>Re-read on hotload so edits apply without restarting - see PumpModel.All.</summary>
	[SkipHotload]
	public static readonly PumpTier[] All = new PumpTier[]
	{
		new()
		{
			Number = 1,
			Name = "Desert Wells",
			Tagline = "Sand, rust, and whatever you can pull up by hand.",
			Tint = new Color( 0.72f, 0.50f, 0.24f ),
			// These nine are all ways of getting water out of a hole in the ground.
			// The old set were leftovers from when there were nine tiers rather than
			// twelve, so tier 1 - the one whose whole premise is hand-pulled water -
			// contained a Steam Pressure Pump, a Diesel Derrick and a Solar Filtration
			// Rig, each of which is the name of a tier the player has not reached yet.
			PumpNames = new[]
			{
				"Rusty Hand Pump", "Iron Well Pump", "Bucket Windlass",
				"Windmill Well", "Cattle Trough Bore", "Stone Well House",
				"Desert Water Tower", "Twin Bore Rig", "The Great Standpipe"
			}
		},
		new()
		{
			Number = 2,
			Name = "The Steamworks",
			Tagline = "Brass, pressure gauges, and a great deal of hissing.",
			Tint = new Color( 0.66f, 0.42f, 0.20f ),
			PumpNames = new[]
			{
				"Brass Piston Well", "Boiler Draw", "Twin Cylinder Rig",
				"Pressure Cathedral", "Governor Engine", "Flywheel Colossus",
				"Condenser Array", "Turbine Hall", "The Great Manifold"
			}
		},
		new()
		{
			Number = 3,
			Name = "Oil Country",
			Tagline = "If it worked for crude, it'll work for water.",
			Tint = new Color( 0.34f, 0.34f, 0.30f ),
			PumpNames = new[]
			{
				"Nodding Donkey", "Wildcat Rig", "Slant Drill",
				"Offshore Jacket", "Deep Casing Pump", "Fracture Head",
				"Pipeline Junction", "Refinery Tap", "The Black Column"
			}
		},
		new()
		{
			Number = 4,
			Name = "Solar Frontier",
			Tagline = "Free light, endless panels, no moving parts.",
			Tint = new Color( 0.28f, 0.46f, 0.78f ),
			PumpNames = new[]
			{
				"Panel Trickle", "Mirror Trough", "Heliostat Field",
				"Molten Salt Loop", "Photovoltaic Mesa", "Tower of Light",
				"Orbital Reflector", "Fusion Preheater", "The Sun Engine"
			}
		},
		new()
		{
			Number = 5,
			Name = "The Lost Oasis",
			Tagline = "Someone was pumping here long before you.",
			Tint = new Color( 0.86f, 0.70f, 0.26f ),
			PumpNames = new[]
			{
				"Sunken Step Well", "Palm Court Spring", "Mosaic Cistern",
				"Colonnade Fountain", "Serpent Aqueduct", "Sun Disc Basin",
				"Hall of Rains", "Temple of the Flood", "The First Spring"
			}
		},
		new()
		{
			Number = 6,
			Name = "Deep Aquifer",
			Tagline = "Down where the rock has been holding its breath.",
			Tint = new Color( 0.30f, 0.52f, 0.55f ),
			PumpNames = new[]
			{
				"Bore Shaft", "Karst Siphon", "Cavern Lake Pump",
				"Sinkhole Intake", "Mantle Straw", "Pressure Fault",
				"Abyssal Column", "Tectonic Draw", "The Sleeping Sea"
			}
		},
		new()
		{
			Number = 7,
			Name = "Storm Harvest",
			Tagline = "Stop digging. Start taking it out of the sky.",
			Tint = new Color( 0.42f, 0.46f, 0.62f ),
			PumpNames = new[]
			{
				"Rain Catcher", "Cloud Seeder", "Squall Funnel",
				"Lightning Condenser", "Monsoon Gate", "Cyclone Tap",
				"Hurricane Yoke", "Jet Stream Weir", "The Storm Crown"
			}
		},
		new()
		{
			Number = 8,
			Name = "Glacier Melt",
			Tagline = "Ten thousand years of snow, cashed in.",
			Tint = new Color( 0.58f, 0.78f, 0.86f ),
			PumpNames = new[]
			{
				"Meltwater Channel", "Crevasse Pump", "Ice Core Drill",
				"Moraine Sluice", "Calving Front Rig", "Ice Shelf Siphon",
				"Polar Reservoir", "Continental Thaw", "The Long Winter Tap"
			}
		},
		new()
		{
			Number = 9,
			Name = "Ocean Reclaim",
			Tagline = "Salt is just an engineering problem.",
			Tint = new Color( 0.20f, 0.52f, 0.62f ),
			PumpNames = new[]
			{
				"Beach Well", "Reverse Osmosis Bank", "Desalination Pier",
				"Tidal Intake", "Trench Pump", "Current Harness",
				"Abyssal Plain Array", "Continental Shelf Works", "The Ocean Engine"
			}
		},
		new()
		{
			Number = 10,
			Name = "Sky Condensers",
			Tagline = "The whole atmosphere, wrung out like a cloth.",
			Tint = new Color( 0.66f, 0.72f, 0.86f ),
			PumpNames = new[]
			{
				"Fog Net", "Dew Spire", "Stratosphere Coil",
				"Cloud Anchor", "Mesosphere Rig", "Aurora Collector",
				"Orbital Ring Tap", "Atmospheric Siphon", "The Great Condenser"
			}
		},
		new()
		{
			Number = 11,
			Name = "Void Springs",
			Tagline = "The water is coming from somewhere. Don't ask where.",
			Tint = new Color( 0.52f, 0.36f, 0.78f ),
			PumpNames = new[]
			{
				"Rift Trickle", "Phase Well", "Folded Space Pump",
				"Null Aquifer", "Entropy Siphon", "Singularity Draw",
				"Event Horizon Tap", "Vacuum Spring", "The Hollow Between"
			}
		},
		new()
		{
			Number = 12,
			Name = "Cosmic Wellspring",
			Tagline = "Comets are mostly ice, and there are rather a lot of them.",
			Tint = new Color( 0.30f, 0.80f, 0.92f ),
			PumpNames = new[]
			{
				"Comet Harpoon", "Ring System Skimmer", "Ice Moon Bore",
				"Nebula Trawler", "Rogue World Tap", "Stellar Nursery Pump",
				"Galactic Aqueduct", "Dark Flow Intake", "The Wellspring"
			}
		},
	};

	public static int Count => All.Length;

	/// <summary>Total pumps across every tier.</summary>
	public static int TotalPumps => Count * PumpsPerTier;

	/// <summary>Tier for a 0-based pump index.</summary>
	public static PumpTier ForPump( int pumpIndex ) =>
		All[Math.Clamp( pumpIndex / PumpsPerTier, 0, Count - 1 )];

	/// <summary>Tier by its 1-12 number.</summary>
	public static PumpTier Get( int number ) => All[Math.Clamp( number - 1, 0, Count - 1 )];
}