예제 #1
0
        public static void Postfix(CastleGate __instance)
        {
            TeamAISiegeComponent aic = Mission.Current.AttackerTeam.TeamAI as TeamAISiegeComponent;

            if (__instance.GameEntity.HasTag("inner_gate"))
            {
                Main.Log("Inner gate destroyed!", true);
                foreach (Formation f in Mission.Current.PlayerTeam.FormationsIncludingSpecial)
                {
                    if (Main.IsPIC(f) && !f.IsAIControlled)
                    {
                        Traverse.Create(f).Method("DisbandAttackEntityDetachment").GetValue();
                    }
                }
            }
            if (__instance.GameEntity.HasTag("outer_gate"))
            {
                Main.Log("Outer gate destroyed!", true);
                foreach (MissionObject mo in Mission.Current.ActiveMissionObjects)
                {
                    foreach (Formation f in Mission.Current.PlayerTeam.Formations)
                    {
                        if (f.IsUsingMachine(mo as BatteringRam) && !aic.InnerGate.IsDestroyed && Main.IsPIC(f) && !f.IsAIControlled)
                        {
                            if (Mission.Current.PlayerTeam.IsAttacker)
                            {
                                Main.Log("Sending detachment to attack inner gate!", true);
                            }
                            Traverse.Create(f).Method("FormAttackEntityDetachment", aic.InnerGate.GameEntity).GetValue();
                        }
                    }
                }
            }
            if (Mission.Current.PlayerTeam.IsAttacker && aic.InnerGate.IsDestroyed && aic.OuterGate.IsDestroyed)
            {
                Main.Log("Charge when ready!", true);
            }
        }
예제 #2
0
        protected override void CalculateCurrentOrder()
        {
            if (base.Formation.QuerySystem.IsInfantryFormation)
            {
                mobilityModifier = 1.25f;
            }
            else
            {
                mobilityModifier = 1f;
            }
            WorldPosition position = base.Formation.QuerySystem.MedianPosition;

            _isEnemyReachable = base.Formation.QuerySystem.ClosestSignificantlyLargeEnemyFormation != null && (!(base.Formation.Team.TeamAI is TeamAISiegeComponent) || !TeamAISiegeComponent.IsFormationInsideCastle(base.Formation.QuerySystem.ClosestSignificantlyLargeEnemyFormation.Formation, includeOnlyPositionedUnits: false));
            Vec2 averagePosition = base.Formation.QuerySystem.AveragePosition;

            if (!_isEnemyReachable)
            {
                position.SetVec2(averagePosition);
            }
            else
            {
                float skirmishRange = 45f / mobilityModifier;
                float flankRange    = 25f;

                Formation enemyFormation = base.Formation.QuerySystem.ClosestSignificantlyLargeEnemyFormation.Formation;
                Formation allyFormation  = Utilities.FindSignificantAlly(base.Formation, true, true, false, false, false);

                if (base.Formation != null && base.Formation.QuerySystem.IsInfantryFormation)
                {
                    enemyFormation = Utilities.FindSignificantEnemyToPosition(base.Formation, position, true, true, false, false, false, false);
                }

                Vec2          averageAllyFormationPosition  = base.Formation.QuerySystem.Team.AveragePosition;
                WorldPosition medianTargetFormationPosition = base.Formation.QuerySystem.Team.MedianTargetFormationPosition;
                Vec2          enemyDirection = (medianTargetFormationPosition.AsVec2 - averageAllyFormationPosition).Normalized();

                switch (_skirmishMode)
                {
                case SkirmishMode.Reform:
                {
                    _returnTimer = null;
                    if (averagePosition.Distance(enemyFormation.QuerySystem.AveragePosition) > skirmishRange)
                    {
                        if (_reformTimer == null)
                        {
                            _reformTimer = new Timer(Mission.Current.CurrentTime, 4f / mobilityModifier);
                        }
                    }
                    if (_reformTimer != null && _reformTimer.Check(Mission.Current.CurrentTime))
                    {
                        _skirmishMode = SkirmishMode.Attack;
                    }

                    if (behaviorSide == FormationAI.BehaviorSide.Right || FlankSide == FormationAI.BehaviorSide.Right)
                    {
                        Vec2 calcPosition = allyFormation.CurrentPosition + enemyDirection.RightVec().Normalized() * (allyFormation.Width + base.Formation.Width + flankRange);
                        position.SetVec2(calcPosition);
                    }
                    else if (behaviorSide == FormationAI.BehaviorSide.Left || FlankSide == FormationAI.BehaviorSide.Left)
                    {
                        Vec2 calcPosition = allyFormation.CurrentPosition + enemyDirection.LeftVec().Normalized() * (allyFormation.Width + base.Formation.Width + flankRange);
                        position.SetVec2(calcPosition);
                    }
                    else
                    {
                        if (allyFormation != null)
                        {
                            position = allyFormation.QuerySystem.MedianPosition;
                        }
                        else
                        {
                            position.SetVec2(medianTargetFormationPosition.AsVec2 + enemyDirection.Normalized() * 150f);
                        }
                    }
                    break;
                }

                case SkirmishMode.Returning:
                {
                    _attackTimer = null;
                    if (_returnTimer == null)
                    {
                        _returnTimer = new Timer(Mission.Current.CurrentTime, 10f / mobilityModifier);
                    }
                    if (_returnTimer != null && _returnTimer.Check(Mission.Current.CurrentTime))
                    {
                        _skirmishMode = SkirmishMode.Reform;
                    }

                    if (behaviorSide == FormationAI.BehaviorSide.Right || FlankSide == FormationAI.BehaviorSide.Right)
                    {
                        Vec2 calcPosition = allyFormation.CurrentPosition + enemyDirection.RightVec().Normalized() * (allyFormation.Width + base.Formation.Width + flankRange);
                        position.SetVec2(calcPosition);
                    }
                    else if (behaviorSide == FormationAI.BehaviorSide.Left || FlankSide == FormationAI.BehaviorSide.Left)
                    {
                        Vec2 calcPosition = allyFormation.CurrentPosition + enemyDirection.LeftVec().Normalized() * (allyFormation.Width + base.Formation.Width + flankRange);
                        position.SetVec2(calcPosition);
                    }
                    else
                    {
                        if (allyFormation != null)
                        {
                            position = allyFormation.QuerySystem.MedianPosition;
                        }
                        else
                        {
                            position.SetVec2(medianTargetFormationPosition.AsVec2 + enemyDirection.Normalized() * 150f);
                        }
                    }

                    break;
                }

                case SkirmishMode.Attack:
                {
                    _reformTimer = null;
                    if ((averagePosition.Distance(enemyFormation.QuerySystem.AveragePosition) < skirmishRange) || (base.Formation.QuerySystem.MakingRangedAttackRatio > 0.1f))
                    {
                        if (_attackTimer == null)
                        {
                            _attackTimer = new Timer(Mission.Current.CurrentTime, 3f * mobilityModifier);
                        }
                    }
                    if (_attackTimer != null && _attackTimer.Check(Mission.Current.CurrentTime))
                    {
                        _skirmishMode = SkirmishMode.Returning;
                    }

                    if (behaviorSide == FormationAI.BehaviorSide.Right || FlankSide == FormationAI.BehaviorSide.Right)
                    {
                        position = medianTargetFormationPosition;
                        Vec2 calcPosition = position.AsVec2 - enemyDirection * (skirmishRange - (10f + base.Formation.Depth * 0.5f));
                        calcPosition = calcPosition + enemyFormation.Direction.LeftVec().Normalized() * (enemyFormation.Width / 2f) * mobilityModifier;
                        position.SetVec2(calcPosition);
                    }
                    else if (behaviorSide == FormationAI.BehaviorSide.Left || FlankSide == FormationAI.BehaviorSide.Left)
                    {
                        position = medianTargetFormationPosition;
                        Vec2 calcPosition = position.AsVec2 - enemyDirection * (skirmishRange - (10f + base.Formation.Depth * 0.5f));
                        calcPosition = calcPosition + enemyFormation.Direction.RightVec().Normalized() * (enemyFormation.Width / 2f) * mobilityModifier;
                        position.SetVec2(calcPosition);
                    }
                    else
                    {
                        position = medianTargetFormationPosition;
                        Vec2 calcPosition = position.AsVec2 - enemyDirection * (skirmishRange - (10f + base.Formation.Depth * 0.5f));
                        position.SetVec2(calcPosition);
                    }

                    //position = enemyFormation.QuerySystem.MedianPosition;
                    break;
                }
                }
            }
            base.CurrentOrder = MovementOrder.MovementOrderMove(position);
        }