public override async Task ExecuteAsync(MainRepository repo, Character character, IEnumerable <CharacterCommandParameter> options, CommandSystemData game) { var townOptional = await repo.Town.GetByIdAsync(character.TownId); if (!townOptional.HasData) { await game.CharacterLogAsync("ID:" + character.TownId + " の都市は存在しません。<emerge>管理者にお問い合わせください</emerge>"); return; } var town = townOptional.Data; if (town.CountryId != character.CountryId) { await game.CharacterLogAsync("<town>" + town.Name + "</town>で内政しようとしましたが、自国の都市ではありません"); return; } var countryOptional = await repo.Country.GetAliveByIdAsync(character.CountryId); if (!countryOptional.HasData) { await game.CharacterLogAsync("ID:" + character.CountryId + " の国は存在しません。<emerge>管理者にお問い合わせください</emerge>"); return; } var country = countryOptional.Data; var typeParameter = options.FirstOrDefault(p => p.Type == 1); if (typeParameter == null) { await game.CharacterLogAsync($"建築物撤去に必要なパラメータが足りません。<emerge>管理者にお問い合わせください</emerge>"); return; } var type = (TownSubBuildingType)typeParameter.NumberValue; var infoOptional = TownSubBuildingTypeInfoes.Get(type); if (!infoOptional.HasData) { await game.CharacterLogAsync($"ID: <num>{(int)type}</num> の建築物の情報が見つかりません。<emerge>管理者にお問い合わせください</emerge>"); return; } var info = infoOptional.Data; if (country.SafeMoney + character.Money < info.Money / 2) { await game.CharacterLogAsync($"{info.Name} (金: <num>{info.Money / 2}</num>) を建設しようとしましたが、金が足りません"); return; } var subBuildings = await repo.Town.GetSubBuildingsAsync(); var townSubBuildings = subBuildings.Where(s => s.TownId == town.Id); if (subBuildings.Any(d => d.CharacterId == character.Id && (d.Status == TownSubBuildingStatus.Removing || d.Status == TownSubBuildingStatus.UnderConstruction))) { await game.CharacterLogAsync($"建築物を撤去しようとしましたが、1人の武将が建設または撤去を同時に行うことはできません"); return; } var end = game.GameDateTime.AddMonth(info.BuildDuring / 2); var subBuilding = townSubBuildings.FirstOrDefault(s => s.TownId == town.Id && s.Type == type && s.Status == TownSubBuildingStatus.Available); if (subBuilding == null) { await game.CharacterLogAsync($"建築物を撤去しようとしましたが、{info.Name} は <town>{town.Name}</town> に存在しないか、建設中です"); return; } if (country.SafeMoney >= info.Money / 2) { country.SafeMoney -= info.Money / 2; } else { character.Money -= info.Money / 2 - country.SafeMoney; country.SafeMoney = 0; } character.Contribution += 100; character.AddStrongEx(100); character.SkillPoint++; subBuilding.CharacterId = character.Id; subBuilding.Status = TownSubBuildingStatus.Removing; subBuilding.StatusFinishGameDateTime = end; info.OnRemoving?.Invoke(town); await game.CharacterLogAsync($"<town>{town.Name}</town> で {info.Name} の撤去を開始しました。終了: <num>{end.Year}</num>年<num>{end.Month}</num>月"); await StatusStreaming.Default.SendTownToAllAsync(ApiData.From(subBuilding), repo, town); }
public override async Task ExecuteAsync(MainRepository repo, Character character, IEnumerable <CharacterCommandParameter> options, CommandSystemData game) { var townOptional = await repo.Town.GetByIdAsync(character.TownId); if (!townOptional.HasData) { await game.CharacterLogAsync("ID:" + character.TownId + " の都市は存在しません。<emerge>管理者にお問い合わせください</emerge>"); return; } var town = townOptional.Data; if (town.CountryId != character.CountryId) { await game.CharacterLogAsync("<town>" + town.Name + "</town>で内政しようとしましたが、自国の都市ではありません"); return; } var countryOptional = await repo.Country.GetAliveByIdAsync(character.CountryId); if (!countryOptional.HasData) { await game.CharacterLogAsync("ID:" + character.CountryId + " の国は存在しません。<emerge>管理者にお問い合わせください</emerge>"); return; } var country = countryOptional.Data; var typeParameter = options.FirstOrDefault(p => p.Type == 1); if (typeParameter == null) { await game.CharacterLogAsync($"建築物建設に必要なパラメータが足りません。<emerge>管理者にお問い合わせください</emerge>"); return; } var type = (TownSubBuildingType)typeParameter.NumberValue; var infoOptional = TownSubBuildingTypeInfoes.Get(type); if (!infoOptional.HasData) { await game.CharacterLogAsync($"ID: <num>{(int)type}</num> の建築物の情報が見つかりません。<emerge>管理者にお問い合わせください</emerge>"); return; } var info = infoOptional.Data; if (info.BuildSubject?.Invoke(character) == false && country.AiType == CountryAiType.Human) { await game.CharacterLogAsync($"建築物 {info.Name} の建築条件を満たしていません"); return; } if (info.BuildSubjectSkills?.Invoke(await repo.Character.GetSkillsAsync(character.Id)) == false && country.AiType == CountryAiType.Human) { await game.CharacterLogAsync($"建築物 {info.Name} の建築条件を満たしていません"); return; } if (country.SafeMoney + character.Money < info.Money) { await game.CharacterLogAsync($"{info.Name} (金: <num>{info.Money}</num>) を建設しようとしましたが、金が足りません"); return; } var policies = await repo.Country.GetPoliciesAsync(country.Id); var subBuildings = await repo.Town.GetSubBuildingsAsync(); var townSubBuildings = subBuildings.Where(s => s.TownId == town.Id); var sizeMax = town.Type == TownType.Agriculture ? 2 : town.Type == TownType.Commercial ? 2 : town.Type == TownType.Fortress ? 3 : town.Type == TownType.Large ? 4 : 0; sizeMax += country.TownSubBuildingExtraSpace; sizeMax += town.TownSubBuildingExtraSpace; var currentSize = townSubBuildings.GetInfoes().Sum(i => i.Size); if (currentSize + info.Size > sizeMax && country.AiType == CountryAiType.Human) { await game.CharacterLogAsync($"<town>{town.Name}</town> に {info.Name} (敷地: <num>{info.Size}</num>) を建設しようとしましたが、敷地上限 <num>{sizeMax}</num> を超過します。残り敷地: <num>{sizeMax - currentSize}</num>"); return; } if (!info.CanBuildMultiple && townSubBuildings.Any(b => b.Type == type && b.Status != TownSubBuildingStatus.Removing)) { await game.CharacterLogAsync($"<town>{town.Name}</town> に {info.Name} (敷地: <num>{info.Size}</num>) を建設しようとしましたが、同一都市に複数建設することはできません"); return; } if (subBuildings.Any(d => d.CharacterId == character.Id && (d.Status == TownSubBuildingStatus.Removing || d.Status == TownSubBuildingStatus.UnderConstruction))) { await game.CharacterLogAsync($"建築物を建設しようとしましたが、1人の武将が建設または撤去を同時に行うことはできません"); return; } var end = game.GameDateTime.AddMonth(info.BuildDuring); var subBuilding = new TownSubBuilding { TownId = town.Id, CharacterId = character.Id, Type = type, Status = TownSubBuildingStatus.UnderConstruction, StatusFinishGameDateTime = end, }; await repo.Town.AddSubBuildingAsync(subBuilding); if (country.SafeMoney >= info.Money) { country.SafeMoney -= info.Money; } else { character.Money -= info.Money - country.SafeMoney; country.SafeMoney = 0; } character.Contribution += 100; character.AddStrongEx(100); character.SkillPoint++; await game.CharacterLogAsync($"<town>{town.Name}</town> で {info.Name} の建設を開始しました。終了: <num>{end.Year}</num>年<num>{end.Month}</num>月"); await repo.SaveChangesAsync(); await StatusStreaming.Default.SendTownToAllAsync(ApiData.From(subBuilding), repo, town); }