mirror of
https://github.com/VolmitSoftware/Iris.git
synced 2026-10-11 19:14:11 +00:00
Modded 26.3
- Fabric, Forge and NeoForge target Minecraft 26.3 - Fabric uses loader 0.19.5 with Fabric API modules from 0.161.0+26.3 - Forge uses 26.3-66.0.8 with ForgeGradle 7.0.40 - NeoForge uses 26.3.0.33-beta with ModDevGradle 2.0.147 - Modded forced datapacks use the 26.3 data fixer and pack format 121 - Biome mob spawns are written as vanilla overlays - Stronghold ring biome searches use the natural biome stream - Chunk generation mob spawns go through the loader spawn position event - README and the bug template list the supported versions
This commit is contained in:
@@ -49,9 +49,11 @@ body:
|
||||
id: mcversion
|
||||
attributes:
|
||||
label: Minecraft Version
|
||||
description: What version of Minecraft is the server on? Iris 4.x targets 26.2 only; older versions are not supported.
|
||||
description: What version of Minecraft is the server on? Iris 4.x supports 26.1.2 to 26.3 on Bukkit-family servers and 26.3 on Fabric, Forge and NeoForge; older versions are not supported.
|
||||
options:
|
||||
- '26.3'
|
||||
- '26.2'
|
||||
- '26.1.2'
|
||||
- Other (unsupported)
|
||||
validations:
|
||||
required: true
|
||||
@@ -59,7 +61,7 @@ body:
|
||||
id: loaderversion
|
||||
attributes:
|
||||
label: Platform / Loader Version
|
||||
description: Exact server or loader build (see console). For example "Paper 26.2-60", "Fabric Loader 0.19.3", "NeoForge 26.2.0.12-beta".
|
||||
description: Exact server or loader build (see console). For example "Paper 26.3-133", "Fabric Loader 0.19.5", "NeoForge 26.3.0.33-beta".
|
||||
placeholder: DO NOT SAY "LATEST"
|
||||
validations:
|
||||
required: true
|
||||
|
||||
@@ -4,7 +4,7 @@ Iris is a world generation engine for Minecraft servers and mod loaders. It gene
|
||||
biomes, caves, structures, objects, and entities from editable JSON packs, with a full in-game
|
||||
studio authoring workflow. The same engine runs as a Bukkit-family plugin and as a Fabric, Forge,
|
||||
or NeoForge server mod. Cross-platform generation targets deterministic parity for identical
|
||||
artifacts, pack bytes, seeds, and test areas. The master branch targets Minecraft 26.2.
|
||||
artifacts, pack bytes, seeds, and test areas. The master branch targets Minecraft 26.3.
|
||||
|
||||
# [Support](https://discord.gg/3xxPTpT) **|** [Documentation](https://github.com/VolmitSoftware/docs/blob/master/iris/00-overview.md) **|** [Git](https://github.com/IrisDimensions)
|
||||
|
||||
@@ -20,12 +20,12 @@ Canonical English is defined in the typed Java catalogs under `core/src/main/jav
|
||||
|
||||
| Platform | Artifact | Minecraft | Notes |
|
||||
|---|---|---|---|
|
||||
| Paper / Purpur / Leaf / Canvas | plugin jar | 26.1.2 - 26.2 | Full feature set |
|
||||
| Folia | plugin jar | 26.1.2 - 26.2 | Region-safe scheduling throughout |
|
||||
| Spigot / CraftBukkit | plugin jar | 26.1.2 - 26.2 | Managed `iris:*` creation and generation; exact vanilla-slot `/iris replace` is unavailable |
|
||||
| Fabric | mod jar | 26.2 | Server worldgen + client HUD; requires Fabric Loader 0.19.3+ |
|
||||
| Forge | mod jar | 26.2 | Server worldgen + client HUD; current target is Forge 26.2-65.1.1 |
|
||||
| NeoForge | mod jar | 26.2 | Server worldgen + client HUD; current target is NeoForge 26.2.0.59 |
|
||||
| Paper / Purpur / Leaf / Canvas | plugin jar | 26.1.2 - 26.3 | Full feature set |
|
||||
| Folia | plugin jar | 26.1.2 - 26.3 | Region-safe scheduling throughout |
|
||||
| Spigot / CraftBukkit | plugin jar | 26.1.2 - 26.3 | Managed `iris:*` creation and generation; exact vanilla-slot `/iris replace` is unavailable |
|
||||
| Fabric | mod jar | 26.3 | Server worldgen + client HUD; requires Fabric Loader 0.19.5+ |
|
||||
| Forge | mod jar | 26.3 | Server worldgen + client HUD; current target is Forge 26.3-66.0.8 |
|
||||
| NeoForge | mod jar | 26.3 | Server worldgen + client HUD; current target is NeoForge 26.3.0.33-beta |
|
||||
|
||||
Java 25 is required on every platform.
|
||||
|
||||
|
||||
+3
@@ -13,6 +13,7 @@ import net.minecraft.data.registries.VanillaRegistries;
|
||||
import net.minecraft.resources.RegistryOps;
|
||||
import net.minecraft.server.Bootstrap;
|
||||
import net.minecraft.world.attribute.EnvironmentAttributes;
|
||||
import net.minecraft.world.attribute.modifier.MobSpawnSettingsModifier;
|
||||
import net.minecraft.world.entity.MobCategory;
|
||||
import net.minecraft.world.level.biome.Biome;
|
||||
import net.minecraft.world.level.biome.MobSpawnSettings;
|
||||
@@ -53,5 +54,7 @@ public class CustomBiomeCodecTest {
|
||||
assertEquals(2, decoded.count().minInclusive());
|
||||
assertEquals(4, decoded.count().maxInclusive());
|
||||
assertEquals(0x102030, biome.getWaterColor() & 0xFFFFFF);
|
||||
assertEquals(MobSpawnSettingsModifier.overlay(),
|
||||
biome.getAttributes().get(EnvironmentAttributes.NATURAL_MOB_SPAWNS).modifier());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -60,8 +60,8 @@ apply from: file('../../gradle/modded-generation-build-revision.gradle')
|
||||
Properties rootProperties = new Properties()
|
||||
file('../../gradle.properties').withInputStream { InputStream stream -> rootProperties.load(stream) }
|
||||
String irisVersion = providers.gradleProperty('irisVersion').getOrElse(rootProperties.getProperty('irisVersion', '4.1.2-26.2'))
|
||||
String minecraftVersion = providers.gradleProperty('minecraftVersion').getOrElse(rootProperties.getProperty('minecraftVersion', '26.2'))
|
||||
String fabricLoaderVersion = providers.gradleProperty('fabricLoaderVersion').getOrElse(rootProperties.getProperty('fabricLoaderVersion', '0.19.3'))
|
||||
String minecraftVersion = providers.gradleProperty('minecraftVersion').getOrElse(rootProperties.getProperty('minecraftVersion', '26.3'))
|
||||
String fabricLoaderVersion = providers.gradleProperty('fabricLoaderVersion').getOrElse(rootProperties.getProperty('fabricLoaderVersion', '0.19.5'))
|
||||
String volmLibCoordinate = providers.gradleProperty('volmLibCoordinate').getOrElse(rootProperties.getProperty('volmLibCoordinate', 'com.github.VolmitSoftware:VolmLib:master-SNAPSHOT'))
|
||||
Closure<String> irisArtifactName = { String platform, String targetVersion ->
|
||||
return "Iris v${project.version} [${platform}] ${targetVersion}.jar"
|
||||
|
||||
@@ -70,7 +70,7 @@
|
||||
}
|
||||
],
|
||||
"depends": {
|
||||
"fabricloader": ">=0.19.3",
|
||||
"fabricloader": ">=0.19.5",
|
||||
"minecraft": "~${minecraftVersion}",
|
||||
"java": ">=25"
|
||||
}
|
||||
|
||||
+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));
|
||||
}
|
||||
}
|
||||
@@ -42,7 +42,7 @@ buildscript {
|
||||
|
||||
plugins {
|
||||
id 'java'
|
||||
id 'net.minecraftforge.gradle' version '7.0.31'
|
||||
id 'net.minecraftforge.gradle' version '7.0.40'
|
||||
alias(libs.plugins.shadow)
|
||||
}
|
||||
|
||||
@@ -60,8 +60,8 @@ apply from: file('../../gradle/modded-generation-build-revision.gradle')
|
||||
Properties rootProperties = new Properties()
|
||||
file('../../gradle.properties').withInputStream { InputStream stream -> rootProperties.load(stream) }
|
||||
String irisVersion = providers.gradleProperty('irisVersion').getOrElse(rootProperties.getProperty('irisVersion', '4.1.2-26.2'))
|
||||
String minecraftVersion = providers.gradleProperty('minecraftVersion').getOrElse(rootProperties.getProperty('minecraftVersion', '26.2'))
|
||||
String forgeVersion = providers.gradleProperty('forgeVersion').getOrElse(rootProperties.getProperty('forgeVersion', '26.2-65.1.1'))
|
||||
String minecraftVersion = providers.gradleProperty('minecraftVersion').getOrElse(rootProperties.getProperty('minecraftVersion', '26.3'))
|
||||
String forgeVersion = providers.gradleProperty('forgeVersion').getOrElse(rootProperties.getProperty('forgeVersion', '26.3-66.0.8'))
|
||||
String volmLibCoordinate = providers.gradleProperty('volmLibCoordinate').getOrElse(rootProperties.getProperty('volmLibCoordinate', 'com.github.VolmitSoftware:VolmLib:master-SNAPSHOT'))
|
||||
Closure<String> loaderDisplayVersion = { String loaderVersion ->
|
||||
String coordinatePrefix = "${minecraftVersion}-"
|
||||
@@ -272,7 +272,7 @@ tasks.named('shadowJar', ShadowJar).configure {
|
||||
}
|
||||
}
|
||||
manifest {
|
||||
// FML 26.2 has no TOML mixin handling at all (ModFileParser reads neither [[mixins]] nor
|
||||
// FML 26.3 has no TOML mixin handling at all (ModFileParser reads neither [[mixins]] nor
|
||||
// accessTransformers on Forge). This manifest attribute is the only registration mechanism;
|
||||
// do not move it into mods.toml.
|
||||
attributes('MixinConfigs': 'volmlib.entity.mixins.json,volmlib.client.mixins.json')
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
modLoader = "javafml"
|
||||
loaderVersion = "[65,66)"
|
||||
loaderVersion = "[66,67)"
|
||||
license = "GPL-3.0"
|
||||
issueTrackerURL = "https://github.com/VolmitSoftware/Iris/issues"
|
||||
|
||||
@@ -16,7 +16,7 @@ logoFile = "assets/irisworldgen/icon.png"
|
||||
[[dependencies.irisworldgen]]
|
||||
modId = "forge"
|
||||
mandatory = true
|
||||
versionRange = "[65,66)"
|
||||
versionRange = "[66,67)"
|
||||
ordering = "NONE"
|
||||
side = "BOTH"
|
||||
|
||||
|
||||
+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.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.NativeGeneratorHandle;
|
||||
@@ -1011,6 +1012,11 @@ public final class IrisModdedChunkGenerator implements NativeGeneratorOwner, Nat
|
||||
return ModdedEngineBootstrap.currentServer();
|
||||
}
|
||||
|
||||
@Override
|
||||
public NativeModdedLoader loader() {
|
||||
return ModdedEngineBootstrap.loader();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Engine current() {
|
||||
return engine();
|
||||
|
||||
@@ -72,6 +72,7 @@ final class ModdedBiomePolicy<H, S> implements NativeModdedBiomePolicy<H, S> {
|
||||
private volatile BiomeHolderTable<H> visibleBiomeCache = new BiomeHolderTable<>();
|
||||
private volatile BiomeHolderTable<H> structureBiomeCache = new BiomeHolderTable<>();
|
||||
private volatile BiomeHolderTable<H> surfaceStructureBiomeCache = new BiomeHolderTable<>();
|
||||
private volatile BiomeHolderTable<H> naturalStructureBiomeCache = new BiomeHolderTable<>();
|
||||
private volatile RuntimeCallbacks runtime;
|
||||
private volatile Set<String> possibleStructureBiomeKeys;
|
||||
private volatile BiomeKeySets biomeKeySets;
|
||||
@@ -94,6 +95,7 @@ final class ModdedBiomePolicy<H, S> implements NativeModdedBiomePolicy<H, S> {
|
||||
visibleBiomeCache = new BiomeHolderTable<>();
|
||||
structureBiomeCache = new BiomeHolderTable<>();
|
||||
surfaceStructureBiomeCache = new BiomeHolderTable<>();
|
||||
naturalStructureBiomeCache = new BiomeHolderTable<>();
|
||||
warnedUnresolvedBiomeKeys.clear();
|
||||
possibleStructureBiomeKeys = null;
|
||||
biomeKeySets = null;
|
||||
@@ -104,6 +106,7 @@ final class ModdedBiomePolicy<H, S> implements NativeModdedBiomePolicy<H, S> {
|
||||
visibleBiomeCache.evictRuntime(runtimeIdentity);
|
||||
structureBiomeCache.evictRuntime(runtimeIdentity);
|
||||
surfaceStructureBiomeCache.evictRuntime(runtimeIdentity);
|
||||
naturalStructureBiomeCache.evictRuntime(runtimeIdentity);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -791,11 +794,40 @@ final class ModdedBiomePolicy<H, S> implements NativeModdedBiomePolicy<H, S> {
|
||||
if (!isReady(engine)) {
|
||||
throw new IllegalStateException("Iris structure biome lookup has no active engine runtime");
|
||||
}
|
||||
return getNoiseBiome(engine, quartX, quartY, quartZ, sampler);
|
||||
return getNaturalStructureBiome(engine, quartX, quartZ);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// The structure state only samples biomes for the concentric-ring search, which reaches ~24k blocks out for
|
||||
// strongholds. The natural surface answers there without planning hydrology tiles, the same as the Bukkit ring search.
|
||||
private H getNaturalStructureBiome(Engine engine, int quartX, int quartZ) {
|
||||
long key = packColumnKey(quartX, quartZ);
|
||||
int runtimeIdentity = engine.getCacheID();
|
||||
BiomeHolderTable<H> cache = naturalStructureBiomeCache;
|
||||
H cached = cache.get(runtimeIdentity, key);
|
||||
if (cached != null) {
|
||||
return cached;
|
||||
}
|
||||
NativeBiomeSourceAccess.RegistryView<H> registry = biomeRegistry();
|
||||
if (registry == null) {
|
||||
throw new IllegalStateException("Iris structure biome lookup has no biome registry");
|
||||
}
|
||||
int blockX = quartX << 2;
|
||||
int blockZ = quartZ << 2;
|
||||
IrisBiome irisBiome = engine.getComplex().getNaturalTrueBiomeStream().get(blockX, blockZ);
|
||||
if (irisBiome == null) {
|
||||
throw new IllegalStateException("Iris returned no natural structure biome at block " + blockX + "," + blockZ);
|
||||
}
|
||||
H resolved = resolveHolder(registry, irisBiome.getStructureDerivativeKey());
|
||||
if (resolved == null) {
|
||||
throw new IllegalStateException("Iris natural structure biome derivative '"
|
||||
+ irisBiome.getStructureDerivativeKey() + "' is not registered at block " + blockX + "," + blockZ);
|
||||
}
|
||||
cache.put(runtimeIdentity, key, resolved);
|
||||
return resolved;
|
||||
}
|
||||
|
||||
static long biomeResolutionSeed(long worldSeed, int blockX, int blockY, int blockZ) {
|
||||
return worldSeed
|
||||
^ ((long) blockX * 341873128712L)
|
||||
|
||||
+4
-4
@@ -315,11 +315,11 @@ public final class ModdedForcedDatapack {
|
||||
throw new IllegalStateException("SHA-256 is unavailable", missing);
|
||||
}
|
||||
digest.update((HASH_SALT + '|' + ModdedEngineBootstrap.loader().platformName()
|
||||
+ '|' + DataVersion.V26_2.getPackFormat() + '\n').getBytes(StandardCharsets.UTF_8));
|
||||
+ '|' + DataVersion.V26_3.getPackFormat() + '\n').getBytes(StandardCharsets.UTF_8));
|
||||
String inputFingerprint = IrisDatapackCompiler.computeInputFingerprint(
|
||||
compilationPackRoots(),
|
||||
List.of(),
|
||||
DataVersion.V26_2.get(),
|
||||
DataVersion.V26_3.get(),
|
||||
false
|
||||
);
|
||||
digest.update(inputFingerprint.getBytes(StandardCharsets.UTF_8));
|
||||
@@ -328,7 +328,7 @@ public final class ModdedForcedDatapack {
|
||||
|
||||
private static void writeStagedPack(Path stagingDirectory) throws IOException {
|
||||
Map<String, KSet<String>> seenBiomes = new LinkedHashMap<>();
|
||||
IDataFixer fixer = DataVersion.V26_2.get();
|
||||
IDataFixer fixer = DataVersion.V26_3.get();
|
||||
|
||||
int packCount = 0;
|
||||
KList<String> presetIds = new KList<>();
|
||||
@@ -679,7 +679,7 @@ public final class ModdedForcedDatapack {
|
||||
}
|
||||
|
||||
static void writePackMeta(Path packDirectory) throws IOException {
|
||||
int packFormat = DataVersion.V26_2.getPackFormat();
|
||||
int packFormat = DataVersion.V26_3.getPackFormat();
|
||||
String json = "{\n"
|
||||
+ " \"pack\": {\n"
|
||||
+ " \"description\": \"Iris world generation biomes and dimension types for installed packs.\",\n"
|
||||
|
||||
+1
-1
@@ -55,7 +55,7 @@ final class WorldCheckDimensionContract {
|
||||
}
|
||||
|
||||
static Dimension expectedDimensionContract(IrisDimension dimension) {
|
||||
JSONObject json = new JSONObject(dimension.getDimensionType().toJson(DataVersion.V26_2.get()));
|
||||
JSONObject json = new JSONObject(dimension.getDimensionType().toJson(DataVersion.V26_3.get()));
|
||||
return new Dimension(
|
||||
json.getInt("min_y"),
|
||||
json.getInt("height"),
|
||||
|
||||
+2
-2
@@ -165,7 +165,7 @@ public final class ModdedDatapackCommands {
|
||||
IrisDimension dimension = engine.getDimension();
|
||||
String json;
|
||||
try {
|
||||
json = dimension.getDimensionType().toJson(DataVersion.V26_2.get());
|
||||
json = dimension.getDimensionType().toJson(DataVersion.V26_3.get());
|
||||
} catch (Throwable e) {
|
||||
ModdedIrisLog.error("Iris dimension type generation failed for {}", dimension.getLoadKey(), e);
|
||||
IrisModdedCommands.fail(source, IrisLanguage.plain(ModdedCommandMessages.MODDED_DATAPACK_COMMANDS_DIMENSION_TYPE_GENERATION_FAILED, MessageArgument.untrusted("value", level.name()), MessageArgument.untrusted("value2", String.valueOf(e.getMessage()))));
|
||||
@@ -187,7 +187,7 @@ public final class ModdedDatapackCommands {
|
||||
}
|
||||
|
||||
File mcmeta = new File(worldDatapacksFolder(server), WORLD_PACK_NAME + "/pack.mcmeta");
|
||||
int packFormat = DataVersion.V26_2.getPackFormat();
|
||||
int packFormat = DataVersion.V26_3.getPackFormat();
|
||||
String meta = "{\n"
|
||||
+ " \"pack\": {\n"
|
||||
+ " \"description\": \"Iris dimension types derived from the installed Iris packs.\",\n"
|
||||
|
||||
+1
-1
@@ -503,7 +503,7 @@ public final class ModdedPregenMethod implements PregeneratorMethod {
|
||||
/**
|
||||
* A dedicated server with {@code pause-when-empty-seconds > 0} returns from
|
||||
* {@code MinecraftServer#tickServer} before {@code tickChildren} once it has been empty for that
|
||||
* long (26.2 only keeps {@code tickConnection} plus the task/chunk-poll window alive). That
|
||||
* long (26.3 only keeps {@code tickConnection} plus the task/chunk-poll window alive). That
|
||||
* freezes every per-tick Iris service - world manager, scheduler, protocol sync, pregen HUD - and
|
||||
* the loader's own generation hooks for the whole job, and console pregen on a default
|
||||
* server.properties is always empty. The guard zeroes the setting for the duration of the job
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"pack": {
|
||||
"description": "Iris client resources and mod data",
|
||||
"min_format": [88, 0],
|
||||
"max_format": [107, 1]
|
||||
"min_format": [97, 1],
|
||||
"max_format": [121, 0]
|
||||
}
|
||||
}
|
||||
|
||||
+5
-4
@@ -6,6 +6,7 @@ import net.minecraft.SharedConstants;
|
||||
import net.minecraft.server.Bootstrap;
|
||||
import net.minecraft.util.random.Weighted;
|
||||
import net.minecraft.util.random.WeightedList;
|
||||
import net.minecraft.util.valueproviders.UniformInt;
|
||||
import net.minecraft.world.entity.EntityTypes;
|
||||
import net.minecraft.world.level.biome.MobSpawnSettings;
|
||||
import org.junit.Test;
|
||||
@@ -24,10 +25,10 @@ public class IrisModdedChunkGeneratorSpawnTest {
|
||||
|
||||
@Test
|
||||
public void explicitSpawnsReplaceMatchingVanillaTypesAndPreserveOthers() {
|
||||
MobSpawnSettings.SpawnerData zombie = new MobSpawnSettings.SpawnerData(EntityTypes.ZOMBIE, 1, 4);
|
||||
MobSpawnSettings.SpawnerData vanillaSlime = new MobSpawnSettings.SpawnerData(EntityTypes.SLIME, 1, 1);
|
||||
MobSpawnSettings.SpawnerData explicitSlime = new MobSpawnSettings.SpawnerData(EntityTypes.SLIME, 2, 5);
|
||||
MobSpawnSettings.SpawnerData explicitCow = new MobSpawnSettings.SpawnerData(EntityTypes.COW, 2, 4);
|
||||
MobSpawnSettings.SpawnerData zombie = new MobSpawnSettings.SpawnerData(EntityTypes.ZOMBIE, UniformInt.of(1, 4));
|
||||
MobSpawnSettings.SpawnerData vanillaSlime = new MobSpawnSettings.SpawnerData(EntityTypes.SLIME, UniformInt.of(1, 1));
|
||||
MobSpawnSettings.SpawnerData explicitSlime = new MobSpawnSettings.SpawnerData(EntityTypes.SLIME, UniformInt.of(2, 5));
|
||||
MobSpawnSettings.SpawnerData explicitCow = new MobSpawnSettings.SpawnerData(EntityTypes.COW, UniformInt.of(2, 4));
|
||||
WeightedList<MobSpawnSettings.SpawnerData> vanilla = WeightedList.of(List.of(
|
||||
new Weighted<>(zombie, 100),
|
||||
new Weighted<>(vanillaSlime, 1)));
|
||||
|
||||
+32
@@ -1,6 +1,12 @@
|
||||
package art.arcane.iris.modded;
|
||||
|
||||
import art.arcane.iris.generation.biome.IrisBiome;
|
||||
import art.arcane.iris.generation.runtime.Engine;
|
||||
import art.arcane.iris.generation.runtime.GenerationSessionLease;
|
||||
import art.arcane.iris.generation.runtime.IrisComplex;
|
||||
import art.arcane.volmlib.nativelib.terrain.NativeBiomeSourceAccess;
|
||||
import art.arcane.volmlib.util.stream.ProceduralStream;
|
||||
import art.arcane.volmlib.util.stream.interpolation.Interpolated;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.util.ArrayList;
|
||||
@@ -13,6 +19,9 @@ import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertSame;
|
||||
import static org.junit.Assert.assertThrows;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.mockito.ArgumentMatchers.anyString;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
public class ModdedBiomePolicyTest {
|
||||
@Test
|
||||
@@ -52,6 +61,29 @@ public class ModdedBiomePolicyTest {
|
||||
assertTrue(failure.getMessage().contains("example:missing"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void structureRingBiomesResolveFromTheNaturalSurfaceWithoutPlanningHydrology() throws Exception {
|
||||
BiomeToken forest = new BiomeToken("minecraft:forest");
|
||||
IrisBiome natural = mock(IrisBiome.class);
|
||||
when(natural.getStructureDerivativeKey()).thenReturn(forest.key());
|
||||
IrisComplex complex = mock(IrisComplex.class);
|
||||
when(complex.getNaturalTrueBiomeStream()).thenReturn(
|
||||
ProceduralStream.of((x, z) -> natural, Interpolated.of(value -> 0D, value -> null)));
|
||||
when(complex.getTrueBiomeStream()).thenThrow(
|
||||
new AssertionError("Stronghold ring lookups must not plan hydrology"));
|
||||
Engine engine = mock(Engine.class);
|
||||
when(engine.getComplex()).thenReturn(complex);
|
||||
when(engine.getMinHeight()).thenReturn(-64);
|
||||
when(engine.acquireGenerationLease(anyString())).thenReturn(GenerationSessionLease.noop());
|
||||
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));
|
||||
|
||||
assertSame(forest, policy.requiredStructureBiome(6000, 0, -6000, null));
|
||||
assertSame(forest, policy.requiredStructureBiome(6000, -30, -6000, null));
|
||||
}
|
||||
|
||||
private static ModdedBiomePolicy<BiomeToken, Object> policy(List<BiomeToken> entries,
|
||||
AtomicReference<Set<String>> configured) {
|
||||
ModdedBiomePolicy<BiomeToken, Object> policy = new ModdedBiomePolicy<>(new Access(entries));
|
||||
|
||||
+1
-1
@@ -79,7 +79,7 @@ public class ModdedDimensionTypeParityTest {
|
||||
IrisDimension end = dimension("the_end", IrisEnvironment.THE_END, 0, 256, 256, new IrisDimensionTypeOptions());
|
||||
IrisDimension custom = dimension("custom_contract", IrisEnvironment.CUSTOM, -128, 384, 384, customOptions);
|
||||
List<IrisDimension> dimensions = List.of(overworld, nether, end, custom);
|
||||
IDataFixer fixer = DataVersion.V26_2.get();
|
||||
IDataFixer fixer = DataVersion.V26_3.get();
|
||||
Path packDirectory = Files.createTempDirectory("iris-dimension-contracts");
|
||||
KList<File> roots = new KList<>();
|
||||
roots.add(packDirectory.toFile());
|
||||
|
||||
+4
-4
@@ -51,15 +51,15 @@ import static org.junit.Assert.assertTrue;
|
||||
|
||||
public class ModdedForcedDatapackTest {
|
||||
@Test
|
||||
public void metadataRetains262FormatWhenBukkitAlsoSupports263() throws IOException {
|
||||
public void metadataUses263DataFormat() throws IOException {
|
||||
Path packDirectory = Files.createTempDirectory("iris-modded-pack-format");
|
||||
try {
|
||||
ModdedForcedDatapack.writePackMeta(packDirectory);
|
||||
JSONObject pack = new JSONObject(Files.readString(packDirectory.resolve("pack.mcmeta")))
|
||||
.getJSONObject("pack");
|
||||
assertEquals(107, pack.getInt("pack_format"));
|
||||
assertEquals(107, pack.getInt("min_format"));
|
||||
assertEquals(107, pack.getInt("max_format"));
|
||||
assertEquals(121, pack.getInt("pack_format"));
|
||||
assertEquals(121, pack.getInt("min_format"));
|
||||
assertEquals(121, pack.getInt("max_format"));
|
||||
} finally {
|
||||
deleteTree(packDirectory);
|
||||
}
|
||||
|
||||
+9
-1
@@ -9,6 +9,9 @@ import art.arcane.volmlib.nativelib.minecraft26_2.modded.ModdedServerAccess;
|
||||
import art.arcane.volmlib.nativelib.minecraft26_2.modded.ModdedServerLevels;
|
||||
import net.minecraft.server.level.ServerLevel;
|
||||
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 org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
@@ -33,7 +36,7 @@ public class ModdedPlatformPathsTest {
|
||||
|
||||
@Override
|
||||
public String minecraftVersion() {
|
||||
return "26.2";
|
||||
return "26.3";
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -83,6 +86,11 @@ public class ModdedPlatformPathsTest {
|
||||
public boolean canBreakBlock(ServerLevel level, ServerPlayer player, BlockPos position, BlockState state) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean checkSpawnPosition(Mob mob, ServerLevelAccessor level, EntitySpawnReason reason) {
|
||||
return false;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
+12
-12
@@ -14,16 +14,18 @@ import net.minecraft.core.registries.Registries;
|
||||
import net.minecraft.resources.Identifier;
|
||||
import net.minecraft.resources.ResourceKey;
|
||||
import net.minecraft.server.Bootstrap;
|
||||
import net.minecraft.world.level.ChunkPos;
|
||||
import net.minecraft.world.level.biome.Biome;
|
||||
import net.minecraft.world.level.biome.BiomeResolver;
|
||||
import net.minecraft.world.level.biome.BiomeSource;
|
||||
import net.minecraft.world.level.biome.Climate;
|
||||
import net.minecraft.world.level.chunk.ChunkGeneratorStructureState;
|
||||
import net.minecraft.world.level.levelgen.RandomState;
|
||||
import net.minecraft.world.level.levelgen.structure.StructureSet;
|
||||
import net.minecraft.world.level.levelgen.structure.placement.AbstractSpreadingStructurePlacement;
|
||||
import net.minecraft.world.level.levelgen.structure.placement.RandomSpreadStructurePlacement;
|
||||
import net.minecraft.world.level.levelgen.structure.placement.RandomSpreadType;
|
||||
import net.minecraft.world.level.levelgen.structure.placement.StructurePlacement;
|
||||
import net.minecraft.world.level.levelgen.structure.placement.StructurePlacementType;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
|
||||
@@ -166,10 +168,10 @@ public class ModdedStructureSetFrequencyOverridesTest {
|
||||
) {
|
||||
return new RandomSpreadStructurePlacement(
|
||||
Vec3i.ZERO,
|
||||
StructurePlacement.FrequencyReductionMethod.DEFAULT,
|
||||
AbstractSpreadingStructurePlacement.FrequencyReductionMethod.DEFAULT,
|
||||
1F,
|
||||
salt,
|
||||
Optional.of(new StructurePlacement.ExclusionZone(exclusionTarget, 1)),
|
||||
Optional.of(new AbstractSpreadingStructurePlacement.ExclusionZone(exclusionTarget, 1)),
|
||||
spacing,
|
||||
separation,
|
||||
RandomSpreadType.LINEAR);
|
||||
@@ -183,6 +185,7 @@ public class ModdedStructureSetFrequencyOverridesTest {
|
||||
RandomState.class,
|
||||
BiomeSource.class,
|
||||
long.class,
|
||||
ChunkPos.class,
|
||||
long.class,
|
||||
List.class);
|
||||
constructor.setAccessible(true);
|
||||
@@ -190,6 +193,7 @@ public class ModdedStructureSetFrequencyOverridesTest {
|
||||
null,
|
||||
new EmptyBiomeSource(),
|
||||
1L,
|
||||
ChunkPos.ZERO,
|
||||
1L,
|
||||
sets);
|
||||
}
|
||||
@@ -211,8 +215,8 @@ public class ModdedStructureSetFrequencyOverridesTest {
|
||||
|
||||
private static final class EmptyBiomeSource extends BiomeSource {
|
||||
@Override
|
||||
public Holder<Biome> getNoiseBiome(int x, int y, int z, Climate.Sampler sampler) {
|
||||
return null;
|
||||
public BiomeResolver createResolver(Climate.Sampler sampler) {
|
||||
return (x, y, z) -> null;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -226,18 +230,14 @@ public class ModdedStructureSetFrequencyOverridesTest {
|
||||
}
|
||||
}
|
||||
|
||||
private static final class UnsupportedPlacement extends StructurePlacement {
|
||||
private UnsupportedPlacement() {
|
||||
super(Vec3i.ZERO, FrequencyReductionMethod.DEFAULT, 1F, 1, Optional.empty());
|
||||
}
|
||||
|
||||
private static final class UnsupportedPlacement implements StructurePlacement {
|
||||
@Override
|
||||
protected boolean isPlacementChunk(ChunkGeneratorStructureState state, int x, int z) {
|
||||
public boolean isStructureChunk(ChunkGeneratorStructureState state, int x, int z) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public StructurePlacementType<?> type() {
|
||||
public com.mojang.serialization.MapCodec<? extends StructurePlacement> codec() {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
+4
-3
@@ -19,6 +19,7 @@ import net.minecraft.world.level.block.Blocks;
|
||||
import net.minecraft.world.level.block.entity.BarrelBlockEntity;
|
||||
import net.minecraft.world.level.block.entity.ChestBlockEntity;
|
||||
import net.minecraft.world.level.block.entity.SignBlockEntity;
|
||||
import net.minecraft.world.level.block.entity.SignTextSlot;
|
||||
import net.minecraft.world.level.block.entity.SpawnerBlockEntity;
|
||||
import net.minecraft.world.level.storage.TagValueInput;
|
||||
import org.junit.BeforeClass;
|
||||
@@ -61,9 +62,9 @@ public class ModdedTileParityTest {
|
||||
|
||||
sign.loadWithComponents(TagValueInput.create(ProblemReporter.DISCARDING, registries, tile.nativeData().payload()));
|
||||
|
||||
assertEquals("Iris", sign.getFrontText().getMessage(0, false).getString());
|
||||
assertEquals("parity", sign.getBackText().getMessage(3, false).getString());
|
||||
assertEquals(DyeColor.BLUE, sign.getFrontText().getColor());
|
||||
assertEquals("Iris", sign.getText(SignTextSlot.FRONT).getMessages(false).get(0).getString());
|
||||
assertEquals("parity", sign.getText(SignTextSlot.BACK).getMessages(false).get(3).getString());
|
||||
assertEquals(DyeColor.BLUE, sign.getText(SignTextSlot.FRONT).getColor());
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
+7
@@ -12,8 +12,11 @@ import art.arcane.volmlib.util.math.RNG;
|
||||
import net.minecraft.SharedConstants;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.core.registries.BuiltInRegistries;
|
||||
import net.minecraft.core.registries.Registries;
|
||||
import net.minecraft.server.Bootstrap;
|
||||
import net.minecraft.server.level.ServerLevel;
|
||||
import net.minecraft.tags.BlockTags;
|
||||
import net.minecraft.tags.TagLoader;
|
||||
import net.minecraft.world.level.block.Block;
|
||||
import net.minecraft.world.level.block.Blocks;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
@@ -22,6 +25,8 @@ import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
@@ -42,6 +47,8 @@ public class ModdedWaterEntitySpawnTest {
|
||||
state.initCache();
|
||||
}
|
||||
}
|
||||
BuiltInRegistries.BLOCK.prepareTagReload(new TagLoader.LoadResult<>(Registries.BLOCK, Map.of(
|
||||
BlockTags.BLOCKS_MOTION, List.of(Blocks.OAK_FENCE.builtInRegistryHolder())))).apply();
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
+10
-6
@@ -6,7 +6,11 @@ import art.arcane.volmlib.nativelib.minecraft26_2.modded.ModdedPlatformWorld;
|
||||
|
||||
import net.minecraft.SharedConstants;
|
||||
import net.minecraft.server.Bootstrap;
|
||||
import net.minecraft.world.level.levelgen.feature.Feature;
|
||||
import net.minecraft.world.level.levelgen.feature.FallenTreeFeature;
|
||||
import net.minecraft.world.level.levelgen.feature.HugeBrownMushroomFeature;
|
||||
import net.minecraft.world.level.levelgen.feature.HugeRedMushroomFeature;
|
||||
import net.minecraft.world.level.levelgen.feature.OreFeature;
|
||||
import net.minecraft.world.level.levelgen.feature.TreeFeature;
|
||||
import net.minecraft.world.level.levelgen.structure.BoundingBox;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
@@ -32,11 +36,11 @@ public class NativeStructureOperationsTest {
|
||||
|
||||
@Test
|
||||
public void objectFeaturesMatchPaperGroups() {
|
||||
assertEquals("trees", NativeStructureOperations.classifyFeature(Feature.TREE));
|
||||
assertEquals("fallen_trees", NativeStructureOperations.classifyFeature(Feature.FALLEN_TREE));
|
||||
assertEquals("mushrooms", NativeStructureOperations.classifyFeature(Feature.HUGE_BROWN_MUSHROOM));
|
||||
assertEquals("mushrooms", NativeStructureOperations.classifyFeature(Feature.HUGE_RED_MUSHROOM));
|
||||
assertNull(NativeStructureOperations.classifyFeature(Feature.ORE));
|
||||
assertEquals("trees", NativeStructureOperations.classifyFeature(mock(TreeFeature.class)));
|
||||
assertEquals("fallen_trees", NativeStructureOperations.classifyFeature(mock(FallenTreeFeature.class)));
|
||||
assertEquals("mushrooms", NativeStructureOperations.classifyFeature(mock(HugeBrownMushroomFeature.class)));
|
||||
assertEquals("mushrooms", NativeStructureOperations.classifyFeature(mock(HugeRedMushroomFeature.class)));
|
||||
assertNull(NativeStructureOperations.classifyFeature(mock(OreFeature.class)));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -42,7 +42,7 @@ buildscript {
|
||||
|
||||
plugins {
|
||||
id 'java'
|
||||
id 'net.neoforged.moddev' version '2.0.141'
|
||||
id 'net.neoforged.moddev' version '2.0.147'
|
||||
alias(libs.plugins.shadow)
|
||||
}
|
||||
|
||||
@@ -60,8 +60,8 @@ apply from: file('../../gradle/modded-generation-build-revision.gradle')
|
||||
Properties rootProperties = new Properties()
|
||||
file('../../gradle.properties').withInputStream { InputStream stream -> rootProperties.load(stream) }
|
||||
String irisVersion = providers.gradleProperty('irisVersion').getOrElse(rootProperties.getProperty('irisVersion', '4.1.2-26.2'))
|
||||
String minecraftVersion = providers.gradleProperty('minecraftVersion').getOrElse(rootProperties.getProperty('minecraftVersion', '26.2'))
|
||||
String neoForgeVersion = providers.gradleProperty('neoForgeVersion').getOrElse(rootProperties.getProperty('neoForgeVersion', '26.2.0.59'))
|
||||
String minecraftVersion = providers.gradleProperty('minecraftVersion').getOrElse(rootProperties.getProperty('minecraftVersion', '26.3'))
|
||||
String neoForgeVersion = providers.gradleProperty('neoForgeVersion').getOrElse(rootProperties.getProperty('neoForgeVersion', '26.3.0.33-beta'))
|
||||
String volmLibCoordinate = providers.gradleProperty('volmLibCoordinate').getOrElse(rootProperties.getProperty('volmLibCoordinate', 'com.github.VolmitSoftware:VolmLib:master-SNAPSHOT'))
|
||||
Closure<String> irisArtifactName = { String platform, String targetVersion ->
|
||||
return "Iris v${project.version} [${platform}] ${targetVersion}.jar"
|
||||
|
||||
@@ -25,7 +25,7 @@ logoFile = "assets/irisworldgen/icon.png"
|
||||
[[dependencies.irisworldgen]]
|
||||
modId = "neoforge"
|
||||
type = "required"
|
||||
versionRange = "[26.2,26.3)"
|
||||
versionRange = "[26.3,26.4)"
|
||||
ordering = "NONE"
|
||||
side = "BOTH"
|
||||
|
||||
|
||||
+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);
|
||||
}
|
||||
}
|
||||
}
|
||||
+5
-12
@@ -70,12 +70,12 @@ project(':core') {
|
||||
group = 'art.arcane'
|
||||
version = rootProject.version
|
||||
}
|
||||
String minecraftVersion = providers.gradleProperty('minecraftVersion').getOrElse('26.2')
|
||||
// The Bukkit jar retains 26.1.2 and 26.2 alongside 26.3; loader jars stay 26.2-only.
|
||||
String minecraftVersion = providers.gradleProperty('minecraftVersion').getOrElse('26.3')
|
||||
// The Bukkit jar retains 26.1.2 and 26.2 alongside 26.3; loader jars are 26.3-only.
|
||||
String bukkitMinecraftRange = providers.gradleProperty('bukkitMinecraftRange').getOrElse('26.1.2-26.3')
|
||||
String fabricLoaderVersion = providers.gradleProperty('fabricLoaderVersion').getOrElse('0.19.3')
|
||||
String forgeVersion = providers.gradleProperty('forgeVersion').getOrElse('26.2-65.1.1')
|
||||
String neoForgeVersion = providers.gradleProperty('neoForgeVersion').getOrElse('26.2.0.59')
|
||||
String fabricLoaderVersion = providers.gradleProperty('fabricLoaderVersion').getOrElse('0.19.5')
|
||||
String forgeVersion = providers.gradleProperty('forgeVersion').getOrElse('26.3-66.0.8')
|
||||
String neoForgeVersion = providers.gradleProperty('neoForgeVersion').getOrElse('26.3.0.33-beta')
|
||||
String volmLibCoordinate = providers.gradleProperty('volmLibCoordinate')
|
||||
.orElse('com.github.VolmitSoftware:VolmLib:master-SNAPSHOT')
|
||||
.get()
|
||||
@@ -997,15 +997,8 @@ project(':adapters:bukkit:nms:v26_3_R1') {
|
||||
TaskProvider<Sync> unpackHeadlessNativeSources = tasks.register('unpackHeadlessNativeSources', Sync) {
|
||||
dependsOn(headlessNativeSources)
|
||||
inputs.property('nativeTypes', headlessNativeTypes)
|
||||
inputs.property('nativeVersion', '26.3')
|
||||
from(provider { headlessNativeSources.collect { File artifact -> zipTree(artifact) } }) {
|
||||
headlessNativeTypes.each { String type -> include("art/arcane/volmlib/nativelib/minecraft26_2/modded/${type}.java") }
|
||||
include('versions/26.3/**')
|
||||
eachFile { FileCopyDetails source ->
|
||||
if (source.path.startsWith('versions/26.3/')) {
|
||||
source.path = source.path.substring('versions/26.3/'.length())
|
||||
}
|
||||
}
|
||||
}
|
||||
from(rootProject.file('adapters/modded-common/src/main/java')) {
|
||||
include('art/arcane/iris/modded/ModdedDecoratorHooks.java',
|
||||
|
||||
@@ -34,9 +34,12 @@ public final class DataFixerV263 extends DataFixerV1217 {
|
||||
.put("max_inclusive", maximum));
|
||||
}
|
||||
}
|
||||
// Vanilla writes spawns as an overlay. A bare value decodes as an override, which NeoForge biome modifiers refuse to edit.
|
||||
attributes.put("minecraft:gameplay/natural_mob_spawns", new JSONObject()
|
||||
.put("spawns_by_category", spawners)
|
||||
.put("spawn_costs", fixed.getJSONObject("spawn_costs")));
|
||||
.put("argument", new JSONObject()
|
||||
.put("spawns_by_category", spawners)
|
||||
.put("spawn_costs", fixed.getJSONObject("spawn_costs")))
|
||||
.put("modifier", "overlay"));
|
||||
Object probability = fixed.remove("creature_spawn_probability");
|
||||
if (probability != null) {
|
||||
attributes.put("minecraft:gameplay/creature_world_gen_spawn_probability", probability);
|
||||
|
||||
+5
-5
@@ -22,10 +22,10 @@ org.gradle.caching=true
|
||||
org.gradle.configureondemand=false
|
||||
|
||||
irisVersion=4.1.2-26.2
|
||||
minecraftVersion=26.2
|
||||
# Bukkit plugin api-version: lowest supported Minecraft release line so one artifact loads on 26.1.2 and 26.2
|
||||
minecraftVersion=26.3
|
||||
# Bukkit plugin api-version: lowest supported Minecraft release line so one artifact loads on 26.1.2 through 26.3
|
||||
apiVersion=26.1
|
||||
fabricLoaderVersion=0.19.3
|
||||
forgeVersion=26.2-65.1.1
|
||||
neoForgeVersion=26.2.0.59
|
||||
fabricLoaderVersion=0.19.5
|
||||
forgeVersion=26.3-66.0.8
|
||||
neoForgeVersion=26.3.0.33-beta
|
||||
volmLibCoordinate=com.github.VolmitSoftware.VolmLib:volmlib-shared:d24d28acddbf3555c0c30ac99569ebacd476ce27
|
||||
|
||||
+10
-10
@@ -49,16 +49,16 @@ multiverseCore = "5.8.0"
|
||||
craftengine = "26.8.2" # https://github.com/Xiao-MoMi/craft-engine/releases
|
||||
|
||||
# Fabric API (net.fabricmc.fabric-api) - each module is independently versioned
|
||||
fabricApi-base = "2.0.4+ece063239e"
|
||||
fabricApi-registrySync = "7.1.0+c7bd5b8e9e"
|
||||
fabricApi-resourceLoader = "2.0.13+9edec1269e"
|
||||
fabricApi-lifecycleEvents = "4.1.3+4575b05f9e"
|
||||
fabricApi-commandApi = "3.1.0+00cb03469e"
|
||||
fabricApi-eventsInteraction = "5.2.6+8f57f7ee9e"
|
||||
fabricApi-networking = "6.3.3+72073ef09e"
|
||||
fabricApi-rendering = "25.3.1+6988455e9e"
|
||||
fabricApi-keyMapping = "2.0.5+e2bdee789e"
|
||||
fabricApi-permission = "1.0.3+b7020ca29e"
|
||||
fabricApi-base = "2.0.6+fcdff87f5d"
|
||||
fabricApi-registrySync = "8.0.1+fcdff87f5d"
|
||||
fabricApi-resourceLoader = "3.0.4+fcdff87f5d"
|
||||
fabricApi-lifecycleEvents = "4.1.9+ffef5f675d"
|
||||
fabricApi-commandApi = "3.1.2+fcdff87f5d"
|
||||
fabricApi-eventsInteraction = "5.3.6+3434d6d95d"
|
||||
fabricApi-networking = "6.3.8+fcdff87f5d"
|
||||
fabricApi-rendering = "27.0.14+901a437c5d"
|
||||
fabricApi-keyMapping = "2.0.8+3434d6d95d"
|
||||
fabricApi-permission = "1.0.8+fcdff87f5d"
|
||||
|
||||
[libraries]
|
||||
# Core Libraries
|
||||
|
||||
@@ -9,7 +9,7 @@ String nativeLibraryCoordinate = providers.gradleProperty('volmLibCoordinate')
|
||||
.getOrElse(nativeLibraryProperties.getProperty('volmLibCoordinate'))
|
||||
String nativeSourceLoader = extensions.extraProperties.get('nativeSourceLoader')
|
||||
String nativeSourceImplementation = 'minecraft26_2'
|
||||
String nativeSourceMinecraftVersion = providers.gradleProperty('minecraftVersion').getOrElse('26.2')
|
||||
String nativeSourceMinecraftVersion = providers.gradleProperty('minecraftVersion').getOrElse('26.3')
|
||||
extensions.extraProperties.set('nativeSourceImplementation', nativeSourceImplementation)
|
||||
dependencies.add(nativeMinecraftSources.name,
|
||||
"com.github.VolmitSoftware.VolmLib:native-${nativeSourceImplementation}-sources:${nativeLibraryCoordinate.tokenize(':').last()}")
|
||||
|
||||
Reference in New Issue
Block a user