Create Game Engine, update race model with defaults.
This commit is contained in:
@ -120,6 +120,7 @@ public class Game
|
||||
public void RegisterServicesForGame()
|
||||
{
|
||||
Locator.CurrentMutable.RegisterConstant(this, typeof(Services.Game));
|
||||
GameEngine.Game = this;
|
||||
Locator.CurrentMutable.RegisterConstant(new CSVDataLoader(), typeof(CSVDataLoader));
|
||||
Locator.CurrentMutable.Register(() => new StarsDatabase(DatabaseFileName), typeof(StarsDatabase));
|
||||
|
||||
|
@ -1,8 +1,162 @@
|
||||
using System;
|
||||
using Splat;
|
||||
|
||||
namespace StarsAssistant.Services;
|
||||
|
||||
public class GameEngine
|
||||
{
|
||||
/// <summary>
|
||||
/// Helper reference to the Game, populated during service registration for the
|
||||
/// loaded game.
|
||||
/// </summary>
|
||||
// TODO: check for better options here.
|
||||
public static Game Game { get; set; } = null!;
|
||||
|
||||
/// <summary>
|
||||
/// Minimum effective value of a planet for purposes of maximum population etc.
|
||||
/// </summary>
|
||||
public const int MinEffectiveValue = 5;
|
||||
|
||||
/// <summary>
|
||||
/// Normalize a planet value for minimum effetive value.
|
||||
/// </summary>
|
||||
/// <param name="value">Real planet value</param>
|
||||
/// <returns>Effective plante value</returns>
|
||||
public static int EffectivePlanetValue(int value) => (value < MinEffectiveValue) ? MinEffectiveValue : value;
|
||||
|
||||
/// <summary>
|
||||
/// Compute the maximum regular (non-overcrowded) population on a planet for the active player.
|
||||
/// </summary>
|
||||
/// <param name="value">Real planet value</param>
|
||||
/// <returns>effective maximum population</returns>
|
||||
public static int MaxPopOnPlanetForPlayer(int value) => Game.Player.MaxPopOnPlanet * EffectivePlanetValue(value) / 100;
|
||||
|
||||
/// <summary>
|
||||
/// Compute population growth for player planets.
|
||||
/// </summary>
|
||||
/// <param name="currentPop">Current population on planet</param>
|
||||
/// <param name="value">Real planet value</param>
|
||||
/// <returns>population growth per turn</returns>
|
||||
public static int PlanetPopGrowthForPlayer(int currentPop, int value)
|
||||
{
|
||||
int maxPop = MaxPopOnPlanetForPlayer(value);
|
||||
int growth;
|
||||
|
||||
if (value < 0)
|
||||
{
|
||||
growth = currentPop * value / 10;
|
||||
}
|
||||
else
|
||||
{
|
||||
double popRatio = currentPop / maxPop;
|
||||
if (popRatio <= 0.25)
|
||||
growth = currentPop * value * Game.Player.GrowthRatePercent / 100;
|
||||
else if (popRatio <= 1)
|
||||
growth = currentPop * value * Game.Player.GrowthRatePercent /100 * 16 / 9 * ((int) Math.Pow(1 - popRatio, 2));
|
||||
else
|
||||
growth = (int) (currentPop * (popRatio - 1) * 0.04);
|
||||
}
|
||||
|
||||
// round to nearest 100
|
||||
return growth / 100 * 100;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the maximum operable factories on a given player planet for a given value.
|
||||
/// </summary>
|
||||
/// <param name="currentPop">Population on planet</param>
|
||||
/// <param name="value">Real planet value</param>
|
||||
/// <returns>Maximum operable factories for currentPop</returns>
|
||||
public static int MaxOperableFactoriesForPlayer(int currentPop, int value)
|
||||
{
|
||||
int effectivePop = Math.Min(currentPop, MaxPopOnPlanetForPlayer(value));
|
||||
double tmp = (double) effectivePop / 10000 * Game.Player.FactoryNumberPer10k;
|
||||
return (int) tmp;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Maximum buildable factories on a player planet with a given value.
|
||||
/// </summary>
|
||||
/// <param name="value">Real Planet Value</param>
|
||||
/// <returns>Maximum buildable factories</returns>
|
||||
public static int MaxBuildableFactoriesForPlayer(int value)
|
||||
{
|
||||
double tmp = (double) MaxPopOnPlanetForPlayer(value) / 10000 * Game.Player.FactoryNumberPer10k;
|
||||
return (int) tmp;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the maximum operable mines on a given player planet for a given value.
|
||||
/// </summary>
|
||||
/// <param name="currentPop">Population on planet</param>
|
||||
/// <param name="value">Real planet value</param>
|
||||
/// <returns>Maximum operable mines for currentPop</returns>
|
||||
public static int MaxOperableMinesForPlayer(int currentPop, int value)
|
||||
{
|
||||
int effectivePop = Math.Min(currentPop, MaxPopOnPlanetForPlayer(value));
|
||||
double tmp = (double) effectivePop / 10000 * Game.Player.MineNumberPer10k;
|
||||
return (int) tmp;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Maximum buildable factories on a player planet with a given value.
|
||||
/// </summary>
|
||||
/// <param name="value">Real Planet Value</param>
|
||||
/// <returns>Maximum buildable factories</returns>
|
||||
public static int MaxBuildableMinesForPlayer(int value)
|
||||
{
|
||||
double tmp = (double) MaxPopOnPlanetForPlayer(value) / 10000 * Game.Player.MineNumberPer10k;
|
||||
return (int) tmp;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Ressources produced by population on a player planet with a given value. Takes
|
||||
/// less effective overcrowding pop into account.
|
||||
/// </summary>
|
||||
/// <param name="currentPop">Current planetary population</param>
|
||||
/// <param name="value">Real planet value</param>
|
||||
/// <returns>Resources generated by populationa</returns>
|
||||
public static int ResourcesFromPopForPlayer(int currentPop, int value)
|
||||
{
|
||||
if (Game.Player.ColonistsPerResource == 0)
|
||||
return 0;
|
||||
|
||||
int maxPop = MaxPopOnPlanetForPlayer(value);
|
||||
int popFullEfficiency;
|
||||
int popHalfEfficiency;
|
||||
if (currentPop <= maxPop) {
|
||||
popHalfEfficiency = 0;
|
||||
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 / Services.Game.Player.ColonistsPerResource;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Ressources generated by factories on a player planet for a given value an
|
||||
/// population. Takes maximum operable factories into account.
|
||||
/// </summary>
|
||||
/// <param name="currentPop">Current planetary population</param>
|
||||
/// <param name="factories">Number of factories built</param>
|
||||
/// <param name="value">Real planet value</param>
|
||||
/// <returns>Resources generated by factories</returns>
|
||||
public static int ResourcesFromFactForPlayer(int currentPop, int factories, int value)
|
||||
{
|
||||
int maxPop = MaxPopOnPlanetForPlayer(value);
|
||||
int effectivePop = Math.Min(currentPop, maxPop);
|
||||
double tmp = (double) effectivePop / 10000 * Game.Player.FactoryNumberPer10k;
|
||||
int maxOperableFactories = (int) tmp;
|
||||
int operableFactories = Math.Min(factories, maxOperableFactories);
|
||||
tmp = (double) operableFactories / 10 * Services.Game.Player.FactoryResPer10;
|
||||
return (int) tmp;
|
||||
}
|
||||
|
||||
}
|
||||
|
Reference in New Issue
Block a user