mirror of
https://github.com/VolmitSoftware/Iris.git
synced 2026-08-27 04:37:47 +00:00
First Test MV
This commit is contained in:
+21
-17
@@ -6,6 +6,7 @@ import ca.spottedleaf.moonrise.patches.chunk_system.scheduling.NewChunkHolder;
|
||||
import com.mojang.brigadier.exceptions.CommandSyntaxException;
|
||||
import art.arcane.iris.spi.IrisLogging;
|
||||
import art.arcane.iris.core.nms.INMSBinding;
|
||||
import art.arcane.iris.core.nms.MinecraftVersion;
|
||||
import art.arcane.iris.core.nms.container.BiomeColor;
|
||||
import art.arcane.iris.core.nms.container.Pair;
|
||||
import art.arcane.iris.core.nms.container.BlockProperty;
|
||||
@@ -161,6 +162,7 @@ import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
public class NMSBinding implements INMSBinding {
|
||||
private final KMap<Biome, Object> baseBiomeCache = new KMap<>();
|
||||
private volatile DataVersion dataVersion;
|
||||
private final BlockData AIR = Material.AIR.createBlockData();
|
||||
private final AtomicCache<MCAIdMap<net.minecraft.world.level.biome.Biome>> biomeMapCache = new AtomicCache<>();
|
||||
private final AtomicBoolean injected = new AtomicBoolean();
|
||||
@@ -1238,23 +1240,19 @@ public class NMSBinding implements INMSBinding {
|
||||
}
|
||||
|
||||
try {
|
||||
String descriptionId = "entity.minecraft." + entity.name().toLowerCase(Locale.ROOT);
|
||||
Field[] fields = EntityType.class.getDeclaredFields();
|
||||
for (Field field : fields) {
|
||||
if (!Modifier.isStatic(field.getModifiers()) || !field.getType().equals(EntityType.class)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
EntityType entityType = (EntityType) field.get(null);
|
||||
if (entityType == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (descriptionId.equals(entityType.getDescriptionId())) {
|
||||
return new Vector3d(entityType.getWidth(), entityType.getHeight(), entityType.getWidth());
|
||||
}
|
||||
// Registry lookup instead of an EntityType static-field scan: 26.2 moved the constants
|
||||
// to a separate EntityTypes holder class that 26.1.2 does not have, while the registry
|
||||
// resolves identically on both. ENTITY_TYPE is a DefaultedRegistry, so guard containsKey
|
||||
// to avoid silently resolving unknown keys to the default entry.
|
||||
Identifier key = Identifier.fromNamespaceAndPath(entity.getKey().getNamespace(), entity.getKey().getKey());
|
||||
if (!BuiltInRegistries.ENTITY_TYPE.containsKey(key)) {
|
||||
return null;
|
||||
}
|
||||
return null;
|
||||
EntityType<?> entityType = BuiltInRegistries.ENTITY_TYPE.getValue(key);
|
||||
if (entityType == null) {
|
||||
return null;
|
||||
}
|
||||
return new Vector3d(entityType.getWidth(), entityType.getHeight(), entityType.getWidth());
|
||||
} catch (Throwable e) {
|
||||
IrisLogging.error("Unable to get entity dimensions for " + entity + "!");
|
||||
IrisLogging.reportError(e);
|
||||
@@ -1362,7 +1360,13 @@ public class NMSBinding implements INMSBinding {
|
||||
|
||||
@Override
|
||||
public DataVersion getDataVersion() {
|
||||
return DataVersion.V26_2;
|
||||
DataVersion cached = dataVersion;
|
||||
if (cached == null) {
|
||||
MinecraftVersion detected = MinecraftVersion.detect(Bukkit.getServer());
|
||||
cached = detected != null && detected.isSameRelease(26, 1, 2) ? DataVersion.V26_1_2 : DataVersion.V26_2;
|
||||
dataVersion = cached;
|
||||
}
|
||||
return cached;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+16
-34
@@ -6,7 +6,6 @@ import art.arcane.iris.engine.object.IrisStructureTerrain;
|
||||
import art.arcane.iris.engine.object.IrisStructureTerrainMode;
|
||||
import com.mojang.datafixers.util.Either;
|
||||
import com.mojang.serialization.Codec;
|
||||
import com.mojang.serialization.MapCodec;
|
||||
import net.minecraft.SharedConstants;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.core.Holder;
|
||||
@@ -17,7 +16,6 @@ import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.server.Bootstrap;
|
||||
import net.minecraft.util.RandomSource;
|
||||
import net.minecraft.world.level.ChunkPos;
|
||||
import net.minecraft.world.level.LevelReader;
|
||||
import net.minecraft.world.level.LevelHeightAccessor;
|
||||
import net.minecraft.world.level.WorldGenLevel;
|
||||
import net.minecraft.world.level.biome.Biome;
|
||||
@@ -46,8 +44,11 @@ import net.minecraft.world.level.levelgen.structure.pools.ListPoolElement;
|
||||
import net.minecraft.world.level.levelgen.structure.pools.SinglePoolElement;
|
||||
import net.minecraft.world.level.levelgen.structure.pools.StructurePoolElement;
|
||||
import net.minecraft.world.level.levelgen.structure.pools.StructureTemplatePool;
|
||||
import net.minecraft.world.level.levelgen.structure.templatesystem.AlwaysTrueTest;
|
||||
import net.minecraft.world.level.levelgen.structure.templatesystem.BlockStateMatchTest;
|
||||
import net.minecraft.world.level.levelgen.structure.templatesystem.LiquidSettings;
|
||||
import net.minecraft.world.level.levelgen.structure.templatesystem.BlockIgnoreProcessor;
|
||||
import net.minecraft.world.level.levelgen.structure.templatesystem.ProcessorRule;
|
||||
import net.minecraft.world.level.levelgen.structure.templatesystem.RuleProcessor;
|
||||
import net.minecraft.world.level.levelgen.structure.structures.DesertPyramidPiece;
|
||||
import net.minecraft.world.level.levelgen.structure.structures.DesertPyramidStructure;
|
||||
import net.minecraft.world.level.levelgen.structure.templatesystem.StructurePlaceSettings;
|
||||
@@ -267,7 +268,7 @@ public class NativeStructurePostProcessorSurfaceTerrainTest {
|
||||
block(0, 0, 0, Blocks.COBBLESTONE.defaultBlockState()),
|
||||
block(15, 0, 0, Blocks.STONE.defaultBlockState())));
|
||||
InlineSinglePoolElement element = new InlineSinglePoolElement(
|
||||
sparseTemplate, List.of(new ReplaceBlockProcessor(
|
||||
sparseTemplate, List.of(replaceBlockProcessor(
|
||||
Blocks.STONE.defaultBlockState(), Blocks.AIR.defaultBlockState())));
|
||||
PoolElementStructurePiece piece = rigidTemplatePiece(
|
||||
element, new BoundingBox(0, 64, 0, 15, 70, 3), 1, Rotation.NONE);
|
||||
@@ -369,7 +370,7 @@ public class NativeStructurePostProcessorSurfaceTerrainTest {
|
||||
block(2, 0, 0, Blocks.AIR.defaultBlockState()),
|
||||
block(2, 2, 0, Blocks.COBBLESTONE.defaultBlockState())));
|
||||
InlineSinglePoolElement element = new InlineSinglePoolElement(
|
||||
template, List.of(new ReplaceBlockProcessor(
|
||||
template, List.of(replaceBlockProcessor(
|
||||
Blocks.STONE.defaultBlockState(), Blocks.AIR.defaultBlockState())));
|
||||
PoolElementStructurePiece piece = rigidTemplatePiece(
|
||||
element, new BoundingBox(0, 65, 0, 2, 72, 0), 1, Rotation.NONE);
|
||||
@@ -551,7 +552,7 @@ public class NativeStructurePostProcessorSurfaceTerrainTest {
|
||||
block(0, 0, 0, Blocks.STONE.defaultBlockState()),
|
||||
block(0, 2, 0, Blocks.COBBLESTONE.defaultBlockState())));
|
||||
PoolElementStructurePiece piece = rigidTemplatePiece(
|
||||
new InlineSinglePoolElement(template, List.of(new ReplaceBlockProcessor(
|
||||
new InlineSinglePoolElement(template, List.of(replaceBlockProcessor(
|
||||
Blocks.STONE.defaultBlockState(), Blocks.AIR.defaultBlockState()))),
|
||||
new BoundingBox(0, 66, 0, 7, 72, 7), 1, Rotation.NONE);
|
||||
StructureStart start = rigidSurfaceStart(List.of(piece), TerrainAdjustment.NONE);
|
||||
@@ -1081,10 +1082,10 @@ public class NativeStructurePostProcessorSurfaceTerrainTest {
|
||||
block(1, 0, 0, Blocks.STONE.defaultBlockState())));
|
||||
InlineSinglePoolElement upperElement = new InlineSinglePoolElement(
|
||||
upperTemplate, List.of(
|
||||
new ReplaceBlockProcessor(
|
||||
replaceBlockProcessor(
|
||||
Blocks.COBBLESTONE.defaultBlockState(),
|
||||
Blocks.AIR.defaultBlockState()),
|
||||
new ReplaceBlockProcessor(
|
||||
replaceBlockProcessor(
|
||||
Blocks.STONE.defaultBlockState(),
|
||||
Blocks.WATER.defaultBlockState())));
|
||||
PoolElementStructurePiece lower = rigidTemplatePiece(
|
||||
@@ -2131,32 +2132,13 @@ public class NativeStructurePostProcessorSurfaceTerrainTest {
|
||||
}
|
||||
}
|
||||
|
||||
private static final class ReplaceBlockProcessor implements StructureProcessor {
|
||||
private final BlockState source;
|
||||
private final BlockState replacement;
|
||||
|
||||
private ReplaceBlockProcessor(BlockState source, BlockState replacement) {
|
||||
this.source = source;
|
||||
this.replacement = replacement;
|
||||
}
|
||||
|
||||
@Override
|
||||
public StructureTemplate.StructureBlockInfo processBlock(
|
||||
LevelReader level, BlockPos targetPosition, BlockPos referencePos,
|
||||
BlockPos templateRelativePos,
|
||||
StructureTemplate.StructureBlockInfo processedBlockInfo,
|
||||
StructurePlaceSettings settings) {
|
||||
if (!processedBlockInfo.state().equals(source)) {
|
||||
return processedBlockInfo;
|
||||
}
|
||||
return new StructureTemplate.StructureBlockInfo(
|
||||
processedBlockInfo.pos(), replacement, processedBlockInfo.nbt());
|
||||
}
|
||||
|
||||
@Override
|
||||
public MapCodec<? extends StructureProcessor> codec() {
|
||||
return BlockIgnoreProcessor.STRUCTURE_BLOCK.codec();
|
||||
}
|
||||
private static StructureProcessor replaceBlockProcessor(BlockState source, BlockState replacement) {
|
||||
// Vanilla RuleProcessor instead of a custom StructureProcessor subtype: StructureProcessor
|
||||
// is an abstract class on 26.1.2 and an interface on 26.2, so a direct subtype cannot
|
||||
// compile against both dev bundles. BlockStateMatchTest matches the exact source state,
|
||||
// matching the previous custom processor's identity-equality semantics.
|
||||
return new RuleProcessor(List.of(new ProcessorRule(
|
||||
new BlockStateMatchTest(source), AlwaysTrueTest.INSTANCE, replacement)));
|
||||
}
|
||||
|
||||
private static StructureStart desertStart() {
|
||||
|
||||
+46
-43
@@ -1,15 +1,16 @@
|
||||
package art.arcane.iris.nativegen;
|
||||
|
||||
import com.mojang.datafixers.util.Either;
|
||||
import com.mojang.serialization.MapCodec;
|
||||
import net.minecraft.SharedConstants;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.core.Holder;
|
||||
import net.minecraft.core.HolderSet;
|
||||
import net.minecraft.core.registries.BuiltInRegistries;
|
||||
import net.minecraft.core.registries.Registries;
|
||||
import net.minecraft.resources.Identifier;
|
||||
import net.minecraft.server.Bootstrap;
|
||||
import net.minecraft.tags.TagKey;
|
||||
import net.minecraft.util.valueproviders.ConstantInt;
|
||||
import net.minecraft.world.level.LevelReader;
|
||||
import net.minecraft.world.level.WorldGenLevel;
|
||||
import net.minecraft.world.level.block.Blocks;
|
||||
import net.minecraft.world.level.block.Rotation;
|
||||
@@ -34,11 +35,13 @@ import net.minecraft.world.level.levelgen.structure.templatesystem.StructureProc
|
||||
import net.minecraft.world.level.levelgen.structure.templatesystem.StructureProcessorList;
|
||||
import net.minecraft.world.level.levelgen.structure.templatesystem.StructureTemplate;
|
||||
import net.minecraft.world.level.levelgen.structure.templatesystem.StructureTemplateManager;
|
||||
import org.junit.Assume;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.InvocationHandler;
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.Proxy;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
@@ -62,38 +65,33 @@ public class NativeStructureTemplateOccupancyTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void straddlingGravityPieceReadsHeightsOnlyInsideTheProcessingArea() throws Exception {
|
||||
public void straddlingGravityPieceHeightReadsHonorTheVanillaClipContract() throws Exception {
|
||||
ColumnRecorder recorder = new ColumnRecorder();
|
||||
|
||||
resolve(straddlingPiece(
|
||||
List.of(new GravityProcessor(Heightmap.Types.WORLD_SURFACE_WG, 0))), recorder);
|
||||
|
||||
assertEquals(columns(0, 15), recorder.heightColumns);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void straddlingPieceRunsProcessorsOnlyInsideTheProcessingArea() throws Exception {
|
||||
CountingProcessor counter = new CountingProcessor();
|
||||
|
||||
resolve(straddlingPiece(List.of(counter)), new ColumnRecorder());
|
||||
|
||||
assertEquals(columns(0, 15), counter.columns);
|
||||
assertTrue(counter.columns.size() < TEMPLATE_WIDTH);
|
||||
// 26.2 vanilla clips processor evaluation to the placement bounding box; 26.1.2 vanilla
|
||||
// runs processors across the whole piece. Iris mirrors the pinned version's semantics.
|
||||
assertEquals(expectedClippedColumns(), recorder.heightColumns);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void cappedStraddlingPieceRunsProcessorsAcrossTheWholePiece() throws Exception {
|
||||
CountingProcessor counter = new CountingProcessor();
|
||||
ColumnRecorder recorder = new ColumnRecorder();
|
||||
|
||||
resolve(straddlingPiece(List.of(counter,
|
||||
new CappedProcessor(NopProcessor.INSTANCE, ConstantInt.of(0)))),
|
||||
new ColumnRecorder());
|
||||
resolve(straddlingPiece(List.of(
|
||||
new GravityProcessor(Heightmap.Types.WORLD_SURFACE_WG, 0),
|
||||
new CappedProcessor(NopProcessor.INSTANCE, ConstantInt.of(0)))), recorder);
|
||||
|
||||
assertEquals(columns(0, TEMPLATE_WIDTH - 1), counter.columns);
|
||||
assertEquals(columns(0, TEMPLATE_WIDTH - 1), recorder.heightColumns);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void cappedProcessorIsTheOnlyProcessorThatDisablesTheProcessingAreaClip() {
|
||||
public void cappedProcessorIsTheOnlyProcessorThatDisablesTheProcessingAreaClip() throws Exception {
|
||||
Method contract = clipContractMethod();
|
||||
Assume.assumeTrue("evaluatesEntirePieceState only exists on 26.2+", contract != null);
|
||||
|
||||
for (StructureProcessor processor : List.of(
|
||||
BlockIgnoreProcessor.STRUCTURE_BLOCK,
|
||||
JigsawReplacementProcessor.INSTANCE,
|
||||
@@ -103,12 +101,12 @@ public class NativeStructureTemplateOccupancyTest {
|
||||
new GravityProcessor(Heightmap.Types.WORLD_SURFACE_WG, 0),
|
||||
new RuleProcessor(List.of()),
|
||||
new BlockAgeProcessor(0.5F),
|
||||
new ProtectedBlockProcessor(HolderSet.empty()))) {
|
||||
protectedBlockProcessor())) {
|
||||
assertFalse(processor.getClass().getName(),
|
||||
processor.evaluatesEntirePieceState());
|
||||
(Boolean) contract.invoke(processor));
|
||||
}
|
||||
assertTrue(new CappedProcessor(NopProcessor.INSTANCE, ConstantInt.of(4))
|
||||
.evaluatesEntirePieceState());
|
||||
assertTrue((Boolean) contract.invoke(
|
||||
new CappedProcessor(NopProcessor.INSTANCE, ConstantInt.of(4))));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -146,6 +144,30 @@ public class NativeStructureTemplateOccupancyTest {
|
||||
return columns;
|
||||
}
|
||||
|
||||
private static Method clipContractMethod() {
|
||||
try {
|
||||
return StructureProcessor.class.getMethod("evaluatesEntirePieceState");
|
||||
} catch (NoSuchMethodException absent) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private static Set<Integer> expectedClippedColumns() {
|
||||
return clipContractMethod() != null
|
||||
? columns(PROCESSING_AREA.minX(), PROCESSING_AREA.maxX())
|
||||
: columns(0, TEMPLATE_WIDTH - 1);
|
||||
}
|
||||
|
||||
private static StructureProcessor protectedBlockProcessor() throws Exception {
|
||||
// Constructed reflectively: the constructor takes HolderSet on 26.2 and TagKey on 26.1.2.
|
||||
Constructor<?> constructor = ProtectedBlockProcessor.class.getConstructors()[0];
|
||||
Class<?> parameter = constructor.getParameterTypes()[0];
|
||||
Object argument = parameter == HolderSet.class
|
||||
? HolderSet.empty()
|
||||
: TagKey.create(Registries.BLOCK, Identifier.fromNamespaceAndPath("minecraft", "air"));
|
||||
return (StructureProcessor) constructor.newInstance(argument);
|
||||
}
|
||||
|
||||
private static StructureTemplateManager forbiddenTemplateManager() {
|
||||
throw new AssertionError("Inline templates must not resolve a template manager");
|
||||
}
|
||||
@@ -202,25 +224,6 @@ public class NativeStructureTemplateOccupancyTest {
|
||||
private final Set<Integer> stateColumns = new TreeSet<>();
|
||||
}
|
||||
|
||||
private static final class CountingProcessor implements StructureProcessor {
|
||||
private final Set<Integer> columns = new TreeSet<>();
|
||||
|
||||
@Override
|
||||
public StructureTemplate.StructureBlockInfo processBlock(
|
||||
LevelReader level, BlockPos targetPosition, BlockPos referencePos,
|
||||
BlockPos templateRelativePos,
|
||||
StructureTemplate.StructureBlockInfo processedBlockInfo,
|
||||
StructurePlaceSettings settings) {
|
||||
columns.add(processedBlockInfo.pos().getX());
|
||||
return processedBlockInfo;
|
||||
}
|
||||
|
||||
@Override
|
||||
public MapCodec<? extends StructureProcessor> codec() {
|
||||
return BlockIgnoreProcessor.STRUCTURE_BLOCK.codec();
|
||||
}
|
||||
}
|
||||
|
||||
private static final class InlineSinglePoolElement extends SinglePoolElement {
|
||||
private InlineSinglePoolElement(
|
||||
StructureTemplate template, List<StructureProcessor> processors) {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
String apiVersion = providers.gradleProperty('minecraftVersion').get()
|
||||
String apiVersion = providers.gradleProperty('apiVersion').get()
|
||||
def mainClass = 'art.arcane.iris.Iris'
|
||||
def bootstrapperClass = 'art.arcane.iris.IrisBootstrap'
|
||||
|
||||
|
||||
Reference in New Issue
Block a user