Merged biome retention

- Saved biome behavior is integrated with current Iris changes
This commit is contained in:
Brian Neumann-Fopiano committed 2026-09-05 20:30:52 -04:00
commit 80843114fc
57 files changed
+4460 -385

No files matched your search

@@ -600,7 +600,8 @@ public final class IrisWorldGeneratorResolver {
throw new IllegalStateException("Immutable Iris generation pack at " + packRoot
+ " does not contain dimension " + dimensionKey + ".");
}
GenerationEpoch.DimensionContract actualContract = captureDimensionContract(data, dimension);
GenerationEpoch.DimensionContract actualContract = GenerationEpochContractFactory.createForEpoch(
dimension, dimensionTypeKey(data, dimension), epoch);
if (!epoch.dimensionContract().equals(actualContract)) {
throw new IllegalStateException("Immutable Iris generation pack dimension contract changed at "
+ packRoot + ".");
@@ -612,7 +613,15 @@ public final class IrisWorldGeneratorResolver {
IrisData data,
IrisDimension dimension
) {
String dimensionTypeKey = IrisPlatforms.get()
return GenerationEpochContractFactory.create(
dimension,
dimension.getLoadKey(),
dimensionTypeKey(data, dimension)
);
}
private static String dimensionTypeKey(IrisData data, IrisDimension dimension) {
return IrisPlatforms.get()
.registries()
.generationRegistry()
.dimensionTypeResourceKey(
@@ -620,11 +629,6 @@ public final class IrisWorldGeneratorResolver {
dimension.getLoadKey(),
dimension.getDimensionTypeKey()
);
return GenerationEpochContractFactory.create(
dimension,
dimension.getLoadKey(),
dimensionTypeKey
);
}
private static File requireActivePack(GenerationHistory history) {
@@ -31,6 +31,7 @@ import art.arcane.iris.engine.framework.GenerationSessionLease;
import art.arcane.iris.engine.platform.EngineBukkitOps;
import art.arcane.iris.util.project.context.IrisContext;
import art.arcane.iris.engine.object.IrisBiome;
import art.arcane.iris.engine.history.SavedBiomeUnavailableException;
import art.arcane.iris.engine.object.IrisRegion;
import art.arcane.iris.util.common.director.DirectorExecutor;
import art.arcane.iris.util.common.plugin.VolmitSender;
@@ -82,21 +83,36 @@ public class CommandWhat implements DirectorExecutor {
@Director(description = "What biome am i in?", descriptionKey = "iris.director.commandwhat.director.what_biome_am_i", origin = DirectorOrigin.PLAYER)
public void biome() {
VolmitSender commandSender = sender();
Player player = player();
onPlayerThread(player, () -> describeBiome(commandSender, player));
}
private void describeBiome(VolmitSender commandSender, Player player) {
Location location = player.getLocation();
try {
IrisBiome b = engine().getBiome(player().getLocation().getBlockX(), player().getLocation().getBlockY() - player().getWorld().getMinHeight(), player().getLocation().getBlockZ());
Engine engine = IrisToolbelt.access(location.getWorld()).getEngine();
IrisBiome b = engine.getBiome(location.getBlockX(), location.getBlockY() - location.getWorld().getMinHeight(), location.getBlockZ());
Biome derivative = b.getDerivative();
NamespacedKey derivativeKey = resolveBiomeKey(derivative);
sender().sendMessage(IrisLanguage.text(BukkitCommandMessagesExtended.COMMAND_WHAT_IBIOME, MessageArgument.untrusted("value", b.getLoadKey()), MessageArgument.untrusted("value2", derivativeKey == null ? IrisLanguage.plain(RuntimeUiMessages.STATUS_UNREGISTERED) : derivativeKey.getKey())));
commandSender.sendMessage(IrisLanguage.text(BukkitCommandMessagesExtended.COMMAND_WHAT_IBIOME, MessageArgument.untrusted("value", b.getLoadKey()), MessageArgument.untrusted("value2", derivativeKey == null ? IrisLanguage.plain(RuntimeUiMessages.STATUS_UNREGISTERED) : derivativeKey.getKey())));
} catch (SavedBiomeUnavailableException e) {
if (e.getCause() != null) {
Iris.reportError(e);
}
commandSender.sendMessage(e.isLoading()
? "Saved biome data is loading. Run the command again shortly."
: e.getMessage());
} catch (Throwable e) {
Iris.reportError(e);
Biome biome = player().getLocation().getBlock().getBiome();
Biome biome = location.getBlock().getBiome();
NamespacedKey key = resolveBiomeKey(biome);
sender().sendMessage(IrisLanguage.text(BukkitCommandMessagesExtended.COMMAND_WHAT_NON_IRIS_BIOME, MessageArgument.untrusted("value", key == null ? IrisLanguage.plain(RuntimeUiMessages.STATUS_UNREGISTERED) : key)));
commandSender.sendMessage(IrisLanguage.text(BukkitCommandMessagesExtended.COMMAND_WHAT_NON_IRIS_BIOME, MessageArgument.untrusted("value", key == null ? IrisLanguage.plain(RuntimeUiMessages.STATUS_UNREGISTERED) : key)));
if (key == null || key.getKey().equals("custom")) {
try {
sender().sendMessage(IrisLanguage.text(BukkitCommandMessagesExtended.COMMAND_WHAT_DATA_PACK_BIOME_ID, MessageArgument.untrusted("value", INMS.get().getTrueBiomeBaseKey(player().getLocation())), MessageArgument.untrusted("value2", INMS.get().getTrueBiomeBaseId(INMS.get().getTrueBiomeBase(player().getLocation())))));
commandSender.sendMessage(IrisLanguage.text(BukkitCommandMessagesExtended.COMMAND_WHAT_DATA_PACK_BIOME_ID, MessageArgument.untrusted("value", INMS.get().getTrueBiomeBaseKey(location)), MessageArgument.untrusted("value2", INMS.get().getTrueBiomeBaseId(INMS.get().getTrueBiomeBase(location)))));
} catch (Throwable ee) {
Iris.reportError(ee);
}
@@ -118,6 +134,13 @@ public class CommandWhat implements DirectorExecutor {
IrisRegion r = EngineBukkitOps.getRegion(engine, chunk);
commandSender.sendMessage(IrisLanguage.text(BukkitCommandMessagesExtended.COMMAND_WHAT_IREGION, MessageArgument.untrusted("value", r.getLoadKey()), MessageArgument.untrusted("value2", r.getName())));
} catch (SavedBiomeUnavailableException e) {
if (e.getCause() != null) {
Iris.reportError(e);
}
commandSender.sendMessage(e.isLoading()
? "Saved biome data is loading. Run the command again shortly."
: e.getMessage());
} catch (Throwable e) {
Iris.reportError(e);
commandSender.sendMessage(IrisLanguage.text(BukkitCommandMessagesExtended.COMMAND_WHAT_IRIS_WORLDS_ONLY));
@@ -0,0 +1,80 @@
package art.arcane.iris.core.commands;
import art.arcane.iris.core.localization.BukkitCommandMessagesExtended;
import art.arcane.iris.core.localization.IrisLanguage;
import art.arcane.iris.core.localization.RuntimeUiMessages;
import art.arcane.iris.core.tools.IrisToolbelt;
import art.arcane.iris.engine.framework.Engine;
import art.arcane.iris.engine.object.IrisBiome;
import art.arcane.iris.engine.platform.PlatformChunkGenerator;
import art.arcane.iris.util.common.director.DirectorContext;
import art.arcane.iris.util.common.plugin.VolmitSender;
import art.arcane.iris.util.common.scheduling.J;
import art.arcane.volmlib.util.localization.MessageArgument;
import org.bukkit.Location;
import org.bukkit.World;
import org.bukkit.entity.Player;
import org.junit.Test;
import org.mockito.MockedStatic;
import java.util.concurrent.atomic.AtomicReference;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
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.never;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyNoInteractions;
import static org.mockito.Mockito.when;
public class CommandWhatBiomeTest {
@Test
public void scheduledBiomeDescriptionUsesThePlayersWorldAfterCommandContextClears() {
VolmitSender sender = mock(VolmitSender.class);
Player player = mock(Player.class);
World world = mock(World.class);
Engine engine = mock(Engine.class);
PlatformChunkGenerator generator = mock(PlatformChunkGenerator.class);
IrisBiome biome = mock(IrisBiome.class);
AtomicReference<Runnable> scheduled = new AtomicReference<>();
when(sender.player()).thenReturn(player);
when(sender.isPlayer()).thenReturn(true);
when(player.getWorld()).thenReturn(world);
when(player.getLocation()).thenReturn(new Location(world, 19, 70, -3));
when(world.getMinHeight()).thenReturn(-64);
when(generator.getEngine()).thenReturn(engine);
when(engine.getBiome(19, 134, -3)).thenReturn(biome);
when(biome.getLoadKey()).thenReturn("retained-flat");
try (MockedStatic<J> scheduler = mockStatic(J.class);
MockedStatic<IrisToolbelt> toolbelt = mockStatic(IrisToolbelt.class);
MockedStatic<IrisLanguage> language = mockStatic(IrisLanguage.class)) {
scheduler.when(() -> J.runEntity(eq(player), any(Runnable.class))).thenAnswer(invocation -> {
scheduled.set(invocation.getArgument(1));
return true;
});
toolbelt.when(() -> IrisToolbelt.access(world)).thenReturn(generator);
language.when(() -> IrisLanguage.plain(RuntimeUiMessages.STATUS_UNREGISTERED)).thenReturn("unregistered");
language.when(() -> IrisLanguage.text(eq(BukkitCommandMessagesExtended.COMMAND_WHAT_IBIOME),
any(MessageArgument.class), any(MessageArgument.class))).thenReturn("Iris biome: retained-flat");
DirectorContext.touch(sender);
try {
new CommandWhat().biome();
} finally {
DirectorContext.remove();
}
assertNull(DirectorContext.get());
assertNotNull(scheduled.get());
verifyNoInteractions(engine);
scheduled.get().run();
verify(engine).getBiome(19, 134, -3);
verify(sender).sendMessage("Iris biome: retained-flat");
verify(world, never()).getBlockAt(anyInt(), anyInt(), anyInt());
}
}
}