using System.ComponentModel.DataAnnotations; using System.Globalization; namespace StarsAssistant.Model; public class Planet { #region Persistant and derived propeties public const int MinEffectiveValue = 5; [Key] public required string Name { get; set; } public string? OwnerId { get; set; } public string? StarbaseType { get; set; } public int ReportAge { get; set; } = 0; public int? Population { get; set; } public int? Value { get; set; } public int? Mines { get; set; } public int? Factories { get; set; } public decimal? DefPercent { get; set; } public int? SurfaceIronium { get; set; } public int? SurfaceBoranium { get; set; } public int? SurfaceGermanium { get; set; } public int? MRIronium { get; set; } public int? MRBoranium { get; set; } public int? MRGermanium { get; set; } public int? MCIronium { get; set; } public int? MCBoranium { get; set; } public int? MCGermanium { get; set; } public int? Resources { get; set; } public decimal? Gravity { get; set; } public decimal? Temperature { get; set; } public decimal? Radiation { get; set; } public decimal? GravityOrig { get; set; } public decimal? TemperatureOrig { get; set; } public decimal? RadiationOrig { get; set; } public int? MaxTerraforming { get; set; } public int? CapacityPercent { get; set; } public int? ScanRange { get; set; } public int? PenScanRange { get; set; } public int? Driver { get; set; } public int? DriverWarp { get; set; } public string? RouteTarget { get; set; } public int? GateRange { get; set; } public int? GateMass { get; set; } public int? PctDamage { get; set; } #endregion #region Relationships public Race? Owner { get; set; } #endregion #region Derived Properties public static int EffectiveValue(int? value) { if (value == null) return 0; if (value < MinEffectiveValue) return MinEffectiveValue; return (int) value; } public int EffectiveValue() => EffectiveValue(Value); public static int MaxPopOnPlanet (int? value) { return Race.Player.MaxPopOnPlanet * EffectiveValue(value) / 100; } public int MaxPopOnPlanet() => MaxPopOnPlanet(Value); public int PopGrowth(int currentPop, int maxPop, int value) { // What to do with non player races? if (OwnerId != Race.Player.Name) return 0; double popRatio = currentPop / maxPop; int growth = 0; if (value < 0) growth = currentPop * value / 10; else if (popRatio <= 0.25) growth = currentPop * value * (Race.Player.GrowthRatePercent ?? 0) / 100; else if (popRatio <= 1) growth = currentPop * value * (Race.Player.GrowthRatePercent ?? 0) /100 * 16 / 9 * ((int) Math.Pow(1 - popRatio, 2)); else growth = (int) (currentPop * (popRatio - 1) * 0.04); return growth / 100 * 100; } public int PopGrowth() => PopGrowth(Population ?? 0, MaxPopOnPlanet(), Value ?? 0); public int MaxFact(int currentPop) { int effectivePop = Math.Min(currentPop, MaxPopOnPlanet()); double tmp = (double) effectivePop / 10000 * Race.Player.FactoryNumberPer10k ?? 0; return (int) tmp; } public int MaxFact() => MaxFact(Population ?? 0); public int MaxMines(int currentPop) { int effectivePop = Math.Min(currentPop, MaxPopOnPlanet()); double tmp = (double) effectivePop / 10000 * Race.Player.MineNumberPer10k ?? 0; return (int) tmp; } public int MaxMines() => MaxMines(Population ?? 0); public static int ResourcesFromPop(int currentPop, int value) { if (Race.Player.ColonistsPerResource == null || Race.Player.ColonistsPerResource == 0) { return 0; } int maxPop = MaxPopOnPlanet(value); int popFullEfficiency = 0; int popHalfEfficiency = 0; if (currentPop <= maxPop) { popFullEfficiency = currentPop; } else if (currentPop <= 3 * maxPop) { popFullEfficiency = maxPop; popHalfEfficiency = currentPop - maxPop; } else { popFullEfficiency = maxPop; popHalfEfficiency = 2 * maxPop; } int popEffective = popFullEfficiency + (popHalfEfficiency / 2); return (popEffective / Race.Player.ColonistsPerResource) ?? 0; } public int ResourcesFromPop() => ResourcesFromPop(Population ?? 0, Value ?? 0); public static int ResourcesFromFact(int currentPop, int factories, int value) { int maxPop = MaxPopOnPlanet(value); int effectivePop = Math.Min(currentPop, maxPop); double tmp = (double) effectivePop / 10000 * Race.Player.FactoryNumberPer10k ?? 0; int maxOperableFactories = (int) tmp; int operableFactories = Math.Min(factories, maxOperableFactories); tmp = (double) operableFactories / 10 * Race.Player.FactoryResPer10 ?? 0; return (int) tmp; } public int ResourcesFromFact() => ResourcesFromFact(Population ?? 0, Factories ?? 0, Value ?? 0); #endregion }