Partial MatchSimulation class that tracks stoppage time for each half. Counts added time from incidents, restarts and goals, then exposes the broadcast clock and referee added-time signals.
using System;
namespace Socer;
public sealed partial class MatchSimulation
{
// Four simulation seconds represent one displayed football minute.
public int FirstHalfAddedMinutes=-1,SecondHalfAddedMinutes=-1;
public float HalfStoppageSeconds;
public int AddedMinutes => SecondHalf?Math.Max(0,SecondHalfAddedMinutes):Math.Max(0,FirstHalfAddedMinutes);
public bool InAddedTime => !SecondHalf
? FirstHalfAddedMinutes>=0 && Seconds>=180
: SecondHalfAddedMinutes>=0 && Seconds>=360+Math.Max(0,FirstHalfAddedMinutes)*4;
public string BroadcastClock
{
get
{
if((ShootoutActive || ShootoutComplete) && shootoutMatchClock!=null)return shootoutMatchClock;
float elapsed=Seconds-(SecondHalf?Math.Max(0,FirstHalfAddedMinutes)*4:0);
int total=Math.Max(0,(int)MathF.Floor(elapsed*15));
return $"{total/60:00}:{total%60:00}";
}
}
public string ClockLabel
{
get
{
if((ShootoutActive || ShootoutComplete) && shootoutMatchClockLabel!=null)return shootoutMatchClockLabel;
if(!SecondHalf)
return InAddedTime?$"45+{Math.Clamp((int)Math.Floor((Seconds-180)/4)+1,1,Math.Max(1,FirstHalfAddedMinutes))}":$"{Minute:00}";
float regularEnd=360+Math.Max(0,FirstHalfAddedMinutes)*4;
return InAddedTime?$"90+{Math.Clamp((int)Math.Floor((Seconds-regularEnd)/4)+1,1,Math.Max(1,SecondHalfAddedMinutes))}":$"{Minute:00}";
}
}
void CountStoppage(float dt)
{
if((SecondHalf?SecondHalfAddedMinutes:FirstHalfAddedMinutes)>=0)return;
if(IncidentRemaining>0)HalfStoppageSeconds+=dt;
else if(RestartRemaining>0 && SetPiece!=RestartKind.KickOff)HalfStoppageSeconds+=dt*.45f;
}
void CountGoalStoppage(float dt)
{
if((SecondHalf?SecondHalfAddedMinutes:FirstHalfAddedMinutes)<0)HalfStoppageSeconds+=dt*.8f;
}
static int AddedFor(float stoppage,int maximum)=>Math.Clamp((int)MathF.Ceiling(stoppage/4),0,maximum);
void AnnounceAddedTime()
{
if(!SecondHalf && Seconds>=180 && FirstHalfAddedMinutes<0)
{
FirstHalfAddedMinutes=AddedFor(HalfStoppageSeconds,5);
RefereeSignal=$"+{FirstHalfAddedMinutes} МИН";RefereeSignalUntil=Seconds+3;ShownCard=0;
AddEvent($"Судья добавил {FirstHalfAddedMinutes} мин. к первому тайму");
}
else if(SecondHalf && Seconds>=360+Math.Max(0,FirstHalfAddedMinutes)*4 && SecondHalfAddedMinutes<0)
{
SecondHalfAddedMinutes=AddedFor(HalfStoppageSeconds,7);
RefereeSignal=$"+{SecondHalfAddedMinutes} МИН";RefereeSignalUntil=Seconds+3;ShownCard=0;
AddEvent($"Судья добавил {SecondHalfAddedMinutes} мин. ко второму тайму");
}
}
}