private GameState() { currencyState = new CurrencyState(); merchState = new MerchState(); concertState = new ConcertState(); equipmentState = new EquipmentState(); }
/// <summary> /// Computes the overall currency /// </summary> public void RefreshCurrency() { // Compute currency according to 61.57(c)(6) ( => (c)(3)) (i) and (ii) including each one's expiration. if (m_fCacheValid) { return; } // 61.57(c)(6)(i) => (c)(3)(i) - no passengers. IPC covers this. FlightCurrency fc6157c6i = fcGliderIFRTime.AND(fcGliderInstrumentManeuvers).OR(fcGliderIPC); // 61.57(c)(6)(ii) => (c)(3)(ii) - passengers. Above + two more. Again, IPC covers this too. FlightCurrency fc6157c6ii = fc6157c6i.AND(fcGliderIFRTimePassengers).AND(fcGliderInstrumentPassengers).OR(fcGliderIPC); m_fCurrentSolo = fc6157c6i.IsCurrent(); m_fCurrentPassengers = fc6157c6ii.IsCurrent(); if (m_fCurrentSolo || m_fCurrentPassengers) { if (m_fCurrentPassengers) { m_csCurrent = fc6157c6ii.CurrentState; m_dtExpiration = fc6157c6ii.ExpirationDate; m_szDiscrepancy = fc6157c6ii.DiscrepancyString; } else // must be current solo) { m_csCurrent = fc6157c6i.CurrentState; m_dtExpiration = fc6157c6i.ExpirationDate; m_szDiscrepancy = fc6157c6i.DiscrepancyString; } // check to see if there is an embedded gap that needs an IPC CurrencyPeriod[] rgcpMissingIPC = fc6157c6i.FindCurrencyGap(fcGliderIPC.MostRecentEventDate, 6); if (rgcpMissingIPC != null && m_szDiscrepancy.Length == 0) { m_szDiscrepancy = String.Format(CultureInfo.CurrentCulture, Resources.Currency.IPCMayBeRequired, rgcpMissingIPC[0].EndDate.ToShortDateString(), rgcpMissingIPC[1].StartDate.ToShortDateString()); } } else { // And expiration date is the later of the passenger/no-passenger date m_dtExpiration = fc6157c6i.ExpirationDate.LaterDate(fc6157c6ii.ExpirationDate); // see if we need an IPC // if more than 6 calendar months have passed since expiration, an IPC is required. // otherwise, just name the one that is short if (DateTime.Compare(m_dtExpiration.AddCalendarMonths(6).Date, DateTime.Now.Date) > 0) { m_szDiscrepancy = String.Format(CultureInfo.CurrentCulture, Resources.Currency.DiscrepancyTemplateGliderIFRPassengers, fcGliderIFRTime.Discrepancy, fcGliderInstrumentManeuvers.Discrepancy); } else { m_szDiscrepancy = Resources.Currency.IPCRequired; } } m_fCacheValid = true; }
/// <summary> /// Return the currency status for all of the user's current deadlines. /// </summary> /// <param name="szUser">The user</param> /// <param name="daysForWarning">How many days to use for "getting close"</param> /// <returns></returns> public static IEnumerable <CurrencyStatusItem> CurrencyForUser(string szUser, int daysForWarning = 30) { List <CurrencyStatusItem> lst = new List <CurrencyStatusItem>(); IEnumerable <DeadlineCurrency> deadlines = DeadlinesForUser(szUser); foreach (DeadlineCurrency dc in deadlines) { string szLabel = dc.AircraftID > 0 ? String.Format(CultureInfo.CurrentCulture, "{0} - {1}", dc.TailNumber, dc.Name) : dc.Name; if (dc.UsesHours) { lst.Add(new CurrencyStatusItem(szLabel, dc.AircraftHours.ToString("#,##0.0#", CultureInfo.CurrentCulture), CurrencyState.NoDate, string.Empty) { AssociatedResourceID = dc.AircraftID, CurrencyGroup = CurrencyStatusItem.CurrencyGroups.Deadline }); } else if (dc.Expiration.HasValue()) { TimeSpan ts = dc.Expiration.Subtract(DateTime.Now); int days = (int)Math.Ceiling(ts.TotalDays); CurrencyState cs = (ts.Days < 0) ? CurrencyState.NotCurrent : ((days < daysForWarning) ? CurrencyState.GettingClose : CurrencyState.OK); lst.Add(new CurrencyStatusItem(szLabel, dc.Expiration.ToShortDateString(), cs, cs == CurrencyState.GettingClose ? String.Format(CultureInfo.CurrentCulture, Resources.Profile.ProfileCurrencyStatusClose, days) : (cs == CurrencyState.NotCurrent) ? String.Format(CultureInfo.CurrentCulture, Resources.Profile.ProfileCurrencyStatusNotCurrent, -days) : string.Empty) { AssociatedResourceID = dc.AircraftID, CurrencyGroup = CurrencyStatusItem.CurrencyGroups.Deadline }); } } return(lst); }
protected override void LoadData(MemoryStream ms) { IFormatter formatter = new BinaryFormatter(); GameState gd = (GameState)formatter.Deserialize(ms); this.tourState = gd.tourState == null ? new TourState() : gd.tourState; this.currencyState = gd.currencyState == null ? new CurrencyState() : gd.currencyState; }
void Awake() { songController = (SongController)FindObjectOfType (typeof(SongController)); concertController = (ConcertController)FindObjectOfType (typeof(ConcertController)); tourController = (TourController)FindObjectOfType(typeof(TourController)); merchController = (MerchController)FindObjectOfType(typeof(MerchController)); equipmentController = (EquipmentController)FindObjectOfType(typeof(EquipmentController)); hudUI = (HudUI)FindObjectOfType(typeof(HudUI)); currencyState = GameState.instance.Currency; }
private void RefreshCurrency() { if (m_fCacheValid) { return; } // Compute both loose (ignores takeoffs) and strict (requires takeoffs) night currencies. // Discrepancy can't be counted on after AND/OR so we set that to the one we wish to expose FlightCurrency fc6157b = this; // just for clarity that the "this" object does the basic 61.57(b) implementation. FlightCurrency fc6157e4i = m_fc6157eTotalTime.AND(m_fc6157Passenger).AND(m_fc6157TimeInType).AND(m_fc6157ei); FlightCurrency fc6157e4ii = m_fc6157eTotalTime.AND(m_fc6157Passenger).AND(m_fc6157TimeInType).AND(m_fc6157eii); FlightCurrency fcLoose = fc6157b.OR(fc6157e4i.OR(fc6157e4ii)); fcLoose.Discrepancy = fc6157b.Discrepancy; FlightCurrency fc6157bStrict = fc6157b.AND(NightTakeoffCurrency); FlightCurrency fc6157e4iStrict = fc6157e4i.AND(m_fc6157eiTakeoffs); FlightCurrency fc6157e4iiStrict = fc6157e4ii.AND(m_fc6157eiiTakeoffs); FlightCurrency fcStrict = fc6157bStrict.OR(fc6157e4iStrict).OR(fc6157e4iiStrict); // Loose rules for purposes of determining state m_csCurrent = fcLoose.CurrentState; m_dtExpiration = fcLoose.ExpirationDate; m_szDiscrepancy = fcLoose.DiscrepancyString; // determine the correct discrepancy string to show // if we've met the strict definition, we're fine - no discrepancy if (fcStrict.CurrentState.IsCurrent()) { m_szDiscrepancy = string.Empty; m_dtExpiration = fcStrict.ExpirationDate; } // else if we met the loose definition but not strict - meaning takeoffs were not found; Give a reminder about required takeoffs else if (m_csCurrent.IsCurrent()) { if (NightTakeoffCurrency.Discrepancy >= NightTakeoffCurrency.RequiredEvents) { m_szDiscrepancy = Resources.Currency.NightTakeoffReminder; } else { m_szDiscrepancy = String.Format(CultureInfo.CurrentCulture, Resources.Currency.DiscrepancyTemplateNight, NightTakeoffCurrency.Discrepancy, (NightTakeoffCurrency.Discrepancy > 1) ? Resources.Currency.Takeoffs : Resources.Currency.Takeoff); } } // else we aren't current at all - use the full discrepancy template using 61.57(b). DON'T CALL DISCREPANCY STRING because that causes an infinite recursion. else { m_szDiscrepancy = String.Format(CultureInfo.CurrentCulture, Resources.Currency.DiscrepancyTemplate, this.Discrepancy, (this.Discrepancy > 1) ? Resources.Totals.Landings : Resources.Totals.Landing); } m_fCacheValid = true; }
protected string CSSForItem(CurrencyState cs) { switch (cs) { case CurrencyState.GettingClose: return("currencynearlydue"); case CurrencyState.NotCurrent: return("currencyexpired"); case CurrencyState.OK: return("currencyok"); } return(string.Empty); }
private static CurrencyStatusItem StatusForDate(DateTime dt, string szLabel, CurrencyStatusItem.CurrencyGroups rt) { if (dt.CompareTo(DateTime.MinValue) != 0) { TimeSpan ts = dt.Subtract(DateTime.Now); int days = (int)Math.Ceiling(ts.TotalDays); CurrencyState cs = (days < 0) ? CurrencyState.NotCurrent : ((ts.Days < 30) ? CurrencyState.GettingClose : CurrencyState.OK); return(new CurrencyStatusItem(szLabel, CurrencyExaminer.StatusDisplayForDate(dt), cs, (cs == CurrencyState.GettingClose) ? String.Format(CultureInfo.CurrentCulture, Resources.Profile.ProfileCurrencyStatusClose, days) : (cs == CurrencyState.NotCurrent) ? String.Format(CultureInfo.CurrentCulture, Resources.Profile.ProfileCurrencyStatusNotCurrent, -days) : string.Empty) { CurrencyGroup = rt }); } else { return(null); } }
protected string CSSForItem(CurrencyState cs) { switch (cs) { case CurrencyState.GettingClose: return(CssCurrencyNearlyDue); case CurrencyState.NotCurrent: return(CssNotCurrent); case CurrencyState.OK: return(CssOK); case CurrencyState.NoDate: return(CssCurrencyNoDate); } return(string.Empty); }
private void RefreshCurrency() { if (m_fCacheValid) { return; } // 401.05(3)(a)-(c) say you have an IPC OR 6approaches+6hours OR 6approaches+6hours instructing. FlightCurrency fcIFRCanada = fc401_05_3_a.OR(fc401_05_3_bTime.AND(fc401_05_3_bApproaches)).OR(fc401_05_3_cTime.AND(fc401_05_3_cApproaches)); m_csCurrent = fcIFRCanada.CurrentState; m_dtExpiration = fcIFRCanada.ExpirationDate; if (m_csCurrent == CurrencyState.NotCurrent) { m_szDiscrepancy = Resources.Currency.IPCRequired; } m_fCacheValid = true; }
public IEnumerable <CurrencyStatusItem> CurrencyForUser() { List <CurrencyStatusItem> rgCS = new List <CurrencyStatusItem>(); IEnumerable <CurrencyStatusItem> lstMedicals = MedicalStatus(); CurrencyStatusItem csBasicMed = new BasicMed(CurrentUser.UserName).Status; /* Scenarios for combining regular medical and basicmed. * * +--------------------+--------------------+--------------------+--------------------+ * |\_____ Medical | | | | * | \______ | Never Current | Expired | Valid | * | BasicMed \_____ | | | | * +--------------------+--------------------+--------------------+--------------------+ * | Never Current | Show Nothing | Show Expired | Show Valid | * | | | Medical | Medical | * +--------------------+--------------------+--------------------+--------------------+ * | Expired | N/A | Show Expired | Show Valid Medical | * | | | Medical, BasicMed | Suppress BasicMed | * +--------------------+--------------------+--------------------+--------------------+ * | | | Show Valid | Show Valid | * | Valid | N/A | BasicMed, note | Medical, show | * | | | BasicMed only | BasicMed too | * +--------------------+--------------------+--------------------+--------------------+ * * * a) Medical has never been valid -> by definition, neither has basic med: NO STATUS * b) Medical expired * 1) BasicMed never valid -> show only expired medical * 2) BasicMed expired -> show expired medical, expired basicmed (so you can tell which is easier to renew) * 3) BasicMed is valid -> Show valid BasicMed, that you are ONLY basicmed * c) Medical valid: * 1) BasicMed never valid -> Show only valid medical * 2) BasicMed expired -> show valid medical don't bother showing the expired basicmed since it's kinda pointless * 3) BasicMed is still valid -> show both (hey, seeing green is good) */ if (lstMedicals.Any()) // (a) above - i.e., left column of chart; nothing to add if never had valid medical { if (csBasicMed == null) // b.1 and c.1 above, i.e., top row of chart - Just show medical status { rgCS.AddRange(lstMedicals); } else { CurrencyState state = CurrencyState.NotCurrent; foreach (CurrencyStatusItem cs in lstMedicals) { state = (CurrencyState)Math.Max((int)state, (int)cs.Status); } switch (state) { case CurrencyState.OK: case CurrencyState.GettingClose: // Medical valid - c.2 and c.3 above - show medical, show basic med if valid rgCS.AddRange(lstMedicals); if (csBasicMed.Status != CurrencyState.NotCurrent) { rgCS.Add(csBasicMed); } break; case CurrencyState.NotCurrent: // Medical is not current but basicmed has been - always show basicmed, show medical only if basicmed is also expired rgCS.Add(csBasicMed); if (csBasicMed.Status == CurrencyState.NotCurrent) { rgCS.AddRange(lstMedicals); } break; } } } BFREvents = null; // clear the cache - but this will let the next three calls (LastBFR/LastBFRR22/LastBFRR44) hit the DB only once. DateTime dtBfrLast = LastBFR(); if (dtBfrLast.HasValue()) { rgCS.Add(StatusForDate(NextBFR(dtBfrLast), Resources.Currency.NextFlightReview, CurrencyStatusItem.CurrencyGroups.FlightReview)); } BFREvents = null; // clear the cache again (memory). if (CurrentUser.CertificateExpiration.HasValue()) { rgCS.Add(StatusForDate(CurrentUser.CertificateExpiration, Resources.Currency.CertificateExpiration, CurrencyStatusItem.CurrencyGroups.Certificates)); } if (CurrentUser.EnglishProficiencyExpiration.HasValue()) { rgCS.Add(StatusForDate(CurrentUser.EnglishProficiencyExpiration, Resources.Currency.NextLanguageProficiency, CurrencyStatusItem.CurrencyGroups.Certificates)); } return(rgCS); }
protected override void LoadData(MemoryStream ms) { IFormatter formatter = new BinaryFormatter(); GameState gd = (GameState)formatter.Deserialize(ms); this.currencyState = gd.currencyState == null ? new CurrencyState() : gd.currencyState; this.merchState = gd.merchState == null ? new MerchState() : gd.merchState; this.concertState = gd.concertState == null ? new ConcertState() : gd.concertState; this.equipmentState = gd.equipmentState == null ? new EquipmentState() : gd.equipmentState; this.currencyState.SynchronizeRealCurrencyAndScreenCurrency(); }
/// <summary> /// Determines if the currency state is any of the current states. /// </summary> /// <param name="cs"></param> /// <returns></returns> public static bool IsCurrent(this CurrencyState cs) { return(cs != CurrencyState.NotCurrent); }
/// <summary> /// Computes the overall currency - DEPRECATED /// </summary> public void RefreshCurrencyOLD() { // Compute currency according to 61.57(c)(6) (i) and (ii) => (c)(3) including each one's expiration. if (m_fCacheValid) { return; } m_szDiscrepancy = string.Empty; m_csCurrent = CurrencyState.NotCurrent; m_dtExpiration = DateTime.MinValue; DateTime dtExpirationSolo; DateTime dtExpirationPassengers; // 61.57(c)(6)(i) => (c)(3)(i) - basic instrument currency if (fcGliderIFRTime.HasBeenCurrent && fcGliderInstrumentManeuvers.HasBeenCurrent) { // find the earliest expiration DateTime dtExpIFRTime = fcGliderIFRTime.ExpirationDate; DateTime dtExpInstMan = fcGliderInstrumentManeuvers.ExpirationDate; dtExpirationSolo = dtExpIFRTime; dtExpirationSolo = dtExpInstMan.EarlierDate(dtExpirationSolo); m_dtExpiration = dtExpirationSolo; m_csCurrent = FlightCurrency.IsAlmostCurrent(m_dtExpiration) ? CurrencyState.GettingClose : (FlightCurrency.IsCurrent(m_dtExpiration) ? CurrencyState.OK : CurrencyState.NotCurrent); m_fCurrentSolo = (m_csCurrent != CurrencyState.NotCurrent); // at this point we've determined if you're current for solo (61.57(c)(6)(i)) => (c)(3)(i); now see if we can carry passengers if (m_fCurrentSolo && fcGliderIFRTimePassengers.HasBeenCurrent && fcGliderInstrumentPassengers.HasBeenCurrent) { DateTime dtExpIFRTimePassengers = fcGliderIFRTimePassengers.ExpirationDate; DateTime dtExpIFRPassengers = fcGliderInstrumentPassengers.ExpirationDate; dtExpirationPassengers = dtExpIFRTimePassengers.EarlierDate(dtExpIFRPassengers); CurrencyState csPassengers = FlightCurrency.IsAlmostCurrent(dtExpirationPassengers) ? CurrencyState.GettingClose : (FlightCurrency.IsCurrent(dtExpirationPassengers) ? CurrencyState.OK : CurrencyState.NotCurrent); // if current for passengers, then we are the more restrictive of overall close to losing currency or fully current. if (m_fCurrentPassengers = (csPassengers != CurrencyState.NotCurrent)) { m_csCurrent = (m_csCurrent == CurrencyState.OK && csPassengers == CurrencyState.OK) ? CurrencyState.OK : CurrencyState.GettingClose; m_dtExpiration = dtExpirationPassengers.EarlierDate(dtExpirationSolo); } } } // IPC can also set currency. if (fcGliderIPC.HasBeenCurrent) { // set currency to the most permissive of either current state or IPC state m_csCurrent = (fcGliderIPC.CurrentState > m_csCurrent) ? fcGliderIPC.CurrentState : m_csCurrent; // Expiration date is the LATER of the current expiration date OR the IPC expiration date, with one exception below. m_dtExpiration = fcGliderIPC.ExpirationDate.LaterDate(m_dtExpiration); // if you have a valid IPC, you are currently valid for both passengers and solo. // however, IPC could expire before the solo requirements expire, so if it is the // IPC that is driving passengers, use the IPC date as the expiration date. Otherwise, use the later one. // That way, when the IPC expires, your passenger privs expire too, so you'll see a new "no passengers" priv remaining // with a new date. if (fcGliderIPC.IsCurrent()) { if (m_fCurrentSolo && !m_fCurrentPassengers) { m_dtExpiration = fcGliderIPC.ExpirationDate; } m_fCurrentPassengers = m_fCurrentSolo = true; } } m_fCacheValid = true; }
/// <summary> /// Computes the overall currency /// </summary> protected void RefreshCurrency() { // Compute currency according to 61.57(c)(1)-(5) and 61.57(e) // including each one's expiration. The one that expires latest is the expiration date if you are current, the one that // expired most recently is the expiration date since when you were not current. if (m_fCacheValid) { return; } // This is ((61.57(c)(1) OR (2) OR (3) OR (4) OR (5) OR 61.57(e)), each of which is the AND of several currencies. // 61.57(c)(1) (66-HIT in airplane) FlightCurrency fc6157c1 = fcIFRApproach.AND(fcIFRHold); // 61.57(c)(2) (66-HIT in an FTD or flight simulator) FlightCurrency fc6157c2 = fcFTDApproach.AND(fcFTDHold); // 61.57(c)(3) - ATD FlightCurrency fc6157c3 = fcATDHold.AND(fcATDApproach).AND(fcUnusualAttitudesAsc).AND(fcUnusualAttitudesDesc).AND(fcInstrumentHours); // 61.57(c)(4) - Combo STRICT - 6 approaches/hold in an ATD PLUS an approach/hold in an airplane PLUS an approach/hold in an FTD FlightCurrency fc6157c4 = fcATDAppch6Month.AND(fcATDHold6Month).AND(fcIFRHold).AND(fcAirplaneApproach6Month).AND(fcFTDApproach6Month).AND(fcFTDHold); // 61.57(c)(4) - Combo LOOSE - any combination that yields 66-HIT, but require at least one aircraft approach and hold. // FlightCurrency fc6157c4Loose = fcComboApproach6Month.AND(fcAirplaneApproach6Month).AND(fcIFRHold.OR(fcATDHold6Month).OR(fcFTDHold)); // 61.57(c)(5) - combo meal, but seems redundant with (c)(2)/(3). I.e., if you've met this, you've met (2) or (3). // 61.57 (e) - IPC; no need to AND anything together for this one. FlightCurrency fcIFR = fc6157c1.OR(fc6157c2).OR(fc6157c3).OR(fc6157c4).OR(fcIPCOrCheckride); /* * if (m_fUseLoose6157c4) * fcIFR = fcIFR.OR(fc6157c4Loose); */ m_csCurrent = fcIFR.CurrentState; m_dtExpiration = fcIFR.ExpirationDate; if (fcIPCOrCheckride.IsCurrent() && fcIPCOrCheckride.ExpirationDate.CompareTo(m_dtExpiration) >= 0) { Query.HasHolds = Query.HasApproaches = false; Query.PropertiesConjunction = GroupConjunction.Any; Query.PropertyTypes.Clear(); foreach (CustomPropertyType cpt in CustomPropertyType.GetCustomPropertyTypes()) { if (cpt.IsIPC) { Query.PropertyTypes.Add(cpt); } } } if (m_csCurrent == CurrencyState.NotCurrent) { // if more than 6 calendar months have passed since expiration, an IPC is required. // otherwise, just assume 66-HIT. if (DateTime.Compare(m_dtExpiration.AddCalendarMonths(6).Date, DateTime.Now.Date) > 0) { m_szDiscrepancy = String.Format(CultureInfo.CurrentCulture, Resources.Currency.DiscrepancyTemplateIFR, fcIFRHold.Discrepancy, (fcIFRHold.Discrepancy == 1) ? Resources.Currency.Hold : Resources.Currency.Holds, fcIFRApproach.Discrepancy, (fcIFRApproach.Discrepancy == 1) ? Resources.Totals.Approach : Resources.Totals.Approaches); } else { m_szDiscrepancy = Resources.Currency.IPCRequired; } } else { // Check to see if IPC is required by looking for > 6 month gap in IFR currency. // For now, we won't make you un-current, but we'll warn. // (IPC above, though, is un-current). CurrencyPeriod[] rgcpMissingIPC = fcIFR.FindCurrencyGap(fcIPCOrCheckride.MostRecentEventDate, 6); if (rgcpMissingIPC != null) { m_szDiscrepancy = String.Format(CultureInfo.CurrentCulture, Resources.Currency.IPCMayBeRequired, rgcpMissingIPC[0].EndDate.ToShortDateString(), rgcpMissingIPC[1].StartDate.ToShortDateString()); } else { m_szDiscrepancy = string.Empty; } } m_fCacheValid = true; }