Updating peasants

This commit is contained in:
hz
2026-05-20 04:09:32 -05:00
parent 864835a8f9
commit 194dae43da
13 changed files with 557 additions and 62 deletions
@@ -263,6 +263,7 @@ public class LocationService
var update = Builders<Location>.Update
.Set(x => x.BuildingStatus, "Built")
.Set(x => x.BuildingBuiltAtUtc, now)
.Set(x => x.StoredResourceCapacity, 10)
.Set(x => x.UpdatedAtUtc, now);
var updated = await _locations.FindOneAndUpdateAsync(
@@ -275,25 +276,120 @@ public class LocationService
if (updated is not null)
{
if (updated.BuildingType == "LogCamp")
{
var woodPerMinute = await _settings.GetNonNegativeIntAsync(GameSettingsService.LogCampWoodPerMinute, _logCampWoodPerMinute);
await _resources.AddWoodGenerationAsync(username, woodPerMinute);
}
else if (updated.BuildingType == "Mine")
{
var orePerMinute = await _settings.GetNonNegativeIntAsync(GameSettingsService.MineOrePerMinute, _mineOrePerMinute);
await _resources.AddOreGenerationAsync(username, orePerMinute);
}
else if (updated.BuildingType == "Farm")
{
var foodPerMinute = await _settings.GetNonNegativeIntAsync(GameSettingsService.FarmFoodPerMinute, _farmFoodPerMinute);
await _resources.AddFoodGenerationAsync(username, foodPerMinute);
}
await RecalculateWorkerGenerationAsync(username);
}
}
}
public async Task<Location?> AssignWorkerAsync(string username, AssignWorkerRequest request)
{
var now = DateTime.UtcNow;
var location = await GetAsync(request.Q, request.R);
if (location is null ||
!string.Equals(location.OwnerUsername, username, StringComparison.OrdinalIgnoreCase) ||
string.IsNullOrWhiteSpace(location.BuildingType) ||
location.BuildingStatus == "Building" ||
!string.IsNullOrWhiteSpace(location.WorkerUnitId))
{
return null;
}
var unit = await _units.Find(x =>
x.Id == request.UnitId &&
x.Username == username &&
x.UnitType == "Peasant" &&
x.Status == "Idle")
.FirstOrDefaultAsync();
if (unit is null)
{
return null;
}
var claimed = await _units.UpdateOneAsync(
x => x.Id == unit.Id && x.Status == "Idle",
Builders<UnitInstance>.Update
.Set(x => x.Q, request.Q)
.Set(x => x.R, request.R)
.Set(x => x.Status, "Working")
.Set(x => x.UpdatedAtUtc, now));
if (claimed.ModifiedCount == 0)
{
return null;
}
var updated = await _locations.FindOneAndUpdateAsync(
x => x.Id == location.Id && (x.WorkerUnitId == null || x.WorkerUnitId == ""),
Builders<Location>.Update
.Set(x => x.WorkerUnitId, unit.Id)
.Set(x => x.WorkerUnitType, "Peasant")
.Set(x => x.LastResourceGeneratedAtUtc, now)
.Set(x => x.UpdatedAtUtc, now),
new FindOneAndUpdateOptions<Location> { ReturnDocument = ReturnDocument.After });
if (updated is null)
{
await _units.UpdateOneAsync(
x => x.Id == unit.Id,
Builders<UnitInstance>.Update
.Set(x => x.Status, "Idle")
.Set(x => x.UpdatedAtUtc, DateTime.UtcNow));
return null;
}
await RecalculateWorkerGenerationAsync(username);
return updated;
}
public async Task<Location?> DeassignWorkerAsync(string username, DeassignWorkerRequest request)
{
var now = DateTime.UtcNow;
var location = await GetAsync(request.Q, request.R);
if (location is null ||
!string.Equals(location.OwnerUsername, username, StringComparison.OrdinalIgnoreCase) ||
string.IsNullOrWhiteSpace(location.WorkerUnitId))
{
return null;
}
await _units.UpdateOneAsync(
x => x.Id == location.WorkerUnitId && x.Username == username && x.Status == "Working",
Builders<UnitInstance>.Update
.Set(x => x.Q, request.Q)
.Set(x => x.R, request.R)
.Set(x => x.Status, "Idle")
.Set(x => x.UpdatedAtUtc, now));
var updated = await _locations.FindOneAndUpdateAsync(
x => x.Id == location.Id,
Builders<Location>.Update
.Unset(x => x.WorkerUnitId)
.Unset(x => x.WorkerUnitType)
.Set(x => x.UpdatedAtUtc, now),
new FindOneAndUpdateOptions<Location> { ReturnDocument = ReturnDocument.After });
await RecalculateWorkerGenerationAsync(username);
return updated;
}
private async Task RecalculateWorkerGenerationAsync(string username)
{
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();
var woodPerMinute = await _settings.GetNonNegativeIntAsync(GameSettingsService.LogCampWoodPerMinute, _logCampWoodPerMinute);
var orePerMinute = await _settings.GetNonNegativeIntAsync(GameSettingsService.MineOrePerMinute, _mineOrePerMinute);
var foodPerMinute = await _settings.GetNonNegativeIntAsync(GameSettingsService.FarmFoodPerMinute, _farmFoodPerMinute);
await _resources.SetBuildingGenerationAsync(
username,
built.Count(x => x.BuildingType == "LogCamp") * woodPerMinute,
built.Count(x => x.BuildingType == "Mine") * orePerMinute,
built.Count(x => x.BuildingType == "Farm") * foodPerMinute);
}
public async Task<Location?> GetHomeAsync(string username) =>
await _locations.Find(x => x.OwnerUsername == username && x.Kind == "Home").FirstOrDefaultAsync();
@@ -337,6 +433,7 @@ public class LocationService
public async Task<List<LocationResponse>> GetVisibleAsync(string username, int? visibilityDepth = null)
{
await CompleteFinishedBuildingsAsync(username);
await RecalculateWorkerGenerationAsync(username);
var ownedLocations = await _locations.Find(x => x.OwnerUsername == username).ToListAsync();
if (ownedLocations.Count == 0)
@@ -551,6 +648,11 @@ public class LocationService
.Set(x => x.BuildingStartedAtUtc, location.BuildingStartedAtUtc)
.Set(x => x.BuildingCompletesAtUtc, location.BuildingCompletesAtUtc)
.Set(x => x.BuildingBuiltAtUtc, location.BuildingBuiltAtUtc)
.Set(x => x.WorkerUnitId, location.WorkerUnitId)
.Set(x => x.WorkerUnitType, location.WorkerUnitType)
.Set(x => x.StoredResourceAmount, location.StoredResourceAmount)
.Set(x => x.StoredResourceCapacity, location.StoredResourceCapacity)
.Set(x => x.LastResourceGeneratedAtUtc, location.LastResourceGeneratedAtUtc)
.Set(x => x.HomeAssignedAtUtc, location.HomeAssignedAtUtc)
.Set(x => x.ObservedAtUtc, now)
.Set(x => x.UpdatedAtUtc, now);