예제 #1
0
        public override async Task ExecuteAsync(MainRepository repo, Character character, IEnumerable <CharacterCommandParameter> options, CommandSystemData game)
        {
            var system = await repo.System.GetAsync();

            var townOptional = await repo.Town.GetByIdAsync(character.TownId);

            var countryOptional = await repo.Country.GetAliveByIdAsync(character.CountryId);

            var directionOptional = options.FirstOrDefault(p => p.Type == 1).ToOptional();
            var townTypeOptional  = options.FirstOrDefault(p => p.Type == 2).ToOptional();

            if (character.Money < 50_0000 && system.RuleSet != GameRuleSet.SimpleBattle)
            {
                await game.CharacterLogAsync("都市建設しようとしましたが、金が足りません。<num>50 0000</num> 必要です");

                return;
            }

            if (!townOptional.HasData)
            {
                await game.CharacterLogAsync("ID:" + character.TownId + " の都市は存在しません。<emerge>管理者にお問い合わせください</emerge>");

                return;
            }
            var town = townOptional.Data;

            var countryName = countryOptional.Data?.Name ?? "無所属";

            if (!directionOptional.HasData)
            {
                await game.CharacterLogAsync("都市建設のパラメータが不正です。<emerge>管理者にお問い合わせください</emerge>");

                return;
            }
            var direction = (CreateTownDirection)directionOptional.Data.NumberValue;

            if (!townTypeOptional.HasData)
            {
                await game.CharacterLogAsync("都市建設のパラメータが不正です。<emerge>管理者にお問い合わせください</emerge>");

                return;
            }
            var townType = (TownType)townTypeOptional.Data.NumberValue;

            var items = await repo.Character.GetItemsAsync(character.Id);

            var item = items.FirstOrDefault(i => i.Type == CharacterItemType.CastleBlueprint);

            if (item == null)
            {
                await game.CharacterLogAsync("都市建設しようとしましたが、コマンド実行に必要なアイテムを所持していません");

                return;
            }

            if (system.RuleSet == GameRuleSet.SimpleBattle)
            {
                await game.CharacterLogAsync("都市建設しようとしましたが、原理ルールでは都市建設ができません。代わりに大都市計画書が与えられます");

                await ItemService.SpendCharacterAsync(repo, item, character);

                await ItemService.GenerateItemAndSaveAsync(repo, new CharacterItem
                {
                    CharacterId = character.Id,
                    Type        = CharacterItemType.LargeTownPlanningDocument,
                    Status      = CharacterItemStatus.CharacterHold,
                });

                return;
            }

            var x = (direction == CreateTownDirection.Left || direction == CreateTownDirection.LeftBottom || direction == CreateTownDirection.LeftTop) ? town.X - 1 :
                    (direction == CreateTownDirection.Right || direction == CreateTownDirection.RightBottom || direction == CreateTownDirection.RightTop) ? town.X + 1 : town.X;
            var y = (direction == CreateTownDirection.Top || direction == CreateTownDirection.LeftTop || direction == CreateTownDirection.RightTop) ? town.Y - 1 :
                    (direction == CreateTownDirection.Bottom || direction == CreateTownDirection.LeftBottom || direction == CreateTownDirection.RightBottom) ? town.Y + 1 : town.Y;

            if (x < 0 || x >= 10 || y < 0 || y >= 10)
            {
                await game.CharacterLogAsync($"<town>{town.Name}</town> の隣に都市を建設しようとしましたが、そこには建設できません");

                return;
            }

            var towns = await repo.Town.GetAllAsync();

            var tt = towns.FirstOrDefault(t => t.X == x && t.Y == y);

            if (tt != null)
            {
                await game.CharacterLogAsync($"<town>{town.Name}</town> の隣に都市を建設しようとしましたが、その方向には別の都市 <town>{tt.Name}</town> があります");

                return;
            }

            var isCapital = false;

            if (towns.Any(t => t.CountryId == character.CountryId))
            {
                if (town.CountryId != character.CountryId)
                {
                    await game.CharacterLogAsync($"<town>{town.Name}</town> の隣に都市を建設しようとしましたが、自国以外の国の都市から建設を行うことはできません");

                    return;
                }
            }
            else if (countryOptional.HasData && !countryOptional.Data.HasOverthrown)
            {
                isCapital = true;
            }

            var newTown = MapService.CreateTown(isCapital ? TownType.Large : townType);

            newTown.X                 = (short)x;
            newTown.Y                 = (short)y;
            newTown.Name              = MapService.GetTownName((short)x, (short)y);
            newTown.CountryId         = character.CountryId;
            newTown.UniqueCharacterId = item.UniqueCharacterId != 0 ? item.UniqueCharacterId : character.Id;
            if (isCapital)
            {
                newTown.SubType = townType;
            }
            await repo.Town.AddTownsAsync(new Town[] { newTown, });

            if (isCapital)
            {
                if (countryOptional.Data.Religion == ReligionType.Confucianism)
                {
                    newTown.Confucianism = 500;
                }
                if (countryOptional.Data.Religion == ReligionType.Taoism)
                {
                    newTown.Taoism = 500;
                }
                if (countryOptional.Data.Religion == ReligionType.Buddhism)
                {
                    newTown.Buddhism = 500;
                }
                await repo.SaveChangesAsync();

                countryOptional.Data.CapitalTownId = newTown.Id;
                await StatusStreaming.Default.SendCountryAsync(ApiData.From(countryOptional.Data), countryOptional.Data.Id);

                await StatusStreaming.Default.SendAllExceptForCountryAsync(ApiData.From(new CountryForAnonymous(countryOptional.Data)), countryOptional.Data.Id);
            }

            await AnonymousStreaming.Default.SendAllAsync(ApiData.From(newTown));

            await StatusStreaming.Default.SendTownToAllAsync(ApiData.From(newTown), repo);

            character.Money -= 50_0000;
            await ItemService.SpendCharacterAsync(repo, item, character);

            if (isCapital)
            {
                await game.MapLogAsync(EventType.NewTownForCapital, $"<country>{countryName}</country> の <character>{character.Name}</character> は新たな都市 <town>{newTown.Name}</town> を建設し、首都としました", true);
            }
            else
            {
                await game.MapLogAsync(EventType.NewTown, $"<country>{countryName}</country> の <character>{character.Name}</character> は新たな都市 <town>{newTown.Name}</town> を建設しました", true);
            }
            await game.CharacterLogAsync($"都市 <town>{newTown.Name}</town> を建設しました");
        }