public override async Task ExecuteAsync(MainRepository repo, Character character, IEnumerable <CharacterCommandParameter> options, CommandSystemData game) { var typeParam = options.FirstOrDefault(p => p.Type == 1); if (typeParam == null) { await game.CharacterLogAsync($"政務官を雇おうとしましたが、コマンドパラメータが足りません。<emerge>管理者に連絡してください</emerge>"); return; } var type = (CharacterAiType)typeParam.NumberValue; var targetTownParam = options.FirstOrDefault(p => p.Type == 2); var targetTownId = (uint)targetTownParam.NumberValue; var targetTownOptional = await repo.Town.GetByIdAsync(targetTownId); var countryOptional = await repo.Country.GetByIdAsync(character.CountryId); if (!countryOptional.HasData) { await game.CharacterLogAsync($"政務官を雇おうとしましたが、あなたの国はすでに滅亡しているか無所属です"); return; } var country = countryOptional.Data; var secretaries = (await repo.Country.GetCharactersAsync(country.Id)).Where(c => c.AiType.IsSecretary()); // var policies = await repo.Country.GetPoliciesAsync(country.Id); var secretaryMax = 4; // CountryService.GetSecretaryMax(policies.Where(p => p.Status == CountryPolicyStatus.Available).Select(p => p.Type)); var currentSecretaryPoint = CountryService.GetCurrentSecretaryPoint(secretaries.Select(c => c.AiType)); if (currentSecretaryPoint >= secretaryMax) { await game.CharacterLogAsync($"政務官を雇おうとしましたが、すでに政務官ポイントが上限 <num>{secretaryMax}</num> に達しています"); return; } var afterSecretaryPoint = CountryService.GetCurrentSecretaryPoint(secretaries.Select(c => c.AiType).Append(type)); if (afterSecretaryPoint > secretaryMax) { await game.CharacterLogAsync($"政務官を雇おうとしましたが、雇用後の政務官ポイントが上限 <num>{secretaryMax}</num> を越えます"); return; } var cost = Config.SecretaryCost; if (character.Money < cost && country.SafeMoney < cost) { await game.CharacterLogAsync($"政務官を雇おうとしましたが、武将所持または国庫に金 <num>{cost}</num> がありません"); return; } if (country.SafeMoney >= cost) { country.SafeMoney -= cost; } else { character.Money -= cost; } var system = await repo.System.GetAsync(); var ai = AiCharacterFactory.Create(type); ai.Initialize(game.GameDateTime); ai.Character.CountryId = character.CountryId; ai.Character.TownId = (type != CharacterAiType.SecretaryUnitLeader && targetTownOptional.HasData) ? targetTownId : country.CapitalTownId; ai.Character.Money = 10000; ai.Character.Rice = 10000; if (type == CharacterAiType.SecretaryEvangelist) { ai.Character.Religion = country.Religion; ai.Character.From = country.Religion == ReligionType.Confucianism ? CharacterFrom.Confucianism : country.Religion == ReligionType.Taoism ? CharacterFrom.Taoism : CharacterFrom.Buddhism; } if (type != CharacterAiType.SecretaryScouter) { ai.Character.LastUpdated = character.LastUpdated.AddSeconds(Config.UpdateTime + 10); if (ai.Character.LastUpdated > system.CurrentMonthStartDateTime.AddSeconds(Config.UpdateTime)) { ai.Character.LastUpdatedGameDate = game.GameDateTime.NextMonth(); } else { ai.Character.LastUpdatedGameDate = game.GameDateTime; } } else { // 斥候は0分0秒更新で諜報する ai.Character.LastUpdated = system.CurrentMonthStartDateTime.AddSeconds(Config.UpdateTime); ai.Character.LastUpdatedGameDate = game.GameDateTime.NextMonth(); } await repo.Character.AddAsync(ai.Character); await repo.SaveChangesAsync(); await AiService.SetIconAsync(repo, ai.Character); if (type == CharacterAiType.SecretaryUnitLeader) { await UnitService.CreateAndSaveAsync(repo, new Unit { CountryId = character.CountryId, IsLimited = false, Name = "政務官部隊 ID:" + ai.Character.Id, }, ai.Character.Id); } ai.Character.Name += ai.Character.Id; character.Contribution += 30; character.AddLeadershipEx(50); character.SkillPoint++; if (targetTownOptional.HasData && type != CharacterAiType.SecretaryUnitLeader) { await game.CharacterLogAsync($"政務官 <character>{ai.Character.Name}</character> を <town>{targetTownOptional.Data.Name}</town> で雇いました"); } else { await game.CharacterLogAsync($"政務官 <character>{ai.Character.Name}</character> を雇いました"); } await game.MapLogAsync(EventType.SecretaryAdded, $"<country>{country.Name}</country> は、新しく政務官 <character>{ai.Character.Name}</character> を雇いました", false); await CharacterService.StreamCharacterAsync(repo, ai.Character); }