addressing starvation

This commit is contained in:
hz
2026-05-20 23:57:20 -05:00
parent c89c3a0947
commit de42f85835
5 changed files with 66 additions and 3 deletions
@@ -27,6 +27,7 @@ public class GameSettingsService
public const string ProductionBuildingResourceCapacity = "ProductionBuildingResourceCapacity";
public const string StartingGold = "StartingGold";
public const string HeadquartersGoldPerMinute = "HeadquartersGoldPerMinute";
public const string TownHallFoodPerMinute = "TownHallFoodPerMinute";
public const string TownHallGoldCapacity = "TownHallGoldCapacity";
public const string TownHallWoodCapacity = "TownHallWoodCapacity";
public const string TownHallOreCapacity = "TownHallOreCapacity";
@@ -16,6 +16,7 @@ public class ResourceService
private readonly GameSettingsService _settings;
private readonly int _startingGold;
private readonly int _headquartersGoldPerMinute;
private readonly int _townHallFoodPerMinute;
private readonly int _townHallGoldCapacity;
private readonly int _townHallWoodCapacity;
private readonly int _townHallOreCapacity;
@@ -38,6 +39,9 @@ public class ResourceService
_headquartersGoldPerMinute = int.TryParse(cfg["Resources:HeadquartersGoldPerMinute"], out var goldPerMinute)
? Math.Max(0, goldPerMinute)
: 10;
_townHallFoodPerMinute = int.TryParse(cfg["Resources:TownHallFoodPerMinute"], out var townHallFoodPerMinute)
? Math.Max(0, townHallFoodPerMinute)
: 5;
_townHallGoldCapacity = int.TryParse(cfg["Resources:TownHallGoldCapacity"], out var goldCapacity)
? Math.Max(0, goldCapacity)
: 500;
@@ -231,10 +235,16 @@ public class ResourceService
{
await EnsureAsync(username);
var now = DateTime.UtcNow;
var townHallFoodPerMinute = await _settings.GetNonNegativeIntAsync(GameSettingsService.TownHallFoodPerMinute, _townHallFoodPerMinute);
var hasTownHall = await _locations.Find(x =>
x.OwnerUsername == username &&
x.Kind == "Home")
.AnyAsync();
var totalFoodPerMinute = Math.Max(0, foodPerMinute) + (hasTownHall ? townHallFoodPerMinute : 0);
var update = Builders<PlayerResources>.Update
.Set(x => x.WoodPerMinute, Math.Max(0, woodPerMinute))
.Set(x => x.OrePerMinute, Math.Max(0, orePerMinute))
.Set(x => x.FoodPerMinute, Math.Max(0, foodPerMinute))
.Set(x => x.FoodPerMinute, totalFoodPerMinute)
.Set(x => x.UpdatedAtUtc, now);
if (woodPerMinute > 0)
@@ -245,7 +255,7 @@ public class ResourceService
{
update = update.Set(x => x.LastOreGeneratedAtUtc, now);
}
if (foodPerMinute > 0)
if (totalFoodPerMinute > 0)
{
update = update.Set(x => x.LastFoodGeneratedAtUtc, now);
}
@@ -489,14 +499,19 @@ public class ResourceService
private async Task<int> CalculateFoodProductionPerMinuteAsync(string username)
{
var townHallFoodPerMinute = await _settings.GetNonNegativeIntAsync(GameSettingsService.TownHallFoodPerMinute, _townHallFoodPerMinute);
var farmFoodPerMinute = await _settings.GetNonNegativeIntAsync(GameSettingsService.FarmFoodPerMinute, 5);
var hasTownHall = await _locations.Find(x =>
x.OwnerUsername == username &&
x.Kind == "Home")
.AnyAsync();
var farms = await _locations.CountDocumentsAsync(x =>
x.OwnerUsername == username &&
!string.IsNullOrWhiteSpace(x.WorkerUnitId) &&
(x.BuildingStatus == "Built" || x.BuildingStatus == null || x.BuildingStatus == "") &&
x.BuildingType == "Farm");
return checked((int)farms) * farmFoodPerMinute;
return (hasTownHall ? townHallFoodPerMinute : 0) + checked((int)farms) * farmFoodPerMinute;
}
private async Task CompletePendingWorkerAssignmentsAsync(string username, DateTime now)
@@ -686,8 +701,29 @@ public class ResourceService
await _units.DeleteManyAsync(x =>
x.Username == username &&
instanceIds.Contains(x.Id));
await RecalculateWorkerGenerationAsync(username);
}
}
private async Task RecalculateWorkerGenerationAsync(string username)
{
var logCampWoodPerMinute = await _settings.GetNonNegativeIntAsync(GameSettingsService.LogCampWoodPerMinute, 5);
var mineOrePerMinute = await _settings.GetNonNegativeIntAsync(GameSettingsService.MineOrePerMinute, 5);
var farmFoodPerMinute = await _settings.GetNonNegativeIntAsync(GameSettingsService.FarmFoodPerMinute, 5);
var built = await _locations.Find(x =>
x.OwnerUsername == username &&
!string.IsNullOrWhiteSpace(x.WorkerUnitId) &&
(x.BuildingStatus == "Built" || x.BuildingStatus == null || x.BuildingStatus == "") &&
(x.BuildingType == "LogCamp" || x.BuildingType == "Mine" || x.BuildingType == "Farm"))
.ToListAsync();
await SetBuildingGenerationAsync(
username,
built.Count(x => x.BuildingType == "LogCamp") * logCampWoodPerMinute,
built.Count(x => x.BuildingType == "Mine") * mineOrePerMinute,
built.Count(x => x.BuildingType == "Farm") * farmFoodPerMinute);
}
private sealed record FoodConsumingUnit(string Id, string UnitType, bool IsTrainingRecord);
}
@@ -22,6 +22,7 @@
"Resources": {
"StartingGold": 100,
"HeadquartersGoldPerMinute": 10,
"TownHallFoodPerMinute": 5,
"TownHallGoldCapacity": 500,
"TownHallWoodCapacity": 100,
"TownHallOreCapacity": 100,
@@ -13,6 +13,7 @@ data:
World__VisibilityDepth: "3"
Resources__StartingGold: "100"
Resources__HeadquartersGoldPerMinute: "10"
Resources__TownHallFoodPerMinute: "5"
Resources__TownHallGoldCapacity: "500"
Resources__TownHallWoodCapacity: "100"
Resources__TownHallOreCapacity: "100"