Skip to content

Commit

Permalink
Merge pull request #6 from bigbang1112-cz/dev
Browse files Browse the repository at this point in the history
Add lap counter (1.3.0 update)
  • Loading branch information
BigBang1112 authored Aug 6, 2023
2 parents 283c921 + bbdc267 commit bfa8501
Show file tree
Hide file tree
Showing 5 changed files with 176 additions and 20 deletions.
6 changes: 4 additions & 2 deletions ClipCheckpoint/ClipCheckpoint.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
<AssemblyTitle>Clip Checkpoint</AssemblyTitle>
<Authors>Petr 'BigBang1112' Pivoňka</Authors>
<Copyright>Copyright © Petr 'BigBang1112' Pivoňka</Copyright>
<Version>1.2.3</Version>
<Version>1.3.0</Version>
</PropertyGroup>

<PropertyGroup>
Expand All @@ -17,10 +17,12 @@
<TargetFramework>net7.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<IsTrimmable>true</IsTrimmable>
<EnableTrimAnalyzer>true</EnableTrimAnalyzer>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="GbxToolAPI" Version="1.0.3" />
<PackageReference Include="GbxToolAPI" Version="1.0.4" />
</ItemGroup>

<ItemGroup>
Expand Down
34 changes: 33 additions & 1 deletion ClipCheckpoint/ClipCheckpointConfig.cs
Original file line number Diff line number Diff line change
Expand Up @@ -45,10 +45,30 @@ public class ClipCheckpointConfig : Config, IHasTextDictionary<ClipCheckpointDic
[YamlMember(Description = "Scale of the lap time text (multiplied on Scale).")]
public Vec2 LapTimeScale { get; set; } = (0.75f, 0.75f);

[YamlMember(Description = "Color of the main checkpoint time.")]
[YamlMember(Description = "Color of the lap time.")]
[Color]
public Vec4 LapTimeColor { get; set; } = (1, 1, 0, 1);

[YamlMember(Description = "Position offset of the lap crossing text (added on Position).")]
public Vec2 LapCrossPositionOffset { get; set; } = (0, 0.2f);

[YamlMember(Description = "Scale of the lap crossing text (multiplied on Scale).")]
public Vec2 LapCrossScale { get; set; } = (0.7f, 0.75f);

[YamlMember(Description = "Color of the lap crossing.")]
[Color]
public Vec4 LapCrossColor { get; set; } = (1, 1, 1, 1);

[YamlMember(Description = "Position offset of the lap counting text (added on Position).")]
public Vec2 LapCounterPosition { get; set; } = (-1.5f, 0.2f);

[YamlMember(Description = "Scale of the lap counting text (multiplied on Scale).")]
public Vec2 LapCounterScale { get; set; } = (0.95f, 1);

[YamlMember(Description = "Color of the lap counting.")]
[Color]
public Vec4 LapCounterColor { get; set; } = (1, 1, 1, 1);

[YamlMember(Description = "Position offset of the delta time text (added on Position).")]
public Vec2 DeltaTimePositionOffset { get; set; } = (0, -0.1f);

Expand Down Expand Up @@ -85,6 +105,12 @@ public class ClipCheckpointConfig : Config, IHasTextDictionary<ClipCheckpointDic
[YamlMember(Description = "If the sound should be included.")]
public bool IncludeSound { get; set; } = true;

[YamlMember(Description = "If the lap cross should be included.")]
public bool IncludeLapCross { get; set; } = true;

[YamlMember(Description = "If the lap counter should be included.")]
public bool IncludeLapCounter { get; set; } = true;

[YamlMember(Description = "Format of the main checkpoint time text. {0} is the time (X:XX.XXX or X:XX.XX)")]
public string TextCheckpointFormat { get; set; } = "$o$n{0}";

Expand All @@ -97,6 +123,12 @@ public class ClipCheckpointConfig : Config, IHasTextDictionary<ClipCheckpointDic
[YamlMember(Description = "Format of the stunts score addition to the main checkpoint time text. {0} is the stunts score.")]
public string TextStuntsFormat { get; set; } = "({0} pts.)";

[YamlMember(Description = "Format of the lap crossing text. {0} is the entering lap, {1} is total amount of laps.")]
public string TextLapCrossFormat { get; set; } = "$sLap {0}/{1}";

[YamlMember(Description = "Format of the lap counting text. {0} is the entering lap, {1} is total amount of laps.")]
public string TextLapCounterFormat { get; set; } = "$s{0} / {1}";

/*[YamlMember(Description = "URL location of the regular checkpoint sound (must be ogg).")]
public string CheckpointSoundUrl { get; set; } = "https://bigbang1112.cz/temp/RaceCheckPoint.ogg";
Expand Down
6 changes: 6 additions & 0 deletions ClipCheckpoint/ClipCheckpointDictionary.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,4 +19,10 @@ public class ClipCheckpointDictionary : ITextDictionary

[YamlMember(Description = "Name of the checkpoint delta text track.")]
public string MediaTrackerTrackCheckpointDelta { get; set; } = "CC: Delta";

[YamlMember(Description = "Name of the lap cross text track.")]
public string MediaTrackerTrackCheckpointLapCross { get; set; } = "CC: Lap Cross";

[YamlMember(Description = "Name of the lap counter text track.")]
public string MediaTrackerTrackCheckpointLapCounter { get; set; } = "CC: Lap Counter";
}
142 changes: 128 additions & 14 deletions ClipCheckpoint/ClipCheckpointTool.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,10 @@
using GBX.NET.Engines.Game;
using GbxToolAPI;
using System.Diagnostics;
using System.Drawing;
using System.Xml;
using TmEssentials;
using static System.Net.Mime.MediaTypeNames;

namespace ClipCheckpoint;

Expand Down Expand Up @@ -112,6 +114,10 @@ public NodeFile<CGameCtnMediaClip> Produce()
var textDeltaMediaBlocks = new CGameCtnMediaBlockText[deltaGhost is null ? 0 : checkpoints.Length];
var soundMediaBlocks = new CGameCtnMediaBlockSound[Config.IncludeSound ? checkpointCount : 0];

var textMultilapCrossMediaBlocks = new CGameCtnMediaBlockText[laps > 0 ? laps - 1 : 0];
var textMultilapCounterMediaBlocks = new CGameCtnMediaBlockText[isMultilap ? laps : 0];
var lapCounterStartTime = TimeSingle.Zero;

for (var i = 0; i < checkpoints.Length; i++)
{
//Console.WriteLine("Checkpoint {0}:", i + 1);
Expand All @@ -129,20 +135,41 @@ public NodeFile<CGameCtnMediaClip> Produce()
throw new CheckpointIsMinusOneException();
}

// Lap MT blocks - if lap race - and an unique lap time was reached
if (isMultilap && i >= checkpointCountPerLap)
if (isMultilap)
{
// Index to use for assinging to the lap MT block array
var index = i - checkpointCountPerLap;

//Console.Write("-> Creating lap text media block... ");
textMultilapMediaBlocks[index] = CreateLapMediaBlock(
time,
checkpoints,
currentCheckpointIndex: i,
checkpointCountPerLap,
isFromTM2);
//Console.WriteLine("Done");
if ((i + 1) % checkpointCountPerLap == 0)
{
var lapNumber = (i + 1) / checkpointCountPerLap + 1;
//Console.WriteLine("-> Lap checkpoint.");

//Console.Write("-> Creating lap text media block... ");
if (Config.IncludeLapCross && lapNumber <= laps)
{
textMultilapCrossMediaBlocks[lapNumber - 2] = CreateLapCrossMediaBlock(time, lapNumber, laps);
}

if (Config.IncludeLapCounter)
{
textMultilapCounterMediaBlocks[lapNumber - 2] = CreateLapCounterMediaBlock(lapCounterStartTime, time, lapNumber - 1, laps);
lapCounterStartTime = time;
}
}

// Lap MT blocks - if lap race - and an unique lap time was reached
if (i >= checkpointCountPerLap)
{
// Index to use for assinging to the lap MT block array
var index = i - checkpointCountPerLap;

//Console.Write("-> Creating lap text media block... ");
textMultilapMediaBlocks[index] = CreateLapMediaBlock(
time,
checkpoints,
currentCheckpointIndex: i,
checkpointCountPerLap,
isFromTM2);
//Console.WriteLine("Done");
}
}

if (deltaGhost is not null)
Expand Down Expand Up @@ -197,7 +224,7 @@ public NodeFile<CGameCtnMediaClip> Produce()
}

//Console.Write("Cleaning up overlapping... ");
ClearOverlappingOnText(textMediaBlocks, textShadowMediaBlocks, textMultilapMediaBlocks, textDeltaMediaBlocks);
ClearOverlappingOnText(textMediaBlocks, textShadowMediaBlocks, textMultilapMediaBlocks, textDeltaMediaBlocks, textMultilapCrossMediaBlocks);
ClearOverlappingOnSound(soundMediaBlocks);
//Console.WriteLine("Done");

Expand Down Expand Up @@ -227,6 +254,16 @@ public NodeFile<CGameCtnMediaClip> Produce()
{
//Console.Write("Creating media track for the multilap media blocks... ");
trackList.Add(CreateMediaTrack(textMultilapMediaBlocks, name: Config.Dictionary.MediaTrackerTrackCheckpointLap));

if (Config.IncludeLapCross)
{
trackList.Add(CreateMediaTrack(textMultilapCrossMediaBlocks, name: Config.Dictionary.MediaTrackerTrackCheckpointLapCross));
}

if (Config.IncludeLapCounter)
{
trackList.Add(CreateMediaTrack(textMultilapCounterMediaBlocks, name: Config.Dictionary.MediaTrackerTrackCheckpointLapCounter));
}
//Console.WriteLine("Done");
}

Expand Down Expand Up @@ -366,6 +403,83 @@ private CGameCtnMediaBlockText CreateLapMediaBlock(TimeSpan time, CGameCtnGhost.
scale: Config.LapTimeScale);
}

private CGameCtnMediaBlockText CreateLapCrossMediaBlock(TimeInt32 time, int lapNumber, int laps)
{
var lapText = string.Format(Config.TextLapCrossFormat, lapNumber, laps);

return CreateCheckpointTextMediaBlock(time,
lapText,
offsetPosition: Config.LapCrossPositionOffset,
color: Config.LapCrossColor,
scale: Config.LapCrossScale);
}

private CGameCtnMediaBlockText CreateLapCounterMediaBlock(TimeSingle startTime, TimeSingle endTime, int lapNumber, int laps)
{
var lapText = string.Format(Config.TextLapCounterFormat, lapNumber, laps);

var position = Config.LapCounterPosition * (Config.AspectRatio.Y / Config.AspectRatio.X, 1);

var keys = new List<CControlEffectSimi.Key>
{
new CControlEffectSimi.Key
{
Time = startTime + (lapNumber == 1 ? Config.AnimationInLength : TimeSingle.Zero),
Opacity = 1,
Position = position,
Scale = Config.LapCounterScale,
Depth = Config.Depth
},
new CControlEffectSimi.Key
{
Time = endTime,
Opacity = 1,
Position = position,
Scale = Config.LapCounterScale,
Depth = Config.Depth
}
};

if (lapNumber == 1)
{
keys.Insert(0, new CControlEffectSimi.Key
{
Time = startTime,
Opacity = 0,
Position = position,
Scale = Config.LapCounterScale,
Depth = Config.Depth
});
}
else if (lapNumber == laps)
{
keys.Add(new CControlEffectSimi.Key
{
Time = endTime + Config.AnimationOutLength,
Opacity = 0,
Position = position,
Scale = Config.LapCounterScale,
Depth = Config.Depth
});
}

var effectBuilder = CControlEffectSimi.Create()
.WithKeys(keys)
.Centered();

var effect = Config.Legacy
? effectBuilder.ForTMSX().Build()
: effectBuilder.ForTMUF().Interpolated().Build();

var mediaBlockBuilder = CGameCtnMediaBlockText.Create(effect)
.WithText(lapText)
.WithColor(new(Config.LapCounterColor.X, Config.LapCounterColor.Y, Config.LapCounterColor.Z));

return Config.Legacy
? mediaBlockBuilder.ForTMSX().Build()
: mediaBlockBuilder.ForTMUF().Build();
}

private CGameCtnMediaBlockSound CreateCheckpointSoundMediaBlock(TimeSpan time, FileRef soundFileRef)
{
var soundKeys = GetCheckpointSoundMediaBlockKeys(time);
Expand Down
8 changes: 5 additions & 3 deletions ClipCheckpointCLI/ClipCheckpointCLI.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
<AssemblyTitle>Clip Checkpoint CLI</AssemblyTitle>
<Authors>Petr 'BigBang1112' Pivoňka</Authors>
<Copyright>Copyright © Petr 'BigBang1112' Pivoňka</Copyright>
<Version>1.2.3</Version>
<Version>1.3.0</Version>
</PropertyGroup>

<PropertyGroup>
Expand All @@ -25,11 +25,13 @@
</PropertyGroup>

<ItemGroup>
<PackageReference Include="GbxToolAPI.CLI" Version="1.0.3" />
<PackageReference Include="GbxToolAPI.CLI" Version="1.0.9" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\ClipCheckpoint\ClipCheckpoint.csproj" />
<ProjectReference Include="..\ClipCheckpoint\ClipCheckpoint.csproj">
<IsTrimmable>false</IsTrimmable>
</ProjectReference>
</ItemGroup>

<ItemGroup>
Expand Down

0 comments on commit bfa8501

Please sign in to comment.