adding timer cfgs
This commit is contained in:
@@ -31,6 +31,9 @@ var training_bar: ProgressBar
|
|||||||
var training_started_unix := 0.0
|
var training_started_unix := 0.0
|
||||||
var training_completes_unix := 0.0
|
var training_completes_unix := 0.0
|
||||||
var training_completion_refresh_requested := false
|
var training_completion_refresh_requested := false
|
||||||
|
var building_started_unix := 0.0
|
||||||
|
var building_completes_unix := 0.0
|
||||||
|
var building_completion_refresh_requested := false
|
||||||
var claim_button: Button
|
var claim_button: Button
|
||||||
var build_log_camp_button: Button
|
var build_log_camp_button: Button
|
||||||
var selected_q := 0
|
var selected_q := 0
|
||||||
@@ -48,6 +51,7 @@ func _ready() -> void:
|
|||||||
func _process(_delta: float) -> void:
|
func _process(_delta: float) -> void:
|
||||||
_update_tick_bar()
|
_update_tick_bar()
|
||||||
_update_training_bar()
|
_update_training_bar()
|
||||||
|
_update_building_timer()
|
||||||
|
|
||||||
|
|
||||||
func _unhandled_input(event: InputEvent) -> void:
|
func _unhandled_input(event: InputEvent) -> void:
|
||||||
@@ -634,7 +638,13 @@ func _on_build_request_completed(result: int, response_code: int, _headers: Pack
|
|||||||
|
|
||||||
selected_can_build_log_camp = false
|
selected_can_build_log_camp = false
|
||||||
build_log_camp_button.disabled = true
|
build_log_camp_button.disabled = true
|
||||||
coordinate_label.text = "Log Camp built. Wood production increased."
|
var parsed = JSON.parse_string(text)
|
||||||
|
if typeof(parsed) == TYPE_DICTIONARY:
|
||||||
|
var location: Dictionary = parsed
|
||||||
|
building_started_unix = _parse_utc_timestamp(str(location.get("buildingStartedAtUtc", "")))
|
||||||
|
building_completes_unix = _parse_utc_timestamp(str(location.get("buildingCompletesAtUtc", "")))
|
||||||
|
building_completion_refresh_requested = false
|
||||||
|
coordinate_label.text = "Log Camp construction started. Completion takes 1 minute."
|
||||||
_load_visible_locations()
|
_load_visible_locations()
|
||||||
_refresh_player_state()
|
_refresh_player_state()
|
||||||
|
|
||||||
@@ -682,6 +692,20 @@ func _update_training_bar() -> void:
|
|||||||
training_label.text = "Training: %ds" % remaining
|
training_label.text = "Training: %ds" % remaining
|
||||||
|
|
||||||
|
|
||||||
|
func _update_building_timer() -> void:
|
||||||
|
if building_started_unix <= 0.0 or building_completes_unix <= 0.0:
|
||||||
|
return
|
||||||
|
|
||||||
|
var remaining: int = int(max(0, int(ceil(building_completes_unix - Time.get_unix_time_from_system()))))
|
||||||
|
if remaining > 0:
|
||||||
|
return
|
||||||
|
|
||||||
|
if not building_completion_refresh_requested:
|
||||||
|
building_completion_refresh_requested = true
|
||||||
|
_load_visible_locations()
|
||||||
|
_refresh_player_state()
|
||||||
|
|
||||||
|
|
||||||
func _parse_utc_timestamp(timestamp: String) -> float:
|
func _parse_utc_timestamp(timestamp: String) -> float:
|
||||||
if timestamp.is_empty():
|
if timestamp.is_empty():
|
||||||
return 0.0
|
return 0.0
|
||||||
|
|||||||
@@ -162,8 +162,11 @@ func _draw_tile(tile: Dictionary) -> void:
|
|||||||
|
|
||||||
var visible_location: Dictionary = visible_tiles.get(key, {})
|
var visible_location: Dictionary = visible_tiles.get(key, {})
|
||||||
var building_type: String = str(visible_location.get("buildingType", ""))
|
var building_type: String = str(visible_location.get("buildingType", ""))
|
||||||
if building_type == "LogCamp":
|
var building_status: String = str(visible_location.get("buildingStatus", ""))
|
||||||
|
if building_type == "LogCamp" and (building_status == "Built" or building_status.is_empty()):
|
||||||
_draw_log_camp_marker(center, height)
|
_draw_log_camp_marker(center, height)
|
||||||
|
elif building_type == "LogCamp":
|
||||||
|
_draw_building_marker(center, height)
|
||||||
|
|
||||||
|
|
||||||
func _draw_control_regions(sorted_tiles: Array) -> void:
|
func _draw_control_regions(sorted_tiles: Array) -> void:
|
||||||
@@ -298,6 +301,13 @@ func _draw_log_camp_marker(center: Vector2, height: float) -> void:
|
|||||||
draw_line(marker_center + Vector2(-width * 0.38, marker_height * 0.86), marker_center + Vector2(width * 0.38, marker_height * 0.86), log_color.darkened(0.12), 3.0 * zoom)
|
draw_line(marker_center + Vector2(-width * 0.38, marker_height * 0.86), marker_center + Vector2(width * 0.38, marker_height * 0.86), log_color.darkened(0.12), 3.0 * zoom)
|
||||||
|
|
||||||
|
|
||||||
|
func _draw_building_marker(center: Vector2, height: float) -> void:
|
||||||
|
var marker_center: Vector2 = center + Vector2(0, -height * zoom - 1.0)
|
||||||
|
var radius: float = 7.0 * zoom
|
||||||
|
draw_arc(marker_center, radius, 0.0, TAU, 24, Color(0.95, 0.76, 0.28), 2.0 * zoom)
|
||||||
|
draw_line(marker_center + Vector2(-radius * 0.7, radius * 0.7), marker_center + Vector2(radius * 0.7, -radius * 0.7), Color(0.95, 0.76, 0.28), 2.0 * zoom)
|
||||||
|
|
||||||
|
|
||||||
func _tile_data(q: int, r: int) -> Dictionary:
|
func _tile_data(q: int, r: int) -> Dictionary:
|
||||||
for tile in tiles:
|
for tile in tiles:
|
||||||
if int(tile["q"]) == q and int(tile["r"]) == r:
|
if int(tile["q"]) == q and int(tile["r"]) == r:
|
||||||
@@ -389,9 +399,10 @@ func _neighbor_coordinates(q: int, r: int) -> Array[Vector2i]:
|
|||||||
func _tile_display_label(key: String, data: Dictionary) -> String:
|
func _tile_display_label(key: String, data: Dictionary) -> String:
|
||||||
var terrain: String = str(data.get("terrain", "Open"))
|
var terrain: String = str(data.get("terrain", "Open"))
|
||||||
var building_type: String = str(data.get("buildingType", ""))
|
var building_type: String = str(data.get("buildingType", ""))
|
||||||
|
var building_status: String = str(data.get("buildingStatus", ""))
|
||||||
var building_label: String = ""
|
var building_label: String = ""
|
||||||
if building_type == "LogCamp":
|
if building_type == "LogCamp":
|
||||||
building_label = " | Log Camp"
|
building_label = " | Log Camp" if building_status == "Built" or building_status.is_empty() else " | Log Camp building"
|
||||||
|
|
||||||
if home_tile == Vector2i(int(data.get("q", 0)), int(data.get("r", 0))):
|
if home_tile == Vector2i(int(data.get("q", 0)), int(data.get("r", 0))):
|
||||||
return "%s | Your home%s" % [terrain, building_label]
|
return "%s | Your home%s" % [terrain, building_label]
|
||||||
@@ -444,7 +455,7 @@ func _terrain_color_for_name(terrain: String, _q: int, _r: int, _height: float)
|
|||||||
"Command":
|
"Command":
|
||||||
return Color(0.68, 0.58, 0.28)
|
return Color(0.68, 0.58, 0.28)
|
||||||
"Forest":
|
"Forest":
|
||||||
return Color(0.24, 0.45, 0.29)
|
return Color(0.12, 0.31, 0.18)
|
||||||
"Ore":
|
"Ore":
|
||||||
return Color(0.42, 0.46, 0.5)
|
return Color(0.42, 0.46, 0.5)
|
||||||
"Highland":
|
"Highland":
|
||||||
|
|||||||
@@ -33,6 +33,9 @@ public class LocationResponse
|
|||||||
public string? Label { get; set; }
|
public string? Label { get; set; }
|
||||||
public int Level { get; set; }
|
public int Level { get; set; }
|
||||||
public string? BuildingType { get; set; }
|
public string? BuildingType { get; set; }
|
||||||
|
public string? BuildingStatus { get; set; }
|
||||||
|
public DateTime? BuildingStartedAtUtc { get; set; }
|
||||||
|
public DateTime? BuildingCompletesAtUtc { get; set; }
|
||||||
public DateTime? BuildingBuiltAtUtc { get; set; }
|
public DateTime? BuildingBuiltAtUtc { get; set; }
|
||||||
public DateTime? HomeAssignedAtUtc { get; set; }
|
public DateTime? HomeAssignedAtUtc { get; set; }
|
||||||
public DateTime UpdatedAtUtc { get; set; }
|
public DateTime UpdatedAtUtc { get; set; }
|
||||||
@@ -49,6 +52,11 @@ public class LocationResponse
|
|||||||
Label = location.Label,
|
Label = location.Label,
|
||||||
Level = location.Level,
|
Level = location.Level,
|
||||||
BuildingType = location.BuildingType,
|
BuildingType = location.BuildingType,
|
||||||
|
BuildingStatus = location.BuildingType == "LogCamp" && string.IsNullOrWhiteSpace(location.BuildingStatus)
|
||||||
|
? "Built"
|
||||||
|
: location.BuildingStatus,
|
||||||
|
BuildingStartedAtUtc = location.BuildingStartedAtUtc,
|
||||||
|
BuildingCompletesAtUtc = location.BuildingCompletesAtUtc,
|
||||||
BuildingBuiltAtUtc = location.BuildingBuiltAtUtc,
|
BuildingBuiltAtUtc = location.BuildingBuiltAtUtc,
|
||||||
HomeAssignedAtUtc = location.HomeAssignedAtUtc,
|
HomeAssignedAtUtc = location.HomeAssignedAtUtc,
|
||||||
UpdatedAtUtc = location.UpdatedAtUtc,
|
UpdatedAtUtc = location.UpdatedAtUtc,
|
||||||
|
|||||||
@@ -0,0 +1,16 @@
|
|||||||
|
using MongoDB.Bson;
|
||||||
|
using MongoDB.Bson.Serialization.Attributes;
|
||||||
|
|
||||||
|
namespace LocationsApi.Models;
|
||||||
|
|
||||||
|
public class GameSetting
|
||||||
|
{
|
||||||
|
[BsonId]
|
||||||
|
[BsonRepresentation(BsonType.ObjectId)]
|
||||||
|
public string Id { get; set; } = "";
|
||||||
|
|
||||||
|
public string Key { get; set; } = "";
|
||||||
|
public int IntValue { get; set; }
|
||||||
|
public DateTime CreatedAtUtc { get; set; } = DateTime.UtcNow;
|
||||||
|
public DateTime UpdatedAtUtc { get; set; } = DateTime.UtcNow;
|
||||||
|
}
|
||||||
@@ -17,6 +17,9 @@ public class Location
|
|||||||
public string? Label { get; set; }
|
public string? Label { get; set; }
|
||||||
public int Level { get; set; } = 1;
|
public int Level { get; set; } = 1;
|
||||||
public string? BuildingType { get; set; }
|
public string? BuildingType { get; set; }
|
||||||
|
public string? BuildingStatus { get; set; }
|
||||||
|
public DateTime? BuildingStartedAtUtc { get; set; }
|
||||||
|
public DateTime? BuildingCompletesAtUtc { get; set; }
|
||||||
public DateTime? BuildingBuiltAtUtc { get; set; }
|
public DateTime? BuildingBuiltAtUtc { get; set; }
|
||||||
public DateTime? HomeAssignedAtUtc { get; set; }
|
public DateTime? HomeAssignedAtUtc { get; set; }
|
||||||
public DateTime CreatedAtUtc { get; set; } = DateTime.UtcNow;
|
public DateTime CreatedAtUtc { get; set; } = DateTime.UtcNow;
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ builder.Services.AddControllers();
|
|||||||
builder.Services.AddSingleton<LocationService>();
|
builder.Services.AddSingleton<LocationService>();
|
||||||
builder.Services.AddSingleton<ResourceService>();
|
builder.Services.AddSingleton<ResourceService>();
|
||||||
builder.Services.AddSingleton<UnitTrainingService>();
|
builder.Services.AddSingleton<UnitTrainingService>();
|
||||||
|
builder.Services.AddSingleton<GameSettingsService>();
|
||||||
builder.Services.AddEndpointsApiExplorer();
|
builder.Services.AddEndpointsApiExplorer();
|
||||||
builder.Services.AddSwaggerGen(c =>
|
builder.Services.AddSwaggerGen(c =>
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -41,5 +41,12 @@ unclaimed visible location consumes one completed Scout.
|
|||||||
## Buildings
|
## Buildings
|
||||||
|
|
||||||
Buildings are stored on location records. The first building type is `LogCamp`,
|
Buildings are stored on location records. The first building type is `LogCamp`,
|
||||||
which can be built on controlled Forest territory and adds 5 wood per minute to
|
which can be built on controlled Forest territory, takes 60 seconds to build,
|
||||||
the owning player's resource generation.
|
and adds 5 wood per minute to the owning player's resource generation after it
|
||||||
|
finishes.
|
||||||
|
|
||||||
|
Timer settings are stored in the MongoDB `GameSettings` collection and are
|
||||||
|
seeded on first read:
|
||||||
|
|
||||||
|
- `ScoutTrainingSeconds`
|
||||||
|
- `LogCampBuildSeconds`
|
||||||
|
|||||||
@@ -0,0 +1,44 @@
|
|||||||
|
using LocationsApi.Models;
|
||||||
|
using MongoDB.Driver;
|
||||||
|
|
||||||
|
namespace LocationsApi.Services;
|
||||||
|
|
||||||
|
public class GameSettingsService
|
||||||
|
{
|
||||||
|
public const string ScoutTrainingSeconds = "ScoutTrainingSeconds";
|
||||||
|
public const string LogCampBuildSeconds = "LogCampBuildSeconds";
|
||||||
|
|
||||||
|
private readonly IMongoCollection<GameSetting> _settings;
|
||||||
|
|
||||||
|
public GameSettingsService(IConfiguration cfg)
|
||||||
|
{
|
||||||
|
var connectionString = cfg["MongoDB:ConnectionString"] ?? "mongodb://127.0.0.1:27017";
|
||||||
|
var databaseName = cfg["MongoDB:DatabaseName"] ?? "territory-autobattler";
|
||||||
|
var client = new MongoClient(connectionString);
|
||||||
|
var database = client.GetDatabase(databaseName);
|
||||||
|
_settings = database.GetCollection<GameSetting>("GameSettings");
|
||||||
|
|
||||||
|
_settings.Indexes.CreateOne(new CreateIndexModel<GameSetting>(
|
||||||
|
Builders<GameSetting>.IndexKeys.Ascending(x => x.Key),
|
||||||
|
new CreateIndexOptions { Unique = true }));
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<int> GetIntAsync(string key, int defaultValue)
|
||||||
|
{
|
||||||
|
var now = DateTime.UtcNow;
|
||||||
|
var setting = await _settings.FindOneAndUpdateAsync(
|
||||||
|
x => x.Key == key,
|
||||||
|
Builders<GameSetting>.Update
|
||||||
|
.SetOnInsert(x => x.Key, key)
|
||||||
|
.SetOnInsert(x => x.IntValue, defaultValue)
|
||||||
|
.SetOnInsert(x => x.CreatedAtUtc, now)
|
||||||
|
.Set(x => x.UpdatedAtUtc, now),
|
||||||
|
new FindOneAndUpdateOptions<GameSetting>
|
||||||
|
{
|
||||||
|
IsUpsert = true,
|
||||||
|
ReturnDocument = ReturnDocument.After
|
||||||
|
});
|
||||||
|
|
||||||
|
return Math.Max(1, setting.IntValue);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -7,12 +7,14 @@ public class LocationService
|
|||||||
{
|
{
|
||||||
private readonly IMongoCollection<Location> _locations;
|
private readonly IMongoCollection<Location> _locations;
|
||||||
private readonly ResourceService _resources;
|
private readonly ResourceService _resources;
|
||||||
|
private readonly GameSettingsService _settings;
|
||||||
private readonly int _homeMinDistance;
|
private readonly int _homeMinDistance;
|
||||||
private readonly int _homeSearchRadius;
|
private readonly int _homeSearchRadius;
|
||||||
private readonly int _visibilityDepth;
|
private readonly int _visibilityDepth;
|
||||||
private readonly int _logCampWoodPerMinute;
|
private readonly int _logCampWoodPerMinute;
|
||||||
|
private readonly int _defaultLogCampBuildSeconds;
|
||||||
|
|
||||||
public LocationService(IConfiguration cfg, ResourceService resources)
|
public LocationService(IConfiguration cfg, ResourceService resources, GameSettingsService settings)
|
||||||
{
|
{
|
||||||
var connectionString = cfg["MongoDB:ConnectionString"] ?? "mongodb://127.0.0.1:27017";
|
var connectionString = cfg["MongoDB:ConnectionString"] ?? "mongodb://127.0.0.1:27017";
|
||||||
var databaseName = cfg["MongoDB:DatabaseName"] ?? "territory-autobattler";
|
var databaseName = cfg["MongoDB:DatabaseName"] ?? "territory-autobattler";
|
||||||
@@ -20,12 +22,16 @@ public class LocationService
|
|||||||
var database = client.GetDatabase(databaseName);
|
var database = client.GetDatabase(databaseName);
|
||||||
_locations = database.GetCollection<Location>("Locations");
|
_locations = database.GetCollection<Location>("Locations");
|
||||||
_resources = resources;
|
_resources = resources;
|
||||||
|
_settings = settings;
|
||||||
_homeMinDistance = int.TryParse(cfg["World:HomeMinDistance"], out var minDistance) ? Math.Max(1, minDistance) : 8;
|
_homeMinDistance = int.TryParse(cfg["World:HomeMinDistance"], out var minDistance) ? Math.Max(1, minDistance) : 8;
|
||||||
_homeSearchRadius = int.TryParse(cfg["World:HomeSearchRadius"], out var searchRadius) ? Math.Max(_homeMinDistance, searchRadius) : 80;
|
_homeSearchRadius = int.TryParse(cfg["World:HomeSearchRadius"], out var searchRadius) ? Math.Max(_homeMinDistance, searchRadius) : 80;
|
||||||
_visibilityDepth = int.TryParse(cfg["World:VisibilityDepth"], out var visibilityDepth) ? Math.Max(0, visibilityDepth) : 3;
|
_visibilityDepth = int.TryParse(cfg["World:VisibilityDepth"], out var visibilityDepth) ? Math.Max(0, visibilityDepth) : 3;
|
||||||
_logCampWoodPerMinute = int.TryParse(cfg["Buildings:LogCampWoodPerMinute"], out var logCampWoodPerMinute)
|
_logCampWoodPerMinute = int.TryParse(cfg["Buildings:LogCampWoodPerMinute"], out var logCampWoodPerMinute)
|
||||||
? Math.Max(1, logCampWoodPerMinute)
|
? Math.Max(1, logCampWoodPerMinute)
|
||||||
: 5;
|
: 5;
|
||||||
|
_defaultLogCampBuildSeconds = int.TryParse(cfg["Buildings:LogCampBuildSeconds"], out var logCampBuildSeconds)
|
||||||
|
? Math.Max(1, logCampBuildSeconds)
|
||||||
|
: 60;
|
||||||
|
|
||||||
var coordinateIndex = Builders<Location>.IndexKeys
|
var coordinateIndex = Builders<Location>.IndexKeys
|
||||||
.Ascending(x => x.Q)
|
.Ascending(x => x.Q)
|
||||||
@@ -139,10 +145,15 @@ public class LocationService
|
|||||||
throw new InvalidOperationException("Log Camps can only be built on Forest territory.");
|
throw new InvalidOperationException("Log Camps can only be built on Forest territory.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
await CompleteFinishedBuildingsAsync(username);
|
||||||
|
|
||||||
var now = DateTime.UtcNow;
|
var now = DateTime.UtcNow;
|
||||||
|
var buildSeconds = await _settings.GetIntAsync(GameSettingsService.LogCampBuildSeconds, _defaultLogCampBuildSeconds);
|
||||||
var update = Builders<Location>.Update
|
var update = Builders<Location>.Update
|
||||||
.Set(x => x.BuildingType, "LogCamp")
|
.Set(x => x.BuildingType, "LogCamp")
|
||||||
.Set(x => x.BuildingBuiltAtUtc, now)
|
.Set(x => x.BuildingStatus, "Building")
|
||||||
|
.Set(x => x.BuildingStartedAtUtc, now)
|
||||||
|
.Set(x => x.BuildingCompletesAtUtc, now.AddSeconds(buildSeconds))
|
||||||
.Set(x => x.UpdatedAtUtc, now);
|
.Set(x => x.UpdatedAtUtc, now);
|
||||||
|
|
||||||
var updated = await _locations.FindOneAndUpdateAsync(
|
var updated = await _locations.FindOneAndUpdateAsync(
|
||||||
@@ -158,10 +169,41 @@ public class LocationService
|
|||||||
throw new InvalidOperationException("This location already has a building.");
|
throw new InvalidOperationException("This location already has a building.");
|
||||||
}
|
}
|
||||||
|
|
||||||
await _resources.AddWoodGenerationAsync(username, _logCampWoodPerMinute);
|
|
||||||
return updated;
|
return updated;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public async Task CompleteFinishedBuildingsAsync(string username)
|
||||||
|
{
|
||||||
|
var now = DateTime.UtcNow;
|
||||||
|
var readyBuildings = await _locations.Find(x =>
|
||||||
|
x.OwnerUsername == username &&
|
||||||
|
x.BuildingType == "LogCamp" &&
|
||||||
|
x.BuildingStatus == "Building" &&
|
||||||
|
x.BuildingCompletesAtUtc <= now)
|
||||||
|
.ToListAsync();
|
||||||
|
|
||||||
|
foreach (var building in readyBuildings)
|
||||||
|
{
|
||||||
|
var update = Builders<Location>.Update
|
||||||
|
.Set(x => x.BuildingStatus, "Built")
|
||||||
|
.Set(x => x.BuildingBuiltAtUtc, now)
|
||||||
|
.Set(x => x.UpdatedAtUtc, now);
|
||||||
|
|
||||||
|
var updated = await _locations.FindOneAndUpdateAsync(
|
||||||
|
x => x.Id == building.Id && x.BuildingStatus == "Building",
|
||||||
|
update,
|
||||||
|
new FindOneAndUpdateOptions<Location>
|
||||||
|
{
|
||||||
|
ReturnDocument = ReturnDocument.After
|
||||||
|
});
|
||||||
|
|
||||||
|
if (updated is not null)
|
||||||
|
{
|
||||||
|
await _resources.AddWoodGenerationAsync(username, _logCampWoodPerMinute);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public async Task<Location?> GetHomeAsync(string username) =>
|
public async Task<Location?> GetHomeAsync(string username) =>
|
||||||
await _locations.Find(x => x.OwnerUsername == username && x.Kind == "Home").FirstOrDefaultAsync();
|
await _locations.Find(x => x.OwnerUsername == username && x.Kind == "Home").FirstOrDefaultAsync();
|
||||||
|
|
||||||
@@ -204,6 +246,8 @@ public class LocationService
|
|||||||
|
|
||||||
public async Task<List<LocationResponse>> GetVisibleAsync(string username, int? visibilityDepth = null)
|
public async Task<List<LocationResponse>> GetVisibleAsync(string username, int? visibilityDepth = null)
|
||||||
{
|
{
|
||||||
|
await CompleteFinishedBuildingsAsync(username);
|
||||||
|
|
||||||
var ownedLocations = await _locations.Find(x => x.OwnerUsername == username).ToListAsync();
|
var ownedLocations = await _locations.Find(x => x.OwnerUsername == username).ToListAsync();
|
||||||
if (ownedLocations.Count == 0)
|
if (ownedLocations.Count == 0)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -9,10 +9,11 @@ public class UnitTrainingService
|
|||||||
|
|
||||||
private readonly IMongoCollection<UnitTraining> _training;
|
private readonly IMongoCollection<UnitTraining> _training;
|
||||||
private readonly ResourceService _resources;
|
private readonly ResourceService _resources;
|
||||||
|
private readonly GameSettingsService _settings;
|
||||||
private readonly int _scoutGoldCost;
|
private readonly int _scoutGoldCost;
|
||||||
private readonly int _scoutTrainingSeconds;
|
private readonly int _defaultScoutTrainingSeconds;
|
||||||
|
|
||||||
public UnitTrainingService(IConfiguration cfg, ResourceService resources)
|
public UnitTrainingService(IConfiguration cfg, ResourceService resources, GameSettingsService settings)
|
||||||
{
|
{
|
||||||
var connectionString = cfg["MongoDB:ConnectionString"] ?? "mongodb://127.0.0.1:27017";
|
var connectionString = cfg["MongoDB:ConnectionString"] ?? "mongodb://127.0.0.1:27017";
|
||||||
var databaseName = cfg["MongoDB:DatabaseName"] ?? "territory-autobattler";
|
var databaseName = cfg["MongoDB:DatabaseName"] ?? "territory-autobattler";
|
||||||
@@ -20,8 +21,9 @@ public class UnitTrainingService
|
|||||||
var database = client.GetDatabase(databaseName);
|
var database = client.GetDatabase(databaseName);
|
||||||
_training = database.GetCollection<UnitTraining>("UnitTraining");
|
_training = database.GetCollection<UnitTraining>("UnitTraining");
|
||||||
_resources = resources;
|
_resources = resources;
|
||||||
|
_settings = settings;
|
||||||
_scoutGoldCost = int.TryParse(cfg["Units:ScoutGoldCost"], out var scoutGoldCost) ? Math.Max(0, scoutGoldCost) : 50;
|
_scoutGoldCost = int.TryParse(cfg["Units:ScoutGoldCost"], out var scoutGoldCost) ? Math.Max(0, scoutGoldCost) : 50;
|
||||||
_scoutTrainingSeconds = int.TryParse(cfg["Units:ScoutTrainingSeconds"], out var scoutTrainingSeconds)
|
_defaultScoutTrainingSeconds = int.TryParse(cfg["Units:ScoutTrainingSeconds"], out var scoutTrainingSeconds)
|
||||||
? Math.Max(1, scoutTrainingSeconds)
|
? Math.Max(1, scoutTrainingSeconds)
|
||||||
: 60;
|
: 60;
|
||||||
|
|
||||||
@@ -62,6 +64,7 @@ public class UnitTrainingService
|
|||||||
}
|
}
|
||||||
|
|
||||||
var now = DateTime.UtcNow;
|
var now = DateTime.UtcNow;
|
||||||
|
var scoutTrainingSeconds = await _settings.GetIntAsync(GameSettingsService.ScoutTrainingSeconds, _defaultScoutTrainingSeconds);
|
||||||
var training = new UnitTraining
|
var training = new UnitTraining
|
||||||
{
|
{
|
||||||
Username = username,
|
Username = username,
|
||||||
@@ -69,7 +72,7 @@ public class UnitTrainingService
|
|||||||
GoldCost = _scoutGoldCost,
|
GoldCost = _scoutGoldCost,
|
||||||
Status = "Training",
|
Status = "Training",
|
||||||
StartedAtUtc = now,
|
StartedAtUtc = now,
|
||||||
CompletesAtUtc = now.AddSeconds(_scoutTrainingSeconds),
|
CompletesAtUtc = now.AddSeconds(scoutTrainingSeconds),
|
||||||
CreatedAtUtc = now,
|
CreatedAtUtc = now,
|
||||||
UpdatedAtUtc = now
|
UpdatedAtUtc = now
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -28,7 +28,8 @@
|
|||||||
"ScoutTrainingSeconds": 60
|
"ScoutTrainingSeconds": 60
|
||||||
},
|
},
|
||||||
"Buildings": {
|
"Buildings": {
|
||||||
"LogCampWoodPerMinute": 5
|
"LogCampWoodPerMinute": 5,
|
||||||
|
"LogCampBuildSeconds": 60
|
||||||
},
|
},
|
||||||
"AllowedHosts": "*"
|
"AllowedHosts": "*"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,3 +16,4 @@ data:
|
|||||||
Units__ScoutGoldCost: "50"
|
Units__ScoutGoldCost: "50"
|
||||||
Units__ScoutTrainingSeconds: "60"
|
Units__ScoutTrainingSeconds: "60"
|
||||||
Buildings__LogCampWoodPerMinute: "5"
|
Buildings__LogCampWoodPerMinute: "5"
|
||||||
|
Buildings__LogCampBuildSeconds: "60"
|
||||||
|
|||||||
Reference in New Issue
Block a user