protected override Vec2 GetLocalDirectionOfUnit(int fileIndex, int rankIndex)
        {
            int  unitCountOfRank = this.GetUnitCountOfRank(rankIndex);
            int  num             = (this.FileCount - unitCountOfRank) / 2;
            Vec2 vec2            = Vec2.FromRotation((float)((double)((fileIndex - num) * 2) * 3.14159274101257 / (double)unitCountOfRank + 3.14159274101257));

            vec2.x *= -1f;
            return(vec2);
        }
Esempio n. 2
0
        private static IEnumerable <StrategicArea> CreateStrategicAreas(
            Mission mission,
            int count,
            WorldPosition center,
            float distance,
            WorldPosition target,
            float width,
            int capacity,
            BattleSideEnum side)
        {
            Scene scene = mission.Scene;
            float distanceMultiplied   = distance * 0.7f;
            Func <WorldPosition> func1 = (Func <WorldPosition>)(() =>
            {
                WorldPosition worldPosition = center;
                float rotation = (float)((double)MBRandom.RandomFloat * 3.14159274101257 * 2.0);
                worldPosition.SetVec2(center.AsVec2 + Vec2.FromRotation(rotation) * distanceMultiplied);
                return(worldPosition);
            });

            WorldPosition[] worldPositionArray = ((Func <WorldPosition[]>)(() =>
            {
                float rotation = (float)((double)MBRandom.RandomFloat * 3.14159274101257 * 2.0);
                switch (count)
                {
                case 2:
                    WorldPosition worldPosition1 = center;
                    worldPosition1.SetVec2(center.AsVec2 + Vec2.FromRotation(rotation) * distanceMultiplied);
                    WorldPosition worldPosition2 = center;
                    worldPosition2.SetVec2(center.AsVec2 + Vec2.FromRotation(rotation + 3.141593f) * distanceMultiplied);
                    return(new WorldPosition[2]
                    {
                        worldPosition1,
                        worldPosition2
                    });

                case 3:
                    WorldPosition worldPosition3 = center;
                    worldPosition3.SetVec2(center.AsVec2 + Vec2.FromRotation(rotation + 0.0f) * distanceMultiplied);
                    WorldPosition worldPosition4 = center;
                    worldPosition4.SetVec2(center.AsVec2 + Vec2.FromRotation(rotation + 2.094395f) * distanceMultiplied);
                    WorldPosition worldPosition5 = center;
                    worldPosition5.SetVec2(center.AsVec2 + Vec2.FromRotation(rotation + 4.18879f) * distanceMultiplied);
                    return(new WorldPosition[3]
                    {
                        worldPosition3,
                        worldPosition4,
                        worldPosition5
                    });

                case 4:
                    WorldPosition worldPosition6 = center;
                    worldPosition6.SetVec2(center.AsVec2 + Vec2.FromRotation(rotation + 0.0f) * distanceMultiplied);
                    WorldPosition worldPosition7 = center;
                    worldPosition7.SetVec2(center.AsVec2 + Vec2.FromRotation(rotation + 1.570796f) * distanceMultiplied);
                    WorldPosition worldPosition8 = center;
                    worldPosition8.SetVec2(center.AsVec2 + Vec2.FromRotation(rotation + 3.141593f) * distanceMultiplied);
                    WorldPosition worldPosition9 = center;
                    worldPosition9.SetVec2(center.AsVec2 + Vec2.FromRotation(rotation + 4.712389f) * distanceMultiplied);
                    return(new WorldPosition[4]
                    {
                        worldPosition6,
                        worldPosition7,
                        worldPosition8,
                        worldPosition9
                    });

                default:
                    return(new WorldPosition[0]);
                }
            }))();
            List <WorldPosition> positions = new List <WorldPosition>();

            foreach (WorldPosition worldPosition in worldPositionArray)
            {
                WorldPosition center1            = worldPosition;
                WorldPosition position           = mission.FindPositionWithBiggestSlopeTowardsDirectionInSquare(ref center1, distance * 0.25f, ref target);
                Func <WorldPosition, bool> func2 = (Func <WorldPosition, bool>)(p =>
                {
                    float pathDistance;
                    if (positions.Any <WorldPosition>((Func <WorldPosition, bool>)(wp => (double)wp.AsVec2.DistanceSquared(p.AsVec2) < 1.0)) || (!scene.GetPathDistanceBetweenPositions(ref center, ref p, 0.0f, out pathDistance) ? 0 : ((double)pathDistance < (double)center.AsVec2.Distance(p.AsVec2) * 2.0 ? 1 : 0)) == 0)
                    {
                        return(false);
                    }
                    positions.Add(position);
                    return(true);
                });
                if (!func2(position) && !func2(worldPosition))
                {
                    int num = 0;
                    do
                    {
                        ;
                    }while (num++ < 10 && !func2(func1()));
                    if (num >= 10)
                    {
                        positions.Add(center);
                    }
                }
            }
            Vec2 direction = (target.AsVec2 - center.AsVec2).Normalized();

            foreach (WorldPosition position in positions)
            {
                yield return(ArrangementOrder.CreateStrategicArea(scene, position, direction, width, capacity, side));
            }
        }
        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);
                    }