166 lines
4.0 KiB
C#
166 lines
4.0 KiB
C#
|
namespace TPSBR.UI
|
||
|
{
|
||
|
using UnityEngine;
|
||
|
using System.Collections.Generic;
|
||
|
using TMPro;
|
||
|
|
||
|
public class UIScoreboard : UIWidget
|
||
|
{
|
||
|
// PRIVATE MEMBERS
|
||
|
|
||
|
[SerializeField]
|
||
|
private UIScoreboardItem _item;
|
||
|
[SerializeField]
|
||
|
private TextMeshProUGUI _livesHeader;
|
||
|
[SerializeField]
|
||
|
private UIValue _totalPlayers;
|
||
|
|
||
|
[SerializeField]
|
||
|
private RectTransform _recordsGapSeparator;
|
||
|
|
||
|
[SerializeField]
|
||
|
private int _maxShownRecords = 10;
|
||
|
[SerializeField]
|
||
|
private int _fixedFirstPlaces = 3;
|
||
|
|
||
|
|
||
|
private ElementCache<UIScoreboardItem> _items;
|
||
|
private float _refreshTimer;
|
||
|
private static readonly PlayerStatisticsComparer _playerStatisticsComparer = new PlayerStatisticsComparer();
|
||
|
|
||
|
// UIView INTERFAFCE
|
||
|
|
||
|
protected override void OnInitialize()
|
||
|
{
|
||
|
base.OnInitialize();
|
||
|
|
||
|
_items = new ElementCache<UIScoreboardItem>(_item, 16);
|
||
|
_refreshTimer = default;
|
||
|
}
|
||
|
|
||
|
protected override void OnVisible()
|
||
|
{
|
||
|
base.OnVisible();
|
||
|
|
||
|
Refresh();
|
||
|
}
|
||
|
|
||
|
protected override void OnTick()
|
||
|
{
|
||
|
base.OnTick();
|
||
|
|
||
|
_refreshTimer -= Time.deltaTime;
|
||
|
|
||
|
if (_refreshTimer > 0f)
|
||
|
return;
|
||
|
|
||
|
Refresh();
|
||
|
}
|
||
|
|
||
|
// PRIVATE METHODS
|
||
|
|
||
|
private void Refresh()
|
||
|
{
|
||
|
if (Context.Runner == null || Context.Runner.Exists(Context.GameplayMode.Object) == false)
|
||
|
return;
|
||
|
|
||
|
var allStatistics = ListPool.Get<PlayerStatistics>(200);
|
||
|
var localPlayerPosition = 0;
|
||
|
|
||
|
int playersCount = 0;
|
||
|
|
||
|
foreach (var player in Context.NetworkGame.ActivePlayers)
|
||
|
{
|
||
|
if (player == null)
|
||
|
continue;
|
||
|
|
||
|
var statistics = player.Statistics;
|
||
|
|
||
|
allStatistics.Add(statistics);
|
||
|
|
||
|
if (statistics.PlayerRef == Context.LocalPlayerRef)
|
||
|
{
|
||
|
localPlayerPosition = statistics.Position;
|
||
|
}
|
||
|
|
||
|
playersCount++;
|
||
|
}
|
||
|
|
||
|
_totalPlayers.SetValue(playersCount);
|
||
|
|
||
|
allStatistics.Sort(_playerStatisticsComparer);
|
||
|
|
||
|
var showLives = Context.GameplayMode is EliminationGameplayMode;
|
||
|
_livesHeader.SetActive(showLives);
|
||
|
|
||
|
if (localPlayerPosition <= _maxShownRecords)
|
||
|
{
|
||
|
var i = 0;
|
||
|
var count = Mathf.Min(_maxShownRecords, allStatistics.Count);
|
||
|
for (; i < count; i++)
|
||
|
{
|
||
|
var statistics = allStatistics[i];
|
||
|
var player = Context.NetworkGame.GetPlayer(statistics.PlayerRef);
|
||
|
|
||
|
if (player != null)
|
||
|
{
|
||
|
_items[i].SetData(statistics, player.Nickname, showLives, Context.LocalPlayerRef == statistics.PlayerRef);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
_items.HideAll(i);
|
||
|
|
||
|
_recordsGapSeparator.SetActive(allStatistics.Count > _maxShownRecords);
|
||
|
_recordsGapSeparator.SetSiblingIndex(count + 2);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
var i = 0;
|
||
|
for (int count = _fixedFirstPlaces; i < count; i++)
|
||
|
{
|
||
|
var statistics = allStatistics[i];
|
||
|
var player = Context.NetworkGame.GetPlayer(statistics.PlayerRef);
|
||
|
|
||
|
_items[i].SetData(statistics, player.Nickname, showLives, Context.LocalPlayerRef == statistics.PlayerRef);
|
||
|
}
|
||
|
|
||
|
_recordsGapSeparator.SetSiblingIndex(i + 2);
|
||
|
_recordsGapSeparator.SetActive(true);
|
||
|
|
||
|
var aroundPlayer = _maxShownRecords - _fixedFirstPlaces;
|
||
|
var secondsBlockStart = localPlayerPosition - aroundPlayer / 2 - 1;
|
||
|
|
||
|
if (secondsBlockStart + aroundPlayer > allStatistics.Count)
|
||
|
{
|
||
|
secondsBlockStart -= secondsBlockStart + aroundPlayer - allStatistics.Count;
|
||
|
}
|
||
|
|
||
|
for (int y = secondsBlockStart; y < secondsBlockStart + aroundPlayer; i++, y++)
|
||
|
{
|
||
|
var statistics = allStatistics[y];
|
||
|
var player = Context.NetworkGame.GetPlayer(statistics.PlayerRef);
|
||
|
|
||
|
_items[i].SetData(statistics, player.Nickname, showLives, Context.LocalPlayerRef == statistics.PlayerRef);
|
||
|
}
|
||
|
|
||
|
_items.HideAll(i);
|
||
|
}
|
||
|
|
||
|
|
||
|
ListPool.Return(allStatistics);
|
||
|
|
||
|
_refreshTimer = Context.GameplayMode.State == GameplayMode.EState.Finished ? 9999f : 1f;
|
||
|
}
|
||
|
|
||
|
// HELPERS
|
||
|
|
||
|
private class PlayerStatisticsComparer : IComparer<PlayerStatistics>
|
||
|
{
|
||
|
int IComparer<PlayerStatistics>.Compare(PlayerStatistics x, PlayerStatistics y)
|
||
|
{
|
||
|
return x.Position.CompareTo(y.Position);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|