コード例 #1
0
            public async Task <Unit> Handle(SurrenderAllGamesCommand request, CancellationToken cancellationToken)
            {
                var gameIds = await _gameContext.GameMeta.GetAsync(x => x.UserName == request.UserName, x => x.Id, cancellationToken);

                _gameContext.GameMeta.Delete(x => x.UserName == request.UserName);
                _gameContext.SceneSegments.Delete(x => gameIds.Contains(x.Id));
                await _gameContext.ApplyChangesAsync(cancellationToken);

                return(Unit.Value);
            }
コード例 #2
0
ファイル: CreateNewGameCommand.cs プロジェクト: Ig101/TheCoil
            public async Task <Unit> Handle(CreateNewGameCommand request, CancellationToken cancellationToken)
            {
                var random   = new Random();
                var gameMeta = new GameMeta()
                {
                    Id          = Guid.NewGuid(),
                    UserName    = request.UserName,
                    Session     = Guid.NewGuid().ToString(),
                    Incrementor = 2,
                    Width       = Consts.MapWidth,
                    Height      = Consts.MapHeight,
                    Turn        = 0,
                    GameState   = GameState.Pending,
                    PlayerScene = Consts.InitialSceneId,
                    StartDate   = DateTime.Now,
                    LastDate    = DateTime.Now,
                    PlayerActor = new Actor()
                    {
                        Id       = 1,
                        X        = Consts.PlayerInitialX,
                        Y        = Consts.PlayerInitialY,
                        Name     = request.PlayerName,
                        NativeId = Consts.PlayerNativeId
                    }
                };

                _gameContext.GameMeta.InsertOne(gameMeta);
                var sceneSegment = await _mediator.Send(new GenerateNewSegmentCommand()
                {
                    GameId  = gameMeta.Id,
                    SceneId = Consts.InitialSceneId,
                    Seed    = random.Next()
                });

                _gameContext.SceneSegments.InsertOne(sceneSegment);
                await _gameContext.ApplyChangesAsync(cancellationToken);

                return(Unit.Value);
            }
コード例 #3
0
            public async Task <Unit> Handle(SurrenderGameCommand request, CancellationToken cancellationToken)
            {
                var check = await _gameContext.GameMeta.GetOneAsync(
                    x => x.Id == request.GameId && x.UserName == request.UserName,
                    x => (Guid?)x.Id,
                    cancellationToken);

                if (check == null)
                {
                    throw new HttpException()
                          {
                              StatusCode = 404,
                              Error      = "Game is not found."
                          };
                }

                _gameContext.GameMeta.Delete(x => x.Id == request.GameId);
                _gameContext.SceneSegments.Delete(x => x.GameId == request.GameId);
                await _gameContext.ApplyChangesAsync(cancellationToken);

                return(Unit.Value);
            }
コード例 #4
0
            public async Task <ActiveUserDto> Handle(GetActiveUserQuery request, CancellationToken cancellationToken)
            {
                var user = await _userManager.GetUserAsync(request.User);

                var statusInBattle = _battleService.IsUserInBattle(user.Id);
                var roster         = await _gameContext.Rosters.GetOneAsync(x => x.UserId == user.Id);

                IEnumerable <Character> characters;

                if (roster == null)
                {
                    roster = new Roster()
                    {
                        Id             = user.Id,
                        UserId         = user.Id,
                        Experience     = 0,
                        Seed           = user.Id.GetHashCode(),
                        TavernCapacity = 6,
                        BoughtPatrons  = new int[0]
                    };
                    _gameContext.Rosters.InsertOne(roster);
                    var userCharacter = new Character()
                    {
                        Id             = Guid.NewGuid().ToString(),
                        Deleted        = false,
                        IsKeyCharacter = true,
                        RosterId       = roster.Id,
                        Name           = user.ViewName,
                        ChosenTalents  = new int[0]
                    };
                    _gameContext.Characters.InsertOne(userCharacter);
                    characters = new Character[] { userCharacter };
                    await _gameContext.ApplyChangesAsync();
                }
                else
                {
                    characters = await _gameContext.Characters.GetAsync(x => x.RosterId == roster.Id && !x.Deleted);
                }

                var tavern = new List <CharacterForSaleDto>();

                for (int i = 1; i <= roster.TavernCapacity; i++)
                {
                    if (!roster.BoughtPatrons.Any(x => x == i))
                    {
                        tavern.Add(new CharacterForSaleDto()
                        {
                            Id = i
                        });
                    }
                }

                var talents = await _registryContext.TalentMap.GetAsync(x => true);

                return(new ActiveUserDto()
                {
                    Name = user.ViewName,
                    UniqueId = user.UserName,
                    Id = user.Id,
                    Email = user.Email,
                    State = statusInBattle ? UserState.Battle : UserState.Lobby,
                    Experience = roster.Experience,
                    Tavern = tavern,
                    Roster = characters.Select(x =>
                    {
                        return new CharacterDto()
                        {
                            Id = x.Id,
                            Name = x.Name,
                            IsKeyCharacter = x.IsKeyCharacter,
                            Talents = x.ChosenTalents.Select(k =>
                            {
                                var coordinates = TalentPositionHelper.GetCoordinatesFromPosition(k);
                                return new PointDto()
                                {
                                    X = coordinates.x,
                                    Y = coordinates.y
                                };
                            })
                        };
                    }),
                    TalentsMap = talents.Select(x =>
                    {
                        var position = TalentPositionHelper.GetCoordinatesFromPosition(x.Position);
                        return new TalentNodeDto()
                        {
                            X = position.x,
                            Y = position.y,
                            Name = x.Name,
                            Description = x.UniqueDescription,
                            Id = x.Id,
                            Speed = x.SpeedModifier,
                            Strength = x.StrengthModifier,
                            Willpower = x.WillpowerModifier,
                            Constitution = x.ConstitutionModifier,
                            Class = x.Class,
                            ClassPoints = x.ClassPoints,
                            Prerequisites = x.Prerequisites,
                            Exceptions = x.Exceptions,
                            SkillsAmount = x.SkillsAmount
                        };
                    })
                });
            }
コード例 #5
0
            public async Task <NewCharacterDto> Handle(HirePatronCommand request, CancellationToken cancellationToken)
            {
                if (_queueService.IsUserInQueue(request.UserId) != null || _battleService.IsUserInBattle(request.UserId))
                {
                    throw new CannotPerformOperationException("User cannot do that in queue or battle.");
                }

                var roster = await _gameContext.Rosters.GetOneAsync(x => x.UserId == request.UserId);

                var characters = await _gameContext.Characters.GetAsync(x => x.RosterId == roster.Id);

                if (characters.Count() < 3 && request.CharacterForReplace != null)
                {
                    throw new CannotPerformOperationException("Cannot fire character while roster is not full.");
                }

                if (characters.Count() >= 3 && request.CharacterForReplace == null)
                {
                    throw new CannotPerformOperationException("Need character to fire while roster is not full.");
                }

                if (request.CharacterForReplace != null && !characters.Any(x => x.Id == request.CharacterForReplace))
                {
                    throw new CannotPerformOperationException("Firing character is not yours.");
                }

                if (roster.BoughtPatrons.Contains(request.PatronId) || request.PatronId > roster.TavernCapacity || request.PatronId < 1)
                {
                    throw new CannotPerformOperationException("Patron has already been hired.");
                }

                var characterForReplace = characters.FirstOrDefault(x => x.Id == request.CharacterForReplace);

                if (request.CharacterForReplace != null && characterForReplace.IsKeyCharacter)
                {
                    throw new CannotPerformOperationException("Cannot fire key character");
                }

                _gameContext.Rosters.Update(
                    x => x.UserId == roster.UserId,
                    Builders <Roster> .Update.Set(x => x.BoughtPatrons, roster.BoughtPatrons.Append(request.PatronId)));
                var character = new Character()
                {
                    Id             = characterForReplace != null ? characterForReplace.Id : Guid.NewGuid().ToString(),
                    Deleted        = false,
                    IsKeyCharacter = false,
                    RosterId       = roster.Id,
                    Name           = request.Name.Trim(),
                    ChosenTalents  = new int[0]
                };

                if (request.CharacterForReplace != null)
                {
                    _gameContext.Characters.ReplaceOne(x => x.Id == request.CharacterForReplace, character, true);
                }
                else
                {
                    _gameContext.Characters.InsertOne(character);
                }

                await _gameContext.ApplyChangesAsync(cancellationToken);

                return(new NewCharacterDto()
                {
                    Id = character.Id
                });
            }
コード例 #6
0
            public async Task <Unit> Handle(ChangeCharacterTalentsCommand request, CancellationToken cancellationToken)
            {
                var roster = await _gameContext.Rosters.GetOneAsync(x => x.UserId == request.UserId);

                if (roster == null)
                {
                    throw new NotFoundException("User is not found");
                }

                var character = await _gameContext.Characters.GetOneAsync(x => x.Id == request.CharacterId);

                if (character == null)
                {
                    throw new NotFoundException("Character is not found");
                }

                if (character.RosterId != roster.Id)
                {
                    throw new CannotPerformOperationException("Character is not belong to user");
                }

                var changedTalentPositions = request.Changes.Select(x => TalentPositionHelper.GetPositionFromCoordinates(x.X, x.Y)).ToList();
                var allTalentPositions     = character.ChosenTalents.Union(changedTalentPositions).Distinct().ToList();
                var allTalents             = await _registryContext.TalentMap.GetAsync(x => allTalentPositions.Contains(x.Position));

                var characterTalents = allTalents.Where(x => character.ChosenTalents.Contains(x.Position)).ToList();

                var strength     = BattleHelper.DefaultStrength;
                var willpower    = BattleHelper.DefaultWillpower;
                var constitution = BattleHelper.DefaultConstitution;
                var speed        = BattleHelper.DefaultSpeed;
                var skillsCount  = 1;
                var cost         = 0;
                var talentsCount = 0;

                characterTalents.ForEach(x =>
                {
                    strength     += x.StrengthModifier;
                    willpower    += x.WillpowerModifier;
                    constitution += x.ConstitutionModifier;
                    speed        += x.SpeedModifier;
                    skillsCount  += x.SkillsAmount;
                    talentsCount++;
                });

                var newTalents = new List <TalentNodeChangeDeclarationDto>();

                foreach (var change in request.Changes)
                {
                    var changePosition = TalentPositionHelper.GetPositionFromCoordinates(change.X, change.Y);

                    // Accessibility check
                    TalentNodeChangeDeclarationDto talent;
                    if ((talent = newTalents.FirstOrDefault(x => x.X == change.X && x.Y == change.Y)) != null)
                    {
                        if (change.State == talent.State)
                        {
                            throw new CannotPerformOperationException("Cannot do the same action with talent twice");
                        }

                        cost--;
                        newTalents.Remove(talent);
                    }
                    else
                    {
                        if (characterTalents.Any(x => x.Position == changePosition) == change.State)
                        {
                            throw new CannotPerformOperationException("Cannot do action with talent");
                        }

                        cost++;
                        newTalents.Add(change);
                    }

                    var changeTalent = allTalents.First(x => x.Position == changePosition);

                    // ConditionalsCheck
                    if (change.State)
                    {
                        if (!((Math.Abs(change.X - _centerX) == 1 && change.Y == _centerY) || (Math.Abs(change.Y - _centerY) == 1 && change.X == _centerX)) &&
                            !characterTalents.Any(x =>
                        {
                            var talentCoordinates = TalentPositionHelper.GetCoordinatesFromPosition(x.Position);
                            return((Math.Abs(change.X - talentCoordinates.x) == 1 && change.Y == talentCoordinates.y) ||
                                   (Math.Abs(change.Y - talentCoordinates.y) == 1 && change.X == talentCoordinates.x));
                        }))
                        {
                            throw new CannotPerformOperationException("Cannot pick remote talent");
                        }

                        if (changeTalent.Exceptions != null && characterTalents.Any(x => changeTalent.Exceptions.Contains(x.Id)))
                        {
                            throw new CannotPerformOperationException("Cannot add talent with unprocessible exceptions");
                        }

                        if (changeTalent.Prerequisites != null && changeTalent.Prerequisites.Any(x => !characterTalents.Any(t => t.Id == x)))
                        {
                            throw new CannotPerformOperationException("Cannot add talent with unresolved prerequisites");
                        }

                        talentsCount++;
                        strength     += changeTalent.StrengthModifier;
                        willpower    += changeTalent.WillpowerModifier;
                        constitution += changeTalent.ConstitutionModifier;
                        speed        += changeTalent.SpeedModifier;
                        skillsCount  += changeTalent.SkillsAmount;

                        characterTalents.Add(changeTalent);
                    }
                    else
                    {
                        talentsCount--;
                        strength     -= changeTalent.StrengthModifier;
                        willpower    -= changeTalent.WillpowerModifier;
                        constitution -= changeTalent.ConstitutionModifier;
                        speed        -= changeTalent.SpeedModifier;
                        skillsCount  -= changeTalent.SkillsAmount;

                        characterTalents.Remove(characterTalents.First(x => x.Position == changePosition));

                        var leftTalent = characterTalents.FirstOrDefault(x =>
                        {
                            var coordinates = TalentPositionHelper.GetCoordinatesFromPosition(x.Position);
                            return(coordinates.x == change.X + 1 && coordinates.y == change.Y);
                        });
                        var rightTalent = characterTalents.FirstOrDefault(x =>
                        {
                            var coordinates = TalentPositionHelper.GetCoordinatesFromPosition(x.Position);
                            return(coordinates.x == change.X - 1 && coordinates.y == change.Y);
                        });
                        var topTalent = characterTalents.FirstOrDefault(x =>
                        {
                            var coordinates = TalentPositionHelper.GetCoordinatesFromPosition(x.Position);
                            return(coordinates.x == change.X && coordinates.y == change.Y - 1);
                        });
                        var bottomTalent = characterTalents.FirstOrDefault(x =>
                        {
                            var coordinates = TalentPositionHelper.GetCoordinatesFromPosition(x.Position);
                            return(coordinates.x == change.X && coordinates.y == change.Y + 1);
                        });
                        if ((leftTalent != null && !FindPath(leftTalent, characterTalents, new List <TalentNode>())) ||
                            (rightTalent != null && !FindPath(rightTalent, characterTalents, new List <TalentNode>())) ||
                            (topTalent != null && !FindPath(topTalent, characterTalents, new List <TalentNode>())) ||
                            (bottomTalent != null && !FindPath(bottomTalent, characterTalents, new List <TalentNode>())))
                        {
                            throw new CannotPerformOperationException("Remains talents without bonds");
                        }
                    }

                    if (talentsCount > _talentsMaxCount)
                    {
                        throw new CannotPerformOperationException("Extra talents");
                    }

                    if (cost > roster.Experience)
                    {
                        throw new CannotPerformOperationException("Not enough money");
                    }

                    if (strength < 5 || willpower < 5 || constitution < 5 || speed < 5)
                    {
                        throw new CannotPerformOperationException("Stats cannot be less than five");
                    }

                    if (skillsCount > 5)
                    {
                        throw new CannotPerformOperationException("Skills amount cannot be more than 5");
                    }
                }

                foreach (var change in newTalents)
                {
                    if (change.State)
                    {
                        _gameContext.Characters.Update(
                            x => x.Id == character.Id,
                            Builders <Character> .Update.Push(k => k.ChosenTalents, TalentPositionHelper.GetPositionFromCoordinates(change.X, change.Y)));
                    }
                    else
                    {
                        _gameContext.Characters.Update(
                            x => x.Id == character.Id,
                            Builders <Character> .Update.Pull(k => k.ChosenTalents, TalentPositionHelper.GetPositionFromCoordinates(change.X, change.Y)));
                    }
                }

                _gameContext.Rosters.Update(
                    x => x.UserId == roster.UserId,
                    Builders <Roster> .Update.Set(k => k.Experience, roster.Experience - cost));

                await _gameContext.ApplyChangesAsync();

                return(Unit.Value);
            }
コード例 #7
0
            public async Task <FullGameStateDto> Handle(GetPlayerGameSavedDataQuery request, CancellationToken cancellationToken)
            {
                var gameState = await _gameContext.GameMeta.GetOneAsync(x => x.Id == request.GameId && x.UserName == request.UserName, cancellationToken);

                if (gameState == null)
                {
                    throw new HttpException()
                          {
                              StatusCode = 404,
                              Error      = "Game is not found."
                          };
                }

                var currentPlayerScene = await _gameContext.SceneSegments.GetOneAsync(
                    x => x.GameId == request.GameId && x.SceneId == gameState.PlayerScene, cancellationToken);

                if (currentPlayerScene == null)
                {
                    _gameContext.GameMeta.Delete(x => x.Id == request.GameId);
                    _gameContext.SceneSegments.Delete(x => x.GameId == request.GameId);
                    await _gameContext.ApplyChangesAsync(cancellationToken);

                    throw new HttpException()
                          {
                              StatusCode = 500,
                              Error      = "Game is broken."
                          };
                }

                var random = new Random();

                var playerScenes = await _gameContext.SceneSegments.GetAsync(
                    x => x.GameId == request.GameId && (x.SceneId == currentPlayerScene.NextSceneId || x.NextSceneId == currentPlayerScene.SceneId), cancellationToken);

                if (currentPlayerScene.NextSceneId != null && !playerScenes.Any(x => x.SceneId == currentPlayerScene.NextSceneId))
                {
                    // NextLevel
                    var segment = await _mediator.Send(new GenerateNewSegmentCommand()
                    {
                        GameId  = request.GameId,
                        SceneId = currentPlayerScene.NextSceneId.Value,
                        Seed    = random.Next()
                    });

                    if (segment != null)
                    {
                        _gameContext.SceneSegments.InsertOne(segment);
                        playerScenes = playerScenes.Append(segment);
                    }
                }

                if (!playerScenes.Any(x => x.NextSceneId == currentPlayerScene.SceneId))
                {
                    // PreviousLevel
                    var segment = await _mediator.Send(new GenerateNewSegmentCommand()
                    {
                        GameId    = request.GameId,
                        SceneId   = currentPlayerScene.NextSceneId.Value,
                        NextScene = true,
                        Seed      = random.Next()
                    });

                    if (segment != null)
                    {
                        _gameContext.SceneSegments.InsertOne(segment);
                        playerScenes = playerScenes.Append(segment);
                    }
                }

                playerScenes = playerScenes.Append(currentPlayerScene).ToList();
                var session = Guid.NewGuid().ToString();

                _gameContext.GameMeta.Update(
                    x => x.Id == request.GameId,
                    new UpdateDefinitionBuilder <GameMeta>().Set(x => x.Session, session));
                await _gameContext.ApplyChangesAsync(cancellationToken);

                return(new FullGameStateDto()
                {
                    Player = new PlayerDto()
                    {
                        Scene = gameState.PlayerScene,
                        Actor = new ActorDto()
                        {
                            Id = gameState.PlayerActor.Id,
                            X = gameState.PlayerActor.X,
                            Y = gameState.PlayerActor.Y,
                            Name = gameState.PlayerActor.Name,
                            NativeId = gameState.PlayerActor.NativeId,
                            Durability = gameState.PlayerActor.Durability,
                            Energy = gameState.PlayerActor.Energy,
                            RemainedTurnTime = gameState.PlayerActor.RemainedTurnTime
                        }
                    },
                    MetaInformation = new MetaInformationDto()
                    {
                        GameId = request.GameId,
                        Session = session,
                        Incrementor = gameState.Incrementor,
                        Height = gameState.Height,
                        Width = gameState.Width,
                        Turn = gameState.Turn,
                        GameState = gameState.GameState
                    },
                    SceneSegments = playerScenes.Select(x => new SceneSegmentDto()
                    {
                        Seed = x.Seed,
                        RoomType = x.RoomType,
                        Difficulty = x.Difficulty,
                        LastSaveTurn = x.LastSaveTurn,
                        Actors = x.Actors.Select(actor => new ActorDto()
                        {
                            Id = actor.Id,
                            X = actor.X,
                            Y = actor.Y,
                            Name = actor.Name,
                            NativeId = actor.NativeId,
                            Durability = actor.Durability,
                            Energy = actor.Energy,
                            RemainedTurnTime = actor.RemainedTurnTime
                        }),
                        Tiles = x.Tiles.Select(tile => new TileDto()
                        {
                            X = tile.X,
                            Y = tile.Y,
                            NativeId = tile.NativeId
                        }),
                        Id = x.SceneId,
                        NextId = x.NextSceneId
                    }),
                    UnsettledActors = new UnsettledActorDto[0]
                });
            }
コード例 #8
0
            public async Task <GameStateDto> Handle(SendGameSynchronizationInfoCommand request, CancellationToken cancellationToken)
            {
                var check = await _gameContext.GameMeta.GetOneAsync(
                    x => x.Id == request.GameId && x.Session == request.Session && x.UserName == request.UserName,
                    x => (Guid?)x.Id,
                    cancellationToken);

                if (check == null)
                {
                    throw new HttpException()
                          {
                              StatusCode = 404,
                              Error      = "Wrong session or game is not found."
                          };
                }

                var playerActor = request.Player.Actor;
                var update      = new UpdateDefinitionBuilder <GameMeta>()
                                  .Set(x => x.Incrementor, request.MetaInformation.Incrementor)
                                  .Set(x => x.LastDate, DateTime.Now)
                                  .Set(x => x.PlayerScene, request.Player.Scene)
                                  .Set(x => x.Turn, request.MetaInformation.Turn)
                                  .Set(x => x.PlayerActor, new Actor()
                {
                    Id               = playerActor.Id,
                    X                = playerActor.X,
                    Y                = playerActor.Y,
                    Name             = playerActor.Name,
                    NativeId         = playerActor.NativeId,
                    Durability       = playerActor.Durability,
                    Energy           = playerActor.Energy,
                    RemainedTurnTime = playerActor.RemainedTurnTime
                });

                _gameContext.GameMeta.Update(x => x.Id == request.GameId, update);
                foreach (var segment in request.SceneSegments)
                {
                    var sceneUpdate = new UpdateDefinitionBuilder <SceneSegment>()
                                      .Set(x => x.LastSaveTurn, segment.LastSaveTurn)
                                      .Set(x => x.NextSceneId, segment.NextId)
                                      .Set(x => x.Difficulty, segment.Difficulty)
                                      .Set(x => x.Actors, segment.Actors.Select(actor => new Actor()
                    {
                        Id               = actor.Id,
                        X                = actor.X,
                        Y                = actor.Y,
                        Name             = actor.Name,
                        NativeId         = actor.NativeId,
                        Durability       = actor.Durability,
                        Energy           = actor.Energy,
                        RemainedTurnTime = actor.RemainedTurnTime
                    }))
                                      .Set(x => x.Tiles, segment.Tiles.Select(tile => new Tile()
                    {
                        X        = tile.X,
                        Y        = tile.Y,
                        NativeId = tile.NativeId
                    }));
                    _gameContext.SceneSegments.Update(x => x.GameId == request.GameId && x.SceneId == segment.Id, sceneUpdate);
                }

                var random             = new Random();
                var currentPlayerScene = request.SceneSegments.FirstOrDefault(x => x.Id == request.Player.Scene);
                var newScenes          = new List <SceneSegment>();

                if (currentPlayerScene.NextId != null && !request.SceneSegments.Any(x => x.Id == currentPlayerScene.NextId))
                {
                    // NextLevel
                    var segment = await _gameContext.SceneSegments.GetOneAsync(
                        x => request.GameId == x.GameId && x.SceneId == currentPlayerScene.NextId, cancellationToken);

                    if (segment == null)
                    {
                        segment = await _mediator.Send(new GenerateNewSegmentCommand()
                        {
                            GameId  = request.GameId,
                            SceneId = currentPlayerScene.NextId.Value,
                            Seed    = random.Next()
                        });
                    }

                    if (segment != null)
                    {
                        _gameContext.SceneSegments.InsertOne(segment);
                        newScenes.Add(segment);
                    }
                }

                if (!request.SceneSegments.Any(x => x.NextId == currentPlayerScene.Id))
                {
                    // PreviousLevel
                    var segment = await _gameContext.SceneSegments.GetOneAsync(
                        x => request.GameId == x.GameId && x.NextSceneId == currentPlayerScene.Id, cancellationToken);

                    if (segment == null)
                    {
                        segment = await _mediator.Send(new GenerateNewSegmentCommand()
                        {
                            GameId    = request.GameId,
                            SceneId   = currentPlayerScene.NextId.Value,
                            NextScene = true,
                            Seed      = random.Next()
                        });
                    }

                    if (segment != null)
                    {
                        _gameContext.SceneSegments.InsertOne(segment);
                        newScenes.Add(segment);
                    }
                }

                await _gameContext.ApplyChangesAsync(cancellationToken);

                return(new GameStateDto()
                {
                    SceneSegments = newScenes.Select(x => new SceneSegmentDto()
                    {
                        Seed = x.Seed,
                        RoomType = x.RoomType,
                        Difficulty = x.Difficulty,
                        LastSaveTurn = x.LastSaveTurn,
                        Actors = x.Actors.Select(actor => new ActorDto()
                        {
                            Id = actor.Id,
                            X = actor.X,
                            Y = actor.Y,
                            Name = actor.Name,
                            NativeId = actor.NativeId,
                            Durability = actor.Durability,
                            Energy = actor.Energy,
                            RemainedTurnTime = actor.RemainedTurnTime
                        }),
                        Tiles = x.Tiles.Select(tile => new TileDto()
                        {
                            X = tile.X,
                            Y = tile.Y,
                            NativeId = tile.NativeId
                        }),
                        Id = x.SceneId,
                        NextId = x.NextSceneId
                    }),
                    UnsettledActors = new UnsettledActorDto[0]
                });
            }