Esempio n. 1
0
        public static void ResolveCollision(ref Manifold m)
        {
            var rv = m.B.Velocity - m.A.Velocity;

            if (float.IsNaN(m.Normal.X) || float.IsNaN(m.Normal.Y))
            {
                return;
            }

            var velAlongNormal = Vec2.DotProduct(rv, m.Normal);

            if (velAlongNormal > 0)
            {
                return;
            }

            var e = Math.Min(m.A.Restitution, m.B.Restitution);

            var j = -(1 + e) * velAlongNormal;

            j = j / (m.A.IMass + m.B.IMass);

            var impulse = m.Normal * j;

            m.A.Velocity = !m.A.Locked ? m.A.Velocity - impulse * m.A.IMass : m.A.Velocity;
            m.B.Velocity = !m.B.Locked ? m.B.Velocity + impulse * m.B.IMass : m.B.Velocity;
        }
Esempio n. 2
0
        private bool IsTacticalPositionEligible(TacticalPosition tacticalPosition)
        {
            if (!this.CheckAndDetermineFormation(ref this._mainInfantry, (Func <Formation, bool>)(f => f.QuerySystem.IsInfantryFormation)))
            {
                return(false);
            }
            float num1 = this.team.QuerySystem.AveragePosition.Distance(tacticalPosition.Position.AsVec2);
            Vec2  vec2 = this.team.QuerySystem.AverageEnemyPosition;
            float num2 = vec2.Distance(this._mainInfantry.QuerySystem.AveragePosition);

            if ((double)num1 > 20.0 && (double)num1 > (double)num2 * 0.5)
            {
                return(false);
            }
            int countOfUnits = this._mainInfantry.CountOfUnits;

            if ((double)this._mainInfantry.MaximumInterval * (double)(countOfUnits - 1) + (double)this._mainInfantry.UnitDiameter * (double)countOfUnits < (double)tacticalPosition.Width)
            {
                return(false);
            }
            vec2 = this.team.QuerySystem.AverageEnemyPosition - tacticalPosition.Position.AsVec2;
            vec2 = vec2.Normalized();
            float num3 = vec2.DotProduct(tacticalPosition.Direction);

            return(tacticalPosition.IsInsurmountable ? (double)Math.Abs(num3) >= 0.5 : (double)num3 >= 0.5);
        }
        protected override void CalculateCurrentOrder()
        {
            WorldPosition medianPosition;
            Vec2          direction;

            if (this.formation.QuerySystem.ClosestEnemyFormation != null)
            {
                medianPosition = this.formation.QuerySystem.MedianPosition;
                medianPosition.SetVec2((double)this.formation.QuerySystem.AveragePosition.DistanceSquared(this.formation.QuerySystem.ClosestEnemyFormation.MedianPosition.AsVec2) > 400.0 ? this.formation.QuerySystem.HighGroundCloseToForeseenBattleGround : this.formation.QuerySystem.AveragePosition);
                Vec2 vec2_1;
                if ((double)this.formation.QuerySystem.AveragePosition.DistanceSquared(this.formation.QuerySystem.HighGroundCloseToForeseenBattleGround) <= 25.0)
                {
                    Vec2 vec2_2 = this.formation.Direction;
                    vec2_2 = (double)vec2_2.DotProduct((this.formation.QuerySystem.ClosestEnemyFormation.MedianPosition.AsVec2 - this.formation.QuerySystem.AveragePosition).Normalized()) < 0.5 ? this.formation.QuerySystem.ClosestEnemyFormation.MedianPosition.AsVec2 - this.formation.QuerySystem.AveragePosition : this.formation.Direction;
                    vec2_1 = vec2_2.Normalized();
                }
                else
                {
                    vec2_1 = (this.formation.QuerySystem.Team.MedianTargetFormationPosition.AsVec2 - medianPosition.AsVec2).Normalized();
                }
                direction = vec2_1;
            }
            else
            {
                direction      = this.formation.Direction;
                medianPosition = this.formation.QuerySystem.MedianPosition;
                medianPosition.SetVec2(this.formation.QuerySystem.AveragePosition);
            }
            this.CurrentOrder       = MovementOrder.MovementOrderMove(medianPosition);
            this.CurrentFacingOrder = FacingOrder.FacingOrderLookAtDirection(direction);
        }
        public Vec3 GetClosestPointToEscape(Vec2 position)
        {
            if (this._nodes.Count == 1)
            {
                return(this._nodes[0]);
            }
            float num1   = float.MaxValue;
            Vec3  vec3_1 = this._nodes[0];

            for (int index = 0; index < this._nodes.Count - 1; ++index)
            {
                Vec3  node1 = this._nodes[index];
                Vec3  node2 = this._nodes[index + 1];
                float num2  = node1.DistanceSquared(node2);
                if ((double)num2 > 0.0)
                {
                    float num3   = Math.Max(0.0f, Math.Min(1f, Vec2.DotProduct(position - node1.AsVec2, node2.AsVec2 - node1.AsVec2) / num2));
                    Vec3  vec3_2 = node1 + num3 * (node2 - node1);
                    float num4   = vec3_2.AsVec2.DistanceSquared(position);
                    if ((double)num1 > (double)num4)
                    {
                        num1   = num4;
                        vec3_1 = vec3_2;
                    }
                }
                else
                {
                    num1   = 0.0f;
                    vec3_1 = node1;
                }
            }
            return(vec3_1);
        }
 protected override void CalculateCurrentOrder()
 {
     if (this._switchedToShieldWallRecently && !this._switchedToShieldWallTimer.Check(Mission.Current.Time) && (double)this.formation.QuerySystem.FormationDispersedness > 2.0)
     {
         WorldPosition medianPosition = this.formation.QuerySystem.MedianPosition;
         if (this._reformPosition.IsValid)
         {
             medianPosition.SetVec2(this._reformPosition);
         }
         else
         {
             this._reformPosition = this.formation.QuerySystem.AveragePosition + (this.formation.QuerySystem.Team.MedianTargetFormationPosition.AsVec2 - this.formation.QuerySystem.AveragePosition).Normalized() * 5f;
             medianPosition.SetVec2(this._reformPosition);
         }
         this.CurrentOrder = MovementOrder.MovementOrderMove(medianPosition);
     }
     else
     {
         this._switchedToShieldWallRecently = false;
         bool flag = false;
         Vec2 vec2_1;
         if (this.formation.QuerySystem.ClosestEnemyFormation != null && this.formation.QuerySystem.ClosestEnemyFormation.IsCavalryFormation)
         {
             Vec2   vec2_2          = this.formation.QuerySystem.AveragePosition - this.formation.QuerySystem.ClosestEnemyFormation.AveragePosition;
             double num1            = (double)vec2_2.Normalize();
             Vec2   currentVelocity = this.formation.QuerySystem.ClosestEnemyFormation.CurrentVelocity;
             float  num2            = currentVelocity.Normalize();
             if (num1 < 30.0 && (double)num2 > 2.0 && (double)vec2_2.DotProduct(currentVelocity) > 0.5)
             {
                 flag = true;
                 WorldPosition medianPosition = this.formation.QuerySystem.MedianPosition;
                 if (this._reformPosition.IsValid)
                 {
                     medianPosition.SetVec2(this._reformPosition);
                 }
                 else
                 {
                     vec2_1 = this.formation.QuerySystem.Team.MedianTargetFormationPosition.AsVec2 - this.formation.QuerySystem.AveragePosition;
                     this._reformPosition = this.formation.QuerySystem.AveragePosition + vec2_1.Normalized() * 5f;
                     medianPosition.SetVec2(this._reformPosition);
                 }
                 this.CurrentOrder = MovementOrder.MovementOrderMove(medianPosition);
             }
         }
         if (flag)
         {
             return;
         }
         this._reformPosition = Vec2.Invalid;
         WorldPosition position = this.formation.Team.QuerySystem.EnemyTeams.SelectMany <TeamQuerySystem, Formation>((Func <TeamQuerySystem, IEnumerable <Formation> >)(t => t.Team.FormationsIncludingSpecial)).Count <Formation>() == 1 ? this.formation.QuerySystem.ClosestEnemyFormation.MedianPosition : this.formation.QuerySystem.Team.MedianTargetFormationPosition;
         vec2_1 = this.formation.QuerySystem.Team.MedianTargetFormationPosition.AsVec2 - this.formation.QuerySystem.AveragePosition;
         Vec2 direction = vec2_1.Normalized();
         this.CurrentOrder       = MovementOrder.MovementOrderMove(position);
         this.CurrentFacingOrder = FacingOrder.FacingOrderLookAtDirection(direction);
     }
 }
Esempio n. 6
0
        protected override void CalculateCurrentOrder()
        {
            Vec2          vec2_1;
            WorldPosition medianPosition;
            Vec2          vec2_2;
            WorldPosition worldPosition;

            if (this.formation.QuerySystem.ClosestEnemyFormation == null || this._mainFormation == null)
            {
                vec2_1         = this.formation.Direction;
                medianPosition = this.formation.QuerySystem.MedianPosition;
                medianPosition.SetVec2(this.formation.QuerySystem.AveragePosition);
            }
            else
            {
                vec2_2 = this.formation.Direction;
                ref Vec2 local = ref vec2_2;
                worldPosition = this.formation.QuerySystem.ClosestEnemyFormation.MedianPosition;
                Vec2 asVec2_1 = worldPosition.AsVec2;
                worldPosition = this._mainFormation.QuerySystem.MedianPosition;
                Vec2 asVec2_2 = worldPosition.AsVec2;
                Vec2 v        = (asVec2_1 - asVec2_2).Normalized();
                Vec2 vec2_3;
                if ((double)local.DotProduct(v) >= 0.5)
                {
                    vec2_3 = this.formation.Direction;
                }
                else
                {
                    worldPosition = this.formation.QuerySystem.ClosestEnemyFormation.MedianPosition;
                    Vec2 asVec2_3 = worldPosition.AsVec2;
                    worldPosition = this._mainFormation.QuerySystem.MedianPosition;
                    Vec2 asVec2_4 = worldPosition.AsVec2;
                    vec2_3 = asVec2_3 - asVec2_4;
                }
                vec2_1        = vec2_3.Normalized();
                worldPosition = this._mainFormation.OrderPosition;
                Vec2 asVec2_5 = worldPosition.AsVec2;
                worldPosition = this._mainFormation.QuerySystem.MedianPosition;
                Vec2  asVec2_6 = worldPosition.AsVec2;
                Vec2  vec2_4   = asVec2_5 - asVec2_6;
                float num1     = this._mainFormation.QuerySystem.MovementSpeed * 7f;
                float length   = vec2_4.Length;
                if ((double)length > 0.0)
                {
                    float num2 = num1 / length;
                    if ((double)num2 < 1.0)
                    {
                        vec2_4 *= num2;
                    }
                }
                medianPosition = this._mainFormation.QuerySystem.MedianPosition;
                medianPosition.SetVec2(medianPosition.AsVec2 + vec2_1 * 8f + vec2_4);
            }
        public Vec2 GetDirection(Formation f)
        {
            Vec2 vec2 = this.Direction(f);

            if (f.IsAIControlled && (double)vec2.DotProduct(this._previousDirection) > 0.870000004768372)
            {
                vec2 = this._previousDirection;
            }
            else
            {
                this._previousDirection = vec2;
            }
            return(vec2);
        }
            protected override float GetAiWeight()
            {
                FormationQuerySystem querySystem = attackingFormation.QuerySystem;

                if (querySystem.ClosestEnemyFormation == null || querySystem.ClosestEnemyFormation.ClosestEnemyFormation == querySystem)
                {
                    return(0f);
                }
                Vec2 vec = (querySystem.ClosestEnemyFormation.MedianPosition.AsVec2 - querySystem.AveragePosition).Normalized();
                Vec2 v   = (querySystem.ClosestEnemyFormation.ClosestEnemyFormation.MedianPosition.AsVec2 - querySystem.ClosestEnemyFormation.MedianPosition.AsVec2).Normalized();

                if (vec.DotProduct(v) > -0.5f)
                {
                    return(0f);
                }
                return(1.2f);
            }
Esempio n. 9
0
        protected override float GetAiWeight()
        {
            FormationQuerySystem querySystem = this.formation.QuerySystem;

            if (querySystem.ClosestEnemyFormation == null || querySystem.ClosestEnemyFormation.ClosestEnemyFormation == querySystem)
            {
                return(0.0f);
            }
            Vec2          vec2           = (querySystem.ClosestEnemyFormation.MedianPosition.AsVec2 - querySystem.AveragePosition).Normalized();
            WorldPosition medianPosition = querySystem.ClosestEnemyFormation.ClosestEnemyFormation.MedianPosition;
            Vec2          asVec2_1       = medianPosition.AsVec2;

            medianPosition = querySystem.ClosestEnemyFormation.MedianPosition;
            Vec2 asVec2_2 = medianPosition.AsVec2;
            Vec2 v        = (asVec2_1 - asVec2_2).Normalized();

            return((double)vec2.DotProduct(v) > -0.5 ? 0.0f : 1.2f);
        }
Esempio n. 10
0
        protected override void CalculateCurrentOrder()
        {
            Vec2 vec2_1;

            if (this.formation.QuerySystem.ClosestSignificantlyLargeEnemyFormation != null && this._mainFormation != null)
            {
                Vec2 vec2_2 = (this.formation.QuerySystem.ClosestSignificantlyLargeEnemyFormation.MedianPosition.AsVec2 - this.formation.QuerySystem.AveragePosition).Normalized();
                Vec2 v      = (this._mainFormation.QuerySystem.MedianPosition.AsVec2 - this.formation.QuerySystem.AveragePosition).Normalized();
                vec2_1 = (double)vec2_2.DotProduct(v) <= 0.5 ? vec2_2 : this._mainFormation.FacingOrder.GetDirection(this._mainFormation);
            }
            else
            {
                vec2_1 = this.formation.Direction;
            }
            WorldPosition medianPosition;

            if (this._mainFormation == null)
            {
                medianPosition = this.formation.QuerySystem.MedianPosition;
                medianPosition.SetVec2(this.formation.QuerySystem.AveragePosition);
            }
            else
            {
                medianPosition = this._mainFormation.QuerySystem.MedianPosition;
                medianPosition.SetVec2(medianPosition.AsVec2 - vec2_1 * (float)(((double)this._mainFormation.Depth + (double)this.formation.Depth) * 0.5));
            }
            WorldPosition worldPosition = this.CurrentOrder.GetPosition(this.formation);

            if (worldPosition.IsValid && this.formation.QuerySystem.ClosestSignificantlyLargeEnemyFormation.IsRangedCavalryFormation)
            {
                Vec2     averagePosition = this.formation.QuerySystem.AveragePosition;
                ref Vec2 local           = ref averagePosition;
                worldPosition = this.formation.QuerySystem.ClosestSignificantlyLargeEnemyFormation.MedianPosition;
                Vec2 asVec2 = worldPosition.GetNavMeshVec3().AsVec2;
                if ((double)local.DistanceSquared(asVec2) < (double)this.formation.QuerySystem.ClosestSignificantlyLargeEnemyFormation.MissileRange * (double)this.formation.QuerySystem.ClosestSignificantlyLargeEnemyFormation.MissileRange)
                {
                    worldPosition = this.CurrentOrder.GetPosition(this.formation);
                    if ((double)worldPosition.GetNavMeshVec3().DistanceSquared(medianPosition.GetNavMeshVec3()) < (double)this.formation.Depth * (double)this.formation.Depth)
                    {
                        goto label_10;
                    }
                }
            }
Esempio n. 11
0
        public override float Distance(Vec3 pp)
        {
            var p = pp + _offset;
            //From http://mercury.sexy/hg_sdf/
            var q         = new Vec2(new Vec2(p.X, p.Z).Magnitude(), p.Y);
            var tip       = q - new Vec2(0, _height);
            var mantleDir = new Vec2(_height, _radius).Normalize();

            var mantle    = Vec2.DotProduct(tip, mantleDir);
            var d         = Math.Max(mantle, -q.Y);
            var projected = Vec2.DotProduct(tip, new Vec2(mantleDir.Y, mantleDir.X));

            if (q.Y > _height && projected < 0)
            {
                d = (float)Math.Max(d, tip.Magnitude());
            }

            if (q.X > _radius && projected > new Vec2(_height, _radius).Magnitude())
            {
                d = (float)Math.Max(d, (q - new Vec2(_radius, 0)).Magnitude());
            }

            return(d);
        }
Esempio n. 12
0
            public Vec2 GetTargetPos(Vec2 position, float distance)
            {
                Vec2 v1     = this._direction.LeftVec();
                Vec2 vec2_1 = this._center + v1 * this._halfLength;
                Vec2 vec2_2 = this._center - v1 * this._halfLength;
                Vec2 vec2_3 = position - this._center;
                bool flag1  = (double)vec2_3.Normalized().DotProduct(this._direction) > 0.0;
                Vec2 vec2_4 = vec2_3.DotProduct(v1) * v1;
                bool flag2  = (double)vec2_4.Length < (double)this._halfLength;
                bool flag3  = true;
                Vec2 vec2_5;

                if (flag2)
                {
                    position = this._center + vec2_4 + this._direction * (this._radius * (flag1 ? 1f : -1f));
                }
                else
                {
                    flag3  = (double)vec2_4.DotProduct(v1) > 0.0;
                    vec2_5 = position - (flag3 ? vec2_1 : vec2_2);
                    Vec2 vec2_6 = vec2_5.Normalized();
                    position = (flag3 ? vec2_1 : vec2_2) + vec2_6 * this._radius;
                }
                Vec2   vec2_7 = this._center + vec2_4;
                double num1   = 2.0 * Math.PI * (double)this._radius;

                while ((double)distance > 0.0)
                {
                    if (flag2 & flag1)
                    {
                        vec2_5 = vec2_1 - vec2_7;
                        double num2;
                        if ((double)vec2_5.Length >= (double)distance)
                        {
                            num2 = (double)distance;
                        }
                        else
                        {
                            vec2_5 = vec2_1 - vec2_7;
                            num2   = (double)vec2_5.Length;
                        }
                        float num3   = (float)num2;
                        Vec2  vec2_6 = vec2_7;
                        vec2_5 = vec2_1 - vec2_7;
                        Vec2 vec2_8 = vec2_5.Normalized() * num3;
                        position  = vec2_6 + vec2_8;
                        position += this._direction * this._radius;
                        distance -= num3;
                        flag2     = false;
                        flag3     = true;
                    }
                    else if (!flag2 & flag3)
                    {
                        vec2_5 = position - vec2_1;
                        Vec2 v2 = vec2_5.Normalized();
                        vec2_5 = this._direction;
                        double num2      = Math.Acos((double)MBMath.ClampFloat(vec2_5.DotProduct(v2), -1f, 1f));
                        double num3      = 2.0 * Math.PI * ((double)distance / num1);
                        double num4      = num2 + num3 < Math.PI ? num2 + num3 : Math.PI;
                        double num5      = (num4 - num2) / Math.PI * (num1 / 2.0);
                        Vec2   direction = this._direction;
                        direction.RotateCCW((float)num4);
                        position  = vec2_1 + direction * this._radius;
                        distance -= (float)num5;
                        flag2     = true;
                        flag1     = false;
                    }
                    else if (flag2)
                    {
                        vec2_5 = vec2_2 - vec2_7;
                        double num2;
                        if ((double)vec2_5.Length >= (double)distance)
                        {
                            num2 = (double)distance;
                        }
                        else
                        {
                            vec2_5 = vec2_2 - vec2_7;
                            num2   = (double)vec2_5.Length;
                        }
                        float num3   = (float)num2;
                        Vec2  vec2_6 = vec2_7;
                        vec2_5 = vec2_2 - vec2_7;
                        Vec2 vec2_8 = vec2_5.Normalized() * num3;
                        position  = vec2_6 + vec2_8;
                        position -= this._direction * this._radius;
                        distance -= num3;
                        flag2     = false;
                        flag3     = false;
                    }
                    else
                    {
                        vec2_5 = position - vec2_2;
                        Vec2 v2 = vec2_5.Normalized();
                        vec2_5 = this._direction;
                        double num2   = Math.Acos((double)MBMath.ClampFloat(vec2_5.DotProduct(v2), -1f, 1f));
                        double num3   = 2.0 * Math.PI * ((double)distance / num1);
                        double num4   = num2 - num3 > 0.0 ? num2 - num3 : 0.0;
                        double num5   = num2 - num4;
                        double num6   = num5 / Math.PI * (num1 / 2.0);
                        Vec2   vec2_6 = v2;
                        vec2_6.RotateCCW((float)num5);
                        position  = vec2_2 + vec2_6 * this._radius;
                        distance -= (float)num6;
                        flag2     = true;
                        flag1     = true;
                    }
                }
                return(position);
            }
Esempio n. 13
0
        private int LocateAttackers(SiegeQuerySystem.RegionEnum region)
        {
            int num1 = 0;
            int num2 = 0;
            int num3 = 0;
            int num4 = 0;
            int num5 = 0;
            int num6 = 0;
            int num7 = 0;

            foreach (Agent activeAgent in this._attackerTeam.ActiveAgents)
            {
                Vec3 position = activeAgent.Position;
                Vec2 vec2     = position.AsVec2 - this._leftDefenderOrigin;
                if ((double)vec2.Normalize() < 10.0)
                {
                    ++num2;
                    ++num1;
                }
                else
                {
                    if ((double)vec2.DotProduct(this._leftToMidDir) >= 0.0 && (double)vec2.DotProduct(this._leftToMidDir.RightVec()) >= 0.0)
                    {
                        ++num1;
                    }
                    else
                    {
                        position = activeAgent.Position;
                        vec2     = position.AsVec2 - this._middleDefenderOrigin;
                        if ((double)vec2.DotProduct(this._midToLeftDir) >= 0.0 && (double)vec2.DotProduct(this._midToLeftDir.RightVec()) >= 0.0)
                        {
                            ++num1;
                        }
                    }
                    position = activeAgent.Position;
                    vec2     = position.AsVec2 - this._middleDefenderOrigin;
                    if ((double)vec2.Normalize() < 10.0)
                    {
                        ++num4;
                        ++num3;
                    }
                    else
                    {
                        if ((double)vec2.DotProduct(this._leftToMidDir) >= 0.0 && (double)vec2.DotProduct(this._leftToMidDir.LeftVec()) >= 0.0)
                        {
                            ++num3;
                        }
                        else
                        {
                            position = activeAgent.Position;
                            vec2     = position.AsVec2 - this._rightDefenderOrigin;
                            if ((double)vec2.DotProduct(this._rightToMidDir) >= 0.0 && (double)vec2.DotProduct(this._rightToMidDir.RightVec()) >= 0.0)
                            {
                                ++num3;
                            }
                        }
                        position = activeAgent.Position;
                        vec2     = position.AsVec2 - this._rightDefenderOrigin;
                        if ((double)vec2.Normalize() < 10.0)
                        {
                            ++num6;
                            ++num5;
                        }
                        else
                        {
                            if ((double)vec2.DotProduct(this._midToRightDir) >= 0.0 && (double)vec2.DotProduct(this._midToRightDir.LeftVec()) >= 0.0)
                            {
                                ++num5;
                            }
                            else
                            {
                                position = activeAgent.Position;
                                vec2     = position.AsVec2 - this._rightDefenderOrigin;
                                if ((double)vec2.DotProduct(this._rightToMidDir) >= 0.0 && (double)vec2.DotProduct(this._rightToMidDir.LeftVec()) >= 0.0)
                                {
                                    ++num5;
                                }
                            }
                            if (activeAgent.GetCurrentNavigationFaceId() % 10 == 1)
                            {
                                ++num7;
                            }
                        }
                    }
                }
            }
            float time = MBCommon.GetTime(MBCommon.TimeType.Mission);

            this._leftRegionMemberCount.SetValue(num1, time);
            this._leftCloseAttackerCount.SetValue(num2, time);
            this._middleRegionMemberCount.SetValue(num3, time);
            this._middleCloseAttackerCount.SetValue(num4, time);
            this._rightRegionMemberCount.SetValue(num5, time);
            this._rightCloseAttackerCount.SetValue(num6, time);
            this._insideAttackerCount.SetValue(num7, time);
            switch (region)
            {
            case SiegeQuerySystem.RegionEnum.Left:
                return(num1);

            case SiegeQuerySystem.RegionEnum.LeftClose:
                return(num2);

            case SiegeQuerySystem.RegionEnum.Middle:
                return(num3);

            case SiegeQuerySystem.RegionEnum.MiddleClose:
                return(num4);

            case SiegeQuerySystem.RegionEnum.Right:
                return(num5);

            case SiegeQuerySystem.RegionEnum.RightClose:
                return(num6);

            case SiegeQuerySystem.RegionEnum.Inside:
                return(num7);

            default:
                return(0);
            }
        }
        public RTSCameraAgentComponent(Agent agent) : base(agent)
        {
            for (int i = 0; i < _colors.Length; ++i)
            {
                _colors[i] = new Contour(null, false);
            }

            CurrentTargetPosition = new QueryData <WorldPosition>(() =>
            {
                try
                {
                    var unit      = Agent;
                    var formation = unit.Formation;
                    if (formation == null)
                    {
                        return(WorldPosition.Invalid);
                    }
                    var targetFormation = QueryDataStore.Get(formation.TargetFormation);

                    if (QueryLibrary.IsRangedCavalry(unit))
                    {
                        var targetAgent = unit.GetTargetAgent();
                        if (targetAgent == null || targetAgent.Formation != formation.TargetFormation)
                        {
                            Vec2 unitPosition = unit.Position.AsVec2;
                            targetAgent       = targetFormation.NearestAgent(unitPosition);
                        }

                        return(targetAgent?.GetWorldPosition() ?? new WorldPosition());
                    }

                    if (QueryLibrary.IsCavalry(unit))
                    {
                        var targetAgent = unit.GetTargetAgent();
                        if (targetAgent == null || targetAgent.Formation != formation.TargetFormation)
                        {
                            Vec2 unitPosition = formation.GetCurrentGlobalPositionOfUnit(unit, true) * 0.2f +
                                                unit.Position.AsVec2 * 0.8f;
                            targetAgent = targetFormation.NearestOfAverageOfNearestPosition(unitPosition, 7);
                        }

                        if (targetAgent != null)
                        {
                            if (targetAgent.HasMount)
                            {
                                return(targetAgent.GetWorldPosition());
                            }

                            var targetPosition  = targetAgent.GetWorldPosition();
                            var targetDirection = targetPosition.AsVec2 - unit.Position.AsVec2;
                            var distance        = targetDirection.Normalize();
                            var result          = targetPosition;

                            // new
                            if (distance > 20)
                            {
                                CurrentDirection = targetDirection;
                                result.SetVec2(targetDirection * 10 + targetPosition.AsVec2);
                            }
                            else if (distance > 5 && targetDirection.DotProduct(CurrentDirection) < 0)
                            {
                                result.SetVec2(
                                    (CurrentDirection.DotProduct(targetDirection * distance) + 50) * CurrentDirection +
                                    unit.Position.AsVec2);
                            }
                            else
                            {
                                result.SetVec2(CurrentDirection * 10 + targetPosition.AsVec2);
                            }


                            // old
                            //if (distance < 3)
                            //{
                            //    result = unit.GetWorldPosition();
                            //    result.SetVec2(CurrentDirection * 20 + result.AsVec2);
                            //}
                            //else
                            //{
                            //    if (distance < 20 && targetDirection.DotProduct(CurrentDirection) < 0)
                            //    {
                            //        result.SetVec2(-targetDirection * 50 + result.AsVec2);
                            //    }
                            //    else
                            //    {
                            //        CurrentDirection = targetDirection;
                            //        result.SetVec2(targetDirection * 10 + result.AsVec2);
                            //    }

                            //}


                            return(result.GetNavMesh() == UIntPtr.Zero ||
                                   !Mission.Current.IsPositionInsideBoundaries(result.AsVec2)
                                ? targetPosition
                                : result);
                        }

                        return(WorldPosition.Invalid);
                    }
                    else
                    {
                        var targetAgent = unit.GetTargetAgent();
                        if (targetAgent == null || targetAgent.Formation != formation.TargetFormation)
                        {
                            Vec2 unitPosition = formation.GetCurrentGlobalPositionOfUnit(unit, true) * 0.2f +
                                                unit.Position.AsVec2 * 0.8f;
                            targetAgent = targetFormation.NearestAgent(unitPosition);
                        }

                        return(targetAgent?.GetWorldPosition() ?? new WorldPosition());
                    }
                }
                catch (Exception e)
                {
                    Utility.DisplayMessage(e.ToString());
                }

                return(WorldPosition.Invalid);
            }, 0.2f);
        }
        private BehaviorTacticalCharge.ChargeState CheckAndChangeState()
        {
            BehaviorTacticalCharge.ChargeState chargeState = this._chargeState;
            if (this.formation.QuerySystem.ClosestEnemyFormation == null)
            {
                chargeState = BehaviorTacticalCharge.ChargeState.Undetermined;
            }
            else
            {
                switch (this._chargeState)
                {
                case BehaviorTacticalCharge.ChargeState.Undetermined:
                    if (this.formation.QuerySystem.ClosestEnemyFormation != null && (!this.formation.QuerySystem.IsCavalryFormation && !this.formation.QuerySystem.IsRangedCavalryFormation || (double)this.formation.QuerySystem.AveragePosition.Distance(this.formation.QuerySystem.ClosestEnemyFormation.MedianPosition.AsVec2) / (double)this.formation.QuerySystem.MovementSpeedMaximum <= 5.0))
                    {
                        chargeState = BehaviorTacticalCharge.ChargeState.Charging;
                        break;
                    }
                    break;

                case BehaviorTacticalCharge.ChargeState.Charging:
                    if (!this.formation.QuerySystem.IsCavalryFormation && !this.formation.QuerySystem.IsRangedCavalryFormation)
                    {
                        if (!this.formation.QuerySystem.IsInfantryFormation || !this.formation.QuerySystem.ClosestEnemyFormation.IsCavalryFormation)
                        {
                            chargeState = BehaviorTacticalCharge.ChargeState.Charging;
                            break;
                        }
                        Vec2   vec2            = this.formation.QuerySystem.AveragePosition - this.formation.QuerySystem.ClosestEnemyFormation.AveragePosition;
                        double num1            = (double)vec2.Normalize();
                        Vec2   currentVelocity = this.formation.QuerySystem.ClosestEnemyFormation.CurrentVelocity;
                        double num2            = (double)currentVelocity.Normalize();
                        if (num1 / num2 <= 6.0 && (double)vec2.DotProduct(currentVelocity) > 0.5)
                        {
                            this._chargeState = BehaviorTacticalCharge.ChargeState.Bracing;
                            break;
                        }
                        break;
                    }
                    if ((double)this._initialChargeDirection.DotProduct(this.formation.QuerySystem.ClosestEnemyFormation.MedianPosition.AsVec2 - this.formation.QuerySystem.AveragePosition) <= 0.0)
                    {
                        chargeState = BehaviorTacticalCharge.ChargeState.ChargingPast;
                        break;
                    }
                    break;

                case BehaviorTacticalCharge.ChargeState.ChargingPast:
                    if (this._chargingPastTimer.Check(MBCommon.GetTime(MBCommon.TimeType.Mission)) || (double)this.formation.QuerySystem.AveragePosition.Distance(this.formation.QuerySystem.ClosestEnemyFormation.MedianPosition.AsVec2) >= (double)this._desiredChargeStopDistance)
                    {
                        chargeState = BehaviorTacticalCharge.ChargeState.Reforming;
                        break;
                    }
                    break;

                case BehaviorTacticalCharge.ChargeState.Reforming:
                    if (this._reformTimer.Check(MBCommon.GetTime(MBCommon.TimeType.Mission)) || (double)this.formation.QuerySystem.AveragePosition.Distance(this.formation.QuerySystem.ClosestEnemyFormation.MedianPosition.AsVec2) <= 30.0)
                    {
                        chargeState = BehaviorTacticalCharge.ChargeState.Charging;
                        break;
                    }
                    break;

                case BehaviorTacticalCharge.ChargeState.Bracing:
                    bool flag = false;
                    if (this.formation.QuerySystem.IsInfantryFormation && this.formation.QuerySystem.ClosestEnemyFormation.IsCavalryFormation)
                    {
                        Vec2   vec2            = this.formation.QuerySystem.AveragePosition - this.formation.QuerySystem.ClosestEnemyFormation.AveragePosition;
                        double num1            = (double)vec2.Normalize();
                        Vec2   currentVelocity = this.formation.QuerySystem.ClosestEnemyFormation.CurrentVelocity;
                        double num2            = (double)currentVelocity.Normalize();
                        if (num1 / num2 <= 8.0 && (double)vec2.DotProduct(currentVelocity) > 0.330000013113022)
                        {
                            flag = true;
                        }
                    }
                    if (!flag)
                    {
                        this._bracePosition = Vec2.Invalid;
                        this._chargeState   = BehaviorTacticalCharge.ChargeState.Charging;
                        break;
                    }
                    break;
                }
            }
            return(chargeState);
        }
        static void PostfixCalculateCurrentOrder(ref Formation ___formation, BehaviorMountedSkirmish __instance, ref bool ____engaging, ref MovementOrder ____currentOrder)
        {
            WorldPosition position = ___formation.QuerySystem.MedianPosition;

            if (___formation.QuerySystem.ClosestSignificantlyLargeEnemyFormation == null)
            {
                position.SetVec2(___formation.QuerySystem.AveragePosition);
            }
            else
            {
                bool num      = (___formation.QuerySystem.AverageAllyPosition - ___formation.Team.QuerySystem.AverageEnemyPosition).LengthSquared <= 3600f;
                bool engaging = ____engaging;
                engaging = (____engaging = (num || ((!____engaging) ? ((___formation.QuerySystem.AveragePosition - ___formation.QuerySystem.AverageAllyPosition).LengthSquared <= 3600f) : (!(___formation.QuerySystem.UnderRangedAttackRatio > ___formation.QuerySystem.MakingRangedAttackRatio) && ((!___formation.QuerySystem.FastestSignificantlyLargeEnemyFormation.IsCavalryFormation && !___formation.QuerySystem.FastestSignificantlyLargeEnemyFormation.IsRangedCavalryFormation) || (___formation.QuerySystem.AveragePosition - ___formation.QuerySystem.FastestSignificantlyLargeEnemyFormation.MedianPosition.AsVec2).LengthSquared / (___formation.QuerySystem.FastestSignificantlyLargeEnemyFormation.MovementSpeed * ___formation.QuerySystem.FastestSignificantlyLargeEnemyFormation.MovementSpeed) >= 16f)))));
                if (!____engaging)
                {
                    position = new WorldPosition(Mission.Current.Scene, new Vec3(___formation.QuerySystem.AverageAllyPosition, ___formation.Team.QuerySystem.MedianPosition.GetNavMeshZ() + 100f));
                }
                else
                {
                    Vec2 vec = (___formation.QuerySystem.AveragePosition - ___formation.QuerySystem.ClosestSignificantlyLargeEnemyFormation.AveragePosition).Normalized().LeftVec();
                    FormationQuerySystem closestSignificantlyLargeEnemyFormation = ___formation.QuerySystem.ClosestSignificantlyLargeEnemyFormation;
                    float     num2      = 50f + (___formation.QuerySystem.ClosestSignificantlyLargeEnemyFormation.Formation.Width + ___formation.Depth) * 0.5f;
                    float     num3      = 0f;
                    Formation formation = ___formation.QuerySystem.ClosestSignificantlyLargeEnemyFormation.Formation;
                    for (int i = 0; i < Mission.Current.Teams.Count; i++)
                    {
                        Team team = Mission.Current.Teams[i];
                        if (!team.IsEnemyOf(___formation.Team))
                        {
                            continue;
                        }
                        for (int j = 0; j < team.FormationsIncludingSpecialAndEmpty.Count; j++)
                        {
                            Formation formation2 = team.FormationsIncludingSpecialAndEmpty[j];
                            if (formation2.CountOfUnits > 0 && formation2.QuerySystem != closestSignificantlyLargeEnemyFormation)
                            {
                                Vec2  v    = formation2.QuerySystem.AveragePosition - closestSignificantlyLargeEnemyFormation.AveragePosition;
                                float num4 = v.Normalize();
                                if (vec.DotProduct(v) > 0.8f && num4 < num2 && num4 > num3)
                                {
                                    num3      = num4;
                                    formation = formation2;
                                }
                            }
                        }
                    }
                    if (___formation.QuerySystem.RangedCavalryUnitRatio > 0.95f && ___formation.QuerySystem.ClosestSignificantlyLargeEnemyFormation.Formation == formation)
                    {
                        ____currentOrder = MovementOrder.MovementOrderCharge;
                        return;
                    }
                    bool  flag = formation.QuerySystem.IsCavalryFormation || formation.QuerySystem.IsRangedCavalryFormation;
                    float num5 = flag ? 35f : 20f;
                    num5 += (formation.Depth + ___formation.Width) * 0.25f;
                    //num5 = Math.Min(num5, ___formation.QuerySystem.MissileRange - ___formation.Width * 0.5f);
                    Ellipse ellipse = new Ellipse(formation.QuerySystem.MedianPosition.AsVec2, num5, formation.Width * 0.25f * (flag ? 1.5f : 1f), formation.Direction);
                    position.SetVec2(ellipse.GetTargetPos(___formation.QuerySystem.AveragePosition, 20f));
                }
            }
            ____currentOrder = MovementOrder.MovementOrderMove(position);
        }
            public Vec2 GetTargetPos(Vec2 position, float distance)
            {
                Vec2 v     = _direction.LeftVec();
                Vec2 vec   = _center + v * _halfLength;
                Vec2 vec2  = _center - v * _halfLength;
                Vec2 vec3  = position - _center;
                bool flag  = vec3.Normalized().DotProduct(_direction) > 0f;
                Vec2 v2    = vec3.DotProduct(v) * v;
                bool flag2 = v2.Length < _halfLength;
                bool flag3 = true;

                if (flag2)
                {
                    position = _center + v2 + _direction * (_radius * (float)(flag ? 1 : (-1)));
                }
                else
                {
                    flag3 = (v2.DotProduct(v) > 0f);
                    Vec2 v3 = (position - (flag3 ? vec : vec2)).Normalized();
                    position = (flag3 ? vec : vec2) + v3 * _radius;
                }
                Vec2   vec4 = _center + v2;
                double num  = Math.PI * 2.0 * (double)_radius;

                while (distance > 0f)
                {
                    if (flag2 && flag)
                    {
                        float num2 = ((vec - vec4).Length < distance) ? (vec - vec4).Length : distance;
                        position  = vec4 + (vec - vec4).Normalized() * num2;
                        position += _direction * _radius;
                        distance -= num2;
                        flag2     = false;
                        flag3     = true;
                    }
                    else if (!flag2 && flag3)
                    {
                        Vec2   v4        = (position - vec).Normalized();
                        double num3      = Math.Acos(MBMath.ClampFloat(_direction.DotProduct(v4), -1f, 1f));
                        double num4      = Math.PI * 2.0 * ((double)distance / num);
                        double num5      = (num3 + num4 < Math.PI) ? (num3 + num4) : Math.PI;
                        double num6      = (num5 - num3) / Math.PI * (num / 2.0);
                        Vec2   direction = _direction;
                        direction.RotateCCW((float)num5);
                        position  = vec + direction * _radius;
                        distance -= (float)num6;
                        flag2     = true;
                        flag      = false;
                    }
                    else if (flag2)
                    {
                        float num7 = ((vec2 - vec4).Length < distance) ? (vec2 - vec4).Length : distance;
                        position  = vec4 + (vec2 - vec4).Normalized() * num7;
                        position -= _direction * _radius;
                        distance -= num7;
                        flag2     = false;
                        flag3     = false;
                    }
                    else
                    {
                        Vec2   vec5  = (position - vec2).Normalized();
                        double num8  = Math.Acos(MBMath.ClampFloat(_direction.DotProduct(vec5), -1f, 1f));
                        double num9  = Math.PI * 2.0 * ((double)distance / num);
                        double num10 = (num8 - num9 > 0.0) ? (num8 - num9) : 0.0;
                        double num11 = num8 - num10;
                        double num12 = num11 / Math.PI * (num / 2.0);
                        Vec2   v5    = vec5;
                        v5.RotateCCW((float)num11);
                        position  = vec2 + v5 * _radius;
                        distance -= (float)num12;
                        flag2     = true;
                        flag      = true;
                    }
                }
                return(position);
            }
Esempio n. 18
0
        protected override void CalculateCurrentOrder()
        {
            WorldPosition position = this.formation.QuerySystem.MedianPosition;

            if (this.formation.QuerySystem.ClosestSignificantlyLargeEnemyFormation == null)
            {
                position.SetVec2(this.formation.QuerySystem.AveragePosition);
            }
            else
            {
                int  num1     = (double)(this.formation.QuerySystem.AverageAllyPosition - this.formation.Team.QuerySystem.AverageEnemyPosition).LengthSquared <= 3600.0 ? 1 : 0;
                bool engaging = this._engaging;
                this._engaging = num1 != 0 || (this._engaging ? (double)this.formation.QuerySystem.UnderRangedAttackRatio <= (double)this.formation.QuerySystem.MakingRangedAttackRatio && (!this.formation.QuerySystem.FastestSignificantlyLargeEnemyFormation.IsCavalryFormation && !this.formation.QuerySystem.FastestSignificantlyLargeEnemyFormation.IsRangedCavalryFormation || (double)(this.formation.QuerySystem.AveragePosition - this.formation.QuerySystem.FastestSignificantlyLargeEnemyFormation.MedianPosition.AsVec2).LengthSquared / ((double)this.formation.QuerySystem.FastestSignificantlyLargeEnemyFormation.MovementSpeed * (double)this.formation.QuerySystem.FastestSignificantlyLargeEnemyFormation.MovementSpeed) >= 16.0) : (double)(this.formation.QuerySystem.AveragePosition - this.formation.QuerySystem.AverageAllyPosition).LengthSquared <= 3600.0);
                if (this._engaging)
                {
                    Vec2 vec2_1 = this.formation.QuerySystem.AveragePosition - this.formation.QuerySystem.ClosestSignificantlyLargeEnemyFormation.AveragePosition;
                    vec2_1 = vec2_1.Normalized();
                    Vec2 vec2_2 = vec2_1.LeftVec();
                    FormationQuerySystem largeEnemyFormation = this.formation.QuerySystem.ClosestSignificantlyLargeEnemyFormation;
                    float     num2       = (float)(50.0 + ((double)this.formation.QuerySystem.ClosestSignificantlyLargeEnemyFormation.Formation.Width + (double)this.formation.Depth) * 0.5);
                    float     num3       = 0.0f;
                    Formation formation1 = this.formation.QuerySystem.ClosestSignificantlyLargeEnemyFormation.Formation;
                    for (int index1 = 0; index1 < Mission.Current.Teams.Count; ++index1)
                    {
                        Team team = Mission.Current.Teams[index1];
                        if (team.IsEnemyOf(this.formation.Team))
                        {
                            for (int index2 = 0; index2 < team.FormationsIncludingSpecialAndEmpty.Count; ++index2)
                            {
                                Formation formation2 = team.FormationsIncludingSpecialAndEmpty[index2];
                                if (formation2.CountOfUnits > 0 && formation2.QuerySystem != largeEnemyFormation)
                                {
                                    Vec2  v    = formation2.QuerySystem.AveragePosition - largeEnemyFormation.AveragePosition;
                                    float num4 = v.Normalize();
                                    if ((double)vec2_2.DotProduct(v) > 0.800000011920929 && (double)num4 < (double)num2 && (double)num4 > (double)num3)
                                    {
                                        num3       = num4;
                                        formation1 = formation2;
                                    }
                                }
                            }
                        }
                    }
                    if (((double)this.formation.QuerySystem.RangedCavalryUnitRatio <= 0.949999988079071 ? 0 : (this.formation.QuerySystem.ClosestSignificantlyLargeEnemyFormation.Formation == formation1 ? 1 : 0)) == 0)
                    {
                        bool  flag   = formation1.QuerySystem.IsCavalryFormation || formation1.QuerySystem.IsRangedCavalryFormation;
                        float radius = Math.Min((flag ? 35f : 20f) + (float)(((double)formation1.Depth + (double)this.formation.Width) * 0.5), this.formation.QuerySystem.MissileRange - this.formation.Width * 0.5f);
                        BehaviorMountedSkirmish.Ellipse ellipse = new BehaviorMountedSkirmish.Ellipse(formation1.QuerySystem.MedianPosition.AsVec2, radius, (float)((double)formation1.Width * 0.5 * (flag ? 1.5 : 1.0)), formation1.Direction);
                        position.SetVec2(ellipse.GetTargetPos(this.formation.QuerySystem.AveragePosition, 20f));
                    }
                    else
                    {
                        this.CurrentOrder = MovementOrder.MovementOrderCharge;
                        return;
                    }
                }
                else
                {
                    position = new WorldPosition(Mission.Current.Scene, new Vec3(this.formation.QuerySystem.AverageAllyPosition, this.formation.Team.QuerySystem.MedianPosition.GetNavMeshZ() + 100f));
                }
            }
            this.CurrentOrder = MovementOrder.MovementOrderMove(position);
        }