Ejemplo n.º 1
0
        public TeamQuerySystem(Team team)
        {
            TeamQuerySystem teamQuerySystem = this;

            this.Team                  = team;
            this._mission              = Mission.Current;
            this._memberCount          = new QueryData <int>((Func <int>)(() => teamQuerySystem.Team.FormationsIncludingSpecial.Sum <Formation>((Func <Formation, int>)(f => f.CountOfUnits))), 2f);
            this._allyMemberCount      = new QueryData <int>((Func <int>)(() => teamQuerySystem.AllyTeams.Sum <TeamQuerySystem>((Func <TeamQuerySystem, int>)(t => t.MemberCount))), 2f);
            this._enemyMemberCount     = new QueryData <int>((Func <int>)(() => teamQuerySystem.EnemyTeams.Sum <TeamQuerySystem>((Func <TeamQuerySystem, int>)(t => t.MemberCount))), 2f);
            this._averagePosition      = new QueryData <Vec2>((Func <Vec2>)(() => teamQuerySystem._mission.GetAveragePositionOfTeam(team)), 5f);
            this._medianPosition       = new QueryData <WorldPosition>((Func <WorldPosition>)(() => teamQuerySystem._mission.GetMedianPositionOfTeam(team, teamQuerySystem.AveragePosition)), 5f);
            this._averageEnemyPosition = new QueryData <Vec2>((Func <Vec2>)(() =>
            {
                Vec2 positionOfEnemies = teamQuerySystem._mission.GetAveragePositionOfEnemies(team);
                if (positionOfEnemies.IsValid)
                {
                    return(positionOfEnemies);
                }
                if (team.Side == BattleSideEnum.Attacker)
                {
                    SiegeDeploymentHandler missionBehaviour = teamQuerySystem._mission.GetMissionBehaviour <SiegeDeploymentHandler>();
                    if (missionBehaviour != null)
                    {
                        return(missionBehaviour.GetEstimatedAverageDefenderPosition());
                    }
                }
                return(teamQuerySystem.AveragePosition.IsValid ? teamQuerySystem.AveragePosition : teamQuerySystem._mission.GetAveragePositionOfTeam(team));
            }), 5f);
            this._medianTargetFormationPosition = new QueryData <WorldPosition>((Func <WorldPosition>)(() => !teamQuerySystem._mission.Teams.Where <Team>((Func <Team, bool>)(t => t.IsEnemyOf(teamQuerySystem.Team))).SelectMany <Team, Formation>((Func <Team, IEnumerable <Formation> >)(t => t.FormationsIncludingSpecial)).Any <Formation>() ? teamQuerySystem.MedianPosition : teamQuerySystem._mission.Teams.Where <Team>((Func <Team, bool>)(t => t.IsEnemyOf(teamQuerySystem.Team))).SelectMany <Team, Formation>((Func <Team, IEnumerable <Formation> >)(t => t.FormationsIncludingSpecial)).MinBy <Formation, float>((Func <Formation, float>)(f => f.QuerySystem.MedianPosition.AsVec2.DistanceSquared(teamQuerySystem.AverageEnemyPosition))).QuerySystem.MedianPosition), 1f);
            QueryData <WorldPosition> .SetupSyncGroup((IQueryData)this._averageEnemyPosition, (IQueryData)this._medianTargetFormationPosition);

            this._leftFlankEdgePosition = new QueryData <WorldPosition>((Func <WorldPosition>)(() =>
            {
                Vec2 vec2  = (teamQuerySystem.MedianTargetFormationPosition.AsVec2 - teamQuerySystem.AveragePosition).RightVec();
                double num = (double)vec2.Normalize();
                WorldPosition formationPosition = teamQuerySystem.MedianTargetFormationPosition;
                formationPosition.SetVec2(formationPosition.AsVec2 - vec2 * 50f);
                return(formationPosition);
            }), 5f);
            this._rightFlankEdgePosition = new QueryData <WorldPosition>((Func <WorldPosition>)(() =>
            {
                Vec2 vec2  = (teamQuerySystem.MedianTargetFormationPosition.AsVec2 - teamQuerySystem.AveragePosition).RightVec();
                double num = (double)vec2.Normalize();
                WorldPosition formationPosition = teamQuerySystem.MedianTargetFormationPosition;
                formationPosition.SetVec2(formationPosition.AsVec2 + vec2 * 50f);
                return(formationPosition);
            }), 5f);
            this._infantryRatio      = new QueryData <float>((Func <float>)(() => teamQuerySystem.MemberCount != 0 ? (teamQuerySystem.Team.FormationsIncludingSpecial.Sum <Formation>((Func <Formation, float>)(f => f.QuerySystem.InfantryUnitRatio * (float)f.CountOfUnits)) + (float)team.Heroes.Count <Agent>((Func <Agent, bool>)(h => QueryLibrary.IsInfantry(h)))) / (float)teamQuerySystem.MemberCount : 0.0f), 15f);
            this._rangedRatio        = new QueryData <float>((Func <float>)(() => teamQuerySystem.MemberCount != 0 ? (teamQuerySystem.Team.FormationsIncludingSpecial.Sum <Formation>((Func <Formation, float>)(f => f.QuerySystem.RangedUnitRatio * (float)f.CountOfUnits)) + (float)team.Heroes.Count <Agent>((Func <Agent, bool>)(h => QueryLibrary.IsRanged(h)))) / (float)teamQuerySystem.MemberCount : 0.0f), 15f);
            this._cavalryRatio       = new QueryData <float>((Func <float>)(() => teamQuerySystem.MemberCount != 0 ? (teamQuerySystem.Team.FormationsIncludingSpecial.Sum <Formation>((Func <Formation, float>)(f => f.QuerySystem.CavalryUnitRatio * (float)f.CountOfUnits)) + (float)team.Heroes.Count <Agent>((Func <Agent, bool>)(h => QueryLibrary.IsCavalry(h)))) / (float)teamQuerySystem.MemberCount : 0.0f), 15f);
            this._rangedCavalryRatio = new QueryData <float>((Func <float>)(() => teamQuerySystem.MemberCount != 0 ? (teamQuerySystem.Team.FormationsIncludingSpecial.Sum <Formation>((Func <Formation, float>)(f => f.QuerySystem.RangedCavalryUnitRatio * (float)f.CountOfUnits)) + (float)team.Heroes.Count <Agent>((Func <Agent, bool>)(h => QueryLibrary.IsRangedCavalry(h)))) / (float)teamQuerySystem.MemberCount : 0.0f), 15f);
            QueryData <float> .SetupSyncGroup((IQueryData)this._infantryRatio, (IQueryData)this._rangedRatio, (IQueryData)this._cavalryRatio, (IQueryData)this._rangedCavalryRatio);

            this._allyInfantryRatio = new QueryData <float>((Func <float>)(() =>
            {
                int num = teamQuerySystem.AllyTeams.Sum <TeamQuerySystem>((Func <TeamQuerySystem, int>)(a => a.MemberCount));
                return(num == 0 ? 0.0f : teamQuerySystem.AllyTeams.Sum <TeamQuerySystem>((Func <TeamQuerySystem, float>)(a => a.InfantryRatio * (float)a.MemberCount)) / (float)num);
            }), 15f);
            this._allyRangedRatio = new QueryData <float>((Func <float>)(() =>
            {
                int num = teamQuerySystem.AllyTeams.Sum <TeamQuerySystem>((Func <TeamQuerySystem, int>)(a => a.MemberCount));
                return(num == 0 ? 0.0f : teamQuerySystem.AllyTeams.Sum <TeamQuerySystem>((Func <TeamQuerySystem, float>)(a => a.RangedRatio * (float)a.MemberCount)) / (float)num);
            }), 15f);
            this._allyCavalryRatio = new QueryData <float>((Func <float>)(() =>
            {
                int num = teamQuerySystem.AllyTeams.Sum <TeamQuerySystem>((Func <TeamQuerySystem, int>)(a => a.MemberCount));
                return(num == 0 ? 0.0f : teamQuerySystem.AllyTeams.Sum <TeamQuerySystem>((Func <TeamQuerySystem, float>)(a => a.CavalryRatio * (float)a.MemberCount)) / (float)num);
            }), 15f);
            this._allyRangedCavalryRatio = new QueryData <float>((Func <float>)(() =>
            {
                int num = teamQuerySystem.AllyTeams.Sum <TeamQuerySystem>((Func <TeamQuerySystem, int>)(a => a.MemberCount));
                return(num == 0 ? 0.0f : teamQuerySystem.AllyTeams.Sum <TeamQuerySystem>((Func <TeamQuerySystem, float>)(a => a.RangedCavalryRatio * (float)a.MemberCount)) / (float)num);
            }), 15f);
            QueryData <float> .SetupSyncGroup((IQueryData)this._allyInfantryRatio, (IQueryData)this._allyRangedRatio, (IQueryData)this._allyCavalryRatio, (IQueryData)this._allyRangedCavalryRatio);

            this._enemyInfantryRatio      = new QueryData <float>((Func <float>)(() => teamQuerySystem.EnemyTeams.Sum <TeamQuerySystem>((Func <TeamQuerySystem, int>)(e => e.MemberCount)) != 0 ? teamQuerySystem.EnemyTeams.Sum <TeamQuerySystem>((Func <TeamQuerySystem, float>)(e => e.InfantryRatio * (float)e.MemberCount)) / (float)teamQuerySystem.EnemyTeams.Sum <TeamQuerySystem>((Func <TeamQuerySystem, int>)(e => e.MemberCount)) : 0.0f), 15f);
            this._enemyRangedRatio        = new QueryData <float>((Func <float>)(() => teamQuerySystem.EnemyTeams.Sum <TeamQuerySystem>((Func <TeamQuerySystem, int>)(e => e.MemberCount)) != 0 ? teamQuerySystem.EnemyTeams.Sum <TeamQuerySystem>((Func <TeamQuerySystem, float>)(e => e.RangedRatio * (float)e.MemberCount)) / (float)teamQuerySystem.EnemyTeams.Sum <TeamQuerySystem>((Func <TeamQuerySystem, int>)(e => e.MemberCount)) : 0.0f), 15f);
            this._enemyCavalryRatio       = new QueryData <float>((Func <float>)(() => teamQuerySystem.EnemyTeams.Sum <TeamQuerySystem>((Func <TeamQuerySystem, int>)(e => e.MemberCount)) != 0 ? teamQuerySystem.EnemyTeams.Sum <TeamQuerySystem>((Func <TeamQuerySystem, float>)(e => e.CavalryRatio * (float)e.MemberCount)) / (float)teamQuerySystem.EnemyTeams.Sum <TeamQuerySystem>((Func <TeamQuerySystem, int>)(e => e.MemberCount)) : 0.0f), 15f);
            this._enemyRangedCavalryRatio = new QueryData <float>((Func <float>)(() => teamQuerySystem.EnemyTeams.Sum <TeamQuerySystem>((Func <TeamQuerySystem, int>)(e => e.MemberCount)) != 0 ? teamQuerySystem.EnemyTeams.Sum <TeamQuerySystem>((Func <TeamQuerySystem, float>)(e => e.RangedCavalryRatio * (float)e.MemberCount)) / (float)teamQuerySystem.EnemyTeams.Sum <TeamQuerySystem>((Func <TeamQuerySystem, int>)(e => e.MemberCount)) : 0.0f), 15f);
            this._teamPower                     = new QueryData <float>((Func <float>)(() => team.FormationsIncludingSpecial.Sum <Formation>((Func <Formation, float>)(f => f.GetFormationPower()))), 5f);
            this._overallPowerRatio             = new QueryData <float>((Func <float>)(() => (float)((double)teamQuerySystem.AllyTeams.Sum <TeamQuerySystem>((Func <TeamQuerySystem, float>)(at => at.Team.FormationsIncludingSpecial.Sum <Formation>((Func <Formation, float>)(f => f.QuerySystem.FormationPower)) + 1f)) * 1.0 / ((double)teamQuerySystem._mission.Teams.GetEnemiesOf(team).Sum <Team>((Func <Team, float>)(et => et.FormationsIncludingSpecial.Sum <Formation>((Func <Formation, float>)(f => f.QuerySystem.FormationPower)))) + 1.0))), 5f);
            this._powerRatioIncludingCasualties = new QueryData <float>((Func <float>)(() =>
            {
                CasualtyHandler casualtyHandler = teamQuerySystem._mission.GetMissionBehaviour <CasualtyHandler>();
                return((float)(((double)teamQuerySystem.AllyTeams.Sum <TeamQuerySystem>((Func <TeamQuerySystem, float>)(at => at.Team.FormationsIncludingSpecialAndEmpty.Sum <Formation>((Func <Formation, float>)(f => f.GetFormationPower() + casualtyHandler.GetCasualtyPowerLossOfFormation(f))))) + 1.0) / ((double)teamQuerySystem._mission.Teams.GetEnemiesOf(team).Sum <Team>((Func <Team, float>)(et => et.FormationsIncludingSpecialAndEmpty.Sum <Formation>((Func <Formation, float>)(f => f.GetFormationPower() + casualtyHandler.GetCasualtyPowerLossOfFormation(f))))) + 1.0)));
            }), 10f);
            this._insideWallsRatio = new QueryData <float>((Func <float>)(() =>
            {
                if (!(team.TeamAI is TeamAISiegeComponent))
                {
                    return(1f);
                }
                if (teamQuerySystem.AllyUnitCount == 0)
                {
                    return(0.0f);
                }
                int num = 0;
                foreach (Team team1 in Mission.Current.Teams.GetAlliesOf(team, true))
                {
                    foreach (Formation formation in team1.FormationsIncludingSpecial)
                    {
                        num += formation.CountUnitsOnNavMeshIDMod10(1, false);
                    }
                }
                return((float)num / (float)teamQuerySystem.AllyUnitCount);
            }), 10f);
            this._maxUnderRangedAttackRatio = new QueryData <float>((Func <float>)(() =>
            {
                float num1;
                if (teamQuerySystem.AllyUnitCount == 0)
                {
                    num1 = 0.0f;
                }
                else
                {
                    float currentTime = MBCommon.TimeType.Mission.GetTime();
                    int num2          = 0;
                    foreach (TeamQuerySystem allyTeam in teamQuerySystem.AllyTeams)
                    {
                        foreach (Formation formation in allyTeam.Team.Formations)
                        {
                            num2 += formation.GetCountOfUnitsWithCondition((Func <Agent, bool>)(agent => (double)currentTime - (double)agent.LastRangedHitTime < 10.0 && !agent.Equipment.HasShield()));
                        }
                    }
                    num1 = (float)num2 / (float)teamQuerySystem.AllyUnitCount;
                }
                return((double)num1 > (double)teamQuerySystem._maxUnderRangedAttackRatio.GetCachedValue() ? num1 : teamQuerySystem._maxUnderRangedAttackRatio.GetCachedValue());
            }), 3f);
            this.DeathCount         = 0;
            this.DeathByRangedCount = 0;
            this.InitializeTelemetryScopeNames();
        }
        public FormationQuerySystem(Formation formation)
        {
            FormationQuerySystem formationQuerySystem = this;

            this.Formation = formation;
            Mission mission = Mission.Current;

            this._formationPower = new QueryData <float>(new Func <float>(formation.GetFormationPower), 2.5f);
            this._formationMeleeFightingPower = new QueryData <float>(new Func <float>(formation.GetFormationMeleeFightingPower), 2.5f);
            this._averagePosition             = new QueryData <Vec2>((Func <Vec2>)(() =>
            {
                Vec2 vec2  = formation.CountOfUnitsWithoutDetachedOnes > 1 ? formation.GetAveragePositionOfUnits(true, true) : (formation.CountOfUnitsWithoutDetachedOnes > 0 ? formation.GetAveragePositionOfUnits(true, false) : formation.OrderPosition.AsVec2);
                float time = MBCommon.GetTime(MBCommon.TimeType.Mission);
                float num  = time - formationQuerySystem._lastAveragePositionCalculateTime;
                if ((double)num > 0.0)
                {
                    formationQuerySystem._currentVelocity.SetValue((vec2 - formationQuerySystem._averagePosition.GetCachedValue()) * (1f / num), time);
                }
                formationQuerySystem._lastAveragePositionCalculateTime = time;
                return(vec2);
            }), 0.05f);
            this._currentVelocity = new QueryData <Vec2>((Func <Vec2>)(() =>
            {
                formationQuerySystem._averagePosition.Evaluate(MBCommon.GetTime(MBCommon.TimeType.Mission));
                return(formationQuerySystem._currentVelocity.GetCachedValue());
            }), 1f);
            this._estimatedDirection = new QueryData <Vec2>((Func <Vec2>)(() =>
            {
                if (formation.CountOfUnitsWithoutDetachedOnes > 0)
                {
                    Vec2 averagePositionOfUnits = formation.GetAveragePositionOfUnits(true, false);
                    float num1 = 0.0f;
                    float num2 = 0.0f;
                    Vec2 localAveragePosition = formation.OrderLocalAveragePosition;
                    foreach (Agent looseDetachedOne in formation.UnitsWithoutLooseDetachedOnes)
                    {
                        Vec2?positionOfUnitOrDefault = formation.arrangement.GetLocalPositionOfUnitOrDefault((IFormationUnit)looseDetachedOne);
                        if (positionOfUnitOrDefault.HasValue)
                        {
                            Vec2 vec2   = positionOfUnitOrDefault.Value;
                            Vec2 asVec2 = looseDetachedOne.Position.AsVec2;
                            num1       += (float)(((double)vec2.x - (double)localAveragePosition.x) * ((double)asVec2.x - (double)averagePositionOfUnits.x) + ((double)vec2.y - (double)localAveragePosition.y) * ((double)asVec2.y - (double)averagePositionOfUnits.y));
                            num2       += (float)(((double)vec2.x - (double)localAveragePosition.x) * ((double)asVec2.y - (double)averagePositionOfUnits.y) - ((double)vec2.y - (double)localAveragePosition.y) * ((double)asVec2.x - (double)averagePositionOfUnits.x));
                        }
                    }
                    float num3 = 1f / (float)formation.CountOfUnitsWithoutDetachedOnes;
                    float num4 = num1 * num3;
                    float num5 = num2 * num3;
                    float num6 = MathF.Sqrt((float)((double)num4 * (double)num4 + (double)num5 * (double)num5));
                    if ((double)num6 > 0.0)
                    {
                        double num7 = Math.Acos((double)MBMath.ClampFloat(num4 / num6, -1f, 1f));
                        Vec2 vec2_1 = Vec2.FromRotation((float)num7);
                        Vec2 vec2_2 = Vec2.FromRotation((float)-num7);
                        float num8  = 0.0f;
                        float num9  = 0.0f;
                        foreach (Agent looseDetachedOne in formation.UnitsWithoutLooseDetachedOnes)
                        {
                            Vec2?positionOfUnitOrDefault = formation.arrangement.GetLocalPositionOfUnitOrDefault((IFormationUnit)looseDetachedOne);
                            if (positionOfUnitOrDefault.HasValue)
                            {
                                Vec2 parentUnitF1 = vec2_1.TransformToParentUnitF(positionOfUnitOrDefault.Value - localAveragePosition);
                                Vec2 parentUnitF2 = vec2_2.TransformToParentUnitF(positionOfUnitOrDefault.Value - localAveragePosition);
                                Vec2 asVec2       = looseDetachedOne.Position.AsVec2;
                                num8 += (parentUnitF1 - asVec2 + averagePositionOfUnits).LengthSquared;
                                num9 += (parentUnitF2 - asVec2 + averagePositionOfUnits).LengthSquared;
                            }
                        }
                        return((double)num8 >= (double)num9 ? vec2_2 : vec2_1);
                    }
                }
                return(new Vec2(0.0f, 1f));
            }), 0.2f);
            this._medianPosition = new QueryData <WorldPosition>((Func <WorldPosition>)(() =>
            {
                if (formation.CountOfUnitsWithoutDetachedOnes != 0)
                {
                    return(formation.CountOfUnitsWithoutDetachedOnes != 1 ? formation.GetMedianAgent(true, true, formationQuerySystem.AveragePosition).GetWorldPosition() : formation.GetMedianAgent(true, false, formationQuerySystem.AveragePosition).GetWorldPosition());
                }
                if (formation.CountOfUnits == 0)
                {
                    return(formation.OrderPosition);
                }
                return(formation.CountOfUnits != 1 ? formation.GetMedianAgent(false, true, formationQuerySystem.AveragePosition).GetWorldPosition() : formation.GetFirstUnit().GetWorldPosition());
            }), 0.05f);
            this._averageAllyPosition = new QueryData <Vec2>((Func <Vec2>)(() =>
            {
                IEnumerable <Formation> source = mission.Teams.GetAlliesOf(formation.Team, true).SelectMany <TaleWorlds.MountAndBlade.Team, Formation>((Func <TaleWorlds.MountAndBlade.Team, IEnumerable <Formation> >)(t => t.FormationsIncludingSpecial)).Where <Formation>(closure_1 ?? (closure_1 = (Func <Formation, bool>)(f => f != formation)));
                if (source.IsEmpty <Formation>())
                {
                    return(closure_0.AveragePosition);
                }
                Vec2 zero = Vec2.Zero;
                int num   = 0;
                foreach (Formation formation1 in source)
                {
                    zero += formation1.GetAveragePositionOfUnits(false, false) * (float)formation1.CountOfUnits;
                    num  += formation1.CountOfUnits;
                }
                return(num == 0 ? Vec2.Invalid : zero *(1f / (float)num));
            }), 5f);
            this._idealAverageDisplacement = new QueryData <float>((Func <float>)(() => (float)Math.Sqrt(Math.Pow((double)formation.Width / 2.0, 2.0) + Math.Pow((double)formation.Depth / 2.0, 2.0)) / 2f), 5f);
            this._formationIntegrityData   = new QueryData <FormationQuerySystem.FormationIntegrityDataGroup>((Func <FormationQuerySystem.FormationIntegrityDataGroup>)(() =>
            {
                if (formation.CountOfUnitsWithoutDetachedOnes > 0)
                {
                    float num1 = 0.0f;
                    List <IFormationUnit> allUnits = formation.arrangement.GetAllUnits();
                    Vec3 vec3;
                    for (int index = 0; index < allUnits.Count; ++index)
                    {
                        Agent unit  = allUnits[index] as Agent;
                        double num2 = (double)num1;
                        Vec2 globalPositionOfUnit = formation.GetCurrentGlobalPositionOfUnit(unit, false);
                        vec3                 = unit.Position;
                        Vec2 asVec2          = vec3.AsVec2;
                        double lengthSquared = (double)(globalPositionOfUnit - asVec2).LengthSquared;
                        num1                 = (float)(num2 + lengthSquared);
                    }
                    Vec2 vec2_1;
                    for (int index = 0; index < formation.LooseDetachedUnits.Count; ++index)
                    {
                        Agent looseDetachedUnit   = formation.LooseDetachedUnits[index];
                        double num2               = (double)num1;
                        Vec2 globalPositionOfUnit = formation.GetCurrentGlobalPositionOfUnit(looseDetachedUnit, false);
                        vec3                 = looseDetachedUnit.Position;
                        Vec2 asVec2          = vec3.AsVec2;
                        vec2_1               = globalPositionOfUnit - asVec2;
                        double lengthSquared = (double)vec2_1.LengthSquared;
                        num1                 = (float)(num2 + lengthSquared);
                    }
                    float num3  = (float)((double)num1 / (double)formation.CountOfUnitsWithoutDetachedOnes * 4.0);
                    float num4  = 0.0f;
                    Vec2 vec2_2 = Vec2.Zero;
                    float num5  = 0.0f;
                    int num6    = 0;
                    for (int index = 0; index < allUnits.Count; ++index)
                    {
                        Agent unit = allUnits[index] as Agent;
                        Vec2 globalPositionOfUnit = formation.GetCurrentGlobalPositionOfUnit(unit, false);
                        vec3                = unit.Position;
                        Vec2 asVec2_1       = vec3.AsVec2;
                        vec2_1              = globalPositionOfUnit - asVec2_1;
                        float lengthSquared = vec2_1.LengthSquared;
                        if ((double)lengthSquared < (double)num3)
                        {
                            num4         += lengthSquared;
                            Vec2 vec2_3   = vec2_2;
                            vec3          = unit.AverageVelocity;
                            Vec2 asVec2_2 = vec3.AsVec2;
                            vec2_2        = vec2_3 + asVec2_2;
                            num5         += unit.MaximumForwardUnlimitedSpeed;
                            ++num6;
                        }
                    }
                    for (int index = 0; index < formation.LooseDetachedUnits.Count; ++index)
                    {
                        Agent looseDetachedUnit   = formation.LooseDetachedUnits[index];
                        Vec2 globalPositionOfUnit = formation.GetCurrentGlobalPositionOfUnit(looseDetachedUnit, false);
                        vec3                = looseDetachedUnit.Position;
                        Vec2 asVec2_1       = vec3.AsVec2;
                        vec2_1              = globalPositionOfUnit - asVec2_1;
                        float lengthSquared = vec2_1.LengthSquared;
                        if ((double)lengthSquared < (double)num3)
                        {
                            num4         += lengthSquared;
                            Vec2 vec2_3   = vec2_2;
                            vec3          = looseDetachedUnit.AverageVelocity;
                            Vec2 asVec2_2 = vec3.AsVec2;
                            vec2_2        = vec2_3 + asVec2_2;
                            num5         += looseDetachedUnit.MaximumForwardUnlimitedSpeed;
                            ++num6;
                        }
                    }
                    if (num6 > 0)
                    {
                        Vec2 vec2_3 = vec2_2 * (1f / (float)num6);
                        float x     = num4 / (float)num6;
                        float num2  = num5 / (float)num6;
                        FormationQuerySystem.FormationIntegrityDataGroup integrityDataGroup;
                        integrityDataGroup.AverageVelocityExcludeFarAgents          = vec2_3;
                        integrityDataGroup.DeviationOfPositionsExcludeFarAgents     = MathF.Sqrt(x);
                        integrityDataGroup.AverageMaxUnlimitedSpeedExcludeFarAgents = num2;
                        return(integrityDataGroup);
                    }
                }
                FormationQuerySystem.FormationIntegrityDataGroup integrityDataGroup1;
                integrityDataGroup1.AverageVelocityExcludeFarAgents          = Vec2.Zero;
                integrityDataGroup1.DeviationOfPositionsExcludeFarAgents     = 0.0f;
                integrityDataGroup1.AverageMaxUnlimitedSpeedExcludeFarAgents = 0.0f;
                return(integrityDataGroup1);
            }), 1f);
            this._formationDispersedness = new QueryData <float>((Func <float>)(() =>
            {
                if (formation.CountOfUnits == 0)
                {
                    return(0.0f);
                }
                float num1 = 0.0f;
                int num2   = 0;
                foreach (IFormationUnit allUnit in formation.arrangement.GetAllUnits())
                {
                    Vec2?positionOfUnitOrDefault = formation.arrangement.GetLocalPositionOfUnitOrDefault(allUnit);
                    if (positionOfUnitOrDefault.HasValue)
                    {
                        MatrixFrame m = new MatrixFrame(Mat3.Identity, new Vec3(positionOfUnitOrDefault.Value));
                        MatrixFrame matrixFrame;
                        ref MatrixFrame local = ref matrixFrame;
                        Mat3 rot = new Mat3(new Vec3(formation.Direction.RightVec()), new Vec3(formation.Direction), new Vec3(z: 1f));
                        WorldPosition worldPosition = formation.QuerySystem.MedianPosition;
                        Vec3 navMeshVec3            = worldPosition.GetNavMeshVec3();
                        local = new MatrixFrame(rot, navMeshVec3);
                        MatrixFrame parent = matrixFrame.TransformToParent(m);
                        double num3        = (double)num1;
                        worldPosition      = (allUnit as Agent).GetWorldPosition();
                        double num4        = (double)worldPosition.GetGroundVec3().Distance(parent.origin);
                        num1 = (float)(num3 + num4);
                    }