protected override bool TryGetArmyData() { if (this.createFirstArmyTicket != null) { return(false); } if (base.AIDataArmyGUID.IsValid) { return(true); } if (this.currentTicket != null) { return(false); } IGameEntity gameEntity; if (!this.gameEntityRepositoryService.TryGetValue(this.SourceGuid, out gameEntity)) { base.Completion = AICommanderMission.AICommanderMissionCompletion.Fail; return(false); } for (int i = this.UnitGuids.Length - 1; i >= 0; i--) { AIData_Unit aidata_Unit; this.aiDataRepository.TryGetAIData <AIData_Unit>(this.UnitGuids[i], out aidata_Unit); if (aidata_Unit == null) { Diagnostics.LogWarning("[AICommanderMission_RegroupArmyAt] no AIData for Unit {0}", new object[] { this.UnitGuids[i].ToString() }); } else { if (aidata_Unit.IsUnitLocked() && !aidata_Unit.IsUnitLockedByMe(base.InternalGUID)) { WorldPosition worldPosition = WorldPosition.Invalid; if (aidata_Unit.Unit.Garrison is IWorldPositionable) { worldPosition = (aidata_Unit.Unit.Garrison as IWorldPositionable).WorldPosition; } Diagnostics.LogWarning(string.Format("{1} {2} LOCKING: Unit shouldn't be in use, current unit state: {0}", aidata_Unit.GetLockingStateString(), base.Commander.Empire, worldPosition)); base.Completion = AICommanderMission.AICommanderMissionCompletion.Fail; return(false); } if (aidata_Unit.Unit.UnitDesign.Tags.Contains(DownloadableContent9.TagSolitary)) { Diagnostics.LogWarning("You cannot regroup Colossus or Solitary unit with something else."); base.Completion = AICommanderMission.AICommanderMissionCompletion.Fail; return(false); } } } IGarrison garrison = gameEntity as IGarrison; if (garrison == null) { base.Completion = AICommanderMission.AICommanderMissionCompletion.Fail; return(false); } if (this.AICommanderRegroupArmies != null && this.AICommanderRegroupArmies.RequestUnitListMessageID != 0UL) { RequestUnitListMessage requestUnitListMessage = base.Commander.AIPlayer.Blackboard.GetMessage(this.AICommanderRegroupArmies.RequestUnitListMessageID) as RequestUnitListMessage; if (requestUnitListMessage == null) { base.Completion = AICommanderMission.AICommanderMissionCompletion.Fail; return(false); } requestUnitListMessage.ExecutionState = RequestUnitListMessage.RequestUnitListState.Regrouping; } bool flag = false; for (int j = 0; j < this.UnitGuids.Length; j++) { if (!garrison.ContainsUnit(this.UnitGuids[j])) { flag = true; break; } } if (flag) { List <GameEntityGUID> list = new List <GameEntityGUID>(); for (int k = 0; k < this.UnitGuids.Length; k++) { if (garrison.ContainsUnit(this.UnitGuids[k])) { list.Add(this.UnitGuids[k]); } } this.UnitGuids = list.ToArray(); } if (this.UnitGuids.Length == 0) { base.Completion = AICommanderMission.AICommanderMissionCompletion.Fail; return(false); } WorldPosition armyPosition = WorldPosition.Invalid; Army army = gameEntity as Army; if (army != null) { AIData_Army aidata = this.aiDataRepository.GetAIData <AIData_Army>(gameEntity.GUID); Diagnostics.Assert(aidata != null); if (army.GetPropertyValue(SimulationProperties.Movement) <= 0f) { return(false); } if (aidata.CommanderMission != null) { aidata.CommanderMission.Interrupt(); } if (aidata.Army.IsInEncounter || aidata.Army.IsLocked) { return(false); } if (aidata.Army.StandardUnits.Count != this.UnitGuids.Length) { armyPosition = AILayer_ArmyRecruitment.GetValidArmySpawningPosition(aidata.Army, this.worldPositionningService, this.pathfindingService); int num = (int)base.Commander.Empire.GetPropertyValue(SimulationProperties.ArmyUnitSlot); if (aidata.Army.StandardUnits.Count > num) { Array.Resize <GameEntityGUID>(ref this.UnitGuids, num); } } else { if (!aidata.AssignCommanderMission(this)) { base.Completion = AICommanderMission.AICommanderMissionCompletion.Fail; return(false); } base.AIDataArmyGUID = gameEntity.GUID; return(true); } } else if (gameEntity is Village) { Village village = gameEntity as Village; if (village.IsInEncounter) { return(false); } WorldPosition worldPosition2 = village.WorldPosition; WorldOrientation worldOrientation = WorldOrientation.East; if (this.AICommanderRegroupArmies.FinalPosition.IsValid) { worldOrientation = this.worldPositionningService.GetOrientation(worldPosition2, this.AICommanderRegroupArmies.FinalPosition); } for (int l = 0; l < 6; l++) { WorldPosition neighbourTile = this.worldPositionningService.GetNeighbourTile(worldPosition2, worldOrientation, 1); if (DepartmentOfDefense.CheckWhetherTargetPositionIsValidForUseAsArmySpawnLocation(neighbourTile, PathfindingMovementCapacity.Ground | PathfindingMovementCapacity.Water) && this.pathfindingService.IsTransitionPassable(village.WorldPosition, neighbourTile, this.pathfindingContext, PathfindingFlags.IgnoreFogOfWar, null) && this.pathfindingService.IsTilePassable(neighbourTile, this.pathfindingContext, (PathfindingFlags)0, null) && this.pathfindingService.IsTileStopable(neighbourTile, this.pathfindingContext, (PathfindingFlags)0, null)) { if (this.worldPositionningService.GetArmyAtPosition(neighbourTile) == null) { armyPosition = neighbourTile; break; } } else { worldOrientation = worldOrientation.Rotate(1); } } } else if (gameEntity is City) { City city = gameEntity as City; if (city.IsInEncounter) { return(false); } if (!DepartmentOfTheInterior.TryGetWorldPositionForNewArmyFromCity(city, this.pathfindingService, this.pathfindingContext, out armyPosition)) { return(false); } } else { Diagnostics.LogError(string.Format("[AICommanderMission_RegroupArmyAt] The garrison {0} is not valid.", garrison.GUID)); } if (armyPosition.IsValid) { if (army != null && army.WorldPath != null && army.WorldPath.Destination != army.WorldPosition) { OrderGoTo orderGoTo = new OrderGoTo(army.Empire.Index, army.GUID, army.WorldPosition); orderGoTo.Flags = (PathfindingFlags)0; base.Commander.Empire.PlayerControllers.AI.PostOrder(orderGoTo, out this.currentTicket, new EventHandler <TicketRaisedEventArgs>(this.MoveOrder_TicketRaised)); if (this.currentTicket != null) { return(false); } if (!this.orderExecuted) { Diagnostics.LogError("[AICommanderMission_RegroupArmyAt] new cancelation move order was not executed, from {0} to {1}", new object[] { army.WorldPosition, army.WorldPosition }); return(false); } } for (int m = 0; m < this.UnitGuids.Length; m++) { AIData_Unit aidata_Unit2; this.aiDataRepository.TryGetAIData <AIData_Unit>(this.UnitGuids[m], out aidata_Unit2); if (aidata_Unit2 == null) { Diagnostics.LogWarning("[AICommanderMission_RegroupArmyAt] no AIData for Unit {0}", new object[] { this.UnitGuids[m].ToString() }); } else if (!aidata_Unit2.IsUnitLockedByMe(base.InternalGUID)) { aidata_Unit2.TryLockUnit(base.InternalGUID, base.GetType().ToString(), AIData_Unit.AIDataReservationExtraTag.Regrouping, base.Commander.GetPriority(this)); } } OrderTransferGarrisonToNewArmy order = new OrderTransferGarrisonToNewArmy(base.Commander.Empire.Index, this.SourceGuid, this.UnitGuids, armyPosition, "Regroup", false, true, true); base.Commander.Empire.PlayerControllers.Server.PostOrder(order, out this.createFirstArmyTicket, new EventHandler <TicketRaisedEventArgs>(this.OrderTransferUnitToNewArmyTicketRaised)); } return(false); }
protected override State Execute(AIBehaviorTree aiBehaviorTree, params object[] parameters) { Army army; if (base.GetArmyUnlessLocked(aiBehaviorTree, "$Army", out army) != AIArmyMission.AIArmyMissionErrorCode.None) { return(State.Failure); } if (this.currentTicket != null) { if (!this.currentTicket.Raised) { return(State.Running); } bool flag = this.currentTicket.PostOrderResponse == PostOrderResponse.PreprocessHasFailed || this.currentTicket.PostOrderResponse == PostOrderResponse.AuthenticationHasFailed; this.currentTicket = null; if (flag) { aiBehaviorTree.ErrorCode = 29; aiBehaviorTree.LogWarning("OrderGotoFail", new object[0]); return(State.Failure); } if (army.GetPropertyValue(SimulationProperties.Movement) > 1.401298E-45f) { aiBehaviorTree.ErrorCode = 28; return(State.Running); } return(State.Success); } else { if (army.IsMoving) { return(State.Running); } if (!aiBehaviorTree.Variables.ContainsKey(this.PathVarName)) { aiBehaviorTree.LogError("{0} not set", new object[] { this.PathVarName }); return(State.Failure); } WorldPath worldPath = aiBehaviorTree.Variables[this.PathVarName] as WorldPath; if (worldPath == null || worldPath.Length < 2) { aiBehaviorTree.LogError("Path is null.", new object[0]); aiBehaviorTree.ErrorCode = 3; return(State.Failure); } if (!worldPath.IsValid) { aiBehaviorTree.ErrorCode = 3; return(State.Failure); } if (this.TypeOfMove.Equals("AvoidEnemy") && this.IsEnemyDetectedOnPath(army)) { aiBehaviorTree.ErrorCode = 23; return(State.Failure); } int num = -1; for (int i = 0; i < worldPath.WorldPositions.Length; i++) { if (worldPath.WorldPositions[i] == army.WorldPosition) { num = i; break; } } if (num == worldPath.Length - 1) { return(State.Success); } if (num == -1) { return(State.Failure); } if (this.ArmyCanTeleport == AIBehaviorTreeNode_Action_Move.TeleportState.NotChecked) { this.ArmyCanTeleport = AIBehaviorTreeNode_Action_Move.TeleportState.HasTeleport; if (!army.IsSolitary || !(army.Empire is MajorEmpire)) { this.ArmyCanTeleport = AIBehaviorTreeNode_Action_Move.TeleportState.NoTeleport; } else { using (IEnumerator <Unit> enumerator = army.Units.GetEnumerator()) { while (enumerator.MoveNext()) { if (!enumerator.Current.CheckUnitAbility("UnitAbilityTeleportInRange", -1)) { this.ArmyCanTeleport = AIBehaviorTreeNode_Action_Move.TeleportState.NoTeleport; break; } } } } } if (this.ArmyCanTeleport == AIBehaviorTreeNode_Action_Move.TeleportState.HasTeleport && Amplitude.Unity.Framework.Application.Preferences.EnableModdingTools) { Diagnostics.Log("ELCP {0} Army {1} has teleport {2} {3} {4} {5}", new object[] { army.Empire, army.LocalizedName, worldPath.Destination, worldPath.Length, worldPath.ControlPoints.Length, num }); } if (this.ArmyCanTeleport == AIBehaviorTreeNode_Action_Move.TeleportState.HasTeleport && worldPath.ControlPoints.Length != 0 && worldPath.ControlPoints.Any((ushort cp) => cp > (ushort)num) && this.TryTeleportInRange(aiBehaviorTree, army, worldPath, num)) { return(State.Running); } WorldPosition worldPosition = WorldPosition.Invalid; int num3 = -1; int num2 = 0; int k; int j; for (j = num + 1; j < worldPath.WorldPositions.Length; j = k + 1) { if (this.pathfindingService.IsTilePassable(worldPath.WorldPositions[j], army, (PathfindingFlags)0, null) && this.pathfindingService.IsTileStopable(worldPath.WorldPositions[j], army, (PathfindingFlags)0, null)) { worldPosition = worldPath.WorldPositions[j]; num2++; if (num2 > 1) { break; } } else if (worldPath.ControlPoints.Length != 0 && Array.Exists <ushort>(worldPath.ControlPoints, (ushort p) => (int)p == j)) { num3 = j; } k = j; } if (num3 >= 0) { List <WorldPosition> neighbours = worldPath.WorldPositions[num3].GetNeighbours(this.game.World.WorldParameters); WorldPosition worldPosition2 = (num3 > 0) ? worldPath.WorldPositions[num3 - 1] : army.WorldPosition; List <WorldPosition> neighbours2 = worldPosition2.GetNeighbours(this.game.World.WorldParameters); PathfindingFlags flags = PathfindingFlags.IgnoreArmies | PathfindingFlags.IgnoreOtherEmpireDistrict | PathfindingFlags.IgnoreDiplomacy | PathfindingFlags.IgnoreEncounterAreas | PathfindingFlags.IgnoreFogOfWar | PathfindingFlags.IgnoreZoneOfControl | PathfindingFlags.IgnorePOI | PathfindingFlags.IgnoreSieges | PathfindingFlags.IgnoreDistrict; if (Amplitude.Unity.Framework.Application.Preferences.EnableModdingTools) { Diagnostics.Log("ELCP {0}/{1} AIBehaviorTreeNode_Action_Move posses: {2}/{3}", new object[] { army.Empire, army.LocalizedName, worldPosition2, worldPath.WorldPositions[num3] }); } foreach (WorldPosition worldPosition3 in neighbours) { if (Amplitude.Unity.Framework.Application.Preferences.EnableModdingTools) { Diagnostics.Log("ELCP {0}/{1} AIBehaviorTreeNode_Action_Move checking neighbor {2} {3} {4} {5} {6}", new object[] { army.Empire, army.LocalizedName, worldPosition3, neighbours2.Contains(worldPosition3), this.pathfindingService.IsTileStopable(worldPosition3, army, (PathfindingFlags)0, null), this.pathfindingService.IsTransitionPassable(worldPosition2, worldPosition3, army, flags, null), this.pathfindingService.IsTransitionPassable(worldPosition3, worldPath.WorldPositions[num3], army, flags, null) }); } if (neighbours2.Contains(worldPosition3) && this.pathfindingService.IsTileStopable(worldPosition3, army, (PathfindingFlags)0, null) && this.pathfindingService.IsTransitionPassable(worldPosition2, worldPosition3, army, flags, null) && this.pathfindingService.IsTransitionPassable(worldPosition3, worldPath.WorldPositions[num3], army, flags, null)) { if (Amplitude.Unity.Framework.Application.Preferences.EnableModdingTools) { Diagnostics.Log("ELCP {0}/{1} AIBehaviorTreeNode_Action_Move {2} is a suitable alternative goal", new object[] { army.Empire, army.LocalizedName, worldPosition3 }); } worldPosition = worldPosition3; break; } } } if (worldPosition == WorldPosition.Invalid) { aiBehaviorTree.ErrorCode = 3; return(State.Failure); } OrderGoTo orderGoTo = new OrderGoTo(army.Empire.Index, army.GUID, worldPosition); orderGoTo.Flags = PathfindingFlags.IgnoreFogOfWar; aiBehaviorTree.AICommander.Empire.PlayerControllers.AI.PostOrder(orderGoTo, out this.currentTicket, null); return(State.Running); } }
private void ValidatePath() { IGuiService service = Services.GetService <IGuiService>(); IAudioEventService service2 = Services.GetService <IAudioEventService>(); Diagnostics.Assert(service2 != null); bool flag = base.SelectedUnits.Length == 0 || base.SelectedUnits.Length == this.Army.StandardUnits.Count || (this.Garrison.UnitsCount == 1 && this.Garrison.Hero != null); if (!base.IsTransferable(WorldCursor.HighlightedWorldPosition) && flag) { global::Empire empire = this.WorldArmy.Army.Empire; if (this.battleTarget is Army) { Army army = this.battleTarget as Army; if (army.Empire.Index == this.Army.Empire.Index) { int num = Mathf.Max(army.MaximumUnitSlot - army.CurrentUnitSlot, 0); if (this.Army.HasCatspaw || army.HasCatspaw) { QuickWarningPanel.Show("%UnitsTransferImpossibleWithCatsPawArmy"); } else if (this.Army.StandardUnits.Count > num) { QuickWarningPanel.Show(string.Format(AgeLocalizer.Instance.LocalizeString("%UnitsTransferNotEnoughSlotsInTargetArmy"), num)); } else if (this.Army.GetPropertyValue(SimulationProperties.Movement) <= 0f && base.WorldPositionningService.GetDistance(this.Army.WorldPosition, army.WorldPosition) == 1) { QuickWarningPanel.Show(AgeLocalizer.Instance.LocalizeString("%" + ArmyAction_TransferUnits.NotEnoughMovementToTransfer + "Description")); } else if (this.TemporaryWorldPath != null && this.TemporaryWorldPath.Length > 1 && !this.Army.HasCatspaw && !army.HasCatspaw) { OrderGoToAndMerge order = new OrderGoToAndMerge(empire.Index, this.WorldArmy.Army.GUID, this.battleTarget.GUID, (from unit in base.SelectedUnits select unit.GUID).ToArray <GameEntityGUID>(), this.TemporaryWorldPath); this.PlayerControllerRepositoryService.ActivePlayerController.PostOrder(order); } } else { DepartmentOfForeignAffairs agency = empire.GetAgency <DepartmentOfForeignAffairs>(); Diagnostics.Assert(agency != null); bool flag2 = this.Army.IsNaval == army.IsNaval; if ((agency.CanAttack(this.battleTarget) || this.WorldArmy.Army.IsPrivateers) && flag2) { ArmyAction armyAction = null; IDatabase <ArmyAction> database = Databases.GetDatabase <ArmyAction>(false); float cost = 0f; if (database != null && database.TryGetValue(ArmyAction_Attack.ReadOnlyName, out armyAction)) { cost = armyAction.GetCostInActionPoints(); } if (!this.Army.HasEnoughActionPoint(cost)) { QuickWarningPanel.Show(AgeLocalizer.Instance.LocalizeString("%ArmyNotEnoughActionPointsDescription")); } else if (this.TemporaryWorldPath != null && this.TemporaryWorldPath.Length > 1) { OrderGoToAndAttack order2 = new OrderGoToAndAttack(empire.Index, this.WorldArmy.Army.GUID, this.battleTarget.GUID, this.TemporaryWorldPath); this.PlayerControllerRepositoryService.ActivePlayerController.PostOrder(order2); } else { OrderAttack order3 = new OrderAttack(empire.Index, this.WorldArmy.Army.GUID, this.battleTarget.GUID); this.PlayerControllerRepositoryService.ActivePlayerController.PostOrder(order3); } service2.Play2DEvent("Gui/Interface/InGame/OrderAttack"); } else if (army.Empire is MajorEmpire && flag2) { global::Empire empire2 = army.Empire; service.GetGuiPanel <WarDeclarationModalPanel>().Show(new object[] { empire2, "AttackTarget" }); } } } else { bool flag3 = false; if (this.battleTarget != null) { if (this.TemporaryWorldPath != null && this.TemporaryWorldPath.Length > 1) { flag3 = (this.TemporaryWorldPath.ControlPoints.Length == 0); flag3 |= (this.TemporaryWorldPath.ControlPoints.Length == 1 && (int)this.TemporaryWorldPath.ControlPoints[0] == this.TemporaryWorldPath.Length - 1); } else { flag3 = base.PathfindingService.IsTransitionPassable(this.Army.WorldPosition, this.battleTarget.WorldPosition, this.Army, PathfindingFlags.IgnoreArmies | PathfindingFlags.IgnoreOtherEmpireDistrict | PathfindingFlags.IgnoreDiplomacy | PathfindingFlags.IgnorePOI | PathfindingFlags.IgnoreSieges | PathfindingFlags.IgnoreKaijuGarrisons, null); } } if (flag3 || this.battleTarget is Fortress || this.battleTarget is KaijuGarrison) { flag3 = false; bool flag4 = true; if (this.battleTarget is KaijuGarrison) { KaijuGarrison kaijuGarrison = this.battleTarget as KaijuGarrison; DepartmentOfForeignAffairs agency2 = empire.GetAgency <DepartmentOfForeignAffairs>(); Diagnostics.Assert(agency2 != null); if (!agency2.CanAttack(this.battleTarget)) { flag4 = false; global::Empire empire3 = kaijuGarrison.Empire; service.GetGuiPanel <WarDeclarationModalPanel>().Show(new object[] { empire3, "AttackTarget" }); } } if (flag4) { ArmyActionModalPanel guiPanel = service.GetGuiPanel <ArmyActionModalPanel>(); if (guiPanel != null) { WorldPosition destination = (this.TemporaryWorldPath == null || this.TemporaryWorldPath.Length <= 1) ? WorldPosition.Invalid : this.TemporaryWorldPath.Destination; if (guiPanel.CheckForArmyActionsAvailability(this.Army, this.battleTarget, destination).Count > 0) { flag3 = true; } } } } if (flag3 && this.battleTarget != null && !this.Army.IsPrivateers) { MajorEmpire majorEmpire = null; if (this.battleTarget is Garrison) { majorEmpire = ((this.battleTarget as Garrison).Empire as MajorEmpire); } else if (this.battleTarget is District) { majorEmpire = ((this.battleTarget as District).Empire as MajorEmpire); } if (majorEmpire != null && majorEmpire.Index != this.Army.Empire.Index) { flag3 = this.Army.Empire.GetAgency <DepartmentOfForeignAffairs>().IsSymetricallyDiscovered(majorEmpire); } } if (flag3) { WorldPosition worldPosition = (this.TemporaryWorldPath == null || this.TemporaryWorldPath.Length <= 1) ? WorldPosition.Invalid : this.TemporaryWorldPath.Destination; service.Show(typeof(ArmyActionModalPanel), new object[] { this.Army, this.battleTarget, base.SelectedUnits, worldPosition }); } else if (this.TemporaryWorldPath != null && this.TemporaryWorldPath.Destination != WorldPosition.Invalid) { OrderGoTo order4 = new OrderGoTo(empire.Index, this.WorldArmy.Army.GUID, this.TemporaryWorldPath.Destination); this.PlayerControllerRepositoryService.ActivePlayerController.PostOrder(order4); service2.Play2DEvent("Gui/Interface/InGame/OrderGoTo"); } else if (WorldCursor.HighlightedWorldPosition != WorldPosition.Invalid) { Region region = base.WorldPositionningService.GetRegion(WorldCursor.HighlightedWorldPosition); if (region != null && region.City != null && region.City.Empire != null) { DepartmentOfForeignAffairs agency3 = this.Army.Empire.GetAgency <DepartmentOfForeignAffairs>(); Diagnostics.Assert(agency3 != null); if (!agency3.CanMoveOn(WorldCursor.HighlightedWorldPosition, this.WorldArmy.Army.IsPrivateers, this.WorldArmy.Army.IsCamouflaged)) { District district = base.WorldPositionningService.GetDistrict(WorldCursor.HighlightedWorldPosition); if ((district == null || district.Type == DistrictType.Exploitation) && region.City.Empire is MajorEmpire) { service.GetGuiPanel <WarDeclarationModalPanel>().Show(new object[] { region.City.Empire, "BreakCloseBorder" }); } } } } } } this.LastHighlightedWorldPosition = WorldPosition.Invalid; this.LastUnpathableWorldPosition = WorldPosition.Invalid; this.SelectTarget(); this.UpdateBattlegroundVisibility(); if (this.TemporaryWorldPath != null) { this.PathRendererService.RemovePath(this.TemporaryWorldPath); this.TemporaryWorldPath = null; } }