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