private FormationAI.BehaviorSide DetermineGatheringSide() { this.DetermineMostImportantInvadingEnemyFormation(); if (this._targetEnemyFormation == null) { if (this._behaviourState == BehaviorEliminateEnemyInsideCastle.BehaviourState.Attacking) { this._behaviourState = BehaviorEliminateEnemyInsideCastle.BehaviourState.UnSet; } return(this.behaviorSide); } int connectedSides = TeamAISiegeComponent.QuerySystem.DeterminePositionAssociatedSide(this._targetEnemyFormation.QuerySystem.MedianPosition.GetNavMeshVec3()); IEnumerable <SiegeLane> source1 = TeamAISiegeComponent.SiegeLanes.Where <SiegeLane>((Func <SiegeLane, bool>)(sl => sl.LaneState != SiegeLane.LaneStateEnum.Conceited && !SiegeQuerySystem.AreSidesRelated(sl.LaneSide, connectedSides))); FormationAI.BehaviorSide behaviorSide = this.behaviorSide; if (source1.Any <SiegeLane>()) { if (source1.Count <SiegeLane>() > 1) { int leastDangerousLaneState = source1.Min <SiegeLane>((Func <SiegeLane, int>)(pgl => (int)pgl.LaneState)); IEnumerable <SiegeLane> source2 = source1.Where <SiegeLane>((Func <SiegeLane, bool>)(pgl => pgl.LaneState == (SiegeLane.LaneStateEnum)leastDangerousLaneState)); behaviorSide = source2.Count <SiegeLane>() <= 1 ? source2.First <SiegeLane>().LaneSide : source2.MinBy <SiegeLane, int>((Func <SiegeLane, int>)(ldl => SiegeQuerySystem.SideDistance(1 << connectedSides, 1 << (int)(ldl.LaneSide & (FormationAI.BehaviorSide) 31)))).LaneSide; } else { behaviorSide = source1.First <SiegeLane>().LaneSide; } } return(behaviorSide); }
private void ResetOrderPositions() { this._behaviourState = BehaviorRetakeCastleKeyPosition.BehaviourState.UnSet; this._gatheringSide = this.DetermineGatheringSide(); SiegeLane siegeLane = TeamAISiegeComponent.SiegeLanes.FirstOrDefault <SiegeLane>((Func <SiegeLane, bool>)(sl => sl.LaneSide == this._gatheringSide)); WorldFrame defenseWaitFrame = siegeLane.DefensePoints.FirstOrDefault <ICastleKeyPosition>().DefenseWaitFrame; this._gatheringTacticalPos = siegeLane.DefensePoints.FirstOrDefault <ICastleKeyPosition>().WaitPosition; if (this._gatheringTacticalPos != null) { this._gatherOrder = MovementOrder.MovementOrderMove(this._gatheringTacticalPos.Position); this._gatheringFacingOrder = FacingOrder.FacingOrderLookAtEnemy; } else if (defenseWaitFrame.Origin.IsValid) { double num = (double)defenseWaitFrame.Rotation.f.Normalize(); this._gatherOrder = MovementOrder.MovementOrderMove(defenseWaitFrame.Origin); this._gatheringFacingOrder = FacingOrder.FacingOrderLookAtEnemy; } else { this._gatherOrder = MovementOrder.MovementOrderMove(this.formation.QuerySystem.MedianPosition); this._gatheringFacingOrder = FacingOrder.FacingOrderLookAtEnemy; } this._attackOrder = MovementOrder.MovementOrderMove(TeamAISiegeComponent.SiegeLanes.FirstOrDefault <SiegeLane>((Func <SiegeLane, bool>)(sl => sl.LaneSide == this.behaviorSide)).DefensePoints.FirstOrDefault <ICastleKeyPosition>().MiddleFrame.Origin); this._attackFacingOrder = FacingOrder.FacingOrderLookAtEnemy; this.CurrentOrder = this._behaviourState == BehaviorRetakeCastleKeyPosition.BehaviourState.Attacking ? this._attackOrder : this._gatherOrder; this.CurrentFacingOrder = this._behaviourState == BehaviorRetakeCastleKeyPosition.BehaviourState.Attacking ? this._attackFacingOrder : this._gatheringFacingOrder; }
internal override void Tick(float dt) { if (!this._noProperLaneRemains) { List <SiegeLane> siegeLaneList = new List <SiegeLane>(); foreach (SiegeLane siegeLane in TeamAISiegeComponent.SiegeLanes) { siegeLane.RefreshLane(); siegeLane.DetermineLaneState(); } if (!TeamAISiegeComponent.SiegeLanes.Any <SiegeLane>()) { this._noProperLaneRemains = true; foreach (FormationAI.BehaviorSide behaviorSide in this.CastleKeyPositions.Where <MissionObject>((Func <MissionObject, bool>)(ckp => ckp is CastleGate && (ckp as CastleGate).DefenseSide != FormationAI.BehaviorSide.BehaviorSideNotSet)).Select <MissionObject, FormationAI.BehaviorSide>((Func <MissionObject, FormationAI.BehaviorSide>)(ckp => (ckp as CastleGate).DefenseSide))) { FormationAI.BehaviorSide difficultLaneSide = behaviorSide; SiegeLane siegeLane = new SiegeLane(difficultLaneSide, TeamAISiegeComponent.QuerySystem); siegeLane.SetPrimarySiegeWeapons(new List <IPrimarySiegeWeapon>()); siegeLane.SetDefensePoints(this.CastleKeyPositions.Where <MissionObject>((Func <MissionObject, bool>)(ckp => (ckp as ICastleKeyPosition).DefenseSide == difficultLaneSide && ckp is CastleGate)).Select <MissionObject, ICastleKeyPosition>((Func <MissionObject, ICastleKeyPosition>)(dp => dp as ICastleKeyPosition)).ToList <ICastleKeyPosition>()); siegeLane.RefreshLane(); siegeLane.DetermineLaneState(); TeamAISiegeComponent.SiegeLanes.Add(siegeLane); } } } else { foreach (SiegeLane siegeLane in TeamAISiegeComponent.SiegeLanes) { siegeLane.RefreshLane(); siegeLane.DetermineLaneState(); } } base.Tick(dt); }
private void SetBreachSideDeploymentPoint() { this._isBreachSideDeploymentPoint = true; this._deploymentPointType = DeploymentPoint.DeploymentPointType.Breach; FormationAI.BehaviorSide deploymentPointSide = (this._weapons.FirstOrDefault <SynchedMissionObject>((Func <SynchedMissionObject, bool>)(w => w is SiegeTower)) as IPrimarySiegeWeapon).WeaponSide; this.AssociatedWallSegment = Mission.Current.ActiveMissionObjects.FindAllWithType <WallSegment>().FirstOrDefault <WallSegment>((Func <WallSegment, bool>)(ws => ws.DefenseSide == deploymentPointSide)); this.DeploymentTargetPosition = this.AssociatedWallSegment.GameEntity.GlobalPosition; }
protected internal override void TickOccasionally() { base.TickOccasionally(); if (this.formation.AI.Side != this.behaviourSide) { this.behaviourSide = this.formation.AI.Side; this._siegeTower = Mission.Current.ActiveMissionObjects.FindAllWithType <SiegeTower>().FirstOrDefault <SiegeTower>((Func <SiegeTower, bool>)(st => st.WeaponSide == this.behaviourSide)); } if (this._siegeTower == null || this._siegeTower.IsDestroyed) { return; } this.formation.MovementOrder = this.CurrentOrder; }
internal Vec3 CalculateSallyOutReferencePosition(FormationAI.BehaviorSide side) { switch (side) { case FormationAI.BehaviorSide.Left: SiegeTower siegeTower1 = this.SiegeTowers.FirstOrDefault <SiegeTower>((Func <SiegeTower, bool>)(st => st.WeaponSide == FormationAI.BehaviorSide.Left)); return(siegeTower1 == null ? this.Ram.GameEntity.GlobalPosition : siegeTower1.GameEntity.GlobalPosition); case FormationAI.BehaviorSide.Right: SiegeTower siegeTower2 = this.SiegeTowers.FirstOrDefault <SiegeTower>((Func <SiegeTower, bool>)(st => st.WeaponSide == FormationAI.BehaviorSide.Right)); return(siegeTower2 == null ? this.Ram.GameEntity.GlobalPosition : siegeTower2.GameEntity.GlobalPosition); default: return(this.Ram.GameEntity.GlobalPosition); } }
public void OnPlayerChoiceMade( FormationClass chosenFormationClass, FormationAI.BehaviorSide formationBehaviorSide = FormationAI.BehaviorSide.Middle) { Team playerTeam = this.Mission.PlayerTeam; Formation formation = playerTeam.Formations.Where <Formation>((Func <Formation, bool>)(f => f.PrimaryClass == chosenFormationClass && f.AI.Side == formationBehaviorSide)).MaxBy <Formation, float>((Func <Formation, float>)(f => f.QuerySystem.FormationPower)); if (playerTeam.IsPlayerSergeant) { formation.PlayerOwner = Agent.Main; formation.IsAIControlled = false; formation.IsPlayerInFormation = true; } else { formation.IsPlayerInFormation = true; } Agent.Main.Formation = formation; playerTeam.TriggerOnFormationsChanged(formation); }
internal bool CalculateIsChargePastWallsApplicable(FormationAI.BehaviorSide side) { if (side == FormationAI.BehaviorSide.BehaviorSideNotSet && this.InnerGate != null && !this.InnerGate.IsGateOpen) { return(false); } foreach (SiegeLane siegeLane in TeamAISiegeComponent.SiegeLanes) { if (side == FormationAI.BehaviorSide.BehaviorSideNotSet) { if (!siegeLane.IsOpen) { return(false); } } else if (side == siegeLane.LaneSide) { return(siegeLane.IsOpen && (siegeLane.IsBreach || siegeLane.HasGate && (this.InnerGate == null || this.InnerGate.IsGateOpen))); } } return(true); }
public int DeterminePositionAssociatedSide(Vec3 position) { float num1 = position.AsVec2.DistanceSquared(this.LeftDefenderOrigin); float num2 = position.AsVec2.DistanceSquared(this.MidDefenderOrigin); float num3 = position.AsVec2.DistanceSquared(this.RightDefenderOrigin); FormationAI.BehaviorSide behaviorSide1 = (double)num1 >= (double)num2 || (double)num1 >= (double)num3 ? ((double)num3 >= (double)num2 ? FormationAI.BehaviorSide.Middle : FormationAI.BehaviorSide.Right) : FormationAI.BehaviorSide.Left; FormationAI.BehaviorSide behaviorSide2 = FormationAI.BehaviorSide.BehaviorSideNotSet; switch (behaviorSide1) { case FormationAI.BehaviorSide.Left: if ((double)(position.AsVec2 - this.LeftDefenderOrigin).Normalized().DotProduct(this.DefenderLeftToDefenderMidDir) > 0.0) { behaviorSide2 = FormationAI.BehaviorSide.Middle; break; } break; case FormationAI.BehaviorSide.Middle: behaviorSide2 = (double)(position.AsVec2 - this.MidDefenderOrigin).Normalized().DotProduct(this.DefenderMidToDefenderRightDir) <= 0.0 ? FormationAI.BehaviorSide.Left : FormationAI.BehaviorSide.Right; break; case FormationAI.BehaviorSide.Right: if ((double)(position.AsVec2 - this.RightDefenderOrigin).Normalized().DotProduct(this.DefenderMidToDefenderRightDir) < 0.0) { behaviorSide2 = FormationAI.BehaviorSide.Middle; break; } break; } int num4 = 1 << (int)(behaviorSide1 & (FormationAI.BehaviorSide) 31); if (behaviorSide2 != FormationAI.BehaviorSide.BehaviorSideNotSet) { num4 |= 1 << (int)(behaviorSide2 & (FormationAI.BehaviorSide) 31); } return(num4); }
protected internal override void TickOccasionally() { IEnumerable <Formation> formations = this.Formations.Where <Formation>((Func <Formation, bool>)(f => f.IsRanged())); FormationAI.BehaviorSide behaviorSide = FormationAI.BehaviorSide.Left; foreach (Formation formation in formations) { formation.AI.Side = behaviorSide; behaviorSide = behaviorSide == FormationAI.BehaviorSide.Left ? FormationAI.BehaviorSide.Right : FormationAI.BehaviorSide.Left; } foreach (Formation formation in this.Formations) { formation.AI.ResetBehaviorWeights(); if (formation.IsRanged()) { formation.AI.SetBehaviorWeight <BehaviorFlank>(1f); } else { formation.AI.SetBehaviorWeight <BehaviorAdvance>(1f); } } }
private void DefendTwoMainPositions() { FormationAI.BehaviorSide infantrySide = FormationAI.BehaviorSide.BehaviorSideNotSet; if (this._mainInfantry != null) { this._mainInfantry.AI.ResetBehaviorWeights(); TacticComponent.SetDefaultBehaviorWeights(this._mainInfantry); this._mainInfantry.AI.SetBehaviorWeight <BehaviorDefendSiegeWeapon>(1f); BehaviorDefendSiegeWeapon behavior = this._mainInfantry.AI.GetBehavior <BehaviorDefendSiegeWeapon>(); SiegeWeapon siegeWeapon = this._destructableSiegeWeapons.FirstOrDefault <SiegeWeapon>((Func <SiegeWeapon, bool>)(dsw => dsw is IPrimarySiegeWeapon && dsw is IMoveableSiegeWeapon && (dsw as IPrimarySiegeWeapon).WeaponSide == FormationAI.BehaviorSide.Middle)); if (siegeWeapon != null) { infantrySide = FormationAI.BehaviorSide.Middle; } else { siegeWeapon = this._destructableSiegeWeapons.Where <SiegeWeapon>((Func <SiegeWeapon, bool>)(dsw => dsw is IPrimarySiegeWeapon && dsw is IMoveableSiegeWeapon)).MinBy <SiegeWeapon, float>((Func <SiegeWeapon, float>)(dsw => dsw.GameEntity.GlobalPosition.AsVec2.DistanceSquared(this._mainInfantry.QuerySystem.AveragePosition))); infantrySide = (siegeWeapon as IPrimarySiegeWeapon).WeaponSide; } behavior.SetDefensePositionFromTactic(this._teamAISallyOutDefender.CalculateSallyOutReferencePosition(infantrySide).ToWorldPosition()); behavior.SetDefendedSiegeWeaponFromTactic(siegeWeapon); this._mainInfantry.AI.SetBehaviorWeight <BehaviorTacticalCharge>(1f); } if (this._archers != null) { this._archers.AI.ResetBehaviorWeights(); TacticComponent.SetDefaultBehaviorWeights(this._archers); this._archers.AI.SetBehaviorWeight <BehaviorSkirmishLine>(1f); this._archers.AI.SetBehaviorWeight <BehaviorScreenedSkirmish>(1f); this._archers.AI.SetBehaviorWeight <BehaviorSkirmish>(1f); } if (this._cavalryFormation != null) { if (infantrySide != FormationAI.BehaviorSide.BehaviorSideNotSet) { this._cavalryFormation.AI.ResetBehaviorWeights(); TacticComponent.SetDefaultBehaviorWeights(this._cavalryFormation); this._cavalryFormation.AI.SetBehaviorWeight <BehaviorDefendSiegeWeapon>(1f); BehaviorDefendSiegeWeapon behavior = this._cavalryFormation.AI.GetBehavior <BehaviorDefendSiegeWeapon>(); SiegeWeapon siegeWeapon = this._destructableSiegeWeapons.FirstOrDefault <SiegeWeapon>((Func <SiegeWeapon, bool>)(dsw => dsw is IPrimarySiegeWeapon && (dsw as IPrimarySiegeWeapon).WeaponSide != infantrySide)); behavior.SetDefensePositionFromTactic(this._teamAISallyOutDefender.CalculateSallyOutReferencePosition(siegeWeapon == null ? (this._destructableSiegeWeapons.Where <SiegeWeapon>((Func <SiegeWeapon, bool>)(dsw => dsw is IPrimarySiegeWeapon && dsw is IMoveableSiegeWeapon)).MinBy <SiegeWeapon, float>((Func <SiegeWeapon, float>)(dsw => dsw.GameEntity.GlobalPosition.AsVec2.DistanceSquared(this._cavalryFormation.QuerySystem.AveragePosition))) as IPrimarySiegeWeapon).WeaponSide : (siegeWeapon as IPrimarySiegeWeapon).WeaponSide).ToWorldPosition()); behavior.SetDefendedSiegeWeaponFromTactic(siegeWeapon); this._cavalryFormation.AI.SetBehaviorWeight <BehaviorTacticalCharge>(1f); } else { this._cavalryFormation.AI.ResetBehaviorWeights(); TacticComponent.SetDefaultBehaviorWeights(this._cavalryFormation); this._cavalryFormation.AI.SetBehaviorWeight <BehaviorDefendSiegeWeapon>(1f); BehaviorDefendSiegeWeapon behavior = this._cavalryFormation.AI.GetBehavior <BehaviorDefendSiegeWeapon>(); SiegeWeapon siegeWeapon = this._destructableSiegeWeapons.FirstOrDefault <SiegeWeapon>((Func <SiegeWeapon, bool>)(dsw => dsw is IPrimarySiegeWeapon && (dsw as IPrimarySiegeWeapon).WeaponSide == FormationAI.BehaviorSide.Middle)); FormationAI.BehaviorSide side; if (siegeWeapon != null) { side = FormationAI.BehaviorSide.Middle; } else { siegeWeapon = this._destructableSiegeWeapons.Where <SiegeWeapon>((Func <SiegeWeapon, bool>)(dsw => dsw is IPrimarySiegeWeapon && dsw is IMoveableSiegeWeapon)).MinBy <SiegeWeapon, float>((Func <SiegeWeapon, float>)(dsw => dsw.GameEntity.GlobalPosition.AsVec2.DistanceSquared(this._cavalryFormation.QuerySystem.AveragePosition))); side = (siegeWeapon as IPrimarySiegeWeapon).WeaponSide; } behavior.SetDefensePositionFromTactic(this._teamAISallyOutDefender.CalculateSallyOutReferencePosition(side).ToWorldPosition()); behavior.SetDefendedSiegeWeaponFromTactic(siegeWeapon); this._cavalryFormation.AI.SetBehaviorWeight <BehaviorTacticalCharge>(1f); } } if (this._rangedCavalry == null) { return; } this._rangedCavalry.AI.ResetBehaviorWeights(); TacticComponent.SetDefaultBehaviorWeights(this._rangedCavalry); this._rangedCavalry.AI.SetBehaviorWeight <BehaviorMountedSkirmish>(1f); this._rangedCavalry.AI.SetBehaviorWeight <BehaviorHorseArcherSkirmish>(1f); }
public BehaviorShootFromSiegeTower(Formation formation) : base(formation) { this.behaviourSide = formation.AI.Side; this._siegeTower = Mission.Current.ActiveMissionObjects.FindAllWithType <SiegeTower>().FirstOrDefault <SiegeTower>((Func <SiegeTower, bool>)(st => st.WeaponSide == this.behaviourSide)); }
public static bool AreSidesRelated(FormationAI.BehaviorSide side, int connectedSides) => (uint)(1 << (int)(side & (FormationAI.BehaviorSide) 31) & connectedSides) > 0U;