using System.Reflection.PortableExecutable;
using Splat;
using StarsAssistant.Model;
namespace StarsAssistant.Services;
public class Game
{
///
/// Default constructor, initialize required fields manually, targeted
/// for Initial DB creation.
///
public Game() {}
///
/// Init game state from database, targeted for CLI arg.
///
/// Record loaded from DB
public Game(Model.Game dbGame)
{
GamePath = dbGame.GamePath;
BaseName = dbGame.BaseName;
}
///
/// Helper to construct the game from a command line.
///
/// The command line to parse.
public Game(string[]? args)
{
GamePath = "/home/torben/Nextcloud/Documents/Stars!/Games/goingth/";
BaseName = "GOINGTH";
string dbPath = DatabaseFileName;
using StarsDatabase starsDB = new(dbPath);
if (Path.Exists(dbPath))
{
Model.Game dbGame = starsDB.Game.First();
}
else
{
starsDB.Database.EnsureCreated();
SaveToDatabase(starsDB);
__doCreateTestData = true;
}
}
///
/// The base path in which all game files reside.
///
public string GamePath { get; set; } = String.Empty;
///
/// The base name without extensions of your game, inside the GamePath folder.
/// All dependant files are resolved using this name.
///
public string BaseName { get; set; } = String.Empty;
///
/// Combine into the DatabaseName
///
public string DatabaseFileName => Path.Combine(GamePath, $"{BaseName}.sqlite");
///
/// Search for Planet files using this pattern, will give you all pxx files.
///
public string PlanetFileSearchPattern => $"{BaseName}.p*";
///
/// Search for Planet files using this pattern, will give you all pxx files.
///
public string FleetFileSearchPattern => $"{BaseName}.f*";
///
/// Internal helper to lazily load the current player from the DB.
///
private readonly static LazyLazyPlayer = new ( () => {
using var db = Locator.Current.GetService()!;
Race result = db.Race
.Where(r => r.PlayerRace == true)
.First();
return result;
});
///
/// Get the Race object for the current player, lazy initialized.
///
public static Race Player => LazyPlayer.Value;
///
/// Get the name of a planet file for a given race.
///
/// The race to load.
/// Fully qualified file path.
public string PlanetFileForRace (Race r) => Path.Combine(GamePath, $"{BaseName}.p{r.PlayerFileId}");
///
/// Get the name of a planet file for a given race.
///
/// The race to load.
/// Fully qualified file path.
public string FleetFileForRace (Race r) => Path.Combine(GamePath, $"{BaseName}.f{r.PlayerFileId}");
///
/// Save this record in the database. Uses the service locator to access the
/// database unless you specify an instance. This is needed during initial
/// game creation, where the services are not yet established.
///
/// Optional DB instance if services are yet unavailable.
public void SaveToDatabase(StarsDatabase? db = null)
{
db ??= Locator.Current.GetService()!;
Model.Game? dbGame = db.Game.FirstOrDefault();
if (dbGame == null)
{
dbGame = new Model.Game();
db.Add(dbGame);
db.SaveChanges();
}
dbGame.GamePath = GamePath;
dbGame.BaseName = BaseName;
db.Update(dbGame);
db.SaveChanges();
}
///
/// Registers all services depending on this Game, in the order required.
/// This is called once the framework is initialized but before the main
/// window is active and has its models.
///
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));
PlanetManager PlanetManager = new();
Locator.CurrentMutable.RegisterConstant(PlanetManager, typeof(Services.PlanetManager));
FleetManager FleetManager = new();
Locator.CurrentMutable.RegisterConstant(FleetManager, typeof(Services.FleetManager));
// TESTING HELPER
if (__doCreateTestData)
__createTestData();
PlanetManager.InitFromDatabase();
}
///
/// Starts all required background servies, so that we are in normal UI
/// operation mode. This is called after the UI is up and running.
///
public void StartBackgroundServices()
{
CSVDataLoader csvloader = Locator.Current.GetService()!;
csvloader.StartCSVWatcher();
}
private bool __doCreateTestData = false;
///
/// TESTING HELPER
///
private void __createTestData ()
{
using var db = Locator.Current.GetService()!;
// Note: This sample requires the database to be created before running.
// Console.WriteLine($"Database path: {db.DbPath}.");
Race r = new()
{
Name = "Atlantis",
PlayerRace = true,
PlayerFileId = 1,
ColonistsPerResource = 1000,
GrowthRatePercent = 19,
PRT = PRT.Other,
HasOBRM = true,
FactoryCost3 = false,
FactoryNumberPer10k = 9,
FactoryResCost = 9,
FactoryResPer10 = 15,
MineResCost = 3,
MineMineralsPer10 = 10,
MineNumberPer10k = 10
};
db.Add(r);
db.SaveChanges();
var planetLoader = new CSV.PlanetLoader();
planetLoader.ImportForRace(Services.Game.Player);
var fleetLoader = new CSV.FleetLoader();
fleetLoader.ImportForRace(Services.Game.Player);
}
}