The relegation choice dialog for the career mode UI. Shows the division drop, lets the player pay a fine with a card-by-card preview or play a Media League match, with English and Russian text.
@using Sandbox
@using Sandbox.UI
@using Socer
@using System
@using System.Linq
@using System.Globalization
@inherits PanelComponent
<root class="relegation-choice-hud localized-text">
@if(Game?.RelegationChoiceOpen==true && Game.Career?.HasRelegationChoice==true)
{
var plan=ShownPlan;
<div class="relegation-choice-shade">
<div class="relegation-choice-card @(ReviewFine?"reviewing-fine":"")">
<div class="relegation-choice-heading">
<div><label class="relegation-kicker">@Text("SEASON CONSEQUENCES","ИТОГИ СЕЗОНА")</label><label class="relegation-title">@(ReviewFine?Text("Review the fine","Проверить штраф"):Text("Relegation has a price","За вылет придётся ответить"))</label></div>
<button class="relegation-choice-close" onclick=@(()=>Game.CloseRelegationChoice())>×</button>
</div>
<div class="relegation-league-change"><label>@LeagueName(Game.Career.Relegation.FromDivision)</label><label class="relegation-down-arrow">↓</label><label>@LeagueName(Game.Career.Relegation.ToDivision)</label></div>
@if(!ReviewFine)
{
<label class="relegation-intro">@Text("The board offers two ways to answer for the season. Pay the fine, or put on a show against the Media League.","Правление предлагает два варианта: заплатить штраф или выйти на поле против Медиа-лиги. Деньги или контент — решать тренеру.")</label>
<div class="relegation-options">
<div class="relegation-option fine-option">
<div class="relegation-option-art"><img src="/ui-icons/ui-line-nav-coins.svg" /><label>@($"{Number(plan?.Fine??Game.Career.Relegation.Fine)} ◈")</label></div>
<label class="relegation-option-title">@Text("Pay the fine","Заплатить штраф")</label>
<label class="relegation-option-copy">@Text("Coins first. If they are not enough, spare cards cover the balance. Your starting lineup is protected.","Сначала монеты. Если их не хватит — недорогие карточки из резерва. Стартовый состав защищён.")</label>
@if(plan is not null)
{
<div class="relegation-fine-quick"><label>@Text("From the wallet","Из кошелька")</label><b>@($"−{Number(plan.MoneyCharged)} ◈")</b></div>
<div class="relegation-fine-quick"><label>@Text("Spare cards","Карточек из резерва")</label><b>@plan.Cards.Count</b></div>
}
<button class="relegation-preview-fine" onclick=@PreviewFine>@Text("See exact losses →","Посмотреть списания →")</button>
</div>
<div class="relegation-option media-option">
<div class="relegation-option-art"><img src="/ui-icons/ui-line-nav-play.svg" /><label>@Text("LIVE","ЭФИР")</label></div>
<label class="relegation-option-title">@Text("A Media League match","Матч Медиа-лиги")</label>
<label class="relegation-option-copy">@Text("Coach a fictional amateur squad against another amateur team. About 4½ minutes of live football with pings and orders.","Вы тренируете вымышленный состав любителей против таких же любителей. Около 4,5 минут трансляции с пингами и приказами.")</label>
<div class="relegation-media-promise"><label>@Text("Finish the match — no fine","Доиграете матч — штрафа нет")</label><label>@Text("The result does not matter. Coins and cards stay with your club.","Победа не обязательна. Монеты и карточки остаются у клуба.")</label></div>
<button class="relegation-start-media" onclick=@(()=>Game.StartRelegationMediaMatch())>@(Game.Career.Relegation.MediaStarted?Text("Return to the show →","Вернуться в эфир →"):Text("Take the touchline →","Выйти к бровке →"))</button>
</div>
</div>
<label class="relegation-pending-note">@Text("Finish one option to start your next season. Reloading restarts the entire match with the same teams and conditions.","Следующий сезон ждёт оплаты штрафа или завершения матча. После перезапуска матч играется заново с теми же командами и условиями.")</label>
}
else if(plan is not null)
{
<label class="relegation-intro">@Text("These are the exact losses on confirmation. Player cards listed below will leave your club.","Это точные списания после подтверждения. Перечисленные карточки игроков покинут клуб.")</label>
<div class="relegation-fine-review">
<div class="relegation-fine-ledger">
<div><label>@Text("Fine","Назначенный штраф")</label><b>@($"{Number(plan.Fine)} ◈")</b></div>
<div class="fine-charge"><label>@Text("Coins deducted","Монет к списанию")</label><b>@($"−{Number(plan.MoneyCharged)} ◈")</b></div>
<div><label>@Text("Card value","Стоимость карточек")</label><b>@($"{Number(plan.CardValue)} ◈")</b></div>
@if(plan.ChangeReturned>0){<div class="fine-return"><label>@Text("Change returned","Вернётся сдача")</label><b>@($"+{Number(plan.ChangeReturned)} ◈")</b></div>}
@if(plan.ShortfallWaived>0){<div class="fine-waived"><label>@Text("Unpayable balance waived","Недостающая сумма прощена")</label><b>@($"{Number(plan.ShortfallWaived)} ◈")</b></div>}
<div class="fine-total"><label>@Text("Actual fine paid","Фактический штраф")</label><b>@($"{Number(plan.EffectiveFine)} ◈")</b></div>
</div>
<div class="relegation-card-losses">
<label class="relegation-list-heading">@($"{Text("CARDS TO REMOVE","КАРТОЧКИ К СПИСАНИЮ")} · {plan.Cards.Count}")</label>
<div class="relegation-card-loss-list">
@foreach(var card in plan.Cards)
{
<div @key="card.Id" class="relegation-card-loss"><label class="relegation-loss-ovr">@card.Overall</label><label class="relegation-loss-name">@card.Name</label><label class="relegation-loss-value">@($"{Number(card.Value)} ◈")</label></div>
}
@if(plan.Cards.Count==0){<label class="relegation-no-card-loss">@Text("No player cards will be removed.","Карточки игроков не будут списаны.")</label>}
</div>
<label class="relegation-protected-note">@Text("Your selected starting lineup is protected. Any card overpayment is returned as coins.","Выбранный стартовый состав защищён. Переплата за целую карточку возвращается монетами.")</label>
</div>
</div>
@if(PreviewChanged){<label class="relegation-preview-changed">@Text("Your balance or squad changed. Refresh the preview before accepting.","Бюджет или состав изменился. Обновите расчёт перед подтверждением.")</label>}
<div class="relegation-confirm-actions">
<button class="relegation-fine-back" onclick=@(()=>{ReviewFine=false;ReviewedPlan=null;})>@Text("← Choose another option","← Вернуться к выбору")</button>
@if(PreviewChanged){<button class="relegation-refresh-fine" onclick=@PreviewFine>@Text("Refresh preview","Обновить расчёт")</button>}
else{<button class="relegation-confirm-fine" onclick=@ConfirmFine>@Text("Confirm the losses","Подтвердить списание")</button>}
</div>
}
</div>
</div>
}
</root>
@code {
MatchController cachedGame;
MatchController Game
{
get
{
if(cachedGame?.GameObject?.IsValid!=true || cachedGame.Scene!=Scene)
cachedGame=Scene.GetAllComponents<MatchController>().FirstOrDefault();
return cachedGame;
}
}
bool ReviewFine,wasOpen;
RelegationFinePlan ReviewedPlan;
RelegationFinePlan ShownPlan=>ReviewFine?ReviewedPlan:Game.RelegationFinePreview;
bool PreviewChanged=>ReviewFine && ReviewedPlan?.PreviewKey!=Game.RelegationFinePreview?.PreviewKey;
protected override void OnUpdate()
{
base.OnUpdate();
bool open=Game?.RelegationChoiceOpen==true;
if(open!=wasOpen){ReviewFine=false;ReviewedPlan=null;wasOpen=open;}
}
void PreviewFine(){ReviewedPlan=Game.RelegationFinePreview;ReviewFine=ReviewedPlan is not null;}
void ConfirmFine(){if(ReviewedPlan is not null && !PreviewChanged)Game.AcceptRelegationFine(ReviewedPlan.PreviewKey);}
static string Text(string en,string ru)=>GamePreferences.Russian?ru:en;
static string Number(int value)=>value.ToString("N0",CultureInfo.InvariantCulture).Replace(","," ");
static string LeagueName(int division)=>GamePreferences.Russian?new[]{"Третья лига","Вторая лига","Первая лига","Национальная лига","Премьер-лига"}[Math.Clamp(division-1,0,4)]:ClubCareer.DivisionNames[Math.Clamp(division-1,0,4)];
protected override int BuildHash()=>Game?.RelegationChoiceOpen!=true?0:
HashCode.Combine(Game.Career?.Relegation?.Seed,Game.Career?.Coins,Game.Career?.Cards.Count,ReviewFine,ReviewedPlan?.PreviewKey,Game.RelegationFinePreview?.PreviewKey,GamePreferences.Revision);
}