diff --git a/src/main/java/net/minecraftforge/event/ForgeEventFactory.java b/src/main/java/net/minecraftforge/event/ForgeEventFactory.java index 2d462f86cb3..88a8a3ca9c1 100644 --- a/src/main/java/net/minecraftforge/event/ForgeEventFactory.java +++ b/src/main/java/net/minecraftforge/event/ForgeEventFactory.java @@ -82,9 +82,7 @@ import org.jetbrains.annotations.Nullable; import java.io.File; -import java.util.EnumSet; -import java.util.List; -import java.util.Optional; +import java.util.*; import java.util.concurrent.atomic.AtomicBoolean; import java.util.function.BooleanSupplier; import java.util.function.Consumer; @@ -184,6 +182,25 @@ public static boolean checkSpawnPositionSpawner(Mob mob, ServerLevelAccessor lev return event.getResult() == Result.ALLOW; } + // We insert this into onFinalizeSpawn with a mixin for best compatibility. + private static final ThreadLocal> kilt$fabricOriginal = ThreadLocal.withInitial(() -> null); + + public static final ThreadLocal> kilt$hasFiredInitializeEvent = ThreadLocal.withInitial(HashSet::new); + + // Ideally, I would have wanted to turn onFinalizeSpawn into a stub calling this. + // Unfortunately: https://github.com/The-Aether-Team/The-Aether/blob/1.20.1-develop/src/main/java/com/aetherteam/aether/mixin/mixins/common/ForgeEventFactoryMixin.java#L24-L29 + public static SpawnGroupData kilt$onFinalizeSpawn( + Mob mob, ServerLevelAccessor level, DifficultyInstance difficulty, MobSpawnType spawnType, + @Nullable SpawnGroupData spawnData, @Nullable CompoundTag spawnTag, Operation original + ) { + try { + kilt$fabricOriginal.set(original); + return onFinalizeSpawn(mob, level, difficulty, spawnType, spawnData, spawnTag); + } finally { + kilt$fabricOriginal.set(null); + } + } // Removing would likely just cause unnecessary lag. + /** * Vanilla calls to {@link Mob#finalizeSpawn} are replaced with calls to this method via coremod.
* Mods should call this method in place of calling {@link Mob#finalizeSpawn}. Super calls (from within overrides) should not be wrapped. @@ -218,15 +235,20 @@ public static boolean checkSpawnPositionSpawner(Mob mob, ServerLevelAccessor lev @SuppressWarnings("deprecation") // Call to deprecated Mob#finalizeSpawn is expected. public static SpawnGroupData onFinalizeSpawn(Mob mob, ServerLevelAccessor level, DifficultyInstance difficulty, MobSpawnType spawnType, @Nullable SpawnGroupData spawnData, @Nullable CompoundTag spawnTag) { - var event = new MobSpawnEvent.FinalizeSpawn(mob, level, mob.getX(), mob.getY(), mob.getZ(), difficulty, spawnType, spawnData, spawnTag, null); - boolean cancel = MinecraftForge.EVENT_BUS.post(event); + try { + var event = new MobSpawnEvent.FinalizeSpawn(mob, level, mob.getX(), mob.getY(), mob.getZ(), difficulty, spawnType, spawnData, spawnTag, null); + boolean cancel = MinecraftForge.EVENT_BUS.post(event); + kilt$hasFiredInitializeEvent.get().add(mob); - if (!cancel) - { - return mob.finalizeSpawn(level, event.getDifficulty(), event.getSpawnType(), event.getSpawnData(), event.getSpawnTag()); - } + if (!cancel) + { + return mob.finalizeSpawn(level, event.getDifficulty(), event.getSpawnType(), event.getSpawnData(), event.getSpawnTag()); + } - return null; + return null; + } finally { + kilt$hasFiredInitializeEvent.get().remove(mob); + } } /**