public async Task GetWeatherAsync(DateTime dateTime, IEnumerable <string> zones, int forcastIntervals, CancellationToken cancellationToken) { if (zones == null) { foreach (var territory in _territoryList) { var eorzeaDateTime = new EorzeaDateTime(dateTime); var zone = territory.PlaceName; for (var i = 0; i < forcastIntervals; i++) { var weather = await Task.Run(() => territory.WeatherRate.Forecast(eorzeaDateTime).Name, cancellationToken); //var localTime = eorzeaDateTime.GetRealTime().ToLocalTime(); _sendMessageEvent.OnSendMessageEvent(new SendMessageEventArgs($"{zone} - {weather}")); eorzeaDateTime = Increment(eorzeaDateTime); } } } else { foreach (var zone in zones) { var eorzeaDateTime = new EorzeaDateTime(dateTime); for (var i = 0; i < forcastIntervals; i++) { var weather = await Task.Run(() => _territoryList.FirstOrDefault(_ => _.PlaceName.ToString() == zone).WeatherRate.Forecast(eorzeaDateTime).Name, cancellationToken); var localTime = eorzeaDateTime.GetRealTime().ToLocalTime(); _sendMessageEvent.OnSendMessageEvent(new SendMessageEventArgs($"{eorzeaDateTime}({localTime}): {zone} - {weather}")); eorzeaDateTime = Increment(eorzeaDateTime); } } } }
private double DaysIntoLunarCycle(EorzeaDateTime eDate) { var epoch = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc); var epochTimeFactor = (60.0 * 24.0) / 70.0; //20.571428571428573 // Take an Eorzean DateTime and turn it into UTC var eorzeaToUTC = eDate.GetRealTime().ToUniversalTime(); // Find total eorzian milliseconds since epoch var eorzeaTotalMilliseconds = eorzeaToUTC.Subtract(epoch).TotalMilliseconds *epochTimeFactor; // Get number of days into the cycle. // Moon is visible starting around 6pm. Change phase around noon when it can't be seen. // ((Total Eorzian Milliseconds since epoch / ([milliseconds in second] * [seconds in minute] * [minutes in hour] * [hours in day])) + mid-day) % [days in cycle(month)] return(((eorzeaTotalMilliseconds / (1000 * 60 * 60 * 24)) + .5) % 32); }
public void GetMoonPhase(EorzeaDateTime eDate) { string[] moons = { "New Moon", "Waxing Crescent", "First Quarter", "Waxing Gibbous", "Full Moon", "Waning Gibbous", "Last Quarter", "Waning Crescent" }; if (eDate == null) { eDate = new EorzeaDateTime(DateTime.Now); } var daysIntoCycle = DaysIntoLunarCycle(eDate); // 16 days until new or full moon. var percent = Math.Round(((daysIntoCycle % 16) / 16) * 100); // 4 days per moon. var index = Convert.ToInt32(Math.Floor(daysIntoCycle / 4)); _sendMessageEvent.OnSendMessageEvent(new SendMessageEventArgs($"Moon Phase: {moons[index]} {percent}%")); }
private static int CalculateTarget(EorzeaDateTime time) { var unix = time.GetUnixTime(); // Get Eorzea hour for weather start var bell = unix / 175; // Do the magic 'cause for calculations 16:00 is 0, 00:00 is 8 and 08:00 is 16 var increment = ((uint)(bell + 8 - (bell % 8))) % 24; // Take Eorzea days since unix epoch var totalDays = (uint)(unix / 4200); var calcBase = (totalDays * 0x64) + increment; var step1 = (calcBase << 0xB) ^ calcBase; var step2 = (step1 >> 8) ^ step1; return((int)(step2 % 0x64)); }
public static EorzeaDateTime Increment(EorzeaDateTime eDT) { eDT.Minute = 0; if (eDT.Bell < 8) { eDT.Bell = 8; } else if (eDT.Bell < 16) { eDT.Bell = 16; } else { eDT.Bell = 0; eDT.Sun += 1; } return(eDT); }
private EorzeaDateTime Increment(EorzeaDateTime eorzeaDateTime) { eorzeaDateTime.Minute = 0; if (eorzeaDateTime.Bell < 8) { eorzeaDateTime.Bell = 8; } else if (eorzeaDateTime.Bell < 16) { eorzeaDateTime.Bell = 16; } else { eorzeaDateTime.Bell = 0; eorzeaDateTime.Sun++; } return(eorzeaDateTime); }
/// <summary> /// Calculate the value used for the <see cref="Forecast" /> at a specific <see cref="EorzeaDateTime" />. /// </summary> /// <param name="time"><see cref="EorzeaDateTime" /> for which to calculate the value.</param> /// <returns>The value from 0..99 (inclusive) calculated based on <c>time</c>.</returns> private static int CalculateTarget(EorzeaDateTime time) { var unix = time.GetUnixTime(); // Get Eorzea hour for weather start var bell = unix / 175; // Do the magic 'cause for calculations 16:00 is 0, 00:00 is 8 and 08:00 is 16 var increment = ((uint)(bell + 8 - (bell % 8))) % 24; // Take Eorzea days since unix epoch var totalDays = (uint)(unix / 4200); var calcBase = (totalDays * 0x64) + increment; var step1 = (calcBase << 0xB) ^ calcBase; var step2 = (step1 >> 8) ^ step1; return (int)(step2 % 0x64); }
/// <summary> /// Forecast the <see cref="Weather" /> for the current location at a specific <see cref="EorzeaDateTime" />. /// </summary> /// <param name="time"><see cref="EorzeaDateTime" /> for which to forecast the weather.</param> /// <returns>The <see cref="Weather" /> at the current location at <c>time</c>.</returns> public Weather Forecast(EorzeaDateTime time) { var target = CalculateTarget(time); return _WeatherRates.Where(_ => target < _.Item1).Select(_ => _.Item2).FirstOrDefault(); }
public static string GetThisWeather(DateTime dateTime, string[] zones, int forcastIntervals) { EorzeaDateTime eorzeaDateTime = new EorzeaDateTime(dateTime); Territory t; string weatherForcast; bool sRankCentralShroudCondition = false; // double rain (2 Eorzean hours into 2nd rain/shower) DateTime sRankEasternLaNosceaCondition = new DateTime(); // No rain/showers for 200 RL minutes sRankEasternLaNosceaCondition = DateTime.Now; if (zones == null) { var enumerator = Territory.territory.GetEnumerator(); while (enumerator.MoveNext()) { EorzeaDateTime eorzeaDateTimeIncrements = new EorzeaDateTime(eorzeaDateTime); var pair = enumerator.Current; t = pair.Value; weatherForcast = $"{t.PlaceName}:\r\n"; for (int i = 0; i < forcastIntervals; i++) { int forcastIndex = CalculateTarget(eorzeaDateTimeIncrements); if (t.ThisWeatherRate != null) { weatherForcast += $"{eorzeaDateTimeIncrements} ({eorzeaDateTimeIncrements.GetRealTime().ToLocalTime().ToShortTimeString()}) - {Forcast(forcastIndex, t.ThisWeatherRate)}\r\n"; } eorzeaDateTimeIncrements = Increment(eorzeaDateTimeIncrements); } return(weatherForcast); } } else { foreach (var zone in zones) { EorzeaDateTime eorzeaDateTimeIncrements = new EorzeaDateTime(eorzeaDateTime); t = Territory.territory.FirstOrDefault(pN => pN.Value.PlaceName == zone).Value; weatherForcast = $"{t.PlaceName}:\r\n"; for (int i = 0; i < forcastIntervals; i++) { int forcastIndex = CalculateTarget(eorzeaDateTimeIncrements); if (t.ThisWeatherRate != null) { string weather = Forcast(forcastIndex, t.ThisWeatherRate); DateTime localTime = eorzeaDateTimeIncrements.GetRealTime().ToLocalTime(); weatherForcast += $"{eorzeaDateTimeIncrements} ({localTime}) - {weather}\r\n"; if (zone == "Central Shroud" && (weather == "Rain" || weather == "Showers")) { if (sRankCentralShroudCondition) { EorzeaDateTime spawnTime = eorzeaDateTimeIncrements; spawnTime.Bell = Convert.ToInt32(spawnTime.Bell) + 2; weatherForcast += $"\r\nCould spawn @ {spawnTime} {spawnTime.GetRealTime().ToLocalTime()}\r\n\r\n"; } sRankCentralShroudCondition = true; } else if (zone == "Eastern La Noscea") { if (weather == "Rain" || weather == "Showers") { sRankEasternLaNosceaCondition = localTime.AddMinutes(23).AddSeconds(20); } else if (localTime >= sRankEasternLaNosceaCondition.AddMinutes(200) && sRankEasternLaNosceaCondition.Year != 1) { EorzeaDateTime spawnTime = new EorzeaDateTime(sRankEasternLaNosceaCondition.AddMinutes(200)); weatherForcast += $"\r\nCould spawn @ {spawnTime} {spawnTime.GetRealTime().ToLocalTime()}\r\n\r\n"; } } else { sRankCentralShroudCondition = false; } } eorzeaDateTimeIncrements = Increment(eorzeaDateTimeIncrements); } return(weatherForcast); } } return(null); }
public static void GetThisWeather(EorzeaDateTime eorzeaDateTime, string[] zones = null, int forcastIntervals = 1) { DateTime dateTime = eorzeaDateTime.GetRealTime(); GetThisWeather(dateTime, zones, forcastIntervals); }
/// <summary> /// Forecast the <see cref="Weather" /> for the current location at a specific <see cref="EorzeaDateTime" />. /// </summary> /// <param name="time"><see cref="EorzeaDateTime" /> for which to forecast the weather.</param> /// <returns>The <see cref="Weather" /> at the current location at <c>time</c>.</returns> public Weather Forecast(EorzeaDateTime time) { var target = CalculateTarget(time); return(_WeatherRates.Where(_ => target < _.Item1).Select(_ => _.Item2).FirstOrDefault()); }