private static bool AttackOrRunAway(MyFormation formation, EnemyFormation enemy) { foreach (var enemyFormation in Global.EnemyFormations) { if (enemyFormation.Rect.IsInside(enemy.Center)) { var dangerForEnemy = formation.DangerFor(enemy); var dangerForMe = enemy.DangerFor(formation); if (dangerForMe < dangerForEnemy * 1.5) { MakeAttackOrder(formation, enemy, true); return(true); } if (MoveToAlly(formation, Global.MyArrvs)) { return(true); } if (MoveToAlly(formation, Global.MyIfvs)) { return(true); } if (MoveToAlly(formation, Global.MyTanks)) { return(true); } } } return(false); }
public static EnemyFormation CreateEnemyFormation(IEnumerable <VehicleWrapper> vehicles) { var formation = new EnemyFormation(); foreach (var v in vehicles) { formation.Vehicles.Add(v.Id, v); } formation.Update(); Global.EnemyFormations.Add(formation); return(formation); }
public static bool MakeAttackOrder(MyFormation me, EnemyFormation enemy, bool breakCurrentAction) { if (!(me.Alive && (!me.Busy || breakCurrentAction))) { return(false); } var pointToMove = enemy == null ? Point.EndOfWorld / 2 : enemy.MassCenter; var myMassCenter = me.MassCenter; var distance = pointToMove.Distance(myMassCenter); if (enemy != null) { var enemySpeedScalar = enemy.AvgSpeed.Length(); var mySpeedScalar = me.MaxSpeed; var myDirection = (pointToMove - myMassCenter).Normalized(); var enemyDirection = enemy.AvgSpeed.Normalized(); var resultDirection = (myDirection + enemySpeedScalar / mySpeedScalar * enemyDirection).Normalized(); pointToMove = myMassCenter + distance * resultDirection; } if (distance > 100) { pointToMove = (me.Center + pointToMove) / 2; } if (me.ExecutingAction != null && me.ExecutingAction.ActionType == ActionType.Move) { var oldVector = new Point(me.ExecutingAction.GetX(), me.ExecutingAction.GetY()); var newVector = pointToMove - me.Center; var scalar = oldVector.Normalized() * newVector.Normalized(); if (scalar > 0.95) // около 18 градусов { return(false); } } var actionMove = me.MoveCenterTo(pointToMove); if (me.Density < 0.01 && distance > 200) { var actionScale = me.ScaleCenter(0.1); AbortAndAddToExecutingSequence(me, actionScale, actionMove); } else { AbortAndAddToExecutingSequence(me, actionMove); } foreach (var facility in Global.World.Facilities) { if (facility.SelectedAsTargetForGroup == me.GroupIndex) { facility.SelectedAsTargetForGroup = null; } } return(true); }
public static bool Attack(MyFormation formation) { var enemyFightersCount = Global.EnemyFighters.Count(); if (formation == Global.MyHelicopters && enemyFightersCount > 30) { var enemyFighters = FormationFactory.CreateEnemyFormation(Global.EnemyFighters); if ((enemyFighters.Rect.RightBottom - enemyFighters.Rect.LeftTop).Length() < 300) { MyFormation foundAllyGround = null; if (Global.MyIfvs.Alive && Global.MyIfvs.Vehicles.Count > 30) { foundAllyGround = Global.MyIfvs; } else if (Global.MyArrvs.Alive && Global.MyArrvs.Vehicles.Count > 30) { foundAllyGround = Global.MyArrvs; } if (foundAllyGround != null) { var actionMove = formation.MoveCenterTo(Global.MyIfvs.Center); AbortAndAddToExecutingSequence(formation, actionMove); return(true); } } } if (formation == Global.MyFighters) { if (enemyFightersCount > 10) { var enemy = FormationFactory.CreateEnemyFormation(Global.EnemyFighters); var enemyLength = (enemy.Rect.RightBottom - enemy.Rect.LeftTop).Length(); if (enemyLength < 200) { MakeAttackOrder(formation, enemy, true); return(true); } } if (Global.EnemyHelicopters.Count() > 10) { var enemy = FormationFactory.CreateEnemyFormation(Global.EnemyHelicopters); var enemyLength = (enemy.Rect.RightBottom - enemy.Rect.LeftTop).Length(); if (enemyLength < 300) { MakeAttackOrder(formation, enemy, true); return(true); } } // if (Global.MyArrvs.Alive && Global.MyArrvs.Vehicles.Count > 30) // { // var actionMove = formation.MoveCenterTo(Global.MyArrvs.Center); // AbortAndAddToExecutingSequence(formation, actionMove); // return true; // } } var oneShotDanger = new Dictionary <EnemyFormation, double>(); foreach (var enemy in Global.EnemyFormations) { var dangerForEnemy = formation.DangerFor(enemy); var dangerForMe = enemy.DangerFor(formation); oneShotDanger.Add(enemy, dangerForEnemy - dangerForMe); } // todo: давать правильную команду // выбирать также по расстоянию EnemyFormation target = null; var targetPair = oneShotDanger.OrderByDescending(kv => kv.Value).First(); if (targetPair.Value > 0) { target = targetPair.Key; } if (target != null) { var targetFacility = Global.World.Facilities .Where(f => f.SelectedAsTargetForGroup == formation.GroupIndex).ToList(); if (targetFacility.Any()) { foreach (var facility in targetFacility) { facility.SelectedAsTargetForGroup = null; } OccupyFacilities(formation); return(true); } MakeAttackOrder(formation, target, false); return(true); } return(false); }
public static bool Attack(MyFormation formation) { if (AirAttack(formation)) { return(true); } var targetFacility = formation.FacilityAsTarget == null ? null : Global.World.Facilities.FirstOrDefault(f => f.Id == formation.FacilityAsTarget.Value); if (formation.FacilityAsTarget == null) { OccupyFacilities(formation, true); targetFacility = formation.FacilityAsTarget == null ? null : Global.World.Facilities.FirstOrDefault(f => f.Id == formation.FacilityAsTarget.Value); } if (targetFacility != null) { if (targetFacility.IsMine) { targetFacility = null; formation.FacilityAsTarget = null; } } double maxAttackDistance = (targetFacility == null) ? Global.World.Width / 2 : Math.Min(100, formation.Center.Distance(targetFacility.Center) / 2); var myDurability = Global.MyVehicles.Values.Sum(v => v.Durability); var enemyDurability = Global.EnemyVehicles.Values.Sum(v => v.Durability); var betterCoeff = Math.Max(1, myDurability / (enemyDurability + 1.0)); var oneShotDanger = new Dictionary <EnemyFormation, double>(); foreach (var enemy in Global.EnemyFormations) { var dangerForEnemy = formation.DangerFor(enemy); var dangerForMe = enemy.DangerFor(formation); if (enemy.Center.Distance(formation.Center) < maxAttackDistance) { oneShotDanger.Add(enemy, (betterCoeff) * dangerForEnemy - dangerForMe); } } EnemyFormation target = null; if (oneShotDanger.Count > 0) { var targetPair = oneShotDanger .OrderByDescending(kv => kv.Value) .FirstOrDefault(); if (targetPair.Value > 0) { target = targetPair.Key; } } if (target != null) { MakeAttackOrder(formation, target, false); return(true); } var runAwayDanger = new Dictionary <EnemyFormation, double>(); foreach (var enemy in Global.EnemyFormations) { var dangerForEnemy = formation.DangerFor(enemy); var dangerForMe = enemy.DangerFor(formation); if (enemy.Center.Distance(formation.Center) < 150) { runAwayDanger.Add(enemy, (dangerForEnemy - dangerForMe) / (formation.Count + 1.0)); } } if (runAwayDanger.Count > 0) { var targetPair = runAwayDanger .OrderBy(kv => kv.Value) .FirstOrDefault(); if (targetPair.Value < -10) { var runAwayFromThis = targetPair.Key; var direction = (formation.MassCenter - runAwayFromThis.MassCenter).Normalized(); formation.FacilityAsTarget = null; Global.ActionQueue.AbortOldActionsFor(formation); var actionMove = formation.ShiftTo(direction * 100); actionMove.Priority = ActionPriority.High; actionMove.StartCondition = () => true; actionMove.Interruptable = false; var sequence = new ActionSequence(actionMove); Global.ActionQueue.Add(sequence); } } if (targetFacility != null) { var actionMove = formation.MoveCenterTo(targetFacility.Center); var sequence = new ActionSequence(actionMove); Global.ActionQueue.Add(sequence); } return(false); }