From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Ivan Pekov <ivan@mrivanplays.com>
Date: Mon, 4 Jan 2021 20:12:36 +0200
Subject: [PATCH] Optimised hallowen checker


diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java
index 75481bd6265054879877afb6c4686155c3caaf6d..ee0b256632e23bc18f94cbcf478e9dc7fc2c50e9 100644
--- a/src/main/java/net/minecraft/server/MinecraftServer.java
+++ b/src/main/java/net/minecraft/server/MinecraftServer.java
@@ -1474,6 +1474,7 @@ public abstract class MinecraftServer extends IAsyncTaskHandlerReentrant<TickTas
         // Paper end
 
         com.tuinity.tuinity.util.CachedLists.reset(); // Tuinity
+        org.yatopiamc.yatopia.server.entity.HalloweenChecker.tick(); // Yatopia
 
         // Paper start
         long endTime = System.nanoTime();
diff --git a/src/main/java/net/minecraft/world/entity/ambient/EntityBat.java b/src/main/java/net/minecraft/world/entity/ambient/EntityBat.java
index e6c5d21da445c9b66dcca33d9029d1768bbe046a..56dbac9b4d97bf012a99e138add98fcc8ae453e4 100644
--- a/src/main/java/net/minecraft/world/entity/ambient/EntityBat.java
+++ b/src/main/java/net/minecraft/world/entity/ambient/EntityBat.java
@@ -307,11 +307,16 @@ public class EntityBat extends EntityAmbient {
     }
 
     private static boolean eJ() {
+        // Yatopia start - optimised halloween checker
+        /*
         LocalDate localdate = LocalDate.now();
         int i = localdate.get(ChronoField.DAY_OF_MONTH);
         int j = localdate.get(ChronoField.MONTH_OF_YEAR);
 
         return j == 10 && i >= 20 || j == 11 && i <= 3;
+         */
+        return org.yatopiamc.yatopia.server.entity.HalloweenChecker.isHalloweenSeason();
+        // Yatopia end
     }
 
     @Override
diff --git a/src/main/java/net/minecraft/world/entity/monster/EntitySkeletonAbstract.java b/src/main/java/net/minecraft/world/entity/monster/EntitySkeletonAbstract.java
index 7ec60987229927e5fe7164f1d4eae8222832e920..faae6cdd816c86b3c7b86104a2017974c05e3452 100644
--- a/src/main/java/net/minecraft/world/entity/monster/EntitySkeletonAbstract.java
+++ b/src/main/java/net/minecraft/world/entity/monster/EntitySkeletonAbstract.java
@@ -154,11 +154,15 @@ public abstract class EntitySkeletonAbstract extends EntityMonster implements IR
         this.eL();
         this.setCanPickupLoot(this.world.paperConfig.skeletonsAlwaysCanPickUpLoot || this.random.nextFloat() < 0.55F * difficultydamagescaler.d()); // Paper
         if (this.getEquipment(EnumItemSlot.HEAD).isEmpty()) {
+            /* // Yatopia start - optimised halloween checker
             LocalDate localdate = LocalDate.now();
             int i = localdate.get(ChronoField.DAY_OF_MONTH);
             int j = localdate.get(ChronoField.MONTH_OF_YEAR);
 
             if (j == 10 && i == 31 && this.random.nextFloat() < 0.25F) {
+             */
+            if (org.yatopiamc.yatopia.server.entity.HalloweenChecker.isHalloweenDay() && this.random.nextFloat() < 0.25F) {
+            // Yatopia end
                 this.setSlot(EnumItemSlot.HEAD, new ItemStack(this.random.nextFloat() < 0.1F ? Blocks.JACK_O_LANTERN : Blocks.CARVED_PUMPKIN));
                 this.dropChanceArmor[EnumItemSlot.HEAD.b()] = 0.0F;
             }
diff --git a/src/main/java/net/minecraft/world/entity/monster/EntityZombie.java b/src/main/java/net/minecraft/world/entity/monster/EntityZombie.java
index 7112db516e62ca75a445482005c524129b84f54c..5060c8c32ceb13475c60f831e0f4fd132cf952b3 100644
--- a/src/main/java/net/minecraft/world/entity/monster/EntityZombie.java
+++ b/src/main/java/net/minecraft/world/entity/monster/EntityZombie.java
@@ -585,11 +585,15 @@ public class EntityZombie extends EntityMonster {
         }
 
         if (this.getEquipment(EnumItemSlot.HEAD).isEmpty()) {
+            /* // Yatopia start - optimised halloween checker
             LocalDate localdate = LocalDate.now();
             int i = localdate.get(ChronoField.DAY_OF_MONTH);
             int j = localdate.get(ChronoField.MONTH_OF_YEAR);
 
             if (j == 10 && i == 31 && this.random.nextFloat() < 0.25F) {
+             */
+            if (org.yatopiamc.yatopia.server.entity.HalloweenChecker.isHalloweenDay() && this.random.nextFloat() < 0.25F) {
+            // Yatopia end
                 this.setSlot(EnumItemSlot.HEAD, new ItemStack(this.random.nextFloat() < 0.1F ? Blocks.JACK_O_LANTERN : Blocks.CARVED_PUMPKIN));
                 this.dropChanceArmor[EnumItemSlot.HEAD.b()] = 0.0F;
             }
diff --git a/src/main/java/org/yatopiamc/yatopia/server/entity/HalloweenChecker.java b/src/main/java/org/yatopiamc/yatopia/server/entity/HalloweenChecker.java
new file mode 100644
index 0000000000000000000000000000000000000000..b9e8c25fa4c4cc088a12c2b865887751c8cdbcd8
--- /dev/null
+++ b/src/main/java/org/yatopiamc/yatopia/server/entity/HalloweenChecker.java
@@ -0,0 +1,59 @@
+package org.yatopiamc.yatopia.server.entity;
+
+import java.time.LocalDate;
+import java.time.temporal.ChronoField;
+import net.minecraft.server.MinecraftServer;
+
+/**
+ * Entity halloween checker
+ * <p>
+ * Checks whether or not it is halloween at a specific rate rather than every time when
+ * a entity is being spawned.
+ * <p>
+ * The rate changes depending on how much TPS the server has. By default, the rate is every
+ * 2 hours, or every 144k ticks (if the server has _that_ much uptime)
+ *
+ * @author MrIvanPlays
+ */
+public class HalloweenChecker {
+
+    private static boolean halloweenSeason = false;
+    private static boolean halloweenDay = false;
+
+    private static int delay = (20 * 60 * 60) * 2;
+    private static int lastCheckTick = -delay;
+
+    public static void tick() {
+        if (MinecraftServer.currentTick % 100 == 0) {
+            // update the delay every 100 ticks
+            if (MinecraftServer.TPS >= 20) {
+                delay = (20 * 60 * 60) * 2;
+            }
+            if (MinecraftServer.TPS < 15) {
+                delay = delay + (20 * 60 * 15);
+            }
+            if (MinecraftServer.TPS < 10) {
+                delay = delay + (20 * 60 * 30);
+            }
+        }
+        if (MinecraftServer.currentTick - lastCheckTick > delay) {
+            LocalDate now = LocalDate.now();
+            int day = now.getDayOfMonth();
+            int month = now.get(ChronoField.MONTH_OF_YEAR);
+
+            halloweenDay = (month == 10) && (day == 31);
+            halloweenSeason = ((month == 10) && (day >= 20)) || ((month == 11) && (day <= 3));
+
+            lastCheckTick = MinecraftServer.currentTick;
+        }
+    }
+
+    public static boolean isHalloweenSeason() {
+        return halloweenSeason;
+    }
+
+    public static boolean isHalloweenDay() {
+        return halloweenDay;
+    }
+
+}
