From 28287824f962579bba440b825a22e1d607442745 Mon Sep 17 00:00:00 2001 From: Brennan Ward <3682588+Shadows-of-Fire@users.noreply.github.com> Date: Tue, 16 Apr 2024 22:24:14 -0700 Subject: [PATCH 1/5] Refactor tick events into distinct subclasses --- .../net/minecraft/client/Minecraft.java.patch | 24 ++-- .../server/MinecraftServer.java.patch | 11 +- .../world/entity/player/Player.java.patch | 4 +- .../capabilities/CapabilityHooks.java | 16 +-- .../neoforge/client/ClientHooks.java | 38 +++++++ .../client/event/ClientTickEvent.java | 36 ++++++ .../client/event/RenderFrameEvent.java | 54 +++++++++ .../neoforge/common/CommonHooks.java | 20 +++- .../neoforge/common/NeoForgeEventHandler.java | 11 +- .../neoforged/neoforge/event/EventHooks.java | 79 ++++++++----- .../neoforged/neoforge/event/TickEvent.java | 107 ------------------ .../event/entity/living/LivingEvent.java | 18 --- .../neoforge/event/tick/LevelTickEvent.java | 70 ++++++++++++ .../neoforge/event/tick/LivingTickEvent.java | 58 ++++++++++ .../neoforge/event/tick/PlayerTickEvent.java | 50 ++++++++ .../neoforge/event/tick/ServerTickEvent.java | 67 +++++++++++ .../neoforge/event/tick/package-info.java | 13 +++ .../neoforge/debug/client/ClientTests.java | 5 +- .../neoforge/debug/level/LevelTests.java | 4 +- .../rendering/CustomParticleTypeTest.java | 6 +- 20 files changed, 493 insertions(+), 198 deletions(-) create mode 100644 src/main/java/net/neoforged/neoforge/client/event/ClientTickEvent.java create mode 100644 src/main/java/net/neoforged/neoforge/client/event/RenderFrameEvent.java delete mode 100644 src/main/java/net/neoforged/neoforge/event/TickEvent.java create mode 100644 src/main/java/net/neoforged/neoforge/event/tick/LevelTickEvent.java create mode 100644 src/main/java/net/neoforged/neoforge/event/tick/LivingTickEvent.java create mode 100644 src/main/java/net/neoforged/neoforge/event/tick/PlayerTickEvent.java create mode 100644 src/main/java/net/neoforged/neoforge/event/tick/ServerTickEvent.java create mode 100644 src/main/java/net/neoforged/neoforge/event/tick/package-info.java diff --git a/patches/net/minecraft/client/Minecraft.java.patch b/patches/net/minecraft/client/Minecraft.java.patch index 744ebb1662..7a8dcecbfe 100644 --- a/patches/net/minecraft/client/Minecraft.java.patch +++ b/patches/net/minecraft/client/Minecraft.java.patch @@ -209,11 +209,11 @@ this.profiler.pop(); if (!this.noRender) { + this.realPartialTick = this.pause ? this.pausePartialTick : this.timer.partialTick; // Cache this since pause is volatile -+ net.neoforged.neoforge.event.EventHooks.onRenderTickStart(this.realPartialTick); ++ net.neoforged.neoforge.client.ClientHooks.fireRenderFramePre(this.realPartialTick); this.profiler.popPush("gameRenderer"); this.gameRenderer.render(this.pause ? this.pausePartialTick : this.timer.partialTick, i, p_91384_); this.profiler.pop(); -+ net.neoforged.neoforge.event.EventHooks.onRenderTickEnd(this.realPartialTick); ++ net.neoforged.neoforge.client.ClientHooks.fireRenderFramePost(this.realPartialTick); } if (this.fpsPieResults != null) { @@ -326,20 +326,20 @@ if (!itemstack.isEmpty()) { InteractionResult interactionresult2 = this.gameMode.useItem(this.player, interactionhand); if (interactionresult2.consumesAction()) { -@@ -1808,6 +_,8 @@ - this.rightClickDelay--; - } +@@ -1800,6 +_,8 @@ -+ net.neoforged.neoforge.event.EventHooks.onPreClientTick(); + public void tick() { + this.clientTickCount++; ++ net.neoforged.neoforge.client.ClientHooks.fireClientTickPre(); + - this.profiler.push("gui"); - this.chatListener.tick(); - this.gui.tick(this.pause); + if (this.level != null && !this.pause) { + this.level.tickRateManager().tick(); + } @@ -1892,6 +_,7 @@ this.tutorial.tick(); -+ net.neoforged.neoforge.event.EventHooks.onPreLevelTick(this.level, () -> true); ++ net.neoforged.neoforge.event.EventHooks.fireLevelTickPre(this.level, () -> true); try { this.level.tick(() -> true); } catch (Throwable throwable) { @@ -347,7 +347,7 @@ throw new ReportedException(crashreport); } -+ net.neoforged.neoforge.event.EventHooks.onPostLevelTick(this.level, () -> true); ++ net.neoforged.neoforge.event.EventHooks.fireLevelTickPost(this.level, () -> true); } this.profiler.popPush("animateTick"); @@ -356,7 +356,7 @@ this.keyboardHandler.tick(); this.profiler.pop(); + -+ net.neoforged.neoforge.event.EventHooks.onPostClientTick(); ++ net.neoforged.neoforge.client.ClientHooks.fireClientTickPost(); } private boolean isMultiplayerServer() { diff --git a/patches/net/minecraft/server/MinecraftServer.java.patch b/patches/net/minecraft/server/MinecraftServer.java.patch index 1fa90521d0..caa911ba00 100644 --- a/patches/net/minecraft/server/MinecraftServer.java.patch +++ b/patches/net/minecraft/server/MinecraftServer.java.patch @@ -86,12 +86,11 @@ this.onServerExit(); } } -@@ -876,12 +_,14 @@ - +@@ -877,11 +_,13 @@ public void tickServer(BooleanSupplier p_129871_) { long i = Util.getNanos(); -+ net.neoforged.neoforge.event.EventHooks.onPreServerTick(p_129871_, this); this.tickCount++; ++ net.neoforged.neoforge.event.EventHooks.fireServerTickPre(p_129871_, this); this.tickRateManager.tick(); this.tickChildren(p_129871_); if (i - this.lastServerStatus >= STATUS_EXPIRE_TIME_NANOS) { @@ -105,7 +104,7 @@ this.smoothedTickTimeMillis = this.smoothedTickTimeMillis * 0.8F + (float)j / (float)TimeUtil.NANOSECONDS_PER_MILLISECOND * 0.19999999F; this.logTickMethodTime(i); this.profiler.pop(); -+ net.neoforged.neoforge.event.EventHooks.onPostServerTick(p_129871_, this); ++ net.neoforged.neoforge.event.EventHooks.fireServerTickPost(p_129871_, this); } private void logTickMethodTime(long p_321837_) { @@ -150,7 +149,7 @@ } this.profiler.push("tick"); -+ net.neoforged.neoforge.event.EventHooks.onPreLevelTick(serverlevel, p_129954_); ++ net.neoforged.neoforge.event.EventHooks.fireLevelTickPre(serverlevel, p_129954_); try { serverlevel.tick(p_129954_); @@ -158,7 +157,7 @@ serverlevel.fillReportDetails(crashreport); throw new ReportedException(crashreport); } -+ net.neoforged.neoforge.event.EventHooks.onPostLevelTick(serverlevel, p_129954_); ++ net.neoforged.neoforge.event.EventHooks.fireLevelTickPost(serverlevel, p_129954_); this.profiler.pop(); this.profiler.pop(); diff --git a/patches/net/minecraft/world/entity/player/Player.java.patch b/patches/net/minecraft/world/entity/player/Player.java.patch index a710798b92..530f8ebdf7 100644 --- a/patches/net/minecraft/world/entity/player/Player.java.patch +++ b/patches/net/minecraft/world/entity/player/Player.java.patch @@ -35,7 +35,7 @@ @Override public void tick() { -+ net.neoforged.neoforge.event.EventHooks.onPlayerPreTick(this); ++ net.neoforged.neoforge.event.EventHooks.firePlayerTickPre(this); this.noPhysics = this.isSpectator(); if (this.isSpectator()) { this.setOnGround(false); @@ -52,7 +52,7 @@ this.turtleHelmetTick(); this.cooldowns.tick(); this.updatePlayerPose(); -+ net.neoforged.neoforge.event.EventHooks.onPlayerPostTick(this); ++ net.neoforged.neoforge.event.EventHooks.firePlayerTickPost(this); } @Override diff --git a/src/main/java/net/neoforged/neoforge/capabilities/CapabilityHooks.java b/src/main/java/net/neoforged/neoforge/capabilities/CapabilityHooks.java index 7f9869a35e..7d53bf075c 100644 --- a/src/main/java/net/neoforged/neoforge/capabilities/CapabilityHooks.java +++ b/src/main/java/net/neoforged/neoforge/capabilities/CapabilityHooks.java @@ -20,8 +20,8 @@ import net.minecraft.world.level.block.entity.BlockEntityType; import net.neoforged.fml.ModLoader; import net.neoforged.neoforge.common.NeoForgeMod; -import net.neoforged.neoforge.event.TickEvent; import net.neoforged.neoforge.event.level.ChunkEvent; +import net.neoforged.neoforge.event.tick.LevelTickEvent; import net.neoforged.neoforge.fluids.capability.wrappers.FluidBucketWrapper; import net.neoforged.neoforge.items.VanillaHopperItemHandler; import net.neoforged.neoforge.items.wrapper.CombinedInvWrapper; @@ -152,20 +152,20 @@ else if (entity instanceof LivingEntity livingEntity) } public static void invalidateCapsOnChunkLoad(ChunkEvent.Load event) { - if (!event.getLevel().isClientSide()) { - ((ServerLevel) event.getLevel()).invalidateCapabilities(event.getChunk().getPos()); + if (event.getLevel() instanceof ServerLevel sl) { + sl.invalidateCapabilities(event.getChunk().getPos()); } } public static void invalidateCapsOnChunkUnload(ChunkEvent.Unload event) { - if (!event.getLevel().isClientSide()) { - ((ServerLevel) event.getLevel()).invalidateCapabilities(event.getChunk().getPos()); + if (event.getLevel() instanceof ServerLevel sl) { + sl.invalidateCapabilities(event.getChunk().getPos()); } } - public static void cleanCapabilityListenerReferencesOnTick(TickEvent.LevelTickEvent event) { - if (event.phase == TickEvent.Phase.END && event.side.isServer()) { - ((ServerLevel) event.level).cleanCapabilityListenerReferences(); + public static void cleanCapabilityListenerReferencesOnTick(LevelTickEvent.Post event) { + if (event.getLevel() instanceof ServerLevel sl) { + sl.cleanCapabilityListenerReferences(); } } } diff --git a/src/main/java/net/neoforged/neoforge/client/ClientHooks.java b/src/main/java/net/neoforged/neoforge/client/ClientHooks.java index 8d50223480..23cfa1d4de 100644 --- a/src/main/java/net/neoforged/neoforge/client/ClientHooks.java +++ b/src/main/java/net/neoforged/neoforge/client/ClientHooks.java @@ -134,6 +134,7 @@ import net.neoforged.neoforge.client.event.ClientPauseUpdatedEvent; import net.neoforged.neoforge.client.event.ClientPlayerChangeGameTypeEvent; import net.neoforged.neoforge.client.event.ClientPlayerNetworkEvent; +import net.neoforged.neoforge.client.event.ClientTickEvent; import net.neoforged.neoforge.client.event.ComputeFovModifierEvent; import net.neoforged.neoforge.client.event.CustomizeGuiOverlayEvent; import net.neoforged.neoforge.client.event.EntityRenderersEvent; @@ -149,6 +150,7 @@ import net.neoforged.neoforge.client.event.RegisterSpriteSourceTypesEvent; import net.neoforged.neoforge.client.event.RenderArmEvent; import net.neoforged.neoforge.client.event.RenderBlockScreenEffectEvent; +import net.neoforged.neoforge.client.event.RenderFrameEvent; import net.neoforged.neoforge.client.event.RenderHandEvent; import net.neoforged.neoforge.client.event.RenderHighlightEvent; import net.neoforged.neoforge.client.event.RenderLevelStageEvent; @@ -1003,4 +1005,40 @@ public static void initClientHooks(Minecraft mc, ReloadableResourceManager resou ItemDecoratorHandler.init(); PresetEditorManager.init(); } + + /** + * Fires {@link RenderFrameEvent.Pre}. Called just before {@link GameRenderer#render(float, long, boolean)} in {@link Minecraft#runTick(boolean)}. + *

+ * Fired before the profiler section for "gameRenderer" is started. + * + * @param partialTick The current partial tick + */ + public static void fireRenderFramePre(float partialTick) { + NeoForge.EVENT_BUS.post(new RenderFrameEvent.Pre(partialTick)); + } + + /** + * Fires {@link RenderFrameEvent.Post}. Called just after {@link GameRenderer#render(float, long, boolean)} in {@link Minecraft#runTick(boolean)}. + *

+ * Fired after the profiler section for "gameRenderer" is ended. + * + * @param partialTick The current partial tick + */ + public static void fireRenderFramePost(float partialRick) { + NeoForge.EVENT_BUS.post(new RenderFrameEvent.Post(partialRick)); + } + + /** + * Fires {@link ClientTickEvent.Pre}. Called from the head of {@link Minecraft#tick()}. + */ + public static void fireClientTickPre() { + NeoForge.EVENT_BUS.post(new ClientTickEvent.Pre()); + } + + /** + * Fires {@link ClientTickEvent.Post}. Called from the tail of {@link Minecraft#tick()}. + */ + public static void fireClientTickPost() { + NeoForge.EVENT_BUS.post(new ClientTickEvent.Post()); + } } diff --git a/src/main/java/net/neoforged/neoforge/client/event/ClientTickEvent.java b/src/main/java/net/neoforged/neoforge/client/event/ClientTickEvent.java new file mode 100644 index 0000000000..80341cb7b0 --- /dev/null +++ b/src/main/java/net/neoforged/neoforge/client/event/ClientTickEvent.java @@ -0,0 +1,36 @@ +/* + * Copyright (c) NeoForged and contributors + * SPDX-License-Identifier: LGPL-2.1-only + */ + +package net.neoforged.neoforge.client.event; + +import net.neoforged.bus.api.Event; + +/** + * Base class of the two client tick events. + * + * @see Pre + * @see Post + */ +public abstract class ClientTickEvent extends Event { + public ClientTickEvent() {} + + /** + * {@link ClientTickEvent.Pre} is fired once per client tick, before the client performs work for the current tick. + *

+ * This event only fires on the physical client. + */ + public static class Pre extends ClientTickEvent { + public Pre() {} + } + + /** + * {@link ClientTickEvent.Post} is fired once per client tick, after the client performs work for the current tick. + *

+ * This event only fires on the physical client. + */ + public static class Post extends ClientTickEvent { + public Post() {} + } +} diff --git a/src/main/java/net/neoforged/neoforge/client/event/RenderFrameEvent.java b/src/main/java/net/neoforged/neoforge/client/event/RenderFrameEvent.java new file mode 100644 index 0000000000..59cbd54a6a --- /dev/null +++ b/src/main/java/net/neoforged/neoforge/client/event/RenderFrameEvent.java @@ -0,0 +1,54 @@ +/* + * Copyright (c) NeoForged and contributors + * SPDX-License-Identifier: LGPL-2.1-only + */ + +package net.neoforged.neoforge.client.event; + +import net.minecraft.client.renderer.GameRenderer; +import net.neoforged.bus.api.Event; + +/** + * Base class of the two render frame events. + *

+ * These events can be used to setup and teardown global render state that must persist for the current frame. + * + * @see Pre + * @see Post + */ +public abstract class RenderFrameEvent extends Event { + protected final float partialTick; + + protected RenderFrameEvent(float partialTick) { + this.partialTick = partialTick; + } + + /** + * {@return the current partial tick, which is either the true partial tick or the pause partial tick, depending on if the game is paused} + */ + public float getPartialTick() { + return this.partialTick; + } + + /** + * {@link RenderFrameEvent.Pre} is fired once per frame, before the current frame is rendered via {@link GameRenderer#render(float, long, boolean)}. + *

+ * This event only fires on the physical client. + */ + public static class Pre extends RenderFrameEvent { + public Pre(float partialTick) { + super(partialTick); + } + } + + /** + * {@link RenderFrameEvent.Post} is fired once per frame, after the current frame is rendered via {@link GameRenderer#render(float, long, boolean)}. + *

+ * This event only fires on the physical client. + */ + public static class Post extends RenderFrameEvent { + public Post(float partialTick) { + super(partialTick); + } + } +} diff --git a/src/main/java/net/neoforged/neoforge/common/CommonHooks.java b/src/main/java/net/neoforged/neoforge/common/CommonHooks.java index ce5d91c41a..935fb33eb8 100644 --- a/src/main/java/net/neoforged/neoforge/common/CommonHooks.java +++ b/src/main/java/net/neoforged/neoforge/common/CommonHooks.java @@ -185,6 +185,7 @@ import net.neoforged.neoforge.event.entity.player.PlayerInteractEvent; import net.neoforged.neoforge.event.level.BlockEvent; import net.neoforged.neoforge.event.level.NoteBlockEvent; +import net.neoforged.neoforge.event.tick.LivingTickEvent; import net.neoforged.neoforge.fluids.FluidType; import net.neoforged.neoforge.registries.NeoForgeRegistries; import net.neoforged.neoforge.resource.ResourcePackLoader; @@ -234,8 +235,23 @@ public static LivingChangeTargetEvent onLivingChangeTarget(LivingEntity entity, return event; } - public static boolean onLivingTick(LivingEntity entity) { - return NeoForge.EVENT_BUS.post(new LivingEvent.LivingTickEvent(entity)).isCanceled(); + /** + * Fires {@link LivingTickEvent.Pre}. Called from the head of {@link LivingEntity#tick()}. + * + * @param entity The entity being ticked + * @return The event + */ + public static LivingTickEvent.Pre fireLivingTickPre(LivingEntity entity) { + return NeoForge.EVENT_BUS.post(new LivingTickEvent.Pre(entity)); + } + + /** + * Fires {@link LivingTickEvent.Post}. Called from the tail of {@link LivingEntity#tick()}. + * + * @param entity The entity being ticked + */ + public static void fireLivingTickPost(LivingEntity entity) { + NeoForge.EVENT_BUS.post(new LivingTickEvent.Post(entity)); } public static boolean onLivingAttack(LivingEntity entity, DamageSource src, float amount) { diff --git a/src/main/java/net/neoforged/neoforge/common/NeoForgeEventHandler.java b/src/main/java/net/neoforged/neoforge/common/NeoForgeEventHandler.java index 5c2b42b1cf..4397530fb4 100644 --- a/src/main/java/net/neoforged/neoforge/common/NeoForgeEventHandler.java +++ b/src/main/java/net/neoforged/neoforge/common/NeoForgeEventHandler.java @@ -30,11 +30,11 @@ import net.neoforged.neoforge.event.OnDatapackSyncEvent; import net.neoforged.neoforge.event.RegisterCommandsEvent; import net.neoforged.neoforge.event.TagsUpdatedEvent; -import net.neoforged.neoforge.event.TickEvent; import net.neoforged.neoforge.event.entity.EntityJoinLevelEvent; import net.neoforged.neoforge.event.entity.player.PlayerEvent; import net.neoforged.neoforge.event.level.ChunkEvent; import net.neoforged.neoforge.event.level.LevelEvent; +import net.neoforged.neoforge.event.tick.ServerTickEvent; import net.neoforged.neoforge.network.PacketDistributor; import net.neoforged.neoforge.network.payload.RegistryDataMapSyncPayload; import net.neoforged.neoforge.registries.DataMapLoader; @@ -70,14 +70,13 @@ public void onDimensionUnload(LevelEvent.Unload event) { } @SubscribeEvent - public void onServerTick(TickEvent.ServerTickEvent event) { - WorldWorkerManager.tick(event.phase == TickEvent.Phase.START); + public void preServerTick(ServerTickEvent.Pre event) { + WorldWorkerManager.tick(true); } @SubscribeEvent - public void checkSettings(TickEvent.ClientTickEvent event) { - //if (event.phase == Phase.END) - // CloudRenderer.updateCloudSettings(); + public void postServerTick(ServerTickEvent.Post event) { + WorldWorkerManager.tick(false); } @SubscribeEvent diff --git a/src/main/java/net/neoforged/neoforge/event/EventHooks.java b/src/main/java/net/neoforged/neoforge/event/EventHooks.java index a5972ce6ab..7dbc1227a7 100644 --- a/src/main/java/net/neoforged/neoforge/event/EventHooks.java +++ b/src/main/java/net/neoforged/neoforge/event/EventHooks.java @@ -15,6 +15,7 @@ import java.util.function.Consumer; import net.minecraft.advancements.AdvancementHolder; import net.minecraft.advancements.AdvancementProgress; +import net.minecraft.client.Minecraft; import net.minecraft.commands.CommandBuildContext; import net.minecraft.commands.CommandSourceStack; import net.minecraft.commands.Commands; @@ -93,7 +94,6 @@ import net.minecraft.world.phys.HitResult; import net.minecraft.world.phys.Vec3; import net.neoforged.bus.api.Event.Result; -import net.neoforged.fml.LogicalSide; import net.neoforged.fml.ModLoader; import net.neoforged.neoforge.common.EffectCure; import net.neoforged.neoforge.common.NeoForge; @@ -160,6 +160,9 @@ import net.neoforged.neoforge.event.level.PistonEvent; import net.neoforged.neoforge.event.level.SaplingGrowTreeEvent; import net.neoforged.neoforge.event.level.SleepFinishedTimeEvent; +import net.neoforged.neoforge.event.tick.LevelTickEvent; +import net.neoforged.neoforge.event.tick.PlayerTickEvent; +import net.neoforged.neoforge.event.tick.ServerTickEvent; import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.Nullable; @@ -809,44 +812,62 @@ public static void firePlayerSmeltedEvent(Player player, ItemStack smelted) { NeoForge.EVENT_BUS.post(new PlayerEvent.ItemSmeltedEvent(player, smelted)); } - public static void onRenderTickStart(float timer) { - NeoForge.EVENT_BUS.post(new TickEvent.RenderTickEvent(TickEvent.Phase.START, timer)); - } - - public static void onRenderTickEnd(float timer) { - NeoForge.EVENT_BUS.post(new TickEvent.RenderTickEvent(TickEvent.Phase.END, timer)); - } - - public static void onPlayerPreTick(Player player) { - NeoForge.EVENT_BUS.post(new TickEvent.PlayerTickEvent(TickEvent.Phase.START, player)); - } - - public static void onPlayerPostTick(Player player) { - NeoForge.EVENT_BUS.post(new TickEvent.PlayerTickEvent(TickEvent.Phase.END, player)); - } - - public static void onPreLevelTick(Level level, BooleanSupplier haveTime) { - NeoForge.EVENT_BUS.post(new TickEvent.LevelTickEvent(level.isClientSide ? LogicalSide.CLIENT : LogicalSide.SERVER, TickEvent.Phase.START, level, haveTime)); + /** + * Fires {@link PlayerTickEvent.Pre}. Called from the head of {@link Player#tick()}. + * + * @param player The player being ticked + */ + public static void firePlayerTickPre(Player player) { + NeoForge.EVENT_BUS.post(new PlayerTickEvent.Pre(player)); } - public static void onPostLevelTick(Level level, BooleanSupplier haveTime) { - NeoForge.EVENT_BUS.post(new TickEvent.LevelTickEvent(level.isClientSide ? LogicalSide.CLIENT : LogicalSide.SERVER, TickEvent.Phase.END, level, haveTime)); + /** + * Fires {@link PlayerTickEvent.Post}. Called from the tail of {@link Player#tick()}. + * + * @param player The player being ticked + */ + public static void firePlayerTickPost(Player player) { + NeoForge.EVENT_BUS.post(new PlayerTickEvent.Post(player)); } - public static void onPreClientTick() { - NeoForge.EVENT_BUS.post(new TickEvent.ClientTickEvent(TickEvent.Phase.START)); + /** + * Fires {@link LevelTickEvent.Pre}. Called from {@link Minecraft#tick()} and {@link MinecraftServer#tickChildren(BooleanSupplier)} just before the try block for level tick is entered. + * + * @param level The level being ticked + * @param haveTime The time supplier, indicating if there is remaining time to do work in the current tick. + */ + public static void fireLevelTickPre(Level level, BooleanSupplier haveTime) { + NeoForge.EVENT_BUS.post(new LevelTickEvent.Pre(haveTime, level)); } - public static void onPostClientTick() { - NeoForge.EVENT_BUS.post(new TickEvent.ClientTickEvent(TickEvent.Phase.END)); + /** + * Fires {@link LevelTickEvent.Post}. Called from {@link Minecraft#tick()} and {@link MinecraftServer#tickChildren(BooleanSupplier)} just after the try block for level tick is exited. + * + * @param level The level being ticked + * @param haveTime The time supplier, indicating if there is remaining time to do work in the current tick. + */ + public static void fireLevelTickPost(Level level, BooleanSupplier haveTime) { + NeoForge.EVENT_BUS.post(new LevelTickEvent.Post(haveTime, level)); } - public static void onPreServerTick(BooleanSupplier haveTime, MinecraftServer server) { - NeoForge.EVENT_BUS.post(new TickEvent.ServerTickEvent(TickEvent.Phase.START, haveTime, server)); + /** + * Fires {@link ServerTickEvent.Pre}. Called from the head of {@link MinecraftServer#tickServer(BooleanSupplier)}. + * + * @param haveTime The time supplier, indicating if there is remaining time to do work in the current tick. + * @param server The current server + */ + public static void fireServerTickPre(BooleanSupplier haveTime, MinecraftServer server) { + NeoForge.EVENT_BUS.post(new ServerTickEvent.Pre(haveTime, server)); } - public static void onPostServerTick(BooleanSupplier haveTime, MinecraftServer server) { - NeoForge.EVENT_BUS.post(new TickEvent.ServerTickEvent(TickEvent.Phase.END, haveTime, server)); + /** + * Fires {@link ServerTickEvent.Post}. Called from the tail of {@link MinecraftServer#tickServer(BooleanSupplier)}. + * + * @param haveTime The time supplier, indicating if there is remaining time to do work in the current tick. + * @param server The current server + */ + public static void fireServerTickPost(BooleanSupplier haveTime, MinecraftServer server) { + NeoForge.EVENT_BUS.post(new ServerTickEvent.Post(haveTime, server)); } private static final WeightedRandomList NO_SPAWNS = WeightedRandomList.create(); diff --git a/src/main/java/net/neoforged/neoforge/event/TickEvent.java b/src/main/java/net/neoforged/neoforge/event/TickEvent.java deleted file mode 100644 index 68a8cd8c5b..0000000000 --- a/src/main/java/net/neoforged/neoforge/event/TickEvent.java +++ /dev/null @@ -1,107 +0,0 @@ -/* - * Copyright (c) Forge Development LLC and contributors - * SPDX-License-Identifier: LGPL-2.1-only - */ - -package net.neoforged.neoforge.event; - -import java.util.function.BooleanSupplier; -import net.minecraft.server.MinecraftServer; -import net.minecraft.server.level.ServerPlayer; -import net.minecraft.world.entity.player.Player; -import net.minecraft.world.level.Level; -import net.neoforged.bus.api.Event; -import net.neoforged.fml.LogicalSide; - -public abstract class TickEvent extends Event { - public enum Type { - LEVEL, PLAYER, CLIENT, SERVER, RENDER; - } - - public enum Phase { - START, END; - } - - public final Type type; - public final LogicalSide side; - public final Phase phase; - - public TickEvent(Type type, LogicalSide side, Phase phase) { - this.type = type; - this.side = side; - this.phase = phase; - } - - public static class ServerTickEvent extends TickEvent { - private final BooleanSupplier haveTime; - private final MinecraftServer server; - - public ServerTickEvent(Phase phase, BooleanSupplier haveTime, MinecraftServer server) { - super(Type.SERVER, LogicalSide.SERVER, phase); - this.haveTime = haveTime; - this.server = server; - } - - /** - * @return {@code true} whether the server has enough time to perform any - * additional tasks (usually IO related) during the current tick, - * otherwise {@code false} - */ - public boolean haveTime() { - return this.haveTime.getAsBoolean(); - } - - /** - * {@return the server instance} - */ - public MinecraftServer getServer() { - return server; - } - } - - public static class ClientTickEvent extends TickEvent { - public ClientTickEvent(Phase phase) { - super(Type.CLIENT, LogicalSide.CLIENT, phase); - } - } - - public static class LevelTickEvent extends TickEvent { - public final Level level; - private final BooleanSupplier haveTime; - - public LevelTickEvent(LogicalSide side, Phase phase, Level level, BooleanSupplier haveTime) { - super(Type.LEVEL, side, phase); - this.level = level; - this.haveTime = haveTime; - } - - /** - * @return {@code true} whether the server has enough time to perform any - * additional tasks (usually IO related) during the current tick, - * otherwise {@code false} - * - * @see ServerTickEvent#haveTime() - */ - public boolean haveTime() { - return this.haveTime.getAsBoolean(); - } - } - - public static class PlayerTickEvent extends TickEvent { - public final Player player; - - public PlayerTickEvent(Phase phase, Player player) { - super(Type.PLAYER, player instanceof ServerPlayer ? LogicalSide.SERVER : LogicalSide.CLIENT, phase); - this.player = player; - } - } - - public static class RenderTickEvent extends TickEvent { - public final float renderTickTime; - - public RenderTickEvent(Phase phase, float renderTickTime) { - super(Type.RENDER, LogicalSide.CLIENT, phase); - this.renderTickTime = renderTickTime; - } - } -} diff --git a/src/main/java/net/neoforged/neoforge/event/entity/living/LivingEvent.java b/src/main/java/net/neoforged/neoforge/event/entity/living/LivingEvent.java index a3af4493c5..872e8ef5bd 100644 --- a/src/main/java/net/neoforged/neoforge/event/entity/living/LivingEvent.java +++ b/src/main/java/net/neoforged/neoforge/event/entity/living/LivingEvent.java @@ -34,24 +34,6 @@ public LivingEntity getEntity() { return livingEntity; } - /** - * LivingUpdateEvent is fired when a LivingEntity is ticked in {@link LivingEntity#tick()}.
- *
- * This event is fired via the {@link CommonHooks#onLivingTick(LivingEntity)}.
- *
- * This event is {@link ICancellableEvent}.
- * If this event is canceled, the Entity does not update.
- *
- * This event does not have a result. {@link HasResult}
- *
- * This event is fired on the {@link NeoForge#EVENT_BUS}. - **/ - public static class LivingTickEvent extends LivingEvent implements ICancellableEvent { - public LivingTickEvent(LivingEntity e) { - super(e); - } - } - /** * LivingJumpEvent is fired when an Entity jumps.
* This event is fired whenever an Entity jumps in diff --git a/src/main/java/net/neoforged/neoforge/event/tick/LevelTickEvent.java b/src/main/java/net/neoforged/neoforge/event/tick/LevelTickEvent.java new file mode 100644 index 0000000000..d3f2af47a5 --- /dev/null +++ b/src/main/java/net/neoforged/neoforge/event/tick/LevelTickEvent.java @@ -0,0 +1,70 @@ +/* + * Copyright (c) NeoForged and contributors + * SPDX-License-Identifier: LGPL-2.1-only + */ + +package net.neoforged.neoforge.event.tick; + +import java.util.function.BooleanSupplier; +import net.minecraft.client.multiplayer.ClientLevel; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.world.level.Level; +import net.neoforged.bus.api.Event; +import org.jetbrains.annotations.ApiStatus; + +/** + * Base class of the two level tick events. + * + * @see Pre + * @see Post + */ +public abstract class LevelTickEvent extends Event { + private final BooleanSupplier hasTime; + private final Level level; + + protected LevelTickEvent(BooleanSupplier hasTime, Level level) { + this.hasTime = hasTime; + this.level = level; + } + + /** + * On the server, returns true if the server has enough time to perform any + * additional tasks (usually IO related) during the current tick. + * + * On the client, always returns true. + */ + public boolean hasTime() { + return this.hasTime.getAsBoolean(); + } + + /** + * {@return the level being ticked} + */ + public Level getLevel() { + return level; + } + + /** + * {@link LevelTickEvent.Pre} is fired once per game tick, per level, before the level performs work for the current tick. + *

+ * This event fires on both the logical client and logical server, for {@link ClientLevel} and {@link ServerLevel} respectively. + */ + public static class Pre extends LevelTickEvent { + @ApiStatus.Internal + public Pre(BooleanSupplier haveTime, Level level) { + super(haveTime, level); + } + } + + /** + * {@link LevelTickEvent.Post} is fired once per game tick, per level, after the level performs work for the current tick. + *

+ * This event fires on both the logical client and logical server, for {@link ClientLevel} and {@link ServerLevel} respectively. + */ + public static class Post extends LevelTickEvent { + @ApiStatus.Internal + public Post(BooleanSupplier haveTime, Level level) { + super(haveTime, level); + } + } +} diff --git a/src/main/java/net/neoforged/neoforge/event/tick/LivingTickEvent.java b/src/main/java/net/neoforged/neoforge/event/tick/LivingTickEvent.java new file mode 100644 index 0000000000..6fdc7cad1b --- /dev/null +++ b/src/main/java/net/neoforged/neoforge/event/tick/LivingTickEvent.java @@ -0,0 +1,58 @@ +/* + * Copyright (c) NeoForged and contributors + * SPDX-License-Identifier: LGPL-2.1-only + */ + +package net.neoforged.neoforge.event.tick; + +import net.minecraft.world.entity.LivingEntity; +import net.neoforged.bus.api.ICancellableEvent; +import net.neoforged.neoforge.event.entity.living.LivingEvent; +import org.jetbrains.annotations.ApiStatus; + +/** + * Base class of the two player tick events. + * + * @see Pre + * @see Post + */ +public abstract class LivingTickEvent extends LivingEvent { + @ApiStatus.Internal + public LivingTickEvent(LivingEntity entity) { + super(entity); + } + + /** + * {@link LivingTickEvent.Pre} is fired once per game tick, per entity, before the entity performs work for the current tick. + *

+ * This event fires on both the logical server and logical client. + */ + public static class Pre extends LivingTickEvent implements ICancellableEvent { + public Pre(LivingEntity entity) { + super(entity); + } + + /** + * Cancels this event, preventing the current tick from being executed for the entity. + *

+ * Additionally, if this event is canceled, then {@link LivingTickEvent.Post} will not be fired for the current tick. + */ + @Override + public void setCanceled(boolean canceled) { + ICancellableEvent.super.setCanceled(canceled); + } + } + + /** + * {@link LivingTickEvent.Post} is fired once per game tick, per entity, after the entity performs work for the current tick. + *

+ * If {@link LivingTickEvent.Pre} was canceled for the current tick, this event will not fire. + *

+ * This event fires on both the logical server and logical client. + */ + public static class Post extends LivingTickEvent { + public Post(LivingEntity entity) { + super(entity); + } + } +} diff --git a/src/main/java/net/neoforged/neoforge/event/tick/PlayerTickEvent.java b/src/main/java/net/neoforged/neoforge/event/tick/PlayerTickEvent.java new file mode 100644 index 0000000000..f05e5eb0a0 --- /dev/null +++ b/src/main/java/net/neoforged/neoforge/event/tick/PlayerTickEvent.java @@ -0,0 +1,50 @@ +/* + * Copyright (c) NeoForged and contributors + * SPDX-License-Identifier: LGPL-2.1-only + */ + +package net.neoforged.neoforge.event.tick; + +import net.minecraft.world.entity.player.Player; +import net.neoforged.neoforge.event.entity.player.PlayerEvent; +import org.jetbrains.annotations.ApiStatus; + +/** + * Base class of the two player tick events. + * + * @see Pre + * @see Post + */ +public abstract class PlayerTickEvent extends PlayerEvent { + protected PlayerTickEvent(Player player) { + super(player); + } + + /** + * {@link PlayerTickEvent.Pre} is fired once per game tick, per player, before the player performs work for the current tick. + *

+ * This event will fire on both the logical server and logical client, for all subclasses of {@link Player} on their respective sides. + *

+ * As such, be sure to check {@link Level#isClientSide()} before performing any operations. + */ + public static class Pre extends PlayerTickEvent { + @ApiStatus.Internal + public Pre(Player player) { + super(player); + } + } + + /** + * {@link PlayerTickEvent.Post} is fired once per game tick, per player, after the player performs work for the current tick. + *

+ * This event will fire on both the logical server and logical client, for all subclasses of {@link Player} on their respective sides. + *

+ * As such, be sure to check {@link Level#isClientSide()} before performing any operations. + */ + public static class Post extends PlayerTickEvent { + @ApiStatus.Internal + public Post(Player player) { + super(player); + } + } +} diff --git a/src/main/java/net/neoforged/neoforge/event/tick/ServerTickEvent.java b/src/main/java/net/neoforged/neoforge/event/tick/ServerTickEvent.java new file mode 100644 index 0000000000..ecaed07ffc --- /dev/null +++ b/src/main/java/net/neoforged/neoforge/event/tick/ServerTickEvent.java @@ -0,0 +1,67 @@ +/* + * Copyright (c) NeoForged and contributors + * SPDX-License-Identifier: LGPL-2.1-only + */ + +package net.neoforged.neoforge.event.tick; + +import java.util.function.BooleanSupplier; +import net.minecraft.server.MinecraftServer; +import net.neoforged.bus.api.Event; +import org.jetbrains.annotations.ApiStatus; + +/** + * Base class of the two server tick events. + * + * @see Pre + * @see Post + */ +public abstract class ServerTickEvent extends Event { + private final BooleanSupplier hasTime; + private final MinecraftServer server; + + protected ServerTickEvent(BooleanSupplier hasTime, MinecraftServer server) { + this.hasTime = hasTime; + this.server = server; + } + + /** + * {@return true if the server has enough time to perform any + * additional tasks (usually IO related) during the current tick, + * otherwise false} + */ + public boolean hasTime() { + return this.hasTime.getAsBoolean(); + } + + /** + * {@return the server instance} + */ + public MinecraftServer getServer() { + return server; + } + + /** + * {@link ServerTickEvent.Pre} is fired once per server tick, before the server performs work for the current tick. + *

+ * This event only fires on the logical server. + */ + public static class Pre extends ServerTickEvent { + @ApiStatus.Internal + public Pre(BooleanSupplier haveTime, MinecraftServer server) { + super(haveTime, server); + } + } + + /** + * {@link ServerTickEvent.Post} is fired once per server tick, after the server performs work for the current tick. + *

+ * This event only fires on the logical server. + */ + public static class Post extends ServerTickEvent { + @ApiStatus.Internal + public Post(BooleanSupplier haveTime, MinecraftServer server) { + super(haveTime, server); + } + } +} diff --git a/src/main/java/net/neoforged/neoforge/event/tick/package-info.java b/src/main/java/net/neoforged/neoforge/event/tick/package-info.java new file mode 100644 index 0000000000..3d0ece4888 --- /dev/null +++ b/src/main/java/net/neoforged/neoforge/event/tick/package-info.java @@ -0,0 +1,13 @@ +/* + * Copyright (c) NeoForged and contributors + * SPDX-License-Identifier: LGPL-2.1-only + */ + +@FieldsAreNonnullByDefault +@MethodsReturnNonnullByDefault +@ParametersAreNonnullByDefault +package net.neoforged.neoforge.event.tick; + +import javax.annotation.ParametersAreNonnullByDefault; +import net.minecraft.FieldsAreNonnullByDefault; +import net.minecraft.MethodsReturnNonnullByDefault; diff --git a/tests/src/main/java/net/neoforged/neoforge/debug/client/ClientTests.java b/tests/src/main/java/net/neoforged/neoforge/debug/client/ClientTests.java index e117d3ec74..290dadd9d6 100644 --- a/tests/src/main/java/net/neoforged/neoforge/debug/client/ClientTests.java +++ b/tests/src/main/java/net/neoforged/neoforge/debug/client/ClientTests.java @@ -24,9 +24,9 @@ import net.minecraft.world.phys.Vec3; import net.neoforged.api.distmarker.Dist; import net.neoforged.neoforge.client.event.ClientChatEvent; +import net.neoforged.neoforge.client.event.ClientTickEvent; import net.neoforged.neoforge.client.event.RegisterKeyMappingsEvent; import net.neoforged.neoforge.common.data.LanguageProvider; -import net.neoforged.neoforge.event.TickEvent; import net.neoforged.testframework.DynamicTest; import net.neoforged.testframework.annotation.ForEachTest; import net.neoforged.testframework.annotation.TestHolder; @@ -63,8 +63,7 @@ static void keyMappingTest(final DynamicTest test) { event.register(stickKey); }); - test.eventListeners().forge().addListener((final TickEvent.ClientTickEvent event) -> { - if (event.phase != TickEvent.Phase.START) return; + test.eventListeners().forge().addListener((ClientTickEvent.Pre event) -> { if (stickKey.consumeClick()) { Player player = Minecraft.getInstance().player; if (player != null && player.getMainHandItem().is(Items.STICK)) { diff --git a/tests/src/main/java/net/neoforged/neoforge/debug/level/LevelTests.java b/tests/src/main/java/net/neoforged/neoforge/debug/level/LevelTests.java index cd1a005c47..0bfd2a8609 100644 --- a/tests/src/main/java/net/neoforged/neoforge/debug/level/LevelTests.java +++ b/tests/src/main/java/net/neoforged/neoforge/debug/level/LevelTests.java @@ -9,7 +9,7 @@ import net.minecraft.server.level.ServerPlayer; import net.minecraft.world.level.GameRules; import net.minecraft.world.level.GameType; -import net.neoforged.neoforge.event.entity.living.LivingEvent; +import net.neoforged.neoforge.event.tick.LivingTickEvent; import net.neoforged.testframework.DynamicTest; import net.neoforged.testframework.annotation.ForEachTest; import net.neoforged.testframework.annotation.TestHolder; @@ -49,7 +49,7 @@ static void customGameRule(final DynamicTest test) { final GameRules.Key booleanGameRule = GameRules.register("%s:custom_boolean_game_rule".formatted(test.createModId()), GameRules.Category.MISC, GameRules.BooleanValue.create(true)); final GameRules.Key integerGameRule = GameRules.register("%s:custom_integer_game_rule".formatted(test.createModId()), GameRules.Category.MISC, GameRules.IntegerValue.create(1337)); - test.eventListeners().forge().addListener((final LivingEvent.LivingTickEvent event) -> { + test.eventListeners().forge().addListener((LivingTickEvent.Pre event) -> { if (event.getEntity() instanceof ServerPlayer player && player.getGameProfile().getName().equals("test-mock-player")) { if (player.level().getGameRules().getBoolean(booleanGameRule)) { player.setHealth(player.getHealth() - player.level().getGameRules().getInt(integerGameRule)); diff --git a/tests/src/main/java/net/neoforged/neoforge/oldtest/client/rendering/CustomParticleTypeTest.java b/tests/src/main/java/net/neoforged/neoforge/oldtest/client/rendering/CustomParticleTypeTest.java index d8770eff1c..182c9427a1 100644 --- a/tests/src/main/java/net/neoforged/neoforge/oldtest/client/rendering/CustomParticleTypeTest.java +++ b/tests/src/main/java/net/neoforged/neoforge/oldtest/client/rendering/CustomParticleTypeTest.java @@ -18,7 +18,7 @@ import net.neoforged.bus.api.SubscribeEvent; import net.neoforged.fml.common.EventBusSubscriber; import net.neoforged.fml.common.Mod; -import net.neoforged.neoforge.event.TickEvent; +import net.neoforged.neoforge.client.event.ClientTickEvent; @Mod(CustomParticleTypeTest.MOD_ID) public class CustomParticleTypeTest { @@ -77,8 +77,8 @@ public ParticleRenderType getRenderType() { } @SubscribeEvent - public static void onClientTick(final TickEvent.ClientTickEvent event) { - if (!ENABLED || event.phase != TickEvent.Phase.START) { + public static void onClientTick(ClientTickEvent.Pre event) { + if (!ENABLED) { return; } From 74344373b63712bbf07a6a8f53b074769f5d4d55 Mon Sep 17 00:00:00 2001 From: Brennan Ward <3682588+Shadows-of-Fire@users.noreply.github.com> Date: Sun, 21 Apr 2024 18:12:25 -0700 Subject: [PATCH 2/5] Update entity tick semantics --- .../client/multiplayer/ClientLevel.java.patch | 10 ++++-- .../server/level/ServerLevel.java.patch | 18 ++++++---- .../minecraft/world/entity/Entity.java.patch | 33 +++++-------------- .../world/entity/LivingEntity.java.patch | 8 ----- .../neoforge/common/CommonHooks.java | 21 +----------- .../common/extensions/IEntityExtension.java | 4 --- .../neoforged/neoforge/event/EventHooks.java | 20 +++++++++++ ...ingTickEvent.java => EntityTickEvent.java} | 29 ++++++++-------- .../neoforge/event/tick/PlayerTickEvent.java | 17 ++++++++-- .../neoforge/debug/level/LevelTests.java | 4 +-- 10 files changed, 79 insertions(+), 85 deletions(-) rename src/main/java/net/neoforged/neoforge/event/tick/{LivingTickEvent.java => EntityTickEvent.java} (61%) diff --git a/patches/net/minecraft/client/multiplayer/ClientLevel.java.patch b/patches/net/minecraft/client/multiplayer/ClientLevel.java.patch index 83dd22e286..50fe9d1fef 100644 --- a/patches/net/minecraft/client/multiplayer/ClientLevel.java.patch +++ b/patches/net/minecraft/client/multiplayer/ClientLevel.java.patch @@ -25,14 +25,18 @@ } public void queueLightUpdate(Runnable p_194172_) { -@@ -282,6 +_,7 @@ +@@ -282,7 +_,10 @@ p_104640_.setOldPosAndRot(); p_104640_.tickCount++; this.getProfiler().push(() -> BuiltInRegistries.ENTITY_TYPE.getKey(p_104640_.getType()).toString()); -+ if (p_104640_.canUpdate()) - p_104640_.tick(); +- p_104640_.tick(); ++ // Neo: Permit cancellation of Entity#tick via EntityTickEvent.Pre ++ if (!net.neoforged.neoforge.event.EventHooks.fireEntityTickPre(p_104640_).isCanceled()) { ++ p_104640_.tick(); ++ } this.getProfiler().pop(); + for (Entity entity : p_104640_.getPassengers()) { @@ -330,8 +_,10 @@ } diff --git a/patches/net/minecraft/server/level/ServerLevel.java.patch b/patches/net/minecraft/server/level/ServerLevel.java.patch index eb3dede221..71bfa4bf8d 100644 --- a/patches/net/minecraft/server/level/ServerLevel.java.patch +++ b/patches/net/minecraft/server/level/ServerLevel.java.patch @@ -79,14 +79,18 @@ } } -@@ -774,6 +_,7 @@ - ProfilerFiller profilerfiller = this.getProfiler(); - profilerfiller.push(() -> BuiltInRegistries.ENTITY_TYPE.getKey(p_8664_.getType()).toString()); - profilerfiller.incrementCounter("tickPassenger"); -+ if (p_8664_.canUpdate()) - p_8664_.rideTick(); - profilerfiller.pop(); +@@ -757,7 +_,10 @@ + p_8648_.tickCount++; + this.getProfiler().push(() -> BuiltInRegistries.ENTITY_TYPE.getKey(p_8648_.getType()).toString()); + profilerfiller.incrementCounter("tickNonPassenger"); +- p_8648_.tick(); ++ // Neo: Permit cancellation of Entity#tick via EntityTickEvent.Pre ++ if (!net.neoforged.neoforge.event.EventHooks.fireEntityTickPre(p_8648_).isCanceled()) { ++ p_8648_.tick(); ++ } + this.getProfiler().pop(); + for (Entity entity : p_8648_.getPassengers()) { @@ -806,6 +_,7 @@ } else { this.entityManager.autoSave(); diff --git a/patches/net/minecraft/world/entity/Entity.java.patch b/patches/net/minecraft/world/entity/Entity.java.patch index fed6996757..624d488e13 100644 --- a/patches/net/minecraft/world/entity/Entity.java.patch +++ b/patches/net/minecraft/world/entity/Entity.java.patch @@ -198,15 +198,6 @@ } public void moveRelative(float p_19921_, Vec3 p_19922_) { -@@ -1645,6 +_,8 @@ - p_20241_.putBoolean("HasVisualFire", this.hasVisualFire); - } - -+ p_20241_.putBoolean("CanUpdate", canUpdate); -+ - if (!this.tags.isEmpty()) { - ListTag listtag = new ListTag(); - @@ -1655,6 +_,10 @@ p_20241_.put("Tags", listtag); } @@ -218,12 +209,11 @@ this.addAdditionalSaveData(p_20241_); if (this.isVehicle()) { ListTag listtag1 = new ListTag(); -@@ -1735,6 +_,9 @@ +@@ -1735,6 +_,8 @@ this.setGlowingTag(p_20259_.getBoolean("Glowing")); this.setTicksFrozen(p_20259_.getInt("TicksFrozen")); this.hasVisualFire = p_20259_.getBoolean("HasVisualFire"); + if (p_20259_.contains("NeoForgeData", 10)) persistentData = p_20259_.getCompound("NeoForgeData"); -+ if (p_20259_.contains("CanUpdate", 99)) this.canUpdate(p_20259_.getBoolean("CanUpdate")); + if (p_20259_.contains(ATTACHMENTS_NBT_KEY, net.minecraft.nbt.Tag.TAG_COMPOUND)) deserializeAttachments(registryAccess(), p_20259_.getCompound(ATTACHMENTS_NBT_KEY)); if (p_20259_.contains("Tags", 9)) { this.tags.clear(); @@ -237,14 +227,18 @@ this.level().addFreshEntity(itementity); return itementity; } -@@ -1865,6 +_,7 @@ +@@ -1865,7 +_,10 @@ public void rideTick() { this.setDeltaMovement(Vec3.ZERO); -+ if (canUpdate()) - this.tick(); +- this.tick(); ++ // Neo: Permit cancellation of Entity#tick via EntityTickEvent.Pre ++ if (!net.neoforged.neoforge.event.EventHooks.fireEntityTickPre(this).isCanceled()) { ++ this.tick(); ++ } if (this.isPassenger()) { this.getVehicle().positionRider(this); + } @@ -1923,6 +_,7 @@ } } @@ -495,22 +489,13 @@ } public void checkDespawn() { -@@ -3424,6 +_,126 @@ +@@ -3424,6 +_,117 @@ public boolean mayInteract(Level p_146843_, BlockPos p_146844_) { return true; } + + /* ================================== Forge Start =====================================*/ + -+ private boolean canUpdate = true; -+ @Override -+ public void canUpdate(boolean value) { -+ this.canUpdate = value; -+ } -+ @Override -+ public boolean canUpdate() { -+ return this.canUpdate; -+ } + @Nullable + private java.util.Collection captureDrops = null; + @Override diff --git a/patches/net/minecraft/world/entity/LivingEntity.java.patch b/patches/net/minecraft/world/entity/LivingEntity.java.patch index e886785c4d..e20f82d76a 100644 --- a/patches/net/minecraft/world/entity/LivingEntity.java.patch +++ b/patches/net/minecraft/world/entity/LivingEntity.java.patch @@ -430,14 +430,6 @@ d2 = 0.0; } -@@ -2334,6 +_,7 @@ - - @Override - public void tick() { -+ if (net.neoforged.neoforge.common.CommonHooks.onLivingTick(this)) return; - super.tick(); - this.updatingUsingItem(); - this.updateSwimAmount(); @@ -2483,6 +_,7 @@ }; ItemStack itemstack1 = this.getItemBySlot(equipmentslot); diff --git a/src/main/java/net/neoforged/neoforge/common/CommonHooks.java b/src/main/java/net/neoforged/neoforge/common/CommonHooks.java index 935fb33eb8..f17f5a0a1a 100644 --- a/src/main/java/net/neoforged/neoforge/common/CommonHooks.java +++ b/src/main/java/net/neoforged/neoforge/common/CommonHooks.java @@ -185,7 +185,7 @@ import net.neoforged.neoforge.event.entity.player.PlayerInteractEvent; import net.neoforged.neoforge.event.level.BlockEvent; import net.neoforged.neoforge.event.level.NoteBlockEvent; -import net.neoforged.neoforge.event.tick.LivingTickEvent; +import net.neoforged.neoforge.event.tick.EntityTickEvent; import net.neoforged.neoforge.fluids.FluidType; import net.neoforged.neoforge.registries.NeoForgeRegistries; import net.neoforged.neoforge.resource.ResourcePackLoader; @@ -235,25 +235,6 @@ public static LivingChangeTargetEvent onLivingChangeTarget(LivingEntity entity, return event; } - /** - * Fires {@link LivingTickEvent.Pre}. Called from the head of {@link LivingEntity#tick()}. - * - * @param entity The entity being ticked - * @return The event - */ - public static LivingTickEvent.Pre fireLivingTickPre(LivingEntity entity) { - return NeoForge.EVENT_BUS.post(new LivingTickEvent.Pre(entity)); - } - - /** - * Fires {@link LivingTickEvent.Post}. Called from the tail of {@link LivingEntity#tick()}. - * - * @param entity The entity being ticked - */ - public static void fireLivingTickPost(LivingEntity entity) { - NeoForge.EVENT_BUS.post(new LivingTickEvent.Post(entity)); - } - public static boolean onLivingAttack(LivingEntity entity, DamageSource src, float amount) { return entity instanceof Player || !NeoForge.EVENT_BUS.post(new LivingAttackEvent(entity, src, amount)).isCanceled(); } diff --git a/src/main/java/net/neoforged/neoforge/common/extensions/IEntityExtension.java b/src/main/java/net/neoforged/neoforge/common/extensions/IEntityExtension.java index 394586976a..f6b89e5c24 100644 --- a/src/main/java/net/neoforged/neoforge/common/extensions/IEntityExtension.java +++ b/src/main/java/net/neoforged/neoforge/common/extensions/IEntityExtension.java @@ -54,10 +54,6 @@ default CompoundTag serializeNBT(HolderLookup.Provider provider) { return self().saveWithoutId(ret); } - boolean canUpdate(); - - void canUpdate(boolean value); - @Nullable Collection captureDrops(); diff --git a/src/main/java/net/neoforged/neoforge/event/EventHooks.java b/src/main/java/net/neoforged/neoforge/event/EventHooks.java index 7dbc1227a7..8c92a3ffc8 100644 --- a/src/main/java/net/neoforged/neoforge/event/EventHooks.java +++ b/src/main/java/net/neoforged/neoforge/event/EventHooks.java @@ -160,6 +160,7 @@ import net.neoforged.neoforge.event.level.PistonEvent; import net.neoforged.neoforge.event.level.SaplingGrowTreeEvent; import net.neoforged.neoforge.event.level.SleepFinishedTimeEvent; +import net.neoforged.neoforge.event.tick.EntityTickEvent; import net.neoforged.neoforge.event.tick.LevelTickEvent; import net.neoforged.neoforge.event.tick.PlayerTickEvent; import net.neoforged.neoforge.event.tick.ServerTickEvent; @@ -812,6 +813,25 @@ public static void firePlayerSmeltedEvent(Player player, ItemStack smelted) { NeoForge.EVENT_BUS.post(new PlayerEvent.ItemSmeltedEvent(player, smelted)); } + /** + * Fires {@link EntityTickEvent.Pre}. Called from the head of {@link LivingEntity#tick()}. + * + * @param entity The entity being ticked + * @return The event + */ + public static EntityTickEvent.Pre fireEntityTickPre(Entity entity) { + return NeoForge.EVENT_BUS.post(new EntityTickEvent.Pre(entity)); + } + + /** + * Fires {@link EntityTickEvent.Post}. Called from the tail of {@link LivingEntity#tick()}. + * + * @param entity The entity being ticked + */ + public static void fireEntityTickPost(Entity entity) { + NeoForge.EVENT_BUS.post(new EntityTickEvent.Post(entity)); + } + /** * Fires {@link PlayerTickEvent.Pre}. Called from the head of {@link Player#tick()}. * diff --git a/src/main/java/net/neoforged/neoforge/event/tick/LivingTickEvent.java b/src/main/java/net/neoforged/neoforge/event/tick/EntityTickEvent.java similarity index 61% rename from src/main/java/net/neoforged/neoforge/event/tick/LivingTickEvent.java rename to src/main/java/net/neoforged/neoforge/event/tick/EntityTickEvent.java index 6fdc7cad1b..968ff21e81 100644 --- a/src/main/java/net/neoforged/neoforge/event/tick/LivingTickEvent.java +++ b/src/main/java/net/neoforged/neoforge/event/tick/EntityTickEvent.java @@ -5,37 +5,38 @@ package net.neoforged.neoforge.event.tick; -import net.minecraft.world.entity.LivingEntity; -import net.neoforged.bus.api.ICancellableEvent; -import net.neoforged.neoforge.event.entity.living.LivingEvent; import org.jetbrains.annotations.ApiStatus; +import net.minecraft.world.entity.Entity; +import net.neoforged.bus.api.ICancellableEvent; +import net.neoforged.neoforge.event.entity.EntityEvent; + /** - * Base class of the two player tick events. + * Base class of the two entity tick events. * * @see Pre * @see Post */ -public abstract class LivingTickEvent extends LivingEvent { +public abstract class EntityTickEvent extends EntityEvent { @ApiStatus.Internal - public LivingTickEvent(LivingEntity entity) { + public EntityTickEvent(Entity entity) { super(entity); } /** - * {@link LivingTickEvent.Pre} is fired once per game tick, per entity, before the entity performs work for the current tick. + * {@link EntityTickEvent.Pre} is fired once per game tick, per entity, before the entity performs work for the current tick. *

* This event fires on both the logical server and logical client. */ - public static class Pre extends LivingTickEvent implements ICancellableEvent { - public Pre(LivingEntity entity) { + public static class Pre extends EntityTickEvent implements ICancellableEvent { + public Pre(Entity entity) { super(entity); } /** * Cancels this event, preventing the current tick from being executed for the entity. *

- * Additionally, if this event is canceled, then {@link LivingTickEvent.Post} will not be fired for the current tick. + * Additionally, if this event is canceled, then {@link EntityTickEvent.Post} will not be fired for the current tick. */ @Override public void setCanceled(boolean canceled) { @@ -44,14 +45,14 @@ public void setCanceled(boolean canceled) { } /** - * {@link LivingTickEvent.Post} is fired once per game tick, per entity, after the entity performs work for the current tick. + * {@link EntityTickEvent.Post} is fired once per game tick, per entity, after the entity performs work for the current tick. *

- * If {@link LivingTickEvent.Pre} was canceled for the current tick, this event will not fire. + * If {@link EntityTickEvent.Pre} was canceled for the current tick, this event will not fire. *

* This event fires on both the logical server and logical client. */ - public static class Post extends LivingTickEvent { - public Post(LivingEntity entity) { + public static class Post extends EntityTickEvent { + public Post(Entity entity) { super(entity); } } diff --git a/src/main/java/net/neoforged/neoforge/event/tick/PlayerTickEvent.java b/src/main/java/net/neoforged/neoforge/event/tick/PlayerTickEvent.java index f05e5eb0a0..a84cf29b5c 100644 --- a/src/main/java/net/neoforged/neoforge/event/tick/PlayerTickEvent.java +++ b/src/main/java/net/neoforged/neoforge/event/tick/PlayerTickEvent.java @@ -5,12 +5,23 @@ package net.neoforged.neoforge.event.tick; +import org.jetbrains.annotations.ApiStatus; + +import net.minecraft.server.level.ServerPlayer; +import net.minecraft.server.network.ServerGamePacketListenerImpl; +import net.minecraft.world.entity.Entity; import net.minecraft.world.entity.player.Player; +import net.minecraft.world.level.Level; import net.neoforged.neoforge.event.entity.player.PlayerEvent; -import org.jetbrains.annotations.ApiStatus; /** * Base class of the two player tick events. + *

+ * These events are separate from {@link LivingTickEvent} due to the semantics of player ticks. + * On the client, players tick from the usual {@link Entity#tick()} method, but on the server, they rely + * on {@link ServerPlayer#doTick()} which is called from {@link ServerGamePacketListenerImpl#tick()}. + *

+ * Use of these events should only be necessary if you rely on this specific timing. * * @see Pre * @see Post @@ -23,7 +34,7 @@ protected PlayerTickEvent(Player player) { /** * {@link PlayerTickEvent.Pre} is fired once per game tick, per player, before the player performs work for the current tick. *

- * This event will fire on both the logical server and logical client, for all subclasses of {@link Player} on their respective sides. + * This event will fire on both the logical server and logical client, for subclasses of {@link Player} on their respective sides. *

* As such, be sure to check {@link Level#isClientSide()} before performing any operations. */ @@ -37,7 +48,7 @@ public Pre(Player player) { /** * {@link PlayerTickEvent.Post} is fired once per game tick, per player, after the player performs work for the current tick. *

- * This event will fire on both the logical server and logical client, for all subclasses of {@link Player} on their respective sides. + * This event will fire on both the logical server and logical client, for subclasses of {@link Player} on their respective sides. *

* As such, be sure to check {@link Level#isClientSide()} before performing any operations. */ diff --git a/tests/src/main/java/net/neoforged/neoforge/debug/level/LevelTests.java b/tests/src/main/java/net/neoforged/neoforge/debug/level/LevelTests.java index 0bfd2a8609..0310ba7cdb 100644 --- a/tests/src/main/java/net/neoforged/neoforge/debug/level/LevelTests.java +++ b/tests/src/main/java/net/neoforged/neoforge/debug/level/LevelTests.java @@ -9,7 +9,7 @@ import net.minecraft.server.level.ServerPlayer; import net.minecraft.world.level.GameRules; import net.minecraft.world.level.GameType; -import net.neoforged.neoforge.event.tick.LivingTickEvent; +import net.neoforged.neoforge.event.tick.EntityTickEvent; import net.neoforged.testframework.DynamicTest; import net.neoforged.testframework.annotation.ForEachTest; import net.neoforged.testframework.annotation.TestHolder; @@ -49,7 +49,7 @@ static void customGameRule(final DynamicTest test) { final GameRules.Key booleanGameRule = GameRules.register("%s:custom_boolean_game_rule".formatted(test.createModId()), GameRules.Category.MISC, GameRules.BooleanValue.create(true)); final GameRules.Key integerGameRule = GameRules.register("%s:custom_integer_game_rule".formatted(test.createModId()), GameRules.Category.MISC, GameRules.IntegerValue.create(1337)); - test.eventListeners().forge().addListener((LivingTickEvent.Pre event) -> { + test.eventListeners().forge().addListener((EntityTickEvent.Pre event) -> { if (event.getEntity() instanceof ServerPlayer player && player.getGameProfile().getName().equals("test-mock-player")) { if (player.level().getGameRules().getBoolean(booleanGameRule)) { player.setHealth(player.getHealth() - player.level().getGameRules().getInt(integerGameRule)); From 5366b25f676d2a247287a120baca35896aa58c4d Mon Sep 17 00:00:00 2001 From: Brennan Ward <3682588+Shadows-of-Fire@users.noreply.github.com> Date: Sun, 21 Apr 2024 20:29:03 -0700 Subject: [PATCH 3/5] spotless --- src/main/java/net/neoforged/neoforge/common/CommonHooks.java | 1 - src/main/java/net/neoforged/neoforge/event/EventHooks.java | 2 +- .../net/neoforged/neoforge/event/tick/EntityTickEvent.java | 3 +-- .../net/neoforged/neoforge/event/tick/PlayerTickEvent.java | 3 +-- 4 files changed, 3 insertions(+), 6 deletions(-) diff --git a/src/main/java/net/neoforged/neoforge/common/CommonHooks.java b/src/main/java/net/neoforged/neoforge/common/CommonHooks.java index f17f5a0a1a..2942f5cbfe 100644 --- a/src/main/java/net/neoforged/neoforge/common/CommonHooks.java +++ b/src/main/java/net/neoforged/neoforge/common/CommonHooks.java @@ -185,7 +185,6 @@ import net.neoforged.neoforge.event.entity.player.PlayerInteractEvent; import net.neoforged.neoforge.event.level.BlockEvent; import net.neoforged.neoforge.event.level.NoteBlockEvent; -import net.neoforged.neoforge.event.tick.EntityTickEvent; import net.neoforged.neoforge.fluids.FluidType; import net.neoforged.neoforge.registries.NeoForgeRegistries; import net.neoforged.neoforge.resource.ResourcePackLoader; diff --git a/src/main/java/net/neoforged/neoforge/event/EventHooks.java b/src/main/java/net/neoforged/neoforge/event/EventHooks.java index 8c92a3ffc8..5fcce50710 100644 --- a/src/main/java/net/neoforged/neoforge/event/EventHooks.java +++ b/src/main/java/net/neoforged/neoforge/event/EventHooks.java @@ -831,7 +831,7 @@ public static EntityTickEvent.Pre fireEntityTickPre(Entity entity) { public static void fireEntityTickPost(Entity entity) { NeoForge.EVENT_BUS.post(new EntityTickEvent.Post(entity)); } - + /** * Fires {@link PlayerTickEvent.Pre}. Called from the head of {@link Player#tick()}. * diff --git a/src/main/java/net/neoforged/neoforge/event/tick/EntityTickEvent.java b/src/main/java/net/neoforged/neoforge/event/tick/EntityTickEvent.java index 968ff21e81..d2af6aebf5 100644 --- a/src/main/java/net/neoforged/neoforge/event/tick/EntityTickEvent.java +++ b/src/main/java/net/neoforged/neoforge/event/tick/EntityTickEvent.java @@ -5,11 +5,10 @@ package net.neoforged.neoforge.event.tick; -import org.jetbrains.annotations.ApiStatus; - import net.minecraft.world.entity.Entity; import net.neoforged.bus.api.ICancellableEvent; import net.neoforged.neoforge.event.entity.EntityEvent; +import org.jetbrains.annotations.ApiStatus; /** * Base class of the two entity tick events. diff --git a/src/main/java/net/neoforged/neoforge/event/tick/PlayerTickEvent.java b/src/main/java/net/neoforged/neoforge/event/tick/PlayerTickEvent.java index a84cf29b5c..6f0a4072e3 100644 --- a/src/main/java/net/neoforged/neoforge/event/tick/PlayerTickEvent.java +++ b/src/main/java/net/neoforged/neoforge/event/tick/PlayerTickEvent.java @@ -5,14 +5,13 @@ package net.neoforged.neoforge.event.tick; -import org.jetbrains.annotations.ApiStatus; - import net.minecraft.server.level.ServerPlayer; import net.minecraft.server.network.ServerGamePacketListenerImpl; import net.minecraft.world.entity.Entity; import net.minecraft.world.entity.player.Player; import net.minecraft.world.level.Level; import net.neoforged.neoforge.event.entity.player.PlayerEvent; +import org.jetbrains.annotations.ApiStatus; /** * Base class of the two player tick events. From 1e758f28113111b617faa6d45393f88ed83eb24a Mon Sep 17 00:00:00 2001 From: Brennan Ward <3682588+Shadows-of-Fire@users.noreply.github.com> Date: Sat, 27 Apr 2024 14:44:52 -0700 Subject: [PATCH 4/5] standardize ctors --- .../neoforged/neoforge/client/event/ClientTickEvent.java | 6 ++---- .../neoforged/neoforge/client/event/RenderFrameEvent.java | 4 ++-- .../neoforged/neoforge/event/tick/EntityTickEvent.java | 8 +++----- .../net/neoforged/neoforge/event/tick/LevelTickEvent.java | 7 ++----- .../neoforged/neoforge/event/tick/PlayerTickEvent.java | 7 ++----- .../neoforged/neoforge/event/tick/ServerTickEvent.java | 7 ++----- 6 files changed, 13 insertions(+), 26 deletions(-) diff --git a/src/main/java/net/neoforged/neoforge/client/event/ClientTickEvent.java b/src/main/java/net/neoforged/neoforge/client/event/ClientTickEvent.java index 80341cb7b0..e448dbf353 100644 --- a/src/main/java/net/neoforged/neoforge/client/event/ClientTickEvent.java +++ b/src/main/java/net/neoforged/neoforge/client/event/ClientTickEvent.java @@ -10,12 +10,10 @@ /** * Base class of the two client tick events. * - * @see Pre - * @see Post + * @see ClientTickEvent.Pre + * @see ClientTickEvent.Post */ public abstract class ClientTickEvent extends Event { - public ClientTickEvent() {} - /** * {@link ClientTickEvent.Pre} is fired once per client tick, before the client performs work for the current tick. *

diff --git a/src/main/java/net/neoforged/neoforge/client/event/RenderFrameEvent.java b/src/main/java/net/neoforged/neoforge/client/event/RenderFrameEvent.java index 59cbd54a6a..7f7ea7d287 100644 --- a/src/main/java/net/neoforged/neoforge/client/event/RenderFrameEvent.java +++ b/src/main/java/net/neoforged/neoforge/client/event/RenderFrameEvent.java @@ -13,8 +13,8 @@ *

* These events can be used to setup and teardown global render state that must persist for the current frame. * - * @see Pre - * @see Post + * @see RenderFrameEvent.Pre + * @see RenderFrameEvent.Post */ public abstract class RenderFrameEvent extends Event { protected final float partialTick; diff --git a/src/main/java/net/neoforged/neoforge/event/tick/EntityTickEvent.java b/src/main/java/net/neoforged/neoforge/event/tick/EntityTickEvent.java index d2af6aebf5..b70e452c1a 100644 --- a/src/main/java/net/neoforged/neoforge/event/tick/EntityTickEvent.java +++ b/src/main/java/net/neoforged/neoforge/event/tick/EntityTickEvent.java @@ -8,17 +8,15 @@ import net.minecraft.world.entity.Entity; import net.neoforged.bus.api.ICancellableEvent; import net.neoforged.neoforge.event.entity.EntityEvent; -import org.jetbrains.annotations.ApiStatus; /** * Base class of the two entity tick events. * - * @see Pre - * @see Post + * @see EntityTickEvent.Pre + * @see EntityTickEvent.Post */ public abstract class EntityTickEvent extends EntityEvent { - @ApiStatus.Internal - public EntityTickEvent(Entity entity) { + protected EntityTickEvent(Entity entity) { super(entity); } diff --git a/src/main/java/net/neoforged/neoforge/event/tick/LevelTickEvent.java b/src/main/java/net/neoforged/neoforge/event/tick/LevelTickEvent.java index d3f2af47a5..879ad503e0 100644 --- a/src/main/java/net/neoforged/neoforge/event/tick/LevelTickEvent.java +++ b/src/main/java/net/neoforged/neoforge/event/tick/LevelTickEvent.java @@ -10,13 +10,12 @@ import net.minecraft.server.level.ServerLevel; import net.minecraft.world.level.Level; import net.neoforged.bus.api.Event; -import org.jetbrains.annotations.ApiStatus; /** * Base class of the two level tick events. * - * @see Pre - * @see Post + * @see LevelTickEvent.Pre + * @see LevelTickEvent.Post */ public abstract class LevelTickEvent extends Event { private final BooleanSupplier hasTime; @@ -50,7 +49,6 @@ public Level getLevel() { * This event fires on both the logical client and logical server, for {@link ClientLevel} and {@link ServerLevel} respectively. */ public static class Pre extends LevelTickEvent { - @ApiStatus.Internal public Pre(BooleanSupplier haveTime, Level level) { super(haveTime, level); } @@ -62,7 +60,6 @@ public Pre(BooleanSupplier haveTime, Level level) { * This event fires on both the logical client and logical server, for {@link ClientLevel} and {@link ServerLevel} respectively. */ public static class Post extends LevelTickEvent { - @ApiStatus.Internal public Post(BooleanSupplier haveTime, Level level) { super(haveTime, level); } diff --git a/src/main/java/net/neoforged/neoforge/event/tick/PlayerTickEvent.java b/src/main/java/net/neoforged/neoforge/event/tick/PlayerTickEvent.java index 6f0a4072e3..148de6e6e1 100644 --- a/src/main/java/net/neoforged/neoforge/event/tick/PlayerTickEvent.java +++ b/src/main/java/net/neoforged/neoforge/event/tick/PlayerTickEvent.java @@ -11,7 +11,6 @@ import net.minecraft.world.entity.player.Player; import net.minecraft.world.level.Level; import net.neoforged.neoforge.event.entity.player.PlayerEvent; -import org.jetbrains.annotations.ApiStatus; /** * Base class of the two player tick events. @@ -22,8 +21,8 @@ *

* Use of these events should only be necessary if you rely on this specific timing. * - * @see Pre - * @see Post + * @see PlayerTickEvent.Pre + * @see PlayerTickEvent.Post */ public abstract class PlayerTickEvent extends PlayerEvent { protected PlayerTickEvent(Player player) { @@ -38,7 +37,6 @@ protected PlayerTickEvent(Player player) { * As such, be sure to check {@link Level#isClientSide()} before performing any operations. */ public static class Pre extends PlayerTickEvent { - @ApiStatus.Internal public Pre(Player player) { super(player); } @@ -52,7 +50,6 @@ public Pre(Player player) { * As such, be sure to check {@link Level#isClientSide()} before performing any operations. */ public static class Post extends PlayerTickEvent { - @ApiStatus.Internal public Post(Player player) { super(player); } diff --git a/src/main/java/net/neoforged/neoforge/event/tick/ServerTickEvent.java b/src/main/java/net/neoforged/neoforge/event/tick/ServerTickEvent.java index ecaed07ffc..9c48e8103c 100644 --- a/src/main/java/net/neoforged/neoforge/event/tick/ServerTickEvent.java +++ b/src/main/java/net/neoforged/neoforge/event/tick/ServerTickEvent.java @@ -8,13 +8,12 @@ import java.util.function.BooleanSupplier; import net.minecraft.server.MinecraftServer; import net.neoforged.bus.api.Event; -import org.jetbrains.annotations.ApiStatus; /** * Base class of the two server tick events. * - * @see Pre - * @see Post + * @see ServerTickEvent.Pre + * @see ServerTickEvent.Post */ public abstract class ServerTickEvent extends Event { private final BooleanSupplier hasTime; @@ -47,7 +46,6 @@ public MinecraftServer getServer() { * This event only fires on the logical server. */ public static class Pre extends ServerTickEvent { - @ApiStatus.Internal public Pre(BooleanSupplier haveTime, MinecraftServer server) { super(haveTime, server); } @@ -59,7 +57,6 @@ public Pre(BooleanSupplier haveTime, MinecraftServer server) { * This event only fires on the logical server. */ public static class Post extends ServerTickEvent { - @ApiStatus.Internal public Post(BooleanSupplier haveTime, MinecraftServer server) { super(haveTime, server); } From 7dc32e7b3961b3c4ae1224486bd1f49f02646863 Mon Sep 17 00:00:00 2001 From: Brennan Ward <3682588+Shadows-of-Fire@users.noreply.github.com> Date: Sat, 27 Apr 2024 14:48:11 -0700 Subject: [PATCH 5/5] link renderframe/clienttick via doc --- .../net/neoforged/neoforge/client/event/ClientTickEvent.java | 2 ++ .../net/neoforged/neoforge/client/event/RenderFrameEvent.java | 2 ++ 2 files changed, 4 insertions(+) diff --git a/src/main/java/net/neoforged/neoforge/client/event/ClientTickEvent.java b/src/main/java/net/neoforged/neoforge/client/event/ClientTickEvent.java index e448dbf353..78c33948c0 100644 --- a/src/main/java/net/neoforged/neoforge/client/event/ClientTickEvent.java +++ b/src/main/java/net/neoforged/neoforge/client/event/ClientTickEvent.java @@ -9,6 +9,8 @@ /** * Base class of the two client tick events. + *

+ * For the event that fires once per frame (instead of per tick), see {@link RenderFrameEvent}. * * @see ClientTickEvent.Pre * @see ClientTickEvent.Post diff --git a/src/main/java/net/neoforged/neoforge/client/event/RenderFrameEvent.java b/src/main/java/net/neoforged/neoforge/client/event/RenderFrameEvent.java index 7f7ea7d287..f5451cb8db 100644 --- a/src/main/java/net/neoforged/neoforge/client/event/RenderFrameEvent.java +++ b/src/main/java/net/neoforged/neoforge/client/event/RenderFrameEvent.java @@ -12,6 +12,8 @@ * Base class of the two render frame events. *

* These events can be used to setup and teardown global render state that must persist for the current frame. + *

+ * For the event that fires once per client tick (instead of per frame), see {@link ClientTickEvent}. * * @see RenderFrameEvent.Pre * @see RenderFrameEvent.Post