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 ResetOrderPositions() { this.behaviorSide = this.DetermineGatheringSide(); SiegeLane siegeLane = TeamAISiegeComponent.SiegeLanes.FirstOrDefault <SiegeLane>((Func <SiegeLane, bool>)(sl => sl.LaneSide == this.behaviorSide)); WorldFrame worldFrame = siegeLane == null ? WorldFrame.Invalid : siegeLane.DefensePoints.FirstOrDefault <ICastleKeyPosition>().DefenseWaitFrame; this._gatheringTacticalPos = siegeLane != null?siegeLane.DefensePoints.FirstOrDefault <ICastleKeyPosition>().WaitPosition : (TacticalPosition)null; if (this._gatheringTacticalPos != null) { this._gatherOrder = MovementOrder.MovementOrderMove(this._gatheringTacticalPos.Position); this._gatheringFacingOrder = FacingOrder.FacingOrderLookAtEnemy; } else if (worldFrame.Origin.IsValid) { double num = (double)worldFrame.Rotation.f.Normalize(); this._gatherOrder = MovementOrder.MovementOrderMove(worldFrame.Origin); this._gatheringFacingOrder = FacingOrder.FacingOrderLookAtEnemy; } else { this._gatherOrder = MovementOrder.MovementOrderMove(this.formation.QuerySystem.MedianPosition); this._gatheringFacingOrder = FacingOrder.FacingOrderLookAtEnemy; } this._attackOrder = MovementOrder.MovementOrderChargeToTarget(this._targetEnemyFormation); this._attackFacingOrder = FacingOrder.FacingOrderLookAtEnemy; this.CurrentOrder = this._behaviourState == BehaviorEliminateEnemyInsideCastle.BehaviourState.Attacking ? this._attackOrder : this._gatherOrder; this.CurrentFacingOrder = this._behaviourState == BehaviorEliminateEnemyInsideCastle.BehaviourState.Attacking ? this._attackFacingOrder : this._gatheringFacingOrder; }
private void AssignMeleeFormationsToLanes( List <Formation> meleeFormationsSource, List <SiegeLane> currentLanes) { List <Formation> meleeFormations = new List <Formation>(meleeFormationsSource.Count); meleeFormations.AddRange((IEnumerable <Formation>)meleeFormationsSource); List <SiegeLane> list = currentLanes.ToList <SiegeLane>(); Formation strongestFormation = meleeFormations.Any <Formation>() ? meleeFormations.MaxBy <Formation, float>((Func <Formation, float>)(mf => mf.QuerySystem.FormationPower)) : (Formation)null; bool flag = meleeFormations.Count <Formation>() <= 1 || (double)strongestFormation.QuerySystem.FormationPower > (double)meleeFormations.Where <Formation>((Func <Formation, bool>)(f => f != strongestFormation)).Average <Formation>((Func <Formation, float>)(f => f.QuerySystem.FormationPower)) * 2.0; while (meleeFormations.Any <Formation>() && list.Any <SiegeLane>()) { SiegeLane assaultedLane = list.FirstOrDefault <SiegeLane>((Func <SiegeLane, bool>)(l => meleeFormations.Any <Formation>((Func <Formation, bool>)(mf => mf.AI.Side == l.LaneSide)))); if (assaultedLane != null) { IEnumerable <Formation> source = meleeFormations.Where <Formation>((Func <Formation, bool>)(mf => mf.AI.Side == assaultedLane.LaneSide)); Formation f = source.Any <Formation>((Func <Formation, bool>)(pdf => pdf.IsAIControlled)) ? source.Where <Formation>((Func <Formation, bool>)(pdf => pdf.IsAIControlled)).MaxBy <Formation, float>((Func <Formation, float>)(pdf => pdf.QuerySystem.FormationPower)) : source.MaxBy <Formation, float>((Func <Formation, float>)(pdf => pdf.QuerySystem.FormationPower)); f.AI.ResetBehaviorWeights(); TacticComponent.SetDefaultBehaviorWeights(f); f.AI.SetBehaviorWeight <BehaviorAssaultWalls>(1f); f.AI.SetBehaviorWeight <BehaviorUseSiegeMachines>(1f); f.AI.SetBehaviorWeight <BehaviorWaitForLadders>(1f); meleeFormations.Remove(f); list.Remove(assaultedLane); } else { Formation f = meleeFormations.Any <Formation>((Func <Formation, bool>)(mf => mf.IsAIControlled)) ? meleeFormations.Where <Formation>((Func <Formation, bool>)(mf => mf.IsAIControlled)).MaxBy <Formation, float>((Func <Formation, float>)(mf => mf.QuerySystem.FormationPower)) : meleeFormations.MaxBy <Formation, float>((Func <Formation, float>)(mf => mf.QuerySystem.FormationPower)); SiegeLane siegeLane = flag ? list.MinBy <SiegeLane, float>((Func <SiegeLane, float>)(l => l.LaneDifficulty)) : list.MaxBy <SiegeLane, float>((Func <SiegeLane, float>)(l => l.LaneDifficulty)); f.AI.Side = siegeLane.LaneSide; f.AI.ResetBehaviorWeights(); TacticComponent.SetDefaultBehaviorWeights(f); f.AI.SetBehaviorWeight <BehaviorAssaultWalls>(1f); f.AI.SetBehaviorWeight <BehaviorUseSiegeMachines>(1f); f.AI.SetBehaviorWeight <BehaviorWaitForLadders>(1f); meleeFormations.Remove(f); list.Remove(siegeLane); } } while (meleeFormations.Any <Formation>()) { if (list.IsEmpty <SiegeLane>()) { list.AddRange((IEnumerable <SiegeLane>)currentLanes); } Formation f = meleeFormations.MaxBy <Formation, float>((Func <Formation, float>)(mf => mf.QuerySystem.FormationPower)); SiegeLane siegeLane = list.MaxBy <SiegeLane, float>((Func <SiegeLane, float>)(l => l.GetLaneCapacity())); f.AI.Side = siegeLane.LaneSide; f.AI.ResetBehaviorWeights(); TacticComponent.SetDefaultBehaviorWeights(f); f.AI.SetBehaviorWeight <BehaviorAssaultWalls>(1f); f.AI.SetBehaviorWeight <BehaviorUseSiegeMachines>(1f); f.AI.SetBehaviorWeight <BehaviorWaitForLadders>(1f); meleeFormations.Remove(f); list.Remove(siegeLane); } }
private void ConfirmGatheringSide() { SiegeLane siegeLane = TeamAISiegeComponent.SiegeLanes.FirstOrDefault <SiegeLane>((Func <SiegeLane, bool>)(sl => sl.LaneSide == this._gatheringSide)); if (siegeLane != null && siegeLane.LaneState < SiegeLane.LaneStateEnum.Conceited) { return; } this.ResetOrderPositions(); }
internal override void OnValidBehaviorSideSet() { base.OnValidBehaviorSideSet(); this._ladders = Mission.Current.ActiveMissionObjects.Where <MissionObject>((Func <MissionObject, bool>)(amo => amo is SiegeLadder)).Select <MissionObject, SiegeLadder>((Func <MissionObject, SiegeLadder>)(amo => amo as SiegeLadder)).ToList <SiegeLadder>(); this._ladders.RemoveAll((Predicate <SiegeLadder>)(l => l.IsDeactivated || l.WeaponSide != this.behaviorSide)); SiegeLane siegeLane = TeamAISiegeComponent.SiegeLanes.FirstOrDefault <SiegeLane>((Func <SiegeLane, bool>)(sl => sl.LaneSide == this.behaviorSide)); this._breachedWallSegment = (siegeLane != null ? siegeLane.DefensePoints.FirstOrDefault <ICastleKeyPosition>((Func <ICastleKeyPosition, bool>)(dp => dp is WallSegment && (dp as WallSegment).IsBreachedWall)) : (ICastleKeyPosition)null) as WallSegment; this.ResetFollowOrder(); this._behaviourState = BehaviorWaitForLadders.BehaviourState.Unset; }
private BehaviorAssaultWalls.BehaviorState CheckAndChangeState() { switch (this._behaviourState) { case BehaviorAssaultWalls.BehaviorState.Deciding: if (!this._isGateLane && this._wallSegment == null) { return(BehaviorAssaultWalls.BehaviorState.Charging); } return(this._isGateLane ? BehaviorAssaultWalls.BehaviorState.AttackEntity : BehaviorAssaultWalls.BehaviorState.ClimbWall); case BehaviorAssaultWalls.BehaviorState.ClimbWall: if (this._wallSegment == null) { return(BehaviorAssaultWalls.BehaviorState.Charging); } bool flag = false; if (this.behaviorSide < FormationAI.BehaviorSide.BehaviorSideNotSet) { SiegeLane siegeLane = TeamAISiegeComponent.SiegeLanes[(int)this.behaviorSide]; flag = siegeLane.IsUnderAttack() && !siegeLane.IsDefended(); } return(flag | (double)this.formation.QuerySystem.MedianPosition.GetNavMeshVec3().DistanceSquared(this._wallSegment.MiddleFrame.Origin.GetNavMeshVec3()) < (double)this.formation.Depth * (double)this.formation.Depth ? BehaviorAssaultWalls.BehaviorState.TakeControl : BehaviorAssaultWalls.BehaviorState.ClimbWall); case BehaviorAssaultWalls.BehaviorState.AttackEntity: return(this._teamAISiegeComponent.OuterGate.IsGateOpen && this._teamAISiegeComponent.InnerGate.IsGateOpen ? BehaviorAssaultWalls.BehaviorState.Charging : BehaviorAssaultWalls.BehaviorState.AttackEntity); case BehaviorAssaultWalls.BehaviorState.TakeControl: if (this.formation.QuerySystem.ClosestEnemyFormation == null) { return(BehaviorAssaultWalls.BehaviorState.Deciding); } if (TeamAISiegeComponent.SiegeLanes.FirstOrDefault <SiegeLane>((Func <SiegeLane, bool>)(sl => sl.LaneSide == this.behaviorSide)).IsDefended()) { return(BehaviorAssaultWalls.BehaviorState.TakeControl); } return(!this._teamAISiegeComponent.OuterGate.IsGateOpen || !this._teamAISiegeComponent.InnerGate.IsGateOpen ? BehaviorAssaultWalls.BehaviorState.MoveToGate : BehaviorAssaultWalls.BehaviorState.Charging); case BehaviorAssaultWalls.BehaviorState.MoveToGate: return(this._teamAISiegeComponent.OuterGate.IsGateOpen && this._teamAISiegeComponent.InnerGate.IsGateOpen ? BehaviorAssaultWalls.BehaviorState.Charging : BehaviorAssaultWalls.BehaviorState.MoveToGate); case BehaviorAssaultWalls.BehaviorState.Charging: if (!TeamAISiegeComponent.IsFormationInsideCastle(this.formation, true)) { return(BehaviorAssaultWalls.BehaviorState.Deciding); } return(this.formation.QuerySystem.ClosestEnemyFormation == null ? BehaviorAssaultWalls.BehaviorState.Stop : BehaviorAssaultWalls.BehaviorState.Charging); default: return(this.formation.QuerySystem.ClosestEnemyFormation != null ? BehaviorAssaultWalls.BehaviorState.Deciding : BehaviorAssaultWalls.BehaviorState.Stop); } }
private float GetFormationBehaviourLaneEffectiveness( SiegeLane siegeLane, Formation formation, BehaviorComponent behaviour) { switch (behaviour) { case BehaviorAssaultWalls _: return((float)((formation.AI.Side == siegeLane.LaneSide ? 5.0 : 1.0) * (formation.AI.ActiveBehavior == null || !(formation.AI.ActiveBehavior.GetType() == behaviour.GetType()) ? 1.0 : 3.0)) * TacticComponent.GetFormationEffectivenessOverOrder(formation, OrderType.Charge) * siegeLane.PrimarySiegeWeapons.Where <IPrimarySiegeWeapon>((Func <IPrimarySiegeWeapon, bool>)(psw => psw.HasCompletedAction())).Max <IPrimarySiegeWeapon>((Func <IPrimarySiegeWeapon, float>)(psw => psw.SiegeWeaponPriority))); case BehaviorUseSiegeMachines _: return((float)((formation.AI.Side == siegeLane.LaneSide ? 5.0 : 1.0) * (formation.AI.ActiveBehavior == null || !(formation.AI.ActiveBehavior.GetType() == behaviour.GetType()) ? 1.0 : 3.0)) * TacticComponent.GetFormationEffectivenessOverOrder(formation, OrderType.Charge) * siegeLane.PrimarySiegeWeapons.Where <IPrimarySiegeWeapon>((Func <IPrimarySiegeWeapon, bool>)(psw => !psw.HasCompletedAction())).Max <IPrimarySiegeWeapon>((Func <IPrimarySiegeWeapon, float>)(psw => psw.SiegeWeaponPriority))); default: return(0.0f); } }
public void OnDeploymentFinished() { TeamAISiegeComponent.SiegeLanes.Clear(); for (int i = 0; i < 3; i++) { TeamAISiegeComponent.SiegeLanes.Add(new SiegeLane((FormationAI.BehaviorSide)i, TeamAISiegeComponent.QuerySystem)); SiegeLane siegeLane = TeamAISiegeComponent.SiegeLanes[i]; siegeLane.SetPrimarySiegeWeapons(this.PrimarySiegeWeapons.Where <SiegeWeapon>((Func <SiegeWeapon, bool>)(psw => psw is IPrimarySiegeWeapon && (psw as IPrimarySiegeWeapon).WeaponSide == (FormationAI.BehaviorSide)i)).Select <SiegeWeapon, IPrimarySiegeWeapon>((Func <SiegeWeapon, IPrimarySiegeWeapon>)(um => um as IPrimarySiegeWeapon)).ToList <IPrimarySiegeWeapon>()); siegeLane.SetDefensePoints(this.CastleKeyPositions.Where <MissionObject>((Func <MissionObject, bool>)(ckp => (ckp as ICastleKeyPosition).DefenseSide == (FormationAI.BehaviorSide)i)).Select <MissionObject, ICastleKeyPosition>((Func <MissionObject, ICastleKeyPosition>)(dp => dp as ICastleKeyPosition)).ToList <ICastleKeyPosition>()); siegeLane.RefreshLane(); siegeLane.DetermineLaneState(); siegeLane.DetermineOrigins(); } TeamAISiegeComponent.QuerySystem = new SiegeQuerySystem(this.Team, (IEnumerable <SiegeLane>)TeamAISiegeComponent.SiegeLanes); TeamAISiegeComponent.QuerySystem.Expire(); TeamAISiegeComponent.SiegeLanes.ForEach((Action <SiegeLane>)(sl => sl.SetSiegeQuerySystem(TeamAISiegeComponent.QuerySystem))); this.ArcherPositions.ForEach((Action <ArcherPosition>)(ap => ap.OnDeploymentFinished(TeamAISiegeComponent.QuerySystem, BattleSideEnum.Defender))); }
internal SiegeQuerySystem(Team team, IEnumerable <SiegeLane> lanes) { Mission mission = Mission.Current; this._attackerTeam = mission.AttackerTeam; Team defenderTeam = mission.DefenderTeam; SiegeLane siegeLane1 = lanes.FirstOrDefault <SiegeLane>((Func <SiegeLane, bool>)(l => l.LaneSide == FormationAI.BehaviorSide.Left)); WorldPosition worldPosition = siegeLane1.DefenderOrigin; this._leftDefenderOrigin = worldPosition.AsVec2; worldPosition = siegeLane1.AttackerOrigin; this._leftAttackerOrigin = worldPosition.AsVec2; SiegeLane siegeLane2 = lanes.FirstOrDefault <SiegeLane>((Func <SiegeLane, bool>)(l => l.LaneSide == FormationAI.BehaviorSide.Middle)); worldPosition = siegeLane2.DefenderOrigin; this._middleDefenderOrigin = worldPosition.AsVec2; worldPosition = siegeLane2.AttackerOrigin; this._middleAttackerOrigin = worldPosition.AsVec2; SiegeLane siegeLane3 = lanes.FirstOrDefault <SiegeLane>((Func <SiegeLane, bool>)(l => l.LaneSide == FormationAI.BehaviorSide.Right)); worldPosition = siegeLane3.DefenderOrigin; this._rightDefenderOrigin = worldPosition.AsVec2; worldPosition = siegeLane3.AttackerOrigin; this._rightAttackerOrigin = worldPosition.AsVec2; this._leftToMidDir = (this._middleAttackerOrigin - this._leftDefenderOrigin).Normalized(); this._midToLeftDir = (this._leftAttackerOrigin - this._middleDefenderOrigin).Normalized(); this._midToRightDir = (this._rightAttackerOrigin - this._middleDefenderOrigin).Normalized(); this._rightToMidDir = (this._middleAttackerOrigin - this._rightDefenderOrigin).Normalized(); this._leftRegionMemberCount = new QueryData <int>((Func <int>)(() => this.LocateAttackers(SiegeQuerySystem.RegionEnum.Left)), 5f); this._leftCloseAttackerCount = new QueryData <int>((Func <int>)(() => this.LocateAttackers(SiegeQuerySystem.RegionEnum.LeftClose)), 5f); this._middleRegionMemberCount = new QueryData <int>((Func <int>)(() => this.LocateAttackers(SiegeQuerySystem.RegionEnum.Middle)), 5f); this._middleCloseAttackerCount = new QueryData <int>((Func <int>)(() => this.LocateAttackers(SiegeQuerySystem.RegionEnum.MiddleClose)), 5f); this._rightRegionMemberCount = new QueryData <int>((Func <int>)(() => this.LocateAttackers(SiegeQuerySystem.RegionEnum.Right)), 5f); this._rightCloseAttackerCount = new QueryData <int>((Func <int>)(() => this.LocateAttackers(SiegeQuerySystem.RegionEnum.RightClose)), 5f); this._insideAttackerCount = new QueryData <int>((Func <int>)(() => this.LocateAttackers(SiegeQuerySystem.RegionEnum.Inside)), 5f); this._leftDefenderCount = new QueryData <int>((Func <int>)(() => mission.GetNearbyAllyAgents(this._leftDefenderOrigin, 10f, defenderTeam).Count <Agent>()), 5f); this._middleDefenderCount = new QueryData <int>((Func <int>)(() => mission.GetNearbyAllyAgents(this._middleDefenderOrigin, 10f, defenderTeam).Count <Agent>()), 5f); this._rightDefenderCount = new QueryData <int>((Func <int>)(() => mission.GetNearbyAllyAgents(this._rightDefenderOrigin, 10f, defenderTeam).Count <Agent>()), 5f); this.DefenderLeftToDefenderMidDir = (this._middleDefenderOrigin - this._leftDefenderOrigin).Normalized(); this.DefenderMidToDefenderRightDir = (this._rightDefenderOrigin - this._middleDefenderOrigin).Normalized(); this.InitializeTelemetryScopeNames(); }
public BehaviorWaitForLadders(Formation formation) : base(formation) { this.behaviorSide = formation.AI.Side; this._ladders = Mission.Current.ActiveMissionObjects.Where <MissionObject>((Func <MissionObject, bool>)(amo => amo is SiegeLadder)).Select <MissionObject, SiegeLadder>((Func <MissionObject, SiegeLadder>)(amo => amo as SiegeLadder)).ToList <SiegeLadder>(); this._ladders.RemoveAll((Predicate <SiegeLadder>)(l => l.IsDeactivated || l.WeaponSide != this.behaviorSide)); this._teamAISiegeComponent = (TeamAISiegeComponent)formation.Team.TeamAI; SiegeLane siegeLane = TeamAISiegeComponent.SiegeLanes.FirstOrDefault <SiegeLane>((Func <SiegeLane, bool>)(sl => sl.LaneSide == this.behaviorSide)); this._breachedWallSegment = (siegeLane != null ? siegeLane.DefensePoints.FirstOrDefault <ICastleKeyPosition>((Func <ICastleKeyPosition, bool>)(dp => dp is WallSegment && (dp as WallSegment).IsBreachedWall)) : (ICastleKeyPosition)null) as WallSegment; this.ResetFollowOrder(); this._stopOrder = MovementOrder.MovementOrderStop; if (this._followOrder != (object)null) { this.CurrentOrder = this._followOrder; this._behaviourState = BehaviorWaitForLadders.BehaviourState.Follow; } else { this.CurrentOrder = this._stopOrder; this._behaviourState = BehaviorWaitForLadders.BehaviourState.Stop; } }
private void ResetOrderPositions() { SiegeLane siegeLane = TeamAISiegeComponent.SiegeLanes.FirstOrDefault <SiegeLane>((Func <SiegeLane, bool>)(sl => sl.LaneSide == FormationAI.BehaviorSide.Middle)); WorldFrame worldFrame = (siegeLane != null ? siegeLane.DefensePoints.FirstOrDefault <ICastleKeyPosition>()?.DefenseWaitFrame : new WorldFrame?()) ?? WorldFrame.Invalid; this._gatheringTacticalPos = siegeLane != null?siegeLane.DefensePoints.FirstOrDefault <ICastleKeyPosition>()?.WaitPosition : (TacticalPosition)null; if (this._gatheringTacticalPos != null) { this._gatherOrder = MovementOrder.MovementOrderMove(this._gatheringTacticalPos.Position); } else if (worldFrame.Origin.IsValid) { double num = (double)worldFrame.Rotation.f.Normalize(); this._gatherOrder = MovementOrder.MovementOrderMove(worldFrame.Origin); } else { this._gatherOrder = MovementOrder.MovementOrderMove(this.formation.QuerySystem.MedianPosition); } this._attackOrder = MovementOrder.MovementOrderCharge; this.CurrentOrder = this._calculateShouldStartAttacking ? this._attackOrder : this._gatherOrder; }