2024-09-21 12:40:13 +00:00
|
|
|
using System.Reflection.PortableExecutable;
|
2024-09-20 17:01:09 +00:00
|
|
|
using Splat;
|
2024-09-22 16:54:16 +00:00
|
|
|
using StarsAssistant.Model;
|
2024-09-20 17:01:09 +00:00
|
|
|
|
2024-09-17 18:20:42 +00:00
|
|
|
namespace StarsAssistant.Services;
|
|
|
|
|
|
|
|
public class Game
|
|
|
|
{
|
2024-09-20 17:01:09 +00:00
|
|
|
/// <summary>
|
|
|
|
/// Default constructor, initialize required fields manually, targeted
|
|
|
|
/// for Initial DB creation.
|
|
|
|
/// </summary>
|
|
|
|
public Game() {}
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// Init game state from database, targeted for CLI arg.
|
|
|
|
/// </summary>
|
|
|
|
/// <param name="dbGame">Record loaded from DB</param>
|
|
|
|
public Game(Model.Game dbGame)
|
|
|
|
{
|
|
|
|
GamePath = dbGame.GamePath;
|
|
|
|
BaseName = dbGame.BaseName;
|
|
|
|
}
|
|
|
|
|
|
|
|
/// <summary>
|
2024-09-22 16:54:16 +00:00
|
|
|
/// Helper to construct the game from a command line.
|
2024-09-20 17:01:09 +00:00
|
|
|
/// </summary>
|
2024-09-22 16:54:16 +00:00
|
|
|
/// <param name="args">The command line to parse.</param>
|
|
|
|
public Game(string[]? args)
|
2024-09-20 17:01:09 +00:00
|
|
|
{
|
2024-09-22 16:54:16 +00:00
|
|
|
GamePath = "/home/torben/Nextcloud/Documents/Stars!/Games/goingth/";
|
|
|
|
BaseName = "GOINGTH";
|
|
|
|
string dbPath = DatabaseFileName;
|
|
|
|
|
|
|
|
using StarsDatabase starsDB = new(dbPath);
|
|
|
|
if (Path.Exists(dbPath))
|
2024-09-20 17:01:09 +00:00
|
|
|
{
|
2024-09-22 16:54:16 +00:00
|
|
|
Model.Game dbGame = starsDB.Game.First();
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
starsDB.Database.EnsureCreated();
|
|
|
|
SaveToDatabase(starsDB);
|
|
|
|
__doCreateTestData = true;
|
2024-09-20 17:01:09 +00:00
|
|
|
}
|
|
|
|
}
|
2024-09-22 16:54:16 +00:00
|
|
|
|
2024-09-17 18:20:42 +00:00
|
|
|
/// <summary>
|
|
|
|
/// The base path in which all game files reside.
|
|
|
|
/// </summary>
|
2024-09-20 17:01:09 +00:00
|
|
|
public string GamePath { get; set; } = String.Empty;
|
2024-09-17 18:20:42 +00:00
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// The base name without extensions of your game, inside the GamePath folder.
|
|
|
|
/// All dependant files are resolved using this name.
|
|
|
|
/// </summary>
|
2024-09-20 17:01:09 +00:00
|
|
|
public string BaseName { get; set; } = String.Empty;
|
2024-09-17 18:20:42 +00:00
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// Combine into the DatabaseName
|
|
|
|
/// </summary>
|
|
|
|
public string DatabaseFileName => Path.Combine(GamePath, $"{BaseName}.sqlite");
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// Search for Planet files using this pattern, will give you all pxx files.
|
|
|
|
/// </summary>
|
|
|
|
public string PlanetFileSearchPattern => $"{BaseName}.p*";
|
|
|
|
|
2024-09-21 12:40:13 +00:00
|
|
|
/// <summary>
|
|
|
|
/// Internal helper to lazily load the current player from the DB.
|
|
|
|
/// </summary>
|
2024-09-22 16:54:16 +00:00
|
|
|
private readonly static Lazy<Race>LazyPlayer = new ( () => {
|
|
|
|
using var db = Locator.Current.GetService<StarsDatabase>()!;
|
|
|
|
Race result = db.Race
|
2024-09-21 12:40:13 +00:00
|
|
|
.Where(r => r.PlayerRace == true)
|
|
|
|
.First();
|
|
|
|
return result;
|
|
|
|
});
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// Get the Race object for the current player, lazy initialized.
|
|
|
|
/// </summary>
|
2024-09-22 16:54:16 +00:00
|
|
|
public static Race Player => LazyPlayer.Value;
|
2024-09-21 12:40:13 +00:00
|
|
|
|
2024-09-17 18:20:42 +00:00
|
|
|
/// <summary>
|
|
|
|
/// Get the name of a planet file for a given race.
|
|
|
|
/// </summary>
|
|
|
|
/// <param name="r">The race to load.</param>
|
|
|
|
/// <returns>Fully qualified file path.</returns>
|
2024-09-22 16:54:16 +00:00
|
|
|
public string PlanetFileForRace (Race r) => Path.Combine(GamePath, $"{BaseName}.p{r.PlayerFileId}");
|
|
|
|
|
2024-10-01 20:21:50 +00:00
|
|
|
/// <summary>
|
|
|
|
/// Get the name of a planet file for a given race.
|
|
|
|
/// </summary>
|
|
|
|
/// <param name="r">The race to load.</param>
|
|
|
|
/// <returns>Fully qualified file path.</returns>
|
|
|
|
public string FleetFileForRace (Race r) => Path.Combine(GamePath, $"{BaseName}.f{r.PlayerFileId}");
|
|
|
|
|
2024-09-22 16:54:16 +00:00
|
|
|
/// <summary>
|
|
|
|
/// 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.
|
|
|
|
/// </summary>
|
|
|
|
/// <param name="db">Optional DB instance if services are yet unavailable.</param>
|
|
|
|
public void SaveToDatabase(StarsDatabase? db = null)
|
|
|
|
{
|
|
|
|
db ??= Locator.Current.GetService<StarsDatabase>()!;
|
|
|
|
|
|
|
|
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();
|
|
|
|
}
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// 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.
|
|
|
|
/// </summary>
|
|
|
|
public void RegisterServicesForGame()
|
|
|
|
{
|
|
|
|
Locator.CurrentMutable.RegisterConstant(this, typeof(Services.Game));
|
2024-09-24 18:17:49 +00:00
|
|
|
GameEngine.Game = this;
|
2024-09-22 16:54:16 +00:00
|
|
|
Locator.CurrentMutable.RegisterConstant(new CSVDataLoader(), typeof(CSVDataLoader));
|
|
|
|
Locator.CurrentMutable.Register(() => new StarsDatabase(DatabaseFileName), typeof(StarsDatabase));
|
2024-09-26 20:18:50 +00:00
|
|
|
PlanetManager PlanetManager = new();
|
|
|
|
Locator.CurrentMutable.RegisterConstant(PlanetManager, typeof(Services.PlanetManager));
|
2024-09-22 16:54:16 +00:00
|
|
|
|
|
|
|
// TESTING HELPER
|
|
|
|
if (__doCreateTestData)
|
|
|
|
__createTestData();
|
2024-09-26 20:18:50 +00:00
|
|
|
|
|
|
|
PlanetManager.InitFromDatabase();
|
2024-09-22 16:54:16 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// Starts all required background servies, so that we are in normal UI
|
|
|
|
/// operation mode. This is called after the UI is up and running.
|
|
|
|
/// </summary>
|
|
|
|
public void StartBackgroundServices()
|
|
|
|
{
|
|
|
|
CSVDataLoader csvloader = Locator.Current.GetService<Services.CSVDataLoader>()!;
|
|
|
|
csvloader.StartCSVWatcher();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private bool __doCreateTestData = false;
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// TESTING HELPER
|
|
|
|
/// </summary>
|
|
|
|
private void __createTestData ()
|
|
|
|
{
|
|
|
|
using var db = Locator.Current.GetService<StarsDatabase>()!;
|
|
|
|
|
|
|
|
// 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,
|
2024-09-26 20:18:50 +00:00
|
|
|
FactoryNumberPer10k = 9,
|
|
|
|
FactoryResCost = 9,
|
2024-09-22 16:54:16 +00:00
|
|
|
FactoryResPer10 = 15,
|
|
|
|
MineResCost = 3,
|
|
|
|
MineMineralsPer10 = 10,
|
|
|
|
MineNumberPer10k = 10
|
|
|
|
};
|
|
|
|
db.Add(r);
|
|
|
|
db.SaveChanges();
|
|
|
|
|
2024-10-01 20:21:50 +00:00
|
|
|
var planetLoader = new CSV.PlanetLoader();
|
|
|
|
planetLoader.ImportForRace(Services.Game.Player);
|
|
|
|
|
|
|
|
var fleetLoader = new CSV.FleetLoader();
|
|
|
|
fleetLoader.ImportForRace(Services.Game.Player);
|
|
|
|
|
2024-09-22 16:54:16 +00:00
|
|
|
}
|
2024-09-17 18:20:42 +00:00
|
|
|
|
|
|
|
}
|