From 46fd6258c3f147ed1dfd1ecf152f41b0b56d284f Mon Sep 17 00:00:00 2001 From: Rime <81419447+Emirlol@users.noreply.github.com> Date: Mon, 15 Jul 2024 11:33:16 +0300 Subject: SkyblockTime improvements. - Added skyblock hour - Added events for each time unit (year, season, month, day, hour) that are fired when the time unit changes value - Removed magic numbers and added constant fields holding the numbers --- .../de/hysky/skyblocker/utils/SkyblockTime.java | 116 ++++++++++++++++++--- 1 file changed, 103 insertions(+), 13 deletions(-) (limited to 'src') diff --git a/src/main/java/de/hysky/skyblocker/utils/SkyblockTime.java b/src/main/java/de/hysky/skyblocker/utils/SkyblockTime.java index ec3effaf..175156c0 100644 --- a/src/main/java/de/hysky/skyblocker/utils/SkyblockTime.java +++ b/src/main/java/de/hysky/skyblocker/utils/SkyblockTime.java @@ -1,6 +1,8 @@ package de.hysky.skyblocker.utils; import de.hysky.skyblocker.utils.scheduler.Scheduler; +import net.fabricmc.fabric.api.event.Event; +import net.fabricmc.fabric.api.event.EventFactory; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -13,39 +15,77 @@ public class SkyblockTime { public static final AtomicReference skyblockSeason = new AtomicReference<>(Season.SPRING); public static final AtomicReference skyblockMonth = new AtomicReference<>(Month.EARLY_SPRING); public static final AtomicInteger skyblockDay = new AtomicInteger(0); + public static final AtomicInteger skyblockHour = new AtomicInteger(0); private static final Logger LOGGER = LoggerFactory.getLogger("Skyblocker Time"); + //All time lengths are in milliseconds + public static final double HOUR_LENGTH = 50000; + public static final double DAY_LENGTH = HOUR_LENGTH * 24; + public static final double MONTH_LENGTH = DAY_LENGTH * 31; + public static final double SEASON_LENGTH = MONTH_LENGTH * 3; + public static final double YEAR_LENGTH = SEASON_LENGTH * 4; + private SkyblockTime() { } + /** + * Updates the time and schedules a cyclic scheduler which will update the time every hour, to be run on the next hour change. + */ public static void init() { updateTime(); - //ScheduleCyclic already runs the task upon scheduling, so there's no need to call updateTime() here - Scheduler.INSTANCE.schedule(() -> Scheduler.INSTANCE.scheduleCyclic(SkyblockTime::updateTime, 1200 * 20), (int) (1200000 - (getSkyblockMillis() % 1200000)) / 50); + //scheduleCyclic already runs the task upon scheduling, so there's no need to call updateTime() in the lambda as well + //The division by 50 is to convert the time to ticks + Scheduler.INSTANCE.schedule(() -> Scheduler.INSTANCE.scheduleCyclic(SkyblockTime::updateTime, (int) (HOUR_LENGTH / 50)), (int) (HOUR_LENGTH - (getSkyblockMillis() % HOUR_LENGTH)) / 50); } public static long getSkyblockMillis() { return System.currentTimeMillis() - SKYBLOCK_EPOCH; } - private static int getSkyblockYear() { - return (int) (Math.floor(getSkyblockMillis() / 446400000.0) + 1); + private static int calculateSkyblockYear() { + return (int) (Math.floor(getSkyblockMillis() / YEAR_LENGTH) + 1); + } + + private static int calculateSkyblockMonth() { + return (int) (Math.floor(getSkyblockMillis() / MONTH_LENGTH) % 12); } - private static int getSkyblockMonth() { - return (int) (Math.floor(getSkyblockMillis() / 37200000.0) % 12); + private static int calculateSkyblockDay() { + return (int) (Math.floor(getSkyblockMillis() / DAY_LENGTH) % 31 + 1); } - private static int getSkyblockDay() { - return (int) (Math.floor(getSkyblockMillis() / 1200000.0) % 31 + 1); + private static int calculateSkyblockHour() { + return (int) (Math.floor(getSkyblockMillis() / HOUR_LENGTH) % 24); } + //This could probably be compacted by abstracting the logic into a method that takes a Supplier and a Consumer, etc. but there's really no need private static void updateTime() { - skyblockYear.set(getSkyblockYear()); - skyblockSeason.set(Season.values()[getSkyblockMonth() / 3]); - skyblockMonth.set(Month.values()[getSkyblockMonth()]); - skyblockDay.set(getSkyblockDay()); - LOGGER.info("[Skyblocker Time] Skyblock time updated to Year {}, Season {}, Month {}, Day {}", skyblockYear.get(), skyblockSeason.get(), skyblockMonth.get(), skyblockDay.get()); + int year = calculateSkyblockYear(); + if (skyblockYear.get() != year) { + skyblockYear.set(year); + YEAR_CHANGE.invoker().onYearChange(year); + } + Season season = Season.values()[calculateSkyblockMonth() / 3]; + if (skyblockSeason.get() != season) { + skyblockSeason.set(season); + SEASON_CHANGE.invoker().onSeasonChange(season); + } + Month month = Month.values()[calculateSkyblockMonth()]; + if (skyblockMonth.get() != month) { + skyblockMonth.set(month); + MONTH_CHANGE.invoker().onMonthChange(month); + } + int day = calculateSkyblockDay(); + if (skyblockDay.get() != day) { + skyblockDay.set(day); + DAY_CHANGE.invoker().onDayChange(day); + } + int hour = calculateSkyblockHour(); + if (skyblockHour.get() != hour) { + skyblockHour.set(hour); + HOUR_CHANGE.invoker().onHourChange(hour); + } + LOGGER.info("[Skyblocker Time] Skyblock time updated to Year {}, Season {}, Month {}, Day {}, Hour {}", year, season, month, day, hour); } public enum Season { @@ -58,4 +98,54 @@ public class SkyblockTime { EARLY_FALL, FALL, LATE_FALL, EARLY_WINTER, WINTER, LATE_WINTER } + + public interface OnHourChange { + void onHourChange(int hour); + } + + public interface OnDayChange { + void onDayChange(int day); + } + + public interface OnMonthChange { + void onMonthChange(Month month); + } + + public interface OnSeasonChange { + void onSeasonChange(Season season); + } + + public interface OnYearChange { + void onYearChange(int year); + } + + public static final Event HOUR_CHANGE = EventFactory.createArrayBacked(OnHourChange.class, listeners -> hour -> { + for (OnHourChange listener : listeners) { + listener.onHourChange(hour); + } + }); + + public static final Event DAY_CHANGE = EventFactory.createArrayBacked(OnDayChange.class, listeners -> day -> { + for (OnDayChange listener : listeners) { + listener.onDayChange(day); + } + }); + + public static final Event MONTH_CHANGE = EventFactory.createArrayBacked(OnMonthChange.class, listeners -> month -> { + for (OnMonthChange listener : listeners) { + listener.onMonthChange(month); + } + }); + + public static final Event SEASON_CHANGE = EventFactory.createArrayBacked(OnSeasonChange.class, listeners -> season -> { + for (OnSeasonChange listener : listeners) { + listener.onSeasonChange(season); + } + }); + + public static final Event YEAR_CHANGE = EventFactory.createArrayBacked(OnYearChange.class, listeners -> year -> { + for (OnYearChange listener : listeners) { + listener.onYearChange(year); + } + }); } -- cgit