Data class defining food types for the game. Declares properties for stats (boosts, costs, pellet visuals), several predefined FoodDef instances (Flakes, Pellets, FreezeDried, etc.), a Catalog list, and lookup helpers Find and FindExact.
namespace NoChillquarium;
/// <summary>
/// Escalating food ladder. Nothing free — buy Fish Flakes first, then weirder food.
/// </summary>
public sealed class FoodDef
{
public string Id { get; init; }
public string Name { get; init; }
/// <summary>Optional short HUD label (inventory). Falls back to <see cref="Name"/>.</summary>
public string InvName { get; init; }
public string Note { get; init; }
/// <summary>Name for inventory / compact UI.</summary>
public string DisplayInv => string.IsNullOrWhiteSpace( InvName ) ? Name : InvName;
public double UnlockCost { get; init; }
public float BoostDuration { get; init; }
public float BoostMultiplier { get; init; }
public float ChaosOnFeed { get; init; }
public int PelletCount { get; init; }
public string PelletColor { get; init; }
public float BobMulWhileBoost { get; init; }
public float SpeedMulWhileBoost { get; init; }
/// <summary>Playtime seconds required before unlock is available (0 = start).</summary>
public float UnlockPlaytime { get; init; }
public static readonly FoodDef Flakes = new()
{
Id = "flakes",
Name = "Fish Flakes",
InvName = "Fish Flakes",
Note = "starter",
UnlockCost = 10,
BoostDuration = 6f,
BoostMultiplier = 1.75f,
ChaosOnFeed = 0f,
PelletCount = 5,
PelletColor = "#e8c060",
BobMulWhileBoost = 1f,
SpeedMulWhileBoost = 1f,
UnlockPlaytime = 0f
};
public static readonly FoodDef Pellets = new()
{
Id = "pellets",
Name = "Pellets",
Note = "crunch",
UnlockCost = 20,
BoostDuration = 8f,
BoostMultiplier = 2.0f,
ChaosOnFeed = 0f,
PelletCount = 6,
PelletColor = "#d09040",
BobMulWhileBoost = 1.05f,
SpeedMulWhileBoost = 1.05f,
UnlockPlaytime = 0f
};
public static readonly FoodDef FreezeDried = new()
{
Id = "freeze_dried",
Name = "Freeze-Dried",
Note = "fancy",
UnlockCost = 45,
BoostDuration = 9f,
BoostMultiplier = 2.25f,
ChaosOnFeed = 0.5f,
PelletCount = 7,
PelletColor = "#c07050",
BobMulWhileBoost = 1.1f,
SpeedMulWhileBoost = 1.1f,
UnlockPlaytime = 20f * 60f // ~20 min
};
public static readonly FoodDef FriedChicken = new()
{
Id = "fried_chicken",
Name = "Fried Chicken",
Note = "greasy",
UnlockCost = 80,
BoostDuration = 10f,
BoostMultiplier = 2.6f,
ChaosOnFeed = 2f,
PelletCount = 5,
PelletColor = "#e8a040",
BobMulWhileBoost = 0.85f,
SpeedMulWhileBoost = 0.9f,
UnlockPlaytime = 40f * 60f // ~40 min
};
public static readonly FoodDef WeedGummies = new()
{
Id = "weed_gummies",
Name = "Weed Gummies",
InvName = "Gummies",
Note = "trippy",
UnlockCost = 110,
BoostDuration = 14f,
BoostMultiplier = 2.4f,
ChaosOnFeed = 4f,
PelletCount = 6,
PelletColor = "#50d060",
BobMulWhileBoost = 0.5f,
SpeedMulWhileBoost = 0.55f,
UnlockPlaytime = 60f * 60f // ~1h
};
public static readonly FoodDef OtherFish = new()
{
Id = "other_fish",
Name = "Other Fish",
Note = "cannibal",
UnlockCost = 160,
BoostDuration = 11f,
BoostMultiplier = 3.0f,
ChaosOnFeed = 6f,
PelletCount = 4,
PelletColor = "#e06070",
BobMulWhileBoost = 1.2f,
SpeedMulWhileBoost = 1.15f,
UnlockPlaytime = 90f * 60f // ~1h30
};
public static readonly FoodDef Hand = new()
{
Id = "hand",
Name = "Dismembered Hand",
Note = "hand",
UnlockCost = 220,
BoostDuration = 12f,
BoostMultiplier = 3.4f,
ChaosOnFeed = 10f,
PelletCount = 3,
PelletColor = "#d08070",
BobMulWhileBoost = 1.3f,
SpeedMulWhileBoost = 1.2f,
UnlockPlaytime = 2.25f * 3600f // ~2h15
};
public static readonly FoodDef HomelessMan = new()
{
Id = "homeless_man",
Name = "Homeless Man",
Note = "unhinged",
UnlockCost = 350,
BoostDuration = 14f,
BoostMultiplier = 4.0f,
ChaosOnFeed = 15f,
PelletCount = 4,
PelletColor = "#a09080",
BobMulWhileBoost = 1.4f,
SpeedMulWhileBoost = 1.25f,
UnlockPlaytime = 3f * 3600f // ~3h
};
public static IReadOnlyList<FoodDef> Catalog { get; } = new[]
{
Flakes,
Pellets,
FreezeDried,
FriedChicken,
WeedGummies,
OtherFish,
Hand,
HomelessMan
};
public static FoodDef Find( string id ) =>
Catalog.FirstOrDefault( f => f.Id == id ) ?? Flakes;
/// <summary>Lookup without flakes fallback (null if unknown / empty).</summary>
public static FoodDef FindExact( string id ) =>
string.IsNullOrWhiteSpace( id ) ? null : Catalog.FirstOrDefault( f => f.Id == id );
}