public void ExecuteAbility(IGameUnit user, IAbility ability, MapPoint targetPoint) { var targetPoints = ability.AreaPoints.Select(x => x.ApplyOffset(targetPoint.X, targetPoint.Y)); var foundTargets = _gameMap.FindAllMapObjectsInBounds(out var targets, targetPoints); var validTargets = AbilityTargetCalculator.FilterTargets(user, ability, targets); // Get a queue of abilities and their execution _executionQueue = CreateAbiltyQueue(user, ability, validTargets, targetPoint, _gameMap); // Now execute each entry in our queue while (_executionQueue.Any()) { var executionParams = _executionQueue.Dequeue(); var executionResults = new List <AbilityResultContainer>(); // If the params doesn't have a target assigned we'll create dupes and populate the targets if (executionParams.Target == null) { var newParams = executionParams.AllTargets.Select(x => new AbilityExecuteParameters(executionParams.UnitExecuting, executionParams.AbilityExecuting, x, executionParams.AllTargets, executionParams.TargetPoint, executionParams.GameMap)); var newParamsResults = newParams.SelectMany(x => ExecuteAbilityParameters(x)).ToList(); executionResults.AddRange(newParamsResults); } // Otherwise we'll just execute the ability else { var paramsResults = ExecuteAbilityParameters(executionParams); executionResults.AddRange(paramsResults); } // DO SOME ANIMATION HERE? // ALSO IF A COUNTER HAS A COST IT ISN"T DEDUCTED EVER } // Now that we executed the ability we need to consume the cost of the ability ConsumeAbilityForUnit(user, ability); // Check for defeated units validTargets.OfType <IGameUnit>().Where(x => x.IsDead()).ForEach(x => RemoveUnit(x)); if (user.IsDead()) { RemoveUnit(user); } }