예제 #1
0
        /// <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);
        }
예제 #2
0
        public bool LandOnBase()
        {
            GameManager.Instance.Log.LogDebug(
                string.Format("AircraftUnit->LandOnBase: Unit {0}.", ToString()));

            SetDirty(GameConstants.DirtyStatus.UnitChanged);
            if (LaunchedFromUnit == null || LaunchedFromUnit.Position == null ||
                LaunchedFromUnit.IsMarkedForDeletion || LaunchedFromUnit.HitPoints <= 0)
            {
                if (!_hasSentCarrierLostMessage)
                {
                    _hasSentCarrierLostMessage = true;
                    SetHomeToNewCarrier();
                }
                return(false);
            }
            double distanceM = MapHelper.CalculateDistanceM(this.Position.Coordinate, LaunchedFromUnit.Position.Coordinate);

            if (distanceM > GameConstants.DISTANCE_TO_TARGET_IS_HIT_M * 3.0)
            {
                GameManager.Instance.Log.LogDebug(
                    string.Format("LandOnBase: {0} is {1:F}m away from {2}, reattempting ReturnToBase.",
                                  Id, distanceM, LaunchedFromUnit));
                this.IsOrderedToReturnToBase = false;
                return(ReturnToBase());
            }
            if (LaunchedFromUnit.AircraftHangar == null)
            {
                OwnerPlayer.Send(new GameStateInfo(GameConstants.GameStateInfoType.AircraftLandingFailed, this.Id, LaunchedFromUnit.Id));
                GameManager.Instance.Log.LogError(
                    string.Format("Unit{0} cannot land on unit {1} since it has no AircraftHangar",
                                  ToShortString(), LaunchedFromUnit.ToShortString()));
                SetHomeToNewCarrier();
                return(false);
            }
            if (LaunchedFromUnit.AircraftHangar.ReadyInSec > GameConstants.DEFAULT_TIME_BETWEEN_TAKEOFFS_SEC * 2) //it is damaged
            {
                TimeSpan time = TimeSpan.FromSeconds(LaunchedFromUnit.AircraftHangar.ReadyInSec);
                OwnerPlayer.Send(new GameStateInfo(GameConstants.GameStateInfoType.AircraftLandingFailed, this.Id, LaunchedFromUnit.Id));
                SetHomeToNewCarrier();
                return(false);
            }
            double CrashChancePercent       = 0;
            int    EffectiveLandingSeaState = LaunchedFromUnit.GetEffectiveSeaState();

            if (EffectiveLandingSeaState > GameConstants.AIRCRAFT_LANDING_MAX_SEA_STATE)
            {
                OwnerPlayer.Send(new GameStateInfo(GameConstants.GameStateInfoType.AircraftLandingFailed, this.Id, LaunchedFromUnit.Id));

                GameManager.Instance.Log.LogDebug(string.Format(
                                                      "LandOnBase: Unit {0} could not land due to rough weather. Max sea state is {1},"
                                                      + "effective sea state is {2}",
                                                      ToShortString(), GameConstants.AIRCRAFT_LANDING_MAX_SEA_STATE,
                                                      EffectiveLandingSeaState));
                return(false);
            }
            else if (GetEffectiveSeaState() == GameConstants.AIRCRAFT_LANDING_MAX_SEA_STATE)
            {
                CrashChancePercent = 25.0;
            }
            if (CrashChancePercent > 0 && GameManager.Instance.ThrowDice(CrashChancePercent))
            {
                IsMarkedForDeletion = true;
                OwnerPlayer.Send(new GameStateInfo(GameConstants.GameStateInfoType.AircraftCrashedOnLandingRoughWeather, this.Id, LaunchedFromUnit.Id));
                GameManager.Instance.Log.LogDebug(string.Format(
                                                      "LandOnBase: {0} CRASHED due to rough weather. Effective sea state is {1}", ToShortString(),
                                                      EffectiveLandingSeaState));
                return(false);
            }

            if (LaunchedFromUnit.UnitClass.CarriedRunwayStyle < this.UnitClass.RequiredRunwayStyle)
            {
                OwnerPlayer.Send(new GameStateInfo(GameConstants.GameStateInfoType.AircraftLandingFailed, this.Id, LaunchedFromUnit.Id));
                GameManager.Instance.Log.LogError(string.Format(
                                                      "LandOnBase: {0} cannot land on {1}: Requires {2}.", ToShortString(),
                                                      LaunchedFromUnit.ToShortString(), this.UnitClass.RequiredRunwayStyle));
                SetHomeToNewCarrier();
                return(false);
            }
            if (OwnerPlayer != null && OwnerPlayer.TcpPlayerIndex > 0)
            {
                //GameManager.Instance.Log.LogDebug("LandOnBase: Sending GameStateInfo object");
                OwnerPlayer.Send(new GameStateInfo()
                {
                    Id          = this.Id,
                    InfoType    = GameConstants.GameStateInfoType.AircraftIsLanded,
                    SecondaryId = LaunchedFromUnit.Id,
                    UnitClassId = this.UnitClass.Id,
                    BearingDeg  = (double)this.Position.BearingDeg,
                });
            }
            _hasSentCarrierLostMessage = false;
            CarriedByUnit = LaunchedFromUnit;
            _hasCheckedForNearestCarrier   = false;
            _hasSentActiveDetectionMessage = false;
            MovementOrder = null;
            Orders.Clear();
            IsOrderedToReturnToBase = false;
            TargetDetectedUnit      = null;
            Position = null;

            LaunchedFromUnit.AircraftHangar.Aircraft.Add(this);
            try
            {
                UnitClassWeaponLoads load = UnitClass.WeaponLoads.Single <UnitClassWeaponLoads>(l => l.Name == this.CurrentWeaponLoadName);
                if (load != null)
                {
                    ReadyInSec = load.TimeToReloadHour * 60 * 60;
                }
                else
                {
                    ReadyInSec = LaunchedFromUnit.AircraftHangar.GetStatusChangeTimeSec(
                        GameConstants.AircraftDockingStatus.TankingAndRefitting,
                        GameConstants.AircraftDockingStatus.ReadyForTakeoff);
                }
            }
            catch (Exception)
            {   //default reload time
                ReadyInSec = LaunchedFromUnit.AircraftHangar.GetStatusChangeTimeSec(
                    GameConstants.AircraftDockingStatus.TankingAndRefitting,
                    GameConstants.AircraftDockingStatus.ReadyForTakeoff);
            }
            MissionType            = GameConstants.MissionType.Patrol;
            MissionTargetType      = GameConstants.MissionTargetType.Undefined;
            AssignedHighLevelOrder = null;
            LaunchedFromUnit.SetDirty(GameConstants.DirtyStatus.UnitChanged);
            var wpnLoad = GameManager.Instance.GameData.GetWeaponLoadByName(UnitClass.Id, CurrentWeaponLoadName);

            if (wpnLoad != null)
            {
                bool isEnoughAmmoToReload = CanChangeToWeaponLoad(wpnLoad, false);
                if (!isEnoughAmmoToReload)
                {
                    SetWeaponLoad(string.Empty); //default
                }
                foreach (var weapon in Weapons)
                {
                    weapon.ReadyInSec          = 0;
                    weapon.IsOperational       = true;
                    weapon.AmmunitionRemaining = weapon.MaxAmmunition;
                }
            }
            foreach (var sensor in Sensors)
            {
                sensor.ReadyInSec    = 0;
                sensor.IsOperational = true;
                sensor.IsDamaged     = false;
                if (sensor.SensorClass.MaxSpeedDeployedKph > 0 || sensor.SensorClass.MaxHeightDeployedM > 0)
                {
                    sensor.IsOperational = false; //if sensor has height/speed restrictions, set non-operational
                }
                //sensor.IsActive = false;

                if (sensor.SensorClass.IsPassiveActiveSensor)
                {
                    sensor.IsActive = false;
                }
            }
            FuelDistanceCoveredSinceRefuelM = 0;
            if (_refuelingFromAircraft != null)
            {
                _refuelingFromAircraft.RemoveFromFuelQueue(this);
            }
            SetDirty(GameConstants.DirtyStatus.UnitChanged);
            return(true);
        }