139 lines
		
	
	
		
			3.3 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
			
		
		
	
	
			139 lines
		
	
	
		
			3.3 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
| using Fusion;
 | |
| using System.Collections.Generic;
 | |
| using UnityEngine;
 | |
| 
 | |
| namespace TPSBR
 | |
| {
 | |
| 	public class EliminationGameplayMode : GameplayMode
 | |
| 	{
 | |
| 		// PRIVATE MEMBERS
 | |
| 
 | |
| 		[SerializeField]
 | |
| 		private int _extraLives = 4;
 | |
| 
 | |
| 		private EliminationComparer _playerComparer = new EliminationComparer();
 | |
| 
 | |
| 		// GameplayMode INTERFACE
 | |
| 
 | |
| 		protected override void PreparePlayerStatistics(ref PlayerStatistics playerStatistics)
 | |
| 		{
 | |
| 			base.PreparePlayerStatistics(ref playerStatistics);
 | |
| 
 | |
| 			// Do not add extra lives after reconnect
 | |
| 			if (playerStatistics.Deaths == 0 && playerStatistics.IsEliminated == false && playerStatistics.ExtraLives == 0)
 | |
| 			{
 | |
| 				playerStatistics.ExtraLives = (short)GetExtraLivesForNewPlayer();
 | |
| 			}
 | |
| 		}
 | |
| 
 | |
| 		protected override float GetRespawnTime(PlayerStatistics playerStatistics)
 | |
| 		{
 | |
| 			if (playerStatistics.ExtraLives > 0)
 | |
| 				return base.GetRespawnTime(playerStatistics);
 | |
| 
 | |
| 			return -1f;
 | |
| 		}
 | |
| 
 | |
| 		protected override void AgentDeath(ref PlayerStatistics victimStatistics, ref PlayerStatistics killerStatistics)
 | |
| 		{
 | |
| 			base.AgentDeath(ref victimStatistics, ref killerStatistics);
 | |
| 
 | |
| 			if (victimStatistics.ExtraLives > 0)
 | |
| 			{
 | |
| 				victimStatistics.ExtraLives -= 1;
 | |
| 			}
 | |
| 		}
 | |
| 
 | |
| 		protected override void SortPlayers(List<PlayerStatistics> allStatistics)
 | |
| 		{
 | |
| 			allStatistics.Sort(_playerComparer);
 | |
| 		}
 | |
| 
 | |
| 		protected override void CheckWinCondition()
 | |
| 		{
 | |
| 			var alivePlayers    = 0;
 | |
| 			var lastAlivePlayer = PlayerRef.None;
 | |
| 
 | |
| 			foreach (var player in Context.NetworkGame.ActivePlayers)
 | |
| 			{
 | |
| 				if (player == null)
 | |
| 					continue;
 | |
| 
 | |
| 				var statistics = player.Statistics;
 | |
| 				if (statistics.ExtraLives > 0 || statistics.IsAlive == true || statistics.RespawnTimer.IsRunning == true)
 | |
| 				{
 | |
| 					if (alivePlayers > 0)
 | |
| 						return;
 | |
| 
 | |
| 					alivePlayers    += 1;
 | |
| 					lastAlivePlayer  = player.Object.InputAuthority;
 | |
| 				}
 | |
| 			}
 | |
| 
 | |
| 			if (alivePlayers == 1)
 | |
| 			{
 | |
| 				FinishGameplay();
 | |
| 				Log.Info($"Player {lastAlivePlayer} won the match!");
 | |
| 			}
 | |
| 			else if (alivePlayers == 0)
 | |
| 			{
 | |
| 				Log.Error("No player alive, this should not happen");
 | |
| 				FinishGameplay();
 | |
| 			}
 | |
| 		}
 | |
| 
 | |
| 		// PRIVATE METHODS
 | |
| 
 | |
| 		private int GetExtraLivesForNewPlayer()
 | |
| 		{
 | |
| 			int minExtraLives = int.MaxValue;
 | |
| 			int maxExtraLives = int.MinValue;
 | |
| 
 | |
| 			foreach (var player in Context.NetworkGame.ActivePlayers)
 | |
| 			{
 | |
| 				if (player == null)
 | |
| 					continue;
 | |
| 
 | |
| 				var playerStatistics = player.Statistics;
 | |
| 
 | |
| 				if (playerStatistics.Deaths == 0 && playerStatistics.ExtraLives == 0 && playerStatistics.IsEliminated == false)
 | |
| 					continue; // Player not yet initialized properly
 | |
| 
 | |
| 				minExtraLives = Mathf.Min(minExtraLives, playerStatistics.ExtraLives);
 | |
| 				maxExtraLives = Mathf.Max(maxExtraLives, playerStatistics.ExtraLives);
 | |
| 			}
 | |
| 
 | |
| 			int extraLives = _extraLives;
 | |
| 
 | |
| 			if (minExtraLives < int.MaxValue && maxExtraLives > int.MinValue)
 | |
| 			{
 | |
| 				extraLives = Mathf.Clamp(Mathf.RoundToInt((minExtraLives + maxExtraLives) * 0.5f), 0, _extraLives);
 | |
| 			}
 | |
| 
 | |
| 			return extraLives;
 | |
| 		}
 | |
| 
 | |
| 		// HELPERS
 | |
| 
 | |
| 		private class EliminationComparer : IComparer<PlayerStatistics>
 | |
| 		{
 | |
| 			public int Compare(PlayerStatistics x, PlayerStatistics y)
 | |
| 			{
 | |
| 				var result = x.IsEliminated.CompareTo(y.IsEliminated);
 | |
| 				if (result != 0)
 | |
| 					return result;
 | |
| 
 | |
| 				result = y.ExtraLives.CompareTo(x.ExtraLives);
 | |
| 				if (result != 0)
 | |
| 					return result;
 | |
| 
 | |
| 				result = y.Kills.CompareTo(x.Kills);
 | |
| 				if (result != 0)
 | |
| 					return result;
 | |
| 
 | |
| 				return x.Deaths.CompareTo(y.Deaths);
 | |
| 			}
 | |
| 		}
 | |
| 	}
 | |
| }
 |