diff --git a/platforms/bukkit/common/src/main/java/com/dfsek/terra/bukkit/PlatformImpl.java b/platforms/bukkit/common/src/main/java/com/dfsek/terra/bukkit/PlatformImpl.java
index f802fcac5..a6849ec31 100644
--- a/platforms/bukkit/common/src/main/java/com/dfsek/terra/bukkit/PlatformImpl.java
+++ b/platforms/bukkit/common/src/main/java/com/dfsek/terra/bukkit/PlatformImpl.java
@@ -18,8 +18,6 @@
package com.dfsek.terra.bukkit;
import com.dfsek.tectonic.api.TypeRegistry;
-import com.dfsek.tectonic.api.depth.DepthTracker;
-import com.dfsek.tectonic.api.exception.LoadException;
import org.bukkit.Bukkit;
import org.bukkit.entity.EntityType;
import org.jetbrains.annotations.NotNull;
@@ -28,18 +26,15 @@ import org.slf4j.LoggerFactory;
import java.io.File;
import java.util.List;
-import java.util.Locale;
import com.dfsek.terra.AbstractPlatform;
import com.dfsek.terra.api.addon.BaseAddon;
import com.dfsek.terra.api.block.state.BlockState;
import com.dfsek.terra.api.handle.ItemHandle;
import com.dfsek.terra.api.handle.WorldHandle;
-import com.dfsek.terra.api.world.biome.PlatformBiome;
import com.dfsek.terra.bukkit.generator.BukkitChunkGeneratorWrapper;
import com.dfsek.terra.bukkit.handles.BukkitItemHandle;
import com.dfsek.terra.bukkit.handles.BukkitWorldHandle;
-import com.dfsek.terra.bukkit.world.BukkitPlatformBiome;
public class PlatformImpl extends AbstractPlatform {
@@ -112,13 +107,7 @@ public class PlatformImpl extends AbstractPlatform {
public void register(TypeRegistry registry) {
super.register(registry);
registry.registerLoader(BlockState.class, (type, o, loader, depthTracker) -> handle.createBlockState((String) o))
- .registerLoader(PlatformBiome.class, (type, o, loader, depthTracker) -> parseBiome((String) o, depthTracker))
.registerLoader(EntityType.class, (type, o, loader, depthTracker) -> EntityType.valueOf((String) o));
}
-
- protected BukkitPlatformBiome parseBiome(String id, DepthTracker depthTracker) throws LoadException {
- if(!id.startsWith("minecraft:")) throw new LoadException("Invalid biome identifier " + id, depthTracker);
- return new BukkitPlatformBiome(org.bukkit.block.Biome.valueOf(id.toUpperCase(Locale.ROOT).substring(10)));
- }
}
diff --git a/platforms/bukkit/common/src/main/java/com/dfsek/terra/bukkit/world/BukkitPlatformBiome.java b/platforms/bukkit/common/src/main/java/com/dfsek/terra/bukkit/world/BukkitPlatformBiome.java
deleted file mode 100644
index aff5773fa..000000000
--- a/platforms/bukkit/common/src/main/java/com/dfsek/terra/bukkit/world/BukkitPlatformBiome.java
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * This file is part of Terra.
- *
- * Terra is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * Terra is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Terra. If not, see .
- */
-
-package com.dfsek.terra.bukkit.world;
-
-import com.dfsek.terra.api.properties.Context;
-import com.dfsek.terra.api.properties.PropertyHolder;
-import com.dfsek.terra.api.world.biome.PlatformBiome;
-
-
-public class BukkitPlatformBiome implements PlatformBiome, PropertyHolder {
- private final org.bukkit.block.Biome biome;
- private final Context context = new Context();
-
- public BukkitPlatformBiome(org.bukkit.block.Biome biome) {
- this.biome = biome;
- }
-
- @Override
- public org.bukkit.block.Biome getHandle() {
- return biome;
- }
-
- @Override
- public Context getContext() {
- return context;
- }
-}
diff --git a/platforms/bukkit/nms/v1_19_R1/src/main/java/com/dfsek/terra/bukkit/nms/v1_19_R1/AwfulBukkitHacks.java b/platforms/bukkit/nms/v1_19_R1/src/main/java/com/dfsek/terra/bukkit/nms/v1_19_R1/AwfulBukkitHacks.java
index f2e4b30dd..9521c7532 100644
--- a/platforms/bukkit/nms/v1_19_R1/src/main/java/com/dfsek/terra/bukkit/nms/v1_19_R1/AwfulBukkitHacks.java
+++ b/platforms/bukkit/nms/v1_19_R1/src/main/java/com/dfsek/terra/bukkit/nms/v1_19_R1/AwfulBukkitHacks.java
@@ -1,31 +1,24 @@
package com.dfsek.terra.bukkit.nms.v1_19_R1;
-import com.google.common.collect.ImmutableMap;
-import com.mojang.serialization.Lifecycle;
+import com.dfsek.terra.bukkit.nms.v1_19_R1.util.BiomeUtil;
+
+import com.dfsek.terra.bukkit.nms.v1_19_R1.util.TagUtil;
+
import net.minecraft.core.Holder;
import net.minecraft.core.MappedRegistry;
-import net.minecraft.core.Registry;
import net.minecraft.core.WritableRegistry;
-import net.minecraft.data.BuiltinRegistries;
-import net.minecraft.resources.ResourceKey;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.tags.TagKey;
-import net.minecraft.world.entity.npc.VillagerType;
import net.minecraft.world.level.biome.Biome;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
-import java.util.Objects;
-import java.util.Optional;
import com.dfsek.terra.api.structure.configured.ConfiguredStructure;
import com.dfsek.terra.api.util.collection.ProbabilityCollection;
-import com.dfsek.terra.bukkit.nms.v1_19_R1.config.VanillaBiomeProperties;
-import com.dfsek.terra.bukkit.world.BukkitPlatformBiome;
import com.dfsek.terra.registry.master.ConfigRegistry;
@@ -46,62 +39,12 @@ public class AwfulBukkitHacks {
Reflection.MAPPED_REGISTRY.setFrozen((MappedRegistry>) biomeRegistry, false);
configRegistry.forEach(pack -> pack.getRegistry(com.dfsek.terra.api.world.biome.Biome.class).forEach((key, biome) -> {
- try {
- BukkitPlatformBiome platformBiome = (BukkitPlatformBiome) biome.getPlatformBiome();
-
- ResourceKey delegateKey = ResourceKey.create(Registry.BIOME_REGISTRY,
- new ResourceLocation("terra",
- NMSBiomeInjector.createBiomeID(pack, key)));
-
- VanillaBiomeProperties vanillaBiomeProperties = biome.getContext().get(VanillaBiomeProperties.class);
-
- Biome platform = NMSBiomeInjector.createBiome(vanillaBiomeProperties);
-
- BuiltinRegistries.register(BuiltinRegistries.BIOME, delegateKey, platform);
- biomeRegistry.register(delegateKey, platform, Lifecycle.stable());
- platformBiome.getContext().put(new NMSBiomeInfo(delegateKey));
-
- Map villagerMap = Reflection.VILLAGER_TYPE.getByBiome();
-
- villagerMap.put(ResourceKey.create(Registry.BIOME_REGISTRY, delegateKey.location()),
- Objects.requireNonNullElse(vanillaBiomeProperties.getVillagerType(), VillagerType.PLAINS));
-
- TERRA_BIOME_FERTILIZABLE_MAP.put(Holder.direct(platform), vanillaBiomeProperties.getFertilizables());
-
- for(ResourceLocation tag : vanillaBiomeProperties.getTags()) {
- TERRA_BIOME_TAG_MAP.getOrDefault(TagKey.create(Registry.BIOME_REGISTRY, tag), new ArrayList<>()).add(
- delegateKey.location());
- }
-
- LOGGER.debug("Registered biome: " + delegateKey);
- } catch(NoSuchFieldException | SecurityException | IllegalArgumentException | IllegalAccessException e) {
- throw new RuntimeException(e);
- }
+ BiomeUtil.registerBiome(biome, pack, key);
}));
Reflection.MAPPED_REGISTRY.setFrozen((MappedRegistry>) biomeRegistry, true); // freeze registry again :)
- LOGGER.info("Doing data-driven biome tag garbage....");
- LOGGER.info("who let this data drive?");
- Map, List>> collect = biomeRegistry
- .getTags() // streamKeysAndEntries
- .collect(HashMap::new,
- (map, pair) ->
- map.put(pair.getFirst(), new ArrayList<>(pair.getSecond().stream().toList())),
- HashMap::putAll);
-
- TERRA_BIOME_TAG_MAP.forEach((tag, biomeList) -> {
- collect.getOrDefault(tag, new ArrayList<>())
- .addAll(biomeList.stream()
- .map(biomeRegistry::getOptional)
- .filter(Optional::isPresent)
- .map(Optional::get)
- .map(Holder::direct)
- .toList());
- });
-
- biomeRegistry.resetTags();
- biomeRegistry.bindTags(ImmutableMap.copyOf(collect));
+ TagUtil.registerBiomeTags(biomeRegistry);
} catch(SecurityException | IllegalArgumentException exception) {
throw new RuntimeException(exception);
diff --git a/platforms/bukkit/nms/v1_19_R1/src/main/java/com/dfsek/terra/bukkit/nms/v1_19_R1/NMSBiomeProvider.java b/platforms/bukkit/nms/v1_19_R1/src/main/java/com/dfsek/terra/bukkit/nms/v1_19_R1/NMSBiomeProvider.java
index 0c5a8ef06..642a40509 100644
--- a/platforms/bukkit/nms/v1_19_R1/src/main/java/com/dfsek/terra/bukkit/nms/v1_19_R1/NMSBiomeProvider.java
+++ b/platforms/bukkit/nms/v1_19_R1/src/main/java/com/dfsek/terra/bukkit/nms/v1_19_R1/NMSBiomeProvider.java
@@ -1,5 +1,7 @@
package com.dfsek.terra.bukkit.nms.v1_19_R1;
+import com.dfsek.terra.bukkit.nms.v1_19_R1.config.ProtoPlatformBiome;
+
import com.mojang.serialization.Codec;
import net.minecraft.core.Holder;
import net.minecraft.core.Registry;
@@ -9,7 +11,6 @@ import net.minecraft.world.level.biome.Climate.Sampler;
import org.jetbrains.annotations.NotNull;
import com.dfsek.terra.api.world.biome.generation.BiomeProvider;
-import com.dfsek.terra.bukkit.world.BukkitPlatformBiome;
public class NMSBiomeProvider extends BiomeSource {
@@ -20,9 +21,7 @@ public class NMSBiomeProvider extends BiomeSource {
public NMSBiomeProvider(BiomeProvider delegate, long seed) {
super(delegate.stream()
.map(biome -> Registries.biomeRegistry()
- .getHolderOrThrow(((BukkitPlatformBiome) biome.getPlatformBiome()).getContext()
- .get(NMSBiomeInfo.class)
- .biomeKey())));
+ .getHolderOrThrow(((ProtoPlatformBiome) biome.getPlatformBiome()).getBiome())));
this.delegate = delegate;
this.seed = seed;
}
@@ -34,9 +33,7 @@ public class NMSBiomeProvider extends BiomeSource {
@Override
public @NotNull Holder getNoiseBiome(int x, int y, int z, @NotNull Sampler sampler) {
- return biomeRegistry.getHolderOrThrow(((BukkitPlatformBiome) delegate.getBiome(x << 2, y << 2, z << 2, seed)
- .getPlatformBiome()).getContext()
- .get(NMSBiomeInfo.class)
- .biomeKey());
+ return biomeRegistry.getHolderOrThrow(((ProtoPlatformBiome) delegate.getBiome(x << 2, y << 2, z << 2, seed)
+ .getPlatformBiome()).getBiome());
}
}
diff --git a/platforms/bukkit/nms/v1_19_R1/src/main/java/com/dfsek/terra/bukkit/nms/v1_19_R1/NMSInjectListener.java b/platforms/bukkit/nms/v1_19_R1/src/main/java/com/dfsek/terra/bukkit/nms/v1_19_R1/NMSInjectListener.java
index 1c8bf5170..59cf101e5 100644
--- a/platforms/bukkit/nms/v1_19_R1/src/main/java/com/dfsek/terra/bukkit/nms/v1_19_R1/NMSInjectListener.java
+++ b/platforms/bukkit/nms/v1_19_R1/src/main/java/com/dfsek/terra/bukkit/nms/v1_19_R1/NMSInjectListener.java
@@ -1,33 +1,21 @@
package com.dfsek.terra.bukkit.nms.v1_19_R1;
-import net.minecraft.resources.ResourceLocation;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.world.level.chunk.ChunkGenerator;
import org.bukkit.World;
-import org.bukkit.block.Block;
import org.bukkit.craftbukkit.v1_19_R1.CraftWorld;
import org.bukkit.event.EventHandler;
-import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
-import org.bukkit.event.block.BlockEvent;
-import org.bukkit.event.block.BlockFertilizeEvent;
-import org.bukkit.event.block.BlockGrowEvent;
-import org.bukkit.event.world.StructureGrowEvent;
import org.bukkit.event.world.WorldInitEvent;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.HashSet;
-import java.util.Random;
import java.util.Set;
import java.util.concurrent.locks.ReentrantLock;
import com.dfsek.terra.api.config.ConfigPack;
-import com.dfsek.terra.api.util.vector.Vector3Int;
-import com.dfsek.terra.api.world.ServerWorld;
import com.dfsek.terra.bukkit.generator.BukkitChunkGeneratorWrapper;
-import com.dfsek.terra.bukkit.nms.v1_19_R1.util.FertilizableUtil;
-import com.dfsek.terra.bukkit.world.BukkitAdapter;
public class NMSInjectListener implements Listener {
@@ -60,21 +48,4 @@ public class NMSInjectListener implements Listener {
INJECT_LOCK.unlock();
}
}
-
- @EventHandler(priority = EventPriority.HIGHEST)
- public void onBlockGrow(BlockGrowEvent event) {
- event.setCancelled(onGrow(event));
- }
-
- @EventHandler(priority = EventPriority.HIGHEST)
- public void onBlockFertilize(BlockFertilizeEvent event) {
- event.setCancelled(onGrow(event));
- }
-
- public boolean onGrow(BlockEvent event) {
- Block block = event.getBlock();
- Vector3Int pos = Vector3Int.of(block.getX(), block.getY(), block.getZ());
- ServerWorld world = BukkitAdapter.adapt(block.getWorld());
- return FertilizableUtil.grow(world, new Random(), pos, ResourceLocation.tryParse(block.getType().getKey().asString()));
- }
}
diff --git a/platforms/bukkit/nms/v1_19_R1/src/main/java/com/dfsek/terra/bukkit/nms/v1_19_R1/NMSPlatform.java b/platforms/bukkit/nms/v1_19_R1/src/main/java/com/dfsek/terra/bukkit/nms/v1_19_R1/NMSPlatform.java
index a43c271ef..47e67618d 100644
--- a/platforms/bukkit/nms/v1_19_R1/src/main/java/com/dfsek/terra/bukkit/nms/v1_19_R1/NMSPlatform.java
+++ b/platforms/bukkit/nms/v1_19_R1/src/main/java/com/dfsek/terra/bukkit/nms/v1_19_R1/NMSPlatform.java
@@ -1,6 +1,7 @@
package com.dfsek.terra.bukkit.nms.v1_19_R1;
import com.dfsek.tectonic.api.TypeRegistry;
+import com.dfsek.tectonic.api.depth.DepthTracker;
import com.dfsek.tectonic.api.exception.LoadException;
import com.dfsek.terra.api.addon.BaseAddon;
@@ -13,7 +14,9 @@ import com.dfsek.terra.bukkit.nms.v1_19_R1.config.BiomeMoodSoundTemplate;
import com.dfsek.terra.bukkit.nms.v1_19_R1.config.BiomeParticleConfigTemplate;
import com.dfsek.terra.bukkit.nms.v1_19_R1.config.EntityTypeTemplate;
+import com.dfsek.terra.bukkit.nms.v1_19_R1.config.FertilizableConfig;
import com.dfsek.terra.bukkit.nms.v1_19_R1.config.MusicSoundTemplate;
+import com.dfsek.terra.bukkit.nms.v1_19_R1.config.ProtoPlatformBiome;
import com.dfsek.terra.bukkit.nms.v1_19_R1.config.SoundEventTemplate;
import com.dfsek.terra.bukkit.nms.v1_19_R1.config.SpawnCostConfig;
@@ -25,6 +28,10 @@ import com.dfsek.terra.bukkit.nms.v1_19_R1.config.SpawnTypeConfig;
import com.dfsek.terra.bukkit.nms.v1_19_R1.config.VillagerTypeTemplate;
+import com.dfsek.terra.bukkit.nms.v1_19_R1.util.BiomeUtil;
+
+import net.minecraft.data.BuiltinRegistries;
+import net.minecraft.resources.ResourceKey;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.sounds.Music;
import net.minecraft.sounds.SoundEvent;
@@ -34,6 +41,7 @@ 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.level.biome.Biome;
import net.minecraft.world.level.biome.Biome.Precipitation;
import net.minecraft.world.level.biome.Biome.TemperatureModifier;
import net.minecraft.world.level.biome.BiomeSpecialEffects.GrassColorModifier;
@@ -55,6 +63,10 @@ public class NMSPlatform extends PlatformImpl {
Bukkit.getPluginManager().registerEvents(new NMSInjectListener(), plugin);
}
+ public ResourceKey getBiomeKey(ResourceLocation identifier) {
+ return BiomeUtil.getBiomeKey(identifier);
+ }
+
@Override
public void register(TypeRegistry registry) {
super.register(registry);
@@ -73,7 +85,7 @@ public class NMSPlatform extends PlatformImpl {
.registerLoader(GrassColorModifier.class,
(type, o, loader, depthTracker) -> TemperatureModifier.valueOf(((String) o).toUpperCase(
Locale.ROOT)))
- .registerLoader(MobCategory.class, (type, o, loader, depthTracker) -> MobCategory.valueOf((String) o))
+ .registerLoader(MobCategory.class,(type, o, loader, depthTracker) -> MobCategory.valueOf((String) o))
.registerLoader(AmbientParticleSettings.class, BiomeParticleConfigTemplate::new)
.registerLoader(SoundEvent.class, SoundEventTemplate::new)
.registerLoader(AmbientMoodSettings.class, BiomeMoodSoundTemplate::new)
@@ -84,7 +96,15 @@ public class NMSPlatform extends PlatformImpl {
.registerLoader(SpawnerData.class, SpawnEntryTemplate::new)
.registerLoader(SpawnTypeConfig.class, SpawnTypeConfig::new)
.registerLoader(MobSpawnSettings.class, SpawnSettingsTemplate::new)
- .registerLoader(VillagerType.class, VillagerTypeTemplate::new);
+ .registerLoader(VillagerType.class, VillagerTypeTemplate::new)
+ .registerLoader(FertilizableConfig.class, FertilizableConfig::new);
+ }
+
+
+ private ProtoPlatformBiome parseBiome(String id, DepthTracker tracker) throws LoadException {
+ ResourceLocation identifier = ResourceLocation.tryParse(id);
+ if(BuiltinRegistries.BIOME.get(identifier) == null) throw new LoadException("Invalid Biome ID: " + identifier, tracker); // failure.
+ return new ProtoPlatformBiome(identifier, getBiomeKey(identifier));
}
@Override
diff --git a/platforms/bukkit/nms/v1_19_R1/src/main/java/com/dfsek/terra/bukkit/nms/v1_19_R1/config/FertilizableConfig.java b/platforms/bukkit/nms/v1_19_R1/src/main/java/com/dfsek/terra/bukkit/nms/v1_19_R1/config/FertilizableConfig.java
new file mode 100644
index 000000000..1e545169e
--- /dev/null
+++ b/platforms/bukkit/nms/v1_19_R1/src/main/java/com/dfsek/terra/bukkit/nms/v1_19_R1/config/FertilizableConfig.java
@@ -0,0 +1,49 @@
+package com.dfsek.terra.bukkit.nms.v1_19_R1.config;
+
+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 java.util.Map;
+import net.minecraft.resources.ResourceLocation;
+import com.dfsek.terra.api.structure.configured.ConfiguredStructure;
+import com.dfsek.terra.api.util.collection.ProbabilityCollection;
+
+
+public class FertilizableConfig implements ObjectTemplate {
+ @Value("strucutres")
+ @Default
+ private ProbabilityCollection structures = null;
+
+ @Value("cooldowns")
+ @Default
+ private Map cooldowns = null;
+
+ @Value("can-grow")
+ @Default
+ private ConfiguredStructure canGrow = null;
+
+ @Value("villager-fertilizable")
+ @Default
+ private Boolean villagerFertilizable = null;
+
+ public ProbabilityCollection getStructures() {
+ return structures;
+ }
+
+ public Map getCooldowns() {
+ return cooldowns;
+ }
+
+ public ConfiguredStructure getCanGrow() {
+ return canGrow;
+ }
+
+ public Boolean isVillagerFertilizable() {
+ return villagerFertilizable;
+ }
+
+ @Override
+ public FertilizableConfig get() {
+ return this;
+ }
+}
diff --git a/platforms/bukkit/nms/v1_19_R1/src/main/java/com/dfsek/terra/bukkit/nms/v1_19_R1/config/ProtoPlatformBiome.java b/platforms/bukkit/nms/v1_19_R1/src/main/java/com/dfsek/terra/bukkit/nms/v1_19_R1/config/ProtoPlatformBiome.java
new file mode 100644
index 000000000..81284df60
--- /dev/null
+++ b/platforms/bukkit/nms/v1_19_R1/src/main/java/com/dfsek/terra/bukkit/nms/v1_19_R1/config/ProtoPlatformBiome.java
@@ -0,0 +1,51 @@
+/*
+ * This file is part of Terra.
+ *
+ * Terra is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Terra is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Terra. If not, see .
+ */
+
+package com.dfsek.terra.bukkit.nms.v1_19_R1.config;
+
+import com.dfsek.terra.api.world.biome.PlatformBiome;
+import com.dfsek.terra.bukkit.nms.v1_19_R1.util.MinecraftUtil;
+
+import net.minecraft.core.Registry;
+import net.minecraft.resources.ResourceKey;
+import net.minecraft.resources.ResourceLocation;
+import net.minecraft.world.level.biome.Biome;
+
+
+public class ProtoPlatformBiome implements PlatformBiome {
+ private final ResourceLocation identifier;
+
+ private final ResourceKey biome;
+
+ public ProtoPlatformBiome(ResourceLocation identifier, ResourceKey biome) {
+ this.identifier = identifier;
+ this.biome = biome;
+ }
+
+ public ResourceKey get(Registry registry) {
+ return MinecraftUtil.getEntry(registry, identifier).orElseThrow().unwrapKey().orElseThrow();
+ }
+
+ @Override
+ public Object getHandle() {
+ return identifier;
+ }
+
+ public ResourceKey getBiome() {
+ return biome;
+ }
+}
diff --git a/platforms/bukkit/nms/v1_19_R1/src/main/java/com/dfsek/terra/bukkit/nms/v1_19_R1/config/VanillaBiomeProperties.java b/platforms/bukkit/nms/v1_19_R1/src/main/java/com/dfsek/terra/bukkit/nms/v1_19_R1/config/VanillaBiomeProperties.java
index fd624c6c1..fd4db759a 100644
--- a/platforms/bukkit/nms/v1_19_R1/src/main/java/com/dfsek/terra/bukkit/nms/v1_19_R1/config/VanillaBiomeProperties.java
+++ b/platforms/bukkit/nms/v1_19_R1/src/main/java/com/dfsek/terra/bukkit/nms/v1_19_R1/config/VanillaBiomeProperties.java
@@ -3,6 +3,10 @@ package com.dfsek.terra.bukkit.nms.v1_19_R1.config;
import com.dfsek.tectonic.api.config.template.ConfigTemplate;
import com.dfsek.tectonic.api.config.template.annotations.Default;
import com.dfsek.tectonic.api.config.template.annotations.Value;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+
import net.minecraft.resources.ResourceLocation;
import net.minecraft.sounds.Music;
import net.minecraft.sounds.SoundEvent;
@@ -14,53 +18,46 @@ import net.minecraft.world.level.biome.Biome.Precipitation;
import net.minecraft.world.level.biome.Biome.TemperatureModifier;
import net.minecraft.world.level.biome.BiomeSpecialEffects.GrassColorModifier;
import net.minecraft.world.level.biome.MobSpawnSettings;
-
-import java.util.Collections;
-import java.util.List;
-import java.util.Map;
-
import com.dfsek.terra.api.properties.Properties;
-import com.dfsek.terra.api.structure.configured.ConfiguredStructure;
-import com.dfsek.terra.api.util.collection.ProbabilityCollection;
public class VanillaBiomeProperties implements ConfigTemplate, Properties {
@Value("minecraft.fertilizables")
@Default
- private Map> fertilizables = Collections.emptyMap();
+ private Map fertilizables = Collections.emptyMap();
@Value("minecraft.tags")
@Default
- private List tags = null;
+ private List tags = Collections.emptyList();
@Value("minecraft.colors.grass")
@Default
- private Integer grassColor = null;
+ private Integer grassColor = 0;
@Value("minecraft.colors.fog")
@Default
- private Integer fogColor = null;
+ private Integer fogColor = 0;
@Value("minecraft.colors.water")
@Default
- private Integer waterColor = null;
+ private Integer waterColor = 0;
@Value("minecraft.colors.water-fog")
@Default
- private Integer waterFogColor = null;
+ private Integer waterFogColor = 0;
@Value("minecraft.colors.foliage")
@Default
- private Integer foliageColor = null;
+ private Integer foliageColor = 0;
@Value("minecraft.colors.sky")
@Default
- private Integer skyColor = null;
+ private Integer skyColor = 0;
@Value("minecraft.colors.modifier")
@Default
- private GrassColorModifier grassColorModifier = null;
+ private GrassColorModifier grassColorModifier = GrassColorModifier.NONE;
@Value("minecraft.particles")
@Default
@@ -68,19 +65,19 @@ public class VanillaBiomeProperties implements ConfigTemplate, Properties {
@Value("minecraft.climate.precipitation")
@Default
- private Precipitation precipitation = null;
+ private Precipitation precipitation = Precipitation.NONE;
@Value("minecraft.climate.temperature")
@Default
- private Float temperature = null;
+ private Float temperature = 0.0f;
@Value("minecraft.climate.temperature-modifier")
@Default
- private TemperatureModifier temperatureModifier = null;
+ private TemperatureModifier temperatureModifier = TemperatureModifier.NONE;
@Value("minecraft.climate.downfall")
@Default
- private Float downfall = null;
+ private Float downfall = 0.0f;
@Value("minecraft.sound.loop-sound.sound")
@Default
@@ -100,13 +97,13 @@ public class VanillaBiomeProperties implements ConfigTemplate, Properties {
@Value("minecraft.spawning")
@Default
- private MobSpawnSettings spawnSettings = null;
+ private MobSpawnSettings spawnSettings = MobSpawnSettings.EMPTY;
@Value("minecraft.villager-type")
@Default
private VillagerType villagerType = null;
- public Map> getFertilizables() {
+ public Map getFertilizables() {
return fertilizables;
}
diff --git a/platforms/bukkit/nms/v1_19_R1/src/main/java/com/dfsek/terra/bukkit/nms/v1_19_R1/util/BiomeUtil.java b/platforms/bukkit/nms/v1_19_R1/src/main/java/com/dfsek/terra/bukkit/nms/v1_19_R1/util/BiomeUtil.java
new file mode 100644
index 000000000..32530f8c6
--- /dev/null
+++ b/platforms/bukkit/nms/v1_19_R1/src/main/java/com/dfsek/terra/bukkit/nms/v1_19_R1/util/BiomeUtil.java
@@ -0,0 +1,75 @@
+package com.dfsek.terra.bukkit.nms.v1_19_R1.util;
+
+import com.dfsek.terra.bukkit.nms.v1_19_R1.Reflection;
+import com.dfsek.terra.bukkit.nms.v1_19_R1.config.FertilizableConfig;
+import com.dfsek.terra.bukkit.nms.v1_19_R1.config.ProtoPlatformBiome;
+import com.dfsek.terra.bukkit.nms.v1_19_R1.config.VanillaBiomeProperties;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+import net.minecraft.core.Holder;
+import net.minecraft.core.Registry;
+import net.minecraft.data.BuiltinRegistries;
+import net.minecraft.resources.ResourceKey;
+import net.minecraft.resources.ResourceLocation;
+import net.minecraft.tags.TagKey;
+import net.minecraft.world.entity.npc.VillagerType;
+import com.dfsek.terra.api.config.ConfigPack;
+import com.dfsek.terra.api.world.biome.Biome;
+
+public class BiomeUtil {
+ private static final Logger logger = LoggerFactory.getLogger(BiomeUtil.class);
+
+ public static final Map, Map>
+ TERRA_BIOME_FERTILIZABLE_MAP = new HashMap<>();
+
+ public static final Map, List>
+ TERRA_BIOME_TAG_MAP = new HashMap<>();
+
+ protected static ResourceKey registerBiome(ResourceLocation identifier,
+ net.minecraft.world.level.biome.Biome biome) {
+ BuiltinRegistries.register(BuiltinRegistries.BIOME,
+ MinecraftUtil.registerKey(identifier)
+ .location(),
+ biome);
+ return getBiomeKey(identifier);
+ }
+
+ public static ResourceKey getBiomeKey(ResourceLocation identifier) {
+ return BuiltinRegistries.BIOME.getResourceKey(BuiltinRegistries.BIOME.get(identifier)).orElseThrow();
+ }
+
+ /**
+ * Clones a Vanilla biome and injects Terra data to create a Terra-vanilla biome delegate.
+ *
+ * @param biome The Terra BiomeBuilder.
+ * @param pack The ConfigPack this biome belongs to.
+ */
+ public static void registerBiome(Biome biome, ConfigPack pack,
+ com.dfsek.terra.api.registry.key.RegistryKey id) {
+ VanillaBiomeProperties vanillaBiomeProperties = biome.getContext().get(VanillaBiomeProperties.class);
+
+ net.minecraft.world.level.biome.Biome minecraftBiome = MinecraftUtil.createBiome(vanillaBiomeProperties);
+
+ ResourceLocation identifier = new ResourceLocation("terra", MinecraftUtil.createBiomeID(pack, id));
+
+ biome.setPlatformBiome(new ProtoPlatformBiome(identifier, registerBiome(identifier, minecraftBiome)));
+
+ Map villagerMap = Reflection.VILLAGER_TYPE.getByBiome();
+
+ villagerMap.put(ResourceKey.create(Registry.BIOME_REGISTRY, identifier),
+ Objects.requireNonNullElse(vanillaBiomeProperties.getVillagerType(), VillagerType.PLAINS));
+
+ TERRA_BIOME_FERTILIZABLE_MAP.put(Holder.direct(minecraftBiome), vanillaBiomeProperties.getFertilizables());
+
+ for(ResourceLocation tag : vanillaBiomeProperties.getTags()) {
+ TERRA_BIOME_TAG_MAP.getOrDefault(TagKey.create(Registry.BIOME_REGISTRY, tag), new ArrayList<>()).add(identifier);
+ }
+ }
+}
diff --git a/platforms/bukkit/nms/v1_19_R1/src/main/java/com/dfsek/terra/bukkit/nms/v1_19_R1/util/FertilizableUtil.java b/platforms/bukkit/nms/v1_19_R1/src/main/java/com/dfsek/terra/bukkit/nms/v1_19_R1/util/FertilizableUtil.java
deleted file mode 100644
index caa936035..000000000
--- a/platforms/bukkit/nms/v1_19_R1/src/main/java/com/dfsek/terra/bukkit/nms/v1_19_R1/util/FertilizableUtil.java
+++ /dev/null
@@ -1,29 +0,0 @@
-package com.dfsek.terra.bukkit.nms.v1_19_R1.util;
-
-import net.minecraft.resources.ResourceLocation;
-
-import java.util.Map;
-import java.util.Random;
-
-import com.dfsek.terra.api.structure.configured.ConfiguredStructure;
-import com.dfsek.terra.api.util.Rotation;
-import com.dfsek.terra.api.util.collection.ProbabilityCollection;
-import com.dfsek.terra.api.util.vector.Vector3Int;
-import com.dfsek.terra.api.world.ServerWorld;
-import com.dfsek.terra.bukkit.nms.v1_19_R1.AwfulBukkitHacks;
-
-
-public class FertilizableUtil {
- public static boolean grow(ServerWorld world, Random random, Vector3Int pos, ResourceLocation block) {
- Map> fertilizables = AwfulBukkitHacks.TERRA_BIOME_FERTILIZABLE_MAP.get(world.getBiomeProvider().getBiome(pos, world.getSeed()));
- if (fertilizables != null) {
- ProbabilityCollection probabilityCollection = fertilizables.get(block);
- if (probabilityCollection != null) {
- ConfiguredStructure structure = probabilityCollection.get(random);
- structure.getStructure().get(random).generate(pos, world, random, Rotation.NONE);
- return true;
- }
- }
- return false;
- }
-}
diff --git a/platforms/bukkit/nms/v1_19_R1/src/main/java/com/dfsek/terra/bukkit/nms/v1_19_R1/util/MinecraftAdapter.java b/platforms/bukkit/nms/v1_19_R1/src/main/java/com/dfsek/terra/bukkit/nms/v1_19_R1/util/MinecraftAdapter.java
new file mode 100644
index 000000000..1b830202f
--- /dev/null
+++ b/platforms/bukkit/nms/v1_19_R1/src/main/java/com/dfsek/terra/bukkit/nms/v1_19_R1/util/MinecraftAdapter.java
@@ -0,0 +1,55 @@
+/*
+ * This file is part of Terra.
+ *
+ * Terra is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Terra is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Terra. If not, see .
+ */
+
+package com.dfsek.terra.bukkit.nms.v1_19_R1.util;
+
+import com.dfsek.terra.api.util.vector.Vector3;
+import com.dfsek.terra.api.world.info.WorldProperties;
+import net.minecraft.core.BlockPos;
+import net.minecraft.world.level.LevelHeightAccessor;
+
+
+public final class MinecraftAdapter {
+
+ public static Vector3 adapt(BlockPos pos) {
+ return Vector3.of(pos.getX(), pos.getY(), pos.getZ());
+ }
+
+ public static WorldProperties adapt(LevelHeightAccessor height, long seed) {
+ return new WorldProperties() {
+ @Override
+ public long getSeed() {
+ return seed;
+ }
+
+ @Override
+ public int getMaxHeight() {
+ return height.getMaxBuildHeight();
+ }
+
+ @Override
+ public int getMinHeight() {
+ return height.getMinBuildHeight();
+ }
+
+ @Override
+ public Object getHandle() {
+ return height;
+ }
+ };
+ }
+}
diff --git a/platforms/bukkit/nms/v1_19_R1/src/main/java/com/dfsek/terra/bukkit/nms/v1_19_R1/util/MinecraftUtil.java b/platforms/bukkit/nms/v1_19_R1/src/main/java/com/dfsek/terra/bukkit/nms/v1_19_R1/util/MinecraftUtil.java
new file mode 100644
index 000000000..f6f8db471
--- /dev/null
+++ b/platforms/bukkit/nms/v1_19_R1/src/main/java/com/dfsek/terra/bukkit/nms/v1_19_R1/util/MinecraftUtil.java
@@ -0,0 +1,124 @@
+package com.dfsek.terra.bukkit.nms.v1_19_R1.util;
+
+import com.dfsek.terra.bukkit.nms.v1_19_R1.config.VanillaBiomeProperties;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.Locale;
+import java.util.Objects;
+import java.util.Optional;
+import net.minecraft.core.BlockPos;
+import net.minecraft.core.Holder;
+import net.minecraft.core.Registry;
+import net.minecraft.resources.ResourceKey;
+import net.minecraft.resources.ResourceLocation;
+import net.minecraft.world.level.LevelAccessor;
+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 net.minecraft.world.level.block.entity.RandomizableContainerBlockEntity;
+import net.minecraft.world.level.block.entity.SignBlockEntity;
+import net.minecraft.world.level.block.entity.SpawnerBlockEntity;
+import com.dfsek.terra.api.block.entity.BlockEntity;
+import com.dfsek.terra.api.block.entity.Container;
+import com.dfsek.terra.api.block.entity.MobSpawner;
+import com.dfsek.terra.api.block.entity.Sign;
+import com.dfsek.terra.api.config.ConfigPack;
+
+
+public final class MinecraftUtil {
+ public static final Logger logger = LoggerFactory.getLogger(MinecraftUtil.class);
+
+
+ private MinecraftUtil() {
+
+ }
+
+ public static Optional> getEntry(Registry registry, ResourceLocation identifier) {
+ return registry.getOptional(identifier)
+ .flatMap(registry::getResourceKey)
+ .map(registry::getOrCreateHolderOrThrow);
+ }
+
+ public static BlockEntity createState(LevelAccessor worldAccess, BlockPos pos) {
+ net.minecraft.world.level.block.entity.BlockEntity entity = worldAccess.getBlockEntity(pos);
+ if(entity instanceof SignBlockEntity) {
+ return (Sign) entity;
+ } else if(entity instanceof SpawnerBlockEntity) {
+ return (MobSpawner) entity;
+ } else if(entity instanceof RandomizableContainerBlockEntity) {
+ return (Container) entity;
+ }
+ return null;
+ }
+
+ public static ResourceKey registerKey(ResourceLocation identifier) {
+ return ResourceKey.create(Registry.BIOME_REGISTRY, identifier);
+ }
+
+ public static Biome createBiome(VanillaBiomeProperties vanillaBiomeProperties) {
+
+ BiomeGenerationSettings.Builder generationSettings = new BiomeGenerationSettings.Builder();
+
+ BiomeSpecialEffects.Builder effects = new BiomeSpecialEffects.Builder();
+
+ BiomeBuilder builder = new BiomeBuilder();
+
+ effects.waterColor(Objects.requireNonNull(vanillaBiomeProperties.getWaterColor()))
+ .waterFogColor(Objects.requireNonNull(vanillaBiomeProperties.getWaterFogColor()))
+ .fogColor(Objects.requireNonNull(vanillaBiomeProperties.getFogColor()))
+ .skyColor(Objects.requireNonNull(vanillaBiomeProperties.getSkyColor()))
+ .grassColorModifier(
+ Objects.requireNonNull(vanillaBiomeProperties.getGrassColorModifier()));
+
+ if(vanillaBiomeProperties.getFoliageColor() != null) {
+ effects.foliageColorOverride(vanillaBiomeProperties.getFoliageColor());
+ }
+
+ if(vanillaBiomeProperties.getGrassColor() != null) {
+ effects.grassColorOverride(vanillaBiomeProperties.getGrassColor());
+ }
+
+ if(vanillaBiomeProperties.getParticleConfig() != null) {
+ effects.ambientParticle(vanillaBiomeProperties.getParticleConfig());
+ }
+
+ if(vanillaBiomeProperties.getLoopSound() != null) {
+ effects.ambientLoopSound(vanillaBiomeProperties.getLoopSound());
+ }
+
+ if(vanillaBiomeProperties.getMoodSound() != null) {
+ effects.ambientMoodSound(vanillaBiomeProperties.getMoodSound());
+ }
+
+ if(vanillaBiomeProperties.getAdditionsSound() != null) {
+ effects.ambientAdditionsSound(vanillaBiomeProperties.getAdditionsSound());
+ }
+
+ if(vanillaBiomeProperties.getMusic() != null) {
+ effects.backgroundMusic(vanillaBiomeProperties.getMusic());
+ }
+
+ builder.precipitation(Objects.requireNonNull(vanillaBiomeProperties.getPrecipitation()));
+
+ builder.temperature(Objects.requireNonNull(vanillaBiomeProperties.getTemperature()));
+
+ builder.downfall(Objects.requireNonNull(vanillaBiomeProperties.getDownfall()));
+
+ builder.temperatureAdjustment(Objects.requireNonNull(vanillaBiomeProperties.getTemperatureModifier()));
+
+ builder.mobSpawnSettings(Objects.requireNonNull(vanillaBiomeProperties.getSpawnSettings()));
+
+ return builder
+ .specialEffects(effects.build())
+ .generationSettings(generationSettings.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);
+ }
+}
diff --git a/platforms/bukkit/nms/v1_19_R1/src/main/java/com/dfsek/terra/bukkit/nms/v1_19_R1/util/TagUtil.java b/platforms/bukkit/nms/v1_19_R1/src/main/java/com/dfsek/terra/bukkit/nms/v1_19_R1/util/TagUtil.java
new file mode 100644
index 000000000..669791c71
--- /dev/null
+++ b/platforms/bukkit/nms/v1_19_R1/src/main/java/com/dfsek/terra/bukkit/nms/v1_19_R1/util/TagUtil.java
@@ -0,0 +1,60 @@
+package com.dfsek.terra.bukkit.nms.v1_19_R1.util;
+
+
+import com.google.common.collect.ImmutableMap;
+import net.minecraft.core.Holder;
+import net.minecraft.core.Registry;
+import net.minecraft.tags.TagKey;
+import net.minecraft.world.level.biome.Biome;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+
+
+public final class TagUtil {
+ private static final Logger logger = LoggerFactory.getLogger(TagUtil.class);
+
+ private TagUtil() {
+
+ }
+
+ private static Map, List>> tagsToMutableMap(Registry registry) {
+ return registry
+ .getTags()
+ .collect(HashMap::new,
+ (map, pair) ->
+ map.put(pair.getFirst(), new ArrayList<>(pair.getSecond().stream().toList())),
+ HashMap::putAll);
+ }
+
+ public static void registerBiomeTags(Registry registry) {
+ logger.info("Doing data-driven biome tag garbage....");
+ logger.info("who let this data drive?");
+ Map, List>> collect = tagsToMutableMap(registry);
+
+ BiomeUtil.TERRA_BIOME_TAG_MAP.forEach((tag, biomeList) -> {
+ collect.getOrDefault(tag, new ArrayList<>())
+ .addAll(biomeList.stream()
+ .map(registry::getOptional)
+ .filter(Optional::isPresent)
+ .map(Optional::get)
+ .map(Holder::direct)
+ .toList());
+ });
+
+ registry.resetTags();
+ registry.bindTags(ImmutableMap.copyOf(collect));
+
+ if(logger.isDebugEnabled()) {
+ registry.holders()
+ .map(e -> e.key().location() + ": " +
+ e.tags().reduce("", (s, t) -> t.location() + ", " + s, String::concat))
+ .forEach(logger::debug);
+ }
+ }
+}