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); }
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); }
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); }
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 }; }) }); }
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 }); }
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); }
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] }); }
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] }); }