adding farms
This commit is contained in:
@@ -7,9 +7,25 @@ public class GameSettingsService
|
||||
{
|
||||
public const string ScoutTrainingSeconds = "ScoutTrainingSeconds";
|
||||
public const string ArcherTrainingSeconds = "ArcherTrainingSeconds";
|
||||
public const string ScoutGoldCost = "ScoutGoldCost";
|
||||
public const string ArcherGoldCost = "ArcherGoldCost";
|
||||
public const string ArcherWoodCost = "ArcherWoodCost";
|
||||
public const string LogCampBuildSeconds = "LogCampBuildSeconds";
|
||||
public const string MineBuildSeconds = "MineBuildSeconds";
|
||||
public const string BarracksBuildSeconds = "BarracksBuildSeconds";
|
||||
public const string FarmBuildSeconds = "FarmBuildSeconds";
|
||||
public const string BarracksGoldCost = "BarracksGoldCost";
|
||||
public const string BarracksWoodCost = "BarracksWoodCost";
|
||||
public const string BarracksOreCost = "BarracksOreCost";
|
||||
public const string LogCampWoodPerMinute = "LogCampWoodPerMinute";
|
||||
public const string MineOrePerMinute = "MineOrePerMinute";
|
||||
public const string FarmFoodPerMinute = "FarmFoodPerMinute";
|
||||
public const string StartingGold = "StartingGold";
|
||||
public const string HeadquartersGoldPerMinute = "HeadquartersGoldPerMinute";
|
||||
public const string TownHallGoldCapacity = "TownHallGoldCapacity";
|
||||
public const string TownHallWoodCapacity = "TownHallWoodCapacity";
|
||||
public const string TownHallOreCapacity = "TownHallOreCapacity";
|
||||
public const string TownHallFoodCapacity = "TownHallFoodCapacity";
|
||||
|
||||
private readonly IMongoCollection<GameSetting> _settings;
|
||||
|
||||
@@ -44,4 +60,23 @@ public class GameSettingsService
|
||||
|
||||
return Math.Max(1, setting.IntValue);
|
||||
}
|
||||
|
||||
public async Task<int> GetNonNegativeIntAsync(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(0, setting.IntValue);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,9 +15,11 @@ public class LocationService
|
||||
private readonly int _visibilityDepth;
|
||||
private readonly int _logCampWoodPerMinute;
|
||||
private readonly int _mineOrePerMinute;
|
||||
private readonly int _farmFoodPerMinute;
|
||||
private readonly int _defaultLogCampBuildSeconds;
|
||||
private readonly int _defaultMineBuildSeconds;
|
||||
private readonly int _defaultBarracksBuildSeconds;
|
||||
private readonly int _defaultFarmBuildSeconds;
|
||||
private readonly int _barracksGoldCost;
|
||||
private readonly int _barracksWoodCost;
|
||||
private readonly int _barracksOreCost;
|
||||
@@ -42,6 +44,9 @@ public class LocationService
|
||||
_mineOrePerMinute = int.TryParse(cfg["Buildings:MineOrePerMinute"], out var mineOrePerMinute)
|
||||
? Math.Max(1, mineOrePerMinute)
|
||||
: 5;
|
||||
_farmFoodPerMinute = int.TryParse(cfg["Buildings:FarmFoodPerMinute"], out var farmFoodPerMinute)
|
||||
? Math.Max(1, farmFoodPerMinute)
|
||||
: 5;
|
||||
_defaultLogCampBuildSeconds = int.TryParse(cfg["Buildings:LogCampBuildSeconds"], out var logCampBuildSeconds)
|
||||
? Math.Max(1, logCampBuildSeconds)
|
||||
: 60;
|
||||
@@ -51,6 +56,9 @@ public class LocationService
|
||||
_defaultBarracksBuildSeconds = int.TryParse(cfg["Buildings:BarracksBuildSeconds"], out var barracksBuildSeconds)
|
||||
? Math.Max(1, barracksBuildSeconds)
|
||||
: 60;
|
||||
_defaultFarmBuildSeconds = int.TryParse(cfg["Buildings:FarmBuildSeconds"], out var farmBuildSeconds)
|
||||
? Math.Max(1, farmBuildSeconds)
|
||||
: 60;
|
||||
_barracksGoldCost = int.TryParse(cfg["Buildings:BarracksGoldCost"], out var barracksGoldCost)
|
||||
? Math.Max(0, barracksGoldCost)
|
||||
: 500;
|
||||
@@ -215,7 +223,10 @@ public class LocationService
|
||||
|
||||
if (buildingType == "Barracks")
|
||||
{
|
||||
var spent = await _resources.TrySpendResourcesAsync(username, _barracksGoldCost, _barracksWoodCost, _barracksOreCost);
|
||||
var barracksGoldCost = await _settings.GetNonNegativeIntAsync(GameSettingsService.BarracksGoldCost, _barracksGoldCost);
|
||||
var barracksWoodCost = await _settings.GetNonNegativeIntAsync(GameSettingsService.BarracksWoodCost, _barracksWoodCost);
|
||||
var barracksOreCost = await _settings.GetNonNegativeIntAsync(GameSettingsService.BarracksOreCost, _barracksOreCost);
|
||||
var spent = await _resources.TrySpendResourcesAsync(username, barracksGoldCost, barracksWoodCost, barracksOreCost);
|
||||
if (!spent)
|
||||
{
|
||||
var rollback = Builders<Location>.Update
|
||||
@@ -230,7 +241,7 @@ public class LocationService
|
||||
x => x.Id == updated.Id && x.BuildingType == "Barracks" && x.BuildingStatus == "Building" && x.BuildingStartedAtUtc == now,
|
||||
rollback);
|
||||
|
||||
throw new InvalidOperationException($"Not enough resources to build Barracks. Required: {_barracksGoldCost} gold, {_barracksWoodCost} wood, {_barracksOreCost} ore.");
|
||||
throw new InvalidOperationException($"Not enough resources to build Barracks. Required: {barracksGoldCost} gold, {barracksWoodCost} wood, {barracksOreCost} ore.");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -242,7 +253,7 @@ public class LocationService
|
||||
var now = DateTime.UtcNow;
|
||||
var readyBuildings = await _locations.Find(x =>
|
||||
x.OwnerUsername == username &&
|
||||
(x.BuildingType == "LogCamp" || x.BuildingType == "Mine" || x.BuildingType == "Barracks") &&
|
||||
(x.BuildingType == "LogCamp" || x.BuildingType == "Mine" || x.BuildingType == "Barracks" || x.BuildingType == "Farm") &&
|
||||
x.BuildingStatus == "Building" &&
|
||||
x.BuildingCompletesAtUtc <= now)
|
||||
.ToListAsync();
|
||||
@@ -266,11 +277,18 @@ public class LocationService
|
||||
{
|
||||
if (updated.BuildingType == "LogCamp")
|
||||
{
|
||||
await _resources.AddWoodGenerationAsync(username, _logCampWoodPerMinute);
|
||||
var woodPerMinute = await _settings.GetNonNegativeIntAsync(GameSettingsService.LogCampWoodPerMinute, _logCampWoodPerMinute);
|
||||
await _resources.AddWoodGenerationAsync(username, woodPerMinute);
|
||||
}
|
||||
else if (updated.BuildingType == "Mine")
|
||||
{
|
||||
await _resources.AddOreGenerationAsync(username, _mineOrePerMinute);
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -758,6 +776,7 @@ public class LocationService
|
||||
"logcamp" or "log camp" => "LogCamp",
|
||||
"mine" => "Mine",
|
||||
"barracks" => "Barracks",
|
||||
"farm" => "Farm",
|
||||
_ => null
|
||||
};
|
||||
}
|
||||
@@ -767,6 +786,7 @@ public class LocationService
|
||||
{
|
||||
"LogCamp" => "Forest",
|
||||
"Mine" => "Ore",
|
||||
"Farm" => "Field",
|
||||
"Barracks" => null,
|
||||
_ => null
|
||||
};
|
||||
@@ -777,6 +797,7 @@ public class LocationService
|
||||
"LogCamp" => GameSettingsService.LogCampBuildSeconds,
|
||||
"Mine" => GameSettingsService.MineBuildSeconds,
|
||||
"Barracks" => GameSettingsService.BarracksBuildSeconds,
|
||||
"Farm" => GameSettingsService.FarmBuildSeconds,
|
||||
_ => GameSettingsService.LogCampBuildSeconds
|
||||
};
|
||||
|
||||
@@ -786,6 +807,7 @@ public class LocationService
|
||||
"LogCamp" => _defaultLogCampBuildSeconds,
|
||||
"Mine" => _defaultMineBuildSeconds,
|
||||
"Barracks" => _defaultBarracksBuildSeconds,
|
||||
"Farm" => _defaultFarmBuildSeconds,
|
||||
_ => 60
|
||||
};
|
||||
}
|
||||
|
||||
@@ -6,19 +6,22 @@ namespace LocationsApi.Services;
|
||||
public class ResourceService
|
||||
{
|
||||
private readonly IMongoCollection<PlayerResources> _resources;
|
||||
private readonly GameSettingsService _settings;
|
||||
private readonly int _startingGold;
|
||||
private readonly int _headquartersGoldPerMinute;
|
||||
private readonly int _townHallGoldCapacity;
|
||||
private readonly int _townHallWoodCapacity;
|
||||
private readonly int _townHallOreCapacity;
|
||||
private readonly int _townHallFoodCapacity;
|
||||
|
||||
public ResourceService(IConfiguration cfg)
|
||||
public ResourceService(IConfiguration cfg, GameSettingsService settings)
|
||||
{
|
||||
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);
|
||||
_resources = database.GetCollection<PlayerResources>("PlayerResources");
|
||||
_settings = settings;
|
||||
_startingGold = int.TryParse(cfg["Resources:StartingGold"], out var startingGold) ? Math.Max(0, startingGold) : 100;
|
||||
_headquartersGoldPerMinute = int.TryParse(cfg["Resources:HeadquartersGoldPerMinute"], out var goldPerMinute)
|
||||
? Math.Max(0, goldPerMinute)
|
||||
@@ -32,6 +35,9 @@ public class ResourceService
|
||||
_townHallOreCapacity = int.TryParse(cfg["Resources:TownHallOreCapacity"], out var oreCapacity)
|
||||
? Math.Max(0, oreCapacity)
|
||||
: 100;
|
||||
_townHallFoodCapacity = int.TryParse(cfg["Resources:TownHallFoodCapacity"], out var foodCapacity)
|
||||
? Math.Max(0, foodCapacity)
|
||||
: 100;
|
||||
|
||||
_resources.Indexes.CreateOne(new CreateIndexModel<PlayerResources>(
|
||||
Builders<PlayerResources>.IndexKeys.Ascending(x => x.Username),
|
||||
@@ -41,19 +47,28 @@ public class ResourceService
|
||||
public async Task<PlayerResources> EnsureAsync(string username)
|
||||
{
|
||||
var now = DateTime.UtcNow;
|
||||
var startingGold = await _settings.GetNonNegativeIntAsync(GameSettingsService.StartingGold, _startingGold);
|
||||
var goldPerMinute = await _settings.GetNonNegativeIntAsync(GameSettingsService.HeadquartersGoldPerMinute, _headquartersGoldPerMinute);
|
||||
var goldCapacity = await _settings.GetNonNegativeIntAsync(GameSettingsService.TownHallGoldCapacity, _townHallGoldCapacity);
|
||||
var woodCapacity = await _settings.GetNonNegativeIntAsync(GameSettingsService.TownHallWoodCapacity, _townHallWoodCapacity);
|
||||
var oreCapacity = await _settings.GetNonNegativeIntAsync(GameSettingsService.TownHallOreCapacity, _townHallOreCapacity);
|
||||
var foodCapacity = await _settings.GetNonNegativeIntAsync(GameSettingsService.TownHallFoodCapacity, _townHallFoodCapacity);
|
||||
var update = Builders<PlayerResources>.Update
|
||||
.SetOnInsert(x => x.Username, username)
|
||||
.SetOnInsert(x => x.Gold, Math.Min(_startingGold, _townHallGoldCapacity))
|
||||
.SetOnInsert(x => x.Gold, Math.Min(startingGold, goldCapacity))
|
||||
.SetOnInsert(x => x.Wood, 0)
|
||||
.SetOnInsert(x => x.Ore, 0)
|
||||
.SetOnInsert(x => x.Food, 0)
|
||||
.SetOnInsert(x => x.CreatedAtUtc, now)
|
||||
.SetOnInsert(x => x.LastGoldGeneratedAtUtc, now)
|
||||
.SetOnInsert(x => x.LastWoodGeneratedAtUtc, now)
|
||||
.SetOnInsert(x => x.LastOreGeneratedAtUtc, now)
|
||||
.Set(x => x.GoldPerMinute, _headquartersGoldPerMinute)
|
||||
.Set(x => x.GoldCapacity, _townHallGoldCapacity)
|
||||
.Set(x => x.WoodCapacity, _townHallWoodCapacity)
|
||||
.Set(x => x.OreCapacity, _townHallOreCapacity)
|
||||
.SetOnInsert(x => x.LastFoodGeneratedAtUtc, now)
|
||||
.Set(x => x.GoldPerMinute, goldPerMinute)
|
||||
.Set(x => x.GoldCapacity, goldCapacity)
|
||||
.Set(x => x.WoodCapacity, woodCapacity)
|
||||
.Set(x => x.OreCapacity, oreCapacity)
|
||||
.Set(x => x.FoodCapacity, foodCapacity)
|
||||
.Set(x => x.UpdatedAtUtc, now);
|
||||
|
||||
var resources = await _resources.FindOneAndUpdateAsync(
|
||||
@@ -65,7 +80,7 @@ public class ResourceService
|
||||
ReturnDocument = ReturnDocument.After
|
||||
});
|
||||
|
||||
return await ApplyGoldGenerationAsync(resources);
|
||||
return await ApplyResourceGenerationAsync(resources);
|
||||
}
|
||||
|
||||
public async Task<PlayerResources> GetAsync(string username)
|
||||
@@ -170,10 +185,37 @@ public class ResourceService
|
||||
await _resources.UpdateOneAsync(x => x.Username == username, update);
|
||||
}
|
||||
|
||||
private async Task<PlayerResources> ApplyGoldGenerationAsync(PlayerResources resources)
|
||||
public async Task AddFoodGenerationAsync(string username, int foodPerMinute)
|
||||
{
|
||||
if (foodPerMinute <= 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var resources = await EnsureAsync(username);
|
||||
var now = DateTime.UtcNow;
|
||||
|
||||
var update = Builders<PlayerResources>.Update
|
||||
.Inc(x => x.FoodPerMinute, foodPerMinute)
|
||||
.Set(x => x.UpdatedAtUtc, now);
|
||||
|
||||
if (resources.FoodPerMinute <= 0 || resources.LastFoodGeneratedAtUtc.Year < 2000)
|
||||
{
|
||||
update = update.Set(x => x.LastFoodGeneratedAtUtc, now);
|
||||
}
|
||||
|
||||
await _resources.UpdateOneAsync(x => x.Username == username, update);
|
||||
}
|
||||
|
||||
private async Task<PlayerResources> ApplyResourceGenerationAsync(PlayerResources resources)
|
||||
{
|
||||
var now = DateTime.UtcNow;
|
||||
var goldElapsedMinutes = resources.GoldPerMinute <= 0
|
||||
var goldPerMinute = await _settings.GetNonNegativeIntAsync(GameSettingsService.HeadquartersGoldPerMinute, _headquartersGoldPerMinute);
|
||||
var goldCapacity = await _settings.GetNonNegativeIntAsync(GameSettingsService.TownHallGoldCapacity, _townHallGoldCapacity);
|
||||
var woodCapacity = await _settings.GetNonNegativeIntAsync(GameSettingsService.TownHallWoodCapacity, _townHallWoodCapacity);
|
||||
var oreCapacity = await _settings.GetNonNegativeIntAsync(GameSettingsService.TownHallOreCapacity, _townHallOreCapacity);
|
||||
var foodCapacity = await _settings.GetNonNegativeIntAsync(GameSettingsService.TownHallFoodCapacity, _townHallFoodCapacity);
|
||||
var goldElapsedMinutes = goldPerMinute <= 0
|
||||
? 0
|
||||
: (int)Math.Floor((now - resources.LastGoldGeneratedAtUtc).TotalMinutes);
|
||||
var woodElapsedMinutes = resources.WoodPerMinute <= 0 || resources.LastWoodGeneratedAtUtc.Year < 2000
|
||||
@@ -182,21 +224,26 @@ public class ResourceService
|
||||
var oreElapsedMinutes = resources.OrePerMinute <= 0 || resources.LastOreGeneratedAtUtc.Year < 2000
|
||||
? 0
|
||||
: (int)Math.Floor((now - resources.LastOreGeneratedAtUtc).TotalMinutes);
|
||||
var cappedGold = Math.Min(resources.Gold, _townHallGoldCapacity);
|
||||
var cappedWood = Math.Min(resources.Wood, _townHallWoodCapacity);
|
||||
var cappedOre = Math.Min(resources.Ore, _townHallOreCapacity);
|
||||
var isOverCapacity = resources.Gold != cappedGold || resources.Wood != cappedWood || resources.Ore != cappedOre;
|
||||
var foodElapsedMinutes = resources.FoodPerMinute <= 0 || resources.LastFoodGeneratedAtUtc.Year < 2000
|
||||
? 0
|
||||
: (int)Math.Floor((now - resources.LastFoodGeneratedAtUtc).TotalMinutes);
|
||||
var cappedGold = Math.Min(resources.Gold, goldCapacity);
|
||||
var cappedWood = Math.Min(resources.Wood, woodCapacity);
|
||||
var cappedOre = Math.Min(resources.Ore, oreCapacity);
|
||||
var cappedFood = Math.Min(resources.Food, foodCapacity);
|
||||
var isOverCapacity = resources.Gold != cappedGold || resources.Wood != cappedWood || resources.Ore != cappedOre || resources.Food != cappedFood;
|
||||
|
||||
if (goldElapsedMinutes <= 0 && woodElapsedMinutes <= 0 && oreElapsedMinutes <= 0 && !isOverCapacity)
|
||||
if (goldElapsedMinutes <= 0 && woodElapsedMinutes <= 0 && oreElapsedMinutes <= 0 && foodElapsedMinutes <= 0 && !isOverCapacity)
|
||||
{
|
||||
return resources;
|
||||
}
|
||||
|
||||
var update = Builders<PlayerResources>.Update
|
||||
.Set(x => x.GoldPerMinute, _headquartersGoldPerMinute)
|
||||
.Set(x => x.GoldCapacity, _townHallGoldCapacity)
|
||||
.Set(x => x.WoodCapacity, _townHallWoodCapacity)
|
||||
.Set(x => x.OreCapacity, _townHallOreCapacity)
|
||||
.Set(x => x.GoldPerMinute, goldPerMinute)
|
||||
.Set(x => x.GoldCapacity, goldCapacity)
|
||||
.Set(x => x.WoodCapacity, woodCapacity)
|
||||
.Set(x => x.OreCapacity, oreCapacity)
|
||||
.Set(x => x.FoodCapacity, foodCapacity)
|
||||
.Set(x => x.UpdatedAtUtc, now);
|
||||
|
||||
if (isOverCapacity)
|
||||
@@ -204,12 +251,13 @@ public class ResourceService
|
||||
update = update
|
||||
.Set(x => x.Gold, cappedGold)
|
||||
.Set(x => x.Wood, cappedWood)
|
||||
.Set(x => x.Ore, cappedOre);
|
||||
.Set(x => x.Ore, cappedOre)
|
||||
.Set(x => x.Food, cappedFood);
|
||||
}
|
||||
|
||||
if (goldElapsedMinutes > 0)
|
||||
{
|
||||
var generatedGold = Math.Min(_townHallGoldCapacity, cappedGold + (goldElapsedMinutes * resources.GoldPerMinute));
|
||||
var generatedGold = Math.Min(goldCapacity, cappedGold + (goldElapsedMinutes * goldPerMinute));
|
||||
update = update
|
||||
.Set(x => x.Gold, generatedGold)
|
||||
.Set(x => x.LastGoldGeneratedAtUtc, resources.LastGoldGeneratedAtUtc.AddMinutes(goldElapsedMinutes));
|
||||
@@ -217,7 +265,7 @@ public class ResourceService
|
||||
|
||||
if (woodElapsedMinutes > 0)
|
||||
{
|
||||
var generatedWood = Math.Min(_townHallWoodCapacity, cappedWood + (woodElapsedMinutes * resources.WoodPerMinute));
|
||||
var generatedWood = Math.Min(woodCapacity, cappedWood + (woodElapsedMinutes * resources.WoodPerMinute));
|
||||
update = update
|
||||
.Set(x => x.Wood, generatedWood)
|
||||
.Set(x => x.LastWoodGeneratedAtUtc, resources.LastWoodGeneratedAtUtc.AddMinutes(woodElapsedMinutes));
|
||||
@@ -225,12 +273,20 @@ public class ResourceService
|
||||
|
||||
if (oreElapsedMinutes > 0)
|
||||
{
|
||||
var generatedOre = Math.Min(_townHallOreCapacity, cappedOre + (oreElapsedMinutes * resources.OrePerMinute));
|
||||
var generatedOre = Math.Min(oreCapacity, cappedOre + (oreElapsedMinutes * resources.OrePerMinute));
|
||||
update = update
|
||||
.Set(x => x.Ore, generatedOre)
|
||||
.Set(x => x.LastOreGeneratedAtUtc, resources.LastOreGeneratedAtUtc.AddMinutes(oreElapsedMinutes));
|
||||
}
|
||||
|
||||
if (foodElapsedMinutes > 0)
|
||||
{
|
||||
var generatedFood = Math.Min(foodCapacity, cappedFood + (foodElapsedMinutes * resources.FoodPerMinute));
|
||||
update = update
|
||||
.Set(x => x.Food, generatedFood)
|
||||
.Set(x => x.LastFoodGeneratedAtUtc, resources.LastFoodGeneratedAtUtc.AddMinutes(foodElapsedMinutes));
|
||||
}
|
||||
|
||||
return await _resources.FindOneAndUpdateAsync(
|
||||
x => x.Username == resources.Username,
|
||||
update,
|
||||
|
||||
@@ -107,8 +107,12 @@ public class UnitTrainingService
|
||||
}
|
||||
}
|
||||
|
||||
var goldCost = normalizedUnitType == ArcherUnitType ? _archerGoldCost : _scoutGoldCost;
|
||||
var woodCost = normalizedUnitType == ArcherUnitType ? _archerWoodCost : 0;
|
||||
var goldCost = normalizedUnitType == ArcherUnitType
|
||||
? await _settings.GetNonNegativeIntAsync(GameSettingsService.ArcherGoldCost, _archerGoldCost)
|
||||
: await _settings.GetNonNegativeIntAsync(GameSettingsService.ScoutGoldCost, _scoutGoldCost);
|
||||
var woodCost = normalizedUnitType == ArcherUnitType
|
||||
? await _settings.GetNonNegativeIntAsync(GameSettingsService.ArcherWoodCost, _archerWoodCost)
|
||||
: 0;
|
||||
var spent = normalizedUnitType == ArcherUnitType
|
||||
? await _resources.TrySpendResourcesAsync(username, goldCost, woodCost, 0)
|
||||
: await _resources.TrySpendGoldAsync(username, goldCost);
|
||||
@@ -241,7 +245,9 @@ public class UnitTrainingService
|
||||
{
|
||||
var hasOtherUnits = await _units.Find(x => x.Username != username && x.Q == q && x.R == r).AnyAsync();
|
||||
var target = await _locations.Find(x => x.Q == q && x.R == r).FirstOrDefaultAsync();
|
||||
var hasBuilding = target is not null && !string.IsNullOrWhiteSpace(target.BuildingType);
|
||||
var hasBuilding = target is not null &&
|
||||
(!string.IsNullOrWhiteSpace(target.BuildingType) ||
|
||||
string.Equals(target.Kind, "Home", StringComparison.OrdinalIgnoreCase));
|
||||
|
||||
if (hasOtherUnits || hasBuilding)
|
||||
{
|
||||
@@ -278,14 +284,15 @@ public class UnitTrainingService
|
||||
return;
|
||||
}
|
||||
|
||||
var emptyBuildingFilter = Builders<Location>.Filter.And(
|
||||
var capturableFilter = Builders<Location>.Filter.And(
|
||||
Builders<Location>.Filter.Eq(x => x.Id, target.Id),
|
||||
Builders<Location>.Filter.Ne(x => x.Kind, "Home"),
|
||||
Builders<Location>.Filter.Or(
|
||||
Builders<Location>.Filter.Eq(x => x.BuildingType, null),
|
||||
Builders<Location>.Filter.Eq(x => x.BuildingType, "")));
|
||||
|
||||
await _locations.UpdateOneAsync(
|
||||
emptyBuildingFilter,
|
||||
capturableFilter,
|
||||
Builders<Location>.Update
|
||||
.Set(x => x.OwnerUsername, username)
|
||||
.Set(x => x.Kind, "Claimed")
|
||||
|
||||
Reference in New Issue
Block a user