public void Tick(Squad owner) { if (!owner.IsValid) { return; } if (!owner.TargetIsValid) { var targeter = owner.units.Random(owner.random); var closestEnemy = owner.bot.FindClosestEnemy(targeter, targeter.CenterPosition); if (closestEnemy != null) { owner.Target = closestEnemy; } else { owner.fsm.ChangeState(owner, new GroundUnitsFleeState(), true); return; } } Actor leader = owner.units.ClosestTo(owner.Target.CenterPosition); if (leader == null) { return; } var ownUnits = owner.world.FindActorsInCircle(leader.CenterPosition, WRange.FromCells(owner.units.Count) / 3) .Where(a => a.Owner == owner.units.FirstOrDefault().Owner&& owner.units.Contains(a)).ToList(); if (ownUnits.Count < owner.units.Count) { owner.world.IssueOrder(new Order("Stop", leader, false)); foreach (var unit in owner.units.Where(a => !ownUnits.Contains(a))) { owner.world.IssueOrder(new Order("AttackMove", unit, false) { TargetLocation = leader.CenterPosition.ToCPos() }); } } else { var enemys = owner.world.FindActorsInCircle(leader.CenterPosition, WRange.FromCells(12)) .Where(a1 => !a1.Destroyed && !a1.IsDead()).ToList(); var enemynearby = enemys.Where(a1 => a1.HasTrait <ITargetable>() && leader.Owner.Stances[a1.Owner] == Stance.Enemy).ToList(); if (enemynearby.Any()) { owner.Target = enemynearby.ClosestTo(leader.CenterPosition); owner.fsm.ChangeState(owner, new GroundUnitsAttackState(), true); return; } else { foreach (var a in owner.units) { owner.world.IssueOrder(new Order("AttackMove", a, false) { TargetLocation = owner.Target.Location }); } } } if (ShouldFlee(owner)) { owner.fsm.ChangeState(owner, new GroundUnitsFleeState(), true); return; } }
public void Tick(Squad owner) { if (!owner.IsValid) { return; } if (!owner.TargetIsValid) { var targeter = owner.units.First(); var t = owner.bot.FindClosestEnemy(targeter, targeter.CenterPosition); if (t == null) { return; } owner.Target = t; } var enemyUnits = owner.world.FindActorsInCircle(owner.Target.CenterPosition, WRange.FromCells(10)) .Where(unit => owner.bot.p.Stances[unit.Owner] == Stance.Enemy).ToList(); if (enemyUnits.Any()) { if (owner.attackOrFleeFuzzy.CanAttack(owner.units, enemyUnits)) { foreach (var u in owner.units) { owner.world.IssueOrder(new Order("AttackMove", u, false) { TargetLocation = owner.Target.CenterPosition.ToCPos() }); } // We have gathered sufficient units. Attack the nearest enemy unit. owner.fsm.ChangeState(owner, new GroundUnitsAttackMoveState(), true); return; } else { owner.fsm.ChangeState(owner, new GroundUnitsFleeState(), true); } } }