public override VehicleFormationResult PerformAction(World world, Player me, Game game) { var myArmy = new VehiclesGroup(Id, VehicleIds, VehicleRegistry, CommandManager); commands.RemoveAll(c => c.IsStarted() && c.IsFinished(world.TickIndex, VehicleRegistry)); if (commands.Any()) { return(new VehicleFormationResult(this)); } if (FormationHelper.IsNukeAlert(world.GetOpponentPlayer()) && world.TickIndex - nukePreventionTick > game.BaseTacticalNuclearStrikeCooldown / 2) { commands.Clear(); CommandManager.ClearCommandsQueue(Id); this.PreventNuke(myArmy, world, game, commands); nukePreventionTick = world.TickIndex; return(new VehicleFormationResult(this)); } var myVehicles = VehicleRegistry.GetVehiclesByIds(VehicleIds).ToList(); if (cachedTargetGroup != null && this.TryNuke(myArmy, myVehicles, VehicleRegistry.GetVehiclesByIds(cachedTargetGroup), me, game, world, commands)) { return(new VehicleFormationResult(new ShrinkGroundVehicleFormation(Id, VehicleIds, CommandManager, VehicleRegistry))); } if (commands.Any(c => !c.IsFinished(world.TickIndex, VehicleRegistry))) { return(new VehicleFormationResult(this)); } var nextTarget = NextTarget(myArmy, world, me, game); var direction = myArmy.Center.To(nextTarget); myArmy .Select(Id) .MoveByVector(direction.Length() > 20 ? direction.Mul(0.1) : direction, game.TankSpeed * game.ForestTerrainSpeedFactor); #if DEBUG RewindClient.Instance.Line(myArmy.Center.X, myArmy.Center.Y, nextTarget.X, nextTarget.Y, Color.Fuchsia); #endif commands.Add(CommandManager.PeekLastCommand(Id)); return(new VehicleFormationResult(this)); }
public override VehicleFormationResult PerformAction(World world, Player me, Game game) { var army = new VehiclesGroup(Id, VehicleIds, VehicleRegistry, CommandManager); if (!binded) { Bind(army); return(new VehicleFormationResult(this)); } commands.RemoveAll(c => c.IsStarted() && c.IsFinished(world.TickIndex, VehicleRegistry)); if (FormationHelper.IsNukeAlert(world.GetOpponentPlayer()) && world.TickIndex - nukePreventionTick > game.BaseTacticalNuclearStrikeCooldown / 2) { commands.Clear(); CommandManager.ClearCommandsQueue(Id); this.PreventNuke(army, world, game, commands); nukePreventionTick = world.TickIndex; return(new VehicleFormationResult(this)); } if (commands.Any()) { return(new VehicleFormationResult(this)); } var closestUncapturedFacility = VehicleRegistry.GetUncapturedFacilities(world, me, Id) .Where(f => f.Type == FacilityType.VehicleFactory) .OrderBy(f => army.Center.GetDistanceTo(f.ToPoint(game))) .FirstOrDefault(); var myGroudForcesCenter = VehicleRegistry.GetVehiclesByIds( VehicleRegistry.GetVehicleIdsByFormationId(MagicConstants.GroundFormationGroupId)) .ToList() .GetCenterPoint(); var enemyVehicles = VehicleRegistry.EnemyVehicles(me); var enemies = Dbscan.GetEnemiesClusters(enemyVehicles, DbscanRadius, DbscanMinimumClusterSize, world.TickIndex); var nearestEnemy = enemies.OrderBy(c => c.GetCenterPoint().GetDistanceTo(army.Center)).FirstOrDefault(); if (nearestEnemy != null && this.TryNuke(army, VehicleRegistry.GetVehiclesByIds(army.VehicleIds), nearestEnemy, me, game, world, commands)) { return(new VehicleFormationResult(new ShrinkAirVehicleFormation(Id, VehicleIds, CommandManager, VehicleRegistry))); } if (nearestEnemy != null && army.Center.GetDistanceTo(nearestEnemy.GetCenterPoint()) < game.TankVisionRange * 0.8 && nearestEnemy.Count > 1.2 * VehicleIds.Count) { army .Select(Id) .MoveByVector(nearestEnemy.GetCenterPoint().To(army.Center), game.TankSpeed); commands.Add(CommandManager.PeekLastCommand(Id)); return(new VehicleFormationResult(this)); } var nextTarget = closestUncapturedFacility?.ToPoint(game) ?? myGroudForcesCenter; if (army.Center.GetDistanceTo(myGroudForcesCenter) < MagicConstants.NewVehiclesJoinRadius) { army .Select(Id) .Assign(MagicConstants.GroundFormationGroupId); return(new VehicleFormationResult()); } var direction = army.Center.To(nextTarget); army .Select(Id) .MoveByVector(direction.Length() > 20 ? direction.Mul(0.1) : direction, game.TankSpeed); #if DEBUG RewindClient.Instance.Line(army.Center.X, army.Center.Y, nextTarget.X, nextTarget.Y, Color.Fuchsia); #endif commands.Add(CommandManager.PeekLastCommand(Id)); return(new VehicleFormationResult(this)); }
public override VehicleFormationResult PerformAction(World world, Player me, Game game) { #if DEBUG if (cachedTargetGroup != null) { foreach (var cachedTarget in VehicleRegistry.GetVehiclesByIds(cachedTargetGroup)) { RewindClient.Instance.Rectangle(cachedTarget.X - game.VehicleRadius, cachedTarget.Y - game.VehicleRadius, cachedTarget.X + game.VehicleRadius, cachedTarget.Y + game.VehicleRadius, Color.Pink); } } #endif var myArmy = new VehiclesGroup(Id, VehicleIds, VehicleRegistry, CommandManager); commands.RemoveAll(c => c.IsStarted() && c.IsFinished(world.TickIndex, VehicleRegistry)); if (commands.Any()) { return(new VehicleFormationResult(this)); } if (FormationHelper.IsNukeAlert(world.GetOpponentPlayer()) && world.TickIndex - nukePreventionTick > game.BaseTacticalNuclearStrikeCooldown / 2) { commands.Clear(); CommandManager.ClearCommandsQueue(Id); this.PreventNuke(myArmy, world, game, commands); nukePreventionTick = world.TickIndex; return(new VehicleFormationResult(this)); } var myVehicles = VehicleRegistry.GetVehiclesByIds(VehicleIds).ToList(); if (cachedTargetGroup != null && this.TryNuke(myArmy, myVehicles, VehicleRegistry.GetVehiclesByIds(cachedTargetGroup), me, game, world, commands)) { return(new VehicleFormationResult(new ShrinkAirVehicleFormation(Id, VehicleIds, CommandManager, VehicleRegistry))); } if (commands.Any(c => !c.IsFinished(world.TickIndex, VehicleRegistry))) { return(new VehicleFormationResult(this)); } Vector2D direction; var groundFormationVehicles = VehicleRegistry.GetVehiclesByIds( VehicleRegistry.GetVehicleIdsByFormationId(MagicConstants.GroundFormationGroupId)) .ToList(); var myGroudForcesCenter = groundFormationVehicles.Any() ? groundFormationVehicles.GetCenterPoint() : new Point2D(0, 0); if (TimeToRetreat(myVehicles)) { #if DEBUG RewindClient.Instance.Message("=== TIME TO RETREAT! ==="); #endif var ifvs = groundFormationVehicles.Where(v => v.Type == VehicleType.Ifv).ToList(); if (ifvs.Any()) { var ifvsCenter = ifvs.GetCenterPoint(); if (myArmy.Center.GetDistanceTo(ifvsCenter) < 10) { return(new VehicleFormationResult(this)); } direction = myArmy.Center.To(ifvsCenter); } else { if (myArmy.Center.GetDistanceTo(myGroudForcesCenter) < 10) { myArmy .Select(MagicConstants.AirFormationGroupId) .Assign(MagicConstants.GroundFormationGroupId); return(new VehicleFormationResult()); } direction = myArmy.Center.To(myGroudForcesCenter); } } else { var nextTargetGroup = NextTargetGroup(myArmy, world, me); var closest = VehicleRegistry.GetVehiclesByIds(nextTargetGroup).GetClosest(myGroudForcesCenter); var nextTargetClosestPoint = nextTargetGroup.Any() ? (closest?.ToPoint() ?? new Point2D(0, 0)) : VehicleRegistry .GetUncapturedFacilities(world, me, Id) .Select(f => f.ToPoint(game)) .FirstOrDefault(); var minimumDistanceToNextTargetCenter = myVehicles.GetMinimumDistanceTo(nextTargetClosestPoint); var minimumDistanceToNextTargetCenterCondition = minimumDistanceToNextTargetCenter > 0.8 * game.HelicopterVisionRange; var nextTargetGroupCount = nextTargetGroup.Count; var myVehiclesCount = VehicleIds.Count; var countCondition = nextTargetGroupCount < myVehiclesCount / 2 - 1; var myForcesCenterToNextTargetCenterDistance = myGroudForcesCenter.GetDistanceTo(nextTargetClosestPoint); var myGroundForcesToMyArmyCenterCondition = myGroudForcesCenter.GetDistanceTo(myArmy.Center); var myGroundForcesCondition = myForcesCenterToNextTargetCenterDistance < myGroundForcesToMyArmyCenterCondition; #if DEBUG RewindClient.Instance.Message($"=== minimumDistanceToNextTargetCenter = {minimumDistanceToNextTargetCenter} ==="); RewindClient.Instance.Message($"=== minimumDistanceToNextTargetCenterCondition = {minimumDistanceToNextTargetCenterCondition} ==="); RewindClient.Instance.Message($"=== nextTargetGroupCount = {nextTargetGroupCount} ==="); RewindClient.Instance.Message($"=== myVehiclesCount = {myVehiclesCount} ==="); RewindClient.Instance.Message($"=== countCondition = {countCondition} ==="); RewindClient.Instance.Message($"=== myForcesCenterToNextTargetCenterDistance = {myForcesCenterToNextTargetCenterDistance} ==="); RewindClient.Instance.Message($"=== myGroundForcesToMyArmyCenterCondition = {myGroundForcesToMyArmyCenterCondition} ==="); RewindClient.Instance.Message($"=== myGroundForcesCondition = {myGroundForcesCondition} ==="); #endif direction = minimumDistanceToNextTargetCenterCondition || countCondition || myGroundForcesCondition ? myArmy.Center.To(nextTargetClosestPoint) : nextTargetClosestPoint.To(myArmy.Center); } myArmy .Select(Id) .MoveByVector(direction.Length() > 5 ? direction.Mul(0.1) : direction, game.HelicopterSpeed * game.RainWeatherSpeedFactor); #if DEBUG RewindClient.Instance.Line(myArmy.Center.X, myArmy.Center.Y, myArmy.Center.X + direction.X, myArmy.Center.Y + direction.Y, Color.Fuchsia); #endif commands.Add(CommandManager.PeekLastCommand(Id)); return(new VehicleFormationResult(this)); }