public async Task SetCountryPolicyAsync( [FromBody] CountryPolicy param) { ErrorCode.NotSupportedError.Throw(); var info = CountryPolicyTypeInfoes.Get(param.Type); if (!info.HasData) { ErrorCode.InvalidParameterError.Throw(); } using (var repo = MainRepository.WithReadAndWrite()) { var system = await repo.System.GetAsync(); var chara = await repo.Character.GetByIdAsync(this.AuthData.CharacterId).GetOrErrorAsync(ErrorCode.LoginCharacterNotFoundError); var country = await repo.Country.GetAliveByIdAsync(chara.CountryId).GetOrErrorAsync(ErrorCode.CountryNotFoundError); var posts = await repo.Country.GetCharacterPostsAsync(chara.Id); if (!posts.Any(p => p.Type.CanPolicy())) { ErrorCode.NotPermissionError.Throw(); } var isSucceed = await CountryService.SetPolicyAndSaveAsync(repo, country, param.Type); if (!isSucceed) { ErrorCode.InvalidOperationError.Throw(); } } }
private static async Task RunCountryPolicyAsync(MainRepository repo, Country country, CountryPolicyType type) { if (type == CountryPolicyType.TotalMobilization || type == CountryPolicyType.TotalMobilization2) { foreach (var chara in await repo.Country.GetCharactersAsync(country.Id)) { chara.SoldierNumber = chara.Leadership; chara.Proficiency = 100; var formation = await repo.Character.GetFormationAsync(chara.Id, chara.FormationType); formation.Experience += 5000; await CharacterService.StreamCharacterAsync(repo, chara); await StatusStreaming.Default.SendCharacterAsync(ApiData.From(formation), chara.Id); } await LogService.AddMapLogAsync(repo, true, EventType.Policy, $"<country>{country.Name}</country> は、国民総動員を発動しました"); } else if (type == CountryPolicyType.TotalMobilizationWall || type == CountryPolicyType.TotalMobilizationWall2) { foreach (var town in await repo.Town.GetByCountryIdAsync(country.Id)) { town.Technology = town.TechnologyMax; town.Wall = town.WallMax; await StatusStreaming.Default.SendTownToAllAsync(ApiData.From(town), repo); } await LogService.AddMapLogAsync(repo, true, EventType.Policy, $"<country>{country.Name}</country> は、城壁作業員総動員を発動しました"); } else if (type == CountryPolicyType.Austerity || type == CountryPolicyType.Austerity2) { foreach (var chara in await repo.Country.GetCharactersAsync(country.Id)) { chara.Money += 20_0000; await CharacterService.StreamCharacterAsync(repo, chara); } await LogService.AddMapLogAsync(repo, true, EventType.Policy, $"<country>{country.Name}</country> は、緊縮財政を発動しました"); } var info = CountryPolicyTypeInfoes.Get(type); if (info.HasData && info.Data.Effects.Any(e => e.Type == CountryPolicyEffectType.SubBuildingSizeMax)) { country.TownSubBuildingExtraSpace += (short)info.Data.Effects .Where(e => e.Type == CountryPolicyEffectType.SubBuildingSizeMax) .Sum(e => e.Value); } }
public static async Task <bool> SetPolicyAndSaveAsync(MainRepository repo, Country country, CountryPolicyType type, CountryPolicyStatus status = CountryPolicyStatus.Available, bool isCheckSubjects = true) { return(true); var info = CountryPolicyTypeInfoes.Get(type); if (!info.HasData) { return(false); } var policies = await repo.Country.GetPoliciesAsync(country.Id); var old = policies.FirstOrDefault(p => p.Type == type); if (old != null && old.Status == CountryPolicyStatus.Available) { return(false); } var oldStatus = old?.Status ?? CountryPolicyStatus.Unadopted; if (status == CountryPolicyStatus.Available && country.PolicyPoint < info.Data.GetRequestedPoint(oldStatus)) { return(false); } if (isCheckSubjects && info.Data.SubjectAppear != null && !info.Data.SubjectAppear(policies.Where(p => p.Status == CountryPolicyStatus.Available).Select(p => p.Type))) { return(false); } var system = await repo.System.GetAsync(); var param = new CountryPolicy { CountryId = country.Id, Status = status, Type = type, GameDate = system.GameDateTime.Year >= Config.UpdateStartYear ? system.GameDateTime : new GameDateTime { Year = Config.UpdateStartYear, Month = 1, }, }; if (status == CountryPolicyStatus.Available) { country.PolicyPoint -= info.Data.GetRequestedPoint(oldStatus); if (info.Data.AvailableDuring > 0) { status = param.Status = CountryPolicyStatus.Availabling; } // 採用した瞬間に効果を発揮する政策 await RunCountryPolicyAsync(repo, country, type); } if (old != null) { repo.Country.RemovePolicy(old); } await repo.Country.AddPolicyAsync(param); await repo.SaveChangesAsync(); await StatusStreaming.Default.SendCountryAsync(ApiData.From(param), country.Id); await StatusStreaming.Default.SendCountryAsync(ApiData.From(country), country.Id); await StatusStreaming.Default.SendAllAsync(ApiData.From(new CountryForAnonymous(country))); foreach (CountryPolicyType boostType in info.Data.Effects.Where(e => e.Type == CountryPolicyEffectType.BoostWith).Select(e => e.Value)) { var boostInfo = CountryPolicyTypeInfoes.Get(boostType); if (boostInfo.HasData) { await SetPolicyAndSaveAsync(repo, country, boostType, CountryPolicyStatus.Boosted); } } return(true); }
public override async Task ExecuteAsync(MainRepository repo, Character character, IEnumerable <CharacterCommandParameter> options, CommandSystemData game) { if (character.Money < 50) { await game.CharacterLogAsync($"金が足りません。<num>50</num> 必要です"); return; } var townOptional = await repo.Town.GetByIdAsync(character.TownId); if (townOptional.HasData) { var countryOptional = await repo.Country.GetAliveByIdAsync(character.CountryId); if (!countryOptional.HasData) { await game.CharacterLogAsync($"政策開発しようとしましたが、無所属は実行できません"); return; } var country = countryOptional.Data; var town = townOptional.Data; var isWandering = false; if (town.CountryId != character.CountryId) { var townsCount = await repo.Town.CountByCountryIdAsync(character.CountryId); if (townsCount > 0) { await game.CharacterLogAsync("<town>" + town.Name + "</town>で政策開発しようとしましたが、自国の都市ではありません"); return; } else { // 放浪軍による政策開発 isWandering = true; } } var skills = await repo.Character.GetSkillsAsync(character.Id); // 内政値に加算する // $kgat += int($klea/6 + rand($klea/6)); var current = country.PolicyPoint; var attribute = Math.Max(character.Strong, character.Intellect); var add = (int)(attribute / 20.0f + RandomService.Next(0, attribute / 40)); if (add < 1) { add = 1; } country.PolicyPoint += add; // 政策ブースト if (RandomService.Next(0, 1000) <= skills.GetSumOfValues(CharacterSkillEffectType.PolicyBoostProbabilityThousandth)) { var policies = await repo.Country.GetPoliciesAsync(country.Id); var allPolicies = CountryPolicyTypeInfoes.GetAll(); var notPolicies = allPolicies.Where(pi => pi.CanBoost && !policies.Any(p => p.Status != CountryPolicyStatus.Unadopted && p.Status != CountryPolicyStatus.Boosting && p.Type == pi.Type)); if (notPolicies.Any()) { var info = RandomService.Next(notPolicies); await CountryService.SetPolicyAndSaveAsync(repo, country, info.Type, CountryPolicyStatus.Boosted, false); await game.CharacterLogAsync($"<country>{country.Name}</country> の政策 {info.Name} について新しい知見を得、政策をブーストしました"); } } // 経験値、金の増減 character.Contribution += 30; character.SkillPoint++; character.Money -= 50; if (character.Strong > character.Intellect) { character.AddStrongEx(50); } else { character.AddIntellectEx(50); } if (isWandering) { await game.CharacterLogAsync($"<country>{country.Name}</country> の政策ポイントを <num>+{add}</num> 上げました。合計: <num>{country.PolicyPoint}</num>"); } else { await game.CharacterLogAsync($"<country>{country.Name}</country> の政策ポイントを <num>+{add}</num> 上げました"); } if (RandomService.Next(0, 256) == 0) { var info = await ItemService.PickTownHiddenItemAsync(repo, character.TownId, character); if (info.HasData) { await game.CharacterLogAsync($"<town>{town.Name}</town> に隠されたアイテム {info.Data.Name} を手に入れました"); } } await StatusStreaming.Default.SendCountryAsync(ApiData.From(country), country.Id); } else { await game.CharacterLogAsync("ID:" + character.TownId + " の都市は存在しません。<emerge>管理者にお問い合わせください</emerge>"); } }