/// <summary> /// Players turn processing /// </summary> /// <param name="player"></param> /// <param name="request"></param> public void ProcessBlockSwap(Player player, BlockSwapRequest request) { if (player.CurrentMatch == null) { Console.WriteLine($"Player {player.ClientID} is not in the game"); return; } GameMatch match = player.CurrentMatch; Field playerField = match.Player1 == player ? match.Field1 : match.Field2; Field enemyField = match.Player1 == player ? match.Field2 : match.Field1; Player enemy = match.Player1 == player ? match.Player2 : match.Player1; List <EffectData> effectsData = new List <EffectData>(); FieldManager.RefreshGlobalEffects(playerField, player); FieldManager.RefreshGlobalEffects(enemyField, enemy); if (!player.TrySpendMana(player.BlockSwapCost)) { SendError(player, ErrorType.NotEnoughMana); return; } else { EffectData hData = new EffectData(); hData.EffectType = EffectType.ManaChanged; hData.Data = new Dictionary <string, object>(); hData.Data["Target"] = player.InGameID; hData.Data["Value"] = -player.BlockSwapCost; effectsData.Add(hData); } FieldManager.RefreshDurationEffects(playerField); FieldManager.RefreshDurationEffects(enemyField); if (!FieldManager.TryRebuildFieldFromSwap(playerField, new Swap(request.X, request.Y, request.Direction), out List <Block> blocks)) { SendError(player, ErrorType.ImpossibleTurn); } List <Combo> combos = FieldManager.CheckForCombos(playerField, blocks); foreach (Combo combo in combos) { FieldManager.DestroyBlocks(enemyField, combo.Blocks, BlockState.DestroyedAsCombo); effectsData.AddRange(BlockEffectsManager.ApplyEffectsFromCombo(match, match.Player1 == player ? 1 : 2, combo)); } effectsData.AddRange(FieldManager.ClearDestroyedBlocks(playerField, match, player)); effectsData.AddRange(FieldManager.ClearDestroyedBlocks(enemyField, match, enemy)); FieldManager.FillHoles(playerField); FieldManager.FillHoles(enemyField); GameStateResponse response = new GameStateResponse { GameState = GetPlayer1MatchStateData(match), Effects = effectsData.ToArray() }; Server.SendDataToClient(match.Player1.ClientID, (int)DataTypes.GameStateResponse, response); if (match.GameMode == GameMode.Practice) { FieldManager.SetDefaultState(playerField); FieldManager.SetDefaultState(enemyField); if (CheckForGameEnd(match, out GameEndResponse gameEndResponseDebug)) { GiveMatchReward(match, gameEndResponseDebug.PlayerWon); RecalculateRating(match, gameEndResponseDebug.PlayerWon); PlayersManager.UpdatePlayer(match.Player1); MatchManager.DropMatch(player.CurrentMatch); gameEndResponseDebug.PlayerStats = match.Player1.GetStatsData(); Server.SendDataToClient(match.Player1.ClientID, (int)DataTypes.GameEndResponse, gameEndResponseDebug); } return; } response = new GameStateResponse { GameState = GetPlayer2MatchStateData(match), Effects = effectsData.ToArray() }; Server.SendDataToClient(match.Player2.ClientID, (int)DataTypes.GameStateResponse, response); FieldManager.SetDefaultState(playerField); effectsData.AddRange(FieldManager.ClearDestroyedBlocks(playerField, match, player)); FieldManager.SetDefaultState(enemyField); effectsData.AddRange(FieldManager.ClearDestroyedBlocks(enemyField, match, enemy)); if (CheckForGameEnd(match, out GameEndResponse gameEndResponse)) { GiveMatchReward(match, gameEndResponse.PlayerWon); RecalculateRating(match, gameEndResponse.PlayerWon); PlayersManager.UpdatePlayer(match.Player1); PlayersManager.UpdatePlayer(match.Player2); MatchManager.DropMatch(player.CurrentMatch); gameEndResponse.PlayerStats = match.Player1.GetStatsData(); Server.SendDataToClient(match.Player1.ClientID, (int)DataTypes.GameEndResponse, gameEndResponse); gameEndResponse.PlayerStats = match.Player2.GetStatsData(); Server.SendDataToClient(match.Player2.ClientID, (int)DataTypes.GameEndResponse, gameEndResponse); return; } }