mirror of
https://github.com/VolmitSoftware/Iris.git
synced 2026-10-26 14:00:26 +00:00
Loader spawn position check
- The modded chunk generator hands VolmLib the bound loader for chunk-generation creature checks - Each loader build tests its spawn position check: Forge and NeoForge fire MobSpawnEvent.PositionCheck and honor a denial, Fabric applies the vanilla rule and obstruction checks
This commit is contained in:
1 parent
92e5daa13e
commit
4da9661885
5 files changed
+167
No files matched your search
+43
@@ -0,0 +1,43 @@
|
|||||||
|
package art.arcane.volmlib.nativelib.minecraft26_2.fabric;
|
||||||
|
|
||||||
|
import art.arcane.volmlib.nativelib.modded.NativeLoaderOptions;
|
||||||
|
import net.minecraft.SharedConstants;
|
||||||
|
import net.minecraft.server.Bootstrap;
|
||||||
|
import net.minecraft.world.entity.EntitySpawnReason;
|
||||||
|
import net.minecraft.world.entity.Mob;
|
||||||
|
import net.minecraft.world.level.ServerLevelAccessor;
|
||||||
|
import org.junit.BeforeClass;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import java.util.function.BooleanSupplier;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertFalse;
|
||||||
|
import static org.junit.Assert.assertTrue;
|
||||||
|
import static org.mockito.Mockito.mock;
|
||||||
|
import static org.mockito.Mockito.when;
|
||||||
|
|
||||||
|
public class NativeFabricSpawnPositionTest {
|
||||||
|
@BeforeClass
|
||||||
|
public static void bootstrap() {
|
||||||
|
SharedConstants.tryDetectVersion();
|
||||||
|
Bootstrap.bootStrap();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void chunkGenerationSpawnsUseTheVanillaRulesAndObstructionChecks() {
|
||||||
|
NativeFabricLoader loader = new NativeFabricLoader(
|
||||||
|
new NativeLoaderOptions("irisworldgen", "treefeller", BooleanSupplier::getAsBoolean));
|
||||||
|
ServerLevelAccessor level = mock(ServerLevelAccessor.class);
|
||||||
|
Mob mob = mock(Mob.class);
|
||||||
|
when(mob.checkSpawnRules(level, EntitySpawnReason.CHUNK_GENERATION)).thenReturn(true);
|
||||||
|
when(mob.checkSpawnObstruction(level)).thenReturn(true);
|
||||||
|
assertTrue(loader.checkSpawnPosition(mob, level, EntitySpawnReason.CHUNK_GENERATION));
|
||||||
|
|
||||||
|
when(mob.checkSpawnObstruction(level)).thenReturn(false);
|
||||||
|
assertFalse(loader.checkSpawnPosition(mob, level, EntitySpawnReason.CHUNK_GENERATION));
|
||||||
|
|
||||||
|
when(mob.checkSpawnObstruction(level)).thenReturn(true);
|
||||||
|
when(mob.checkSpawnRules(level, EntitySpawnReason.CHUNK_GENERATION)).thenReturn(false);
|
||||||
|
assertFalse(loader.checkSpawnPosition(mob, level, EntitySpawnReason.CHUNK_GENERATION));
|
||||||
|
}
|
||||||
|
}
|
||||||
+52
@@ -0,0 +1,52 @@
|
|||||||
|
package art.arcane.volmlib.nativelib.minecraft26_2.forge;
|
||||||
|
|
||||||
|
import art.arcane.volmlib.nativelib.modded.NativeLoaderOptions;
|
||||||
|
import net.minecraft.SharedConstants;
|
||||||
|
import net.minecraft.server.Bootstrap;
|
||||||
|
import net.minecraft.world.entity.EntitySpawnReason;
|
||||||
|
import net.minecraft.world.entity.Mob;
|
||||||
|
import net.minecraft.world.level.ServerLevelAccessor;
|
||||||
|
import net.minecraftforge.common.util.Result;
|
||||||
|
import net.minecraftforge.event.entity.living.MobSpawnEvent;
|
||||||
|
import net.minecraftforge.eventbus.api.listener.EventListener;
|
||||||
|
import org.junit.BeforeClass;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import java.util.concurrent.atomic.AtomicReference;
|
||||||
|
import java.util.function.BooleanSupplier;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
import static org.junit.Assert.assertFalse;
|
||||||
|
import static org.junit.Assert.assertTrue;
|
||||||
|
import static org.mockito.Mockito.mock;
|
||||||
|
import static org.mockito.Mockito.when;
|
||||||
|
|
||||||
|
public class NativeForgeSpawnPositionTest {
|
||||||
|
@BeforeClass
|
||||||
|
public static void bootstrap() {
|
||||||
|
SharedConstants.tryDetectVersion();
|
||||||
|
Bootstrap.bootStrap();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void chunkGenerationSpawnsFireThePositionCheckEventAndHonorItsDenial() {
|
||||||
|
NativeForgeLoader loader = new NativeForgeLoader(
|
||||||
|
new NativeLoaderOptions("irisworldgen", "treefeller", BooleanSupplier::getAsBoolean));
|
||||||
|
ServerLevelAccessor level = mock(ServerLevelAccessor.class);
|
||||||
|
Mob mob = mock(Mob.class);
|
||||||
|
when(mob.checkSpawnRules(level, EntitySpawnReason.CHUNK_GENERATION)).thenReturn(true);
|
||||||
|
when(mob.checkSpawnObstruction(level)).thenReturn(true);
|
||||||
|
AtomicReference<EntitySpawnReason> observed = new AtomicReference<>();
|
||||||
|
EventListener listener = MobSpawnEvent.PositionCheck.BUS.addListener((MobSpawnEvent.PositionCheck event) -> {
|
||||||
|
observed.set(event.getSpawnReason());
|
||||||
|
event.setResult(Result.DENY);
|
||||||
|
});
|
||||||
|
try {
|
||||||
|
assertFalse(loader.checkSpawnPosition(mob, level, EntitySpawnReason.CHUNK_GENERATION));
|
||||||
|
} finally {
|
||||||
|
MobSpawnEvent.PositionCheck.BUS.removeListener(listener);
|
||||||
|
}
|
||||||
|
assertEquals(EntitySpawnReason.CHUNK_GENERATION, observed.get());
|
||||||
|
assertTrue(loader.checkSpawnPosition(mob, level, EntitySpawnReason.CHUNK_GENERATION));
|
||||||
|
}
|
||||||
|
}
|
||||||
+6
@@ -44,6 +44,7 @@ import art.arcane.volmlib.nativelib.minecraft26_2.modded.NativeFeatureBiomeSourc
|
|||||||
import art.arcane.volmlib.nativelib.minecraft26_2.modded.NativeDimensionRuntime;
|
import art.arcane.volmlib.nativelib.minecraft26_2.modded.NativeDimensionRuntime;
|
||||||
|
|
||||||
import art.arcane.volmlib.nativelib.minecraft26_2.modded.NativeModdedServer;
|
import art.arcane.volmlib.nativelib.minecraft26_2.modded.NativeModdedServer;
|
||||||
|
import art.arcane.volmlib.nativelib.minecraft26_2.modded.NativeModdedLoader;
|
||||||
|
|
||||||
import art.arcane.volmlib.nativelib.minecraft26_2.modded.NativeGeneratorOwner;
|
import art.arcane.volmlib.nativelib.minecraft26_2.modded.NativeGeneratorOwner;
|
||||||
import art.arcane.volmlib.nativelib.minecraft26_2.modded.NativeGeneratorHandle;
|
import art.arcane.volmlib.nativelib.minecraft26_2.modded.NativeGeneratorHandle;
|
||||||
@@ -1011,6 +1012,11 @@ public final class IrisModdedChunkGenerator implements NativeGeneratorOwner, Nat
|
|||||||
return ModdedEngineBootstrap.currentServer();
|
return ModdedEngineBootstrap.currentServer();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public NativeModdedLoader loader() {
|
||||||
|
return ModdedEngineBootstrap.loader();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Engine current() {
|
public Engine current() {
|
||||||
return engine();
|
return engine();
|
||||||
|
|||||||
+8
@@ -9,6 +9,9 @@ import art.arcane.volmlib.nativelib.minecraft26_2.modded.ModdedServerAccess;
|
|||||||
import art.arcane.volmlib.nativelib.minecraft26_2.modded.ModdedServerLevels;
|
import art.arcane.volmlib.nativelib.minecraft26_2.modded.ModdedServerLevels;
|
||||||
import net.minecraft.server.level.ServerLevel;
|
import net.minecraft.server.level.ServerLevel;
|
||||||
import net.minecraft.server.level.ServerPlayer;
|
import net.minecraft.server.level.ServerPlayer;
|
||||||
|
import net.minecraft.world.entity.EntitySpawnReason;
|
||||||
|
import net.minecraft.world.entity.Mob;
|
||||||
|
import net.minecraft.world.level.ServerLevelAccessor;
|
||||||
import net.minecraft.world.level.block.state.BlockState;
|
import net.minecraft.world.level.block.state.BlockState;
|
||||||
import org.junit.Rule;
|
import org.junit.Rule;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
@@ -83,6 +86,11 @@ public class ModdedPlatformPathsTest {
|
|||||||
public boolean canBreakBlock(ServerLevel level, ServerPlayer player, BlockPos position, BlockState state) {
|
public boolean canBreakBlock(ServerLevel level, ServerPlayer player, BlockPos position, BlockState state) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean checkSpawnPosition(Mob mob, ServerLevelAccessor level, EntitySpawnReason reason) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+58
@@ -0,0 +1,58 @@
|
|||||||
|
package art.arcane.volmlib.nativelib.minecraft26_2.neoforge;
|
||||||
|
|
||||||
|
import art.arcane.volmlib.nativelib.modded.NativeLoaderOptions;
|
||||||
|
import net.minecraft.SharedConstants;
|
||||||
|
import net.minecraft.server.Bootstrap;
|
||||||
|
import net.minecraft.world.entity.EntitySpawnReason;
|
||||||
|
import net.minecraft.world.entity.Mob;
|
||||||
|
import net.minecraft.world.level.ServerLevelAccessor;
|
||||||
|
import net.neoforged.neoforge.common.NeoForge;
|
||||||
|
import net.neoforged.neoforge.event.entity.living.MobSpawnEvent;
|
||||||
|
import org.junit.BeforeClass;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import java.util.concurrent.atomic.AtomicBoolean;
|
||||||
|
import java.util.concurrent.atomic.AtomicReference;
|
||||||
|
import java.util.function.BooleanSupplier;
|
||||||
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
import static org.junit.Assert.assertFalse;
|
||||||
|
import static org.junit.Assert.assertTrue;
|
||||||
|
import static org.mockito.Mockito.mock;
|
||||||
|
import static org.mockito.Mockito.when;
|
||||||
|
|
||||||
|
public class NativeNeoForgeSpawnPositionTest {
|
||||||
|
@BeforeClass
|
||||||
|
public static void bootstrap() {
|
||||||
|
SharedConstants.tryDetectVersion();
|
||||||
|
Bootstrap.bootStrap();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void chunkGenerationSpawnsFireThePositionCheckEventAndHonorItsDenial() {
|
||||||
|
NativeNeoForgeLoader loader = new NativeNeoForgeLoader(
|
||||||
|
new NativeLoaderOptions("irisworldgen", "treefeller", BooleanSupplier::getAsBoolean));
|
||||||
|
ServerLevelAccessor level = mock(ServerLevelAccessor.class);
|
||||||
|
Mob mob = mock(Mob.class);
|
||||||
|
when(mob.checkSpawnRules(level, EntitySpawnReason.CHUNK_GENERATION)).thenReturn(true);
|
||||||
|
when(mob.checkSpawnObstruction(level)).thenReturn(true);
|
||||||
|
AtomicBoolean deny = new AtomicBoolean(true);
|
||||||
|
AtomicReference<EntitySpawnReason> observed = new AtomicReference<>();
|
||||||
|
Consumer<MobSpawnEvent.PositionCheck> listener = (MobSpawnEvent.PositionCheck event) -> {
|
||||||
|
if (event.getEntity() == mob && deny.get()) {
|
||||||
|
observed.set(event.getSpawnType());
|
||||||
|
event.setResult(MobSpawnEvent.PositionCheck.Result.FAIL);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
NeoForge.EVENT_BUS.addListener(MobSpawnEvent.PositionCheck.class, listener);
|
||||||
|
try {
|
||||||
|
assertFalse(loader.checkSpawnPosition(mob, level, EntitySpawnReason.CHUNK_GENERATION));
|
||||||
|
assertEquals(EntitySpawnReason.CHUNK_GENERATION, observed.get());
|
||||||
|
deny.set(false);
|
||||||
|
assertTrue(loader.checkSpawnPosition(mob, level, EntitySpawnReason.CHUNK_GENERATION));
|
||||||
|
} finally {
|
||||||
|
NeoForge.EVENT_BUS.unregister(listener);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in new issue
Block a user