Part of the match controller. Handles the relegation choice overlay, media league match setup and preview mode, fine acceptance, and finishing or restarting the media presentation.
using Sandbox;
using Socer;
using System.Linq;
public sealed partial class MatchController
{
public bool RelegationChoiceOpen {get;private set;}
public bool MediaLeagueActive {get;private set;}
public bool MediaLeaguePreview {get;private set;}
public bool CanLeaveMediaLeague=>MediaLeagueActive && Match.IsMediaLeague && Match.Finished && !Match.Abandoned;
public RelegationFinePlan RelegationFinePreview=>Career?.PreviewRelegationFine();
bool mediaExitAllowed,mediaChoiceWasPaused;
RelegationChoiceHud relegationHud;
// Also adds the overlay to an already running editor session after hotload.
void EnsureRelegationInterface()
{
if(relegationHud?.GameObject?.IsValid==true)return;
relegationHud=Scene.GetAllComponents<RelegationChoiceHud>().FirstOrDefault();
if(relegationHud!=null)return;
var ui=Scene.GetAllComponents<MatchHud>().FirstOrDefault()?.GameObject;
if(ui!=null)relegationHud=ui.Components.Create<RelegationChoiceHud>();
}
bool RequireRelegationResolved()
{
if(Career?.HasRelegationChoice!=true && !MediaLeagueActive)return true;
OpenRelegationChoice();return false;
}
public void OpenRelegationChoice()
{
if(MediaLeaguePreview){ExitMediaLeaguePreview();return;}
if(Career?.HasRelegationChoice!=true)return;
if(GameSettingsOpen)ToggleGameSettings();
if(!RelegationChoiceOpen)mediaChoiceWasPaused=Paused;
CloseCommandWheel();CancelDirectOrder();SetFieldDragSlow(false);
RelegationChoiceOpen=true;Paused=true;accumulator=0;Revision++;
}
public void CloseRelegationChoice()
{
if(!RelegationChoiceOpen)return;
RelegationChoiceOpen=false;
Paused=MediaLeagueActive?mediaChoiceWasPaused:true;
accumulator=0;Revision++;
}
public void StartRelegationMediaMatch()
{
if(Career?.HasRelegationChoice!=true || Career.Pending!=null || QuickMatchRunning)return;
if(MediaLeagueActive)
{CloseRelegationChoice();ClubOpen=false;Paused=false;return;}
int seed=Career.BeginRelegationMediaMatch();if(seed==0)return;
StartMediaPresentation(seed,false);
ClubNotice=RelegationText("Медиа-лига: досмотрите матч или выберите штраф.","Media league: watch the match to the end or choose the fine.");
SaveCareer();Revision++;
}
// A career-preserving exhibition for viewing the same players and AI.
public void StartMediaLeaguePreview(int seed)
{
if(MediaLeagueActive || QuickMatchRunning || Career?.HasRelegationChoice==true)return;
StartMediaPresentation(seed,true);Revision++;
}
public void ExitMediaLeaguePreview()
{
if(!MediaLeaguePreview)return;
FinishMediaPresentation();ClubOpen=true;Paused=true;Revision++;
}
void StartMediaPresentation(int seed,bool preview)
{
if(StrategyLabOpen)CloseStrategyLab();
if(MatchTutorialActive)EndMatchTutorial();
if(GameSettingsOpen)ToggleGameSettings();
if(TutorialStep>=0)FinishTutorial(false);
PreparingMatch=false;MatchModeSelection=false;QuickBroadcastOpen=false;
// The preview mechanism preserves the club match, substitutions and camera.
// The persistent obligation, rather than a competitive fixture, owns this match.
ShowRulesPreview("football-ai");
Match=MatchSimulation.MediaLeagueMatch(seed);
MediaLeagueActive=true;MediaLeaguePreview=preview;RelegationChoiceOpen=false;
FootballLabActive=false;PreviewManualSetPieces=false;PreviewCameraWidth=0;
Director=new MatchDirector{Automatic=false,ManualSpeed=1.5f};Director.Update(Match,0);
Broadcast=new BroadcastCamera();SelectedPlayer=OrderedPlayer=9;
CloseCommandWheel();CancelDirectOrder();fieldPings.Clear();pingMatch=Match;
manualSelectionMatch=Match;manualCameraMatch=Match;manualCameraUntil=0;FieldDragSlow=false;
Replay.Reset();Replay.Capture(Match);observedGoals=0;replayAfterGoal=0;accumulator=0;
Settlement=null;SkipMatchIntro();ClubOpen=false;Paused=false;
}
public void AcceptRelegationFine(string previewKey)
{
if(Career?.HasRelegationChoice!=true)return;
if(!Career.ApplyRelegationFine(previewKey))
{
ClubNotice=RelegationText("Состав или баланс изменился. Проверьте новый расчёт штрафа.","Your squad or balance changed. Review the updated fine.");
Revision++;return;
}
FinishMediaPresentation();RelegationChoiceOpen=false;
ClubOpen=true;Paused=true;ClubPage="Главная";ClubNotice=Career.LastResult;
SaveCareer();Revision++;
}
public void CompleteMediaLeagueMatch()
{
if(MediaLeaguePreview){ExitMediaLeaguePreview();return;}
if(!CanLeaveMediaLeague || !Career.ResolveRelegationMediaMatch(Match))return;
FinishMediaPresentation();RelegationChoiceOpen=false;
ClubOpen=true;Paused=true;ClubPage="Главная";ClubNotice=Career.LastResult;
SaveCareer();Revision++;
}
public void RestartAbandonedMediaMatch()
{
if(!MediaLeagueActive || !Match.Abandoned || Career?.HasRelegationChoice!=true)return;
FinishMediaPresentation();StartRelegationMediaMatch();
}
void FinishMediaPresentation()
{
if(!MediaLeagueActive)return;
mediaExitAllowed=true;EndRulesPreview();mediaExitAllowed=false;
MediaLeagueActive=false;MediaLeaguePreview=false;CloseCommandWheel();CancelDirectOrder();fieldPings.Clear();
Replay.Reset();SkipMatchIntro();accumulator=0;FieldDragSlow=false;
QuickBroadcastOpen=false;QuickMatchRunning=false;RevealedCard=null;RevealedPack=null;
}
static string RelegationText(string ru,string en)=>GamePreferences.Russian?ru:en;
}