public void Interact(GridPosition gridPosition) { if (_selectedEntity == null) { return; } var clickedEntity = Entities.FirstOrDefault(entity => entity.Position == gridPosition); if (clickedEntity == null) { if (_selectedEntity.CanMove) { var obstacles = Entities .Where(entity => entity.IsObstacle(PlayerSide)) .Select(entity => entity.Position) .ToList(); var path = _astar.Calculate(_selectedEntity.Position, gridPosition, obstacles); if (path != null && path.Count <= _selectedEntity.MovementRange + 1) { BlockUI = true; StartCoroutine(Move(_selectedEntity, path)); } } } else { if (_selectedEntity.CanAttack) { var target = clickedEntity as LivingEntity; if (target != null && target.Side != PlayerSide) { var range = GridPosition.Distance(_selectedEntity.Position, target.Position); if (range <= _selectedEntity.Weapon.Range) { BlockUI = true; StartCoroutine(Attack(_selectedEntity, target)); } } } } }
public IEnumerator CalculateTurn(List <Entity> entities, Astar astar, Side side, float movementSpeed, float salvoFlightTime) { var ownEntities = entities.OfType <LivingEntity>().Where(entity => entity.Side == side).ToList(); var enemyShips = entities.OfType <LivingEntity>().Where(entity => entity.Side != side).ToList(); foreach (var own in ownEntities) { if (!own.CanAttack) { continue; } var blackList = new List <LivingEntity>(); bool selectNewEnemy; do { selectNewEnemy = false; var enemy = GetNearestEnemy(own, enemyShips.Except(blackList)); if (GridPosition.Distance(own.Position, enemy.Position) <= own.Weapon.Range) { yield return(own.Attack(enemy, salvoFlightTime)); } else { var obstacles = entities .Except(ownEntities) .Where(entity => entity != enemy) .Select(entity => entity.Position) .ToList(); var destinations = GetDestinations(enemy.Position, own.Weapon.Range) .Except(entities.Select(entity => entity.Position)) .Distinct(); IList <GridPosition> shortestPath = null; foreach (var destination in destinations) { var path = astar.Calculate(own.Position, destination, obstacles); if (shortestPath == null || path.Count < shortestPath.Count) { shortestPath = path; } } if (shortestPath != null) { var path = shortestPath.Count > own.MovementRange + 2 ? shortestPath.Take(own.MovementRange + 1).ToList() : shortestPath; yield return(own.Move(path, movementSpeed)); if (GridPosition.Distance(own.Position, enemy.Position) <= own.Weapon.Range) { yield return(own.Attack(enemy, salvoFlightTime)); } } else { blackList.Add(enemy); selectNewEnemy = true; } } } while (selectNewEnemy && blackList.Count < enemyShips.Count); } }