package joshie.harvest.calendar; import gnu.trove.map.TIntIntMap; import joshie.harvest.api.calendar.CalendarDate; import joshie.harvest.api.calendar.Season; import joshie.harvest.api.calendar.Weekday; import joshie.harvest.calendar.data.CalendarServer; import joshie.harvest.core.HFTrackers; import net.minecraft.server.MinecraftServer; import net.minecraft.world.World; import net.minecraft.world.WorldServer; import javax.annotation.Nonnull; import static joshie.harvest.api.calendar.CalendarDate.DAYS_PER_SEASON; import static joshie.harvest.calendar.HFCalendar.TICKS_PER_DAY; public class CalendarHelper { public static final Season[] SEASONS; public static final Weekday[] DAYS; static { SEASONS = Season.class.getEnumConstants(); DAYS = Weekday.class.getEnumConstants(); } //Dates are 0-29 public static boolean isDateSame(CalendarDate today, CalendarDate dateOffByOne) { int dayToCompareAgainst = dateOffByOne.getDay() - 1; int compareMin = getMinDay(dayToCompareAgainst); int compareMax = getMaxDay(dayToCompareAgainst); return today.getDay() >= compareMin && today.getDay() <= compareMax && today.getSeason() == dateOffByOne.getSeason(); } //Returns 0-29 public static int getMinDay(int day) { return (int) (((double)(day) / 30D) * CalendarDate.DAYS_PER_SEASON); } //Returns 0-29 public static int getMaxDay(int day) { return (int) (((double)(day + 1) / 30D) * CalendarDate.DAYS_PER_SEASON) - 1; } private static Weekday getWeekday(int days) { int modulus = days % 7; if (modulus < 0) modulus = 0; return DAYS[modulus]; } public static Weekday getWeekday(long time) { return getWeekday(getElapsedDays(time)); } public static void setDate(World world, CalendarDate date) { long time = world.getWorldTime(); Season previous = date.getSeason(); date.setDate(getWeekday(time), getDay(time), getSeason(time), getYear(time)); if (previous != date.getSeason()) { HFTrackers.getCalendar(world).onSeasonChanged(); } } private static int getYear(long totalTime) { return (int) Math.floor((double)getElapsedDays(totalTime) / 4 / DAYS_PER_SEASON); } public static Season getSeason(long totalTime) { return SEASONS[Math.max(0, (int)Math.floor((getElapsedDays(totalTime) / DAYS_PER_SEASON) % 4))]; } private static int getDay(long totalTime) { return getElapsedDays(totalTime) % DAYS_PER_SEASON; } public static int getElapsedDays(long totalTime) { return (int) (totalTime / TICKS_PER_DAY); } private static int getTotalDays(int day, Season season, int year) { int season_days = DAYS_PER_SEASON * season.ordinal(); int year_days = (year - 1) * (DAYS_PER_SEASON * 4); return day + season_days + year_days; } public static int getTotalDays(CalendarDate date) { int current_days = date.getDay(); int season_days = CalendarDate.DAYS_PER_SEASON * date.getSeason().ordinal(); int year_days = (date.getYear() - 1) * (DAYS_PER_SEASON * 4); return current_days + season_days + year_days; } public static int getYearsPassed(@Nonnull CalendarDate birthday, @Nonnull CalendarDate date) { double current_total_days = getTotalDays(date); double birthday_total_days = getTotalDays(birthday); int one_year = DAYS_PER_SEASON * 4; int years_passed = (int) Math.floor(current_total_days / one_year); int birthday_years = (int) Math.floor(birthday_total_days / one_year); return Math.max(0, years_passed - birthday_years); } public static long getTime(int day, Season season, int year) { return (getTotalDays(day, season, year)) * TICKS_PER_DAY; } public static long getTime(World world) { return (world.getWorldTime() + 6000) % TICKS_PER_DAY; } public static int getScaledTime(int time) { return (int) (((double)time / TICKS_PER_DAY) * 24000D); } public static void setWorldTime(MinecraftServer server, long worldTime) { worldTime = Math.max(0L, worldTime); for (int j = 0; j < server.worldServers.length; ++j) { WorldServer worldserver = server.worldServers[j]; worldserver.setWorldTime(worldTime); } if (worldTime % TICKS_PER_DAY != 23999) { CalendarServer calendar = HFTrackers.getCalendar(server.worldServers[0]); calendar.recalculateAndUpdate(server.worldServers[0]); } } public static int getBlendedColour(TIntIntMap map, int original, int additional) { try { int ret = map.get(original); if (ret != map.getNoEntryValue()) return ret; else { int size = 2; int r = (original & 0xFF0000) >> 16; int g = (original & 0x00FF00) >> 8; int b = original & 0x0000FF; r += (additional & 0xFF0000) >> 16; g += (additional & 0x00FF00) >> 8; b += additional & 0x0000FF; int value = (r / size & 255) << 16 | (g / size & 255) << 8 | b / size & 255; map.put(original, value); return value; } } catch (IndexOutOfBoundsException exception) { return original; } } public static boolean isBetween(World world, int open, int close) { long daytime = CalendarHelper.getTime(world); //0-23999 by default int scaledOpening = CalendarHelper.getScaledTime(open); int scaledClosing = CalendarHelper.getScaledTime(close); return daytime >= scaledOpening && daytime <= scaledClosing; } public static int getDays(CalendarDate then, CalendarDate now) { int thenDays = getTotalDays(then); int nowDays = getTotalDays(now); return (nowDays - thenDays); } }