Partial class for the soccer match simulation. Adds a broadcast tactical plan per team, storing tempo and mentality, adjusting pass decisions, off ball movement and effort.
using System;
namespace Socer;
public sealed partial class MatchSimulation
{
public float[] TeamTempo={.5f,.5f},TeamMentality={.5f,.5f};
public bool[] BroadcastPlanActive=new bool[2];
public void SetBroadcastPlan(float tempo,float mentality,int team=0)
{
tempo=Math.Clamp(tempo,0,1);mentality=Math.Clamp(mentality,0,1);
SetClubPlan(mentality<.3f?0:mentality>.7f?2:1,team);
TeamTempo[team]=tempo;TeamMentality[team]=mentality;BroadcastPlanActive[team]=true;
}
public float DecisionTempo(int team)=>BroadcastPlanActive[team]?1.55f-TeamTempo[team]*1.1f:1;
float PlanPassValue(Footballer p,float gain,float safety,float distance)
{
if(!BroadcastPlanActive[p.Team])return 0;
float tempo=TeamTempo[p.Team]-.5f,attack=TeamMentality[p.Team]-.5f;
// Quick progression competes with carrying; patient play rewards safe recycling.
return tempo*(3+safety*5+Math.Clamp(gain,-4,10)*.4f)+
attack*Math.Clamp(gain,-6,12)*.65f-Math.Max(0,-tempo)*(1-safety)*7-
(tempo<0 && distance>26?-tempo*3:0);
}
Point BroadcastPlanMovement(Footballer p,Point target,int possessionTeam)
{
if(!BroadcastPlanActive[p.Team] || p.Keeper || Owner<0 || p.Id==Owner ||
WindupPlayer==p.Id || DuelDefender==p.Id || p.DirectOrderUntil>Seconds ||
p.BoxRole>0 || p.RunUntil>Seconds || p.FootballRunUntil>Seconds)return target;
float attack=TeamMentality[p.Team]-.5f;
if(possessionTeam==p.Team)
target.X+=Direction(p.Team)*attack*(BackLine(p)?8:14);
else if(p.Id!=chasers[p.Team] && p.Id!=secondChasers[p.Team])
{
var local=World(target,p.Team);var ball=World(Ball,p.Team);
if(attack<0)
{
local.X=Math.Max(StrikerRole(p)?38:9,Math.Min(local.X+attack*12,ball.X-4+attack*12));
local.Y=34+(local.Y-34)*(1+attack*.35f);
}
else local.X+=attack*12;
target=World(local,p.Team);
}
else if(p.Id==secondChasers[p.Team] && attack>.2f && (p.Position-Ball).Length<12+attack*12)
{target=Ball;p.Action="Прессинг";}
return target;
}
float PlanEffort(int team)=>BroadcastPlanActive[team]?
1+(TeamTempo[team]-.5f)*.32f+(TeamMentality[team]-.5f)*.36f:1;
}