Static helper for the PlayerCard type in the Socer namespace. Holds training stat names, initializes card potential, stat caps and edition on save load, and exposes small stat helpers (Stats, TrainingStats, Cap, Add, Fits) plus stubbed no-op training plan/supporting stat methods.
using System;
using System.Linq;
namespace Socer;
// Compatibility helpers for old saves and tools. Player levels, XP and their
// growth plan are retired: upgrade cards change a skill slot, never these stats.
public static class CardDevelopment
{
public const int MaxTrainingLevel=10;
public const int TrainingStatCount=10;
public static readonly string[] TrainingStatNames={"Pace","Shooting","Passing","Defending","Stamina","Goalkeeping","Dribbling","Physical","Aggression","Composure"};
public static void Initialize(PlayerCard card)
{
if(card==null)return;
// Retain every already-earned attribute. No level-dependent endpoint,
// free skill or latent stat increase is applied during save loading.
card.Potential=Math.Clamp(Math.Max(card.Overall,card.Potential),card.Overall,99);
if(card.StatCaps?.Length!=6)card.StatCaps=Stats(card);
if(string.IsNullOrEmpty(card.Edition))card.Edition=card.Overall>=CardRatings.Elite?"ELITE":
card.Overall>=CardRatings.Gold?"GOLD":card.Overall>=CardRatings.Silver?"SILVER":"BRONZE";
}
public static int[] Stats(PlayerCard p)=>new[]{p.Pace,p.Shooting,p.Passing,p.Defence,p.Endurance,p.Keeping};
public static int[] TrainingStats(PlayerCard p)=>new[]{p.Pace,p.Shooting,p.Passing,p.Defence,p.Endurance,p.Keeping,
PlayerCardDetails.Dribbling(p),PlayerCardDetails.Physical(p),p.Aggression,p.Composure};
public static int Cap(PlayerCard p,int stat)=>p.TrainingTargets?.Length==TrainingStatCount?p.TrainingTargets[stat]:
p.StatCaps?.Length==6 && stat<6?p.StatCaps[stat]:99;
// Kept as an explicit data-editing helper for existing verification tools;
// no career upgrade or match reward calls it.
public static void Add(PlayerCard p,int stat,int amount)
{
switch(stat)
{
case 0:p.Pace+=amount;break;
case 1:p.Shooting+=amount;break;
case 2:p.Passing+=amount;break;
case 3:p.Defence+=amount;break;
case 4:p.Endurance+=amount;break;
case 5:p.Keeping+=amount;break;
case 6:p.Dribbling=PlayerCardDetails.Dribbling(p)+amount;break;
case 7:p.Physical=PlayerCardDetails.Physical(p)+amount;break;
case 8:p.Aggression+=amount;break;
case 9:p.Composure+=amount;break;
}
}
public static void ApplySupportingStats(PlayerCard p,int[] gains) { }
public static bool Fits(PlayerCard p,int[] gains)=>gains!=null && gains.All(g=>g==0);
public static int[] TrainingPlan(PlayerCard player,TrainingCardItem item)=>new int[TrainingStatCount];
}