public void RemoveFromFuelQueue(AircraftUnit unit) { if (_aircraftsToRefuel != null && unit._refuelingFromAircraft == this) { _aircraftsToRefuel.RemoveAll(pair => pair.Key.Id == unit.Id); unit._refuelingFromAircraft = null; } }
/// <summary> /// Refuel the aircraft unit in air. /// </summary> /// <param name="refuelingAircraft">The aircraft unit to refuel from.</param> /// <returns></returns> public bool RefuelInAir(AircraftUnit refuelingAircraft) { // Check if refueling aircraft is within distance var distanceToTargetM = MapHelper.CalculateDistanceM(Position.Coordinate, refuelingAircraft.Position.Coordinate); if (distanceToTargetM < GameConstants.DISTANCE_TO_TARGET_IS_HIT_M) { // Make sure we're in the queue if (!refuelingAircraft.IsInFuelQueue(this) && !refuelingAircraft.AddToFuelQueue(this, FuelDistanceCoveredSinceRefuelM)) { return(false); } return(refuelingAircraft.GiveFuel(this)); } // Take bingo fuel factor into account distanceToTargetM *= GameConstants.BINGO_FUEL_FACTOR; if (distanceToTargetM < FuelDistanceRemainingM) { // Check if refueling aircraft has enough fuel to give us. Make sure to remove from queue before adding refuelingAircraft.RemoveFromFuelQueue(this); if (refuelingAircraft.AddToFuelQueue(this, FuelDistanceCoveredSinceRefuelM + distanceToTargetM)) { MissionType = GameConstants.MissionType.Ferry; MissionTargetType = GameConstants.MissionTargetType.Undefined; TargetDetectedUnit = null; IsOrderedToReturnToBase = true; ActualSpeedKph = GetSpeedInKphFromSpeedType(GameConstants.UnitSpeedType.Cruise); SetActualSpeed(ActualSpeedKph); //force afterburners off immediately UserDefinedSpeed = GameConstants.UnitSpeedType.Cruise; SetDirty(GameConstants.DirtyStatus.UnitChanged); // Change speed on refueling aircraft as well refuelingAircraft.ActualSpeedKph = refuelingAircraft.GetSpeedInKphFromSpeedType(GameConstants.UnitSpeedType.Slow); refuelingAircraft.SetActualSpeed(refuelingAircraft.ActualSpeedKph); refuelingAircraft.UserDefinedSpeed = GameConstants.UnitSpeedType.Slow; refuelingAircraft.SetDirty(GameConstants.DirtyStatus.UnitChanged); // Create waypoint to the refueling aircraft and add refuel order if (MovementOrder is MovementFormationOrder) { MovementOrder = new MovementOrder(); } var wp = new Waypoint(refuelingAircraft); wp.DesiredDistanceToTargetM = GameConstants.DISTANCE_TO_TARGET_IS_HIT_M; // TODO: set proper distance wp.IsNotRecurring = true; wp.Orders.Add(new BaseOrder() { OrderType = GameConstants.OrderType.RefuelInAir, SecondId = refuelingAircraft.Id }); MovementOrder.AddWaypointToTop(wp); ReCalculateEta(); return(true); } } return(false); }
/// <summary> /// Transfer fuel to another aircraft unit. /// </summary> /// <param name="unit">The aircraft unit to transfer fuel to.</param> /// <param name="fuelDistanceM">The amount of fuel to transfer.</param> /// <returns>True if any fuel was transferred.</returns> private bool GiveFuel(AircraftUnit unit) { // Make sure unit is in queue if (!IsInFuelQueue(unit)) { return(false); } // Get amount to give var fuelDistanceM = _aircraftsToRefuel.Where(pair => pair.Key != null && pair.Key.Id == unit.Id).Sum(pair => pair.Value); // Make sure we don't give too much fuel fuelDistanceM = fuelDistanceM.Clamp(0.0, GetMaxFuelDistanceToGiveM()); if (fuelDistanceM > unit.FuelDistanceCoveredSinceRefuelM) { fuelDistanceM = unit.FuelDistanceCoveredSinceRefuelM; } // Give fuel to unit unit.IsOrderedToReturnToBase = false; unit.FuelDistanceCoveredSinceRefuelM -= fuelDistanceM; // Remove fuel from ourself FuelDistanceCoveredSinceRefuelM += fuelDistanceM; // Remove unit from fueling list RemoveFromFuelQueue(unit); // Also remove units that's marked for deletion _aircraftsToRefuel.RemoveAll( pair => pair.Key == null || pair.Key.IsMarkedForDeletion); // Go back to cruise speed if no more units to refuel // TODO: go back to the user defined speed instead if (!_aircraftsToRefuel.Any()) { ActualSpeedKph = GetSpeedInKphFromSpeedType(GameConstants.UnitSpeedType.Cruise); SetActualSpeed(ActualSpeedKph); UserDefinedSpeed = GameConstants.UnitSpeedType.Cruise; } SetDirty(GameConstants.DirtyStatus.UnitChanged); unit.SetDirty(GameConstants.DirtyStatus.UnitChanged); // The unit should check for bingo fuel after refueling as it might be too far away from base. //CheckForBingoFuel(); //removed to avoid stack exhausted //unit.CheckForBingoFuel(); return(fuelDistanceM > 0.0); }
/// <summary> /// Add an aircraft unit to the fuel queue. Also make sure to remove any old aircrafts that's either deleted or has landed. /// Aircraft is only added to the queue if we currently have enough fuel to give. /// </summary> /// <param name="unit"></param> /// <param name="fuelDistanceM"></param> /// <returns></returns> public bool AddToFuelQueue(AircraftUnit unit, double fuelDistanceM) { // Remove units that's marked for deletion if (_aircraftsToRefuel != null) { _aircraftsToRefuel.RemoveAll(pair => pair.Key == null || pair.Key.IsMarkedForDeletion); } if (GetMaxFuelDistanceToGiveM() >= fuelDistanceM) { if (_aircraftsToRefuel == null) { _aircraftsToRefuel = new List <KeyValuePair <AircraftUnit, double> >(); } _aircraftsToRefuel.Add(new KeyValuePair <AircraftUnit, double>(unit, fuelDistanceM)); unit._refuelingFromAircraft = this; return(true); } return(false); }
public bool IsInFuelQueue(AircraftUnit unit) { return(_aircraftsToRefuel != null && _aircraftsToRefuel.Any(pair => pair.Key.Id == unit.Id)); }