Skip to content

Commit

Permalink
Fix rank in spec info (#202)
Browse files Browse the repository at this point in the history
Co-authored-by: Alexander Raszka <alexander.raszka@storeplus.de>
  • Loading branch information
araszka and Alexander Raszka authored Sep 21, 2023
1 parent d27f921 commit 607bbe8
Show file tree
Hide file tree
Showing 6 changed files with 188 additions and 26 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
using EvoSC.Common.Controllers.Context;
using EvoSC.Common.Events.Attributes;
using EvoSC.Common.Remote;
using EvoSC.Common.Remote.EventArgsModels;
using GbxRemoteNet.Events;
using SpectatorTargetInfo.Interfaces;

Expand All @@ -21,4 +22,16 @@ public SpectatorTargetInfoEventController(ISpectatorTargetInfoService spectatorT
[Subscribe(GbxRemoteEvent.PlayerConnect)]
public Task OnPlayerConnect(object x, PlayerConnectGbxEventArgs args) =>
_spectatorTargetInfoService.SendManiaLink(args.Login);

[Subscribe(ModeScriptEvent.WayPoint)]
public Task OnWayPoint(object sender, WayPointEventArgs wayPointEventArgs) =>
_spectatorTargetInfoService.ForwardCheckpointTimeToClients(wayPointEventArgs);

[Subscribe(ModeScriptEvent.StartRoundStart)]
public Task OnNewRound(object sender, RoundEventArgs roundEventArgs) =>
_spectatorTargetInfoService.ResetCheckpointTimes();

[Subscribe(ModeScriptEvent.GiveUp)]
public Task OnPlayerGiveUp(object sender, PlayerUpdateEventArgs playerUpdateEventArgs) =>
_spectatorTargetInfoService.ForwardDnf(playerUpdateEventArgs);
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
namespace SpectatorTargetInfo.Interfaces;
using EvoSC.Common.Remote.EventArgsModels;

namespace SpectatorTargetInfo.Interfaces;

public interface ISpectatorTargetInfoService
{
Expand All @@ -22,4 +24,16 @@ public interface ISpectatorTargetInfoService
/// Shows the default spectator info.
/// </summary>
public Task ShowNadeoSpectatorInfo();
/// <summary>
/// Maps wayPointEventArgs and sends data to clients.
/// </summary>
public Task ForwardCheckpointTimeToClients(WayPointEventArgs wayPointEventArgs);
/// <summary>
/// Clears the checkpoint times for the clients.
/// </summary>
public Task ResetCheckpointTimes();
/// <summary>
/// Sends players DNF to clients.
/// </summary>
public Task ForwardDnf(PlayerUpdateEventArgs playerUpdateEventArgs);
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using EvoSC.Common.Config.Models;
using EvoSC.Common.Interfaces;
using EvoSC.Common.Remote.EventArgsModels;
using EvoSC.Common.Services.Attributes;
using EvoSC.Common.Services.Models;
using EvoSC.Manialinks.Interfaces;
Expand Down Expand Up @@ -37,8 +38,8 @@ private async Task<dynamic> GetWidgetData()
{
return new
{
primaryColor = _config.Theme.UI.PrimaryColor,
backgroundColor = _config.Theme.UI.BackgroundColor,
primaryColor = _config.Theme.UI.PrimaryColor,
backgroundColor = _config.Theme.UI.BackgroundColor,
headerColor = _config.Theme.UI.HeaderBackgroundColor
};
}
Expand Down Expand Up @@ -84,4 +85,31 @@ public Task ShowNadeoSpectatorInfo()

return _server.Remote.TriggerModeScriptEventArrayAsync("Common.UIModules.SetProperties", hudSettings.ToArray());
}

public Task ForwardCheckpointTimeToClients(WayPointEventArgs wayPointEventArgs)
{
return _manialinks.SendManialinkAsync("SpectatorTargetInfo.NewCpTime",
new
{
accountId = wayPointEventArgs.AccountId,
time = wayPointEventArgs.RaceTime,
cpIndex = wayPointEventArgs.CheckpointInRace
});
}

public Task ResetCheckpointTimes()
{
_manialinks.HideManialinkAsync("SpectatorTargetInfo.NewCpTime");
return _manialinks.SendManialinkAsync("SpectatorTargetInfo.ResetCpTimes");
}

public Task ForwardDnf(PlayerUpdateEventArgs playerUpdateEventArgs)
{
return _manialinks.SendManialinkAsync("SpectatorTargetInfo.NewCpTime", new
{
accountId = playerUpdateEventArgs.AccountId,
time = 0,
cpIndex = -1
});
}
}
24 changes: 24 additions & 0 deletions src/Modules/SpectatorTargetInfo/Templates/NewCpTime.mt
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
<component>
<property type="string" name="accountId" />
<property type="int" name="cpIndex" />
<property type="int" name="time" />

<template>
</template>

<script><!--
#Struct EvoSC_CheckpointTime {
Text AccountId;
Integer CpIndex;
Integer Time;
}

main() {
declare EvoSC_CheckpointTime[Text] EvoCheckpointTimes for UI;
declare Integer EvoCheckpointTimesUpdate for UI;

EvoCheckpointTimes["{{ accountId }}"] = EvoSC_CheckpointTime{ AccountId = "{{ accountId }}", Time = {{ time }}, CpIndex = {{ cpIndex }} };
EvoCheckpointTimesUpdate = Now;
}
--></script>
</component>
22 changes: 22 additions & 0 deletions src/Modules/SpectatorTargetInfo/Templates/ResetCpTimes.mt
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
<component>
<template>
</template>

<script><!--
#Struct EvoSC_CheckpointTime {
Text AccountId;
Integer CpIndex;
Integer Time;
}

main() {
declare EvoSC_CheckpointTime[Text] EvoCheckpointTimes for UI;
declare Integer EvoCheckpointTimesUpdate for UI;
declare Boolean EvoCheckpointTimesReset for UI = False;

EvoCheckpointTimes = EvoSC_CheckpointTime[Text];
EvoCheckpointTimesUpdate = Now;
EvoCheckpointTimesReset = True;
}
--></script>
</component>
107 changes: 84 additions & 23 deletions src/Modules/SpectatorTargetInfo/Templates/SpectatorTargetInfo.mt
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,12 @@
#Const C_Status_NotSpawned 2
#Const C_Status_Spectating 3

#Struct EvoSC_CheckpointTime {
Text AccountId;
Integer CpIndex;
Integer Time;
}

declare Integer FirstPositionTime;
declare Integer LocalPositionTime;

Expand Down Expand Up @@ -136,33 +142,69 @@
return 0;
}

Integer GetPlayerRank(CSmPlayer player) {
declare rank = 1;
foreach(Score => Weight in GetSortedScores()){
if(rank == 1){
declare CSmPlayer Driver for Score;
FirstPositionTime = GetCurrentCheckpointTime(Driver);
}
if(Score == player.Score){
declare CSmPlayer Driver for Score;
LocalPositionTime = GetCurrentCheckpointTime(Driver);
break;
Integer GetPlayerRank(Integer[Text] ranksByAccountId, CSmPlayer player) {
declare accountId = player.User.WebServicesUserId;

if(ranksByAccountId.existskey(accountId)){
return ranksByAccountId[accountId];
}

return -1;
}

Integer[Text] CalculatePlayerDiffs(Integer[Text] ranksByAccountId) {
declare Integer[Text] scoresByAccountId;
declare Integer[Text] diffsByAccountId;
declare Integer bestTime = -1;

foreach(player in Players){
scoresByAccountId[player.User.WebServicesUserId] = GetCurrentCheckpointTime(player);
}

foreach(rank in ranksByAccountId){
declare accountId = ranksByAccountId.keyof(rank);

if(scoresByAccountId.existskey(accountId)){
if(bestTime == -1){
bestTime = scoresByAccountId[accountId];
}

diffsByAccountId[accountId] = ML::Abs(scoresByAccountId[accountId] - bestTime);
}
rank += 1;
}

return rank;
return diffsByAccountId;
}

Text StripLeadingZeroes(Text input) {
return TL::RegexReplace("^[0:]+", input, "", "");
}

Void AssignDrivers() {
foreach(Player in Players){
declare CSmPlayer Driver for Player.Score;
Driver <=> Player;
Integer[Text] GetRanksForAccountIds(EvoSC_CheckpointTime[Text] checkpointTimes){
declare Integer[Text][Integer] timesByCheckpoints;

foreach(cpTime in checkpointTimes){
declare index = cpTime.CpIndex * -1;

if(!timesByCheckpoints.existskey(cpTime.CpIndex)){
timesByCheckpoints[index] = Integer[Text];
}

timesByCheckpoints[index][cpTime.AccountId] = cpTime.Time;
}

declare Integer[Text] sortedTimes;
declare Integer rank = 1;

foreach(checkpointsTimes in timesByCheckpoints.sortkey()){
foreach(cpTime in checkpointsTimes.sort()){
declare accountId = checkpointsTimes.keyof(cpTime);
sortedTimes[accountId] = rank;
rank += 1;
}
}

return sortedTimes;
}

main() {
Expand All @@ -175,12 +217,24 @@
declare clubTagLabel <=> (Page.MainFrame.GetFirstChild("club") as CMlLabel);
declare lastAssignUpdate = 0;

declare EvoSC_CheckpointTime[Text] EvoCheckpointTimes for UI;
declare Integer EvoCheckpointTimesUpdate for UI;
declare Boolean EvoCheckpointTimesReset for UI = False;
declare Integer lastCheckpointUpdateCheck = 0;
declare Integer[Text] ranksByAccountId;
declare Integer[Text] diffs;

FirstPositionTime = 0;
LocalPositionTime = 0;

while(True) {
yield;

if(EvoCheckpointTimesReset){
ranksByAccountId = Integer[Text];
EvoCheckpointTimesReset = False;
}

if(GUIPlayer == Null || GUIPlayer.User == LocalUser){
sleep(100);
if(mainFrame.Visible){
Expand All @@ -189,20 +243,27 @@
continue;
}

if(lastCheckpointUpdateCheck != EvoCheckpointTimesUpdate){
lastCheckpointUpdateCheck = EvoCheckpointTimesUpdate;
log("[SpecInfo] CALCULATE RANKS AND DIFFS.");
ranksByAccountId = GetRanksForAccountIds(EvoCheckpointTimes);
diffs = CalculatePlayerDiffs(ranksByAccountId);
log("[SpecInfo] Ranks: " ^ ranksByAccountId);
log("[SpecInfo] Diffs: " ^ diffs);
}

if(!mainFrame.Visible){
mainFrame.Show();
}

if(lastAssignUpdate + 2500 < Now){
AssignDrivers();
lastAssignUpdate = Now;
declare Integer timeDifference = 0;
if(diffs.existskey(GUIPlayer.User.WebServicesUserId)){
timeDifference = diffs[GUIPlayer.User.WebServicesUserId];
}

declare timeDifference = ML::Abs(LocalPositionTime - FirstPositionTime);

nameLabel.Value = GUIPlayer.User.Name;
diffLabel.Value = "+" ^ StripLeadingZeroes(TL::TimeToText(timeDifference, True, True));
positionLabel.Value = GetPlayerRank(GUIPlayer) ^ ".";
positionLabel.Value = GetPlayerRank(ranksByAccountId, GUIPlayer) ^ ".";
clubTagLabel.Value = GUIPlayer.User.ClubTag;

if(GUIPlayer.User.ClubTag != ""){
Expand Down

0 comments on commit 607bbe8

Please sign in to comment.