diff --git a/.github/workflows/gradle-build.yml b/.github/workflows/gradle-build.yml index b289ca1aa5..959a6a81f5 100644 --- a/.github/workflows/gradle-build.yml +++ b/.github/workflows/gradle-build.yml @@ -18,10 +18,10 @@ jobs: steps: - uses: actions/checkout@v4.2.2 - - name: Set up JDK 21 + - name: Set up JDK 25 uses: actions/setup-java@v4.7.1 with: - java-version: '21' + java-version: '25' distribution: 'temurin' server-id: github # Value of the distributionManagement/repository/id field of the pom.xml settings-path: ${{ github.workspace }} # location for the settings.xml file diff --git a/buildSrc/build.gradle.kts b/buildSrc/build.gradle.kts index 5ca04d11a5..c0a763e2d9 100644 --- a/buildSrc/build.gradle.kts +++ b/buildSrc/build.gradle.kts @@ -24,7 +24,7 @@ dependencies { //TODO Allow pulling from Versions.kt implementation("com.gradleup.shadow", "shadow-gradle-plugin", "8.3.9") - implementation("io.papermc.paperweight.userdev", "io.papermc.paperweight.userdev.gradle.plugin", "2.0.0-beta.18") + implementation("io.papermc.paperweight.userdev", "io.papermc.paperweight.userdev.gradle.plugin", "2.0.0-beta.21") implementation("org.ow2.asm", "asm", "9.9") implementation("org.ow2.asm", "asm-tree", "9.9") implementation("com.dfsek.tectonic", "common", "4.3.1") diff --git a/buildSrc/src/main/kotlin/Utils.kt b/buildSrc/src/main/kotlin/Utils.kt index 679786788b..b786d0645c 100644 --- a/buildSrc/src/main/kotlin/Utils.kt +++ b/buildSrc/src/main/kotlin/Utils.kt @@ -7,19 +7,14 @@ var isPrerelease = false fun Project.getGitHash(): String { - val stdout = ByteArrayOutputStream() - exec { + return providers.exec { commandLine = mutableListOf("git", "rev-parse", "--short", "HEAD") - standardOutput = stdout - } - return stdout.toString().trim() + }.standardOutput.asText.get().trim() } fun Project.gitClone(name: String) { - val stdout = ByteArrayOutputStream() - exec { + providers.exec { commandLine = mutableListOf("git", "clone", name) - standardOutput = stdout } } diff --git a/buildSrc/src/main/kotlin/Versions.kt b/buildSrc/src/main/kotlin/Versions.kt index cb593331ab..3add39691a 100644 --- a/buildSrc/src/main/kotlin/Versions.kt +++ b/buildSrc/src/main/kotlin/Versions.kt @@ -60,16 +60,16 @@ object Versions { // } object Bukkit { - const val minecraft = "1.21.10" + const val minecraft = "26.1.2" const val nms = "$minecraft-R0.1" - const val paperBuild = "$nms-20251012.013929-7" + const val paperBuild = "26.1.2.build.60-stable" const val paper = paperBuild const val paperLib = "1.0.8" const val reflectionRemapper = "0.1.3" const val paperDevBundle = paperBuild - const val runPaper = "2.3.1" - const val paperWeight = "2.0.0-beta.19" - const val cloud = "2.0.0-beta.12" + const val runPaper = "3.0.2" + const val paperWeight = "2.0.0-beta.21" + const val cloud = "2.0.0-beta.15" const val multiverse = "5.3.0" } diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 9128c7d428..3f8cf63e72 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,7 +1,7 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists distributionSha256Sum=845952a9d6afa783db70bb3b0effaae45ae5542ca2bb7929619e8af49cb634cf -distributionUrl=https\://services.gradle.org/distributions/gradle-8.14.1-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-9.5.0-bin.zip networkTimeout=10000 validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME diff --git a/platforms/bukkit/build.gradle.kts b/platforms/bukkit/build.gradle.kts index b55db49b62..377eaaf957 100644 --- a/platforms/bukkit/build.gradle.kts +++ b/platforms/bukkit/build.gradle.kts @@ -12,6 +12,10 @@ dependencies { shaded("xyz.jpenilla", "reflection-remapper", Versions.Bukkit.reflectionRemapper) } +tasks.withType().configureEach { + options.release = 25 +} + tasks { shadowJar { relocate("io.papermc.lib", "com.dfsek.terra.lib.paperlib") diff --git a/platforms/bukkit/common/build.gradle.kts b/platforms/bukkit/common/build.gradle.kts index 57c7ba5a92..11673f8fca 100644 --- a/platforms/bukkit/common/build.gradle.kts +++ b/platforms/bukkit/common/build.gradle.kts @@ -1,6 +1,9 @@ repositories { } +tasks.withType().configureEach { + options.release = 25 +} dependencies { shadedApi(project(":common:implementation:base")) diff --git a/platforms/bukkit/common/src/main/java/com/dfsek/terra/bukkit/NMSInitializer.java b/platforms/bukkit/common/src/main/java/com/dfsek/terra/bukkit/NMSInitializer.java index f15beea0a6..bb89ec8685 100644 --- a/platforms/bukkit/common/src/main/java/com/dfsek/terra/bukkit/NMSInitializer.java +++ b/platforms/bukkit/common/src/main/java/com/dfsek/terra/bukkit/NMSInitializer.java @@ -9,7 +9,7 @@ public interface NMSInitializer { - List SUPPORTED_VERSIONS = List.of("v1.21.9", "v1.21.10"); + List SUPPORTED_VERSIONS = List.of("v26.1.2"); String MINECRAFT_VERSION = VersionUtil.getMinecraftVersionInfo().toString(); String TERRA_PACKAGE = NMSInitializer.class.getPackageName(); diff --git a/platforms/bukkit/common/src/main/java/com/dfsek/terra/bukkit/handles/BukkitWorldHandle.java b/platforms/bukkit/common/src/main/java/com/dfsek/terra/bukkit/handles/BukkitWorldHandle.java index 0136d4389a..3ad138d837 100644 --- a/platforms/bukkit/common/src/main/java/com/dfsek/terra/bukkit/handles/BukkitWorldHandle.java +++ b/platforms/bukkit/common/src/main/java/com/dfsek/terra/bukkit/handles/BukkitWorldHandle.java @@ -19,6 +19,7 @@ import org.bukkit.Bukkit; import org.bukkit.Material; +import org.bukkit.block.data.BlockData; import org.jetbrains.annotations.NotNull; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -29,6 +30,9 @@ import com.dfsek.terra.bukkit.util.BukkitUtils; import com.dfsek.terra.bukkit.world.block.data.BukkitBlockState; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; + public class BukkitWorldHandle implements WorldHandle { private static final Logger logger = LoggerFactory.getLogger(BukkitWorldHandle.class); @@ -40,9 +44,19 @@ public BukkitWorldHandle() { @Override public synchronized @NotNull BlockState createBlockState(@NotNull String data) { - org.bukkit.block.data.BlockData bukkitData = Bukkit.createBlockData( - data); // somehow bukkit managed to make this not thread safe! :) - return BukkitBlockState.newInstance(bukkitData); + try { + org.bukkit.block.data.BlockData bukkitData = Bukkit.createBlockData(data); // somehow bukkit managed to make this not thread safe! :) + return BukkitBlockState.newInstance(bukkitData); + } catch (Exception ignored) { + try { + Class hacks = Class.forName("com.dfsek.terra.bukkit.nms.AwfulBukkitHacks"); + Method method = hacks.getMethod("createBlockState", String.class); + Object result = method.invoke(null, data); + return BukkitBlockState.newInstance((BlockData) result); + } catch (ClassNotFoundException | NoSuchMethodException | IllegalAccessException | InvocationTargetException e) { + throw new IllegalArgumentException("Invalid block state data: " + data); + } + } } @Override diff --git a/platforms/bukkit/common/src/main/java/com/dfsek/terra/bukkit/util/BukkitUtils.java b/platforms/bukkit/common/src/main/java/com/dfsek/terra/bukkit/util/BukkitUtils.java index eb5d622708..d2c80f5ff9 100644 --- a/platforms/bukkit/common/src/main/java/com/dfsek/terra/bukkit/util/BukkitUtils.java +++ b/platforms/bukkit/common/src/main/java/com/dfsek/terra/bukkit/util/BukkitUtils.java @@ -23,6 +23,13 @@ public static EntityType getEntityType(String id) { if(!id.startsWith("minecraft:")) throw new IllegalArgumentException("Invalid entity identifier " + id); String entityID = id.toUpperCase(Locale.ROOT).substring(10); + // TODO: remove this + // the default end seems to use this, this should be removed otherwise + // or replaced by a proper entity & NBT loader + if (entityID.contains("END_CRYSTAL")) { + entityID = "END_CRYSTAL"; + } + return new BukkitEntityType(switch(entityID) { case "END_CRYSTAL" -> org.bukkit.entity.EntityType.END_CRYSTAL; case "ENDER_CRYSTAL" -> throw new IllegalArgumentException( diff --git a/platforms/bukkit/nms/build.gradle.kts b/platforms/bukkit/nms/build.gradle.kts index b521d372ab..032aa34d6d 100644 --- a/platforms/bukkit/nms/build.gradle.kts +++ b/platforms/bukkit/nms/build.gradle.kts @@ -2,6 +2,10 @@ plugins { id("io.papermc.paperweight.userdev") } +tasks.withType().configureEach { + options.release = 25 +} + dependencies { api(project(":platforms:bukkit:common")) paperweight.paperDevBundle(Versions.Bukkit.paperDevBundle) diff --git a/platforms/bukkit/nms/src/main/java/com/dfsek/terra/bukkit/nms/AwfulBukkitHacks.java b/platforms/bukkit/nms/src/main/java/com/dfsek/terra/bukkit/nms/AwfulBukkitHacks.java index beea1c536d..5b4bb1eafc 100644 --- a/platforms/bukkit/nms/src/main/java/com/dfsek/terra/bukkit/nms/AwfulBukkitHacks.java +++ b/platforms/bukkit/nms/src/main/java/com/dfsek/terra/bukkit/nms/AwfulBukkitHacks.java @@ -1,18 +1,29 @@ package com.dfsek.terra.bukkit.nms; +import com.mojang.brigadier.StringReader; +import com.mojang.brigadier.exceptions.CommandSyntaxException; +import net.minecraft.commands.arguments.blocks.BlockStateParser; +import net.minecraft.commands.arguments.blocks.BlockStateParser.BlockResult; import net.minecraft.core.Holder; import net.minecraft.core.Holder.Reference; -import net.minecraft.core.HolderSet; +import net.minecraft.core.HolderLookup; import net.minecraft.core.HolderSet.Named; import net.minecraft.core.MappedRegistry; import net.minecraft.core.RegistrationInfo; import net.minecraft.core.registries.Registries; +import net.minecraft.resources.Identifier; import net.minecraft.resources.ResourceKey; -import net.minecraft.resources.ResourceLocation; +import net.minecraft.server.MinecraftServer; import net.minecraft.tags.TagKey; -import net.minecraft.world.entity.npc.VillagerType; +import net.minecraft.world.entity.npc.villager.VillagerType; import net.minecraft.world.level.biome.Biome; +import net.minecraft.world.level.block.Block; +import org.bukkit.Bukkit; import org.bukkit.NamespacedKey; +import org.bukkit.block.data.BlockData; +import org.bukkit.craftbukkit.CraftServer; +import org.bukkit.craftbukkit.block.data.CraftBlockData; +import org.jetbrains.annotations.NotNull; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -34,7 +45,7 @@ public class AwfulBukkitHacks { private static final Logger LOGGER = LoggerFactory.getLogger(AwfulBukkitHacks.class); - private static final Map> terraBiomeMap = new HashMap<>(); + private static final Map> terraBiomeMap = new HashMap<>(); public static void registerBiomes(ConfigRegistry configRegistry) { try { @@ -50,7 +61,7 @@ public static void registerBiomes(ConfigRegistry configRegistry) { BukkitPlatformBiome platformBiome = (BukkitPlatformBiome) biome.getPlatformBiome(); NamespacedKey vanillaBukkitKey = platformBiome.getHandle().getKey(); - ResourceLocation vanillaMinecraftKey = ResourceLocation.fromNamespaceAndPath(vanillaBukkitKey.getNamespace(), + Identifier vanillaMinecraftKey = Identifier.fromNamespaceAndPath(vanillaBukkitKey.getNamespace(), vanillaBukkitKey.getKey()); VanillaBiomeProperties vanillaBiomeProperties = biome.getContext().get(VanillaBiomeProperties.class); @@ -58,7 +69,7 @@ public static void registerBiomes(ConfigRegistry configRegistry) { Biome platform = NMSBiomeInjector.createBiome(biomeRegistry.get(vanillaMinecraftKey).orElseThrow().value(), vanillaBiomeProperties); - ResourceLocation delegateMinecraftKey = ResourceLocation.fromNamespaceAndPath("terra", + Identifier delegateMinecraftKey = Identifier.fromNamespaceAndPath("terra", NMSBiomeInjector.createBiomeID(pack, key)); NamespacedKey delegateBukkitKey = NamespacedKey.fromString(delegateMinecraftKey.toString()); ResourceKey delegateKey = ResourceKey.create(Registries.BIOME, delegateMinecraftKey); @@ -75,7 +86,7 @@ public static void registerBiomes(ConfigRegistry configRegistry) { Objects.requireNonNullElse(vanillaBiomeProperties.getVillagerType(), villagerMap.getOrDefault(delegateKey, VillagerType.PLAINS))); - terraBiomeMap.computeIfAbsent(vanillaMinecraftKey, i -> new ArrayList<>()).add(delegateKey.location()); + terraBiomeMap.computeIfAbsent(vanillaMinecraftKey, i -> new ArrayList<>()).add(delegateKey.identifier()); LOGGER.debug("Registered biome: " + delegateKey); } catch(NoSuchFieldException | SecurityException | IllegalArgumentException | IllegalAccessException e) { @@ -100,8 +111,8 @@ public static void registerBiomes(ConfigRegistry configRegistry) { tb -> NMSBiomeInjector.getEntry(biomeRegistry, tb).ifPresentOrElse( terra -> { LOGGER.debug("{} (vanilla for {}): {}", - vanilla.unwrapKey().orElseThrow().location(), - terra.unwrapKey().orElseThrow().location(), + vanilla.unwrapKey().orElseThrow().identifier(), + terra.unwrapKey().orElseThrow().identifier(), vanilla.tags().toList()); vanilla.tags() .forEach(tag -> collect @@ -120,7 +131,7 @@ public static void registerBiomes(ConfigRegistry configRegistry) { } private static void bindTags(MappedRegistry registry, Map, List>> tagEntries) { - Map, List>> map = new IdentityHashMap<>(); + Map, List>> map = new IdentityHashMap<>(); Reflection.MAPPED_REGISTRY.getByKey(registry).values().forEach(entry -> map.put(entry, new ArrayList<>())); tagEntries.forEach((tag, entries) -> { for(Holder holder : entries) { @@ -145,7 +156,7 @@ private static void bindTags(MappedRegistry registry, Map, List // ); // } - Map, HolderSet.Named> map2 = new IdentityHashMap<>(registry.getTags().collect(Collectors.toMap( + Map, Named> map2 = new IdentityHashMap<>(registry.getTags().collect(Collectors.toMap( Named::key, (named) -> named ))); @@ -160,5 +171,14 @@ private static void resetTags(MappedRegistry registry) { Reflection.MAPPED_REGISTRY.getByKey(registry).values().forEach( entry -> Reflection.HOLDER_REFERENCE.invokeBindTags(entry, Set.of())); } + + // used by BukkitWorldHandle + public static BlockData createBlockState(@NotNull String data) throws CommandSyntaxException { + MinecraftServer server = ((CraftServer) Bukkit.getServer()).getServer(); + HolderLookup.Provider lookup = server.registryAccess(); + final HolderLookup blocks = lookup.lookupOrThrow(Registries.BLOCK); + BlockResult result = BlockStateParser.parseForBlock(blocks, new StringReader(data), true); + return CraftBlockData.createData(result.blockState()); + } } diff --git a/platforms/bukkit/nms/src/main/java/com/dfsek/terra/bukkit/nms/NMSBiomeInjector.java b/platforms/bukkit/nms/src/main/java/com/dfsek/terra/bukkit/nms/NMSBiomeInjector.java index fea134c9ef..4b2668814b 100644 --- a/platforms/bukkit/nms/src/main/java/com/dfsek/terra/bukkit/nms/NMSBiomeInjector.java +++ b/platforms/bukkit/nms/src/main/java/com/dfsek/terra/bukkit/nms/NMSBiomeInjector.java @@ -1,12 +1,28 @@ package com.dfsek.terra.bukkit.nms; +import com.dfsek.terra.api.registry.key.RegistryKey; + import net.minecraft.core.Holder; import net.minecraft.core.Registry; -import net.minecraft.resources.ResourceLocation; +import net.minecraft.resources.Identifier; +import net.minecraft.sounds.SoundEvent; +import net.minecraft.world.attribute.AmbientAdditionsSettings; +import net.minecraft.world.attribute.AmbientMoodSettings; +import net.minecraft.world.attribute.AmbientParticle; +import net.minecraft.world.attribute.AmbientSounds; +import net.minecraft.world.attribute.BackgroundMusic; +import net.minecraft.world.attribute.EnvironmentAttribute; +import net.minecraft.world.attribute.EnvironmentAttributeMap; +import net.minecraft.world.attribute.EnvironmentAttributeMap.Entry; +import net.minecraft.world.attribute.EnvironmentAttributes; +import net.minecraft.world.attribute.modifier.AttributeModifier; import net.minecraft.world.level.biome.Biome; +import net.minecraft.world.level.biome.Biome.BiomeBuilder; import net.minecraft.world.level.biome.BiomeGenerationSettings; import net.minecraft.world.level.biome.BiomeSpecialEffects; +import java.util.Collections; +import java.util.List; import java.util.Locale; import java.util.Objects; import java.util.Optional; @@ -17,10 +33,8 @@ public class NMSBiomeInjector { - public static Optional> getEntry(Registry registry, ResourceLocation identifier) { - return registry.getOptional(identifier) - .flatMap(registry::getResourceKey) - .flatMap(registry::get); + public static Optional> getEntry(Registry registry, Identifier identifier) { + return registry.getOptional(identifier).flatMap(registry::getResourceKey).flatMap(registry::get); } public static Biome createBiome(Biome vanilla, VanillaBiomeProperties vanillaBiomeProperties) @@ -28,76 +42,146 @@ public static Biome createBiome(Biome vanilla, VanillaBiomeProperties vanillaBio Biome.BiomeBuilder builder = new Biome.BiomeBuilder(); BiomeSpecialEffects.Builder effects = new BiomeSpecialEffects.Builder(); + EnvironmentAttributeMap attributes = vanilla.getAttributes(); + + Integer vanillaFogColour = extractInt(attributes, EnvironmentAttributes.FOG_COLOR); + Integer vanillaWaterFogColour = extractInt(attributes, EnvironmentAttributes.WATER_FOG_COLOR); + Integer vanillaSkyColour = extractInt(attributes, EnvironmentAttributes.SKY_COLOR); + Float vanillaMusicVolume = extractFloat(attributes, EnvironmentAttributes.MUSIC_VOLUME); + + applyIfPresent(builder, EnvironmentAttributes.FOG_COLOR, + vanillaBiomeProperties.getFogColor(), vanillaFogColour); + + applyIfPresent(builder, EnvironmentAttributes.WATER_FOG_COLOR, + vanillaBiomeProperties.getWaterFogColor(), vanillaWaterFogColour); - effects.fogColor(Objects.requireNonNullElse(vanillaBiomeProperties.getFogColor(), vanilla.getFogColor())) - .waterColor(Objects.requireNonNullElse(vanillaBiomeProperties.getWaterColor(), vanilla.getWaterColor())) - .waterFogColor(Objects.requireNonNullElse(vanillaBiomeProperties.getWaterFogColor(), vanilla.getWaterFogColor())) - .skyColor(Objects.requireNonNullElse(vanillaBiomeProperties.getSkyColor(), vanilla.getSkyColor())) - .grassColorModifier(Objects.requireNonNullElse(vanillaBiomeProperties.getGrassColorModifier(), - vanilla.getSpecialEffects().getGrassColorModifier())) - .backgroundMusicVolume(Objects.requireNonNullElse(vanillaBiomeProperties.getMusicVolume(), vanilla.getBackgroundMusicVolume())); + applyIfPresent(builder, EnvironmentAttributes.SKY_COLOR, + vanillaBiomeProperties.getSkyColor(), vanillaSkyColour); + + applyIfPresent(builder, EnvironmentAttributes.MUSIC_VOLUME, + vanillaBiomeProperties.getMusicVolume(), vanillaMusicVolume); + + effects.waterColor(Objects.requireNonNullElse(vanillaBiomeProperties.getWaterColor(), vanilla.getWaterColor())); + effects.grassColorModifier( + Objects.requireNonNullElse(vanillaBiomeProperties.getGrassColorModifier(), vanilla.getSpecialEffects().grassColorModifier())); if(vanillaBiomeProperties.getGrassColor() == null) { - vanilla.getSpecialEffects().getGrassColorOverride().ifPresent(effects::grassColorOverride); + vanilla.getSpecialEffects().grassColorOverride().ifPresent(effects::grassColorOverride); } else { effects.grassColorOverride(vanillaBiomeProperties.getGrassColor()); } if(vanillaBiomeProperties.getFoliageColor() == null) { - vanilla.getSpecialEffects().getFoliageColorOverride().ifPresent(effects::foliageColorOverride); + vanilla.getSpecialEffects().foliageColorOverride().ifPresent(effects::foliageColorOverride); } else { effects.foliageColorOverride(vanillaBiomeProperties.getFoliageColor()); } if(vanillaBiomeProperties.getParticleConfig() == null) { - vanilla.getSpecialEffects().getAmbientParticleSettings().ifPresent(effects::ambientParticle); + Entry ambientEntry = attributes.get(EnvironmentAttributes.AMBIENT_PARTICLES); + if(ambientEntry != null) { + Object arg = ambientEntry.argument(); + + // this is not nice + if(arg instanceof List rawList) { + List ambientParticles = + rawList.stream() + .filter(AmbientParticle.class::isInstance) + .map(AmbientParticle.class::cast) + .toList(); + + builder.modifyAttribute( + EnvironmentAttributes.AMBIENT_PARTICLES, + AttributeModifier.override(), + ambientParticles + ); + } + } } else { - effects.ambientParticle(vanillaBiomeProperties.getParticleConfig()); + builder.modifyAttribute(EnvironmentAttributes.AMBIENT_PARTICLES, AttributeModifier.override(), + List.of(vanillaBiomeProperties.getParticleConfig())); } - if(vanillaBiomeProperties.getLoopSound() == null) { - vanilla.getSpecialEffects().getAmbientLoopSoundEvent().ifPresent(effects::ambientLoopSound); - } else { - RegistryFetcher.soundEventRegistry().get(vanillaBiomeProperties.getLoopSound().location()).ifPresent(effects::ambientLoopSound); + Optional> loop = Optional.empty(); + Optional mood = Optional.empty(); + List additions = Collections.emptyList(); + + if(attributes.contains(EnvironmentAttributes.AMBIENT_SOUNDS)) { + AmbientSounds sounds = + (AmbientSounds) Objects.requireNonNull(attributes.get(EnvironmentAttributes.AMBIENT_SOUNDS)).argument(); + + loop = sounds.loop(); + mood = sounds.mood(); + additions = sounds.additions(); } - if(vanillaBiomeProperties.getMoodSound() == null) { - vanilla.getSpecialEffects().getAmbientMoodSettings().ifPresent(effects::ambientMoodSound); - } else { - effects.ambientMoodSound(vanillaBiomeProperties.getMoodSound()); + if(vanillaBiomeProperties.getLoopSound() != null) { + loop = RegistryFetcher.soundEventRegistry() + .get(vanillaBiomeProperties.getLoopSound().location()) + .map(ref -> ref); } - if(vanillaBiomeProperties.getAdditionsSound() == null) { - vanilla.getSpecialEffects().getAmbientAdditionsSettings().ifPresent(effects::ambientAdditionsSound); - } else { - effects.ambientAdditionsSound(vanillaBiomeProperties.getAdditionsSound()); + if(vanillaBiomeProperties.getMoodSound() != null) { + mood = Optional.ofNullable(vanillaBiomeProperties.getMoodSound()); } + if(vanillaBiomeProperties.getAdditionsSound() != null) { + additions = Collections.singletonList(vanillaBiomeProperties.getAdditionsSound()); + } + + builder.modifyAttribute(EnvironmentAttributes.AMBIENT_SOUNDS, AttributeModifier.override(), + new AmbientSounds(loop, mood, additions)); + if(vanillaBiomeProperties.getMusic() == null) { - vanilla.getSpecialEffects().getBackgroundMusic().ifPresent(effects::backgroundMusic); + if(attributes.contains(EnvironmentAttributes.BACKGROUND_MUSIC)) { + BackgroundMusic music = (BackgroundMusic) Objects.requireNonNull(attributes.get(EnvironmentAttributes.BACKGROUND_MUSIC)) + .argument(); + builder.modifyAttribute(EnvironmentAttributes.BACKGROUND_MUSIC, AttributeModifier.override(), music); + } } else { - effects.backgroundMusic(vanillaBiomeProperties.getMusic()); + builder.modifyAttribute(EnvironmentAttributes.BACKGROUND_MUSIC, AttributeModifier.override(), + new BackgroundMusic(vanillaBiomeProperties.getMusic())); } builder.hasPrecipitation(Objects.requireNonNullElse(vanillaBiomeProperties.getPrecipitation(), vanilla.hasPrecipitation())); - builder.temperature(Objects.requireNonNullElse(vanillaBiomeProperties.getTemperature(), vanilla.getBaseTemperature())); - builder.downfall(Objects.requireNonNullElse(vanillaBiomeProperties.getDownfall(), vanilla.climateSettings.downfall())); - builder.temperatureAdjustment( Objects.requireNonNullElse(vanillaBiomeProperties.getTemperatureModifier(), vanilla.climateSettings.temperatureModifier())); - builder.mobSpawnSettings(Objects.requireNonNullElse(vanillaBiomeProperties.getSpawnSettings(), vanilla.getMobSettings())); - return builder - .specialEffects(effects.build()) - .generationSettings(new BiomeGenerationSettings.PlainBuilder().build()) - .build(); + return builder.specialEffects(effects.build()).generationSettings(new BiomeGenerationSettings.PlainBuilder().build()).build(); } - public static String createBiomeID(ConfigPack pack, com.dfsek.terra.api.registry.key.RegistryKey biomeID) { - return pack.getID() - .toLowerCase() + "/" + biomeID.getNamespace().toLowerCase(Locale.ROOT) + "/" + biomeID.getID().toLowerCase(Locale.ROOT); + public static String createBiomeID(ConfigPack pack, RegistryKey biomeID) { + return pack.getID().toLowerCase() + "/" + biomeID.getNamespace().toLowerCase(Locale.ROOT) + "/" + biomeID.getID().toLowerCase( + Locale.ROOT); + } + + private static Integer extractInt(EnvironmentAttributeMap attributes, + EnvironmentAttribute key) { + Entry attr = attributes.get(key); + return attr != null ? (Integer) attr.argument() : null; + } + + private static Float extractFloat(EnvironmentAttributeMap attributes, + EnvironmentAttribute key) { + Entry attr = attributes.get(key); + return attr != null ? (Float) attr.argument() : null; + } + + private static void applyIfPresent( + BiomeBuilder builder, + EnvironmentAttribute attr, + T overrideValue, + T fallbackValue + ) { + T value = overrideValue != null ? overrideValue : fallbackValue; + + if (value == null) { + return; + } + + builder.modifyAttribute(attr, AttributeModifier.override(), value); } } diff --git a/platforms/bukkit/nms/src/main/java/com/dfsek/terra/bukkit/nms/NMSChunkGeneratorDelegate.java b/platforms/bukkit/nms/src/main/java/com/dfsek/terra/bukkit/nms/NMSChunkGeneratorDelegate.java index 0b21b9d128..e22ff1e6b3 100644 --- a/platforms/bukkit/nms/src/main/java/com/dfsek/terra/bukkit/nms/NMSChunkGeneratorDelegate.java +++ b/platforms/bukkit/nms/src/main/java/com/dfsek/terra/bukkit/nms/NMSChunkGeneratorDelegate.java @@ -106,8 +106,8 @@ private void beard(StructureManager structureAccessor, ChunkAccess chunk, WorldP Beardifier structureWeightSampler = Beardifier.forStructuresInChunk(structureAccessor, chunk.getPos()); double threshold = compatibilityOptions.getBeardThreshold(); double airThreshold = compatibilityOptions.getAirThreshold(); - int xi = chunk.getPos().x << 4; - int zi = chunk.getPos().z << 4; + int xi = chunk.getPos().x() << 4; + int zi = chunk.getPos().z() << 4; for(int x = 0; x < 16; x++) { for(int z = 0; z < 16; z++) { int depth = 0; diff --git a/platforms/bukkit/nms/src/main/java/com/dfsek/terra/bukkit/nms/NMSPlatform.java b/platforms/bukkit/nms/src/main/java/com/dfsek/terra/bukkit/nms/NMSPlatform.java index efbdde212d..e54b2fd04c 100644 --- a/platforms/bukkit/nms/src/main/java/com/dfsek/terra/bukkit/nms/NMSPlatform.java +++ b/platforms/bukkit/nms/src/main/java/com/dfsek/terra/bukkit/nms/NMSPlatform.java @@ -2,15 +2,15 @@ import com.dfsek.tectonic.api.TypeRegistry; import com.dfsek.tectonic.api.exception.LoadException; -import net.minecraft.resources.ResourceLocation; +import net.minecraft.resources.Identifier; import net.minecraft.sounds.Music; import net.minecraft.sounds.SoundEvent; +import net.minecraft.world.attribute.AmbientAdditionsSettings; +import net.minecraft.world.attribute.AmbientMoodSettings; +import net.minecraft.world.attribute.AmbientParticle; import net.minecraft.world.entity.EntityType; import net.minecraft.world.entity.MobCategory; -import net.minecraft.world.entity.npc.VillagerType; -import net.minecraft.world.level.biome.AmbientAdditionsSettings; -import net.minecraft.world.level.biome.AmbientMoodSettings; -import net.minecraft.world.level.biome.AmbientParticleSettings; +import net.minecraft.world.entity.npc.villager.VillagerType; import net.minecraft.world.level.biome.Biome.Precipitation; import net.minecraft.world.level.biome.Biome.TemperatureModifier; import net.minecraft.world.level.biome.BiomeSpecialEffects.GrassColorModifier; @@ -52,8 +52,8 @@ public NMSPlatform(TerraBukkitPlugin plugin) { public void register(TypeRegistry registry) { super.register(registry); registry.registerLoader(PlatformBiome.class, (type, o, loader, depthTracker) -> parseBiome((String) o, depthTracker)) - .registerLoader(ResourceLocation.class, (type, o, loader, depthTracker) -> { - ResourceLocation identifier = ResourceLocation.tryParse((String) o); + .registerLoader(Identifier.class, (type, o, loader, depthTracker) -> { + Identifier identifier = Identifier.tryParse((String) o); if(identifier == null) throw new LoadException("Invalid identifier: " + o, depthTracker); return identifier; @@ -67,7 +67,7 @@ public void register(TypeRegistry registry) { (type, o, loader, depthTracker) -> TemperatureModifier.valueOf(((String) o).toUpperCase( Locale.ROOT))) .registerLoader(MobCategory.class, (type, o, loader, depthTracker) -> MobCategory.valueOf((String) o)) - .registerLoader(AmbientParticleSettings.class, BiomeParticleConfigTemplate::new) + .registerLoader(AmbientParticle.class, BiomeParticleConfigTemplate::new) .registerLoader(SoundEvent.class, SoundEventTemplate::new) .registerLoader(AmbientMoodSettings.class, BiomeMoodSoundTemplate::new) .registerLoader(AmbientAdditionsSettings.class, BiomeAdditionsSoundTemplate::new) diff --git a/platforms/bukkit/nms/src/main/java/com/dfsek/terra/bukkit/nms/Reflection.java b/platforms/bukkit/nms/src/main/java/com/dfsek/terra/bukkit/nms/Reflection.java index 3c0e93e67a..32d6c91328 100644 --- a/platforms/bukkit/nms/src/main/java/com/dfsek/terra/bukkit/nms/Reflection.java +++ b/platforms/bukkit/nms/src/main/java/com/dfsek/terra/bukkit/nms/Reflection.java @@ -7,7 +7,7 @@ import net.minecraft.resources.ResourceKey; import net.minecraft.server.level.ChunkMap; import net.minecraft.tags.TagKey; -import net.minecraft.world.entity.npc.VillagerType; +import net.minecraft.world.entity.npc.villager.VillagerType; import net.minecraft.world.level.LevelAccessor; import net.minecraft.world.level.StructureManager; import net.minecraft.world.level.biome.Biome; @@ -24,7 +24,6 @@ import java.util.List; import java.util.Map; - public class Reflection { public static final MappedRegistryProxy MAPPED_REGISTRY; public static final MappedRegistryTagSetProxy MAPPED_REGISTRY_TAG_SET; diff --git a/platforms/bukkit/nms/src/main/java/com/dfsek/terra/bukkit/nms/config/BiomeAdditionsSoundTemplate.java b/platforms/bukkit/nms/src/main/java/com/dfsek/terra/bukkit/nms/config/BiomeAdditionsSoundTemplate.java index 83ac758b2d..3e3286098f 100644 --- a/platforms/bukkit/nms/src/main/java/com/dfsek/terra/bukkit/nms/config/BiomeAdditionsSoundTemplate.java +++ b/platforms/bukkit/nms/src/main/java/com/dfsek/terra/bukkit/nms/config/BiomeAdditionsSoundTemplate.java @@ -5,7 +5,7 @@ import com.dfsek.tectonic.api.config.template.object.ObjectTemplate; import net.minecraft.core.registries.BuiltInRegistries; import net.minecraft.sounds.SoundEvent; -import net.minecraft.world.level.biome.AmbientAdditionsSettings; +import net.minecraft.world.attribute.AmbientAdditionsSettings; public class BiomeAdditionsSoundTemplate implements ObjectTemplate { diff --git a/platforms/bukkit/nms/src/main/java/com/dfsek/terra/bukkit/nms/config/BiomeMoodSoundTemplate.java b/platforms/bukkit/nms/src/main/java/com/dfsek/terra/bukkit/nms/config/BiomeMoodSoundTemplate.java index 20f982920f..b7b774ae3c 100644 --- a/platforms/bukkit/nms/src/main/java/com/dfsek/terra/bukkit/nms/config/BiomeMoodSoundTemplate.java +++ b/platforms/bukkit/nms/src/main/java/com/dfsek/terra/bukkit/nms/config/BiomeMoodSoundTemplate.java @@ -5,7 +5,7 @@ import com.dfsek.tectonic.api.config.template.object.ObjectTemplate; import net.minecraft.core.registries.BuiltInRegistries; import net.minecraft.sounds.SoundEvent; -import net.minecraft.world.level.biome.AmbientMoodSettings; +import net.minecraft.world.attribute.AmbientMoodSettings; public class BiomeMoodSoundTemplate implements ObjectTemplate { diff --git a/platforms/bukkit/nms/src/main/java/com/dfsek/terra/bukkit/nms/config/BiomeParticleConfigTemplate.java b/platforms/bukkit/nms/src/main/java/com/dfsek/terra/bukkit/nms/config/BiomeParticleConfigTemplate.java index 99fe0cda39..7c31521f2b 100644 --- a/platforms/bukkit/nms/src/main/java/com/dfsek/terra/bukkit/nms/config/BiomeParticleConfigTemplate.java +++ b/platforms/bukkit/nms/src/main/java/com/dfsek/terra/bukkit/nms/config/BiomeParticleConfigTemplate.java @@ -8,12 +8,12 @@ import net.minecraft.commands.arguments.ParticleArgument; import net.minecraft.core.HolderLookup; import net.minecraft.core.registries.BuiltInRegistries; -import net.minecraft.world.level.biome.AmbientParticleSettings; +import net.minecraft.world.attribute.AmbientParticle; import java.util.stream.Stream; -public class BiomeParticleConfigTemplate implements ObjectTemplate { +public class BiomeParticleConfigTemplate implements ObjectTemplate { @Value("particle") @Default private String particle = null; @@ -23,13 +23,13 @@ public class BiomeParticleConfigTemplate implements ObjectTemplate> { @Value("id") @Default - private ResourceLocation id = null; + private Identifier id = null; @Override public EntityType get() { diff --git a/platforms/bukkit/nms/src/main/java/com/dfsek/terra/bukkit/nms/config/SoundEventTemplate.java b/platforms/bukkit/nms/src/main/java/com/dfsek/terra/bukkit/nms/config/SoundEventTemplate.java index 2535823611..4d7b7bddd1 100644 --- a/platforms/bukkit/nms/src/main/java/com/dfsek/terra/bukkit/nms/config/SoundEventTemplate.java +++ b/platforms/bukkit/nms/src/main/java/com/dfsek/terra/bukkit/nms/config/SoundEventTemplate.java @@ -3,14 +3,14 @@ import com.dfsek.tectonic.api.config.template.annotations.Default; import com.dfsek.tectonic.api.config.template.annotations.Value; import com.dfsek.tectonic.api.config.template.object.ObjectTemplate; -import net.minecraft.resources.ResourceLocation; +import net.minecraft.resources.Identifier; import net.minecraft.sounds.SoundEvent; public class SoundEventTemplate implements ObjectTemplate { @Value("id") @Default - private ResourceLocation id = null; + private Identifier id = null; @Value("distance-to-travel") @Default diff --git a/platforms/bukkit/nms/src/main/java/com/dfsek/terra/bukkit/nms/config/VanillaBiomeProperties.java b/platforms/bukkit/nms/src/main/java/com/dfsek/terra/bukkit/nms/config/VanillaBiomeProperties.java index 3cd1e992bb..cb74f635d9 100644 --- a/platforms/bukkit/nms/src/main/java/com/dfsek/terra/bukkit/nms/config/VanillaBiomeProperties.java +++ b/platforms/bukkit/nms/src/main/java/com/dfsek/terra/bukkit/nms/config/VanillaBiomeProperties.java @@ -6,10 +6,10 @@ import net.minecraft.resources.ResourceKey; import net.minecraft.sounds.Music; import net.minecraft.sounds.SoundEvent; -import net.minecraft.world.entity.npc.VillagerType; -import net.minecraft.world.level.biome.AmbientAdditionsSettings; -import net.minecraft.world.level.biome.AmbientMoodSettings; -import net.minecraft.world.level.biome.AmbientParticleSettings; +import net.minecraft.world.attribute.AmbientAdditionsSettings; +import net.minecraft.world.attribute.AmbientMoodSettings; +import net.minecraft.world.attribute.AmbientParticle; +import net.minecraft.world.entity.npc.villager.VillagerType; import net.minecraft.world.level.biome.Biome.TemperatureModifier; import net.minecraft.world.level.biome.BiomeSpecialEffects.GrassColorModifier; import net.minecraft.world.level.biome.MobSpawnSettings; @@ -52,7 +52,7 @@ public class VanillaBiomeProperties implements ConfigTemplate, Properties { @Value("particles") @Default - private AmbientParticleSettings particleConfig = null; + private AmbientParticle particleConfig = null; @Value("climate.precipitation") @Default @@ -130,7 +130,7 @@ public GrassColorModifier getGrassColorModifier() { return grassColorModifier; } - public AmbientParticleSettings getParticleConfig() { + public AmbientParticle getParticleConfig() { return particleConfig; } diff --git a/platforms/bukkit/nms/src/main/java/com/dfsek/terra/bukkit/nms/config/VillagerTypeTemplate.java b/platforms/bukkit/nms/src/main/java/com/dfsek/terra/bukkit/nms/config/VillagerTypeTemplate.java index c254628b8f..209ce3da7a 100644 --- a/platforms/bukkit/nms/src/main/java/com/dfsek/terra/bukkit/nms/config/VillagerTypeTemplate.java +++ b/platforms/bukkit/nms/src/main/java/com/dfsek/terra/bukkit/nms/config/VillagerTypeTemplate.java @@ -4,15 +4,15 @@ import com.dfsek.tectonic.api.config.template.annotations.Value; import com.dfsek.tectonic.api.config.template.object.ObjectTemplate; import net.minecraft.core.registries.BuiltInRegistries; +import net.minecraft.resources.Identifier; import net.minecraft.resources.ResourceKey; -import net.minecraft.resources.ResourceLocation; -import net.minecraft.world.entity.npc.VillagerType; +import net.minecraft.world.entity.npc.villager.VillagerType; public class VillagerTypeTemplate implements ObjectTemplate> { @Value("id") @Default - private ResourceLocation id = null; + private Identifier id = null; @Override public ResourceKey get() {