mirror of
https://github.com/VolmitSoftware/Iris.git
synced 2026-11-01 17:00:26 +00:00
Modded structure state key
- Modded biome policy supplies the structure state key from the generator - History worlds key structure state by the active epoch - Studio worlds get a fresh transient key - Tests cover the key binding and the structure state codec
This commit is contained in:
1 parent
618bb28591
commit
b61d2f305b
4 files changed
+94
-6
No files matched your search
+10
-1
@@ -105,6 +105,7 @@ import java.util.Objects;
|
||||
import java.util.OptionalLong;
|
||||
import java.util.Set;
|
||||
import java.util.TreeSet;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
import java.util.function.IntConsumer;
|
||||
@@ -946,6 +947,14 @@ public final class IrisModdedChunkGenerator implements NativeGeneratorOwner, Nat
|
||||
+ " requires an attached generation-history runtime router."));
|
||||
}
|
||||
|
||||
private String structureStateKey() {
|
||||
Engine current = boundEngineOrNull();
|
||||
if (current == null || allowsGenerationHistoryBypass(current)) {
|
||||
return "transient:" + UUID.randomUUID();
|
||||
}
|
||||
return "epoch:" + requireHistoryRouter(current, "structure state key").history().activeEpoch().epochId();
|
||||
}
|
||||
|
||||
boolean allowsGenerationHistoryBypass(Engine current) {
|
||||
if (generationMode != ModdedGenerationMode.TRANSIENT_STUDIO) {
|
||||
return false;
|
||||
@@ -985,7 +994,7 @@ public final class IrisModdedChunkGenerator implements NativeGeneratorOwner, Nat
|
||||
ModdedBiomePolicy<H, S> policy = new ModdedBiomePolicy<>(source);
|
||||
policy.bind(new ModdedBiomePolicy.RuntimeCallbacks(this::boundEngineOrNull, this::awaitStructureEngine,
|
||||
this::allowsGenerationHistoryBypass, this::configuredStructureBiomeKeys,
|
||||
IrisModdedChunkGenerator::retainedBiomeKeys, this::visibleBiomeSeed));
|
||||
IrisModdedChunkGenerator::retainedBiomeKeys, this::visibleBiomeSeed, this::structureStateKey));
|
||||
return policy;
|
||||
}
|
||||
|
||||
|
||||
@@ -1395,6 +1395,11 @@ final class ModdedBiomePolicy<H, S> implements NativeModdedBiomePolicy<H, S> {
|
||||
return requireConfiguredStructureBiomeKeys(exactStructureBiomeKeys());
|
||||
}
|
||||
|
||||
@Override
|
||||
public String structureStateKey() {
|
||||
return Objects.requireNonNull(runtime, "runtime").structureStateKey().get();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int horizontalSearchStep(int blockY, int searchRadius) {
|
||||
return horizontalBiomeSearchQuartStep(blockY, searchRadius);
|
||||
@@ -1402,6 +1407,7 @@ final class ModdedBiomePolicy<H, S> implements NativeModdedBiomePolicy<H, S> {
|
||||
|
||||
record RuntimeCallbacks(Supplier<Engine> currentEngine, Supplier<Engine> awaitEngine,
|
||||
Predicate<Engine> historyBypass, Supplier<Set<String>> configuredStructureKeys,
|
||||
Function<Engine, Set<String>> retainedBiomeKeys, LongSupplier visibleBiomeSeed) {
|
||||
Function<Engine, Set<String>> retainedBiomeKeys, LongSupplier visibleBiomeSeed,
|
||||
Supplier<String> structureStateKey) {
|
||||
}
|
||||
}
|
||||
+13
-4
@@ -102,6 +102,15 @@ public class ModdedBiomePolicyTest {
|
||||
assertSame(desert, policy.orderedPossibleBiomes().getFirst());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void structureStateKeyComesFromTheBoundRuntime() {
|
||||
ModdedBiomePolicy<BiomeToken, Object> policy = new ModdedBiomePolicy<>(new Access(new ArrayList<>()));
|
||||
policy.bind(new ModdedBiomePolicy.RuntimeCallbacks(() -> null, () -> null, engine -> false,
|
||||
Set::of, engine -> Set.of(), () -> 0L, () -> "epoch:example"));
|
||||
|
||||
assertEquals("epoch:example", policy.structureStateKey());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void missingRequiredStructureBiomesFailBeforePublishingAPartialSet() {
|
||||
AtomicReference<Set<String>> configured = new AtomicReference<>(Set.of("example:missing"));
|
||||
@@ -130,7 +139,7 @@ public class ModdedBiomePolicyTest {
|
||||
ModdedBiomePolicy<BiomeToken, Object> policy = new ModdedBiomePolicy<>(
|
||||
new Access(new ArrayList<>(List.of(forest))));
|
||||
policy.bind(new ModdedBiomePolicy.RuntimeCallbacks(() -> engine, () -> engine, bound -> true,
|
||||
() -> Set.of(forest.key()), bound -> Set.of(), () -> 0L));
|
||||
() -> Set.of(forest.key()), bound -> Set.of(), () -> 0L, () -> "transient:test"));
|
||||
|
||||
assertSame(forest, policy.requiredStructureBiome(6000, 0, -6000, null));
|
||||
assertSame(forest, policy.requiredStructureBiome(6000, -30, -6000, null));
|
||||
@@ -212,7 +221,7 @@ public class ModdedBiomePolicyTest {
|
||||
ModdedBiomePolicy<BiomeToken, Object> policy = new ModdedBiomePolicy<>(
|
||||
new Access(new ArrayList<>(List.of(plains, mirage))));
|
||||
policy.bind(new ModdedBiomePolicy.RuntimeCallbacks(() -> engine, () -> engine, bound -> false,
|
||||
() -> Set.of(plains.key(), mirage.key()), bound -> Set.of(), () -> 0L));
|
||||
() -> Set.of(plains.key(), mirage.key()), bound -> Set.of(), () -> 0L, () -> "transient:test"));
|
||||
int[] columns = {0, 1024, 2048, 3072, 4096, 5120};
|
||||
|
||||
NativeBiomeSourcePolicy.BiomeLocation<BiomeToken> found = policy.findClosestBiome3d(
|
||||
@@ -241,7 +250,7 @@ public class ModdedBiomePolicyTest {
|
||||
private static ModdedBiomePolicy<BiomeToken, Object> boundTo(Engine engine) {
|
||||
ModdedBiomePolicy<BiomeToken, Object> policy = new ModdedBiomePolicy<>(new Access(new ArrayList<>()));
|
||||
policy.bind(new ModdedBiomePolicy.RuntimeCallbacks(() -> engine, () -> engine, bound -> true,
|
||||
Set::of, bound -> Set.of(), () -> 0L));
|
||||
Set::of, bound -> Set.of(), () -> 0L, () -> "transient:test"));
|
||||
return policy;
|
||||
}
|
||||
|
||||
@@ -249,7 +258,7 @@ public class ModdedBiomePolicyTest {
|
||||
AtomicReference<Set<String>> configured) {
|
||||
ModdedBiomePolicy<BiomeToken, Object> policy = new ModdedBiomePolicy<>(new Access(entries));
|
||||
policy.bind(new ModdedBiomePolicy.RuntimeCallbacks(() -> null, () -> null, engine -> false,
|
||||
configured::get, engine -> Set.of(), () -> 0L));
|
||||
configured::get, engine -> Set.of(), () -> 0L, () -> "transient:test"));
|
||||
return policy;
|
||||
}
|
||||
|
||||
|
||||
+64
@@ -0,0 +1,64 @@
|
||||
package art.arcane.volmlib.nativelib.minecraft26_2.modded;
|
||||
|
||||
import art.arcane.volmlib.nativelib.terrain.NativeModdedBiomePolicy;
|
||||
import com.google.gson.JsonElement;
|
||||
import com.mojang.serialization.DataResult;
|
||||
import com.mojang.serialization.JsonOps;
|
||||
import com.mojang.serialization.MapCodec;
|
||||
import net.minecraft.SharedConstants;
|
||||
import net.minecraft.core.Holder;
|
||||
import net.minecraft.server.Bootstrap;
|
||||
import net.minecraft.world.level.biome.Biome;
|
||||
import net.minecraft.world.level.biome.BiomeSource;
|
||||
import net.minecraft.world.level.biome.Climate;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.util.Set;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
public class NativeModdedBiomeSourceCodecTest {
|
||||
@BeforeClass
|
||||
public static void bootstrap() {
|
||||
SharedConstants.tryDetectVersion();
|
||||
Bootstrap.bootStrap();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void runtimeSourceEncodeReportsErrorInsteadOfThrowing() {
|
||||
DataResult<JsonElement> result = BiomeSource.CODEC.encodeStart(JsonOps.INSTANCE, runtimeSource("epoch:unused"));
|
||||
assertTrue(result.isError());
|
||||
}
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("unchecked")
|
||||
public void structureStateSourceEncodesItsGenerationKey() throws ReflectiveOperationException {
|
||||
BiomeSource structureState = structureState(runtimeSource("epoch:example"));
|
||||
MapCodec<BiomeSource> codec = (MapCodec<BiomeSource>) NativeModdedBiomeSource.STRUCTURE_STATE_CODEC;
|
||||
|
||||
JsonElement encoded = codec.codec().encodeStart(JsonOps.INSTANCE, structureState).getOrThrow();
|
||||
|
||||
assertEquals("epoch:example", encoded.getAsJsonObject().get("generation").getAsString());
|
||||
assertTrue(codec.codec().parse(JsonOps.INSTANCE, encoded).isError());
|
||||
}
|
||||
|
||||
private static BiomeSource structureState(NativeModdedBiomeSource<?> source) throws ReflectiveOperationException {
|
||||
Class<?> type = Class.forName(NativeModdedBiomeSource.class.getName() + "$StructureStateBiomeSource");
|
||||
Constructor<?> constructor = type.getDeclaredConstructor(NativeModdedBiomeSource.class, Set.class);
|
||||
constructor.setAccessible(true);
|
||||
return (BiomeSource) constructor.newInstance(source, Set.<Holder<Biome>>of());
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private static NativeModdedBiomeSource<NativeModdedBiomePolicy<Holder<Biome>, Climate.Sampler>> runtimeSource(String key) {
|
||||
NativeModdedBiomePolicy<Holder<Biome>, Climate.Sampler> policy = mock(NativeModdedBiomePolicy.class);
|
||||
when(policy.structureStateKey()).thenReturn(key);
|
||||
return new NativeModdedBiomeSource<>(new NativeModdedBiomeSource.Options<>(
|
||||
mock(BiomeSource.class), () -> null, access -> policy));
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user