Beispiel #1
0
    protected void UpdateRowsForCatClass(CategoryClass.CatClassID idCatClass)
    {
        bool fIsGlider = idCatClass == CategoryClass.CatClassID.Glider;

        divTMG.Visible       = fIsGlider;
        divTailwheel.Visible = CategoryClass.IsAirplane(idCatClass) && !CategoryClass.IsSeaClass(idCatClass);
        divMultiHeli.Visible = (idCatClass == CategoryClass.CatClassID.Helicopter);

        bool hasEngine = CategoryClass.HasEngine(idCatClass);

        rowEngineType.Visible    = hasEngine;
        pnlHighPerfBlock.Visible = ckConstantProp.Enabled = ckComplex.Enabled = hasEngine;

        divComplex.Style["display"] = hasEngine || fIsGlider ? "inline-block" : "none";
        if (!hasEngine)
        {
            ckComplex.Checked            = ckConstantProp.Checked = ckCowlFlaps.Checked = ckRetract.Checked = false;
            rblTurbineType.SelectedIndex = 0;
        }

        bool fIsLegacyEligible = (idCatClass == CategoryClass.CatClassID.AMEL || idCatClass == CategoryClass.CatClassID.AMES || idCatClass == CategoryClass.CatClassID.Helicopter);

        pnlLegacyHighPerf.Style["display"] = fIsLegacyEligible ? "inline" : "none";
        if (ckLegacyHighPerf.Checked && !fIsLegacyEligible)
        {
            HighPerfType = MakeModel.HighPerfType.NotHighPerf;
        }
    }
Beispiel #2
0
        public override void ExamineFlight(ExaminerFlightRow cfr)
        {
            bool fIsAirplane = CategoryClass.IsAirplane(cfr.idCatClassOverride);
            bool fIsIFRSim   = (fIsAirplane && cfr.fIsFTD);

            if (fIsAirplane || cfr.fIsRealAircraft)
            {
                miMinInstrumentTime.AddTrainingEvent(cfr.IMC + cfr.IMCSim, ATPMaxIFRSimulator, fIsIFRSim);
            }

            if (fIsAirplane && cfr.idCatClassOverride == requiredCatClassID)
            {
                bool fIsFullSim = !cfr.fIsRealAircraft && cfr.fIsCertifiedLanding;
                if (fIsAirplane && (cfr.fIsRealAircraft || fIsFullSim))
                {
                    miMinTimeInClass.AddTrainingEvent(cfr.Total, ATPMinTimeInClassFullSimulator, fIsFullSim);
                }
            }

            // Above are the only things to which we will alow training devices.
            if (!cfr.fIsRealAircraft)
            {
                return;
            }

            miTotal.AddEvent(Math.Max(CanCreditSICAndFlightEngineer ? cfr.SIC : 0, cfr.Total));
            miMinXCTime.AddEvent(cfr.XC);
            miMinNightTime.AddEvent(cfr.Night);

            if (CanCreditSICAndFlightEngineer)
            {
                decimal flightEngineerTime = 0.0M;
                cfr.ForEachEvent((pe) => { if (pe.PropTypeID == (int)CustomPropertyType.KnownProperties.IDPropFlightEngineerTime)
                                           {
                                               flightEngineerTime += pe.DecValue;
                                           }
                                 });

                if (flightEngineerTime > 0)
                {
                    miTotal.AddTrainingEvent(flightEngineerTime / 3.0M, ATPMaxFlightEngineer, true);
                }
            }

            // Remainder must be done in a real aircraft and it must be in an airplane.
            // Not clear if the night takeoffs/landings need to be in a real aircraft / airplane, but I'll require it to be safe.
            if (fIsAirplane)
            {
                miMinPIC.AddEvent(cfr.PIC);
                miMinPICXC.AddEvent(Math.Min(cfr.PIC, cfr.XC));
                miMinPICNight.AddEvent(Math.Min(cfr.PIC, cfr.Night));
                cfr.ForEachEvent((pe) => { if (pe.PropertyType.IsNightTakeOff)
                                           {
                                               miNightTO.AddEvent(pe.IntValue);
                                           }
                                 });
                miNightLanding.AddEvent(cfr.cFullStopNightLandings);
            }
        }
Beispiel #3
0
 protected override bool IsQualifyingFlight(ExaminerFlightRow cfr)
 {
     if (cfr == null)
     {
         throw new ArgumentNullException(nameof(cfr));
     }
     return(cfr.fIsRealAircraft && (cfr.fMotorGlider || CategoryClass.IsAirplane(cfr.idCatClassOverride)));
 }
Beispiel #4
0
        private void CheckAirportIssues(LogbookEntryBase le)
        {
            IEnumerable <string> rgCodes = airport.SplitCodes(le.Route);

            foreach (string szCode in rgCodes)
            {
                if (szCode.StartsWith(airport.ForceNavaidPrefix, StringComparison.CurrentCultureIgnoreCase))
                {
                    continue;
                }

                if (szCode.CompareCurrentCultureIgnoreCase("LOCAL") == 0 || szCode.CompareCurrentCultureIgnoreCase("LCL") == 0)
                {
                    AddIssue(LintOptions.AirportIssues, Resources.FlightLint.warningAirportLocal);
                    continue;
                }

                airport ap = alSubset.GetAirportByCode(szCode);

                if (ap == null)
                {
                    AddIssue(LintOptions.AirportIssues, String.Format(CultureInfo.CurrentCulture, Resources.FlightLint.warningAirportNotFound, szCode));
                }
                else
                {
                    AddConditionalIssue((currentCatClassID == CategoryClass.CatClassID.AMEL || currentCatClassID == CategoryClass.CatClassID.ASEL) && ap.IsSeaport, LintOptions.AirportIssues, String.Format(CultureInfo.CurrentCulture, Resources.FlightLint.warningAirportLandPlaneAtSeaport, szCode));
                    AddConditionalIssue(CategoryClass.IsAirplane(currentCatClassID) && ap.FacilityTypeCode == "H", LintOptions.AirportIssues, String.Format(CultureInfo.CurrentCulture, Resources.FlightLint.warningAirportAirplaneAtHeliport, szCode));
                }
            }

            // Sanity check for speed
            if (le.TotalFlightTime > 0)
            {
                double dist  = alSubset.DistanceForRoute();
                double speed = dist / (double)le.TotalFlightTime;

                AddConditionalIssue(speed > (currentModel.EngineType == MakeModel.TurbineLevel.Piston ? 500 : 1000), LintOptions.AirportIssues, String.Format(CultureInfo.CurrentCulture, Resources.FlightLint.warningAirportUnlikelyImpliedSpeed, speed));
            }

            // Look for missing night takeoffs or landings
            if (rgCodes.Any())
            {
                airport apDep = alSubset.GetAirportByCode(rgCodes.ElementAt(0));
                airport apArr = alSubset.GetAirportByCode(rgCodes.ElementAt(rgCodes.Count() - 1));
                if (apDep != null)
                {
                    AddConditionalIssue(le.FlightStart.HasValue() && !le.CustomProperties.PropertyExistsWithID(CustomPropertyType.KnownProperties.IDPropNightTakeoff) &&
                                        new SolarTools.SunriseSunsetTimes(le.FlightStart, apDep.LatLong.Latitude, apDep.LatLong.Longitude).IsFAANight, LintOptions.AirportIssues, String.Format(CultureInfo.CurrentCulture, Resources.FlightLint.warningAirportMissingNightTakeoff, apDep.Code, le.FlightStart.UTCFormattedStringOrEmpty(false)));
                }
                if (apArr != null)
                {
                    AddConditionalIssue(le.FlightEnd.HasValue() && le.NightLandings == 0 &&
                                        new SolarTools.SunriseSunsetTimes(le.FlightEnd, apArr.LatLong.Latitude, apArr.LatLong.Longitude).IsFAANight, LintOptions.AirportIssues, String.Format(CultureInfo.CurrentCulture, Resources.FlightLint.warningAirportMissingNightLanding, apArr.Code, le.FlightEnd.UTCFormattedStringOrEmpty(false)));
                }
            }
        }
Beispiel #5
0
 /// <summary>
 /// Returns the LAPL license that corresponds to the category/class in the row; can be used as a key in computing currency
 /// </summary>
 /// <param name="cfr">The flight row</param>
 /// <returns>A string suitable for use as a dictionary key, else empty</returns>
 public static string KeyForLAPL(ExaminerFlightRow cfr)
 {
     if (cfr == null)
     {
         throw new ArgumentNullException(nameof(cfr));
     }
     if (cfr.fIsRealAircraft)
     {
         if (cfr.fMotorGlider || CategoryClass.IsAirplane(cfr.idCatClassOverride))
         {
             return(Resources.Currency.LAPLA);
         }
         if (cfr.idCatClassOverride == CategoryClass.CatClassID.Helicopter)
         {
             return(Resources.Currency.LAPLH);
         }
     }
     return(string.Empty);
 }
        public override void ExamineFlight(ExaminerFlightRow cfr)
        {
            if (cfr == null)
            {
                throw new ArgumentNullException(nameof(cfr));
            }

            // Only ever applies to airplanes
            if (!CategoryClass.IsAirplane(cfr.idCatClassOverride))
            {
                return;
            }

            cfr.FlightProps.ForEachEvent((pfe) =>
            {
                if (pfe.PropTypeID == (int)CustomPropertyType.KnownProperties.IDProp125291IPC)
                {
                    AddRecentFlightEvents(cfr.dtFlight, 1);
                }
            });
        }
Beispiel #7
0
 /// <summary>
 /// Instantiates an LAPL Currency appropriate for the flight row.  Can be null if we don't support LAPL currency for this aircraft.
 /// Useful to call KeyForLAPL first since it is a lightweight way (no object instantiation) to check this.
 /// </summary>
 /// <param name="cfr">The flight row</param>
 /// <returns>Null if there is no appropriate currency object.</returns>
 public static LAPLBase LAPLACurrencyForCategoryClass(ExaminerFlightRow cfr)
 {
     if (cfr == null)
     {
         throw new ArgumentNullException(nameof(cfr));
     }
     if (!cfr.fIsRealAircraft)
     {
         return(null);
     }
     if (cfr.fMotorGlider || CategoryClass.IsAirplane(cfr.idCatClassOverride))
     {
         return(new LAPLACurrency());
     }
     else if (cfr.idCatClassOverride == CategoryClass.CatClassID.Helicopter)
     {
         return(new LAPLHCurrency());
     }
     else
     {
         return(null);
     }
 }
        public override void ExamineFlight(ExaminerFlightRow cfr)
        {
            if (cfr == null)
            {
                throw new ArgumentNullException(nameof(cfr));
            }

            if (!cfr.fIsRealAircraft)
            {
                return;
            }

            bool fIsAirplane = CategoryClass.IsAirplane(cfr.idCatClassOverride);

            if (fIsAirplane || cfr.idCatClassOverride == CategoryClass.CatClassID.Helicopter || cfr.idCatClassOverride == CategoryClass.CatClassID.Airship)
            {
                decimal PICXC = Math.Min(cfr.PIC, cfr.XC);
                miMinXCPICTime.AddEvent(PICXC);
                if (fIsAirplane)
                {
                    miMinXCPICTimeInCategory.AddEvent(PICXC);
                }
            }
        }
Beispiel #9
0
 protected override bool IsMatchingCategory(CategoryClass.CatClassID ccid)
 {
     return(CategoryClass.IsAirplane(ccid));
 }
        /// <summary>
        /// Determines if the category/class matches the rating being sought
        /// </summary>
        /// <param name="ccid">The category/class</param>
        /// <returns>True if it applies to the rating</returns>
        protected bool CatClassMatchesRatingSought(CategoryClass.CatClassID ccid)
        {
            switch (RatingSought)
            {
            case RatingType.PPLAirplaneMulti:
            case RatingType.CommercialAMES:
            case RatingType.CommercialAMEL:
            case RatingType.PPLPart141MultiEngine:
                return(ccid == CategoryClass.CatClassID.AMEL || ccid == CategoryClass.CatClassID.AMES);

            case RatingType.PPLAirplaneSingle:
            case RatingType.CommercialASEL:
            case RatingType.CommercialASES:
            case RatingType.PPLPart141SingleEngine:
                return(ccid == CategoryClass.CatClassID.ASEL || ccid == CategoryClass.CatClassID.ASES);

            case RatingType.PPLHelicopter:
            case RatingType.InstrumentHelicopter:
            case RatingType.CommercialHelicopter:
            case RatingType.PPLPart141Helicopter:
            case RatingType.SAPPLHelicopter:
            case RatingType.SAPPLNightHelicopter:
            case RatingType.CAPPLHelicopter:
            case RatingType.CANightHelicopter:
            case RatingType.PPLJARHelicopter:
                return(ccid == CategoryClass.CatClassID.Helicopter);

            case RatingType.InstrumentAirplane:
            case RatingType.SAPPLAirplane:
            case RatingType.SAPPLNightAirplane:
            case RatingType.CAPPLAirplaneLand:
            case RatingType.CAPPLAirplaneSea:
            case RatingType.CANightAirplane:
            case RatingType.PPLJARAirplane:
                return(CategoryClass.IsAirplane(ccid));

            case RatingType.InstrumentPoweredLift:
                return(ccid == CategoryClass.CatClassID.PoweredLift);

            case RatingType.PPLPart141Gyroplane:
            case RatingType.PPLGyroplane:
                return(ccid == CategoryClass.CatClassID.Gyroplane);

            case RatingType.PPLPoweredLift:
                return(ccid == CategoryClass.CatClassID.PoweredLift);

            case RatingType.PPLAirship:
                return(ccid == CategoryClass.CatClassID.Airship);

            case RatingType.PPLGlider:
            case RatingType.PPLPart141Glider:
            case RatingType.CommercialGlider:
                return(ccid == CategoryClass.CatClassID.Glider);

            case RatingType.PPLBalloon:
                return(CategoryClass.IsBalloon(ccid));

            case RatingType.CommercialBalloonGas:
                return(ccid == CategoryClass.CatClassID.GasBalloon);

            case RatingType.CommercialBalloonHot:
                return(ccid == CategoryClass.CatClassID.HotAirBalloon);

            case RatingType.PPLPoweredParachute:
                return(ccid == CategoryClass.CatClassID.PoweredParachuteLand || ccid == CategoryClass.CatClassID.PoweredParachuteSea);

            case RatingType.PPLWeightShift:
                return(ccid == CategoryClass.CatClassID.WeightShiftControlLand || ccid == CategoryClass.CatClassID.WeightShiftControlSea);

            default:
                throw new NotImplementedException();
            }
        }
        public override void ExamineFlight(ExaminerFlightRow cfr)
        {
            if (cfr == null)
            {
                throw new ArgumentNullException(nameof(cfr));
            }
            base.ExamineFlight(cfr);

            if (!cfr.fIsCertifiedLanding)
            {
                return;
            }

            // 61.57(e) only applies if turbine and type rated.  Everything else must be in certified landing, or turbine airplane, or not type rated, or not in the type for this aircraft
            bool fIsMatchingType     = !String.IsNullOrEmpty(TypeDesignator) && cfr.szType.CompareCurrentCultureIgnoreCase(cfr.szType) == 0 && CategoryClass.IsAirplane(cfr.idCatClassOverride) && cfr.turbineLevel.IsTurbine() && !cfr.fIsCertifiedSinglePilot;
            NightCurrencyOptions nco = fIsMatchingType ? (cfr.fIsRealAircraft ? NightCurrencyOptions.FAR6157eAirplane : NightCurrencyOptions.FAR6157eSim) : NightCurrencyOptions.FAR6157bOnly;

            // 61.57(e)(4)(i/ii)(A) - 1500 hrs - comes into play after finalize

            // 61.57(e)(4)(i/ii)(C) - 15 hours in this type in the last 90 days.  Only if in an actual aircraft, since it doesn't seem to allow sim time.
            // Do this first because we'll exclude others if you were pilot monitoring
            if (nco == NightCurrencyOptions.FAR6157eAirplane)
            {
                m_fc6157TimeInType.AddRecentFlightEvents(cfr.dtFlight, cfr.Total);
            }

            if (!cfr.FlightProps.PropertyExistsWithID(CustomPropertyType.KnownProperties.IDPropPilotMonitoring))
            {
                // we need to subtract out monitored landings, or ignore all if you were monitoring for the whole flight
                int cMonitoredLandings = cfr.FlightProps.TotalCountForPredicate(p => p.PropTypeID == (int)CustomPropertyType.KnownProperties.IDPropMonitoredNightLandings);
                int cMonitoredTakeoffs = cfr.FlightProps.TotalCountForPredicate(p => p.PropTypeID == (int)CustomPropertyType.KnownProperties.IDPropMonitoredNightTakeoffs);

                // 61.57(e)(4)(i/ii)(B) - passenger currency in this type
                m_fc6157Passenger.ExamineFlight(cfr);

                // 61.57(b), 61.57(e)(4)(i/ii)(D) - Night takeoffs/landings
                if (cfr.cFullStopNightLandings > 0)
                {
                    AddNighttimeLandingEvent(cfr.dtFlight, Math.Max(cfr.cFullStopNightLandings - cMonitoredLandings, 0), nco);
                }

                // Night-time take-offs are also technically required for night currency
                int cNightTakeoffs = cfr.FlightProps.TotalCountForPredicate(cfp => cfp.PropertyType.IsNightTakeOff);
                if (cNightTakeoffs > 0)
                {
                    AddNighttimeTakeOffEvent(cfr.dtFlight, Math.Max(cNightTakeoffs - cMonitoredTakeoffs, 0), nco);
                }
            }
        }