mirror of
https://github.com/VolmitSoftware/Iris.git
synced 2026-10-27 14:30:14 +00:00
Fix biome names and conditions
- Register readable client biome IDs while preserving saved registry identities. - Audit the modded registry naming mixin. - Return false from MythicMobs conditions while saved biome data loads. - Cover biome naming and MythicMobs loading behavior with regression tests.
This commit is contained in:
1 parent
ee5aaec87c
commit
c479e94c49
6 files changed
+254
-3
No files matched your search
@@ -45,6 +45,9 @@ public final class ModdedMixinAudit {
|
|||||||
private static final AtomicBoolean AUDITED = new AtomicBoolean(false);
|
private static final AtomicBoolean AUDITED = new AtomicBoolean(false);
|
||||||
|
|
||||||
static final List<ExpectedMixin> EXPECTED = List.of(
|
static final List<ExpectedMixin> EXPECTED = List.of(
|
||||||
|
new ExpectedMixin(ENTITY_CONFIG, "RegistryClientNamesMixin",
|
||||||
|
NativeMixinTarget.REGISTRY_PACKET, "volmlib$clientRegistryNames",
|
||||||
|
false, NativeMixinFlags::registryClientNamesRan),
|
||||||
new ExpectedMixin(ENTITY_CONFIG, "EntityPersistenceMixin",
|
new ExpectedMixin(ENTITY_CONFIG, "EntityPersistenceMixin",
|
||||||
NativeMixinTarget.ENTITY, "iris$applyGeneratedPersistence",
|
NativeMixinTarget.ENTITY, "iris$applyGeneratedPersistence",
|
||||||
false, NativeMixinFlags::entityPersistenceRan),
|
false, NativeMixinFlags::entityPersistenceRan),
|
||||||
@@ -108,7 +111,7 @@ public final class ModdedMixinAudit {
|
|||||||
ModdedIrisLog.error(" missing: {}", entry);
|
ModdedIrisLog.error(" missing: {}", entry);
|
||||||
}
|
}
|
||||||
ModdedIrisLog.error("The mixin config was not registered for this loader (fabric.mod.json mixins, neoforge.mods.toml [[mixins]], forge MixinConfigs manifest attribute).");
|
ModdedIrisLog.error("The mixin config was not registered for this loader (fabric.mod.json mixins, neoforge.mods.toml [[mixins]], forge MixinConfigs manifest attribute).");
|
||||||
ModdedIrisLog.error("Entity persistence, custom mob loot, parallel structure safety, or Iris world-type labels are disabled until this is fixed.");
|
ModdedIrisLog.error("Entity persistence, custom mob loot, parallel structure safety, readable biome identifiers, or Iris world-type labels are disabled until this is fixed.");
|
||||||
ModdedIrisLog.error("===============================================================");
|
ModdedIrisLog.error("===============================================================");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -168,6 +168,8 @@ dependencies {
|
|||||||
testImplementation(libs.log4j.core)
|
testImplementation(libs.log4j.core)
|
||||||
testRuntimeOnly(libs.paper.api)
|
testRuntimeOnly(libs.paper.api)
|
||||||
testImplementation(libs.multiverseCore)
|
testImplementation(libs.multiverseCore)
|
||||||
|
testImplementation(libs.annotations)
|
||||||
|
testImplementation(libs.mythic)
|
||||||
}
|
}
|
||||||
|
|
||||||
tasks.named('test').configure {
|
tasks.named('test').configure {
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ package art.arcane.iris.integration.data;
|
|||||||
import art.arcane.iris.integration.ExternalDataProvider;
|
import art.arcane.iris.integration.ExternalDataProvider;
|
||||||
import art.arcane.iris.integration.Identifier;
|
import art.arcane.iris.integration.Identifier;
|
||||||
import art.arcane.iris.world.IrisToolbelt;
|
import art.arcane.iris.world.IrisToolbelt;
|
||||||
|
import art.arcane.iris.world.history.SavedBiomeUnavailableException;
|
||||||
import art.arcane.iris.generation.runtime.Engine;
|
import art.arcane.iris.generation.runtime.Engine;
|
||||||
import art.arcane.iris.generation.biome.IrisBiome;
|
import art.arcane.iris.generation.biome.IrisBiome;
|
||||||
import art.arcane.iris.generation.terrain.IrisRegion;
|
import art.arcane.iris.generation.terrain.IrisRegion;
|
||||||
@@ -110,10 +111,17 @@ public class MythicMobsDataProvider extends ExternalDataProvider implements List
|
|||||||
if (access == null) return false;
|
if (access == null) return false;
|
||||||
Engine engine = access.getEngine();
|
Engine engine = access.getEngine();
|
||||||
if (engine == null) return false;
|
if (engine == null) return false;
|
||||||
|
try {
|
||||||
IrisBiome biome = surface ?
|
IrisBiome biome = surface ?
|
||||||
engine.getSurfaceBiome(target.getBlockX(), target.getBlockZ()) :
|
engine.getSurfaceBiome(target.getBlockX(), target.getBlockZ()) :
|
||||||
engine.getBiomeOrMantle(target.getBlockX(), target.getBlockY() - engine.getMinHeight(), target.getBlockZ());
|
engine.getBiomeOrMantle(target.getBlockX(), target.getBlockY() - engine.getMinHeight(), target.getBlockZ());
|
||||||
return biomes.contains(biome.getLoadKey());
|
return biomes.contains(biome.getLoadKey());
|
||||||
|
} catch (SavedBiomeUnavailableException unavailable) {
|
||||||
|
if (unavailable.isLoading() && unavailable.getSuppressed().length == 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
throw unavailable;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -134,9 +142,16 @@ public class MythicMobsDataProvider extends ExternalDataProvider implements List
|
|||||||
if (access == null) return false;
|
if (access == null) return false;
|
||||||
Engine engine = access.getEngine();
|
Engine engine = access.getEngine();
|
||||||
if (engine == null) return false;
|
if (engine == null) return false;
|
||||||
|
try {
|
||||||
IrisRegion region = engine.getRegion(
|
IrisRegion region = engine.getRegion(
|
||||||
target.getBlockX(), target.getBlockY() - engine.getMinHeight(), target.getBlockZ());
|
target.getBlockX(), target.getBlockY() - engine.getMinHeight(), target.getBlockZ());
|
||||||
return regions.contains(region.getLoadKey());
|
return regions.contains(region.getLoadKey());
|
||||||
|
} catch (SavedBiomeUnavailableException unavailable) {
|
||||||
|
if (unavailable.isLoading() && unavailable.getSuppressed().length == 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
throw unavailable;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
+18
-2
@@ -23,6 +23,7 @@ import art.arcane.iris.generation.terrain.IrisRegion;
|
|||||||
import art.arcane.iris.structure.placement.IrisStructurePlacement;
|
import art.arcane.iris.structure.placement.IrisStructurePlacement;
|
||||||
import art.arcane.iris.spi.IrisPlatforms;
|
import art.arcane.iris.spi.IrisPlatforms;
|
||||||
import art.arcane.iris.spi.PlatformGenerationRegistry;
|
import art.arcane.iris.spi.PlatformGenerationRegistry;
|
||||||
|
import art.arcane.volmlib.nativelib.terrain.RegistryClientNames;
|
||||||
import art.arcane.iris.spi.PlatformRegistries;
|
import art.arcane.iris.spi.PlatformRegistries;
|
||||||
import art.arcane.volmlib.util.collection.KList;
|
import art.arcane.volmlib.util.collection.KList;
|
||||||
import com.google.gson.JsonArray;
|
import com.google.gson.JsonArray;
|
||||||
@@ -253,6 +254,7 @@ public final class GenerationRegistryContractFactory {
|
|||||||
requiredBiome.getId()
|
requiredBiome.getId()
|
||||||
);
|
);
|
||||||
String resourceKey = requiredRegistry.customBiomeResourceKey(identityFingerprint);
|
String resourceKey = requiredRegistry.customBiomeResourceKey(identityFingerprint);
|
||||||
|
registerCustomBiomeName(requiredDimension.getLoadKey(), requiredBiome.getId(), resourceKey);
|
||||||
GenerationRegistryContract.PhysicalResourceKey physicalKey = key(BIOME_REGISTRY, resourceKey);
|
GenerationRegistryContract.PhysicalResourceKey physicalKey = key(BIOME_REGISTRY, resourceKey);
|
||||||
PlatformGenerationRegistry.Definition canonicalDefinition = requiredRegistry.canonicalDefinition(
|
PlatformGenerationRegistry.Definition canonicalDefinition = requiredRegistry.canonicalDefinition(
|
||||||
BIOME_REGISTRY,
|
BIOME_REGISTRY,
|
||||||
@@ -285,13 +287,15 @@ public final class GenerationRegistryContractFactory {
|
|||||||
ContentGate contentGate
|
ContentGate contentGate
|
||||||
) {
|
) {
|
||||||
IrisBiomeCustom requiredBiome = Objects.requireNonNull(customBiome, "customBiome");
|
IrisBiomeCustom requiredBiome = Objects.requireNonNull(customBiome, "customBiome");
|
||||||
return PlatformGenerationRegistry.contentAddressedCustomBiomeResourceKey(
|
String resourceKey = PlatformGenerationRegistry.contentAddressedCustomBiomeResourceKey(
|
||||||
fingerprintCustomBiomeIdentity(
|
fingerprintCustomBiomeIdentity(
|
||||||
fingerprintCustomBiomeEffectiveDefinition(requiredBiome, contentGate),
|
fingerprintCustomBiomeEffectiveDefinition(requiredBiome, contentGate),
|
||||||
dimensionKey,
|
dimensionKey,
|
||||||
requiredBiome.getId()
|
requiredBiome.getId()
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
registerCustomBiomeName(dimensionKey, requiredBiome.getId(), resourceKey);
|
||||||
|
return resourceKey;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String customBiomeResourceKey(
|
public static String customBiomeResourceKey(
|
||||||
@@ -310,13 +314,15 @@ public final class GenerationRegistryContractFactory {
|
|||||||
) {
|
) {
|
||||||
IrisBiomeCustom requiredBiome = Objects.requireNonNull(customBiome, "customBiome");
|
IrisBiomeCustom requiredBiome = Objects.requireNonNull(customBiome, "customBiome");
|
||||||
PlatformGenerationRegistry requiredRegistry = Objects.requireNonNull(registry, "registry");
|
PlatformGenerationRegistry requiredRegistry = Objects.requireNonNull(registry, "registry");
|
||||||
return requiredRegistry.customBiomeResourceKey(
|
String resourceKey = requiredRegistry.customBiomeResourceKey(
|
||||||
fingerprintCustomBiomeIdentity(
|
fingerprintCustomBiomeIdentity(
|
||||||
fingerprintCustomBiomeEffectiveDefinition(requiredBiome, contentGate),
|
fingerprintCustomBiomeEffectiveDefinition(requiredBiome, contentGate),
|
||||||
dimensionKey,
|
dimensionKey,
|
||||||
requiredBiome.getId()
|
requiredBiome.getId()
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
registerCustomBiomeName(dimensionKey, requiredBiome.getId(), resourceKey);
|
||||||
|
return resourceKey;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String fingerprintCustomBiomeIdentity(
|
public static String fingerprintCustomBiomeIdentity(
|
||||||
@@ -387,6 +393,7 @@ public final class GenerationRegistryContractFactory {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (selectedKey != null) {
|
if (selectedKey != null) {
|
||||||
|
registerCustomBiomeName(dimensionKey, customBiomeId, selectedKey);
|
||||||
return selectedKey;
|
return selectedKey;
|
||||||
}
|
}
|
||||||
throw new IOException("Historical generation registry contract has no custom biome mapping for "
|
throw new IOException("Historical generation registry contract has no custom biome mapping for "
|
||||||
@@ -1539,6 +1546,14 @@ public final class GenerationRegistryContractFactory {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static void registerCustomBiomeName(String dimensionKey, String biomeId, String resourceKey) {
|
||||||
|
String dimension = requireText(dimensionKey, "Dimension load key").toLowerCase(Locale.ROOT)
|
||||||
|
.replaceAll("[^a-z0-9/._-]", "_");
|
||||||
|
String biome = requireText(biomeId, "Custom biome ID").toLowerCase(Locale.ROOT)
|
||||||
|
.replaceAll("[^a-z0-9/._-]", "_");
|
||||||
|
RegistryClientNames.register(BIOME_REGISTRY, resourceKey, "iris:" + dimension + "/" + biome);
|
||||||
|
}
|
||||||
|
|
||||||
private static void updateString(MessageDigest digest, String value) {
|
private static void updateString(MessageDigest digest, String value) {
|
||||||
byte[] bytes = value.getBytes(StandardCharsets.UTF_8);
|
byte[] bytes = value.getBytes(StandardCharsets.UTF_8);
|
||||||
updateInt(digest, bytes.length);
|
updateInt(digest, bytes.length);
|
||||||
@@ -1608,6 +1623,7 @@ public final class GenerationRegistryContractFactory {
|
|||||||
+ dimension + ":" + requiredBiome.getId() + ".");
|
+ dimension + ":" + requiredBiome.getId() + ".");
|
||||||
}
|
}
|
||||||
requireGeneratedSemanticFingerprint(physicalKey, source, contract.definitions().get(physicalKey));
|
requireGeneratedSemanticFingerprint(physicalKey, source, contract.definitions().get(physicalKey));
|
||||||
|
registerCustomBiomeName(dimension, requiredBiome.getId(), resourceKey);
|
||||||
dimensionKeys.put(requiredBiome, resourceKey);
|
dimensionKeys.put(requiredBiome, resourceKey);
|
||||||
return resourceKey;
|
return resourceKey;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,192 @@
|
|||||||
|
package art.arcane.iris.integration.data;
|
||||||
|
|
||||||
|
import art.arcane.iris.generation.biome.IrisBiome;
|
||||||
|
import art.arcane.iris.generation.runtime.Engine;
|
||||||
|
import art.arcane.iris.generation.terrain.IrisRegion;
|
||||||
|
import art.arcane.iris.platform.generation.PlatformChunkGenerator;
|
||||||
|
import art.arcane.iris.world.IrisToolbelt;
|
||||||
|
import art.arcane.iris.world.history.SavedBiomeUnavailableException;
|
||||||
|
import io.lumine.mythic.api.adapters.AbstractLocation;
|
||||||
|
import io.lumine.mythic.api.config.MythicLineConfig;
|
||||||
|
import io.lumine.mythic.api.skills.conditions.ILocationCondition;
|
||||||
|
import io.lumine.mythic.bukkit.MythicBukkit;
|
||||||
|
import io.lumine.mythic.bukkit.adapters.BukkitWorld;
|
||||||
|
import io.lumine.mythic.core.skills.SkillExecutor;
|
||||||
|
import org.bukkit.World;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.mockito.MockedStatic;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertFalse;
|
||||||
|
import static org.junit.Assert.assertSame;
|
||||||
|
import static org.junit.Assert.assertThrows;
|
||||||
|
import static org.junit.Assert.assertTrue;
|
||||||
|
import static org.mockito.ArgumentMatchers.any;
|
||||||
|
import static org.mockito.ArgumentMatchers.anyInt;
|
||||||
|
import static org.mockito.ArgumentMatchers.eq;
|
||||||
|
import static org.mockito.Mockito.mock;
|
||||||
|
import static org.mockito.Mockito.mockStatic;
|
||||||
|
import static org.mockito.Mockito.verify;
|
||||||
|
import static org.mockito.Mockito.when;
|
||||||
|
|
||||||
|
public class MythicMobsDataProviderTest {
|
||||||
|
@Test
|
||||||
|
public void loadingChecksRetryTheSameLocationOnceSavedEnvironmentIsReady() {
|
||||||
|
for (Query query : Query.values()) {
|
||||||
|
try (Fixture fixture = new Fixture()) {
|
||||||
|
ILocationCondition condition = fixture.condition(query);
|
||||||
|
fixture.failure = new SavedBiomeUnavailableException("Saved biome information is loading", true);
|
||||||
|
|
||||||
|
assertFalse(condition.check(fixture.target));
|
||||||
|
|
||||||
|
fixture.failure = null;
|
||||||
|
assertTrue(condition.check(fixture.target));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void readyEnvironmentMustMatchTheConfiguredName() {
|
||||||
|
for (Query query : Query.values()) {
|
||||||
|
try (Fixture fixture = new Fixture()) {
|
||||||
|
ILocationCondition condition = fixture.condition(query);
|
||||||
|
when(fixture.biome.getLoadKey()).thenReturn("other");
|
||||||
|
when(fixture.region.getLoadKey()).thenReturn("other");
|
||||||
|
|
||||||
|
assertFalse(condition.check(fixture.target));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void locationsWithoutAnIrisGeneratorOrEngineDoNotMatch() {
|
||||||
|
for (Query query : Query.values()) {
|
||||||
|
try (Fixture fixture = new Fixture()) {
|
||||||
|
ILocationCondition condition = fixture.condition(query);
|
||||||
|
fixture.toolbelt.when(() -> IrisToolbelt.access(fixture.world)).thenReturn(null);
|
||||||
|
assertFalse(condition.check(fixture.target));
|
||||||
|
|
||||||
|
fixture.toolbelt.when(() -> IrisToolbelt.access(fixture.world)).thenReturn(fixture.generator);
|
||||||
|
when(fixture.generator.getEngine()).thenReturn(null);
|
||||||
|
assertFalse(condition.check(fixture.target));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void permanentSavedEnvironmentFailuresPropagateUnchanged() {
|
||||||
|
for (Query query : Query.values()) {
|
||||||
|
try (Fixture fixture = new Fixture()) {
|
||||||
|
ILocationCondition condition = fixture.condition(query);
|
||||||
|
fixture.failure = new SavedBiomeUnavailableException("Saved epoch is missing", false);
|
||||||
|
|
||||||
|
assertSame(fixture.failure, assertThrows(SavedBiomeUnavailableException.class,
|
||||||
|
() -> condition.check(fixture.target)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void loadingFailuresWithSuppressedErrorsRemainVisible() {
|
||||||
|
for (Query query : Query.values()) {
|
||||||
|
try (Fixture fixture = new Fixture()) {
|
||||||
|
ILocationCondition condition = fixture.condition(query);
|
||||||
|
fixture.failure = new SavedBiomeUnavailableException("Saved biome information is loading", true);
|
||||||
|
fixture.failure.addSuppressed(new IllegalStateException("failed to close saved epoch"));
|
||||||
|
|
||||||
|
assertSame(fixture.failure, assertThrows(SavedBiomeUnavailableException.class,
|
||||||
|
() -> condition.check(fixture.target)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void unrelatedRuntimeFailuresAreNotHidden() {
|
||||||
|
for (Query query : Query.values()) {
|
||||||
|
try (Fixture fixture = new Fixture()) {
|
||||||
|
ILocationCondition condition = fixture.condition(query);
|
||||||
|
fixture.failure = new IllegalStateException("broken integration query");
|
||||||
|
|
||||||
|
assertSame(fixture.failure, assertThrows(IllegalStateException.class,
|
||||||
|
() -> condition.check(fixture.target)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void volumeAndRegionQueriesUseWorldHeightWhileSurfaceUsesHorizontalCoordinates() {
|
||||||
|
try (Fixture fixture = new Fixture()) {
|
||||||
|
assertTrue(fixture.condition(Query.VOLUME).check(fixture.target));
|
||||||
|
assertTrue(fixture.condition(Query.SURFACE).check(fixture.target));
|
||||||
|
assertTrue(fixture.condition(Query.REGION).check(fixture.target));
|
||||||
|
|
||||||
|
verify(fixture.engine).getBiomeOrMantle(12, 134, -18);
|
||||||
|
verify(fixture.engine).getSurfaceBiome(12, -18);
|
||||||
|
verify(fixture.engine).getRegion(12, 134, -18);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private enum Query {
|
||||||
|
VOLUME, SURFACE, REGION
|
||||||
|
}
|
||||||
|
|
||||||
|
private static final class Fixture implements AutoCloseable {
|
||||||
|
private final World world = mock(World.class);
|
||||||
|
private final PlatformChunkGenerator generator = mock(PlatformChunkGenerator.class);
|
||||||
|
private final Engine engine = mock(Engine.class);
|
||||||
|
private final IrisBiome biome = mock(IrisBiome.class);
|
||||||
|
private final IrisRegion region = mock(IrisRegion.class);
|
||||||
|
private final AbstractLocation target = mock(AbstractLocation.class);
|
||||||
|
private final MockedStatic<IrisToolbelt> toolbelt = mockStatic(IrisToolbelt.class);
|
||||||
|
private final MockedStatic<MythicBukkit> mythic = mockStatic(MythicBukkit.class);
|
||||||
|
private RuntimeException failure;
|
||||||
|
|
||||||
|
private Fixture() {
|
||||||
|
MythicBukkit plugin = mock(MythicBukkit.class);
|
||||||
|
when(plugin.getSkillManager()).thenReturn(mock(SkillExecutor.class));
|
||||||
|
mythic.when(MythicBukkit::inst).thenReturn(plugin);
|
||||||
|
BukkitWorld targetWorld = mock(BukkitWorld.class);
|
||||||
|
when(targetWorld.getBukkitWorld()).thenReturn(world);
|
||||||
|
when(target.getWorld()).thenReturn(targetWorld);
|
||||||
|
when(target.getBlockX()).thenReturn(12);
|
||||||
|
when(target.getBlockY()).thenReturn(70);
|
||||||
|
when(target.getBlockZ()).thenReturn(-18);
|
||||||
|
toolbelt.when(() -> IrisToolbelt.access(world)).thenReturn(generator);
|
||||||
|
when(generator.getEngine()).thenReturn(engine);
|
||||||
|
when(engine.getMinHeight()).thenReturn(-64);
|
||||||
|
when(biome.getLoadKey()).thenReturn("matching");
|
||||||
|
when(region.getLoadKey()).thenReturn("matching");
|
||||||
|
when(engine.getBiomeOrMantle(anyInt(), anyInt(), anyInt())).thenAnswer(invocation -> resolvedBiome());
|
||||||
|
when(engine.getSurfaceBiome(anyInt(), anyInt())).thenAnswer(invocation -> resolvedBiome());
|
||||||
|
when(engine.getRegion(anyInt(), anyInt(), anyInt())).thenAnswer(invocation -> resolvedRegion());
|
||||||
|
}
|
||||||
|
|
||||||
|
private ILocationCondition condition(Query query) {
|
||||||
|
MythicLineConfig config = mock(MythicLineConfig.class);
|
||||||
|
when(config.getString(any(String[].class), eq(""))).thenReturn("matching");
|
||||||
|
when(config.getBoolean(any(String[].class), eq(false))).thenReturn(query == Query.SURFACE);
|
||||||
|
return query == Query.REGION
|
||||||
|
? new MythicMobsDataProvider.IrisRegionCondition("irisregion", config)
|
||||||
|
: new MythicMobsDataProvider.IrisBiomeCondition("irisbiome", config);
|
||||||
|
}
|
||||||
|
|
||||||
|
private IrisBiome resolvedBiome() {
|
||||||
|
if (failure != null) {
|
||||||
|
throw failure;
|
||||||
|
}
|
||||||
|
return biome;
|
||||||
|
}
|
||||||
|
|
||||||
|
private IrisRegion resolvedRegion() {
|
||||||
|
if (failure != null) {
|
||||||
|
throw failure;
|
||||||
|
}
|
||||||
|
return region;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void close() {
|
||||||
|
mythic.close();
|
||||||
|
toolbelt.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+23
@@ -19,6 +19,7 @@ import art.arcane.iris.generation.terrain.IrisDimensionTypeOptions;
|
|||||||
import art.arcane.iris.structure.nativegen.IrisNativeStructure;
|
import art.arcane.iris.structure.nativegen.IrisNativeStructure;
|
||||||
import art.arcane.iris.structure.placement.IrisStructurePlacement;
|
import art.arcane.iris.structure.placement.IrisStructurePlacement;
|
||||||
import art.arcane.iris.spi.PlatformGenerationRegistry;
|
import art.arcane.iris.spi.PlatformGenerationRegistry;
|
||||||
|
import art.arcane.volmlib.nativelib.terrain.RegistryClientNames;
|
||||||
import art.arcane.iris.spi.PlatformRegistries;
|
import art.arcane.iris.spi.PlatformRegistries;
|
||||||
import art.arcane.volmlib.util.collection.KList;
|
import art.arcane.volmlib.util.collection.KList;
|
||||||
import art.arcane.volmlib.util.json.JSONObject;
|
import art.arcane.volmlib.util.json.JSONObject;
|
||||||
@@ -195,6 +196,9 @@ public class GenerationRegistryContractFactoryTest {
|
|||||||
new GenerationRegistryContractFactory.CustomBiomeResourceResolver(contract, registry::customBiomeResourceKey);
|
new GenerationRegistryContractFactory.CustomBiomeResourceResolver(contract, registry::customBiomeResourceKey);
|
||||||
assertEquals(plateauKey, resolver.resolve("overworld", plateau));
|
assertEquals(plateauKey, resolver.resolve("overworld", plateau));
|
||||||
assertEquals(vanillaKey, resolver.resolve("overworld", vanilla));
|
assertEquals(vanillaKey, resolver.resolve("overworld", vanilla));
|
||||||
|
assertEquals(Set.of("iris:overworld/savanna_plateau", "iris_2:overworld/savanna_plateau"),
|
||||||
|
Set.copyOf(RegistryClientNames.resolve(GenerationRegistryContractFactory.BIOME_REGISTRY,
|
||||||
|
List.of(plateauKey, vanillaKey))));
|
||||||
assertNotEquals(plateauKey, GenerationRegistryContractFactory.customBiomeResourceKey("overworld", plateau, registry));
|
assertNotEquals(plateauKey, GenerationRegistryContractFactory.customBiomeResourceKey("overworld", plateau, registry));
|
||||||
assertThrows(IOException.class,
|
assertThrows(IOException.class,
|
||||||
() -> resolver.resolve("overworld", new IrisBiomeCustom().setId("savanna_plateau").setGrassColor("#FF0000")));
|
() -> resolver.resolve("overworld", new IrisBiomeCustom().setId("savanna_plateau").setGrassColor("#FF0000")));
|
||||||
@@ -236,6 +240,25 @@ public class GenerationRegistryContractFactoryTest {
|
|||||||
PlatformGenerationRegistry.contentAddressedCustomBiomeResourceKey(first));
|
PlatformGenerationRegistry.contentAddressedCustomBiomeResourceKey(first));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void clientBiomeNamesUseAuthoredIdsWhilePhysicalIdentitiesStayDistinct() {
|
||||||
|
IrisBiomeCustom first = new IrisBiomeCustom().setId("Mist").setTemperature(0.5D);
|
||||||
|
IrisBiomeCustom second = new IrisBiomeCustom().setId("Mist").setTemperature(0.7D);
|
||||||
|
String firstKey = GenerationRegistryContractFactory.customBiomeResourceKey("Overworld", first);
|
||||||
|
String secondKey = GenerationRegistryContractFactory.customBiomeResourceKey("Overworld", second);
|
||||||
|
List<String> physicalKeys = List.of("minecraft:plains", firstKey, secondKey);
|
||||||
|
|
||||||
|
List<String> clientKeys = RegistryClientNames.resolve(
|
||||||
|
GenerationRegistryContractFactory.BIOME_REGISTRY, physicalKeys);
|
||||||
|
|
||||||
|
assertNotEquals(firstKey, secondKey);
|
||||||
|
assertEquals("minecraft:plains", clientKeys.getFirst());
|
||||||
|
assertEquals(Set.of("iris:overworld/mist", "iris_2:overworld/mist"),
|
||||||
|
Set.of(clientKeys.get(1), clientKeys.get(2)));
|
||||||
|
assertTrue(firstKey.matches("iris:biomes/[a-f0-9]{64}"));
|
||||||
|
assertEquals(List.of("minecraft:plains", firstKey, secondKey), physicalKeys);
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void contentGateEffectsParticipateInCustomBiomeIdentity() {
|
public void contentGateEffectsParticipateInCustomBiomeIdentity() {
|
||||||
IrisBiomeCustom custom = new IrisBiomeCustom()
|
IrisBiomeCustom custom = new IrisBiomeCustom()
|
||||||
|
|||||||
Reference in new issue
Block a user